mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2024-11-10 08:34:12 +01:00
FFMpegCore: use the argument builder in the ffmpeg methods
Former-commit-id: 3729d65e24
This commit is contained in:
parent
9b855736ab
commit
b0c2a7ea92
10 changed files with 158 additions and 192 deletions
|
@ -25,13 +25,12 @@ public ArgumentBuilderTests() : base()
|
||||||
private string GetArgumentsString(params Argument[] args)
|
private string GetArgumentsString(params Argument[] args)
|
||||||
{
|
{
|
||||||
var container = new ArgumentsContainer();
|
var container = new ArgumentsContainer();
|
||||||
container.Add(new OutputArgument("output.mp4"));
|
|
||||||
container.Add(new InputArgument("input.mp4"));
|
container.Add(new InputArgument("input.mp4"));
|
||||||
|
|
||||||
foreach (var a in args)
|
foreach (var a in args)
|
||||||
{
|
{
|
||||||
container.Add(a);
|
container.Add(a);
|
||||||
}
|
}
|
||||||
|
container.Add(new OutputArgument("output.mp4"));
|
||||||
|
|
||||||
return builder.BuildArguments(container);
|
return builder.BuildArguments(container);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +41,7 @@ public void Builder_BuildString_IO_1()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString();
|
var str = GetArgumentsString();
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -50,15 +49,14 @@ public void Builder_BuildString_Scale()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new ScaleArgument(VideoSize.Hd));
|
var str = GetArgumentsString(new ScaleArgument(VideoSize.Hd));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -vf scale=-1:720 \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -vf scale=-1:720 \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Builder_BuildString_AudioCodec()
|
public void Builder_BuildString_AudioCodec()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new AudioCodecArgument(AudioCodec.Aac, AudioQuality.Normal));
|
var str = GetArgumentsString(new AudioCodecArgument(AudioCodec.Aac, AudioQuality.Normal));
|
||||||
|
Assert.AreEqual(str, "-i \"input.mp4\" -codec:a aac -b:a 128k -strict experimental \"output.mp4\"");
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -codec:a aac -b:a 128k -strict experimental \"output.mp4\"");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -66,20 +64,20 @@ public void Builder_BuildString_BitStream()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new BitStreamFilterArgument(Channel.Audio, Filter.H264_Mp4ToAnnexB));
|
var str = GetArgumentsString(new BitStreamFilterArgument(Channel.Audio, Filter.H264_Mp4ToAnnexB));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -bsf:a h264_mp4toannexb \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -bsf:a h264_mp4toannexb \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Builder_BuildString_Concat()
|
public void Builder_BuildString_Concat()
|
||||||
{
|
{
|
||||||
var container = new ArgumentsContainer();
|
var container = new ArgumentsContainer();
|
||||||
container.Add(new OutputArgument("output.mp4"));
|
|
||||||
|
|
||||||
container.Add(new ConcatArgument(concatFiles));
|
container.Add(new ConcatArgument(concatFiles));
|
||||||
|
container.Add(new OutputArgument("output.mp4"));
|
||||||
|
|
||||||
var str = builder.BuildArguments(container);
|
var str = builder.BuildArguments(container);
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"concat:1.mp4|2.mp4|3.mp4|4.mp4\" \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"concat:1.mp4|2.mp4|3.mp4|4.mp4\" \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -87,7 +85,7 @@ public void Builder_BuildString_Copy_Audio()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new CopyArgument(Channel.Audio));
|
var str = GetArgumentsString(new CopyArgument(Channel.Audio));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -c:a copy \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -c:a copy \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,7 +94,7 @@ public void Builder_BuildString_Copy_Video()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new CopyArgument(Channel.Video));
|
var str = GetArgumentsString(new CopyArgument(Channel.Video));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -c:v copy \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -c:v copy \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -104,7 +102,7 @@ public void Builder_BuildString_Copy_Both()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new CopyArgument(Channel.Both));
|
var str = GetArgumentsString(new CopyArgument(Channel.Both));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -c copy \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -c copy \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -112,7 +110,7 @@ public void Builder_BuildString_CpuSpeed()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new CpuSpeedArgument(10));
|
var str = GetArgumentsString(new CpuSpeedArgument(10));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -quality good -cpu-used 10 -deadline realtime \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -quality good -cpu-used 10 -deadline realtime \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -120,7 +118,7 @@ public void Builder_BuildString_ForceFormat()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new ForceFormatArgument(VideoCodec.LibX264));
|
var str = GetArgumentsString(new ForceFormatArgument(VideoCodec.LibX264));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -f libx264 \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -f libx264 \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -128,7 +126,7 @@ public void Builder_BuildString_FrameOutputCount()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new FrameOutputCountArgument(50));
|
var str = GetArgumentsString(new FrameOutputCountArgument(50));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -vframes 50 \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -vframes 50 \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -136,7 +134,7 @@ public void Builder_BuildString_FrameRate()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new FrameRateArgument(50));
|
var str = GetArgumentsString(new FrameRateArgument(50));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -r 50 \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -r 50 \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -144,7 +142,7 @@ public void Builder_BuildString_Loop()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new LoopArgument(50));
|
var str = GetArgumentsString(new LoopArgument(50));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -loop 50 \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -loop 50 \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -152,7 +150,7 @@ public void Builder_BuildString_Seek()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new SeekArgument(TimeSpan.FromSeconds(10)));
|
var str = GetArgumentsString(new SeekArgument(TimeSpan.FromSeconds(10)));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -ss 00:00:10 \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -ss 00:00:10 \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -160,7 +158,7 @@ public void Builder_BuildString_Shortest()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new ShortestArgument(true));
|
var str = GetArgumentsString(new ShortestArgument(true));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -shortest \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -shortest \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -168,7 +166,7 @@ public void Builder_BuildString_Size()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new SizeArgument(1920, 1080));
|
var str = GetArgumentsString(new SizeArgument(1920, 1080));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -s 1920x1080 \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -s 1920x1080 \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -176,7 +174,7 @@ public void Builder_BuildString_Speed()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new SpeedArgument(Speed.Fast));
|
var str = GetArgumentsString(new SpeedArgument(Speed.Fast));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -preset fast \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -preset fast \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -184,7 +182,7 @@ public void Builder_BuildString_StartNumber()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new StartNumberArgument(50));
|
var str = GetArgumentsString(new StartNumberArgument(50));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -start_number 50 \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -start_number 50 \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -192,7 +190,7 @@ public void Builder_BuildString_Threads_1()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new ThreadsArgument(50));
|
var str = GetArgumentsString(new ThreadsArgument(50));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -threads 50 \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -threads 50 \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -200,7 +198,7 @@ public void Builder_BuildString_Threads_2()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new ThreadsArgument(true));
|
var str = GetArgumentsString(new ThreadsArgument(true));
|
||||||
|
|
||||||
Assert.IsTrue(str == $"-i \"input.mp4\" -threads {Environment.ProcessorCount} \"output.mp4\"");
|
Assert.AreEqual(str, $"-i \"input.mp4\" -threads {Environment.ProcessorCount} \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -209,7 +207,7 @@ public void Builder_BuildString_Codec()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new VideoCodecArgument(VideoCodec.LibX264));
|
var str = GetArgumentsString(new VideoCodecArgument(VideoCodec.LibX264));
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -codec:v libx264 -pix_fmt yuv420p \"output.mp4\"");
|
Assert.AreEqual(str, "-i \"input.mp4\" -codec:v libx264 -pix_fmt yuv420p \"output.mp4\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -217,7 +215,7 @@ public void Builder_BuildString_Codec_Override()
|
||||||
{
|
{
|
||||||
var str = GetArgumentsString(new VideoCodecArgument(VideoCodec.LibX264), new OverrideArgument());
|
var str = GetArgumentsString(new VideoCodecArgument(VideoCodec.LibX264), new OverrideArgument());
|
||||||
|
|
||||||
Assert.IsTrue(str == "-i \"input.mp4\" -codec:v libx264 -pix_fmt yuv420p \"output.mp4\" -y");
|
Assert.AreEqual(str, "-i \"input.mp4\" -codec:v libx264 -pix_fmt yuv420p -y \"output.mp4\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,11 +69,17 @@ public void Convert(VideoType type, ArgumentsContainer container)
|
||||||
{
|
{
|
||||||
var input = VideoInfo.FromFileInfo(Input);
|
var input = VideoInfo.FromFileInfo(Input);
|
||||||
|
|
||||||
container.Add(new InputArgument(input));
|
var arguments = new ArgumentsContainer();
|
||||||
container.Add(new OutputArgument(output));
|
arguments.Add(new InputArgument(input));
|
||||||
|
foreach (var arg in container)
|
||||||
|
{
|
||||||
|
arguments.Add(arg.Value);
|
||||||
|
}
|
||||||
|
arguments.Add(new OutputArgument(output));
|
||||||
|
|
||||||
var scaling = container.Find<ScaleArgument>();
|
var scaling = container.Find<ScaleArgument>();
|
||||||
|
|
||||||
Encoder.Convert(container);
|
Encoder.Convert(arguments);
|
||||||
|
|
||||||
var outputVideo = new VideoInfo(output.FullName);
|
var outputVideo = new VideoInfo(output.FullName);
|
||||||
|
|
||||||
|
|
27
FFMpegCore/FFMPEG/Arguments/DisableChannelArgument.cs
Normal file
27
FFMpegCore/FFMPEG/Arguments/DisableChannelArgument.cs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
using FFMpegCore.FFMPEG.Enums;
|
||||||
|
|
||||||
|
namespace FFMpegCore.FFMPEG.Arguments
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents cpu speed parameter
|
||||||
|
/// </summary>
|
||||||
|
public class DisableChannelArgument : Argument<Channel>
|
||||||
|
{
|
||||||
|
public DisableChannelArgument()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DisableChannelArgument(Channel value) : base(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// String representation of the argument
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>String representation of the argument</returns>
|
||||||
|
public override string GetStringValue()
|
||||||
|
{
|
||||||
|
return ArgumentsStringifier.Disable(Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,68 +26,13 @@ public string BuildArguments(ArgumentsContainer container)
|
||||||
|
|
||||||
CheckContainerException(container);
|
CheckContainerException(container);
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
sb.Append(GetInput(container).GetStringValue().Trim() + " ");
|
return string.Join(" ", container.Select(argument => argument.Value.GetStringValue().Trim()));
|
||||||
|
|
||||||
foreach(var a in container)
|
|
||||||
{
|
|
||||||
if(!IsInputOrOutput(a.Key))
|
|
||||||
{
|
|
||||||
sb.Append(a.Value.GetStringValue().Trim() + " ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.Append(container[typeof(OutputArgument)].GetStringValue().Trim());
|
|
||||||
|
|
||||||
var overrideArg = container.Find<OverrideArgument>();
|
|
||||||
if (overrideArg != null)
|
|
||||||
sb.Append(" " + overrideArg.GetStringValue().Trim());
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Builds parameters string from <see cref="ArgumentsContainer"/> that would be passed to ffmpeg process
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="container">Container of arguments</param>
|
|
||||||
/// <param name="input">Input file</param>
|
|
||||||
/// <param name="output">Output file</param>
|
|
||||||
/// <returns>Parameters string</returns>
|
|
||||||
public string BuildArguments(ArgumentsContainer container, FileInfo input, FileInfo output)
|
|
||||||
{
|
|
||||||
CheckContainerException(container);
|
|
||||||
CheckExtensionOfOutputExtension(container, output);
|
|
||||||
FFMpegHelper.ConversionExceptionCheck(input, output);
|
|
||||||
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
var inputA = new InputArgument(input);
|
|
||||||
var outputA = new OutputArgument();
|
|
||||||
|
|
||||||
sb.Append(inputA.GetStringValue().Trim() + " ");
|
|
||||||
|
|
||||||
foreach (var a in container)
|
|
||||||
{
|
|
||||||
if (!IsInputOrOutput(a.Key))
|
|
||||||
{
|
|
||||||
sb.Append(a.Value.GetStringValue().Trim() + " ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.Append(outputA.GetStringValue().Trim());
|
|
||||||
|
|
||||||
var overrideArg = container.Find<OverrideArgument>();
|
|
||||||
if (overrideArg != null)
|
|
||||||
sb.Append(" " + overrideArg.GetStringValue().Trim());
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckContainerException(ArgumentsContainer container)
|
private void CheckContainerException(ArgumentsContainer container)
|
||||||
{
|
{
|
||||||
//TODO: implement arguments check
|
// TODO: implement arguments check
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckExtensionOfOutputExtension(ArgumentsContainer container, FileInfo output)
|
private void CheckExtensionOfOutputExtension(ArgumentsContainer container, FileInfo output)
|
||||||
|
|
|
@ -11,7 +11,5 @@ namespace FFMpegCore.FFMPEG.Arguments
|
||||||
public interface IArgumentBuilder
|
public interface IArgumentBuilder
|
||||||
{
|
{
|
||||||
string BuildArguments(ArgumentsContainer container);
|
string BuildArguments(ArgumentsContainer container);
|
||||||
|
|
||||||
string BuildArguments(ArgumentsContainer container, FileInfo input, FileInfo output);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,25 +10,25 @@ namespace FFMpegCore.FFMPEG.Arguments
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents input parameter
|
/// Represents input parameter
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class InputArgument : Argument<string>
|
public class InputArgument : Argument<string[]>
|
||||||
{
|
{
|
||||||
public InputArgument()
|
public InputArgument()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputArgument(string value) : base(value)
|
public InputArgument(params string[] values) : base(values)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputArgument(VideoInfo value) : base(value.FullName)
|
public InputArgument(params VideoInfo[] values) : base(values.Select(v => v.FullName).ToArray())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputArgument(FileInfo value) : base(value.FullName)
|
public InputArgument(params FileInfo[] values) : base(values.Select(v => v.FullName).ToArray())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputArgument(Uri value) : base(value.AbsolutePath)
|
public InputArgument(params Uri[] values) : base(values.Select(v => v.AbsolutePath).ToArray())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ public InputArgument(Uri value) : base(value.AbsolutePath)
|
||||||
/// <returns>String representation of the argument</returns>
|
/// <returns>String representation of the argument</returns>
|
||||||
public override string GetStringValue()
|
public override string GetStringValue()
|
||||||
{
|
{
|
||||||
return ArgumentsStringifier.Input(Value);
|
return string.Join(" ", Value.Select(v => ArgumentsStringifier.Input(v)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace FFMpegCore.FFMPEG.Arguments
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents output parameter
|
/// Represents output parameter
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class OutputArgument : InputArgument
|
public class OutputArgument : Argument<string>
|
||||||
{
|
{
|
||||||
public OutputArgument()
|
public OutputArgument()
|
||||||
{
|
{
|
||||||
|
@ -20,15 +20,15 @@ public OutputArgument(string value) : base(value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputArgument(VideoInfo value) : base(value)
|
public OutputArgument(VideoInfo value) : base(value.FullName)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputArgument(FileInfo value) : base(value)
|
public OutputArgument(FileInfo value) : base(value.FullName)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputArgument(Uri value) : base(value)
|
public OutputArgument(Uri value) : base(value.AbsolutePath)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,13 @@ namespace FFMpegCore.FFMPEG.Arguments
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents seek parameter
|
/// Represents seek parameter
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SeekArgument : Argument<TimeSpan>
|
public class SeekArgument : Argument<TimeSpan?>
|
||||||
{
|
{
|
||||||
public SeekArgument()
|
public SeekArgument()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public SeekArgument(TimeSpan value) : base(value)
|
public SeekArgument(TimeSpan? value) : base(value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ public SizeArgument()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public SizeArgument(Size value) : base(value)
|
public SizeArgument(Size? value) : base(value.HasValue ? value.Value : new Size())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,15 +91,15 @@ public Bitmap Snapshot(VideoInfo source, FileInfo output, Size? size = null, Tim
|
||||||
}
|
}
|
||||||
|
|
||||||
FFMpegHelper.ConversionExceptionCheck(source.ToFileInfo(), output);
|
FFMpegHelper.ConversionExceptionCheck(source.ToFileInfo(), output);
|
||||||
|
var container = new ArgumentsContainer();
|
||||||
|
container.Add(new InputArgument(source));
|
||||||
|
container.Add(new VideoCodecArgument(VideoCodec.Png));
|
||||||
|
container.Add(new FrameOutputCountArgument(1));
|
||||||
|
container.Add(new SeekArgument(captureTime));
|
||||||
|
container.Add(new SizeArgument(size));
|
||||||
|
container.Add(new OutputArgument(output));
|
||||||
|
|
||||||
var thumbArgs = ArgumentsStringifier.Input(source) +
|
if (!RunProcess(container, output))
|
||||||
ArgumentsStringifier.Video(VideoCodec.Png) +
|
|
||||||
ArgumentsStringifier.FrameOutputCount(1) +
|
|
||||||
ArgumentsStringifier.Seek(captureTime) +
|
|
||||||
ArgumentsStringifier.Size(size) +
|
|
||||||
ArgumentsStringifier.Output(output);
|
|
||||||
|
|
||||||
if (!RunProcess(thumbArgs, output))
|
|
||||||
{
|
{
|
||||||
throw new OperationCanceledException("Could not take snapshot!");
|
throw new OperationCanceledException("Could not take snapshot!");
|
||||||
}
|
}
|
||||||
|
@ -150,8 +150,6 @@ public VideoInfo Convert(
|
||||||
FFMpegHelper.ExtensionExceptionCheck(output, FileExtension.ForType(type));
|
FFMpegHelper.ExtensionExceptionCheck(output, FileExtension.ForType(type));
|
||||||
FFMpegHelper.ConversionSizeExceptionCheck(source);
|
FFMpegHelper.ConversionSizeExceptionCheck(source);
|
||||||
|
|
||||||
string args = "";
|
|
||||||
|
|
||||||
var scale = VideoSize.Original == size ? 1 :
|
var scale = VideoSize.Original == size ? 1 :
|
||||||
(double)source.Height / (int)size;
|
(double)source.Height / (int)size;
|
||||||
|
|
||||||
|
@ -165,38 +163,38 @@ public VideoInfo Convert(
|
||||||
outputSize.Width += 1;
|
outputSize.Width += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var container = new ArgumentsContainer();
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case VideoType.Mp4:
|
case VideoType.Mp4:
|
||||||
|
container.Add(new InputArgument(source));
|
||||||
args = ArgumentsStringifier.Input(source) +
|
container.Add(new ThreadsArgument(multithreaded));
|
||||||
ArgumentsStringifier.Threads(multithreaded) +
|
container.Add(new ScaleArgument(outputSize));
|
||||||
ArgumentsStringifier.Scale(outputSize) +
|
container.Add(new VideoCodecArgument(VideoCodec.LibX264, 2400));
|
||||||
ArgumentsStringifier.Video(VideoCodec.LibX264, 2400) +
|
container.Add(new SpeedArgument(speed));
|
||||||
ArgumentsStringifier.Speed(speed) +
|
container.Add(new AudioCodecArgument(AudioCodec.Aac, audioQuality));
|
||||||
ArgumentsStringifier.Audio(AudioCodec.Aac, audioQuality) +
|
container.Add(new OutputArgument(output));
|
||||||
ArgumentsStringifier.Output(output);
|
|
||||||
break;
|
break;
|
||||||
case VideoType.Ogv:
|
case VideoType.Ogv:
|
||||||
args = ArgumentsStringifier.Input(source) +
|
container.Add(new InputArgument(source));
|
||||||
ArgumentsStringifier.Threads(multithreaded) +
|
container.Add(new ThreadsArgument(multithreaded));
|
||||||
ArgumentsStringifier.Scale(outputSize) +
|
container.Add(new ScaleArgument(outputSize));
|
||||||
ArgumentsStringifier.Video(VideoCodec.LibTheora, 2400) +
|
container.Add(new VideoCodecArgument(VideoCodec.LibTheora, 2400));
|
||||||
ArgumentsStringifier.Speed(16) +
|
container.Add(new SpeedArgument(speed));
|
||||||
ArgumentsStringifier.Audio(AudioCodec.LibVorbis, audioQuality) +
|
container.Add(new AudioCodecArgument(AudioCodec.LibVorbis, audioQuality));
|
||||||
ArgumentsStringifier.Output(output);
|
container.Add(new OutputArgument(output));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case VideoType.Ts:
|
case VideoType.Ts:
|
||||||
args = ArgumentsStringifier.Input(source) +
|
container.Add(new InputArgument(source));
|
||||||
ArgumentsStringifier.Copy() +
|
container.Add(new CopyArgument());
|
||||||
ArgumentsStringifier.BitStreamFilter(Channel.Video, Filter.H264_Mp4ToAnnexB) +
|
container.Add(new BitStreamFilterArgument(Channel.Video, Filter.H264_Mp4ToAnnexB));
|
||||||
ArgumentsStringifier.ForceFormat(VideoCodec.MpegTs) +
|
container.Add(new ForceFormatArgument(VideoCodec.MpegTs));
|
||||||
ArgumentsStringifier.Output(output);
|
container.Add(new OutputArgument(output));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RunProcess(args, output))
|
if (!RunProcess(container, output))
|
||||||
{
|
{
|
||||||
throw new FFMpegException(FFMpegExceptionType.Conversion, $"The video could not be converted to {Enum.GetName(typeof(VideoType), type)}");
|
throw new FFMpegException(FFMpegExceptionType.Conversion, $"The video could not be converted to {Enum.GetName(typeof(VideoType), type)}");
|
||||||
}
|
}
|
||||||
|
@ -217,15 +215,15 @@ public VideoInfo PosterWithAudio(FileInfo image, FileInfo audio, FileInfo output
|
||||||
FFMpegHelper.ExtensionExceptionCheck(output, FileExtension.Mp4);
|
FFMpegHelper.ExtensionExceptionCheck(output, FileExtension.Mp4);
|
||||||
FFMpegHelper.ConversionSizeExceptionCheck(Image.FromFile(image.FullName));
|
FFMpegHelper.ConversionSizeExceptionCheck(Image.FromFile(image.FullName));
|
||||||
|
|
||||||
var args = ArgumentsStringifier.Loop(1) +
|
var container = new ArgumentsContainer();
|
||||||
ArgumentsStringifier.Input(image) +
|
container.Add(new LoopArgument(1));
|
||||||
ArgumentsStringifier.Input(audio) +
|
container.Add(new InputArgument(image.FullName, audio.FullName));
|
||||||
ArgumentsStringifier.Video(VideoCodec.LibX264, 2400) +
|
container.Add(new VideoCodecArgument(VideoCodec.LibX264, 2400));
|
||||||
ArgumentsStringifier.Audio(AudioCodec.Aac, AudioQuality.Normal) +
|
container.Add(new AudioCodecArgument(AudioCodec.Aac, AudioQuality.Normal));
|
||||||
ArgumentsStringifier.FinalizeAtShortestInput(true) +
|
container.Add(new ShortestArgument(true));
|
||||||
ArgumentsStringifier.Output(output);
|
container.Add(new OutputArgument(output));
|
||||||
|
|
||||||
if (!RunProcess(args, output))
|
if (!RunProcess(container, output))
|
||||||
{
|
{
|
||||||
throw new FFMpegException(FFMpegExceptionType.Operation, "An error occured while adding the audio file to the image.");
|
throw new FFMpegException(FFMpegExceptionType.Operation, "An error occured while adding the audio file to the image.");
|
||||||
}
|
}
|
||||||
|
@ -256,14 +254,15 @@ public VideoInfo Join(FileInfo output, params VideoInfo[] videos)
|
||||||
return destinationPath;
|
return destinationPath;
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
var args = ArgumentsStringifier.InputConcat(temporaryVideoParts) +
|
var container = new ArgumentsContainer();
|
||||||
ArgumentsStringifier.Copy() +
|
container.Add(new ConcatArgument(temporaryVideoParts));
|
||||||
ArgumentsStringifier.BitStreamFilter(Channel.Audio, Filter.Aac_AdtstoAsc) +
|
container.Add(new CopyArgument());
|
||||||
ArgumentsStringifier.Output(output);
|
container.Add(new BitStreamFilterArgument(Channel.Audio, Filter.Aac_AdtstoAsc));
|
||||||
|
container.Add(new OutputArgument(output));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!RunProcess(args, output))
|
if (!RunProcess(container, output))
|
||||||
{
|
{
|
||||||
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not join the provided video files.");
|
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not join the provided video files.");
|
||||||
}
|
}
|
||||||
|
@ -296,17 +295,18 @@ public VideoInfo JoinImageSequence(FileInfo output, double frameRate = 30, param
|
||||||
|
|
||||||
var firstImage = images.First();
|
var firstImage = images.First();
|
||||||
|
|
||||||
var args = ArgumentsStringifier.FrameRate(frameRate) +
|
var container = new ArgumentsContainer();
|
||||||
ArgumentsStringifier.Size(new Size(firstImage.Width, firstImage.Height)) +
|
container.Add(new FrameRateArgument(frameRate));
|
||||||
ArgumentsStringifier.StartNumber(0) +
|
container.Add(new SizeArgument(firstImage.Width, firstImage.Height));
|
||||||
ArgumentsStringifier.Input($"{firstImage.Directory}\\%09d.png") +
|
container.Add(new StartNumberArgument(0));
|
||||||
ArgumentsStringifier.FrameOutputCount(images.Length) +
|
container.Add(new InputArgument($"{firstImage.Directory}\\%09d.png"));
|
||||||
ArgumentsStringifier.Video(VideoCodec.LibX264) +
|
container.Add(new FrameOutputCountArgument(images.Length));
|
||||||
ArgumentsStringifier.Output(output);
|
container.Add(new VideoCodecArgument(VideoCodec.LibX264));
|
||||||
|
container.Add(new OutputArgument(output));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!RunProcess(args, output))
|
if (!RunProcess(container, output))
|
||||||
{
|
{
|
||||||
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not join the provided image sequence.");
|
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not join the provided image sequence.");
|
||||||
}
|
}
|
||||||
|
@ -331,10 +331,11 @@ public VideoInfo SaveM3U8Stream(Uri uri, FileInfo output)
|
||||||
|
|
||||||
if (uri.Scheme == "http" || uri.Scheme == "https")
|
if (uri.Scheme == "http" || uri.Scheme == "https")
|
||||||
{
|
{
|
||||||
var args = ArgumentsStringifier.Input(uri) +
|
var container = new ArgumentsContainer();
|
||||||
ArgumentsStringifier.Output(output);
|
container.Add(new InputArgument(uri));
|
||||||
|
container.Add(new OutputArgument(output));
|
||||||
|
|
||||||
if (!RunProcess(args, output))
|
if (!RunProcess(container, output))
|
||||||
{
|
{
|
||||||
throw new FFMpegException(FFMpegExceptionType.Operation, $"Saving the ${uri.AbsoluteUri} stream failed.");
|
throw new FFMpegException(FFMpegExceptionType.Operation, $"Saving the ${uri.AbsoluteUri} stream failed.");
|
||||||
}
|
}
|
||||||
|
@ -356,12 +357,13 @@ public VideoInfo Mute(VideoInfo source, FileInfo output)
|
||||||
FFMpegHelper.ConversionSizeExceptionCheck(source);
|
FFMpegHelper.ConversionSizeExceptionCheck(source);
|
||||||
FFMpegHelper.ExtensionExceptionCheck(output, source.Extension);
|
FFMpegHelper.ExtensionExceptionCheck(output, source.Extension);
|
||||||
|
|
||||||
var args = ArgumentsStringifier.Input(source) +
|
var container = new ArgumentsContainer();
|
||||||
ArgumentsStringifier.Copy() +
|
container.Add(new InputArgument(source));
|
||||||
ArgumentsStringifier.Disable(Channel.Audio) +
|
container.Add(new CopyArgument());
|
||||||
ArgumentsStringifier.Output(output);
|
container.Add(new DisableChannelArgument(Channel.Audio));
|
||||||
|
container.Add(new OutputArgument(output));
|
||||||
|
|
||||||
if (!RunProcess(args, output))
|
if (!RunProcess(container, output))
|
||||||
{
|
{
|
||||||
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not mute the requested video.");
|
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not mute the requested video.");
|
||||||
}
|
}
|
||||||
|
@ -380,11 +382,12 @@ public FileInfo ExtractAudio(VideoInfo source, FileInfo output)
|
||||||
FFMpegHelper.ConversionExceptionCheck(source.ToFileInfo(), output);
|
FFMpegHelper.ConversionExceptionCheck(source.ToFileInfo(), output);
|
||||||
FFMpegHelper.ExtensionExceptionCheck(output, FileExtension.Mp3);
|
FFMpegHelper.ExtensionExceptionCheck(output, FileExtension.Mp3);
|
||||||
|
|
||||||
var args = ArgumentsStringifier.Input(source) +
|
var container = new ArgumentsContainer();
|
||||||
ArgumentsStringifier.Disable(Channel.Video) +
|
container.Add(new InputArgument(source));
|
||||||
ArgumentsStringifier.Output(output);
|
container.Add(new DisableChannelArgument(Channel.Video));
|
||||||
|
container.Add(new OutputArgument(output));
|
||||||
|
|
||||||
if (!RunProcess(args, output))
|
if (!RunProcess(container, output))
|
||||||
{
|
{
|
||||||
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not extract the audio from the requested video.");
|
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not extract the audio from the requested video.");
|
||||||
}
|
}
|
||||||
|
@ -409,14 +412,15 @@ public VideoInfo ReplaceAudio(VideoInfo source, FileInfo audio, FileInfo output,
|
||||||
FFMpegHelper.ConversionSizeExceptionCheck(source);
|
FFMpegHelper.ConversionSizeExceptionCheck(source);
|
||||||
FFMpegHelper.ExtensionExceptionCheck(output, source.Extension);
|
FFMpegHelper.ExtensionExceptionCheck(output, source.Extension);
|
||||||
|
|
||||||
var args = ArgumentsStringifier.Input(source) +
|
var container = new ArgumentsContainer();
|
||||||
ArgumentsStringifier.Input(audio) +
|
container.Add(new InputArgument(source.FullName, audio.FullName));
|
||||||
ArgumentsStringifier.Copy(Channel.Video) +
|
//container.Add(new InputArgument(audio));
|
||||||
ArgumentsStringifier.Audio(AudioCodec.Aac, AudioQuality.Hd) +
|
container.Add(new CopyArgument());
|
||||||
ArgumentsStringifier.FinalizeAtShortestInput(stopAtShortest) +
|
container.Add(new AudioCodecArgument(AudioCodec.Aac, AudioQuality.Hd));
|
||||||
ArgumentsStringifier.Output(output);
|
container.Add(new ShortestArgument(stopAtShortest));
|
||||||
|
container.Add(new OutputArgument(output));
|
||||||
|
|
||||||
if (!RunProcess(args, output))
|
if (!RunProcess(container, output))
|
||||||
{
|
{
|
||||||
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not replace the video audio.");
|
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not replace the video audio.");
|
||||||
}
|
}
|
||||||
|
@ -429,19 +433,7 @@ public VideoInfo Convert(ArgumentsContainer arguments)
|
||||||
var args = argumentBuilder.BuildArguments(arguments);
|
var args = argumentBuilder.BuildArguments(arguments);
|
||||||
var output = ((OutputArgument)arguments[typeof(OutputArgument)]).GetAsFileInfo();
|
var output = ((OutputArgument)arguments[typeof(OutputArgument)]).GetAsFileInfo();
|
||||||
|
|
||||||
if (!RunProcess(args, output))
|
if (!RunProcess(arguments, output))
|
||||||
{
|
|
||||||
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not replace the video audio.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new VideoInfo(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
public VideoInfo Convert(ArgumentsContainer arguments, FileInfo input, FileInfo output)
|
|
||||||
{
|
|
||||||
var args = argumentBuilder.BuildArguments(arguments, input, output);
|
|
||||||
|
|
||||||
if (!RunProcess(args, output))
|
|
||||||
{
|
{
|
||||||
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not replace the video audio.");
|
throw new FFMpegException(FFMpegExceptionType.Operation, "Could not replace the video audio.");
|
||||||
}
|
}
|
||||||
|
@ -467,11 +459,11 @@ public void Stop()
|
||||||
|
|
||||||
private volatile StringBuilder _errorOutput = new StringBuilder();
|
private volatile StringBuilder _errorOutput = new StringBuilder();
|
||||||
|
|
||||||
private bool RunProcess(string args, FileInfo output)
|
private bool RunProcess(ArgumentsContainer container, FileInfo output)
|
||||||
{
|
{
|
||||||
var successState = true;
|
var successState = true;
|
||||||
|
|
||||||
CreateProcess(args, _ffmpegPath, true, rStandardError: true);
|
CreateProcess(this.argumentBuilder.BuildArguments(container), _ffmpegPath, true, rStandardError: true);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue