手把手教你做投屏AAC的详细介绍-千里马带你学framework

145 阅读5分钟

背景:

在学习投屏专题开发相关课程时候,不可以避免的就是需要了解音视频相关的知识点,前面已经分享过了音视频的相关基础知识,也详细介绍了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,解码时忽略这个参数

重点关注常见两个字段,一个采样率一个声道数:

  1. sample_freq_index : 4代表44100hz
  2. 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 blog.csdn.net/leixiaohua1…

刚好代码验证一下手动查表是否正确: 在这里插入图片描述

同时也可以使用官方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 在这里插入图片描述 具体详情试看方式: 投屏专题部分: mp.weixin.qq.com/s/IGm6VHMiA… 在这里插入图片描述

更多framework技术干货,请关注“千里马学框架”