Python通过subprocess调用FFmpeg录制摄像头视频故障求助
解决Python subprocess调用FFmpeg录制摄像头的问题
问题原因分析
- 使用
shell=True时,FFmpeg进程被shell进程包裹,直接终止子进程无法杀掉底层shell,导致录制无法停止。 - 使用
shell=False时,若给设备名加引号,引号会被FFmpeg当成设备名的一部分,导致找不到设备;若不加引号直接写带空格的设备名,subprocess会把空格作为参数分隔符,将设备名拆成多个无效参数,导致FFmpeg无法正常工作,生成损坏的视频文件。
解决方案
直接将FFmpeg命令拆分为参数列表,每个参数作为列表的独立元素,设备名保留原始空格和括号,不需要加引号:
示例代码
import subprocess import time # 拆分后的FFmpeg参数列表,每个参数独立,设备名完整保留原始格式 ffmpeg_args = [ "ffmpeg", "-f", "dshow", "-rtbufsize", "2000M", "-i", "video=HP HD Camera:audio=Headset (realme Buds Wireless 2 Neo Hands-Free AG Audio)", "-y", "-vcodec", "libx264", "-crf", "24", "output.mp4" ] # 启动FFmpeg进程(shell=False是核心) proc = subprocess.Popen(ffmpeg_args, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # 模拟录制时长(实际场景可根据业务逻辑触发终止) time.sleep(5) # 终止录制,直接结束FFmpeg进程 proc.terminate() # 等待进程结束并获取输出(用于排查错误) stdout, stderr = proc.communicate() # 打印FFmpeg的错误信息,方便定位问题 print(stderr.decode("utf-8", errors="ignore"))
关键说明
shell=False时,subprocess会将列表中的每个元素直接作为参数传递给FFmpeg,不会解析空格或引号,因此设备名能被正确识别。- 终止进程时使用
proc.terminate()或proc.kill(),可以直接结束FFmpeg进程,不会有shell残留的问题。 - 如果仍有问题,查看
stderr的输出内容,FFmpeg会明确提示设备是否存在、参数是否有误等信息。
内容的提问来源于stack exchange,提问作者Eular
相关产品推荐
相关产品推荐

