首页 > 解决方案 > 在 Windows 上使用 Popen (python) 的 ffmpeg

问题描述

我正在尝试将 ffmpeg 与 Popen 一起使用。我正在尝试的 ffmpeg 命令可在 cmd 上运行,但在使用 Popen 时出现错误。

我正在使用独立的 ffmpeg .exe:

ffmpeg -f gdigrab -offset_x 10 -offset_y 20 -show_region 1 -i desktop -video_size 1536x864 -b:v 2M -maxrate 1M -bufsize 1M -tune fastdecode -crf 15 -preset ultrafast -pix_fmt yuv420p -r 25 <path>/video.mov -qp 1 -y -an

这给了我Invalid argument,但是如果我删除最后一个参数以使输出成为字符串上的最后一件事,我会得到一个不同的错误:

Output file #0 does not contain any stream

我尝试使用-f dshow -i video="UScreenCapture"而不是 gdigrab,但最终无论有无参数,都会给我同样的错误。

这两个命令都在命令行上工作。

在命令行上,这ffmpeg -list_devices true -f dshow -i dummy将返回:

[dshow @ 000001b24fa6a300] DirectShow video devices (some may be both video and audio devices)
[dshow @ 000001b24fa6a300]  "Integrated Webcam"
[dshow @ 000001b24fa6a300]     Alternative name "@device_pnp_\\?\usb#vid_1bcf&pid_2b8a&mi_00#6&2c03619a&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 000001b24fa6a300]  "UScreenCapture"
[dshow @ 000001b24fa6a300]     Alternative name "@device_sw_{860BB310-5D01-11D0-BD3B-00A0C911CE86}\UScreenCapture"
[dshow @ 000001b24fa6a300] DirectShow audio devices
[dshow @ 000001b24fa6a300]  "Microphone (Realtek Audio)"
[dshow @ 000001b24fa6a300]     Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{35EBFC89-7B09-4557-8032-85AA0B688FE9}"

但是在 popen 我无法检查它:

-list_devices true -f dshow -i dummy: Invalid argument

对于我正在使用的代码的 python 部分:

p = subprocess.Popen([getPathForFile("windows/ffmpeg").replace('\\','/'),  " -f gdigrab -offset_x 10 -offset_y 20 -show_region 1 -i desktop -video_size 1536x864 -b:v 2M -maxrate 1M -bufsize 1M -tune fastdecode -crf 15 -preset ultrafast -pix_fmt yuv420p -r 25 -qp 1 -y -an "+ path.replace('\\\\','/').replace('\\','/')+"video.mov"], shell=True)

getPathForFile是一个返回路径的自定义函数。这是正确的,主要是因为我得到的错误来自ffmpeg,所以......

我在 Windows 10 上。FFmpeg 4.0。蟒蛇 3.5。

有什么想法为什么我会在 Popen 上而不是在命令行上收到这些错误以及如何修复它们?(主要是第二个错误)

标签: python-3.xffmpeg

解决方案


将每个参数放在自己的字符串中并关闭外壳。像这样:

import subprocess
import os

cmd = ["-f", "gdigrab", "-offset_x", "10", "-offset_y", "20",
    "-show_region", "1", "-video_size", "1536x864", "-i", "desktop",
    "-b:v", "2M", "-maxrate", "1M", "-bufsize", "1M", "-tune", "fastdecode",
    "-preset", "ultrafast", "-pix_fmt", "yuv420p",
    "-r", "25", "-qp", "1", "-y", "-an",
    os.path.join(path, "video.mov")]

p = subprocess.Popen([getPathForFile("windows/ffmpeg")]+cmd)
p.communicate()

推荐阅读