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

  typedef struct _AdtsHeader

  {

  unsigned int nSyncWord;

  unsigned int nId;

  unsigned int nLayer;

  unsigned int nProtectionAbsent;

  unsigned int nProfile;

  unsigned int nSfIndex;

  unsigned int nPrivateBit;

  unsigned int nChannelConfiguration;

  unsigned int nOriginal;

  unsigned int nHome;

  unsigned int nCopyrightIdentificationBit;

  unsigned int nCopyrigthIdentificationStart;

  unsigned int nAacFrameLength;

  unsigned int nAdtsBufferFullness;

  unsigned int nNoRawDataBlocksInFrame;

  } AdtsHeader;

  int _tmain(int argc, _TCHAR* argv[])

  {

  FILE *fd = fopen("D:\ffmpeg-4.1-tool\bin\audio.aac", "rb+");

  if (fd == NULL)

  {

  printf("fopen is failed,err %d

", GetLastError());

  }

  char adts[7];

  int adtslen = 7;

  int ret = fread(adts, adtslen, 1, fd);

  if (ret != 1)

  {

  printf("fread is failed,err %d

", GetLastError());

  }

  char *p = adts;

  GetAdtsSpecificConfig(p, &tAdtsHeader);

  printf("AAC key param:

");

  printf("id: %d

", tAdtsHeader.nId);

  printf("layer: %d

", tAdtsHeader.nLayer);

  printf("ProtectionAbsent: %d

", tAdtsHeader.nProtectionAbsent);

  printf("Profile: %d

", tAdtsHeader.nProfile);

  printf("SfIndex: %d

", tAdtsHeader.nSfIndex);

  printf("PrivateBit: %d

", tAdtsHeader.nPrivateBit);

  printf("ChannelConfiguration: %d

", tAdtsHeader.nChannelConfiguration);

  printf("Original: %d

", tAdtsHeader.nOriginal);

  printf("nHome: %d

", tAdtsHeader.nHome);

  printf("nCopyrigthIdentificationStart: %d

", tAdtsHeader.nCopyrigthIdentificationStart);

  printf("nAacFrameLength: %d

", tAdtsHeader.nAacFrameLength);

  printf("nAdtsBufferFullness: %d

", tAdtsHeader.nAdtsBufferFullness);

  printf("NoRawDataBlocksInFrame: %d

", tAdtsHeader.nNoRawDataBlocksInFrame);

  getchar();

  return 0;

  }

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

推荐阅读