mirror of
https://github.com/rosenbjerg/FFMpegCore.git
synced 2025-12-14 01:55:45 +00:00
Merge 398ab1fd96 into cc75e03ec9
This commit is contained in:
commit
e78f6a07bd
42 changed files with 942 additions and 3 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using FFMpegCore.Arguments;
|
using FFMpegCore.Arguments;
|
||||||
|
using FFMpegCore.Arguments.MainOptions;
|
||||||
using FFMpegCore.Enums;
|
using FFMpegCore.Enums;
|
||||||
using FFMpegCore.Pipes;
|
using FFMpegCore.Pipes;
|
||||||
|
|
||||||
|
|
@ -46,6 +47,38 @@ public class ArgumentBuilderTest
|
||||||
Assert.AreEqual("-i \"input.mp4\" -b:a 128k \"output.mp4\" -y", str);
|
Assert.AreEqual("-i \"input.mp4\" -b:a 128k \"output.mp4\" -y", str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Builder_BuildString_HideBanner()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments.FromFileInput("input.mp4").WithGlobalOptions(opt => opt.WithHideBanner())
|
||||||
|
.OutputToFile("output.mp4", false).Arguments;
|
||||||
|
Assert.AreEqual("-hide_banner -i \"input.mp4\" \"output.mp4\"", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Builder_BuildString_NoStats()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments.FromFileInput("input.mp4").WithGlobalOptions(opt => opt.WithNoStats())
|
||||||
|
.OutputToFile("output.mp4", false).Arguments;
|
||||||
|
Assert.AreEqual("-nostats -i \"input.mp4\" \"output.mp4\"", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Builder_BuildString_With_Explicit_Stats()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments.FromFileInput("input.mp4").WithGlobalOptions(opt => opt.WithArgument(new Stats(true)))
|
||||||
|
.OutputToFile("output.mp4", false).Arguments;
|
||||||
|
Assert.AreEqual("-stats -i \"input.mp4\" \"output.mp4\"", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Builder_BuildString_HardwareAccelerationOutputFormat()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments.FromFileInput("input.mp4").WithGlobalOptions(opt => opt.WithHardwareAccelerationOutputFormat(HardwareAccelerationDevice.Auto))
|
||||||
|
.OutputToFile("output.mp4", false).Arguments;
|
||||||
|
Assert.AreEqual("-hwaccel_output_format auto -i \"input.mp4\" \"output.mp4\"", str);
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Builder_BuildString_Quiet()
|
public void Builder_BuildString_Quiet()
|
||||||
{
|
{
|
||||||
|
|
@ -552,6 +585,191 @@ public class ArgumentBuilderTest
|
||||||
str);
|
str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Builder_BuildString_VideoFilter_Vaapi_Scale()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments
|
||||||
|
.FromFileInput("input.mp4")
|
||||||
|
.OutputToFile("output.mp4", false, opt => opt
|
||||||
|
.WithVideoFilters(filterOptions => filterOptions
|
||||||
|
.Format("nv12", "vaapi")
|
||||||
|
.HardwareUpload()
|
||||||
|
.WithVaapiVideoFilter(options => options
|
||||||
|
.Scale(VideoSize.FullHd)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.WithVaapiRcMode(VaapiRcMode.CQP)
|
||||||
|
.WithH264VaapiOptions(options => options
|
||||||
|
.WithQuantizer(28)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.Arguments;
|
||||||
|
|
||||||
|
Assert.AreEqual(
|
||||||
|
"-i \"input.mp4\" -vf \"format=pix_fmts=nv12|vaapi, hwupload, scale_vaapi=-1:1080\" -rc_mode CQP -qp 28 \"output.mp4\"",
|
||||||
|
str);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Builder_BuildString_VideoFilter_Vaapi_Scale2()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments
|
||||||
|
.FromFileInput("input.mp4")
|
||||||
|
.OutputToFile("output.mp4", false, opt => opt
|
||||||
|
.WithVideoFilters(filterOptions => filterOptions
|
||||||
|
.Format("nv12", "vaapi")
|
||||||
|
.HardwareUpload()
|
||||||
|
.WithVaapiVideoFilter(options => options
|
||||||
|
.Scale(2560, 1440)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.WithVaapiRcMode(VaapiRcMode.CQP)
|
||||||
|
.WithH264VaapiOptions(options => options
|
||||||
|
.WithQuantizer(28)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.Arguments;
|
||||||
|
|
||||||
|
Assert.AreEqual(
|
||||||
|
"-i \"input.mp4\" -vf \"format=pix_fmts=nv12|vaapi, hwupload, scale_vaapi=2560:1440\" -rc_mode CQP -qp 28 \"output.mp4\"",
|
||||||
|
str);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Builder_BuildString_VideoFilter_Vaapi_Scale3()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments
|
||||||
|
.FromFileInput("input.mp4")
|
||||||
|
.OutputToFile("output.mp4", false, opt => opt
|
||||||
|
.WithVideoFilters(filterOptions => filterOptions
|
||||||
|
.Format("nv12", "vaapi")
|
||||||
|
.HardwareUpload()
|
||||||
|
.WithVaapiVideoFilter(options => options
|
||||||
|
.Scale(new Size(1280, 720))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.WithVaapiRcMode(VaapiRcMode.CQP)
|
||||||
|
.WithH264VaapiOptions(options => options
|
||||||
|
.WithQuantizer(28)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.Arguments;
|
||||||
|
|
||||||
|
Assert.AreEqual(
|
||||||
|
"-i \"input.mp4\" -vf \"format=pix_fmts=nv12|vaapi, hwupload, scale_vaapi=1280:720\" -rc_mode CQP -qp 28 \"output.mp4\"",
|
||||||
|
str);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Builder_BuildString_VideoFilter_Vaapi_Scale4()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments
|
||||||
|
.FromFileInput("input.mp4")
|
||||||
|
.OutputToFile("output.mp4", false, opt => opt
|
||||||
|
.WithVideoFilters(filterOptions => filterOptions
|
||||||
|
.Format("nv12", "vaapi")
|
||||||
|
.HardwareUpload()
|
||||||
|
.WithVaapiVideoFilter(options => options
|
||||||
|
.Scale(VideoSize.Original)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.WithVaapiRcMode(VaapiRcMode.CQP)
|
||||||
|
.WithH264VaapiOptions(options => options
|
||||||
|
.WithQuantizer(28)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.Arguments;
|
||||||
|
|
||||||
|
Assert.AreEqual(
|
||||||
|
"-i \"input.mp4\" -vf \"format=pix_fmts=nv12|vaapi, hwupload\" -rc_mode CQP -qp 28 \"output.mp4\"",
|
||||||
|
str);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Builder_BuildString_Single_Image()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments
|
||||||
|
.FromFileInput("input.jpg")
|
||||||
|
.OutputToFile("output.jpg", false, opt => opt
|
||||||
|
.WithVideoFilters(filterOptions => filterOptions
|
||||||
|
.Scale(-1, 120)
|
||||||
|
)
|
||||||
|
.WithImage2Options(options => options
|
||||||
|
.WithUpdate()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.Arguments;
|
||||||
|
|
||||||
|
Assert.AreEqual(
|
||||||
|
"-i \"input.jpg\" -vf \"scale=-1:120\" -update 1 \"output.jpg\"",
|
||||||
|
str);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Builder_BuildString_Segments()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments
|
||||||
|
.FromFileInput("input.mp4")
|
||||||
|
.OutputToFile("output-%Y%m%d-%s.mp4", false, opt => opt
|
||||||
|
.WithUseWallclockAsTimestamps()
|
||||||
|
.ForceFormat("segment")
|
||||||
|
.WithSegmentOptions(options => options
|
||||||
|
.WithSegmentAtClocktime()
|
||||||
|
.WithSegmentTime(TimeSpan.FromMinutes(10))
|
||||||
|
.WithMinimumSegmentDuration(TimeSpan.FromMinutes(5))
|
||||||
|
.WithResetTimestamps()
|
||||||
|
.WithStrftime()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.Arguments;
|
||||||
|
|
||||||
|
Assert.AreEqual(
|
||||||
|
"-i \"input.mp4\" -use_wallclock_as_timestamps 1 -f segment -segment_atclocktime 1 -segment_time 600 -min_seg_duration 300 -reset_timestamps 1 -strftime 1 \"output-%Y%m%d-%s.mp4\"",
|
||||||
|
str);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Builder_BuildString_Segments_WUseWallclockTimestamps()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments
|
||||||
|
.FromFileInput("input.mp4")
|
||||||
|
.OutputToFile("output-%Y%m%d-%s.mp4", false, opt => opt
|
||||||
|
.WithUseWallclockAsTimestamps(false)
|
||||||
|
.ForceFormat("segment")
|
||||||
|
.WithSegmentOptions(options => options
|
||||||
|
.WithSegmentAtClocktime()
|
||||||
|
.WithSegmentTime(TimeSpan.FromMinutes(10))
|
||||||
|
.WithMinimumSegmentDuration(TimeSpan.FromMinutes(5))
|
||||||
|
.WithResetTimestamps()
|
||||||
|
.WithStrftime()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.Arguments;
|
||||||
|
|
||||||
|
Assert.AreEqual(
|
||||||
|
"-i \"input.mp4\" -use_wallclock_as_timestamps 0 -f segment -segment_atclocktime 1 -segment_time 600 -min_seg_duration 300 -reset_timestamps 1 -strftime 1 \"output-%Y%m%d-%s.mp4\"",
|
||||||
|
str);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Builder_BuildString_Rtsp_Stream()
|
||||||
|
{
|
||||||
|
var str = FFMpegArguments
|
||||||
|
.FromUrlInput(new Uri("rtsp://server/stream?query"), options => options
|
||||||
|
.WithAnalyzeDuration(TimeSpan.FromSeconds(1))
|
||||||
|
.WithProbeSize(1_000_000)
|
||||||
|
.WithRtspProtocolOptions(argumentOptions => argumentOptions
|
||||||
|
.WithRtspTransport(RtspTransportProtocol.tcp)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.OutputToFile("output.mp4", false)
|
||||||
|
.Arguments;
|
||||||
|
|
||||||
|
Assert.AreEqual(
|
||||||
|
"-analyzeduration 1000000 -probesize 1000000 -rtsp_transport tcp -i \"rtsp://server/stream?query\" \"output.mp4\"",
|
||||||
|
str);
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Builder_BuildString_GifPalette()
|
public void Builder_BuildString_GifPalette()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
11
FFMpegCore/FFMpeg/Arguments/BaseBoolArgument.cs
Normal file
11
FFMpegCore/FFMpeg/Arguments/BaseBoolArgument.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
namespace FFMpegCore.Arguments;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Base class for boolean arguments with value <c>0</c> or <c>1</c>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public abstract class BaseBoolArgument(bool value) : IArgument
|
||||||
|
{
|
||||||
|
protected abstract string ArgumentName { get; }
|
||||||
|
public string Text => $"-{ArgumentName} {(value ? '1' : '0')}";
|
||||||
|
}
|
||||||
14
FFMpegCore/FFMpeg/Arguments/BaseOptionArgument.cs
Normal file
14
FFMpegCore/FFMpeg/Arguments/BaseOptionArgument.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace FFMpegCore.Arguments;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg.html#Options" />
|
||||||
|
/// Base class for option arguments.
|
||||||
|
/// Options which do not take arguments are boolean options, and set the corresponding value to true.
|
||||||
|
/// They can be set to false by prefixing the option name with "no". For example using "-nofoo" will set the boolean option with name "foo" to false.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public abstract class BaseOptionArgument(bool value) : IArgument
|
||||||
|
{
|
||||||
|
protected abstract string ArgumentName { get; }
|
||||||
|
public string Text => $"-{(value ? "" : "no")}{ArgumentName}";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
using FFMpegCore.Enums;
|
||||||
|
|
||||||
|
namespace FFMpegCore.Arguments.Codecs.Vaapi;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://www.ffmpeg.org/ffmpeg-codecs.html#VAAPI-encoders" />
|
||||||
|
/// Set the rate control mode to use. A given driver may only support a subset of modes.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class VaapiRcModeArgument(VaapiRcMode rcMode) : IArgument
|
||||||
|
{
|
||||||
|
public string Text => $"-rc_mode {rcMode}";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
namespace FFMpegCore.Arguments.Codecs.Vaapi.h264Vaapi;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-formats.html#image2_002c-image2pipe" />
|
||||||
|
/// </summary>
|
||||||
|
public sealed class H264VaapiArgumentOptions
|
||||||
|
{
|
||||||
|
private readonly FFMpegArgumentOptions _options;
|
||||||
|
|
||||||
|
internal H264VaapiArgumentOptions(FFMpegArgumentOptions options)
|
||||||
|
{
|
||||||
|
_options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="VaapiQpArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="quantizer"><c>0</c> - <c>52</c></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public H264VaapiArgumentOptions WithQuantizer(sbyte quantizer)
|
||||||
|
{
|
||||||
|
return WithArgument(new VaapiQpArgument(quantizer));
|
||||||
|
}
|
||||||
|
|
||||||
|
public H264VaapiArgumentOptions WithArgument(IH264VaapiArgument argument)
|
||||||
|
{
|
||||||
|
_options.WithArgument(argument);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
namespace FFMpegCore.Arguments.Codecs.Vaapi.h264Vaapi;
|
||||||
|
|
||||||
|
public interface IH264VaapiArgument : IArgument;
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
namespace FFMpegCore.Arguments.Codecs.Vaapi.h264Vaapi;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// undocumented(?) <see href="https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/vaapi_encode_h264.c#L1073"/>
|
||||||
|
/// Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="quantizer"><c>0</c> - <c>52</c></param>
|
||||||
|
public sealed class VaapiQpArgument(sbyte quantizer) : IH264VaapiArgument
|
||||||
|
{
|
||||||
|
public string Text => $"-qp {quantizer}";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-formats.html#Format-Options"/>
|
||||||
|
/// Specify how many microseconds are analyzed to probe the input.
|
||||||
|
/// A higher value will enable detecting more accurate information, but will increase latency.
|
||||||
|
/// It defaults to 5,000,000 microseconds = 5 seconds.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class AnalyzeDurationArgument(TimeSpan duration) : IArgument
|
||||||
|
{
|
||||||
|
#if NET8_OR_GREATER
|
||||||
|
private readonly long _duration = Convert.ToInt64(duration.TotalMicroseconds);
|
||||||
|
#else
|
||||||
|
// https://github.com/dotnet/runtime/blob/e8812e7419db9137f20b990786a53ed71e27e11e/src/libraries/System.Private.CoreLib/src/System/TimeSpan.cs#L371
|
||||||
|
private readonly long _duration = Convert.ToInt64((double)duration.Ticks / 10);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public string Text => $"-analyzeduration {_duration}";
|
||||||
|
}
|
||||||
3
FFMpegCore/FFMpeg/Arguments/Formats/IDemuxerArgument.cs
Normal file
3
FFMpegCore/FFMpeg/Arguments/Formats/IDemuxerArgument.cs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats;
|
||||||
|
|
||||||
|
public interface IDemuxerArgument : IArgument;
|
||||||
3
FFMpegCore/FFMpeg/Arguments/Formats/IMuxerArgument.cs
Normal file
3
FFMpegCore/FFMpeg/Arguments/Formats/IMuxerArgument.cs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats;
|
||||||
|
|
||||||
|
public interface IMuxerArgument : IArgument;
|
||||||
12
FFMpegCore/FFMpeg/Arguments/Formats/ProbeSizeArgument.cs
Normal file
12
FFMpegCore/FFMpeg/Arguments/Formats/ProbeSizeArgument.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-formats.html#Format-Options"/>
|
||||||
|
/// Set probing size in bytes, i.e. the size of the data to analyze to get stream information.
|
||||||
|
/// A higher value will enable detecting more information in case it is dispersed into the stream, but will increase latency.
|
||||||
|
/// Must be an integer not lesser than 32. It is 5000000 by default.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ProbeSizeArgument(long probesize) : IArgument
|
||||||
|
{
|
||||||
|
public string Text => $"-probesize {probesize}";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-formats.html#Format-Options" />
|
||||||
|
/// Use wallclock as timestamps if set to 1. Default is 0.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class UseWallclockAsTimestampsArgument(bool value) : BaseBoolArgument(value)
|
||||||
|
{
|
||||||
|
protected override string ArgumentName => "use_wallclock_as_timestamps";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats.image2;
|
||||||
|
|
||||||
|
public interface IImage2Argument : IArgument;
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats.image2;
|
||||||
|
|
||||||
|
public interface IImage2MuxerArgument :
|
||||||
|
IImage2Argument,
|
||||||
|
IDemuxerArgument;
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats.image2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-formats.html#image2_002c-image2pipe" />
|
||||||
|
/// </summary>
|
||||||
|
public sealed class Image2ArgumentOptions
|
||||||
|
{
|
||||||
|
private readonly FFMpegArgumentOptions _options;
|
||||||
|
|
||||||
|
internal Image2ArgumentOptions(FFMpegArgumentOptions options)
|
||||||
|
{
|
||||||
|
_options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="UpdateArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public Image2ArgumentOptions WithUpdate(bool value = true)
|
||||||
|
{
|
||||||
|
return WithArgument(new UpdateArgument(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Image2ArgumentOptions WithArgument(IImage2Argument argument)
|
||||||
|
{
|
||||||
|
_options.WithArgument(argument);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
FFMpegCore/FFMpeg/Arguments/Formats/image2/UpdateArgument.cs
Normal file
10
FFMpegCore/FFMpeg/Arguments/Formats/image2/UpdateArgument.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats.image2;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-formats.html#Options-27" />
|
||||||
|
/// If set to 1, the filename will always be interpreted as just a filename, not a pattern, and the corresponding file will be continuously overwritten with new images. Default value is 0.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class UpdateArgument(bool value = false) : BaseBoolArgument(value), IImage2MuxerArgument
|
||||||
|
{
|
||||||
|
protected override string ArgumentName => "update";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats.segment;
|
||||||
|
|
||||||
|
public interface ISegmentArgument : IArgument;
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats.segment;
|
||||||
|
|
||||||
|
public interface ISegmentMuxerArgument :
|
||||||
|
ISegmentArgument,
|
||||||
|
IDemuxerArgument;
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats.segment;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment" />
|
||||||
|
/// Set minimum segment duration to time, the value must be a duration specification.
|
||||||
|
/// This prevents the muxer ending segments at a duration below this value.
|
||||||
|
/// Only effective with segment_time. Default value is "0".
|
||||||
|
/// </summary>
|
||||||
|
public sealed class MinSegmentDurationArgument(TimeSpan duration) : ISegmentMuxerArgument
|
||||||
|
{
|
||||||
|
private readonly long _duration = Convert.ToInt64(duration.TotalSeconds);
|
||||||
|
|
||||||
|
public string Text => $"-min_seg_duration {_duration}";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats.segment;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment" />
|
||||||
|
/// Reset timestamps at the beginning of each segment, so that each segment will start with near-zero timestamps.
|
||||||
|
/// It is meant to ease the playback of the generated segments.
|
||||||
|
/// May not work with some combinations of muxers/codecs.
|
||||||
|
/// It is set to <c>0</c> by default.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class ResetTimestampsArgument(bool value) : BaseBoolArgument(value), ISegmentMuxerArgument
|
||||||
|
{
|
||||||
|
protected override string ArgumentName => "reset_timestamps";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats.segment;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment" />
|
||||||
|
/// </summary>
|
||||||
|
public sealed class SegmentArgumentOptions
|
||||||
|
{
|
||||||
|
private readonly FFMpegArgumentOptions _options;
|
||||||
|
|
||||||
|
internal SegmentArgumentOptions(FFMpegArgumentOptions options)
|
||||||
|
{
|
||||||
|
_options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="MinSegmentDurationArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="duration"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public SegmentArgumentOptions WithMinimumSegmentDuration(TimeSpan duration)
|
||||||
|
{
|
||||||
|
return WithArgument(new MinSegmentDurationArgument(duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="SegmentTimeArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="duration"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public SegmentArgumentOptions WithSegmentTime(TimeSpan duration)
|
||||||
|
{
|
||||||
|
return WithArgument(new SegmentTimeArgument(duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="SegmentAtClocktimeArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public SegmentArgumentOptions WithSegmentAtClocktime(bool value = true)
|
||||||
|
{
|
||||||
|
return WithArgument(new SegmentAtClocktimeArgument(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="StrftimeArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public SegmentArgumentOptions WithStrftime(bool value = true)
|
||||||
|
{
|
||||||
|
return WithArgument(new StrftimeArgument(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="ResetTimestampsArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public SegmentArgumentOptions WithResetTimestamps(bool value = true)
|
||||||
|
{
|
||||||
|
return WithArgument(new ResetTimestampsArgument(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SegmentArgumentOptions WithArgument(ISegmentArgument argument)
|
||||||
|
{
|
||||||
|
_options.WithArgument(argument);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats.segment;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment" />
|
||||||
|
/// If set to "1" split at regular clock time intervals starting from 00:00 o’clock.
|
||||||
|
/// The time value specified in segment_time is used for setting the length of the splitting interval.
|
||||||
|
/// For example with segment_time set to "900" this makes it possible to create files at 12:00 o’clock, 12:15, 12:30, etc.
|
||||||
|
/// Default value is "0".
|
||||||
|
/// </summary>
|
||||||
|
public sealed class SegmentAtClocktimeArgument(bool value) : BaseBoolArgument(value), ISegmentMuxerArgument
|
||||||
|
{
|
||||||
|
protected override string ArgumentName => "segment_atclocktime";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats.segment;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment" />
|
||||||
|
/// Set segment duration to time, the value must be a duration specification. Default value is "2". See also the segment_times option.
|
||||||
|
/// Note that splitting may not be accurate, unless you force the reference stream key-frames at the given time. See the introductory notice and the examples below.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class SegmentTimeArgument(TimeSpan duration) : ISegmentMuxerArgument
|
||||||
|
{
|
||||||
|
private readonly long _duration = Convert.ToInt64(duration.TotalSeconds);
|
||||||
|
|
||||||
|
public string Text => $"-segment_time {_duration}";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace FFMpegCore.Arguments.Formats.segment;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment" />
|
||||||
|
/// Use the strftime function to define the name of the new segments to write.
|
||||||
|
/// If this is selected, the output segment name must contain a strftime function template.
|
||||||
|
/// Default value is 0.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class StrftimeArgument(bool value) : BaseBoolArgument(value), ISegmentMuxerArgument
|
||||||
|
{
|
||||||
|
protected override string ArgumentName => "strftime";
|
||||||
|
}
|
||||||
12
FFMpegCore/FFMpeg/Arguments/GenericOptions/HideBanner.cs
Normal file
12
FFMpegCore/FFMpeg/Arguments/GenericOptions/HideBanner.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace FFMpegCore.Arguments.GenericOptions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg.html#Generic-options" />
|
||||||
|
/// Suppress printing banner.
|
||||||
|
/// All FFmpeg tools will normally show a copyright notice, build options and library versions.
|
||||||
|
/// This option can be used to suppress printing this information.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class HideBanner : IArgument
|
||||||
|
{
|
||||||
|
public string Text => "-hide_banner";
|
||||||
|
}
|
||||||
10
FFMpegCore/FFMpeg/Arguments/MainOptions/Stats.cs
Normal file
10
FFMpegCore/FFMpeg/Arguments/MainOptions/Stats.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace FFMpegCore.Arguments.MainOptions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg.html#Main-options" />
|
||||||
|
/// Explicitly disable logging of encoding progress/statistics.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class Stats(bool value) : BaseOptionArgument(value)
|
||||||
|
{
|
||||||
|
protected override string ArgumentName => "stats";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
namespace FFMpegCore.Arguments.Protocols.Rtsp;
|
||||||
|
|
||||||
|
public interface IRtspArgument : IArgument;
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
using FFMpegCore.Arguments.Formats;
|
||||||
|
|
||||||
|
namespace FFMpegCore.Arguments.Protocols.Rtsp;
|
||||||
|
|
||||||
|
public interface IRtspDemuxerArgument :
|
||||||
|
IRtspArgument,
|
||||||
|
IDemuxerArgument;
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
using FFMpegCore.Arguments.Formats;
|
||||||
|
|
||||||
|
namespace FFMpegCore.Arguments.Protocols.Rtsp;
|
||||||
|
|
||||||
|
public interface IRtspMuxerArgument :
|
||||||
|
IRtspArgument,
|
||||||
|
IDemuxerArgument;
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
using FFMpegCore.Enums;
|
||||||
|
|
||||||
|
namespace FFMpegCore.Arguments.Protocols.Rtsp;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-protocols.html#rtsp" />
|
||||||
|
/// </summary>
|
||||||
|
public sealed class RtspArgumentOptions
|
||||||
|
{
|
||||||
|
private readonly FFMpegArgumentOptions _options;
|
||||||
|
|
||||||
|
internal RtspArgumentOptions(FFMpegArgumentOptions options)
|
||||||
|
{
|
||||||
|
_options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="RtspTransportArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rtspTransportProtocol"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public RtspArgumentOptions WithRtspTransport(RtspTransportProtocol rtspTransportProtocol)
|
||||||
|
{
|
||||||
|
return WithArgument(new RtspTransportArgument(rtspTransportProtocol));
|
||||||
|
}
|
||||||
|
|
||||||
|
public RtspArgumentOptions WithArgument(IRtspArgument argument)
|
||||||
|
{
|
||||||
|
_options.WithArgument(argument);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
using FFMpegCore.Enums;
|
||||||
|
|
||||||
|
namespace FFMpegCore.Arguments.Protocols.Rtsp;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-protocols.html#rtsp" />
|
||||||
|
/// Set RTSP transport protocols.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class RtspTransportArgument(RtspTransportProtocol protocol) : IRtspMuxerArgument, IRtspDemuxerArgument
|
||||||
|
{
|
||||||
|
public string Text => $"-rtsp_transport {protocol}";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
namespace FFMpegCore.Arguments.VideoFilters.Vaapi;
|
||||||
|
|
||||||
|
public interface IVaapiVideoFilterArgument : IVideoFilterArgument;
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
using System.Drawing;
|
||||||
|
using FFMpegCore.Enums;
|
||||||
|
|
||||||
|
namespace FFMpegCore.Arguments.VideoFilters.Vaapi;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://www.ffmpeg.org/ffmpeg-filters.html#VAAPI-Video-Filters" />
|
||||||
|
/// </summary>
|
||||||
|
public sealed class VaapiVideoFilterOptions
|
||||||
|
{
|
||||||
|
private readonly VideoFilterOptions _options;
|
||||||
|
|
||||||
|
internal VaapiVideoFilterOptions(VideoFilterOptions options)
|
||||||
|
{
|
||||||
|
_options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="VideoFilterScaleVaapiArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="videosize"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public VaapiVideoFilterOptions Scale(VideoSize videosize)
|
||||||
|
{
|
||||||
|
return WithArgument(new VideoFilterScaleVaapiArgument(videosize));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="VideoFilterScaleVaapiArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="width"></param>
|
||||||
|
/// <param name="height"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public VaapiVideoFilterOptions Scale(int width, int height)
|
||||||
|
{
|
||||||
|
return WithArgument(new VideoFilterScaleVaapiArgument(width, height));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="VideoFilterScaleVaapiArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="size"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public VaapiVideoFilterOptions Scale(Size size)
|
||||||
|
{
|
||||||
|
return WithArgument(new VideoFilterScaleVaapiArgument(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
public VaapiVideoFilterOptions WithArgument(IVaapiVideoFilterArgument argument)
|
||||||
|
{
|
||||||
|
_options.Arguments.Add(argument);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
using System.Drawing;
|
||||||
|
using FFMpegCore.Enums;
|
||||||
|
|
||||||
|
namespace FFMpegCore.Arguments.VideoFilters.Vaapi;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://trac.ffmpeg.org/wiki/Hardware/VAAPI#SurfaceFormats" />
|
||||||
|
/// undocumented in: <see href="https://www.ffmpeg.org/ffmpeg-filters.html#VAAPI-Video-Filters" />
|
||||||
|
/// may refer to: <see href="https://www.ffmpeg.org/ffmpeg-filters.html#scale-1" />
|
||||||
|
/// </summary>
|
||||||
|
public sealed class VideoFilterScaleVaapiArgument : IVaapiVideoFilterArgument
|
||||||
|
{
|
||||||
|
private readonly Size? _size;
|
||||||
|
|
||||||
|
public VideoFilterScaleVaapiArgument(Size? size)
|
||||||
|
{
|
||||||
|
_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VideoFilterScaleVaapiArgument(int width, int height) : this(new Size(width, height)) { }
|
||||||
|
|
||||||
|
public VideoFilterScaleVaapiArgument(VideoSize videosize)
|
||||||
|
{
|
||||||
|
_size = videosize == VideoSize.Original ? null : new Size(-1, (int)videosize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Key => "scale_vaapi";
|
||||||
|
public string Value => _size == null ? string.Empty : $"{_size.Value.Width}:{_size.Value.Height}";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
namespace FFMpegCore.Arguments.VideoFilters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://www.ffmpeg.org/ffmpeg-filters.html#format-1" />
|
||||||
|
/// Convert the input video to one of the specified pixel formats.
|
||||||
|
/// Libavfilter will try to pick one that is suitable as input to the next filter.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class VideoFilterFormatArgument : IVideoFilterArgument
|
||||||
|
{
|
||||||
|
public string Key => "format";
|
||||||
|
public string Value { get; }
|
||||||
|
|
||||||
|
private VideoFilterFormatArgument(string pixelFormat)
|
||||||
|
{
|
||||||
|
Value = $"pix_fmts={pixelFormat}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public VideoFilterFormatArgument(params ReadOnlySpan<string?> pixelFormats)
|
||||||
|
#if NETSTANDARD2_1_OR_GREATER || NET8_OR_GREATER
|
||||||
|
: this(string.Join('|', pixelFormats))
|
||||||
|
#else
|
||||||
|
: this(string.Join("|", pixelFormats.ToArray()))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
namespace FFMpegCore.Arguments.VideoFilters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://www.ffmpeg.org/ffmpeg-filters.html#hwupload" />
|
||||||
|
/// Upload system memory frames to hardware surfaces.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class VideoFilterHardwareUploadArgument : IVideoFilterArgument
|
||||||
|
{
|
||||||
|
public string Key => string.Empty;
|
||||||
|
public string Value => "hwupload";
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using FFMpegCore.Arguments.VideoFilters;
|
||||||
|
using FFMpegCore.Arguments.VideoFilters.Vaapi;
|
||||||
using FFMpegCore.Enums;
|
using FFMpegCore.Enums;
|
||||||
using FFMpegCore.Exceptions;
|
using FFMpegCore.Exceptions;
|
||||||
|
|
||||||
|
|
@ -94,7 +96,32 @@ public class VideoFilterOptions
|
||||||
return WithArgument(new PadArgument(padOptions));
|
return WithArgument(new PadArgument(padOptions));
|
||||||
}
|
}
|
||||||
|
|
||||||
private VideoFilterOptions WithArgument(IVideoFilterArgument argument)
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="VideoFilterFormatArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pixelFormats"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public VideoFilterOptions Format(params ReadOnlySpan<string?> pixelFormats)
|
||||||
|
{
|
||||||
|
return WithArgument(new VideoFilterFormatArgument(pixelFormats));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="VideoFilterHardwareUploadArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public VideoFilterOptions HardwareUpload()
|
||||||
|
{
|
||||||
|
return WithArgument(new VideoFilterHardwareUploadArgument());
|
||||||
|
}
|
||||||
|
|
||||||
|
public VideoFilterOptions WithVaapiVideoFilter(Action<VaapiVideoFilterOptions> setupAction)
|
||||||
|
{
|
||||||
|
setupAction(new VaapiVideoFilterOptions(this));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VideoFilterOptions WithArgument(IVideoFilterArgument argument)
|
||||||
{
|
{
|
||||||
Arguments.Add(argument);
|
Arguments.Add(argument);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
using FFMpegCore.Enums;
|
||||||
|
|
||||||
|
namespace FFMpegCore.Arguments.VideoOptions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://trac.ffmpeg.org/wiki/Hardware/VAAPI#SurfaceFormats" />
|
||||||
|
/// undocumented in <see href="https://www.ffmpeg.org/ffmpeg.html#Advanced-Video-options" />
|
||||||
|
/// </summary>
|
||||||
|
public sealed class HardwareAccelerationOutputFormatArgument(HardwareAccelerationDevice hardwareAccelerationDevice) : IArgument
|
||||||
|
{
|
||||||
|
public string Text => $"-hwaccel_output_format {hardwareAccelerationDevice.ToString().ToLowerInvariant()}";
|
||||||
|
}
|
||||||
14
FFMpegCore/FFMpeg/Enums/RtspTransportProtocol.cs
Normal file
14
FFMpegCore/FFMpeg/Enums/RtspTransportProtocol.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace FFMpegCore.Enums;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://ffmpeg.org/ffmpeg-protocols.html#rtsp" />
|
||||||
|
/// RTSP transport protocols
|
||||||
|
/// </summary>
|
||||||
|
public enum RtspTransportProtocol
|
||||||
|
{
|
||||||
|
udp,
|
||||||
|
tcp,
|
||||||
|
udp_multicast,
|
||||||
|
http,
|
||||||
|
https,
|
||||||
|
}
|
||||||
42
FFMpegCore/FFMpeg/Enums/VaapiRcMode.cs
Normal file
42
FFMpegCore/FFMpeg/Enums/VaapiRcMode.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
namespace FFMpegCore.Enums;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <see href="https://www.ffmpeg.org/ffmpeg-codecs.html#VAAPI-encoders" />
|
||||||
|
/// </summary>
|
||||||
|
public enum VaapiRcMode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Choose the mode automatically based on driver support and the other options. This is the default.
|
||||||
|
/// </summary>
|
||||||
|
auto,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constant-quality.
|
||||||
|
/// </summary>
|
||||||
|
CQP,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constant-bitrate.
|
||||||
|
/// </summary>
|
||||||
|
CBR,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Variable-bitrate.
|
||||||
|
/// </summary>
|
||||||
|
VBR,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Intelligent constant-quality.
|
||||||
|
/// </summary>
|
||||||
|
ICQ,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Quality-defined variable-bitrate.
|
||||||
|
/// </summary>
|
||||||
|
QVBR,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Average variable bitrate.
|
||||||
|
/// </summary>
|
||||||
|
AVBR,
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using FFMpegCore.Arguments;
|
using FFMpegCore.Arguments;
|
||||||
|
using FFMpegCore.Arguments.Codecs.Vaapi;
|
||||||
|
using FFMpegCore.Arguments.Codecs.Vaapi.h264Vaapi;
|
||||||
|
using FFMpegCore.Arguments.Formats;
|
||||||
|
using FFMpegCore.Arguments.Formats.image2;
|
||||||
|
using FFMpegCore.Arguments.Formats.segment;
|
||||||
|
using FFMpegCore.Arguments.Protocols.Rtsp;
|
||||||
using FFMpegCore.Enums;
|
using FFMpegCore.Enums;
|
||||||
|
|
||||||
namespace FFMpegCore;
|
namespace FFMpegCore;
|
||||||
|
|
@ -268,6 +274,70 @@ public class FFMpegArgumentOptions : FFMpegArgumentsBase
|
||||||
return WithArgument(new CopyCodecArgument());
|
return WithArgument(new CopyCodecArgument());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="WithUseWallclockAsTimestamps"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public FFMpegArgumentOptions WithUseWallclockAsTimestamps(bool value = true)
|
||||||
|
{
|
||||||
|
return WithArgument(new UseWallclockAsTimestampsArgument(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="AnalyzeDurationArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="duration"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public FFMpegArgumentOptions WithAnalyzeDuration(TimeSpan duration)
|
||||||
|
{
|
||||||
|
return WithArgument(new AnalyzeDurationArgument(duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="ProbeSizeArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="probesizeInBytes"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public FFMpegArgumentOptions WithProbeSize(long probesizeInBytes = 5000000)
|
||||||
|
{
|
||||||
|
return WithArgument(new ProbeSizeArgument(probesizeInBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="VaapiRcModeArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rcMode"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public FFMpegArgumentOptions WithVaapiRcMode(VaapiRcMode rcMode)
|
||||||
|
{
|
||||||
|
return WithArgument(new VaapiRcModeArgument(rcMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
public FFMpegArgumentOptions WithImage2Options(Action<Image2ArgumentOptions> setupAction)
|
||||||
|
{
|
||||||
|
setupAction(new Image2ArgumentOptions(this));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FFMpegArgumentOptions WithSegmentOptions(Action<SegmentArgumentOptions> setupAction)
|
||||||
|
{
|
||||||
|
setupAction(new SegmentArgumentOptions(this));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FFMpegArgumentOptions WithH264VaapiOptions(Action<H264VaapiArgumentOptions> setupAction)
|
||||||
|
{
|
||||||
|
setupAction(new H264VaapiArgumentOptions(this));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FFMpegArgumentOptions WithRtspProtocolOptions(Action<RtspArgumentOptions> setupAction)
|
||||||
|
{
|
||||||
|
setupAction(new RtspArgumentOptions(this));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public FFMpegArgumentOptions WithArgument(IArgument argument)
|
public FFMpegArgumentOptions WithArgument(IArgument argument)
|
||||||
{
|
{
|
||||||
Arguments.Add(argument);
|
Arguments.Add(argument);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
using FFMpegCore.Arguments;
|
using FFMpegCore.Arguments;
|
||||||
|
using FFMpegCore.Arguments.GenericOptions;
|
||||||
|
using FFMpegCore.Arguments.MainOptions;
|
||||||
|
using FFMpegCore.Arguments.VideoOptions;
|
||||||
|
using FFMpegCore.Enums;
|
||||||
|
|
||||||
namespace FFMpegCore;
|
namespace FFMpegCore;
|
||||||
|
|
||||||
|
|
@ -8,10 +12,38 @@ public sealed class FFMpegGlobalArguments : FFMpegArgumentsBase
|
||||||
|
|
||||||
public FFMpegGlobalArguments WithVerbosityLevel(VerbosityLevel verbosityLevel = VerbosityLevel.Error)
|
public FFMpegGlobalArguments WithVerbosityLevel(VerbosityLevel verbosityLevel = VerbosityLevel.Error)
|
||||||
{
|
{
|
||||||
return WithOption(new VerbosityLevelArgument(verbosityLevel));
|
return WithArgument(new VerbosityLevelArgument(verbosityLevel));
|
||||||
}
|
}
|
||||||
|
|
||||||
private FFMpegGlobalArguments WithOption(IArgument argument)
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="HardwareAccelerationOutputFormatArgument"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="device"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public FFMpegGlobalArguments WithHardwareAccelerationOutputFormat(HardwareAccelerationDevice device)
|
||||||
|
{
|
||||||
|
return WithArgument(new HardwareAccelerationOutputFormatArgument(device));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="HideBanner"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public FFMpegGlobalArguments WithHideBanner()
|
||||||
|
{
|
||||||
|
return WithArgument(new HideBanner());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <inheritdoc cref="Stats"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public FFMpegGlobalArguments WithNoStats()
|
||||||
|
{
|
||||||
|
return WithArgument(new Stats(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public FFMpegGlobalArguments WithArgument(IArgument argument)
|
||||||
{
|
{
|
||||||
Arguments.Add(argument);
|
Arguments.Add(argument);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue