基于Django websocket实现视频画面的实时传输案例

这篇具有很好参考价值的文章主要介绍了基于Django websocket实现视频画面的实时传输案例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于Django websocket实现视频画面的实时传输案例

📌本案例是基于B/S架构的视频监控画面的实时传输,使用django作为服务端的开发框架。

Django Channels 是一个用于在 Django 框架中实现实时、异步通信的扩展库。传统的 Django 是基于请求-响应模式的,每个请求都会经过 Django 的视图函数进行处理并返回响应。而 Channels 提供了基于事件驱动的编程模型,使得开发者可以处理实时的事件,如 WebSocket 连接、消息队列、定时任务等。

Channels 的主要特性包括:

  • 支持 WebSocket:Channels 可以轻松地处理 WebSocket 连接,实现实时的双向通信;
  • 异步处理:Channels 使用异步方式处理请求和事件,可以提高应用的性能和并发能力;
  • Channels 可以与诸如 Celery 等任务队列库集成,处理后台任务和定时任务。

Channels可以跟Django无缝衔接,常用于开发聊天室、实时通知、实时数据更新等。

WebSocket 是一种在客户端和服务器之间进行双向通信的网络协议。与传统的 HTTP 请求-响应模式不同,WebSocket 只需要完成一次握手就可以创建持久性的连接,允许服务器主动向客户端推送数据,而不需要客户端发起请求。

在使用 WebSocket 进行通信时,涉及到异步和同步两个概念:

在异步模式下,websocket使用异步的方式操作i/o,允许同时处理多个连接或事件。

在同步模式下,每个 WebSocket 连接会被分配给一个线程或进程进行处理,消息的接收和发送是同步的操作。同步方式适用于一对一的连接事件。

环境配置

1、下载安装channels库

pip install channels

2、添加 Channels 到 Django 项目的安装应用列表中:打开 Django 项目的 settings.py 文件,在 INSTALLED_APPS 设置中添加 'channels',确保它出现在其他应用的前面:

INSTALLED_APPS = [
    ...
    'channels',
    ...
]

并且在settings.py 文件添加以下内容:

ASGI_APPLICATION = "projetc2.asgi.application" #project2为项目名称

CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels.layers.InMemoryChannelLayer',
    },
}

Django Channels 运行于 ASGI(Asynchronous Server Gateway Interface)协议上。ASGI 是一个用于处理异步 Python Web 应用程序的协议,它提供了一种标准的方式来与 Web 服务器和应用程序框架之间进行通信。

3、配置 Channels 的 ASGI 应用程序:在 Django 项目的根目录下有一个名为 asgi.py 的文件,然后将文件中修改为以下内容:

import os

from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from projetc2 import routing 

os.environ.setdefault('DJANGO_SETTINGS_MODULE', '项目名称.settings')

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": URLRouter(routing.websocket_urlpatterns)
})


4、配置 WebSocket 路由:在 Django 项目 project的目录下创建一个名为 routing.py 的文件,然后定义您的 WebSocket 路由。以下是一个示例:

from django.urls import re_path
from app import consumers
websocket_urlpatterns = [
    re_path(r'ws/some-path1/$', consumers.TailfConsumer.as_asgi()),
]

5、创建 WebSocket 消费者:在 myapp 应用的目录下创建一个名为 consumers.py 的文件,定义您的 WebSocket 消费者类。

使用 Django WebSocket 实现循环发送图像数据

当使用 Django WebSocket 实现循环发送数据时,可能会遇到 “took too long to shut down and was killed” 错误。这个错误通常是因为循环发送数据的操作没有正确终止导致的。

AsyncWebsocketConsumer 是 Django Channels 中用于处理 WebSocket 连接的异步消费者类。它是一个基于协程的类,用于处理 WebSocket 连接的生命周期、接收和发送消息等操作。

创建一个继承AsyncWebsocketConsumer的自定义消费者类


class TailfConsumer(AsyncWebsocketConsumer):
    async def connect(self):
    
        """
        这里定义连接建立时的逻辑
        """
        
        # 接受客户端连接        
        await self.accept()
        # 开启循环发送数据
        asyncio.ensure_future(self.send_data_loop())


    async def disconnect(self, close_code):
        # 连接断开时的逻辑
        pass
        
     
    async def send_data_loop(self):
        while True:
            # 获取数据
            
            data = await self.get_data()
            await self.send(json.dumps(data))
            await asyncio.sleep(1)  # 假设每秒发送一次数据

   async def get_data(self):
        """
        监听端口5000 ,实时获取视频图像数据
        """
        import pickle
        import socket
        # 创建客户端 socket 对象
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置服务器地址和端口号
        server_address = ('192.168.1.106', 5000)
        # 连接服务器
        client_socket.connect(server_address)
        decoded_data = {"leftimg":""}
        try:
            # 接收数据
            received_data = client_socket.recv(600000000)
            # 如果接收到数据,则进行处理
            if received_data:
                try:
                    decoded_data = pickle.loads(received_data)
                    # 在这里处理解码后的数据
                except pickle.UnpicklingError as e:
                    # 处理解码错误
                    print(f"Failed to decode pickle data: {e}")
                client_socket.close()
        except Exception as e:
            print('接收数据时出错:', str(e))
        return decoded_data


asyncawait 是 Python 中用于定义和处理异步操作的关键字。它们与协程(coroutine)一起使用,以实现更高效的并发和非阻塞的编程。

创建一个脚本打开摄像头模拟通过socket发送图像数据,由于直接打开摄像头不能被多个用户同时获取数据,所以采用这种方式实时发送数据,脚本如下:

import pickle
import socket
import threading
import cv2
import base64

video_source = 0
# 创建视频捕获对象
cap = cv2.VideoCapture(video_source)
# 获取视频的宽度和高度
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 用于存储连接的客户端 Socket
client_sockets = []
import random

# 生成一个包含19个随机整数的列表


# 创建 socket 对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定服务器地址和端口
server_address = ('192.168.1.106', 5000)
server_socket.bind(server_address)

# 监听客户端连接
server_socket.listen(1)


def image_to_base64(image):
    # 将图像数据编码为 Base64 字符串
    image_base64 = base64.b64encode(image).decode('utf-8')
    return image_base64



# 定义发送视频数据的函数
def send_video_data():
    while True:
        ret, frame = cap.read()
        if not ret:
            break

        # 将图像编码为 JPEG 格式
        _, image_data = cv2.imencode('.jpg', frame)
        # 遍历所有客户端连接,发送视频数据
        for client_socket in client_sockets:
            try:
                # 发送图像数据
                encoded_data = pickle.dumps({
                    "leftimg": image_to_base64(image_data),
                })

                client_socket.sendall(encoded_data)
            except Exception as e:
                print(f"Error sending video data to client: {e}")
                client_socket.close()
                client_sockets.remove(client_socket)



# 定义处理客户端连接的函数
def handle_client_connection(client_socket):
    while True:
        try:
            # 接收客户端请求
            data = client_socket.recv(1024)
            if not data:
                break
            # 处理客户端请求
            # 在此可以添加其他自定义逻辑
        except Exception as e:
            print(f"Error handling client connection: {e}")
            break

    # 关闭客户端连接
    client_socket.close()
    client_sockets.remove(client_socket)


# 接受客户端连接,并启动视频发送线程
def accept_client_connections():
    while True:
        client_socket, _ = server_socket.accept()
        client_sockets.append(client_socket)

# 启动视频发送线程和客户端连接接受线程
send_thread = threading.Thread(target=send_video_data)
accept_thread = threading.Thread(target=accept_client_connections)

send_thread.start()
accept_thread.start()

前端代码:文章来源地址https://www.toymoban.com/news/detail-763795.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<img  width="800" height="500" id="image">

<script>
    var socket = new WebSocket("ws://192.168.1.106:8000/ws/some-path1/");
    socket.onopen = function(event) {
        console.log("WebSocket连接已打开");
    };

    socket.onmessage = function(event) {
        // 接收到消息时的处理
        const imageData = event.data; // 从事件中获取图像数据
        // 在前端显示图像数据,这里假设有一个img元素来显示图像
        const imgElement = document.getElementById('image');
        imgElement.src = "data:image/jpeg;base64," + JSON.parse(imageData)["leftimg"];
    };

    socket.onclose = function(event) {
        console.log("WebSocket连接已关闭");
    };

</script>

</body>
</html>

到了这里,关于基于Django websocket实现视频画面的实时传输案例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JRTP实时音视频传输(2)-使用TCP通信的案例

    环境搭建等参考:JRTP实时音视频传输(1)-必做的环境搭建与demo测试 先将example1拷贝为myclienttcp.cpp和myservertcp.cpp cp example1.cpp myclienttcp.cpp cp example1.cpp myservertcp.cpp 改写jrtplib/JRTPLIB/examples/CMakeLists.txt,添加myclienttcp和myservertcp编译 重新生成Makefile并编译 可以看到成功编译了myclient

    2024年01月18日
    浏览(44)
  • Unity实时画面传输插件FMETP STREAM的使用

    FMETP STREAM是一个局域网实时画面传输的插件,可以用于PC端,安卓端等等,支持画面一对一、一对多传输。接下来我就来介绍一下这个插件的基本使用。 1、导入插件实时画面传输插件FMETP STREAM,资源链接我待会会放在文末,需要的小伙伴可以自取。 2、画面传输端的设置 2.

    2024年02月06日
    浏览(36)
  • 前端(二十一)——WebSocket:实现实时双向数据传输的Web通信协议

    🤨博主:小猫娃来啦 🤨文章核心: WebSocket:实现实时双向数据传输的Web通信协议 在当今互联网时代,实时通信已成为很多应用的需求。为了满足这种需求,WebSocket协议被设计出来。WebSocket是一种基于TCP议的全双工通信协议,通过WebSocket,Web应用程序可以与服务器建立持久

    2024年02月04日
    浏览(56)
  • Android实时获取摄像头画面传输至PC端

    最近在做一个PC端小应用,需要获取摄像头画面,但是电脑摄像头像素太低,而且位置调整不方便,又不想为此单独买个摄像头。于是想起了之前淘汰掉的手机,成像质量还是杠杠的,能不能把手机摄像头连接到电脑上使用呢?经过搜索,在网上找到了几款这类应用,但是都

    2024年02月12日
    浏览(38)
  • 基于ZLMediaKit的webrtc实时视频传输demo搭建

    环境 部署ZLMediaKit流媒体服务器 安装openssl 首先可以检查一下自己的openssl的版本如果是1.1.1以上就可以忽略这一步 安装libsrtp 其中初始化配置的时候可能会报错,如果报错换成 ./configure --enable-openssl 即可 对于一些比较新的编译环境(如GCC 10+),编译 libsrtp-2.3.0 可能会存在问题

    2024年02月02日
    浏览(28)
  • 电脑传输数据STM32模拟I2C显示实时画面到OLED

    写的不好,还望大家指正,有的地方引用了一下大佬的代码。 一、所需硬件: STM32F103C8T6 USB转串口模块 OLED 128*64显示屏 STLINK 二、代码部分 1.stm32串口部分代码 2.stm32OLED屏幕部分代码 3.主程序 4.电脑通过opencv库截取电脑当前1080p一帧画面,并对图片二值化处理,通过电脑端编写

    2024年02月13日
    浏览(33)
  • 使用Python基于opencv实现多视频画面拼接融合算法demo

    单个相机视频画面尺寸有限,在需要全景展示的场景下,就需要将多个相机视频进行拼接融合,得到一张全景图。本文基于opencv实现一个视频拼接的demo,熟悉视频拼接流程和opencv接口。 直接上代码吧,注释还是比较清楚的: 该demo使用ORB算法检测关键点,使用BFMatcher进行特征

    2024年02月04日
    浏览(39)
  • 如何使用Django 结合WebSocket 进行实时目标检测呢?以yolov5 为例,实现:FPS 25+ (0: 系统简介与架构)

    访问:http://127.0.0.1:8000/ObjectDetection/ObjectDetection1/ 先看下效果:两个摄像头实时展示 之后更新了效果,打算加上检测结果和 FPS ,结果加上FPS 实测了一下,好家伙一秒30-40 帧都行 在我的3060 上,这是python 写的 前后端实时检测你敢信,还两个摄像头机位。

    2023年04月08日
    浏览(29)
  • 进度变动实时通知-使用SocketIO实现前后端的通信(基于WebSocket的实时通信库)

    最近在接触的一个项目,将PDF上传到项目里,通过调用OCR云服务把PDF里的表格数据识别出来。在此过程中,前后端需要实时通信,对识别数据进行“进度跟踪”。因此我们采用SocketIO的通讯方式,识别中前端和后端服务建立SocketIO连接,根据事件进行数据的实时更新百分比进度

    2024年02月06日
    浏览(40)
  • 基于netty框架不使用SSL证书,实现websocket数据加密传输

    1、简介 2、实现方式 3、服务端主要代码 4、客户端主要代码 5、调用方式 为什么不使用SSL证书? 1、服务器运行在专网环境,不能访问互联网。证书有有效期,CA机构规定,证书有效期最多2年。在客户的专网环境里更新和维护证书就会增加运营成本。 实现逻辑? 参照SSL的实

    2024年02月04日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包