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;
namespace FFMpegCore.Arguments
namespace FFMpegCore.Arguments;
/// <summary>
/// Represents output parameter
/// </summary>
public class OutputSegmentArgument : IOutputArgument
{
/// <summary>
/// Represents output parameter
/// </summary>
public class OutputSegmentArgument : IOutputArgument
public readonly SegmentArgumentOptions Options;
public readonly bool Overwrite;
public readonly string SegmentPattern;
public OutputSegmentArgument(SegmentArgument segmentArgument)
{
public readonly string SegmentPattern;
public readonly bool Overwrite;
public readonly SegmentArgumentOptions Options;
public OutputSegmentArgument(SegmentArgument segmentArgument)
SegmentPattern = segmentArgument.SegmentPattern;
Overwrite = segmentArgument.Overwrite;
var segmentArgumentobj = new SegmentArgumentOptions();
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;
Overwrite = segmentArgument.Overwrite;
var segmentArgumentobj = new SegmentArgumentOptions();
segmentArgument.Options?.Invoke(segmentArgumentobj);
Options = segmentArgumentobj;
throw new FFMpegException(FFMpegExceptionType.Process, "Parameter SegmentTime cannot be negative or equal to zero");
}
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")
{
throw new FFMpegException(FFMpegExceptionType.Process, "Parameter SegmentWrap cannot equal to zero");
}
}
public Task During(CancellationToken cancellationToken = default) => 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 =>
{
return arg.Value;
});
return $"-f segment {string.Join(" ", arguments)} \"{SegmentPattern}\"{(Overwrite ? " -y" : string.Empty)}";
}
}
public interface ISegmentArgument
{
public string Key { get; }
public string Value { get; }
}
public class SegmentArgumentOptions
{
public List<ISegmentArgument> Arguments { get; } = new();
public SegmentArgumentOptions ResetTimeStamps(bool resetTimestamps = true) => WithArgument(new SegmentResetTimeStampsArgument(resetTimestamps));
public SegmentArgumentOptions Strftime(bool enable = false) => WithArgument(new SegmentStrftimeArgument(enable));
public SegmentArgumentOptions Time(int time = 60) => WithArgument(new SegmentTimeArgument(time));
public SegmentArgumentOptions Wrap(int limit = -1) => WithArgument(new SegmentWrapArgument(limit));
public SegmentArgumentOptions WithCustomArgument(string argument) => WithArgument(new SegmentCustomArgument(argument));
private SegmentArgumentOptions WithArgument(ISegmentArgument argument)
{
Arguments.Add(argument);
return this;
}
}
public class SegmentArgument
{
public readonly string SegmentPattern;
public readonly bool Overwrite;
public readonly Action<SegmentArgumentOptions> Options;
public SegmentArgument(string segmentPattern, bool overwrite, Action<SegmentArgumentOptions> options)
{
SegmentPattern = segmentPattern;
Overwrite = overwrite;
Options = options;
}
return $"-f segment {string.Join(" ", arguments)} \"{SegmentPattern}\"{(Overwrite ? " -y" : string.Empty)}";
}
}
public interface ISegmentArgument
{
public string Key { get; }
public string Value { get; }
}
public class SegmentArgumentOptions
{
public List<ISegmentArgument> Arguments { get; } = new();
public SegmentArgumentOptions ResetTimeStamps(bool resetTimestamps = true)
{
return WithArgument(new SegmentResetTimeStampsArgument(resetTimestamps));
}
public SegmentArgumentOptions Strftime(bool enable = false)
{
return WithArgument(new SegmentStrftimeArgument(enable));
}
public SegmentArgumentOptions Time(int time = 60)
{
return WithArgument(new SegmentTimeArgument(time));
}
public SegmentArgumentOptions Wrap(int limit = -1)
{
return WithArgument(new SegmentWrapArgument(limit));
}
public SegmentArgumentOptions WithCustomArgument(string argument)
{
return WithArgument(new SegmentCustomArgument(argument));
}
private SegmentArgumentOptions WithArgument(ISegmentArgument argument)
{
Arguments.Add(argument);
return this;
}
}
public class SegmentArgument
{
public readonly Action<SegmentArgumentOptions> Options;
public readonly bool Overwrite;
public readonly string SegmentPattern;
public SegmentArgument(string segmentPattern, bool overwrite, Action<SegmentArgumentOptions> options)
{
SegmentPattern = segmentPattern;
Overwrite = overwrite;
Options = options;
}
}

View file

@ -1,14 +1,14 @@
namespace FFMpegCore.Arguments
{
public class SegmentCustomArgument : ISegmentArgument
{
public readonly string Argument;
namespace FFMpegCore.Arguments;
public SegmentCustomArgument(string argument)
{
Argument = argument;
}
public string Key => "custom";
public string Value => Argument ?? string.Empty;
public class SegmentCustomArgument : ISegmentArgument
{
public readonly string Argument;
public SegmentCustomArgument(string argument)
{
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>
/// Represents reset_timestamps parameter
/// Represents reset_timestamps parameter
/// </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;
/// <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;
ResetTimestamps = resetTimestamps;
}
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>
/// 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>
public class SegmentStrftimeArgument : ISegmentArgument
/// <param name="enable">true to enable strftime</param>
public SegmentStrftimeArgument(bool enable)
{
public readonly bool 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;
Enable = enable;
}
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>
/// Represents segment_time parameter
/// Represents segment_time parameter
/// </summary>
public class SegmentTimeArgument : ISegmentArgument
/// <param name="time">time in seconds of the segment</param>
public SegmentTimeArgument(int time)
{
public readonly int 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}";
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>
/// Represents segment_wrap parameter
/// Represents segment_wrap parameter
/// </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;
/// <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}";
Limit = 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 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>
/// Working directory for the ffmpeg/ffprobe instance
/// </summary>
public string WorkingDirectory { get; set; } = string.Empty;
get => Encoding.GetEncoding(EncodingWebName);
set => EncodingWebName = value?.WebName ?? Encoding.Default.WebName;
}
/// <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>
/// The log level to use when calling of the ffmpeg executable.
/// <para>
/// 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>
/// Folder used for temporary files necessary for static methods on FFMpeg class
/// </summary>
public string TemporaryFilesFolder { get; set; } = Path.GetTempPath();
/// <summary>
/// </summary>
public Dictionary<string, string> ExtensionOverrides { get; set; } = new() { { "mpegts", ".ts" } };
/// <summary>
/// Encoding web name used to persist encoding <see cref="Encoding"/>
/// </summary>
public string EncodingWebName { get; set; } = Encoding.Default.WebName;
/// <summary>
/// Whether to cache calls to get ffmpeg codec, pixel- and container-formats
/// </summary>
public bool UseCache { get; set; } = true;
/// <summary>
/// Encoding used for parsing stdout/stderr on ffmpeg and ffprobe processes
/// </summary>
[JsonIgnore]
public Encoding Encoding
{
get => Encoding.GetEncoding(EncodingWebName);
set => EncodingWebName = value?.WebName ?? Encoding.Default.WebName;
}
/// <inheritdoc />
object ICloneable.Clone()
{
return Clone();
}
/// <summary>
/// The log level to use when calling of the ffmpeg executable.
/// <para>
/// 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>
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();
/// <summary>
/// Creates a new object that is a copy of the current instance.
/// </summary>
public FFOptions Clone()
{
return (FFOptions)MemberwiseClone();
}
}