From 18a5b4182a67a24bcff52cbe2dee62966988ba47 Mon Sep 17 00:00:00 2001 From: reven Date: Sat, 8 Jan 2022 18:45:28 +1300 Subject: [PATCH] adding comskip chapter node, and fixing issue with comskip remove ads only looking for spaces fixed issue witgh Executor requiring output variables --- BasicNodes/Tools/Executor.cs | 3 +- VideoNodes/Tests/VideoInfoHelperTests.cs | 20 +++++ VideoNodes/VideoNodes.csproj | Bin 3922 -> 3922 bytes VideoNodes/VideoNodes.en.json | 7 ++ VideoNodes/VideoNodes/ComskipChapters.cs | 93 ++++++++++++++++++++++ VideoNodes/VideoNodes/ComskipRemoveAds.cs | 2 +- 6 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 VideoNodes/VideoNodes/ComskipChapters.cs diff --git a/BasicNodes/Tools/Executor.cs b/BasicNodes/Tools/Executor.cs index 0ae8e114..988a3962 100644 --- a/BasicNodes/Tools/Executor.cs +++ b/BasicNodes/Tools/Executor.cs @@ -14,7 +14,7 @@ public override FlowElementType Type => FlowElementType.Process; public override string Icon => "fas fa-terminal"; - private const string VariablePattern = "^([a-zA-Z_]+)[a-zA-Z_0-9]*$"; + private const string VariablePattern = @"(^[\s]*$)|(^([a-zA-Z_]+)[a-zA-Z_0-9]*$)"; [Required] [File(1)] @@ -37,6 +37,7 @@ [Text(6)] [System.ComponentModel.DataAnnotations.RegularExpression(VariablePattern)] public string OutputVariable { get; set; } + [Text(7)] [System.ComponentModel.DataAnnotations.RegularExpression(VariablePattern)] public string OutputErrorVariable { get; set; } diff --git a/VideoNodes/Tests/VideoInfoHelperTests.cs b/VideoNodes/Tests/VideoInfoHelperTests.cs index bc53fb2c..f72b31f3 100644 --- a/VideoNodes/Tests/VideoInfoHelperTests.cs +++ b/VideoNodes/Tests/VideoInfoHelperTests.cs @@ -321,6 +321,26 @@ namespace VideoNodes.Tests Assert.AreEqual(1, output); } + [TestMethod] + public void Comskip_Chapters() + { + const string file = @"D:\videos\recordings\Rescue My Renovation (2001).ts"; + const string ffmpeg = @"C:\utils\ffmpeg\ffmpeg.exe"; + var args = new FileFlows.Plugin.NodeParameters(file, new TestLogger(), false, string.Empty); + + args.GetToolPath = (string tool) => @"C:\utils\ffmpeg\ffmpeg.exe"; + args.TempPath = @"D:\videos\temp"; + + + var vi = new VideoInfoHelper(@"C:\utils\ffmpeg\ffmpeg.exe", new TestLogger()); + var vii = vi.Read(file); + args.SetParameter("VideoInfo", vii); + //args.Process = new FileFlows.Plugin.ProcessHelper(args.Logger); + + var node = new ComskipChapters(); + int output = node.Execute(args); + Assert.AreEqual(1, output); + } } } diff --git a/VideoNodes/VideoNodes.csproj b/VideoNodes/VideoNodes.csproj index 123cae99b4264ec26b2439060247d621c7b1eda6..22b3d8d85762a511d27a9a94288731218b4fb8da 100644 GIT binary patch delta 20 ccmca4cS&x;113iE$q$*r8O=9aGE4FR09G{y!~g&Q delta 20 ccmca4cS&x;113hJ$q$*r8I3kuGE4FR09D%tx&QzG diff --git a/VideoNodes/VideoNodes.en.json b/VideoNodes/VideoNodes.en.json index 1853fa12..966c5310 100644 --- a/VideoNodes/VideoNodes.en.json +++ b/VideoNodes/VideoNodes.en.json @@ -50,6 +50,13 @@ "Language-Help": "The ISO 639-2 language code to use. \nhttps://en.wikipedia.org/wiki/List_of_ISO_639-2_codes" } }, + "ComskipChapters": { + "Description": "Uses a comskip EDL file and will create chapters given that EDL comskip file.", + "Outputs": { + "1": "Commericals chapters created, saved to temporary file", + "2": "No commericals detected" + } + }, "ComskipRemoveAds": { "Description": "Uses a comskip EDL file and will remove commericals using that file.", "Outputs": { diff --git a/VideoNodes/VideoNodes/ComskipChapters.cs b/VideoNodes/VideoNodes/ComskipChapters.cs new file mode 100644 index 00000000..6415b59e --- /dev/null +++ b/VideoNodes/VideoNodes/ComskipChapters.cs @@ -0,0 +1,93 @@ +namespace FileFlows.VideoNodes +{ + using FileFlows.Plugin; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using System.Text.RegularExpressions; + using System.Threading.Tasks; + + + public class ComskipChapters: EncodingNode + { + public override int Outputs => 2; + + public override int Execute(NodeParameters args) + { + string ffmpegExe = GetFFMpegExe(args); + if (string.IsNullOrEmpty(ffmpegExe)) + return -1; + VideoInfo videoInfo = GetVideoInfo(args); + if (videoInfo == null) + return -1; + float totalTime = (float)videoInfo.VideoStreams[0].Duration.TotalSeconds; + + + string edlFile = args.WorkingFile.Substring(0, args.WorkingFile.LastIndexOf(".") + 1) + "edl"; + if(File.Exists(edlFile) == false) + edlFile = args.WorkingFile.Substring(0, args.WorkingFile.LastIndexOf(".") + 1) + "edl"; + if (File.Exists(edlFile) == false) + { + args.Logger?.ILog("No EDL file found for file"); + return 2; + } + + string text = File.ReadAllText(edlFile) ?? string.Empty; + float last = 0; + + StringBuilder metadata = new StringBuilder(); + metadata.AppendLine(";FFMETADATA1"); + metadata.AppendLine(""); + int chapter = 0; + + foreach (string line in text.Split(new string[] { "\r\n", "\n", "\r"}, StringSplitOptions.RemoveEmptyEntries)) + { + // 93526.47 93650.13 0 + string[] parts = line.Split(new[] { " ", "\t" }, StringSplitOptions.RemoveEmptyEntries); + if (parts.Length < 2) + continue; + float start = 0; + float end = 0; + if (float.TryParse(parts[0], out start) == false || float.TryParse(parts[1], out end) == false) + continue; + + if (start < last) + continue; + + AddChapter(last, start); + last = end; + } + + if(chapter == 0) + { + args.Logger?.ILog("No ads found in edl file"); + return 2; + } + AddChapter(last, totalTime); + + string tempMetaDataFile = Path.Combine(args.TempPath, Guid.NewGuid().ToString() + ".txt"); + File.WriteAllText(tempMetaDataFile, metadata.ToString()); + + string ffArgs = $"-i \"{tempMetaDataFile}\" -map_metadata 1 -max_muxing_queue_size 1024"; + if (Encode(args, ffmpegExe, ffArgs)) + { + args.Logger?.ILog($"Adding {chapter} chapters to file"); + return 1; + } + args.Logger?.ELog("Processing failed"); + return -1; + + void AddChapter(float start, float end) + { + + metadata.AppendLine("[CHAPTER]"); + metadata.AppendLine("TIMEBASE=1/1000"); + metadata.AppendLine("START=" + ((int)(start * 1000))); + metadata.AppendLine("END=" + ((int)(end * 1000))); + metadata.AppendLine("title=Chapter " + (++chapter)); + metadata.AppendLine(); + } + } + } +} diff --git a/VideoNodes/VideoNodes/ComskipRemoveAds.cs b/VideoNodes/VideoNodes/ComskipRemoveAds.cs index dea74a62..4e9bf9cf 100644 --- a/VideoNodes/VideoNodes/ComskipRemoveAds.cs +++ b/VideoNodes/VideoNodes/ComskipRemoveAds.cs @@ -39,7 +39,7 @@ foreach(string line in text.Split(new string[] { "\r\n", "\n", "\r"}, StringSplitOptions.RemoveEmptyEntries)) { // 93526.47 93650.13 0 - string[] parts = line.Split(" "); + string[] parts = line.Split(new[] { " ", "\t" }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length < 2) continue; float start = 0;