public void Video_Duration() { var video = FFProbe.Analyse(VideoLibrary.LocalVideo.FullName); var output = Input.OutputLocation(VideoType.Mp4); try { FFMpegArguments .FromInputFiles(VideoLibrary.LocalVideo) .WithDuration(TimeSpan.FromSeconds(video.Duration.TotalSeconds - 5)) .OutputToFile(output) .ProcessSynchronously(); Assert.IsTrue(File.Exists(output)); var outputVideo = FFProbe.Analyse(output); 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 - 5, outputVideo.Duration.Seconds); } finally { if (File.Exists(output)) { File.Delete(output); } } }
public void Builder_BuildString_Raw() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").WithCustomArgument(null).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" \"output.mp4\"", str); str = FFMpegArguments.FromInputFiles(true, "input.mp4").WithCustomArgument("-acodec copy").OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -acodec copy \"output.mp4\"", str); }
public void Builder_BuildString_DrawtextFilter_Alt() { var str = FFMpegArguments .FromInputFiles(true, "input.mp4") .DrawText(DrawTextOptions .Create("Stack Overflow", "/path/to/font.ttf", ("fontcolor", "white"), ("fontsize", "24"))) .OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -vf drawtext=\"text='Stack Overflow':fontfile=/path/to/font.ttf:fontcolor=white:fontsize=24\" \"output.mp4\"", str); }
public void Convert(ContainerFormat type, Action <IMediaAnalysis> validationMethod, params IArgument[] inputArguments) { var output = Input.OutputLocation(type); try { var input = FFProbe.Analyse(Input.FullName); var arguments = FFMpegArguments.FromInputFiles(VideoLibrary.LocalVideo.FullName); foreach (var arg in inputArguments) { arguments.WithArgument(arg); } var processor = arguments.OutputToFile(output); var scaling = arguments.Find <ScaleArgument>(); processor.ProcessSynchronously(); var outputVideo = FFProbe.Analyse(output); Assert.IsTrue(File.Exists(output)); 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); } } finally { if (File.Exists(output)) { File.Delete(output); } } }
public async Task TestDuplicateRun() { FFMpegArguments.FromInputFiles(VideoLibrary.LocalVideo) .OutputToFile("temporary.mp4", true) .ProcessSynchronously(); await FFMpegArguments.FromInputFiles(VideoLibrary.LocalVideo) .OutputToFile("temporary.mp4", true) .ProcessAsynchronously(); File.Delete("temporary.mp4"); }
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(); }
// [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 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); }
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 Video_UpdatesProgress() { var output = Input.OutputLocation(VideoType.Mp4); var percentageDone = 0.0; var timeDone = TimeSpan.Zero; void OnPercentageProgess(double percentage) => percentageDone = percentage; void OnTimeProgess(TimeSpan time) => timeDone = time; var analysis = FFProbe.Analyse(VideoLibrary.LocalVideo.FullName); try { var success = FFMpegArguments .FromInputFiles(VideoLibrary.LocalVideo) .WithDuration(TimeSpan.FromSeconds(8)) .OutputToFile(output) .NotifyOnProgress(OnPercentageProgess, analysis.Duration) .NotifyOnProgress(OnTimeProgess) .ProcessSynchronously(); Assert.IsTrue(success); Assert.IsTrue(File.Exists(output)); Assert.AreNotEqual(0.0, percentageDone); Assert.AreNotEqual(TimeSpan.Zero, timeDone); } finally { if (File.Exists(output)) { File.Delete(output); } } }
public void Builder_BuildString_ForcePixelFormat() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").ForcePixelFormat("yuv444p").OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -pix_fmt yuv444p \"output.mp4\"", str); }
public void Builder_BuildString_Codec_Override() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").WithVideoCodec(VideoCodec.LibX264).ForcePixelFormat("yuv420p").OutputToFile("output.mp4", true).Arguments; Assert.AreEqual("-i \"input.mp4\" -c:v libx264 -pix_fmt yuv420p \"output.mp4\" -y", str); }
public void Builder_BuildString_Duration() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").WithDuration(TimeSpan.FromSeconds(20)).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -t 00:00:20 \"output.mp4\"", str); }
public void Builder_BuildString_Copy_Both() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").CopyChannel().OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -c copy \"output.mp4\"", str); }
public void Builder_BuildString_Shortest() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").UsingShortest().OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -shortest \"output.mp4\"", str); }
public void Builder_BuildString_StartNumber() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").WithStartNumber(50).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -start_number 50 \"output.mp4\"", str); }
public void Builder_BuildString_AudioCodec_Fluent() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").WithAudioCodec(AudioCodec.Aac).WithAudioBitrate(128).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -c:a aac -b:a 128k \"output.mp4\"", str); }
public void Builder_BuildString_Loop() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").Loop(50).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -loop 50 \"output.mp4\"", str); }
public void Builder_BuildString_FrameRate() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").WithFramerate(50).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -r 50 \"output.mp4\"", str); }
public void Builder_BuildString_Speed() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").WithSpeedPreset(Speed.Fast).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -preset fast \"output.mp4\"", str); }
public void Builder_BuildString_Size() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").Resize(1920, 1080).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -s 1920x1080 \"output.mp4\"", str); }
public void Builder_BuildString_Scale() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").Scale(VideoSize.Hd).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -vf scale=-1:720 \"output.mp4\"", str); }
public void Builder_BuildString_AudioBitrate() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").WithAudioBitrate(AudioQuality.Normal).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -b:a 128k \"output.mp4\"", str); }
public void Builder_BuildString_Threads_1() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").UsingThreads(50).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -threads 50 \"output.mp4\"", str); }
public void Builder_BuildString_Quiet() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").WithVerbosityLevel().OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -hide_banner -loglevel error \"output.mp4\"", str); }
public void Builder_BuildString_Threads_2() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").UsingMultithreading(true).OutputToFile("output.mp4").Arguments; Assert.AreEqual($"-i \"input.mp4\" -threads {Environment.ProcessorCount} \"output.mp4\"", str); }
public void Builder_BuildString_BitStream() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").WithBitStreamFilter(Channel.Audio, Filter.H264_Mp4ToAnnexB).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -bsf:a h264_mp4toannexb \"output.mp4\"", str); }
public void Builder_BuildString_Codec() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").WithVideoCodec(VideoCodec.LibX264).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -c:v libx264 \"output.mp4\"", str); }
public async Task Produce(ConcurrentQueue <MutableByteImage> queue) { try { FFMpegOptions.Configure(new FFMpegOptions { RootDirectory = _arguments.PathToFfmpeg }); var result = await FFProbe.AnalyseAsync(_arguments.InputFiles.First()).ConfigureAwait(false); var width = result.PrimaryVideoStream.Width; var height = result.PrimaryVideoStream.Height; var bpp = Image.GetPixelFormatSize(System.Drawing.Imaging.PixelFormat.Format24bppRgb) / 8; var pixelsPerFrame = width * height; var frameSizeInBytes = pixelsPerFrame * bpp; _logger.WriteLine("Input from ffmpeg currently only supports rgb24-convertable input", Verbosity.Warning); var chunksQueue = new ConcurrentQueue <byte[]>(); using var memoryStream = new ChunkedMemoryStream(frameSizeInBytes, chunksQueue); // new MemoryStream(frameSizeInBytes); StreamPipeSink sink = new StreamPipeSink(memoryStream); var args = FFMpegArguments .FromInputFiles(_arguments.InputFiles) .UsingMultithreading(true) .ForceFormat("rawvideo") .ForcePixelFormat("bgr24") .OutputToPipe(sink) .NotifyOnProgress( percent => _logger.NotifyFillstate(Convert.ToInt32(percent), "InputVideoParsing"), TimeSpan.FromSeconds(1)); var produceTask = args.ProcessAsynchronously(true).ContinueWith((_) => parsingFinished.Cancel()); var consumeTask = ParseInputStream(queue, chunksQueue, width, height, frameSizeInBytes, memoryStream); await Task.WhenAll(produceTask, consumeTask); // await Task.WhenAny(produceTask, consumeTask).ConfigureAwait(false); } catch (Exception e) { } async Task ParseInputStream(ConcurrentQueue <MutableByteImage> queue, ConcurrentQueue <byte[]> chunksQueue, int width, int height, int frameSizeInBytes, ChunkedMemoryStream memoryStream) { int count = 0; while (true) //while ((memoryStream.HasUnwrittenData || chunksQueue.Count > 0) && !parsingFinished.IsCancellationRequested) { try { var foo = await chunksQueue.TryDequeueOrWait(parsingFinished); if (foo.cancelled) { break; } _logger.NotifyFillstate(++count, "ParsedImages"); _logger.NotifyFillstate(chunksQueue.Count, "ChunkedQueue"); queue.Enqueue(_factory.FromBytes(width, height, foo.item)); } catch (Exception e) { _logger.LogException(e); } await queue.WaitForBufferSpace(24); } Console.WriteLine(memoryStream.HasUnwrittenData); } }
public void Builder_BuildString_Seek() { var str = FFMpegArguments.FromInputFiles(true, "input.mp4").Seek(TimeSpan.FromSeconds(10)).OutputToFile("output.mp4").Arguments; Assert.AreEqual("-i \"input.mp4\" -ss 00:00:10 \"output.mp4\"", str); }