我正在尝试使用python + ffmpeg + oggenc将任何音频文件转换为ogg。该计划几乎可以运作。但对于大文件(我认为> ~6mb),ffmpeg进程开始在pipe_wait上休眠。我不知道它等待哪条管道。
如果我杀了ffmpeg进程,oggenc进程会继续,我得到的结果ogg文件大约是所有声音的2:40。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from subprocess import Popen, PIPE
from sys import argv
ffmpeg = Popen([
"ffmpeg",
"-i", argv[1],
"-vcodec", "null",
"-acodec", "pcm_s16le",
"-ac", "2",
"-ab", "44100",
"-f", "wav",
"-"
],stdout = PIPE,stderr = PIPE)
oggenc = Popen([
"oggenc",
"-", "--raw",
"-q", "4",
"-o", argv[2]
],stdin = ffmpeg.stdout,stderr = PIPE)
oggenc.communicate()
ffmpeg.communicate()
编辑:
我想我可以补充说这很有效:
#!/bin/bash
ffmpeg -i "$1" -vcodec null -acodec pcm_s16le -ac 2 -ab 44100 -f wav - | oggenc - --raw -q 4 -o "$2"
答案 0 :(得分:5)
您究竟对这两个管道的stderr
渠道做了什么?
编码器/解码器通常会产生大量的stderr输出,作为状态更新;此输出通过管道输送到您的进程,缓冲区将变满。也许您应该在(无用的,我认为)ffmpeg.stderr.read()
调用之前添加一些虚拟.communicate
调用,或者甚至更好地完全删除stderr=PIPE
个参数。
对于等效的>/dev/null
,请执行以下操作:
nulfp = open(os.devnull, "w")
…
… = subprocess.Popen(…, stderr=nulfp.fileno())
显然,您可以为要忽略的所有nulfp
重复使用相同的stderr
。
答案 1 :(得分:0)
看看谁需要传递管道很棘手,我的意思是你应该使用像NetBeans这样的调试器来帮助收集更多线索。管道可能不是最好的方法,也许使用临时文件可以简化事情。