如何读取 MKV 字节作为视频?
How to read MKV bytes as video?
我正在接收以字节为单位的 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, video, frame, individual frame, FFmpeg, imageio, single frame, BytesIO, bytes, MKV, Matroska.
Mark Setchell 做对了;不过 - 在 2022 年 - 你不必再一路下降到 get_reader
就可以做到这一点。
设置:
创建测试视频:
ffmpeg -f lavfi -i testsrc -t 5 testsrc.mkv
创建 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")
我正在接收以字节为单位的 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, video, frame, individual frame, FFmpeg, imageio, single frame, BytesIO, bytes, MKV, Matroska.
Mark Setchell 做对了;不过 - 在 2022 年 - 你不必再一路下降到 get_reader
就可以做到这一点。
设置:
创建测试视频:
ffmpeg -f lavfi -i testsrc -t 5 testsrc.mkv
创建 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")