python - 在python中读取base64的视频

标签 python video base64 plotly-dash

我想处理通过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/

相关文章:

Python webapp 无法在 Heroku 上正常运行?

python - Xpath() 方法不使用 Scrapy 返回结果

video - ffmpeg:连接视频并与一个音频合并

video - 如何在 ffmpeg 中向视频添加不透明的叠加层?

JAVA Spring 返回图像字节 - 错误 406 Not Acceptable

python - Python中Pareto前沿的快速计算

python - 函数如何稳定地引用自身?

video - FFMPEG:将 UHD H265 转码为 SDR H264 而不会丢失颜色

iOS 将 base64 编码图像上传到 RESTful 服务器时获取 http 400

java - 为什么对于同一文本,Python 和 Java Base64 编码有不同的结果?