混音

下载pdf
更新时间:2019-09-27 10:07

1 功能简介

ZegoAudioRoom SDK 为开发者提供了混音功能。

混音是指,SDK 从 App 获取一路音频数据,将其与采集的音频数据,整合为一路混音数据,进而推流。

直播过程中的掌声,口哨,背景音等音效均可通过混音实现。

2 步骤

混音的使用流程如下:

  1. App 启用混音功能
  2. App 设置混音音量
  3. App 将混音数据传递给 SDK

2.1 启用混音功能

调用此 API 启用混音功能。

ZegoAudioRoomApi-Publisher.h

/**
 混音开关

 @param enable true 启用混音输入,false 关闭混音输入。默认 false
 @return true 成功,false 失败
 @attention 必须确保在 initSDK 后调用
 @note 主播端开启混音后,SDK 在 [ZegoAudioRoomApi (Publisher) -onAuxCallback:dataLen:sampleRate:channelCount:] 中获取混音输入数据
 */
- (bool)enableAux:(BOOL)enable;

请注意,后续操作均基于开启混音功能的基础上。

2.2 设置混音音量

启用混音后,调用此 API 调整混音音量。

ZegoAudioRoomApi-Publisher.h

/**
 设置混音音量

 @param volume 0~100,默认为 50
 */
- (void)setAuxVolume:(int)volume;

也可调用此 API 设置混音静音。

ZegoAudioRoomApi-Publisher.h

/**
 混音静音开关

 @param bMute true: aux 输入播放静音,false: 不静音。默认 false
 @return true 成功,false 失败
 @attention 推流开始前调用本 API 进行参数配置
 */
- (bool)muteAux:(bool)bMute;

请注意,SDK 对上述两个混音音量相关的 API 的调用时机无要求,混音前或混音后调用均可,取决于用户需求。

2.3 App 传递数据给 SDK

启用混音后,SDK 通过此 API 获取待传递的混音数据。

ZegoAudioRoomApi-Publisher.h

/**
 混音数据输入回调

 @param pData App 提供的混音数据,格式要求必须为 PCM,如果不是 PCM,请转换为 PCM
 @param pDataLen 缓冲区长度。实际填充长度必须为 0 或是缓冲区长度。0 代表无混音数据。
 @param pSampleRate 混音数据采样率,支持16k、32k、44.1k、48k
 @param pChannelCount 混音数据声道数,支持1、2
 @attention 用户调用该 API 将混音数据传递给 SDK
 @note 混音数据 bit depth 必须为 16
 */
- (void)onAuxCallback:(void *)pData dataLen:(int *)pDataLen sampleRate:(int *)pSampleRate channelCount:(int *)pChannelCount;

示例代码片段如下:

- (void)onAuxCallback:(void *)pData dataLen:(int *)pDataLen sampleRate:(int *)pSampleRate channelCount:(int *)pChannelCount
{
    if (self.auxData == nil)
    {
        //初始化 auxData,此处待混音的是 a.pcm 音频数据
        NSURL *auxURL = [[NSBundle mainBundle] URLForResource:@"a.pcm" withExtension:nil];
        if (auxURL)
        {
            self.auxData = [NSData dataWithContentsOfURL:auxURL options:0 error:nil];
            self.pPos = (void *)[self.auxData bytes];
        }
    }

    if (self.auxData)
    {
        int nLen = (int)[self.auxData length];
        if (self.pPos == 0)
            self.pPos = (void *)[self.auxData bytes];

        const void *pAuxData = [self.auxData bytes];
        if (pAuxData == NULL)
            return;

        int nLeftLen = (int)(pAuxData + nLen - self.pPos);
        if (nLeftLen < *pDataLen) {
            self.pPos = (void *)pAuxData;
            *pDataLen = 0;
            return;
        }

        if (pSampleRate)
            *pSampleRate = 44100;

        if (pChannelCount)
            *pChannelCount = 2;

        // 将 self.pPos 中的数据复制给 pData
        memcpy(pData, self.pPos, *pDataLen);

        // Demo 中演示的是循环播放音频,请开发者按照各自的需求实现该方法,不要直接复制。
        self.pPos = self.pPos + *pDataLen;
    }
}

请注意:

  1. 示例中演示的是循环播放音频,请开发者按照各自的需求实现该方法,不要直接复制。
  2. 由于 SDK 每次会取 20ms 的数据。如果开发者传入的 pDataLen 不为 0,则必须传递一个固定值。该值由数据的采样率、声道和 20ms 的时间计算得来。否则可能导致混音结果异常。