快速实现
KTV API 是声网为降低开发者的集成难度,为 K 歌房场景提供的场景化 API。KTV API 对声网实时互动 SDK 的 API 进行了一系列业务封装,提供出了 K 歌业务常见的业务功能接口,例如,获取版权歌单、下载版权音乐、切换演唱身份等。你只需要调用简单几个场景化 API 即可实现需要通过实时互动 API 才能实现的复杂代码逻辑,从而更轻松实现 K 歌场景。声网在 GitHub 上提供 KTV 场景化 API 的源码文件 KTVApi.kt 和 KTVApiImpl.kt 供你参考。
在线 K 歌房内用户角色说明如下:
角色 | 描述 |
---|---|
房主 | 歌房创建者。可以收、发音频流。 |
独唱 | 在没有伴唱加入、伴唱中途退出后,演唱的人的用户角色为独唱者。 |
主唱 | 如果有伴唱加入合唱,独唱成为主唱,可以收、发音频流。 |
伴唱 | 独唱开始唱歌后,如有人加入合唱,则其成为合唱中的伴唱,可以收、发音频流。 |
听众 | 进入歌房的倾听者,只能接收音频流。 |
K 歌场景下主唱及独唱的业务流程图如下:
伴唱及听众的业务流程图如下:
本文介绍如何集成 KTV API 并实现在线 K 歌。
- 本文仅适用于 K 歌场景化 API v4.3.0。
- 在使用场景化 API 方案前,请联系技术支持获取指定的 SDK 版本。
前提条件
开始前,请确保你的开发环境满足以下条件:
-
Android Studio 4.0.0 或以上版本。
-
Android 4.1 或以上版本的设备。
-
有效的声网开发者账号、声网项目,并获取项目的 App ID、RTC Token,详情请参考开通服务。
- 你可以参考开通服务获取临时 RTC Token 用于测试,但在正式生产环境中,你需要自己部署一个 RTC Token 服务器来生成、更新 Token,详见使用 Token 鉴权。如果你使用了声网的版权音乐,你还需要使用 RTM Token,详见部署 RTM Token。
- 如果你的网络环境部署了防火墙,请参考应用企业防火墙限制以正常使用声网服务。
集成 SDK 和 KTV API
参考以下步骤来集成实时互动 SDK 和 KTV API:
-
打开你的项目根目录下的
/Gradle Scripts/settings.gradle
文件,添加 Maven Central 依赖 (如果已有可忽略):Javarepositories {
...
mavenCentral()
...
}注意如果你的 Android 项目设置了 dependencyResolutionManagement,添加 Maven Central 依赖的方式可能存在差异。
-
打开
/Gradle Scripts/build.gradle(Module: <projectname>.app)
文件,在dependencies
中添加声网实时互动 SDK 的依赖。Java...
dependencies {
...
implementation 'io.agora.rtc:agora-special-full:4.1.1.23'
} -
在工程文件中引入 KTVApi.kt 文件和 KTVApiImpl.kt 文件。
实现在线 K 歌
本节介绍使用 KTV API 实现在线 K 歌的基本逻辑。
1. 创建并初始化 KTV API 模块
-
调用
create
初始化RtcEngine
。注意为避免引发程序异常甚至崩溃,请确保
RtcEngine
的生命周期大于 KTV API 模块的生命周期。Kotlin// 初始化 RtcEngine
val config = RtcEngineConfig()
config.mContext = context.getApplicationContext()
// 填入你项目的 App ID,可在声网控制台获取
config.mAppId = "<Your_Agora_Appid>"
config.mEventHandler = object : IRtcEngineEventHandler() {}
config.mChannelProfile = CHANNEL_PROFILE_LIVE_BROADCASTING
val mRtcEngine = RtcEngine.create(config) as RtcEngineEx -
调用
createKTVApi
创建并初始化 KTV API 实例。在大合唱场景下,你需要调用createKTVGiantChorusApi
来创建大合唱场景下的 KTV API 实例。- 大合唱场景
- 其他场景
Kotlin// 创建并初始化 KTV API 实例
val ktvApiProtocol =
createKTVGiantChorusApi(
KTVGiantChorusApiConfig(
// 你的 App ID
"<Your Agora Appid>",
// RTM Token,如果你使用的是本地的曲库而非声网提供的版权音乐,该参数可为空
"<Your Agora Rtm Token>",
mRtcEngine,
// 用户 ID
"<Your Uid>",
// 观众频道的频道名称
"<Audience Channel Name>",
// 根据频观众频道名和用户 ID 生成的 Token,用于加入观众频道时鉴权
"<Audience Channel Token>",
// 演唱频道的频道名,由外部指定
"<Your Chorus Channel Name>",
// 根据演唱频道名和用户 ID 生成的 Token,用于加入演唱频道时鉴权
"<Your Agora Chorus Token>",
// 发布音乐流的用户 ID
"<Music Stream Uid>",
// 根据演唱频道名和音乐流的用户 ID 生成的 Token,用于加入演唱频道时鉴权
"<Music Stream Token>",
// 设置可缓存的音乐资源数量,最多不能超过 50
10,
// 音乐资源类型,默认为声网音乐内容中心提供的版权音乐
KTVMusicType.SONG_CODE
)
)Kotlin// 创建并初始化 KTV API 实例
val ktvApiProtocol =
createKTVApi(
KTVApiConfig(
// 你的 App ID
"<Your Agora Appid>",
// RTM Token,如果你使用的是本地的曲库而非声网提供的版权音乐,该参数可为空
"<Your Agora Rtm Token>",
mRtcEngine,
// 需加入的频道名称
"<Your Channel Name>",
// 用户 ID
"<Your Uid>",
// 合唱子频道的频道名,由外部指定
"<Your Chorus Channel Name>",
// 根据频合唱子频道名和用户 ID 生成的 Token,用于加入该频道时鉴权
"<Your Agora Chorus Token>"
),
// 设置可缓存的音乐资源数量,最多不能超过 50
10,
// 设置 K 歌的场景
KTVType.Normal,
// 音乐资源类型,默认为声网音乐内容中心提供的版权音乐
KTVMusicType.SONG_CODE
)
- 当用于加入主频道的 Token 即将过期前,你会收到
IRtcEngineEventHandler
类下的 onTokenPrivilegeWillExpire 回调,你需要调用IRtcEngine
下的renewToken
来更新 Token。 - 如需更新加入合唱子频道的 Token,直接调用 KTVApi 下的
renewToken
来更新 Token。 - 如果你使用了声网的版权音乐,当用于鉴权的 RTM Token、用于加入合唱子频道的 Token 即将过期时,你会收到
onTokenPrivilegeWillExpire
回调。如需更新 RTM Token,你需要调用KTVApi
下的renewToken
来更新 Token。
2. 订阅事件回调
调用 addEventHandler
订阅 KTV API 事件,KTV API 模块支持订阅多个事件。如果你需要取消订阅事件,可调用 removeEventHandler
方法。
val ktvApiEvent = object: IKTVApiEventHandler() {
override fun onTokenPrivilegeWillExpire() {
}
}
// 订阅 KTVAPI 事件
ktvApiProtocol.addEventHandler(ktvApiEvent)
// 取消订阅 KTVAPI 事件
ktvApiProtocol.removeEventHandler(ktvApiEvent)
3. 同步数据流
为同步频道内的歌词进度等状态信息,你需要在调用 joinChannel
成功加入频道后调用 renewInnerDataStreamId
来创建数据流通道。一个频道中最多只能创建 5 个数据流通道。
// 更新数据流 ID
ktvApiProtocol.renewInnerDataStreamId();
如果退出频道后再次加入频道,你需要在加入频道成功后重新调用 renewInnerDataStreamId
来创建数据流通道。
4. 加载及播放歌曲
声网提供正版版权音乐库,如需加载版权歌单,请参考获取版权音乐。声网也支持你加载自己本地的歌曲曲库。你可以调用 loadMusic
[2/2] 来加载并播放你本地的音乐文件。
// 加载音乐
ktvApiProtocol.loadMusic(
KTVLoadMusicConfiguration(songId, mainSingerUid, KTVLoadMusicMode.LOAD_MUSIC_AND_LRC),
url
)
目前仅支持一次加载一首歌曲,请在一首歌曲加载完成后再加载下一首。
5. 切换角色
KTV API 初始化时默认用户角色为听众,如果需要开始独唱或加入合唱,需要调用 switchSingerRole
来切换至相应的角色。 KTV API 内部会根据角色的切换来控制演唱过程中音乐播放器的播放、同步,以及订阅和发布音频流的行为。你还可以通过 ISwitchRoleStateListener
接口类下的回调来获取切换的状态。
请参考下图来进行角色切换:
// 根据你的业务场景,将用户角色设为独唱、领唱、合唱、伴唱
ktvApiProtocol.switchSingerRole(KTVSingRole.CoSinger, object: ISwitchRoleStateListener {
override fun onSwitchRoleSuccess() {}
override fun onSwitchRoleFail(reason: SwitchRoleFailReason) {}
})
6. 监听并控制歌曲播放
歌曲播放时,音乐播放器会通过 onMusicPlayerStateChanged
回调向业务层通知歌曲播放状态改变。收到 onPlayerStateChanged(PLAYER_STATE_OPEN_COMPLETED)
回调后,你可以通过 seekSing
、pauseSing
、resumeSing
等方法控制播放器。
KTV API 模块内部会自动处理播放器同步,因此你也可以通过 onMusicPlayerStateChanged
回调获取远端播放器的状态。
// 跳转到指定时间播放歌曲。
ktvApiProtocol.seekSing(time)
7. 销毁 KTV API 实例
退出 K 歌场景时,你需要调用 release
释放 KTV API 模块内的资源和取消注册事件回调。请确保 RtcEngine
的生命周期大于 KTV API 模块。释放资源时,请在释放 KTV API 模块之后再销毁 RtcEngine
实例。
// 先释放 KTV API 模块资源
ktvApiProtocol.release()
// 再销毁 RtcEngine 实例
RtcEngine.destroy()
下图展示 KTV API 的调用时序图:
实现上述基本的业务逻辑后,你可以根据你实际的业务场景,选择独唱、合唱、大合唱、抢唱或接唱方案。
相关信息
本节介绍集成 KTV API 的其他相关信息和文档。
获取歌曲进度和音高信息
-
为实时获取歌曲进度、人声音高等信息来渲染歌词及音高线,你的歌词组件类需要继承 ILrcView,并实现该类中的回调。
Kotlinclass LrcView: ILrcView {
// 人声音高回调,每 20 ms 更新一次
override fun onUpdatePitch(pitch: Float) {
}
// 歌词播放进度回调,每 20 ms 更新一次
override fun onUpdateProgress(progress: Long) {
}
// 歌词下载回调,此处可以下载歌词文件
override fun onDownloadLrcData(url: String) {
}
// 当你播放的是歌曲副歌片段时,会触发该回调报告副歌片段的起始和结束时间
override fun onHighPartTime(highStartTime: Long, highEndTime: Long) {
}
} -
调用
setLrcView
方法将你的歌词组件对象传递给 KTV API 模块。
API 参考
本文集成步骤中使用如下 API: