私はいくつかの質問を見てきましたが、まだこれを理解することはできません。私はPyQtを使用しています。プログレスバーを作成できるように、
ffmpeg -i file.mp4 file.avi
を実行し、ストリームとして出力を取得することを望んでいます。
私はこれらの質問を見ました:
Can ffmpeg show a progress bar?catching stdout in realtime from subprocessこのコードを使用して、rsyncコマンドの出力を確認できます。
import subprocess, time, os, sys
cmd = "rsync -vaz -P source/ dest/"
p, line = True, 'start'
p = subprocess.Popen(cmd,
shell=True,
bufsize=64,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
for line in p.stdout:
print("OUTPUT>>> " + str(line.rstrip()))
p.stdout.flush()
しかし、コマンドを
ffmpeg -i file.mp4 file.avi
に変更すると、出力が表示されません。私はこれが標準出力/出力バッファリングと関係があると推測していますが、次のような行を読む方法については行き詰っています
frame= 51 fps= 27 q=31.0 Lsize= 769kB time=2.04 bitrate=3092.8kbits/s
進捗状況を把握するために使用できます。
誰かが私にffmpegからpythonにこの情報を取得する方法の例を教えてもらえますか?PyQtの使用の有無にかかわらず(可能であれば)
編集:
私はjlpのソリューションに行き着き、私のコードは次のようになりました。
import pexpect
cmd = 'ffmpeg -i file.MTS file.avi'
thread = pexpect.spawn(cmd)
print "started %s" % cmd
cpl = thread.compile_pattern_list([
pexpect.EOF,
"frame= *\d+",
'(.+)'
])
while True:
i = thread.expect_list(cpl, timeout=None)
if i == 0:
print "the sub process exited"
break
elif i == 1:
frame_number = thread.match.group(0)
print frame_number
thread.close
elif i == 2:
pass
これはこの出力を与えます:
started ffmpeg -i file.MTS file.avi
frame= 13
frame= 31
frame= 48
frame= 64
frame= 80
frame= 97
frame= 115
frame= 133
frame= 152
frame= 170
frame= 188
frame= 205
frame= 220
frame= 226
the sub process exited
パーフェクト!
子プロセスから動的なフィードバック/出力を得るために私が見つけた唯一の方法は、pexpectのようなものを使用することです:
import pexpect
cmd = "foo.sh"
thread = pexpect.spawn(cmd)
print "started %s" % cmd
cpl = thread.compile_pattern_list([pexpect.EOF,
'waited (\d+)'])
while True:
i = thread.expect_list(cpl, timeout=None)
if i == 0:
print "the sub process exited"
break
elif i == 1:
waited_time = thread.match.group(1)
print "the sub process waited %d seconds" % int(waited_time)
thread.close()
呼び出されたサブプロセスfoo.shは、10秒から20秒の間のランダムな時間だけ待機します。そのコードを次に示します。
#! /bin/sh
n=5
while [ $n -gt 0 ]; do
ns=`date +%N`
p=`expr $ns % 10 + 10`
sleep $p
echo waited $p
n=`expr $n - 1`
done
ffmpegから取得する出力に一致する正規表現を使用し、プログレスバーを表示するために何らかの計算を行いますが、少なくともffmpegからのバッファーなしの出力が取得されます。