Run code cleanup

This commit is contained in:
Malte Rosenbjerg 2025-10-16 15:14:14 +02:00
parent c60e217a2f
commit 0956870875
7 changed files with 232 additions and 199 deletions

View file

@ -1,88 +1,114 @@
using FFMpegCore.Exceptions; using FFMpegCore.Exceptions;
namespace FFMpegCore.Arguments namespace FFMpegCore.Arguments;
/// <summary>
/// Represents output parameter
/// </summary>
public class OutputSegmentArgument : IOutputArgument
{ {
/// <summary> public readonly SegmentArgumentOptions Options;
/// Represents output parameter public readonly bool Overwrite;
/// </summary> public readonly string SegmentPattern;
public class OutputSegmentArgument : IOutputArgument
public OutputSegmentArgument(SegmentArgument segmentArgument)
{ {
public readonly string SegmentPattern; SegmentPattern = segmentArgument.SegmentPattern;
public readonly bool Overwrite; Overwrite = segmentArgument.Overwrite;
public readonly SegmentArgumentOptions Options; var segmentArgumentobj = new SegmentArgumentOptions();
public OutputSegmentArgument(SegmentArgument segmentArgument) segmentArgument.Options?.Invoke(segmentArgumentobj);
Options = segmentArgumentobj;
}
public void Pre()
{
if (int.TryParse(Options.Arguments.FirstOrDefault(x => x.Key == "segment_time").Value, out var result) && result < 1)
{ {
SegmentPattern = segmentArgument.SegmentPattern; throw new FFMpegException(FFMpegExceptionType.Process, "Parameter SegmentTime cannot be negative or equal to zero");
Overwrite = segmentArgument.Overwrite;
var segmentArgumentobj = new SegmentArgumentOptions();
segmentArgument.Options?.Invoke(segmentArgumentobj);
Options = segmentArgumentobj;
} }
public void Pre() if (Options.Arguments.FirstOrDefault(x => x.Key == "segment_time").Value == "0")
{ {
if (int.TryParse(Options.Arguments.FirstOrDefault(x => x.Key == "segment_time").Value, out var result) && result < 1) throw new FFMpegException(FFMpegExceptionType.Process, "Parameter SegmentWrap cannot equal to zero");
}
}
public Task During(CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}
public void Post()
{
}
public string Text => GetText();
private string GetText()
{
var arguments = Options.Arguments
.Where(arg => !string.IsNullOrWhiteSpace(arg.Value) && !string.IsNullOrWhiteSpace(arg.Key))
.Select(arg =>
{ {
throw new FFMpegException(FFMpegExceptionType.Process, "Parameter SegmentTime cannot be negative or equal to zero"); return arg.Value;
} });
if (Options.Arguments.FirstOrDefault(x => x.Key == "segment_time").Value == "0") return $"-f segment {string.Join(" ", arguments)} \"{SegmentPattern}\"{(Overwrite ? " -y" : string.Empty)}";
{ }
throw new FFMpegException(FFMpegExceptionType.Process, "Parameter SegmentWrap cannot equal to zero"); }
}
} public interface ISegmentArgument
public Task During(CancellationToken cancellationToken = default) => Task.CompletedTask; {
public void Post() public string Key { get; }
{ public string Value { get; }
} }
public string Text => GetText(); public class SegmentArgumentOptions
private string GetText() {
{ public List<ISegmentArgument> Arguments { get; } = new();
var arguments = Options.Arguments
.Where(arg => !string.IsNullOrWhiteSpace(arg.Value) && !string.IsNullOrWhiteSpace(arg.Key)) public SegmentArgumentOptions ResetTimeStamps(bool resetTimestamps = true)
.Select(arg => {
{ return WithArgument(new SegmentResetTimeStampsArgument(resetTimestamps));
return arg.Value; }
});
public SegmentArgumentOptions Strftime(bool enable = false)
return $"-f segment {string.Join(" ", arguments)} \"{SegmentPattern}\"{(Overwrite ? " -y" : string.Empty)}"; {
} return WithArgument(new SegmentStrftimeArgument(enable));
} }
public interface ISegmentArgument public SegmentArgumentOptions Time(int time = 60)
{ {
public string Key { get; } return WithArgument(new SegmentTimeArgument(time));
public string Value { get; } }
}
public SegmentArgumentOptions Wrap(int limit = -1)
public class SegmentArgumentOptions {
{ return WithArgument(new SegmentWrapArgument(limit));
public List<ISegmentArgument> Arguments { get; } = new(); }
public SegmentArgumentOptions ResetTimeStamps(bool resetTimestamps = true) => WithArgument(new SegmentResetTimeStampsArgument(resetTimestamps)); public SegmentArgumentOptions WithCustomArgument(string argument)
public SegmentArgumentOptions Strftime(bool enable = false) => WithArgument(new SegmentStrftimeArgument(enable)); {
public SegmentArgumentOptions Time(int time = 60) => WithArgument(new SegmentTimeArgument(time)); return WithArgument(new SegmentCustomArgument(argument));
public SegmentArgumentOptions Wrap(int limit = -1) => WithArgument(new SegmentWrapArgument(limit)); }
public SegmentArgumentOptions WithCustomArgument(string argument) => WithArgument(new SegmentCustomArgument(argument));
private SegmentArgumentOptions WithArgument(ISegmentArgument argument) private SegmentArgumentOptions WithArgument(ISegmentArgument argument)
{ {
Arguments.Add(argument); Arguments.Add(argument);
return this; return this;
} }
} }
public class SegmentArgument public class SegmentArgument
{ {
public readonly string SegmentPattern; public readonly Action<SegmentArgumentOptions> Options;
public readonly bool Overwrite; public readonly bool Overwrite;
public readonly Action<SegmentArgumentOptions> Options; public readonly string SegmentPattern;
public SegmentArgument(string segmentPattern, bool overwrite, Action<SegmentArgumentOptions> options) public SegmentArgument(string segmentPattern, bool overwrite, Action<SegmentArgumentOptions> options)
{ {
SegmentPattern = segmentPattern; SegmentPattern = segmentPattern;
Overwrite = overwrite; Overwrite = overwrite;
Options = options; Options = options;
}
} }
} }

View file

@ -1,14 +1,14 @@
namespace FFMpegCore.Arguments namespace FFMpegCore.Arguments;
{
public class SegmentCustomArgument : ISegmentArgument
{
public readonly string Argument;
public SegmentCustomArgument(string argument) public class SegmentCustomArgument : ISegmentArgument
{ {
Argument = argument; public readonly string Argument;
}
public string Key => "custom"; public SegmentCustomArgument(string argument)
public string Value => Argument ?? string.Empty; {
Argument = argument;
} }
public string Key => "custom";
public string Value => Argument ?? string.Empty;
} }

View file

@ -1,20 +1,21 @@
namespace FFMpegCore.Arguments namespace FFMpegCore.Arguments;
/// <summary>
/// Represents reset_timestamps parameter
/// </summary>
public class SegmentResetTimeStampsArgument : ISegmentArgument
{ {
public readonly bool ResetTimestamps;
/// <summary> /// <summary>
/// Represents reset_timestamps parameter /// Represents reset_timestamps parameter
/// </summary> /// </summary>
public class SegmentResetTimeStampsArgument : ISegmentArgument /// <param name="resetTimestamps">true if files timestamps are to be reset</param>
public SegmentResetTimeStampsArgument(bool resetTimestamps)
{ {
public readonly bool ResetTimestamps; ResetTimestamps = resetTimestamps;
/// <summary>
/// Represents reset_timestamps parameter
/// </summary>
/// <param name="resetTimestamps">true if files timestamps are to be reset</param>
public SegmentResetTimeStampsArgument(bool resetTimestamps)
{
ResetTimestamps = resetTimestamps;
}
public string Key { get; } = "reset_timestamps";
public string Value => ResetTimestamps ? $"-reset_timestamps 1" : string.Empty;
} }
public string Key { get; } = "reset_timestamps";
public string Value => ResetTimestamps ? "-reset_timestamps 1" : string.Empty;
} }

View file

@ -1,20 +1,23 @@
namespace FFMpegCore.Arguments namespace FFMpegCore.Arguments;
/// <summary>
/// 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 class SegmentStrftimeArgument : ISegmentArgument
{ {
public readonly bool Enable;
/// <summary> /// <summary>
/// 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. /// 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> /// </summary>
public class SegmentStrftimeArgument : ISegmentArgument /// <param name="enable">true to enable strftime</param>
public SegmentStrftimeArgument(bool enable)
{ {
public readonly bool Enable; Enable = enable;
/// <summary>
/// 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>
/// <param name="enable">true to enable strftime</param>
public SegmentStrftimeArgument(bool enable)
{
Enable = enable;
}
public string Key { get; } = "strftime";
public string Value => Enable ? $"-strftime 1" : string.Empty;
} }
public string Key { get; } = "strftime";
public string Value => Enable ? "-strftime 1" : string.Empty;
} }

View file

@ -1,20 +1,21 @@
namespace FFMpegCore.Arguments namespace FFMpegCore.Arguments;
/// <summary>
/// Represents segment_time parameter
/// </summary>
public class SegmentTimeArgument : ISegmentArgument
{ {
public readonly int Time;
/// <summary> /// <summary>
/// Represents segment_time parameter /// Represents segment_time parameter
/// </summary> /// </summary>
public class SegmentTimeArgument : ISegmentArgument /// <param name="time">time in seconds of the segment</param>
public SegmentTimeArgument(int time)
{ {
public readonly int Time; Time = time;
/// <summary>
/// Represents segment_time parameter
/// </summary>
/// <param name="time">time in seconds of the segment</param>
public SegmentTimeArgument(int time)
{
Time = time;
}
public string Key { get; } = "segment_time";
public string Value => Time <= 0 ? string.Empty : $"-segment_time {Time}";
} }
public string Key { get; } = "segment_time";
public string Value => Time <= 0 ? string.Empty : $"-segment_time {Time}";
} }

View file

@ -1,20 +1,21 @@
namespace FFMpegCore.Arguments namespace FFMpegCore.Arguments;
/// <summary>
/// Represents segment_wrap parameter
/// </summary>
public class SegmentWrapArgument : ISegmentArgument
{ {
public readonly int Limit;
/// <summary> /// <summary>
/// Represents segment_wrap parameter /// Represents segment_wrap parameter
/// </summary> /// </summary>
public class SegmentWrapArgument : ISegmentArgument /// <param name="limit">limit value after which segment index will wrap around</param>
public SegmentWrapArgument(int limit)
{ {
public readonly int Limit; Limit = limit;
/// <summary>
/// Represents segment_wrap parameter
/// </summary>
/// <param name="limit">limit value after which segment index will wrap around</param>
public SegmentWrapArgument(int limit)
{
Limit = limit;
}
public string Key { get; } = "segment_wrap";
public string Value => Limit <= 0 ? string.Empty : $"-segment_wrap {Limit}";
} }
public string Key { get; } = "segment_wrap";
public string Value => Limit <= 0 ? string.Empty : $"-segment_wrap {Limit}";
} }

View file

@ -2,68 +2,69 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using FFMpegCore.Enums; using FFMpegCore.Enums;
namespace FFMpegCore namespace FFMpegCore;
public class FFOptions : ICloneable
{ {
public class FFOptions : ICloneable /// <summary>
/// Working directory for the ffmpeg/ffprobe instance
/// </summary>
public string WorkingDirectory { get; set; } = string.Empty;
/// <summary>
/// Folder container ffmpeg and ffprobe binaries. Leave empty if ffmpeg and ffprobe are present in PATH
/// </summary>
public string BinaryFolder { get; set; } = string.Empty;
/// <summary>
/// Folder used for temporary files necessary for static methods on FFMpeg class
/// </summary>
public string TemporaryFilesFolder { get; set; } = Path.GetTempPath();
/// <summary>
/// Encoding web name used to persist encoding <see cref="Encoding" />
/// </summary>
public string EncodingWebName { get; set; } = Encoding.Default.WebName;
/// <summary>
/// Encoding used for parsing stdout/stderr on ffmpeg and ffprobe processes
/// </summary>
[JsonIgnore]
public Encoding Encoding
{ {
/// <summary> get => Encoding.GetEncoding(EncodingWebName);
/// Working directory for the ffmpeg/ffprobe instance set => EncodingWebName = value?.WebName ?? Encoding.Default.WebName;
/// </summary> }
public string WorkingDirectory { get; set; } = string.Empty;
/// <summary> /// <summary>
/// Folder container ffmpeg and ffprobe binaries. Leave empty if ffmpeg and ffprobe are present in PATH /// The log level to use when calling of the ffmpeg executable.
/// </summary> /// <para>
public string BinaryFolder { get; set; } = string.Empty; /// This option can be overridden before an execution of a Process command
/// to set the log level for that command.
/// </para>
/// </summary>
public FFMpegLogLevel? LogLevel { get; set; }
/// <summary> /// <summary>
/// Folder used for temporary files necessary for static methods on FFMpeg class /// </summary>
/// </summary> public Dictionary<string, string> ExtensionOverrides { get; set; } = new() { { "mpegts", ".ts" } };
public string TemporaryFilesFolder { get; set; } = Path.GetTempPath();
/// <summary> /// <summary>
/// Encoding web name used to persist encoding <see cref="Encoding"/> /// Whether to cache calls to get ffmpeg codec, pixel- and container-formats
/// </summary> /// </summary>
public string EncodingWebName { get; set; } = Encoding.Default.WebName; public bool UseCache { get; set; } = true;
/// <summary> /// <inheritdoc />
/// Encoding used for parsing stdout/stderr on ffmpeg and ffprobe processes object ICloneable.Clone()
/// </summary> {
[JsonIgnore] return Clone();
public Encoding Encoding }
{
get => Encoding.GetEncoding(EncodingWebName);
set => EncodingWebName = value?.WebName ?? Encoding.Default.WebName;
}
/// <summary> /// <summary>
/// The log level to use when calling of the ffmpeg executable. /// Creates a new object that is a copy of the current instance.
/// <para> /// </summary>
/// This option can be overridden before an execution of a Process command public FFOptions Clone()
/// to set the log level for that command. {
/// </para> return (FFOptions)MemberwiseClone();
/// </summary>
public FFMpegLogLevel? LogLevel { get; set; }
/// <summary>
///
/// </summary>
public Dictionary<string, string> ExtensionOverrides { get; set; } = new()
{
{ "mpegts", ".ts" },
};
/// <summary>
/// Whether to cache calls to get ffmpeg codec, pixel- and container-formats
/// </summary>
public bool UseCache { get; set; } = true;
/// <inheritdoc/>
object ICloneable.Clone() => Clone();
/// <summary>
/// Creates a new object that is a copy of the current instance.
/// </summary>
public FFOptions Clone() => (FFOptions)MemberwiseClone();
} }
} }