WebRTC实现多人视频聊天

写在前面

实现房间内人员的视频聊天,由于并未很完善,所以需要严格按照步骤来,当然基于此完善,就是时间的问题了。


架构

整个设计架构如下:

多人视频聊天

图片来自于参考博文。我使用的是第一种Mesh 架构,无需任何流媒体服务器,直接利用成熟的WebRTC 协议。该体系架构基于从每一个发送者创建多个一对一 的数据流到每一个接收端。客户端创建多个对等连接,连接数量基于房间内的其它成员数。


应用程序实现

基础实现如下:

多人视频聊天交互设计

第1步:将 注册用户身份信息和表明想加入房间号和连接建立成功放在一起是为了在连接一建立成功就向信令服务器发送信息。

第2步:客户端发起多个连接创建请求(即视频通话请求)。

第3步:响应客户端的多个连接创建请求,返回房间内成员信息;排除自己以及以及发起了多个连接创建请求的成员。

第4步:客户端创建多个连接,并将包含多个连接的offer和成员信息的消息发送给信令服务器。

第5步:注册onIceCandidate 事件,发送 单个candidate 给信令服务器。

第6步:接收信令服务器的单个 answer 消息,设置为对应用户连接的desc。

第7步:接收信令服务器的单个 candidate 消息,添加到对应用户连接的iceCandidate。


客户端

客户端使用adapter.js , demo的代码来自于开源的webrtc-samples,基于其中的 peerconnection 内容修改而成的。效果如下图:

多人视频聊天效果截图

注:其中两个客户端采用的是虚拟摄像头

关于客户端更详细的设计参考推荐博文。


信令服务器设计

信令服务器的作用在于转发各个sdp 给对应的客户端,协助对等连接的建立。

如果需要实现多人视频聊天,其中的逻辑则更为复杂。通过websockets 来实现客户端与信令服务器之间的消息传输,并且设置了多种消息格式,具体格式如下:

const requestType = {
    // 用户认证
    USER_IDENTITY: 'USER_IDENTITY',
    // type 为 offer 的 desc
    SDP_OFFER: 'SDP_OFFER',
    // type 为 answer 的 desc
    SDP_ANSWER: 'SDP_ANSWER',
    // candidate
    SDP_CANDIDATE: 'SDP_CANDIDATE',
    // 创建多个连接请求
    CLIENT_MULTIPLY_CONNECTION_CREATEQUE: 'CLIENT_MULTIPLY_CONNECTION_CREATEQUE',
    // 房间成员消息响应
    SERVER_CALLEESRESP: 'SERVER_CALLEESRESP'
};

关于信令服务器更详细的设计参考推荐博文。


源码

源码地址,以下流程可能不适用,以源码中的 readme 为准,代码写的有点晦涩,欢迎哥哥们提意见 /鲜花。

  1. 启动信令服务器,修改前端代码中的websockets 地址,部署启动前端代码
  2. 客户端A 访问地址 …/index.html?name=clientA&roomId=001, 点击start
  3. 客户端A 访问地址 …/index.html?name=clientB&roomId=001,点击start
  4. 客户端C 访问地址 …/index.html?name=clientC&roomId=001,点击start
  5. 客户端D 访问地址 …/index.html?name=clientD&roomId=001,点击start, 并点击Call。
  6. 整个完整的流程如上。

注:以上流程能够得到保证,其它流程我的代码均未考虑。并且执行一次以上流程可能需要重启信令服务器,重新执行整个流程。


推荐博文


WebRTC实现多人视频聊天之客户端设计
WebRTC实现多人视频聊天之信令服务器设计


参考博文


https://blog.csdn.net/gupar/article/details/53101435 基于webrtc 多人音视频的研究

如果你觉得我的文章对你有所帮助的话,欢迎关注我的公众号。赞!我与风来
认认真真学习,做思想的产出者,而不是文字的搬运工。错误之处,还望指出!

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
WebRTC实现多人语音聊天代码比较复杂,需要涉及到媒体流处理、信令服务器等方面的代码。下面是WebRTC实现多人语音聊天的大致代码流程: 1. 创建本地媒体流 ```javascript // 获取本地媒体流 navigator.mediaDevices.getUserMedia({ audio: true, video: true }) .then(function (stream) { // 成功获取媒体流 // 在页面中显示本地音视频 var localVideo = document.querySelector('#localVideo'); localVideo.srcObject = stream; // 保存媒体流 localStream = stream; }) .catch(function (error) { // 获取媒体流失败 console.error('getUserMedia error:', error); }); ``` 2. 媒体流处理 ```javascript // 创建PeerConnection对象 var pc = new RTCPeerConnection(configuration); // 将本地媒体流添加到PeerConnection中 localStream.getTracks().forEach(function (track) { pc.addTrack(track, localStream); }); // 接收远程媒体流 pc.ontrack = function (event) { // 将远程音视频添加到页面中 var remoteVideo = document.querySelector('#remoteVideo'); remoteVideo.srcObject = event.streams[0]; }; // 处理ICE候选项 pc.onicecandidate = function (event) { if (event.candidate) { // 发送ICE候选项到远程端 sendIceCandidate(event.candidate); } }; // 创建SDP offer pc.createOffer(function (offer) { // 设置本地SDP pc.setLocalDescription(offer); // 发送SDP offer到远程端 sendSdp(offer); }, function (error) { console.error('createOffer error:', error); }); ``` 3. 媒体流传输 ```javascript // 创建WebSocket连接 var ws = new WebSocket(url); // 发送SDP offer或answer到远程端 function sendSdp(sdp) { ws.send(JSON.stringify({ type: 'sdp', sdp: sdp })); } // 发送ICE候选项到远程端 function sendIceCandidate(candidate) { ws.send(JSON.stringify({ type: 'ice', candidate: candidate })); } // 处理远程SDP function handleRemoteSdp(sdp) { // 设置远程SDP pc.setRemoteDescription(new RTCSessionDescription(sdp)); // 创建SDP answer pc.createAnswer(function (answer) { // 设置本地SDP pc.setLocalDescription(answer); // 发送SDP answer到远程端 sendSdp(answer); }, function (error) { console.error('createAnswer error:', error); }); } // 处理远程ICE候选项 function handleRemoteIceCandidate(candidate) { // 添加远程ICE候选项 pc.addIceCandidate(new RTCIceCandidate(candidate)); } ``` 需要注意的是,WebRTC实现多人语音聊天还需要使用信令服务器,用于传输SDP offer和answer、ICE候选项等消息。此外,需要考虑多人通信的协调、流量控制、音视频质量等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值