【问题标题】:Running a 2-pass video conversion using Python's subprocess module and ffmpeg使用 Python 的 subprocess 模块和 ffmpeg 运行 2-pass 视频转换
【发布时间】:2012-08-26 13:44:42
【问题描述】:

我正在尝试转换一堆视频以在我的 iPad 上播放。我正在使用 subprocess 模块,据我了解,它在与我的脚本不同的进程中启动二进制文件。我不确定如何处理要求第一个进程在第二个进程开始之前终止的 2-pass 编码。

这是我的代码:

def convert(filename):
  extension = filename[-3:]

  destination_filename_720 = filename[-4:] + '-a720p' + '.mp4'
  destination_filename_1080 = filename[-4:] + '-a1080p' + '.mp4'

  p = subprocess.Popen(['ffmpeg','-i', str(filename) ,
                        '-acodec' , 'aac' ,
                        '-ab' , '160k' ,
                        '-ac' , '2' ,
                        '-vcodec' , 'libx264' ,
                        '-strict' , '-2' ,
                        '-vpre' , 'ipod640' ,
                        '-threads' , '8' ,
                        '-s' , '1280x720' ,
                        '-b:v' , '2000k' ,
                        '-pass' , '1' ,
                        '-y' ,
                        destination_filename_720])

  p = subprocess.Popen(['ffmpeg','-i', str(filename) ,
                        '-acodec' , 'aac' ,
                        '-ab' , '160k' ,
                        '-ac' , '2' ,
                        '-vcodec' , 'libx264' ,
                        '-strict' , '-2' ,
                        '-vpre' , 'ipod640' ,
                        '-threads' , '8' ,
                        '-s' , '1280x720' ,
                        '-b:v' , '2000k' ,
                        '-pass' , '2' ,
                        '-y' ,
                        destination_filename_720])

调用 convert() 函数后,两个进程都会立即生成。

第二个过程失败,因为第一个过程尚未完成。

我该如何解决这个问题?或者,有没有更好的方法?

【问题讨论】:

  • ffmpg 不能在 stdios 上运行?不能将第一个进程的标准输出连接到第二个进程的标准输入吗?
  • 这很奇怪。当我从 shell 运行它时,我看到它们几乎同时执行。第二个失败,但第一个通过。 ffmpeg 不会使用这些标志进入背景。
  • @tmc 我在这样做时遇到了麻烦,因为元数据并不总是在文件的开头。输出到标准输出很好,但输入给了我问题,除非元数据在开头。
  • 如果第一个通过,并且不在后台,那么它们如何同时进行?
  • 如果你真的不能从下一个管道传输,我想我只会对目录中的文件进行第一次传递而不是第二次传递;而不是尝试一次对每个文件进行两次传递。

标签: python ffmpeg subprocess


【解决方案1】:

只需将 p.wait() 添加到您的 supprocess,它不会继续,直到您的第一次通过完成。

p = subprocess.Popen(['ffmpeg','-i' ...etc])
p.wait()

出于可读性目的,像在终端中那样编写命令可能更容易,然后只需使用 split() 将其放入字符串数组中。示例:

p = subprocess.Popen(
   'ffmpeg -i blah.mov -s 128x72 blah.jpg'.split())
p.wait()

【讨论】:

  • 我从未想到过 "".split() 技巧,您先生是个天才!
  • subprocess.check_call() 可用于具有相同参数的第一个命令。您不需要 () 围绕字符串 "".split() 工作。支持带空格的文件:[arg1, file_with_spaces_in_a_variable] + 'constant args with no shell meta chars'.split() + [argn]
  • 好收获。我会更新的。额外的 () 来自我将变量传递到字符串中的快速复制粘贴。
【解决方案2】:

(没有找到“评论”链接,所以为“回答”:)

最后一行应该是 1080,而不是 720?

【讨论】:

    【解决方案3】:

    你最好使用 pexpect,因为 ffmpeg 通常不会刷新输出

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-31
      • 2010-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-24
      • 2010-11-09
      相关资源
      最近更新 更多