从stdin管道输入时ffmpeg损坏

2024-04-20 08:38:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个程序,可以生成图像并用它们创建视频。目前的工作是一次创建所有图像,然后在一个子进程中运行FFmpeg并通过stdin管道将图像传送到创建一个视频:

cmd = ['ffmpeg', '-y',
       '-s', '{}x{}'.format(OUTPUT_WIDTH, OUTPUT_HEIGHT),
       '-r', str(OUTPUT_VIDEO_FPS),
       '-an',
       '-pix_fmt', colour,
       '-c:v', 'rawvideo', '-f', 'rawvideo',
       '-i', '-',
       '-vcodec', 'libx264',
       '-pix_fmt', 'yuv420p',
       '-preset', 'medium', OUTPUT_VIDEO_PATH]

out_frames = []
for i in range(num_frames):
    out_frame = render_frame(...)
    out_frames.append(out_frame)

with _call_subprocess(sp.Popen(cmd, stdin=sp.PIPE, stderr=sp.PIPE, stdout=DEVNULL)) as pipe:
    for frame_no, frame in enumerate(out_frames):
        pipe.stdin.write(frame)

但是,当我有数千个图像不能全部放入内存时,这就变得不可行了,因为子进程fork call请求了太多内存而失败了。我的解决方案是在程序开始时分叉(避免内存错误),然后在创建帧时将其管道传输到stdin:

^{pr2}$

但是,ffmpeg的输出现在已损坏。我很确定这与我现在渲染帧时写入stdin之间有一些处理时间有关-我注意到,如果我使用第一个解决方案,但只需在写入stdin之间添加一些睡眠时间,输出也会损坏!在

cmd = ['ffmpeg', '-y',
       '-s', '{}x{}'.format(OUTPUT_WIDTH, OUTPUT_HEIGHT),
       '-r', str(OUTPUT_VIDEO_FPS),
       '-an',
       '-pix_fmt', colour,
       '-c:v', 'rawvideo', '-f', 'rawvideo',
       '-i', '-',
       '-vcodec', 'libx264',
       '-pix_fmt', 'yuv420p',
       '-preset', 'medium', OUTPUT_VIDEO_PATH]

out_frames = []
for i in range(num_frames):
    out_frame = render_frame(...)
    out_frames.append(out_frame)

with _call_subprocess(sp.Popen(cmd, stdin=sp.PIPE, stderr=sp.PIPE, stdout=DEVNULL)) as pipe:
    for frame_no, frame in enumerate(out_frames):
        time.sleep(1) # <------------------- This sleep ruins everything!!
        pipe.stdin.write(frame)

然而,我不知道是什么导致了这个问题,或者如何修复它(FFmpeg不知怎么地轮询了一个空管道,然后被破坏了?我甚至不明白子进程通信是如何工作的。任何帮助都将不胜感激。在


Tags: in图像cmdforoutputframesvideostdin
1条回答
网友
1楼 · 发布于 2024-04-20 08:38:46

不知道这是为什么,但是将sp.Popen调用从sp.Popen(cmd, stdin=sp.PIPE, stderr=sp.PIPE, stdout=DEVNULL)改为sp.Popen(cmd, stdin=sp.PIPE, stderr=DEVNULL, stdout=DEVNULL)起作用了。我猜这和this SO question about piping issues with stderr有关。在

相关问题 更多 >