Eul*_*lar 2 audio video subprocess ffmpeg
我正在尝试使用 ffmpeg 从 python 录制网络摄像头视频。从 cmd 运行时,以下 ffmpeg 可以正常工作
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
Run Code Online (Sandbox Code Playgroud)
我已经检查了音频和视频输入
ffmpeg -list_devices true -f dshow -i dummy
Run Code Online (Sandbox Code Playgroud)
现在,当我尝试使用子进程调用命令时,会发生问题。我可以像这样传递整个命令
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
Run Code Online (Sandbox Code Playgroud)
现在,由于这是运行的,因此shell=True不会终止录制,并且我已经检查了不同的解决方案,但它们也不起作用。所以,我选择了shell=False。我尝试过
recorder = subprocess.Popen(['ffmpeg', '-f', 'dshow', '-rtbufsize', '2000M', '-t', '60', '-i', 'video="HP HD Camera":audio="Headset (realme Buds Wireless 2 Neo Hands-Free AG Audio)"', '-y', '-vcodec', 'libx264', '-crf', '24', 'output.mp4'],shell=False)
Run Code Online (Sandbox Code Playgroud)
这会引发错误
[dshow @ 0000024f2becd540] Could not find video device with name ["HP HD Camera"] among source devices of type video.
video="HP HD Camera":audio="Headset (realme Buds Wireless 2 Neo Hands-Free AG Audio)": I/O error
Run Code Online (Sandbox Code Playgroud)
然后,我尝试了
ffmpeg -list_devices true -f dshow -i dummy
Run Code Online (Sandbox Code Playgroud)
这会创建输出,但视频无法播放。
如何解决这个问题?
我们可以添加双引号,让 Pythonsubprocess知道该字符串是一个参数,并且我们必须优雅地关闭 FFmpeg。
添加双引号:
将以下部分替换video="HP HD Camera":audio="Headset (realme Buds Wireless 2 Neo Hands-Free AG Audio)"为:需要
"video=""HP HD Camera"":audio=""Headset (realme Buds Wireless 2 Neo Hands-Free AG Audio)"""
加倍引号,因为is 位于引号之间。"""" ... "
""我们也可以在没有:的情况下使用它"video=HP HD Camera:audio=Headset (realme Buds Wireless 2 Neo Hands-Free AG Audio)"。
为了获得可播放的文件,我们必须优雅地关闭 FFmpeg 。
为了简单地记录 10 秒,我们可以添加-t 10参数。
为了以编程方式优雅地关闭 FFmpeg,我们可以写入'q'.encode("GBK")FFmpegstdin子进程的管道。
写入q模拟q用户按下该键(停止录制)。
添加stdin=subprocess.PIPE参数到subprocess.Popen.
添加后time.sleep(10):
recorder.stdin.write('q'.encode("GBK")) # Simulate user pressing q key
recorder.communicate()
Run Code Online (Sandbox Code Playgroud)
添加recorder.wait()(而不是recorder.terminate()和recorder.kill())。
作为良好的实践,我们还可以添加shlex.split(...)将命令行转换为参数列表的功能。
在 Windows 中它应该可以在没有它的情况下工作,但在 Linux 中则不然。
代码示例:
recorder.stdin.write('q'.encode("GBK")) # Simulate user pressing q key
recorder.communicate()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1797 次 |
| 最近记录: |