乐趣区

WebRTC建立连接过程介绍

概述

因为最近在做 WebRTC 相关的项目,为了对 WebRTC 建立连接和传输有更深入的了解,还是写一篇文章介绍一下。最开始是从 WebRTC 的官方文档入手,当然还有里面的 samples。因为通信的过程还没有涉及到,先从连接过程做切入。

SDP

SDP 是 Session Description Protocol,从文档里面可以看到,是 p2p 连接的标准协议,里面包括了 codec、地址和音视频的时间信息。这里面 SDP 不是通信协议,通信协议一般是 RTP 或者 SRTP(安全的 RTP),但是一般都会需要 SDP 来先进行连接建立。

Session description

session 是都过一行一个 field 的方式来描述的,格式是:

<character>=<value>

其中 <character> 是一个大小写敏感的字母,<value> 是一个结构化的字符串,通常是 utf- 8 编码的,等号后面不能直接跟空格。
SDP 消息里面有 3 个主要的块,session, timingmedia描述。每个消息都包含了多个 timingmedia描述。每一行 field 顺序是固定的,*= 代表是可选的,每个含义如下:

**Session description**
    v=  (protocol version number, currently only 0)
    o=  (originator and session identifier : username, id, version number, network address)
    s=  (session name : mandatory with at least one UTF-8-encoded character)
    i=\* (session title or short information)
    u=\* (URI of description)
    e=\* (zero or more email address with optional name of contacts)
    p=\* (zero or more phone number with optional name of contacts)
    c=\* (connection information—not required if included in all media)
    b=\* (zero or more bandwidth information lines)
    _One or more **Time descriptions** ("t=" and "r=" lines; see below)_
    z=\* (time zone adjustments)
    k=\* (encryption key)
    a=\* (zero or more session attribute lines)
    _Zero or more **Media descriptions** (each one starting by an "m=" line; see below)_
**Time description** (mandatory)
    t=  (time the session is active)
    r=\* (zero or more repeat times)
**Media description** (if present)
    m=  (media name and transport address)
    i=\* (media title or information field)
    c=\* (connection information — optional if included at session level)
    b=\* (zero or more bandwidth information lines)
    k=\* (encryption key)
    a=\* (zero or more media attribute lines — overriding the Session attribute lines)

一个常见的 SDP 消息是这样的:

   v=0
   o=alice 2890844526 2890844526 IN IP4 host.anywhere.com
   s=
   c=IN IP4 host.anywhere.com
   t=0 0
   m=audio 49170 RTP/AVP 0
   a=rtpmap:0 PCMU/8000
   m=video 51372 RTP/AVP 31
   a=rtpmap:31 H261/90000
   m=video 53000 RTP/AVP 32
   a=rtpmap:32 MPV/90000

RTCPeerConnection

所有连接都是从 RTCPeerConnection 这个对象开始,他继承自 EventTarget,拥有一些增加事件监听的能力。

Caller 打电话者(推流方 pc1)

  • 创建 RTCPeerConnection 对象,以及准备需要推的 Stream 对象
pc1 = new RTCPeerConnection(servers);
localStream.getTracks().forEach((track) => {pc1.addTrack(track, localStream);
});
  • 创建一个 Offer,并设置为自己的 LocalDescription
const offerOptions = {
  offerToReceiveAudio: 1,
  offerToReceiveVideo: 1
};
const offer = await pc1.createOffer(offerOptions);
pc1.setLocalDescription(offer);
  • 拿到 pc2 的 Anwser,并设置为自己的 RemoteDescription
pc1.setRemoteDescription(answer);

Callee 接电话者(播放方 pc2)

  • 拿到 pc1 的 Offer,设置为自己的 RemoteDescription
pc2.setLocalDescription(desc);
  • 创建一个 Anwser,设置为自己的 LocalDescription
const answer =pc2.createAnswer();
pc2.setLocalDescription(answer);
退出移动版