mirror of
https://github.com/revenz/FileFlowsPlugins.git
synced 2026-02-14 07:18:27 -06:00
FF-1811: Fixing blocking issue with reading audio information
This commit is contained in:
@@ -34,37 +34,40 @@ public class FFmpegHelper(string ffmpeg, string ffprobe) : IFFmpegHelper
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var process = new Process())
|
||||
using var process = new Process();
|
||||
process.StartInfo = new ProcessStartInfo
|
||||
{
|
||||
process.StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = ffmpeg,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true,
|
||||
ArgumentList = {
|
||||
"-hide_banner",
|
||||
"-i",
|
||||
file
|
||||
}
|
||||
};
|
||||
process.Start();
|
||||
|
||||
bool exited = process.WaitForExit(60000);
|
||||
if (exited == false)
|
||||
{
|
||||
process.Kill();
|
||||
string pkOutput = process.StandardError.ReadToEnd()?.EmptyAsNull() ?? process.StandardOutput.ReadToEnd();
|
||||
return Result<string>.Fail("Process timed out." + Environment.NewLine + pkOutput);
|
||||
FileName = ffmpeg,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow = true,
|
||||
ArgumentList = {
|
||||
"-hide_banner",
|
||||
"-i",
|
||||
file
|
||||
}
|
||||
};
|
||||
|
||||
// we use error here, since we're not specify an output file, FFmpeg will report it as an error, but we don't care
|
||||
string output = process.StandardOutput.ReadToEnd();
|
||||
string error = process.StandardError.ReadToEnd();
|
||||
process.Start();
|
||||
|
||||
return output?.EmptyAsNull() ?? error;
|
||||
// Read asynchronously from both output and error streams
|
||||
var outputTask = process.StandardOutput.ReadToEndAsync();
|
||||
var errorTask = process.StandardError.ReadToEndAsync();
|
||||
|
||||
bool exited = process.WaitForExit(60000);
|
||||
if (!exited)
|
||||
{
|
||||
process.Kill();
|
||||
string pkOutput = errorTask.Result.EmptyAsNull() ?? outputTask.Result;
|
||||
return Result<string>.Fail("Process timed out." + Environment.NewLine + pkOutput);
|
||||
}
|
||||
|
||||
// Await both the output and error tasks
|
||||
string output = outputTask.Result;
|
||||
string error = errorTask.Result;
|
||||
|
||||
return output?.EmptyAsNull() ?? error;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -93,18 +96,24 @@ public class FFmpegHelper(string ffmpeg, string ffprobe) : IFFmpegHelper
|
||||
file
|
||||
}
|
||||
};
|
||||
|
||||
process.Start();
|
||||
|
||||
// Read asynchronously from both output and error streams
|
||||
var outputTask = process.StandardOutput.ReadToEndAsync();
|
||||
var errorTask = process.StandardError.ReadToEndAsync();
|
||||
|
||||
bool exited = process.WaitForExit(60000);
|
||||
if (exited == false)
|
||||
if (!exited)
|
||||
{
|
||||
process.Kill();
|
||||
string pkOutput = process.StandardError.ReadToEnd()?.EmptyAsNull() ?? process.StandardOutput.ReadToEnd();
|
||||
string pkOutput = errorTask.Result.EmptyAsNull() ?? outputTask.Result;
|
||||
return Result<string>.Fail("Process timed out." + Environment.NewLine + pkOutput);
|
||||
}
|
||||
|
||||
string output = process.StandardOutput.ReadToEnd();
|
||||
string error = process.StandardError.ReadToEnd();
|
||||
// Await both the output and error tasks
|
||||
string output = outputTask.Result;
|
||||
string error = errorTask.Result;
|
||||
|
||||
if (string.IsNullOrEmpty(error) == false)
|
||||
return Result<string>.Fail($"Failed reading ffmpeg info: {error}");
|
||||
@@ -116,4 +125,5 @@ public class FFmpegHelper(string ffmpeg, string ffprobe) : IFFmpegHelper
|
||||
return Result<string>.Fail($"An error occurred: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// using FileFlows.VideoNodes.FfmpegBuilderNodes.Models;
|
||||
//
|
||||
// namespace FileFlows.VideoNodes.FfmpegBuilderNodes;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// FFmpeg Builder flow element that burns in a subtitle
|
||||
// /// </summary>
|
||||
// public class FfmpegBuilderSubtitleBurnIn: TrackSelectorFlowElement<FfmpegBuilderSubtitleBurnIn>
|
||||
// {
|
||||
// /// <inheritdoc />
|
||||
// public override string HelpUrl => "https://fileflows.com/docs/plugins/video-nodes/ffmpeg-builder/subtitle-burn-in";
|
||||
// /// <inheritdoc />
|
||||
// public override string Icon => "fas fa-fire";
|
||||
// /// <inheritdoc />
|
||||
// public override int Outputs => 2;
|
||||
//
|
||||
// /// <inheritdoc />
|
||||
// public override int Execute(NodeParameters args)
|
||||
// {
|
||||
// // Select a single subtitle track to burn in
|
||||
// var subtitleTrack = Model.SubtitleStreams.FirstOrDefault(track =>
|
||||
// !track.Deleted && StreamMatches(track));
|
||||
//
|
||||
// if (subtitleTrack == null)
|
||||
// {
|
||||
// args.Logger?.ILog("No matching subtitle track found to burn in.");
|
||||
// return 2; // No matching track, exit
|
||||
// }
|
||||
//
|
||||
// args.Logger?.ILog($"Burning in subtitle track: {subtitleTrack}");
|
||||
//
|
||||
// // Build FFmpeg command for burning in the subtitle
|
||||
// string subtitleFilter = BuildSubtitleFilter(subtitleTrack);
|
||||
// if (string.IsNullOrEmpty(subtitleFilter))
|
||||
// {
|
||||
// args.Logger?.ILog("Failed to build subtitle filter for FFmpeg.");
|
||||
// return 2; // Failed to create subtitle filter
|
||||
// }
|
||||
//
|
||||
// Model.VideoStreams[0].Filter.Add(subtitleFilter); // Add the subtitle filter to the FFmpeg filter chain
|
||||
// subtitleTrack.Deleted = true;
|
||||
//
|
||||
// return 1;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Builds the FFmpeg filter string for burning in the selected subtitle track.
|
||||
// /// </summary>
|
||||
// /// <param name="subtitleTrack">The subtitle track to burn in.</param>
|
||||
// /// <returns>FFmpeg filter string for burning in the subtitle.</returns>
|
||||
// private string BuildSubtitleFilter(FfmpegSubtitleStream subtitleTrack)
|
||||
// {
|
||||
// // For different subtitle codecs, we need different filter formats
|
||||
// if (subtitleTrack.Codec.ToLowerInvariant() is "subrip" or "srt" or "ass")
|
||||
// {
|
||||
// // FFmpeg filter for SRT subtitles
|
||||
// if (int.TryParse(subtitleTrack.Stream.IndexString.Split(':')[0], out int index) == false)
|
||||
// return null;
|
||||
// if (index < 0 || index > Model.InputFiles.Count)
|
||||
// return null;
|
||||
//
|
||||
// return $"subtitles={Model.InputFiles[index].FileName}:{subtitleTrack.Stream.TypeIndex}";
|
||||
// }
|
||||
//
|
||||
// // Unsupported subtitle format
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,67 @@
|
||||
// #if(DEBUG)
|
||||
//
|
||||
// using FileFlows.VideoNodes.FfmpegBuilderNodes;
|
||||
// using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
// using VideoNodes.Tests;
|
||||
//
|
||||
// namespace FileFlows.VideoNodes.Tests.FfmpegBuilderTests;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Tests the subtitle burning in
|
||||
// /// </summary>
|
||||
// [TestClass]
|
||||
// public class FFmpegBuilder_SubtitleBurnInTests : VideoTestBase
|
||||
// {
|
||||
// NodeParameters args;
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Sets up the test environment before each test.
|
||||
// /// Initializes video parameters and executes the video file setup.
|
||||
// /// </summary>
|
||||
// private void InitVideo(string file)
|
||||
// {
|
||||
// args = GetVideoNodeParameters(file);
|
||||
// VideoFile vf = new VideoFile();
|
||||
// vf.PreExecute(args);
|
||||
// vf.Execute(args);
|
||||
//
|
||||
// FfmpegBuilderStart ffStart = new();
|
||||
// ffStart.PreExecute(args);
|
||||
// Assert.AreEqual(1, ffStart.Execute(args));
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// Burn In
|
||||
// /// </summary>
|
||||
// [TestMethod]
|
||||
// public void BurnIn()
|
||||
// {
|
||||
// InitVideo(VideoSubtitles);
|
||||
//
|
||||
// var ffSubtitleBurnIn = new FfmpegBuilderSubtitleBurnIn()
|
||||
// {
|
||||
// CustomTrackSelection = true,
|
||||
// TrackSelectionOptions = new()
|
||||
// {
|
||||
// new("Language", "English")
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// ffSubtitleBurnIn.PreExecute(args);
|
||||
// ffSubtitleBurnIn.Execute(args);
|
||||
//
|
||||
// var ffRemoveSubtitles = new FfmpegBuilderAudioTrackRemover();
|
||||
// ffRemoveSubtitles.RemoveAll = true;
|
||||
// ffRemoveSubtitles.StreamType = "Subtitle";
|
||||
// ffRemoveSubtitles.PreExecute(args);
|
||||
// ffRemoveSubtitles.Execute(args);
|
||||
//
|
||||
// var ffExecutor = new FfmpegBuilderExecutor();
|
||||
// ffExecutor.PreExecute(args);
|
||||
// int result = ffExecutor.Execute(args);
|
||||
//
|
||||
// Assert.AreEqual(1, result);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// #endif
|
||||
Reference in New Issue
Block a user