added new video nodes

This commit is contained in:
reven
2022-01-07 12:09:12 +13:00
parent 9eccb00a77
commit 3fc174831e
6 changed files with 256 additions and 1 deletions
Binary file not shown.
+34
View File
@@ -1,6 +1,28 @@
{
"Flow":{
"Parts": {
"AudioAdjustVolume": {
"Outputs": {
"1": "Audio tracks volume was adjusted and saved to temporary file",
"2": "Audio tracks were not adjusted"
},
"Description": "Adjusts audio tracks volume in a video file using FFMPEG",
"Fields": {
"VolumePercent": "Volume Percent",
"VolumePercent-Help": "The percent of the adjusted volume.\n100 means no adjustment\n50 means half volume\n0 means muted"
}
},
"AudioNormalization": {
"Outputs": {
"1": "Audio tracks were normalized and saved to temporary file",
"2": "Audio tracks were not normalized"
},
"Description": "Normalizes all audio tracks in a video file using FFMPEGs loudnorm filter",
"Fields": {
"AllAudio": "All Audio Tracks",
"AllAudio-Help": "If all audio tracks should be normalized or if just the first track should be"
}
},
"AudioTrackReorder": {
"Outputs": {
"1": "Audio tracks re-ordred in new temporary file",
@@ -55,6 +77,18 @@
"CommandLine-Help": "The command line to run with FFMPEG.\n'{WorkingFile}': the working file of the flow\n'{Output}': The output file that will be passed as the last parameter to FFMPEG including the extension defined above."
}
},
"RemuxToMKV": {
"Descritption": "Remuxes a video file into a MKV container. All streams will be copied to the new container",
"Outputs": {
"1": "File remuxed to temporary file"
}
},
"RemuxToMP4": {
"Descritption": "Remuxes a video file into a MP4 container. All streams will be copied to the new container",
"Outputs": {
"1": "File remuxed to temporary file"
}
},
"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",
"Outputs": {
@@ -0,0 +1,76 @@
namespace FileFlows.VideoNodes
{
using FileFlows.Plugin;
using FileFlows.Plugin.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
public class AudioAdjustVolume: EncodingNode
{
public override int Outputs => 2;
public override string Icon => "fas fa-volume-up";
[NumberInt(1)]
[Range(0, 1000)]
public int VolumePercent { 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;
if (videoInfo.AudioStreams?.Any() != true)
{
args.Logger?.ILog("No audio streams detected");
return 2;
}
if(VolumePercent == 100)
{
args.Logger?.ILog("Volume percent set to 100, no adjustment necassary");
return 2;
}
List<string> ffArgs = new List<string>();
ffArgs.Add($"-map 0:v");
float volume = this.VolumePercent / 100f;
foreach (var audio in videoInfo.AudioStreams)
{
ffArgs.Add($"-map 0:{audio.Index} -filter:a \"volume={volume.ToString(".0######")}\"");
}
if (videoInfo.SubtitleStreams?.Any() == true)
ffArgs.Add("-map 0:s -c copy");
string ffArgsLine = string.Join(" ", ffArgs);
string extension = new FileInfo(args.WorkingFile).Extension;
if(extension.StartsWith("."))
extension = extension.Substring(1);
if (Encode(args, ffmpegExe, ffArgsLine, extension) == false)
return -1;
return 1;
}
catch (Exception ex)
{
args.Logger?.ELog("Failed processing VideoFile: " + ex.Message);
return -1;
}
}
}
}
@@ -0,0 +1,84 @@
namespace FileFlows.VideoNodes
{
using FileFlows.Plugin;
using FileFlows.Plugin.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
public class AudioNormalization: EncodingNode
{
public override int Outputs => 2;
public override string Icon => "fas fa-volume-up";
[Boolean(1)]
public bool AllAudio { 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;
if (videoInfo.AudioStreams?.Any() != true)
{
args.Logger?.ILog("No audio streams detected");
return 2;
}
//for (int i = 0; i < videoInfo.AudioStreams.Count; i++)
//{
// if (i > 0 && AllAudio == false)
// break;
List<string> ffArgs = new List<string>();
if(videoInfo.VideoStreams?.Any() == true)
ffArgs.Add($"-map 0:v");
for (int j = 0; j < videoInfo.AudioStreams.Count;j++)
{
var audio = videoInfo.AudioStreams[j];
if (AllAudio || j == 0)
{
int sampleRate = audio.SampleRate > 0 ? audio.SampleRate : 48_000;
ffArgs.Add($"-map 0:{audio.Index} -c:a {audio.Codec} -ar {sampleRate} -af loudnorm=I=-24:LRA=7:TP=-2.0");
}
else
ffArgs.Add($"-map 0:{audio.Index} -c copy");
}
if(videoInfo.SubtitleStreams?.Any() == true)
ffArgs.Add("-map 0:s -c copy");
string ffArgsLine = string.Join(" ", ffArgs);
string extension = new FileInfo(args.WorkingFile).Extension;
if (extension.StartsWith("."))
extension = extension.Substring(1);
if (Encode(args, ffmpegExe, ffArgsLine, extension) == false)
return -1;
//}
return 1;
}
catch (Exception ex)
{
args.Logger?.ELog("Failed processing VideoFile: " + ex.Message);
return -1;
}
}
}
}
+3 -1
View File
@@ -98,7 +98,9 @@
ffArgs.Add($"-map " + audio.IndexString);
}
ffArgs.Add("-map 0:s -c copy");
if (videoInfo.SubtitleStreams?.Any() == true)
ffArgs.Add("-map 0:s -c copy");
// this makes the first audio track now the default track
ffArgs.Add("-disposition:a:0 default");
+59
View File
@@ -0,0 +1,59 @@
namespace FileFlows.VideoNodes
{
using FileFlows.Plugin;
using System;
public class RemuxToMKV: EncodingNode
{
public override int Outputs => 1;
public override string Icon => "far fa-file-video";
public override int Execute(NodeParameters args)
{
string ffmpegExe = GetFFMpegExe(args);
if (string.IsNullOrEmpty(ffmpegExe))
return -1;
try
{
if (Encode(args, ffmpegExe, "-c copy -map 0", "mkv") == false)
return -1;
return 1;
}
catch (Exception ex)
{
args.Logger?.ELog("Failed processing VideoFile: " + ex.Message);
return -1;
}
}
}
public class RemuxToMP4 : EncodingNode
{
public override int Outputs => 1;
public override string Icon => "far fa-file-video";
public override int Execute(NodeParameters args)
{
string ffmpegExe = GetFFMpegExe(args);
if (string.IsNullOrEmpty(ffmpegExe))
return -1;
try
{
if (Encode(args, ffmpegExe, "-c copy -map 0", "mp4") == false)
return -1;
return 1;
}
catch (Exception ex)
{
args.Logger?.ELog("Failed processing VideoFile: " + ex.Message);
return -1;
}
}
}
}