Commit graph

336 commits

Author SHA1 Message Date
9288555d8e
zebra-report: deploy UA-gated auto-rejoin (mobile waits for tap) 2026-06-04 11:53:18 -04:00
15eca2bc92
zebra-report: deploy AudioContext oscillator-prime for Firefox Android 2026-06-04 11:50:00 -04:00
9d6b27842d
zebra-report: deploy AudioContext listener audio path (Firefox Android autoplay fix) 2026-06-04 11:46:27 -04:00
10d705beb3
zebra-report: deploy silent wedge-recovery for stuck audio elements 2026-06-04 11:37:16 -04:00
aaf7402912
zebra-report: deploy state-based autoplay-block detection 2026-06-04 11:30:57 -04:00
b8fd50c37b
zebra-report: deploy tap-to-resume + kick-clears-auto-rejoin 2026-06-04 11:27:39 -04:00
e5bb1366fc
zebra-report: deploy mod-action serializer (two-kick fix) 2026-06-04 10:44:49 -04:00
382d72b687
zebra-report: deploy realtime telemetry 2026-06-04 10:38:14 -04:00
5fc18d2423
zebra-report: deploy self-listener-mode include-self fix 2026-06-04 10:33:32 -04:00
d9e8041a37
zebra-report: deploy self-listener mode
Speakers, cohosts, and hosts can flip their own row's stream toggle
to listen via the buffered HTTP Ogg/Opus broadcast tap instead of
WebRTC. Mic auto-mutes while in that mode; unmuting hops back to the
live mesh seamlessly. Survives cellular ICE churn that breaks the
WebRTC path.
2026-06-04 10:29:34 -04:00
f39f6a4ea9
zebra-report: deploy auto-rejoin restore
Hard refresh resumes the last space again — the one-tap friction
buyback didn't actually fix the Firefox Android listener-audio bug
it was supposed to fix.
2026-06-04 10:01:23 -04:00
0843aa1317
zebra-report: deploy DJ-unmute + video lip-sync fixes
- DJ self-monitor stream now plays audibly (was muted-start with no
  unmute path for non-listeners)
- Screen / camera / game receivers get the same playoutDelayHint as
  audio so the picture stays in sync with the voice
2026-06-04 09:52:33 -04:00
22ecc0b5ba
zebra-report: remove dead audioPath references — fixes leave button
Mirror of zebra-report 3bc3edf.
2026-06-03 23:01:14 -04:00
b0bb2a1be4
zebra-report: cache-busting meta on the HTML root
Mirror of zebra-report 7981e9e.
2026-06-03 22:44:14 -04:00
63ff3ba5ec
zebra-report: trace leave click + global JS error logging
Mirror of zebra-report 6d5a2d4.
2026-06-03 22:41:28 -04:00
ccab98bee6
zebra-report: auto-rejoin pre-fills only; mute+leave hidden idle
Mirror of zebra-report 12df78a.
2026-06-03 22:21:36 -04:00
0f70d62148
zebra-report: pre-bless audio-element pool on entry click
Mirror of zebra-report 44e05b2.
2026-06-03 22:12:59 -04:00
cef405c204
zebra-report: drop play button for listeners — autoplay WebRTC
Mirror of zebra-report 9eb5b82.
2026-06-03 22:04:10 -04:00
4891a90be0
zebra-report: revert auto-DJ for listeners, restore WebRTC playback
Mirror of zebra-report 901bab1.
2026-06-03 21:42:27 -04:00
2c5d2618d6
zebra-report: swap fresh <audio> in listener click — Firefox Android fix
Mirror of zebra-report 1de3f2c.
2026-06-03 21:26:39 -04:00
c81e7e00f2
zebra-report: deeper audio-element telemetry for listener path
Mirror of zebra-report c8fc119.
2026-06-03 21:22:49 -04:00
e9aa3412f2
zebra-report: clear DJ state on leave + re-prime audio every entry
Leave was tearing down WebRTC but leaving streamMode/streamAudio/
audioPath stale — re-entry as listener saw "already enrolled" and
never made a fresh /stream request. Now leave wipes all three maps,
removes the <audio> elements, and stops the retry loop. Plus the
primeAudio one-shot gate is gone so every entry click re-primes the
mobile audio session (it can be suspended across tab background).
2026-06-03 21:12:59 -04:00
013b5c775c
zebra-report: telemetry on listener audio path
Mirror of zebra-report f196714.
2026-06-03 21:04:31 -04:00
e8bb5aadbd
zebra-report: 4s auto-enrol retry loop covers post-join publish race
If the host's mic publish lands after the listener's initial DJ auto-
enrol attempt, the 404 from the SFU was permanent — no event re-
triggered enrol. 4s interval re-checks every speaker and starts streams
that are still missing. Stops on transition out of listener.
2026-06-03 21:02:29 -04:00
fb1fabc810
zebra-report: listener mute button doubles as audio-unlock gesture
Mirror of zebra-report 334ee82.
2026-06-03 20:57:18 -04:00
995a9b230e
zebra-report: prime audio on entry click — drop tap-to-resume
Replaces the regressive tap-anywhere-to-resume queue with
primeAudioOnGesture(): the entry-button click handler plays a 1-frame
silent WAV through a hidden <audio>, blessing the page for audio.
Auto-enrolled DJ streams then play() without further user gesture.
No more "tap anywhere" message; no more flip-flop on stalled.
2026-06-03 20:31:13 -04:00
31bb90293a
zebra-report: tap-resume reload + log retry result
Calls a.load() inside the gesture before a.play() so the retry isn't
no-op'ing on an aborted element. Adds 'click' to the listened events
since Firefox Android only grants gesture-activation on click in some
configs. Logs retry success/failure so we know what's happening.
2026-06-03 20:19:01 -04:00
393b81fb23
zebra-report: tap-anywhere-to-resume on mobile autoplay block
When mobile Firefox/Safari blocks audio.play() on auto-enrolled DJ
streams, queue the elements and retry on the first pointerdown/
touchstart anywhere on the page. WebRTC stays unmuted as fallback
so the listener isn't silent in the meantime.
2026-06-03 20:16:20 -04:00
e3363d9cf1
zebra-report: stream-toggle reliability fixes
Three coupled fixes to the DJ-stream toggle path:
  - await setSinkId() before setting .src so it doesn't race + abort
    the in-flight media load
  - drop the 'stalled' handler that was ping-ponging WebRTC ↔ stream
    on every transient mobile-cellular buffer pause
  - make startStream idempotent on the same URL so a peer-joined
    auto-enrollment race can't reset .src and self-abort

Plus preload="auto" and playsInline on the dynamic <audio> for
mobile compat. Fixes "no music on phone stream stalled" and the
"autoplay blocked: aborted at user's request" log spam from host
self-monitor clicks.
2026-06-03 20:06:45 -04:00
94b981da29
zebra-report: mute button + peer-force-muted handler
Mirror of zebra-report a3c49f1 + proxy.unturf.com 90a5e96.
2026-06-03 19:51:30 -04:00
d91e908eb3
zebra-report: stream toggle uses its own top-row grid column
Moves the ◉/○ DJ-stream button out of the bottom mod-actions stack
into the dedicated `strm` grid column on the top row (next to the
mic icon). No more extra sub-row per speaker for the self-monitor or
host-controlled stream toggle — fixes the vertical scroll regression
when many members were in the room.
2026-06-03 19:39:11 -04:00
29beeb71d7
zebra-report: mod-action buttons horizontal via inline-block
Mirror of zebra-report 55d5e52.
2026-06-03 19:36:17 -04:00
5163613d1e
zebra-report: defer WebRTC mute until DJ stream actually plays
Mirror of zebra-report ebcd257.
2026-06-03 19:30:58 -04:00
ed93bb8fca
zebra-report: lock listeners into DJ mode — no per-speaker opt-out
Mirror of zebra-report 9fd6b06.
2026-06-03 19:28:30 -04:00
6d827b29d2
zebra-report: default-on DJ mode for listeners + 4s RTC playout buffer
Mirror of zebra-report 0cbbc37.
2026-06-03 19:19:45 -04:00
5f9a67b8e7
zebra-report: stream-gating + layout + 2s playout + bfcache-safe bye
Mirror of zebra-report de5b530.
2026-06-03 19:11:36 -04:00
486243cda6
zebra-report: kick + ban onto a dedicated row in mod-actions
Mirror of zebra-report 148116a.
2026-06-03 18:58:18 -04:00
ab82577cdc
zebra-report: mod-actions wraps so stream toggle doesn't cause scroll
Swap grid-auto-flow:column to grid-template-columns:repeat(auto-fit,max-content)
so the now-5-button row wraps to a second line on narrow panels instead
of overflowing horizontally.
2026-06-03 18:48:11 -04:00
e14c92e037
zebra-report: stream toggle on own row — DJ self-monitor
DJ can preview the ~2s delayed Ogg/Opus stream of their own mic to
confirm what listeners hear. Closed headphones recommended; open
speakers + music mode = feedback (title attr warns).
2026-06-03 18:44:14 -04:00
9b55fd96ce
zebra-report: per-speaker "stream" toggle (DJ mode, Ogg/Opus over HTTP)
Each speaker row carries a stream toggle that swaps their audio from
WebRTC subscribe (~700ms latency, glitchy under loss) to a plain
HTTP <audio> pulling Ogg/Opus from the SFU's new /stream endpoint
(~2s latency, browser-managed jitter buffer, bulletproof for DJ
playback). Requires matching proxy.unturf.com SFU build.
2026-06-03 18:35:52 -04:00
147dbc0f9e
zebra-report: revert remaining new Chrome-path codec params
Choppy persisted after every other dial-back. The only remaining new
Chrome-publisher params were the fullband pin and the 320k bump. Drop
both. Chrome publisher's SDP now back to the pre-feature shape
(stereo + FEC + 256k, no maxplaybackrate / sprop-maxcapturerate / cbr).

Kept: Firefox SDP regex fix, UA-gated NACK, speaker picker.
2026-06-03 18:12:49 -04:00
fcbac50caf
zebra-report: 320k Opus + drop maxptime + fix Firefox SDP no-op
Choppy persisted after NACK rollback. Dial back to 320k (transparent
threshold, much less stress on uploads alongside screen+camera). Drop
a=maxptime:120 — receivers + 700ms playout buffer don't handle larger
frames well. Fix the SDP regex that silently no-op'd on Firefox
publishers (Firefox's Opus fmtp lacks minptime=10 — the matcher
required it). Firefox publishers will now actually carry the music
codec params.
2026-06-03 18:07:54 -04:00
959d2dc65c
zebra-report: UA-gated audio NACK — Chrome↔Chrome reactive, Firefox honest
RTCRtpSender.getCapabilities probe decides whether to advertise NACK
in our Opus offers. Chromium publishes it (responds to retransmits),
Firefox/Safari omit (can't respond). Receivers honor only what the
sender promised — mixed-browser rooms stay clean, same-browser rooms
get the full reactive recovery.
2026-06-03 18:02:31 -04:00
01bdd802f2
zebra-report: drop audio NACK — Firefox→Chrome listener choppy/skipping
Chrome listeners requested NACK retransmits that Firefox publishers
never replied to (Firefox never implemented the audio NACK responder).
Chrome's jitter buffer waited for recovery that never arrived, then
skipped. useinbandfec + 700ms playout buffer remain.
2026-06-03 17:58:19 -04:00
c2c2183012
zebra-report: music-mode polish — 510k Opus, fullband pins, NACK, speaker picker
Codec headroom + loss resilience without DSP filters:
  - Opus 256k → 510k (spec ceiling) on mic SFU + mesh + screen + game audio
  - Fullband pin: maxplaybackrate / sprop-maxcapturerate = 48000, cbr=0
  - Audio NACK feedback on Opus rtpmap (reactive packet recovery)
  - a=maxptime:120 advertises tolerance for larger peer frames

Playback chain:
  - New speaker-output selector (setSinkId) routes peer audio to a
    chosen sink (studio monitors / external DAC). Hidden on Safari.

Hard refresh required for the new speaker-picker row to appear.
2026-06-03 17:51:34 -04:00
bbe6b14438
zebra-report: JS-bound heartbeat — 15s alive ping while joined
Mirror of zebra-report 1dde43f + proxy.unturf.com edb1009. Closes
the 'backgrounded tab squats in room' gap that WS-level pings
can't catch (browsers auto-pong below JS).
2026-06-03 17:37:41 -04:00
a11826b072
zebra-report: kick + ban buttons; pagehide sends 'bye'
Mirror of zebra-report 740ed2b + proxy.unturf.com 0733d61.

 - moderation: split single 'boot' into 'kick' (rejoinable) and 'ban'
   (blocks pubkey). Server adds matching kick wire-type alongside
   renamed boot→ban.
 - tab-close lifecycle: pagehide handler fires a 'bye' so closing a
   tab triggers a strong-leave (peer-left + SFU evict immediately)
   instead of waiting 8s for the hiccup grace. Fix for the case
   where Will's phone-tab close left audio leaking until the host
   manually kicked him.
2026-06-03 16:57:03 -04:00
60e4548665
zebra-report: rebuild <video> on MSID supplant — autoplay grant resets
Mirror of zebra-report fb7228b. Will refreshed; the supplant ontrack
hit autoplay block on srcObject swap. Fresh <video> dodges the
mid-life play() rejection.
2026-06-03 16:08:08 -04:00
e09a1793b9
zebra-report: surface boot errors + watchFirstFrame keyframe diagnostic
Mirror of zebra-report 3ca9042 + proxy.unturf.com bc04362.

 - moderation: boot failures now log to the moderator's page instead
   of looking like the button did nothing (stale uuid case).
 - diagnostic: watchFirstFrame fires 'still black after 2500ms — no
   keyframe?' if a fresh SFU video tile never decodes a first frame.
 - proxy-side companion: longer keyframe-burst on subscriber attach
   so a dropped PLI no longer leaves the tile permanently black.
2026-06-03 15:51:39 -04:00
19922ee9fa
zebra-report: deploy — mesh PC exponential backoff + give-up cap 2026-06-03 15:15:49 -04:00