WebRTC项目一对一视频

embedded/2024/11/9 5:13:04/

开发步骤


1.客户端显示界面
2.打开摄像头并显示到页面
3.websocket连接
4.join、new-peer、resp-join信令实现
5.leave、peer-leave信令实现
6.offer、answer、candidate信令实现
7.综合调试和完善

1.客户端显示界面

步骤:创建html页面
主要是input、button、video控件的布局。

2.打开摄像头并显示到页面

function openLocalStream() {//初始化本地码流navigator.mediaDevices.getUserMedia({ //初始化本地码流信息audio: true,video: { width: 640, height: 480 }}).then(function (stream) { // 打开本地码流console.log('Open local stream');localVideo.srcObject = stream;localStream = stream;}).catch(function (e) { //错误cbalert("getUserMedia() error: " + e.name);});
}
document.getElementById('joinBtn').onclick = function () {console.log("加入按钮被点击");openLocalStream();
};function closeLocalStream() {if (localStream) {localStream.getTracks().forEach(track => {track.stop();});localStream = null;localVideo.srcObject = null;}
}
document.getElementById('leaveBtn').onclick = function () {console.log("离开按钮被点击");closeLocalStream();
};

3.websocket连接

 封装websocket 

class RTCEngine {constructor(wsUrl) {this.init(wsUrl);}init(wsUrl) {this.wsUrl = wsUrl;this.signaling = null;}onOpen() {console.log("websocket open");}onMessage(event) {console.log("onMessage: " + event.data);}onError(event) {console.log("onError: " + event.data);}onClose(event) {console.log("onClose -> code: " + event.code + ", reason: " + event.reason);}createWebSocket() {this.signaling = new WebSocket(this.wsUrl);this.signaling.onopen = () => this.onOpen();this.signaling.onmessage = ev => this.onMessage(ev);this.signaling.onerror = ev => this.onError(ev);this.signaling.onclose = ev => this.onClose(ev);}
}import RTCEngine from './RTCEngineWS.js';
const rtce = new RTCEngine("ws://192.168.1.25:8099");
rtce.createWebSocket();

4.join、new-peer、resp-join overload信令设计

信令设计:
RTCEngineWS.js  websocket封装类负责接收,发送消息以及连接状态管理。
signal.js   信令的设计集合
main.js 主逻辑
思路:(1)点击加入开妞;(2)响应加入按钮事件;(3)将join发送给服务器;(4)服务器 根据当前房间的人数
做处理,如果房间已经有人则通知房间里面的人有新人加入(newpeer),并通知自己房间里面是什么人(resp-join)。如果房间存在2个 则返回房间号人数已满


var jsonMsg = {'cmd': 'join','roomId': roomId,'uid': localUserId,
};
var jsonMsg = {'cmd': 'resp‐join','remoteUid': remoteUid
};
var jsonMsg = {'cmd': 'new‐peer','remoteUid': uid
};
var jsonMsg = {'cmd': 'overload',
};

5.leave、peer-leave 信令实现

思路:(1)点击离开按钮;(2)响应离开按钮事件;(3)将leave发送给服务器;(4)服
务器处理leave,将发送者删除并通知房间(peer leave)的其他人;(5)房间的其他人在客户
端响应peer leave事件。

var jsonMsg = {'cmd': 'leave','roomId': roomId,'uid': localUserId,
};
var jsonMsg = {'cmd': 'peer‐leave','remoteUid': uid
};
var jsonMsg = {'cmd': 'peer‐leave','remoteUid': uid
}; 

 6.offer、answer、candidate信令实现

 思路:
(1C)收到newpeer (handleRemoteNewPeer处理),作为发起者创建RTCPeerConnection,绑定事件响应函数,加入本地流;
(2C)创建offer sdp,设置本地sdp,并将offer sdp发送到服务器;
(3SSS)服务器收到offer sdp 转发给指定的remoteClient;
(4C)接收者收到offer,也创建RTCPeerConnection,绑定事件响应函数,加入本地流;
(5C)接收者设置远程sdp,并创建answer sdp,然后设置本地sdp并将answer sdp发送到服务器;
(6SSS)服务器收到answer sdp 转发给指定的remoteClient;
(7C)发起者收到answer sdp,则设置远程sdp;
(8C)发起者和接收者都收到ontrack回调事件,获取到对方码流的对象句柄;

(9)发起者和接收者都开始请求打洞,通过onIceCandidate获取到打洞信息(candidate)并发送给对方
(10)如果P2P能成功则进行P2P通话,如果P2P不成功则进行中继转发通话。

offer、answer、candidate分别如下
var jsonMsg = {'cmd': SIGNAL_TYPE_OFFER,'roomId': roomId,'uid': localUserId,'remoteUid': remoteUserId,'msg': JSON.stringify(session)
};
var jsonMsg = {'cmd': SIGNAL_TYPE_ANSWER,'roomId': roomId,'uid': localUserId,'remoteUid': remoteUserId,'msg': JSON.stringify(session)
};
var jsonMsg = {'cmd': SIGNAL_TYPE_CANDIDATE,'roomId': roomId,'uid': localUserId,'remoteUid': remoteUserId,'msg': JSON.stringify(event.candidate)
};

 

7.综合调试和完善

正常退出和关闭工作

思路:

(1)点击离开时,要将本地摄像头和麦克风关闭; 要将RTCPeerConnection关闭(close);

(2)检测到客户端退出时,服务器再次检测该客户端是否已经退出房间。

总结

信令服务器设计,主要是转发客户端发来的消息到对端,根据类型进行转发。


 

 学习资料分享

0voice · GitHub


http://www.ppmy.cn/embedded/136086.html

相关文章

O-RAN Fronthual CU/Sync/Mgmt 平面和协议栈

O-RAN Fronthual CU/Sync/Mgmt 平面和协议栈 O-RAN Fronthual CU/Sync/Mgmt 平面和协议栈O-RAN前端O-RAN 前传平面C-Plane(控制平面):控制平面消息定义数据传输、波束形成等所需的调度、协调。U-Plane(用户平面)&#…

深入探索哈尔滨二级等保下的负载均衡SLB及其核心算法

在当今的信息化时代,网络安全和数据保护显得尤为重要。特别是在获得二级等级保护认证(简称“二级等保”)的企业或机构中,确保网络系统的高可用性和安全性更是至关重要。负载均衡(Server Load Balancer,简称…

CST汽车天线仿真(双向混合求解)

CST从2018版本开始具有双向混合求解,到2019版已经通用微波工作室的各个求解器之间的双向混合。具体的混合对象如下图: 对天线的安装和耦合仿真,意味着对复杂结构(天线)和电大尺寸环境(安装平台,…

css:基础

前言 我们之前其实也可以写出一个看起来算是一个网页的网页,为什么我们还要学css? CSS(Cascading Style Sheets)也叫层叠样式表,是负责美化的,我们之前说html就是一个骨架,css就可以用来美化网…

SQL server增删改查语句和实例

在 SQL Server 中,增删改查操作分别对应 INSERT、DELETE、UPDATE 和 SELECT 语句。以下是具体介绍及实例: 一、插入数据(INSERT) 语法: INSERT INTO table_name (column1, column2, column3,...) VALUES (value1, val…

[云讷科技]DASA数字孪生机器人概念

DASA数字孪生机器人概念 我们在 虚幻引擎 (UE) 的帮助下在 DASA 中建立了数字孪生机器人概念。 UE 是 Epic Games 开发的 3D 计算机图形游戏引擎,广泛应用于视频游戏、电影和电视。我们在 DASA 中利用强大的 UE 功能来实现外观逼真的数字机器人,并允许与…

2. 多线程带来的风险—线程安全

一、线程安全问题 1. 观察线程不安全 class Demo{// 此处定义⼀个 int 类型的变量private static int count 0;public static void main(String[] args) throws InterruptedException {Thread t1 new Thread(() -> {// 对 count 变量进⾏⾃增 5w 次 for (int i 0; i &l…

区间数位和

额 这题居然还卡了一会儿 一个是要用另一个变量暂存循环变量i 另一个是while里面不能写(num%10>0) 得写num>0 因为会遇到那种10的倍数… #include <bits/stdc.h> using namespace std;/* 完成下面的函数 */ int getRangeDigitSum(int a, int b) {int sum 0;…