范围语音

更新时间: 2024/03/15 17:20:45

范围语音是指在一个 RTC 房间内,用户可以与一定距离内的其他用户进行实时语音通话。您可以调用 NERtc 客户端接口来更新声源方位,以告知服务器本端的位置,服务器根据本端世界坐标+本端接收音频的范围,与其他端世界坐标 + 其他端接收音频的范围进行判断,然后对玩家范围内的音频流进行转发。

NERTC SDK 从 V5.5.10 开始支持范围语音。

应用场景

范围语音的应用场景举例如下:

应用场景 说明
大逃杀游戏 提供大逃杀类型游戏、生存射击类手游中特有的“仅小队”或“所有人”的语音模式。在游戏设置中,根据玩家选择:
  • 仅小队:仅小队内的玩家可以进行语音通话。
  • 所有人:听见队伍中队友声音,以及一定范围内其他对局玩家说话的声音。

基本概念

使用范围语音功能,涉及到范围语音的模式语音接收范围以及 TeamID 这三个概念。

  • 范围语音的模式

    当进入范围语音房间时,有两种语音模式可供选择:

    语音模式 参数名称 功能
    所有人 NERtcRangeAudioModeDefault
    • 其他玩家在一定范围内可以听到该玩家说话,如果范围内有其他玩家也选择了此模式,则它们可以进行互相通话。
    • TeamID 相同的队友可以互相听到。
    仅小队 NERtcRangeAudioModeTeam 仅 TeamID 相同的队友可以互相听到。

    队友之间的通话不受距离以及语音模式的影响。

  • 语音接收范围

    范围语音接收范围.png

    如果设置的语音模式为所有人(NERtcRangeAudioModeDefault ),此时的语音接收范围受 updateSelfPosition 接口影响。

    假设以下两个玩家 A 与 B 为不同的小队,且设置的语音模式为所有人(NERtcRangeAudioModeDefault )

    玩家坐标 语音接收范围 与另一玩家声音可达情况 与队友声音可达情况
    A(0,0,0) 10米 可以听到玩家 B 的声音,因为 B 玩家距离 A 玩家在 10 米内 不影响同一小队成员互相通话
    B(0,8,0) 5米 不可以听到玩家 A 的声音,因为 A 玩家与 B 玩家距离超过 5 米 不影响同一小队成员互相通话
  • TeamID

    以下介绍 TeamID 为 0 和非 0 代表的意义。

    • 当进入语音房间时指定的 TeamID != 0 时,将启用范围语音房间模式。如果某成员使用 TeamID = 1 进入语音房间,当他设置语音模式为 NERtcRangeAudioModeTeam ,则只有 TeamID = 1 的成员能听到他的声音;如果他设置的语音模式为 NERtcRangeAudioModeDefault ,则除了 TeamID = 1 的成员,一定范围内的玩家也能听到他的声音。
    TeamID 情况语音模式范围声音可达情况
    TeamID != 0,假设 TeamID = 1 NERtcRangeAudioModeTeam 10米声音只能和 TeamID = 1 的成员互通
    NERtcRangeAudioModeDefault 10米声音能和 TeamID = 1 的成员、以及语音模式设置为 NERtcRangeAudioModeDefault 的同房间10米范围内成员互通
    • 如果某成员使用 TeamID = 0 进入语音房间,将启用范围语音主持人模式。房间内所有人(不论范围语音的模式是所有人还是仅小队)都可以听到该成员的声音。
    TeamID 情况TeamID 修改时机范围声音可达情况
    TeamID = 0 进房前 无论TeamID 是否为 0,以 TeamID = 0 进入房间10米说话声音全房间成员(不论语音模式是所有人还是仅小队)都能听到
    能与 TeamID = 0 的成员互相沟通
    不能听到房间内其他人说话声音

场景示例

  • 大逃杀游戏: 例如一个生存射击类型的游戏,每 4 个人为一个队伍,则这 4 个人需要设置一个小队号 TeamID,每 100 人为一个对局房间,一个对局共 25 个小队,则 25 个小队都进入一个语音房间。在对局中,如果某玩家想和 10 米范围内的陌生人沟通,则将语音距离范围设置为 10,将语音模式设置为 NERtcRangeAudioModeDefault ,同时打开麦克风及扬声器。如果他只想和小队成员沟通,不和非小队的成员沟通,则只需要将语音模式设置为 NERtcRangeAudioModeTeam
  • 主持人模式: 在游戏中例如虚拟桌游场景,主持人说话声音即要房间内所有人听见,也要听见范围内玩家说话的声音,可以让主持人先以 TeamID != 0 的形式进入房间,进房后将 TeamID 设置为 0,此时主持人说话全房间的人都能听见。

API 调用时序

sequenceDiagram
    participant 应用层
    participant NERtcSDK
    participant 云信服务器

    Note over 应用层, 云信服务器: 启用并配置范围语音
    rect rgb(191, 223, 255)
    应用层->>NERtcSDK: setAudioRecvRange 设置语音范围
    应用层->>NERtcSDK: setRangeAudioTeamID 设置队伍号

    应用层->>NERtcSDK: setRangeAudioMode 设置语音模式
   
    end

    Note over 应用层, 云信服务器: 加入房间
    应用层->>NERtcSDK: joinChannel
    NERtcSDK->>云信服务器: joinChannel
    云信服务器->>NERtcSDK: onJoinChannel
    NERtcSDK->>应用层: onJoinChannel

    Note over 应用层, 云信服务器: 添加或更新位置信息
    rect rgb(191, 223, 255)
    应用层->>NERtcSDK: updateSelfPosition 动态更新本端空间坐标信息

    应用层->>NERtcSDK: setRangeAudioTeamID 动态设置队伍号[可选]
    应用层->>NERtcSDK: setRangeAudioMode 动态设置语音模式[可选]
    应用层->>NERtcSDK: setAudioRecvRange 动态设置语音范围[可选]

    NERtcSDK->>云信服务器: Voice data setting & rendering
    end

实现方法

步骤1 设置范围语音的距离范围

在加入房间前,调用 setAudioRecvRange 接口设置语音范围。

参数描述如下表所示:

参数 类型 描述
audibleDistance Integer 监听器能接收到音频的最大距离,用户的声音在该范围内可被听见。在该范围内,声音将会随距离的增加而衰减,直至超出所设置的范围,则不再有声音。
取值范围:[1, max int) ,无默认值。
conversationalDistance Integer 该参数设置的值对范围语音不起作用,保持默认值即可。监听器不对音频进行衰减的距离,在该距离范围内,扬声器音频保持其原始音量,超出该范围时,声音将会随距离的增加而衰减。默认值为 1。

rollOff

Integer

该参数设置的值对范围语音不起作用,保持默认值即可。距离衰减模式。一共有四种:

  • kNERtcDistanceRolloffLogarithmic(0):指数衰减。
  • kNERtcDistanceRolloffLinear(1):线性衰减。
  • kNERtcDistanceRolloffNone(2):无衰减。
  • kNERtcDistanceRolloffLinearOnly (3):仅线性衰减,没有方位效果。

如果您只想要实现范围语音,不需要小队模式,您只需要调用setAudioRecvRange 接口设置语音的距离范围即可,不需要调用 setRangeAudioTeamIDsetRangeAudioMode

步骤2 设置 TeamID

在加入房间前,调用 setRangeAudioTeamID 接口设置队伍号。

  • 加入房间后,可通过此接口修改队伍号,设置后立即生效。
  • 离开房间后,TeamID 失效,需要重新配置TeamID ,请在每次加入房间之前都调用此方法设置 TeamID。
  • 如果离开房间后再加入房间,请在收到退房成功回调(onLeaveChannel)后,再调用设置队伍号接口。

步骤3 设置范围语音的模式

在加入房间前,调用 setRangeAudioMode 接口设置语音模式。

语音模式的参数说明如下表所示。

语音模式 参数名称 功能
所有人 NERtcRangeAudioModeDefault
  • 其他玩家在一定范围内可以听到该玩家说话,如果范围内有其他玩家也选择了此模式,则它们可以进行互相通话。
  • TeamID 相同的队友可以互相听到。
仅小队 NERtcRangeAudioModeTeam 仅 TeamID 相同的队友可以互相听到。
  • 加入房间后,可以随时修改语音模式,并立即生效。
  • 离开房间后,此参数不会自动重置为 NERtcRangeAudioModeDefault ,所以请在每次加入房间之前都调用此方法设置语音模式。
  • 不同范围语音模式,发声者声音的可接收情况说明请参见附录

步骤4 更新声源方位

更新声源方位的目的是向服务器传达本端的位置,以便通过本端的世界坐标和接收范围,与其他端的世界坐标和接收范围进行比较,以实现范围语音的效果。

在加入房间后,每帧调用 updateSelfPosition 方法并设置 info 参数,以更新音源或听者的空间位置信息。

参数 类型 描述
speakerPositionX CGFloat 发声坐标,表示左右,默认值为 0
speakerPositionY CGFloat 发声坐标,表示上下,默认值为 0
speakerPositionZ CGFloat 发声坐标,表示前后,默认值为 0
speakerQuaternionX CGFloat 发声旋转角度,4元素,默认值为 0
speakerQuaternionY CGFloat 发声旋转角度,4元素,默认值为 0
speakerQuaternionZ CGFloat 发声旋转角度,4元素,默认值为 0
speakerQuaternionW CGFloat 发声旋转角度,4元素,默认值为 0
headPositionX CGFloat 听觉坐标,表示左右,默认值为 0
headPositionY CGFloat 听觉坐标,表示上下,默认值为 0
headPositionZ CGFloat 听觉坐标,表示前后,默认值为 0
headQuaternionX CGFloat 听觉旋转角度,4元素,默认值为 0
headQuaternionY CGFloat 听觉旋转角度,4元素,默认值为 0
headQuaternionZ CGFloat 听觉旋转角度,4元素,默认值为 0
headQuaternionW CGFloat 听觉旋转角度,4元素,默认值为 0

3D坐标.png

示例代码

objective-c// Step 0: 创建并初始化好引擎
.....

// Step 1: 加入房间前设置范围语音相关参数
[[NERtcEngine sharedEngine] setAudioRecvRange:audibleDistance conversationalDistance:conversationalDistance rollOff:rollOff];
[[NERtcEngine sharedEngine] setRangeAudioMode:mode];    // 主要设置 audibleDistance,其他参数设置默认值即可
[[NERtcEngine sharedEngine] setRangeAudioTeamID:teamId];

// step 2: 加入房间,进行能力协商
[NERtcEngine.sharedEngine joinChannelWithToken:@"Your Token"
                                channelName: Your roomId
                                    myUid:Your userId
                        channelOptions:NERtcJoinChannelOptions
                            completion:^(NSError * _Nullable error, uint64_t channelId, uint64_t elapesd) {
                                                if (error) {
                                                    //加入失败
                                                } else {
                                                    //加入成功
                                                }
                            }];

// Step 3: 通话中获取本地用户的空间坐标
NERtcPositionInfo *spatializerPositionInfo = [[NERtcPositionInfo alloc] init];
// 更新说话人的位置 ...
[[NERtcEngine sharedEngine] updateSelfPosition:spatializerPositionInfo];

// Step 4: [可选] 通话中动态更新范围语音参数
[[NERtcEngine sharedEngine] setAudioRecvRange:audibleDistance2 conversationalDistance:conversationalDistance rollOff:rollOff];
[[NERtcEngine sharedEngine] setRangeAudioMode:mode2];
[[NERtcEngine sharedEngine] setRangeAudioTeamID:teamId2];

相关文档

文档 描述
空间音效 如果需要更加沉浸式的体验,建议范围语音配合 3D 音效一起使用。
设置音频转发路由 您可以设置推流白名单、拉流白名单或拉流黑名单,从而实现只推流给指定用户或只订阅指定用户的音频。可以和范围语音配合使用,以便满足游戏语音等场景下的需求。

附录

  • 假设 A 玩家状态为“所有人”,对应 B 玩家在不同语音模式下声音可达情况:
是否同一小队是否范围内语音模式A与B 是否能相互听到对方的声音
同一小队 NERtcRangeAudioModeDefault
NERtcRangeAudioModeTeam
NERtcRangeAudioModeDefault
NERtcRangeAudioModeTeam
不同小队 NERtcRangeAudioModeDefault
NERtcRangeAudioModeTeam
NERtcRangeAudioModeDefault
NERtcRangeAudioModeTeam
  • 假设 A 玩家状态为“仅小队”,对应 B 玩家在不同语音模式下声音可达情况:
是否同一小队是否范围内语音模式A与B 是否能相互听到对方的声音
同一小队 NERtcRangeAudioModeDefault
NERtcRangeAudioModeTeam
NERtcRangeAudioModeDefault
NERtcRangeAudioModeTeam
不同小队 NERtcRangeAudioModeDefault
NERtcRangeAudioModeTeam
NERtcRangeAudioModeDefault
NERtcRangeAudioModeTeam
此文档是否对你有帮助?
有帮助
去反馈
  • 应用场景
  • 基本概念
  • 场景示例
  • API 调用时序
  • 实现方法
  • 步骤1 设置范围语音的距离范围
  • 步骤2 设置 TeamID
  • 步骤3 设置范围语音的模式
  • 步骤4 更新声源方位
  • 示例代码
  • 相关文档
  • 附录