音视频小白系统入门课-2

本系列笔记为博主学习李超老师课程的课堂笔记,仅供参阅

课程传送门:音视频小白系统入门课 音视频基础+ffmpeg原理

往期课程笔记传送门:

课程实践代码仓库:传送门

音视频编解码

可以通过ffmpeg -f avfoundation -list_devices true -i "" 查看Mac设备支持的设备编号

编解码器

上下行网络一般是非对称的(下行带宽一般更大,因为大多数终端都是拉取数据)

压缩-质量 trade off

压缩方法:

  • 消除冗余信息:有损压缩

    • 剔除人类听觉范围外的音频 (20Hz-20kHz)

    • 被遮蔽的音频信号(心理声学模型)

      • 频域遮蔽

      • 时域遮蔽

  • 无损压缩:熵编码

    • 哈夫曼编码
    • 算数编码
    • 香农编码

常见的音频编解码器:

  • OPUS:新兴、延迟小、压缩率高,WebRTC
  • AAC:应用广泛,支持好,取代mp3
  • Ogg:收费
  • Speex:混音消除,以前流行
  • G.711:窄带音频,固定电话,声音损耗严重

压缩效果:OPUS > AAC > Ogg


AAC编解码器:

  • AAC LC(基础,128k)
  • AAC HE V1(废弃,按64k左右)+ SBR技术,按频谱分开保存
  • AAC HE V2(添加新技术)+ PS技术,多声道差异保存

AAC格式:

  • ADIF(Audio Data Interchange Format):从头解码,多用在磁盘文件
  • ADTS(Audio Data Transport Stream):每一帧有一个同步字,大一些,可以在音频流的任意位置解码

ADTS结构:7/9个字节,2字节CRC校验

Audio Object Types:

1 AAC Main

2 AAC LC

5 SBR : AAC HE V1

29 PS:AAC HE V2

Sampling Frequency Index:

4 44100 Hz

11 48000 HZ

ADTS头规范验证:http://p23.nl/projects/aac-header

  • ffmpeg -i demo.mp3 -vn -c:a libfdk_aac -ar 44100 -channel_layout mono/stereo -profile:a aac_he_v2 demo_mp3.aac
    • -i 指定输入源
    • -vn 过滤视频
    • -c:a libfdk_aac codec:audio 音频编码器指定为fdk_aac
    • -ar 44100 采样率44.1kHz
    • -channel_layout stereo 立体声采样
    • -profile:a aac_he_v2设置音频编码格式

为了支持libfdk_aac库,对于brew安装的ffmpeg需要使用homebrew-ffmpeg第三方库安装支持fdk-aac的版本;对于源码安装的ffmpeg,需要在configure时打开libfdk-aac选项重新编译

音频重采样:转换音频三元组(采样率、位深/采样大小、通道数)

什么是重采样?

  • 目标:将音频从一种采样格式(如 48000Hz F32LE 单声道)转换为另一种(如 44100Hz S16LE 单声道)。
  • 关键操作:
    • 采样率转换(如 48kHz → 44.1kHz):通过插值/抽取算法(如线性插值、sinc 滤波)调整样本数量。
    • 格式转换(如 F32LES16LE):量化位深,可能涉及缩放(如 float [-1,1]int16 [-32768,32767])。
    • 声道布局调整(如 立体声 → 单声道):混合或选择声道。

为什么要重采样:

  • 音频设备采集数据与编码器要求数据不一致
  • 扬声器要求的音频数据和播放数据不一致
  • 方便运算:混音消除等场景使用单声道会方便运算

如何知道对应设备要求的规格?

  1. 了解音频设备的参数
  2. 查看ffmpeg的源码

为什么不把swr_init合并到swr_alloc_set_opts2中?

复制代码
(1) 灵活性:允许动态修改配置

- 用户可能在 `alloc` 后需要 调整参数(例如根据实际输入动态修改声道布局),再调用 `swr_init()`。如果合并,每次修改都要重新分配内存,效率更低。

(2) 延迟初始化:节省资源

- 某些场景下,`SwrContext` 可能被创建但 不立即使用(如预初始化一组转换器)。合并会导致无用的计算(如滤波器系数)提前执行。

(3) 错误处理的清晰性

- 分离设计允许:
    - 先检查 `alloc` 是否成功(内存分配问题)。
    - 再检查 `init` 是否成功(参数兼容性问题)。合并后难以区分错误类型。

为什么可以逐帧处理?

复制代码
- 状态保持:`SwrContext` 内部会缓存部分样本,处理跨帧的连续性(例如 48kHz → 44.1kHz 时,一帧输入可能对应不完整输出帧)。
- 增量处理:每次调用 `swr_convert()` 时:
    - 输入:当前帧的音频数据(如 `2048字节 F32LE`)。
    - 输出:尽可能多的重采样后数据(可能比输入少/多,取决于采样率比)。
    - 剩余未处理的样本会暂存在 `SwrContext` 中,等待下一帧输入。

nb_sample 的作用

复制代码
(1)定义

- `nb_sample` 表示 单次处理的音频样本数(注意是"样本数"而非"字节数")。
    - 例如:若音频是单声道 `F32LE`(每个样本占4字节),`2048字节` 对应 `2048 / 4 = 512` 个样本,此时 `nb_sample = 512`。
- 它决定了每次调用 `swr_convert()` 时,输入/输出缓冲区的有效数据量。

(2)为什么需要它?

- 分块处理:音频数据通常是流式分块传输的(比如每次从设备读取一帧),`nb_sample` 告诉重采样器当前块有多少有效样本需要处理。
- 缓冲区管理:输入/输出缓冲区需要预分配足够空间,`nb_sample` 用于计算缓冲区大小(如 `av_samples_alloc_array_and_samples()`)。

为什么 swr_src_datauint8_t**(二级指针)?

复制代码
根本原因:FFmpeg 对多声道音频的通用设计

FFmpeg 的音频处理 API(如 `swr_convert`、`av_samples_alloc_array_and_samples`)需要兼容 多声道音频的平面(Planar)存储格式。

对于多声道音频(如立体声、5.1声道),数据可能按以下两种方式存储:

- 交错(Interleaved):`[LRLRLR...]`(左右声道数据交替排列)
- 平面(Planar):`[LLLL...]` + `[RRRR...]`(每个声道单独连续存储)

 **内存布局示例**

假设立体声(2声道)音频:

- **Planar 模式**:
    
    ```c
    swr_src_data[0] = 左声道数据指针 (LLLL...)
    swr_src_data[1] = 右声道数据指针 (RRRR...)
    ```
    
- **Interleaved 模式**:
    
    ```c
    swr_src_data[0] = 所有声道交织数据指针 (LRLRLR...)
    swr_src_data[1] = NULL (未使用)
    ```

AAC 编码器的输入要求

复制代码
AAC 编码器(如 `libfdk_aac` 或 FFmpeg 内置的 `aac`)通常支持以下格式:

**采样格式(Sample Format)**:

- 必须为 **`AV_SAMPLE_FMT_S16`(16位整型)** 或 **`AV_SAMPLE_FMT_FLTP`(32位浮点平面格式)**。
- 如果设备采集的是其他格式(如 `AV_SAMPLE_FMT_U8`、`AV_SAMPLE_FMT_S32`),需转换。

**声道布局(Channel Layout)**:

- 支持单声道(`AV_CH_LAYOUT_MONO`)或立体声(`AV_CH_LAYOUT_STEREO`)。
- 若设备采集的是多声道(如5.1),需降混(Downmix)或明确编码器是否支持。

**采样率(Sample Rate)**:

- 常见支持 16kHz、32kHz、44.1kHz、48kHz。
- 若设备采集的采样率不匹配(如8kHz),需重采样。

AVFrame:编码前的数据

AVPacket:编码后的数据

调用libfdk_aac编码时运行报错:

c 复制代码
[libfdk_aac @ 0x138e82c90] frame_size (2048) was not respected for a non-last frame
avcodec_send_frame error -22: Invalid argument

经过查阅资料发现,libfkd-aac编码器对每次发送帧的采样数有要求

  • 单通道:必须是2048个采样
  • 双通道:必须是1024个采样

前两帧和最后一帧可以不满足条件。我们音频设备采集的一帧数据经过重采样转换往往不满足条件,因此必须做一定的缓冲处理。

Swift调用C++:https://juejin.cn/post/7265999062242033724

相关推荐
18538162800余。5 小时前
碰一碰发视频系统源码搭建全解析:定制化开发
音视频
李煜鑫7 小时前
音视频相关协议和技术内容
ffmpeg·音视频
do_you_like_van_游戏12 小时前
用ffmpeg 实现拉取h265的flv视频转存成264的mp4 实现方案
ffmpeg·音视频
CoderJia程序员甲12 小时前
KrillinAI:视频跨语言传播的一站式AI解决方案
人工智能·ai·大模型·音视频·短视频
活力板蓝根13 小时前
QQ音乐的 AI 化转型范本:一款音乐 App 如何用大模型重构听歌体验?
人工智能·音视频·娱乐·用户体验
桃花岛主7015 小时前
对于在线教育或知识付费类网站视频处理方案
音视频
Yu_Mao_Cat15 小时前
增强版视频表情分析系统
python·计算机视觉·音视频
Antonio91519 小时前
【音视频】MP4解封装
ffmpeg·音视频