如何正确关闭调用youtube-dl下载Twitch流的控制台程序
问题:终止youtube-dl进程后生成.part文件无法正常使用
按下控制台按键后,youtube-dl及ffmpeg进程被终止,但生成的文件为.part后缀,无法正常使用。预期应生成可用的.mp4文件,但未实现。
测试代码
string url = "https://www.twitch.tv/ricoy"; string outputPath = @"D:\ruta_del_archivo_salida.mp4"; ProcessStartInfo startInfo = new ProcessStartInfo { FileName = "youtube-dl", Arguments = $"-f best -o \"{outputPath}\" \"{url}\"", //RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using (Process process = new Process()) { process.StartInfo = startInfo; process.Start(); //var output = process.StandardOutput.ReadToEnd(); //process.WaitForExit(); Console.Read(); KillProcessAndChildren(process.Id); } static void KillProcessAndChildren(int pid) { // Cannot close 'system idle process'. if (pid == 0) { return; } ManagementObjectSearcher searcher = new ManagementObjectSearcher ("Select * From Win32_Process Where ParentProcessID=" + pid); ManagementObjectCollection moc = searcher.Get(); foreach (ManagementObject mo in moc) { KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"])); } try { Process proc = Process.GetProcessById(pid); proc.Kill(); } catch (ArgumentException) { // Process already exited. } }
解决方案
问题出在你直接强制杀死进程时,youtube-dl还没来得及完成文件收尾工作——它会先把下载内容写到临时的.part文件里,等下载完成后才会重命名为你指定的.mp4文件,强制终止会打断这个流程。
方案1:等待下载完成后自动退出
把代码中注释掉的process.WaitForExit();取消注释,同时删掉Console.Read();和KillProcessAndChildren(process.Id);。这样程序会自动等待youtube-dl完成下载,它会正常完成文件收尾,生成可用的.mp4文件。修改后的核心代码:
using (Process process = new Process()) { process.StartInfo = startInfo; process.Start(); // 等待下载进程完成 process.WaitForExit(); }
方案2:手动触发终止但保留可用文件
不要直接用Kill()强制终止,而是给youtube-dl发送正常的终止信号(比如Ctrl+C),让它有机会处理临时文件。可以通过Windows API实现:
首先添加API导入:
using System.Runtime.InteropServices; [DllImport("kernel32.dll", SetLastError = true)] static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId); [DllImport("kernel32.dll", SetLastError = true)] static extern bool SetConsoleCtrlHandler(IntPtr handlerRoutine, bool add);
然后替换原有的终止逻辑:
using (Process process = new Process()) { process.StartInfo = startInfo; process.Start(); Console.Read(); // 先禁用当前进程的Ctrl+C响应,避免自己被终止 SetConsoleCtrlHandler(IntPtr.Zero, true); // 向目标进程组发送Ctrl+C信号 GenerateConsoleCtrlEvent(0, (uint)process.Id); // 等待进程正常退出,完成文件收尾 process.WaitForExit(); // 恢复当前进程的Ctrl+C响应 SetConsoleCtrlHandler(IntPtr.Zero, false); }
这种方式下,youtube-dl收到终止信号后,会完成当前的写入操作,把.part文件重命名为目标.mp4后再退出,生成的文件就能正常使用了。
内容的提问来源于stack exchange,提问作者ElPavlillo
相关产品推荐
相关产品推荐

