Merge pull request #222 from patagonaa/master

Support cancellation token for cancelling FFMPEG processes

Former-commit-id: e18b010540
This commit is contained in:
Malte Rosenbjerg 2021-07-08 00:09:39 +02:00 committed by GitHub
commit 30bd3674f3
2 changed files with 65 additions and 0 deletions

View file

@ -12,6 +12,7 @@
using FFMpegCore.Arguments; using FFMpegCore.Arguments;
using FFMpegCore.Exceptions; using FFMpegCore.Exceptions;
using FFMpegCore.Pipes; using FFMpegCore.Pipes;
using System.Threading;
namespace FFMpegCore.Test namespace FFMpegCore.Test
{ {
@ -612,5 +613,64 @@ public async Task Video_Cancel_Async_With_Timeout()
Assert.AreEqual("h264", outputInfo.PrimaryVideoStream.CodecName); Assert.AreEqual("h264", outputInfo.PrimaryVideoStream.CodecName);
Assert.AreEqual("aac", outputInfo.PrimaryAudioStream!.CodecName); Assert.AreEqual("aac", outputInfo.PrimaryAudioStream!.CodecName);
} }
[TestMethod, Timeout(10000)]
public async Task Video_Cancel_CancellationToken_Async()
{
var outputFile = new TemporaryFile("out.mp4");
var cts = new CancellationTokenSource();
var task = FFMpegArguments
.FromFileInput("testsrc2=size=320x240[out0]; sine[out1]", false, args => args
.WithCustomArgument("-re")
.ForceFormat("lavfi"))
.OutputToFile(outputFile, false, opt => opt
.WithAudioCodec(AudioCodec.Aac)
.WithVideoCodec(VideoCodec.LibX264)
.WithSpeedPreset(Speed.VeryFast))
.CancellableThrough(cts.Token)
.ProcessAsynchronously(false);
await Task.Delay(300);
cts.Cancel();
var result = await task;
Assert.IsFalse(result);
}
[TestMethod, Timeout(10000)]
public async Task Video_Cancel_CancellationToken_Async_With_Timeout()
{
var outputFile = new TemporaryFile("out.mp4");
var cts = new CancellationTokenSource();
var task = FFMpegArguments
.FromFileInput("testsrc2=size=320x240[out0]; sine[out1]", false, args => args
.WithCustomArgument("-re")
.ForceFormat("lavfi"))
.OutputToFile(outputFile, false, opt => opt
.WithAudioCodec(AudioCodec.Aac)
.WithVideoCodec(VideoCodec.LibX264)
.WithSpeedPreset(Speed.VeryFast))
.CancellableThrough(cts.Token, 10000)
.ProcessAsynchronously(false);
await Task.Delay(300);
cts.Cancel();
var result = await task;
var outputInfo = await FFProbe.AnalyseAsync(outputFile);
Assert.IsTrue(result);
Assert.IsNotNull(outputInfo);
Assert.AreEqual(320, outputInfo.PrimaryVideoStream!.Width);
Assert.AreEqual(240, outputInfo.PrimaryVideoStream.Height);
Assert.AreEqual("h264", outputInfo.PrimaryVideoStream.CodecName);
Assert.AreEqual("aac", outputInfo.PrimaryAudioStream!.CodecName);
}
} }
} }

View file

@ -50,6 +50,11 @@ public FFMpegArgumentProcessor CancellableThrough(out Action cancel, int timeout
cancel = () => CancelEvent?.Invoke(this, timeout); cancel = () => CancelEvent?.Invoke(this, timeout);
return this; return this;
} }
public FFMpegArgumentProcessor CancellableThrough(CancellationToken token, int timeout = 0)
{
token.Register(() => CancelEvent?.Invoke(this, timeout));
return this;
}
public bool ProcessSynchronously(bool throwOnError = true, FFOptions? ffMpegOptions = null) public bool ProcessSynchronously(bool throwOnError = true, FFOptions? ffMpegOptions = null)
{ {
using var instance = PrepareInstance(ffMpegOptions ?? GlobalFFOptions.Current, out var cancellationTokenSource); using var instance = PrepareInstance(ffMpegOptions ?? GlobalFFOptions.Current, out var cancellationTokenSource);