Skip to content

Keep screen share alive across full reconnect#1008

Open
pblazej wants to merge 1 commit into
mainfrom
blaze/screenshare-reconnect
Open

Keep screen share alive across full reconnect#1008
pblazej wants to merge 1 commit into
mainfrom
blaze/screenshare-reconnect

Conversation

@pblazej
Copy link
Copy Markdown
Contributor

@pblazej pblazej commented May 14, 2026

Summary

  • republishAllTracks() routes every local track through unpublish(), which calls track.stop() and tears down the capturer. For iOS broadcast extension and ReplayKit screen capture this closes the IPC and the extension self-terminates — the track gets re-added to the new publisher but no frames flow.
  • Detach screen share publications from the old publisher peer connection without going through unpublish() so the capturer keeps running, then let _publish reattach it to the new publisher.
  • Camera/mic republish flow is unchanged.

Resolves #1004

Test plan

  • iOS: start a screen share via broadcast extension, force a network outage long enough to trigger a full reconnect, confirm frames resume without re-prompting the broadcast picker
  • iOS: same scenario with in-app screen share (no extension)
  • macOS: start screen share, trigger full reconnect, confirm frames resume
  • Regression: camera + mic still survive a full reconnect

🤖 Generated with Claude Code

`republishAllTracks()` routes every local track through `unpublish()`,
which calls `track.stop()` and tears down the capturer. For iOS broadcast
extension and ReplayKit screen capture this kills the IPC and the
extension self-terminates — the track gets re-added to the new publisher
but no frames flow.

Detach screen share publications from the old publisher peer connection
without going through `unpublish()` so the capturer keeps running, then
let `_publish` reattach it to the new publisher.

Resolves #1004

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@pblazej
Copy link
Copy Markdown
Contributor Author

pblazej commented May 14, 2026

WebRTC semantics check

Verified against the libwebrtc tree that reusing the same LKRTCMediaStreamTrack across the old (closed) and new publisher peer connection is sound:

  • PeerConnection::Close() does not end attached tracks. pc/peer_connection.cc:1906-1912 only iterates transceivers and calls StopInternal(), which routes through RtpSenderBase::Stop() (pc/rtp_sender.cc:562-580). Stop() detaches the track and unregisters the sender as an observer, but never mutates track state.
  • Track state is driven by the source, not by the PC. pc/video_track.cc:147-152 is the only set_state(kEnded) call site for video, and it fires only when the underlying MediaSourceInterface::SourceState becomes kEnded. Closing the PC doesn't end the source, so the track stays kLive.
  • The video source is independent of any PC. pc/video_track.cc:60-67 forwards sink registration to video_source_->internal()->AddOrUpdateSink(...). The source outlives the PC; frames keep flowing.
  • Reattaching is supported. AddTransceiver(track, ...) on the new PC creates a fresh RtpSenderBase that registers as a new observer on the still-live track and adds its sink to the same source. No API or invariant prohibits reusing a track across PCs — only per-sender state is reset.
  • Dropping old RtpSender refs is safe. After Stop() the sender is inert (stopped_ = true, media_channel_ = nullptr); destruction via the Swift refcount drop has nothing further to clean up.

Ordering caveat that this fix relies on: cleanUpRTC() awaits _state.transport?.close() before republishAllTracks() runs, so the old PC is fully closed (all old senders Stop()'d, detached from the track) before AddTransceiver registers a new sender on the new PC. No double-sink, no race.

Net effect for screen share: LKRTCVideoSource keeps producing frames into the same LKRTCVideoTrack; closing the old PC detached the old sender but left the track kLive; re-adding the track to the new PC registers a new sender that picks up the same source — frames resume.

@pblazej pblazej marked this pull request as ready for review May 14, 2026 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Screen sharing does not recover after reconnecting from a network outage during a meeting

1 participant