场景介绍
艾媒咨询数据显示,2021年中国在线 K 歌用户规模约为5.1亿人,渗透率约为49.7%。在线 K 歌具有更强的沉浸感体验,多元的玩法也迎合了不同用户群体的个性化需求,目前已经成为了在线泛娱乐领域的主要项目之一。在网络技术革新的基础上,在线 K 歌 App 不断推出多元化的歌唱模式和玩法,不断丰富的功能提升了在线 K 歌 App 的实用性和可玩性。本文将在后续章节详细介绍基于腾讯实时音视频 TRTC 的在线 K 歌场景解决方案。


实现方案
功能模块 | 关键动作及功能点 |
房间管理 | 房间列表、创建房间、加入房间、退出房间、销毁房间 |
麦位管理 | 上/下麦、麦位控制、换麦、锁麦位、邀请上麦、麦位禁言 |
点歌管理 | 歌单展示、搜索歌曲、点歌、排麦、已点列表 |
K 歌管理 | 唱歌玩法、开始/停止/切歌、伴奏和人声音量调节、混响/声效、原声和伴奏切换、歌词同步 |
评分管理 | 歌唱评分、音准线展示 |
在线 K 歌场景整体的业务流程如下图所示。房主创建 K 歌房,用户可以选择感兴趣的歌房加入。进入房间后用户可以上麦参与互动,上麦后也可以选择自己喜欢的歌曲点歌并等待排麦,等排到的时候就可以跟着伴奏演唱。当然,用户也可以选择直接上麦参与合唱,这是两种不同的 K 歌玩法。演唱过程中会有针对单句演唱的音准评分,演唱结束后也会有针对整曲演唱的歌唱评分。


房间管理
房间管理模块主要负责对房间列表的维护,主要包含的功能:创建房间、加入房间、退出房间、销毁房间。而且 K 歌房间有区别于普通房间,需要有单独的 K 歌房间标识符,以启动相关的组件管理:点歌管理、K 歌管理、评分管理 等功能。
创建房间:用户登录业务系统后,可以创建房间,创建房间后房间列表要做新增操作。
加入房间:用户可以选择加入现有房间,加入房间后当前房间人员列表要做新增操作。
退出房间:用户可以选择退出当前房间,退出房间后当前房间人员列表要做删除操作。
销毁房间:所有用户退出房间后,需要销毁房间,销毁房间后房间列表要做删除操作。


说明:
麦位管理
K 歌房内的麦位一般都是有序且有限的。麦位管理主要负责根据业务场景定义房间内的麦位数量,以及当前房间所有麦位的状态管理。麦位管理主要包含的功能:上/下麦、换麦、锁麦位、邀请上麦、麦位禁言等。
用户进入房间后,只有空闲状态的麦位才可以申请上麦。
房主同意用户上麦后,对应麦位状态需要变更为非空闲状态。
用户停止推流下麦后,对应麦位状态需要恢复为空闲状态。
房主有权锁定麦位、邀请上麦、强制下麦、麦上禁言等。
说明:
点歌管理
基本介绍
点歌管理属于在线 K 歌场景比较重要的一环,主要包含的功能:歌单展示、搜索歌曲、点歌和排麦、已点列表。而且每个 K 歌房间都要有需要维护一个已点歌曲列表和自动排麦功能,都是需要业务后台来实现,而歌单展示、搜索歌曲都是需要结合音乐曲库类产品实现的。
实现流程


在整个点歌管理中,主要涉及业务端 App、业务后台、曲库后台,其中各自的职能分别为:
业务端 App:
调用点歌接口上报歌曲信息。
调用切歌接口通知业务后台。
调用演唱确认接口通知业务后台。
业务后台:
维护已点歌单列表。
下发通知告诉业务端 App 切歌。
音乐曲库:
提供可供 TRTC 播放的正版音乐资源。
提供与音乐资源匹配的歌词文件和音高文件等。
K 歌管理
K 歌系统主要包含功能:唱歌玩法、开始/停止/切歌、伴奏和人声音量调节、混响/声效、原声和伴奏切换、歌词同步。下面我们将通过排麦独唱和实时合唱两种典型的 K 歌玩法来详细介绍 K 歌管理模块的实现流程。
排麦独唱
排麦独唱:主要是多人互动的 KTV 场景下,主播/观众上麦后,才可以进行点歌,点歌成功后,会统一在点歌台展示,轮到某人进行点的歌,则在对应的人进行播放歌曲伴奏,开始演唱并进行评分。
方案架构
在整体方案中,主要使用音乐曲库来提供歌曲和歌词等资源,使用 TRTC 来实现演唱者人声的推流、歌曲伴奏的播放及推流。整体的方案架构如下:

具体实现
在排麦独唱的场景,不同角色具有不同的实现流程,存在演唱者、观众两种角色,其角色描述及其区别详见下表:
角色 | 描述 | 区别 |
演唱者 | KTV 房间的演唱者,是房间的主播/观众点歌以后演变而来的,但都需要在麦上才能点歌,下麦自动切走所点歌歌曲。 | 角色必须为主播 上行音视频(无视频上行黑帧) 播放 BGM 发送 SEI 信息(发送歌词信息) 点歌 |
观众 | KTV 房间的观众,播放演唱者/其他人的媒体流。 | 角色为观众,亦可上麦成为主播 下行音视频流 接收 SEI 信息(接收歌词信息) |
实现流程
演唱者


1. 主播/观众,创建/加入 TRTC 的房间,上麦后点歌成为演唱者。
2. 轮到歌曲的演唱者后,需要歌曲的演唱者进行歌曲/歌词的下载,然后通过播放 BGM 接口播放歌曲。
3. 演唱者没有带视频上行的话,需要开启视频上行。
4. 通过 SEI 信息同步所有人的歌词进度。
5. 演唱者下麦,会清除演唱者所点的所有歌曲,变成原角色。
6. 主播/观众,解散/退出 TRTC 房间。
注意:
麦上的主播/观众可以给自己点歌,也可以给别人点歌,但是必须是对应的演唱者去播放 BGM,否则会因为延迟导致演唱者和歌曲声音不同步的问题(延迟约300ms以上)。
观众


1. 主播/连麦主播/观众,创建/加入 TRTC 房间。
2. 监听房间歌曲变化,并加载歌词。
3. 拉取演唱者的流。
4. 解析演唱者发送的 SEI 信息,并同步歌词。
实时合唱
实时合唱是指各端在连麦的基础上,同时播放歌曲伴奏,然后上麦进行合唱。双人模式下主唱和副唱可以互相听到对方声音;多人模式下合唱者之间都能听到彼此声音,几乎感受不到延迟,达到了真正意义上的实时合唱。
方案架构
在媒体流方面,合唱者互相进行推拉流,同时会由一名主唱者推出伴奏音乐,其他合唱者在本地播放伴奏,经过 NTP 进行时间同步。另外,歌曲伴奏和所有合唱者的声音都通过混流机器人进行混流处理形成一条流,并回推到 TRTC 房间,观众只需拉一条流即可听到各端同步的声音,实现多人合唱的效果。实时合唱方案架构如下图所示:

该方案的优点在于:
降低了端到端的时延。
提供了用户中途加入合唱的解决方案。
精准同步不同端之间的伴奏、歌词、人声。
改善各端设备性能和本地时间不精准的情况,降低网络环境造成的时延影响。
注意:
根据业务需要,可以选择纯音频场景或音视频场景的实时合唱方案;若为纯音频场景则需要补黑帧以发送 SEI 消息用于歌词同步。
主唱需要使用子实例同时上行伴奏音乐及人声;其他合唱者仅互相拉取人声流,同时本地播放伴奏音乐;观众只需拉取一路混流。
具体实现
在线 K 歌房中,不同的用户角色具有不同的功能权限及实现流程,划分为三种角色:主唱、合唱和观众,如下表所示:
角色 | 描述 | 区别 |
主唱 | 主唱负责点歌和发送合唱信令,以及 SEI 的发送。 | 角色为 Anchor 上行伴奏和人声 点歌及发起合唱 混流回推房间 发送 SEI 消息 |
合唱 | 合唱者可以接收并处理合唱信令,麦上参与合唱。 | 角色为 Anchor 上行人声 本地播放伴奏 接收合唱 |
观众 | 进入歌房后,在麦下拉流的观众,也可上麦合唱。 | 角色为 Audience 下行混流 接收 SEI 消息 申请上麦成为 Anchor |
实现流程
主唱


1. 主唱需要点播歌曲,发送合唱信令。
2. 主唱创建子实例推送人声和伴奏,并拉取其他合唱者的人声。
3. 在推流后,主唱负责发起混流转推任务。
4. 开唱后,播放伴奏音乐,通过播放进度回调同步歌词。
5. 需要通过 SEI 发送歌曲进度,以便观众端同步歌词。
6. 所有演唱者需要根据 NTP 校准本地歌曲播放进度。
合唱


1. 合唱者推送一路人声流,拉麦上合唱用户的人声流。
2. 合唱者需要监听并接收合唱信令,预加载伴奏音乐资源。
3. 开唱后,本地播放伴奏音乐,合唱者通过播放进度回调同步歌词。
4. 所有演唱者需要根据 NTP 校准本地歌曲播放进度。
观众


1. 进入 TRTC 房间接收合唱混流。
2. 解析混流中 SEI 的歌曲进度信息,用于同步歌词。
3. 上麦后停止拉混流,转为拉麦上人声流,同时开启合唱模式。
评分管理
基本介绍
评分功能也是 K 歌场景的主流玩法之一,主要是能评定用户实际在唱歌的过程的音准与音色的结果,可以作为多人演唱后分数的对比。
实现流程
在整个评分管理流程中,根据用户角色的不同,演唱者和观众有不同的实现。评分通常是在演唱者本地进行,并同步到房间内其他人。
演唱者


主播/观众,创建/加入 TRTC 的房间,上麦后点歌成为演唱者。
轮到歌曲的演唱者后,需要歌曲的演唱者进行歌曲/歌词的下载,然后通过播放 BGM 接口播放歌曲。
将 TRTC 采集的人声音和 BGM 播放进度实时传输给评分模块。
评分模块实时出数据后,通过 SEI 的方式同步到房间内所有人。
观众
观众侧流程跟排麦独唱的观众角色动作流程基本一致,可以参考观众实现流程。
关键业务逻辑
伴奏同步方案
实时方案中需要在开唱后实时同步伴奏进度,避免因伴奏误差而增加端到端延迟。同步伴奏需要基于 NTP 时间,不同设备的本地时钟并不一致,存在一定误差,因此需要引入腾讯云自研 NTP 服务。同时,中途加入合唱的用户也需要同步伴奏进度,只有同步进度后,才能参与合唱。
伴奏同步的做法为:主唱用户约定在未来某个时间点(如延迟 3 秒后)开始播放伴奏,其他用户参与合唱。各端的时间都以 NTP 时间为准,NTP 时间会在 TRTC SDK 初始化后开始同步。


具体流程如下:
1. 各端进行 NTP 校时,向 TRTC 云端更新并获取最新的 NTP 时间 T。
2. 主唱端发送合唱信令(自定义消息),约定合唱开始时间 T2。
3. 本地根据 T2 预加载伴奏音乐,定时播放。
4. 其他合唱用户接收到合唱信令后执行步骤3。
5. 过程中对本地伴奏播放进度进行校验,当 TE 与 TC 差值超过50ms即 seek 校准。
说明:
这里的50ms误差是个典型值,可以根据业务容忍度适当调整,建议在50ms上下浮动。
歌词同步方案
歌词同步方案中,三种不同角色的动作如下:
主唱 | 合唱 | 观众 |
NTP 校时 开启补黑帧 发送 SEI 消息 本地歌词同步 更新歌词控件 | NTP 校时 本地歌词同步 更新歌词控件 | NTP 校时 接收 SEI 消息 更新歌词控件 |
其中,主唱及合唱根据同步后的伴奏音乐播放进度,在本地更新歌词进度;观众端则需要接收由主唱端发送的,包含最新歌词进度的 SEI 消息来更新本地的歌词进度。歌词同步方案整体流程如下图所示。


音频调优策略最佳实践
在整个 K 歌场景中,音频质量主要受采样率、声道数、码率、3A 等参数的影响。根据不同的房间场景,我们推荐不同的音频参数和音量配比方案,以及经常会用到的人声和伴奏同步对齐方案。
1. 场景最佳参数配置
房间场景 | 进房模式 | 音频质量 | 音量类型 | 隐藏接口 |
排麦独唱 | 视频或转推 CDN 需求:LIVE 纯音频和纯 RTC 需求: VOICE_CHATROOM | MUSIC | TRTCSystemVolumeTypeMedia | enableBlackStream |
实时合唱 | 视频或转推 CDN 需求:LIVE 纯音频和纯 RTC 需求: VOICE_CHATROOM | MUSIC | TRTCSystemVolumeTypeMedia | enableBlackStream enableChorus setLowLatencyModeEnabled |
语聊听歌 | VOICE_CHATROOM | DEFAULT | TRTCSystemVolumeTypeAuto | 无 |
2. 场景最佳音量配比
TRTC SDK 对于人声采集和音乐播放都有初始默认值,如果在使用默认值的情况下,存在直播间内音乐声音压制人声,导致人声被音乐声音掩盖的现象,可以根据下表推荐值适当调节人声和音乐音量配比。
房间场景 | 人声/音乐/音效推荐配置 |
排麦独唱 | 人声采集音量:60 音乐播放音量:50 开启混响特效:是 |
| 实时合唱 |
语聊听歌 | 人声采集音量:100 音乐播放音量:30 开启混响特效:否 |
3. 人声伴奏同步对齐
由于本地人声采集的 JitterBuffer、歌曲播放混音的 JitterBuffer,以及人耳接收伴奏音乐到开始演唱过程中存在一定的 GAP,所以如果演唱者完全跟着歌词和伴奏演唱,远端观众可能会感知到人声、伴奏和歌词之间存在一定延迟和不对齐的情况。这种情况可以通过下述两种方式改善。
开启合唱模式
JSONObject jsonObject = new JSONObject();try {jsonObject.put("api", "enableChorus");JSONObject params = new JSONObject();params.put("enable", true);params.put("audioSource", 0);jsonObject.put("params", params);mTRTCCloud.callExperimentalAPI(String.format(Locale.ENGLISH, jsonObject.toString()));} catch (JSONException e) {e.printStackTrace();}
NSDictionary *jsonDic = @{@"api": @"enableChorus",@"params": @{@"enable": @(YES),@"audioSource": @(0)}};NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDic options:NSJSONWritingPrettyPrinted error:nil];NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];[trtcCloud callExperimentalAPI:jsonString];
注意:
audioSource: 0(人声),audioSource: 1(伴奏);若采用单实例推流则 audioSource 统一设置为 0 即可。
开启低时延模式
JSONObject jsonObject = new JSONObject();try {jsonObject.put("api", "setLowLatencyModeEnabled");JSONObject params = new JSONObject();params.put("enable", true);jsonObject.put("params", params);mTRTCCloud.callExperimentalAPI(String.format(Locale.ENGLISH, jsonObject.toString()));} catch (JSONException e) {e.printStackTrace();}
NSDictionary *jsonDic = @{@"api": @"setLowLatencyModeEnabled",@"params": @{@"enable": @(1)}};NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDic options:NSJSONWritingPrettyPrinted error:nil];NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];[trtcCloud callExperimentalAPI:jsonString];
场景玩法
排麦独唱
观众上麦后可以进行点歌排麦等待,歌曲开始播放后即可进行个人演唱。此种玩法相对简单,采用 TRTC 单实例混音推流即可。
实时合唱
观众上麦后和主唱同时合唱一首歌曲。此种玩法相对复杂,主唱端需要采用 TRTC 双实例推流,同时各端还需注意伴奏同步和歌词同步。
全民抢唱
用户可根据自己的爱好选择不同分类的歌曲房间,房间内随机播放音乐片段,房间内用户可随时抢麦,进行歌曲片段演唱。
分段接唱
同一首歌分段并分配给不同的麦上观众,主唱领唱一段后,其他麦上观众按所分配的音乐片段分别接唱。
跨房斗唱
不同房间主播之间进行 PK 演唱,各自房间观众为主播助力。此种玩法除了 K 歌场景外,还涉及到 TRTC 跨房 PK,需要注意不同房间音视频流的订阅逻辑。
方案配套产品
系统层级 | 产品名称 | 场景用途 |
接入层 | 提供低延时、高品质的多人音频实时互动直播解决方案,是在线 K 歌场景的基础底座能力。 | |
接入层 | 提供基于群组功能的房间管理、麦位管理能力,实现直播间全员消息、公屏消息等富媒体消息收发,以及自定义信令等通信需要。 |