一、了解AAC:
AAC是Advanced Audio Coding简写,即高级音频编码,其压缩后的音质效果比MP3要好,是目前主流的音频压缩格式。AAC单独编码出来的流后缀为aac或者m4a(iPhone等产品)。AAC有两种数据传输格式:ADIF和ADTS。
ADIF:整个流数据仅含有一个文件描述头,必须从头的明确定义处开始解析,适合本地播放文件;
ADTS:每一个packet都有同步字,可以从流中的任意位置开始播放,适合流媒体传输;
常见的的 AAC规格有三种:LC-AAC(最基本的),HE-AAC(AACPlus v1),HE-AAC v2(AACPlus v2)。
二、ADTS格式介绍:
ADTS_header | ES_data | ADTS_header | ES_data | … | ADTS_header | ES_data |
---|
可以看到,AAC的数据排布都是如上的方式,每一个packet都有一个头信息,描述了这个packet的采样率、位宽及帧长度等等。头信息都是固定字节数,通常为7字节,如果有CRC信息则为9字节。
ADTS头信息描述如下:
序号 | 描述 | 长度(bits | 说明 |
---|---|---|---|
1 | Syncword | 12 | 固定全部为1 |
2 | MPEG version | 1 | 0: MPEG-4;1:MPEG-2 |
3 | Layer | 2 | 总是0 |
4 | Protection Absent | 1 | 0:无CRC;1:有CRC |
5 | Profile | 2 | 用于描述 MPEG-4的音频类型 |
6 | MPEG-4 Sampling Frequency Index | 4 | 采样率 |
7 | Private Stream | 1 | 0:编码;1:解码 |
8 | MPEG-4 Channel Configuration | 3 | 声道数 |
9 | Originality | 1 | 编码时设置为0,解码忽略 |
10 | Home | 1 | 编码时设置为0,解码忽略 |
11 | Copyrighted Stream | 1 | 编码时设置为0,解码忽略 |
12 | Copyrighted Stream | 1 | 编码时设置为0,解码忽略 |
13 | Frame Length | 13 | 描述当前packet总长度:7/9字节 + Frames |
14 | Buffer Fullness | 11 | 跟码率有关系 |
15 | Number of AAC Frames | 2 | 一包packet包含多少个frame |
16 | CRC | 16 | CRC |
profile关键字的介绍:
在MPEG-2 AAC中定义了3种profile:
MPEG-2 AAC Main
MPEG-2 AAC LC (Low Complexity)
MPEG-2 AAC SSR (Scalable Sampling Rate)
在MPEG-4 AAC中定义了6种profile:
MPEG-4 AAC Main
MPEG-4 AAC LC (Low Complexity)
MPEG-4 AAC SSR (Scalable Sample Rate)
MPEG-4 AAC LTP (Long Term Predicition)
MPEG-4 AAC LD (Low Delay)
MPEG-4 AAC HE (High Efficiency) AACPlusV1/V2(3GPP)
profile决定了每个AAC的packet包含多少帧:
PROFILE | SAMPLES |
---|---|
HE-AAC v1/v2 | 2048 |
AAC-LC | 1024 |
AAC-LD/AAC-ELD | 480/512 |
三、 FFmpeg分离AAC流的指令:
ffmpeg -i input.mp4 -vn -acodec copy output.aac
四、AAC文件精确时长计算:
从前面的header信息中,我们可以获取到每一包packet的总长度,注意这个长度包括header的长度加上AAC帧数的长度,通过遍历整个文件获取到AAC的总帧数,然后使用总帧数去除以描述的采样率,位宽和声道数就可以获取最终的duration了,下面举个例子:
先取前面7个字节:FF F1 0D 80 0D 7F FC
换算成二进制为:1111 1111 1111 0001 0000 1101 1000 0000 0000 1101 0111 1111 1111 1100
取出31~43bit:1101011
换算成十进制为107,遍历十六进制数据可以看到,在下一个ADTS之前,刚好是107个字节。