From d7a705e9aea63fc5946b912c55b11d7fc4ad2d3d Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Tue, 12 May 2020 21:28:50 +0200 Subject: [PATCH] Revert "Cleanup" This reverts commit 152683323e3bdcd3f7365d5f31667dba2a3804e3 [formerly d95f687e46eda15a7d8df084256d09f24fcc29ca]. Former-commit-id: 1dc7524ecdf247ab0a5aa7bc7a1228f3bdd64e78 --- FFMpegCore.Test/ArgumentBuilderTest.cs | 3 +- FFMpegCore.Test/AudioTest.cs | 2 +- FFMpegCore.Test/FFProbeTests.cs | 2 +- FFMpegCore.Test/PixelFormatTests.cs | 17 +- FFMpegCore.Test/Resources/VideoLibrary.cs | 5 +- FFMpegCore.Test/VideoTest.cs | 34 ++-- .../FFMpeg/Arguments/AudioCodecArgument.cs | 2 +- .../Arguments/DisableChannelArgument.cs | 2 +- .../FFMpeg/Arguments/ForceFormatArgument.cs | 2 +- .../FFMpeg/Arguments/ForcePixelFormat.cs | 2 +- FFMpegCore/FFMpeg/Arguments/InputArgument.cs | 2 +- FFMpegCore/FFMpeg/Arguments/OutputArgument.cs | 8 +- FFMpegCore/FFMpeg/Arguments/PipeArgument.cs | 5 +- .../FFMpeg/Arguments/VideoCodecArgument.cs | 2 +- FFMpegCore/FFMpeg/Enums/Channel.cs | 9 - FFMpegCore/FFMpeg/{Models => Enums}/Codec.cs | 44 ++-- FFMpegCore/FFMpeg/Enums/CodecType.cs | 14 -- .../{Models => Enums}/ContainerFormat.cs | 7 +- FFMpegCore/FFMpeg/Enums/Enums.cs | 54 +++++ FFMpegCore/FFMpeg/Enums/FeatureStatus.cs | 9 - .../FFMpeg/{Utils => Enums}/FileExtension.cs | 3 +- FFMpegCore/FFMpeg/Enums/Filter.cs | 8 - .../FFMpeg/{Models => Enums}/PixelFormat.cs | 11 +- .../{Models => Exceptions}/FFMpegException.cs | 2 +- FFMpegCore/FFMpeg/FFMpeg.cs | 176 +++++++++++++++- FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs | 2 +- FFMpegCore/FFMpeg/FFMpegArguments.cs | 7 +- FFMpegCore/FFMpeg/FFMpegCache.cs | 10 +- FFMpegCore/FFMpeg/FFMpegUtils.cs | 189 ------------------ .../FFMpeg/Pipes/RawVideoPipeDataWriter.cs | 2 +- FFMpegCore/FFMpeg/Utils/AudioCodec.cs | 14 -- FFMpegCore/FFMpeg/Utils/VideoCodec.cs | 13 -- FFMpegCore/FFMpeg/Utils/VideoType.cs | 15 -- FFMpegCore/FFMpegCore.csproj | 4 + .../FFProbe/{Models => }/AudioStream.cs | 0 FFMpegCore/FFProbe/FFProbe.cs | 12 +- FFMpegCore/FFProbe/FFProbeAnalysis.cs | 63 ++++++ FFMpegCore/FFProbe/MediaAnalysis.cs | 24 +-- .../SimpleStream.cs => MediaStream.cs} | 9 +- FFMpegCore/FFProbe/Models/MediaStream.cs | 12 -- FFMpegCore/FFProbe/Models/TextStream.cs | 7 - FFMpegCore/FFProbe/Stream.cs | 64 ------ FFMpegCore/FFProbe/Tags.cs | 13 -- .../FFProbe/{Models => }/VideoStream.cs | 4 +- FFMpegCore/Helpers/FFMpegHelper.cs | 2 +- FFMpegCore/Helpers/FFProbeHelper.cs | 2 +- FFMpegCore/ImageInfo.cs | 2 +- 47 files changed, 410 insertions(+), 485 deletions(-) delete mode 100644 FFMpegCore/FFMpeg/Enums/Channel.cs rename FFMpegCore/FFMpeg/{Models => Enums}/Codec.cs (82%) delete mode 100644 FFMpegCore/FFMpeg/Enums/CodecType.cs rename FFMpegCore/FFMpeg/{Models => Enums}/ContainerFormat.cs (90%) create mode 100644 FFMpegCore/FFMpeg/Enums/Enums.cs delete mode 100644 FFMpegCore/FFMpeg/Enums/FeatureStatus.cs rename FFMpegCore/FFMpeg/{Utils => Enums}/FileExtension.cs (93%) delete mode 100644 FFMpegCore/FFMpeg/Enums/Filter.cs rename FFMpegCore/FFMpeg/{Models => Enums}/PixelFormat.cs (84%) rename FFMpegCore/FFMpeg/{Models => Exceptions}/FFMpegException.cs (94%) delete mode 100644 FFMpegCore/FFMpeg/FFMpegUtils.cs delete mode 100644 FFMpegCore/FFMpeg/Utils/AudioCodec.cs delete mode 100644 FFMpegCore/FFMpeg/Utils/VideoCodec.cs delete mode 100644 FFMpegCore/FFMpeg/Utils/VideoType.cs rename FFMpegCore/FFProbe/{Models => }/AudioStream.cs (100%) rename FFMpegCore/FFProbe/{Models/SimpleStream.cs => MediaStream.cs} (59%) delete mode 100644 FFMpegCore/FFProbe/Models/MediaStream.cs delete mode 100644 FFMpegCore/FFProbe/Models/TextStream.cs delete mode 100644 FFMpegCore/FFProbe/Stream.cs delete mode 100644 FFMpegCore/FFProbe/Tags.cs rename FFMpegCore/FFProbe/{Models => }/VideoStream.cs (82%) diff --git a/FFMpegCore.Test/ArgumentBuilderTest.cs b/FFMpegCore.Test/ArgumentBuilderTest.cs index 943d7a6..6667624 100644 --- a/FFMpegCore.Test/ArgumentBuilderTest.cs +++ b/FFMpegCore.Test/ArgumentBuilderTest.cs @@ -2,8 +2,7 @@ using System; using FFMpegCore.Arguments; using FFMpegCore.Enums; -using FFMpegCore.Models; -using FFMpegCore.Utils; +using FFMpegCore.Exceptions; namespace FFMpegCore.Test { diff --git a/FFMpegCore.Test/AudioTest.cs b/FFMpegCore.Test/AudioTest.cs index 8ebf03b..552ca24 100644 --- a/FFMpegCore.Test/AudioTest.cs +++ b/FFMpegCore.Test/AudioTest.cs @@ -1,8 +1,8 @@ using System; +using FFMpegCore.Enums; using FFMpegCore.Test.Resources; using Microsoft.VisualStudio.TestTools.UnitTesting; using System.IO; -using FFMpegCore.Utils; namespace FFMpegCore.Test { diff --git a/FFMpegCore.Test/FFProbeTests.cs b/FFMpegCore.Test/FFProbeTests.cs index 74aef63..558f29c 100644 --- a/FFMpegCore.Test/FFProbeTests.cs +++ b/FFMpegCore.Test/FFProbeTests.cs @@ -49,7 +49,7 @@ public async Task Probe_Async_Success() var info = await FFProbe.AnalyseAsync(VideoLibrary.LocalVideo.FullName); Assert.AreEqual(13, info.Duration.Seconds); } - + [TestMethod, Timeout(10000)] public void Probe_Success_FromStream() { diff --git a/FFMpegCore.Test/PixelFormatTests.cs b/FFMpegCore.Test/PixelFormatTests.cs index f1d98c0..3e7e841 100644 --- a/FFMpegCore.Test/PixelFormatTests.cs +++ b/FFMpegCore.Test/PixelFormatTests.cs @@ -1,5 +1,8 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using FFMpegCore.Models; +using FFMpegCore.Exceptions; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Text; namespace FFMpegCore.Test { @@ -9,33 +12,33 @@ public class PixelFormatTests [TestMethod] public void PixelFormats_Enumerate() { - var formats = FFMpegUtils.GetPixelFormats(); + var formats = FFMpeg.GetPixelFormats(); Assert.IsTrue(formats.Count > 0); } [TestMethod] public void PixelFormats_TryGetExisting() { - Assert.IsTrue(FFMpegUtils.TryGetPixelFormat("yuv420p", out _)); + Assert.IsTrue(FFMpeg.TryGetPixelFormat("yuv420p", out _)); } [TestMethod] public void PixelFormats_TryGetNotExisting() { - Assert.IsFalse(FFMpegUtils.TryGetPixelFormat("yuv420pppUnknown", out _)); + Assert.IsFalse(FFMpeg.TryGetPixelFormat("yuv420pppUnknown", out _)); } [TestMethod] public void PixelFormats_GetExisting() { - var fmt = FFMpegUtils.GetPixelFormat("yuv420p"); + var fmt = FFMpeg.GetPixelFormat("yuv420p"); Assert.IsTrue(fmt.Components == 3 && fmt.BitsPerPixel == 12); } [TestMethod] public void PixelFormats_GetNotExisting() { - Assert.ThrowsException(() => FFMpegUtils.GetPixelFormat("yuv420pppUnknown")); + Assert.ThrowsException(() => FFMpeg.GetPixelFormat("yuv420pppUnknown")); } } } diff --git a/FFMpegCore.Test/Resources/VideoLibrary.cs b/FFMpegCore.Test/Resources/VideoLibrary.cs index d25e107..3b0c4e0 100644 --- a/FFMpegCore.Test/Resources/VideoLibrary.cs +++ b/FFMpegCore.Test/Resources/VideoLibrary.cs @@ -1,5 +1,6 @@ -using System.IO; -using FFMpegCore.Models; +using System; +using System.IO; +using FFMpegCore.Enums; namespace FFMpegCore.Test.Resources { diff --git a/FFMpegCore.Test/VideoTest.cs b/FFMpegCore.Test/VideoTest.cs index 645e3bf..ffa5da3 100644 --- a/FFMpegCore.Test/VideoTest.cs +++ b/FFMpegCore.Test/VideoTest.cs @@ -7,9 +7,8 @@ using System.IO; using System.Linq; using FFMpegCore.Arguments; -using FFMpegCore.Models; +using FFMpegCore.Exceptions; using FFMpegCore.Pipes; -using FFMpegCore.Utils; namespace FFMpegCore.Test { @@ -128,8 +127,7 @@ private void ConvertToStreamPipe(params IArgument[] inputArguments) var scaling = arguments.Find(); - var result = processor.ProcessSynchronously(); - Assert.IsTrue(result); + processor.ProcessSynchronously(); ms.Position = 0; var outputVideo = FFProbe.Analyse(ms); @@ -159,7 +157,7 @@ private void ConvertToStreamPipe(params IArgument[] inputArguments) } } - private void Convert(ContainerFormat type, Action validationMethod, params IArgument[] inputArguments) + public void Convert(ContainerFormat type, Action validationMethod, params IArgument[] inputArguments) { var output = Input.OutputLocation(type); @@ -208,8 +206,13 @@ private void Convert(ContainerFormat type, Action validationMetho File.Delete(output); } } - - private void ConvertFromPipe(ContainerFormat type, System.Drawing.Imaging.PixelFormat fmt, params IArgument[] inputArguments) + + public void Convert(ContainerFormat type, params IArgument[] inputArguments) + { + Convert(type, null, inputArguments); + } + + public void ConvertFromPipe(ContainerFormat type, System.Drawing.Imaging.PixelFormat fmt, params IArgument[] inputArguments) { var output = Input.OutputLocation(type); @@ -273,7 +276,7 @@ public void Video_ToMP4_YUV444p() [TestMethod] public void Video_ToMP4_Args() { - Convert(VideoType.Mp4, null, new VideoCodecArgument(VideoCodec.LibX264)); + Convert(VideoType.Mp4, new VideoCodecArgument(VideoCodec.LibX264)); } [DataTestMethod] @@ -318,14 +321,13 @@ public void Video_ToMP4_Args_StreamOutputPipe_Async() { using var ms = new MemoryStream(); var pipeSource = new StreamPipeDataReader(ms); - var result = FFMpegArguments + FFMpegArguments .FromInputFiles(VideoLibrary.LocalVideo) .WithVideoCodec(VideoCodec.LibX264) .ForceFormat("matroska") .OutputToPipe(pipeSource) .ProcessAsynchronously() .WaitForResult(); - Assert.IsTrue(result); } [TestMethod] @@ -343,7 +345,7 @@ public void Video_ToTS() [TestMethod] public void Video_ToTS_Args() { - Convert(VideoType.Ts, null, + Convert(VideoType.Ts, new CopyArgument(), new BitStreamFilterArgument(Channel.Video, Filter.H264_Mp4ToAnnexB), new ForceFormatArgument(VideoType.MpegTs)); @@ -367,7 +369,7 @@ public void Video_ToOGV_Resize() [TestMethod] public void Video_ToOGV_Resize_Args() { - Convert(VideoType.Ogv, null, new ScaleArgument(VideoSize.Ed), new VideoCodecArgument(VideoCodec.LibTheora)); + Convert(VideoType.Ogv, new ScaleArgument(VideoSize.Ed), new VideoCodecArgument(VideoCodec.LibTheora)); } [DataTestMethod] @@ -388,7 +390,7 @@ public void Video_ToMP4_Resize() [TestMethod] public void Video_ToMP4_Resize_Args() { - Convert(VideoType.Mp4, null, new ScaleArgument(VideoSize.Ld), new VideoCodecArgument(VideoCodec.LibX264)); + Convert(VideoType.Mp4, new ScaleArgument(VideoSize.Ld), new VideoCodecArgument(VideoCodec.LibX264)); } [DataTestMethod] @@ -545,6 +547,7 @@ public void Video_With_Only_Audio_Should_Extract_Metadata() Assert.AreEqual(null, video.PrimaryVideoStream); Assert.AreEqual("aac", video.PrimaryAudioStream.CodecName); Assert.AreEqual(79.5, video.Duration.TotalSeconds, 0.5); + // Assert.AreEqual(1.25, video.Size); } [TestMethod] @@ -618,14 +621,13 @@ public void Video_TranscodeInMemory() var reader = new StreamPipeDataReader(resStream); var writer = new RawVideoPipeDataWriter(BitmapSource.CreateBitmaps(128, System.Drawing.Imaging.PixelFormat.Format24bppRgb, 128, 128)); - var result = FFMpegArguments + FFMpegArguments .FromPipe(writer) .WithVideoCodec("vp9") .ForceFormat("webm") .OutputToPipe(reader) .ProcessSynchronously(); - Assert.IsTrue(result); - + resStream.Position = 0; var vi = FFProbe.Analyse(resStream); Assert.AreEqual(vi.PrimaryVideoStream.Width, 128); diff --git a/FFMpegCore/FFMpeg/Arguments/AudioCodecArgument.cs b/FFMpegCore/FFMpeg/Arguments/AudioCodecArgument.cs index 4d3102a..273bb02 100644 --- a/FFMpegCore/FFMpeg/Arguments/AudioCodecArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/AudioCodecArgument.cs @@ -1,5 +1,5 @@ using FFMpegCore.Enums; -using FFMpegCore.Models; +using FFMpegCore.Exceptions; namespace FFMpegCore.Arguments { diff --git a/FFMpegCore/FFMpeg/Arguments/DisableChannelArgument.cs b/FFMpegCore/FFMpeg/Arguments/DisableChannelArgument.cs index 98c01b7..d683775 100644 --- a/FFMpegCore/FFMpeg/Arguments/DisableChannelArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/DisableChannelArgument.cs @@ -1,5 +1,5 @@ using FFMpegCore.Enums; -using FFMpegCore.Models; +using FFMpegCore.Exceptions; namespace FFMpegCore.Arguments { diff --git a/FFMpegCore/FFMpeg/Arguments/ForceFormatArgument.cs b/FFMpegCore/FFMpeg/Arguments/ForceFormatArgument.cs index fcf80cb..9524698 100644 --- a/FFMpegCore/FFMpeg/Arguments/ForceFormatArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/ForceFormatArgument.cs @@ -1,4 +1,4 @@ -using FFMpegCore.Models; +using FFMpegCore.Enums; namespace FFMpegCore.Arguments { diff --git a/FFMpegCore/FFMpeg/Arguments/ForcePixelFormat.cs b/FFMpegCore/FFMpeg/Arguments/ForcePixelFormat.cs index 3935c6f..7614ae3 100644 --- a/FFMpegCore/FFMpeg/Arguments/ForcePixelFormat.cs +++ b/FFMpegCore/FFMpeg/Arguments/ForcePixelFormat.cs @@ -1,4 +1,4 @@ -using FFMpegCore.Models; +using FFMpegCore.Enums; namespace FFMpegCore.Arguments { diff --git a/FFMpegCore/FFMpeg/Arguments/InputArgument.cs b/FFMpegCore/FFMpeg/Arguments/InputArgument.cs index 20e7b7b..c201c1f 100644 --- a/FFMpegCore/FFMpeg/Arguments/InputArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/InputArgument.cs @@ -50,7 +50,7 @@ public interface IArgument public interface IInputOutputArgument : IArgument { void Pre() {} - Task During(CancellationToken cancellationToken) => Task.CompletedTask; + Task During(CancellationToken? cancellationToken = null) => Task.CompletedTask; void Post() {} } diff --git a/FFMpegCore/FFMpeg/Arguments/OutputArgument.cs b/FFMpegCore/FFMpeg/Arguments/OutputArgument.cs index d5b4ff6..5a53886 100644 --- a/FFMpegCore/FFMpeg/Arguments/OutputArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/OutputArgument.cs @@ -1,6 +1,6 @@ using System; using System.IO; -using FFMpegCore.Models; +using FFMpegCore.Exceptions; namespace FFMpegCore.Arguments { @@ -11,13 +11,11 @@ public class OutputArgument : IOutputArgument { public readonly string Path; public readonly bool Overwrite; - public readonly bool VerifyOutputExists; - public OutputArgument(string path, bool overwrite = false, bool verifyOutputExists = true) + public OutputArgument(string path, bool overwrite = false) { Path = path; Overwrite = overwrite; - VerifyOutputExists = verifyOutputExists; } public void Pre() @@ -27,7 +25,7 @@ public void Pre() } public void Post() { - if (VerifyOutputExists && !File.Exists(Path)) + if (!File.Exists(Path)) throw new FFMpegException(FFMpegExceptionType.File, "Output file was not created"); } diff --git a/FFMpegCore/FFMpeg/Arguments/PipeArgument.cs b/FFMpegCore/FFMpeg/Arguments/PipeArgument.cs index 8660ab2..77db5db 100644 --- a/FFMpegCore/FFMpeg/Arguments/PipeArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/PipeArgument.cs @@ -34,15 +34,16 @@ public void Post() Pipe = null!; } - public async Task During(CancellationToken cancellationToken) + public async Task During(CancellationToken? cancellationToken = null) { try { - await ProcessDataAsync(cancellationToken).ConfigureAwait(false); + await ProcessDataAsync(cancellationToken ?? CancellationToken.None).ConfigureAwait(false); } catch (TaskCanceledException) { } + Post(); } public abstract Task ProcessDataAsync(CancellationToken token); diff --git a/FFMpegCore/FFMpeg/Arguments/VideoCodecArgument.cs b/FFMpegCore/FFMpeg/Arguments/VideoCodecArgument.cs index 6b91da3..9386822 100644 --- a/FFMpegCore/FFMpeg/Arguments/VideoCodecArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/VideoCodecArgument.cs @@ -1,5 +1,5 @@ using FFMpegCore.Enums; -using FFMpegCore.Models; +using FFMpegCore.Exceptions; namespace FFMpegCore.Arguments { diff --git a/FFMpegCore/FFMpeg/Enums/Channel.cs b/FFMpegCore/FFMpeg/Enums/Channel.cs deleted file mode 100644 index 51e0254..0000000 --- a/FFMpegCore/FFMpeg/Enums/Channel.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace FFMpegCore.Enums -{ - public enum Channel - { - Audio, - Video, - Both - } -} \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/Models/Codec.cs b/FFMpegCore/FFMpeg/Enums/Codec.cs similarity index 82% rename from FFMpegCore/FFMpeg/Models/Codec.cs rename to FFMpegCore/FFMpeg/Enums/Codec.cs index fdad529..1c4ce31 100644 --- a/FFMpegCore/FFMpeg/Models/Codec.cs +++ b/FFMpegCore/FFMpeg/Enums/Codec.cs @@ -1,13 +1,22 @@ -using System; +using FFMpegCore.Exceptions; +using System; +using System.Collections.Generic; +using System.Text; using System.Text.RegularExpressions; -using FFMpegCore.Enums; -namespace FFMpegCore.Models +namespace FFMpegCore.Enums { + public enum FeatureStatus + { + Unknown, + NotSupported, + Supported, + } + public class Codec { - private static readonly Regex CodecsFormatRegex = new Regex(@"([D\.])([E\.])([VASD\.])([I\.])([L\.])([S\.])\s+([a-z0-9_-]+)\s+(.+)", RegexOptions.Compiled); - private static readonly Regex DecodersEncodersFormatRegex = new Regex(@"([VASD\.])([F\.])([S\.])([X\.])([B\.])([D\.])\s+([a-z0-9_-]+)\s+(.+)", RegexOptions.Compiled); + private static readonly Regex _codecsFormatRegex = new Regex(@"([D\.])([E\.])([VASD\.])([I\.])([L\.])([S\.])\s+([a-z0-9_-]+)\s+(.+)"); + private static readonly Regex _decodersEncodersFormatRegex = new Regex(@"([VASD\.])([F\.])([S\.])([X\.])([B\.])([D\.])\s+([a-z0-9_-]+)\s+(.+)"); public class FeatureLevel { @@ -49,7 +58,7 @@ internal Codec(string name, CodecType type) internal static bool TryParseFromCodecs(string line, out Codec codec) { - var match = CodecsFormatRegex.Match(line); + var match = _codecsFormatRegex.Match(line); if (!match.Success) { codec = null!; @@ -72,21 +81,20 @@ internal static bool TryParseFromCodecs(string line, out Codec codec) return false; } - codec = new Codec(name, type) - { - DecodingSupported = match.Groups[1].Value != ".", - EncodingSupported = match.Groups[2].Value != ".", - IsIntraFrameOnly = match.Groups[4].Value != ".", - IsLossy = match.Groups[5].Value != ".", - IsLossless = match.Groups[6].Value != ".", - Description = match.Groups[8].Value - }; - + codec = new Codec(name, type); + + codec.DecodingSupported = match.Groups[1].Value != "."; + codec.EncodingSupported = match.Groups[2].Value != "."; + codec.IsIntraFrameOnly = match.Groups[4].Value != "."; + codec.IsLossy = match.Groups[5].Value != "."; + codec.IsLossless = match.Groups[6].Value != "."; + codec.Description = match.Groups[8].Value; + return true; } internal static bool TryParseFromEncodersDecoders(string line, out Codec codec, bool isEncoder) { - var match = DecodersEncodersFormatRegex.Match(line); + var match = _decodersEncodersFormatRegex.Match(line); if (!match.Success) { codec = null!; @@ -127,7 +135,7 @@ internal static bool TryParseFromEncodersDecoders(string line, out Codec codec, internal void Merge(Codec other) { if (Name != other.Name) - throw new FFMpegException(FFMpegExceptionType.Operation, "different codecs unable to merge"); + throw new FFMpegException(FFMpegExceptionType.Operation, "different codecs enable to merge"); Type |= other.Type; DecodingSupported |= other.DecodingSupported; diff --git a/FFMpegCore/FFMpeg/Enums/CodecType.cs b/FFMpegCore/FFMpeg/Enums/CodecType.cs deleted file mode 100644 index 3900d74..0000000 --- a/FFMpegCore/FFMpeg/Enums/CodecType.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace FFMpegCore.Enums -{ - [Flags] - public enum CodecType - { - Unknown = 0, - Video = 1 << 1, - Audio = 1 << 2, - Subtitle = 1 << 3, - Data = 1 << 4, - } -} \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/Models/ContainerFormat.cs b/FFMpegCore/FFMpeg/Enums/ContainerFormat.cs similarity index 90% rename from FFMpegCore/FFMpeg/Models/ContainerFormat.cs rename to FFMpegCore/FFMpeg/Enums/ContainerFormat.cs index 6ef5b9c..f15e5a7 100644 --- a/FFMpegCore/FFMpeg/Models/ContainerFormat.cs +++ b/FFMpegCore/FFMpeg/Enums/ContainerFormat.cs @@ -1,6 +1,9 @@ -using System.Text.RegularExpressions; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; -namespace FFMpegCore.Models +namespace FFMpegCore.Enums { public class ContainerFormat { diff --git a/FFMpegCore/FFMpeg/Enums/Enums.cs b/FFMpegCore/FFMpeg/Enums/Enums.cs new file mode 100644 index 0000000..2bbab5f --- /dev/null +++ b/FFMpegCore/FFMpeg/Enums/Enums.cs @@ -0,0 +1,54 @@ +namespace FFMpegCore.Enums +{ + public enum CodecType + { + Unknown = 0, + Video = 1 << 1, + Audio = 1 << 2, + Subtitle = 1 << 3, + Data = 1 << 4, + } + + public static class VideoCodec + { + public static Codec LibX264 => FFMpeg.GetCodec("libx264"); + public static Codec LibVpx => FFMpeg.GetCodec("libvpx"); + public static Codec LibTheora => FFMpeg.GetCodec("libtheora"); + public static Codec Png => FFMpeg.GetCodec("png"); + public static Codec MpegTs => FFMpeg.GetCodec("mpegts"); + } + + public static class AudioCodec + { + public static Codec Aac => FFMpeg.GetCodec("aac"); + public static Codec LibVorbis => FFMpeg.GetCodec("libvorbis"); + public static Codec LibFdk_Aac => FFMpeg.GetCodec("libfdk_aac"); + public static Codec Ac3 => FFMpeg.GetCodec("ac3"); + public static Codec Eac3 => FFMpeg.GetCodec("eac3"); + public static Codec LibMp3Lame => FFMpeg.GetCodec("libmp3lame"); + } + + public static class VideoType + { + public static ContainerFormat MpegTs => FFMpeg.GetContinerFormat("mpegts"); + public static ContainerFormat Ts => FFMpeg.GetContinerFormat("mpegts"); + public static ContainerFormat Mp4 => FFMpeg.GetContinerFormat("mp4"); + public static ContainerFormat Mov => FFMpeg.GetContinerFormat("mov"); + public static ContainerFormat Avi => FFMpeg.GetContinerFormat("avi"); + public static ContainerFormat Ogv => FFMpeg.GetContinerFormat("ogv"); + public static ContainerFormat WebM => FFMpeg.GetContinerFormat("webm"); + } + + public enum Filter + { + H264_Mp4ToAnnexB, + Aac_AdtstoAsc + } + + public enum Channel + { + Audio, + Video, + Both + } +} \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/Enums/FeatureStatus.cs b/FFMpegCore/FFMpeg/Enums/FeatureStatus.cs deleted file mode 100644 index 78d2885..0000000 --- a/FFMpegCore/FFMpeg/Enums/FeatureStatus.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace FFMpegCore.Enums -{ - public enum FeatureStatus - { - Unknown, - NotSupported, - Supported, - } -} \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/Utils/FileExtension.cs b/FFMpegCore/FFMpeg/Enums/FileExtension.cs similarity index 93% rename from FFMpegCore/FFMpeg/Utils/FileExtension.cs rename to FFMpegCore/FFMpeg/Enums/FileExtension.cs index 1673a84..d2e4a63 100644 --- a/FFMpegCore/FFMpeg/Utils/FileExtension.cs +++ b/FFMpegCore/FFMpeg/Enums/FileExtension.cs @@ -1,7 +1,6 @@ using System; -using FFMpegCore.Models; -namespace FFMpegCore.Utils +namespace FFMpegCore.Enums { public static class FileExtension { diff --git a/FFMpegCore/FFMpeg/Enums/Filter.cs b/FFMpegCore/FFMpeg/Enums/Filter.cs deleted file mode 100644 index 27a9cd8..0000000 --- a/FFMpegCore/FFMpeg/Enums/Filter.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace FFMpegCore.Enums -{ - public enum Filter - { - H264_Mp4ToAnnexB, - Aac_AdtstoAsc - } -} \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/Models/PixelFormat.cs b/FFMpegCore/FFMpeg/Enums/PixelFormat.cs similarity index 84% rename from FFMpegCore/FFMpeg/Models/PixelFormat.cs rename to FFMpegCore/FFMpeg/Enums/PixelFormat.cs index 275caa9..4262a74 100644 --- a/FFMpegCore/FFMpeg/Models/PixelFormat.cs +++ b/FFMpegCore/FFMpeg/Enums/PixelFormat.cs @@ -1,10 +1,13 @@ -using System.Text.RegularExpressions; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; -namespace FFMpegCore.Models +namespace FFMpegCore.Enums { public class PixelFormat { - private static readonly Regex FormatRegex = new Regex(@"([I\.])([O\.])([H\.])([P\.])([B\.])\s+(\S+)\s+([0-9]+)\s+([0-9]+)", RegexOptions.Compiled); + private static readonly Regex _formatRegex = new Regex(@"([I\.])([O\.])([H\.])([P\.])([B\.])\s+(\S+)\s+([0-9]+)\s+([0-9]+)"); public bool InputConversionSupported { get; private set; } public bool OutputConversionSupported { get; private set; } @@ -27,7 +30,7 @@ internal PixelFormat(string name) internal static bool TryParse(string line, out PixelFormat fmt) { - var match = FormatRegex.Match(line); + var match = _formatRegex.Match(line); if (!match.Success) { fmt = null!; diff --git a/FFMpegCore/FFMpeg/Models/FFMpegException.cs b/FFMpegCore/FFMpeg/Exceptions/FFMpegException.cs similarity index 94% rename from FFMpegCore/FFMpeg/Models/FFMpegException.cs rename to FFMpegCore/FFMpeg/Exceptions/FFMpegException.cs index 592c4ff..6bd608d 100644 --- a/FFMpegCore/FFMpeg/Models/FFMpegException.cs +++ b/FFMpegCore/FFMpeg/Exceptions/FFMpegException.cs @@ -1,6 +1,6 @@ using System; -namespace FFMpegCore.Models +namespace FFMpegCore.Exceptions { public enum FFMpegExceptionType { diff --git a/FFMpegCore/FFMpeg/FFMpeg.cs b/FFMpegCore/FFMpeg/FFMpeg.cs index 9a82e87..13d141f 100644 --- a/FFMpegCore/FFMpeg/FFMpeg.cs +++ b/FFMpegCore/FFMpeg/FFMpeg.cs @@ -5,13 +5,12 @@ using System.IO; using System.Linq; using FFMpegCore.Enums; +using FFMpegCore.Exceptions; using FFMpegCore.Helpers; -using FFMpegCore.Models; -using FFMpegCore.Utils; namespace FFMpegCore { - public static partial class FFMpeg + public static class FFMpeg { /// /// Saves a 'png' thumbnail from the input video. @@ -325,7 +324,178 @@ public static bool ReplaceAudio(string input, string inputAudio, string output, .ProcessSynchronously(); } + #region PixelFormats + internal static IReadOnlyList GetPixelFormatsInternal() + { + FFMpegHelper.RootExceptionCheck(FFMpegOptions.Options.RootDirectory); + var list = new List(); + using var instance = new Instances.Instance(FFMpegOptions.Options.FFmpegBinary(), "-pix_fmts"); + instance.DataReceived += (e, args) => + { + if (Enums.PixelFormat.TryParse(args.Data, out var fmt)) + list.Add(fmt); + }; + + var exitCode = instance.BlockUntilFinished(); + if (exitCode != 0) throw new FFMpegException(FFMpegExceptionType.Process, string.Join("\r\n", instance.OutputData)); + + return list.AsReadOnly(); + } + + public static IReadOnlyList GetPixelFormats() + { + if (!FFMpegOptions.Options.UseCache) + return GetPixelFormatsInternal(); + return FFMpegCache.PixelFormats.Values.ToList().AsReadOnly(); + } + + public static bool TryGetPixelFormat(string name, out Enums.PixelFormat fmt) + { + if (!FFMpegOptions.Options.UseCache) + { + fmt = GetPixelFormatsInternal().FirstOrDefault(x => x.Name == name.ToLowerInvariant().Trim()); + return fmt != null; + } + else + return FFMpegCache.PixelFormats.TryGetValue(name, out fmt); + } + + public static Enums.PixelFormat GetPixelFormat(string name) + { + if (TryGetPixelFormat(name, out var fmt)) + return fmt; + throw new FFMpegException(FFMpegExceptionType.Operation, $"Pixel format \"{name}\" not supported"); + } + #endregion + + #region Codecs + internal static void ParsePartOfCodecs(Dictionary codecs, string arguments, Func parser) + { + FFMpegHelper.RootExceptionCheck(FFMpegOptions.Options.RootDirectory); + + using var instance = new Instances.Instance(FFMpegOptions.Options.FFmpegBinary(), arguments); + instance.DataReceived += (e, args) => + { + var codec = parser(args.Data); + if(codec != null) + if (codecs.TryGetValue(codec.Name, out var parentCodec)) + parentCodec.Merge(codec); + else + codecs.Add(codec.Name, codec); + }; + + var exitCode = instance.BlockUntilFinished(); + if (exitCode != 0) throw new FFMpegException(FFMpegExceptionType.Process, string.Join("\r\n", instance.OutputData)); + } + + internal static Dictionary GetCodecsInternal() + { + var res = new Dictionary(); + ParsePartOfCodecs(res, "-codecs", (s) => + { + if (Codec.TryParseFromCodecs(s, out var codec)) + return codec; + return null; + }); + ParsePartOfCodecs(res, "-encoders", (s) => + { + if (Codec.TryParseFromEncodersDecoders(s, out var codec, true)) + return codec; + return null; + }); + ParsePartOfCodecs(res, "-decoders", (s) => + { + if (Codec.TryParseFromEncodersDecoders(s, out var codec, false)) + return codec; + return null; + }); + + return res; + } + + public static IReadOnlyList GetCodecs() + { + if (!FFMpegOptions.Options.UseCache) + return GetCodecsInternal().Values.ToList().AsReadOnly(); + return FFMpegCache.Codecs.Values.ToList().AsReadOnly(); + } + + public static IReadOnlyList GetCodecs(CodecType type) + { + if (!FFMpegOptions.Options.UseCache) + return GetCodecsInternal().Values.Where(x => x.Type == type).ToList().AsReadOnly(); + return FFMpegCache.Codecs.Values.Where(x=>x.Type == type).ToList().AsReadOnly(); + } + + public static IReadOnlyList GetVideoCodecs() => GetCodecs(CodecType.Video); + public static IReadOnlyList GetAudioCodecs() => GetCodecs(CodecType.Audio); + public static IReadOnlyList GetSubtitleCodecs() => GetCodecs(CodecType.Subtitle); + public static IReadOnlyList GetDataCodecs() => GetCodecs(CodecType.Data); + + public static bool TryGetCodec(string name, out Codec codec) + { + if (!FFMpegOptions.Options.UseCache) + { + codec = GetCodecsInternal().Values.FirstOrDefault(x => x.Name == name.ToLowerInvariant().Trim()); + return codec != null; + } + else + return FFMpegCache.Codecs.TryGetValue(name, out codec); + } + + public static Codec GetCodec(string name) + { + if (TryGetCodec(name, out var codec) && codec != null) + return codec; + throw new FFMpegException(FFMpegExceptionType.Operation, $"Codec \"{name}\" not supported"); + } + #endregion + + #region ContainerFormats + internal static IReadOnlyList GetContainersFormatsInternal() + { + FFMpegHelper.RootExceptionCheck(FFMpegOptions.Options.RootDirectory); + + var list = new List(); + using var instance = new Instances.Instance(FFMpegOptions.Options.FFmpegBinary(), "-formats"); + instance.DataReceived += (e, args) => + { + if (ContainerFormat.TryParse(args.Data, out var fmt)) + list.Add(fmt); + }; + + var exitCode = instance.BlockUntilFinished(); + if (exitCode != 0) throw new FFMpegException(FFMpegExceptionType.Process, string.Join("\r\n", instance.OutputData)); + + return list.AsReadOnly(); + } + + public static IReadOnlyList GetContainerFormats() + { + if (!FFMpegOptions.Options.UseCache) + return GetContainersFormatsInternal(); + return FFMpegCache.ContainerFormats.Values.ToList().AsReadOnly(); + } + + public static bool TryGetContainerFormat(string name, out ContainerFormat fmt) + { + if (!FFMpegOptions.Options.UseCache) + { + fmt = GetContainersFormatsInternal().FirstOrDefault(x => x.Name == name.ToLowerInvariant().Trim()); + return fmt != null; + } + else + return FFMpegCache.ContainerFormats.TryGetValue(name, out fmt); + } + + public static ContainerFormat GetContinerFormat(string name) + { + if (TryGetContainerFormat(name, out var fmt)) + return fmt; + throw new FFMpegException(FFMpegExceptionType.Operation, $"Container format \"{name}\" not supported"); + } + #endregion private static void Cleanup(IEnumerable pathList) { diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs b/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs index ab43d49..3349e19 100644 --- a/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs +++ b/FFMpegCore/FFMpeg/FFMpegArgumentProcessor.cs @@ -4,8 +4,8 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; +using FFMpegCore.Exceptions; using FFMpegCore.Helpers; -using FFMpegCore.Models; using Instances; namespace FFMpegCore diff --git a/FFMpegCore/FFMpeg/FFMpegArguments.cs b/FFMpegCore/FFMpeg/FFMpegArguments.cs index d0a3a2c..bcfe28c 100644 --- a/FFMpegCore/FFMpeg/FFMpegArguments.cs +++ b/FFMpegCore/FFMpeg/FFMpegArguments.cs @@ -7,7 +7,6 @@ using System.Threading.Tasks; using FFMpegCore.Arguments; using FFMpegCore.Enums; -using FFMpegCore.Models; using FFMpegCore.Pipes; namespace FFMpegCore @@ -86,8 +85,8 @@ private FFMpegArguments(IInputArgument inputArgument) public FFMpegArguments DrawText(DrawTextOptions drawTextOptions) => WithArgument(new DrawTextArgument(drawTextOptions)); - public FFMpegArgumentProcessor OutputToFile(string file, bool overwrite = false, bool verifyOutputExists = true) => ToProcessor(new OutputArgument(file, overwrite, verifyOutputExists)); - public FFMpegArgumentProcessor OutputToFile(Uri uri, bool overwrite = false, bool verifyOutputExists = true) => ToProcessor(new OutputArgument(uri.AbsolutePath, overwrite, verifyOutputExists)); + public FFMpegArgumentProcessor OutputToFile(string file, bool overwrite = false) => ToProcessor(new OutputArgument(file, overwrite)); + public FFMpegArgumentProcessor OutputToFile(Uri uri, bool overwrite = false) => ToProcessor(new OutputArgument(uri.AbsolutePath, overwrite)); public FFMpegArgumentProcessor OutputToPipe(IPipeDataReader reader) => ToProcessor(new OutputPipeArgument(reader)); public FFMpegArguments WithArgument(IArgument argument) @@ -107,7 +106,7 @@ internal void Pre() _inputArgument.Pre(); _outputArgument.Pre(); } - internal async Task During(CancellationToken cancellationToken) + internal async Task During(CancellationToken? cancellationToken = null) { await Task.WhenAll(_inputArgument.During(cancellationToken), _outputArgument.During(cancellationToken)).ConfigureAwait(false); } diff --git a/FFMpegCore/FFMpeg/FFMpegCache.cs b/FFMpegCore/FFMpeg/FFMpegCache.cs index 15d06bc..0847202 100644 --- a/FFMpegCore/FFMpeg/FFMpegCache.cs +++ b/FFMpegCore/FFMpeg/FFMpegCache.cs @@ -1,6 +1,6 @@ -using System.Collections.Generic; +using FFMpegCore.Enums; +using System.Collections.Generic; using System.Linq; -using FFMpegCore.Models; namespace FFMpegCore { @@ -18,7 +18,7 @@ public static IReadOnlyDictionary PixelFormats if (_pixelFormats == null) //First check not thread safe lock (_syncObject) if (_pixelFormats == null)//Second check thread safe - _pixelFormats = FFMpegUtils.GetPixelFormatsInternal().ToDictionary(x => x.Name); + _pixelFormats = FFMpeg.GetPixelFormatsInternal().ToDictionary(x => x.Name); return _pixelFormats; } @@ -31,7 +31,7 @@ public static IReadOnlyDictionary Codecs if (_codecs == null) //First check not thread safe lock (_syncObject) if (_codecs == null)//Second check thread safe - _codecs = FFMpegUtils.GetCodecsInternal(); + _codecs = FFMpeg.GetCodecsInternal(); return _codecs; } @@ -44,7 +44,7 @@ public static IReadOnlyDictionary ContainerFormats if (_containers == null) //First check not thread safe lock (_syncObject) if (_containers == null)//Second check thread safe - _containers = FFMpegUtils.GetContainersFormatsInternal().ToDictionary(x => x.Name); + _containers = FFMpeg.GetContainersFormatsInternal().ToDictionary(x => x.Name); return _containers; } diff --git a/FFMpegCore/FFMpeg/FFMpegUtils.cs b/FFMpegCore/FFMpeg/FFMpegUtils.cs deleted file mode 100644 index 799ac3a..0000000 --- a/FFMpegCore/FFMpeg/FFMpegUtils.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using FFMpegCore.Enums; -using FFMpegCore.Helpers; -using FFMpegCore.Models; - -namespace FFMpegCore -{ - public static class FFMpegUtils - { - #region PixelFormats - internal static IReadOnlyList GetPixelFormatsInternal() - { - FFMpegHelper.RootExceptionCheck(FFMpegOptions.Options.RootDirectory); - - var list = new List(); - using var instance = new Instances.Instance(FFMpegOptions.Options.FFmpegBinary(), "-pix_fmts"); - instance.DataReceived += (e, args) => - { - if (PixelFormat.TryParse(args.Data, out var fmt)) - list.Add(fmt); - }; - - var exitCode = instance.BlockUntilFinished(); - if (exitCode != 0) throw new FFMpegException(FFMpegExceptionType.Process, string.Join("\r\n", instance.OutputData)); - - return list.AsReadOnly(); - } - - public static IReadOnlyList GetPixelFormats() - { - if (!FFMpegOptions.Options.UseCache) - return GetPixelFormatsInternal(); - return FFMpegCache.PixelFormats.Values.ToList().AsReadOnly(); - } - - public static bool TryGetPixelFormat(string name, out PixelFormat fmt) - { - if (!FFMpegOptions.Options.UseCache) - { - fmt = GetPixelFormatsInternal().FirstOrDefault(x => x.Name == name.ToLowerInvariant().Trim()); - return fmt != null; - } - else - return FFMpegCache.PixelFormats.TryGetValue(name, out fmt); - } - - public static PixelFormat GetPixelFormat(string name) - { - if (TryGetPixelFormat(name, out var fmt)) - return fmt; - throw new FFMpegException(FFMpegExceptionType.Operation, $"Pixel format \"{name}\" not supported"); - } - #endregion - - #region ContainerFormats - internal static IReadOnlyList GetContainersFormatsInternal() - { - FFMpegHelper.RootExceptionCheck(FFMpegOptions.Options.RootDirectory); - - var list = new List(); - using var instance = new Instances.Instance(FFMpegOptions.Options.FFmpegBinary(), "-formats"); - instance.DataReceived += (e, args) => - { - if (ContainerFormat.TryParse(args.Data, out var fmt)) - list.Add(fmt); - }; - - var exitCode = instance.BlockUntilFinished(); - if (exitCode != 0) throw new FFMpegException(FFMpegExceptionType.Process, string.Join("\r\n", instance.OutputData)); - - return list.AsReadOnly(); - } - - public static IReadOnlyList GetContainerFormats() - { - if (!FFMpegOptions.Options.UseCache) - return GetContainersFormatsInternal(); - return FFMpegCache.ContainerFormats.Values.ToList().AsReadOnly(); - } - - public static bool TryGetContainerFormat(string name, out ContainerFormat fmt) - { - if (!FFMpegOptions.Options.UseCache) - { - fmt = GetContainersFormatsInternal().FirstOrDefault(x => x.Name == name.ToLowerInvariant().Trim()); - return fmt != null; - } - else - return FFMpegCache.ContainerFormats.TryGetValue(name, out fmt); - } - - public static ContainerFormat GetContainerFormat(string name) - { - if (TryGetContainerFormat(name, out var fmt)) - return fmt; - throw new FFMpegException(FFMpegExceptionType.Operation, $"Container format \"{name}\" not supported"); - } - #endregion - - #region Codecs - - internal static void ParsePartOfCodecs(Dictionary codecs, string arguments, - Func parser) - { - FFMpegHelper.RootExceptionCheck(FFMpegOptions.Options.RootDirectory); - - using var instance = new Instances.Instance(FFMpegOptions.Options.FFmpegBinary(), arguments); - instance.DataReceived += (e, args) => - { - var codec = parser(args.Data); - if (codec != null) - if (codecs.TryGetValue(codec.Name, out var parentCodec)) - parentCodec.Merge(codec); - else - codecs.Add(codec.Name, codec); - }; - - var exitCode = instance.BlockUntilFinished(); - if (exitCode != 0) - throw new FFMpegException(FFMpegExceptionType.Process, string.Join("\r\n", instance.OutputData)); - } - - internal static Dictionary GetCodecsInternal() - { - var res = new Dictionary(); - ParsePartOfCodecs(res, "-codecs", (s) => - { - if (Codec.TryParseFromCodecs(s, out var codec)) - return codec; - return null; - }); - ParsePartOfCodecs(res, "-encoders", (s) => - { - if (Codec.TryParseFromEncodersDecoders(s, out var codec, true)) - return codec; - return null; - }); - ParsePartOfCodecs(res, "-decoders", (s) => - { - if (Codec.TryParseFromEncodersDecoders(s, out var codec, false)) - return codec; - return null; - }); - - return res; - } - - public static IReadOnlyList GetCodecs() - { - if (!FFMpegOptions.Options.UseCache) - return GetCodecsInternal().Values.ToList().AsReadOnly(); - return FFMpegCache.Codecs.Values.ToList().AsReadOnly(); - } - - public static IReadOnlyList GetCodecs(CodecType type) - { - if (!FFMpegOptions.Options.UseCache) - return GetCodecsInternal().Values.Where(x => x.Type == type).ToList().AsReadOnly(); - return FFMpegCache.Codecs.Values.Where(x => x.Type == type).ToList().AsReadOnly(); - } - - public static IReadOnlyList GetVideoCodecs() => GetCodecs(CodecType.Video); - public static IReadOnlyList GetAudioCodecs() => GetCodecs(CodecType.Audio); - public static IReadOnlyList GetSubtitleCodecs() => GetCodecs(CodecType.Subtitle); - public static IReadOnlyList GetDataCodecs() => GetCodecs(CodecType.Data); - - public static bool TryGetCodec(string name, out Codec codec) - { - if (!FFMpegOptions.Options.UseCache) - { - codec = GetCodecsInternal().Values.FirstOrDefault(x => x.Name == name.ToLowerInvariant().Trim()); - return codec != null; - } - else - return FFMpegCache.Codecs.TryGetValue(name, out codec); - } - - public static Codec GetCodec(string name) - { - if (TryGetCodec(name, out var codec) && codec != null) - return codec; - throw new FFMpegException(FFMpegExceptionType.Operation, $"Codec \"{name}\" not supported"); - } - - #endregion - } -} \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/Pipes/RawVideoPipeDataWriter.cs b/FFMpegCore/FFMpeg/Pipes/RawVideoPipeDataWriter.cs index c24e1cc..d35e7d5 100644 --- a/FFMpegCore/FFMpeg/Pipes/RawVideoPipeDataWriter.cs +++ b/FFMpegCore/FFMpeg/Pipes/RawVideoPipeDataWriter.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using FFMpegCore.Models; +using FFMpegCore.Exceptions; namespace FFMpegCore.Pipes { diff --git a/FFMpegCore/FFMpeg/Utils/AudioCodec.cs b/FFMpegCore/FFMpeg/Utils/AudioCodec.cs deleted file mode 100644 index 57a57b7..0000000 --- a/FFMpegCore/FFMpeg/Utils/AudioCodec.cs +++ /dev/null @@ -1,14 +0,0 @@ -using FFMpegCore.Models; - -namespace FFMpegCore.Utils -{ - public static class AudioCodec - { - public static Codec Aac => FFMpegUtils.GetCodec("aac"); - public static Codec LibVorbis => FFMpegUtils.GetCodec("libvorbis"); - public static Codec LibFdkAac => FFMpegUtils.GetCodec("libfdk_aac"); - public static Codec Ac3 => FFMpegUtils.GetCodec("ac3"); - public static Codec Eac3 => FFMpegUtils.GetCodec("eac3"); - public static Codec LibMp3Lame => FFMpegUtils.GetCodec("libmp3lame"); - } -} \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/Utils/VideoCodec.cs b/FFMpegCore/FFMpeg/Utils/VideoCodec.cs deleted file mode 100644 index b6b0752..0000000 --- a/FFMpegCore/FFMpeg/Utils/VideoCodec.cs +++ /dev/null @@ -1,13 +0,0 @@ -using FFMpegCore.Models; - -namespace FFMpegCore.Utils -{ - public static class VideoCodec - { - public static Codec LibX264 => FFMpegUtils.GetCodec("libx264"); - public static Codec LibVpx => FFMpegUtils.GetCodec("libvpx"); - public static Codec LibTheora => FFMpegUtils.GetCodec("libtheora"); - public static Codec Png => FFMpegUtils.GetCodec("png"); - public static Codec MpegTs => FFMpegUtils.GetCodec("mpegts"); - } -} \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/Utils/VideoType.cs b/FFMpegCore/FFMpeg/Utils/VideoType.cs deleted file mode 100644 index 679ed8a..0000000 --- a/FFMpegCore/FFMpeg/Utils/VideoType.cs +++ /dev/null @@ -1,15 +0,0 @@ -using FFMpegCore.Models; - -namespace FFMpegCore.Utils -{ - public static class VideoType - { - public static ContainerFormat MpegTs => FFMpegUtils.GetContainerFormat("mpegts"); - public static ContainerFormat Ts => FFMpegUtils.GetContainerFormat("mpegts"); - public static ContainerFormat Mp4 => FFMpegUtils.GetContainerFormat("mp4"); - public static ContainerFormat Mov => FFMpegUtils.GetContainerFormat("mov"); - public static ContainerFormat Avi => FFMpegUtils.GetContainerFormat("avi"); - public static ContainerFormat Ogv => FFMpegUtils.GetContainerFormat("ogv"); - public static ContainerFormat WebM => FFMpegUtils.GetContainerFormat("webm"); - } -} \ No newline at end of file diff --git a/FFMpegCore/FFMpegCore.csproj b/FFMpegCore/FFMpegCore.csproj index d9aaa89..996d76c 100644 --- a/FFMpegCore/FFMpegCore.csproj +++ b/FFMpegCore/FFMpegCore.csproj @@ -32,4 +32,8 @@ + + + + diff --git a/FFMpegCore/FFProbe/Models/AudioStream.cs b/FFMpegCore/FFProbe/AudioStream.cs similarity index 100% rename from FFMpegCore/FFProbe/Models/AudioStream.cs rename to FFMpegCore/FFProbe/AudioStream.cs diff --git a/FFMpegCore/FFProbe/FFProbe.cs b/FFMpegCore/FFProbe/FFProbe.cs index 7bcb4a0..8dc0154 100644 --- a/FFMpegCore/FFProbe/FFProbe.cs +++ b/FFMpegCore/FFProbe/FFProbe.cs @@ -1,10 +1,10 @@ -using System.IO; +using System; +using System.IO; using System.Text.Json; -using System.Threading; using System.Threading.Tasks; using FFMpegCore.Arguments; +using FFMpegCore.Exceptions; using FFMpegCore.Helpers; -using FFMpegCore.Models; using FFMpegCore.Pipes; using Instances; @@ -28,7 +28,7 @@ public static MediaAnalysis Analyse(System.IO.Stream stream, int outputCapacity var task = instance.FinishedRunning(); try { - pipeArgument.During(CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult(); + pipeArgument.During().ConfigureAwait(false).GetAwaiter().GetResult(); } catch (IOException) { } finally @@ -57,9 +57,9 @@ public static async Task AnalyseAsync(System.IO.Stream stream, in var task = instance.FinishedRunning(); try { - await pipeArgument.During(CancellationToken.None); + await pipeArgument.During(); } - catch (IOException) + catch(IOException) { } finally diff --git a/FFMpegCore/FFProbe/FFProbeAnalysis.cs b/FFMpegCore/FFProbe/FFProbeAnalysis.cs index 8005d89..2a82528 100644 --- a/FFMpegCore/FFProbe/FFProbeAnalysis.cs +++ b/FFMpegCore/FFProbe/FFProbeAnalysis.cs @@ -8,4 +8,67 @@ public class FFProbeAnalysis [JsonPropertyName("streams")] public List Streams { get; set; } = null!; } + + public class Stream + { + [JsonPropertyName("index")] + public int Index { get; set; } + + [JsonPropertyName("avg_frame_rate")] + public string AvgFrameRate { get; set; } = null!; + + [JsonPropertyName("bits_per_raw_sample")] + public string BitsPerRawSample { get; set; } = null!; + + [JsonPropertyName("bit_rate")] + public string BitRate { get; set; } = null!; + + [JsonPropertyName("channels")] + public int? Channels { get; set; } + + [JsonPropertyName("channel_layout")] + public string ChannelLayout { get; set; } = null!; + + [JsonPropertyName("codec_type")] + public string CodecType { get; set; } = null!; + + [JsonPropertyName("codec_name")] + public string CodecName { get; set; } = null!; + + [JsonPropertyName("codec_long_name")] + public string CodecLongName { get; set; } = null!; + + [JsonPropertyName("display_aspect_ratio")] + public string DisplayAspectRatio { get; set; } = null!; + + [JsonPropertyName("duration")] + public string Duration { get; set; } = null!; + + [JsonPropertyName("profile")] + public string Profile { get; set; } = null!; + + [JsonPropertyName("width")] + public int? Width { get; set; } + + [JsonPropertyName("height")] + public int? Height { get; set; } + + [JsonPropertyName("r_frame_rate")] + public string FrameRate { get; set; } = null!; + + [JsonPropertyName("pix_fmt")] + public string PixelFormat { get; set; } = null!; + + [JsonPropertyName("sample_rate")] + public string SampleRate { get; set; } = null!; + + [JsonPropertyName("tags")] + public Tags Tags { get; set; } = null!; + } + + public class Tags + { + [JsonPropertyName("DURATION")] + public string Duration { get; set; } = null!; + } } diff --git a/FFMpegCore/FFProbe/MediaAnalysis.cs b/FFMpegCore/FFProbe/MediaAnalysis.cs index 07b7647..4b638b2 100644 --- a/FFMpegCore/FFProbe/MediaAnalysis.cs +++ b/FFMpegCore/FFProbe/MediaAnalysis.cs @@ -10,29 +10,24 @@ internal MediaAnalysis(string path, FFProbeAnalysis analysis) { VideoStreams = analysis.Streams.Where(stream => stream.CodecType == "video").Select(ParseVideoStream).ToList(); AudioStreams = analysis.Streams.Where(stream => stream.CodecType == "audio").Select(ParseAudioStream).ToList(); - TextStreams = analysis.Streams.Where(stream => stream.CodecTagString == "text").Select(ParseTextStream).ToList(); PrimaryVideoStream = VideoStreams.OrderBy(stream => stream.Index).FirstOrDefault(); PrimaryAudioStream = AudioStreams.OrderBy(stream => stream.Index).FirstOrDefault(); - PrimaryTextStream = TextStreams.OrderBy(stream => stream.Index).FirstOrDefault(); Path = path; } - public string Path { get; } public string Extension => System.IO.Path.GetExtension(Path); public TimeSpan Duration => TimeSpan.FromSeconds(Math.Max( PrimaryVideoStream?.Duration.TotalSeconds ?? 0, PrimaryAudioStream?.Duration.TotalSeconds ?? 0)); + public AudioStream PrimaryAudioStream { get; } public VideoStream PrimaryVideoStream { get; } - public AudioStream PrimaryAudioStream { get; } - public TextStream PrimaryTextStream { get; } public List VideoStreams { get; } public List AudioStreams { get; } - public List TextStreams { get; set; } private VideoStream ParseVideoStream(Stream stream) { @@ -50,8 +45,7 @@ private VideoStream ParseVideoStream(Stream stream) Height = stream.Height!.Value, Width = stream.Width!.Value, Profile = stream.Profile, - PixelFormat = stream.PixelFormat, - Language = stream.Tags.Language + PixelFormat = stream.PixelFormat }; } @@ -73,19 +67,7 @@ private AudioStream ParseAudioStream(Stream stream) Channels = stream.Channels ?? default, ChannelLayout = stream.ChannelLayout, Duration = TimeSpan.FromSeconds(ParseDoubleInvariant(stream.Duration ?? stream.Tags.Duration ?? "0")), - SampleRateHz = !string.IsNullOrEmpty(stream.SampleRate) ? ParseIntInvariant(stream.SampleRate) : default, - Language = stream.Tags.Language - }; - } - private TextStream ParseTextStream(Stream stream) - { - return new TextStream - { - Index = stream.Index, - CodecName = stream.CodecName, - CodecLongName = stream.CodecLongName, - Duration = TimeSpan.FromSeconds(ParseDoubleInvariant(stream.Duration ?? stream.Tags.Duration ?? "0")), - Language = stream.Tags.Language + SampleRateHz = !string.IsNullOrEmpty(stream.SampleRate) ? ParseIntInvariant(stream.SampleRate) : default }; } diff --git a/FFMpegCore/FFProbe/Models/SimpleStream.cs b/FFMpegCore/FFProbe/MediaStream.cs similarity index 59% rename from FFMpegCore/FFProbe/Models/SimpleStream.cs rename to FFMpegCore/FFProbe/MediaStream.cs index 98a7804..8532e51 100644 --- a/FFMpegCore/FFProbe/Models/SimpleStream.cs +++ b/FFMpegCore/FFProbe/MediaStream.cs @@ -1,13 +1,16 @@ -using System; +using FFMpegCore.Enums; +using System; namespace FFMpegCore { - public abstract class SimpleStream + public class MediaStream { public int Index { get; internal set; } public string CodecName { get; internal set; } = null!; public string CodecLongName { get; internal set; } = null!; + public int BitRate { get; internal set; } public TimeSpan Duration { get; internal set; } - public string? Language { get; internal set; } + + public Codec GetCodecInfo() => FFMpeg.GetCodec(CodecName); } } \ No newline at end of file diff --git a/FFMpegCore/FFProbe/Models/MediaStream.cs b/FFMpegCore/FFProbe/Models/MediaStream.cs deleted file mode 100644 index 61fc57b..0000000 --- a/FFMpegCore/FFProbe/Models/MediaStream.cs +++ /dev/null @@ -1,12 +0,0 @@ -using FFMpegCore.Models; - -namespace FFMpegCore -{ - public abstract class MediaStream : SimpleStream - { - public int BitRate { get; internal set; } - - public Codec GetCodecInfo() => FFMpegUtils.GetCodec(CodecName); - - } -} \ No newline at end of file diff --git a/FFMpegCore/FFProbe/Models/TextStream.cs b/FFMpegCore/FFProbe/Models/TextStream.cs deleted file mode 100644 index 61d691e..0000000 --- a/FFMpegCore/FFProbe/Models/TextStream.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace FFMpegCore -{ - public class TextStream : SimpleStream - { - - } -} \ No newline at end of file diff --git a/FFMpegCore/FFProbe/Stream.cs b/FFMpegCore/FFProbe/Stream.cs deleted file mode 100644 index 8ac2ca7..0000000 --- a/FFMpegCore/FFProbe/Stream.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Text.Json.Serialization; - -namespace FFMpegCore -{ - public class Stream - { - [JsonPropertyName("index")] - public int Index { get; set; } - - [JsonPropertyName("avg_frame_rate")] - public string AvgFrameRate { get; set; } = null!; - - [JsonPropertyName("bits_per_raw_sample")] - public string BitsPerRawSample { get; set; } = null!; - - [JsonPropertyName("bit_rate")] - public string BitRate { get; set; } = null!; - - [JsonPropertyName("channels")] - public int? Channels { get; set; } - - [JsonPropertyName("channel_layout")] - public string ChannelLayout { get; set; } = null!; - - [JsonPropertyName("codec_type")] - public string CodecType { get; set; } = null!; - - [JsonPropertyName("codec_name")] - public string CodecName { get; set; } = null!; - - [JsonPropertyName("codec_long_name")] - public string CodecLongName { get; set; } = null!; - - [JsonPropertyName("codec_tag_string")] - public string CodecTagString { get; set; } = null!; - - [JsonPropertyName("display_aspect_ratio")] - public string DisplayAspectRatio { get; set; } = null!; - - [JsonPropertyName("duration")] - public string Duration { get; set; } = null!; - - [JsonPropertyName("profile")] - public string Profile { get; set; } = null!; - - [JsonPropertyName("width")] - public int? Width { get; set; } - - [JsonPropertyName("height")] - public int? Height { get; set; } - - [JsonPropertyName("r_frame_rate")] - public string FrameRate { get; set; } = null!; - - [JsonPropertyName("pix_fmt")] - public string PixelFormat { get; set; } = null!; - - [JsonPropertyName("sample_rate")] - public string SampleRate { get; set; } = null!; - - [JsonPropertyName("tags")] - public Tags Tags { get; set; } = null!; - } -} \ No newline at end of file diff --git a/FFMpegCore/FFProbe/Tags.cs b/FFMpegCore/FFProbe/Tags.cs deleted file mode 100644 index 8feaa8d..0000000 --- a/FFMpegCore/FFProbe/Tags.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text.Json.Serialization; - -namespace FFMpegCore -{ - public class Tags - { - [JsonPropertyName("duration")] - public string Duration { get; set; } = null!; - - [JsonPropertyName("language")] - public string Language { get; set; } = null!; - } -} \ No newline at end of file diff --git a/FFMpegCore/FFProbe/Models/VideoStream.cs b/FFMpegCore/FFProbe/VideoStream.cs similarity index 82% rename from FFMpegCore/FFProbe/Models/VideoStream.cs rename to FFMpegCore/FFProbe/VideoStream.cs index 0ebf202..18533bd 100644 --- a/FFMpegCore/FFProbe/Models/VideoStream.cs +++ b/FFMpegCore/FFProbe/VideoStream.cs @@ -1,4 +1,4 @@ -using FFMpegCore.Models; +using FFMpegCore.Enums; namespace FFMpegCore { @@ -13,6 +13,6 @@ public class VideoStream : MediaStream public double FrameRate { get; internal set; } public string PixelFormat { get; internal set; } = null!; - public PixelFormat GetPixelFormatInfo() => FFMpegUtils.GetPixelFormat(PixelFormat); + public PixelFormat GetPixelFormatInfo() => FFMpeg.GetPixelFormat(PixelFormat); } } \ No newline at end of file diff --git a/FFMpegCore/Helpers/FFMpegHelper.cs b/FFMpegCore/Helpers/FFMpegHelper.cs index 457e014..f280b08 100644 --- a/FFMpegCore/Helpers/FFMpegHelper.cs +++ b/FFMpegCore/Helpers/FFMpegHelper.cs @@ -1,7 +1,7 @@ using System; using System.Drawing; using System.IO; -using FFMpegCore.Models; +using FFMpegCore.Exceptions; namespace FFMpegCore.Helpers { diff --git a/FFMpegCore/Helpers/FFProbeHelper.cs b/FFMpegCore/Helpers/FFProbeHelper.cs index cc4289d..eed1b7a 100644 --- a/FFMpegCore/Helpers/FFProbeHelper.cs +++ b/FFMpegCore/Helpers/FFProbeHelper.cs @@ -1,4 +1,4 @@ -using FFMpegCore.Models; +using FFMpegCore.Exceptions; namespace FFMpegCore.Helpers { diff --git a/FFMpegCore/ImageInfo.cs b/FFMpegCore/ImageInfo.cs index a178e2c..cf8561e 100644 --- a/FFMpegCore/ImageInfo.cs +++ b/FFMpegCore/ImageInfo.cs @@ -1,8 +1,8 @@ using System; using System.Drawing; using System.IO; +using FFMpegCore.Enums; using FFMpegCore.Helpers; -using FFMpegCore.Utils; namespace FFMpegCore {