使用ffmpeg api调用将3gp(amr)转换为mp3

时间:2012-03-13 13:23:57

标签: ffmpeg mp3 amr

使用ffmpeg api调用

将3gp(amr)转换为mp3

我尝试使用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);
    }
}

0 个答案:

没有答案