Django channels摄像头实时视频传输
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摄像头实时视频传输相关推荐
- 计算机视觉——利用openCV与Socket结合进行远程摄像头实时视频传输并保存图片数据
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.TCP协议通信步骤 二.代码实现 1.客户端 2.服务端 三.IP设置方法 四.效果演示 前言 本文的内容是利用o ...
- android 录像实时传送,Android中实时视频传输(摄像头实时视频传输)解决方案
1.使用FFMpeg进行视频采集,使用Live555进行RTP传输,使用VideoView进行播放. 提到:重载FrameSource,写一个服务类,可以从FrameSource的派生类读取帧数据,转 ...
- Android中实时视频传输(摄像头实时视频传输)解决方案二
为什么80%的码农都做不了架构师?>>> 1.使用FFMpeg进行视频采集,使用Live555进行RTP传输,使用VideoView进行播放. csdn提到:重载FrameSo ...
- 海康网络摄像头实时视频预览(流媒体转码推流 red5,nginx-rtmp,ffmpeg)
海康网络摄像头实时视频预览(流媒体转码推流 red5,nginx-rtmp,ffmpeg) 实现思路 获取摄像头rtsp流→流媒体拉流转码推流成rtmp流(网页具备flash可播放)→根据rtmp流地 ...
- linux中c语言实现实时视频传输代码
你可以使用FFmpeg来实现实时视频传输.下面是一个简单的代码示例,可以将视频从一台电脑传输到另一台电脑(假设两台电脑都安装了FFmpeg): // 第一台电脑(发送端): ffmpeg -f avf ...
- Django Channels 入门指南
http://www.oschina.NET/translate/in_deep_with_django_channels_the_future_of_real_time_apps_in_django ...
- 实时视频传输中的BBR拥塞控制
在复杂的网络环境中,想要实现实时视频传输,拥塞控制算法是尤为重点的一环.本文整理自学霸君高级技术总监袁荣喜在LiveVideoStackCon 2019上海大会中的分享,详细介绍了BBR拥塞控制算法在 ...
- django channels
一直都是用HTTP请求糊里糊涂的实现了一次请求,一次响应.最近尝试用Django这种框架实现websocket,用的是Django channels,结合官网给的例子,实现了日志动态展示到页面.源码地 ...
- 树莓派1——摄像头实时视频和截图
准备工作:为树莓派建立远程连接 我使用的树莓派2,未其接上电,连上局域网. 我使用的是xrdp来进行远程桌面连接,首先确定树莓派系统上已经安装好了xrdp,在笔记本(系统是win7旗舰版)上打开远程桌 ...
最新文章
- “数学不行,啥都干不好!”骨灰级程序员:这比努力重要1000倍
- html实体编码遇上js代码
- iOS-生成国际化包-配置App多语言支持
- java的for循环的几种写法
- Android之ExpandableListView的各种效果(默认展开不合闭,自定义父栏目及箭头控制)
- ssh key生成_Stelnet(ssh)登陆华为交换机配置教程
- ZoomBlur 聚焦模糊效果Shader(URP)
- Linux主机通过直连线直连,【IT基础】网线的直连线与交叉线之间的区别
- CSS 文本溢出时显示省略标记
- 小男孩与苹果树(翻译)(06年10月)
- matlab函数_连通区域
- C语言程序设计谭浩强(第四版)期末复习重点
- 希捷7200.11固件门完全DIY修正方法! 不用几块钱, DIYers请进!!!
- linux文件增加自定义属性,Linux 笔记...文件和目录属性useradd、userdel、usermod 、passwd...
- Windows - 强力删除文件
- 揭密中国500岁世外异人的真实生活
- unity Google 广告接入 SDK Android
- OutMan——C语言中的冒泡排序、选择排序、折半查找以及指针的介绍
- 对 COMP 通证经济模型的一般性评价
- apple与android传数据线,可以同时插安卓和苹果的数据线