根据雷神的代码,可以获取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); }