mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2024-11-10 08:34:12 +01:00
Merge pull request #347 from qe201020335/master
Add Stream mapping of multiple streams and negative mapping of streams (deselect)
This commit is contained in:
commit
1ad13e069a
5 changed files with 64 additions and 11 deletions
|
@ -114,7 +114,7 @@ public void Builder_BuildString_Copy_Both()
|
||||||
{
|
{
|
||||||
var str = FFMpegArguments.FromFileInput("input.mp4")
|
var str = FFMpegArguments.FromFileInput("input.mp4")
|
||||||
.OutputToFile("output.mp4", false, opt => opt.CopyChannel()).Arguments;
|
.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]
|
[TestMethod]
|
||||||
|
|
|
@ -16,9 +16,8 @@ public CopyArgument(Channel channel = Channel.Both)
|
||||||
|
|
||||||
public string Text => Channel switch
|
public string Text => Channel switch
|
||||||
{
|
{
|
||||||
Channel.Audio => "-c:a copy",
|
Channel.Both => "-c:a copy -c:v copy",
|
||||||
Channel.Video => "-c:v copy",
|
_ => $"-c{Channel.StreamType()} copy"
|
||||||
_ => "-c copy"
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,30 @@
|
||||||
namespace FFMpegCore.Arguments
|
using FFMpegCore.Enums;
|
||||||
|
|
||||||
|
namespace FFMpegCore.Arguments
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents choice of video stream
|
/// Represents choice of stream by the stream specifier
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MapStreamArgument : IArgument
|
public class MapStreamArgument : IArgument
|
||||||
{
|
{
|
||||||
private readonly int _inputFileIndex;
|
private readonly int _inputFileIndex;
|
||||||
private readonly int _streamIndex;
|
private readonly int _streamIndex;
|
||||||
|
private readonly Channel _channel;
|
||||||
|
private readonly bool _negativeMap;
|
||||||
|
|
||||||
public MapStreamArgument(int streamIndex, int inputFileIndex)
|
public MapStreamArgument(int streamIndex, int inputFileIndex, Channel channel = Channel.All, bool negativeMap = false)
|
||||||
{
|
{
|
||||||
|
if (channel == Channel.Both)
|
||||||
|
{
|
||||||
|
// "Both" is not valid in this case and probably means all stream types
|
||||||
|
channel = Channel.All;
|
||||||
|
}
|
||||||
_inputFileIndex = inputFileIndex;
|
_inputFileIndex = inputFileIndex;
|
||||||
_streamIndex = streamIndex;
|
_streamIndex = streamIndex;
|
||||||
|
_channel = channel;
|
||||||
|
_negativeMap = negativeMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Text => $"-map {_inputFileIndex}:{_streamIndex}";
|
public string Text => $"-map {(_negativeMap?"-":"")}{_inputFileIndex}{_channel.StreamType()}:{_streamIndex}";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -46,10 +46,43 @@ public enum Filter
|
||||||
Aac_AdtstoAsc
|
Aac_AdtstoAsc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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
|
||||||
|
/// </summary>
|
||||||
public enum Channel
|
public enum Channel
|
||||||
{
|
{
|
||||||
Audio,
|
Audio,
|
||||||
Video,
|
Video,
|
||||||
Both
|
Both,
|
||||||
|
VideoNoAttachedPic,
|
||||||
|
Subtitle,
|
||||||
|
Data,
|
||||||
|
Attachments,
|
||||||
|
All
|
||||||
|
}
|
||||||
|
internal static class ChannelMethods
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// <see cref="Channel.Both"/> is left as empty because it cannot be in a single stream specifier
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The stream_type used in stream specifiers</returns>
|
||||||
|
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
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
using FFMpegCore.Arguments;
|
using FFMpegCore.Arguments;
|
||||||
using FFMpegCore.Enums;
|
using FFMpegCore.Enums;
|
||||||
|
|
||||||
|
@ -60,7 +61,16 @@ public FFMpegArgumentOptions WithAudioFilters(Action<AudioFilterOptions> audioFi
|
||||||
public FFMpegArgumentOptions Seek(TimeSpan? seekTo) => WithArgument(new SeekArgument(seekTo));
|
public FFMpegArgumentOptions Seek(TimeSpan? seekTo) => WithArgument(new SeekArgument(seekTo));
|
||||||
public FFMpegArgumentOptions Loop(int times) => WithArgument(new LoopArgument(times));
|
public FFMpegArgumentOptions Loop(int times) => WithArgument(new LoopArgument(times));
|
||||||
public FFMpegArgumentOptions OverwriteExisting() => WithArgument(new OverwriteArgument());
|
public FFMpegArgumentOptions OverwriteExisting() => WithArgument(new OverwriteArgument());
|
||||||
public FFMpegArgumentOptions SelectStream(int streamIndex, int inputFileIndex = 0) => WithArgument(new MapStreamArgument(streamIndex, inputFileIndex));
|
public FFMpegArgumentOptions SelectStream(int streamIndex, int inputFileIndex = 0,
|
||||||
|
Channel channel = Channel.All) => WithArgument(new MapStreamArgument(streamIndex, inputFileIndex, channel));
|
||||||
|
public FFMpegArgumentOptions SelectStreams(IEnumerable<int> 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<int> 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(ContainerFormat format) => WithArgument(new ForceFormatArgument(format));
|
||||||
public FFMpegArgumentOptions ForceFormat(string format) => WithArgument(new ForceFormatArgument(format));
|
public FFMpegArgumentOptions ForceFormat(string format) => WithArgument(new ForceFormatArgument(format));
|
||||||
|
|
Loading…
Reference in a new issue