(十七)深入了解 AVFoundation-编辑:添加背景音乐与音量控制(上)——理论篇

引言

博客专栏链接:AVFoundation架构与实践

博客专栏源码链接:AVFoundation-建议转存大量实战源码

在前两篇博客《音视频裁剪与拼接的实战实现》中,我们基于 AVFoundation 成功完成了素材的裁剪与时间线拼接,初步构建了一个可播放、可导出的编辑系统。至此,视频的“画面结构”已经具备基础处理能力。

但对于一个真正可用的视频编辑系统而言,声音的重要性不亚于画面。配乐、原声、过渡音效的融合,不仅提升观感体验,更直接决定作品的情绪氛围。

本篇将继续深入 AVFoundation 的音频处理能力,聚焦以下几个关键问题:

  1. 如何为视频添加一段背景音乐?
  2. 原声和背景乐能否同时存在?如何混合播放?
  3. 如何控制音轨的音量?比如背景音乐淡入淡出、特定时间段静音?

我们将从原理层面理解 AVMutableAudioMix 与 AVMutableAudioMixInputParameters 的职责,逐步拆解多音轨合成与动态音量控制的实现方式。

在下一篇实战部分,我们还将结合 Demo 工程落地这些功能,实现一个真正具备“声音设计能力”的视频编辑器。

为视频添加背景音乐

1. 背景音乐的本质:额外的音频轨

在 AVFoundation 中,背景音乐的添加,并不是修改原始素材的音轨,而是往 AVMutableComposition 中添加一条新的音频轨道(AVMutableCompositionTrack)。最终生成的合成内容可以包含多条音频轨,例如:

  • 原始视频自带的原声音轨(通常从 videoAsset.tracks(withMediaType: .audio) 获取)
  • 新增的背景音乐音轨(来自独立的音频资源)

AVFoundation 支持多个音频轨同时播放,混合的逻辑在后续播放或导出阶段由 AVAudioMix 负责处理(详见后文)。因此,只要正确添加音轨并保证时间对齐,我们就可以轻松实现背景音乐的合成。

2. 添加背景音乐音轨的关键代码

以下是一个通用的背景音乐插入方法,负责将一段背景音乐资源插入到合成轨道中:

func addBackgroundMusic(to composition: AVMutableComposition, asset: AVAsset, at startTime: CMTime = .zero) {
    // 获取背景音乐的音频轨道
    guard let musicTrack = asset.tracks(withMediaType: .audio).first else { return }

    // 计算插入时长:避免背景音乐超过视频时长
    let duration = min(asset.duration, composition.duration - startTime)

    // 创建新的音频轨道,并插入音频内容
    if let bgmTrack = composition.addMutableTrack(
        withMediaType: .audio,
        preferredTrackID: kCMPersistentTrackID_Invalid
    ) {
        try? bgmTrack.insertTimeRange(
            CMTimeRange(start: .zero, duration: duration),
            of: musicTrack,
            at: startTime
        )
    }
}
说明:
  • composition:目标合成容器;
  • asset:背景音乐的音频资源,通常为 .mp3 或 .m4a 格式的本地音频文件;
  • startTime:背景音乐开始插入的时间点(可用于实现延迟播放);
  • 插入的 duration 不应超过视频本身的时长,避免“音乐比画面长”的问题;
  • 可多次调用此方法添加多个音轨,实现复合音效。

音量控制机制解析

1. 为什么需要音量控制?

在多音轨合成中,声音并不是“简单相加”的问题:

  • 背景音乐过响,可能会掩盖原始对白;
  • 缺乏淡入淡出,可能导致音频突兀;
  • 有时我们希望某一时间段背景音乐静音,仅保留原声。

这些场景的本质需求是:在不修改音轨内容的前提下,动态控制不同轨道在不同时刻的音量

而 AVFoundation 正好提供了一个结构清晰、功能灵活的方案:AVMutableAudioMix。

2. AVMutableAudioMix 的角色

AVMutableAudioMix 是一个“音轨混音参数容器”,可以附加到:

  • AVPlayerItem.audioMix(用于预览)
  • AVAssetExportSession.audioMix(用于导出)

它自身不控制音量,而是持有一组 AVMutableAudioMixInputParameters,每一组参数对应一条音轨。

3. AVMutableAudioMixInputParameters:控制音轨音量的核心

基本使用流程

3.1 针对某条音轨的 trackID 创建一组参数:

let parameters = AVMutableAudioMixInputParameters(track: audioTrack)

3.2 通过以下两种方式设置音量:

固定音量(整条音轨一个音量):

parameters.setVolume(0.5, at: .zero)

渐变音量(支持淡入/淡出):

parameters.setVolumeRamp(fromStartVolume: 0.0, toEndVolume: 1.0, timeRange: CMTimeRange(start: .zero, duration: CMTime(seconds: 3, preferredTimescale: 600)))

3.3 创建 AVMutableAudioMix 并添加参数:

let audioMix = AVMutableAudioMix()
audioMix.inputParameters = [parameters]

4. 多段音量控制:组合使用 setVolumeRamp

可以多次调用 setVolumeRamp 设置多个时间段的音量变化。例如:

let timeRange1 = CMTimeRange(start: .zero, duration: CMTime(seconds: 2, preferredTimescale: 600))
parameters.setVolumeRamp(fromStartVolume: 0.0, toEndVolume: 1.0, timeRange: timeRange1)

let timeRange2 = CMTimeRange(start: CMTime(seconds: 8, preferredTimescale: 600), duration: CMTime(seconds: 2, preferredTimescale: 600))
parameters.setVolumeRamp(fromStartVolume: 1.0, toEndVolume: 0.0, timeRange: timeRange2)

上述代码实现了:

  1. 前 2 秒淡入;
  2. 第 8~10 秒淡出;
  3. 其他时段保持满音量。

5 设置 AudioMix 到播放器或导出器

播放时预览:

playerItem.audioMix = audioMix

导出时应用混音效果:

exportSession.audioMix = audioMix

注意:AVAudioMix 不会改变 AVMutableComposition 本身的数据,只影响播放/导出效果。

小结与预告

在本篇文章中,我们围绕“为视频添加背景音乐与实现音量控制”的核心问题,从原理层面展开了详细解析:

  • 我们了解了如何通过向 AVMutableComposition 添加新的音频轨,实现背景音乐与原声的并存;
  • 借助 AVMutableAudioMix 与 AVMutableAudioMixInputParameters,我们能够精准控制每一条音轨在任意时间点的音量;
  • 包括淡入、淡出、静音、降低背景音乐等常见场景,都可以通过简单的 setVolumeRamp 调用实现。

这些能力共同构成了一个视频编辑系统在音频层面的“基础表达力”。

在下一篇实战篇中,我们将基于当前 AVFoundation 编辑框架的 Demo 工程,带你一步步实现以下功能:

  • 给视频添加背景音乐;
  • 控制原声与背景音乐的相对音量;
  • 实现背景音乐的淡入淡出效果;
  • 在播放或导出中正确应用混音效果。

让我们在代码中把这些理论全部落地,真正做出一个“有声音设计感”的视频!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值