一.基本概念AAC:即MPEG-2 Advanced Audio Coding,分为流格式和文件格式文件格式主要用于文件存储和文件播放,流格式主要用于流媒体在线播放,今天小编就来说说关于aac格式怎么播放音频?下面更多详细答案一起来看看吧!

aac格式怎么播放音频(AAC音频格式详解和实战解析)

aac格式怎么播放音频

一.基本概念

AAC:即MPEG-2 Advanced Audio Coding,分为流格式和文件格式。文件格式主要用于文件存储和文件播放,流格式主要用于流媒体在线播放。

文件格式:adif格式

adif格式

该格式特点:只有开头有一个头部信息,后面都是AAC裸数据。适应磁盘存储和文件播放

流格式:adts_frame格式

adts_frame格式

该格式特点:每一帧数据=固定头(fixed_header) 可变头(variable_header) 帧数据(raw_data),适合流媒体在线播放。

流式AAC可以简单理解如下图:

固定头如下:

syncword 同步字The bit string ‘1111 1111 1111’,说明一个ADTS帧的开始。

ID MPEG 标示符, 设置为1.

layer Indicates which layer is used. Set to ‘00’

protection_absent 表示是否误码校验

profile 表示使用哪个级别的AAC,如01 Low Complexity(LC)--- AACLC

sampling_frequency_index 表示使用的采样率下标

channel_configuration 表示声道数

frame_length 一个ADTS帧的长度包括ADTS头和raw data block.

可变头如下:

adts_buffer_fullness 0x7FF 说明是码率可变的码流

number_of_raw_data_blocks_in_frame

表示ADTS帧中有number_of_raw_data_blocks_in_frame 1个AAC原始帧.

所以说number_of_raw_data_blocks_in_frame == 0 表示说ADTS帧中有一个AAC数据块并不是说没有。

其他字段为定义,可以忽略,。

Raw数据块:

一个帧包含1024个采样

Duration算法:

一个AAC原始帧包含一段时间内1024个采样及相关数据。

一个AAC音频帧的播放时间=一个AAC帧对应的采样样本的个数/采样率。总时间t=总帧数x一个AAC音频帧的播放时间。

时间t=总帧数x一个AAC音频帧的播放时间。

二. 实战演练

1)使用ffmpeg抽取一个mp4文件中的aac音频如下:

ffmpeg.exe -i CCTV-2-dszg-1.mp4 -vn -y -acodec copy audio.aac

2)利用工具分析该aac音频固定头和可变头字段如下:

adts头解析

3)使用程序代码解析

#include"stdafx.h" #include<windows.h> typedefstruct_AdtsHeader { unsignedintnSyncWord; unsignedintnId; unsignedintnLayer; unsignedintnProtectionAbsent; unsignedintnProfile; unsignedintnSfIndex; unsignedintnPrivateBit; unsignedintnChannelConfiguration; unsignedintnOriginal; unsignedintnHome; unsignedintnCopyrightIdentificationBit; unsignedintnCopyrigthIdentificationStart; unsignedintnAacFrameLength; unsignedintnAdtsBufferFullness; unsignedintnNoRawDataBlocksInFrame; }AdtsHeader; int_tmain(intargc,_TCHAR*argv[]) { FILE*fd=fopen("D:\\ffmpeg-4.1-tool\\bin\\audio.aac","rb "); if(fd==NULL) { printf("fopenisfailed,err%d\n",GetLastError()); } charadts[7]; intadtslen=7; intret=fread(adts,adtslen,1,fd); if(ret!=1) { printf("freadisfailed,err%d\n",GetLastError()); } char*p=adts; GetAdtsSpecificConfig(p,&tAdtsHeader); printf("AACkeyparam:\n"); printf("id:%d\n",tAdtsHeader.nId); printf("layer:%d\n",tAdtsHeader.nLayer); printf("ProtectionAbsent:%d\n",tAdtsHeader.nProtectionAbsent); printf("Profile:%d\n",tAdtsHeader.nProfile); printf("SfIndex:%d\n",tAdtsHeader.nSfIndex); printf("PrivateBit:%d\n",tAdtsHeader.nPrivateBit); printf("ChannelConfiguration:%d\n",tAdtsHeader.nChannelConfiguration); printf("Original:%d\n",tAdtsHeader.nOriginal); printf("nHome:%d\n",tAdtsHeader.nHome); printf("nCopyrigthIdentificationStart:%d\n",tAdtsHeader.nCopyrigthIdentificationStart); printf("nAacFrameLength:%d\n",tAdtsHeader.nAacFrameLength); printf("nAdtsBufferFullness:%d\n",tAdtsHeader.nAdtsBufferFullness); printf("NoRawDataBlocksInFrame:%d\n",tAdtsHeader.nNoRawDataBlocksInFrame); getchar(); return0; }

由此可见:代码读出来的参数和工具分析参数一致。

更多更详细资源请关注公众号:AV_Chat