You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让FFMPEG忽略KeyboardInterrupts,完成进程后再终止?

解决FFMPEG被KeyboardInterrupt中断的问题

问题根源:按下Ctrl+C时,操作系统会将SIGINT信号发送给整个进程组,包括Python脚本和它启动的FFMPEG子进程。os.system启动的FFMPEG会直接响应信号终止,而你的Python脚本的KeyboardInterrupt处理逻辑无法阻止子进程提前退出。

解决方案

改用subprocess模块替代os.system,通过配置让FFMPEG子进程忽略SIGINT信号,确保其完成任务后再执行脚本的shutdown流程。

步骤1:替换FFMPEG调用代码

导入所需模块后,将原os.system调用替换为以下代码:

import subprocess
import signal

# 构造命令(保持原逻辑不变)
command = f'"{ffmpeg}" -y -i uploaded/{videofile_name} -c:v {codec} {commandDimensions} {commandCompression} -c:a copy{commandAspect} {outputFilePath}'
print(f"Running command: {command}")

# 启动FFMPEG并设置忽略SIGINT信号
try:
    # preexec_fn在子进程启动前执行,配置忽略SIGINT
    proc = subprocess.Popen(command, shell=True, preexec_fn=lambda: signal.signal(signal.SIGINT, signal.SIG_IGN))
    proc.wait()  # 等待FFMPEG处理完成
    res = proc.returncode
except Exception as e:
    print(f"FFMPEG执行出错: {e}")
    res = -1

步骤2:安全优化(可选)

如果命令中包含不可信输入,建议将命令拆分为列表形式避免shell注入风险:

# 拆分命令为列表格式
cmd_list = [
    ffmpeg,
    "-y",
    "-i", f"uploaded/{videofile_name}",
    "-c:v", codec,
    *commandDimensions.split(),
    *commandCompression.split(),
    "-c:a", "copy",
    *commandAspect.split(),
    str(outputFilePath)
]

proc = subprocess.Popen(cmd_list, preexec_fn=lambda: signal.signal(signal.SIGINT, signal.SIG_IGN))
proc.wait()
res = proc.returncode

效果说明

修改后,按下Ctrl+C时:

  1. Python主线程会捕获KeyboardInterrupt并设置prepareToStop=1;
  2. FFMPEG子进程因已配置忽略SIGINT,会继续完成当前转码任务;
  3. 待FFMPEG执行完毕后,脚本才会退出循环,进入shutdown流程。

内容的提问来源于stack exchange,提问作者Straxan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 23:09:56