From cf00c1f59487f76c3a7cf4929e124ed8d009c4c2 Mon Sep 17 00:00:00 2001 From: John Andrews Date: Tue, 14 Jun 2022 15:33:21 +1200 Subject: [PATCH] renamed audio track remover to track remover and added support for video, audio and subtitles --- Apprise/Apprise.csproj | Bin 2760 -> 2760 bytes BasicNodes/BasicNodes.csproj | Bin 3566 -> 3566 bytes ChecksumNodes/ChecksumNodes.csproj | Bin 2872 -> 2872 bytes CollectionNodes/CollectionNodes.csproj | Bin 3256 -> 3256 bytes DiscordNodes/DiscordNodes.csproj | Bin 2870 -> 2870 bytes EmailNodes/EmailNodes.csproj | Bin 3386 -> 3386 bytes Emby/Emby.csproj | Bin 2844 -> 2844 bytes Gotify/Gotify.csproj | Bin 2752 -> 2752 bytes ImageNodes/ImageNodes.csproj | Bin 3232 -> 3232 bytes MetaNodes/MetaNodes.csproj | Bin 4504 -> 4504 bytes MusicNodes/MusicNodes.csproj | Bin 4228 -> 4228 bytes Plex/Plex.csproj | Bin 2844 -> 2844 bytes .../Audio/FfmpegBuilderAudioTrackRemover.cs | 78 ++++++++++++++---- .../FfmpegBuilder_BasicTests.cs | 43 ++++++++++ VideoNodes/VideoNodes.csproj | Bin 4098 -> 4098 bytes VideoNodes/VideoNodes.en.json | 16 ++-- 16 files changed, 113 insertions(+), 24 deletions(-) diff --git a/Apprise/Apprise.csproj b/Apprise/Apprise.csproj index 5abb4ad4cef1ed966673d252bed8d1baa70e503a..4596b27b63dde2c653a67c8252b88b5275713a6e 100644 GIT binary patch delta 32 ocmX>hdO~!A3lpmegAIfJWN9YJ$$OYMCTB6}F`8_i$)wK#0F$x^UH||9 delta 32 ocmX>hdO~!A3lpmmgAIfJWN9YJ$$OYMCTB6}F&b^2$)wK#0F!nIS^xk5 diff --git a/BasicNodes/BasicNodes.csproj b/BasicNodes/BasicNodes.csproj index b94382d440fa23493d5d6c5a16efb35474270514..541afdb9d3a422a1c85b1ca50538eefad59aae81 100644 GIT binary patch delta 20 ccmaDS{Z4wr8%9Qx$!{4W8BI33GcD%^09-H!q5uE@ delta 20 ccmaDS{Z4wr8%9Q>$!{4W8I3l(GcD%^09*_Qo&W#< diff --git a/ChecksumNodes/ChecksumNodes.csproj b/ChecksumNodes/ChecksumNodes.csproj index 87c6a07a1cd0a0ac2a8920087aba97d4913c9eef..ddd2c5ad18c0a2ded2363af71f84507d9ab477d2 100644 GIT binary patch delta 35 rcmdlXwnJ>gDJE7E1{((b$qShzC*R}ZnykjcH;Gw+(PXnCvp5F;!8i## delta 35 rcmdlXwnJ>gDJE7U1{((b$qShzC*R}ZnykjcH;Gw+(P*b%7 diff --git a/EmailNodes/EmailNodes.csproj b/EmailNodes/EmailNodes.csproj index 918cbb7973a54bb31cfd325f76f1fbfbeed88f84..46dab284938df6264bd1c90407fd182d9791c349 100644 GIT binary patch delta 32 ocmdlbwM%M)3k$0WgAIfJWN8-3$$MD1Cg-r|Fq&+h$+D0G0Fwd;$^ZZW delta 32 ocmdlbwM%M)3k$0egAIfJWN8-3$$MD1Cg-r|FdA*1$+D0G0FuTC#sB~S diff --git a/Emby/Emby.csproj b/Emby/Emby.csproj index ee308ac7f6a97c9ea88ba91f5a679ce1d5ff52b5..4969388d3fa2dd9b4706dcbc105cd8d1d7e2fac7 100644 GIT binary patch delta 20 ccmbOuHb-p3Bqm0a$&;Ca8BI1nXENmg07wP~X8-^I delta 20 ccmbOuHb-p3Bqm0q$&;Ca8I3kSXENmg07v2mV*mgE diff --git a/Gotify/Gotify.csproj b/Gotify/Gotify.csproj index 25c2ef224bdc4c5e1bff66211569b202d8f13107..3bca8b268dfd6f8f11404c9e994a0378e554f836 100644 GIT binary patch delta 32 ocmX>gdO&o83lpmegAIfJWN9YJ$$OYMCTB6}F`8_i$)wH!0Fkl?MgRZ+ delta 32 ocmX>gdO&o83lpmmgAIfJWN9YJ$$OYMCTB6}F&b^2$)wH!0FibGLI3~& diff --git a/ImageNodes/ImageNodes.csproj b/ImageNodes/ImageNodes.csproj index 786a21cf261fe40527c3ac58b42a3fef89e1d56c..d789e8af2ae3fd5ae82173f95ceaa0e4b461c573 100644 GIT binary patch delta 28 kcmZ1=xj=Hm3?^0+1{((b$@xr@leaP1Fq&-s%(Rvh0D3G4m;e9( delta 28 kcmZ1=xj=Hm3?^111{((b$@xr@leaP1FdA+C%(Rvh0D1TblmGw# diff --git a/MetaNodes/MetaNodes.csproj b/MetaNodes/MetaNodes.csproj index 41ab370eea773e487daa277c7c6be156aafa3fd2..deabd4bd96b5dc6abc98d096cf7d3f9dd43c5556 100644 GIT binary patch delta 20 ccmbQCJVSZI9VSMT$#6i;@?)k*Mw899%6i?@?)k*Mx)KP% "https://docs.fileflows.com/plugins/video-nodes/ffmpeg-builder/audio-track-remover"; + public override string HelpUrl => "https://docs.fileflows.com/plugins/video-nodes/ffmpeg-builder/track-remover"; - public override string Icon => "fas fa-volume-off"; + public override string Icon => "fas fa-eraser"; - public override int Outputs => 2; + public override int Outputs => 2; - [Boolean(1)] + + [Select(nameof(StreamTypeOptions), 1)] + public string StreamType { get; set; } + + [Boolean(2)] + [ConditionEquals(nameof(StreamType), "Video", inverse: true)] public bool RemoveAll { get; set; } - [NumberInt(2)] + + [NumberInt(3)] public int RemoveIndex { get; set; } - [TextVariable(3)] + [TextVariable(4)] [ConditionEquals(nameof(RemoveAll), false)] public string Pattern { get; set; } - [Boolean(4)] + [Boolean(5)] [ConditionEquals(nameof(RemoveAll), false)] public bool NotMatching { get; set; } - [Boolean(5)] + [Boolean(6)] [ConditionEquals(nameof(RemoveAll), false)] public bool UseLanguageCode { get; set; } + private static List _StreamTypeOptions; + public static List StreamTypeOptions + { + get + { + if (_StreamTypeOptions == null) + { + _StreamTypeOptions = new List + { + new ListOption { Label = "Audio", Value = "Audio" }, + new ListOption { Label = "Video", Value = "Video" }, + new ListOption { Label = "Subtitle", Value = "Subtitle" } + }; + } + return _StreamTypeOptions; + } + } public override int Execute(NodeParameters args) + { + if(string.IsNullOrEmpty(StreamType) || StreamType.ToLower() == "audio") + return RemoveTracks(Model.AudioStreams) ? 1 : 2; + if (StreamType.ToLower() == "subtitle") + return RemoveTracks(Model.SubtitleStreams) ? 1 : 2; + if (StreamType.ToLower() == "video") + return RemoveTracks(Model.VideoStreams) ? 1 : 2; + + return 2; + } + + private bool RemoveTracks(List tracks) where T: FfmpegStream { bool removing = false; Regex? regex = null; int index = -1; - foreach(var audio in Model.AudioStreams) + foreach (var track in tracks) { - if (audio.Deleted == false) + if (track.Deleted == false) { // only record indexes of tracks that have not been deleted ++index; @@ -41,15 +78,22 @@ public class FfmpegBuilderAudioTrackRemover: FfmpegBuilderNode continue; } - if (RemoveAll) + if (RemoveAll || string.IsNullOrEmpty(this.Pattern)) { - audio.Deleted = true; + track.Deleted = true; removing = true; continue; } - if(regex == null) + + if (regex == null) regex = new Regex(this.Pattern, RegexOptions.IgnoreCase); - string str = UseLanguageCode ? audio.Stream.Language : audio.Stream.Title; + string str = ""; + if(track is FfmpegAudioStream audio) + str = UseLanguageCode ? audio.Stream.Language : audio.Stream.Title; + else if (track is FfmpegSubtitleStream subtitle) + str = UseLanguageCode ? subtitle.Stream.Language : subtitle.Stream.Title; + else if (track is FfmpegVideoStream video) + str = video.Stream.Title; if (string.IsNullOrEmpty(str) == false) // if empty we always use this since we have no info to go on { bool matches = regex.IsMatch(str); @@ -57,11 +101,11 @@ public class FfmpegBuilderAudioTrackRemover: FfmpegBuilderNode matches = !matches; if (matches) { - audio.Deleted = true; + track.Deleted = true; removing = true; } } } - return removing ? 1 : 2; + return removing; } } diff --git a/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_BasicTests.cs b/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_BasicTests.cs index 87197c8d..5db551db 100644 --- a/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_BasicTests.cs +++ b/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_BasicTests.cs @@ -1089,6 +1089,49 @@ public class FfmpegBuilder_BasicTests string log = logger.ToString(); Assert.IsTrue(log.Contains("this is a \"testing bobby drake\" blah")); } + + + [TestMethod] + public void FfmpegBuilder_ImageStream() + { + const string file = @"D:\videos\testfiles\img_stream.mp4"; + var logger = new TestLogger(); + const string ffmpeg = @"C:\utils\ffmpeg\ffmpeg.exe"; + var vi = new VideoInfoHelper(ffmpeg, logger); + var vii = vi.Read(file); + var args = new NodeParameters(file, logger, false, string.Empty); + args.GetToolPathActual = (string tool) => ffmpeg; + args.TempPath = @"D:\videos\temp"; + args.Parameters.Add("VideoInfo", vii); + + FfmpegBuilderStart ffStart = new(); + ffStart.PreExecute(args); + Assert.AreEqual(1, ffStart.Execute(args)); + + FfmpegBuilderRemuxToMkv ffMkv = new(); + ffMkv.PreExecute(args); + Assert.AreEqual(1, ffMkv.Execute(args)); + + FfmpegBuilderAudioTrackRemover ffRemover = new(); + ffRemover.StreamType = "Video"; + ffRemover.RemoveIndex = 1; + ffRemover.PreExecute(args); + Assert.AreEqual(1, ffRemover.Execute(args)); + + + FfmpegBuilderAudioTrackRemover ffRemoverSubtitles = new(); + ffRemoverSubtitles.StreamType = "Subtitle"; + ffRemoverSubtitles.RemoveAll = true; + ffRemoverSubtitles.PreExecute(args); + Assert.AreEqual(1, ffRemoverSubtitles.Execute(args)); + + FfmpegBuilderExecutor ffExecutor = new(); + ffExecutor.PreExecute(args); + int result = ffExecutor.Execute(args); + + string log = logger.ToString(); + Assert.AreEqual(1, result); + } } #endif \ No newline at end of file diff --git a/VideoNodes/VideoNodes.csproj b/VideoNodes/VideoNodes.csproj index 94d1ee318d52f907bcc257d93c22b2a577afd04c..1a3a36571a4026b496d033cf279ce0dab853f444 100644 GIT binary patch delta 20 bcmZotXj0hlh>6i;@?)k*Mw899%tv_uOc4gy delta 20 bcmZotXj0hlh>6i?@?)k*Mx)KP%tv_uOYH{K diff --git a/VideoNodes/VideoNodes.en.json b/VideoNodes/VideoNodes.en.json index da936194..47663435 100644 --- a/VideoNodes/VideoNodes.en.json +++ b/VideoNodes/VideoNodes.en.json @@ -254,23 +254,25 @@ } }, "FfmpegBuilderAudioTrackRemover": { - "Label": "FFMPEG Builder: Audio Track Remover", + "Label": "FFMPEG Builder: Track Remover", "Outputs": { - "1": "Audio tracks set to remove", - "2": "Audio tracks NOT set to removed" + "1": "Tracks set to remove", + "2": "Tracks NOT set to removed" }, - "Description": "Allows you to remove audio tracks based on either their title or their language codes.\n\nAny title (or language code if set to \"Use Language Code\") that is blank will NOT be removed regardless of the pattern.", + "Description": "Allows you to remove tracks based on either their title or their language codes.\n\nAny title (or language code if set to \"Use Language Code\") that is blank will NOT be removed regardless of the pattern.", "Fields": { + "StreamType": "Type", + "StreamType-Help": "The type of tracks to reorder in the FFMPEG Builder", "RemoveAll": "Remove All", - "RemoveAll-Help": "Remove all current tracks from the output file. You can use Add Audio Track afterwards to add tracks of specific codecs", + "RemoveAll-Help": "Remove all current tracks from the output file. You can use Add Track afterwards to add tracks of specific codecs", "Pattern": "Pattern", "Pattern-Help": "A regular expression to match against, eg \"commentary\" to remove commentary tracks", "NotMatching": "Not Matching", "NotMatching-Help": "If audio tracks NOT matching the pattern should be removed", "UseLanguageCode": "Use Language Code", - "UseLanguageCode-Help": "If the language code of the audio track should be used instead of the title", + "UseLanguageCode-Help": "If the language code of the track should be used instead of the title", "RemoveIndex": "Remove Index", - "RemoveIndex-Help": "The start index where to remove the audio tracks from. This allows you to remove all, or all matching, audio streams after the starting index.\nSet to zero to remove all matching the parameters.\nSet to 1 to keep the first audio track and remove any after the first matching the parameters" + "RemoveIndex-Help": "The start index where to remove the tracks from. This allows you to remove all, or all matching, tracks after the starting index.\nSet to zero to remove all matching the parameters.\nSet to 1 to keep the first track and remove any after the first matching the parameters" } }, "FfmpegBuilderAudioTrackReorder": {