欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Django?websocket實(shí)現(xiàn)視頻畫面的實(shí)時(shí)傳輸功能(最新推薦)

 更新時(shí)間:2023年06月09日 10:58:48   作者:cyl-2002  
Django?Channels?是一個(gè)用于在?Django框架中實(shí)現(xiàn)實(shí)時(shí)、異步通信的擴(kuò)展庫,本文給大家介紹基于Django?websocket實(shí)現(xiàn)視頻畫面的實(shí)時(shí)傳輸案例,本案例是基于B/S架構(gòu)的視頻監(jiān)控畫面的實(shí)時(shí)傳輸,使用django作為服務(wù)端的開發(fā)框架,需要的朋友可以參考下

基于Django websocket實(shí)現(xiàn)視頻畫面的實(shí)時(shí)傳輸案例

??本案例是基于B/S架構(gòu)的視頻監(jiān)控畫面的實(shí)時(shí)傳輸,使用django作為服務(wù)端的開發(fā)框架。

Django Channels 是一個(gè)用于在 Django 框架中實(shí)現(xiàn)實(shí)時(shí)、異步通信的擴(kuò)展庫。傳統(tǒng)的 Django 是基于請(qǐng)求-響應(yīng)模式的,每個(gè)請(qǐng)求都會(huì)經(jīng)過 Django 的視圖函數(shù)進(jìn)行處理并返回響應(yīng)。而 Channels 提供了基于事件驅(qū)動(dòng)的編程模型,使得開發(fā)者可以處理實(shí)時(shí)的事件,如 WebSocket 連接、消息隊(duì)列、定時(shí)任務(wù)等。

Channels 的主要特性包括:

  • 支持 WebSocket:Channels 可以輕松地處理 WebSocket 連接,實(shí)現(xiàn)實(shí)時(shí)的雙向通信;
  • 異步處理:Channels 使用異步方式處理請(qǐng)求和事件,可以提高應(yīng)用的性能和并發(fā)能力;
  • Channels 可以與諸如 Celery 等任務(wù)隊(duì)列庫集成,處理后臺(tái)任務(wù)和定時(shí)任務(wù)。

Channels可以跟Django無縫銜接,常用于開發(fā)聊天室、實(shí)時(shí)通知、實(shí)時(shí)數(shù)據(jù)更新等。

WebSocket 是一種在客戶端和服務(wù)器之間進(jìn)行雙向通信的網(wǎng)絡(luò)協(xié)議。與傳統(tǒng)的 HTTP 請(qǐng)求-響應(yīng)模式不同,WebSocket 只需要完成一次握手就可以創(chuàng)建持久性的連接,允許服務(wù)器主動(dòng)向客戶端推送數(shù)據(jù),而不需要客戶端發(fā)起請(qǐng)求。

在使用 WebSocket 進(jìn)行通信時(shí),涉及到異步和同步兩個(gè)概念:

在異步模式下,websocket使用異步的方式操作i/o,允許同時(shí)處理多個(gè)連接或事件。

在同步模式下,每個(gè) WebSocket 連接會(huì)被分配給一個(gè)線程或進(jìn)程進(jìn)行處理,消息的接收和發(fā)送是同步的操作。同步方式適用于一對(duì)一的連接事件。

環(huán)境配置

1、下載安裝channels庫

pip install channels

2、添加 Channels 到 Django 項(xiàng)目的安裝應(yīng)用列表中:打開 Django 項(xiàng)目的 settings.py 文件,在 INSTALLED_APPS 設(shè)置中添加 'channels',確保它出現(xiàn)在其他應(yīng)用的前面:

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

并且在settings.py 文件添加以下內(nèi)容:

ASGI_APPLICATION = "projetc2.asgi.application" #project2為項(xiàng)目名稱
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels.layers.InMemoryChannelLayer',
    },
}

Django Channels 運(yùn)行于 ASGI(Asynchronous Server Gateway Interface)協(xié)議上。ASGI 是一個(gè)用于處理異步 Python Web 應(yīng)用程序的協(xié)議,它提供了一種標(biāo)準(zhǔn)的方式來與 Web 服務(wù)器和應(yīng)用程序框架之間進(jìn)行通信。

3、配置 Channels 的 ASGI 應(yīng)用程序:在 Django 項(xiàng)目的根目錄下有一個(gè)名為 asgi.py 的文件,然后將文件中修改為以下內(nèi)容:

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', '項(xiàng)目名稱.settings')
application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": URLRouter(routing.websocket_urlpatterns)
})

4、配置 WebSocket 路由:在 Django 項(xiàng)目 project的目錄下創(chuàng)建一個(gè)名為 routing.py 的文件,然后定義您的 WebSocket 路由。以下是一個(gè)示例:

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

5、創(chuàng)建 WebSocket 消費(fèi)者:在 myapp 應(yīng)用的目錄下創(chuàng)建一個(gè)名為 consumers.py 的文件,定義您的 WebSocket 消費(fèi)者類。

使用 Django WebSocket 實(shí)現(xiàn)循環(huán)發(fā)送圖像數(shù)據(jù)

當(dāng)使用 Django WebSocket 實(shí)現(xiàn)循環(huán)發(fā)送數(shù)據(jù)時(shí),可能會(huì)遇到 “took too long to shut down and was killed” 錯(cuò)誤。這個(gè)錯(cuò)誤通常是因?yàn)檠h(huán)發(fā)送數(shù)據(jù)的操作沒有正確終止導(dǎo)致的。

AsyncWebsocketConsumer 是 Django Channels 中用于處理 WebSocket 連接的異步消費(fèi)者類。它是一個(gè)基于協(xié)程的類,用于處理 WebSocket 連接的生命周期、接收和發(fā)送消息等操作。

創(chuàng)建一個(gè)繼承AsyncWebsocketConsumer的自定義消費(fèi)者類

class TailfConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        """
        這里定義連接建立時(shí)的邏輯
        """
        # 接受客戶端連接        
        await self.accept()
        # 開啟循環(huán)發(fā)送數(shù)據(jù)
        asyncio.ensure_future(self.send_data_loop())
    async def disconnect(self, close_code):
        # 連接斷開時(shí)的邏輯
        pass
    async def send_data_loop(self):
        while True:
            # 獲取數(shù)據(jù)
            data = await self.get_data()
            await self.send(json.dumps(data))
            await asyncio.sleep(1)  # 假設(shè)每秒發(fā)送一次數(shù)據(jù)
   async def get_data(self):
        """
        監(jiān)聽端口5000 ,實(shí)時(shí)獲取視頻圖像數(shù)據(jù)
        """
        import pickle
        import socket
        # 創(chuàng)建客戶端 socket 對(duì)象
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 設(shè)置服務(wù)器地址和端口號(hào)
        server_address = ('192.168.1.106', 5000)
        # 連接服務(wù)器
        client_socket.connect(server_address)
        decoded_data = {"leftimg":""}
        try:
            # 接收數(shù)據(jù)
            received_data = client_socket.recv(600000000)
            # 如果接收到數(shù)據(jù),則進(jìn)行處理
            if received_data:
                try:
                    decoded_data = pickle.loads(received_data)
                    # 在這里處理解碼后的數(shù)據(jù)
                except pickle.UnpicklingError as e:
                    # 處理解碼錯(cuò)誤
                    print(f"Failed to decode pickle data: {e}")
                client_socket.close()
        except Exception as e:
            print('接收數(shù)據(jù)時(shí)出錯(cuò):', str(e))
        return decoded_data

asyncawait 是 Python 中用于定義和處理異步操作的關(guān)鍵字。它們與協(xié)程(coroutine)一起使用,以實(shí)現(xiàn)更高效的并發(fā)和非阻塞的編程。

創(chuàng)建一個(gè)腳本打開攝像頭模擬通過socket發(fā)送圖像數(shù)據(jù),由于直接打開攝像頭不能被多個(gè)用戶同時(shí)獲取數(shù)據(jù),所以采用這種方式實(shí)時(shí)發(fā)送數(shù)據(jù),腳本如下:

import pickle
import socket
import threading
import cv2
import base64
video_source = 0
# 創(chuàng)建視頻捕獲對(duì)象
cap = cv2.VideoCapture(video_source)
# 獲取視頻的寬度和高度
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 用于存儲(chǔ)連接的客戶端 Socket
client_sockets = []
import random
# 生成一個(gè)包含19個(gè)隨機(jī)整數(shù)的列表
# 創(chuàng)建 socket 對(duì)象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 綁定服務(wù)器地址和端口
server_address = ('192.168.1.106', 5000)
server_socket.bind(server_address)
# 監(jiān)聽客戶端連接
server_socket.listen(1)
def image_to_base64(image):
    # 將圖像數(shù)據(jù)編碼為 Base64 字符串
    image_base64 = base64.b64encode(image).decode('utf-8')
    return image_base64
# 定義發(fā)送視頻數(shù)據(jù)的函數(shù)
def send_video_data():
    while True:
        ret, frame = cap.read()
        if not ret:
            break
        # 將圖像編碼為 JPEG 格式
        _, image_data = cv2.imencode('.jpg', frame)
        # 遍歷所有客戶端連接,發(fā)送視頻數(shù)據(jù)
        for client_socket in client_sockets:
            try:
                # 發(fā)送圖像數(shù)據(jù)
                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)
# 定義處理客戶端連接的函數(shù)
def handle_client_connection(client_socket):
    while True:
        try:
            # 接收客戶端請(qǐng)求
            data = client_socket.recv(1024)
            if not data:
                break
            # 處理客戶端請(qǐng)求
            # 在此可以添加其他自定義邏輯
        except Exception as e:
            print(f"Error handling client connection: {e}")
            break
    # 關(guān)閉客戶端連接
    client_socket.close()
    client_sockets.remove(client_socket)
# 接受客戶端連接,并啟動(dòng)視頻發(fā)送線程
def accept_client_connections():
    while True:
        client_socket, _ = server_socket.accept()
        client_sockets.append(client_socket)
# 啟動(dòng)視頻發(fā)送線程和客戶端連接接受線程
send_thread = threading.Thread(target=send_video_data)
accept_thread = threading.Thread(target=accept_client_connections)
send_thread.start()
accept_thread.start()

前端代碼:

<!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) {
        // 接收到消息時(shí)的處理
        const imageData = event.data; // 從事件中獲取圖像數(shù)據(jù)
        // 在前端顯示圖像數(shù)據(jù),這里假設(shè)有一個(gè)img元素來顯示圖像
        const imgElement = document.getElementById('image');
        imgElement.src = "data:image/jpeg;base64," + JSON.parse(imageData)["leftimg"];
    };
    socket.onclose = function(event) {
        console.log("WebSocket連接已關(guān)閉");
    };
</script>
</body>
</html>

到此這篇關(guān)于基于Django websocket實(shí)現(xiàn)視頻畫面的實(shí)時(shí)傳輸案例的文章就介紹到這了,更多相關(guān)Django websocket實(shí)時(shí)傳輸內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • langchain Prompt大語言模型使用技巧詳解

    langchain Prompt大語言模型使用技巧詳解

    這篇文章主要為大家介紹了langchain Prompt大語言模型使用技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • 詳解Python中數(shù)據(jù)庫管理模塊shelve和dbm的應(yīng)用

    詳解Python中數(shù)據(jù)庫管理模塊shelve和dbm的應(yīng)用

    作為常用的 python 自帶數(shù)據(jù)庫管理模塊,shelve 和 dbm 都是非常方便的對(duì)象持久化存儲(chǔ)和檢索工具,本文將從用法、優(yōu)勢(shì)以及不同點(diǎn)等方面進(jìn)行介紹,希望對(duì)大家有所幫助
    2023-10-10
  • pytest fixtures裝飾器的使用和如何控制用例的執(zhí)行順序

    pytest fixtures裝飾器的使用和如何控制用例的執(zhí)行順序

    這篇文章主要介紹了pytest fixtures裝飾器的使用和如何控制用例的執(zhí)行順序,幫助大家更好的理解和使用pytest測(cè)試框架,感興趣的朋友可以了解下
    2021-01-01
  • 解決python tkinter界面卡死的問題

    解決python tkinter界面卡死的問題

    今天小編就為大家分享一篇解決python tkinter界面卡死的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Python 離線工作環(huán)境搭建的方法步驟

    Python 離線工作環(huán)境搭建的方法步驟

    這篇文章主要介紹了Python 離線工作環(huán)境搭建的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • python 進(jìn)程池pool使用詳解

    python 進(jìn)程池pool使用詳解

    這篇文章主要介紹了python 進(jìn)程池pool使用的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)python進(jìn)程,感興趣的朋友可以了解下
    2020-10-10
  • Python-pandas返回重復(fù)數(shù)據(jù)的index問題

    Python-pandas返回重復(fù)數(shù)據(jù)的index問題

    這篇文章主要介紹了Python-pandas返回重復(fù)數(shù)據(jù)的index問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • 如何使用python進(jìn)行pdf文件分割

    如何使用python進(jìn)行pdf文件分割

    這篇文章主要介紹了如何使用python進(jìn)行pdf文件分割,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Python 實(shí)現(xiàn)一行輸入多個(gè)值的方法

    Python 實(shí)現(xiàn)一行輸入多個(gè)值的方法

    下面小編就為大家分享一篇Python 實(shí)現(xiàn)一行輸入多個(gè)值的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • pycharm 中mark directory as exclude的用法詳解

    pycharm 中mark directory as exclude的用法詳解

    今天小編就為大家分享一篇pycharm 中mark directory as exclude的用法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02

最新評(píng)論