Karaoke 组件是 TUILiveKit 的标准化 K 歌功能模块,可快速集成至视频直播及语音房场景。组件支持本地与在线音乐接入,内置歌词滚动、音准检测、实时打分及多种音效设置。为用户提供低延迟、高保真的实时 K 歌体验。
功能概览
多端人声和音乐同步对齐: 基于
NTP 时间戳对齐技术,确保跨设备间人声与伴奏的精准同步,有效解决网络抖动带来的音画不同步问题。实时打分与音准曲线:曲库歌曲可实时展示标准音高与用户个人音准曲线,唱歌得分同步广播给全房观众;本地导入歌曲暂不支持打分和音准显示。
毫秒级歌词滚动:支持 VTT、LRC 格式歌词,随音乐进度精准滚动。
多样化音乐源支持: 全面支持在线曲库点播与本地音乐(MP3/M4A)上传和播放。

快速接入
步骤1:开通服务
步骤2:代码集成
步骤3:集成 KTV 功能
布局选择与接入
我们提供了两种不同交互的布局模式,您可以根据直播间的业务侧重点(例如:专业 K 歌房、社交娱乐房)选择最合适的集成方案。
该模式主要通过
KaraokeControlView 实现,视图通常固定置于房间顶部。它提供了完整的歌词滚动、音高曲线评分以及播放控制功能。您可以根据业务需求,通过 XML 声明或代码动态构建的方式将该组件集成到应用中。
方式1:通过 XML 布局文件集成(推荐)
适用于 UI 布局相对固定的场景。通过在布局 XML 中直接定义,可以精确控制其在房间顶部的层次关系。
<io.trtc.tuikit.atomicx.karaoke.view.KaraokeControlViewandroid:id="@+id/karaoke_control_view"android:layout_width="match_parent"android:layout_height="170dp"android:layout_marginTop="10dp"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent" />
方式2:通过代码动态构建
对于使用 Kotlin 语言开发的工程,集成逻辑如下。
import android.view.ViewGroupimport io.trtc.tuikit.atomicx.karaoke.view.KaraokeControlViewfun initKaraokeView(container: ViewGroup, roomId: String, isOwner: Boolean) {// 1. 实例化组件val karaokeView = KaraokeControlView(context)// 3. 设置布局参数并添加到容器// 标准模式通常占据屏幕顶部固定高度val layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,500 // 对应高度约 170dp)container.addView(karaokeView, layoutParams)}
该模式主要通过
KaraokeFloatingView 实现,支持手动拖拽。提供了歌词滚动、音准打分曲线及播放控制功能。您可以根据业务需求,通过 XML 声明或代码动态构建的方式将该组件集成到应用中。
方式1:通过 XML 布局文件集成
这是最推荐的集成方式,适用于布局相对固定的场景。通过在布局 XML 中直接定义,可以方便地配合
ConstraintLayout 等容器进行 UI 适配。<io.trtc.tuikit.atomicx.karaoke.view.KaraokeFloatingViewandroid:id="@+id/karaoke_floating_view"android:layout_width="wrap_content"android:layout_height="wrap_content"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintTop_toTopOf="parent" />
方式2:通过代码动态构建
对于使用 Kotlin 语言开发的工程,集成逻辑如下。我们建议将
KaraokeFloatingView 添加到页面的根布局中,以确保其悬浮层级。import android.view.ViewGroupimport android.widget.FrameLayoutimport io.trtc.tuikit.atomicx.karaoke.view.KaraokeFloatingViewfun setupKaraokeFloatingView(container: ViewGroup, roomId: String, isOwner: Boolean) {// 1. 实例化组件val floatingView = KaraokeFloatingView(context)// 2. 将组件挂载到父容器并设置悬浮模式// FloatingMode.RIGHT_HALF_MOVE 表示允许在屏幕右侧半屏区域内上下拖动floatingView.attachAsFloating(container, KaraokeFloatingView.FloatingMode.RIGHT_HALF_MOVE)}
添加音乐
Karaoke 组件提供了灵活的数据源适配机制,支持集成本地音乐资源或商业版权曲库。您可以通过继承
MusicSourceService 类来实现不同场景下的音乐加载逻辑。
场景一:添加本地音乐
若您希望播放应用内置或本地沙盒中的音乐文件,请在您的工程中新建
KaraokeLocalSource.kt 文件。该类继承自 MusicSourceService 基类。在本地音乐模式下,KaraokeLocalSource 核心承担以下两项职责:1. 管理音乐列表:负责检索本地资源(例如 Assets 或沙盒路径),并将其映射为组件可识别的
MusicInfo 标准列表。2. 实现播放鉴权:KTV 场景下需要合唱机器人进入房间协同播放音乐,因此该类需负责获取
UserSig 签名,以确保播放流程的鉴权通过。说明:
实时评分与音准检测功能需配合版权曲库的标准音轨数据实现。因此,本地音乐目前仅支持歌词展示与同步播放,不支持打分和计算用户的实时音准。
package io.trtc.tuikit.atomicx.karaoke.storeimport android.content.Contextimport androidx.core.content.ContextCompatimport com.tencent.qcloud.tuikit.debug.GenerateTestUserSigimport io.trtc.tuikit.atomicx.karaoke.store.utils.MusicInfoimport java.io.File/*** 本地音乐数据源实现类* 负责加载本地存储的演示歌曲,并处理基础鉴权逻辑*/class KaraokeLocalSource(private val context: Context) : MusicSourceService() {/*** 步骤 1:获取本地歌曲列表* 将本地文件路径封装为 MusicInfo 对象并返回*/override fun getSongList(callback: GetSongListCallBack) {// 1. 获取本地存储的绝对路径。// 确保在调用此方法前,相关 mp3/vtt 文件已通过 copyAssetToFile 拷贝至该路径。val localPath = ContextCompat.getExternalFilesDirs(context, null)[0].absolutePath + File.separator// 2. 配置 MusicInfo 核心字段。// musicId: 歌曲唯一标识;musicName: 歌曲名称;artist: 歌手名列表。val demoMusic = MusicInfo().apply {musicId = " local_demo_01" // LiveKit中,本地音乐的musicId前缀是local_demo.musicName = "后来"artist = "刘若英"lyricUrl = "lyricUrl.vtt" // 对应歌词文件的 URLoriginalUrl = "originalUrl.mp3" // 对应原唱文件的 URLaccompanyUrl = "accompanyUrl.mp3" // 对应伴奏文件的 URL}// 4. 构建列表并通过回调返回。val musicList = arrayListOf(demoMusic)callback.onSuccess(musicList)}/*** 步骤 2:生成用户签名* 为当前用户生成合法的业务签名,用于初始化组件和鉴权*/override fun generateUserSig(userId: String, callback: ActionCallback) {// 调用测试环境工具生成 UserSigval userSig = GenerateTestUserSig.genTestUserSig(userId)if (userSig.isNotEmpty()) {callback.onSuccess(userSig)} else {callback.onError(-1, "Generate UserSig failed")}}}
场景二:添加曲库音乐
如果您已购买版权曲库服务(例如音速达曲库),可以通过继承
MusicSourceService 实现云端资源的集成。请在工程中新建 KaraokeOnlineSource.kt 文件。在曲库模式下,该类核心承担以下三项职责:1. 管理云端列表:对接业务后台或腾讯云接口,获取在线歌曲元数据并映射为组件可识别的
MusicInfo 标准列表。2. 实现播放鉴权:KTV 场景下需要合唱机器人进入房间协同播放。该职责负责获取合法的
UserSig 签名,确保机器人具备进房播放权限。3. 获取播放凭证:针对受版权保护的数字音乐,需根据
musicId 向服务器换取 playToken 及 License 授权,这是在线流媒体正常解密播放的核心凭证。package io.trtc.tuikit.atomicx.karaoke.storeimport io.trtc.tuikit.atomicx.karaoke.store.utils.MusicInfo/*** 在线曲库数据源实现类* 职责:1. 检索云端歌曲;2. 提供机器人进房鉴权;3. 获取版权播放凭证*/class KaraokeOnlineSource : MusicSourceService() {/*** 职责一:获取云端歌曲列表* 此处通常调用您的业务后端接口,将返回的 JSON 解析为 MusicInfo 列表*/override fun getSongList(callback: GetSongListCallBack) {// 示例:此处模拟网络请求成功后构建的在线歌曲对象val onlineMusic = MusicInfo().apply {musicId = "online_id_1001" // 云端歌曲唯一 IDmusicName = "在线歌曲示例"artist = mutableListOf("歌手名")coverUrl = "https://example.com/cover.jpg" // 在线封面 URL}callback.onSuccess(arrayListOf(onlineMusic))}/*** 职责二:鉴权播放* 建议由您的业务后端生成 UserSig,确保合唱机器人安全入会*/override fun generateUserSig(userId: String, callback: ActionCallback) {// 示例:此处应发起网络请求从您的服务器获取 UserSigval userSig = "YOUR_SERVER_GENERATED_USERSIG"callback.onSuccess(userSig)}/*** 职责三:获取播放凭证 (在线模式核心)* 根据 musicId 获取播放 Token、License 等版权信息*/override fun queryPlayToken(musicId: String, userId: String, callback: QueryPlayTokenCallBack) {// 示例:此处应向服务器请求该音乐的播放许可val playToken = "YOUR_PLAY_TOKEN"val licenseKey = "YOUR_LICENSE_KEY"val licenseUrl = "YOUR_LICENSE_URL"// 验证成功后返回凭证callback.onSuccess(musicId, playToken, licenseKey, licenseUrl)}}
核心 UI 组件
歌词组件(LyricView)
LyricView 是 Karaoke 组件中负责文本表现的核心视图。它能够根据音乐播放进度,实现毫秒级的歌词平滑滚动与逐字颜色填充,为演唱者提供精准的节奏指引。
组件能力:
1. 高精度对齐:支持 VTT、LRC 等标准歌词格式,确保歌词的逐字染色进度与伴奏精准同步。
2. 自适应排版:内置长句拆行与缩减逻辑,当歌词过长时会自动进行排版优化,防止 UI 溢出。
3. 双行渲染模式:默认采用“当前行+下一行”的双行显示策略,帮助演唱者提前预判歌词内容。
自定义歌词 UI 样式
为了适配不同风格的直播间布局,
LyricView 提供了丰富的自定义接口。您无需修改组件源码,通过简单的 API 调用即可调整歌词的颜色、大小及对齐方式。1. 设置歌词颜色。您可以分别设置第一行(当前行)的两种状态颜色,以及第二行(等待行)的颜色。
// 设置歌词颜色lyricView.setLyricColors(currentLineNormalColor = Color.WHITE, // 第一行:尚未唱到的底色currentLineHighlightedColor = Color.BLUE, // 第一行:已经唱到的高亮色nextLineColor = Color.GRAY // 第二行:等待演唱行的颜色)
2. 调整字体与间距您可以为“当前正在演唱行”和“后续等待行”分别设置不同的字体大小,以增强视觉层级感。
// 设置歌词字体:参数1为高亮行大小,参数2为次行大小 (单位:sp)lyricView.setLyricTextSize(18f, 12f)
3. 变换对齐方式根据 UI 设计需求,您可以灵活切换歌词的水平对齐模式。
// 支持居中对齐 (LyricAlign.CENTER) 或 居右对齐 (LyricAlign.RIGHT)lyricView.setLyricAlign(LyricAlign.CENTER)
4. 实时驱动进度LyricView 的状态由进度数据驱动。您只需将音乐播放器返回的毫秒级进度注入组件,即可实现丝滑的滚动效果。
// 在进度监听器中调用,驱动歌词染色与滚动lyricView.setPlayProgress(currentProgressMs)
音准组件 (PitchView)
PitchView 是 Karaoke 组件中实现专业级打分功能的核心视图。它通过波形化的视觉反馈,将演唱者的实时音高(Pitch)与歌曲标准音轨进行对比,为用户提供极具趣味性与挑战性的“音准校对”体验。
组件能力:
1. 实时音准反馈:毫秒级呈现演唱者的音高动态,通过移动的“音准粒子”实时反馈音准偏移情况。
2. 标准基准线对比:自动加载歌曲的官方标准音高数据,形成可视化的音高参考矩形块,方便演唱者找准音调。
3. 视觉命中反馈:当演唱音高进入标准范围内时,组件会自动触发高亮染色与“蝴蝶点缀”等动效,强化演唱成就感。
4. 多端状态同步:支持将房主的演唱得分与音高曲线实时广播给全房观众,实现跨端的视觉同步。
自定义音准 UI 样式
PitchView 提供了深度的自定义配置接口,允许开发者根据直播间的视觉调性,调整曲线的外观、命中判定规则以及动画效果。1. 开启/关闭打分模式:您可以动态控制打分功能的开关。关闭后,组件将不再显示评分标签。
// 开启打分显示逻辑pitchView.setScoringEnabled(true)
2. 设置标准音轨数据:在歌曲开始播放前,需要将标准音高序列注入组件,用于生成参考背景。
pitchList 数据来自合唱回调 onChorusMusicLoadSucceed 中的 pitchList 字段。// 注入来自 TXChorusMusicPlayer 的标准音高列表pitchView.setPitchList(pitchList)
3. 实时驱动播放进度:PitchView 需要实时进度来驱动音轨的横向滚动。
// 在进度监听器中调用,驱动音轨随音乐进度平滑滚动pitchView.setPlayProgress(currentProgressMs)
4. 注入演唱者当前音高:将人声检测到的实时音高注入组件,用于绘制当前演唱的粒子位置。
// 注入演唱者当前的实时音高值(通常为 0-100)pitchView.setUserPitch(userPitch)
5. 实时更新分数:显示当打分逻辑计算出最新得分时,可以调用此接口更新界面顶部的分数标签。
// 设置当前实时得分,视图会自动更新分数的冒泡显示pitchView.setScore(85)
6. 配置核心颜色:通过代码接口,您可以自定义标准音轨、命中高亮以及背景分割线的颜色。
// 注:PitchView 内部默认集成了以下视觉属性的配置逻辑// 您可以通过 XML 或自定义属性扩展来调整:// 标准音轨色:lineColor (默认灰色)// 命中填充色:highlightColor (默认红色)// 引导粒子色:dotColor (默认白色)
API 参考
合唱相关
TXChorusMusicPlayer 是合唱功能的核心控制单元,封装在 TRTC SDK 中。该组件基于 NTP 时间戳对齐技术,确保跨设备间人声与伴奏的精准同步,并提供了完整的音乐播放控制能力 。注意:
TXChorusMusicPlayer 主要负责音频流的加载、同步与播放控制 。音准检测与实时评分功能是由版权曲库实现的。
核心控制方法
方法名 | 说明 | 调用权限 |
start() | 开始播放合唱音乐。 | 仅限主唱 |
stop() | 停止合唱播放。 | 仅限主唱 |
pause() | 暂停合唱播放。 | 仅限主唱 |
resume() | 恢复合唱播放。 | 仅限主唱 |
seek(long progressMs) | 跳转到指定播放进度。 | 仅限主唱 |
setChorusRole(ChorusRole role, TRTCParams params) | 设置合唱角色(例如主唱、副唱、观众等)。 | 所有角色 |
switchMusicTrack(MusicTrack track) | 切换原唱与伴奏。主唱设置会同步影响观众。 | 主唱/副唱 |
音乐加载与配置
方法名 | 说明 |
loadMusic(ChorusMusicParams params) | 加载版权曲库(例如音速达)音乐。 |
loadExternalMusic(ExternalParams params) | 加载本地或自定义 URL 音乐文件。 |
setPublishVolume(int volume) | 设置主唱推流到远端的 BGM 音量 (0-100)。 |
setPlayoutVolume(int volume) | 设置本地播放的 BGM 音量 (0-100)。 |
事件回调 (ITXChorusPlayerListener)
回调方法 | 触发时机 |
onChorusStarted() | 合唱正式开始播放时触发。 |
onMusicProgressUpdated(long progress, long duration) | 毫秒级播放进度更新。 |
onVoicePitchUpdated(int pitch, boolean hasVoice, long progressMs) | 演唱音高实时更新(-1 表示间奏/无人声)。 |
onVoiceScoreUpdated(int current, int average) | 每一句歌词唱完后的实时得分反馈。 |
onChorusRequireLoadMusic(String musicId) | 主唱发起点播后,通知其他角色同步加载歌曲。 |
点歌台相关
TUISongListManager 负责管理直播间的点唱队列,包括添加歌曲、删除歌曲、歌曲置顶及自动切歌逻辑。方法名 | 说明 |
addSong(List<SongInfo> list, callback) | 将歌曲添加至待播列表。 |
removeSong(List<String> ids, callback) | 从队列中移除指定歌曲。 |
setNextSong(String songId, callback) | 置顶某首歌曲,使其成为下一首播放的曲目。 |
playNextSong(callback) | 立即切换至下一首歌曲。 |
getWaitingList(cursor, count, callback) | 分页获取当前待播列表。 |
getPlayedList(cursor, count, callback) | 分页获取已播放的历史列表。 |
常见问题
是否有推荐的曲库供应商?
为什么演唱时没有音高曲线或实时评分?
音准检测与打分功能高度依赖版权曲库(例如音速达)提供的标准音高基准文件。如果您使用的是本地音乐(External Source),由于缺少标准的参考数据,系统将无法触发
onVoicePitchUpdated(音高更新)和 onVoiceScoreUpdated(分数更新)回调。本地音乐加载失败,报错“Music load failed (-5)”如何处理?
请确认传入 loadExternalMusic 的文件路径是否合法且具备读取权限。如果音乐资源存放在工程的 Assets 目录中,必须先将其拷贝至应用的沙盒路径(例如 getExternalFilesDir)下,方可被底层播放引擎成功识别并加载。
如何解决合唱时人声被伴奏掩盖的问题?
您可以使用 setPublishVolume 接口动态调整推流中伴奏的音量(建议范围 30-60),同时通过 TRTC SDK 的 setAudioCaptureVolume 调大人声采集音量 。此外,建议主唱使用 Music 音质模式(TRTCAudioQualityMusic)以获得更好的音频效果 。