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

基于ASGI服务器的IP摄像头(CCTV)直播流问题求助

问题描述

我使用Django、OpenCV、Daphne搭建ASGI系统,在WSGI模式下可通过StreamingHttpResponse正常在HTML中实现CCTV直播流,但切换为ASGI后该方式失效。参考网络示例调整为WebSocket方案后,HTML页面能正常建立WebSocket连接,但仍无法显示CCTV直播流,求排查建议。

排查方向与修正建议
  • 修复前后端数据编码/解析不匹配问题
    后端当前将帧字节用latin-1解码后塞进JSON,前端直接把整个JSON字符串当作base64使用,既没有解析JSON对象,也用错了编码格式:

    • 后端需将OpenCV编码后的buffer直接转为base64字符串,再封装成JSON发送
    • 前端需先解析WebSocket收到的JSON字符串,提取frame字段的base64值再赋值给img.src
  • 避免阻塞ASGI事件循环
    OpenCV的cap.read()是同步阻塞操作,在异步Consumer的主线程中直接执行会卡死ASGI事件循环,导致消息无法及时推送。需将帧读取操作放到线程池中异步执行。

  • 验证RTSP流读取有效性
    在cap.read()后添加日志,打印ret值、frame的形状等信息,确认OpenCV是否成功从RTSP地址读取到帧数据,排除流地址错误、权限不足、网络连通性等问题。

  • 检查Daphne路由挂载
    确认Daphne启动时正确加载了ASGI应用,WebSocket路由已通过websocket_urlpatterns正确注册到Django的ASGI路由中。

修正后的代码示例

consumer.py

import asyncio
import cv2
import base64
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from asgiref.sync import sync_to_async

class CameraConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        await self.accept()
        self.cap = cv2.VideoCapture("rtsp://admin:ads12345@192.168.1.65:554/")
        # 启动异步任务读取帧
        self.task = asyncio.create_task(self.send_frames())

    async def send_frames(self):
        while True:
            # 用sync_to_async把同步的read操作转成异步
            ret, frame = await sync_to_async(self.cap.read)()
            if not ret:
                print("无法读取视频流")
                break

            _, buffer = cv2.imencode('.jpg', frame)
            # 将buffer转为base64字符串
            frame_base64 = base64.b64encode(buffer).decode('utf-8')
            
            await self.send(json.dumps({'frame': frame_base64}))
            await asyncio.sleep(0.03)

    async def disconnect(self, close_code):
        self.task.cancel()
        self.cap.release()

stream.html

<!DOCTYPE html>
<html>
<head>
    <title>Camera Stream</title>
    <script>
        var socket = new WebSocket("ws://localhost:8000/ws/camera_stream/");

        socket.onmessage = function(event) {
            // 先解析JSON对象
            var data = JSON.parse(event.data);
            var img = document.getElementById("camera-image");
            img.src = "data:image/jpeg;base64," + data.frame;
        };
    </script>
</head>
<body>
    <img id="camera-image" src="" >
</body>
</html>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 03:43:10