阅读本文您将有以下收获:
- 基于ffmpeg5.1版本实现,代码可用性高
- 学习编码的整个流程,提供源码
- 本文有分享在实现这个代码中遇到的问题以及原因
- 代码跨平台,代码是用c++实现
- 如果在编译代码中遇到问题可以在评论区一起探讨
系统环境
MacOS Ventura 13.5
Xcode 14.2
FFmpeg5.1.4
FFmpeg编译
编码库:libfdk_aac
在编译ffmpeg时需要把fdk_aac给加进去,
--enable-libfdk-aac --enable-nonfree"
ffmpeg编译脚本请参考源码
相关命令使用
1.从mp4中提取音频为pcm格式
ffmpeg -i music.mp4 -vn -f s16le -ar 44100 -ac 2 output.pcm
/*
-vn:不处理视频
-f: 保存的数据格式 s16le == 16位小端存储(Signed 16-bit Little-Endian
-ar: 采样率
-ac: 通道数
output.pcm 为输出文件
-i: 为输入文件
*/
2.把pcm编码为aac格式
ffmpeg -f s16le -ar 44100 -ac 2 -i output.pcm -c:a aac -b:a 128k output.aac
/*
相同的字段请参考上面
-c:a 指定编码器
-b:a 比特率
output.aac 为输出文件
*/
3.播放
ffplay -i output.pcm -ac 2 -ar 44100 -f s16le
ffplay -i output.aac
FFmpeg编码流程
1.封装格式
根据文件名利用av_guess_format()来进行决定输出的封装格式,如果此函数报错的话,可以考虑是不是编译FFmpeg --muxers 这个配置项的问题
// 注册和初始化FFmpeg
avformat_network_init();
const AVOutputFormat *oFormat = av_guess_format(NULL, aacFilePath, "audio");
// 创建上下文 _avFormatContext
ret = avformat_alloc_output_context2(&_avFormatContext, oFormat, "aac", aacFilePath);
if (ret < 0) {
LOGI("avformat_alloc_output_context2 error");
return