我想处理通过plotly dash中的上传组件收到的视频。目前我正在创建一个临时文件,然后使用 opencv 读取视频。但是,我想避免将文件写入磁盘。有没有办法直接从内存中处理视频?我的代码如下所示:
def process_motion(contents, filename):
print("Processing video: " + filename)
content_type, content_string = contents.split(',')
decoded = base64.b64decode(content_string)
with tempfile.NamedTemporaryFile() as temp:
temp.write(decoded)
cap = cv2.VideoCapture(temp.name)
frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
fps = cap.get(cv2.CAP_PROP_FPS)
# some calculations
最佳答案
有趣的问题
如@ Dan Mašek已经正确提到,正确的搜索关键字是视频解码。问题是,像 OpenCV 一样,Python 中的解码库必须使用 FFMPEG 作为后端,并且大多数都是 FFMPEG 可执行文件的包装器(在子进程中运行 FFMPEG),并且由于 FFMPEG 接受用于解码的文件路径(或用于解码视频流的 URL) )这些包装器也接受文件路径。
据我所知,唯一接受字节作为输入来解码视频并获取所有帧的包装器库是 imageio它在幕后还将字节转换为临时文件并使用 FFMPEG 对其进行解码。
这是使用 imageio 和您的解决方案的比较。
import base64
import imageio.v3 as iio
import cv2
from time import perf_counter
import tempfile
import numpy as np
with open("example.mp4", "rb") as videoFile:
base_text = base64.b64encode(videoFile.read())
buffer = base64.b64decode(base_text)
start = perf_counter()
frames = iio.imread(buffer, index=None, format_hint=".mp4")
print("iio ffmpeg pluing: ", perf_counter() - start)
print(frames.shape)
start = perf_counter()
frames = iio.imread(buffer, index=None, plugin="pyav", format_hint=".mp4")
print("iio pyav pluing: ", perf_counter() - start)
print(frames.shape)
start = perf_counter()
with tempfile.NamedTemporaryFile() as temp:
temp.write(buffer)
cap = cv2.VideoCapture(temp.name)
frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
fps = cap.get(cv2.CAP_PROP_FPS)
success, frame = cap.read()
frames = [frame]
while success:
success, frame = cap.read()
frames.append(frame)
frames = np.stack(frames[:-1])
print("cv2: ", perf_counter() - start)
print(frames.shape)
============================================
iio ffmpeg pluing: 0.3905044999992242
(901, 270, 480, 3)
No accelerated colorspace conversion found from yuv420p to rgb24.
iio pyav pluing: 0.3710011249931995
(901, 270, 480, 3)
cv2: 0.2388888749992475
(901, 270, 480, 3)
注意:如果您能够为 FFMPEG 创建 python 包装器,则可以将字节数组转换为 FFMPEG 流解码功能可接受的格式。如上所述 here
关于python - 在python中读取base64的视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74919882/