Webrtc 视频通讯 入门体验

2 篇文章 0 订阅

Webrtc 视频通讯 入门体验


WebRTC,名称源自网页即时通信,它于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联盟的W3C推荐标准, 解决了网页浏览器进行实时语音对话或视频对话的问题。

转载请注明出处:https://blog.csdn.net/a1151879477/article/details/97363772

开发环境

  • 最新版本的谷歌浏览器, 现在为:75.0.3770.142
  • 安卓手机一部, 安装最新版本的谷歌浏览器
  • 外网服务器一台,
  • websocket部分使用了swoft php框架

参考链接
https://www.cnblogs.com/fangkm/p/4364553.html 这篇文章里, 讲述了浏览器在实现net穿透中的具体流程。

​​https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection 这个是webrtc的API文档

第一篇文章里最重要的一张流程图:
webrtc交互流程

  • 第一步: 创建Connection对象, 这个是webrtc Api中重要的对象之一
/*
 * 创建 connection对象
 */
function createPeerConnection() {
  var mediaConstraints = {};
  return new RTCPeerConnection({
      iceServers: [
        {"urls":["stun:stun.l.google.com:19302"]}
      ]
  }, mediaConstraints);
}
    
var localClient = createPeerConnection();
var answerClient = createPeerConnection();

第二步: 获取摄像头,麦克风流,获取后, 回显, 并且像Connection对象添加流

navigator.mediaDevices.getUserMedia(mediaConstraints).then(localStream => {
 let localVideo = document.getElementById("local_video");
  //设置回显
  localVideo.srcObject = localStream;
  localVideo.onloadedmetadata = function (e) {
      localVideo.play();
  };
  localVideo.volume = 0.0;
  
  console.log(localStream.getTracks());
  localStream.getTracks().forEach(track => localClient.addTrack(track, localStream));
});

第三步: 创建Session, 并将offer发送给远程用户

localClient.createOffer()
                .then(offer => {
                    localClient.setLocalDescription(offer)
                        .then(() => {
                            // 将offer 发送给被叫
                            ws.send('user.offer:' + JSON.stringify({
                                user_id: getUserId(),
                                connectUserId: $this.data('id'),
                                offer: offer
                            }))
                        })
                })

第四步(被叫端):将受到的offer 设置进 remoteDescription, 生成被叫的answer,将被叫生成的answer 发送给主叫

const sessionDescription = new RTCSessionDescription(offer);
//由于受到的格式为json 需要转变为 RTCSessionDescription后 才能设置成功
answerClient.setRemoteDescription(sessionDescription);
answerClient.createAnswer()
    .then(answer => {
        answerClient.setLocalDescription(answer)
            .then(() => {
                //发送给主叫 answer
                ws.send('user.answer:' + JSON.stringify({
                    user_id: getUserId(),
                    answer: answer,
                    connectUserId: msg.connectUserId
                }))
            })
    });

第五步(主叫):受到被叫的offer 以同样的操作设置 remoteDescription

localClient.setRemoteDescription(new RTCSessionDescription(answer));

第六步(主叫):这时主叫会触发 onicecandidate事件, 这里会自动获取自己的服务器ip端口等信息, 需要将这些信息发送给被叫

answerClient.onicecandidate = function (e) {
    if (e.candidate) {
        ws.send('user.candidate:', JSON.stringify({
            user_id: getUserId(),
            candidateType: 'answerClient',
            connectUserId: remoteUserId,
            candidate: e.candidate
        }))
    }
    console.log('answerClient is on icecandidate');
};

第七步(被叫):被叫收到candidate, 调用 addIceCandidate() 将 candidate记录下, 也会触发被叫的 onicecandidate 事件, 需要进行同样的动作发送给主叫, 主叫同样调用 addIceCandidate 方法记录信息, 这时如果双方网络环境能够穿透的时候就会调用ontrack 方法, 在接受到的事件event 中, 将steam流添加到video标签里就可了。

// 调用addIceCandidate
if (candidate.candidateType === 'officeClient') {
    answerClient.addIceCandidate(candidate)
} else {
    localClient.addIceCandidate(candidate)
}
answerClient.onicecandidate = function (e) {
    if (e.candidate) {
        ws.send('user.candidate:', JSON.stringify({
            user_id: getUserId(),
            candidateType: 'answerClient',
            connectUserId: remoteUserId,
            candidate: e.candidate
        }))


    }
    console.log('answerClient is on icecandidate');
};


localClient.onicecandidate = function (e) {
   if (e.candidate) {
       ws.send('user.candidate:', JSON.stringify({
           user_id: getUserId(),
           candidateType: 'offerClient',
           connectUserId: remoteUserId,
           candidate: e.candidate
       }))
   }
   console.log('answerClient is on icecandidate');
};

answerClient.ontrack = function (e) {
    remoteVideo.srcObject = e.streams[0];
};

localClient.ontrack = function(e){
    remoteVideo.srcObject = e.streams[0];
};

发现的问题
有些时候会穿透失败
需要点两下对方才会显示画面, 自己这边没有对方的画面,目前没找到原因还需要继续完善

github地址: https://github.com/meiyoufengzhengdexian/webrtc-demo

评论 2 您还未登录,请先 登录 后发表或查看评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页

打赏作者

没有风筝的线

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值