You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在内存中将OpenCV帧列表转为Streamlit可播放的H264视频?

解决Streamlit内存内转换帧为H264视频并播放的方案

问题根源

你当前的错误是直接将cv2.VideoWriter对象传入st.video(),但st.video()仅接受视频二进制数据、本地文件路径或URL,不支持OpenCV的视频写入对象。同时要实现内存内处理,必须避开本地临时文件,改用内存字节流存储视频数据。

推荐解决方案(使用imageio)

借助imageio库可以直接在内存中完成H264视频编码,无需本地文件。

步骤1:安装依赖

pip install imageio[ffmpeg]

步骤2:核心代码

import streamlit as st
import imageio.v3 as iio
from io import BytesIO

# 注意:如果你的frames是OpenCV读取的BGR格式,先转成RGB
# frames = [cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) for frame in frames]

# 初始化内存字节流
video_buffer = BytesIO()

# 将帧写入内存流,指定H264编码
iio.imwrite(
    video_buffer,
    frames,
    format="mp4",
    codec="h264",
    fps=1  # 根据需求调整帧率
)

# 将流指针重置到起始位置
video_buffer.seek(0)

# 传入Streamlit播放
st.video(video_buffer)

关键注意事项

  • 颜色格式转换:OpenCV默认读取的帧是BGR格式,而imageio编码视频需要RGB格式,必须转换否则画面颜色异常。
  • 编码兼容性:指定codec="h264"确保生成的视频符合HTML5标准,Streamlit可以直接播放。

替代方案(OpenCV + 内存临时文件)

如果依赖OpenCV而非imageio,可以用内存虚拟文件实现:

import streamlit as st
import cv2
from io import BytesIO
from tempfile import SpooledTemporaryFile

# 假设frames为BGR格式的numpy数组列表
height, width, _ = frames[0].shape
fps = 1

# 创建内存虚拟文件(超过阈值才会写入磁盘,这里设100MB确保内存处理)
with SpooledTemporaryFile(max_size=100*1024*1024) as temp_file:
    # 初始化OpenCV视频写入器
    codec = cv2.VideoWriter_fourcc(*'H264')
    video_writer = cv2.VideoWriter(temp_file.name, codec, fps, (width, height))
    
    # 写入所有帧
    for frame in frames:
        video_writer.write(frame)
    
    video_writer.release()
    # 读取内存中的视频数据
    temp_file.seek(0)
    video_data = temp_file.read()

# 转成BytesIO传给Streamlit
st.video(BytesIO(video_data))

内容的提问来源于stack exchange,提问作者Aus_10

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 20:15:42