phase: 03_audio_share
**Phase 03 final verification pass — complete, 100% green.** - Verified all 4 tasks done in `complete/03_audio_share/`; confirmed implementation in `watch.js` (one composed `MediaStream` per tile, staged-only `setMuted()` policy, `data-audio` state), `share.js` (precise `NotAllowedError` rethrow, 3 honest `#stat-audio` states, mid-share audio republish), conftest flags, and the new `tests/e2e/test_audio_share.py` (11 tests, all **passed** — none skipped). - **Criteria:** (1) viewer inbound audio `bytesReceived` strictly increases + composed stream 1 video/1 audio track while frames still decode — **passed**; (2) staged-only audio via keyboard `m`, mouse button, and `unstage()` re-mute — **passed**; (3) `shared`/`silent`/`not offered` + mid-share audio loss updates panel, roster and tiles — **passed**; (4) cancelled picker reports cancellation, single attempt — **passed**; (5) SECURITY.md §4 Audio, README platform notes, kiosk doc all describe shipped behaviour incl. Linux/PipeWire reality — **verified**; (6) full gate — **passed** (below). - **Gates:** `uv run ruff check . && uv run ruff format --check .` → clean; `uv run pyright` → 0 errors; `uv run pytest` → 245 passed, 4 skipped (only the `MIRROR_REALDISPLAY`-gated X11 tests); `MIRROR_REALDISPLAY=1 uv run pytest -m realdisplay` → 3 passed, 1 skipped (real-capture audio: documented skip naming the exact host/flag reason, per task 04). - **Docs:** README.md reviewed in full against code (env table, CLI flags, routes, kiosk key table, quickstart, audio notes) — consistent, no changes needed. AGENTS.md — all commands/paths/coverage claims verified accurate, no stale statements, no changes needed. - **Defect fixed (pre-existing):** `docs/kiosk-silverblue.md` + `install-kiosk.sh`, `kiosk.conf`, `gnome-kiosk-script` used `mirror.reeselink.com` while README/SECURITY.md use `mirror.reeseapps.com` (the deployment domain, consistent with the fleet); corrected 7 occurrences in 4 files. - No live-infrastructure changes; realdisplay suite ran on private Xvfb only. - **Next pending phase:** `04_reachable_share_cta`.
This commit is contained in:
+27
-4
@@ -107,10 +107,33 @@ the compositor protecting the user, and mirror must not try to work around it.
|
||||
|
||||
### Audio
|
||||
|
||||
Sharing tab/window audio is opt-in in the browser's own picker. mirror falls back
|
||||
to silent capture when the source has no audio rather than failing the share, and
|
||||
viewers start muted (autoplay policy) and must tap to unmute — a deliberate,
|
||||
user-initiated action.
|
||||
Audio is user-initiated by design: it never starts on its own, and a
|
||||
reconnect never revives it.
|
||||
|
||||
What audio exists is the browser's decision, not mirror's. The picker offers
|
||||
it (a "share audio" tickbox in Chrome, tab audio for tabs), and mirror
|
||||
accepts the track when the source has one — falling back to a *silent*
|
||||
capture, rather than failing the share, when it does not. A source that
|
||||
loses its audio mid-share is announced: the sharer's panel flips and every
|
||||
viewer's tile loses its button, instead of keeping a dead control.
|
||||
|
||||
On the wall, **only the staged mirror can be audible**. Every mirror starts
|
||||
muted, and the one deliberate gesture that unmutes — the tile's audio button
|
||||
or the `m` key — is always a click or a keypress. Unmuting one mirror mutes
|
||||
the others, and leaving the stage re-mutes the one you left.
|
||||
|
||||
What *system* audio a browser can capture is a platform fact, stated plainly:
|
||||
|
||||
* **Chrome on Linux** captures *tab* audio reliably, and whole-screen/
|
||||
system audio only where the platform offers it — PipeWire/PulseAudio's
|
||||
loopback, plus the picker's "share audio" tickbox.
|
||||
* **Firefox's desktop capture does not offer system audio at all on Linux.**
|
||||
A wall of Firefox tiles is silent by the browser's rule, not mirror's.
|
||||
|
||||
mirror neither works around that nor fakes it: when a source has no audio,
|
||||
the sharer's panel says `silent` (the browser honoured the request; the
|
||||
source has no track) or `not offered` (the capture only succeeded after the
|
||||
audio constraint was dropped), and the wall shows no button at all.
|
||||
|
||||
## 5. Operational guidance
|
||||
|
||||
|
||||
Reference in New Issue
Block a user