Skip to content

Show your own screenshare track and offer tab audio in the picker - #224

Open
MinitorMHS wants to merge 2 commits into
cloudflare:mainfrom
MinitorMHS:screenshare-local-preview
Open

MinitorMHS wants to merge 2 commits into
cloudflare:mainfrom
MinitorMHS:screenshare-local-preview

Conversation

@MinitorMHS

Copy link
Copy Markdown

Two small screenshare fixes. They're unrelated in code but both affect the
screenshare path, so I'm putting them together to save a review round-trip —
happy to split if you prefer.

1. Your own screenshare tile renders empty

Problem

Cloudflare Calls doesn't loop a published track back to its sender, so
pulledVideoTrack is always undefined for the self participant. Participant
already special-cases self for the camera, but the screenshare case fell
through to the pulled track and rendered nothing.

Change

Extend the self special-case to cover screenshares, using the local capture
track:

const videoTrack =
  isSelf && !isScreenShare
    ? userMedia.videoStreamTrack
    : isSelf && isScreenShare
      ? userMedia.screenShareVideoTrack
      : pulledVideoTrack

screenShareVideoTrack is an useObservableAsValue of
screenshare.video.broadcastTrack$, mirroring the existing camera case.

2. No way to share tab audio

Problem

getScreenshare({ audio: false }) calls getDisplayMedia without an audio
constraint, so Chrome and Edge don't render the "Share tab audio" checkbox.

Change

Pass audio: true to getScreenshare.

Notes on E2EE and stream counts

Neither change adds a stream to the room or affects MLS.

  • The tile fix uses the same unencrypted local capture the camera path already
    uses for self — it's what you captured, not a decrypted remote stream.
  • The picker change only affects what the picker offers. The captured audio
    track isn't published — nothing subscribes to the screenshare audio
    broadcast track — so sender stream counts are unchanged.

Actually publishing screenshare audio would be a separate change: it adds an
MLStream per sender, and the MLS group has to be reconfigured when a sender's
stream count changes.

getScreenshare({ audio: false }) passes audio: undefined to
getDisplayMedia, so Chrome/Edge never render the "Share tab audio"
checkbox and tab/system audio cannot be shared at all.

Flip to audio: true so the constraint is actually requested. Picker UI
only: nothing subscribes to screenshare.audio.broadcastTrack$, so no
extra transceiver is created and the E2EE media path is untouched.
This is deliberately isolated from the earlier attempt (486be4e),
which coupled the same flag to pushing a second audio track through
PartyTracks.
For self + screenshare the tile read from pulledVideoTrack, but Cloudflare
Calls never loops a track back to its sender, so that is always
undefined and the tile renders empty. The other participants see the
screen; the sharer sees nothing.

Use the local capture track for the self screenshare tile, matching how
the self webcam tile already uses userMedia.videoStreamTrack. Rendering
only - no track is pushed, pulled, or re-encrypted, so the E2EE media
path is unchanged.
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.

1 participant