5.5 设置收听者的当前位置
。ZEGO Express SDK 从 2.11.0 版本起,新增游戏语音模块,主要包括:范围语音、3D 音效、小队语音。
功能 | 说明 |
---|---|
范围语音 |
房间内的收听者对音频的接收距离有范围限制,若发声者与自己的距离超过该范围,则无法听到声音。为保证语音清晰,附近超过 20 人发声时,只能听到离自己最近的 20 个发声者的声音。
假如设置音频接收距离的最大范围为 R,若发声者离收听者的距离为 r,则:
上图仅以范围语音模式为“全世界”时为例,更多不同模式组合关系下的声音可达情况请参考 5.10.2 设置通用语音模式。 |
3D 音效 |
声音有 3D 空间感,且按距离衰减。 |
通用语音模式 |
玩家可以选择加入小队,并支持在房间内自由切换“全世界”、“仅小队”、“隐秘小队”语音模式。
|
游戏语音功能适用于吃鸡类游戏、元宇宙类场景。
在吃鸡类游戏中,小队语音提供编队功能,在游戏开始前和开始后都可以更换小队,开发者无需关注流分组以及推拉流的实现,直接实现小队语音功能。
在吃鸡游戏和元宇宙场景中,提供 3D 音效能力,在收听发声者音效时,有方向感距离感,让场景感受更真实。
请参考 下载示例源码 获取源码。
相关源码请查看 “src/Examples/Others/RangeAudio” 目录下的文件。
在实现范围语音之前,请确保:
并确保开发环境满足以下要求:
使用范围语音功能时请务必关注如下注意事项,以免影响接入。
如果您已经使用 ZEGO Express SDK 的实时音视频功能,需要注意以下事项:
上图仅展示了实现游戏语音功能的核心步骤与接口,开发者可以根据业务需要,参考下文文档的详细介绍,实现其他相关接口。
npm i zego-express-engine-webrtc
命令安装依赖。npm 下载包支持 typescript 语言(推荐)。
import { ZegoExpressEngine } from 'zego-express-engine-webrtc'
1. 创建引擎
创建 ZegoExpressEngine 引擎实例,将申请到的 AppID 传入参数 appID
,将接入服务器地址传入参数 server
。
“server” 为接入服务器地址,获取的方式请参考 控制台 - 项目信息 。
初始化 ZegoExpressEngine 实例 zg 和范围语音功能实例 rangeAudio。
const zg = new ZegoExpressEngine(appID, server);
const rangeAudio = zg.createRangeAudioInstance();
2. 监听范围语音事件回调
如果需要注册回调,开发者可根据实际需要,实现 ZegoRangeAudioEvent 中的某些方法,通过范围语音实例 rangeAudio 可调用 on 接口设置回调。
rangeAudio.on("microphoneStateUpdate", (state, errorCode, extendedData) => {
if (state === 0) {
// 关闭麦克风声音
} else if(state === 1) {
// 开启麦克风中
} else if(state === 2) {
// 打开麦克风发送声音
}
})
通过 isAudioContextRunning 接口判断浏览器是否支持自动播放声音,如果 isSupport
为 false
,可以引导用户点击界面的 DOM 元素来触发点击事件,并在点击事件中调用 resumeAudioContext 接口来启动自动播放。
<button onclick="enableAutoPlay()">Click me</button>
const isSupport = rangeAudio.isAudioContextRunning();
async function enableAutoPlay() {
// result 标识是否启用成功
const result = await rangeAudio.resumeAudioContext();
}
1. 获取登录 Token
登录房间需要用于验证身份的 Token,获取方式请参考 用户权限控制。如需快速调试,可使用控制台生成临时 Token。
2. 登录房间
通过 ZegoExpressEngine 实例 zg 调用 loginRoom 接口,传入房间 ID 参数 roomID
、token
和用户参数 user
,根据实际情况传入参数 config
,登录房间。
roomID
、userID
和 userName
参数的取值都为自定义,userName
非必填。roomID
和 userID
都必须唯一,建议开发者将 userID
设置为一个有意义的值,可将其与自己的业务账号系统进行关联。 // 登录房间,成功则返回 true
const result = await zg.loginRoom(roomID, token, {userID, userName});
调用 updateSelfPosition 接口可以添加自身方位,或者在自身方位发生变化时更新自己在世界坐标系中的位置和朝向。
参数名 |
描述 |
position |
自身在世界坐标系中的坐标,参数是长度为 3 的 number 数组,三个值依次表示前、右、上的坐标值。 |
axisForward |
自身坐标系前轴的单位向量,参数是长度为 3 的 number 数组,三个值依次表示前、右、上的坐标值。 |
axisRight |
自身坐标系右轴的单位向量,参数是长度为 3 的 number 数组,三个值依次表示前、右、上的坐标值。 |
axisUp |
自身坐标系上轴的单位向量,参数是长度为 3 的 number 数组,三个值依次表示前、右、上的坐标值。 |
const position = [0,0,0];
const axisForward = [1,0,0];
const axisRight = [0,1,0];
const axisUp = [0,0,1];
rangeAudio.updateSelfPosition(position, axisForward, axisRight, axisUp);
登录房间成功后调用 updateAudioSource 接口来更新发声者位置。
全世界模式下:需要更新房间内,收听者和所有发声者的位置。如果未设置发声者位置,或者发声者超出收听者范围,会出现听不到声音的情况。
这里发声者指的是房间内其他人,收听者指的是自己。
userID:为房间内其他发声用户的 ID。
position:发声者在世界坐标系中的坐标,参数是长度为 3 的 number 数组,三个值依次表示前、右、上的坐标值。
const userID = "other";
const position = [1,0,0];
rangeAudio.updateAudioSource(userID, position);
调用 setAudioReceiveRange 接口设置听者接收音频距离的最大范围,即以自身为起点,3D 空间中以设置的距离为立体空间。设置该范围后,在开启 3D 音效的情况下,声音将会随距离的增加而衰减,直至超出所设置的范围,则不再有声音。小队内的语音,不会受到该值的限制,也不会有 3D 音效。
如果不设置则表示接收音频无距离限制,可听见房间内所有人的声音。
rangeAudio.setAudioReceiveRange(100);
调用 enableSpatializer 接口设置 3D 音效,enable
取值为 true
时表示开启 3D 音效,此时房间内非小队成员的音频,会随着发声者离自身的距离和方向的变化而产生空间感的变化,为 false
时表示关闭 3D 音效。(可随时开启或关闭)
该功能只对小队以外的人生效。
// enable 为 true 表示开启,为 false 表示关闭。默认是关闭。
rangeAudio.enableSpatializer(true);
登录房间成功后:
调用 enableMicrophone 接口设置是否开启麦克风,当 enable
取值为 true
时表示开启,取值为 false
时表示关闭。(可随时开启或关闭)
开发者可以通过监听 microphoneStateUpdate 事件回调,获取麦克风更新后的状态。
调用 enableSpeaker 接口设置是否开启扬声器,enable
取值为 true
时表示开始拉取和播放音频流,为 “false” 时表示停止拉取和播放音频流。(可随时开启或关闭)
调用 enableSpeaker 接口后,当超过最大拉流数限制(目前为 20 路)时,会优先拉取小队内成员音频流(需设置小队模式),再拉取世界内距离自身范围最近的音频流。
rangeAudio.on("microphoneStateUpdate", (state, errorCode, extendedData) => {
if (state === 0) {
// 关闭麦克风声音
} else if(state === 1) {
// 开启麦克风中
} else if(state === 2) {
// 已打开麦克风发送声音
}
})
// 开启麦克风,enable 为 true 表示开启,为 false 表示关闭。
rangeAudio.enableMicrophone(enable);
// 开启扬声器,enable 为 true 表示开启,为 false 表示关闭。
rangeAudio.enableSpeaker(enable);
调用 setTeamID 接口可根据需要设置想要加入的小队 ID(可随时变更 ID),设置 ID 后即可直接加入。加入小队后,与同一小队内队员之间的交流不受范围语音和 3D 音效的限制。
// 参数 teamID 传入字符串表示加入对应 teamID 的小队。
rangeAudio.setTeamID("teamID");
// 参数 teamID 不传或者传 undefined 表示退出小队。
rangeAudio.setTeamID();
调用 setRangeAudioMode 接口设置范围语音模式,mode
参数取值为 0
时表示可以听到所有人的声音,取值为 1
时表示只能听到同一小队内其他成员的声音。
语音模式 | 参数取值 | 功能描述 |
---|---|---|
全世界 |
0 |
设置该模式后,此用户能与小队成员互相通话,且能与范围内其他全世界模式的人互相通话。 |
仅小队 |
1 |
设置该模式后,此用户仅能与小队成员互相通话。 |
// 参数 mode 可传 0 或 1。
// 0 为世界模式,可与登录房间内的所有人交流。
// 1 为仅小队模式,只与小队内的队员交流。
rangeAudio.setRangeAudioMode(1);
不同范围语音模式下,发声者声音的可接收情况有所不同。
是否在同一小队 | 是否在最大范围内 | 范围语音模式 | A 能否听到 B 的声音 | B 能否听到 A 的声音 |
---|---|---|---|---|
同一小队 |
是 |
全世界(World) |
是 |
是 |
仅小队(Team) |
是 |
是 |
||
否 |
全世界(World) |
是 |
是 |
|
仅小队(Team) |
是 |
是 |
||
不同小队 |
是 |
全世界(World) |
是 |
是 |
仅小队(Team) |
否 |
否 |
||
否 |
全世界(World) |
否 |
否 |
|
仅小队(Team) |
否 |
否 |
是否在同一小队 | 是否在最大范围内 | 范围语音模式 | A 能否听到 B 的声音 | B 能否听到 A 的声音 |
---|---|---|---|---|
同一小队 |
是 |
全世界(World) |
是 |
是 |
仅小队(Team) |
是 |
是 |
||
否 |
全世界(World) |
是 |
是 |
|
仅小队(Team) |
是 |
是 |
||
不同小队 |
是 |
全世界(World) |
否 |
否 |
仅小队(Team) |
否 |
否 |
||
否 |
全世界(World) |
否 |
否 |
|
仅小队(Team) |
否 |
否 |
通过自定义语音模式,您可以自由控制音频的收发逻辑,以完成各种音频互动,示例如下: 假设 A、B、C 为同一小队成员,且 C 在 A 的接收范围内,可通过表格中的配置完成预期的音频体验。
用户 | 发声预期 | 收听预期 | 发声模式配置 | 收听模式配置 | 备注 |
---|---|---|---|---|---|
A |
向小队成员和范围内其他用户发送音频 |
收听小队成员和范围内其他用户的音频 |
所有人 |
所有人 |
A 能同时与 B、C 交流 |
B |
仅向小队成员发送音频 |
仅收听小队成员的音频 |
小队 |
小队 |
B 仅能与 A 交流 |
C |
仅向范围内的用户发送音频 |
仅收听范围内用户的音频 |
世界 |
世界 |
C 仅能与 A 交流 |
语音模式 | 参数取值 | 功能描述 | |
---|---|---|---|
发声模式 |
所有人模式 |
0 |
发声到所有人模式,房间内的所有人都能听到发声者的声音。 |
世界模式 |
1 |
发声到世界模式,只有处于范围内的人才能听到发声者的声音。 |
|
小队模式 |
2 |
发声到所属小队模式,只有小队内的成员才能听到发声者的声音(不受范围限制)。 |
|
收听模式 |
所有人模式 |
0 |
收听所有人模式,可以收听到房间内所有人的声音。 |
世界模式 |
1 |
只收听世界的人模式,只收听处于范围内的人员的声音。 |
|
小队模式 |
2 |
只收听所属小队模式,只收听所属小队内的成员的声音(不受范围限制)。 |
zg.setRangeAudioCustomMode(0, 0);
调用 logoutRoom 接口退出房间,退出后将自动关闭麦克风和扬声器(即无法发送自己的音频,也无法收听别人的声音),并清空发声者信息列表。
zg.logoutRoom(roomID)
范围语音最多支持同时拉 20 路流。
为保证语音清晰,附近超过 20 人发声时,只能听到离自己最近的 20 个发声者的声音。如果超过 20 人且距离一样,则按照调用 updateAudioSource 接口时,每个 userID
首次传入的先后顺序而定。
范围语音的“范围”指的是收听范围。
小队中的语音是普通连麦的效果,暂无 3D 音效。
范围语音当前使用主路发送音频,如果客户已经使用主路,则会存在冲突。
浏览器 | 兼容性 |
---|---|
Chrome |
14 及以上 |
Edge |
79 及以上 |
Firefox |
53 及以上 |
Opera |
15 及以上 |
IE |
不支持 |
Safari |
14.1 及以上 |
WebView Android |
55 及以上 |
Firefox for Android |
53 及以上 |
Opera Android |
42 及以上 |
Safari on iOS |
14.5 及以上 |
Samsung Internet |
6.0 及以上 |
联系我们
文档反馈