Преобразование 3gp (amr) в mp3 с использованием вызовов ffmpeg api - PullRequest
3 голосов
/ 13 марта 2012

Преобразование 3gp (amr) в mp3 с использованием вызовов ffmpeg api

Я пытаюсь использовать libavformat (ffmpeg) для создания своей собственной функции, которая преобразует аудиофайлы 3gp (записанные с помощью мобильного устройства Android) в mp3-файлы.

Я использую av_read_frame (), чтобы прочитать кадр из входного файла, и использую avcodec_decode_audio3 (), чтобы декодировать данные. в буфер и использовать этот буфер для кодирования данных в mp3 с помощью avcodec_encode_audio. Это, кажется, дает мне правильный результат для преобразования 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);
    }
}
...