mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2024-11-13 01:34:14 +01:00
Merge pull request #339 from keg247/fire-notify-on-progress
Move NotifyOnProgress processing to ErrorData
Former-commit-id: 0f91c508df
This commit is contained in:
commit
dbec950ddb
2 changed files with 54 additions and 44 deletions
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue