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

基于Gevent与Flask的视频流应用卡顿:客户端断开前无响应

解决Gevent+Flask视频流卡顿问题

你遇到的视频流卡顿问题,核心是几个关键细节没处理到位——结合Gevent的协程特性和Flask流式响应的要求,我来给你一步步修复:

现有代码的核心问题

  1. /video_feed路由没有返回正确的流式响应对象,浏览器无法正确解析视频流,导致一直等待直到连接断开;
  2. 全局的vc对象会引发多客户端冲突,且未释放资源,容易造成内存泄漏;
  3. 没有用Gevent的monkey patch处理阻塞IO,OpenCV的摄像头读取会卡住整个协程池;
  4. 生成器循环没给协程切换留机会,单个请求会占用所有CPU时间。

修复后的完整代码

from gevent import monkey
# 必须先patch所有标准库,将阻塞IO转为协程友好的非阻塞IO
monkey.patch_all()

from flask import Flask, Response
import cv2
import gevent

app = Flask(__name__)

def gen():
    """Video streaming generator function."""
    # 每个请求创建独立的摄像头捕获实例,避免多客户端冲突
    vc = cv2.VideoCapture(0)
    try:
        # 可选:降低摄像头分辨率,减少传输压力
        vc.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
        vc.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
        
        while True:
            rval, frame = vc.read()
            if not rval:
                break  # 读取失败时退出循环
            
            # 调整JPEG质量,平衡画质和传输速度
            _, buffer = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 80])
            frame_bytes = buffer.tobytes()
            
            # 输出符合multipart格式的帧数据
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
            
            # 强制协程切换,让Gevent处理其他请求
            gevent.sleep(0.01)
    finally:
        # 确保请求结束时释放摄像头资源
        vc.release()

@app.route('/video_feed')
def video_feed():
    """视频流路由"""
    # 返回流式响应,指定正确的mime类型
    return Response(
        gen(),
        mimetype='multipart/x-mixed-replace; boundary=frame'
    )

if __name__ == '__main__':
    # 用Gevent的WSGIServer启动,不要用Flask自带的开发服务器
    from gevent.pywsgi import WSGIServer
    http_server = WSGIServer(('0.0.0.0', 5000), app)
    print("Server running on http://0.0.0.0:5000")
    http_server.serve_forever()

关键修复点解析

  • 正确的流式响应:用Response对象包裹生成器,并指定multipart/x-mixed-replace的mime类型,这是浏览器解析逐帧JPEG流的标准格式;
  • Gevent Monkey Patch:monkey.patch_all()替换标准库中的阻塞IO操作,避免OpenCV的摄像头读取卡住整个协程池;
  • 独立摄像头实例:每个请求创建自己的VideoCapture,避免多客户端共享导致的帧混乱,finally块确保资源及时释放;
  • 协程切换延迟:gevent.sleep(0.01)强制当前协程让出CPU,给其他请求处理的机会,避免单个请求占用所有资源;
  • 可选优化:降低摄像头分辨率和JPEG质量,减少数据传输量,进一步缓解卡顿。

额外排查建议

  • 单独测试OpenCV的摄像头读取速度,如果vc.read()本身就慢,可能是硬件驱动问题,尝试更新摄像头驱动;
  • 客户端的img标签不要加缓存属性,确保浏览器实时获取新帧:<img src="/video_feed" alt="Video Stream">;
  • 如果是远程访问,检查网络带宽是否足够,高分辨率视频流需要更大的带宽支撑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:08:08