Merge pull request #373 from koskit/master

Implemented LogLevels and missing Arguments (BlackDetect & BlackFrame)
This commit is contained in:
Malte Rosenbjerg 2023-01-31 20:32:05 +01:00 committed by GitHub
commit 3c316505c0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 86 additions and 3 deletions

View file

@ -0,0 +1,14 @@
namespace FFMpegCore.Arguments
{
public class BlackDetectArgument : IVideoFilterArgument
{
public string Key => "blackdetect";
public string Value { get; }
public BlackDetectArgument(double minimumDuration = 2.0, double pictureBlackRatioThreshold = 0.98, double pixelBlackThreshold = 0.1)
{
Value = $"d={minimumDuration}:pic_th={pictureBlackRatioThreshold}:pix_th={pixelBlackThreshold}";
}
}
}

View file

@ -0,0 +1,14 @@
namespace FFMpegCore.Arguments
{
internal class BlackFrameArgument : IVideoFilterArgument
{
public string Key => "blackframe";
public string Value { get; }
public BlackFrameArgument(int amount = 98, int threshold = 32)
{
Value = $"amount={amount}:threshold={threshold}";
}
}
}

View file

@ -51,6 +51,8 @@ public class VideoFilterOptions
public VideoFilterOptions Mirror(Mirroring mirroring) => WithArgument(new SetMirroringArgument(mirroring)); public VideoFilterOptions Mirror(Mirroring mirroring) => WithArgument(new SetMirroringArgument(mirroring));
public VideoFilterOptions DrawText(DrawTextOptions drawTextOptions) => WithArgument(new DrawTextArgument(drawTextOptions)); public VideoFilterOptions DrawText(DrawTextOptions drawTextOptions) => WithArgument(new DrawTextArgument(drawTextOptions));
public VideoFilterOptions HardBurnSubtitle(SubtitleHardBurnOptions subtitleHardBurnOptions) => WithArgument(new SubtitleHardBurnArgument(subtitleHardBurnOptions)); public VideoFilterOptions HardBurnSubtitle(SubtitleHardBurnOptions subtitleHardBurnOptions) => WithArgument(new SubtitleHardBurnArgument(subtitleHardBurnOptions));
public VideoFilterOptions BlackDetect(double minimumDuration = 2.0, double pictureBlackRatioThreshold = 0.98, double pixelBlackThreshold = 0.1) => WithArgument(new BlackDetectArgument(minimumDuration, pictureBlackRatioThreshold, pixelBlackThreshold));
public VideoFilterOptions BlackFrame(int amount = 98, int threshold = 32) => WithArgument(new BlackFrameArgument(amount, threshold));
private VideoFilterOptions WithArgument(IVideoFilterArgument argument) private VideoFilterOptions WithArgument(IVideoFilterArgument argument)
{ {

View file

@ -0,0 +1,15 @@
namespace FFMpegCore.Enums
{
public enum FFMpegLogLevel
{
Quiet = 0,
Panic = 1,
Fatal = 2,
Error = 3,
Warning = 4,
Info = 5,
Verbose = 6,
Debug = 7,
Trace = 8
}
}

View file

@ -8,6 +8,7 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FFMpegCore.Enums;
namespace FFMpegCore namespace FFMpegCore
{ {
@ -21,6 +22,7 @@ public class FFMpegArgumentProcessor
private Action<string>? _onOutput; private Action<string>? _onOutput;
private Action<string>? _onError; private Action<string>? _onError;
private TimeSpan? _totalTimespan; private TimeSpan? _totalTimespan;
private FFMpegLogLevel? _logLevel;
internal FFMpegArgumentProcessor(FFMpegArguments ffMpegArguments) internal FFMpegArgumentProcessor(FFMpegArguments ffMpegArguments)
{ {
@ -83,12 +85,23 @@ public FFMpegArgumentProcessor Configure(Action<FFOptions> configureOptions)
_configurations.Add(configureOptions); _configurations.Add(configureOptions);
return this; return this;
} }
/// <summary>
/// Sets the log level of this process. Overides the <see cref="FFMpegLogLevel"/>
/// that is set in the <see cref="FFOptions"/> for this specific process.
/// </summary>
/// <param name="logLevel">The log level of the ffmpeg execution.</param>
public FFMpegArgumentProcessor WithLogLevel(FFMpegLogLevel logLevel)
{
_logLevel = logLevel;
return this;
}
public bool ProcessSynchronously(bool throwOnError = true, FFOptions? ffMpegOptions = null) public bool ProcessSynchronously(bool throwOnError = true, FFOptions? ffMpegOptions = null)
{ {
var options = GetConfiguredOptions(ffMpegOptions); var options = GetConfiguredOptions(ffMpegOptions);
var processArguments = PrepareProcessArguments(options, out var cancellationTokenSource); var processArguments = PrepareProcessArguments(options, out var cancellationTokenSource);
IProcessResult? processResult = null; IProcessResult? processResult = null;
try try
{ {
@ -193,10 +206,25 @@ private ProcessArguments PrepareProcessArguments(FFOptions ffOptions,
{ {
FFMpegHelper.RootExceptionCheck(); FFMpegHelper.RootExceptionCheck();
FFMpegHelper.VerifyFFMpegExists(ffOptions); FFMpegHelper.VerifyFFMpegExists(ffOptions);
string? arguments = _ffMpegArguments.Text;
//If local loglevel is null, set the global.
if (_logLevel == null)
_logLevel = ffOptions.LogLevel;
//If neither local nor global loglevel is null, set the argument.
if (_logLevel != null)
{
string normalizedLogLevel = _logLevel.ToString()
.ToLower();
arguments += $" -v {normalizedLogLevel}";
}
var startInfo = new ProcessStartInfo var startInfo = new ProcessStartInfo
{ {
FileName = GlobalFFOptions.GetFFMpegBinaryPath(ffOptions), FileName = GlobalFFOptions.GetFFMpegBinaryPath(ffOptions),
Arguments = _ffMpegArguments.Text, Arguments = arguments,
StandardOutputEncoding = ffOptions.Encoding, StandardOutputEncoding = ffOptions.Encoding,
StandardErrorEncoding = ffOptions.Encoding, StandardErrorEncoding = ffOptions.Encoding,
WorkingDirectory = ffOptions.WorkingDirectory WorkingDirectory = ffOptions.WorkingDirectory

View file

@ -1,4 +1,5 @@
using System; using FFMpegCore.Enums;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
@ -27,6 +28,15 @@ public class FFOptions : ICloneable
/// </summary> /// </summary>
public Encoding Encoding { get; set; } = Encoding.Default; public Encoding Encoding { get; set; } = Encoding.Default;
/// <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>
/// ///
/// </summary> /// </summary>