Files
ytdlp-gui/FFmpeg.cs
2025-05-23 01:34:48 +02:00

127 lines
3.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace ytdlp_gui
{
public class FFmpegProgressEventArgs : EventArgs
{
public FFmpegProgressEventArgs(float progress)
{
this.progress = progress;
}
public readonly float progress;
}
public class FFmpegProcess
{
public FFmpegProcess(Process process, string output_file)
{
this.process = process;
this.output_file = output_file;
ci = (CultureInfo)CultureInfo.CurrentCulture.Clone();
ci.NumberFormat.CurrencyDecimalSeparator = ".";
}
~FFmpegProcess()
{
Cancel();
}
public async Task Run()
{
if (File.Exists(output_file))
System.IO.File.Delete(output_file);
process.Start();
int duration = 0;
int progress = 0;
string line = null;
while ((line = await process.StandardError.ReadLineAsync()) != null)
{
Match match;
match = header_regex.Match(line);
if (match.Success)
{
GroupCollection groups = match.Groups;
duration =
int.Parse(groups[1].Value) * 3600
+ int.Parse(groups[2].Value) * 60
+ int.Parse(groups[3].Value);
}
match = progress_regex.Match(line);
if (match.Success)
{
GroupCollection groups = match.Groups;
progress =
int.Parse(groups[1].Value) * 3600
+ int.Parse(groups[2].Value) * 60
+ int.Parse(groups[3].Value);
Progress?.Invoke(this, new FFmpegProgressEventArgs(Math.Min((float)progress / duration, 1)));
}
}
if (stop)
return;
process.WaitForExit();
Finished?.Invoke(this, new EventArgs());
return;
}
public void Cancel()
{
stop = true;
if (!process.HasExited)
process.Kill();
process.WaitForExit();
}
private readonly Process process;
private readonly string output_file;
private readonly CultureInfo ci;
private readonly Regex header_regex = new Regex(@"Duration: (\d+):(\d+):(\d+)\.(\d+)");
private readonly Regex progress_regex = new Regex(@"time=(\d+):(\d+):(\d+)\.(\d+)");
private bool stop = false;
public event EventHandler<FFmpegProgressEventArgs> Progress;
public event EventHandler Finished;
}
public class FFmpeg : Program
{
public FFmpeg() : base("ffmpeg")
{
}
public FFmpegProcess Convert(string from, string to)
{
Process process = new Process();
process.StartInfo.FileName = program;
process.StartInfo.Arguments = String.Format(
"-i \"{0}\" \"{1}\"",
from.Replace("\"", "\"\"\""),
to.Replace("\"", "\"\"\"")
);
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
// process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
return new FFmpegProcess(process, to);
}
}
}