From 638f4cae8999add55283ec2ff4bc9431cb0a96f8 Mon Sep 17 00:00:00 2001 From: Sky Z Date: Thu, 14 Jul 2022 01:28:51 -0400 Subject: [PATCH 1/4] Add select multiple streams Former-commit-id: df40eeede911ba5114fcf21c9860dd4562aeda76 --- FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs index 7b3da7a..171264e 100644 --- a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs +++ b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs @@ -1,6 +1,7 @@ using System; +using System.Collections.Generic; using System.Drawing; - +using System.Linq; using FFMpegCore.Arguments; using FFMpegCore.Enums; @@ -61,6 +62,8 @@ public FFMpegArgumentOptions WithAudioFilters(Action audioFi public FFMpegArgumentOptions Loop(int times) => WithArgument(new LoopArgument(times)); public FFMpegArgumentOptions OverwriteExisting() => WithArgument(new OverwriteArgument()); public FFMpegArgumentOptions SelectStream(int streamIndex, int inputFileIndex = 0) => WithArgument(new MapStreamArgument(streamIndex, inputFileIndex)); + public FFMpegArgumentOptions SelectStreams(IEnumerable streamIndices, int inputFileIndex = 0) => + streamIndices.Aggregate(this, (options, streamIndex) => options.SelectStream(streamIndex, inputFileIndex)); public FFMpegArgumentOptions ForceFormat(ContainerFormat format) => WithArgument(new ForceFormatArgument(format)); public FFMpegArgumentOptions ForceFormat(string format) => WithArgument(new ForceFormatArgument(format)); From a776db85d2662b936f139616eae51f5df1ceb046 Mon Sep 17 00:00:00 2001 From: Sky Z Date: Thu, 14 Jul 2022 02:23:38 -0400 Subject: [PATCH 2/4] Add other stream types to Channel (V,s,d,t) Former-commit-id: ca8275436b82d3335724c260a2660d09d8633071 --- FFMpegCore/FFMpeg/Arguments/CopyArgument.cs | 5 ++- .../FFMpeg/Arguments/MapStreamArgument.cs | 17 ++++++--- FFMpegCore/FFMpeg/Enums/Enums.cs | 35 ++++++++++++++++++- FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs | 7 ++-- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/FFMpegCore/FFMpeg/Arguments/CopyArgument.cs b/FFMpegCore/FFMpeg/Arguments/CopyArgument.cs index 91419d5..eeac4c8 100644 --- a/FFMpegCore/FFMpeg/Arguments/CopyArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/CopyArgument.cs @@ -16,9 +16,8 @@ public CopyArgument(Channel channel = Channel.Both) public string Text => Channel switch { - Channel.Audio => "-c:a copy", - Channel.Video => "-c:v copy", - _ => "-c copy" + Channel.Both => "-c:a copy -c:v copy", + _ => $"-c{Channel.StreamType()} copy" }; } } diff --git a/FFMpegCore/FFMpeg/Arguments/MapStreamArgument.cs b/FFMpegCore/FFMpeg/Arguments/MapStreamArgument.cs index b904be5..66087b6 100644 --- a/FFMpegCore/FFMpeg/Arguments/MapStreamArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/MapStreamArgument.cs @@ -1,19 +1,28 @@ -namespace FFMpegCore.Arguments +using FFMpegCore.Enums; + +namespace FFMpegCore.Arguments { /// - /// Represents choice of video stream + /// Represents choice of stream by the stream specifier /// public class MapStreamArgument : IArgument { private readonly int _inputFileIndex; private readonly int _streamIndex; + private readonly Channel _channel; - public MapStreamArgument(int streamIndex, int inputFileIndex) + public MapStreamArgument(int streamIndex, int inputFileIndex, Channel channel = Channel.All) { + if (channel == Channel.Both) + { + // "Both" is not valid in this case and probably means all stream types + channel = Channel.All; + } _inputFileIndex = inputFileIndex; _streamIndex = streamIndex; + _channel = channel; } - public string Text => $"-map {_inputFileIndex}:{_streamIndex}"; + public string Text => $"-map {_inputFileIndex}{_channel.StreamType()}:{_streamIndex}"; } } \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/Enums/Enums.cs b/FFMpegCore/FFMpeg/Enums/Enums.cs index 7520fea..a6eb413 100644 --- a/FFMpegCore/FFMpeg/Enums/Enums.cs +++ b/FFMpegCore/FFMpeg/Enums/Enums.cs @@ -46,10 +46,43 @@ public enum Filter Aac_AdtstoAsc } + /// + /// https://ffmpeg.org/ffmpeg.html#Stream-specifiers-1 + /// ’v’ or ’V’ for video, ’a’ for audio, ’s’ for subtitle, ’d’ for data, and ’t’ for attachments + /// ’V’ only matches video streams which are not attached pictures, video thumbnails or cover arts. + /// Both for audio + video + /// All for all types + /// public enum Channel { Audio, Video, - Both + Both, + VideoNoAttachedPic, + Subtitle, + Data, + Attachments, + All } + internal static class ChannelMethods + { + /// + /// is left as empty because it cannot be in a single stream specifier + /// + /// The stream_type used in stream specifiers + public static string StreamType(this Channel channel) + { + return channel switch + { + Channel.Audio => ":a", + Channel.Video => ":v", + Channel.VideoNoAttachedPic => ":V", + Channel.Subtitle => ":s", + Channel.Data => ":d", + Channel.Attachments => ":t", + _ => string.Empty + }; + } + } + } \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs index 171264e..a84c86e 100644 --- a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs +++ b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs @@ -61,9 +61,10 @@ public FFMpegArgumentOptions WithAudioFilters(Action audioFi public FFMpegArgumentOptions Seek(TimeSpan? seekTo) => WithArgument(new SeekArgument(seekTo)); public FFMpegArgumentOptions Loop(int times) => WithArgument(new LoopArgument(times)); public FFMpegArgumentOptions OverwriteExisting() => WithArgument(new OverwriteArgument()); - public FFMpegArgumentOptions SelectStream(int streamIndex, int inputFileIndex = 0) => WithArgument(new MapStreamArgument(streamIndex, inputFileIndex)); - public FFMpegArgumentOptions SelectStreams(IEnumerable streamIndices, int inputFileIndex = 0) => - streamIndices.Aggregate(this, (options, streamIndex) => options.SelectStream(streamIndex, inputFileIndex)); + public FFMpegArgumentOptions SelectStream(int streamIndex, int inputFileIndex = 0, + Channel channel = Channel.All) => WithArgument(new MapStreamArgument(streamIndex, inputFileIndex, channel)); + public FFMpegArgumentOptions SelectStreams(IEnumerable streamIndices, int inputFileIndex = 0, Channel channel = Channel.All) => + streamIndices.Aggregate(this, (options, streamIndex) => options.SelectStream(streamIndex, inputFileIndex, channel)); public FFMpegArgumentOptions ForceFormat(ContainerFormat format) => WithArgument(new ForceFormatArgument(format)); public FFMpegArgumentOptions ForceFormat(string format) => WithArgument(new ForceFormatArgument(format)); From f1e13326b8e4f542e93ec745f746e934fb6e8448 Mon Sep 17 00:00:00 2001 From: Sky Z Date: Thu, 14 Jul 2022 02:34:34 -0400 Subject: [PATCH 3/4] Add negative mapping to select stream (deselect) Former-commit-id: 40f97594f0c2792ae327c1e07f3e86b7ca59eb3b --- FFMpegCore/FFMpeg/Arguments/MapStreamArgument.cs | 6 ++++-- FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs | 10 ++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/FFMpegCore/FFMpeg/Arguments/MapStreamArgument.cs b/FFMpegCore/FFMpeg/Arguments/MapStreamArgument.cs index 66087b6..a9813c7 100644 --- a/FFMpegCore/FFMpeg/Arguments/MapStreamArgument.cs +++ b/FFMpegCore/FFMpeg/Arguments/MapStreamArgument.cs @@ -10,8 +10,9 @@ public class MapStreamArgument : IArgument private readonly int _inputFileIndex; private readonly int _streamIndex; private readonly Channel _channel; + private readonly bool _negativeMap; - public MapStreamArgument(int streamIndex, int inputFileIndex, Channel channel = Channel.All) + public MapStreamArgument(int streamIndex, int inputFileIndex, Channel channel = Channel.All, bool negativeMap = false) { if (channel == Channel.Both) { @@ -21,8 +22,9 @@ public MapStreamArgument(int streamIndex, int inputFileIndex, Channel channel = _inputFileIndex = inputFileIndex; _streamIndex = streamIndex; _channel = channel; + _negativeMap = negativeMap; } - public string Text => $"-map {_inputFileIndex}{_channel.StreamType()}:{_streamIndex}"; + public string Text => $"-map {(_negativeMap?"-":"")}{_inputFileIndex}{_channel.StreamType()}:{_streamIndex}"; } } \ No newline at end of file diff --git a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs index a84c86e..1ff892a 100644 --- a/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs +++ b/FFMpegCore/FFMpeg/FFMpegArgumentOptions.cs @@ -63,8 +63,14 @@ public FFMpegArgumentOptions WithAudioFilters(Action audioFi public FFMpegArgumentOptions OverwriteExisting() => WithArgument(new OverwriteArgument()); public FFMpegArgumentOptions SelectStream(int streamIndex, int inputFileIndex = 0, Channel channel = Channel.All) => WithArgument(new MapStreamArgument(streamIndex, inputFileIndex, channel)); - public FFMpegArgumentOptions SelectStreams(IEnumerable streamIndices, int inputFileIndex = 0, Channel channel = Channel.All) => - streamIndices.Aggregate(this, (options, streamIndex) => options.SelectStream(streamIndex, inputFileIndex, channel)); + public FFMpegArgumentOptions SelectStreams(IEnumerable streamIndices, int inputFileIndex = 0, + Channel channel = Channel.All) => streamIndices.Aggregate(this, + (options, streamIndex) => options.SelectStream(streamIndex, inputFileIndex, channel)); + public FFMpegArgumentOptions DeselectStream(int streamIndex, int inputFileIndex = 0, + Channel channel = Channel.All) => WithArgument(new MapStreamArgument(streamIndex, inputFileIndex, channel, true)); + public FFMpegArgumentOptions DeselectStreams(IEnumerable streamIndices, int inputFileIndex = 0, + Channel channel = Channel.All) => streamIndices.Aggregate(this, + (options, streamIndex) => options.DeselectStream(streamIndex, inputFileIndex, channel)); public FFMpegArgumentOptions ForceFormat(ContainerFormat format) => WithArgument(new ForceFormatArgument(format)); public FFMpegArgumentOptions ForceFormat(string format) => WithArgument(new ForceFormatArgument(format)); From f03ed8ab54951a83bc1d8772e0a6bd950fa17e55 Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Tue, 31 Jan 2023 20:49:56 +0100 Subject: [PATCH 4/4] Update test Former-commit-id: 5510ef0e32c1a87fda29af580e009b39ab9a2005 --- FFMpegCore.Test/ArgumentBuilderTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FFMpegCore.Test/ArgumentBuilderTest.cs b/FFMpegCore.Test/ArgumentBuilderTest.cs index 9cf7e39..906a87b 100644 --- a/FFMpegCore.Test/ArgumentBuilderTest.cs +++ b/FFMpegCore.Test/ArgumentBuilderTest.cs @@ -114,7 +114,7 @@ public void Builder_BuildString_Copy_Both() { var str = FFMpegArguments.FromFileInput("input.mp4") .OutputToFile("output.mp4", false, opt => opt.CopyChannel()).Arguments; - Assert.AreEqual("-i \"input.mp4\" -c copy \"output.mp4\"", str); + Assert.AreEqual("-i \"input.mp4\" -c:a copy -c:v copy \"output.mp4\"", str); } [TestMethod]