// [TestMethod, Timeout(10000)] public async Task Video_ToMP4_Args_StreamOutputPipe_Async_Failure() { await Assert.ThrowsExceptionAsync <FFMpegException>(async() => { await using var ms = new MemoryStream(); var pipeSource = new StreamPipeSink(ms); await FFMpegArguments .FromInputFiles(VideoLibrary.LocalVideo) .ForceFormat("mkv") .OutputToPipe(pipeSource) .ProcessAsynchronously(); }); }
public void Video_ToMP4_Args_StreamOutputPipe_Async() { using var ms = new MemoryStream(); var pipeSource = new StreamPipeSink(ms); FFMpegArguments .FromInputFiles(VideoLibrary.LocalVideo) .WithVideoCodec(VideoCodec.LibX264) .ForceFormat("matroska") .OutputToPipe(pipeSource) .ProcessAsynchronously() .WaitForResult(); }
public async Task TestDuplicateRun() { FFMpegArguments .FromFileInput(TestResources.Mp4Video) .OutputToFile("temporary.mp4") .ProcessSynchronously(); await FFMpegArguments .FromFileInput(TestResources.Mp4Video) .OutputToFile("temporary.mp4") .ProcessAsynchronously(); File.Delete("temporary.mp4"); }
public void ConvertFromPipe(ContainerFormat type, System.Drawing.Imaging.PixelFormat fmt, params IArgument[] arguments) { var output = Input.OutputLocation(type); try { var videoFramesSource = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, fmt, 256, 256)); var processor = FFMpegArguments.FromPipeInput(videoFramesSource).OutputToFile(output, false, opt => { foreach (var arg in arguments) { opt.WithArgument(arg); } }); var scaling = arguments.OfType <ScaleArgument>().FirstOrDefault(); processor.ProcessSynchronously(); var outputVideo = FFProbe.Analyse(output); Assert.IsTrue(File.Exists(output)); if (scaling?.Size == null) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, videoFramesSource.Width); Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, videoFramesSource.Height); } else { if (scaling.Size.Value.Width != -1) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, scaling.Size.Value.Width); } if (scaling.Size.Value.Height != -1) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, scaling.Size.Value.Height); } Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Width, videoFramesSource.Width); Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Height, videoFramesSource.Height); } } finally { if (File.Exists(output)) { File.Delete(output); } } }
public void Builder_BuildString_DrawtextFilter_Alt() { var str = FFMpegArguments .FromFileInput("input.mp4") .OutputToFile("output.mp4", false, opt => opt .WithVideoFilters(filterOptions => filterOptions .DrawText(DrawTextOptions .Create("Stack Overflow", "/path/to/font.ttf", ("fontcolor", "white"), ("fontsize", "24"))))) .Arguments; Assert.AreEqual( "-i \"input.mp4\" -vf \"drawtext=text='Stack Overflow':fontfile=/path/to/font.ttf:fontcolor=white:fontsize=24\" \"output.mp4\"", str); }
/// <summary> /// Asynchronous task aimed to read a certain chunk of open file. /// </summary> /// <param name="secondStart">Starting second of extracted chunk</param> /// <param name="secondEnd">Ending second of extracted chunk</param> /// <returns>Memory chunk containing retrieved samples</returns> private async Task <MemoryStream> readAudioChunk(long secondStart, long secondEnd) { var memoryStream = new MemoryStream(); string time = "-ss " + secondStart + " -to " + secondEnd; await FFMpegArguments .FromFileInput(_filePath, true, options => options.WithCustomArgument(time)) .OutputToPipe(new StreamPipeSink(memoryStream), options => options.ForceFormat("u16be")) .ProcessAsynchronously(); return(memoryStream); }
public void Video_ToTS_Args() { using var outputFile = new TemporaryFile($"out{VideoType.MpegTs.Extension}"); var success = FFMpegArguments .FromFileInput(TestResources.Mp4Video) .OutputToFile(outputFile, false, opt => opt .CopyChannel() .WithBitStreamFilter(Channel.Video, Filter.H264_Mp4ToAnnexB) .ForceFormat(VideoType.MpegTs)) .ProcessSynchronously(); Assert.IsTrue(success); }
public void Audio_ToAAC_Args_Pipe_InvalidSampleRate() { using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); var audioSamplesSource = new RawAudioPipeSource(new List <IAudioSample>()) { SampleRate = 0, }; var ex = Assert.ThrowsException <FFMpegException>(() => FFMpegArguments .FromPipeInput(audioSamplesSource) .OutputToFile(outputFile, false, opt => opt .WithAudioCodec(AudioCodec.Aac)) .ProcessSynchronously()); }
public void Video_StreamFile_OutputToMemoryStream() { var output = new MemoryStream(); FFMpegArguments .FromPipeInput(new StreamPipeSource(File.OpenRead(TestResources.WebmVideo)), options => options.ForceFormat("webm")) .OutputToPipe(new StreamPipeSink(output), options => options .ForceFormat("mpegts")) .ProcessSynchronously(); output.Position = 0; var result = FFProbe.Analyse(output); Console.WriteLine(result.Duration); }
private void ConvertFromStreamPipe(ContainerFormat type, params IArgument[] arguments) { using var outputFile = new TemporaryFile($"out{type.Extension}"); var input = FFProbe.Analyse(TestResources.WebmVideo); using var inputStream = File.OpenRead(input.Path); var processor = FFMpegArguments .FromPipeInput(new StreamPipeSource(inputStream)) .OutputToFile(outputFile, false, opt => { foreach (var arg in arguments) { opt.WithArgument(arg); } }); var scaling = arguments.OfType <ScaleArgument>().FirstOrDefault(); var success = processor.ProcessSynchronously(); var outputVideo = FFProbe.Analyse(outputFile); Assert.IsTrue(success); Assert.IsTrue(File.Exists(outputFile)); Assert.IsTrue(Math.Abs((outputVideo.Duration - input.Duration).TotalMilliseconds) < 1000.0 / input.PrimaryVideoStream.FrameRate); if (scaling?.Size == null) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width); Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height); } else { if (scaling.Size.Value.Width != -1) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, scaling.Size.Value.Width); } if (scaling.Size.Value.Height != -1) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, scaling.Size.Value.Height); } Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width); Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height); } }
public static async Task Convert(string input, string output, Action <TimeSpan, TimeSpan> onProgress) { var info = await FFProbe.AnalyseAsync(input); await FFMpegArguments .FromFileInput(input) .OutputToFile(output, true, options => options .WithVideoCodec("libx265") .WithConstantRateFactor(28) .WithFastStart() ) .NotifyOnProgress(progress => onProgress(progress, info.Duration)) .ProcessAsynchronously(); }
public void Video_ToMP4_YUV444p() { using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); var success = FFMpegArguments .FromFileInput(TestResources.WebmVideo) .OutputToFile(outputFile, false, opt => opt .WithVideoCodec(VideoCodec.LibX264) .ForcePixelFormat("yuv444p")) .ProcessSynchronously(); Assert.IsTrue(success); var analysis = FFProbe.Analyse(outputFile); Assert.IsTrue(analysis.VideoStreams.First().PixelFormat == "yuv444p"); }
/// <summary> /// The Record. /// </summary> /// <param name="outputFilePath">The outputFilePath<see cref="string"/>.</param> /// <param name="element">The element<see cref="FrameworkElement"/>.</param> /// <param name="drawChartAction">The drawChartAction<see cref="Action{int}"/>.</param> /// <param name="frameCount">The frameCount<see cref="int"/>.</param> /// <param name="token">The token<see cref="CancellationToken"/>.</param> public static void Record(string outputFilePath, FrameworkElement element, Action <int> drawChartAction, int frameCount, CancellationToken token) { if (File.Exists(outputFilePath)) { File.Delete(outputFilePath); } var codecArgs = new VideoCodecArgument(VideoCodec.LibX264); var videoType = VideoType.Mp4; var videoFramesSource = new RawVideoPipeSource(CreateChartBitmaps(element, drawChartAction, frameCount, token)); var arguments = FFMpegArguments.FromPipeInput(videoFramesSource); ////arguments.WithArgument(codecArgs); var processor = arguments.OutputToFile(outputFilePath, true, (option) => option.WithArgument(codecArgs)); processor.ProcessSynchronously(); }
public void Builder_BuildString_DrawtextFilter() { var str = FFMpegArguments .FromInputFiles(true, "input.mp4") .DrawText(DrawTextOptions .Create("Stack Overflow", "/path/to/font.ttf") .WithParameter("fontcolor", "white") .WithParameter("fontsize", "24") .WithParameter("box", "1") .WithParameter("boxcolor", "[email protected]") .WithParameter("boxborderw", "5") .WithParameter("x", "(w-text_w)/2") .WithParameter("y", "(h-text_h)/2")) .OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -vf drawtext=\"text='Stack Overflow':fontfile=/path/to/font.ttf:fontcolor=white:fontsize=24:box=1:[email protected]:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2\" \"output.mp4\"", str); }
public void Convert(ContainerFormat type, Action <IMediaAnalysis> validationMethod, params IArgument[] arguments) { using var outputFile = new TemporaryFile($"out{type.Extension}"); var input = FFProbe.Analyse(TestResources.Mp4Video); var processor = FFMpegArguments .FromFileInput(TestResources.Mp4Video) .OutputToFile(outputFile, false, opt => { foreach (var arg in arguments) { opt.WithArgument(arg); } }); var scaling = arguments.OfType <ScaleArgument>().FirstOrDefault(); processor.ProcessSynchronously(); var outputVideo = FFProbe.Analyse(outputFile); Assert.IsTrue(File.Exists(outputFile)); Assert.AreEqual(outputVideo.Duration.TotalSeconds, input.Duration.TotalSeconds, 0.1); validationMethod?.Invoke(outputVideo); if (scaling?.Size == null) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width); Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height); } else { if (scaling.Size.Value.Width != -1) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, scaling.Size.Value.Width); } if (scaling.Size.Value.Height != -1) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, scaling.Size.Value.Height); } Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width); Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height); } }
// [DataRow(PixelFormat.Format48bppRgb)] public void RawVideoPipeSource_Ogv_Scale(System.Drawing.Imaging.PixelFormat pixelFormat) { using var outputFile = new TemporaryFile($"out{VideoType.Ogv.Extension}"); var videoFramesSource = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, pixelFormat, 256, 256)); FFMpegArguments .FromPipeInput(videoFramesSource) .OutputToFile(outputFile, false, opt => opt .WithVideoFilters(filterOptions => filterOptions .Scale(VideoSize.Ed)) .WithVideoCodec(VideoCodec.LibTheora)) .ProcessSynchronously(); var analysis = FFProbe.Analyse(outputFile); Assert.AreEqual((int)VideoSize.Ed, analysis.PrimaryVideoStream !.Width); }
public async Task Video_ToTS_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelFormat) { using var output = new TemporaryFile($"out{VideoType.Ts.Extension}"); var input = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, pixelFormat, 256, 256)); var success = await FFMpegArguments .FromPipeInput(input) .OutputToFile(output, false, opt => opt .ForceFormat(VideoType.Ts)) .ProcessAsynchronously(); Assert.IsTrue(success); var analysis = await FFProbe.AnalyseAsync(output); Assert.AreEqual(VideoType.Ts.Name, analysis.Format.FormatName); }
private async Task <Stream> GenerateSoundStream(Stream inputStream) { MemoryStream returnStream = null; using (Stream outputStream = new MemoryStream()) { await FFMpegArguments .FromPipeInput(new StreamPipeSource(inputStream)) .OutputToPipe(new StreamPipeSink(outputStream), options => options .WithAudioCodec(AudioCodec.LibMp3Lame) .ForceFormat("mp3")) .ProcessAsynchronously(); await outputStream.CopyToAsync(returnStream); } return(returnStream); }
private void ConvertToStreamPipe(params IArgument[] arguments) { using var ms = new MemoryStream(); var processor = FFMpegArguments .FromFileInput(TestResources.Mp4Video) .OutputToPipe(new StreamPipeSink(ms), opt => { foreach (var arg in arguments) { opt.WithArgument(arg); } }); var scaling = arguments.OfType <ScaleArgument>().FirstOrDefault(); processor.ProcessSynchronously(); ms.Position = 0; var outputVideo = FFProbe.Analyse(ms); var input = FFProbe.Analyse(TestResources.Mp4Video); // Assert.IsTrue(Math.Abs((outputVideo.Duration - input.Duration).TotalMilliseconds) < 1000.0 / input.PrimaryVideoStream.FrameRate); if (scaling?.Size == null) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width); Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height); } else { if (scaling.Size.Value.Width != -1) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, scaling.Size.Value.Width); } if (scaling.Size.Value.Height != -1) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, scaling.Size.Value.Height); } Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width); Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height); } }
private void ConvertToStreamPipe(params IArgument[] inputArguments) { using var ms = new MemoryStream(); var arguments = FFMpegArguments.FromInputFiles(VideoLibrary.LocalVideo); foreach (var arg in inputArguments) { arguments.WithArgument(arg); } var streamPipeDataReader = new StreamPipeSink(ms); var processor = arguments.OutputToPipe(streamPipeDataReader); var scaling = arguments.Find <ScaleArgument>(); processor.ProcessSynchronously(); ms.Position = 0; var outputVideo = FFProbe.Analyse(ms); var input = FFProbe.Analyse(VideoLibrary.LocalVideo.FullName); // Assert.IsTrue(Math.Abs((outputVideo.Duration - input.Duration).TotalMilliseconds) < 1000.0 / input.PrimaryVideoStream.FrameRate); if (scaling?.Size == null) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width); Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height); } else { if (scaling.Size.Value.Width != -1) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Width, scaling.Size.Value.Width); } if (scaling.Size.Value.Height != -1) { Assert.AreEqual(outputVideo.PrimaryVideoStream.Height, scaling.Size.Value.Height); } Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Width, input.PrimaryVideoStream.Width); Assert.AreNotEqual(outputVideo.PrimaryVideoStream.Height, input.PrimaryVideoStream.Height); } }
public void TranscodeToMemoryStream_Success() { using var output = new MemoryStream(); var success = FFMpegArguments .FromFileInput(TestResources.WebmVideo) .OutputToPipe(new StreamPipeSink(output), opt => opt .WithVideoCodec(VideoCodec.LibVpx) .ForceFormat("matroska")) .ProcessSynchronously(); Assert.IsTrue(success); output.Position = 0; var inputAnalysis = FFProbe.Analyse(TestResources.WebmVideo); var outputAnalysis = FFProbe.Analyse(output); Assert.AreEqual(inputAnalysis.Duration.TotalSeconds, outputAnalysis.Duration.TotalSeconds, 0.3); }
public void Video_Duration() { var video = FFProbe.Analyse(TestResources.Mp4Video); var outputFile = new TemporaryFile("out.mp4"); FFMpegArguments .FromFileInput(TestResources.Mp4Video) .OutputToFile(outputFile, false, opt => opt.WithDuration(TimeSpan.FromSeconds(video.Duration.TotalSeconds - 2))) .ProcessSynchronously(); Assert.IsTrue(File.Exists(outputFile)); var outputVideo = FFProbe.Analyse(outputFile); Assert.AreEqual(video.Duration.Days, outputVideo.Duration.Days); Assert.AreEqual(video.Duration.Hours, outputVideo.Duration.Hours); Assert.AreEqual(video.Duration.Minutes, outputVideo.Duration.Minutes); Assert.AreEqual(video.Duration.Seconds - 2, outputVideo.Duration.Seconds); }
public void CaptureScreenTest() { var testFilePath = @"C:\Users\benp\test.mp4"; //var args = FFMpegArguments.FromScreenCapture(ScreenCaptureMethod.DShow, captureTarget: @"video=""UScreenCapture"":audio=""Stereo Mix"""); var args = FFMpegArguments.FromScreenCapture(ScreenCaptureMethod.GdiGrab); var processor = args.OutputToFile(testFilePath); var task = processor.CancellableThrough(out var cancelEvent); Task.Run(() => Thread.Sleep(TimeSpan.FromSeconds(5))).ContinueWith((t) => cancelEvent.Invoke()); var result = task.ProcessSynchronously(); var x = FFProbe.Analyse(testFilePath); Assert.IsTrue(result, "Failed to record"); Assert.IsTrue(x.Duration > TimeSpan.FromSeconds(1), "Resulting File too short"); }
public void Builder_BuildString_SubtitleHardBurnFilter() { var str = FFMpegArguments .FromFileInput("input.mp4") .OutputToFile("output.mp4", false, opt => opt .WithVideoFilters(filterOptions => filterOptions .HardBurnSubtitle(SubtitleHardBurnOptions .Create(subtitlePath: "sample.srt") .SetCharacterEncoding("UTF-8") .SetOriginalSize(1366, 768) .SetSubtitleIndex(0) .WithStyle(StyleOptions.Create() .WithParameter("FontName", "DejaVu Serif") .WithParameter("PrimaryColour", "&HAA00FF00"))))) .Arguments; Assert.AreEqual("-i \"input.mp4\" -vf \"subtitles=sample.srt:charenc=UTF-8:original_size=1366x768:stream_index=0:force_style='FontName=DejaVu Serif\\,PrimaryColour=&HAA00FF00'\" \"output.mp4\"", str); }
public void Video_TranscodeInMemory() { using var resStream = new MemoryStream(); var reader = new StreamPipeSink(resStream); var writer = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 128, 128)); FFMpegArguments .FromPipeInput(writer) .OutputToPipe(reader, opt => opt .WithVideoCodec("vp9") .ForceFormat("webm")) .ProcessSynchronously(); resStream.Position = 0; var vi = FFProbe.Analyse(resStream); Assert.AreEqual(vi.PrimaryVideoStream.Width, 128); Assert.AreEqual(vi.PrimaryVideoStream.Height, 128); }
public void Video_OutputsData() { var outputFile = new TemporaryFile("out.mp4"); var dataReceived = false; FFMpegOptions.Configure(opt => opt.Encoding = Encoding.UTF8); var success = FFMpegArguments .FromFileInput(TestResources.Mp4Video) .WithGlobalOptions(options => options .WithVerbosityLevel(VerbosityLevel.Info)) .OutputToFile(outputFile, false, opt => opt .WithDuration(TimeSpan.FromSeconds(2))) .NotifyOnOutput((_, _) => dataReceived = true) .ProcessSynchronously(); Assert.IsTrue(dataReceived); Assert.IsTrue(success); Assert.IsTrue(File.Exists(outputFile)); }
public void Video_ToMP4_Args_Pipe_DifferentImageSizes() { using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); var frames = new List <IVideoFrame> { BitmapSource.CreateVideoFrame(0, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 255, 255, 1, 0), BitmapSource.CreateVideoFrame(0, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 256, 256, 1, 0) }; var videoFramesSource = new RawVideoPipeSource(frames); var ex = Assert.ThrowsException <FFMpegException>(() => FFMpegArguments .FromPipeInput(videoFramesSource) .OutputToFile(outputFile, false, opt => opt .WithVideoCodec(VideoCodec.LibX264)) .ProcessSynchronously()); Assert.IsInstanceOfType(ex.GetBaseException(), typeof(FFMpegStreamFormatException)); }
/// <summary> /// Downloads an Episode based on a M3u8-File. /// </summary> /// <param name="episodeUrl">A Url corresponding to an M3u8-File.</param> /// <param name="targetFilePath">The full Path for the Output-File.</param> public async Task DownloadEpisode(Uri episodeUrl, string targetFilePath) { try { await FFMpegArguments.FromUrlInput(episodeUrl) .OutputToFile(targetFilePath, true, options => options .WithCustomArgument("-bsf:a aac_adtstoasc") .WithCustomArgument("-vcodec copy") .WithCustomArgument("-c copy") .WithCustomArgument("-crf 50") .WithCustomArgument("-tune animation") .UsingThreads(8) .UsingMultithreading(true)) .ProcessAsynchronously(); } catch (Exception genericException) //It is unknow which Exception will be thrown here... { Console.WriteLine($"Ffmpeg ran into the following Error: {genericException.Message}"); } }
public void Audio_ToAAC_Args_Pipe_ValidDefaultConfiguration() { using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); var samples = new List <IAudioSample> { new PcmAudioSampleWrapper(new byte[] { 0, 0 }), new PcmAudioSampleWrapper(new byte[] { 0, 0 }), }; var audioSamplesSource = new RawAudioPipeSource(samples); var success = FFMpegArguments .FromPipeInput(audioSamplesSource) .OutputToFile(outputFile, false, opt => opt .WithAudioCodec(AudioCodec.Aac)) .ProcessSynchronously(); Assert.IsTrue(success); }
public static Stream ConvertToWavFiles(string inputPt, string mimeType) { if (mimeType.EndsWith("/wav")) { return(File.OpenRead(inputPt)); } var outputPt = Path.GetTempFileName() + ".wav"; // pcm_s16le or pcm_s32le var ffargs = FFMpegArguments .FromFileInput(inputPt) .OutputToFile(outputPt, true, options => options.WithCustomArgument("-ar 8000 -c:a pcm_s16le") .ForceFormat("wav") ); ffargs.ProcessAsynchronously().Wait(); return(File.OpenRead(outputPt)); }