Repository navigation
Wait for the first frame of a screen share in waitForDimensions - #2217
Merged
1egoman merged 3 commits intoNov 1, 2026
Merged
Conversation
Chrome reports the resolution a screen share asked for from getSettings() until the capture delivers its first frame: a 1536x664 tab captured with the 1920x1080 ideal reads as 1920x1080. publishTrack reads the dimensions right away, so depending on whether that frame has arrived the layers are announced at 1920x1080 and 960x540 while the encoder sends 1536x664 and 768x332. The server then picks the low layer for any view up to about 600px tall and the shared text arrives upscaled and blurry. Publishing a tab capture as soon as getDisplayMedia resolves, against a local LiveKit 1.13.7 with Chrome 156, the server stored 1920x1080 in 3 of 6 runs on main and in 0 of 6 with this change. Publishing takes about 40ms longer.
CSantosM
requested review from
1egoman,
lukasIO and
xianshijing-lk
as code owners
October 30, 2026 17:48
🦋 Changeset detectedLatest commit: e01ff3d The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Firefox already reports the delivered size from getSettings() as soon as getDisplayMedia resolves, so waiting there only adds publish latency.
1egoman
force-pushed
the
fix/screen-share-first-frame-dimensions
branch
from
November 1, 2026 20:36
5cd2272 to
f5c5bec
Compare
Contributor
|
@CSantosM Thanks for the contribution! I've tested this locally and I think it makes sense! One small change I have made - per your report, this happens on chrome, and testing locally I can't reproduce the same behavior in safari or firefox. Because of this, I've gated your additional check with |
1egoman
approved these changes
Nov 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Chrome reports the resolution a screen share asked for from
getSettings()until the capture delivers its first frame. A 1536x664 tab captured with the 1920x1080 ideal thatScreenShareCaptureOptions.resolutionsets reads as 1920x1080 right aftergetDisplayMediaresolves, and as 1536x664 once a frame has arrived.publishTrackreads the dimensions throughwaitForDimensions, which returns as soon asgetSettings()has a width and a height. Depending on whether the first frame has arrived, the layers are announced at 1920x1080 and 960x540 while the encoder sends 1536x664 and 768x332. The server picks layers by the announced heights, so any view up to about 600px tall gets the low layer, which is really 332px tall, and the shared text arrives upscaled and blurry.Change
waitForDimensionswaits for the first frame of aScreenSharetrack before reading its dimensions, the same wait #2100 and #2110 added for iOS and iPadOS cameras. The comment now covers both cases.Verified
Chrome 156 publishing a tab capture as soon as
getDisplayMediaresolves, against a local LiveKit 1.13.7. The table shows the sizes the server stored, asRoomService.ListParticipantsreports them:mainvitest run src: 59 files, 1029 tests pass, 1 skipped. Two new tests inLocalVideoTrack.test.ts: a screen share reads its size after the first frame, and a camera does not wait. The first one fails without the change.tsc --noEmitpasses, andeslintandprettierreport nothing on the changed files.Not covered
When Chrome starts sharing a tab, it adds a "sharing this tab" bar that makes the tab about 56px shorter. If the first frame arrives before the bar, the layers are announced at 1536x720 and the frames shrink to 1536x664 right after. That happened in 2 of the 6 runs with this change. A resize or a surface switch later in the share leaves the announced layers stale in the same way. The client cannot re-announce layers after publishing, so both cases are for the server to cover with the sizes it parses from the media.