使用ffmpeg子进程管道传压缩流报cannot reshape array of 0 byte错误怎么解决
错误原因
cannot reshape array of 0 byte 报错的核心是pipe2.stdout.read()读到了空字节,说明第二个ffmpeg进程没有正常输出数据,本质是你的两个ffmpeg命令参数都存在配置错误。
需修改的问题点
- 第一个ffmpeg命令配置错误:你要输出H.264裸流给下游管道,
-f参数错误配置为image2pipe,且视频编码参数配置无效,不需要重新编码时直接用copy即可 - 第二个ffmpeg命令输入源配置错误:
-i后面填写的image2pipe是无效值,管道输入需要填- - 缓冲区设置过小:
bufsize=10完全无法承载视频帧数据,会导致管道阻塞 - 缺少数据合法性校验:没有判断读到的字节长度是否符合预期,直接reshape会触发报错
- 废弃API使用:
numpy.fromstring已经废弃,推荐用numpy.frombuffer替代
修复后的完整代码
import cv2 import subprocess as sp import numpy as np IMG_W = 640 IMG_H = 480 FRAME_SIZE = IMG_W * IMG_H * 3 FFMPEG_BIN = "/usr/bin/ffmpeg" # 第一个ffmpeg:读取h264文件,直接拷贝输出h264裸流到管道 ffmpeg_cmd = [FFMPEG_BIN, '-hide_banner', '-loglevel', 'error', # 屏蔽不必要的日志 '-i', 'h264.h264', '-c:v', 'copy', # 直接拷贝流,不需要重新编码 '-f', 'h264', # 输出格式为h264裸流 '-'] # 第二个ffmpeg:从管道读h264流,解码为bgr24原始帧输出 ffmpeg_cmd2 = [FFMPEG_BIN, '-hide_banner', '-loglevel', 'error', '-i', '-', # 从标准输入管道读数据 '-r', '30', '-pix_fmt', 'bgr24', '-c:v', 'rawvideo', '-an','-sn', '-f', 'image2pipe', '-'] # 启动进程,设置足够大的缓冲区,重定向错误输出避免阻塞 pipe = sp.Popen(ffmpeg_cmd, stdout=sp.PIPE, stderr=sp.DEVNULL, bufsize=10**8) pipe2 = sp.Popen(ffmpeg_cmd2, stdin=pipe.stdout, stdout=sp.PIPE, stderr=sp.DEVNULL, bufsize=10**8) while True: raw_image = pipe2.stdout.read(FRAME_SIZE) # 读到空数据说明流已经读完,退出循环 if len(raw_image) != FRAME_SIZE: break # 使用frombuffer替代废弃的fromstring image = np.frombuffer(raw_image, dtype='uint8') image = image.reshape((IMG_H, IMG_W, 3)) cv2.imshow('Video', image) if cv2.waitKey(1) & 0xFF == ord('q'): break # 正确清理进程和资源 pipe2.terminate() pipe.terminate() pipe2.wait() pipe.wait() cv2.destroyAllWindows()
内容的提问来源于stack exchange,提问作者Naseer Ahmed
相关产品推荐
相关产品推荐

