输入关键词搜索,支持 AI 答疑

客户端实现(基于语聊房组件)

更新时间: 2024/11/29 10:32:26

本文为您展示通过网易云信语聊房组件(VoiceRoomKit)实现语聊房场景的相关步骤,帮助您在业务中实现麦位管理、低延时语音互动、文字聊天等能力。

方案架构

网易云信语聊房方案架构说明如下:

  • 主播、连麦者和观众加入同一个音视频房间。

  • 主播和连麦者在音视频房间内进行音频流的实时发布和订阅。

  • 观众在音视频房间内仅订阅音频流,不发布音频流。

    语聊房组件的业务流.png

开发环境

实现语聊房方案的开发环境要求如下:

环境要求 说明
iOS 版本 11.0 及以上的 iPhone 或者 iPad 真机
CPU 架构 ARM64、ARMV7
IDE XCode
其他 安装 CocoaPods

前提条件

根据本文操作前,请确保您已经完成了以下设置:

一:下载源码

请前往 GitHub 下载或克隆 语聊房示例项目源码

二:集成组件

第一步:通过 CocoaPods 集成

  1. 创建项目。

    若您需要创建新项目,在 XCode 里,依次选择 Create a New XCode Project > Single View App > Next 新建工程,再配置工程相关信息和合适的工程本地路径,单击 Create

    image image
  2. 安装 CocoaPods。

    在终端窗口中输入如下命令:

    sudo gem install cocoapods
    
  3. 创建 Podfile 文件。

    从 Terminal 中进入您所创建项目所在路径,运行以下命令创建 Podfile 文件。

    pod init
    
  4. 编辑 Podfile 文件。

    # platform :ios, '9.0'
    target '{YourApp}' do
        pod 'NEVoiceRoomKit', '~> {version}'
    end
    
    • YourApp:您的 Target 名称。
    • version:待集成的 VoiceRoom 组件的版本号。
  5. 执行以下命令查询本地库版本。

    pod search NEVoiceRoomKit
    

    若不是最新版本,可以执行以下命令更新本地库版本。

    pod repo update
    
  6. 执行以下命令安装 SDK。

    pod install
    

第二步:配置权限

使用 SDK 的音视频功能,需要授权麦克风使用权限。请在 App 的 info.plist 中设置以下项:

Privacy - Microphone Usage Description,并填入麦克风使用目的提示语。

三:初始化组件

在调用 SDK 其他接口之前,您首先需要完成初始化操作。

配置初始化相关参数,调用 initialize 方法完成初始化操作。

示例代码如下:

Objective-CNEVoiceRoomKitConfig *config = [[NEVoiceRoomKitConfig alloc] init];
config.appKey = @"";
[NEVoiceRoomKit.getInstance initializeWithConfig:config callback:^(NSInteger code, NSString *_Nullable msg, id _Nullable objc) {

}];

四:登录鉴权

请求 SDK 进行登录鉴权,您只有完成 SDK 登录鉴权才可以创建语聊房房间。

示例代码如下:

Objective-C[NEVoiceRoomKit.getInstance login:account token:token callback:^(NSInteger code, NSString *_Nullable msg, id _Nullable objc) {

}];

示例代码中的 accounttoken 是您的应用服务器向 NERoom 服务器申请创建账号时,返回的 userUuiduserToken 的值,具体请参考 创建账号

五:实现语聊房

API 调用时序

sequenceDiagram
    autonumber
    actor hostClientA as 主播 A client
    participant voiceRoomKitA as VoiceRoomKit
    participant app_server as VoiceRoom_Server
    participant voiceRoomKitB as VoiceRoomKit
    actor audienceB as 观众 B client

    Note over hostClientA, audienceB: 主播开播
    hostClientA ->> voiceRoomKitA:createRoom
    voiceRoomKitA ->> app_server:createRoom
    app_server -->> hostClientA:房间信息
    hostClientA ->> voiceRoomKitA:joinRoom
    voiceRoomKitA ->> app_server:joinRoom
    app_server -->> hostClientA:加入成功
    hostClientA ->> voiceRoomKitA:submitSeatRequest<br>上麦
    voiceRoomKitA ->> app_server:submitSeatRequest<br>上麦
    hostClientA ->> voiceRoomKitA:unmuteMyAudio
    voiceRoomKitA ->> app_server:unmuteMyAudio

    Note over hostClientA, audienceB: 观众进入房间
    audienceB ->> voiceRoomKitB:joinRoom
    voiceRoomKitB ->> app_server:joinRoom
    app_server -->> audienceB:房间信息
    audienceB ->> voiceRoomKitB:unmuteMyAudio
    voiceRoomKitB ->> app_server:unmuteMyAudio

sequenceDiagram
    autonumber
    actor hostClientA as 主播 A client
    participant voiceRoomKitA as VoiceRoomKit
    participant app_server as VoiceRoom_Server
    participant voiceRoomKitB as VoiceRoomKit
    actor audienceB as 观众 B client

    Note over hostClientA, audienceB: 抱观众上麦
    hostClientA ->> voiceRoomKitA:邀请上麦<br>sendSeatInvitation
    voiceRoomKitA ->> app_server:邀请上麦<br>sendSeatInvitation
    app_server ->> voiceRoomKitB:自动同意上麦<br>onSeatInvitationAccepted
    voiceRoomKitB ->> audienceB:自动同意上麦<br>onSeatInvitationAccepted
    app_server ->> voiceRoomKitB:麦位变更<br>onSeatListChanged
    voiceRoomKitB ->> audienceB:麦位变更<br>onSeatListChanged
    app_server ->> voiceRoomKitA:自动同意上麦<br>onSeatInvitationAccepted
    voiceRoomKitA ->> hostClientA:自动同意上麦<br>onSeatInvitationAccepted
    app_server ->> voiceRoomKitA:麦位变更<br>onSeatListChanged
    voiceRoomKitA ->> hostClientA:麦位变更<br>onSeatListChanged
    audienceB ->> audienceB:刷新 UI
    hostClientA ->> hostClientA:刷新 UI

    Note over hostClientA, audienceB: 踢观众下麦
    hostClientA ->> voiceRoomKitA:主播踢观众 B 下麦<br>kickSeat
    voiceRoomKitA ->> app_server:主播踢观众 B 下麦<br>kickSeat
    app_server ->> voiceRoomKitB:主播踢观众 B 下麦<br>onSeatKicked
    voiceRoomKitB ->> audienceB:主播踢观众 B 下麦<br>onSeatKicked
    app_server ->> voiceRoomKitB:麦位变更<br>onSeatListChanged
    voiceRoomKitB ->> audienceB:麦位变更<br>onSeatListChanged
    app_server ->> voiceRoomKitA:主播踢观众 B 下麦<br>onSeatKicked
    voiceRoomKitA ->> hostClientA:主播踢观众 B 下麦<br>onSeatKicked
    app_server ->> voiceRoomKitA:麦位变更<br>onSeatListChanged
    voiceRoomKitA ->> hostClientA:麦位变更<br>onSeatListChanged
    audienceB ->> audienceB:刷新 UI
    hostClientA ->> hostClientA:刷新 UI

观众申请上麦的时序图如下:

sequenceDiagram
    autonumber
    actor hostClientA as 主播 A client
    participant voiceRoomKitA as VoiceRoomKit
    participant app_server as VoiceRoom_Server
    participant voiceRoomKitB as VoiceRoomKit
    actor audienceB as 观众 B client

    audienceB->>voiceRoomKitB: 申请上麦<br>submitSeatRequest
    voiceRoomKitB->>app_server: 申请上麦<br>submitSeatRequest
    app_server-->>voiceRoomKitB: 麦位变更<br>onSeatListChanged
    voiceRoomKitB-->>audienceB: 麦位变更<br>onSeatListChanged
    app_server-->>voiceRoomKitA: 观众 B 申请上麦<br>onSeatRequestSubmitted
    voiceRoomKitA-->>hostClientA: 观众 B 申请上麦<br>onSeatRequestSubmitted
    app_server-->>voiceRoomKitA: 麦位变更<br>onSeatListChanged
    voiceRoomKitA-->>hostClientA: 麦位变更<br>onSeatListChanged
    audienceB->>audienceB: 刷新 UI
    hostClientA->>hostClientA: 刷新 UI

    alt 主播同意上麦申请
        hostClientA->>voiceRoomKitA: 主播同意上麦申请<br>approveSeatRequest
        voiceRoomKitA->>app_server: 主播同意上麦申请<br>approveSeatRequest
        app_server-->>voiceRoomKitA: 主播同意上麦申请<br>onSeatRequestApproved
        voiceRoomKitA-->>hostClientA: 主播同意上麦申请<br>onSeatRequestApproved
        app_server-->>voiceRoomKitB: 主播同意上麦申请<br>onSeatRequestApproved
        voiceRoomKitB-->>audienceB: 主播同意上麦申请<br>onSeatRequestApproved
        app_server-->>voiceRoomKitB: 麦位变更<br>onSeatListChanged
        voiceRoomKitB-->>audienceB: 麦位变更<br>onSeatListChanged
        audienceB->>audienceB: 刷新 UI
        hostClientA->>hostClientA: 刷新 UI
    else 主播拒绝上麦申请
        hostClientA->>voiceRoomKitA: 主播不同意上麦申请<br>rejectSeatRequest
        voiceRoomKitA->>app_server: 主播不同意上麦申请<br>rejectSeatRequest
        app_server-->>voiceRoomKitA: 主播拒绝观众 B 上麦<br>onSeatRequestRejected
        voiceRoomKitA-->>hostClientA: 主播拒绝观众 B 上麦<br>onSeatRequestRejected
        app_server-->>voiceRoomKitB: 主播拒绝观众 B 上麦<br>onSeatRequestRejected
        voiceRoomKitB-->>audienceB: 主播拒绝观众 B 上麦<br>onSeatRequestRejected
        app_server-->>voiceRoomKitB: 麦位变更<br>onSeatListChanged
        voiceRoomKitB-->>audienceB: 麦位变更<br>onSeatListChanged
        audienceB->>audienceB: 刷新 UI
        hostClientA->>hostClientA: 刷新 UI
    end

观众取消申请上麦的时序图如下:

sequenceDiagram
    autonumber
    participant hostClientA as 主播 A client
    participant voiceRoomKitA as VoiceRoomKit
    participant app_server as VoiceRoom_Server
    participant voiceRoomKitB as VoiceRoomKit
    participant audienceB as 观众 B client

    audienceB->>voiceRoomKitB: 取消申请上麦<br>cancelSeatRequest
    voiceRoomKitB->>app_server: 取消申请上麦<br>cancelSeatRequest
    app_server->>voiceRoomKitA: 观众 B 取消上麦<br>onSeatRequestCancelled
    voiceRoomKitA->>hostClientA: 观众 B 取消上麦<br>onSeatRequestCancelled
    app_server->>voiceRoomKitA: 麦位变更<br>onSeatListChanged
    hostClientA->>hostClientA: 刷新 UI
    app_server->>voiceRoomKitB: 观众 B 取消上麦<br>onSeatRequestCancelled
    voiceRoomKitB->>audienceB: 观众 B 取消上麦<br>onSeatRequestCancelled
    app_server->>voiceRoomKitB: 麦位变更<br>onSeatListChanged
    audienceB->>audienceB: 刷新 UI

观众主动下麦的时序图如下:

sequenceDiagram
    autonumber
    participant hostClientA as 主播 A client
    participant voiceRoomKitA as VoiceRoomKit
    participant app_server as VoiceRoom_Server
    participant voiceRoomKitB as VoiceRoomKit
    participant audienceB as 观众 B client

    audienceB->>voiceRoomKitB: 下麦<br>leaveSeat
    voiceRoomKitB->>app_server: 下麦<br>leaveSeat
    app_server->>voiceRoomKitA: 观众 B 成功下麦<br>onSeatLeave
    voiceRoomKitA->>hostClientA: 观众 B 成功下麦<br>onSeatLeave
    app_server->>voiceRoomKitA: 麦位变更<br>onSeatListChanged
    hostClientA->>hostClientA: 刷新 UI
    app_server->>voiceRoomKitB: 观众 B 成功下麦<br>onSeatLeave
    voiceRoomKitB->>audienceB: 观众 B 成功下麦<br>onSeatLeave
    app_server->>voiceRoomKitB: 麦位变更<br>onSeatListChanged
    audienceB->>audienceB: 刷新 UI

主播开播

  1. 主播调用 createRoom 接口创建房间。

    NECreateVoiceRoomParams 参数说明:

    参数 类型
    描述
    title String 房间名。
    最大长度为 64 个字符。
    nick String 昵称。
    seatCount int 麦位个数,默认 8 个,取值范围为 1~20。
    configId int 模版 ID。获取方法请参考 如何获取模板 ID
    cover String 封面,请填写封面图片的 URL 地址。
    extraData String 扩展字段。

    示例代码如下:

    Objective-CNECreateVoiceRoomParams *params = [[NECreateVoiceRoomParams alloc] init];
    params.title = @"语聊房";
    params.seatCount = 9;
    params.configId =
    params.cover = @"";
    
    [[NEVoiceRoomKit getInstance]
        createRoom:params
            options:[[NECreateVoiceRoomOptions alloc] init]
            callback:^(NSInteger code, NSString *_Nullable msg, NEVoiceRoomInfo *_Nullable obj) {
                }];
    
  2. 主播调用 joinRoom 接口加入房间。

    示例代码如下:

    Objective-CNEJoinVoiceRoomParams *param = [NEJoinVoiceRoomParams new];
    param.nick = @"name";
    param.roomUuid = @"roomUuid";
    param.role = @"host";
    param.liveRecordId = liveRecordId;
        [NEVoiceRoomKit.getInstance
        joinRoom:param
        options:[NEJoinVoiceRoomOptions new]
        callback:^(NSInteger code, NSString *_Nullable msg, NEVoiceRoomInfo *_Nullable info) {
            }];
    
  3. 调用 submitSeatRequest 上麦。

    示例代码如下:

    Objective-C[NEVoiceRoomKit.getInstance
              submitSeatRequest:index
                      exclusive:YES
                       callback:^(NSInteger code, NSString *_Nullable msg, id _Nullable obj) {
                       }];
    
  4. 调用 addVoiceRoomListener 接口监听房间里的事件。

    详细的事件列表请参考 NEVoiceRoomListener

    示例代码如下:

    Objective-C[NEVoiceRoomKit.getInstance addVoiceRoomListener:self];
    
  5. 收到加入成功的 onMemberJoinRoom 回调后,调用 unmuteMyAudio 方法开启本地音频采集。

    示例代码如下:

    Objective-C[NEVoiceRoomKit.getInstance
        unmuteMyAudio:^(NSInteger code, NSString *_Nullable msg, id _Nullable obj) {
    
        }];
    

观众进入房间

  1. 观众调用 joinRoom 接口加入房间。

  2. 观众调用 addVoiceRoomListener 接口监听房间里的事件。

  3. 观众调用 muteMyAudio 方法关闭本地音频采集。

    等到上麦后,再开启本地音频采集。

麦位管理

添加麦位事件监听

调用 addVoiceRoomListener 接口,监听麦位相关的事件。

Objective-C/// 成员进入房间回调
/// - Parameter members: 成员列表
- (void)onMemberJoinRoom:(NSArray<NEVoiceRoomMember *> *)members {

}

/// 成员离开房间回调
/// - Parameter members: 成员列表
- (void)onMemberLeaveRoom:(NSArray<NEVoiceRoomMember *> *)members {

}

/// 房间结束回调
/// - Parameter reason: 房间结束原因
- (void)onRoomEnded:(enum NEVoiceRoomEndReason)reason {

}

/// Rtc 频道错误回调
/// - Parameter code: 错误码
- (void)onRtcChannelError:(NSInteger)code {

}

/// 本端音频输出设备变更通知,如切换到扬声器、听筒、耳机等
/// - Parameter device: 音频输出类型
- (void)onAudioOutputDeviceChanged:(enum NEVoiceRoomAudioOutputDevice)device {

}

/// 成员音频关闭回调
/// - Parameters:
///   - member: 成员信息
///   - mute: 是否关闭
///
///   添加监听后,成员音频状态变更会触发此方法
- (void)onMemberAudioMuteChanged:(NEVoiceRoomMember *)member mute:(BOOL)mute operateBy:(NEVoiceRoomMember *)operateBy {

}

/// 聊天室消息回调
/// - Parameter message: 文本消息
///
/// 添加监听后,收到聊天室消息会触发此方法
- (void)onReceiveTextMessage:(NEVoiceRoomChatTextMessage *)message {

}

/// 当前歌曲播放进度
/// - Parameters:
///   - postion: 歌曲播放进度
- (void)onSongPlayingPosition:(uint64_t)postion {

}

/// 成员[user]提交了位置为[seatIndex]的麦位申请
/// - Parameters:
///   - seatIndex: 麦位位置,**-1** 表示未指定位置
///   - account: 申请人的用户 ID
- (void)onSeatRequestSubmitted:(NSInteger)seatIndex account:(NSString *)account {

}

/// 成员[user]取消了位置为[seatIndex]的麦位申请
/// - Parameters:
///   - seatIndex: 麦位位置,**-1** 表示未指定位置
///   - account: 申请人的用户 ID
- (void)onSeatRequestCancelled:(NSInteger)seatIndex account:(NSString *)account {

}

/// 管理员通过了成员[user]的麦位申请,位置为[seatIndex]
/// - Parameters:
///   - seatIndex: 麦位位置
///   - account: 申请人的用户 ID
///   - operateBy: 同意该申请的用户 ID
- (void)onSeatRequestApproved:(NSInteger)seatIndex account:(NSString *)account operateBy:(NSString *)operateBy isAutoAgree:(BOOL)isAutoAgree {

}

/// 管理员拒绝了成员[user]的麦位申请,位置为[seatIndex]
/// - Parameters:
///   - seatIndex: 麦位位置,**-1** 表示未指定位置
///   - account: 申请人的用户 ID
///   - operateBy: 拒绝该申请的用户 ID
- (void)onSeatRequestRejected:(NSInteger)seatIndex account:(NSString *)account operateBy:(NSString *)operateBy {

}

/// 成员下麦,位置为[seatIndex]
/// - Parameters:
///   - seatIndex: 麦位位置
///   - account: 下麦成员
- (void)onSeatLeave:(NSInteger)seatIndex account:(NSString *)account {

}

/// 成员[user]被[operateBy]从位置为[seatIndex]的麦位踢掉
/// - Parameters:
///   - seatIndex: 麦位位置
///   - account: 成员
///   - operateBy: 操作人
- (void)onSeatKicked:(NSInteger)seatIndex account:(NSString *)account operateBy:(NSString *)operateBy {

}

/// 接受邀请
/// - Parameters:
///   - seatIndex: 麦位位置
///   - account: 成员
- (void)onSeatInvitationAccepted:(NSInteger)seatIndex account:(NSString *)account isAutoAgree:(BOOL)isAutoAgree {

}

/// 成员音频禁用事件回调
/// - Parameters:
///   - member: 成员
///   - banned: 是否被禁用音频
- (void)onMemberAudioBanned:(NEVoiceRoomMember *)member banned:(BOOL)banned {

}

/// 麦位变更通知
/// - Parameter seatItems: 麦位列表
- (void)onSeatListChanged:(NSArray<NEVoiceRoomSeatItem *> *)seatItems {

}

主播邀请观众上麦

主播调用 sendSeatInvitation 接口邀请观众上麦。

Objective-C  [NEVoiceRoomKit.getInstance
      sendSeatInvitationWithSeatIndex:seatIndex
                                 user:account
                             callback:^(NSInteger code, NSString *_Nullable msg, id _Nullable obj) {

                             }];

主播同意观众上麦

主播调用 approveSeatRequest 接口同意观众上麦。

Objective-C  [NEVoiceRoomKit.getInstance
      approveSeatRequestWithAccount:seatItem.user
                           callback:^(NSInteger code, NSString *_Nullable msg, id _Nullable obj) {

                           }];

主播拒绝观众上麦

主播调用 rejectSeatRequest 接口拒绝观众上麦。

Objective-C  [NEVoiceRoomKit.getInstance
      rejectSeatRequestWithAccount:seatItem.user
                          callback:^(NSInteger code, NSString *_Nullable msg, id _Nullable obj) {

                          }];

主播将观众移出连麦

主播调用 kickSeat 接口将观众移出连麦。

Objective-C[NEVoiceRoomKit.getInstance
    kickSeatWithAccount:seatItem.user
                callback:^(NSInteger code, NSString *_Nullable msg,
                            id _Nullable obj) {

                }];

观众申请上麦

观众调用 submitSeatRequest 接口申请上麦。

Objective-C[NEVoiceRoomKit.getInstance
    submitSeatRequest:seatItem.index
            exclusive:YES
            callback:^(NSInteger code, NSString *_Nullable msg, id _Nullable obj) {

            }];

观众取消申请上麦

观众调用 cancelSeatRequest 接口取消申请上麦。

Objective-C[NEVoiceRoomKit.getInstance
    cancelSeatRequest:^(NSInteger code, NSString *_Nullable msg, id _Nullable obj) {
    }];

观众主动下麦

观众调用 leaveSeat 接口下麦。

Objective-C[NEVoiceRoomKit.getInstance
    leaveSeat:^(NSInteger code, NSString *_Nullable msg, id _Nullable obj) {

    }];

聊天消息

  1. 调用 sendTextMessage 发送聊天室文本消息。

示例代码如下:

Objective-C[NEVoiceRoomKit.getInstance
    sendTextMessage:text
            callback:^(NSInteger code, NSString *_Nullable msg, id _Nullable obj) {

            }];

离开房间

  1. 调用 leaveRoom 接口离开房间。

    示例代码如下:

    Objective-C[NEVoiceRoomKit.getInstance
        leaveRoom:^(NSInteger code, NSString *_Nullable msg, id _Nullable obj) {
    
        }];
    
  2. 离开房间成功后,会触发 NERoomListener.onMemberLeaveRoom 回调,通知房间内所有成员。

  3. 主播调用 endRoom 接口删除房间。

    示例代码如下:

    Objective-C    [NEVoiceRoomKit.getInstance
        endRoom:^(NSInteger code, NSString *_Nullable msg, id _Nullable obj) {
    
        }];
    
  4. 删除房间成功后,会触发 NERoomListener 协议中的 onRoomEnded 回调方法。

六:进阶功能

伴音

  1. 调用 NEVoiceRoomKitstartAudioMixing 方法播放伴音。

    NEVoiceRoomCreateAudioMixingOption 参数说明如下表所示。

    参数 类型 描述
    path String 待播放的音乐文件的绝对路径或 URL 地址,支持本地 SD 卡中的绝对路径或 URL 地址
    loopCount int 伴音循环播放的次数。
    • 1:(默认)播放一次
    • ≤ 0:无限循环播放
    sendEnabled boolean 是否将伴音发送远端,默认为 true,即远端用户可以听到该伴音。
    sendVolume int 音乐文件的发送音量,取值范围为 0~200。默认为 100,表示使用文件的原始音量。
    playbackEnabled boolean 是否本地播放伴音。默认为 true,即本地用户可以听到该伴音。
    playbackVolume int 音乐文件的播放音量,取值范围为 0~200。默认为 100,表示使用文件的原始音量。
    startTimeStamp long 音乐文件开始播放的时间,UTC 时间戳,即从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到事件发生时的毫秒数。默认值为 0,表示立即播放。
    sendWithAudioType NEVoiceRoomAudioStreamType 伴音跟随音频主流还是辅流,默认跟随主流。
    • NEVoiceRoomAudioStreamTypeMain:伴音跟随主流
    • NEVoiceRoomAudioStreamTypeSub:伴音跟随辅流
  2. 调用 setAudioMixingVolume 设置伴音的音量。

  3. 在离开房间前调用 stopAudioMixing 结束伴音。

示例代码如下:

Objective-C// 打开伴音
NEVoiceRoomCreateAudioMixingOption *opt = [NEVoiceRoomCreateAudioMixingOption new];
opt.path = [[NEVoiceRoomUI ne_sourceBundle] pathForResource:self.context.currentBgm.fileName
                                                    ofType:@"mp3"];
opt.sendVolume = self.context.rtcConfig.audioMixingVolume;
opt.playbackVolume = self.context.rtcConfig.audioMixingVolume;
opt.loopCount = 0;
NSInteger code = [NEVoiceRoomKit.getInstance startAudioMixing:opt];

// 设置伴音音量
[NEVoiceRoomKit.getInstance setAudioMixingVolume:sender.value];

// 结束伴音
[NEVoiceRoomKit.getInstance stopAudioMixing];

音效

  1. 调用 NEVoiceRoomKitplayEffect 方法播放音效。

    NEVoiceRoomCreateAudioEffectOption 参数说明如下表所示。

    参数 类型 描述
    path String 待播放的音乐文件的绝对路径或 URL 地址,支持本地 SD 卡中的绝对路径或 URL 地址
    loopCount int 音效循环播放的次数。1:(默认)播放一次。≤ 0:无限循环播放
    sendEnabled boolean 是否将音效发送远端,默认为 true,即远端用户可以听到该音效。
    sendVolume int 音效文件的发送音量,取值范围为 0~200。默认为 100,表示使用文件的原始音量。
    playbackEnabled boolean 是否本地播放音效。默认为 true,即本地用户可以听到该音效。
    playbackVolume int 音乐文件的播放音量,取值范围为 0~200。默认为 100,表示使用文件的原始音量。
    startTimeStamp long 音乐文件开始播放的时间,UTC 时间戳,即从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到事件发生时的毫秒数。默认值为 0,表示立即播放。
    sendWithAudioType NEVoiceRoomAudioStreamType 伴音跟随音频主流还是辅流,默认跟随主流。
    • NEVoiceRoomAudioStreamTypeMain:伴音跟随主流
    • NEVoiceRoomAudioStreamTypeSub:伴音跟随辅流
  2. 调用 setEffectVolume 方法设置音效的音量。

  3. 在离开房间前,调用 stopAllEffect 方法停止播放所有音效文件。

示例代码如下:

Objective-C// 打开伴音
int eid = 1;
NEVoiceRoomCreateAudioMixingOption *opt = [NEVoiceRoomCreateAudioMixingOption new];
opt.path = [[NEVoiceRoomUI ne_sourceBundle] pathForResource:self.context.currentBgm.fileName
                                                    ofType:@"mp3"];
opt.sendVolume = self.context.rtcConfig.audioMixingVolume;
opt.playbackVolume = self.context.rtcConfig.audioMixingVolume;
opt.loopCount = 0;
NSInteger code = [NEVoiceRoomKit.getInstance playEffect:eid option:opt];

// 设置伴音音量
[NEVoiceRoomKit.getInstance setEffectVolume:eid volume:sender.value];

// 结束伴音
[NEVoiceRoomKit.getInstance stopAllEffect];

耳返

  1. 调用 enableEarback 开启耳返。

    Objective-C[NEVoiceRoomKit.getInstance enableEarBack:100];
    

    开启耳返功能后,必须连接上耳机或耳麦,才能正常使用耳返功能。

  2. 调用 disableEarback 关闭耳返。

    [NEVoiceRoomKit.getInstance disableEarBack];
    

发送和接收礼物

  1. 观众调用 NEVoiceRoomKitsendBatchGift 接口发送礼物。

    参数说明如下:

    参数 类型 描述
    giftId Int 礼物 ID,礼物 ID 由业务服务器自行维护和下发。
    giftCount Int 给单个对象赠送的礼物数量,取值范围为 1 ~ 1314。
    如果礼物赠送对象为多人,则送出的礼物总数为 礼物数量 x 赠送对象数量
    userUuids [String] 礼物赠送对象的用户 ID 的数组,只支持给主播和连麦者赠送礼物。
    userUuid 是您的应用服务器向 NERoom 服务器申请创建账号时,返回的账号,具体请参考 创建账号
    callback NEVoiceRoomCallback? = nil 回调。

    示例代码如下:

    Objective-C[[NEVoiceRoomKit getInstance]
                                    sendBatchGift:giftId
                                        giftCount:giftCount
                                        userUuids:userUuids
                                        callback:^(NSInteger code, NSString *_Nullable msg,
                                                    id _Nullable obj) {
    
                                        }];
    
  2. 接收礼物。

    监听 onReceiveBatchGift 回调。当收到礼物时,会触发该回调。

    示例代码如下:

    Objective-C- (void)onReceiveBatchGiftWithGiftModel:(NEVoiceRoomBatchGiftModel *)giftModel {
    // 收到批量礼物回调
    }
    

设置悬浮小窗(浮窗)模式

当您的手机需要操作其他界面时,您可以单击右上角最小化按钮,将语聊房窗口设置为悬浮小窗模式,使任务切换更便捷。

悬浮小窗时,系统并不会退出当前房间,后台继续运行语聊房。

小窗.png

实现思路如下:

  1. 获取 window 对象,将当前自定义视图添加到 window 上。

  2. 自定义视图内,对坐标进行监听,添加动画,实现吸附效果。

  3. 针对拖拽的同时单击其他 view 的行为进行异常 case 处理,监听 touchesCancelled 方法,实现吸附效果。

  4. 持有房间对象,避免释放。并在收到房间关闭回调时,释放该对象,避免循环引用。

    具体实现方法请参考 语聊房示例项目源码。示例项目源码中的相关说明如下:

    • NEVoiceRoomDraggableButton:自定义悬浮小窗的界面视图。

    • NEVoiceRoomFloatWindowSingleton:控制器持有对象,您可以修改悬浮小窗的相关业务逻辑。例如,当控制器 pop 时,保留原有界面不被销毁,相关设置如下:

      [[NEVoiceRoomFloatWindowSingleton Ins] addViewControllerTarget:target];。若需要释放原有界面,则将 target 设置为 n

展示悬浮小窗

示例代码如下:

Objective-C[[NEVoiceRoomFloatWindowSingleton Ins] setHideWindow:YES];

隐藏悬浮小窗

示例代码如下:

Objective-C[[NEVoiceRoomFloatWindowSingleton Ins] setHideWindow:NO];

音频波谱

主播、连麦者说话时,相应的麦位上会展示音频波谱,以便观众识别当前说话者。

实现方法如下:

  1. 监听 NEVoiceRoomKitonRtcAudioVolumeIndication 回调,成员说话时会触发该回调。
  2. 在回调方法中获取音量值 volumes
  3. 根据 volumes 音量值,使用 LottieAnimationView 三方库加载本地动画。

详细的示例代码请参考 语聊房示例项目源码

此文档是否对你有帮助?
有帮助
去反馈
  • 方案架构
  • 开发环境
  • 前提条件
  • 一:下载源码
  • 二:集成组件
  • 第一步:通过 CocoaPods 集成
  • 第二步:配置权限
  • 三:初始化组件
  • 四:登录鉴权
  • 五:实现语聊房
  • API 调用时序
  • 主播开播
  • 观众进入房间
  • 麦位管理
  • 聊天消息
  • 离开房间
  • 六:进阶功能
  • 伴音
  • 音效
  • 耳返
  • 发送和接收礼物
  • 设置悬浮小窗(浮窗)模式
  • 音频波谱