为了账号安全,请及时绑定邮箱和手机立即绑定

从标准输入管道输入时ffmpeg损坏

从标准输入管道输入时ffmpeg损坏

人到中年有点甜 2022-01-18 13:37:11
我有一个程序可以生成图像并从中创建视频。目前可行的是一次创建所有图像,然后在子进程中运行 FFmpeg 并通过标准输入管道图像以创建视频: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 调用请求了太多内存并且失败了。我的解决方案是在程序开始时分叉(避免内存错误),然后在创建帧时将帧通过管道传输到标准输入: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]with _call_subprocess(sp.Popen(cmd, stdin=sp.PIPE, stderr=sp.PIPE, stdout=DEVNULL)) as pipe:    for i in range(num_frames):        out_frame = render_frame(...)        pipe.stdin.write(out_frame)但是,ffmpeg 的输出现在已损坏。我很确定这与以下事实有关到标准输入,输出也损坏了!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)但是我不确定是什么导致了这个或如何修复它(FFmpeg 是否以某种方式轮询一个空管道然后被损坏?我不明白子进程通信是如何工作的......)。任何帮助,将不胜感激。
查看完整描述

1 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

不知道为什么会这样,但是将sp.Popen运行 FFmpeg 的调用从工作更改sp.Popen(cmd, stdin=sp.PIPE, stderr=sp.PIPE, stdout=DEVNULL)sp.Popen(cmd, stdin=sp.PIPE, stderr=DEVNULL, stdout=DEVNULL)工作。我猜这与这个关于 stderr 管道问题的问题有关


查看完整回答
反对 回复 2022-01-18
  • 1 回答
  • 0 关注
  • 235 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号