mirror of
https://github.com/revenz/FileFlowsPlugins.git
synced 2026-02-22 13:28:26 -06:00
FF-1253 - track sorter
This commit is contained in:
@@ -97,16 +97,16 @@ public class FfmpegBuilderTrackSorter : FfmpegBuilderNode
|
||||
/// <summary>
|
||||
/// Processes the streams
|
||||
/// </summary>
|
||||
/// <param name="logger">the logger parameters</param>
|
||||
/// <param name="args">the node parameters</param>
|
||||
/// <param name="streams">the streams to process for deletion</param>
|
||||
/// <typeparam name="T">the stream type</typeparam>
|
||||
/// <returns>if any changes were made</returns>
|
||||
internal bool ProcessStreams<T>(ILogger logger, List<T> streams, int sortIndex = 0) where T : FfmpegStream
|
||||
internal bool ProcessStreams<T>(NodeParameters args, List<T> streams, int sortIndex = 0) where T : FfmpegStream
|
||||
{
|
||||
if (streams?.Any() != true || Sorters?.Any() != true || sortIndex >= Sorters.Count)
|
||||
return false;
|
||||
|
||||
var orderedStreams = SortStreams(streams);
|
||||
var orderedStreams = SortStreams(args, streams);
|
||||
|
||||
// Replace the unsorted items with the sorted ones
|
||||
for (int i = 0; i < streams.Count; i++)
|
||||
@@ -117,22 +117,22 @@ public class FfmpegBuilderTrackSorter : FfmpegBuilderNode
|
||||
return true;
|
||||
}
|
||||
|
||||
internal List<T> SortStreams<T>(List<T> streams) where T : FfmpegStream
|
||||
internal List<T> SortStreams<T>(NodeParameters args, List<T> streams) where T : FfmpegStream
|
||||
{
|
||||
if (streams?.Any() != true || Sorters?.Any() != true)
|
||||
return streams;
|
||||
|
||||
return streams.OrderBy(stream => GetSortKey(stream))
|
||||
return streams.OrderBy(stream => GetSortKey(args, stream))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private string GetSortKey<T>(T stream) where T : FfmpegStream
|
||||
private string GetSortKey<T>(NodeParameters args, T stream) where T : FfmpegStream
|
||||
{
|
||||
string sortKey = "";
|
||||
|
||||
for (int i = 0; i < Sorters.Count; i++)
|
||||
{
|
||||
var sortValue = Math.Round(SortValue<T>(stream, Sorters[i])).ToString();
|
||||
var sortValue = Math.Round(SortValue<T>(args, stream, Sorters[i])).ToString();
|
||||
// Trim the sort value to 15 characters
|
||||
string trimmedValue = sortValue[..Math.Min(sortValue.Length, 15)];
|
||||
|
||||
@@ -174,22 +174,44 @@ public class FfmpegBuilderTrackSorter : FfmpegBuilderNode
|
||||
/// Calculates the sort value for a stream property based on the specified sorter.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the stream.</typeparam>
|
||||
/// <param name="args">the node parameters</param>
|
||||
/// <param name="stream">The stream instance.</param>
|
||||
/// <param name="sorter">The key-value pair representing the sorter.</param>
|
||||
/// <returns>The calculated sort value for the specified property and sorter.</returns>
|
||||
public static double SortValue<T>(T stream, KeyValuePair<string, string> sorter) where T : FfmpegStream
|
||||
public static double SortValue<T>(NodeParameters args, T stream, KeyValuePair<string, string> sorter) where T : FfmpegStream
|
||||
{
|
||||
string property = sorter.Key;
|
||||
bool invert = property.EndsWith("Desc");
|
||||
if (invert)
|
||||
property = property[..^4]; // remove "Desc"
|
||||
|
||||
string comparison = sorter.Value;
|
||||
string comparison = sorter.Value ?? string.Empty;
|
||||
|
||||
if (comparison.StartsWith("{") && comparison.EndsWith("}"))
|
||||
{
|
||||
comparison = comparison[1..^1];
|
||||
if (args?.Variables?.TryGetValue(comparison, out object variable) == true)
|
||||
comparison = variable?.ToString() ?? string.Empty;
|
||||
else
|
||||
comparison = string.Empty;
|
||||
}
|
||||
else if (args?.Variables?.TryGetValue(comparison, out object oVariable) == true)
|
||||
{
|
||||
comparison = oVariable?.ToString() ?? string.Empty;
|
||||
}
|
||||
|
||||
if (property == nameof(stream.Language))
|
||||
{
|
||||
comparison = string.Join("|",
|
||||
comparison.Split('|', StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(LanguageHelper.GetIso2Code));
|
||||
}
|
||||
|
||||
var value = property switch
|
||||
{
|
||||
nameof(FfmpegStream.Codec) => stream.Codec,
|
||||
nameof(AudioStream.Bitrate) => (stream is FfmpegAudioStream audioStream) ? audioStream?.Stream?.Bitrate : null,
|
||||
nameof(FfmpegStream.Language) => LanguageHelper.GetIso2Code(stream.Language),
|
||||
_ => stream.GetType().GetProperty(property)?.GetValue(stream, null)
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
public void ProcessStreams_SortsStreamsBasedOnSorters()
|
||||
{
|
||||
// Arrange
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
@@ -32,7 +32,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var sorted = trackSorter.SortStreams(streams);
|
||||
var sorted = trackSorter.SortStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(3, sorted[0].Index);
|
||||
@@ -50,7 +50,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
public void ProcessStreams_SortsStreamsBasedOnChannels()
|
||||
{
|
||||
// Arrange
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
@@ -66,7 +66,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = trackSorter.ProcessStreams(logger, streams);
|
||||
var result = trackSorter.ProcessStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(2, streams[0].Index);
|
||||
@@ -83,7 +83,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
public void ProcessStreams_SortsStreamsBasedOnLanguageThenCodec()
|
||||
{
|
||||
// Arrange
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
@@ -100,7 +100,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = trackSorter.ProcessStreams(logger, streams);
|
||||
var result = trackSorter.ProcessStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(3, streams[0].Index);
|
||||
@@ -117,7 +117,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
public void ProcessStreams_SortsStreamsBasedOnCustomMathOperation()
|
||||
{
|
||||
// Arrange
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
@@ -133,7 +133,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = trackSorter.ProcessStreams(logger, streams);
|
||||
var result = trackSorter.ProcessStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(2, streams[0].Index);
|
||||
@@ -151,23 +151,23 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
public void ProcessStreams_SortsStreamsBasedOnRegex()
|
||||
{
|
||||
// Arrange
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
new() { Index = 1, Channels = 2, Language = "en", Codec = "aac" },
|
||||
new() { Index = 2, Channels = 5.1f, Language = "fr", Codec = "aac" },
|
||||
new() { Index = 1, Channels = 2, Language = "en", Codec = "ac3" },
|
||||
new() { Index = 2, Channels = 5.1f, Language = "fr", Codec = "eac3" },
|
||||
new() { Index = 3, Channels = 7.1f, Language = "en", Codec = "ac3" },
|
||||
};
|
||||
|
||||
// Mock sorters by different properties
|
||||
trackSorter.Sorters = new List<KeyValuePair<string, string>>
|
||||
{
|
||||
new ("Language", "^en$"),
|
||||
new ("Codec", "^ac3$"),
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = trackSorter.ProcessStreams(logger, streams);
|
||||
var result = trackSorter.ProcessStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, streams[0].Index);
|
||||
@@ -175,16 +175,16 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
Assert.AreEqual(2, streams[2].Index);
|
||||
|
||||
// Additional assertions for logging
|
||||
Assert.AreEqual("1 / en / aac / 2.0", streams[0].ToString());
|
||||
Assert.AreEqual("1 / en / ac3 / 2.0", streams[0].ToString());
|
||||
Assert.AreEqual("3 / en / ac3 / 7.1", streams[1].ToString());
|
||||
Assert.AreEqual("2 / fr / aac / 5.1", streams[2].ToString());
|
||||
Assert.AreEqual("2 / fr / eac3 / 5.1", streams[2].ToString());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessStreams_SortsStreamsBasedOnMultipleSorters()
|
||||
{
|
||||
// Arrange
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
@@ -209,7 +209,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = trackSorter.ProcessStreams(logger, streams);
|
||||
var result = trackSorter.ProcessStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
|
||||
@@ -239,7 +239,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
public void ProcessStreams_SortsStreamsBasedOnBitrate()
|
||||
{
|
||||
// Arrange
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
@@ -256,7 +256,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var sorted = trackSorter.SortStreams(streams);
|
||||
var sorted = trackSorter.SortStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(3, sorted[0].Index);
|
||||
@@ -275,7 +275,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
public void ProcessStreams_SortsStreamsBasedOnChannelsAsc()
|
||||
{
|
||||
// Arrange
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
@@ -292,7 +292,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var sorted = trackSorter.SortStreams(streams);
|
||||
var sorted = trackSorter.SortStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, sorted[0].Index);
|
||||
@@ -311,13 +311,13 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
public void ProcessStreams_SortsStreamsBasedOnChannelsDesc()
|
||||
{
|
||||
// Arrange
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
new() { Index = 1, Channels = 2, Language = "en", Codec = "aac", Stream = new AudioStream() { Bitrate = 140_000_000 }},
|
||||
new() { Index = 2, Channels = 5.1f, Language = "fr", Codec = "dts" , Stream = new AudioStream() { Bitrate = 200_000_000 }},
|
||||
new() { Index = 3, Channels = 7.1f, Language = "en", Codec = "ac3" , Stream = new AudioStream() { Bitrate = 20_000_000 }},
|
||||
new() { Index = 3, Channels = 7.0999999996f, Language = "en", Codec = "ac3" , Stream = new AudioStream() { Bitrate = 20_000_000 }},
|
||||
new() { Index = 4, Channels = 7.1f, Language = "en", Codec = "ac3" , Stream = new AudioStream() { Bitrate = 200_000_000 }},
|
||||
};
|
||||
|
||||
@@ -328,7 +328,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var sorted = trackSorter.SortStreams(streams);
|
||||
var sorted = trackSorter.SortStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(3, sorted[0].Index);
|
||||
@@ -348,7 +348,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
public void ProcessStreams_SortsStreamsBasedOnBitrateInvert()
|
||||
{
|
||||
// Arrange
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
@@ -365,7 +365,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var sorted = trackSorter.SortStreams(streams);
|
||||
var sorted = trackSorter.SortStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(2, sorted[0].Index);
|
||||
@@ -384,7 +384,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
public void ProcessStreams_SortsStreamsBasedOnBitrateAndCodec()
|
||||
{
|
||||
// Arrange
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
@@ -402,7 +402,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var sorted = trackSorter.SortStreams(streams);
|
||||
var sorted = trackSorter.SortStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(4, sorted[0].Index);
|
||||
@@ -426,7 +426,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
public void ProcessStreams_SortsStreamsBasedOnBitrateUnit()
|
||||
{
|
||||
// Arrange
|
||||
var logger = new TestLogger();
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
@@ -443,7 +443,7 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
};
|
||||
|
||||
// Act
|
||||
var sorted = trackSorter.SortStreams(streams);
|
||||
var sorted = trackSorter.SortStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(2, sorted[0].Index);
|
||||
@@ -457,6 +457,105 @@ public class FfmpegBuilder_TrackSorterTests
|
||||
Assert.AreEqual(140_000_000, sorted[2].Stream.Bitrate);
|
||||
Assert.AreEqual(20_000_000, sorted[3].Stream.Bitrate);
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessStreams_SortsStreamsBasedOnLanguage()
|
||||
{
|
||||
// Arrange
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
new() { Index = 1, Channels = 2, Language = "eng", Codec = "aac" },
|
||||
new() { Index = 2, Channels = 2, Language = "fr", Codec = "aac" },
|
||||
new() { Index = 3, Channels = 5.1f, Language = "en", Codec = "eac3" },
|
||||
new() { Index = 4, Channels = 5.1f, Language = "ger", Codec = "ac3" },
|
||||
new() { Index = 5, Channels = 5.1f, Language = "German", Codec = "dts" },
|
||||
new() { Index = 6, Channels = 5.1f, Language = "English", Codec = "aac" },
|
||||
new() { Index = 7, Channels = 5.1f, Language = "eng", Codec = "ac3" },
|
||||
};
|
||||
|
||||
// Mock sorters by different properties
|
||||
trackSorter.Sorters = new List<KeyValuePair<string, string>>
|
||||
{
|
||||
new("Language", "en")
|
||||
};
|
||||
|
||||
// Act
|
||||
var sorted = trackSorter.SortStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, sorted[0].Index);
|
||||
Assert.AreEqual(3, sorted[1].Index);
|
||||
Assert.AreEqual(6, sorted[2].Index);
|
||||
Assert.AreEqual(7, sorted[3].Index);
|
||||
|
||||
// non english
|
||||
Assert.AreEqual(2, sorted[4].Index);
|
||||
Assert.AreEqual(4, sorted[5].Index);
|
||||
Assert.AreEqual(5, sorted[6].Index);
|
||||
|
||||
// Additional assertions for logging
|
||||
Assert.AreEqual("eng", sorted[0].Language);
|
||||
Assert.AreEqual("en", sorted[1].Language);
|
||||
Assert.AreEqual("English", sorted[2].Language);
|
||||
Assert.AreEqual("eng", sorted[3].Language);
|
||||
|
||||
Assert.AreEqual("fr", sorted[4].Language);
|
||||
Assert.AreEqual("ger", sorted[5].Language);
|
||||
Assert.AreEqual("German", sorted[6].Language);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[TestMethod]
|
||||
public void ProcessStreams_SortsStreamsBasedOnLanguageRegex()
|
||||
{
|
||||
// Arrange
|
||||
var args = new NodeParameters(new TestLogger());
|
||||
var trackSorter = new FfmpegBuilderTrackSorter();
|
||||
List<FfmpegAudioStream> streams = new List<FfmpegAudioStream>
|
||||
{
|
||||
new() { Index = 1, Channels = 2, Language = "eng", Codec = "aac" },
|
||||
new() { Index = 2, Channels = 2, Language = "fr", Codec = "aac" },
|
||||
new() { Index = 3, Channels = 5.1f, Language = "en", Codec = "eac3" },
|
||||
new() { Index = 4, Channels = 5.1f, Language = "ger", Codec = "ac3" },
|
||||
new() { Index = 5, Channels = 5.1f, Language = "German", Codec = "dts" },
|
||||
new() { Index = 6, Channels = 5.1f, Language = "chi", Codec = "aac" },
|
||||
new() { Index = 7, Channels = 5.1f, Language = "mao", Codec = "ac3" },
|
||||
};
|
||||
|
||||
// Mock sorters by different properties
|
||||
trackSorter.Sorters = new List<KeyValuePair<string, string>>
|
||||
{
|
||||
new("Language", "en|deu")
|
||||
};
|
||||
|
||||
// Act
|
||||
var sorted = trackSorter.SortStreams(args, streams);
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(1, sorted[0].Index);
|
||||
Assert.AreEqual(3, sorted[1].Index);
|
||||
Assert.AreEqual(4, sorted[2].Index);
|
||||
Assert.AreEqual(5, sorted[3].Index);
|
||||
|
||||
// non english
|
||||
Assert.AreEqual(2, sorted[4].Index);
|
||||
Assert.AreEqual(6, sorted[5].Index);
|
||||
Assert.AreEqual(7, sorted[6].Index);
|
||||
|
||||
// Additional assertions for logging
|
||||
Assert.AreEqual("eng", sorted[0].Language);
|
||||
Assert.AreEqual("en", sorted[1].Language);
|
||||
Assert.AreEqual("ger", sorted[2].Language);
|
||||
Assert.AreEqual("German", sorted[3].Language);
|
||||
|
||||
Assert.AreEqual("fr", sorted[4].Language);
|
||||
Assert.AreEqual("chi", sorted[5].Language);
|
||||
Assert.AreEqual("mao", sorted[6].Language);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user