从零开始精通RTSP之SDP格式详解

概述

        SDP,即会话描述协议,英文全称为Session Description Protocol,是一种用于描述多媒体会话参数的文本协议(对应RFC2327)。SDP是中立于传输协议的,能够适应多种实时通信场景,比如:VoIP通话、视频会议和实时流媒体。SDP定义了一种标准的格式,用于描述会话的各种参数,包括:媒体类型、媒体格式、媒体地址等。这些参数对于会话的参与者来说至关重要,因为它们需要根据这些信息来正确配置和连接到会话。

        在RTSP框架中,SDP主要通过DESCRIBE请求和响应来交换,为客户端提供启动和控制媒体流所需的所有必要信息。

SDP基本结构

        一个完整的SDP消息是一个文本字符串,由若干行组成。每行代表一个特定的属性或参数,行与行之间通过换行符分隔。每行的格式为:<类型>=<值>。其中,<类型>是一个字符,<值>是结构化的文本串,其格式依<类型>而定。比如:v=0表示协议版本号为0。

        SDP中包含了一系列字段,每个字段都描述了会话中的一个参数或配置信息。SDP通常分为两大部分:会话级别描述和媒体级别描述。会话级别描述涵盖了整个会话的通用信息,比如:所有者、会话标识、网络地址、时间范围等。媒体级别描述则针对每个媒体流提供具体的传输协议、端口、编解码器参数等信息,确保客户端能够正确地建立和控制各个媒体流。

        SDP的整体结构如下。

(以下为会话级别描述)
v=版本号
o=所有者/创建者(用户名和会话标识符)
s=会话名(一般为会话的主题)
i=*会话信息(可选的会话描述)
u=*URI(统一资源标识符,可选的会话描述文件位置)
e=*电子邮件地址(所有者的联系信息,可选)
p=*电话号码(所有者的联系信息,可选)
c=*连接信息(网络类型、地址类型及地址)
b=*带宽信息(会话总体或单个媒体的带宽限制)
t=时间描述(会话开始和结束时间)
r=*重复时间描述(会话的重复周期)
z=*时间区域偏移(用于处理不同时区的参与者)
k=*加密密钥(如需加密会话)
a=*属性行(各种附加会话或媒体级别的属性)

(以下为媒体级别描述)
m=媒体名称(类型和传输协议) port/数目的传输地址
i=*媒体标题(可选的媒体描述)
c=*媒体连接信息(如果与会话级连接信息不同)
b=*媒体带宽信息(如果与会话级带宽信息不同)
k=*媒体加密密钥(如果与会话级加密密钥不同)
a=*媒体属性行(各种附加媒体级别的属性)

...(可能有多个媒体级别描述)

(注:带星号的字段表示可选)

会话级别描述

        这部分信息适用于整个会话,而不是针对某个特定的媒体流。会话级别字段通常出现在SDP消息的开头,常见的字段如下。

        版本(Version)

        格式: v=<protocol version>

        作用: 指定SDP消息遵循的协议版本。目前SDP仅有一个正式版本,即v=0。

        所有者/创建者(Origin)

        格式: o=<username> <session id> <session version> <network type> <address type> <unicast address>

        作用: 描述会话的所有者或创建者的信息,以及会话的唯一标识和版本,各部分含义如下。

        <username>:创建会话的用户的标识,通常是一个电子邮件地址或用户名,但也可以是任意ASCII字符串。如果主机不支持<username>,则用“-”代替。注意:<username>中不能包含空格。

        <session id>:会话的唯一标识符,通常是一个随机生成的整数,确保在一定时间内不会重复,建议使用NTP 时间戳。

        <session version>:会话描述的版本,每次更新会话信息(比如:添加或删除媒体流、更改参数等)时递增,确保客户端能够识别会话描述是否有变化,建议使用NTP 时间戳。

        <network type>:网络类型,通常为IN(Internet)。

        <address type>:地址类型,取值一般为IP4或IP6,表明后续地址使用的是IPv4还是IPv6。

        <unicast address>:所有者的网络地址,可以是单播地址(unicast)或组播地址(multicast),取决于会话的性质。

        会话名称(Session Name)

        格式: s=<session name>

        作用: 提供会话的简短标题或名称,便于参与者理解会话的主题或内容。此字段通常包含人类可读的文本,比如:会议主题、直播节目名称等。

        会话信息(Session Information)

        格式: i=<session information>

        作用: 提供会话的更详细描述或说明,可以包含额外的上下文信息、摘要、版权声明等。这是一个扩展字段,用于增强参与者对会话的理解。

        URI(Uniform Resource Identifier)

        格式: u=<uri>

        作用: 指向外部资源的统一资源标识符(URI),比如:网页、文档或其他相关材料,这可以为参与者提供会话的补充信息或进一步指导。

        电子邮件地址(Email Address)

        格式: e=<email-address>

        作用: 提供所有者或会话管理员的电子邮件联系方式,以便参与者在需要时能够通过电子邮件进行沟通。

        电话号码(Phone Number)

        格式: p=<phone-number>

        作用: 提供所有者或会话管理员的电话联系方式,作为另一种与会话相关的辅助联系方式。

        连接信息(Connection Data)

        格式: c=<nettype> <addrtype> <connection-address>

        作用: 描述会话使用的网络类型、地址类型以及连接地址,这些信息用于帮助参与者找到并接入会话。在网络类型和地址类型与o=字段相同的情况下,这一字段可以省略。比如:“c=IN IP4 236.255.1.1”表示会话使用Internet网络,地址类型为IPv4,连接地址为组播地址236.255.1.1。

        带宽信息(Bandwidth Information)

        格式: b=<bwtype>:<bandwidth>

        作用: 指定会话所需的总体带宽或特定类型的带宽。bwtype可以是AS(应用层信号,Application-Specific),表示总体带宽需求,或者是CT(会议总带宽,Conference Total)等特定类型。bandwidth是带宽值,单位为kpbs。比如:“b=AS:1024”表示会话请求1024 kbps的总体带宽。

        时间描述(Timing)

        格式: t=<start-time> <stop-time>

        作用: 定义会话的开始时间和结束时间,时间以NTP格式的绝对时间戳表示,单位为秒。如果<stop-time>为0,表示过了<start-time>之后,会话一直持续。如果<start-time>和<stop-time>都为0,表示持久会话。

        加密密钥(Encryption Key)

        格式: k=<method>[:<encryption key>]

        作用: 如果会话内容需要加密,k=字段提供加密方法和密钥信息,各部分含义如下。

        <method>:指明所使用的加密方法,可以是预定义的方法名,也可以是特定的加密算法。常见的方法包括三种:第一种是clear,表示未加密,即明文传输;第二种是prompt,表示客户端需要提示用户输入密钥,主要用于点对点通信中临时协商密钥;第三种是base64,表示使用Base64编码的密钥,适用于传输二进制密钥。

        <encryption key>:可选部分,用于提供具体的加密密钥。如果方法允许或要求提供密钥,则在此处填写。密钥的具体内容和长度,取决于所采用的加密方法。

        需要注意的是,直接在SDP中包含加密密钥通常不是一个好的安全实践。在现代通信系统中,密钥通常是通过更安全的密钥交换协议(比如:DTLS)来动态协商的,而不是在SDP描述中静态指定。另外,随着技术的发展和安全标准的提高,SDP中的加密密钥字段已经不再是主要的加密机制,而是被更高级别的加密和安全协议所取代。

        属性(Attributes)

        格式: a=<attribute>[:<value>]

        作用: a=字段用于携带会话级的其他属性或参数,比如:会话控制信息、安全设置、服务质量要求等。属性可以是预定义的标准属性,也可以是扩展属性,多个属性可以单独列出多行。

媒体级别描述

        每个媒体流(比如:视频、音频、文本等)在SDP中都有独立的媒体级别描述段,一个会话可以包含一个或多个这样的描述段。在媒体级别描述中,常见的字段如下。

        媒体类型(Media Type)

        格式: m=<media> <port> [/ <number of ports>] <proto> <fmt list>

        作用: m=字段定义了媒体流的基本属性,包括:类型、接收端口、传输协议以及支持的编解码器列表。这些信息对于客户端来说至关重要,它们用于建立正确的网络连接,选择合适的编解码器,并与服务器进行有效的媒体数据交换。各部分含义如下。

        <media>:媒体类型,取值为:audio、video、text、application等,用于标识媒体流的内容类别。

        <port>:接收媒体流的端口号。如果是单播传输,通常是一个具体的端口号。如果是组播传输,可能是端口范围。

        <number of ports>:可选部分,用于指定端口数量,通常用于RTP/RTCP复用同一个端口范围的情况。

        <proto>:传输协议,取值为:RTP/AVP、RTP/SAVP等。

        <fmt list>:媒体格式列表,即RTP负载类型(Payload Type,PT),每个PT对应一种编解码器或编码格式。具体格式为逗号分隔的整数列表,比如:“96, 97, 98”。

        媒体标题(Media Title)

        格式: i=<media title>

        作用: 可选字段,提供媒体流的简短标题或说明,帮助参与者理解媒体流的内容。

        连接信息(Connection Data)

        格式: c=<nettype> <addrtype> <connection-address>

        作用: 在与会话级别c=字段不同的情况下,提供媒体流的特定连接信息。这些信息包括:网络类型、地址类型以及连接地址,用于指导客户端如何访问媒体流。如果与会话级别c=字段相同,则可以省略。

        带宽信息(Bandwidth Information)

        格式: b=<bwtype>:<bandwidth>

        作用: 指定媒体流所需的特定带宽类型和带宽值。与会话级别b=字段类似,但针对单个媒体流。比如:“b=AS:512”表示该媒体流请求512 kbps的应用层带宽。

        RTP映射(RTP Mapping)

        格式: a=rtpmap:<payload type> <encoding name>/<clock rate>[/<encoding parameters>]

        作用: 将RTP负载类型(PT)映射到具体的编码名称、采样率(或时钟频率)以及可能的编码参数。这对于客户端选择正确的编解码器、解码接收到的媒体数据至关重要。比如:“a=rtpmap:96 OPUS/48000/2”表示PT为96的RTP包对应OPUS编码,采样率为48 kHz,声道数为2。

        编码参数(Format Parameters)

        格式: a=fmtp:<payload type> <format parameters>

        作用: 提供RTP负载类型(PT)对应的编解码器的特定参数。这些参数通常是编解码器特有的,用于进一步定义编码或解码行为。比如:“a=fmtp:96 sprop-stereo=1; useinbandfec=1”表示PT为96的RTP包对应的OPUS编码应启用立体声(sprop-stereo=1)和内嵌前向纠错(useinbandfec=1)。

        控制信息(Control)

        格式: a=control:<URI>

        作用: 在RTSP中,a=control:字段尤为重要,它提供了媒体流的控制URI。客户端可以通过该URI对特定媒体流执行独立的控制操作,如PLAY、PAUSE等。比如:“a=control:trackID=1”表示该媒体流的控制路径为“trackID=1”,客户端可以通过向服务器发送如“PLAY rtsp://example.com/path/to/stream/trackID=1”这样的命令来单独控制该媒体流。

        其他媒体属性(Other Attributes)

        格式: a=<attribute>[:<value>]

        作用: a=字段用于携带媒体级的其他属性或参数,比如:同步信息、媒体方向、多路复用信息、加密设置、服务质量要求等。

实际案例分析

        下面,我们通过一个实际的SDP报文来进行逐行的分析和讲解。

v=0
o=- 1586545639965536 1586545639965536 IN IP4 192.168.50.100
s=H.264 Video Stream
i=Live video from Camera 1
u=http://www.example.com/camera1.html
t=0 0
a=tool:LIVE555 Streaming Media v2016.04.09
a=type:broadcast
a=control:*
a=range:npt=0-
a=x-qt-text-nam:H.264 Video Stream
a=x-qt-text-inf:Live video from Camera 1
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
b=AS:500
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=42001E;sprop-parameter-sets=Z0LAH9kAUAWdAAADABAAAAMApG4H4Q==,aO48gA==
a=control:trackID=1

        v=0:表示SDP遵循版本0的规范。

        o=- 1586545639965536 1586545639965536 IN IP4 192.168.50.100:用户名为-,此处服务器未填写实际用户名。会话标识符和会话描述的版本均为NTP时间戳。网络类型为IN,表示Internet。地址类型为IP4,表示IPv4地址。地址为192.168.50.100,即服务器的IP地址。

        s=H.264 Video Stream:显示会话的主题,此处为H.264 Video Stream。

        i=Live video from Camera 1:提供会话的详细描述,此处为Live video from Camera 1。

        u=http://www.example.com/camera1.html:指向有关会话的外部资源链接,此处可能为摄像头详情页。

        t=0 0:表示会话没有固定的开始和结束时间(无限期有效)。

        a=tool:LIVE555 Streaming Media v2016.04.09:工具名称和版本,表明使用LIVE555 Streaming Media工具,版本为v2016.04.09。

        a=type:broadcast:会话类型,此处为broadcast,表示广播会话。

        a=control:*:控制URL通配符,*表示所有控制命令都适用于该会话。

        a=range:npt=0-:表示可用播放范围,npt=0-意味着从会话开始(0秒)到无穷大(即整个会话)。

        a=x-qt-text-nam:H.264 Video Stream:为QuickTime兼容性提供额外的会话名,内容与s字段相同。

        a=x-qt-text-inf:Live video from Camera 1:为QuickTime兼容性提供额外的会话信息,内容与i字段相同。

        m=video 0 RTP/AVP 96:媒体类型为video,表示这是一个视频媒体流。端口为0表示使用动态端口分配,实际端口在SETUP请求中确定。传输协议为RTP/AVP,表示使用RTP(实时传输协议)传输,通过UDP进行封装,并允许在会话中协商负载类型。负载类型为96,表示视频流使用编号为96的负载类型,对应H.264编码。

        c=IN IP4 0.0.0.0:网络类型为IN,表示Internet。地址类型为IP4,表示IPv4地址。地址为0.0.0.0,通常表示接收端地址待定,实际地址在SETUP请求中确定。

        b=AS:500:指定媒体流所需的带宽,此处为500 kbps。

        a=rtpmap:96 H264/90000:映射PT为96的负载类型到H.264编码,采样率为90000 Hz(表示视频帧率为90 kHz,实际为假定的值,视频帧率通常以fps为单位)。

        a=fmtp:96:提供PT为96的H.264编码的详细参数。

        packetization-mode=1:表示采用单NALU(网络抽象层单元)模式。

        profile-level-id=42001E:指定H.264的Profile和Level,此处为Baseline Profile,Level 3.1。

        sprop-parameter-sets:包含两个参数集(SPS和PPS),它们是解码视频流所必需的额外参数。

        a=control:trackID=1:指定媒体流的控制URI,trackID=1表示客户端可以通过此标识符对视频流进行独立的控制操作。

SDP在RTSP中的应用

        在RTSP中,SDP主要通过以下三种方式发挥作用。

        DESCRIBE请求与响应

        客户端发送DESCRIBE请求给服务器,服务器返回包含SDP描述的响应。客户端解析SDP以了解媒体流的详细信息,比如:编解码器、传输协议、端口等,并据此设置后续的SETUP请求。

        媒体协商

        客户端根据SDP提供的媒体格式列表选择支持的编解码器,并在SETUP请求中告知服务器。服务器确认选择后,双方基于选定的编解码器进行媒体传输。

        会话控制

        客户端通过解析SDP中的a=control属性,得知每个媒体流的控制路径,从而能独立地对音频、视频等不同媒体流执行PLAY、PAUSE等操作。

总结

        在RTSP的交互过程中,SDP起着传递会话参数的作用。当客户端向服务器发送DESCRIBE请求时,服务器会返回一个包含SDP描述的响应。这个SDP描述包含了会话的所有必要参数,比如:媒体类型、传输协议、媒体格式等。总的来说,SDP是流媒体传输中不可或缺的一部分。它提供了描述多媒体会话的标准格式和必要参数,使得参与者能够正确地配置和连接到会话。

  • 35
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

希望_睿智

您的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值