Webrtc之SDP协议

SDP简介

SDP 最常用于 RTC 实时通话的协商过程,在 WebRTC 中,通信双方在连接阶段使用 SDP 来协商后续传输过程中使用的音视频编解码器(codec)、主机候选地址、网络传输协议等。

在实际的应用过程中,通信双方可以使用 HTTP、WebSocket、DataChannel 等传输协议来相互传送 SDP 内容,这个过程称作 offer/answer 交换,也就是发起方发送 offer,接收方收到 offer 后回复一个 answer。例如在下图的服务端架构中,客户端将 offer 发送给信令服务器,信令服务器转发给媒体服务器,媒体服务器将 offer 和自身的能力进行比较后得到 answer,信令服务器再将 answer转发给客户端,随后客户端和媒体服务器就可以进行 RTP 通信。

SDP 协议的设计可以参考 rfc4566 文档。它是一种具有特殊约定格式的纯文本描述文档,也就是它的内容都是由 UTF-8 编码的文本,有点类似于 JSON/XML。一个 SDP 会话描述包括若干行 type=value 形式的文本,其中 type 是一个区分大小写的字母,例如 v、m 等,value 是一个结构化的文本,格式不固定。通常 value 由若干分割符隔开的字段组成或者是一个字符串, 整个协议文本区分大小写。"=" 两侧不允许有空格存在。

SDP 由一个会话级描述(session level description)和多个媒体级描述(media level description)组成。会话级描述的作用域是整个会话,在 SDP 中,从 "v=" 行开始到第一个 "m=" 行之前都是属于会话级描述的内容。媒体级描述对某个媒体流的内容进行描述,例如某个音频流或者某个视频流,从某个 "m=" 行开始到下个 "m=" 行之前是属于一个媒体级描述的内容。如下图所示:

 SDP 中有的字段是必须的,有的字段是可选的,可选的字段在如下的示例中都使用 * 进行标记。 SDP 中 type 出现的顺序是固定的,按照如下顺序进行排列,这样可以增强解析器错误检测的能力,另外也可以简化解析器的实现。有一个很好的网站:webrtchacks.com/sdp-anatomy… 可用于学习 SDP,这个网站里面鼠标移动到 SDP 某一行时,就会显示这一行 SDP 的具体含义。

# 1. 会话级别的描述(及其字段)
v=  (protocol version)
o=  (originator and session identifier)
s=  (session name)
i=* (session information)
u=* (URI of description)
e=* (email address)
p=* (phone number)
c=* (connection information -- not required if included in all media)
b=* (zero or more bandwidth information lines)
# 2. 一个或多个时间描述(字段参见下文)
z=* (time zone adjustments)
k=* (encryption key)
a=* (zero or more session attribute lines)
# 3. 零个或多个媒体级别的描述(字段参见下文)# 时间描述的字段有这些
t=  (time the session is active)
r=* (zero or more repeat times)# 媒体级别的描述字段有这些
m=  (media name and transport address)
i=* (media title)
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)

SDP示例

// SDP 版本信息v=0// session 信息// o=<username> <session-id> <session-version> <nettype> <addrtype> <unicast-address>o=- 1873022542326151139 2 IN IP4 127.0.0.1// s=<session name>s=-// t=<start-time> <stop-time>,如果不规定开始和结束时间,两个都填 0 即可t=0 0// 使用 "a=" 来扩展的 bundle 属性,其含义是 audio 和 video 使用同一个端口发送/接收,具体可以参考下方的 RFC 文档:// https://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-54a=group:BUNDLE audio video// 列出当前SDP中所有的 media stream id,以空格分割// WMS 的含义是这里面的 media stream id 适配 webrtc 的 media stream// 参考 RFC 文档: https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-msid-01#section-3a=msid-semantic: WMS 34b34ced3c5623ea4213vx3// m=<media> <port> <proto> <fmt> ...// port=10 无实际含义,真正通信使用的端口由 ICE Candidate 指定// proto=UDP/TLS/RTP/SAVP 表示用 UDP 来传输 RTP 包,并使用 DTLS 加密// 后面的一串数字是 fmt,表示所有 codec 的 payloadtypem=audio 10 UDP/TLS/RTP/SAVPF 111 114 115 116 123 124 125// c=<nettype> <addrtype> <connection-address>c=IN IP4 0.0.0.0// a=rtcp:<port> [nettype addrtype connection-address]a=rtcp:10 IN IP4 0.0.0.0// ICE 信息,参考 RFC 文档: https://tools.ietf.org/html/rfc5245#section-15.4a=ice-ufrag:aZ/ba=ice-pwd:3tFwvgPAA2PK3pPWoJjVz4FJa=ice-options:trickle renomination// DTLS 信息,参考 RFC 文档: https://tools.ietf.org/html/rfc4572#section-5a=fingerprint:sha-256 5F:78:37:05:D7:83:46:05:F7:3F:17:35:2A:7E:81:D3:2D:26:71:87:8B:9F:57:02:53:30:E3:3E:B6:3E:49:D5// a=setup:<role>// role可选active/passive/actpass/holdconn,// 分别表示端点将发起一个传出连接、端点将接受传入连接、// 端点愿意接受传入连接或启动传出连接、端点暂时不想建立连接// 参考 rfc: https://tools.ietf.org/html/rfc4145#section-4a=setup:actpass// a=mid:<token>// 这个 token 在 a=group 那一行中也有出现,// 也就是说这里描述的媒体正是需要被 bundle 的// 参考 rfc: https://tools.ietf.org/html/rfc5888#section-6a=mid:audio// 以下是这个媒体支持的所有 RTP 扩展头,// 参考rfc: https://tools.ietf.org/html/rfc8285// a=extmap:<value>["/"<direction>] <URI> <extensionattributes>// value=ID// direction 可选 sendonly/recvonly/sendrecv/inactive,默认值 sendrecv// URI 就是这个扩展头的 URI,通信双方可以通过 URI 标明扩展头的含义让双方都能理解// 这里表示 ID=1 的扩展头是 audio level 扩展头,表示 RTP 包中会携带音频包音量大小// 参考 https://tools.ietf.org/html/rfc6464#section-4a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level// rtp stream 信息,参考 rfc: https://tools.ietf.org/html/draft-ietf-avtext-rid-09a=extmap:13 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id// 流的方向,sendrecv 表示可以收也可以发// 参考 rfc:https://tools.ietf.org/html/rfc3264a=sendrecv// 这一行表示 rtcp 和 rtp 复用一个端口,// 参考 rfc:https://tools.ietf.org/html/rfc5761 // 和 rfc:https://tools.ietf.org/html/rfc8035a=rtcp-mux// a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding parameters>]// opus codec 的 payload,// 表明 fmt=111 就是用来传输 opus 数据的// 参考 rfc: https://datatracker.ietf.org/doc/html/rfc7587a=rtpmap:111 opus/48000/2// a=rtcp-fb:<payload type> [...]// 表示支持的 rtcp 反馈报文类型// 这个反馈报文是 tcc 带宽探测用的// 参考 https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01a=rtcp-fb:111 transport-cc// nack,表示 fmt=111 支持 nack 重传包a=rtcp-fb:111 nack// a=fmtp 用来描述 codec 的一些特性,例如这里表示期望的 opus 最小打包时间是 10ms,并且使用 inbandfeca=fmtp:111 minptime=10;useinbandfec=1// 指明了音频 RTX 包的 payloadtype// 参考 rfc:https://tools.ietf.org/html/rfc4588#section-8.6a=rtpmap:114 rtx/48000/2// apt 表示 fmt=114 的 RTX 包是用来重传 fmt=111 音频的a=fmtp:114 apt=111// 指明了 rsfec 包的 payloadtypea=rtpmap:123 rsfec/48000/2// 指明了 red 包的 payloadtype// 参考 https://tools.ietf.org/html/rfc2198a=rtpmap:124 red/48000/2// 指明了音频 RTX 包的 payloadtypea=rtpmap:125 rtx/48000/2// apt 表示 fmt=125 的 RTX 包是用来重传 fmt=124 的 red 包的a=fmtp:125 apt=124// ssrc-group 指明了一组 ssrc 之间的关系,FID 表明后一个 ssrc 是前一个 ssrc 的 rtx// https://tools.ietf.org/html/rfc5576#section-4.2a=ssrc-group:FID 2952055605 1713037948// cname 的内容是一个 16 位 Base64 字符串,含义是传输级的标识符,同一个 PeerConnection 的值相同// 参考 https://datatracker.ietf.org/doc/html/rfc8834#section-4.9a=ssrc:2952055605 cname:vqdagKn92E0lhuXn// 这里出现了两个字符串,// 前一个是 media stream id,后一个是 sender track id// media stream 主要用于音视频同步,每个 track 以 media stream id 作为 sync label 进行同步// 参考 https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-msida=ssrc:2952055605 msid:34b34ced3c5623ea4213vx3 34b34ced3c5623ea4213vx3a0// media stream ida=ssrc:2952055605 mslabel:34b34ced3c5623ea4213vx3// sender track ida=ssrc:2952055605 label:34b34ced3c5623ea4213vx3a0// video mediam=video 10 UDP/TLS/RTP/SAVPF 96 97 101 102 103c=IN IP4 0.0.0.0a=rtcp:10 IN IP4 0.0.0.0a=ice-ufrag:aZ/ba=ice-pwd:3tFwvgPAA2PK3pPWoJjVz4FJa=ice-options:trickle renominationa=fingerprint:sha-256 5F:78:37:05:D7:83:46:05:F7:3F:17:35:2A:7E:81:D3:2D:26:71:87:8B:9F:57:02:53:30:E3:3E:B6:3E:49:D5a=setup:actpassa=mid:video// 传输时间偏移扩展头// 参考 https://datatracker.ietf.org/doc/html/rfc5450a=extmap:2 urn:ietf:params:rtp-hdrext:toffset// abs-send-time 扩展头,gcc 带宽探测用的a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time// 视频朝向扩展头// 参考 https://datatracker.ietf.org/doc/html/rfc6184a=extmap:4 urn:3gpp:video-orientation// transport-cc 扩展头,tcc 带宽探测用的a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01// 扩展头的内容是对播放延迟限制的值a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay// 视频内容类型扩展头a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type// 这个扩展头用于传输每帧的时间信息a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/video-timing// 视频的色域空间扩展头a=extmap:12 http://www.webrtc.org/experiments/rtp-hdrext/color-space// 传输视频 SDES 信息的扩展头// 参考:https://datatracker.ietf.org/doc/html/draft-ietf-avtext-rid-06a=extmap:13 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-ida=sendrecva=rtcp-mux// 支持 rtcp 压缩// 参考 https://datatracker.ietf.org/doc/html/rfc5506#section-1a=rtcp-rsize// 指明 fmt=96 就是用来传输 H264 编码的视频的a=rtpmap:96 H264/90000// remb 反馈报文,gcc 带宽探测用的a=rtcp-fb:96 goog-remba=rtcp-fb:96 transport-cc// FIR(完整帧内请求)反馈报文// 参考 https://datatracker.ietf.org/doc/html/rfc5104a=rtcp-fb:96 ccm fira=rtcp-fb:96 nack// PLI NACK 反馈报文// 参考 https://datatracker.ietf.org/doc/html/rfc5104a=rtcp-fb:96 nack pli// 后面的是一些 H264 的参数a=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01fa=rtpmap:97 rtx/90000a=fmtp:97 apt=96;packetization-mode=1a=rtpmap:101 red/90000a=fmtp:101 packetization-mode=1a=rtpmap:102 rtx/90000a=fmtp:102 apt=101;packetization-mode=1a=rtpmap:103 rsfec/90000a=fmtp:103 packetization-mode=1// ssrc-group:SIM 表示后面的这些 ssrc 是同一个流的 simulcasta=ssrc-group:SIM 2955842370 1032318052a=ssrc-group:FID 2955842370 521905126a=ssrc-group:FID 1032318052 1492521545a=ssrc:2955842370 cname:vqdagKn92E0lhuXna=ssrc:2955842370 msid:34b34ced3c5623ea4213vx3 34b34ced3c5623ea4213vx3v0a=ssrc:2955842370 mslabel:34b34ced3c5623ea4213vx3a=ssrc:2955842370 label:34b34ced3c5623ea4213vx3v0a=ssrc:1032318052 cname:vqdagKn92E0lhuXna=ssrc:1032318052 msid:34b34ced3c5623ea4213vx3 34b34ced3c5623ea4213vx3a=ssrc:1032318052 mslabel:34b34ced3c5623ea4213vx3a=ssrc:1032318052 label:34b34ced3c5623ea4213vx3v0a=ssrc:521905126 cname:vqdagKn92E0lhuXna=ssrc:521905126 msid:34b34ced3c5623ea4213vx3 34b34ced3c5623ea4213vx3v0a=ssrc:521905126 mslabel:34b34ced3c5623ea4213vx3a=ssrc:521905126 label:34b34ced3c5623ea4213vx3v0a=ssrc:1492521545 cname:vqdagKn92E0lhuXna=ssrc:1492521545 msid:34b34ced3c5623ea4213vx3 34b34ced3c5623ea4213vx3v0a=ssrc:1492521545 mslabel:34b34ced3c5623ea4213vx3a=ssrc:1492521545 label:34b34ced3c5623ea4213vx3v0// 使用的 rsfec 的版本a=rsfec-version:1

参考文档

  • SDP 格式规定,RFC4566:datatracker.ietf.org/doc/html/rf…
  • offer/answer 交换过程,RFC3264:datatracker.ietf.org/doc/html/rf…
  • SDP 各字段解释示例:webrtchacks.com/sdp-anatomy…
  • segmentfault.com/a/119000003…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/404716.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux---进程(6)---进程控制

目录 进程创建 写时拷贝 代码共享原理 写时拷贝的设计 写时拷贝原理 进程终止 信号编号 进程退出码 exit函数/_exit函数解析 进程等待 等待接口 status 父进程等待方式 阻塞等待 非阻塞等待 进程替换 进程替换接口 Shell运行规则 环境变量与进程替换 su-/su…

【Datawhale AI夏令营第四期】 浪潮源大模型应用开发方向笔记 Task04 RAG模型 人话八股文Bakwaan_Buddy项目创空间部署

【Datawhale AI夏令营第四期】 浪潮源大模型应用开发方向笔记 Task04 RAG模型 人话八股文Bakwaan_Buddy项目创空间部署 什么是RAG&#xff1a; 我能把这个过程理解为Kimi.ai每次都能列出的一大堆网页参考资料吗&#xff1f;Kimi学了这些资料以后&#xff0c;根据这里面的信息综…

C#发送邮件功能实现全面指南?有哪些方法?

C#发送邮件性能优化技巧&#xff1f;C#发信时如何设置邮件格式&#xff1f; 在现代应用程序开发中&#xff0c;发送电子邮件是一个常见的需求。无论是发送通知、警报&#xff0c;还是定期报告&#xff0c;邮件功能都是至关重要的。AokSend将详细探讨如何在C#中实现发送邮件的功…

SpringBoot教程(二十三) | SpringBoot实现分布式定时任务之xxl-job

SpringBoot教程&#xff08;二十三&#xff09; | SpringBoot实现分布式定时任务之xxl-job 简介一、前置条件&#xff1a;需要搭建调度中心1、先下载调度中心源码2、修改配置文件3、启动项目4、进行访问5、打包部署&#xff08;上正式&#xff09; 二、SpringBoot集成Xxl-Job1.…

stm32的UART重定向printf()

1配置好uart 2打开usart.c文件 3在此文件前面添加头文件 4在末尾添加重定向代码 添加的代码 /* USER CODE BEGIN 1 *///加入以下代码,支持printf函数,而不需要选择use MicroLIB //#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #if 1 //#pragma import(__use_n…

day01- Web开发介绍-HTML-CS

Web开发介绍 1 什么是web开发 Web&#xff1a;全球广域网&#xff0c;也称为万维网(www World Wide Web)&#xff0c;能够通过浏览器访问的网站。 所以Web开发说白了&#xff0c;就是开发网站的&#xff0c;例如下图所示的网站&#xff1a;淘宝&#xff0c;京东等等 那么我们…

JavaEE过滤器的创建与使用过滤器的使用场景

过滤器 Filter也称之为过滤器&#xff0c;过滤器是javaEE规范肿定义的一种技术,可以让请求到达目标servlet之前,先进入到过滤器中,在过滤器中统一进行一些拦截处理,当处理完成后,可以继续向后执行,到达目标servlet,如果配置了多个过滤器,也可以进入下一个过滤器 创建过滤器 创…

asyncua模块实现OPC UA通讯

asyncua是OPCUA的python实现&#xff0c;使用起来非常方便&#xff0c;其github地址是https://github.com/FreeOpcUa/opcua-asyncio UaExpert是OPC UA Client的GUI工具&#xff0c;当编写好server代码后并运行&#xff0c;我们可以使用UaExpert去和server进行通信。UaExpert使…

小程序使用微信支付

接入小程序需要后端进行注册&#xff0c;前端只需要调用API即可。 大概流程如下&#xff1a; 本例使用一个购买商品的例子&#xff0c;前端点击微信支付&#xff0c;后端生成一个商品订单&#xff0c;然后向微信支付系统发起请求&#xff0c;生成一个微信的预支付订单&#xff…

windows上传的文本在linux执行不了,格式转换

在windows编辑的文件脚本上传到linux里面执行不了 1.现象描述 比如在windows编辑简单的文本 2.上传到linux后执行无结果 无响应 3.编码问题 比普通文件多了with CRLF line terminators结尾格式。 cat -v 可以让隐藏的转义字符也打印中显示 4.原因windows和linux的换行符不…

数字化办公OA系统是如何运作的——办公物品领用功能拆解

数字化办公 OA 系统究竟是如何运作的呢&#xff1f;它的核心功能又是如何发挥作用的呢&#xff1f;这篇就以行政 OA 系统为例&#xff0c;从产品视角来深入探讨它是如何运作的。 简道云行政OA管理系统模板&#xff0c;可以直接查看和使用&#xff1a;https://www.jiandaoyun.co…

springboot纹理生成图片系统--论文源码调试讲解

第2章 程序开发技术 2.1 MySQL数据库 开发的程序面向用户的只是程序的功能界面&#xff0c;让用户操作程序界面的各个功能&#xff0c;那么很多人就会问&#xff0c;用户使用程序功能生成的数据信息放在哪里的&#xff1f;这个就需要涉及到数据库的知识了&#xff0c;一般来说…

地平线旭日X3开发板--使用Opencv显示CSI摄像头例程

调试过程发现旭日派无法直接用opencv的VideoCapture()调用CSI摄像头, 需要使用libsrcampy库来获取CSI摄像头图像, 但是从libsrcampy获取的摄像头图像格式是NV12,无法直接在opencv上显示或者处理, 为了能够使用opencv的API来处理图像, 需要增加NV12转化成bgr像素格式的…

springboot项目配置https安装ssl证书教程

1.将下载的ssl证书文件中的jks后缀文件放在/src/main/resource文件夹里面 2.在配置文件中&#xff08;yml后缀配置文件的格式不同&#xff09;添加如下配置即可

ensp小实验(ospf+dhcp+防火墙)

前言 今天给大家分享一个ensp的小实验&#xff0c;里面包含了ospf、dhcp、防火墙的内容&#xff0c;如果需要文件的可以私我。 一、拓扑图 二、实训需求 某学校新建一个分校区网络&#xff0c;经过与校领导和网络管理员的沟通&#xff0c;现通过了设备选型和组网解决方案&…

运维学习————nginx-入门及反向代理搭建

目录 一、简介 二、正向代理和反向代理 1、正向代理 作用 2、反向代理 作用 三、单机版nginx部署 1、查看环境 2、环境安装以及nginx安装 2.1、安装pcre 2.2、安装gzip模块需要 zlib 库 2.3、安装Nginx 3、启动测试 四、反向代理配置 一、简介 nginx [engine x] 是…

计算机Java项目|基于SpringBoot的大学生一体化服务平台的设计与实现

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、CSDN内容合伙人、掘金特邀作者、阿里云博客专家、51CTO特邀作者、多年架构师设计经验、多年校企合作经验&#xff0c;被多个学校常年聘为校外企业导师&#xff0c;指导学生毕业设计并参…

C++入门——16C++11新特性

1.列表初始化 初始化列表时&#xff0c;可添加等号()&#xff0c;也可不添加。 struct Point {int _x;int _y; };int main() {int x1 1;int x2{ 2 };int array1[]{ 1, 2, 3, 4, 5 };int array2[5]{ 0 };Point p{ 1, 2 };// C11中列表初始化也可以适用于new表达式中int* pa …

POK´ELLMON:在宝可梦战斗中实现人类水平的人工智能

人工智能咨询培训老师叶梓 转载标明出处 最近&#xff0c;由美国乔治亚理工学院的Sihao Hu、Tiansheng Huang和Ling Liu发表的论文介绍了POKELLMON&#xff0c;这是一个开创性的基于大模型&#xff08;LLM&#xff09;的具身智能体&#xff0c;它在战术战斗游戏中&#xff0c;特…

海康VisionMaster使用学习笔记11-VisionMaster基本操作

VisionMaster基本操作 VM示例方案 1. 工具拖拽及使用方式 分别从采集和定位栏里拖拽图像源,快速匹配,Blob分析工具 2. 模块连线 依次连线 3.如何订阅 点击快速匹配,可以看到输入源已订阅了图像1的图像,Blob分析类似 4. 方案操作及全局触发 点击快速匹配,创建特征模版,框选…