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

 

posted @ 2025-07-02 15:06  河北大学-徐小波  阅读(265)  评论(0)    收藏  举报