Converting 3gp (amr) to mp3 using ffmpeg api calls

2020-07-22 16:24发布

Converting 3gp (amr) to mp3 using ffmpeg api calls

I try to use libavformat (ffmpeg) to build my own function that converts 3gp audio files (recorded with an android mobile device) into mp3 files.

I use av_read_frame() to read a frame from the input file and use avcodec_decode_audio3() to decode the data into a buffer and use this buffer to encode the data into mp3 with avcodec_encode_audio. This seems to give me a correct result for converting wav to mp3 and mp3 to wav (Or decode one mp3 and encode to another mp3) but not for amr to mp3. My resulting mp3 file seems to has the right length but only consists of noise.

In another post I read that amr-decoder does not use the same sample format than mp3 does. AMR uses FLT and mp3 S16 or S32 und that I have to do resampling. So I call av_audio_resample_init() and audio_resample for each frame that has been decoded. But that does not solve my problem completely. Now I can hear my recorded voice and unsterstand what I was saying, but the quality is very low and there is still a lot of noise. I am not sure if I set the parameters of av_audio_resample correctly, especially the last 4 parameters (I think not) or if I miss something else.

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);
    }
}

标签: ffmpeg mp3 amr
0条回答
登录 后发表回答