独唱
本文介绍如何实现独唱。在此之前,请确保你已参考实现文档集成 KTV API。
方案介绍
用户点歌后,可以开始独唱,K 歌房内的听众都可以听到其演唱。房间内想与独唱者连麦语聊的听众可以上麦。
独唱场景下存在两种角色:
- 独唱者:加入频道,加载并播放歌曲。KTV API 模块内部控制音乐播放器播放音乐,发布音乐到远端,将音乐播放进度同步到远端,让歌词组件进入歌词滚动状态等逻辑。
- 听众:加入频道,加载歌词。KTV API 模块内部控制听众订阅独唱者的人声和音乐的音频合流,同步独唱者的音乐播放进度,让歌词组件进入歌词滚动状态等逻辑。如果普通听众需要上麦聊天,可以更新媒体选项。
下图为独唱方案的技术原理图:
独唱者实现
1. 加入频道
调用 joinChannel
让独唱者加入频道。为保证高音质,声网推荐你在加入频道前调用 setAudioProfile
将音频编码属性设为 MUSIC_HIGH_QUALITY
,将音频场景设为 AUDIO_SCENARIO_GAME_STREAMING
。
// 加入频道
mRtcEngine.joinChannel(
<Your_Rtc_Token>,
<Your_Channel_Name>,
<Your_Uid>,
// 媒体选项详见第 5 步操作
channelMediaOption
)
为同步频道内的歌词进度等状态信息,你需要在成功加入频道后调用 renewInnerDataStreamId
来创建数据流通道。如果退出频道后再次加入频道,你需要在加入频道成功后重新调用该方法来创建数据流通道。一个频道中最多只能创建 5 个数据流通道。
2. 加载及播放歌曲
调用 loadMusic
加载歌曲。在调用该方法后需调用 switchSingerRole
将用户角色设为独唱(SoloSinger
),然后调用 startSing
才可以播放歌曲。
如需加载声网提供的版权音乐,请参考获取版权音乐。
// 加载歌曲
ktvApiProtocol.loadMusic(songCode, KTVLoadMusicConfiguration(false, "<MainSingerUid>", KTVLoadMusicMode.LOAD_MUSIC_AND_LRC), object: IMusicLoadStateListener {
override fun onMusicLoadSuccess(songCode: Long, lyricUrl: String) {
// 加载成功后,将用户角色设为独唱者
ktvApiProtocol.switchSingerRole(SoloSinger)
// 开始播放
ktvApiProtocol.startSing(songCode, 0)
}
// 加载失败
override fun onMusicLoadFail(songCode: Long, reason: KTVLoadSongFailReason) {
}
// 显示加载进度
override fun onMusicLoadProgress(songCode: Long, percent: Int, status: MusicLoadStatus, msg: String?, lyricUrl: String?) {
}
})
3. 歌曲结束
当歌曲播放完成或切歌后,你需要调用 switchSingerRole
将用户的角色切回听众。
ktvApiProtocol.switchSingerRole(KTVSingRole.Audience, null);
4. 关闭麦克风
独唱者停止唱歌或希望暂时关闭麦克风时,可以调用 muteMic(true)
。
ktvApiProtocol.muteMic(true)
5. 根据角色更新媒体选项
通过 updateChannelMediaOptions
方法在主播加入频道后更新频道媒体选项,例如是否开启本地音频采集,是否发布本地音频流等。
val channelMediaOption = ChannelMediaOptions()
// 发布本地麦克风流
channelMediaOption.publishMicrophoneTrack = true
// 启用音频采集和播放
channelMediaOption.enableAudioRecordingOrPlayout = true
// 设置角色为主播
channelMediaOption.clientRoleType = CLIENT_ROLE_BROADCASTER
// 更新媒体选项
mRtcEngine.updateChannelMediaOptions(channelMediaOption)
听众实现
1. 加入频道
调用 joinChannel
让听众加入频道。为保证高音质,声网推荐你在加入频道前调用 setAudioProfile
将音频编码属性设为 MUSIC_HIGH_QUALITY
,将音频场景设为 AUDIO_SCENARIO_GAME_STREAMING
。
// 加入频道。
mRtcEngine.joinChannel(
<Your_Rtc_Token>,
<Your_Channel_Name>,
<Your_Uid>,
// 媒体选项详见第 3 步操作
channelMediaOption
)
2. 加载歌词
调用 loadMusic
加载歌词。听众加入频道后,默认订阅独唱者发布的音频合流,即独唱者人声和音乐混合的音频流,因此观众仅需加载歌词。
// songId 为歌曲的唯一标识
// mainSingerUid 为独唱者的 UID
// KTVLoadMusicMode.LOAD_LRC_ONLY 听众只需要加载歌词
ktvApiProtocol.loadMusic(songId, KTVLoadMusicConfiguration(false, mainSingerUid, KTVLoadMusicMode.LOAD_LRC_ONLY), object: IMusicLoadStateListener {
override fun onMusicLoadSuccess(songCode: Long, lyricUrl: String) {}
override fun onMusicLoadFail(songCode: Long, reason: KTVLoadSongFailReason) {}
override fun onMusicLoadProgress(songCode: Long, percent: Int, status: MusicLoadStatus, msg: String?, lyricUrl: String?) {}
})
3. 根据角色更新媒体选项
通过 updateChannelMediaOptions
方法在听众加入频道后更新频道媒体选项,例如是否开启本地音频采集,是否发布本地音频流等。
听众的用户角色为 CLIENT_ROLE_AUDIENCE
,因此无法在频道内发布音频流。如果听众想上麦与演唱者语聊,需要将用户角色修改为 CLIENT_ROLE_BROADCASTER
。修改角色后,SDK 默认发布该连麦听众的音频流,独唱者和其他听众都能听到连麦听众的声音。
// 对需要上麦聊天的听众更新媒体选项
val channelMediaOption = ChannelMediaOptions()
// 发布本地麦克风流
channelMediaOption.publishMicrophoneTrack = true
// 启用音频采集和播放
channelMediaOption.enableAudioRecordingOrPlayout = true
// 设置角色为主播
channelMediaOption.clientRoleType = CLIENT_ROLE_BROADCASTER
// 更新媒体选项
mRtcEngine.updateChannelMediaOptions(channelMediaOption)
// 对未上麦的听众更新媒体选项
val channelMediaOption = ChannelMediaOptions()
// 不发布本地麦克风流
channelMediaOption.publishMicrophoneTrack = false
// 启用音频采集和播放
channelMediaOption.enableAudioRecordingOrPlayout = true
// 设置角色为观众
channelMediaOption.clientRoleType = CLIENT_ROLE_AUDIENCE
// 更新媒体选项
mRtcEngine.updateChannelMediaOptions(channelMediaOption)
下图展示独唱的 API 调用时序图:
API 参考
本文集成步骤中使用如下 API: