【Flask-9】加载视频流

app.py伪代码:

复制代码
RTSP_URL = rtsp://*.*.*.*:*/video
video_capture = None

def init_video_stream():
    """初始化视频流"""
    global video_capture
    try:
        video_capture = cv2.VideoCapture(RTSP_URL)
        video_capture.set(cv2.CAP_PROP_BUFFERSIZE, 1)
        print("RTSP流初始化成功")
    except Exception as e:
        print(f"RTSP流初始化失败: {e}")

def generate_frames():
    """生成视频帧"""
    while True:
        try:
            if video_capture is None:
                init_video_stream()
                time.sleep(1)
                continue
                
            success, frame = video_capture.read()
            if not success:
                print("读取视频帧失败,尝试重新连接...")
                video_capture.release()
                init_video_stream()
                time.sleep(1)
                continue
                
            # 调整帧大小以提高性能
            frame = cv2.resize(frame, (640, 480))
            
            # 编码为JPEG格式
            ret, buffer = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 80])
            if not ret:
                continue
                
            frame_bytes = buffer.tobytes()
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
                   
        except Exception as e:
            print(f"生成视频帧错误: {e}")
            time.sleep(1)

@app.route('/video_feed')
def video_feed():
    """视频流路由"""
    print("------------------------------视频流已加载---------------------------------------")
    return Response(generate_frames(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')


@app.route('/api/set-mode', methods=['POST'])
def set_mode():
    data = request.get_json()
    mode = data.get('mode')
    print(f"视频模式设置为: {mode}")
    return jsonify({'status': 'ok', 'mode': mode})

html页面伪代码:

复制代码
<div class="video-container">
<img src = "" alt = "实时监控" id = "video-stream" style="display: none;"></div>


<div class="display-controls">
    <div class="display-option">
        <input type="radio" id="show-image" name="display-option" checked>
        <label for="show-image">显示图像</label>
    </div>
    <div class="display-option">
        <input type="radio" id="hide-image" name="display-option">
        <label for="hide-image">隐藏图像</label>
    </div>
</div>

javasrcipt伪代码:

复制代码
const video = document.getElementById('video-stream');
let videoStarted = false;

function startVideo(){
    if(!videoStarted){
        video.src = "/video_feed";
        video.style.display = "block";  //显示元素
        videoStarted = true;
    }
    fetch('/api/set-mode',{
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({mode: 'show'})
    });
}


function stopVideo() {
    video.style.display = 'none';
    
    // 发送到后端
    fetch('/api/set-mode', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({mode: 'hide'})
    });
}


// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
    // 初始化图表
    initTrendChart();
    if(document.getElementById('show-image').checked){
        startVideo();
    }
});
相关推荐
TomEval2 分钟前
【Web UI 自动化】08 - 企业选型·报告·CI/CD
python·功能测试
再吃一根胡萝卜4 分钟前
Rust 桌面宠物拖拽踩坑实录:重影、不跟手、置顶失效
后端
再吃一根胡萝卜4 分钟前
Rust 桌面宠物进化记:从静态图标到会动的"QQ 宠物"
后端
维克兜率天6 分钟前
4.1.3 策略类型全景图:六大策略,你适合哪个
笔记·python·算法·量化
烂蜻蜓11 分钟前
Flask入门教程(十三):数据库操作——SQLAlchemy与CRUD完整实践
数据库·oracle·flask
IT毕设实战小研21 分钟前
基于安卓的考研资讯系统设计与实现
android·大数据·vue.js·爬虫·python·考研·课程设计
2601_9620662324 分钟前
SpringBoot3 快速启动框架
java·spring boot·后端
卷无止境2 小时前
Python能做嵌入式开发吗?一份写给动手派的生态与硬件全景图
后端·python
月光船幽幽6 小时前
检测用户意图复杂性的关键方法
人工智能·python
Sherotree8 小时前
Google Antigravity——Agent 被提到主界面
前端·ide·后端·edge浏览器