feat(publish): Safari hardware encode, worker capture, and a stable video catalog#2190
Open
fperex wants to merge 2 commits into
Open
feat(publish): Safari hardware encode, worker capture, and a stable video catalog#2190fperex wants to merge 2 commits into
fperex wants to merge 2 commits into
Conversation
Reading WebTransport.datagrams.readable tears down the whole session on Safari, and moq-lite-05 always reads it once the negotiated version carries datagrams. There is no catchable failure, so a Safari client that wins the WebTransport race is simply dead. Route Safari onto the qmux WebSocket fallback the same way Firefox already is. The rule lives in a pure pickTransport(userAgent, hasWebTransport) with a user-agent matrix covering Safari, iOS Chrome (CriOS), iOS Firefox (FxiOS), Android WebViews and the legacy Android stock browser, so 'is this WebKit' is testable instead of an inline boolean. @moq/hang gets the twin detectSafari predicate (the support matrix cannot import net's internal pickTransport), and both packages share a user-agent corpus so a drift between them fails a test in each. hang had no test script, so its suite never ran; it does now. Both support matrices report webtransport: partial on Safari and Firefox to surface the degraded path. Safari consequently has no getStats() bandwidth estimate, same as Firefox.
…ideo catalog Publishing on Safari was software-only and the capture path stalled whenever the tab was hidden. - Hardware encode: on Apple Silicon, VideoToolbox only hardware-encodes H.264 and HEVC, but Safari reports the others as prefer-hardware supported anyway, so the support matrix keyed off an echoed hint that lies. Key off the codec instead, and prefer the codecs that actually have a hardware path. - Worker capture: WebKit 18+ exposes MediaStreamTrackProcessor in a worker (plus transferable MediaStreamTrack), so capture runs there. iOS Chrome and Firefox are WebKit too and omit the Safari Version/ token, so the gate reads the iOS OS version, which tracks the WebKit major. Everything older keeps the rAF fallback. - Camera and microphone re-acquire when their track ends, and a backgrounded Safari tab no longer comes back with the camera stuck muted. - The video catalog folds in the encoder-produced codec string and the hvcC/av1C description after the first keyframe, tagged against the requested codec and dimensions, so bandwidth-driven bitrate churn (which fires ~10x a second) can never flap the description. - The stats tab graphs a measured upload bitrate from encoded bytes rather than a transport estimate, which Safari does not have (no getStats).
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.
Split out of #2163.
Publishing on Safari was software-only, and the capture path stalled whenever the tab was hidden.
prefer-hardwaresupported, so the support matrix was keying off an echoed hint that lies (they actually run on software libvpx). Key off the codec instead, and prefer the codecs that genuinely have a hardware path.MediaStreamTrackProcessorin a worker (plus transferableMediaStreamTrack), so capture runs there instead of therequestAnimationFramefallback, which pauses whenever the tab is hidden. The gate reads the iOS OS version when the SafariVersion/token is absent, because iOS Chrome and Firefox are WebKit too and omit it, and the iOS major tracks the WebKit major. Anything older or undetectable keeps the rAF path.getStats()).Public API changes:
@moq/publishgainsVideo.Encoder.bytesEncoded;@moq/hanggainsUtil.Hacks.safariWorkerCapture(both additive).Test plan:
bun test js/publish/src/video js/hang/src/util: 22 tests (codec ordering, catalog description folding against bitrate churn, worker-capture UA gate).just js checkgreen. Verified on device: Safari publishes with hardware H.264 and keeps capturing in a background tab.