Python 中如何在内存中优雅地提取视频帧?

47 天前
 Haku

通过网络传输过来的视频,如何在不保存为文件的情况下,用工具提取视频帧呢?

一开始以为很容易,但是找了很久发现 Opencv 和 ffmpeg 都没有直接从内存中提取的方法,都需要通过一个临时文件才能提取。而目目前需求上需要优化处理视频的时间,所以想着修改这个步骤。

2785 次点击
所在节点    Python
32 条回复
Doraismydora
47 天前
·sws_sacle· 把 ·AVFrame· 转成 rgb32 ,然后弄一个 ·cv::Mat· 复制过去
qsnow6
47 天前
用虚拟文件交换就行了
Latin
47 天前
网络传输中原先的格式是什么链路
Haku
47 天前
@Latin 以 HTTP 的方式将整段视频以二进制字节流完整的传输过来。
SenseHu
47 天前
场景没描述清, 提取之后是被谁消费, 落盘? 其他程序用? 其他程序是什么框架
Haku
47 天前
@SenseHu 提取之后会由 AI 进行处理,所以还会被转换成对应的图片格式保存在内存中。整个过程都在 Python 上处理。
Huelse
47 天前
直接用内存映射不就行了,然后就是正常的 IO 操作
somebody1
47 天前
你能访问视频程序的内存内容,那别的程序不一样能访问,那你的内存不就成了透明的嘛!

这最基础的访问限制都闹不明白吗!!!
sweelia
47 天前
@Haku 可以参考 https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/avio_read_callback.c ,主要是 read_packet 函数,buffer 的装载逻辑( av_file_map )换成你自己的,可以流式加载,不用一次性读完。如果对 c 不熟悉,可以找个 python binding 来使用。decode 之后拿到 AVFrame ,随便玩
Haku
47 天前
@somebody1 啥?我觉得你可能没理解,我这里指我的服务器收到了视频文件,然后我不希望把他写入到硬盘中,而是直接将传输过来的文件进行视频帧提取。
stebest
47 天前
额,这个倒是跟视频没啥关系,不就是想用 bytesIO 嘛。
somebody1
47 天前
@Haku #10
那就是 11 楼的答案了
mightybruce
47 天前
看起来你对 opencv 和 ffmpeg 都不熟悉,先说说你传来的视频流是什么协议吧
stebest
47 天前
@stebest 挺简单的,给个示例吧 import numpy as np
import cv2 as cv
import io

image_stream = io.BytesIO()
image_stream.write(connection.read(image_len))
image_stream.seek(0)
file_bytes = np.asarray(bytearray(image_stream.read()), dtype=np.uint8)
img = cv.imdecode(file_bytes, cv.IMREAD_COLOR)
mightybruce
47 天前
直接读完整的视频就是 bytesIO 二进制流了, 转换一下变成 numpy array 就行
Haku
47 天前
@stebest 好的谢谢,我试试。
Haku
47 天前
@stebest @mightybruce
谢谢两位,可能是我一开始哪里搞错了,我用 cv2 和 ffmpeg 去进行提取时,都报错了,网上查询也没找到一个很好的方法。
NessajCN
47 天前
Python 这语言本来就不适用于直接对内存进行操作
建议换 C 或 Rust
https://ffmpeg.org/doxygen/6.1/group__lavc__decoding.html#ga11e6542c4e66d3028668788a1a74217c
你可能想要这个方法
cooljiang
47 天前
@stebest 确实这个是正解,创建一个 io 字节流。
Anarchy
47 天前
用 pyav 很简单的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1061921

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX