From be477197cc6c88faba5458e07f03a89ea6bf5cf4 Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Wed, 9 Dec 2020 17:07:41 +0100 Subject: [PATCH 1/2] Support specifying output encoding for ffmpeg and ffprobe output Former-commit-id: a4aba666cda695e71a2252be78741aebeb5a844f --- FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs | 9 ++++++++- FFMpegCore/FFMpeg/FFMpegOptions.cs | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs b/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs index 5961ed3..e9369a5 100644 --- a/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs +++ b/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs @@ -130,7 +130,14 @@ private Instance PrepareInstance(out CancellationTokenSource cancellationTokenSo { FFMpegHelper.RootExceptionCheck(); FFMpegHelper.VerifyFFMpegExists(); - var instance = new Instance(FFMpegOptions.Options.FFmpegBinary(), _ffMpegArguments.Text); + var startInfo = new ProcessStartInfo + { + FileName = FFMpegOptions.Options.FFmpegBinary(), + Arguments = _ffMpegArguments.Text, + StandardOutputEncoding = FFMpegOptions.Options.Encoding, + StandardErrorEncoding = FFMpegOptions.Options.Encoding, + }; + var instance = new Instance(startInfo); cancellationTokenSource = new CancellationTokenSource(); if (_onTimeProgress != null || (_onPercentageProgress != null && _totalTimespan != null)) diff --git a/FFMpegCore/FFMpeg/FFMpegOptions.cs b/FFMpegCore/FFMpeg/FFMpegOptions.cs index 947f942..5bdb3a9 100644 --- a/FFMpegCore/FFMpeg/FFMpegOptions.cs +++ b/FFMpegCore/FFMpeg/FFMpegOptions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; +using System.Text; using System.Text.Json; namespace FFMpegCore @@ -48,6 +49,7 @@ static FFMpegOptions() public Dictionary ExtensionOverrides { get; private set; } = new Dictionary(); public bool UseCache { get; set; } = true; + public Encoding Encoding { get; set; } = Encoding.Default; private static string FFBinary(string name) { From 3d640f9e08a3ff60d62959cac5dc2043f0afe03c Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Fri, 18 Dec 2020 00:40:09 +0100 Subject: [PATCH 2/2] Add NotifyOnOutput Former-commit-id: cfee86199b07900d6c5c9e51aa7a902cb2bd88b8 --- FFMpegCore.Test/VideoTest.cs | 22 ++++++++++++++++++++ FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs | 12 +++++++++-- FFMpegCore/FFMpeg/FFMpegOptions.cs | 5 ++--- FFMpegCore/FFMpegCore.csproj | 5 +++-- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/FFMpegCore.Test/VideoTest.cs b/FFMpegCore.Test/VideoTest.cs index b2bff02..eb5b46b 100644 --- a/FFMpegCore.Test/VideoTest.cs +++ b/FFMpegCore.Test/VideoTest.cs @@ -7,6 +7,7 @@ using System.Drawing.Imaging; using System.IO; using System.Linq; +using System.Text; using System.Threading.Tasks; using FFMpegCore.Arguments; using FFMpegCore.Exceptions; @@ -550,6 +551,27 @@ public void Video_UpdatesProgress() Assert.AreNotEqual(TimeSpan.Zero, timeDone); } + [TestMethod, Timeout(10000)] + 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)); + } + [TestMethod, Timeout(10000)] public void Video_TranscodeInMemory() { diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs b/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs index e9369a5..cfbe42a 100644 --- a/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs +++ b/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs @@ -17,6 +17,7 @@ public class FFMpegArgumentProcessor private readonly FFMpegArguments _ffMpegArguments; private Action? _onPercentageProgress; private Action? _onTimeProgress; + private Action? _onOutput; private TimeSpan? _totalTimespan; internal FFMpegArgumentProcessor(FFMpegArguments ffMpegArguments) @@ -39,6 +40,11 @@ public FFMpegArgumentProcessor NotifyOnProgress(Action onTimeProgress) _onTimeProgress = onTimeProgress; return this; } + public FFMpegArgumentProcessor NotifyOnOutput(Action onOutput) + { + _onOutput = onOutput; + return this; + } public FFMpegArgumentProcessor CancellableThrough(out Action cancel) { cancel = () => CancelEvent?.Invoke(this, EventArgs.Empty); @@ -140,7 +146,7 @@ private Instance PrepareInstance(out CancellationTokenSource cancellationTokenSo var instance = new Instance(startInfo); cancellationTokenSource = new CancellationTokenSource(); - if (_onTimeProgress != null || (_onPercentageProgress != null && _totalTimespan != null)) + if (_onOutput != null || _onTimeProgress != null || (_onPercentageProgress != null && _totalTimespan != null)) instance.DataReceived += OutputData; return instance; @@ -157,8 +163,10 @@ private static bool HandleException(bool throwOnError, Exception e, IReadOnlyLis private void OutputData(object sender, (DataType Type, string Data) msg) { - var match = ProgressRegex.Match(msg.Data); Debug.WriteLine(msg.Data); + _onOutput?.Invoke(msg.Data, msg.Type); + + var match = ProgressRegex.Match(msg.Data); if (!match.Success) return; var processed = TimeSpan.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture); diff --git a/FFMpegCore/FFMpeg/FFMpegOptions.cs b/FFMpegCore/FFMpeg/FFMpegOptions.cs index 5bdb3a9..a7d29b4 100644 --- a/FFMpegCore/FFMpeg/FFMpegOptions.cs +++ b/FFMpegCore/FFMpeg/FFMpegOptions.cs @@ -41,6 +41,8 @@ static FFMpegOptions() public string RootDirectory { get; set; } = DefaultRoot; public string TempDirectory { get; set; } = DefaultTemp; + public bool UseCache { get; set; } = true; + public Encoding Encoding { get; set; } = Encoding.Default; public string FFmpegBinary() => FFBinary("FFMpeg"); @@ -48,9 +50,6 @@ static FFMpegOptions() public Dictionary ExtensionOverrides { get; private set; } = new Dictionary(); - public bool UseCache { get; set; } = true; - public Encoding Encoding { get; set; } = Encoding.Default; - private static string FFBinary(string name) { var ffName = name.ToLowerInvariant(); diff --git a/FFMpegCore/FFMpegCore.csproj b/FFMpegCore/FFMpegCore.csproj index 43247f7..ad8ad15 100644 --- a/FFMpegCore/FFMpegCore.csproj +++ b/FFMpegCore/FFMpegCore.csproj @@ -9,9 +9,10 @@ 3.0.0.0 3.0.0.0 3.0.0.0 - - Also include ffmpeg output data on non-zero exit code + - Support for changing encoding used for parsing ffmpeg/ffprobe output +- Support for registrering action to invoke on ffmpeg output 8 - 3.2.4 + 3.3.0 MIT Malte Rosenbjerg, Vlad Jerca ffmpeg ffprobe convert video audio mediafile resize analyze muxing