如何让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时:
- Python主线程会捕获KeyboardInterrupt并设置
prepareToStop=1; - FFMPEG子进程因已配置忽略SIGINT,会继续完成当前转码任务;
- 待FFMPEG执行完毕后,脚本才会退出循环,进入shutdown流程。
内容的提问来源于stack exchange,提问作者Straxan
相关产品推荐
相关产品推荐

