Commit 754b4441 authored by shrabbit's avatar shrabbit
Browse files

支持进程管理,退出时释放。

parent 5c7aa0cb
Loading
Loading
Loading
Loading
+9 −10
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ public class MainCommand : AsyncCommand<MainCommand.Settings>
    /// <param name="file">视频文件路径。</param>
    /// <param name="verbose">输出日志记录</param>
    /// <returns>时长与编码器名称。</returns>
    public static (TimeSpan Duration, string Codec) ProbeMedia(string ffmpegPath, string file, bool verbose)
    public static (TimeSpan Duration, string Codec) ProbeMedia(string ffmpegPath, string file, ProcessManager manager, bool verbose)
    {
        var si = new ProcessStartInfo
        {
@@ -134,10 +134,7 @@ public class MainCommand : AsyncCommand<MainCommand.Settings>
            CreateNoWindow = true,
        };

        using var process = new Process
        {
            StartInfo = si
        };
        using var process = manager.Add(si);

        process.StartInfo.ArgumentList.Add("-hide_banner");
        process.StartInfo.ArgumentList.Add("-i");
@@ -248,6 +245,8 @@ public class MainCommand : AsyncCommand<MainCommand.Settings>

    protected override async Task<int> ExecuteAsync(CommandContext context, Settings settings, CancellationToken cancellationToken)
    {
        using var manager = new ProcessManager();
        
        var dirBridge = DirectoryBridge.Default;
        dirBridge.CreateDirectory(Path.Combine(settings.Directory, settings.Disc));

@@ -255,7 +254,7 @@ public class MainCommand : AsyncCommand<MainCommand.Settings>

        foreach (var f in GetFiles(settings, dirBridge))
        {
            var (duration, codec) = ProbeMedia(settings.FfMpegPath, f, !settings.NoExecute);
            var (duration, codec) = ProbeMedia(settings.FfMpegPath, f, manager, !settings.NoExecute);
            var commands = GenerateFfMpegCommand(settings, f, duration, codec).ToArray();

            if (settings.NoExecute)
@@ -273,7 +272,7 @@ public class MainCommand : AsyncCommand<MainCommand.Settings>
                CancellationToken = cancellationToken,
            }, async (arr, ct) =>
            {
                if (await RunFfMpegAsync(settings.FfMpegPath, arr, ct) != 0)
                if (await RunFfMpegAsync(settings.FfMpegPath, arr, manager, ct) != 0)
                    Interlocked.Increment(ref failed);
            });
        }
@@ -293,7 +292,7 @@ public class MainCommand : AsyncCommand<MainCommand.Settings>
    /// <summary>
    /// 执行一条 ffmpeg 命令并返回退出码。
    /// </summary>
    private static async Task<int> RunFfMpegAsync(string ffmpegPath, string[] args, CancellationToken ct)
    private static async Task<int> RunFfMpegAsync(string ffmpegPath, string[] args, ProcessManager manager, CancellationToken ct)
    {
        var psi = new ProcessStartInfo
        {
@@ -308,7 +307,7 @@ public class MainCommand : AsyncCommand<MainCommand.Settings>
        foreach (var a in args)
            psi.ArgumentList.Add(a);

        using var process = new Process { StartInfo = psi };
        using var process = manager.Add(psi);

        if (!process.Start())
        {
+33 −0
Original line number Diff line number Diff line
using System.Collections.Concurrent;
using System.Diagnostics;

namespace VideoSlice.Cli;

public class ProcessManager : ConcurrentBag<Process>, IDisposable
{
    public Process Add(ProcessStartInfo psi)
    {
        var p = new Process
        {
            StartInfo = psi,
        };
        Add(p);
        
        return p;
    }
    
    public void Dispose()
    {
        foreach (var p in this)
        {
            try
            {
                p.Kill();
            }
            catch (Exception e)
            {
                // ignored
            }
        }
    }
}
 No newline at end of file