added subtitle extractor

This commit is contained in:
reven
2022-01-03 17:29:14 +13:00
parent 85f941cac9
commit cf4113bc33
4 changed files with 101 additions and 1 deletions

View File

@@ -63,6 +63,8 @@ namespace FileFlows.VideoNodes
var rgxStreams = new Regex(@"Stream\s#[\d]+:[\d]+(.*?)(?=(Stream\s#[\d]|$))", RegexOptions.Singleline);
var streamMatches = rgxStreams.Matches(output);
int streamIndex = 0;
int subtitleIndex = 1;
foreach (Match sm in streamMatches)
{
if (sm.Value.Contains(" Video: "))
@@ -95,11 +97,13 @@ namespace FileFlows.VideoNodes
if (sub != null)
{
sub.Index = streamIndex;
sub.TypeIndex = subtitleIndex;
var match = Regex.Match(sm.Value, @"(?<=(Stream #))[\d]+:[\d]+");
if (match.Success)
sub.IndexString = match.Value;
vi.SubtitleStreams.Add(sub);
}
++subtitleIndex;
}
++streamIndex;
}

Binary file not shown.

View File

@@ -38,11 +38,20 @@
}
},
"SubtitleRemover": {
"Description": "Removes subtitles from a video file if found..\n\nOutput 1: Subtitles were removed\nOutput 2: No subtitles found that needed to be removed",
"Description": "Removes subtitles from a video file if found.\n\nOutput 1: Subtitles were removed\nOutput 2: No subtitles found that needed to be removed",
"Fields": {
"SubtitlesToRemove": "Subtitles To Remove"
}
},
"SubtitleExtractor": {
"Description": "Extract a single subtitle tracks and saves it to the destination. Can extract srt, ass, and ssa format.\nThis will NOT update the working file, and will keep the working file the same as the input file.\n\nOutput 1: Subtitles were extracted\nOutput 2: No subtitles found to extract",
"Fields": {
"Language": "Language",
"Language-Help": "The ISO 639-2 language code to use. \nhttps://en.wikipedia.org/wiki/List_of_ISO_639-2_codes",
"OutputFile": "Output File",
"OutputFile-Help": "Where to save the the output file to, e.g. \"'{folder.Orig.FullName}\\{file.Orig.FileName}.srt'\" to save it with the original file as a srt output.\nIf left blank an srt subtitle will be created in the same folder as the original input file."
}
},
"VideoCodec": {
"Description": "This node will check the codecs in the input file, and trigger when matched.\n\nOutput 1: Matches\nOutput 2: Does not match",
"Fields": {

View File

@@ -0,0 +1,87 @@
namespace FileFlows.VideoNodes
{
using FileFlows.Plugin;
using FileFlows.Plugin.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
public class SubtitleExtractor : EncodingNode
{
public override int Outputs => 2;
public override string Icon => "fas fa-comment-dots";
[Text(1)]
public string Language { get; set; }
[File(2)]
public string OutputFile { get; set; }
public override int Execute(NodeParameters args)
{
try
{
VideoInfo videoInfo = GetVideoInfo(args);
if (videoInfo == null)
return -1;
string ffmpegExe = GetFFMpegExe(args);
if (string.IsNullOrEmpty(ffmpegExe))
return -1;
List<string> ffArgs = new List<string>();
// ffmpeg -i input.mkv -map "0:m:language:eng" -map "-0:v" -map "-0:a" output.srt
var subTrack = videoInfo.SubtitleStreams?.Where(x => string.IsNullOrEmpty(Language) || x.Language?.ToLower() == Language.ToLower()).FirstOrDefault();
if (subTrack == null)
{
args.Logger?.ILog("No subtitles found to extract");
return 2;
}
if (string.IsNullOrEmpty(OutputFile) == false)
{
OutputFile = args.ReplaceVariables(OutputFile, true);
}
else
{
var file = new FileInfo(args.FileName);
OutputFile = file.FullName.Substring(0, file.FullName.LastIndexOf(file.Extension)) + ".srt";
}
OutputFile = args.MapPath(OutputFile);
if (File.Exists(OutputFile))
{
args.Logger?.ILog("File already exists, deleting file: " + OutputFile);
File.Delete(OutputFile);
}
// -y means it will overwrite a file if output already exists
var result = args.Process.ExecuteShellCommand(new ExecuteArgs
{
Command = ffmpegExe,
Arguments = $"-i \"{args.WorkingFile}\" -map \"0:s:{subTrack.TypeIndex}\" -map \"-0:v\" -map \"-0:a\" \"{OutputFile}\""
}).Result;
if (result.ExitCode == 0)
{
return 1;
}
args.Logger?.ELog("FFMPEG process failed to extract subtitles");
args.Logger?.ILog("Unexpected exit code: " + result.ExitCode);
args.Logger?.ILog(result.StandardOutput ?? String.Empty);
args.Logger?.ILog(result.StandardError ?? String.Empty);
return -1;
}
catch (Exception ex)
{
args.Logger?.ELog("Failed processing VideoFile: " + ex.Message);
return -1;
}
}
}
}