subprocess.run 输出为空(python 3.8)

Mar*_*aje 6 python subprocess ffmpeg

我正在尝试使用以下代码捕获命令的输出:

lines = subprocess.run(['ffmpeg', '-hide_banner', '-nostats', '-i', in_filename, '-vn', '-af', 'silencedetect=n={}:d={}'.format(silence_threshold, silence_duration), '-f', 'null', '-'], capture_output=True, text=True, shell=True, check=True, encoding='utf-8').stdout 
print (lines)
Run Code Online (Sandbox Code Playgroud)

但lines是一个空字符串并且没有打印任何内容。删除后capture_output=True,将显示正确的输出(不打印)。

我测试了许多组合,包括删除所有subprocess.run参数并仅包含capture_output=True相同的结果。

我还用很少的参数进行了测试,举了一个最小的例子:subprocess.run(['ffmpeg', '-version'], capture_output=True, text=True, shell=True, check=True, encoding='utf-8').stdout

还进行了测试stdout=subprocess.PIPEstderr=subprocess.PIPE作为subprocess.run参数而不是capture_output=True

我不明白发生了什么事。提前致谢!

Vey*_*gun 3

默认情况下ffmpeg 记录stderr. 您使用capture_output=True, 所以run()func 将捕获stdoutstderr

Q-1) Lines 是一个空字符串并且没有打印任何内容。

A-1) 这是正常的,因为 ffmpeg 默认情况下不记录到 stdout。

Q-2)capture_output=True删除后,会显示正确的输出(不打印)。

A-2)这是我们所期望的,当您删除capture_output=True然后ffmpeg登录stderr(默认情况下登录到您的终端/控制台)时,您将在屏幕上看到 ffmpeg 输出(stdin,stdout,and stderr 这些输出通常附加到用户的终端)。当您使用 时capture_output=True,ffmpeg 的日志会转到pipeRAM 中的内核文件状对象(在 Unix 和 Linux 中,对 Windows 没有了解)。print()这就是为什么如果没有捕获的标准输出,您在终端/控制台中看不到任何输出

subprocess.run()func 将返回CompletedProcess(process.args, retcode, stdout, stderr)实例,您可以获取stdout属性的值,但我们不需要这个,我们需要stderr属性的值,因为正如我上面所说,默认情况下ffmpeg会记录到stderr

您需要修改它,例如;

lines = subprocess.run(['ffmpeg', '-hide_banner', '-nostats', '-i', in_filename, '-vn', '-af', 'silencedetect=n={}:d={}'.format(silence_threshold, silence_duration), '-f', 'null', '-'], capture_output=True, text=True, shell=True, check=True, encoding='utf-8').stderr
print (lines)
Run Code Online (Sandbox Code Playgroud)