概述
因为最近在做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, timing 和 media描述。每个消息都包含了多个timing和media描述。每一行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);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。