我尝试使用libavformat(ffmpeg)构建我自己的函数,将3gp音频文件(用android移动设备录制)转换为mp3文件。
我使用av_read_frame()从输入文件中读取一个帧并使用avcodec_decode_audio3()来解码数据 进入缓冲区并使用此缓冲区使用avcodec_encode_audio将数据编码为mp3。 这似乎给了我一个正确的结果,将wav转换为mp3和mp3到wav(或解码一个mp3并编码到另一个mp3),但不是为了amr到mp3。 我生成的mp3文件似乎有正确的长度,但只包含噪音。
在另一篇文章中,我读到amr-decoder不使用与mp3相同的样本格式。 AMR使用FLT和mp3 S16或S32,我必须进行重新采样。 所以我为已经解码的每个帧调用av_audio_resample_init()和audio_resample。 但这并不能完全解决我的问题。现在我可以听到我录制的声音并且不知道我在说什么,但质量非常低,而且还有很多噪音。 我不确定我是否正确设置了av_audio_resample的参数,尤其是最后4个参数(我认为没有)或者我是否错过了其他参数。
ReSampleContext* reSampleContext = av_audio_resample_init(1, 1, 44100, 8000, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT, 0, 0, 0, 0.0);
while(1)
{
if(av_read_frame(ic, &avpkt) < 0)
{
break;
}
out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
int count;
count = avcodec_decode_audio3(audio_stream->codec, (short *)decodedBuffer, &out_size, &avpkt);
if(count < 0)
{
break;
}
if((audio_resample(reSampleContext, (short *)resampledBuffer, (short *)decodedBuffer, out_size / 4)) < 0)
{
fprintf(stderr, "Error\n");
exit(1);
}
out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
pktOut.size = avcodec_encode_audio(c, outbuf, out_size, (short *)resampledBuffer);
if(c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
{
pktOut.pts = av_rescale_q(c->coded_frame->pts, c->time_base, outStream->time_base);
//av_res
}
pktOut.pts = AV_NOPTS_VALUE;
pktOut.dts = AV_NOPTS_VALUE;
pktOut.flags |= AV_PKT_FLAG_KEY;
pktOut.stream_index = audio_stream->index;
pktOut.data = outbuf;
if(av_write_frame(oc, &pktOut) != 0)
{
fprintf(stderr, "Error while writing audio frame\n");
exit(1);
}
}