跨房间连麦
跨房间连麦
依赖版本: plugin-rtc@5.3.0
,对应 imlib 版本为 imlib-v2@2.11.0
或 imlib-next@5.1.0
前提: 跨房间连麦,需要双方都加入各自的直播房间后进行。
跨房间连麦功能中有“主房间”和“副房间”两个概念。
- 主房间:本端加入的直播房间
- 副房间:在接受连麦邀请后加入的对方房间
主流程
获取跨房间连麦处理对象 roomPKHandler
// room 为主播加入各自直播间后,得到的直播房间 room 实例
// 获取跨房间连麦功能处理模块
const { roomPKHandler } = room.getRoomPKHandler();
主播注册跨房间连麦事件监听
// 注册跨房间连麦相关事件监听
roomPKHandler.registerRoomPKEventListener({
/**
* 收到连麦邀请,此时可调 roomPKHandler.responseJoinOtherRoom 响应连麦
*/
onRequestJoinOtherRoom (info: IPKInviteInfo) {},
/**
* 收到连麦邀请已被取消
*/
onCancelRequestOtherRoom (info: IPKInviteInfo) {},
/**
* 收到被邀请方应答,数据中包含对方是否同意请求
* 如果对方同意连麦,此时可调 roomPKHandler.joinOtherRoom 加入对方房间
*/
onResponseJoinOtherRoom: (info: IPKInviteAnswerInfo) => {
console.log(info.agree)
},
/**
* 收到 连麦结束通知
* 连麦结束时,plugin-rtc 内部会退出副房间,业务层只需做 UI 处理
*/
onFinishOtherRoom: (info: IPKEndInfo) => {}
})
发起连麦邀请
向指定房间的某个用户发送跨房间连麦请求
/**
* 发起跨房间连麦请求
* @param inviteeRoomId 被邀请者所处的房间 roomId
* @param inviteeUserId 被邀请者 userId
* @param options.autoMix 是否【在加入副房间后自动】将邀请者发布的资源,合并到被邀请者房间内的 MCU 流中。【退出副房间会自动取消合并】
* @param options.extra 附加信息,可随邀请连麦消息携带给被邀请者
*/
const { code } = await roomPKHandler.requestJoinOtherRoom(inviteeRoomId: string, inviteeUserId: string, options?: IReqRoomPKOptions)
if (code === RCRTCCode.SUCCESS) {
console.log('发送连麦邀请成功');
}
取消连麦邀请
被邀请者未响应连麦请求时,邀请方取消发出去的跨房间连麦请求。
/**
* 取消跨房间连麦请求
* @param inviteeRoomId 被邀请者所处的房间 roomId
* @param inviteeUserId 被邀请者 userId
* @param extra 附加信息,可随取消邀请连麦消息携带给被邀请者
*/
const { code } = await roomPKHandler.cancelRequestJoinOtherRoom(inviteeRoomId: string, inviteeUserId: string, extra?: string)
if (code === RCRTCCode.SUCCESS) {
console.log('发送取消连麦成功');
}
响应连麦请求
被邀请方响应邀请方发出的跨房间连麦请求。
/**
* 响应跨房间连麦请求
* @param inviterRoomId 邀请者所处的房间 roomId
* @param inviterUserId 邀请者 userId
* @param agree 是否同意连麦
* @param options.autoMix 是否【在加入副房间后自动】将被邀请者发布的资源,合并到邀请者房间内的 MCU 流中。【退出副房间会自动取消合并】
* @param options.extra 附加信息,可随响应连麦消息携带给邀请者
*/
const { code } = await roomPKHandler.responseJoinOtherRoom (inviterRoomId: string, inviterUserId: string, agree: boolean, options?: IReqRoomPKOptions)
if (code === RCRTCCode.SUCCESS) {
console.log('发送应答连麦成功');
}
加入副房间
在连麦邀请方与被邀请方建立连麦关系后,加入副房间。副房间内只能订阅资源,不能发布资源。
加入副房间后,SDK 内部会根据 autoMix
值,通知服务是否把本房间资源合并入副房间的合流资源中,所以指定 autoMix
为 true
后,还需要加入副房间。
/**
* 加入副房间
* @param roomId 副房间 Id, 支持大小写英文字母、数字、部分特殊符号 + = - _ 的组合方式 最长 64 个字符
*/
const res = await roomPKHandler.joinOtherRoom(roomId: string)
if (res.code === RCRTCCode.SUCCESS) {
const { room: otherRoom, userIds, tracks } = res
console.log('房间实例: ', otherRoom)
console.log('房间内人员: ', userIds)
console.log('房间内资源: ', tracks)
}
注册副房间事件监听
// 注册房间事件监听器,重复注册时,仅最后一次注册有效
otherRoom.registerRoomEventListener({
/**
* 当本端被剔出房间
* @description 被踢出房间可能是由于服务端超出一定时间未能收到 rtcPing 消息,所以认为己方离线。
* 另一种可能是己方 rtcPing 失败次数超出上限,故而主动断线
* @param byServer
* 当值为 false 时,说明本端 rtcPing 超时
* 当值为 true 时,说明本端收到被踢出房间通知
* @param state 被踢出房间的原因
*/
onKickOff? (byServer: boolean, state?: RCKickReason): void
},
/**
* 接收到房间信令时回调,用户可通过房间实例的 `sendMessage(name, content)` 接口发送信令
* @param name 信令名
* @param content 信令内容
* @param senderUserId 发送者 Id
* @param messageUId 消息唯一标识
*/
onMessageReceive (name: string, content: any, senderUserId: string, messageUId: string) {
},
/**
* 监听房间属性变更通知
* @param name
* @param content
*/
onRoomAttributeChange (name: string, content: string) {
},
/**
* 房间用户禁用/启用音频
* @param audioTrack RCRemoteAudioTrack 类实例
*/
onAudioMuteChange (audioTrack: RCRemoteAudioTrack) {
},
/**
* 房间用户禁用/启用视频
* @param videoTrack RCRemoteVideoTrack 类实例对象
*/
onVideoMuteChange (videoTrack: RCRemoteVideoTrack) {
},
/**
* 房间内用户发布资源
* @param tracks 新发布的音轨与视轨数据列表,包含新发布的 RCRemoteAudioTrack 与 RCRemoteVideoTrack 实例
*/
async onTrackPublish (tracks: RCRemoteTrack[]) {
// 按业务需求选择需要订阅资源,通过 room.subscribe 接口进行订阅
const { code } = await room.subscribe(tracks)
if (code !== RCRTCCode.SUCCESS) {
console.log('资源订阅失败 ->', code)
}
},
/**
* 房间用户取消发布资源
* @param tracks 被取消发布的音轨与视轨数据列表
* @description 当资源被取消发布时,SDK 内部会取消对相关资源的订阅,业务层仅需处理 UI 业务
*/
onTrackUnpublish (tracks: RCRemoteTrack[]) {
},
/**
* 订阅的音视频流通道已建立, track 已可以进行播放
* @param track RCRemoteTrack 类实例
*/
onTrackReady (track: RCRemoteTrack) {
if (track.isAudioTrack()) {
// 音轨不需要传递播放控件
track.play()
} else {
// 视轨需要一个 video 标签才可进行播放
const element = document.createElement('video')
document.body.appendChild(element)
track.play(element)
}
},
/**
* 人员加入
* @param userIds 加入的人员 id 列表
*/
onUserJoin (userIds: string[]) {
},
/**
* 人员退出
* @param userIds
*/
onUserLeave (userIds: string[]) {
},
/**
* 房间内主播和观众切换身份
* @param userId 用户 ID
* @param role 用户角色
* role 值为 RCRTCLiveRole.ANCHOR 时,代表房间内观众升级为主播
* role 值为 RCRTCLiveRole.AUDIENCE 时,代表主播降级为房间内的观众
*/
onSwitchRole (userId: string, role: RCRTCLiveRole) {
}
})
订阅副房间资源
和主房间一致,副房间要订阅的远端资源有两个来源: joinOtherRoom
返回的 tracks
和房间监听事件 onTrackPublish
处收到的 tracks
。订阅成功后,在房间监听事件 onTrackReady
处播放。
const { code } = await otherRoom.subscribe([
// 音频不支持大小流
audioTrack,
{
track: videoTrack,
subTiny: true // 订阅小流
}
])
取消订阅副房间资源
const { code } = await otherRoom.unsubscribe([audioTrack, videoTrack])
// 取消订阅完成后,业务层移除相关的 UI 信息即可
退出副房间
退出副房间,参数 isQuitPK
为 false
时,连麦关系依然存在,可重新加入副房间。
/**
* 退出副房间
* @param room 要退出的副房间 room 实例
* @param isQuitPK 是否结束连麦
*/
const { code } = await roomPKHandler.leaveOtherRoom (room: RCLivingRoom, isQuitPK?: boolean)
房间是否为主房间
/**
* @since version 5.3.2
*/
const isMainRoom = room.isMainRoom()
获取所有的连麦信息
/**
* @since version 5.3.2
*/
const allPKInfo = roomPKHandler.getAllPKInfo()
console.log('所有连麦信息:', allPKInfo)
获取指定副房间的连麦信息
/**
* 获取连麦信息
* @param roomId 连麦房间的 roomId
*/
const PKInfo = roomPKHandler.getPKInfo(roomId)
console.log(`和 ${roomId} 的连麦信息:`, PKInfo)
获取已加入的副房间
const joinedPKRooms: { [roomId: string]: RCLivingRoom } = roomPKHandler.getJoinedPKRooms()