public void Should_ScaleToEvenDimensions_ForTransportStream() { FFmpegProfile ffmpegProfile = TestProfile() with { Resolution = new Resolution { Width = 1280, Height = 720 } }; var version = new MediaVersion { Width = 706, Height = 362, SampleAspectRatio = "32:27" }; FFmpegPlaybackSettings actual = _calculator.CalculateSettings( StreamingMode.TransportStream, ffmpegProfile, version, new MediaStream(), new MediaStream(), DateTimeOffset.Now, DateTimeOffset.Now, TimeSpan.Zero, TimeSpan.Zero, false, None); IDisplaySize scaledSize = actual.ScaledSize.IfNone(new MediaVersion { Width = 0, Height = 0 }); scaledSize.Width.Should().Be(1280); scaledSize.Height.Should().Be(554); actual.PadToDesiredResolution.Should().BeTrue(); }
public FFmpegComplexFilterBuilder WithWatermark( Option <ChannelWatermark> watermark, Option <List <FadePoint> > maybeFadePoints, IDisplaySize resolution, Option <int> watermarkIndex) { _watermark = watermark; _maybeFadePoints = maybeFadePoints; _resolution = resolution; _watermarkIndex = watermarkIndex; return(this); }
public DetailPage() { InitializeComponent(); InitUserImage(); InitSliders(); Display = DependencyService.Get <IDisplaySize>(); TextToSpeech.TextToSpeech_Completed += TextToSpeech_TextToSpeech_Completed; }
public MainPage() { InitializeComponent(); InitUserImage(); InitSliders(); fFile = DependencyService.Get <IFile>(); Display = DependencyService.Get <IDisplaySize>(); TextToSpeech.TextToSpeech_Completed += TextToSpeech_TextToSpeech_Completed; NavigationPage.SetHasNavigationBar(this, false); //if ( Setting.IntroPopup == false) // Navigation.PushModalAsync(new TestCarouselPage()); }
internal static bool IsSameSizeAs(this IDisplaySize @this, IDisplaySize that) => @this.Width == that.Width && @this.Height == that.Height;
internal static IDisplaySize PadToEven(this IDisplaySize size) => new DisplaySize(size.Width + size.Width % 2, size.Height + size.Height % 2);
public FFmpegComplexFilterBuilder WithBlackBars(IDisplaySize padToSize) { _padToSize = Some(padToSize); return(this); }
public FFmpegComplexFilterBuilder WithScaling(IDisplaySize scaleToSize) { _scaleToSize = Some(scaleToSize); return(this); }
public async Task <Command> ForError( string ffmpegPath, Channel channel, Option <TimeSpan> duration, string errorMessage, bool hlsRealtime, long ptsOffset) { FFmpegPlaybackSettings playbackSettings = _playbackSettingsCalculator.CalculateErrorSettings(channel.FFmpegProfile); IDisplaySize desiredResolution = channel.FFmpegProfile.Resolution; var fontSize = (int)Math.Round(channel.FFmpegProfile.Resolution.Height / 20.0); var margin = (int)Math.Round(channel.FFmpegProfile.Resolution.Height * 0.05); string subtitleFile = await new SubtitleBuilder(_tempFilePool) .WithResolution(desiredResolution) .WithFontName("Roboto") .WithFontSize(fontSize) .WithAlignment(2) .WithMarginV(margin) .WithPrimaryColor("&HFFFFFF") .WithFormattedContent(errorMessage.Replace(Environment.NewLine, "\\N")) .BuildFile(); var videoStream = new MediaStream { Index = 0 }; var audioStream = new MediaStream { Index = 0 }; string videoCodec = playbackSettings.VideoFormat switch { FFmpegProfileVideoFormat.Hevc => "libx265", FFmpegProfileVideoFormat.Mpeg2Video => "mpeg2video", _ => "libx264" }; string audioCodec = playbackSettings.AudioFormat switch { FFmpegProfileAudioFormat.Ac3 => "ac3", _ => "aac" }; FFmpegProcessBuilder builder = new FFmpegProcessBuilder(ffmpegPath, false, _logger) .WithThreads(1) .WithQuiet() .WithFormatFlags(playbackSettings.FormatFlags) .WithRealtimeOutput(playbackSettings.RealtimeOutput) .WithLoopedImage(Path.Combine(FileSystemLayout.ResourcesCacheFolder, "background.png")) .WithLibavfilter() .WithInput("anullsrc") .WithSubtitleFile(subtitleFile) .WithFilterComplex( videoStream, audioStream, Path.Combine(FileSystemLayout.ResourcesCacheFolder, "background.png"), "fake-audio-path", playbackSettings.VideoFormat) .WithPixfmt("yuv420p") .WithPlaybackArgs(playbackSettings, videoCodec, audioCodec) .WithMetadata(channel, None); await duration.IfSomeAsync(d => builder = builder.WithDuration(d)); Process process = channel.StreamingMode switch { // HLS needs to segment and generate playlist StreamingMode.HttpLiveStreamingSegmenter => builder.WithHls( channel.Number, None, ptsOffset, playbackSettings.VideoTrackTimeScale, playbackSettings.FrameRate) .Build(), _ => builder.WithFormat("mpegts") .WithPipe() .Build() }; return(Cli.Wrap(process.StartInfo.FileName) .WithArguments(process.StartInfo.ArgumentList) .WithValidation(CommandResultValidation.None) .WithEnvironmentVariables(process.StartInfo.Environment.ToDictionary(kvp => kvp.Key, kvp => kvp.Value)) .WithStandardErrorPipe(PipeTarget.ToStream(Stream.Null))); }
private bool NeedToPad(IDisplaySize target, IDisplaySize displaySize) => displaySize.Width != target.Width || displaySize.Height != target.Height;