#pragma warning(push)
#pragma warning(disable : 4101 4244)
int ConverAudio(const char* input_file, const char* output_file, int samples_rate, int channel)
{
AVFormatContext *infmt_ctx;
unsigned int i = 0;
初始化
avcodec_register_all();
avdevice_register_all();
av_register_all();
infmt_ctx = av_alloc_format_context();
//打开输入文件
if(av_open_input_file(&infmt_ctx, input_file, NULL, 0, NULL)!=0)
{
//debug_string("can't open input file/n");
return -1;
}
//取出流信息
if(av_find_stream_info(infmt_ctx) <0)
{
//debug_string("can't find suitable codec parameters/n");
return -2;
}
//dump_format(infmt_ctx, 0, input_file, 0); //列出输入文件的相关流信息
// 查找音频流信息
int audioindex=-1;
for(unsigned int j = 0; j < infmt_ctx->nb_streams; j++)
{
if(infmt_ctx->streams[j]->codec->codec_type == CODEC_TYPE_AUDIO)
{
audioindex=j;
break;
}
}
if(audioindex == -1) //没有找到音频流
{
//debug_string("can't find audio stream/n");
return -3;
}
AVCodecContext *incode_ctx;
AVCodec *incodec;
incode_ctx = infmt_ctx->streams[audioindex]->codec;
//找到合适的音频解码器
incodec = avcodec_find_decoder(incode_ctx->codec_id);
if(incodec == NULL)
{
//debug_string("can't find suitable audio decoder/n");
return -4;
}
//打开该音频解码器
if(avcodec_open(incode_ctx, incodec) < 0)
{
//debug_string("can't open the audio decoder/n");
return -5;
}
输出
/* 解析输出文件的格式 */
AVOutputFormat *outfmt = guess_format(NULL, output_file, NULL);
if (!outfmt)
{
//printf("Could not deduce output format from file extension: using MPEG./n");
outfmt = guess_format("mpeg", NULL, NULL);
}
if (!outfmt)
{
//debug_string("Could not find suitable output format/n");
return -6;
}
outfmt->audio_codec = CODEC_ID_MP3;
/* allocate the output media context */
AVFormatContext *outfmt_ctx = av_alloc_format_context();
if (!outfmt_ctx)
{
//debug_string("Memory error/n");
return -7;
}
/* 保存输出文件的格式 */
outfmt_ctx->oformat = outfmt;
snprintf(outfmt_ctx->filename, sizeof(outfmt_ctx->filename), "%s", output_file);
/*add the audio and video streams using the default format codecs and initialize the codecs*/
/* 输出文件的视频流编码器ID */
AVCodecContext *outcode_ctx;
AVCodec *outcodec;
AVStream *audio_st = NULL/*, *video_st*/;
//double audio_pts, video_pts;
//if (outfmt->video_codec != CODEC_ID_NONE) {
// video_st = add_video_stream(outfmt_ctx, outfmt->video_codec);
//}
/* 输出文件的音频流编码器ID */
if (outfmt->audio_codec != CODEC_ID_NONE)
{
audio_st = av_new_stream(outfmt_ctx, 1);
outcode_ctx = audio_st->codec;
outcode_ctx->codec_id = outfmt->audio_codec;
outcode_ctx->codec_type = CODEC_TYPE_AUDIO;
//oAcc->bit_rate =inCodecCtx->bit_rate ;
outcode_ctx->sample_rate = samples_rate > 0 ? samples_rate : incode_ctx->sample_rate;
//outcode_ctx->time_base.den = 1;
//outcode_ctx->time_base.num = outcode_ctx->sample_rate;
outcode_ctx->channels = channel > 0 ? channel : incode_ctx->channels;
outcode_ctx->block_align = incode_ctx->block_align;
if(outcode_ctx->block_align == 1 && outcode_ctx->codec_id == CODEC_ID_MP3)
outcode_ctx->block_align = 0;
}
/* 设置输出参数 */
if (av_set_parameters(outfmt_ctx, NULL) < 0)
{
//debug_string("Invalid output format parameters/n");
return -8;
}
/* 列出输出文件的格式信息 */
dump_format(outfmt_ctx, 0, output_file, 1);
strcpy(outfmt_ctx->title, infmt_ctx->title);
strcpy(outfmt_ctx->author, infmt_ctx->author);
strcpy(outfmt_ctx->copyright, infmt_ctx->copyright);
strcpy(outfmt_ctx->comment, infmt_ctx->comment);
strcpy(outfmt_ctx->album, infmt_ctx->album);
outfmt_ctx->year = infmt_ctx->year;
outfmt_ctx->track = infmt_ctx->track;
strcpy(outfmt_ctx->genre, infmt_ctx->genre);
//dump_format(oc,0,output_file_name,1);//列出输出文件的相关流信息
//找到合适的音频编码器
outcodec = avcodec_find_encoder(outfmt_ctx->oformat->audio_codec);//CODEC_ID_AAC
if(!outcodec)
{
//debug_string("can't find suitable audio encoder/n");
return -9;
}
if(avcodec_open(outcode_ctx, outcodec) <0)
{
//debug_string("can't open the output audio codec");
return -10;
}
/* 如果输出文件不存在, 则创建输出文件 */
if (!(outfmt->flags & AVFMT_NOFILE))
{
if (url_fopen(&outfmt_ctx->pb, output_file, URL_WRONLY) < 0)
{
//debug_string("Could not open '%s'/n", output_file);
return -11;
}
}
int ret = 0;
uint8_t* outbuf;
uint8_t* audiobuf;
uint8_t* resamplebuf;
uint8_t* databuf;
int outbuf_len = AVCODEC_MAX_AUDIO_FRAME_SIZE;;
int audiobuf_len = AVCODEC_MAX_AUDIO_FRAME_SIZE;
int resamplebuf_len = AVCODEC_MAX_AUDIO_FRAME_SIZE;
int64_t pt;
outbuf = (uint8_t*)av_malloc(outbuf_len);
audiobuf = (uint8_t*)av_malloc(audiobuf_len);
resamplebuf = (uint8_t*)av_malloc(resamplebuf_len);
databuf = (uint8_t*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
AVFifoBuffer fifo;
av_fifo_init(&fifo, av_fifo_size(&fifo)+AVCODEC_MAX_AUDIO_FRAME_SIZE);
ReSampleContext* resample = audio_resample_init(outcode_ctx->channels,
incode_ctx->channels, outcode_ctx->sample_rate, incode_ctx->sample_rate);
av_write_header(outfmt_ctx);
AVPacket packet;
while(av_read_frame(infmt_ctx, &packet) >= 0)
{
pt = packet.pts;
if(outcode_ctx->codec_id != CODEC_ID_NONE
&& packet.stream_index == audio_st->index)
{
if(incode_ctx->codec_id == outcode_ctx->codec_id
&& incode_ctx->sample_rate == outcode_ctx->sample_rate
&& incode_ctx->channels == incode_ctx->channels)
{
av_write_frame(outfmt_ctx, &packet);
}
else
{
if (packet.size > 0)
{
avcodec_decode_audio(incode_ctx, (short *)audiobuf, &audiobuf_len,
packet.data, packet.size);
if(incode_ctx->sample_rate != outcode_ctx->sample_rate
|| incode_ctx->channels != outcode_ctx->channels)
{
// resample the audio
resamplebuf_len = audio_resample(resample, (short*)resamplebuf,
(short*)audiobuf, audiobuf_len / (incode_ctx->channels * 2));
//av_fifo_realloc(&fifo, av_fifo_size(&fifo)+audiobuf_len);
av_fifo_write(&fifo,resamplebuf,resamplebuf_len*outcode_ctx->channels*2);
}
else
{
//av_fifo_realloc(&fifo, av_fifo_size(&fifo)+audiobuf_len);
av_fifo_write(&fifo, audiobuf, audiobuf_len);
}
if(audiobuf_len > 0)
{
int frame_bytes = outcode_ctx->frame_size * 2 * outcode_ctx->channels;
while(av_fifo_read(&fifo, databuf, frame_bytes) == 0)
{
AVPacket pkt;
av_init_packet(&pkt);
pkt.size = avcodec_encode_audio(outcode_ctx, outbuf, outbuf_len, (short*)databuf);
if (outcode_ctx->coded_frame && outcode_ctx->coded_frame->pts != AV_NOPTS_VALUE)
pkt.pts = av_rescale_q(outcode_ctx->coded_frame->pts,
outcode_ctx->time_base, audio_st->time_base);
pkt.stream_index = audio_st->index;
pkt.data = outbuf;
pkt.flags |= PKT_FLAG_KEY;
// write the compressed frame in the media file
if (pkt.size > 0)
{
ret = av_write_frame(outfmt_ctx, &pkt);
}
av_free_packet(&pkt);
}
}
} //End if
}
}
av_free_packet(&packet);
}
av_fifo_free(&fifo);
/* write the trailer, if any */
av_write_trailer(outfmt_ctx);
av_free(outbuf);
av_free(audiobuf);
av_free(resamplebuf);
av_free(databuf);
audio_resample_close(resample);
avcodec_close(outcode_ctx);
/* free the streams */
for(i = 0; i < outfmt_ctx->nb_streams; i++) {
av_freep(&outfmt_ctx->streams[i]->codec);
av_freep(&outfmt_ctx->streams[i]);
}
if (!(outfmt->flags & AVFMT_NOFILE)) {
/* close the output file */
url_fclose(outfmt_ctx->pb);
}
av_free(outfmt_ctx);
avcodec_close(incode_ctx);
av_close_input_file(infmt_ctx);
return ret;
return 1;
}
#pragma warning(pop)
#pragma warning(disable : 4101 4244)
int ConverAudio(const char* input_file, const char* output_file, int samples_rate, int channel)
{
AVFormatContext *infmt_ctx;
unsigned int i = 0;
初始化
avcodec_register_all();
avdevice_register_all();
av_register_all();
infmt_ctx = av_alloc_format_context();
//打开输入文件
if(av_open_input_file(&infmt_ctx, input_file, NULL, 0, NULL)!=0)
{
//debug_string("can't open input file/n");
return -1;
}
//取出流信息
if(av_find_stream_info(infmt_ctx) <0)
{
//debug_string("can't find suitable codec parameters/n");
return -2;
}
//dump_format(infmt_ctx, 0, input_file, 0); //列出输入文件的相关流信息
// 查找音频流信息
int audioindex=-1;
for(unsigned int j = 0; j < infmt_ctx->nb_streams; j++)
{
if(infmt_ctx->streams[j]->codec->codec_type == CODEC_TYPE_AUDIO)
{
audioindex=j;
break;
}
}
if(audioindex == -1) //没有找到音频流
{
//debug_string("can't find audio stream/n");
return -3;
}
AVCodecContext *incode_ctx;
AVCodec *incodec;
incode_ctx = infmt_ctx->streams[audioindex]->codec;
//找到合适的音频解码器
incodec = avcodec_find_decoder(incode_ctx->codec_id);
if(incodec == NULL)
{
//debug_string("can't find suitable audio decoder/n");
return -4;
}
//打开该音频解码器
if(avcodec_open(incode_ctx, incodec) < 0)
{
//debug_string("can't open the audio decoder/n");
return -5;
}
输出
/* 解析输出文件的格式 */
AVOutputFormat *outfmt = guess_format(NULL, output_file, NULL);
if (!outfmt)
{
//printf("Could not deduce output format from file extension: using MPEG./n");
outfmt = guess_format("mpeg", NULL, NULL);
}
if (!outfmt)
{
//debug_string("Could not find suitable output format/n");
return -6;
}
outfmt->audio_codec = CODEC_ID_MP3;
/* allocate the output media context */
AVFormatContext *outfmt_ctx = av_alloc_format_context();
if (!outfmt_ctx)
{
//debug_string("Memory error/n");
return -7;
}
/* 保存输出文件的格式 */
outfmt_ctx->oformat = outfmt;
snprintf(outfmt_ctx->filename, sizeof(outfmt_ctx->filename), "%s", output_file);
/*add the audio and video streams using the default format codecs and initialize the codecs*/
/* 输出文件的视频流编码器ID */
AVCodecContext *outcode_ctx;
AVCodec *outcodec;
AVStream *audio_st = NULL/*, *video_st*/;
//double audio_pts, video_pts;
//if (outfmt->video_codec != CODEC_ID_NONE) {
// video_st = add_video_stream(outfmt_ctx, outfmt->video_codec);
//}
/* 输出文件的音频流编码器ID */
if (outfmt->audio_codec != CODEC_ID_NONE)
{
audio_st = av_new_stream(outfmt_ctx, 1);
outcode_ctx = audio_st->codec;
outcode_ctx->codec_id = outfmt->audio_codec;
outcode_ctx->codec_type = CODEC_TYPE_AUDIO;
//oAcc->bit_rate =inCodecCtx->bit_rate ;
outcode_ctx->sample_rate = samples_rate > 0 ? samples_rate : incode_ctx->sample_rate;
//outcode_ctx->time_base.den = 1;
//outcode_ctx->time_base.num = outcode_ctx->sample_rate;
outcode_ctx->channels = channel > 0 ? channel : incode_ctx->channels;
outcode_ctx->block_align = incode_ctx->block_align;
if(outcode_ctx->block_align == 1 && outcode_ctx->codec_id == CODEC_ID_MP3)
outcode_ctx->block_align = 0;
}
/* 设置输出参数 */
if (av_set_parameters(outfmt_ctx, NULL) < 0)
{
//debug_string("Invalid output format parameters/n");
return -8;
}
/* 列出输出文件的格式信息 */
dump_format(outfmt_ctx, 0, output_file, 1);
strcpy(outfmt_ctx->title, infmt_ctx->title);
strcpy(outfmt_ctx->author, infmt_ctx->author);
strcpy(outfmt_ctx->copyright, infmt_ctx->copyright);
strcpy(outfmt_ctx->comment, infmt_ctx->comment);
strcpy(outfmt_ctx->album, infmt_ctx->album);
outfmt_ctx->year = infmt_ctx->year;
outfmt_ctx->track = infmt_ctx->track;
strcpy(outfmt_ctx->genre, infmt_ctx->genre);
//dump_format(oc,0,output_file_name,1);//列出输出文件的相关流信息
//找到合适的音频编码器
outcodec = avcodec_find_encoder(outfmt_ctx->oformat->audio_codec);//CODEC_ID_AAC
if(!outcodec)
{
//debug_string("can't find suitable audio encoder/n");
return -9;
}
if(avcodec_open(outcode_ctx, outcodec) <0)
{
//debug_string("can't open the output audio codec");
return -10;
}
/* 如果输出文件不存在, 则创建输出文件 */
if (!(outfmt->flags & AVFMT_NOFILE))
{
if (url_fopen(&outfmt_ctx->pb, output_file, URL_WRONLY) < 0)
{
//debug_string("Could not open '%s'/n", output_file);
return -11;
}
}
int ret = 0;
uint8_t* outbuf;
uint8_t* audiobuf;
uint8_t* resamplebuf;
uint8_t* databuf;
int outbuf_len = AVCODEC_MAX_AUDIO_FRAME_SIZE;;
int audiobuf_len = AVCODEC_MAX_AUDIO_FRAME_SIZE;
int resamplebuf_len = AVCODEC_MAX_AUDIO_FRAME_SIZE;
int64_t pt;
outbuf = (uint8_t*)av_malloc(outbuf_len);
audiobuf = (uint8_t*)av_malloc(audiobuf_len);
resamplebuf = (uint8_t*)av_malloc(resamplebuf_len);
databuf = (uint8_t*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
AVFifoBuffer fifo;
av_fifo_init(&fifo, av_fifo_size(&fifo)+AVCODEC_MAX_AUDIO_FRAME_SIZE);
ReSampleContext* resample = audio_resample_init(outcode_ctx->channels,
incode_ctx->channels, outcode_ctx->sample_rate, incode_ctx->sample_rate);
av_write_header(outfmt_ctx);
AVPacket packet;
while(av_read_frame(infmt_ctx, &packet) >= 0)
{
pt = packet.pts;
if(outcode_ctx->codec_id != CODEC_ID_NONE
&& packet.stream_index == audio_st->index)
{
if(incode_ctx->codec_id == outcode_ctx->codec_id
&& incode_ctx->sample_rate == outcode_ctx->sample_rate
&& incode_ctx->channels == incode_ctx->channels)
{
av_write_frame(outfmt_ctx, &packet);
}
else
{
if (packet.size > 0)
{
avcodec_decode_audio(incode_ctx, (short *)audiobuf, &audiobuf_len,
packet.data, packet.size);
if(incode_ctx->sample_rate != outcode_ctx->sample_rate
|| incode_ctx->channels != outcode_ctx->channels)
{
// resample the audio
resamplebuf_len = audio_resample(resample, (short*)resamplebuf,
(short*)audiobuf, audiobuf_len / (incode_ctx->channels * 2));
//av_fifo_realloc(&fifo, av_fifo_size(&fifo)+audiobuf_len);
av_fifo_write(&fifo,resamplebuf,resamplebuf_len*outcode_ctx->channels*2);
}
else
{
//av_fifo_realloc(&fifo, av_fifo_size(&fifo)+audiobuf_len);
av_fifo_write(&fifo, audiobuf, audiobuf_len);
}
if(audiobuf_len > 0)
{
int frame_bytes = outcode_ctx->frame_size * 2 * outcode_ctx->channels;
while(av_fifo_read(&fifo, databuf, frame_bytes) == 0)
{
AVPacket pkt;
av_init_packet(&pkt);
pkt.size = avcodec_encode_audio(outcode_ctx, outbuf, outbuf_len, (short*)databuf);
if (outcode_ctx->coded_frame && outcode_ctx->coded_frame->pts != AV_NOPTS_VALUE)
pkt.pts = av_rescale_q(outcode_ctx->coded_frame->pts,
outcode_ctx->time_base, audio_st->time_base);
pkt.stream_index = audio_st->index;
pkt.data = outbuf;
pkt.flags |= PKT_FLAG_KEY;
// write the compressed frame in the media file
if (pkt.size > 0)
{
ret = av_write_frame(outfmt_ctx, &pkt);
}
av_free_packet(&pkt);
}
}
} //End if
}
}
av_free_packet(&packet);
}
av_fifo_free(&fifo);
/* write the trailer, if any */
av_write_trailer(outfmt_ctx);
av_free(outbuf);
av_free(audiobuf);
av_free(resamplebuf);
av_free(databuf);
audio_resample_close(resample);
avcodec_close(outcode_ctx);
/* free the streams */
for(i = 0; i < outfmt_ctx->nb_streams; i++) {
av_freep(&outfmt_ctx->streams[i]->codec);
av_freep(&outfmt_ctx->streams[i]);
}
if (!(outfmt->flags & AVFMT_NOFILE)) {
/* close the output file */
url_fclose(outfmt_ctx->pb);
}
av_free(outfmt_ctx);
avcodec_close(incode_ctx);
av_close_input_file(infmt_ctx);
return ret;
return 1;
}
#pragma warning(pop)