为方便用户同时加入多个频道,接收多个频道的音视频流,声网 RTC Native SDK 3.0 及以上版本支持多频道管理,且频道数量无限制。
该功能可应用于类似超级小班课的场景:将一个互动大班里的学生分到不同的小班,学生可以在小班内进行实时音视频互动。根据场景需要,你还可以给每个小班可以配备一名助教老师。
我们在 GitHub 提供以下实现了多频道功能的开源示例项目,你可以前往下载体验,参考源代码。
AgoraRtcChannel 类的频道中发布流:AgoraRtcEngineKit 类的频道中发布流: Breakout Class (iOS)SDK 提供 AgoraRtcChannel 类和 AgoraRtcChannelDelegate 类实现多频道控制。
你可以多次调用 createRtcChannel,通过不同的 channelId 创建多个 AgoraRtcChannel 对象(对应多个频道),然后分别调用 AgoraRtcChannel 中的 joinChannelByToken 方法加入对应的频道。
实现多频道功能的主要步骤如下:
sharedEngineWithAppId 方法,创建并初始化 AgoraRtcEngineKit。setChannelProfile方法,将频道场景设置为直播。createRtcChannel 方法,通过 channelId 创建一个 AgoraRtcChannel 对象。AgoraRtcChannel 类的 setRtcChannelDelegate方法,接收该频道的回调通知。AgoraRtcChannel 类的 setClientRole 设置用户角色。AgoraRtcChannel 类的 joinChannelByToken 方法加入频道。用户加入频道后,默认发布本地流并自动订阅频道内所有其他用户的流。你可以在加入频道时通过 AgoraRtcChannelMediaOptions 设置发布和订阅状态,也可以在加入频道后通过 AgoraRtcChannel 类的 muteLocal 和 muteRemote 为前缀的方法修改发布和订阅状态。加入多个频道的 API 时序如下:
下面的示例代码演示了如何通过 AgoraRtcChannel 类加入多频道,并在加入的第一个频道中发布本地流。
创建并初始化 AgoraRtcEngineKit 对象。
let config = AgoraRtcEngineConfig()
config.appId = KeyCenter.AppId
agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self)
启用视频模块。
agoraKit.enableVideo()
将频道场景设置为直播场景。
agoraKit.setChannelProfile(.liveBroadcasting)
创建并获取 AgoraRtcChannel1 对象,并监听该频道的回调通知。
channel1 = agoraKit.createRtcChannel(channelName1)
channel1?.setRtcChannelDelegate(self)
设置用户角色为主播。
channel1?.setClientRole(.broadcaster)
传入 token 和 channelId, 加入 AgoraRtcChannel1 对象的频道,SDK 会默认发布本地流并自动订阅所有远端流。
let mediaOptions = AgoraRtcChannelMediaOptions()
mediaOptions.autoSubscribeAudio = YES
mediaOptions.autoSubscribeVideo = YES
mediaOptions.publishLocalAudio = YES
mediaOptions.publishLocalVideo = YES
channel1?.join(byToken: "Your token", info: nil, uid: 0, options: mediaOptions)
创建并获取 AgoraRtcChannel2 对象,并监听该频道的回调通知。
channel2 = agoraKit.createRtcChannel(channelName2)
channel2?.setRtcChannelDelegate(self)
设置用户角色为观众,无发流权限。
channel2?.setClientRole(.audience)
传入 token 和 channelId, 加入 AgoraRtcChannel2 对象的频道。你需要设置 publishLocalAudio 和 publishLocalVideo 为 NO,否则加入频道会失败。
let mediaOptions2 = AgoraRtcChannelMediaOptions()
mediaOptions2.autoSubscribeAudio = YES
mediaOptions2.autoSubscribeVideo = YES
mediaOptions2.publishLocalAudio = NO
mediaOptions2.publishLocalVideo = NO
channel2?.join(byToken: "Your token", info: nil, uid: 0, options: mediaOptions2)
离开并销毁 AgoraRtcChannel2 对象的频道。
channel2?.leave()
channel2?.destroy()
离开并销毁 AgoraRtcChannel1 对象的频道。
channel1?.leave()
channel1?.destroy()
销毁 AgoraRtcEngineKit 对象。
agoraKit.destroy()
AgoraRtcChannel 中的 joinChannelByToken 提供媒体订阅选项设置(autoSubscribeAudio 和 autoSubscribeVideo),可以控制在加入频道后是否自动订阅音频流和视频流,默认为自动订阅。在加入频道后,你也可以通过 muteRemoteAudioStream 或 muteRemoteVideoStream 修改订阅状态。
如果你需要在加入 AgoraRtcChannel 的频道时仅订阅指定用户的音频流或视频流,声网建议使用以下方法:
joinChannelByToken 并在 ChannelMediaOptions 中设置 autoSubscribeAudio = NO 或 autoSubscribeVideo = NO 不订阅所有远端用户。muteRemoteAudioStream(uid,NO) 或 muteRemoteVideoStream(uid,NO) 订阅指定的远端用户。在视频场景中,如果远端用户是通过 AgoraRtcChannel 加入频道的,那么在设置远端视图时,还需要在 AgoraRtcVideoCanvas 中指定该远端用户所在频道的 channel ID,否则会无法渲染出远端视频画面。
// Swift
// 在远端用户加入频道的回调中设置用户视图
func rtcChannel(_ rtcChannel: AgoraRtcChannel, didJoinedOfUid uid: UInt, elapsed: Int) {
LogUtils.log(message: "remote user join: \(uid) \(elapsed)ms", level: .info)
let videoCanvas = AgoraRtcVideoCanvas()
videoCanvas.uid = uid
// 待绑定的视图
videoCanvas.view = channel1 == rtcChannel ? channel1RemoteVideo.videoView : channel2RemoteVideo.videoView
videoCanvas.renderMode = .hidden
// 指定远端用户所在频道的 channelId
videoCanvas.channelId = rtcChannel.getId()
// 设置远端用户视图
agoraKit.setupRemoteVideo(videoCanvas)
}
SDK 仅支持用户同一时间在一个频道内发布媒体流。声网推荐以观众角色加入无需发流的频道并在加入频道时设置 AgoraRtcChannelMediaOptions 中的 publishLocalAudio 和 publishLocalVideo 为 NO。
在直播场景中,用户作为主播加入频道一后,SDK 默认发布本地流到频道一。如果用户需要加入频道二,则你需要根据实际场景修改发布状态:
setClientRole(Audience))加入频道二。setClientRole(Audience)),再让用户作为主播(setClientRole(Broadcaster))加入频道二。如果用户已在频道一内发流,并且在频道二内调用如下方法,则该方法会调用失败并返回 -5(AgoraErrorCodeRefused) 错误码。
joinChannelByToken 方法加入频道二时使用 publishLocalAudio = YES 和 publishLocalVideo = YES。muteLocalAudioStream(NO) 或 muteLocalVideoStream(NO)。setClientRole(Broadcaster)。自 3.4.5 版本起,AgoraRtcChannel 类有如下变更:
publish 和 unpublish,并新增 muteLocalAudioStream 和 muteLocalVideoStream 替代。加入频道后,你可以分别设置音频流和视频流的发布状态。AgoraRtcEngineKit 类和 AgoraRtcChannel 类下的 muteLocalAudioStream 和 muteLocalVideoStream 分别控制各自频道的发布状态。AgoraRtcChannelMediaOptions 中新增 publishLocalAudio 和 publishLocalVideo 成员,默认值为 YES。你可以调用 joinChannelByToken 加入频道并设置音视频流的发布状态。如果用户已在一个频道中发流,则不论用户是主播还是观众,都需要在加入其他频道时设置 publishLocalAudio 和 publishLocalVideo 为 NO。否则,加入频道会失败。setClientRole(Broadcaster) 默认发布本地流,无需再调用 publish。在 3.4.5 之前版本中:
AgoraRtcEngineKit 类的 muteLocalAudioStream(true) 或 muteLocalVideoStream(true) 对 AgoraRtcEngineKit 频道和 AgoraRtcChannel 频道都会生效。muteLocalAudioStream 和 muteLocalVideoStream 在加入频道前后调用均可生效。joinChannelByToken 不可以设置本地流的发布状态。AgoraRtcChannel 类的 setClientRole(Broadcaster) 不会发布本地流。你还需要调用 publish。