python - 如何使用 imageio.v3 从字节中获取视频元数据?

标签 python bytesio python-imageio

我正在创建一个 python 类来处理从 http 帖子收到的视频。视频的大小范围很广,从 10 秒到 10 小时不等。我正在寻找一种无需将整个视频存储在内存中即可获取视频元数据(例如 fps、高度、宽度等)的方法。

类初始化如下:

class VideoToolkit:
   def __init__(self,video,video_name,media_type,full_video=True,frame_start=None,frame_stop=None):
    
    self._frames = iio.imiter(video,format_hint=''.join(['.',media_type.split('/')[1]])) # Generator
    self._meta = iio.immeta(video,exclude_applied=False)

self._meta 行不起作用并报错:

OSError: Could not find a backend to open `<bytes>`` with iomode `r`.

是否有类似的方法使用 imageio.v3 获取元数据?而不是将整个视频存储在内存中?

举个例子,可以直接从文件中打开视频获取元数据:

import imageio.v3 as iio

metadata = iio.immeta('./project.mp4',exclude_applied=False)
print(metadata)

输出:

{'plugin': 'ffmpeg', 'nframes': inf, 'ffmpeg_version': '4.2.2-static https://johnvansickle.com/ffmpeg/ built with gcc 8 (Debian 8.3.0-6)', 'codec': 'mpeg4', 'pix_fmt': 'yuv420p', 'fps': 14.25, 'source_size': (500, 258), 'size': (500, 258), 'rotate': 0, 'duration': 1.69}

但是打开与 bytes 相同的文件,这不起作用:

import imageio.v3 as iio
with open('./project.mp4', 'rb') as vfile:
    vbytes = vfile.read()
    metadata = iio.immeta(vbytes,exclude_applied=False)
    print(metadata)

输出:

OSError: Could not find a backend to open `<bytes>`` with iomode `r`.

PS:一种方法是执行 next(self._frames) 获取第一帧,然后获取其形状,但视频 fps 仍然会丢失。

最佳答案

你是对的,你会使用 iio.immeta为了这。这对您来说失败的原因是因为您使用的是 imageio-ffmpeg 后端,它根据 ImageResource 的扩展名来决定是否可以/不能读取某些内容。 bytes 没有扩展名,所以插件会认为它无法读取 ImageResource。以下是解决此问题的不同方法:

import imageio.v3 as iio

# setup
frames = iio.imread("imageio:cockatoo.mp4")
video_bytes = iio.imwrite("<bytes>", frames, extension=".mp4")

# set the `extension` kwarg (check the docs I linked)
meta = iio.immeta(video_bytes, extension=".mp4")

# use the new-ish pyav plugin
# (`pip install av` and ImageIO will pick it up automatically)
meta = iio.immeta(video_bytes)

注意 1:实际上使用 pyav 更可取,因为它提取元数据而不解码像素。这比 imageio-ffmpeg 更快,后者在子进程中内部调用 ffmpeg,将解码一些像素然后丢弃该数据(昂贵的 noop)。从 HTTP 资源读取时尤其如此。

注意 2:在 v2.21.2 中,pyav 插件不报告 FPS,仅报告持续时间。现在有一个 PR ( 853 ) 添加了这个(和其他东西),但它可能在接下来的几周内不会被合并,因为我正忙于我的博士答辩。(现在合并)

注意 3:很多对 FPS 感兴趣的人想知道这个信息来计算视频中的总帧数。在这种情况下,调用 iio.improps 会容易得多。并检查生成的 .shape,例如 iio.improps("imageio:cockatoo.mp4", plugin="pyav").shape # (280, 720, 1280, 3)

关于python - 如何使用 imageio.v3 从字节中获取视频元数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73566589/

相关文章:

python - 实现此 Python 代码的最佳方式是什么

python - 无法选择列表中的对象并将其删除

python-3.x - tempfile 模块和 IO 类文件对象有什么区别

python - ftp 发送 python bytesio 流

image - 如何使用 imageio 调整图像大小?

python - python中的图像尺寸错误

javascript - Python 相当于 JavaScript 的 `Object.defineProperty()`

python - 如何安装博托?

python - 使用 pyPDF2 和 BytesIO 将 PDF 页面转换为图像

python - 删除使用 imageio 或 PIL 创建的 GIF 中的空间插值或压缩