Cross-Room Co-Streaming
In cross-room co-streaming, it's essential to distinguish between the primary room and secondary room. These concepts are relative and defined as follows:
- Primary Room: The room initially joined by the local user.
- Secondary Room: After a co-streaming invitation is accepted, both parties must join each other's rooms.
Before initiating cross-room co-streaming, both users must have joined their respective primary rooms. Co-streaming cannot proceed if either user hasn't joined their primary room.
Handling Co-Streaming Invitations
To establish co-streaming, one host sends an invitation, and the other responds by accepting or rejecting it.
Sending an Invitation
To send a cross-room co-streaming request, call the RCRTCEngine
object's requestJoinSubRoom method. Upon successful delivery, the invitee will receive a notification via the onJoinSubRoomRequestReceived
callback.
Future<int> requestJoinSubRoom(String roomId, String userId, [bool autoLayout = true, String? extra]);
Parameter | Type | Description |
---|---|---|
roomId | String | Target room ID |
userId | String | Target user ID |
autoLayout | bool | Whether to use floating layout. If true , the server merges the invitee's streams into the inviter's view after successful room joining (default: floating layout only). If the invitee hasn't published streams, merging occurs upon publication. Regardless of autoLayout , both parties can manually set layouts using setLiveMixCustomLayouts . Once manually configured, subsequent auto-layout parameters become invalid. Default: true . |
extra | String | Additional information |
// Callback for inviting others to co-stream
engine.onJoinSubRoomRequested = (roomId, userId, code, message) {
if (code == 0) {
// Invitation sent successfully, awaiting response
} else {
// Failed to send invitation
}
};
// Invite another user to co-stream
engine.requestJoinSubRoom(roomId, userId);
Responding to an Invitation
When an invitation is received, the SDK triggers the RCRTCEngine
object's onJoinSubRoomRequestReceived
callback. The invitee must respond by either accepting or rejecting.
- To accept, call
responseJoinSubRoomRequest
withagree
set totrue
, then join the secondary room viajoinSubRoom
. - To reject, call
responseJoinSubRoomRequest
withagree
set tofalse
.
Future<int> responseJoinSubRoomRequest(String roomId, String userId, bool agree, [bool autoLayout = true, String? extra]);
Parameter | Type | Description |
---|---|---|
roomId | String | Target room ID |
userId | String | Target user ID |
autoLayout | Bool | Same as above |
extra | String | Additional information |
After responding, the local user receives confirmation via onJoinSubRoomRequestResponded
, while the inviter gets notified via onJoinSubRoomRequestResponseReceived
.
- If accepted, all non-audience users (except the invitee) in both rooms receive
onJoinSubRoomRequestResponseReceived
.- If rejected, only the inviter receives the rejection callback.
// Callback for received co-stream invitations
engine.onJoinSubRoomRequestReceived = (String roomId, String userId, String? extra) {
// Callback after accepting
engine.onJoinSubRoomRequestResponded = (String roomId, String userId, bool agree, int code, String? errMsg) {
if (code == 0) {
// Acceptance confirmed
} else {
// Failed to accept
}
};
// Accept the invitation
engine.responseJoinSubRoomRequest(roomId, userId, true);
};
Canceling an Invitation
If an inviter wishes to retract an invitation, call RCRTCEngine
's cancelJoinSubRoomRequest method. The invitee will receive onCancelJoinSubRoomRequestReceived
.
Future<int> cancelJoinSubRoomRequest(String roomId, String userId, [String? extra]);
Parameter | Type | Description |
---|---|---|
roomId | String | Target room ID |
userId | String | Target user ID |
// Callback for canceled invitations
engine.onJoinSubRoomRequestCanceled = (String roomId, String userId, int code, String? errMsg) {
if (code == 0) {
// Successfully canceled
} else {
// Failed to cancel
}
};
// Cancel the invitation
engine.cancelJoinSubRoomRequest(roomId, userId);
Joining Secondary Rooms
After accepting an invitation, both parties must join each other's rooms. Relative to the local user's primary room, the other room becomes a secondary room. Join via:
Future<int> joinSubRoom(String roomId);
Timing differs for inviters and invitees:
- Invitee: After accepting (
responseJoinSubRoomRequest
withagree=true
), calljoinSubRoom
. - Inviter: Upon receiving acceptance (
onJoinSubRoomRequestResponseReceived
), calljoinSubRoom
. This triggersonSubRoomJoined
,onSubRoomBanded
, andonUserJoined
.
// Callback for joining secondary rooms
engine.onSubRoomJoined = (String roomId, int code, String? errMsg) {
if (code == 0) {
// Successfully joined
} else {
// Failed to join
}
}
// Join the secondary room
engine.joinSubRoom(roomId);
For multi-host scenarios:
-
Scenario A: If secondary rooms exist before joining the primary room, receive
onSubRoomBanded
afterjoinRoom
, then optionally join those rooms.// Callback for pre-existing secondary rooms
Function(String roomId)? onSubRoomBanded; -
Scenario B: If another host initiates co-streaming after local joining, receive
onSubRoomBanded
to optionally join new secondary rooms.
Subscribing to Streams
After joining a secondary room, subscribe to its hosts' streams via:
-
Direct subscription using
subscribe
(see Subscribing to Streams).engine.onSubscribed = (String id, RCRTCMediaType type, int code, String? message) {
if (code == 0) {
// Subscription successful
} else {
// Subscription failed
}
};
engine.subscribe(userId, RCRTCMediaType.video); -
Automatic subscription via
onRemotePublished
when streams become available.engine.onRemotePublished = (String roomId, String userId, RCRTCMediaType type) {
engine.subscribe(userId, type);
}
To unsubscribe, use unsubscribe
(see Unsubscribing).
Temporarily Pausing Co-Streaming
To pause co-streaming without ending it, leave the secondary room via leaveSubRoom
with disband=false
. This triggers onSubRoomLeft
locally and onUserLeft
for others, who may then unsubscribe.
// Callback for leaving
engine.onSubRoomLeft = (roomId, code, message) {
if (code == 0) {
// Successfully left
} else {
// Failed to leave
}
}
// Pause co-streaming
engine.leaveSubRoom(roomId, false);
The server automatically removes paused streams from the mix. To resume, rejoin the secondary room without re-invitation.
Ending Co-Streaming
To fully end co-streaming, call leaveSubRoom
with disband=true
. This unsubscribes from all streams and triggers onSubRoomLeft
locally and onSubRoomDisband
for others.
// Callbacks
Function(String roomId, int code, String? errMsg)? onSubRoomLeft;
Function(String roomId, String userId)? onSubRoomDisband;
Server-Initiated Room Removal
Use server APIs to remove users from specific rooms.
-
Before removal, notify the client via IM to properly end co-streaming.
-
If removed from the primary room, receive
onKicked
. The SDK automatically leaves all rooms and cleans up resources. -
If removed from a secondary room, receive
onKicked
and automatically leave that room while unsubscribing.// Callback for server-initiated removal
Function(String? roomId, String? errMsg)? onKicked;