Merge pull request #339 from keg247/fire-notify-on-progress

Move NotifyOnProgress processing to ErrorData

Former-commit-id: 0f91c508df
This commit is contained in:
Malte Rosenbjerg 2023-01-28 10:43:15 +01:00 committed by GitHub
commit dbec950ddb
2 changed files with 54 additions and 44 deletions

View file

@ -1,4 +1,7 @@
using FFMpegCore.Enums; using FFMpegCore.Arguments;
using FFMpegCore.Enums;
using FFMpegCore.Exceptions;
using FFMpegCore.Pipes;
using FFMpegCore.Test.Resources; using FFMpegCore.Test.Resources;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using System; using System;
@ -8,11 +11,8 @@
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
using FFMpegCore.Arguments;
using FFMpegCore.Exceptions;
using FFMpegCore.Pipes;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
namespace FFMpegCore.Test namespace FFMpegCore.Test
{ {
@ -23,7 +23,7 @@ public class VideoTest
public void Video_ToOGV() public void Video_ToOGV()
{ {
using var outputFile = new TemporaryFile($"out{VideoType.Ogv.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.Ogv.Extension}");
var success = FFMpegArguments var success = FFMpegArguments
.FromFileInput(TestResources.WebmVideo) .FromFileInput(TestResources.WebmVideo)
.OutputToFile(outputFile, false) .OutputToFile(outputFile, false)
@ -35,7 +35,7 @@ public void Video_ToOGV()
public void Video_ToMP4() public void Video_ToMP4()
{ {
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var success = FFMpegArguments var success = FFMpegArguments
.FromFileInput(TestResources.WebmVideo) .FromFileInput(TestResources.WebmVideo)
.OutputToFile(outputFile, false) .OutputToFile(outputFile, false)
@ -47,7 +47,7 @@ public void Video_ToMP4()
public void Video_ToMP4_YUV444p() public void Video_ToMP4_YUV444p()
{ {
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var success = FFMpegArguments var success = FFMpegArguments
.FromFileInput(TestResources.WebmVideo) .FromFileInput(TestResources.WebmVideo)
.OutputToFile(outputFile, false, opt => opt .OutputToFile(outputFile, false, opt => opt
@ -63,7 +63,7 @@ public void Video_ToMP4_YUV444p()
public void Video_ToMP4_Args() public void Video_ToMP4_Args()
{ {
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var success = FFMpegArguments var success = FFMpegArguments
.FromFileInput(TestResources.WebmVideo) .FromFileInput(TestResources.WebmVideo)
.OutputToFile(outputFile, false, opt => opt .OutputToFile(outputFile, false, opt => opt
@ -76,7 +76,7 @@ public void Video_ToMP4_Args()
public void Video_ToH265_MKV_Args() public void Video_ToH265_MKV_Args()
{ {
using var outputFile = new TemporaryFile($"out.mkv"); using var outputFile = new TemporaryFile($"out.mkv");
var success = FFMpegArguments var success = FFMpegArguments
.FromFileInput(TestResources.WebmVideo) .FromFileInput(TestResources.WebmVideo)
.OutputToFile(outputFile, false, opt => opt .OutputToFile(outputFile, false, opt => opt
@ -106,7 +106,7 @@ public void Video_ToMP4_Args_Pipe_DifferentImageSizes()
{ {
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var frames = new List<IVideoFrame> 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, 255, 255, 1, 0),
BitmapSource.CreateVideoFrame(0, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 256, 256, 1, 0) BitmapSource.CreateVideoFrame(0, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 256, 256, 1, 0)
@ -184,7 +184,7 @@ public void Video_ToMP4_Args_StreamPipe()
{ {
using var input = File.OpenRead(TestResources.WebmVideo); using var input = File.OpenRead(TestResources.WebmVideo);
using var output = new TemporaryFile($"out{VideoType.Mp4.Extension}"); using var output = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var success = FFMpegArguments var success = FFMpegArguments
.FromPipeInput(new StreamPipeSource(input)) .FromPipeInput(new StreamPipeSource(input))
.OutputToFile(output, false, opt => opt .OutputToFile(output, false, opt => opt
@ -260,12 +260,12 @@ public async Task TestDuplicateRun()
.FromFileInput(TestResources.Mp4Video) .FromFileInput(TestResources.Mp4Video)
.OutputToFile("temporary.mp4") .OutputToFile("temporary.mp4")
.ProcessSynchronously(); .ProcessSynchronously();
await FFMpegArguments await FFMpegArguments
.FromFileInput(TestResources.Mp4Video) .FromFileInput(TestResources.Mp4Video)
.OutputToFile("temporary.mp4") .OutputToFile("temporary.mp4")
.ProcessAsynchronously(); .ProcessAsynchronously();
File.Delete("temporary.mp4"); File.Delete("temporary.mp4");
} }
@ -291,7 +291,7 @@ public void TranscodeToMemoryStream_Success()
public void Video_ToTS() public void Video_ToTS()
{ {
using var outputFile = new TemporaryFile($"out{VideoType.MpegTs.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.MpegTs.Extension}");
var success = FFMpegArguments var success = FFMpegArguments
.FromFileInput(TestResources.Mp4Video) .FromFileInput(TestResources.Mp4Video)
.OutputToFile(outputFile, false) .OutputToFile(outputFile, false)
@ -303,7 +303,7 @@ public void Video_ToTS()
public void Video_ToTS_Args() public void Video_ToTS_Args()
{ {
using var outputFile = new TemporaryFile($"out{VideoType.MpegTs.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.MpegTs.Extension}");
var success = FFMpegArguments var success = FFMpegArguments
.FromFileInput(TestResources.Mp4Video) .FromFileInput(TestResources.Mp4Video)
.OutputToFile(outputFile, false, opt => opt .OutputToFile(outputFile, false, opt => opt
@ -321,7 +321,7 @@ public async Task Video_ToTS_Args_Pipe(System.Drawing.Imaging.PixelFormat pixelF
{ {
using var output = new TemporaryFile($"out{VideoType.Ts.Extension}"); using var output = new TemporaryFile($"out{VideoType.Ts.Extension}");
var input = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, pixelFormat, 256, 256)); var input = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, pixelFormat, 256, 256));
var success = await FFMpegArguments var success = await FFMpegArguments
.FromPipeInput(input) .FromPipeInput(input)
.OutputToFile(output, false, opt => opt .OutputToFile(output, false, opt => opt
@ -354,7 +354,7 @@ public void RawVideoPipeSource_Ogv_Scale(System.Drawing.Imaging.PixelFormat pixe
{ {
using var outputFile = new TemporaryFile($"out{VideoType.Ogv.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.Ogv.Extension}");
var videoFramesSource = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, pixelFormat, 256, 256)); var videoFramesSource = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, pixelFormat, 256, 256));
FFMpegArguments FFMpegArguments
.FromPipeInput(videoFramesSource) .FromPipeInput(videoFramesSource)
.OutputToFile(outputFile, false, opt => opt .OutputToFile(outputFile, false, opt => opt
@ -371,7 +371,7 @@ public void RawVideoPipeSource_Ogv_Scale(System.Drawing.Imaging.PixelFormat pixe
public void Scale_Mp4_Multithreaded() public void Scale_Mp4_Multithreaded()
{ {
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var success = FFMpegArguments var success = FFMpegArguments
.FromFileInput(TestResources.Mp4Video) .FromFileInput(TestResources.Mp4Video)
.OutputToFile(outputFile, false, opt => opt .OutputToFile(outputFile, false, opt => opt
@ -389,7 +389,7 @@ public void Video_ToMP4_Resize_Args_Pipe(System.Drawing.Imaging.PixelFormat pixe
{ {
using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}"); using var outputFile = new TemporaryFile($"out{VideoType.Mp4.Extension}");
var videoFramesSource = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, pixelFormat, 256, 256)); var videoFramesSource = new RawVideoPipeSource(BitmapSource.CreateBitmaps(128, pixelFormat, 256, 256));
var success = FFMpegArguments var success = FFMpegArguments
.FromPipeInput(videoFramesSource) .FromPipeInput(videoFramesSource)
.OutputToFile(outputFile, false, opt => opt .OutputToFile(outputFile, false, opt => opt
@ -403,7 +403,7 @@ public void Video_Snapshot_InMemory()
{ {
var input = FFProbe.Analyse(TestResources.Mp4Video); var input = FFProbe.Analyse(TestResources.Mp4Video);
using var bitmap = FFMpeg.Snapshot(TestResources.Mp4Video); using var bitmap = FFMpeg.Snapshot(TestResources.Mp4Video);
Assert.AreEqual(input.PrimaryVideoStream!.Width, bitmap.Width); Assert.AreEqual(input.PrimaryVideoStream!.Width, bitmap.Width);
Assert.AreEqual(input.PrimaryVideoStream.Height, bitmap.Height); Assert.AreEqual(input.PrimaryVideoStream.Height, bitmap.Height);
Assert.AreEqual(bitmap.RawFormat, ImageFormat.Png); Assert.AreEqual(bitmap.RawFormat, ImageFormat.Png);
@ -428,13 +428,13 @@ public void Video_Join()
{ {
var inputCopy = new TemporaryFile("copy-input.mp4"); var inputCopy = new TemporaryFile("copy-input.mp4");
File.Copy(TestResources.Mp4Video, inputCopy); File.Copy(TestResources.Mp4Video, inputCopy);
var outputPath = new TemporaryFile("out.mp4"); var outputPath = new TemporaryFile("out.mp4");
var input = FFProbe.Analyse(TestResources.Mp4Video); var input = FFProbe.Analyse(TestResources.Mp4Video);
var success = FFMpeg.Join(outputPath, TestResources.Mp4Video, inputCopy); var success = FFMpeg.Join(outputPath, TestResources.Mp4Video, inputCopy);
Assert.IsTrue(success); Assert.IsTrue(success);
Assert.IsTrue(File.Exists(outputPath)); Assert.IsTrue(File.Exists(outputPath));
var expectedDuration = input.Duration * 2; var expectedDuration = input.Duration * 2;
var result = FFProbe.Analyse(outputPath); var result = FFProbe.Analyse(outputPath);
Assert.AreEqual(expectedDuration.Days, result.Duration.Days); Assert.AreEqual(expectedDuration.Days, result.Duration.Days);
@ -505,14 +505,22 @@ public void Video_UpdatesProgress()
var percentageDone = 0.0; var percentageDone = 0.0;
var timeDone = TimeSpan.Zero; var timeDone = TimeSpan.Zero;
void OnPercentageProgess(double percentage) => percentageDone = percentage;
void OnTimeProgess(TimeSpan time) => timeDone = time;
var analysis = FFProbe.Analyse(TestResources.Mp4Video); var analysis = FFProbe.Analyse(TestResources.Mp4Video);
void OnPercentageProgess(double percentage)
{
if (percentage < 100) percentageDone = percentage;
}
void OnTimeProgess(TimeSpan time)
{
if (time < analysis.Duration) timeDone = time;
}
var success = FFMpegArguments var success = FFMpegArguments
.FromFileInput(TestResources.Mp4Video) .FromFileInput(TestResources.Mp4Video)
.OutputToFile(outputFile, false, opt => opt .OutputToFile(outputFile, false, opt => opt
.WithDuration(TimeSpan.FromSeconds(2))) .WithDuration(analysis.Duration))
.NotifyOnProgress(OnPercentageProgess, analysis.Duration) .NotifyOnProgress(OnPercentageProgess, analysis.Duration)
.NotifyOnProgress(OnTimeProgess) .NotifyOnProgress(OnTimeProgess)
.ProcessSynchronously(); .ProcessSynchronously();
@ -520,7 +528,9 @@ public void Video_UpdatesProgress()
Assert.IsTrue(success); Assert.IsTrue(success);
Assert.IsTrue(File.Exists(outputFile)); Assert.IsTrue(File.Exists(outputFile));
Assert.AreNotEqual(0.0, percentageDone); Assert.AreNotEqual(0.0, percentageDone);
Assert.AreNotEqual(100.0, percentageDone);
Assert.AreNotEqual(TimeSpan.Zero, timeDone); Assert.AreNotEqual(TimeSpan.Zero, timeDone);
Assert.AreNotEqual(analysis.Duration, timeDone);
} }
[TestMethod, Timeout(10000)] [TestMethod, Timeout(10000)]
@ -528,7 +538,7 @@ public void Video_OutputsData()
{ {
var outputFile = new TemporaryFile("out.mp4"); var outputFile = new TemporaryFile("out.mp4");
var dataReceived = false; var dataReceived = false;
GlobalFFOptions.Configure(opt => opt.Encoding = Encoding.UTF8); GlobalFFOptions.Configure(opt => opt.Encoding = Encoding.UTF8);
var success = FFMpegArguments var success = FFMpegArguments
.FromFileInput(TestResources.Mp4Video) .FromFileInput(TestResources.Mp4Video)

View file

@ -1,13 +1,13 @@
using System; using FFMpegCore.Exceptions;
using FFMpegCore.Helpers;
using Instances;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FFMpegCore.Exceptions;
using FFMpegCore.Helpers;
using Instances;
namespace FFMpegCore namespace FFMpegCore
{ {
@ -88,7 +88,7 @@ public bool ProcessSynchronously(bool throwOnError = true, FFOptions? ffMpegOpti
var options = GetConfiguredOptions(ffMpegOptions); var options = GetConfiguredOptions(ffMpegOptions);
var processArguments = PrepareProcessArguments(options, out var cancellationTokenSource); var processArguments = PrepareProcessArguments(options, out var cancellationTokenSource);
IProcessResult? processResult = null; IProcessResult? processResult = null;
try try
{ {
@ -107,7 +107,7 @@ public async Task<bool> ProcessAsynchronously(bool throwOnError = true, FFOption
{ {
var options = GetConfiguredOptions(ffMpegOptions); var options = GetConfiguredOptions(ffMpegOptions);
var processArguments = PrepareProcessArguments(options, out var cancellationTokenSource); var processArguments = PrepareProcessArguments(options, out var cancellationTokenSource);
IProcessResult? processResult = null; IProcessResult? processResult = null;
try try
{ {
@ -118,7 +118,7 @@ public async Task<bool> ProcessAsynchronously(bool throwOnError = true, FFOption
if (throwOnError) if (throwOnError)
throw; throw;
} }
return HandleCompletion(throwOnError, processResult?.ExitCode ?? -1, processResult?.ErrorData ?? Array.Empty<string>()); return HandleCompletion(throwOnError, processResult?.ExitCode ?? -1, processResult?.ErrorData ?? Array.Empty<string>());
} }
@ -204,10 +204,10 @@ private ProcessArguments PrepareProcessArguments(FFOptions ffOptions,
var processArguments = new ProcessArguments(startInfo); var processArguments = new ProcessArguments(startInfo);
cancellationTokenSource = new CancellationTokenSource(); cancellationTokenSource = new CancellationTokenSource();
if (_onOutput != null || _onTimeProgress != null || (_onPercentageProgress != null && _totalTimespan != null)) if (_onOutput != null)
processArguments.OutputDataReceived += OutputData; processArguments.OutputDataReceived += OutputData;
if (_onError != null) if (_onError != null || _onTimeProgress != null || (_onPercentageProgress != null && _totalTimespan != null))
processArguments.ErrorDataReceived += ErrorData; processArguments.ErrorDataReceived += ErrorData;
return processArguments; return processArguments;
@ -216,12 +216,6 @@ private ProcessArguments PrepareProcessArguments(FFOptions ffOptions,
private void ErrorData(object sender, string msg) private void ErrorData(object sender, string msg)
{ {
_onError?.Invoke(msg); _onError?.Invoke(msg);
}
private void OutputData(object sender, string msg)
{
Debug.WriteLine(msg);
_onOutput?.Invoke(msg);
var match = ProgressRegex.Match(msg); var match = ProgressRegex.Match(msg);
if (!match.Success) return; if (!match.Success) return;
@ -233,5 +227,11 @@ private void OutputData(object sender, string msg)
var percentage = Math.Round(processed.TotalSeconds / _totalTimespan.Value.TotalSeconds * 100, 2); var percentage = Math.Round(processed.TotalSeconds / _totalTimespan.Value.TotalSeconds * 100, 2);
_onPercentageProgress(percentage); _onPercentageProgress(percentage);
} }
private void OutputData(object sender, string msg)
{
Debug.WriteLine(msg);
_onOutput?.Invoke(msg);
}
} }
} }