human: 如何处理七牛云的实时音视频音频裸数据混音

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 使用指南 > iOS >音频裸数据混音

#  音频裸数据混音

最近更新时间: 2023-10-20 19:49:01

本文主要介绍连麦过程中添加 PCM 音频裸数据混音的使用场景。

>   * v5.2.0 版本开始支持使用
> [QNAudioSourceMixer](https://developer.qiniu.com/rtc/api/12270/QNAudioSourceMixer-
> iOS) 进行 PCM 裸数据的混音操作
>   * 在 [QNRTC deinit] 之前，请先离开房间，再销毁 mixer 和 audioTrack 对象
>   * PCM 混音不支持存储格式为大端的裸数据，即音频数据源的 `AudioStreamBasicDescription` 的
> `mFormatFlags` 不能为 `kAudioFormatFlagIsBigEndian`
>

使用方式如下：

# 创建和销毁 QNAudioSourceMixer

SDK 当前支持基于
[QNMicrophoneAudioTrack](https://developer.qiniu.com/rtc/api/8855/QNMicrophoneAudioTrack-
iOS) 和
[QNCustomAudioTrack](https://developer.qiniu.com/rtc/api/8856/QNCustomAudioTrack-
iOS) 的混音功能，可以通过
[QNRTC.createAudioMusicMixer](https://developer.qiniu.com/rtc/api/8834/QNRTC-
iOS#createAudioSourceMixer) 来创建
[QNAudioSourceMixer](https://developer.qiniu.com/rtc/api/12270/QNAudioSourceMixer-
iOS) 对象,使用
[audioTrack.addAudioFilter](https://developer.qiniu.com/rtc/api/8834/QNRTC-
iOS#addAudioFilter) 将 audioSourceMixer 对象添加到 audioTrack 中

    
    
    QNAudioSourceMixer *audioSourceMixer = [QNRTC createAudioSourceMixer:self];
    [audioTrack addAudioFilter:audioMusicMixer];
    

其中，[QNAudioSourceMixerDelegate](https://developer.qiniu.com/rtc/api/12271/QNAudioSourceMixerDelegate)
为 PCM 混音回调代理，回调方法定义如下：

    
    
    /*!
     * @abstract 音源混音发生错误的回调
     *
     * @param audioSourceMixer 音源混音实例
     *
     * @param error 错误
     *
     * @since v5.2.0
     */
    - (void)audioSourceMixer:(QNAudioSourceMixer *)audioSourceMixer didFailWithError:(NSError *)error;
    
    

混音场景下的错误码可参考[混音相关错误码](https://developer.qiniu.com/rtc/development_guidelines/10084/rtc-
error-code-iOS#3)

确认后续不再需要使用或者需要重新创建
[QNAudioSourceMixer](https://developer.qiniu.com/rtc/api/12270/QNAudioSourceMixer-
iOS)，先通过
[audioTrack.removeAudioFilter](https://developer.qiniu.com/rtc/api/8834/QNRTC-
iOS#addAudioFilter) 移除 sourceMixer，再通过
[QNRTC.destroyAudioMusicMixer](https://developer.qiniu.com/rtc/api/8834/QNRTC-
iOS#destroyAudioSourceMixer) 接口进行销毁，使用代码参考如下：

    
    
    [audioTrack removeAudioFilter:sourceMixer];
    [QNRTC destroyAudioSourceMixer:sourceMixer];
    

# 创建和销毁 QNAudioSource

[QNAudioSource](https://developer.qiniu.com/rtc/api/12273/QNAudioSource-iOS)
为音源配置类，支持两种构造方法：

  1. [QNAudioSourceMixer.createAudioSourceWithSourceID[1/2]](https://developer.qiniu.com/rtc/api/12270/QNAudioSourceMixer-iOS#createAudioSourceWithSourceID%5B1/2%5D)：通过非阻塞模式创建 `QNAudioSource`
  2. [QNAudioSourceMixer.createAudioSourceWithSourceID[2/2]](https://developer.qiniu.com/rtc/api/12270/QNAudioSourceMixer-iOS#createAudioSourceWithSourceID%5B2/2%5D)：通过指定阻塞模式创建 `QNAudioSource`

使用代码参考如下：

    
    
    // 非阻塞模式
    QNAudioSource *audioSource = [audioSourceMixer createAudioSource:sourceID];
    
    // 阻塞模式
    QNAudioSource *audioSource = [audioSourceMixer createAudioSource:sourceID blockingMode:YES];
    

> 阻塞模式的配置决定了 SDK 是否会阻塞数据导入的线程：
>
>   * 非阻塞模式下，外部数据需要按照每次送入音频数据的时长间隔依次送入，或者直接使用播放器解码后的回调数据来送入，但不宜送入过快，以免丢弃过多的数据。
>   * 阻塞模式下，外部数据需要持续送入 SDK，但不宜送入太多，以免阻塞导入线程的时间过长。
>

确认后续不再使用某音源，可以通过
[QNAudioEffectMixer.destroyAudioSourceWithSourceID](https://developer.qiniu.com/rtc/api/12270/QNAudioSourceMixer-
iOS#destroyAudioSourceWithSourceID) 接口进行销毁，使用代码参考如下

    
    
    [audioSourceMixer destroyAudioSourceWithSourceID:sourceID];
    

**其中，sourceID 为音源文件的唯一标识符，可自行生成并维护，该标识符为控制一系列音源混音操作的依据，需保证唯一。**

# 音量控制

混音场景下，主要包含三种音量设置：**麦克风混音音量** 、**音源混音音量** 、**本地播放音量** 。三种音量的设置方式参考如下：

  * **麦克风混音音量** ：可以通过 [QNMicrophoneAudioTrack.setVolume](https://developer.qiniu.com/rtc/api/8855/QNMicrophoneAudioTrack-iOS#setVolume) 接口进行配置。
  * **音源混音音量** ：可以通过 [QNAudioSourceMixer.setVolume](https://developer.qiniu.com/rtc/api/12270/QNAudioSourceMixer-iOS#setVolume) 和 [QNAudioSourceMixer.setAllSourcesVolume](https://developer.qiniu.com/rtc/api/12270/QNAudioSourceMixer-iOS#setAllSourcesVolume) 接口分别对指定音源和所有音源进行音量配置。
  * **本地播放音量** ：可以通过 [QNMicrophoneAudioTrack.setPlayingVolume](https://developer.qiniu.com/rtc/api/8855/QNMicrophoneAudioTrack-iOS#setPlayingVolume) 接口进行配置，需要注意的是，播放音量是基于混音后的音频进行调整的，会受到混音音量调整的影响。

参考代码如下：

    
    
    [microphoneAudioTrack setVolume:0.5];                   // 设置麦克风采集(混音)音量
    [microphoneAudioTrack setPlayingVolume:0.5];            // 设置混音后本地播放的音量
    int sourceID = [audioSource getID];
    [audioSourceMixer setVolume:0.5 sourceID:sourceID];     // 设置指定音源的混音音量
    [audioSourceMixer setAllSourcesVolume:0.5];             // 设置所有音源的混音音量
    

# 数据导入

PCM 裸数据导入需要对应 `sourceID` 及音频数据格式 `asbd`

参考代码如下：

    
    
    [audioSourceMixer pushAudioBuffer:&buffer asbd:&asbd sourceID:sourceID];
    

**注意：目前音频裸数据格式，还不支持`kAudioFormatFlagIsBigEndian` 大端**

# 发布

混音场景下，默认音源全部发布到远端，即 `publishEnabled` 均为 YES。可使用
[QNAudioSourceMixer.setPublishEnabled](https://developer.qiniu.com/rtc/api/12270/QNAudioSourceMixer-
iOS#setPublishEnabled) 指定 `sourceID` 选择是否发布到远端，设置 `publishEnabled` 为 NO
时，仅在本地播放，不会发布到远端。

参考代码如下：

    
    
    [audioSourceMixer setPublishEnabled:NO sourceID:sourceID];      // 设置指定音源的不发布到远端，仅在本地播放
    

# 返听

若您在混音场景下，有开启返听的需要，则可以通过
[QNMicrophoneAudioTrack.setEarMonitorEnabled](https://developer.qiniu.com/rtc/api/8855/QNMicrophoneAudioTrack-
iOS#setEarMonitorEnabled) 接口进行开启，参考代码如下：

    
    
    [microphoneAudioTrack setEarMonitorEnabled:YES]; // 开启返听
    

> 为达到最佳体验，建议在**佩戴耳机** 的情况下使用该功能

# 注意事项

  1. **混音** 功能会将混音音频与当前已发布的音频 Track 数据混合并推送出去，若当前的音频 Track 尚未[发布](https://developer.qiniu.com/rtc/development_guidelines/9260/publish-and-subscribe-iOS)，则混音操作将失效。
  2. 混音功能建议在**佩戴耳机** 的情况下使用以获得更好的体验。
  3. 加入房间后，请确保 `AVAudioSession` 的 category 类型和 mode 模式分别是 `AVAudioSessionCategoryPlayAndRecord` 和 `AVAudioSessionModeVoiceChat`，以免出现播放声音突然变小、录屏失败（报错 -5833）等非预期问题。

# 示例代码

多音源混音场景的示例代码可参考 [API-Examples-iOS](https://github.com/pili-engineering/QNRTC-
iOS/blob/master/QNRTC-API-Examples/Api-Examples-
iOS/Module/Other/AudioSourceMix/AudioSourceMixExample.m)

以上内容是否对您有帮助？