Webrtc之SDP协议

news2024/11/15 4:55:17

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-54

a=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-3

a=msid-semantic: WMS 34b34ced3c5623ea4213vx3

// m=<media> <port> <proto> <fmt> ...

// port=10 无实际含义,真正通信使用的端口由 ICE Candidate 指定

// proto=UDP/TLS/RTP/SAVP 表示用 UDP 来传输 RTP 包,并使用 DTLS 加密

// 后面的一串数字是 fmt,表示所有 codec 的 payloadtype

m=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.4

a=ice-ufrag:aZ/b

a=ice-pwd:3tFwvgPAA2PK3pPWoJjVz4FJ

a=ice-options:trickle renomination

// DTLS 信息,参考 RFC 文档: https://tools.ietf.org/html/rfc4572#section-5

a=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-4

a=setup:actpass

// a=mid:<token>

// 这个 token 在 a=group 那一行中也有出现,

// 也就是说这里描述的媒体正是需要被 bundle 的

// 参考 rfc: https://tools.ietf.org/html/rfc5888#section-6

a=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-4

a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level

// rtp stream 信息,参考 rfc: https://tools.ietf.org/html/draft-ietf-avtext-rid-09

a=extmap:13 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id

// 流的方向,sendrecv 表示可以收也可以发

// 参考 rfc:https://tools.ietf.org/html/rfc3264

a=sendrecv

// 这一行表示 rtcp 和 rtp 复用一个端口,

// 参考 rfc:https://tools.ietf.org/html/rfc5761 

// 和 rfc:https://tools.ietf.org/html/rfc8035

a=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/rfc7587

a=rtpmap:111 opus/48000/2

// a=rtcp-fb:<payload type> [...]

// 表示支持的 rtcp 反馈报文类型

// 这个反馈报文是 tcc 带宽探测用的

// 参考 https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01

a=rtcp-fb:111 transport-cc

// nack,表示 fmt=111 支持 nack 重传包

a=rtcp-fb:111 nack

// a=fmtp 用来描述 codec 的一些特性,例如这里表示期望的 opus 最小打包时间是 10ms,并且使用 inbandfec

a=fmtp:111 minptime=10;useinbandfec=1

// 指明了音频 RTX 包的 payloadtype

// 参考 rfc:https://tools.ietf.org/html/rfc4588#section-8.6

a=rtpmap:114 rtx/48000/2

// apt 表示 fmt=114 的 RTX 包是用来重传 fmt=111 音频的

a=fmtp:114 apt=111

// 指明了 rsfec 包的 payloadtype

a=rtpmap:123 rsfec/48000/2

// 指明了 red 包的 payloadtype

// 参考 https://tools.ietf.org/html/rfc2198

a=rtpmap:124 red/48000/2

// 指明了音频 RTX 包的 payloadtype

a=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.2

a=ssrc-group:FID 2952055605 1713037948

// cname 的内容是一个 16 位 Base64 字符串,含义是传输级的标识符,同一个 PeerConnection 的值相同

// 参考 https://datatracker.ietf.org/doc/html/rfc8834#section-4.9

a=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-msid

a=ssrc:2952055605 msid:34b34ced3c5623ea4213vx3 34b34ced3c5623ea4213vx3a0

// media stream id

a=ssrc:2952055605 mslabel:34b34ced3c5623ea4213vx3

// sender track id

a=ssrc:2952055605 label:34b34ced3c5623ea4213vx3a0

// video media

m=video 10 UDP/TLS/RTP/SAVPF 96 97 101 102 103

c=IN IP4 0.0.0.0

a=rtcp:10 IN IP4 0.0.0.0

a=ice-ufrag:aZ/b

a=ice-pwd:3tFwvgPAA2PK3pPWoJjVz4FJ

a=ice-options:trickle renomination

a=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:actpass

a=mid:video

// 传输时间偏移扩展头

// 参考 https://datatracker.ietf.org/doc/html/rfc5450

a=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/rfc6184

a=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-06

a=extmap:13 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id

a=sendrecv

a=rtcp-mux

// 支持 rtcp 压缩

// 参考 https://datatracker.ietf.org/doc/html/rfc5506#section-1

a=rtcp-rsize

// 指明 fmt=96 就是用来传输 H264 编码的视频的

a=rtpmap:96 H264/90000

// remb 反馈报文,gcc 带宽探测用的

a=rtcp-fb:96 goog-remb

a=rtcp-fb:96 transport-cc

// FIR(完整帧内请求)反馈报文

// 参考 https://datatracker.ietf.org/doc/html/rfc5104

a=rtcp-fb:96 ccm fir

a=rtcp-fb:96 nack

// PLI NACK 反馈报文

// 参考 https://datatracker.ietf.org/doc/html/rfc5104

a=rtcp-fb:96 nack pli

// 后面的是一些 H264 的参数

a=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f

a=rtpmap:97 rtx/90000

a=fmtp:97 apt=96;packetization-mode=1

a=rtpmap:101 red/90000

a=fmtp:101 packetization-mode=1

a=rtpmap:102 rtx/90000

a=fmtp:102 apt=101;packetization-mode=1

a=rtpmap:103 rsfec/90000

a=fmtp:103 packetization-mode=1

// ssrc-group:SIM 表示后面的这些 ssrc 是同一个流的 simulcast

a=ssrc-group:SIM 2955842370 1032318052

a=ssrc-group:FID 2955842370 521905126

a=ssrc-group:FID 1032318052 1492521545

a=ssrc:2955842370 cname:vqdagKn92E0lhuXn

a=ssrc:2955842370 msid:34b34ced3c5623ea4213vx3 34b34ced3c5623ea4213vx3v0

a=ssrc:2955842370 mslabel:34b34ced3c5623ea4213vx3

a=ssrc:2955842370 label:34b34ced3c5623ea4213vx3v0

a=ssrc:1032318052 cname:vqdagKn92E0lhuXn

a=ssrc:1032318052 msid:34b34ced3c5623ea4213vx3 34b34ced3c5623ea4213vx3

a=ssrc:1032318052 mslabel:34b34ced3c5623ea4213vx3

a=ssrc:1032318052 label:34b34ced3c5623ea4213vx3v0

a=ssrc:521905126 cname:vqdagKn92E0lhuXn

a=ssrc:521905126 msid:34b34ced3c5623ea4213vx3 34b34ced3c5623ea4213vx3v0

a=ssrc:521905126 mslabel:34b34ced3c5623ea4213vx3

a=ssrc:521905126 label:34b34ced3c5623ea4213vx3v0

a=ssrc:1492521545 cname:vqdagKn92E0lhuXn

a=ssrc:1492521545 msid:34b34ced3c5623ea4213vx3 34b34ced3c5623ea4213vx3v0

a=ssrc:1492521545 mslabel:34b34ced3c5623ea4213vx3

a=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.coloradmin.cn/o/2053488.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL数据库主从复制

主从复制原理 MySQL的复制类型 基于语句的复制 &#xff08;默认&#xff09;基于行的复制混合类型的复制MySQL主从复制的工作过程 主从复制设置 主从复制时基于二进制文件的所以需要打开二进制文件 主数据库 在MySQL配置文件/etc/my.cnf修改或增加 #启用了MySQL的二进制日…

集合及数据结构第三节————包装类和简单认识泛型

系列文章目录 集合及数据结构第三节————包装类和简单认识泛型 包装类和简单认识泛型 基本数据类型和对应的包装类装箱和拆箱泛型泛型类的使用裸类型(Raw Type) &#xff08;了解&#xff09;泛型如何编译的泛型的上界泛型方法 文章目录 系列文章目录集合及数据结构第三节…

linux上常见问题

1.普通用户下&#xff0c;不能使用sudo 解决方法 1.切换到root用户下执行该指令是没有问题的 2.更改配置文件sudoers 1.进入root用户下&#xff1a;su - 2.编辑sudoers :visudo 此时就打开了一个文件 3.在该文件找到这么一行内容&#xff1a;root ALL(ALL) ALL 4.在该行的…

CUDA-MODE课程笔记 第8课: CUDA性能检查清单

我的课程笔记&#xff0c;欢迎关注&#xff1a;https://github.com/BBuf/how-to-optim-algorithm-in-cuda/tree/master/cuda-mode CUDA-MODE课程笔记 第8课: CUDA性能检查清单 课程笔记 这节课实际上算是CUDA-MODE 课程笔记 第一课: 如何在 PyTorch 中 profile CUDA kernels 这…

(16)prometheus(普罗米修斯)监控的搭建

prometheus是由go语言编写的&#xff0c;监控服务器是否正常运行的工具&#xff0c;使用experter工具收集数据&#xff0c;传到prometheus服务器。可以结合grafana图形化和pagerduty报警发送有邮件和信息。 实验环境&#xff1a; 关掉防火墙和selinux grafana.example.com 1…

为什么CNAPP将会是网络安全领域的一场革命?

随着越来越多的组织开始业务上云&#xff0c;云原生应用保护变得越来越复杂。众多高度碎片化产品&#xff0c;很难去保护一个广泛的、动态变化的攻击场景。当前想要解决这一难题&#xff0c;有一个很好的思路&#xff0c;就是云原生应用保护平台&#xff08;CNAPP&#xff09;。…

第二届机器人与软件工程前沿国际会议在贵阳闭幕

2024年8月13日&#xff0c;第二届机器人与软件工程前沿国际会议&#xff08;FRSE 2024&#xff09;在贵阳圆满闭幕。 本次大会由长沙理工大学主办&#xff0c;贵州大学、湖南科技大学、爱迩思出版社&#xff08;ELSP&#xff09;&#xff0c;ESBK国际学术交流中心、AC学术平台…

Python 办公自动化 处理 Excel 数据 【1】推荐

话说学好办公自动化,走遍天下都不怕&#xff01;&#xff01;&#xff01; 好的&#xff0c;现在开始。 因为是一些办公自动化的应用场景&#xff0c;所以需要电脑支持excel、word和ppt以及python的运行环境。 如果有电脑不支持Excel word ppt的以及python环境下载安装配置可…

Spring 声明式事务 @Transactional

目录 一、添加依赖 二、Transactional 作用 三、Transactional详解 3.1 rollbackFor 3.2 事务隔离级别 3.3 Spring 事务传播机制 Spring 声明式事务 Transactional的使用很简单&#xff0c;只需要添加依赖&#xff0c;在需要的方法或者类上添加 Transactional注解即可。 …

珠海盈致联手深圳盈怡成功上线“混工单柔性智能生产装备”

珠海盈致联手深圳盈怡推出的“混工单柔性智能生产装备”在全面而严密的市场测试中显示出卓越的性能和极高的用户满意度。 经过两年的精细研发和内部测试优化&#xff0c;该柔性生产线已成功完成了样板工厂的所有环节&#xff0c;在深圳市贤丰科技有限公司成功试跑上线&#xf…

联影医疗笔试考什么?如何通过联影在线测评|附真题库面试攻略

职小豚 一、联影医疗公司介绍 嘿&#xff0c;朋友们&#xff01;今天咱们来聊聊联影医疗这家在医疗领域大放异彩的企业。 联影医疗&#xff0c;那可是医疗科技界的一颗璀璨明星&#xff01;它就像一位勇敢的探索者&#xff0c;在医疗影像设备的研发和创新道路上不断前行。 联…

机器视觉运动控制一体机VPLC532E在汽车胶带缠绕的开放式CNC应用

市场应用背景 在汽车线束和零配件中&#xff0c;胶带缠绕是一种常见且重要的加工工艺&#xff0c;主要用于线束/零配件的捆扎、固定、绝缘保护等应用。在缠绕头控制下&#xff0c;胶带均匀缠绕在汽车线束/零配件表面&#xff0c;完成缠绕后&#xff0c;系统自动执行切割。汽车…

(普通用户)Cannot connect to the Docker daemon at unix:///var/run/docker.sock.

报错&#xff1a; Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?#大概像以下的报错内容 MernyPierreMBP:~ merny24$ docker info Client:Version: 26.1.4Context: defaultDebug Mode: falseServer: ERROR: Cann…

可以给IP地址申请SSL证书实现HTTPS访问吗?

IP地址证书&#xff0c;全称为IP地址的SSL/TLS证书&#xff0c;是一种专为公网IP地址&#xff08;或内网映射的外网&#xff09;颁发的数字证书。这种证书由受信任的证书颁发机构&#xff08;CA&#xff09;签发&#xff0c;旨在确保通过该IP地址进行的通信&#xff08;特别是H…

家务一键搞定!Astribot S1机器人让你秒变“甩手掌柜“

星尘智能 在这个忙碌的现代社会&#xff0c;谁不渴望拥有一个能够帮我们处理繁琐家务的得力助手呢&#xff1f;就在最近&#xff0c;星尘智能公司推出的全新AI机器人Astribot S1&#xff0c;正在让这个梦想变为触手可及的现实。 Astribot S1 Astribot S1 性能对比 从官网给出的…

【Mdijourney】AI作画提示词工程:精细化技巧与高效实践指南

文章目录 &#x1f4af;AI作画提示词基础结构1 图片链接1.1 上传流程 2 文字描述3 后置参数 &#x1f4af;AI作画提示词的文字描述结构1 主体主体细节描述2 环境背景2.1 环境2.2 光线2.3 色彩2.4 氛围 3 视角4 景别构图5 艺术风格6 图片制作方法7 作品质量万能词 &#x1f4af;…

景区店铺管理系统---附源码91568

摘 要 景区店铺管理系统基于Django框架的设计与实现旨在提高景区内店铺管理的效率和便捷性。该系统利用Django框架的强大功能和易用性&#xff0c;结合数据库管理和用户交互设计&#xff0c;实现了景区店铺信息管理、订单处理、库存管理等功能模块。通过系统的智能化设计和用户…

算法日记day 42(动归之不相交的线|最大子数组和|判断子序列)

一、不相交的线 题目&#xff1a; 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现在&#xff0c;可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线&#xff0c;这些直线需要同时满足&#xff1a; nums1[i] nums2[j]且绘制的直线不与任何其他连线…

Kafka集群搭建的两种方式

目录 1. 依赖Zookeeper搭建集群 1. 下载Kafka二进制文件 2. 更改kafka配置 3. 启动Zookeeper集群和Kafka集群 4. 验证集群 1.创建主题 2. 检查主题是否存在 3. 创建生产者生产数据 4. 创建消费者消费数据 5. 检查Zookeeper中Kafka集群的元数据 2. 不依赖Zookeeper搭…

make/Makefile - ACM 时间及 make 的检查更新

文章目录 一、ACM 时间修改时间改变时间读取时间统一更新时间 二、make 会检查文件的新旧现象gcc 没有检查的功能&#xff0c;这个工作是 make 干的make/Makefile 通过对比时间了解可执行程序是不是最新的新的可执行程序和新的 .o 文件 一、ACM 时间 Linux 下文件属性中有 ACM…