webrtc学习
先弄一个长链接服务:
将同一个房间的用户数据(摄像头或者共享桌面)下发到别的用户
import tornado.ioloop
import tornado.web
import tornado.websocket
import time
clients = {}
rooms = {}
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def open(self, *args, **kwargs):
print("客户端连接...")
self.room_id = self.get_argument("room_id")
self.user_id = self.get_argument("user_id")
clients[self.user_id] = self
if self.room_id in rooms:
rooms[self.room_id] = rooms[self.room_id] + [self.user_id]
else:
rooms[self.room_id] = [self.user_id]
print('用户%s加入房间%s' % (self.user_id, self.room_id))
def on_message(self, message):
#print("收到客户端消息:%s" % message)
user_ids = rooms[self.room_id]
new_user_list = []
for user_id in user_ids:
if user_id == self.user_id:
pass
else:
new_user_list.append(user_id)
if len(new_user_list) == 0:
new_user_list.append(self.user_id)
for user_id in new_user_list:
hander = clients[user_id]
hander.write_message(message)
def on_close(self):
print("客户端关闭连接...")
print('用户%s退出房间%s' % (self.user_id, self.room_id))
if self.user_id in clients:
del clients[self.user_id]
user_ids = rooms[self.room_id]
new_user_list = []
for user_id in user_ids:
if user_id == self.user_id:
pass
else:
new_user_list.append(user_id)
rooms[self.room_id] = new_user_list
def check_origin(self, origin):
# 暂时允许所有来源
return True
application = tornado.web.Application([
(r'/websocket', WebSocketHandler),
])
if __name__ == '__main__':
application.listen(3001)
tornado.ioloop.IOLoop.instance().start()
前端页:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#canvas{
border:2px solid red;
}
#local{
border:2px solid green;
}
#remote{
border:2px solid blue;
}
#remote-img{
border:2px solid yellow;
}
</style>
<script>
let localStream;
let recorder;
const createLocalMediaStream = async () => {
//var devices = navigator.mediaDevices.enumerateDevices(); //列出可用的媒体设备
//console.log(devices);
//getDisplayMedia 共享桌面
//getUserMedia 摄像头
navigator.mediaDevices.enumerateDevices()
.then(devices => {
console.log('设备列表:');
devices.forEach(device => {
console.log(`${device.kind}: ${device.label} (ID: ${device.deviceId})`);
});
console.log('');
});
try{
await navigator.mediaDevices.getUserMedia({
video: true,
audio: false,
}).then(localStream => {
console.log('获取摄像头数据成功...');
conectWebSocket(localStream);
});
}
catch(err){
await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: false,
}).then(localStream => {
console.log('获取共享桌面数据成功...');
conectWebSocket(localStream);
});
}
}
const conectWebSocket = (localStream) => {
if ('WebSocket' in window) {
var local_video = document.getElementById("local");
local_video.srcObject = localStream;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
interval = window.setInterval(function () {
ctx.drawImage(local_video, 0, 0, 300, 180);
}, 60);
// 创建websocket连接
var randomNum = Math.floor(Math.random() * 1000) + 1;
const socket = new WebSocket('ws://127.0.0.1:3001/websocket?room_id=1&user_id='+randomNum);
// 成功连接的时候推送一条消息,此时服务端就可以开始推送数据了
socket.onopen = function(event) {
console.log('连接websocket成功...');
interval = window.setInterval(function () {
socket.send(canvas.toDataURL("image/jpeg", 0.5));
}, 60);
}
socket.onmessage = function(event) {
let data = event.data;
//console.log(data);
document.getElementById('remote-img').src = data;
}
socket.onclose = function(event) {
console.error('关闭websocket连接...');
}
socket.onerror = function(event) {
console.error('websocket发生错误');
}
} else {
console.error('浏览器不支持websocket');
};
}
window.onload = () => {
createLocalMediaStream();
};
</script>
</head>
<body>
<table>
<tr>
<td>canvas</td>
<td>local</td>
</tr>
<tr>
<td><canvas id="canvas" width="300px" height="180px"></canvas></td>
<td><video id="local" autoplay width="300px" height="180px"></video></td>
</tr>
</table>
<table>
<tr>
<td>remote</td>
<td>remote-img</td>
</tr>
<tr>
<td><video id="remote" autoplay width="300px" height="180px"></video></td>
<td><img id="remote-img" style="width: 300px;height: 180px;"></td>
</tr>
</table>
</body>
</html>
效果客户端a:

效果客户端b

本文来自博客园,作者:河北大学-徐小波,转载请注明原文链接:https://www.cnblogs.com/xuxiaobo/p/18961500

浙公网安备 33010602011771号