Repository navigation
feat(publish)!: muted and invisible keep capture open - #7157
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: e473a67
No actionable bugs found. Separating the capture-lifetime gate from encoder mute/hide is a straightforward way to avoid device and AudioContext reopen costs. Clearing the source and disconnecting still reach the source cleanup paths, while the announce gate excludes disabled tracks and the video preview is explicitly hidden. The breaking permission/indicator behavior—including opening both devices when initially muted/hidden—is documented rather than silently preserving the old privacy semantics.
The identity/getUserMedia-count and detach/reattach tests target the important lifecycle guarantees. Static review of the changes and surrounding element, announce, capture, source, and audio-encoder code only; I did not run browser tests, measure resume latency, or verify behavior with real devices. Encoder failure recovery remains a separate concern, as noted in the PR.
WalkthroughThe publish element now keeps selected capture sources enabled while connected, even when muted or invisible. Those controls still gate audio and video encoding. Clearing the source or disconnecting the element releases capture devices. Announcement and preview behavior, documentation, and browser tests were updated to reflect these changes. Priority: Merge Risk:
|
|
Merge summary:
(Written by Claude Opus 5.5) |
|
Merge summary (re-land after
(Written by Claude Opus 5.5) |
|
Follow-up: (Written by Claude Opus 5.5) |
|
Re-landing after the merge queue dropped this PR on (Written by Claude Opus 5.5) |
|
Re-landing after the old merge queue dropped this PR on
(Written by Claude Opus 5.5) |
* chore(quest): claim quest/m1/push-to-talk/mute.md Quest-Claim: e1709a982a08d378 * feat(publish)!: muted and invisible keep capture open `<moq-publish muted>` and `invisible` now disable only the audio or video encoder. The camera, microphone, screen, or file source and the audio capture follow the element's connection gate and `source`, so unmuting skips getUserMedia, AudioContext setup, and the worklet load, and unhiding skips a camera reopen. Clearing `source` or detaching the element still releases both devices. The announce gate counts a muted or hidden track as absent, so a camera that starts both muted and hidden still waits before announcing. A hidden camera also blanks the `<video>` preview and sizes the UI box as empty. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
96c29e9 to
2b61981
Compare
Resolve js/publish/src/ui/element.ts against #7157: keep sizing the box by the slotted content's rendered size, and keep main's rule that a hidden camera sizes it as empty. Drop the fixture's <video> workaround so the no-preview path is what the browser tests cover. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Implements
quest/m1/push-to-talk/mute.md, part of the push-to-talk epic for moq-dev/moq#7101. The epic issue is not closed here.Summary
<moq-publish muted>andinvisiblenow disable only the audio or video encoder (js/publish/src/element.ts).Source.Camera,Source.Microphone,Source.Screen,Source.FileandAudio.Capturefollow the element's lifecycle gate (#enabled) andsource.#eitherEnabledis gone. Unmuting skips getUserMedia, the new AudioContext and the worklet load, and unhiding skips the camera reopen.sourceor detaching the element still stops both tracks, and reattaching reopens them.doc/lib/js/publish.mdandjs/publish/README.md, themuted/invisibledoc comments, and aMIGRATE.mdentry. They say the browser's capture indicators stay lit, and that releasing only one device means building the pipeline with the library and togglingSource.MicrophoneorSource.Cameraenabled.test/interop/clients/js/publish-ui.browser.ts):live, that unmuting flips both catalog entries back with zero new getUserMedia calls, and that the announcement holds. The constraint-change reopen check is unchanged.sourceends both tracks, detaching ends them, and reattaching reopens them.<video>preview. Without one, the UI box shrinks to zero height once a camera is live, which pushes the control bar out of the viewport. The first test only passed on main because it clicked before getUserMedia resolved, and opening capture earlier lost that race.Choices made without asking
js/publish/src/announce.ts). Without this, a camera that starts both muted and hidden would announce an empty catalog, because its sources are now live. With it, camera behavior is the same as before. One screen case changes: a hidden screen share with no audio now retracts its announcement, where before it stayed announced with an empty catalog. Muting and hiding a screen share now keeps the share open, where before it stopped the share.<video>preview path now checks#videoEnabled, matching the<canvas>renderer, which already did. The UI sizes the box as empty while hidden, so the self-view goes dark like before, even though the camera is open.mutedandinvisible": a page that starts withmutednow gets a microphone permission prompt. It is noted inMIGRATE.md. The audio-quality mic client (source="camera" invisible) now also opens the fake camera without encoding it, so I updated its comment.Checks
bun testinjs/publish: 279 pass.sh/js/workspace.py checkon the changed paths (lint, types, format, build, docs): pass.publish-ui.browser.tsin local Chromium: 7 pass, 2 fail. The two failures are the version-list tests, which already fail on main (quest/m0/interop-green/stale-browser-tests.md).Suggested follow-ups
<video>/<canvas>.player--emptykeys off the capture source rather than a visible preview, so the box collapses to zero height and the controls leave the viewport. This affects main too.sourcerecovers it. Worth checking withquest/m1/push-to-talk/reenable.md.Video.Capturecould idle while no encoder or preview reads it.Review
quest review), gpt-6.1-sol, medium effort.maininto the branch).Public API: behavior change to
mutedandinvisible(capture stays open). Wire: none.🤖 Generated with Claude Code
(Written by Claude Opus 5.5)