From e0b7d652d96925c24c9a57f26627837cd22841a7 Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Tue, 12 May 2020 17:55:31 +0200 Subject: [PATCH] Default to throwing on errors Former-commit-id: 3855215000325f5ffb5e141cb7dbbe81962df22f --- FFMpegCore.Test/VideoTest.cs | 28 ++++----- .../FFMpeg/Exceptions/FFMpegException.cs | 5 +- FFMpegCore/FFMpeg/FFMpeg.cs | 2 + FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs | 58 +++++++++++++++---- 4 files changed, 62 insertions(+), 31 deletions(-) diff --git a/FFMpegCore.Test/VideoTest.cs b/FFMpegCore.Test/VideoTest.cs index 6bffa89..ffa5da3 100644 --- a/FFMpegCore.Test/VideoTest.cs +++ b/FFMpegCore.Test/VideoTest.cs @@ -297,28 +297,22 @@ public void Video_ToMP4_Args_StreamPipe() [TestMethod, Timeout(10000)] public void Video_ToMP4_Args_StreamOutputPipe_Async_Failure() { - using var ms = new MemoryStream(); - var pipeSource = new StreamPipeDataReader(ms); - var result = FFMpegArguments - .FromInputFiles(VideoLibrary.LocalVideo) - .ForceFormat("mkv") - .OutputToPipe(pipeSource) - .ProcessAsynchronously() - .WaitForResult(); - Assert.IsFalse(result); + Assert.ThrowsExceptionAsync(async () => + { + await using var ms = new MemoryStream(); + var pipeSource = new StreamPipeDataReader(ms); + await FFMpegArguments + .FromInputFiles(VideoLibrary.LocalVideo) + .ForceFormat("mkv") + .OutputToPipe(pipeSource) + .ProcessAsynchronously(); + }); } [TestMethod, Timeout(10000)] public void Video_ToMP4_Args_StreamOutputPipe_Failure() { - using var ms = new MemoryStream(); - var pipeSource = new StreamPipeDataReader(ms); - var result = FFMpegArguments - .FromInputFiles(VideoLibrary.LocalVideo) - .ForceFormat("mkv") - .OutputToPipe(pipeSource) - .ProcessSynchronously(); - Assert.IsFalse(result); + Assert.ThrowsException(() => ConvertToStreamPipe(new ForceFormatArgument("mkv"))); } diff --git a/FFMpegCore/FFMpeg/Exceptions/FFMpegException.cs b/FFMpegCore/FFMpeg/Exceptions/FFMpegException.cs index 00d3c19..6bd608d 100644 --- a/FFMpegCore/FFMpeg/Exceptions/FFMpegException.cs +++ b/FFMpegCore/FFMpeg/Exceptions/FFMpegException.cs @@ -13,14 +13,15 @@ public enum FFMpegExceptionType public class FFMpegException : Exception { - public FFMpegException(FFMpegExceptionType type, string message): this(type, message, null) { } - public FFMpegException(FFMpegExceptionType type, string? message = null, Exception? innerException = null) + public FFMpegException(FFMpegExceptionType type, string? message = null, Exception? innerException = null, string ffMpegErrorOutput = "") : base(message, innerException) { + FFMpegErrorOutput = ffMpegErrorOutput; Type = type; } public FFMpegExceptionType Type { get; } + public string FFMpegErrorOutput { get; } } } \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/FFMpeg.cs b/FFMpegCore/FFMpeg/FFMpeg.cs index 21a76d8..13d141f 100644 --- a/FFMpegCore/FFMpeg/FFMpeg.cs +++ b/FFMpegCore/FFMpeg/FFMpeg.cs @@ -187,6 +187,7 @@ public static bool Join(string output, params MediaAnalysis[] videos) { FFMpegHelper.ConversionSizeExceptionCheck(video); var destinationPath = Path.Combine(FFMpegOptions.Options.TempDirectory, $"{Path.GetFileNameWithoutExtension(video.Path)}{FileExtension.Ts}"); + Directory.CreateDirectory(FFMpegOptions.Options.TempDirectory); Convert(video, destinationPath, VideoType.Ts); return destinationPath; }).ToArray(); @@ -219,6 +220,7 @@ public static bool JoinImageSequence(string output, double frameRate = 30, param { FFMpegHelper.ConversionSizeExceptionCheck(Image.FromFile(image.FullName)); var destinationPath = Path.Combine(FFMpegOptions.Options.TempDirectory, $"{index.ToString().PadLeft(9, '0')}{image.Extension}"); + Directory.CreateDirectory(FFMpegOptions.Options.TempDirectory); File.Copy(image.FullName, destinationPath); return destinationPath; }).ToArray(); diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs b/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs index 77d67a5..3349e19 100644 --- a/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs +++ b/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs @@ -4,6 +4,7 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; +using FFMpegCore.Exceptions; using FFMpegCore.Helpers; using Instances; @@ -36,7 +37,7 @@ public FFMpegArgumentProcessor NotifyOnProgress(Action? onTimeProgress _onTimeProgress = onTimeProgress; return this; } - public bool ProcessSynchronously() + public bool ProcessSynchronously(bool throwOnError = true) { FFMpegHelper.RootExceptionCheck(FFMpegOptions.Options.RootDirectory); using var instance = new Instance(FFMpegOptions.Options.FFmpegBinary(), _ffMpegArguments.Text); @@ -46,18 +47,34 @@ public bool ProcessSynchronously() _ffMpegArguments.Pre(); var cancellationTokenSource = new CancellationTokenSource(); - Task.WaitAll(instance.FinishedRunning().ContinueWith(t => + try { - errorCode = t.Result; - cancellationTokenSource.Cancel(); - }), _ffMpegArguments.During(cancellationTokenSource.Token)); + Task.WaitAll(instance.FinishedRunning().ContinueWith(t => + { + errorCode = t.Result; + cancellationTokenSource.Cancel(); + }), _ffMpegArguments.During(cancellationTokenSource.Token)); + } + catch (Exception e) + { + if (!throwOnError) + return false; + + throw new FFMpegException(FFMpegExceptionType.Process, "Exception thrown during processing", e, + string.Join("\n", instance.ErrorData)); + } + finally + { + _ffMpegArguments.Post(); + } - _ffMpegArguments.Post(); + if (throwOnError && errorCode != 0) + throw new FFMpegException(FFMpegExceptionType.Conversion, string.Join("\n", instance.ErrorData)); return errorCode == 0; } - public async Task ProcessAsynchronously() + public async Task ProcessAsynchronously(bool throwOnError = true) { FFMpegHelper.RootExceptionCheck(FFMpegOptions.Options.RootDirectory); using var instance = new Instance(FFMpegOptions.Options.FFmpegBinary(), _ffMpegArguments.Text); @@ -68,12 +85,29 @@ public async Task ProcessAsynchronously() _ffMpegArguments.Pre(); var cancellationTokenSource = new CancellationTokenSource(); - await Task.WhenAll(instance.FinishedRunning().ContinueWith(t => + try { - errorCode = t.Result; - cancellationTokenSource.Cancel(); - }), _ffMpegArguments.During(cancellationTokenSource.Token)).ConfigureAwait(false); - _ffMpegArguments.Post(); + await Task.WhenAll(instance.FinishedRunning().ContinueWith(t => + { + errorCode = t.Result; + cancellationTokenSource.Cancel(); + }), _ffMpegArguments.During(cancellationTokenSource.Token)).ConfigureAwait(false); + } + catch (Exception e) + { + if (!throwOnError) + return false; + + throw new FFMpegException(FFMpegExceptionType.Process, "Exception thrown during processing", e, + string.Join("\n", instance.ErrorData)); + } + finally + { + _ffMpegArguments.Post(); + } + + if (throwOnError && errorCode != 0) + throw new FFMpegException(FFMpegExceptionType.Conversion, string.Join("\n", instance.ErrorData)); return errorCode == 0; }