我是FFMpeg的新手,我目前正在尝试将音频数据从PCM AV_SAMPLE_FMT_S16格式转换为Mp3 AV_SAMPLE_FMT_FLTP格式。
为此我使用FFMpeg的AudioResampleContext
av_opt_set_int( audioResampleCtx, "in_sample_fmt", m_aplayer->aCodecCtx->sample_fmt, 0);
av_opt_set_int( audioResampleCtx, "in_sample_rate", m_aplayer->aCodecCtx->sample_rate, 0);
av_opt_set_int( audioResampleCtx, "in_channels", m_aplayer->aCodecCtx->channels,0);
av_opt_set_int( audioResampleCtx, "out_channel_layout", audioCodecCtx->channel_layout, 0);
av_opt_set_int( audioResampleCtx, "out_sample_fmt", audioCodecCtx->sample_fmt, 0);
av_opt_set_int( audioResampleCtx, "out_sample_rate", audioCodecCtx->sample_rate, 0);
av_opt_set_int( audioResampleCtx, "out_channels", audioCodecCtx->channels, 0);
转换效果很好,因为我可以收听我的mp3文件,但问题是我的原始文件是60秒长,输出mp3文件只有34秒。我可以听到它非常加速,就像是什么东西加速了声音。在使用FFMpeg查找信息时,我发现比特率从128kbps到64kbps。
修改 为了完成更多信息,我想用mp3编解码器压缩一些原始音频数据,并具有output.mp3输出格式。原始音频数据样本格式为AV_SAMPLE_FMT_S16,mp3编解码器支持的样本格式为FLTP(或S16P)。 因此,我正在进行从AV_SAMPLE_FMT_S16到AV_SAMPLE_FMT_FLTP的样本格式转换,但它缺少了一半的数据。
有人可以帮我吗?我知道我错过了一些非常简单的事情,但我无法理解。
修改:2 以下是重新采样的代码(来自https://github.com/martin-steghoefer/debian-karlyriceditor/blob/master/src/ffmpegvideoencoder.cpp)。音频源不是AVFrame,而只是一个字节数组:
// Resample the input into the audioSampleBuffer until we proceed the whole decoded data
if ( (err = avresample_convert( audioResampleCtx,
NULL,
0,
0,
audioFrame->data,
0,
audioFrame->nb_samples )) < 0 )
{
qWarning( "Error resampling decoded audio: %d", err );
return -1;
}
if( avresample_available( audioResampleCtx ) >= audioFrame->nb_samples )
{
// Read a frame audio data from the resample fifo
if ( avresample_read( audioResampleCtx, audioFrame->data, audioFrame->nb_samples ) != audioFrame->nb_samples )
{
qWarning( "Error reading resampled audio: %d", err );
return -1;
}
//Init packet, do the encoding and write data to file
感谢您的帮助!
答案 0 :(得分:0)
1)如果音频播放速度快,则采样率可能不正确。检查重采样器的输入采样率是否与解码器中的采样率相同。并且输出采样率与您在编码器中使用的采样率相同。
2)平面与非平面只是将样本保存在缓冲区中的一种方法(请检查:What is the difference between AV_SAMPLE_FMT_S16P and AV_SAMPLE_FMT_S16?)。您不应该错过飞机。
3)由于输出较短:提醒刷新解码器,重采样器,编码器。它们全部缓冲数据。当所有数据都馈送到处理器链(dre)时,您需要刷新每个组件并在下一阶段处理刷新的数据(刷新解码器->重采样->编码;刷新重采样器->编码;刷新编码器)。
您现在找到了解决问题的方法吗?我正在努力解决类似的问题。从S16-> FLTP转换时,出现ffmpeg错误:“处理器:psymodel.c:576:calc_energy:声明'el> = 0'失败。”