iOS meeting screen share: publish ReplayKit broadcast into the SFU room
Gap: on iOS, screen share only worked in native CallKit calls. In a scheduled / code-joined SFU meeting the webview called setScreenShareEnabled() -> getDisplayMedia(), which WKWebView does not implement, so it failed silently. Production meetings are real LiveKit rooms, so we can publish natively instead. Fix (native ReplayKit -> same LiveKit room as a dedicated screen participant): - server: /api/meetings/token accepts screen:true -> mints a distinct <peerId>-screen identity (LiveKit allows one connection per identity), so the native publisher doesn't collide with the webview's own connection. - native plugin: startMeetingScreenShare/stopMeetingScreenShare + connectScreenRoom (a screen-only LiveKit connection: mic off, no camera, no callConnected) that reuses the existing broadcast-extension publishing path. - webview: toggleScreen routes to the native method on iOS SFU meetings; the screenShareState listener now drives the SFU case too (and tears the screen connection down on the system "Stop Broadcast"); sfuAttach/sfuDetach map the '<peerId>-screen' participant's screen track onto the sharer's tile and suppress the phantom person tile + the sharer's own self-view. Web/server deploy now; the native method needs the next Codemagic build to test on device. Verified: db-smoke 22/22; Swift braces balanced. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+7
-1
@@ -1055,7 +1055,13 @@ route('POST', '/api/meetings/token', async (req, res) => {
|
||||
try { const peers = require('./presence').meetingRooms.get(rm); const pr = peers && peers.get(pid); if (pr && pr.uid && pr.uid !== u.id) ok = false; } catch (_) {}
|
||||
if (ok) identity = pid;
|
||||
}
|
||||
const metadata = JSON.stringify({ avatarUrl: u.avatar_url || '' });
|
||||
// Screen-share publisher (iOS): the WebView already holds the meeting connection under `identity`, and
|
||||
// LiveKit allows one connection per identity — so the native ReplayKit publisher joins the SAME room under
|
||||
// a DISTINCT `<identity>-screen` id. The client maps that suffix back onto the sharer's tile. WKWebView has
|
||||
// no getDisplayMedia, so this native second connection is the only way to screen-share in an SFU meeting.
|
||||
const screen = body.screen === true || body.screen === 1 || body.screen === '1';
|
||||
if (screen) identity = identity + '-screen';
|
||||
const metadata = JSON.stringify({ avatarUrl: u.avatar_url || '', screen });
|
||||
const token = livekitToken(identity, u.name || u.email, rm, metadata);
|
||||
json(res, 200, { token, url: LIVEKIT_URL, identity, name: u.name || u.email });
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user