我收到了MKV视频的一部分字节数据。我需要提取其中的第一帧,以供后续处理,但不需要将整个视频保存到磁盘中。对于类似的图像问题,我使用OpenCV或PIL,一切都很好,但是我无法在视频数据上使用相同的方法。您有什么提示可以将视频从字节中读入内存对象中,以便我可以在以后使用OpenCV或其他库进行处理?
我收到了MKV视频的一部分字节数据。我需要提取其中的第一帧,以供后续处理,但不需要将整个视频保存到磁盘中。对于类似的图像问题,我使用OpenCV或PIL,一切都很好,但是我无法在视频数据上使用相同的方法。您有什么提示可以将视频从字节中读入内存对象中,以便我可以在以后使用OpenCV或其他库进行处理?
由于我没有你的 bytes
缓存,我只是用 ffmpeg
创建了一个 MKV 视频文件,像这样:
ffmpeg -i SomeVideo.avi -f matroska -vcodec libx264 video.mkv
然后我使用以下命令安装了imageio
:
pip install imageio
然后我将整个MKV视频加载到内存中,所以我有一个看起来几乎与您在变量content
中接收的bytes
对象相同的东西:
import imageio
# Get bytes of MKV video
with open('video.mkv', 'rb') as file:
content = file.read()
现在我应该已经设置好了,看起来和你一样。作为参考,content
的前几个字节如下:
b'\x1aE\xdf\xa3\x01\x00\x00\x00\x00\x00\x00#B\x86\x81\x01B\xf7\x81\x01'
那么,让我们继续。
# Wrap the content in a BytesIO and get an ffmpeg reader to read it
vid = imageio.get_reader(BytesIO(content), 'ffmpeg')
for num, image in enumerate(vid.iter_data()):
print(image.mean())
metadata = vid.get_meta_data()
print(metadata)
{'plugin': 'ffmpeg',
'nframes': 750,
'ffmpeg_version': '4.1 built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)',
'fps': 25.0,
'source_size': (1280, 720),
'size': (1280, 720),
'duration': 30.0}
关键词: Python, 视频, 帧, 单帧, FFmpeg, imageio, 单独帧, BytesIO, 字节, MKV, Matroska。
Mark Setchell说得没错,但是在2022年,你不必再一路降到get_reader
来完成这个操作了。
设置:
创建一个测试视频:
ffmpeg -f lavfi -i testsrc -t 5 testsrc.mkv
from pathlib import Path
mkv_bytes = Path("testsrc.mkv").read_bytes()
读取第一帧:
ImageIO<2.15.0
import imageio as iio
req = iio.core.Request(mkv_bytes, "r")
# note: this is a bit of a hack, see
# https://github.com/imageio/imageio/issues/686
req._extension = ".mkv"
first_frame = iio.imread(req)
ImageIO>2.15.0(本周发布 - W6 2022)
import imageio as iio
first_frame = iio.v3.imread(mkv_bytes, format_hint=".mkv")