作者:剛強是什麼 | 来源:互联网 | 2023-09-23 15:02
本节主要介绍下RTP包及Java进行编/解码的操作
首先了解下什么是RTP?
1 RTP协议
以下是百度百科的定义:
实时传输协议(Real-time Transport Protocol或简写RTP)是一个网络传输协议,它是由IETF的多媒体传输工作小组1996年在RFC 1889中公布的。
国际电信联盟ITU-T也发布了自己的RTP文档,作为H.225.0,但是后来当IETF发布了关于它的稳定的标准RFC后就被取消了。它作为因特网标准在RFC 3550(该文档的旧版本是RFC 1889)有详细说明。RFC 3551(STD 65,旧版本是RFC 1890)详细描述了使用最小控制的音频和视频会议。
RTP协议详细说明了在互联网上传递音频和视频的标准数据包格式。它一开始被设计为一个多播协议,但后来被用在很多单播应用中。RTP协议常用于流媒体系统(配合RTSP协议),视频会议和一键通(Push to Talk)系统(配合H.323或SIP),使它成为IP电话产业的技术基础。RTP协议和RTP控制协议RTCP一起使用,而且它是创建在UDP协议上的。
2 RTP协议格式
RTP报文由两部分组成:报头和有效载荷。而报头部分又分为固定头和扩展头部分。
2.1 RTP固定头结构
RTP 固定头结构如图所示。
前 12 个字节出现在每个RTP包中,仅仅在被混合器插入时,才出现 CSRC 识别符列表。
各个域的含义如下所示:
-
版本(V):2 比特,此域定义了 RTP 的版本。此协议定义的版本是 2。(值 1 被 RTP 草案版本使用,值 0 用在最初”vat”语音工具使用的协议中。)
-
填充(P):1 比特,若填料比特被设置,则此包包含一到多个附加在末端的填充比特,填充比特不算作负载的一部分。填充的最后一个字节指明可以忽略多少个填充比特。填充可能用于某些具有固定长度的加密算法,或者用于在底层数据单元中传输多个 RTP 包。
-
扩展(X):1 比特,如果设置为允许的话,固定头结构后面(即包的12个字节后面,有效负载的前面)紧跟着一个扩展头结构,该结构是已定义的一种格式。
-
CSRC 计数(CC):4 比特,CSRC 计数包含了跟在固定头后面 CSRC 识别符的数目。
-
标志(M):1 比特,标志的解释由具体协议规定。它用来允许在比特流中标记重要的事件,如帧边界。
-
负载类型(PT):7 比特,此域定义了负载的格式,由具体应用决定其解释,协议可以规定负载类型码和负载格式之间一个默认的匹配。其他的负载类型码可以通过非 RTP 方法动态定义。RTP发送端在任意给定时间发出一个单独的 RTP 负载类型;此域不用来复用不同的媒体流。
-
序列号(sequence number):16 比特,每发送一个 RTP 数据包,序列号加 1,接收端可以据此检测丢包和重建包序列。序列号的初始值是随机的(不可预测),以使即便在源本身不加密时(有时包要通过翻译器,它会这样做),对加密算法泛知的普通文本攻击也会更加困难。
-
时间戳(timestamp):32 比特,时间戳反映了 RTP 数据包中第一个字节的采样时间。时钟频率依赖于负载数据格式,并在描述文件(profile)中进行描述。也可以通过 RTP 方法对负载格式动态描述。
如果 RTP 包是周期性产生的,那么将使用由采样时钟决定的名义上的采样时刻,而不是读取系统时间。例如,对一个固定速率的音频,采样时钟将在每个周期内增加 1。如果一个音频从输入设备中读取含有 160 个采样周期的块,那么对每个块,时间戳的值增加 160。时间戳的初始值应当是随机的,就像序号一样。几个连续的 RTP 包如果是同时产生的。如:属于同一个视频帧的 RTP 包,将有相同的序列号。
不同媒体流的 RTP 时间戳可能以不同的速率增长。而且会有独立的随机偏移量。因此,虽然这些时间戳足以重构一个单独的流的时间,但直接比较不同的媒体流的时间戳不能进行同步。对于每一个媒体,我们把与采样时刻相关联的 RTP 时间戳与来自于参考时钟上的时间戳(NTP)相关联。因此参考时钟的时间戳就是数据的采样时间。(即:RTP 时间戳可用来实现不同媒体流的同步,NTP 时间戳解决了 RTP 时间戳有随机偏移量的问题。)参考时钟用于同步所有媒体的共同时间。这一时间戳对(RTP 时间戳和 NTP 时间戳),用于判断 RTP 时间戳和 NTP 时间戳的对应关系,以进行媒体流的同步。它们不是在每一个数据包中都被发送,而在发送速率更低的 RTCP 的 SR(发送者报告)中。
如果传输的数据是存贮好的,而不是实时采样得到的,那么会使用从参考时钟得到的虚的表示时间线(virtual presentation timeline)。以确定存贮数据中的每个媒体下一帧或下一
个单元应该呈现的时间。此种情况下 RTP 时间戳反映了每一个单元应当回放的时间。真正的回放将由接收者决定。
-
SSRC:32 比特,用以识别同步源。标识符被随机生成,以使在同一个 RTP 会话期中没有任何两个同步源有相同的 SSRC 识别符。尽管多个源选择同一个 SSRC 识别符的概率很低,所有 RTP 实现工具都必须准备检测和解决冲突。若一个源改变本身的源传输地址,必须选择新的SSRC 识别符,以避免被当作一个环路源。
RTP 包流的源,用 RTP 报头中 32 位数值的SSRC 标识符进行标识,使其不依赖于网络地址。一个同步源的所有包构成了相同计时和序列号空间的一部分,这样接收方就可以把一个同步源的包放在一起,来进行重放。
举些同步源的例子,像来自同一信号源的包流的发送方,如麦克风、摄影机、RTP 混频器就是同步源。一个同步源可能随着时间变化而改变其数据格式,如音频编码。SSRC 标识符是一个随机选取的值,它在特定的 RTP 会话中是全局唯一(globally unique)的。参与者并不需要在一个多媒体会议的所有 RTP 会话中,使用相同的 SSRC 标识符;SSRC 标识符的绑定通过RTCP。如果参与者在一个 RTP 会话中生成了多个流,例如来自多个摄影机,则每个摄影机都必须标识成单独的同步源。
-
CSRC列表:0 到 15 项,每项 32 比特,CSRC 列表识别在此包中负载的所有贡献源。识别符的数目在 CC 域中给定。若有贡献源多于 15 个,仅识别 15 个。CSRC 识别符由混合器插入,并列出所有贡献源的 SSRC 识别符。例如语音包,混合产生新包的所有源的 SSRC 标识符都被列出,以在接收端处正确指示参与者。
若一个 RTP 包流的源,对由 RTP 混频器生成的组合流起了作用,则它就是一个作用源。对特定包的生成起作用的源,其 SSRC 标识符组成的列表,被混频器插入到包的 RTP 报头中。这个列表叫做 CSRC 表。相关应用的例子如,在音频会议中,混频器向所有的说话人(talker)指出,谁的话语(speech)将被组合到即将发出的包中,即便所有的包都包含在同一个(混频器的)SSRC 标识符中,也可让听者(接收者)可以清楚谁是当前说话人。
2.2 RTP扩展头结构
RTP 提供扩展机制以允许实现个性化:某些新的与负载格式独立的功能要求的附加信息在RTP 数据包头中传输。设计此方法可以使其它没有扩展的交互忽略此头扩展。RTP扩展头格式如图所示。
若 RTP 固定头中的扩展比特位置 1,则一个长度可变的头扩展部分被加到 RTP 固定头之后。头扩展包含 16 比特的长度域,指示扩展项中 32 比特字的个数,不包括 4 个字节扩展头(因此零是有效值)。RTP 固定头之后只允许有一个头扩展。为允许多个互操作实现独立生成不同的头扩展,或某种特定实现有多种不同的头扩展,扩展项的前 16 比特用以识别标识符或参数。这 16 比特的格式由具体实现的上层协议定义。基本的 RTP 说明并不定义任何头扩展本身。
3 Java常用的几款RTP开源协议
3.1 java.net.RTP库
需要将该库放入jdk/jre/lib/rt.jar(重新打包)包中
下载地址:http://www.cs.columbia.edu/~hgs/teaching/ais/1998/projects/java_rtp/java_net_RTP.tar.gz
3.2 jlibrtp库
国外编写的开源rtp库
源码下载地址:https://sourceforge.net/projects/jlibrtp/
3.3 efflux库
基于Netty3.2编写的rtp库,支持NAT
下载地址:https://github.com/qq1107053351/efflux
3.4 JMF库
好像已经被放弃了
官网地址:https://www.oracle.com/java/technologies/javase/java-media-framework.html
相关文档:http://wwwinfo.deis.unical.it/fortino/teaching/gdmi0708/materiale/jmf2_0-guide.pdf
3.5 RTP
这是个使用 kaitai struct 托管了一个 rtp (实时传输协议)形式规范。该规范可以自动翻译成各种编程语言,以获得解析库。
RTP (Real-time Transport Protocol): Java parsing library:https://formats.kaitai.io/rtp_packet/java.html
4 RTP编/解码
本地Java开发,主要以efflux为基础,根据其源码 + Netty4.x开发。
5 参考资料
- RFC3550
- RFC5285
- RFC3550 RTP 中文版(转载)
- RTP协议整理
- RTP有效负载(载荷)类型,RTP Payload Type
- RTP协议全解析(H264码流和PS流)
- java RTP 下载
- java 封装rtp流
- Jlibrtp库RTP的java实现