Преобразование 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);
}
}