线上剧本杀「多房间 + 多角色 + 强流程」的实时音视频架构

线上剧本杀不只是几个人开视频,它有 DM 主持、分场搜证、私聊密谋、变声扮演和严格的流程推进。本文拆解这套「多房间 + 多角色 + 强流程」的实时音视频架构,并给出基于 ZEGO RTC 的示例代码。

线上剧本杀「多房间 + 多角色 + 强流程」的实时音视频架构

线上剧本杀的特殊性

剧本杀(线上推理 / 沉浸演绎)搬到线上,技术复杂度远超普通多人视频。它不是一个房间从头聊到尾,而是一台有剧本流程、角色权限、动态分组、信息隔离的状态机。实现线上剧本杀语音房的真正的难点是:

  • 分场搜证:玩家被分到不同场景房间,只能听到同房间的人。
  • 私聊密谋:两个玩家临时拉个小房间私聊,不被其他人听到。
  • DM 主持:主持人(DM)能广播、能进任意分房、能控制流程推进。
  • 变声扮演:凶手匿名、NPC 配音需要变声。
  • 氛围与流程:背景音乐、音效、剧本翻页、投票放逐都要全员同步。

一句话:剧本杀 = 多人音视频 + 动态多房间 + 信息隔离 + 流程引擎

角色、阶段与谁能听到谁

剧本杀的音频拓扑是动态变化的,随剧本阶段切换:

阶段音频拓扑技术映射
开本 / 自我介绍全员同房,互相可听单一主房间
分场搜证玩家分散到不同场景,组内可听多个分房间,各自独立
私聊密谋2~3 人临时小房动态创建/销毁的私聊房
公开讨论 / 圆桌全员回主房回到主房间
投票放逐 / 复盘全员同房 + 流程信令主房间 + 状态广播

核心抽象:房间就是声音的隔离边界。玩家在哪个房间,就只能听到那个房间的人。流程推进的本质,就是 DM 控制玩家在房间之间的迁移。

整体架构:主房 + 多分房 + 流程引擎

# 音频拓扑(动态多房间)
              ┌──────── 主房间(全员/圆桌) ────────┐
   DM ────────┤  分房A(书房)   分房B(卧室)        │  私聊房(玩家X+玩家Y)
 (可进任意房)  └──── 玩家按剧本阶段在房间间迁移 ────┘
                        │(每个房间一套独立 RTC)
                        ▼
                 ZEGO 实时音视频云

# 流程面(你的服务端 = 剧本流程引擎,权威)
阶段推进 / 房间分配 / 线索发放 / 投票结果 ── IM(ZIM) & 服务端下发 ──> 客户端
        │  谁该进哪个房、谁能说话、现在第几幕,全部由服务端裁决

设计要点:流程和权限必须由服务端权威控制。客户端不能自己决定我要听别人私聊,房间迁移、麦克权限、线索可见性都由剧本流程引擎下发,客户端只执行。这既是体验需要,也是防作弊的底线。

关键技术点

1. 动态多房间与声音隔离

分场搜证、私聊密谋的本质是按需创建房间并迁移成员。玩家进入分房时,退出主房 RTC、加入分房 RTC,声音边界随之切换。一些 SDK 支持多房间登录,可让 DM 同时在线监听多个房间。房间的命名与生命周期要和流程引擎严格对应。

2. DM 的上帝视角

DM 需要:① 向全体广播(旁白、宣布阶段);② 进入任意分房旁听或引导;③ 强制移动玩家、禁言、控制麦位。实现上 DM 是一个有特权的特殊成员,其操作经服务端校验后对相关房间生效。多房间登录能力让 DM 不必频繁切换就能掌控全局。

3. 变声扮演与匿名

凶手投票阶段的匿名发言、NPC 配音、特殊角色音色,都靠实时变声。变声在推流前应用,配合混响营造氛围。匿名场景还要注意:变声 + 不显示发言人身份,双重保护匿名性。

4. BGM、音效与流程同步

剧本杀强依赖氛围,如紧张 BGM、开门声、心跳声。这些音效要全房间同步播放(作为混音上行或由服务端统一触发),而非各播各的。剧本翻页、线索发放、计时器、投票结果,都是经 IM/服务端广播的流程状态,必须可靠有序送达每个人。

基于 ZEGO RTC 实现线上剧本杀的代码示例

线上剧本杀可由 ZEGO 这些能力拼装:

  • 实时音视频 Express SDK:多人/多房间,麦位/主持
  • 大饼 AI 变声:匿名扮演
  • 音频混音 / 音效播放器:BGM
  • 即时通讯 ZIM:流程/线索/私信
  • 数美内容审核:合规
  • 云端录制:复盘回放

下面以 Web 端演示「主房/分房切换 + 变声 + BGM + 流程广播」的核心代码。

步骤 1:进主房间

import { ZegoExpressEngine } from 'zego-express-engine-webrtc';
const zg = new ZegoExpressEngine(APP_ID, SERVER_URL);

// Token 由服务端签发;剧本杀建议每个房间用独立 streamID 规则
const { token } = await fetch(`/api/zego-token?userID=${userID}`).then(r => r.json());

let currentRoom = null;
async function enterRoom(roomID) {
  if (currentRoom) await leaveRoom();          // 先退出当前房,切断旧声音边界
  await zg.loginRoom(roomID, token, { userID, userName }, { userUpdate: true });
  const mic = await zg.createZegoStream({ camera: { video: true, audio: true } });
  await zg.startPublishingStream(`${roomID}_${userID}`, mic);
  currentRoom = roomID;
}
async function leaveRoom() {
  await zg.stopPublishingStream(`${currentRoom}_${userID}`);
  await zg.logoutRoom(currentRoom);
  currentRoom = null;
}

// 同房成员自动互拉(同一声音边界内才听得到)
zg.on('roomStreamUpdate', async (rid, t, list) => {
  if (t === 'ADD') for (const s of list) {
    const r = await zg.startPlayingStream(s.streamID);
    r.playVideo?.(seatViewFor(s.streamID));
  }
  if (t === 'DELETE') list.forEach(s => zg.stopPlayingStream(s.streamID));
});

步骤 2:分场搜证 / 私聊——服务端驱动房间迁移

// 流程引擎(服务端)下发「该进哪个房」,客户端执行迁移
zg.on('IMRecvBroadcastMessage', (rid, msgs) => {
  msgs.forEach(m => {
    const ev = JSON.parse(m.message);
    if (ev.type === 'move_room' && ev.target === userID) {
      enterRoom(ev.roomID);          // 例:被分配到「书房」分房搜证
    }
  });
});

// 发起私聊:服务端创建临时私聊房,把两人都 move 过去
function requestPrivateTalk(targetUserID) {
  fetch('/api/script/private-room', {
    method: 'POST',
    body: JSON.stringify({ from: userID, to: targetUserID }),
  });   // 服务端校验后下发 move_room 给双方
}

步骤 3:变声扮演 + BGM 氛围

// 匿名/NPC 扮演:推流前应用变声(配合不显示发言身份保护匿名)
zg.setVoiceChangerPreset?.('androidRobot');   // 机器人音;或接「大饼 AI 变声」
zg.setReverbPreset?.('concertHall');          // 混响增强戏剧感

// BGM/音效:作为混音/音效播放器混入推流,全房间同步听到
const sfx = zg.createAudioEffectPlayer?.();
sfx.loadResource('sfx_001', 'https://cdn.example.com/tense-bgm.mp3');
sfx.start('sfx_001', { loopCount: 0 });   // DM 触发紧张 BGM

步骤 4:DM 流程推进与投票(ZIM 权威广播)

// DM 推进阶段 / 发放线索 / 公布投票,均由服务端权威下发
// 阶段推进
broadcast({ type: 'phase', phase: 'discussion', act: 2 });
// 发放线索(仅对特定玩家可见)
sendPrivate(targetUserID, { type: 'clue', clueId: 'C12' });
// 投票放逐:客户端投票 → 服务端汇总 → 广播结果
broadcast({ type: 'vote_result', banished: 'player_3' });

function broadcast(data) { zg.sendBroadcastMessage(currentRoom, JSON.stringify(data)); }

核心心智:房间 = 声音隔离边界,流程引擎(服务端)权威控制玩家在房间间的迁移与权限。变声、BGM 服务于沉浸,IM 服务于流程与信息隔离。

踩坑清单

  1. 房间切换要快且干净:迁移时先退旧房再进新房,避免人到了书房还能听到客厅的串音 bug。
  2. 信息隔离是命门:线索、私聊、身份必须服务端权威控制,客户端绝不能拿到不该看/听的内容,否则游戏直接被破解。
  3. 流程消息要可靠有序:阶段推进、投票结果用可靠通道(IM),不能像音频那样允许丢;用序号防乱序。
  4. BGM 全房同步:音效作为混音上行或服务端统一触发,避免各端各放、氛围错位。
  5. 匿名要双保险:变声 + 隐藏发言人标识,二者缺一匿名就形同虚设。
  6. 合规与留档:陌生人组局接入实时音视频审核;开启云端录制便于纠纷复盘。
  7. 掉线重连回到正确房间:玩家断线重连要根据流程引擎当前状态,恢复到他应该在的房间和阶段。

结语

线上剧本杀是社交泛娱乐里流程最复杂、信息隔离要求最高的场景之一。它把实时音视频从让大家听见推进到精确控制谁在什么阶段能听到谁、能看到什么。技术骨架是动态多房间(声音隔离)+ 服务端流程引擎(权威与防作弊)+ 变声 BGM(沉浸)+ 可靠 IM(流程与线索)。借助 ZEGO 的实时音视频多房间能力、麦位控制、AI 变声、音效播放器、ZIM 与内容审核,开发者可以把这套精密的线上桌面搭起来,把心思真正花在剧本生态和演绎体验上。

本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/info/67247.html

(0)

相关推荐