我正在创建一个 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/