淳安县千岛湖建设集团网站,北京建设工程交易网,淘宝上网站开发,wordpress有多少种语言FFmpeg在很多地方都运用了缓存机制#xff0c;比如《FFmpeg开发实战#xff1a;从零基础到短视频上线》一书的“3.3.2 对视频流重新编码”介绍了编解码的数据缓存#xff0c;不单是视频编码过程和视频解码过程有缓存#xff0c;甚至连音频重采样都用到了缓存。 也就是说比如《FFmpeg开发实战从零基础到短视频上线》一书的“3.3.2 对视频流重新编码”介绍了编解码的数据缓存不单是视频编码过程和视频解码过程有缓存甚至连音频重采样都用到了缓存。 也就是说重采样函数swr_convert一次只会输出指定长度的音频数据超出这个长度的数据被留在重采样的缓存当中。那么在对一个音频文件转换格式之时有可能所有音频帧都遍历完了重采样缓存里面还保存着剩余未取走的音频数据。此时要像对待视频编码缓存那样想办法把剩下的音频数据冲出来。 具体到代码实现上在调用swr_convert函数之时倒数第二个参数填NULL表示输入的数据内容为空倒数第一个参数填0表示输入的数据大小为0。这便告诉采样器已经没有要转换的音频了请把缓存中剩余的数据冲出来吧。那么swr_convert函数的返回值就是本次冲走的输出数据大小当返回值为0时表示重采样缓存已经冲光了再也没有剩余的数据了此时才能结束音频的格式转换操作。 当然对于常见的mp3和aac格式它们每帧的长度是固定的正常情况调用一次swr_convert函数即可输出完整的音频数据无需另外处理重采样缓存。只有ogg、amr、wma等格式的每帧音频长度不固定才需要额外处理音频的重采样缓存于是对《FFmpeg开发实战从零基础到短视频上线》一书第五章的重采样代码改动如下。 打开chapter05/swrmp3.c把下面这行
swr_frame-nb_samples audio_decode_ctx-frame_size;
改为下面几行因为ogg、amr和wma的frame_size为0所以需要另外赋值
swr_frame-nb_samples audio_decode_ctx-frame_size;
if (swr_frame-nb_samples 0) {swr_frame-nb_samples 512;
}
另外在轮询数据包的循环结束之后补充下面的重采样缓存冲刷代码这样新生成的音频文件才是完整的
while (1) { // 冲走重采样的缓存兼容对ogg、amr等格式的重采样// 重采样。也就是把输入的音频数据根据指定的采样规格转换为新的音频数据输出ret swr_convert(swr_ctx, // 音频采样器的实例// 输出的数据内容和数据大小swr_frame-data, swr_frame-nb_samples,// 输入内容填NULL、输入大小填0表示冲走缓存NULL, 0);if (ret 0) {av_log(NULL, AV_LOG_ERROR, swr_convert frame occur error %d.\n, ret);return -1;} else if (ret 0) { // 到末尾了break;}save_mp3_file(fp_out, swr_frame); // 把音频帧保存到MP3文件
}
接着执行下面的编译命令。
gcc swrmp3.c -o swrmp3 -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -lavformat -lavdevice -lavfilter -lavcodec -lavutil -lswscale -lswresample -lpostproc -lm
编译完成后执行以下命令启动测试程序期望把ring.ogg重采样后保存为MP3文件。
./swrmp3 ../ring.ogg
程序运行完毕发现控制台输出以下的日志信息说明完成了对ogg文件重采样mp3音频的操作。
Success open input_file ring.ogg.
audio_decode_ctx frame_size0, sample_fmt8, sample_rate11025, nb_channels1
audio_encode_ctx frame_size1152, sample_fmt6, sample_rate44100, nb_channels1
target audio file is output_swrmp3.mp3
Success resample audio frame as mp3 file.
然后打开影音播放器可以正常播放output_swrmp3.mp3表示上述代码正确实现了将ogg音频数据重采样再转存MP3文件的功能。