概念
AAC(Advanced Audio Coding),中文名:高级音频编码。出现于1997年,基于MPEG-2的音频编码技术。由Fraunhofer IIS、杜比实验室、AT&T、索尼等公司共同开发,目的是取代MP3格式。
RTMP(Real Time Messaging Protocol)是一种由Adobe开发的实时消息传输协议,主要用于音视频数据的传输。RTMP基于TCP/IP协议,支持多路复用和分包传输,确保数据的高效传输和实时性。
AAC可以作为音频被封装再RTMP进行传输。
AAC
封装格式
概念
ADTS(Audio Data Transport Stream)和ADIF(Audio Data Interchange Format)是AAC音频数据的两种不同的封装格式,它们用于不同的应用场景。
ADTS(Audio Data Transport Stream)
ADTS是一种流式传输格式,常用于流媒体传输和存储在容错较差的环境中,如网络流媒体、数字广播和存储在文件中的AAC音频。
ADTS 格式的特点是它是一个有同步字的比特流,也就是说每一帧都有头信息,这使得解码可以在流的任何位置开始。因此,ADTS 可以在任意帧解码
以下是ADTS的一些特点:
帧同步:每个ADTS帧都包含一个同步字,这使得接收器可以快速定位到下一个帧的开始,这对于流式传输非常重要。
帧头:ADTS帧包含一个帧头,其中包含关于帧的元数据,如采样率、声道数、帧长度等。
流式传输:ADTS格式不需要整个文件来解码,可以逐帧解码,这使得它适合于实时传输。
容错:ADTS设计有一定的容错能力,可以在一定程度上抵抗数据错误。
ADIF(Audio Data Interchange Format)
ADIF是一种非流式传输格式,通常用于存储和文件交换。
以下是ADIF的一些特点:
一次性传输:ADIF格式通常用于存储在文件中,整个文件需要一次性传输,因为它不包含帧级别的同步信息。
文件头:ADIF文件开始处有一个文件头,其中包含整个文件的元数据,如采样率、声道配置等。
非流式:ADIF不适合流式传输,因为它没有帧级别的同步信息,这使得它在传输过程中难以定位帧边界。
无容错:由于ADIF不包含帧级别的同步信息,因此它对数据错误更敏感。
在RTMP中传输
概念
在rtmp传输,虽然可以在rtmp body中传输包含ADTS头的aac帧数据,但是按照规范,并不直接这样弄,而是有另外一套定义。
在RTMP中,AAC音频帧可以是以下两种类型之一:
AAC Sequence Header
AAC Raw Frame
搭建测试环境
搭建ngxin_rtmp的rtmp服务器,使用以下ffmpeg命令进行rtmp推流:
ffmpeg -re -i /opt/ServerFiles/UploadFile/official/1/0c0f6734834ecaa7e35f8aceafba1be2.mp3 -ac 1 -acodec aac -f flv rtmp://192.168.5.82:1935/live/43302120000000101010101202412130017
使用ffplay进行播放:
ffplay rtmp://192.168.5.82:1935/live/43302120000000101010101202412130017
抓包分析
在开始播放前,我们进行抓包分析。
使用ip.src 192.168.5.82 and tcp.port 1935过滤下,其中82为rtmp服务器,175为拉流ffplay客户端。
找到抓包的第一包音频数据(AAC Sequence Header):
af:这是RTMP音频消息的类型标志,af 表示这是一个AAC音频帧。
00:AAC音频帧的保留字节,用来标识AAC音频帧的类型,00代表为Sequence Header,01代表为Raw Frame(裸帧)。
12:这是音频配置信息的一部分,它描述了AAC音频流的配置,如采样率、频道配置等。
12 的二进制表示是 00010010,其中:
最高位(第8位)是 0,表示这是一个AAC Sequence Header。
接下来的4位(第7-4位)通常表示AAC对象的类型(如LC、HE-AAC等)。
接下来的2位(第3-2位)表示采样率索引。
最后的1位(第1位)表示频道配置。
08:这是音频配置信息的第二部分。
56 e5:这是音频配置信息的剩余部分。
00:填充字节,无实际作用。
找到抓包的除第一包外的任意音频数据(AAC Raw Frame):
af:这是RTMP音频消息的类型标志,af 表示这是一个AAC音频帧。
01:AAC音频帧的保留字节,用来标识AAC音频帧的类型,00代表为Sequence Header,01代表为Raw Frame(裸帧)。
后面数据(01~0e):实际的AAC音频数据。
总结
为什么rtmp中的aac帧,不以携带adts头的方式,而是用AAC Sequence Header,AAC Raw Frame的方式来区分?
RTMP(Real-Time Messaging Protocol)是一种用于低延迟通信的网络协议,常用于直播和视频会议等实时数据传输场景。在RTMP中,AAC音频帧不使用ADTS头的原因有几个:
效率:ADTS头在每个AAC帧中都会重复相同的元数据,这在大流量的实时传输中是不必要的,会增加带宽消耗。RTMP通过使用AAC Sequence Header和AAC Raw Frame的方式,仅在开始时发送一次音频配置信息,之后只发送音频数据,从而减少了冗余信息。
简化解析:RTMP协议有自己的帧定界机制,因此不需要ADTS头来帮助定位AAC帧的边界。RTMP的帧格式已经包含了足够的信息来处理流中的不同类型的帧(如音频、视频和数据)。
协议设计:RTMP协议是为了在网络上高效传输多媒体内容而设计的,它包含了对音频和视频流的特殊处理。AAC Sequence Header相当于ADTS头中的配置信息,但它只发送一次,而AAC Raw Frames只包含音频数据,不需要额外的元数据。
以下是为什么RTMP选择使用AAC Sequence Header和AAC Raw Frame的原因:
AAC Sequence Header:这个特殊的帧只包含一次,它携带了AAC音频流的配置信息,如采样率、声道数、AAC profile等。这相当于ADTS头中的配置信息部分。一旦客户端接收到这个header,它就知道了如何解码后续的音频帧。
AAC Raw Frame:这些帧包含实际的音频采样数据,不包含配置信息。由于客户端已经通过Sequence Header获得了必要的配置信息,因此可以连续解码Raw Frames而无需额外的开销。
总的来说,RTMP中的这种设计是为了减少冗余数据传输,提高实时传输的效率,并且更好地适应RTMP协议的帧定界和数据处理机制。
参考
https://www.cnblogs.com/8335IT/p/18208384
https://blog.csdn.net/jctian000/article/details/93205521
https://blog.csdn.net/dfb714620427/article/details/61203274