ffmpeg音频重采样
Posted 一二三o-0-O
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ffmpeg音频重采样相关的知识,希望对你有一定的参考价值。
【ffmpeg】音频重采样
个人简介
📦个人主页:一二三o-0-O的博客
🏆技术方向:C/C++客户端资深工程师(直播+音视频剪辑)
👨💻作者简介:数据结构算法与音视频领域创作者
📒 系列专栏:ffmpeg入门
📣专栏目标:务实的掌握FFmpeg相关专业知识
🧡如果对您有帮助的话,欢迎点赞👍收藏📂,关注不迷路
前言
如果是刚刚开始学习音视频的伙伴,可以先看看音视频基 础专栏系列的内容,掌握音视频相关的一些基础理论。
音视频基础专栏系列
(一)【音视频基础】音频基础理论
(二)【音视频基础】视频基础理论
(三)【音视频基础】封装格式与编码数据
如果觉得理论学习枯燥的伙伴,可以先通过以下四篇文章使用ffmpeg实现一个播放器,可以获得些许成就感,为持续在音视频领域扎根打好兴趣基础。
ffmpeg专栏系列
(一)【ffmpeg】ffmpeg命令工具的使用
(二)【ffmpeg】视频解码器
(三)【ffmpeg】SDL视频显示
(四)【ffmpeg】ffmpeg+SDL实现播放器
本节主要阐述音频重采样。
什么是音频重采样
- 音频重采样就是将音频三元组(采样率,采样大小和通道数)的值转换成另外一组值
- 例如:将44100/16/2转成48000/16/2
- 为什么要重采样?
- 从设备采集的音频数据与编码器要求的数据不一致
- 扬声器要求的音频数据与要播放的音频数据不一致
- 更方便运算
- 如何知道是否需要进行重采样
- 要了解音频设备
- 查看ffmpeg源码
- 重采样的步骤
- 创建重采样上下文
- 设置参数
- 初始化重采样
- 进行重采样
实现音频重采样
本节代码在【ffmpeg】音频采集的基础上进行开发。
创建重采样上下文
使用swr_alloc_set_opts分配采样上下文
SwrContext *swrCtx = swr_alloc_set_opts(NULL, // ctx
AV_CH_LAYOUT_STEREO,// 输出channel布局
AV_SAMPLE_FMT_FLT, // 输出的采样格式
44100, // 采样率
AV_CH_LAYOUT_STEREO,// 输入channel布局
AV_SAMPLE_FMT_S16, // 输入的采样格式
44100, // 输入的采样率
0,
NULL);
初始化重采样
1.初始化重采样缓冲区
uint8_t **src_data ;
uint8_t **dst_data ;
2.使用av_samples_alloc_array_and_samples分配缓冲区
// 创建输入缓冲区
av_samples_alloc_array_and_samples(&srcData, // 输出缓冲区地址
&srcLineSize, // 缓冲区的大小
2, // 通道个数
22050, // 单通道采样个数
AV_SAMPLE_FMT_S16, // 采样格式
0);
进行重采样
1.将采集到的AVPacket音频包拷贝到输入缓冲区中
2.使用swr_convert进行重采样
// 进行内存拷贝
memcpy((void *)srcData[0], (void *)pkt.data, pkt.size);
// 重采样
swr_convert(swrCtx, // 重采样的上下文
dstData, // 输出结果缓冲区
22050, // 每个通道的采样数
(const uint8_t **)srcData, // 输入缓冲区
22050); // 输入单个通道的采样数
重点注意:
av_samples_alloc_array_and_samples的nb_samples参数
以及swr_convert的out_count与in_count两个参数表示的都是单通道的采样个数,切记是单通道的采样个数,而不是大小(字节)
计算规则:
因为我的音频采集设备每次采集到的AVPacket大小是88200个字节,采样大小是16位,即每采集一次是两个字节;所以一个Packet是采集了44100次,而一个通道就采集了22050次
ffplay播放
- 播放采样格式为AV_SAMPLE_FMT_S16的音频
- 播放将采样格式为AV_SAMPLE_FMT_S16重采样为AV_SAMPLE_FMT_FLT的音频
参考资料
【1】雷神博客
【2】ffmpeg官方文档
【3】李超:音视频基础+ffmpeg原理
以上是关于ffmpeg音频重采样的主要内容,如果未能解决你的问题,请参考以下文章