背景:
在学习投屏专题开发相关课程时候,不可以避免的就是需要了解音视频相关的知识点,前面已经分享过了音视频的相关基础知识,也详细介绍了h264相关,本节来详细介绍一下aac,这个也是在音视频里很重要的基础知识。
AAC 简介
AAC(Advanced Audio Coding)是一种现代的音频编码技术,用于数字音频的传输和存储领域。AAC是MPEG-2和MPEG-4标准中的一部分,可提供更高质量的音频数据。
AAC被认为是MP3的继任者。AAC比MP3的压缩率更高,压缩后的文件越小,二是保真性比MP3强。ACC最开始是基于MPEG-2的音频编码技术,MPEG-4标准出现后,AAC重新集成了其特性,加入了SBR技术和PS技术。
特点:
更好的声音质量和更低的压缩比,减少了由于压缩而引入的失真和噪音。
支持多种采样率、声道数和比特率。
具有很好的灵活性和可扩展性。
AAC是一种现代的音频编码技术,具有高质量的音频数据、较低的比特率、灵活性和可扩展性等优点。由于其广泛应用于数字音频传输和存储领域,它已经成为音频压缩领域的标准之一。
AAC音频文件格式
AAC的音频文件格式有ADIF & ADTS:
ADIF:
Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。
ADTS:
Audio Data Transport Stream 音频数据传输流。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。
总结:
ADTS可以在任意帧解码,也就是说它每一帧都有头信息。ADIF只有一个统一的头,所以必须得到所有的数据后解码。且这两种的header的格式也是不同的,目前一般编码后的和抽取出的都是ADTS格式的音频流。
ADTS
在ADTS文件中,每个AAC音频帧都以一个长度为7或9个字节的ADTS帧头开始,其中包含了同步标记、帧大小、采样率、声道数和其他元数据。接下来是AAC编码的原始音频数据,这些数据会被添加到ADTS帧中,以形成完整的音频帧。
具体流描述如下网图所示:
ADTS的头信息分为:
ADTS的头信息为两部分组成,其一为固定头信息,紧接着是可变头信息。固定头信息中的数据每一帧都相同,而可变头信息则在帧与帧之间可变。(注意这里可变头不是说头的字节占位可变,是指的头的里面内容值可变)
固定头信息(adts_fixed_header,28bits)和可变头信息(adts_variable_header,28bits)两部分。
固定头:
syncword :同步头代表着1个ADTS帧的开始,所有bit置1,即 0xFFF
ID:MPEG标识符,0标识MPEG-4,1标识MPEG-2
Layer: 直接置00,解码时忽略这个参数
protection_absent:表示是否误码校验。1 no CRC , 0 has CRC
profile:AAC 编码级别, 0: Main Profile, 1:LC(最常用), 2: SSR, 3: reserved.
sampling_frequency_index:采样率标识,重要!
Private bit:直接置0,解码时忽略这个参数
channel_configuration: 声道数标识,重要
original_copy: 直接置0,解码时忽略这个参数
home:直接置0,解码时忽略这个参数
重点关注常见两个字段,一个采样率一个声道数:
- sample_freq_index : 4代表44100hz
- channel_configuration: 2表示双声道
可变头:
copyright_identification_bit: 直接置0,解码时忽略这个参数
copyright_identification_start: 直接置0,解码时忽略这个参数
aac_frame_lenght: ADTS帧长度包括ADTS长度和AAC声音数据长度的和。即 aac_frame_length = (protection_absent == 0 ? 9 : 7) + audio_data_length非常重要
adts_buffer_fullness: 当设置为0x7FF时表示时可变码率
number_of_raw_data_blocks_in_frames: 当前音频包里面包含的音频编码帧数,为0代表1frame.
AAC ES 详解
Elementary Stream
Elementary Stream是一种仅包含单一媒体类型(音频或视频)数据的格式。在音频ES中,不包含任何额外的元数据或者是多媒体容器封装信息,仅仅是纯粹的音频数据。对于AAC而言,ES通常指裸的AAC码流。
AAC ES的处理
要处理AAC ES,开发者需要使用各种编解码库,如FFmpeg的库来解码或编码AAC流。流程大概分为这几步:
编码:将原始音频信号(PCM数据)通过AAC编码器转换成AAC ES。
解码:将AAC ES通过AAC解码器转换回原始音频信号(PCM数据)用于播放。
实战:AAC解析
1、直接16进制手动查表解析
16进制方式查看aac文件
固定头信息 16进制
ff f9 50 8
变成二进制
1111 1111 1111 1001 0101 0000 1000
查询上面的表获取对应两个关键值:
固定头信息得到aac中采样率44100 双声道
可变头信息 16进制
0 2e 7f fc
0000 0010 1110 0111 1111 1111 1100
得出有效信息:
adts这个frame大小为0x173=371,只有一个aac的帧
2、代码解析
这个部分可以参考雷神blog
https://blog.youkuaiyun.com/leixiaohua1020/article/details/50535042
刚好代码验证一下手动查表是否正确:
同时也可以使用官方ffmpeg ,ffprop工具看看:
ffmpeg -i nocturne.aac
Input #0, aac, from 'nocturne.aac':
Duration: 00:00:30.04, bitrate: 127 kb/s
Stream #0:0: Audio: aac (LC), 44100 Hz, stereo, fltp, 127 kb/s
ffprobe -i nocturne.aac -show_frames
具体详情试看方式:
投屏专题部分:
https://mp.weixin.qq.com/s/IGm6VHMiAOPejC_H3N_SNg
更多framework技术干货,请关注下面“千里马学框架”