FF-1255 - added ffmpeg model logging

This commit is contained in:
John Andrews
2024-02-02 11:31:28 +13:00
parent 9ad7a51a62
commit 13863ec9e2
5 changed files with 213 additions and 106 deletions

View File

@@ -44,8 +44,30 @@ namespace FileFlows.VideoNodes.FfmpegBuilderNodes
if(this is FfmpegBuilderStart == false && Model == null)
throw new Exception("FFMPEG Builder Model not set, you must add and use the \"FFMPEG Builder Start\" node first");
if (this is FfmpegBuilderStart == false && Model.VideoInfo == null)
throw new Exception("FFMPEG Builder VideoInfo is null");
if (this is FfmpegBuilderStart == false)
{
if (Model.VideoInfo == null)
throw new Exception("FFMPEG Builder VideoInfo is null");
string header = "------------------------ Starting FFmpeg Builder Model ------------------------";
args.Logger?.ILog(header);
foreach (var stream in Model.VideoStreams ?? new List<FfmpegVideoStream>())
{
string line = "| Video Stream: " + stream;
args.Logger?.ILog(line + new string(' ', Math.Max(1, header.Length - line.Length - 1)) + '|');
}
foreach (var stream in Model.AudioStreams ?? new List<FfmpegAudioStream>())
{
string line = "| Audio Stream: " + stream;
args.Logger?.ILog(line + new string(' ', Math.Max(1, header.Length - line.Length - 1)) + '|');
}
foreach (var stream in Model.SubtitleStreams ?? new List<FfmpegSubtitleStream>())
{
string line = "| Subtitle Stream: " + stream;
args.Logger?.ILog(line + new string(' ', Math.Max(1, header.Length - line.Length - 1)) + '|');
}
args.Logger?.ILog(new string('-', header.Length));
}
return true;
}

View File

@@ -136,7 +136,15 @@ public class FfmpegBuilderTrackSorter : FfmpegBuilderNode
// Replace the unsorted items with the sorted ones
for (int i = 0; i < streams.Count; i++)
{
changes |= streams[i] != orderedStreams[i];
bool newDefault = i == 0;
bool changed = streams[i] != orderedStreams[i] || orderedStreams[i].IsDefault != newDefault;
streams[i].IsDefault = newDefault;
if (changed)
{
streams[i].ForcedChange = true;
orderedStreams[i].ForcedChange = true;
}
changes |= changed;
streams[i] = orderedStreams[i];
}
@@ -145,12 +153,13 @@ public class FfmpegBuilderTrackSorter : FfmpegBuilderNode
internal List<T> SortStreams<T>(NodeParameters args, List<T> streams) where T : FfmpegStream
{
if (streams?.Any() != true || Sorters?.Any() != true)
if (streams?.Any() != true || Sorters?.Any() != true || streams.Count == 1)
return streams;
return streams.OrderBy(stream =>
{
var sortKey = GetSortKey(args, stream);
// we add a 1 to deleted ones first, so they are always sorted after non-deleted ones
var sortKey = (stream.Deleted ? "1|" : "0|") + GetSortKey(args, stream);
args.Logger?.ILog(stream.ToString() + " -> sort key = " + sortKey);
return sortKey;
})
@@ -311,8 +320,8 @@ public class FfmpegBuilderTrackSorter : FfmpegBuilderNode
// Make an educated guess for Mbps to kbps conversion
return adjustedComparison[..^4] switch
{
{ } value when double.TryParse(value, out var numericValue) => (numericValue * 1_000_000).ToString(
CultureInfo.InvariantCulture),
{ } value when double.TryParse(value, out var numericValue) => (numericValue * 1_000_000)
.ToString(CultureInfo.InvariantCulture),
_ => comparisonValue
};
}
@@ -321,32 +330,84 @@ public class FfmpegBuilderTrackSorter : FfmpegBuilderNode
// Make an educated guess for kbps to bps conversion
return adjustedComparison[..^4] switch
{
{ } value when double.TryParse(value, out var numericValue) => (numericValue * 1_000).ToString(
CultureInfo.InvariantCulture),
{ } value when double.TryParse(value, out var numericValue) => (numericValue * 1_000)
.ToString(CultureInfo.InvariantCulture),
_ => comparisonValue
};
}
if (adjustedComparison.EndsWith("kb"))
{
return adjustedComparison[..^2] switch
{
{ } value when double.TryParse(value, out var numericValue) => (numericValue * 1_000 )
.ToString(CultureInfo.InvariantCulture),
_ => comparisonValue
};
}
if (adjustedComparison.EndsWith("mb"))
{
return adjustedComparison[..^2] switch
{
{ } value when double.TryParse(value, out var numericValue) => (numericValue * 1_000_000 )
.ToString(CultureInfo.InvariantCulture),
_ => comparisonValue
};
}
if (adjustedComparison.EndsWith("gb"))
{
// Make an educated guess for GB to bytes conversion
return adjustedComparison[..^2] switch
{
{ } value when double.TryParse(value, out var numericValue) => (numericValue * Math.Pow(1024, 3))
{ } value when double.TryParse(value, out var numericValue) => (numericValue * 1_000_000_000 )
.ToString(CultureInfo.InvariantCulture),
_ => comparisonValue
};
}
if (adjustedComparison.EndsWith("tb"))
{
// Make an educated guess for TB to bytes conversion
return adjustedComparison[..^2] switch
{
{ } value when double.TryParse(value, out var numericValue) => (numericValue * Math.Pow(1024, 4))
{ } value when double.TryParse(value, out var numericValue) => (numericValue * 1_000_000_000_000)
.ToString(CultureInfo.InvariantCulture),
_ => comparisonValue
};
}
if (adjustedComparison.EndsWith("kib"))
{
return adjustedComparison[..^3] switch
{
{ } value when double.TryParse(value, out var numericValue) => (numericValue * 1_024 )
.ToString(CultureInfo.InvariantCulture),
_ => comparisonValue
};
}
if (adjustedComparison.EndsWith("mib"))
{
return adjustedComparison[..^3] switch
{
{ } value when double.TryParse(value, out var numericValue) => (numericValue * 1_048_576 )
.ToString(CultureInfo.InvariantCulture),
_ => comparisonValue
};
}
if (adjustedComparison.EndsWith("gib"))
{
return adjustedComparison[..^3] switch
{
{ } value when double.TryParse(value, out var numericValue) => (numericValue * 1_099_511_627_776 )
.ToString(CultureInfo.InvariantCulture),
_ => comparisonValue
};
}
if (adjustedComparison.EndsWith("tib"))
{
return adjustedComparison[..^3] switch
{
{ } value when double.TryParse(value, out var numericValue) => (numericValue * 1_000_000_000_000)
.ToString(CultureInfo.InvariantCulture),
_ => comparisonValue
};
}
return comparisonValue;
}
@@ -420,6 +481,7 @@ public class FfmpegBuilderTrackSorter : FfmpegBuilderNode
case "==":
return Math.Abs(Convert.ToDouble(value) - Convert.ToDouble(AdjustComparisonValue(operation[2..].Trim()))) < 0.05f;
case "!=":
case "<>":
return Math.Abs(Convert.ToDouble(value) - Convert.ToDouble(AdjustComparisonValue(operation[2..].Trim()))) > 0.05f;
}

View File

@@ -99,7 +99,7 @@
public override string ToString()
{
if (Stream != null)
return Stream.ToString();
return Stream.ToString() + (Deleted ? " / Deleted" : "");
// can be null in unit tests
return string.Join(" / ", new string[]
{
@@ -107,7 +107,8 @@
Language,
Codec,
Title,
Channels > 0 ? Channels.ToString("0.0") : null
Channels > 0 ? Channels.ToString("0.0") : null,
Deleted ? "Deleted" : null
}.Where(x => string.IsNullOrWhiteSpace(x) == false));
}
}

View File

@@ -92,14 +92,16 @@ public class FfmpegSubtitleStream : FfmpegStream
public override string ToString()
{
if (Stream != null)
return Stream.ToString();
return Stream.ToString() + (Deleted ? " / Deleted" : "");
// can be null in unit tests
return string.Join(" / ", new string[]
{
Index.ToString(),
Language,
Codec,
Title
Title,
Deleted ? "Deleted" : null
}.Where(x => string.IsNullOrWhiteSpace(x) == false));
}
}

View File

@@ -1,115 +1,135 @@
namespace FileFlows.VideoNodes.FfmpegBuilderNodes.Models
namespace FileFlows.VideoNodes.FfmpegBuilderNodes.Models;
public class FfmpegVideoStream : FfmpegStream
{
public class FfmpegVideoStream : FfmpegStream
public VideoStream Stream { get; set; }
private List<string> _Filter = new List<string>();
public List<string> Filter
{
public VideoStream Stream { get; set; }
private List<string> _Filter = new List<string>();
public List<string> Filter
get => _Filter;
set
{
get => _Filter;
set
{
_Filter = value ?? new List<string>();
}
_Filter = value ?? new List<string>();
}
private List<string> _OptionalFilter = new List<string>();
}
private List<string> _OptionalFilter = new List<string>();
/// <summary>
/// Gets or sets filters that will process but only if processing is needed, these won't trigger a has changed
/// value of the video file by themselves
/// </summary>
public List<string> OptionalFilter
/// <summary>
/// Gets or sets filters that will process but only if processing is needed, these won't trigger a has changed
/// value of the video file by themselves
/// </summary>
public List<string> OptionalFilter
{
get => _OptionalFilter;
set
{
get => _OptionalFilter;
set
{
_OptionalFilter = value ?? new List<string>();
}
_OptionalFilter = value ?? new List<string>();
}
}
private List<string> _EncodingParameters = new List<string>();
public List<string> EncodingParameters
private List<string> _EncodingParameters = new List<string>();
public List<string> EncodingParameters
{
get => _EncodingParameters;
set
{
get => _EncodingParameters;
set
{
_EncodingParameters = value ?? new List<string>();
}
_EncodingParameters = value ?? new List<string>();
}
// private List<string> _OptionalEncodingParameters = new List<string>();
// /// <summary>
// /// Gets or sets encoding paramaters that will process but only if processing is needed, these won't trigger a has changed
// /// value of the video file by themselves
// /// </summary>
// public List<string> OptionalEncodingParameters
// {
// get => _OptionalEncodingParameters;
// set
// {
// _OptionalEncodingParameters = value ?? new List<string>();
// }
// }
private List<string> _AdditionalParameters = new List<string>();
public List<string> AdditionalParameters
}
// private List<string> _OptionalEncodingParameters = new List<string>();
// /// <summary>
// /// Gets or sets encoding paramaters that will process but only if processing is needed, these won't trigger a has changed
// /// value of the video file by themselves
// /// </summary>
// public List<string> OptionalEncodingParameters
// {
// get => _OptionalEncodingParameters;
// set
// {
// _OptionalEncodingParameters = value ?? new List<string>();
// }
// }
private List<string> _AdditionalParameters = new List<string>();
public List<string> AdditionalParameters
{
get => _AdditionalParameters;
set
{
get => _AdditionalParameters;
set
{
_AdditionalParameters = value ?? new List<string>();
}
_AdditionalParameters = value ?? new List<string>();
}
public override bool HasChange => EncodingParameters.Any() || Filter.Any() || AdditionalParameters.Any();
}
public override bool HasChange => EncodingParameters.Any() || Filter.Any() || AdditionalParameters.Any();
public override string[] GetParameters(GetParametersArgs args)
public override string[] GetParameters(GetParametersArgs args)
{
if (Deleted)
return new string[] { };
var results = new List<string> { "-map", "0:v:{sourceTypeIndex}" };
if (Filter.Any() == false && EncodingParameters.Any() == false && AdditionalParameters.Any() == false)
{
if (Deleted)
return new string[] { };
var results = new List<string> { "-map", "0:v:{sourceTypeIndex}" };
if (Filter.Any() == false && EncodingParameters.Any() == false && AdditionalParameters.Any() == false)
results.Add("-c:v:{index}");
results.Add("copy");
return results.ToArray();
}
else
{
if (EncodingParameters.Any())
{
results.Add("-c:v:{index}");
results.Add("copy");
return results.ToArray();
results.Add("-c:v:" + Stream.TypeIndex);
results.AddRange(EncodingParameters.Select(x => x.Replace("{index}", args.OutputTypeIndex.ToString())));
// if(OptionalEncodingParameters.Any())
// results.AddRange(OptionalEncodingParameters.Select(x => x.Replace("{index}", args.OutputTypeIndex.ToString())));
}
else
{
if (EncodingParameters.Any())
{
results.Add("-c:v:" + Stream.TypeIndex);
results.AddRange(EncodingParameters.Select(x => x.Replace("{index}", args.OutputTypeIndex.ToString())));
// if(OptionalEncodingParameters.Any())
// results.AddRange(OptionalEncodingParameters.Select(x => x.Replace("{index}", args.OutputTypeIndex.ToString())));
}
else
{
// we need to set this codec since a filter will be applied, so we cant copy it.
//results.Add("copy");
}
if (AdditionalParameters.Any())
results.AddRange(AdditionalParameters.Select(x => x.Replace("{index}", args.OutputTypeIndex.ToString())));
if (Filter.Any() || OptionalFilter.Any())
{
results.Add("-filter:v:" + args.OutputTypeIndex);
results.Add(string.Join(", ", Filter.Concat(OptionalFilter)).Replace("{index}", args.OutputTypeIndex.ToString()));
}
// we need to set this codec since a filter will be applied, so we cant copy it.
//results.Add("copy");
}
if (AdditionalParameters.Any())
results.AddRange(AdditionalParameters.Select(x => x.Replace("{index}", args.OutputTypeIndex.ToString())));
if (string.IsNullOrWhiteSpace(this.Title) == false)
if (Filter.Any() || OptionalFilter.Any())
{
results.Add($"-metadata:s:v:{args.OutputTypeIndex}");
results.Add($"title={(this.Title == FfmpegStream.REMOVED ? "" : this.Title)}");
results.Add("-filter:v:" + args.OutputTypeIndex);
results.Add(string.Join(", ", Filter.Concat(OptionalFilter)).Replace("{index}", args.OutputTypeIndex.ToString()));
}
if (Metadata.Any())
{
results.AddRange(Metadata.Select(x => x.Replace("{index}", args.OutputTypeIndex.ToString())));
}
return results.ToArray();
}
if (string.IsNullOrWhiteSpace(this.Title) == false)
{
results.Add($"-metadata:s:v:{args.OutputTypeIndex}");
results.Add($"title={(this.Title == FfmpegStream.REMOVED ? "" : this.Title)}");
}
if (Metadata.Any())
{
results.AddRange(Metadata.Select(x => x.Replace("{index}", args.OutputTypeIndex.ToString())));
}
return results.ToArray();
}
/// <summary>
/// Converts the object to a string
/// </summary>
/// <returns>the string representation of stream</returns>
public override string ToString()
{
if (Stream != null)
return Stream.ToString() + (Deleted ? " / Deleted" : "");
// can be null in unit tests
return string.Join(" / ", new string[]
{
Index.ToString(),
Codec,
Title,
Deleted ? "Deleted" : null
}.Where(x => string.IsNullOrWhiteSpace(x) == false));
}
}