SDP — 什么是SDP,会话描述格式及在WebRTC中的作用

作者: IT Sectr 发布日期: 2026-06-03 阅读时间: 12 分钟

SDP(会话描述协议)是一种用于描述多媒体会话的文本格式,旨在协商参与者之间的连接参数。根据IETF RFC 8866(2021)SDP定义了媒体流、编解码器、传输地址和其他参数的描述结构,而不传输媒体数据本身。该协议已成为WebRTC的关键组件,在建立点对点连接之前确保浏览器和移动应用程序之间的信息交换。

要点

  • SDP — 用于描述多媒体会话的文本协议,不传输媒体数据,仅传输其参数。
  • 格式基于type=value形式的行,每行描述会话的一个参数。
  • WebRTC在建立连接之前使用SDP在参与者之间交换Offer和Answer。
  • 会话字段包括媒体类型、编解码器、端口、传输协议和安全参数。
  • SDP不绑定到特定的传输协议,可以通过HTTP、WebSocket或SIP传输。

什么是SDP(会话描述协议)?

SDP — 是一种应用层协议,旨在以文本格式描述多媒体会话的参数。它是在IETF的MMUSIC(多方多媒体会话控制)工作组框架内开发的,并于1998年在RFC 2327中首次标准化。2021年发布了当前规范RFC 8866,取代了之前的版本RFC 4566。

SDP的主要任务是为会话参与者提供建立连接所需的所有信息:将传输哪些媒体流,支持哪些编解码器,通过哪些网络地址和端口进行传输。SDP不传输媒体数据本身,只描述应如何组织连接。

根据IETF RFC 8866,SDP格式由一组行组成,每行以单字母类型开头,后跟等号和值。例如,行m=audio 5004 RTP/AVP 0表示会话包括端口5004上的音频流,使用RTP/AVP传输协议和PCMU编解码器(类型0)。

SDP的历史和标准化

SDP的第一个版本于1998年4月在RFC 2327中发布,是MMUSIC小组工作的成果。该协议最初是为在Mbone(组播骨干网)框架内宣布组播会话而创建的。随着VoIP和视频会议的发展,SDP的应用范围不断扩大,2006年发布了更新的规范RFC 4566。

SDP使用的真正突破发生在2011年WebRTC的出现。Google将SDP作为其浏览器实时通信框架中媒体会话描述的主要机制。从那时起,SDP成为每个WebRTC实现的强制性组件——从浏览器到iOS和Android上的移动应用程序。

2021年,IETF工作组发布了RFC 8866——取代RFC 4566的当前SDP规范。更新版本明确了ICE(交互式连接建立)的处理,支持DTLS(数据报传输层安全),并扩展了组会话描述的能力。

SDP与传输协议的区别

SDP与传输协议的根本区别在于它不参与数据传输。它仅执行描述功能——类似于多媒体文件的元数据。当RTP(实时传输协议)传输音频和视频数据包,RTCP控制传输质量时,SDP仅指示使用哪些编解码器和端口。

来自Web开发的类比:SDP是描述页面结构的HTML标记,RTP是图像和文本本身。没有SDP,会话参与者不知道如何相互连接,即使网络连接已经建立。NAT穿越机制(ICE)也依赖SDP来传输关于网络候选者的信息。

SDP的结构是怎样的

SDP的结构组织为一系列文本行,每行遵循type=value格式。单字母类型确定行的目的,值包含相应的值。所有行由CRLF换行符分隔。

标准RFC 8866定义了多个必填和可选字段。必填字段包括协议版本(v=)、会话名称(s=)、会话开始和结束时间(t=)。其他字段是可选的,但对于WebRTC会话,还需要媒体描述(m=)、属性(a=)和网络信息(c=)。

text
v=0
o=- 46116397 2 IN IP4 192.168.1.100
s=-
t=0 0
a=group:BUNDLE audio video
m=audio 5004 RTP/SAVPF 111 103 104
c=IN IP4 192.168.1.100
a=rtpmap:111 opus/48000/2
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
m=video 5006 RTP/SAVPF 96 97
a=rtpmap:96 VP8/90000
a=rtpmap:97 H264/90000

上面的示例展示了一个典型的WebRTC会话的SDP片段。行v=0表示协议版本。字段o=包含会话所有者的标识符及其版本。行s=-设置会话名称(连字符表示名称为空)。字段t=0 0表示会话没有时间限制。

字段a=group:BUNDLE audio video是一个属性,将多个媒体流分组到一个传输通道中。BUNDLE机制允许通过单个连接传输音频和视频来节省网络资源。这对于带宽有限的移动设备尤其重要。

SDP的必填字段

规范RFC 8866定义了一组必填和可选字段。必填字段包括v=(版本)、s=(会话名称)和t=(时间)。字段o=(所有者),虽然根据RFC并非严格必填,但在实际实现中几乎总是存在。

字段用途示例
v=SDP协议版本v=0
o=会话所有者和标识符o=- 46116397 2 IN IP4 192.168.1.100
s=会话名称s=Video Conference
t=开始和结束时间t=0 0
m=媒体流描述m=audio 5004 RTP/SAVPF 111
c=网络信息c=IN IP4 192.168.1.100
a=会话或媒体属性a=rtpmap:111 opus/48000/2

m=(媒体)字段是最重要的字段之一。它描述特定的媒体流,包含媒体类型(audio、video、text、application)、端口、传输协议和支持的编解码器列表。在WebRTC中,最常用的类型是audio和video,使用RTP/SAVPF(安全音频/视频配置文件及反馈)或UDP/TLS/RTP/SAVPF传输协议。

a=(属性)字段是最灵活和可扩展的。它可以包含rtpmap(将编解码器编号映射到名称)、fmtp(编解码器参数)、fingerprint(DTLS密钥指纹)、ice-ufrag和ice-pwd(ICE凭据)以及许多其他属性。正是通过属性,SDP支持现代安全机制和NAT穿越。

SDP在WebRTC中如何工作

在WebRTC架构中,SDP扮演着信令协议的角色,用于描述和协商两个参与者之间的媒体会话参数。SDP本身不定义这些描述的传输机制——这一任务由信令通道解决,开发人员通过WebSocket、HTTP或其他协议独立实现。

过程从发起者(呼叫者)创建SDP提议——Offer开始。为此,浏览器在RTCPeerConnection对象上调用createOffer()方法。生成的SDP描述包含发起方的所有会话参数:支持的编解码器、网络地址、ICE候选者和安全要求。

js
const configuration = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] };
const pc = new RTCPeerConnection(configuration);

// 在Android上创建SDP提议
const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: true });
stream.getTracks().forEach(track => pc.addTrack(track, stream));

// 将SDP字符串发送到远程对等方
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);

// Send SDP to remote peer via signaling channel
sendViaSignaling({ type: 'offer', sdp: offer.sdp });

创建Offer并通过setLocalDescription()设置本地描述后,发起者通过信令通道将SDP字符串发送给远程参与者。远程参与者收到SDP Offer后,创建SDP应答——Answer并将其发回。这种交换称为信令交换,是在建立点对点连接之前的强制性步骤。

根据W3C WebRTC规范,SDP交换应在ICE候选者交换开始之前进行。在实践中,许多实现使用ICE trickle机制与SDP并行发送ICE候选者。这缩短了连接建立时间,特别是对于高延迟的移动网络。

ICE在SDP中的作用

ICE(交互式连接建立)——是一种使用SDP属性传输关于网络候选者信息的机制。ICE候选者描述了可能的连接路径:host(本地地址)、srflx(通过STUN获取的NAT后地址)和relay(TURN服务器地址)。

在SDP中,ICE候选者通过a=candidate:属性以及用于ICE流量认证的ice-ufrag和ice-pwd字段传输。每个候选者包括传输协议(UDP、TCP)、IP地址、端口和优先级。成功的连接通过第一个通过连接性测试的候选者建立。ICE restart机制允许在网络更改时更新连接。

对于移动应用程序,ICE候选者尤其重要,因为设备通常位于NAT或公司防火墙之后。ICE机制即使在复杂的网络条件下也能找到工作路径,SDP作为这些信息的传输容器。

WebRTC中SDP的安全性

WebRTC中的SDP必须包含安全属性,特别是DTLS指纹(fingerprint)和SRTP参数。字段a=fingerprint:sha-256包含用于媒体流认证和加密的DTLS证书指纹。没有此属性,WebRTC连接将无法建立。

额外的安全机制包括a=setup:属性,用于确定DTLS握手的角色(active、passive、actpass),以及用于服务器端简化ICE实现的a=ice-lite:。所有这些参数都在SDP内部传输,并在开始传输媒体数据之前由双方检查。

SDP类型:Offer和Answer

在WebRTC模型中,存在两种类型的SDP消息:Offer(提议)和Answer(应答)。Offer由连接发起者创建,包含所需媒体会话的完整描述。Answer由远程参与者创建以响应Offer,包含其功能并考虑提议施加的限制。

Offer和Answer之间的主要区别在于属性的语义。Offer列出了发起者可以提供的所有支持的编解码器、传输协议和网络地址。Answer选择了远程方支持的这些功能的子集。例如,如果Offer提供opus、ISAC和PCMU,Answer可以选择仅opus作为最优先的编解码器。

交换过程由W3C WebRTC规范管理,包括RTCPeerConnection的多个状态。通过createOffer()创建Offer并将其设置为本地描述后,连接进入have-local-offer状态。收到Answer并通过setRemoteDescription()将其设置为远程描述后,连接进入stable状态——准备进行媒体传输的最终状态。

移动SDK中的SDP使用

用于WebRTC的移动SDK——Android版Google WebRTC和iOS版WebRTC.framework——完全支持通过Offer和Answer进行SDP交换。在Android上,使用PeerConnection类及其createOffer()方法创建Offer,类似于浏览器API。获取的SDP描述作为字符串通过信令通道传输。

iOS上,与SDP的工作通过WebRTC框架的RTCSessionDescription类进行。初始化时指定类型(RTCSdpTypeOffer或RTCSdpTypeAnswer)和SDP字符串。平台自动解析SDP并根据传输的参数配置连接。

kotlin
val configuration = PeerConnection.RTCConfiguration(List())
val peerConnection = factory.createPeerConnection(configuration, object : PeerConnection.Observer {
    override fun onIceCandidate(candidate: IceCandidate) { }
})

// Create SDP Offer on Android
peerConnection.createOffer(object : SdpObserver {
    override fun onCreateSuccess(sdp: SessionDescription) {
        peerConnection.setLocalDescription(this, sdp)
        // Send SDP string to remote peer
        sendSdpToRemotePeer(sdp.description)
    }
}, new MediaConstraints())

直接处理SDP字符串的能力为开发人员提供了灵活性:他们可以在发送前修改SDP,添加或删除特定的编解码器,配置ICE参数或添加自定义属性。对于Android应用程序,在网络带宽低时通常需要在SDP中禁用视频——这是通过从SDP描述中删除相应的m=行来完成的。

移动开发中的SDP

在移动开发中,SDP主要在WebRTC的背景下使用——用于创建具有视频通话、语音聊天和流媒体功能的应用程序。Android和iOS上的移动应用程序既可以充当发起者,也可以充当SDP消息的接收者,从而允许构建对称的点对点连接。

移动应用程序的特点是需要在不稳定的网络质量条件下使用SDP。在Wi-Fi和移动互联网之间切换时,以及在带宽变化时,可能需要生成新的SDP描述。为此使用renegotiation机制——通过createOffer()和setLocalDescription()重复SDP交换。

根据Google WebRTC团队(2023年),移动设备的SDP交换优化包括在网络变化时使用ICE restart,优先使用低比特率的编解码器(音频使用opus,视频使用VP8),以及通过排除不必要的媒体流来最小化SDP字符串大小。关键优势是减少移动网络中连接建立的延迟。

针对移动网络的SDP优化

在移动设备上使用SDP的关键任务之一是最小化SDP描述的大小。典型WebRTC会话的完整SDP包含音频和视频可能占用2–5 KB,这对于慢速网络来说是显著的。优化包括使用BUNDLE(合并流)、删除不支持的编解码器和压缩ICE候选者。

移动设备的另一个问题是SDP的有限生命周期。在不稳定的连接条件下,SDP可能在远程参与者处理之前就过期了。解决方案是使用短超时来接收Answer,并在必要时重新发送SDP。ICE restart机制允许在不完全重新创建RTCPeerConnection的情况下更新连接。a=ice-lite属性简化了服务器端的ICE实现。

用于处理SDP的流行库

移动应用程序开发人员可以使用现成的库来简化SDP的处理。libjingle_peerconnection(Google WebRTC)——是适用于Android的主要库,提供用于SDP管理的完整API。对于iOS,使用具有类似功能的WebRTC.framework。这两个库都自动生成和解析SDP,但在需要时提供对原始SDP字符串的访问。

为了更好地控制SDP,存在第三方解决方案:sdp-transform(JavaScript或Node.js)用于解析和修改SDP,NICENICE(Java)用于处理ICE候选者,以及来自WebRTC基础设施提供商的现成SDK,这些SDK处理包括SDP在内的整个信令交换。

常见问题

简单来说什么是SDP?

SDP — 是一种文本格式,会话参与者用它来描述他们支持的编解码器、端口和协议。它不传输视频或音频,只协商连接参数。类比:SDP是菜单,RTP是菜肴本身。

SDP与SIP有何不同?

SIP — 是一种会话管理协议,用于建立、修改和终止呼叫。SDP是一种描述格式,嵌入在SIP消息体中用于传输媒体参数。SIP回答<谁在打电话给谁>的问题,而SDP回答<使用哪些编解码器和端口>。

可以手动更改SDP吗?

可以,SDP字符串可以在建立连接之前修改。开发人员经常编辑SDP以强制选择特定的编解码器、添加自定义属性或删除不支持的媒体流。但是,更改必须经过双方同意,否则连接将无法建立。

SDP如何在参与者之间传输?

SDP通过单独的信令通道传输,该通道由开发人员独立实现。典型选项是用于Web应用程序的WebSocket、HTTP POST请求(REST API)或用于移动应用程序的原生协议。WebRTC不定义SDP的传输方式,只定义其格式。

SDP中的BUNDLE是什么?

BUNDLE — 是SDP的一种机制,将多个媒体流(音频、视频、数据)合并到一个传输通道中。每个流不使用单独的端口,而是使用一个端口和一个ICE连接。这减少了移动设备的负载并降低了延迟。

总结

  • SDP — 用于描述多媒体会话的文本协议,在RFC 8866中标准化,用于WebRTC、VoIP和视频会议。
  • type=value格式 — SDP的基础,每行描述一个参数:版本、会话名称、媒体流、编解码器、端口和属性。
  • WebRTC在建立点对点连接之前使用SDP在参与者之间进行Offer和Answer的信令交换。
  • ICE候选者作为SDP属性传输,为防火墙后的设备提供NAT穿越。
  • 安全性通过DTLS指纹(fingerprint)和SRTP保证,确保媒体流的加密。
  • 移动SDK — Android版Google WebRTC和iOS版WebRTC.framework — 为SDP交换提供完整的API。
  • 优化移动设备的SDP包括BUNDLE、删除不支持的编解码器和网络变化时的ICE restart。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目