diff --git a/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderSetTrackTitles.cs b/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderSetTrackTitles.cs index 0e27cac9..6196f2ca 100644 --- a/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderSetTrackTitles.cs +++ b/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderSetTrackTitles.cs @@ -40,7 +40,8 @@ public class FfmpegBuilderSetTrackTitles: FfmpegBuilderNode { new () { Label = "Audio", Value = "Audio" }, new () { Label = "Subtitle", Value = "Subtitle" }, - new () { Label = "Both", Value = "Both" }, + new () { Label = "Audio and Subtitle", Value = "Both" }, + new () { Label = "Video" , Value = "Video"} }; } return _StreamTypeOptions; @@ -66,6 +67,7 @@ public class FfmpegBuilderSetTrackTitles: FfmpegBuilderNode /// [Select(nameof(CommentaryFormatOptions), 4)] [DefaultValue("Commentary")] + [ConditionEquals(nameof(StreamType), "Video", inverse: true)] public string CommentaryFormat { get; set; } private static List _CommentaryFormatOptions; @@ -156,7 +158,6 @@ public class FfmpegBuilderSetTrackTitles: FfmpegBuilderNode } else { - track.Title = FormatTitle(Format, Separator, track.Language?.EmptyAsNull() ?? track.Stream?.Language, track.Codec?.EmptyAsNull() ?? track.Stream?.Codec, @@ -179,6 +180,23 @@ public class FfmpegBuilderSetTrackTitles: FfmpegBuilderNode } } + if (StreamType is "Video") + { + foreach (var track in Model.VideoStreams) + { + string originalTitle = track.Title; + track.Title = FormatTitle(Format, Separator, + track.Language?.EmptyAsNull(), + track.Codec?.EmptyAsNull() ?? track.Stream?.Codec, + bitrate: track.Stream?.Bitrate ?? 0, + fps: track.Stream?.FramesPerSecond ?? 0, + pixelFormat: track.Stream?.PixelFormat?.EmptyAsNull(), + resolution: track.Stream == null ? null : ResolutionHelper.GetResolution(track.Stream.Width, track.Stream.Height), + dimensions: track.Stream == null ? null : track.Stream.Width + "x" + track.Stream.Height + ); + } + } + if (changes == 0) { args.Logger?.ILog("No changes made"); @@ -236,9 +254,14 @@ public class FfmpegBuilderSetTrackTitles: FfmpegBuilderNode /// if the track is SDH /// if the track is closed captions /// if the track is hearing impared + /// the tracks video resolution + /// the tracks video dimensions + /// the tracks video pixelFormat + /// the tracks video FPS /// the formatted string - public static string FormatTitle(string formatter, string separator, string language, string codec, bool isDefault, float bitrate = 0, - float channels = 0, int sampleRate = 0, bool isForced = false, bool sdh = false, bool cc = false, bool hi = false) + internal static string FormatTitle(string formatter, string separator, string language, string codec, bool isDefault = false, float bitrate = 0, + float channels = 0, int sampleRate = 0, bool isForced = false, bool sdh = false, bool cc = false, bool hi = false, + ResolutionHelper.Resolution? resolution = null, string? dimensions = null, string? pixelFormat = null, float? fps = null) { if (string.IsNullOrWhiteSpace(formatter)) return string.Empty; @@ -281,6 +304,33 @@ public class FfmpegBuilderSetTrackTitles: FfmpegBuilderNode formatter = Replace(formatter, "sample-rate", sampleRate < 1 ? null : ((sampleRate / 1000f).ToString("0.0").Replace(".0", string.Empty) + "kHz")); formatter = Replace(formatter, "sample", sampleRate < 1 ? null : ((sampleRate / 1000f).ToString("0.0").Replace(".0", string.Empty) + "kHz")); + if(formatter.Contains("!fps")) // have to use this, since we're adding "fps" to the string, and without the else, the "fps" we added would be replaced + formatter = Replace(formatter, "!fps", fps > 0 ? fps + "fps" : string.Empty); + else + formatter = Replace(formatter, "fps", fps > 0 ? fps + "FPS" : string.Empty); + + formatter = Replace(formatter, "!resolution", resolution switch + { + ResolutionHelper.Resolution.r4k => "4k", + ResolutionHelper.Resolution.r1440p => "1440p", + ResolutionHelper.Resolution.r1080p => "1080p", + ResolutionHelper.Resolution.r720p => "720p", + ResolutionHelper.Resolution.r480p => "480p", + _ => "" + }); + formatter = Replace(formatter, "resolution", resolution switch + { + ResolutionHelper.Resolution.r4k => "4K", + ResolutionHelper.Resolution.r1440p => "1440P", + ResolutionHelper.Resolution.r1080p => "1080P", + ResolutionHelper.Resolution.r720p => "720P", + ResolutionHelper.Resolution.r480p => "480P", + _ => "" + }); + formatter = Replace(formatter, "!pixelformat!", pixelFormat ?? string.Empty); + formatter = Replace(formatter, "!pixelformat", pixelFormat?.ToLowerInvariant() ?? string.Empty); + formatter = Replace(formatter, "pixelformat", pixelFormat?.ToUpperInvariant() ?? string.Empty); + formatter = Replace(formatter, "dimensions", dimensions ?? string.Empty); // Remove standalone separators if(string.IsNullOrWhiteSpace(separator.Trim()) == false) diff --git a/VideoNodes/Tests/FfmpegBuilderTests/FFmpegBuilder_SetTrackTtitlesTests.cs b/VideoNodes/Tests/FfmpegBuilderTests/FFmpegBuilder_SetTrackTtitlesTests.cs index 563927fa..1df0dac3 100644 --- a/VideoNodes/Tests/FfmpegBuilderTests/FFmpegBuilder_SetTrackTtitlesTests.cs +++ b/VideoNodes/Tests/FfmpegBuilderTests/FFmpegBuilder_SetTrackTtitlesTests.cs @@ -32,6 +32,27 @@ public class FFmpegBuilder_SetTrackTtitlesTests Assert.AreEqual("Track: English / AAC / Stereo / Default / 128Kbps / 44.1kHz", result); } + [TestMethod] + public void FormatTitle_DefaultCase_Success_Exclaim() + { + // Arrange + string formatter = "Track: lang / !codec / channels / default / bitrate / samplerate / cc / sdh / hi"; + string separator = " / "; + string language = "English"; + string codec = "AAC"; + bool isDefault = true; + float bitrate = 128_000; + float channels = 2.0f; + int sampleRate = 44100; + bool isForced = false; + + // Act + string result = FfmpegBuilderSetTrackTitles.FormatTitle(formatter, separator, language, codec, isDefault, bitrate, channels, sampleRate, isForced); + + // Assert + Assert.AreEqual("Track: English / aac / Stereo / Default / 128Kbps / 44.1kHz", result); + } + [TestMethod] public void FormatTitle_SDH() { @@ -329,6 +350,116 @@ public class FFmpegBuilder_SetTrackTtitlesTests } + + [TestMethod] + public void FormatTitle_Video_Resolution() + { + // Arrange + string formatter = "Track: lang / codec / fps / resolution / dimensions / pixelformat"; + string separator = " / "; + string language = "English"; + string codec = "HEVC"; + + ResolutionHelper.Resolution resolution = ResolutionHelper.Resolution.r720p; + + // Act + string result = FfmpegBuilderSetTrackTitles.FormatTitle(formatter, separator, language, codec, + resolution: resolution); + + // Assert + Assert.AreEqual("Track: English / HEVC / 720P", result); + + // Act + formatter = "Track: lang / codec / fps / !resolution / dimensions / pixelformat"; + result = FfmpegBuilderSetTrackTitles.FormatTitle(formatter, separator, language, codec, + resolution: resolution); + + // Assert + Assert.AreEqual("Track: English / HEVC / 720p", result); + } + + [TestMethod] + public void FormatTitle_Video_PixelFormat() + { + // Arrange + string formatter = "Track: lang / codec / fps / resolution / dimensions / pixelformat"; + string separator = " / "; + string language = "English"; + string codec = "HEVC"; + + string pixelFormat = "Nv12"; + + // Act + string result = FfmpegBuilderSetTrackTitles.FormatTitle(formatter, separator, language, codec, + pixelFormat: pixelFormat); + + // Assert + Assert.AreEqual("Track: English / HEVC / NV12", result); + + + // Act + formatter = "Track: lang / codec / fps / resolution / dimensions / !pixelformat"; + result = FfmpegBuilderSetTrackTitles.FormatTitle(formatter, separator, language, codec, + pixelFormat: pixelFormat); + + // Assert + Assert.AreEqual("Track: English / HEVC / nv12", result); + + // Act + formatter = "Track: lang / codec / fps / resolution / dimensions / !pixelformat!"; + result = FfmpegBuilderSetTrackTitles.FormatTitle(formatter, separator, language, codec, + pixelFormat: pixelFormat); + + // Assert + Assert.AreEqual("Track: English / HEVC / Nv12", result); + } + + [TestMethod] + public void FormatTitle_Video_Dimensions() + { + // Arrange + string formatter = "Track: lang / codec / fps / resolution / dimensions / pixelformat"; + string separator = " / "; + string language = "English"; + string codec = "HEVC"; + + string dimensions = "1920x1080"; + + // Act + string result = FfmpegBuilderSetTrackTitles.FormatTitle(formatter, separator, language, codec, + dimensions: dimensions); + + // Assert + Assert.AreEqual("Track: English / HEVC / 1920x1080", result); + } + + [TestMethod] + public void FormatTitle_Video_Fps() + { + // Arrange + string formatter = "Track: lang / codec / fps / resolution / dimensions / pixelformat"; + string separator = " / "; + string language = "English"; + string codec = "HEVC"; + + float fps = 23.9999997f; + + // Act + string result = FfmpegBuilderSetTrackTitles.FormatTitle(formatter, separator, language, codec, + fps: fps); + + // Assert + Assert.AreEqual("Track: English / HEVC / 24FPS", result); + + // Act + fps = 23.9999997f; + formatter = "Track: lang / codec / !fps / resolution / dimensions / pixelformat"; + result = FfmpegBuilderSetTrackTitles.FormatTitle(formatter, separator, language, codec, + fps: fps); + + // Assert + Assert.AreEqual("Track: English / HEVC / 24fps", result); + } } #endif \ No newline at end of file