From 718371505cb78f1bc14ee78f413be88af53e6167 Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Mon, 6 Mar 2023 17:22:08 +1300 Subject: [PATCH 01/15] Add .gif file extension --- FFMpegCore/FFMpeg/Enums/FileExtension.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/FFMpegCore/FFMpeg/Enums/FileExtension.cs b/FFMpegCore/FFMpeg/Enums/FileExtension.cs index b5e775d..f3067ba 100644 --- a/FFMpegCore/FFMpeg/Enums/FileExtension.cs +++ b/FFMpegCore/FFMpeg/Enums/FileExtension.cs @@ -20,5 +20,6 @@ public static string Extension(this Codec type) public static readonly string WebM = VideoType.WebM.Extension; public static readonly string Png = ".png"; public static readonly string Mp3 = ".mp3"; + public static readonly string Gif = ".gif"; } } From 4dbbf345d4912283dc63a92d71d7400b4501783c Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Mon, 6 Mar 2023 17:25:08 +1300 Subject: [PATCH 02/15] Add "GifPalettArgument" for outputting GIFs --- .../FFMpeg/Arguments/GifPalettArgument.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 FFMpegCore/FFMpeg/Arguments/GifPalettArgument.cs diff --git a/FFMpegCore/FFMpeg/Arguments/GifPalettArgument.cs b/FFMpegCore/FFMpeg/Arguments/GifPalettArgument.cs new file mode 100644 index 0000000..408832d --- /dev/null +++ b/FFMpegCore/FFMpeg/Arguments/GifPalettArgument.cs @@ -0,0 +1,21 @@ +using System.Drawing; + +namespace FFMpegCore.Arguments +{ + public class GifPalettArgument : IArgument + { + private readonly int _fps; + + private readonly Size? _size; + + public GifPalettArgument(int fps, Size? size) + { + _fps = fps; + _size = size; + } + + private string ScaleText => _size.HasValue ? $"scale=w={_size.Value.Width}:h={_size.Value.Height}," : string.Empty; + + public string Text => $"-filter_complex \"[0:v] fps={_fps},{ScaleText}split [a][b];[a] palettegen=max_colors=32 [p];[b][p] paletteuse=dither=bayer\""; + } +} From b7fd9890da19e32d9a14c8169d535f66cc2a63ae Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Tue, 7 Mar 2023 16:07:30 +1300 Subject: [PATCH 03/15] Add GifPallet argument builder --- FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs index cc49c5f..635ef29 100644 --- a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs +++ b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs @@ -76,6 +76,7 @@ public FFMpegArgumentOptions DeselectStreams(IEnumerable streamIndices, int public FFMpegArgumentOptions WithAudibleEncryptionKeys(string key, string iv) => WithArgument(new AudibleEncryptionKeyArgument(key, iv)); public FFMpegArgumentOptions WithAudibleActivationBytes(string activationBytes) => WithArgument(new AudibleEncryptionKeyArgument(activationBytes)); public FFMpegArgumentOptions WithTagVersion(int id3v2Version = 3) => WithArgument(new ID3V2VersionArgument(id3v2Version)); + public FFMpegArgumentOptions WithGifPalettArgument(Size? size, int fps = 12) => WithArgument(new GifPalettArgument(fps, size)); public FFMpegArgumentOptions WithArgument(IArgument argument) { From 19c177a248d7a627671b2162534089446855fc6b Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Tue, 7 Mar 2023 16:19:03 +1300 Subject: [PATCH 04/15] Receive stream index as an argument for generating GIFs --- FFMpegCore/FFMpeg/Arguments/GifPalettArgument.cs | 7 +++++-- FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/FFMpegCore/FFMpeg/Arguments/GifPalettArgument.cs b/FFMpegCore/FFMpeg/Arguments/GifPalettArgument.cs index 408832d..9c95045 100644 --- a/FFMpegCore/FFMpeg/Arguments/GifPalettArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/GifPalettArgument.cs @@ -4,18 +4,21 @@ namespace FFMpegCore.Arguments { public class GifPalettArgument : IArgument { + private readonly int _streamIndex; + private readonly int _fps; private readonly Size? _size; - public GifPalettArgument(int fps, Size? size) + public GifPalettArgument(int streamIndex, int fps, Size? size) { + _streamIndex = streamIndex; _fps = fps; _size = size; } private string ScaleText => _size.HasValue ? $"scale=w={_size.Value.Width}:h={_size.Value.Height}," : string.Empty; - public string Text => $"-filter_complex \"[0:v] fps={_fps},{ScaleText}split [a][b];[a] palettegen=max_colors=32 [p];[b][p] paletteuse=dither=bayer\""; + public string Text => $"-filter_complex \"[{_streamIndex}:v] fps={_fps},{ScaleText}split [a][b];[a] palettegen=max_colors=32 [p];[b][p] paletteuse=dither=bayer\""; } } diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs index 635ef29..25394e2 100644 --- a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs +++ b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs @@ -76,7 +76,7 @@ public FFMpegArgumentOptions DeselectStreams(IEnumerable streamIndices, int public FFMpegArgumentOptions WithAudibleEncryptionKeys(string key, string iv) => WithArgument(new AudibleEncryptionKeyArgument(key, iv)); public FFMpegArgumentOptions WithAudibleActivationBytes(string activationBytes) => WithArgument(new AudibleEncryptionKeyArgument(activationBytes)); public FFMpegArgumentOptions WithTagVersion(int id3v2Version = 3) => WithArgument(new ID3V2VersionArgument(id3v2Version)); - public FFMpegArgumentOptions WithGifPalettArgument(Size? size, int fps = 12) => WithArgument(new GifPalettArgument(fps, size)); + public FFMpegArgumentOptions WithGifPalettArgument(int streamIndex, Size? size, int fps = 12) => WithArgument(new GifPalettArgument(streamIndex, fps, size)); public FFMpegArgumentOptions WithArgument(IArgument argument) { From d14ef2268f6b5ae9b9027d181db85dd1d08fe4ba Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Tue, 7 Mar 2023 16:31:45 +1300 Subject: [PATCH 05/15] Add "BuildGifSnapshotArguments" method --- FFMpegCore/FFMpeg/SnapshotArgumentBuilder.cs | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/FFMpegCore/FFMpeg/SnapshotArgumentBuilder.cs b/FFMpegCore/FFMpeg/SnapshotArgumentBuilder.cs index 4456837..2645867 100644 --- a/FFMpegCore/FFMpeg/SnapshotArgumentBuilder.cs +++ b/FFMpegCore/FFMpeg/SnapshotArgumentBuilder.cs @@ -31,6 +31,31 @@ public static (FFMpegArguments, Action outputOptions) Bui .Resize(size)); } + public static (FFMpegArguments, Action outputOptions) BuildGifSnapshotArguments( + string input, + IMediaAnalysis source, + Size? size = null, + TimeSpan? captureTime = null, + TimeSpan? duration = null, + int? streamIndex = null, + int fps = 12) + { + var defaultGifOutputSize = new Size(480, -1); + + captureTime ??= TimeSpan.FromSeconds(source.Duration.TotalSeconds / 3); + size = PrepareSnapshotSize(source, size) ?? defaultGifOutputSize; + streamIndex ??= source.PrimaryVideoStream?.Index + ?? source.VideoStreams.FirstOrDefault()?.Index + ?? 0; + + return (FFMpegArguments + .FromFileInput(input, false, options => options + .Seek(captureTime) + .WithDuration(duration)), + options => options + .WithGifPalettArgument((int)streamIndex, size, fps)); + } + private static Size? PrepareSnapshotSize(IMediaAnalysis source, Size? wantedSize) { if (wantedSize == null || (wantedSize.Value.Height <= 0 && wantedSize.Value.Width <= 0) || source.PrimaryVideoStream == null) From a90918eac69500f914fb171a757d82f70d20f1f9 Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Tue, 7 Mar 2023 16:41:52 +1300 Subject: [PATCH 06/15] Add "GifSnapshot" and "GifSnapshotAsync" methods --- FFMpegCore/FFMpeg/FFMpeg.cs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/FFMpegCore/FFMpeg/FFMpeg.cs b/FFMpegCore/FFMpeg/FFMpeg.cs index 362a865..6cd0cd0 100644 --- a/FFMpegCore/FFMpeg/FFMpeg.cs +++ b/FFMpegCore/FFMpeg/FFMpeg.cs @@ -57,6 +57,36 @@ public static async Task SnapshotAsync(string input, string output, Size? .ProcessAsynchronously(); } + public static bool GifSnapshot(string input, string output, Size? size = null, TimeSpan? captureTime = null, TimeSpan? duration = null, int ? streamIndex = null) + { + if (Path.GetExtension(output)?.ToLower() != FileExtension.Gif) + { + output = Path.Combine(Path.GetDirectoryName(output), Path.GetFileNameWithoutExtension(output) + FileExtension.Gif); + } + + var source = FFProbe.Analyse(input); + var (arguments, outputOptions) = SnapshotArgumentBuilder.BuildGifSnapshotArguments(input, source, size, captureTime, duration, streamIndex); + + return arguments + .OutputToFile(output, true, outputOptions) + .ProcessSynchronously(); + } + + public static async Task GifSnapshotAsync(string input, string output, Size? size = null, TimeSpan? captureTime = null, TimeSpan? duration = null, int? streamIndex = null) + { + if (Path.GetExtension(output)?.ToLower() != FileExtension.Gif) + { + output = Path.Combine(Path.GetDirectoryName(output), Path.GetFileNameWithoutExtension(output) + FileExtension.Gif); + } + + var source = await FFProbe.AnalyseAsync(input).ConfigureAwait(false); + var (arguments, outputOptions) = SnapshotArgumentBuilder.BuildGifSnapshotArguments(input, source, size, captureTime, duration, streamIndex); + + return await arguments + .OutputToFile(output, true, outputOptions) + .ProcessAsynchronously(); + } + /// /// Converts an image sequence to a video. /// From c218b3592bc9e70511d8788e6ad674b3d311efcc Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Tue, 7 Mar 2023 16:44:33 +1300 Subject: [PATCH 07/15] Add unit tests --- FFMpegCore.Test/ArgumentBuilderTest.cs | 36 ++++++++++++++- FFMpegCore.Test/VideoTest.cs | 61 +++++++++++++++++++++++++- 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/FFMpegCore.Test/ArgumentBuilderTest.cs b/FFMpegCore.Test/ArgumentBuilderTest.cs index 2c550c9..efe7f7b 100644 --- a/FFMpegCore.Test/ArgumentBuilderTest.cs +++ b/FFMpegCore.Test/ArgumentBuilderTest.cs @@ -1,4 +1,5 @@ -using FFMpegCore.Arguments; +using System.Drawing; +using FFMpegCore.Arguments; using FFMpegCore.Enums; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -537,5 +538,38 @@ public void Builder_BuildString_PadFilter_Alt() "-i \"input.mp4\" -vf \"pad=aspect=4/3:x=(ow-iw)/2:y=(oh-ih)/2:color=violet:eval=frame\" \"output.mp4\"", str); } + + [TestMethod] + public void Builder_BuildString_GifPallet() + { + var streamIndex = 0; + var size = new Size(640, 480); + + var str = FFMpegArguments + .FromFileInput("input.mp4") + .OutputToFile("output.gif", false, opt => opt + .WithGifPalettArgument(streamIndex, size)) + .Arguments; + + Assert.AreEqual($""" + -i "input.mp4" -filter_complex "[0:v] fps=12,scale=w={size.Width}:h={size.Height},split [a][b];[a] palettegen=max_colors=32 [p];[b][p] paletteuse=dither=bayer" "output.gif" + """, str); + } + + [TestMethod] + public void Builder_BuildString_GifPallet_NullSize_FpsSupplied() + { + var streamIndex = 1; + + var str = FFMpegArguments + .FromFileInput("input.mp4") + .OutputToFile("output.gif", false, opt => opt + .WithGifPalettArgument(streamIndex, null, 10)) + .Arguments; + + Assert.AreEqual($""" + -i "input.mp4" -filter_complex "[{streamIndex}:v] fps=10,split [a][b];[a] palettegen=max_colors=32 [p];[b][p] paletteuse=dither=bayer" "output.gif" + """, str); + } } } diff --git a/FFMpegCore.Test/VideoTest.cs b/FFMpegCore.Test/VideoTest.cs index 4403065..5071a48 100644 --- a/FFMpegCore.Test/VideoTest.cs +++ b/FFMpegCore.Test/VideoTest.cs @@ -1,4 +1,5 @@ -using System.Drawing.Imaging; +using System.Drawing; +using System.Drawing.Imaging; using System.Runtime.Versioning; using System.Text; using FFMpegCore.Arguments; @@ -479,6 +480,64 @@ public void Video_Snapshot_PersistSnapshot() Assert.AreEqual("png", analysis.PrimaryVideoStream!.CodecName); } + [TestMethod, Timeout(BaseTimeoutMilliseconds)] + public void Video_GifSnapshot_PersistSnapshot() + { + using var outputPath = new TemporaryFile("out.gif"); + var input = FFProbe.Analyse(TestResources.Mp4Video); + + FFMpeg.GifSnapshot(TestResources.Mp4Video, outputPath, captureTime: TimeSpan.FromSeconds(0)); + + var analysis = FFProbe.Analyse(outputPath); + Assert.AreNotEqual(input.PrimaryVideoStream!.Width, analysis.PrimaryVideoStream!.Width); + Assert.AreNotEqual(input.PrimaryVideoStream.Height, analysis.PrimaryVideoStream!.Height); + Assert.AreEqual("gif", analysis.PrimaryVideoStream!.CodecName); + } + + [TestMethod, Timeout(BaseTimeoutMilliseconds)] + public void Video_GifSnapshot_PersistSnapshot_SizeSupplied() + { + using var outputPath = new TemporaryFile("out.gif"); + var input = FFProbe.Analyse(TestResources.Mp4Video); + var desiredGifSize = new Size(320, 240); + + FFMpeg.GifSnapshot(TestResources.Mp4Video, outputPath, desiredGifSize, captureTime: TimeSpan.FromSeconds(0)); + + var analysis = FFProbe.Analyse(outputPath); + Assert.AreNotEqual(input.PrimaryVideoStream!.Width, desiredGifSize.Width); + Assert.AreNotEqual(input.PrimaryVideoStream.Height, desiredGifSize.Height); + Assert.AreEqual("gif", analysis.PrimaryVideoStream!.CodecName); + } + + [TestMethod, Timeout(BaseTimeoutMilliseconds)] + public async Task Video_GifSnapshot_PersistSnapshotAsync() + { + using var outputPath = new TemporaryFile("out.gif"); + var input = FFProbe.Analyse(TestResources.Mp4Video); + + await FFMpeg.GifSnapshotAsync(TestResources.Mp4Video, outputPath, captureTime: TimeSpan.FromSeconds(0)); + + var analysis = FFProbe.Analyse(outputPath); + Assert.AreNotEqual(input.PrimaryVideoStream!.Width, analysis.PrimaryVideoStream!.Width); + Assert.AreNotEqual(input.PrimaryVideoStream.Height, analysis.PrimaryVideoStream!.Height); + Assert.AreEqual("gif", analysis.PrimaryVideoStream!.CodecName); + } + + [TestMethod, Timeout(BaseTimeoutMilliseconds)] + public async Task Video_GifSnapshot_PersistSnapshotAsync_SizeSupplied() + { + using var outputPath = new TemporaryFile("out.gif"); + var input = FFProbe.Analyse(TestResources.Mp4Video); + var desiredGifSize = new Size(320, 240); + + await FFMpeg.GifSnapshotAsync(TestResources.Mp4Video, outputPath, desiredGifSize, captureTime: TimeSpan.FromSeconds(0)); + + var analysis = FFProbe.Analyse(outputPath); + Assert.AreNotEqual(input.PrimaryVideoStream!.Width, desiredGifSize.Width); + Assert.AreNotEqual(input.PrimaryVideoStream.Height, desiredGifSize.Height); + Assert.AreEqual("gif", analysis.PrimaryVideoStream!.CodecName); + } + [TestMethod, Timeout(BaseTimeoutMilliseconds)] public void Video_Join() { From 62a9ed628185b2d7a0ab9dc32e61fa5784b2ef6f Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Tue, 7 Mar 2023 16:49:18 +1300 Subject: [PATCH 08/15] Update README to add information about GIF Snapshots --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index d2a9633..365d0be 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,17 @@ var bitmap = FFMpeg.Snapshot(inputPath, new Size(200, 400), TimeSpan.FromMinutes FFMpeg.Snapshot(inputPath, outputPath, new Size(200, 400), TimeSpan.FromMinutes(1)); ``` +### You can also capture GIF snapshots from a video file: +```csharp +FFMpeg.GifSnapshot(inputPath, outputPath, new Size(200, 400), TimeSpan.FromSeconds(10)); + +// or async +await FFMpeg.GifSnapshotAsync(inputPath, outputPath, new Size(200, 400), TimeSpan.FromSeconds(10)); + +// you can also supply -1 to either one of Width/Height Size properties if you'd like FFMPEG to resize while maintaining the aspect ratio +await FFMpeg.GifSnapshotAsync(inputPath, outputPath, new Size(480, -1), TimeSpan.FromSeconds(10)); +``` + ### Join video parts into one single file: ```csharp FFMpeg.Join(@"..\joined_video.mp4", From 7569669f526baafcc0f23421d917d60376156231 Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Tue, 7 Mar 2023 16:55:11 +1300 Subject: [PATCH 09/15] Fix Palette typos --- FFMpegCore.Test/ArgumentBuilderTest.cs | 8 ++++---- .../{GifPalettArgument.cs => GifPaletteArgument.cs} | 4 ++-- FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs | 2 +- FFMpegCore/FFMpeg/SnapshotArgumentBuilder.cs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) rename FFMpegCore/FFMpeg/Arguments/{GifPalettArgument.cs => GifPaletteArgument.cs} (83%) diff --git a/FFMpegCore.Test/ArgumentBuilderTest.cs b/FFMpegCore.Test/ArgumentBuilderTest.cs index efe7f7b..30adabd 100644 --- a/FFMpegCore.Test/ArgumentBuilderTest.cs +++ b/FFMpegCore.Test/ArgumentBuilderTest.cs @@ -540,7 +540,7 @@ public void Builder_BuildString_PadFilter_Alt() } [TestMethod] - public void Builder_BuildString_GifPallet() + public void Builder_BuildString_GifPalette() { var streamIndex = 0; var size = new Size(640, 480); @@ -548,7 +548,7 @@ public void Builder_BuildString_GifPallet() var str = FFMpegArguments .FromFileInput("input.mp4") .OutputToFile("output.gif", false, opt => opt - .WithGifPalettArgument(streamIndex, size)) + .WithGifPaletteArgument(streamIndex, size)) .Arguments; Assert.AreEqual($""" @@ -557,14 +557,14 @@ public void Builder_BuildString_GifPallet() } [TestMethod] - public void Builder_BuildString_GifPallet_NullSize_FpsSupplied() + public void Builder_BuildString_GifPalette_NullSize_FpsSupplied() { var streamIndex = 1; var str = FFMpegArguments .FromFileInput("input.mp4") .OutputToFile("output.gif", false, opt => opt - .WithGifPalettArgument(streamIndex, null, 10)) + .WithGifPaletteArgument(streamIndex, null, 10)) .Arguments; Assert.AreEqual($""" diff --git a/FFMpegCore/FFMpeg/Arguments/GifPalettArgument.cs b/FFMpegCore/FFMpeg/Arguments/GifPaletteArgument.cs similarity index 83% rename from FFMpegCore/FFMpeg/Arguments/GifPalettArgument.cs rename to FFMpegCore/FFMpeg/Arguments/GifPaletteArgument.cs index 9c95045..ac67fcd 100644 --- a/FFMpegCore/FFMpeg/Arguments/GifPalettArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/GifPaletteArgument.cs @@ -2,7 +2,7 @@ namespace FFMpegCore.Arguments { - public class GifPalettArgument : IArgument + public class GifPaletteArgument : IArgument { private readonly int _streamIndex; @@ -10,7 +10,7 @@ public class GifPalettArgument : IArgument private readonly Size? _size; - public GifPalettArgument(int streamIndex, int fps, Size? size) + public GifPaletteArgument(int streamIndex, int fps, Size? size) { _streamIndex = streamIndex; _fps = fps; diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs index 25394e2..4930b52 100644 --- a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs +++ b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs @@ -76,7 +76,7 @@ public FFMpegArgumentOptions DeselectStreams(IEnumerable streamIndices, int public FFMpegArgumentOptions WithAudibleEncryptionKeys(string key, string iv) => WithArgument(new AudibleEncryptionKeyArgument(key, iv)); public FFMpegArgumentOptions WithAudibleActivationBytes(string activationBytes) => WithArgument(new AudibleEncryptionKeyArgument(activationBytes)); public FFMpegArgumentOptions WithTagVersion(int id3v2Version = 3) => WithArgument(new ID3V2VersionArgument(id3v2Version)); - public FFMpegArgumentOptions WithGifPalettArgument(int streamIndex, Size? size, int fps = 12) => WithArgument(new GifPalettArgument(streamIndex, fps, size)); + public FFMpegArgumentOptions WithGifPaletteArgument(int streamIndex, Size? size, int fps = 12) => WithArgument(new GifPaletteArgument(streamIndex, fps, size)); public FFMpegArgumentOptions WithArgument(IArgument argument) { diff --git a/FFMpegCore/FFMpeg/SnapshotArgumentBuilder.cs b/FFMpegCore/FFMpeg/SnapshotArgumentBuilder.cs index 2645867..0d9b414 100644 --- a/FFMpegCore/FFMpeg/SnapshotArgumentBuilder.cs +++ b/FFMpegCore/FFMpeg/SnapshotArgumentBuilder.cs @@ -53,7 +53,7 @@ public static (FFMpegArguments, Action outputOptions) Bui .Seek(captureTime) .WithDuration(duration)), options => options - .WithGifPalettArgument((int)streamIndex, size, fps)); + .WithGifPaletteArgument((int)streamIndex, size, fps)); } private static Size? PrepareSnapshotSize(IMediaAnalysis source, Size? wantedSize) From 3dc2fff0ac8c67567ab5e12cfba2822ac9fbbaf6 Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Tue, 7 Mar 2023 17:04:23 +1300 Subject: [PATCH 10/15] Fix whitespace formatting linting error --- FFMpegCore/FFMpeg/FFMpeg.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FFMpegCore/FFMpeg/FFMpeg.cs b/FFMpegCore/FFMpeg/FFMpeg.cs index 6cd0cd0..a8de12b 100644 --- a/FFMpegCore/FFMpeg/FFMpeg.cs +++ b/FFMpegCore/FFMpeg/FFMpeg.cs @@ -57,7 +57,7 @@ public static async Task SnapshotAsync(string input, string output, Size? .ProcessAsynchronously(); } - public static bool GifSnapshot(string input, string output, Size? size = null, TimeSpan? captureTime = null, TimeSpan? duration = null, int ? streamIndex = null) + public static bool GifSnapshot(string input, string output, Size? size = null, TimeSpan? captureTime = null, TimeSpan? duration = null, int? streamIndex = null) { if (Path.GetExtension(output)?.ToLower() != FileExtension.Gif) { From 943662aa15e8cf73dce0b1a8b93ffe8e8bae274b Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Wed, 15 Mar 2023 13:26:11 +0100 Subject: [PATCH 11/15] Bump nuget version --- FFMpegCore/FFMpegCore.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FFMpegCore/FFMpegCore.csproj b/FFMpegCore/FFMpegCore.csproj index db5abd1..2af7f16 100644 --- a/FFMpegCore/FFMpegCore.csproj +++ b/FFMpegCore/FFMpegCore.csproj @@ -3,7 +3,7 @@ true A .NET Standard FFMpeg/FFProbe wrapper for easily integrating media analysis and conversion into your .NET applications - 5.0.2 + 5.1.0 ../nupkg From d9c4595eec61adeed497c4799aa3cbd89a2c0c47 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Fri, 21 Apr 2023 11:07:56 +0800 Subject: [PATCH 12/15] fix: readme minor mistakes. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 365d0be..33f7ddf 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ FFMpeg.Join(@"..\joined_video.mp4", ``` csharp FFMpeg.SubVideo(inputPath, outputPath, - TimeSpan.FromSeconds(0) + TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(30) ); ``` From 69b01c91c61cf1878ca5f5e99b3056266a456adb Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Wed, 17 May 2023 11:40:20 +1200 Subject: [PATCH 13/15] Add CopyCodecArgument --- FFMpegCore/FFMpeg/Arguments/CopyCodecArgument.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 FFMpegCore/FFMpeg/Arguments/CopyCodecArgument.cs diff --git a/FFMpegCore/FFMpeg/Arguments/CopyCodecArgument.cs b/FFMpegCore/FFMpeg/Arguments/CopyCodecArgument.cs new file mode 100644 index 0000000..8ea3484 --- /dev/null +++ b/FFMpegCore/FFMpeg/Arguments/CopyCodecArgument.cs @@ -0,0 +1,10 @@ +namespace FFMpegCore.Arguments +{ + /// + /// Represents a copy codec parameter + /// + public class CopyCodecArgument : IArgument + { + public string Text => $"-codec copy"; + } +} From 643952db7bf11e611e7e50c786fc105813fa02e3 Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Wed, 17 May 2023 11:40:40 +1200 Subject: [PATCH 14/15] Add "WithCopyCodec" option --- FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs index 4930b52..6a6586c 100644 --- a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs +++ b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs @@ -77,6 +77,7 @@ public FFMpegArgumentOptions DeselectStreams(IEnumerable streamIndices, int public FFMpegArgumentOptions WithAudibleActivationBytes(string activationBytes) => WithArgument(new AudibleEncryptionKeyArgument(activationBytes)); public FFMpegArgumentOptions WithTagVersion(int id3v2Version = 3) => WithArgument(new ID3V2VersionArgument(id3v2Version)); public FFMpegArgumentOptions WithGifPaletteArgument(int streamIndex, Size? size, int fps = 12) => WithArgument(new GifPaletteArgument(streamIndex, fps, size)); + public FFMpegArgumentOptions WithCopyCodec() => WithArgument(new CopyCodecArgument()); public FFMpegArgumentOptions WithArgument(IArgument argument) { From 6c2311c86904a87339dc542160ae6b5ece18b24c Mon Sep 17 00:00:00 2001 From: Rafael Carvalho Date: Wed, 17 May 2023 11:41:13 +1200 Subject: [PATCH 15/15] Update "SaveM3U8Stream" method to use "WithCopyCodec" option --- FFMpegCore/FFMpeg/FFMpeg.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/FFMpegCore/FFMpeg/FFMpeg.cs b/FFMpegCore/FFMpeg/FFMpeg.cs index a8de12b..820d9fb 100644 --- a/FFMpegCore/FFMpeg/FFMpeg.cs +++ b/FFMpegCore/FFMpeg/FFMpeg.cs @@ -333,7 +333,10 @@ public static bool SaveM3U8Stream(Uri uri, string output) } return FFMpegArguments - .FromUrlInput(uri) + .FromUrlInput(uri, options => + { + options.WithCopyCodec(); + }) .OutputToFile(output) .ProcessSynchronously(); }