【问题标题】:Executing ffmpeg from Python从 Python 执行 ffmpeg
【发布时间】:2016-07-12 03:25:19
【问题描述】:

我正在尝试对目录中的所有 WAV 文件运行 ffmpeg 以将它们转换为 mp3。当我在我的 Fedora Linux 机器上从命令行运行此命令时,它运行良好:

/usr/bin/ffmpeg -i "Name With Spaces.wav" Name_With_Spaces.mp3

其中Name With Spaces.wav 是当前目录中的一个文件。但是,在同一目录下运行的 Python 3.2:

import os
files = os.listdir()
os.execl('/usr/bin/ffmpeg', '-i \"' + files[0] + '\"', files[0][:-4].replace(' ', '_') + '.mp3')

给我错误(来自ffmpeg):必须指定至少一个输入文件。我不明白为什么这不起作用,因为'-i \"' + files[0] + '\"' 的计算结果为-i "Name With Spaces.wav",而files[0][:-4].replace(' ', '_') + '.mp3' 的计算结果为Name_With_Spaces.mp3

我尝试转义空格,使用不同的引号,使用完整路径(如/home/.../music/Name\ With\ Spaces.wav),实际上用真实文本替换参数,但没有任何效果。我怎样才能让它工作?

【问题讨论】:

  • 它是否适用于没有空格的文件名?
  • @Fishstick 不,它没有

标签: python python-3.x ffmpeg


【解决方案1】:

如果你想使用 os.execl 方法,你必须稍微修改一下你的语法,并且 -i 必须作为列表中的不同项目

import os
files = os.listdir()
# Separated the args to make it clear
args = '/usr/bin/ffmpeg', '-i', files[0], files[0][:-4].replace(' ', '_') + '.mp3'
# Yes, the binary appears twice
os.execl('/usr/bin/ffmpeg', *args)

各种 exec* 函数采用新参数列表 程序加载到进程中。在每种情况下,这些中的第一个 参数作为它自己的名称而不是作为新程序传递给新程序 用户可能在命令行上键入的参数。对于 C 程序员,这是传递给程序 main() 的 argv[0]。为了 例如, os.execv('/bin/echo', ['foo', 'bar']) 只会打印 bar on 标准输出; foo 似乎会被忽略。

来源https://docs.python.org/2/library/os.html#process-management

【讨论】:

  • 好的,这也可以,但是双二进制有点违反直觉。你能解释一下为什么必须这样吗?
  • 文档中有更多信息,但我不知道您是否使用 python、C 等编写了 shell 脚本,但 execl 的工作方式与类 Unix 方法完全一样,所以基本上第一个参数始终是程序本身。
  • 我将使用与此相关的文档参考更新答案
  • 正如文档所说,您的第一个参数 -i 即 arg[0] 被忽略,因为在这种情况下它应该是您的程序名称 ffmpeg。然后 ffmpeg 抱怨,因为您没有提供输入。
【解决方案2】:

我认为这与os.execl 如何读取您发送的输入有关。从文档中,它将获得的每个参数解释为一个单独的参数,而不是一组参数。所以它在内部做的事情比" ".join() 你给它的论点更聪明。它可能会转义您发送的每个参数中引号外的任何空格。

解决此问题的一种方法是将参数的“-i”部分与参数的其余部分分开:

os.execl('/usr/bin/ffmpeg', '-i', \"' + files[0] + '\", files[0][:-4].replace(' ', '_') + '.mp3')

出于理智,如果您使用os.system 执行相同的代码,它应该可以工作:

os.system(" ".join(['/usr/bin/ffmpeg', '-i \"' + files[0] + '\"', files[0][:-4].replace(' ', '_') + '.mp3']))

或者,您可以使用子流程:

import subprocess
subprocess.call(['/usr/bin/ffmpeg', '-i', \"' + files[0] + '\", files[0][:-4].replace(' ', '_') + '.mp3'])

【讨论】:

  • 我认为您在os.system 调用的末尾缺少),但这样就可以了。谢谢! subprocess 解决方案不起作用,它给出了一个错误(同样来自 ffmpeg),因为它不理解 -i 选项。
  • 编辑了我的回复 - 这有帮助吗?
猜你喜欢
  • 2019-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-29
相关资源
最近更新 更多