通过python子进程的ffmpeg无法找到相机

2022-01-18 00:00:00 python subprocess ffmpeg directshow

问题描述

这里有一个奇怪的问题,我使用这个命令通过 ffmpeg(通过 windows 上的 cmd)捕获我的网络摄像头:

Weird problem here, i use this command to capture my webcam through ffmpeg (through cmd on windows):

ffmpeg -y -t 300 -rtbufsize 1024M -f dshow -i video="Lenovo EasyCamera" -c:v libx264 -preset veryslow -crf 25 Desktop.mkv

一切正常.但是当我通过 python 尝试相同的命令作为子进程时,它失败了.这是python代码:

and everything works fine. But when i try the very same command through python as a subprocess it fails. Here's the python code:

from subprocess import Popen
cmd = ['ffmpeg', '-y', '-t', '300', '-rtbufsize', '1024M', '-f', 'dshow', '-i', 'video="Lenovo EasyCamera"', '-c:v', 'libx264', '-preset', 'veryslow', '-crf', '25', 'Desktop.mkv']
p = Popen(cmd)

输出以下错误并冻结:

[dshow @ 00000000023a2cc0] Could not find video device with name ["Lenovo EasyCamera"] among source devices of type video.
video="Lenovo EasyCamera": I/O error

谁能解决这个问题并告诉我我做错了什么?还是python或子进程模块中的一些已知错误(使用python 3.6.1,但如果它可以帮助我解决这个问题,则不附加到特定版本)?

Can anyone figure this out and tell me what i'm doing wrong? Or is it some known bug in python or the subprocess module (using python 3.6.1, but not attached to the specific version if it will help me solve this problem)?

提前致谢!

PS 这个问题是对这个问题的后续,如果相关的话:如何在 windows 中使用 ffmpeg 抓取笔记本电脑网络摄像头视频

P.S. This question is a follow up to this one, if that's relevant: How to grab laptop webcam video with ffmpeg in windows


解决方案

问题是,在命令行中,video="Lenovo EasyCamera" 使用引号来确保空格没有让它成为另一个论点.

The problem is that, in the commandline, video="Lenovo EasyCamera" uses the quotes to make sure the space doesn't make it another argument.

您可以通过测试 python 文件看到这一点:

You can see this with a test python file:

import sys
print(sys.argv[1:])

> python print_argv.py video="Lenovo EasyCamera"
['video=Lenovo EasyCamera']
> python print_argv.py "video=Lenovo EasyCamera"
['video=Lenovo EasyCamera']
> python
>>> from subprocess import Popen
>>> cmd = ['python', 'print_argv.py', 'video="Lenovo EasyCamera"']
>>> p = Popen(cmd)
['video="Lenovo EasyCamera"']

ffmpeg 认为您正在寻找一个名为 "Lenovo EasyCamera" 而不是 Lenovo EasyCamera

ffmpeg thinks you're looking for a device called "Lenovo EasyCamera" instead of Lenovo EasyCamera

因此,您需要更改命令,使其不在引号中,因为 Popen 不会将其拆分为空格.

So, you need to change your command so that it is not in quotes, as Popen will not split it on spaces.

from subprocess import Popen
cmd = [..., '-i', 'video=Lenovo EasyCamera', ...]
p = Popen(cmd)

相关文章