大合唱
本文介绍如何实现大合唱场景。在此之前,请确保你已参考实现文档集成 KTV API。
方案介绍
大合唱指有 50 到 100 人参与合唱的场景。在此场景下存在三种角色:
- 合唱中的领唱者:领唱者在演唱频道通过两个用户 ID 分别发布音乐流、麦克风采集的音频流。KTV API 模块内部控制音乐播放器播放音乐,同步领唱的音乐播放进度,让歌词组件进入歌词滚动状态等逻辑。
- 合唱中的伴唱:如有人加入合唱,则其成为合唱中的伴唱。伴唱需要加入演唱频道,加载并播放歌曲,发布麦克风采集的音频流和音乐流。KTV API 模块内部控制音乐播放器播放音乐,同步领唱的音乐播放进度,让歌词组件进入歌词滚动状态等逻辑。
- 听众:加入听众频道,加载歌词。KTV API 模块内部控制听众订阅演唱者的人声和音乐的音频合流,并同步演唱者的音乐播放进度,让歌词组件进入歌词滚动状态等逻辑。大合唱场景下,听众人数较多,通常不建议听众上麦聊天。
前提条件
领唱实现
本节介绍领唱实现的具体步骤。
1. 加入频道
调用 joinChannelByToken
加入频道。
// 加入频道
[self.rtcKit joinChannelByToken:<YOUR TOKEN>
channelId:<YOUR CHANNEL NAME>
info:nil
uid:<YOUR UID>
mediaOptions:mediaOption
joinSuccess:nil];
用户调用 joinChannel
默认加入听众频道,切换用户角色为领唱后,KTV API 模块内部会自动退出听众频道然后加入演唱频道来发布人声和音乐流。
2. 加载及播放歌曲
调用 loadMusic
加载歌曲。在调用该方法后需调用 switchSingerRole
将用户角色设为独唱(LeadSinger
),然后调用 startSing
才可以播放歌曲。
如需加载声网提供的版权音乐,请参考获取版权音乐。
KTVSongConfiguration *songConfig = [[KTVSongConfiguration alloc] init];
// 同时加载歌曲和歌词
songConfig.songIdentifier = songIdentifier;
songConfig.mode = KTVLoadMusicModeLoadMusicAndLrc;
songConfig.mainSingerUid = mainSingerUid;
// 歌曲加载失败的原因
- (void)onMusicLoadFailWithSongCode:(NSInteger)songCode
reason:(enum KTVLoadSongFailReason)reason {
}
// 歌曲加载成功的回调,在此回调内调用 switchSingerRole 切换角色,调用 startSing
// 开始播放歌曲
- (void)onMusicLoadSuccessWithSongCode:(NSInteger)songCode
lyricUrl:(NSString *_Nonnull)lyricUrl {
// 切换角色
[weakSelf.ktvApi
switchSingerRoleWithNewRole:KTVSingRoleLeadSinger
onSwitchRoleState:^(KTVSwitchRoleState state,
KTVSwitchRoleFailReason reason){
// 切换角色状态回调
}];
// 开始播放歌曲
[weakSelf.ktvApi startSingWithSongCode:songCode startPos:0];
}
[self.ktvApi loadMusicWithSongCode:songCode
config:songConfig
onMusicLoadStateListener:self];
// 歌曲加载进度回调
- (void)
onMusicLoadProgressWithSongCode:(NSInteger)songCode
percent:(NSInteger)percent
status:(AgoraMusicContentCenterPreloadStatus)status
msg:(NSString *)msg
lyricUrl:(NSString *)lyricUrl {
}
3. 切换角色
在大合唱场景中,没有独唱者角色。用户切换成领唱者角色时,会自动退出听众频道然后加入演唱频道。从领唱切换成听众角色时,会自动退出演唱频道,加入听众频道。
// 歌曲结束后,将角色切换为听众
[weakSelf.ktvApi switchSingerRoleWithNewRole:KTVSingRoleAudience
onSwitchRoleState:^(KTVSwitchRoleState state,
KTVSwitchRoleFailReason reason){
// 切换角色状态回调
}];
4. 开关麦克风
调用 muteMic
方法在成为领唱角色后开关麦克风。
[self.ktvApi muteMicWithMuteStatus: true/false];
伴唱实现
本节介绍伴唱的实现步骤。
1. 加入频道
调用 joinChannelByToken
加入频道。
// 加入频道
[self.rtcKit joinChannelByToken:<YOUR TOKEN>
channelId:<YOUR CHANNEL NAME>
info:nil
uid:<YOUR UID>
mediaOptions:mediaOption
joinSuccess:nil];
用户调用 joinChannel
默认加入听众频道,切换用户角色为伴唱后,KTV API 模块内部会自动退出听众频道然后加入演唱频道来发布人声和音乐流。
2. 加载歌曲
听众加入合唱成为伴唱前,需调用 loadMusic
加载歌曲。歌曲加载完成后,调用 switchSingerRole
将用户角色设为伴唱(CoSinger
),切换成功后会自动退出听众频道然后加入演唱频道,并校准领唱的播放进度。
KTVSongConfiguration *songConfig = [[KTVSongConfiguration alloc] init];
// 同时加载歌曲和歌词
songConfig.songIdentifier = songIdentifier;
songConfig.mode = KTVLoadMusicModeLoadMusicAndLrc;
songConfig.mainSingerUid = mainSingerUid;
// 歌曲加载失败的原因
- (void)onMusicLoadFailWithSongCode:(NSInteger)songCode
reason:(enum KTVLoadSongFailReason)reason {
}
// 歌曲加载成功的回调,在此回调内调用 switchSingerRole 切换角色,调用 startSing
// 开始播放歌曲
- (void)onMusicLoadSuccessWithSongCode:(NSInteger)songCode
lyricUrl:(NSString *_Nonnull)lyricUrl {
// 切换角色
[weakSelf.ktvApi
switchSingerRoleWithNewRole:KTVSingRoleCoSinger
// 切换角色状态回调
onSwitchRoleState:^(KTVSwitchRoleState state,
KTVSwitchRoleFailReason reason){
}];
}
[self.ktvApi loadMusicWithSongCode:songCode
config:songConfig
onMusicLoadStateListener:self];
// 歌曲加载进度回调
- (void)
onMusicLoadProgressWithSongCode:(NSInteger)songCode
percent:(NSInteger)percent
status:(AgoraMusicContentCenterPreloadStatus)status
msg:(NSString *)msg
lyricUrl:(NSString *)lyricUrl {
}
3. 切换角色
当歌曲结束或伴唱想要中途退出合唱时,调用 switchSingerRole
将用户角色切换为听众,切换成听众角色时,会自动退出演唱频道,加入听众频道。
// 歌曲结束后,将角色切换为听众
[weakSelf.ktvApi switchSingerRoleWithNewRole:KTVSingRoleAudience
onSwitchRoleState:^(KTVSwitchRoleState state,
KTVSwitchRoleFailReason reason){
}];
4. 开关麦克风
调用 muteMic
方法在成为伴唱角色后开关麦克风。
[self.ktvApi muteMicWithMuteStatus: true/false];
听众实现
本节介绍听众的实现步骤。
1. 加入频道
调用 joinChannelByToken
加入频道。为保证高音质,声网推荐你在加入频道前调用 setAudioProfile
将音频编码属性设为 AgoraAudioProfileMusicHighQuality
,将音频场景设为 AgoraAudioScenarioGameStreaming
。
// 加入频道
[self.rtcKit joinChannelByToken:<YOUR TOKEN>
channelId:<YOUR CHANNEL NAME>
info:nil
uid:<YOUR UID>
mediaOptions:mediaOption
joinSuccess:nil];
2. 加载歌词
调用 loadMusic
加载歌词。听众加入频道后,默认订阅演唱者人声和音乐混合的音频流。
KTVSongConfiguration *songConfig = [[KTVSongConfiguration alloc] init];
// 同时加载歌曲和歌词
songConfig.songIdentifier = songIdentifier;
songConfig.mode = KTVLoadMusicModeLoadLrc;
songConfig.mainSingerUid = mainSingerUid;
// 歌曲加载失败的原因
- (void)onMusicLoadFailWithSongCode:(NSInteger)songCode
reason:(enum KTVLoadSongFailReason)reason {
}
// 歌曲加载成功的回调,在此回调内调用 switchSingerRole 切换角色,调用 startSing
// 开始播放歌曲
- (void)onMusicLoadSuccessWithSongCode:(NSInteger)songCode
lyricUrl:(NSString *_Nonnull)lyricUrl {
// 切换角色
[weakSelf.ktvApi
switchSingerRoleWithNewRole:KTVSingRoleCoSinger
// 切换角色状态回调
onSwitchRoleState:^(KTVSwitchRoleState state,
KTVSwitchRoleFailReason reason){
}];
}
[self.ktvApi loadMusicWithSongCode:songCode
config:songConfig
onMusicLoadStateListener:self];
// 歌曲加载进度回调
- (void)
onMusicLoadProgressWithSongCode:(NSInteger)songCode
percent:(NSInteger)percent
status:(AgoraMusicContentCenterPreloadStatus)status
msg:(NSString *)msg
lyricUrl:(NSString *)lyricUrl {
}
大合唱场景下由于听众人数较多,为确保房间内的秩序和听感体验,不建议听众上麦聊天。
API 参考
本文集成步骤中使用如下 API: