Sim*_*her 4 python subprocess ffmpeg
通过以下代码,我可以使用 Python、Numpy 和 FFMPEG 二进制文件将视频帧通过管道传输到 FFMPEG:
from __future__ import print_function
import subprocess
import numpy as np
import sys
npshape = [480, 480]
cmd_out = ['ffmpeg',
'-y', # (optional) overwrite output file if it exists
'-f', 'rawvideo',
'-vcodec','rawvideo',
'-s', '%dx%d'%(npshape[1], npshape[0]), # size of one frame
'-pix_fmt', 'rgb24',
'-r', '24', # frames per second
'-i', '-', # The input comes from a pipe
'-an', # Tells FFMPEG not to expect any audio
'-vcodec', 'mpeg4',
'output.mp4']
fout = subprocess.Popen(cmd_out, stdin=subprocess.PIPE, stderr=subprocess.PIPE).stdin
for i in range(24*40):
if i%(24)==0:
print('%d'%(i/24), end=' ')
sys.stdout.flush()
fout.write((np.random.random(npshape[0]*npshape[1]*3)*128).astype('uint8').tostring())
fout.close()
Run Code Online (Sandbox Code Playgroud)
如果我写的帧长度少于 37 秒,这很好用,但是如果我尝试写更多的东西,代码就会挂起。这种行为的根本原因是什么?我该如何解决?
一个极有可能的罪魁祸首是令人作呕的臭subprocess.Popen线。您不仅忽略了它的返回值——你绝对不能这样做,以确保子stderr进程在某个点完成和/或检查它的退出代码——你还创建了一个管道但从不读取它——所以进程必须在以下情况下挂起它的缓冲区已满。
这应该解决它:
p = subprocess.Popen(cmd_out, stdin=subprocess.PIPE)
fout = p.stdin
<...>
fout.close()
p.wait()
if p.returncode !=0: raise subprocess.CalledProcessError(p.returncode,cmd_out)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3055 次 |
| 最近记录: |