Files
ytdlp-gui/FFmpeg.cs
2025-05-20 03:59:39 +02:00

134 lines
4.0 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 = ".";
this.header_regex = new Regex(@"Duration: (\d+):(\d+):(\d+)\.(\d+)");
this.progress_regex = new Regex(@"time=(\d+):(\d+):(\d+)\.(\d+)");
}
~FFmpegProcess()
{
Cancel();
}
public async Task<string> 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((float)progress / duration));
}
}
process.WaitForExit();
process.Close();
Finished?.Invoke(this, new EventArgs());
return null;
}
public void Cancel()
{
bool finished = true;
try // to kill the process before deleting the file
{
finished = process.HasExited;
process.Kill();
process.WaitForExit();
process.Close();
}
catch { }
// if (!finished && File.Exists(output_file))
// System.IO.File.Delete(output_file);
}
private readonly Process process;
private readonly string output_file;
private readonly CultureInfo ci;
private readonly Regex header_regex;
private readonly Regex progress_regex;
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);
}
}
}