目录

前言

正文


前言

WebRTC除了通过API接口控制某些参数外,还能通过SDP信息进行音视频参数的控制,特别是在进行JS SDK开发时,这种情况是非常普遍的。

《WebRTC工作原理精讲》系列-总览

正文

本文以WebRTC的M76版本为例进行介绍。

首先来看一段SDP信息(只包含音频信息):

v=0
o=- 8275923203002055919 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS 6a6d1509-69e0-4fc2-b447-5b4391f9ad69_STS
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 9 102 0 8 105 13 110 113 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:QLMT
a=ice-pwd:V0cOn+fDmd49138wk42548PU
a=ice-options:trickle
a=fingerprint:sha-256 6B:CD:36:F6:8D:F1:CB:E7:44:0A:E9:3B:D4:A1:A4:F3:7F:93:99:4C:EF:4A:3A:A2:91:6A:7F:57:50:49:04:1B
a=setup:actpass
a=mid:audio
b=AS:64
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=sendonly
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 nack
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1;maxaveragebitrate=64000

说到音频码率控制,我们可以关注一下参数 “b=AS” ,WebRTC底层就是通过解析 b=AS 参数来设置音频码率的,当然也可以不设置,这样会使用默认值,一般默认值是32kbps。

SDP信息传递到底层时,会被反序列化,这时就会用到一个方法:

// src/pc/webrtc_sdp.h // Deserializes the passed in SDP string to a JsepSessionDescription. // message - SDP string to be Deserialized. // jdesc - The JsepSessionDescription deserialized from the SDP string. // error - The detail error information when parsing fails. // return - true on success, false on failure. // 解析SDP信息的方法 bool SdpDeserialize(const std::string& message,
                    JsepSessionDescription* jdesc,
                    SdpParseError* error);

方法的具体实现:

bool SdpDeserialize(const std::string& message,
                    JsepSessionDescription* jdesc,
                    SdpParseError* error) {
  std::string session_id;
  std::string session_version; TransportDescription session_td("", "");
  RtpHeaderExtensions session_extmaps;
  rtc::SocketAddress session_connection_addr; auto desc = absl::make_unique<cricket::SessionDescription>(); size_t current_pos = 0; // Session Description if (!ParseSessionDescription(message, &current_pos, &session_id,
                               &session_version, &session_td, &session_extmaps,
                               &session_connection_addr, desc.get(), error)) { return false;
  } // 具体媒体信息解析方法,接下来会具体看它的内部实现和解析过程 std::vector<std::unique_ptr<JsepIceCandidate>> candidates; if (!ParseMediaDescription(message, session_td, session_extmaps,