Skip to content

fix: recover camera and microphone input toggles - #33

Draft
kixelated wants to merge 9 commits into
mainfrom
quest/m0/media-toggles
Draft

kixelated wants to merge 9 commits into
mainfrom
quest/m0/media-toggles

Conversation

@kixelated

@kixelated kixelated commented Nov 7, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Camera off/on can wait forever behind a browser codec probe or final black-frame flush. The controls also obscured pending or denied capture. The required Check subsequently failed because terminal styling in the relay startup record broke the browser runner's address parser.

Approach

Pin published moq-dev/moq#8179 head 1ceb7ac7624cf8f05e59f4d2cec97ef9e46a3b0b in the submodule and Nix input. Follow its current enabled-toggle API and maintainer decision: preserve the compatibility black frame while muted, cancel its wait on track closure/replacement, and release ordering before cosmetic flushing.

Show requested, pending, live, failed and unavailable capture state with a persistent accessible status. Retry uses enabled off/on, waiting for the source to clear its error after processing disabled. Cleanup, changed settings or newer enabled intent cancels that handshake. Device selection can cancel pending capture.

Keep the real controls-to-remote-decode browser regression in just check. Strip terminal styling only when parsing relay readiness, retain raw diagnostics, and test the actual ANSI-styled field format. Merge current Hang main, preserving favorites' unit-only DOM preload and native globals in the browser runner. Finish and remove the media-toggles quest.

Impact

No Hang public API or wire change. No new upstream retry API: the application uses the existing enabled signals.

Alternatives

Use unconditional cancellation, with no product timeout or automatic retry loop. Retain the existing capture recovery policy. Select the supported 2D viewer backend on this host, which lacks WebGL2.

Validation

At c54f9c08e7664d502b942ac19f5258ecf5e0ee18:

  • The ANSI-record regression fails before stripping terminal styling and passes afterward. The original required Check log contains that styled record from an already-listening relay.
  • Full pinned FORCE_COLOR=1 quest gate just check passes: 5 API tests, 8 app tests, and 2 browser tests with 52 assertions (~16.5 seconds for the browser file).
  • The browser test retains real relay connections, encoding, separate remote decoding and nonzero audio PCM: repeated camera/microphone toggles, held native support/probe/final-flush promises, pending capture cancellation, late stream cleanup, denial → Retry, device selection/loss, pending teardown, unavailable devices without a busy indicator, and current-microphone selection while pending. Recovery precedes release of superseded promises. The held-support reproduction failed before the upstream cancellation fix.
  • Focused handshake tests cover acknowledgement, cleanup, changed device/constraints, newer enabled intent and stale Retry actions. Actual camera and microphone refusal → Retry → remote decode passes against the revised source.
  • Pinned quest gate just build and git diff --check pass. Latest merged Hang base is 38ecca4b9688d525e96cb79ae2a805672b8581db.

The fixture uses Chromium fake devices, getUserMedia/native VideoEncoder promise interception and synthetic ended events. Physical hardware loss, real permission dialogs, other browsers and the spatial WebGL scene remain unmeasured.

Review

Previous counted review: Claude Code, Claude Opus 5.5, medium, round 3 reviewed 0207acc5ccacf5ffa2b8fcf553918d26f46933d2 with no findings. Earlier UI, accessibility, fixture cleanup/startup and import findings were fixed; the test-cost concern was answered with measured runs and documented Nix prerequisites.

Current head c54f9c08e7664d502b942ac19f5258ecf5e0ee18 is unreviewed. The fresh required cross-vendor review exited 2 before starting because the configured Claude CLI is logged out. No substitute, exemption or review bypass was used.

Waiting

  • Maintainer: restore the configured reviewer login: claude is not logged in to its default profile (CLAUDE_CONFIG_DIR is unset); run claude auth login. After claude auth login, take the PR with quest iterate 33, run nix develop --accept-flake-config --command quest review --new --base origin/main, resolve any findings and review the resulting committed head, then mark ready. This draft is a clean, pushed checkpoint; the prior review does not cover its new head.

Follow-ups

The broader capture-state redesign remains in moq-dev/moq#8145. Hardware and cross-browser runs would broaden coverage.

(Written by GPT-6.1 Sol with xhigh)

Quest-Claim: e7e78dda8827133a
kixelated and others added 2 commits November 7, 2026 10:24
Pin cancellation-safe MoQ, show capture progress and errors, and offer explicit retry after denied capture. Exercise actual Hang input controls through a separate relay-connected Chromium viewer in the check suite.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Use the upstream cancellation fix, distinguish requested and actual capture state, and provide explicit camera and microphone retry controls. Add a Chromium regression through a local relay and separate viewer to the CI check suite.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
@kixelated kixelated changed the title Recover audio and video after repeated input toggles fix: recover camera and microphone input toggles Nov 7, 2026
kixelated and others added 4 commits November 7, 2026 10:30
Inject held support and flush promises around actual native codecs, then verify a separate relay-connected viewer decodes fresh video before releasing the old promise. This reproduces the stuck effect on the previous encoder implementation.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Keep accessible capture status mounted, make the selected-device action follow requested state, and cover absent devices and pending menu cancellation. Bind the browser fixture relay ephemerally and await its listening event while draining one log stream.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Keep the persistent capture live region as the sole camera availability announcement, while retaining the visible no-camera hint.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
@kixelated
kixelated marked this pull request as ready for review November 7, 2026 18:45
@coderabbitai

coderabbitai Bot commented Nov 7, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 27 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 257de45a-e375-4540-89dc-f2474cb069f5
Commits

Reviewing files that changed from the base of the PR and between c1c30fc and 0207acc.

Files ignored due to path filters: 2

  • bun.lock is excluded by !**/*.lock
  • flake.lock is excluded by !**/*.lock
Files selected for processing: 11

  • app/package.json
  • app/src/controls.tsx
  • app/test/media.browser.ts
  • app/test/media.html
  • app/test/media.tsx
  • app/test/tsconfig.json
  • flake.nix
  • justfile
  • moq
  • quest/m0/README.md
  • quest/m0/media-toggles.md
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

# Conflicts:
#	app/package.json
#	quest/m0/README.md

Copy link
Copy Markdown
Collaborator Author

Design change: follow the current API and cancellation decisions in moq-dev/moq#8179. Hang will pin published head 1ceb7ac7624cf8f05e59f4d2cec97ef9e46a3b0b in both places and implement its existing Retry button through enabled off/on, waiting for the source's cleared-error acknowledgement of the disabled phase. Cleanup, new enabled intent, or a changed device/constraints cancels that handshake. The genuine relay/remote-decoder and held-native-promise regressions remain. The required Check failure is an ANSI-styled relay readiness record; only parser input will be stripped, with a colored-record regression retained in CI. The standing delegation authorizes these recommended choices; no upstream queue changes are needed. A fresh local review will cover this revised approach.

(Written by GPT-6.1 Sol with xhigh)

Wait for the disabled capture acknowledgement before enabling Retry, cancel superseded handshakes, and parse terminal-styled relay startup records in CI.

Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
@kixelated
kixelated marked this pull request as draft November 7, 2026 22:52
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