WebRTC(二)RTCPeerConnection

129 阅读2分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 5 天

书接上文:WebRTC(一)MediaStream

在上文中,我们已经从MediaStream拿到了音频流和视频流,但自己自娱自乐看自己直播可没什么劲,我们要把画面声音推给其他人看

这里就需要我们跟其他人建立连接,这就需要今天的RTCPeerConnection

一般来说,为了保证不同浏览器的兼容问题,我们需要引入adapter来保证兼容性

CDN:

webrtc.github.io/adapter/ada… lf9-cdn-tos.bytecdntp.com/cdn/expire-…

先看示例代码吧:

这个页面上有三个按钮:开始 call 挂断

我们一个一个看

开始按钮和上文几乎一样,先拿到本地的媒体流

然后推送给video标签让他播放

核心代码:

function startAction() {
  startButton.disabled = true;
  navigator.mediaDevices.getUserMedia(mediaStreamConstraints)
    .then(gotLocalMediaStream).catch(handleLocalMediaStreamError);
}

call按钮的工作简单地说就是把流推给远端,具体的介绍看下面代码的注释吧

核心代码:

function callAction() {
  callButton.disabled = true;
  hangupButton.disabled = false;

  console.log('Starting call.');

  // 获取本地流的轨道,localStream就是前面获取到的媒体流
  const videoTracks = localStream.getVideoTracks();
  const audioTracks = localStream.getAudioTracks();
  
  const servers = null; 

  // 创建本地peer连接对象
  localPeerConnection = new RTCPeerConnection(servers);
  console.log('Created local peer connection object localPeerConnection.');

  //icecandidate事件的介绍:
  //https://developer.mozilla.org/zh-CN/docs/Web/API/RTCPeerConnection/icecandidate_event
  localPeerConnection.addEventListener('icecandidate', handleConnection);
  localPeerConnection.addEventListener(
    'iceconnectionstatechange', handleConnectionChange);

  remotePeerConnection = new RTCPeerConnection(servers);
  console.log('Created remote peer connection object remotePeerConnection.');

  remotePeerConnection.addEventListener('icecandidate', handleConnection);
  remotePeerConnection.addEventListener(
    'iceconnectionstatechange', handleConnectionChange);
  remotePeerConnection.addEventListener('addstream', gotRemoteMediaStream);

  // 添加本地流并创建连接
  localPeerConnection.addStream(localStream);
  console.log('Added local stream to localPeerConnection.');

  console.log('localPeerConnection createOffer start.');
  localPeerConnection.createOffer(offerOptions)
    .then(createdOffer).catch(setSessionDescriptionError);
}

这里有一个需要注意的点,不知道hxd们知不知道,这里ICE并不是冰,他的意思是交互式连接建立,可以把他理解为是整合了 STUN 和 TURN的框架。

ICE用于确定可用于双端通信的传输地址对

再建立ice连接后,以event形式传输,从event中取出peerConnection对象和iceCandidate对象。

RTCIceCandidate用于描述WebRTC 能够与远程设备通信所需的协议和路由

function handleConnection(event) {
  const peerConnection = event.target;
  const iceCandidate = event.candidate;

  if (iceCandidate) {
    const newIceCandidate = new RTCIceCandidate(iceCandidate);
    const otherPeer = getOtherPeer(peerConnection);

    otherPeer.addIceCandidate(newIceCandidate)
      .then(() => {}).catch((error) => {});

  }
}