mirror of
https://github.com/revenz/FileFlowsPlugins.git
synced 2026-05-08 06:49:10 -05:00
218 lines
6.8 KiB
C#
218 lines
6.8 KiB
C#
using FileFlows.VideoNodes.FfmpegBuilderNodes.Models;
|
|
using System.Text;
|
|
|
|
namespace FileFlows.VideoNodes.FfmpegBuilderNodes;
|
|
|
|
/// <summary>
|
|
/// FFmpeg Builder: Audio Track Reorder
|
|
/// </summary>
|
|
public class FfmpegBuilderAudioTrackReorder : FfmpegBuilderNode
|
|
{
|
|
/// <summary>
|
|
/// Gets that this node is obsolete
|
|
/// </summary>
|
|
public override bool Obsolete => true;
|
|
/// <summary>
|
|
/// Gets the obsolete message
|
|
/// </summary>
|
|
public override string ObsoleteMessage => "This has been replaced with the Track Sorter flow element.\n\nUse that instead.";
|
|
/// <summary>
|
|
/// Gets the number of output nodes
|
|
/// </summary>
|
|
public override int Outputs => 2;
|
|
/// <summary>
|
|
/// Gets the icon
|
|
/// </summary>
|
|
public override string Icon => "fas fa-sort-alpha-down";
|
|
/// <summary>
|
|
/// Gets the help URL
|
|
/// </summary>
|
|
public override string HelpUrl => "https://fileflows.com/docs/plugins/video-nodes/ffmpeg-builder/track-reorder";
|
|
/// <summary>
|
|
/// Gets or sets the stream type
|
|
/// </summary>
|
|
[Select(nameof(StreamTypeOptions), 1)]
|
|
public string StreamType { get; set; }
|
|
/// <summary>
|
|
/// Gets or sets the languages
|
|
/// </summary>
|
|
[StringArray(2)]
|
|
public List<string> Languages { get; set; }
|
|
/// <summary>
|
|
/// Gets or sets the ordered tracks
|
|
/// </summary>
|
|
[StringArray(3)]
|
|
public List<string> OrderedTracks { get; set; }
|
|
/// <summary>
|
|
/// Gets or sets the channels
|
|
/// </summary>
|
|
[StringArray(4)]
|
|
[ConditionEquals(nameof(StreamType), "Subtitle", inverse: true)]
|
|
public List<string> Channels { get; set; }
|
|
|
|
private static List<ListOption> _StreamTypeOptions;
|
|
/// <summary>
|
|
/// Gets or sets the stream type options
|
|
/// </summary>
|
|
public static List<ListOption> StreamTypeOptions
|
|
{
|
|
get
|
|
{
|
|
if (_StreamTypeOptions == null)
|
|
{
|
|
_StreamTypeOptions = new List<ListOption>
|
|
{
|
|
new ListOption { Label = "Audio", Value = "Audio" },
|
|
new ListOption { Label = "Subtitle", Value = "Subtitle" }
|
|
};
|
|
}
|
|
return _StreamTypeOptions;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes the flow element
|
|
/// </summary>
|
|
/// <param name="args">the node parameters</param>
|
|
/// <returns>the next output node</returns>
|
|
public override int Execute(NodeParameters args)
|
|
{
|
|
OrderedTracks = OrderedTracks?.Select(x => x.ToLower())?.ToList() ?? new();
|
|
|
|
if (StreamType == "Subtitle")
|
|
{
|
|
var reordered = Reorder(Model.SubtitleStreams);
|
|
|
|
bool same = AreSame(Model.SubtitleStreams, reordered);
|
|
|
|
for(int i = 0; i < reordered.Count; i++)
|
|
{
|
|
reordered[i].IsDefault = i == 0;
|
|
}
|
|
|
|
if (same)
|
|
{
|
|
args.Logger?.ILog("No subtitle tracks need reordering");
|
|
return 2;
|
|
}
|
|
|
|
Model.SubtitleStreams = reordered;
|
|
|
|
return 1;
|
|
|
|
}
|
|
else
|
|
{
|
|
var reordered = Reorder(Model.AudioStreams);
|
|
|
|
bool same = AreSame(Model.AudioStreams, reordered);
|
|
|
|
for(int i = 0; i < reordered.Count; i++)
|
|
{
|
|
reordered[i].IsDefault = i == 0;
|
|
}
|
|
|
|
if (same)
|
|
{
|
|
args.Logger?.ILog("No audio tracks need reordering");
|
|
return 2;
|
|
}
|
|
|
|
Model.AudioStreams = reordered;
|
|
Model.ForceEncode = true;
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reorders the tracks
|
|
/// </summary>
|
|
/// <param name="input">the inputs to reorder</param>
|
|
/// <typeparam name="T">the type to reorder</typeparam>
|
|
/// <returns>the reordered tracks</returns>
|
|
public List<T> Reorder<T>(List<T> input) where T : FfmpegStream
|
|
=> Reorder(Languages, OrderedTracks, Channels, input);
|
|
|
|
public static List<T> Reorder<T>(List<string> languages, List<string> orderedTracks, List<string> channels, List<T> input) where T : FfmpegStream
|
|
{
|
|
languages ??= new List<string>();
|
|
orderedTracks ??= new List<string>();
|
|
channels ??= new List<string>();
|
|
List<float> actualChannels = channels.Select(x =>
|
|
{
|
|
if (float.TryParse(x, out float value))
|
|
return value;
|
|
return -1f;
|
|
}).Where(x => x > 0f).ToList();
|
|
|
|
if (languages.Any() == false && orderedTracks.Any() == false && actualChannels.Any() == false)
|
|
return input; // nothing to do
|
|
|
|
languages.Reverse();
|
|
orderedTracks.Reverse();
|
|
actualChannels.Reverse();
|
|
|
|
const int base_number = 1_000_000_000;
|
|
int count = base_number;
|
|
var debug = new StringBuilder();
|
|
var data = input.OrderBy(x =>
|
|
{
|
|
int langIndex = 0;
|
|
int codecIndex = 0;
|
|
int channelIndex = 0;
|
|
|
|
if (x is FfmpegAudioStream audioStream)
|
|
{
|
|
langIndex = languages.IndexOf(audioStream.Stream.Language?.ToLower() ?? String.Empty);
|
|
codecIndex = orderedTracks.IndexOf(audioStream.Stream.Codec?.ToLower() ?? String.Empty);
|
|
float asChannels = audioStream.Channels > 0 ? audioStream.Channels : audioStream.Stream.Channels;
|
|
channelIndex = actualChannels.IndexOf(asChannels);
|
|
}
|
|
else if (x is FfmpegSubtitleStream subStream)
|
|
{
|
|
langIndex = languages.IndexOf(subStream.Stream.Language?.ToLower() ?? String.Empty);
|
|
codecIndex = orderedTracks.IndexOf(subStream.Stream.Codec?.ToLower() ?? String.Empty);
|
|
}
|
|
|
|
int result = base_number;
|
|
if (langIndex >= 0)
|
|
{
|
|
result -= ((langIndex + 1) * 10_000_000);
|
|
}
|
|
if (codecIndex >= 0)
|
|
{
|
|
result -= ((codecIndex + 1) * 100_000);
|
|
}
|
|
if (channelIndex >= 0)
|
|
{
|
|
result -= ((channelIndex + 1) * 1_000);
|
|
}
|
|
if (result == base_number)
|
|
result = ++count;
|
|
return result;
|
|
}).ToList();
|
|
|
|
return data;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tests if two lists are the same
|
|
/// </summary>
|
|
/// <param name="original">the original list</param>
|
|
/// <param name="reordered">the reordered list</param>
|
|
/// <typeparam name="T">the type of items</typeparam>
|
|
/// <returns>true if the lists are the same, otherwise false</returns>
|
|
public bool AreSame<T>(List<T> original, List<T> reordered) where T: FfmpegStream
|
|
{
|
|
for (int i = 0; i < reordered.Count; i++)
|
|
{
|
|
if (reordered[i] != original[i])
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|