html5采集音频转aac,(转) 通过ffmpeg将aac格式转换成wav格式

http://blog.csdn.net/ajaxhe/article/details/6761678

这是一个很简单的小程序,但也让我这个初学者折腾了好几天,走算是入门了,总结下学习的过程,希望能够初学者能有所帮助。

看源代码,首先得让让它跑起来。看了ffmpeg提供源码api-example.c,很好的入门程序,虽然对视频编解码十分顺利,但是源码提供的音频解码是有问题的,mp2文件不能正常的解码,这是很让人沮丧,特别是对一个初学者来说。

在对源程序进行单步调试的过程中,问题定位在了这个语句上:

avcodec_decode_audio3(in_ast_cctx, (int16_t *)outbuf, &out_size, &packet);

再看前面看看,有这样两行语句。

avpkt.data = inbuf;

avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);

这两行代码的意思很明确,就是将待解码数据数据放入avpkt.data这个缓冲区中,通过avcodec_decode_audio3对其进行解码。这些看起来都很合理,但问题出在哪里呢?

且看video_decode_example函数中这段话:

问题已经很明朗了,通过在填充avpkt.data之前,需要进行一个预处理,即通过AAC帧中的同步字(帧头的12bit--0xFFF)来找出完整的一帧。

那就写预处理程序吧,转念一想,ffmpeg这么多行代码,不提供AAC帧解析的API也没有天理了,继续google,找到了下面一篇文章:

文章的标题是:利用libavcodec和libavformat对音频转码。附上了很详细的代码解析,我写的源程序大部分基于该文章。

下面就是test.c文件中的源码

#include

#include "libavformat/avformat.h"

#include "libavcodec/avcodec.h"

#include "audio.h"

#include "neaacdec.h"

intmain(intargc,char**argv)

{

AVFormatContext *in_fctx;

AVCodecContext *in_ast_cctx;

AVCodec *in_ast_codec;

AVPacket packet;

audio_file *aufile;

char*outbuf = (char*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);

intout_size;

intsamples;

//char *filename = "C:\\Users\\ajaxhe\\Desktop\\AudioCodec\\ffmpeg\\MyProject\\output_example2\\Debug\\higher1.aac";

char*filename;

char*wavfile ="debug_test.wav";

//char *wavfile;

intret = 0;

intast_idx = -1;

inti, first_time = 1;

if(argc == 3){

filename = argv[1];

wavfile = argv[2];

}

else{

printf("usage: output_example.exe infile.aac outfile.aac\n");

return-1;

}

av_register_all();

in_fctx = av_alloc_format_context();

ret = av_open_input_file(&in_fctx, filename, NULL, 0, NULL);

if( ret != 0 ){

printf("open input audio file[%s] fail", filename);

return-1;

}

ret = av_find_stream_info(in_fctx);

if( ret 

printf("find stream in audio file[%s] fail", filename);

return-1;

}

//dump_format(in_fctx, 0, filename, 0);

//这里我们假设,如果一个文件包含多个音频流,

//只对第一个音频流做转码,而对于视频流则忽略

for(i=0; inb_streams; ++i){

if(in_fctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO){

ast_idx=i;

break;

}

}

if(ast_idx == -1){

printf("there is not any audio stream in [%s]", filename);

return0;

}

else{

printf("find audio stream in [%s]\n", filename);

}

in_ast_cctx = in_fctx->streams[ast_idx]->codec;

in_ast_codec = avcodec_find_decoder(in_ast_cctx->codec_id);

if(!in_ast_codec){

printf("find decoder for codec_id[%d] fail, file[%s]", in_ast_cctx->codec_id, filename);

return-1;

}

ret = avcodec_open(in_ast_cctx, in_ast_codec);

if(ret >= 0){

printf("open codec[name:%s] for stream[idx:%d] of file[%s]\n", in_ast_codec->name, ast_idx, filename);

}

av_init_packet(&packet);

while(av_read_frame(in_fctx, &packet) >= 0){

out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;

ret = avcodec_decode_audio3(in_ast_cctx, (int16_t *)outbuf, &out_size, &packet);

if(first_time){

aufile = open_audio_file(wavfile, in_ast_cctx->sample_rate, in_ast_cctx->channels, FAAD_FMT_16BIT, OUTPUT_WAV, 0);

first_time = 0;

}

samples = in_ast_cctx->frame_size * in_ast_cctx->channels;

write_audio_file(aufile, outbuf, samples, 0);

}

if(!first_time)

close_audio_file(aufile);

avcodec_close(in_ast_cctx);

av_free(in_ast_cctx);

return0;

}

由于仅仅是一个简单的小程序,只写了个main函数,还请见谅。

#include "audio.h"

#include "neaacdec.h"

这两个头文件是我从faad2源代码中弄过来,时间仓促,没有来得及自己整理下,需要的整个工程朋友就直接从下面这个链接下载吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值