【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();
    }
});
相关推荐
GHZhao_GIS_RS21 小时前
python中的sort和sorted用法汇总
python·排序·列表
永恒的溪流21 小时前
环境出问题,再修改
pytorch·python·深度学习
ruxshui21 小时前
Python多线程环境下连接对象的线程安全管理规范
开发语言·数据库·python·sql
大模型玩家七七21 小时前
向量数据库实战:从“看起来能用”到“真的能用”,中间隔着一堆坑
数据库·人工智能·python·深度学习·ai·oracle
2301_7634724621 小时前
使用PyQt5创建现代化的桌面应用程序
jvm·数据库·python
爱学习的阿磊21 小时前
Web开发与API
jvm·数据库·python
qq_192779871 天前
Python多线程与多进程:如何选择?(GIL全局解释器锁详解)
jvm·数据库·python
naruto_lnq1 天前
NumPy入门:高性能科学计算的基础
jvm·数据库·python
工程师老罗1 天前
Pytorch中的优化器及其用法
人工智能·pytorch·python
2301_822365031 天前
实战:用Python分析某电商销售数据
jvm·数据库·python