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

如何用Streamlit与OpenCV-Python实现双视频并排播放并解决帧持续生成问题

双视频并排播放的Streamlit+OpenCV实现方案

原代码的核心问题是没适配Streamlit的运行机制:while True循环会让页面持续生成新的image组件,导致界面混乱;而且cv2.waitKey在Web环境下完全无效。以下是修正后的实现:

核心改进点

  • 用st.empty()创建占位容器,每次循环只更新容器内的内容,避免重复渲染
  • 引入time.sleep()控制播放帧率,匹配视频原生速度
  • 支持单视频分帧或双独立视频的并排播放
  • 移除无效的OpenCV桌面GUI代码,适配Streamlit的Web运行逻辑

代码实现(双独立视频版本)

import cv2
import streamlit as st
import time

st.set_page_config(page_title="双视频并排播放")
st.title("双视频并排播放")

# 初始化两个视频捕获对象
cap1 = cv2.VideoCapture("videos/video1.mp4")
cap2 = cv2.VideoCapture("videos/video2.mp4")

# 获取视频帧率,用于控制播放速度
fps1 = cap1.get(cv2.CAP_PROP_FPS)
fps2 = cap2.get(cv2.CAP_PROP_FPS)
frame_delay = 1 / max(fps1, fps2)  # 取最高帧率对应的延迟

# 创建并排列和帧占位容器
col1, col2 = st.columns([1, 1])
frame_placeholder1 = col1.empty()
frame_placeholder2 = col2.empty()

# 播放循环
while cap1.isOpened() and cap2.isOpened():
    ret1, frame1 = cap1.read()
    ret2, frame2 = cap2.read()
    
    # 处理视频结束:可选循环播放或终止
    if not ret1:
        cap1.set(cv2.CAP_PROP_POS_FRAMES, 0)
        continue
    if not ret2:
        cap2.set(cv2.CAP_PROP_POS_FRAMES, 0)
        continue
    
    # 更新占位容器内的帧
    frame_placeholder1.image(frame1, channels="BGR")
    frame_placeholder2.image(frame2, channels="BGR")
    
    # 控制帧率,避免过度刷新
    time.sleep(frame_delay)

# 释放资源
cap1.release()
cap2.release()

代码实现(单视频分帧并排版本)

如果是要从同一个视频中取帧并排展示,只需调整捕获逻辑:

import cv2
import streamlit as st
import time

st.set_page_config(page_title="单视频分帧并排播放")
st.title("单视频分帧并排播放")

cap = cv2.VideoCapture("videos/video1.mp4")
fps = cap.get(cv2.CAP_PROP_FPS)
frame_delay = 1 / fps

col1, col2 = st.columns([1, 1])
frame_placeholder1 = col1.empty()
frame_placeholder2 = col2.empty()

while cap.isOpened():
    ret1, frame1 = cap.read()
    ret2, frame2 = cap.read()
    
    if not ret1 or not ret2:
        cap.set(cv2.CAP_PROP_POS_FRAMES, 0)
        continue
    
    frame_placeholder1.image(frame1, channels="BGR")
    frame_placeholder2.image(frame2, channels="BGR")
    
    time.sleep(frame_delay)

cap.release()

关键说明

  • st.empty()的作用:每次循环只更新同一个位置的图像,不会在页面上堆积大量image组件,解决原代码"持续生成视频帧"导致的界面混乱问题
  • 帧率控制:通过视频原生FPS计算延迟,保证播放速度和原视频一致
  • 循环播放:当视频读取到结尾时,重置帧位置到开头,实现循环播放;如果不需要循环,直接break即可
  • 资源释放:视频播放结束后必须调用release()释放捕获对象,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 21:26:21