gpt4 book ai didi

audio - 带有python子进程Popen的ffmpeg

转载 作者:行者123 更新时间:2023-12-02 18:07:05 28 4
gpt4 key购买 nike

我正在尝试使用 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 

我已经检查了音频和视频输入

ffmpeg -list_devices true -f dshow -i dummy

现在,当我尝试使用子进程调用命令时出现问题。我可以像这样传递整个命令

import subprocess, time
recorder = subprocess.Popen('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', shell=True)
time.sleep(10)
recorder.terminate()
recorder.kill()

现在,由于这是使用 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)

这会引发错误

[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

然后,我尝试了

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)

这会创建输出,但视频无法播放。
如何解决这个问题?

最佳答案

我们可以添加双引号让 Python subprocess 知道字符串是一个参数,我们必须优雅地关闭 FFmpeg。

添加双引号:
将以下部分 video="HP HD Camera":audio="Headset (realme Buds Wireless 2 Neo Hands-Free AG Audio)" 替换为:
"video=""惠普高清摄像头"":audio=""耳机(realme Buds Wireless 2 Neo Hands-Free AG 音频)"""
需要加倍引号 "",因为 " 位于引号 "... " 之间。

我们也可以在没有""的情况下使用它:"video=HP HD Camera:audio=Headset (realme Buds Wireless 2 Neo Hands-Free AG Audio)" .


为了获得可播放的文件,我们必须优雅地关闭 FFmpeg。
对于简单的记录 10 秒,我们可以添加 -t 10 参数。

为了以编程方式优雅地关闭 FFmpeg,我们可以将 'q'.encode("GBK") 写入 FFmpeg 子进程的 stdin 管道。
编写 q 模拟用户按下 q 键(停止录制)。

  • stdin=subprocess.PIPE 参数添加到 subprocess.Popen

  • time.sleep(10) 之后添加:

     recorder.stdin.write('q'.encode("GBK"))  # Simulate user pressing q key
    recorder.communicate()
  • 添加 recorder.wait()(代替 recorder.terminate()recorder.kill())。


作为良好实践,我们还可以添加 shlex.split(...) 以将命令行转换为参数列表。
在 Windows 中,它应该可以在没有它的情况下工作,但在 Linux 中则不然。

代码示例:

import subprocess, time, shlex

recorder = subprocess.Popen(shlex.split('ffmpeg -f dshow -rtbufsize 2000M -t 60 -i """video=HP HD Camera:audio=Headset (realme Buds Wireless 2 Neo Hands-Free AG Audio)"":""audio=Headset (realme Buds Wireless 2 Neo Hands-Free AG Audio)"""'
' -y -vcodec libx264 -crf 24 output.mp4'), stdin=subprocess.PIPE, shell=False)

time.sleep(10)

recorder.stdin.write('q'.encode("GBK")) # Simulate user pressing q key
recorder.communicate()
recorder.wait()

关于audio - 带有python子进程Popen的ffmpeg,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73013200/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com