Django channels摄像头实时视频传输(视屏能传别的当然也能传拉)

  • 前言
  • 不想看我瞎扯可以直接跳到这
  • 服务端
    • 步骤
    • 解释
  • 发送端
  • 接收端
  • 运行

前言

(网上绝大多数博客都是发送端或者接收端同时作为服务器,这不扯么…)

不想看我瞎扯可以直接跳到这

使用的框架为Django,发送视频用Python实现(便于与ROS结合);客户端显示先用HTML凑合吧,写个Qt或者Swift太累了…

虽说ROS2内置DDS通讯,但这玩意儿我没接触过用不明白怎么在广域网通讯,所以我选择重复造轮子搭一个Django服务器。

服务端

为了实现双向奔赴通信,我选择websocket;但是蛋疼的是Django 3.0往上走就不支持websocket了,所以这里我通过channels实现websocket。

各位可以先跑一下channels官方的教程demo:https://channels.readthedocs.io/en/latest/tutorial/part_1.html

我只写了前三个tutorial,并且我的代码就是在这个基础上改的;所以我不会从0开始说(以后有时间了再说吧);

以及这个demo实现的是文本传输(聊天室),这不稍微改改就能实现命令和状态传输了么?多好啊

接下来我默认各位已经跑完demo了;接下来我的python版本均为3.8。

步骤

首先再次创建一个app,我将它命名为video:

python manage.py startapp video

并且在mysite/setting.py中注册:

INSTALLED_APPS = ['channels','chat','video','django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',
]

同时在video/urls.py和mysite/urls.py中添加路由:

# mysite/urls.py
from django.conf.urls import include
from django.urls import path
from django.contrib import adminurlpatterns = [path('chat/', include('chat.urls')),path('video/', include('video.urls')),path('admin/', admin.site.urls),
]
# video/urls.py
from django.urls import path
from . import viewsurlpatterns = [path('', views.index, name='index'),path('<str:v_name>/', views.v_name, name='v_name'),
]

编辑video/views.py:

# video/views.py
from django.shortcuts import render# Create your views here.
def index(request):return render(request, 'video/index.html')def v_name(request, v_name):return render(request, 'video/video.html', {'v_name': v_name})

添加video/consumers.py:

# video/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumerclass VideoConsumer(AsyncWebsocketConsumer):async def connect(self):self.room_name = self.scope['url_route']['kwargs']['v_name']self.room_group_name = 'video_%s' % self.room_name#print(self.room_name)# Join room groupawait self.channel_layer.group_add(self.room_group_name,self.channel_name)await self.accept()async def disconnect(self, close_code):# Leave room groupawait self.channel_layer.group_discard(self.room_group_name,self.channel_name)# Receive message from WebSocketasync def receive(self, text_data):# print(1)# Send message to room groupawait self.channel_layer.group_send(self.room_group_name,{'type': 'video_message','message': text_data,})# Receive message from room groupasync def video_message(self, event):# print(1)message = event['message']# Send message to WebSocketawait self.send(text_data=json.dumps({'message': message}))

待会我们再来说这个文件。其实这个文件基本上就是抄的chat/consumers.py,各位应该能看出来。

然后我们在mysite应用中创建routing.py:

# chat/routing.py
from django.urls import re_path
import chat.consumers
import video.consumerswebsocket_urlpatterns = [re_path(r'chat/(?P<room_name>\w+)/$', chat.consumers.ChatConsumer.as_asgi()),re_path(r'video/(?P<v_name>\w+)/$', video.consumers.VideoConsumer.as_asgi())
]

同时修改asgi.py:

# mysite/asgi.py
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application
from channels.auth import AuthMiddlewareStack
# import chat.routing
# import video.routing
from . import routingos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')application = ProtocolTypeRouter({"http": get_asgi_application(),"websocket": AuthMiddlewareStack(URLRouter(routing.websocket_urlpatterns)),
})

这么干是为了让chat和video能够同时工作(同时传输视频和指令/状态)。

解释

这里我只解释video/consumers.py中我修改的代码,其余操作原理与chat相同。
看到receive()函数:

async def receive(self, text_data):await self.channel_layer.group_send(self.room_group_name,{'type': 'video_message','message': text_data,})

由于传输时我将视屏拆解成图片,并将图片编码成base64,所以这里的接收值为text_data。

发送端

send_video.py:

# send_video.py
import asyncio
import websockets
import numpy as np
import json
import cv2
import base64
import timecapture = cv2.VideoCapture(0)
if not capture.isOpened():print('quit')quit()
ret, frame = capture.read()
encode_param=[int(cv2.IMWRITE_JPEG_QUALITY),95]# 向服务器端实时发送视频截图
async def send_video(websocket):global ret, frame# global camwhile True:time.sleep(0.1)result, imgencode = cv2.imencode('.jpg', frame, encode_param)data = np.array(imgencode)img = data.tobytes()# base64编码传输img = base64.b64encode(img).decode()await websocket.send("data:image/jpg;base64,"+ img)ret, frame = capture.read()async def main_logic():async with websockets.connect('ws://127.0.0.1:8000/ws/video/wms/') as websocket:await send_video(websocket)asyncio.get_event_loop().run_until_complete(main_logic())

通过cv2读取摄像头并转码发送到Django后端;这里我默认固定连接 ws://127.0.0.1:8000/ws/video/wms/,便于调试。

接收端

video.html:

<!--video.html-->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Video</title>
</head>
<body><div><h1>Video</h1>
<div>
<div><img id="resImg" src="" />
</div><script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js" ></script>
<script>const ws = new WebSocket('ws://'+ window.location.host+ '/ws/video/'+ 'wms'+ '/');ws.onmessage = function(evt) {v_data = JSON.parse(evt.data);$("#resImg").attr("src", v_data.message);//console.log( "Received Message: " + v_data.message);// ws.close();};ws.onclose = function(evt) {console.log("Connection closed.");};</script>
</body>
</html>

接收端就是解析json数据并反向解码jpg图像并显示;之后我可能会用Swift实现(Qt我写不好运行太慢了)。

运行

在Django工程中运行:

python manage.py runserver

然后运行发送端send_video.py:

python send_video.py

最后在浏览器中输入127.0.0.1:8000/video/wms打开video.html:

YADAZE.

你就可以在网页中看到一张帅气的脸了 v

本地测试完毕,就差部署了。

又是四点多…

项目部署:Django channels nginx+uwsgi+daphne 项目部署

Django channels摄像头实时视频传输相关推荐

  1. 计算机视觉——利用openCV与Socket结合进行远程摄像头实时视频传输并保存图片数据

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.TCP协议通信步骤 二.代码实现 1.客户端 2.服务端 三.IP设置方法 四.效果演示 前言 本文的内容是利用o ...

  2. android 录像实时传送,Android中实时视频传输(摄像头实时视频传输)解决方案

    1.使用FFMpeg进行视频采集,使用Live555进行RTP传输,使用VideoView进行播放. 提到:重载FrameSource,写一个服务类,可以从FrameSource的派生类读取帧数据,转 ...

  3. Android中实时视频传输(摄像头实时视频传输)解决方案二

    为什么80%的码农都做不了架构师?>>>    1.使用FFMpeg进行视频采集,使用Live555进行RTP传输,使用VideoView进行播放. csdn提到:重载FrameSo ...

  4. 海康网络摄像头实时视频预览(流媒体转码推流 red5,nginx-rtmp,ffmpeg)

    海康网络摄像头实时视频预览(流媒体转码推流 red5,nginx-rtmp,ffmpeg) 实现思路 获取摄像头rtsp流→流媒体拉流转码推流成rtmp流(网页具备flash可播放)→根据rtmp流地 ...

  5. linux中c语言实现实时视频传输代码

    你可以使用FFmpeg来实现实时视频传输.下面是一个简单的代码示例,可以将视频从一台电脑传输到另一台电脑(假设两台电脑都安装了FFmpeg): // 第一台电脑(发送端): ffmpeg -f avf ...

  6. Django Channels 入门指南

    http://www.oschina.NET/translate/in_deep_with_django_channels_the_future_of_real_time_apps_in_django ...

  7. 实时视频传输中的BBR拥塞控制

    在复杂的网络环境中,想要实现实时视频传输,拥塞控制算法是尤为重点的一环.本文整理自学霸君高级技术总监袁荣喜在LiveVideoStackCon 2019上海大会中的分享,详细介绍了BBR拥塞控制算法在 ...

  8. django channels

    一直都是用HTTP请求糊里糊涂的实现了一次请求,一次响应.最近尝试用Django这种框架实现websocket,用的是Django channels,结合官网给的例子,实现了日志动态展示到页面.源码地 ...

  9. 树莓派1——摄像头实时视频和截图

    准备工作:为树莓派建立远程连接 我使用的树莓派2,未其接上电,连上局域网. 我使用的是xrdp来进行远程桌面连接,首先确定树莓派系统上已经安装好了xrdp,在笔记本(系统是win7旗舰版)上打开远程桌 ...

最新文章

  1. “数学不行,啥都干不好!”骨灰级程序员:这比努力重要1000倍
  2. html实体编码遇上js代码
  3. iOS-生成国际化包-配置App多语言支持
  4. java的for循环的几种写法
  5. Android之ExpandableListView的各种效果(默认展开不合闭,自定义父栏目及箭头控制)
  6. ssh key生成_Stelnet(ssh)登陆华为交换机配置教程
  7. ZoomBlur 聚焦模糊效果Shader(URP)
  8. Linux主机通过直连线直连,【IT基础】网线的直连线与交叉线之间的区别
  9. CSS 文本溢出时显示省略标记
  10. 小男孩与苹果树(翻译)(06年10月)
  11. matlab函数_连通区域
  12. C语言程序设计谭浩强(第四版)期末复习重点
  13. 希捷7200.11固件门完全DIY修正方法! 不用几块钱, DIYers请进!!!
  14. linux文件增加自定义属性,Linux 笔记...文件和目录属性useradd、userdel、usermod 、passwd...
  15. Windows - 强力删除文件
  16. 揭密中国500岁世外异人的真实生活
  17. unity Google 广告接入 SDK Android
  18. OutMan——C语言中的冒泡排序、选择排序、折半查找以及指针的介绍
  19. 对 COMP 通证经济模型的一般性评价
  20. apple与android传数据线,可以同时插安卓和苹果的数据线

热门文章

  1. 开源软件总体拥有成本指南
  2. BZOJ 4372 烁烁的游戏
  3. c# picturebox 刷新_C# picturebox画图问题
  4. 取消usb计算机连接网络,usb连接(如何设置usb网络连接)
  5. 攻防世界萌新misc-wp
  6. 深度学习实战-词嵌入计算文本相似性
  7. 2022电大国家开放大学网上形考任务-人力资源管理非免费(非答案)
  8. 速算24点(C++)
  9. 上一主题 下一主题 一个微信账号登陆信息提取软件,有人知道吗?
  10. 小米手机与HBuilder连接的问题解决