Python调用FFmpeg提取视频流原始字节生成图像无法打开问题
问题:Python调用FFmpeg提取图像原始字节后存文件无法打开
我看你遇到的问题是:用FFmpeg从视频流提取原始图像字节,直接存成文件后打不开。核心原因其实很简单——你当前输出的是纯RGB像素数据,没有任何图像格式的文件头(比如JPEG/PNG那种标识文件类型的头部信息),系统根本没法识别这是合法的图像文件。
下面给你两种解决思路,按需选择:
方法一:让FFmpeg直接输出带格式的图像字节流
如果只是想验证字节是否正确,或者不需要保留原始RGB数据,直接让FFmpeg输出PNG/JPEG格式的字节流就行,这样写入文件后就是标准图像文件,能直接打开。修改你的命令如下:
import subprocess as sp def getImages(self): url = "你的视频流URL" cmd = [ 'ffmpeg', '-ss', '2', '-i', url, '-t', '2', '-f', 'image2pipe', '-s', '420x360', '-pix_fmt', 'rgb24', '-vcodec', 'png', # 这里把rawvideo改成png,输出PNG格式字节 '-vf', 'fps=fps=1', '-' ] pipe = sp.Popen(cmd, stdout=sp.PIPE, bufsize=1024*1024) # 调整bufsize更合理 # 读取字节并写入文件 with open('output.png', 'wb') as f: f.write(pipe.stdout.read()) pipe.wait()
方法二:保留原始RGB字节,用PIL转成合法图像
如果必须保留原始RGB字节用于后续处理,那需要用图像处理库(比如Pillow)把纯像素数据封装成标准图像格式:
import subprocess as sp from PIL import Image def getImages(self): url = "你的视频流URL" cmd = [ 'ffmpeg', '-ss', '2', '-i', url, '-t', '2', '-f', 'image2pipe', '-s', '420x360', '-pix_fmt', 'rgb24', '-vcodec', 'rawvideo', '-vf', 'fps=fps=1', '-' ] pipe = sp.Popen(cmd, stdout=sp.PIPE, bufsize=1024*1024) # 计算单帧图像的字节数:宽度*高度*每个像素的字节数(rgb24是3字节) frame_size = 420 * 360 * 3 raw_bytes = pipe.stdout.read(frame_size) pipe.wait() # 把原始字节转成PIL图像 img = Image.frombytes('RGB', (420, 360), raw_bytes) # 保存成PNG文件验证 img.save('output_raw.png') # 这里的raw_bytes就可以拿去做你需要的后续处理了
额外注意点
- 你的
-ss参数原来写的是整数2,FFmpeg需要字符串参数,记得改成'2'(不过Python的subprocess会自动转,但规范起见还是用字符串) - 如果是网络视频流,把
-ss放在-i之前的快速seek可能失效,这时候可以把-ss移到-i后面,虽然会先下载部分内容再跳转,但兼容性更好 - bufsize不用设10^8这么大,单帧图像也就几百KB,设成1MB(1024*1024)完全足够
内容的提问来源于stack exchange,提问作者user3745870




