跳到主要内容

跨房间连麦

跨房间连麦

依赖版本: plugin-rtc@5.3.0,对应 imlib 版本为 imlib-v2@2.11.0imlib-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 值,通知服务是否把本房间资源合并入副房间的合流资源中,所以指定 autoMixtrue 后,还需要加入副房间。

/**
* 加入副房间
* @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 信息即可

退出副房间

退出副房间,参数 isQuitPKfalse 时,连麦关系依然存在,可重新加入副房间。

/**
* 退出副房间
* @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()