ffmpeg编码aac文件通过extradata添加adts头

转载一篇文章:

1:ffmpeg的aac通过pcm编码得到的数据是latm的,如果需要存成adts能播的文件需要加头,ffmpeg并没有给相关的filter,通过extradata自己做解析加头;

2:aac_adtstoasc这个filter是把adts转成latm;

3:h264_mp4toannexb是将4个字节长度前缀的h264转成00 00 00 01 前缀的能播放的h264;

下面为转载;

转载链接:https://blog.csdn.net/lichen18848950451/article/details/78266054

根据雷神的代码,可以获取mp3等音频文件。网址是:http://blog.csdn.net/leixiaohua1020/article/details/39767055

同时,还可以把数据回调出去,进行其他的处理,是没有任何问题的。可是,现在的视频文件大都是H264+AAC。可是,根据雷神的代码是获取的数据,在播放器上播放失败。这是由于获取的aac数据是缺少adts文件头,添加上去就可以了。说着容易,可是做就难了。

网上的文章大都是介绍adts的,进行处理的代码很少。不过还是找到了,网址是http://blog.csdn.net/leixiaohua1020/article/details/39767055

不过,他的代码只是提供一些写好的函数,关于如何调用,自己还是花了不少时间研究。


typedef struct  
 
{
      int write_adts;  
      int objecttype;  
      int sample_rate_index;  
      int channel_conf;  
 
}ADTSContext;  
以上是定义的一个结构体。

int aac_decode_extradata(ADTSContext *adts, unsigned char *pbuf, int bufsize)  
{  
      int aot, aotext, samfreindex;  
      int i, channelconfig;  
      unsigned char *p = pbuf;  
      if (!adts || !pbuf || bufsize<2)  
      {  
            return -1;  
      }  
      aot = (p[0]>>3)&0x1f;  
      if (aot == 31)  
      {  
            aotext = (p[0]<<3 | (p[1]>>5)) & 0x3f;  
            aot = 32 + aotext;  
            samfreindex = (p[1]>>1) & 0x0f;   
            if (samfreindex == 0x0f)  
            {  
                  channelconfig = ((p[4]<<3) | (p[5]>>5)) & 0x0f;  
            }  
            else  
            {  
                  channelconfig = ((p[1]<<3)|(p[2]>>5)) & 0x0f;  
            }  
      }  
      else  
      {  
            samfreindex = ((p[0]<<1)|p[1]>>7) & 0x0f;  
            if (samfreindex == 0x0f)  
            {  
                  channelconfig = (p[4]>>3) & 0x0f;  
            }  
            else  
            {  
                  channelconfig = (p[1]>>3) & 0x0f;  
            }  
      }  
#ifdef AOT_PROFILE_CTRL  
      if (aot < 2) aot = 2;  
#endif  
      adts->objecttype = aot-1;  
      adts->sample_rate_index = samfreindex;  
      adts->channel_conf = channelconfig;  
      adts->write_adts = 1;  
      return 0;  
}  
上面的这个函数用来获取用来获取adts所需要的信息。第一个参数就不必说了,关键是后两个参数。是结构体AVCodecContext中的两个元素:
uint8_t *extradata; int extradata_size;adts中的信息在extradata中。通过处理,就可以获得adts的信息。


 int aac_set_adts_head(ADTSContext *acfg, unsigned char *buf, int size)  
{         
      unsigned char byte;    
      if (size < ADTS_HEADER_SIZE)  
      {  
            return -1;  
      }       
      buf[0] = 0xff;  
      buf[1] = 0xf1;  
      byte = 0;  
      byte |= (acfg->objecttype & 0x03) << 6;  
      byte |= (acfg->sample_rate_index & 0x0f) << 2;  
      byte |= (acfg->channel_conf & 0x07) >> 2;  
      buf[2] = byte;  
      byte = 0;  
      byte |= (acfg->channel_conf & 0x07) << 6;  
      byte |= (ADTS_HEADER_SIZE + size) >> 11;  
      buf[3] = byte;  
      byte = 0;  
      byte |= (ADTS_HEADER_SIZE + size) >> 3;  
      buf[4] = byte;  
      byte = 0;  
      byte |= ((ADTS_HEADER_SIZE + size) & 0x7) << 5;  
      byte |= (0x7ff >> 6) & 0x1f;  
      buf[5] = byte;  
      byte = 0;  
      byte |= (0x7ff & 0x3f) << 2;  
      buf[6] = byte;     
      return 0;  
}  
传入的第一个参数就是上面第一个函数获取的结构体,第二个参数是自己传入的一个指针,用来获取adts。第三个参数是长度,是每个packet的size。
下面是伪代码,希望对大家有所帮助吧:


ADTSContext               AdtsCtx;
AVCodecContext*       pCodecCtx;
while(av_read_frame(,&packet)>=0)
{
    aac_decode_extradata(&AdtsCtx, pCodecCtx->extradata, pCodecCtx->extradata_size);
    char* pAdts = new char [7];
    aac_set_adts_head(&AdtsCtx, pAdts, packet.size);
    fwrite(pAdts, 1, 7, fp);
    fwrite(packet.data, 1, packet.size, fp);
}

————————————————
版权声明:本文为CSDN博主「那年晴天」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lichen18848950451/article/details/78266054

 

上述有不足之处请各位指正。

如有错误请指正:

交流请加QQ群:62054820
QQ:379969650.

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用FFmpeg工具分析AACextradata数据,可以按照以下步骤进行: 1. 使用FFmpeg工具打开AAC音频文件,例如: ``` ffmpeg -i input.aac ``` 2. 在输出信息中找到AAC流所在的音频流,通常以“Stream #0:1”表示。复制该流的完整信息,包括编解码器信息、采样率、通道数等。 3. 使用FFmpeg工具分离AAC流到一个单独的文件中,例如: ``` ffmpeg -i input.aac -map 0:1 -c copy -f adts output.aac ``` 其中,“-map 0:1”表示只提取第二个音频流(即AAC流),而“-c copy -f adts”表示将该流复制到一个ADTS格式的文件中。 4. 使用FFmpeg工具查看输出的ADTS文件的详细信息,例如: ``` ffmpeg -i output.aac ``` 5. 在输出信息中找到“Audio”部分的信息,其中包括AACextradata,通常以“Audio: aac (LC), 48000 Hz, 2 channels, fltp, 139 kb/s”表示。复制该extradata信息。 6. 将复制的extradata信息转换为16进制格式,并保存到一个文件中,例如: ``` echo -n "XXXXXXX" | xxd -r -p > extradata.bin ``` 其中,“XXXXXXX”为复制的extradata信息。 7. 使用FFmpeg工具将转换后的extradata文件应用到原始AAC文件中,例如: ``` ffmpeg -i input.aac -map 0:1 -c copy -bsf:a aac_adtstoasc -codec:a copy -flags +global_header -f segment -segment_time 10 -segment_format_options movflags=+faststart -segment_list test.m3u8 -segment_list_type m3u8 -segment_list_flags +live -segment_list_size 10 -segment_list_entry_prefix test/ -segment_start_number 0 -metadata:s:a:0 handler_name="ChitGPT" -metadata:s:a:0 language=eng -metadata:s:a:0 title="ChitGPT Audio" -metadata:s:a:0 extradata_file=extradata.bin -y test%03d.aac ``` 其中,“-metadata:s:a:0 extradata_file=extradata.bin”表示将复制的extradata文件应用到AAC流中。 通过以上步骤,你就可以使用FFmpeg工具分析AACextradata数据了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值