在python中阅读base64的视频

5cnsuln7  于 2022-12-28  发布在  Python
关注(0)|答案(1)|浏览(207)

我想用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
nnsrf1az

nnsrf1az1#

有趣的问题
正如@Dan Mašek正确提到的,正确的关键字应该是video decoding。问题是,像OpenCV一样,Python中必须使用FFMPEG作为后端的解码库,其中大多数是FFMPEG可执行文件的 Package 器(在子进程中运行FFMPEG),由于FFMPEG接受解码的文件路径(或解码视频流的URL),因此这些 Package 器也接受文件路径。
AFAIK是唯一一个接受字节作为输入来解码视频并获取所有帧的 Package 器库,它是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 Package 器,就可以将字节数组转换成FFMPEG流解码函数可接受的格式。

相关问题