Music Assistant TV Audio Recovery - wagnerks1990/RoomGoblin GitHub Wiki
Music Assistant TV Audio Recovery
RoomGoblin supports Music Assistant playback on classroom displays through managed Android Native Sendspin and a browser Sendspin compatibility path. A player can be connected and report playing while the TV is silent if Chromium blocks the browser Web Audio AudioContext.
September 2026 regression
Physical TV testing reproduced:
Sendspin: Connected to server
Sendspin: Stream started
The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page.
The September 9 selective dedicated-Sendspin migration retained the browser receiver but intentionally omitted the previous browser audio-unlock hook. That omission caused the regression after receiver reload/navigation.
Required fallback behavior
The maintained receiver now owns the unlock behavior directly in public/display/index.html:
- a current Sendspin player can be unlocked with
window.roomGoblinUnlockMusicAssistantAudio()for diagnostics; - real
pointerdown,touchstart, orkeydowngestures invokeSendspinPlayer.unlock()while audio is locked; - status reports
audioLocked/audioUnlockedrather than treating transport activity as proof of sound; - desired volume and mute are sent only after the Sendspin connection promise resolves, preventing startup
WebSocket not connectedstate-send errors; - reconnecting/replacing the browser player resets unlock state.
agents/android-tv/.../MainActivity.java must also retain setMediaPlaybackRequiresUserGesture(false) for ordinary media autoplay, but that WebView setting does not replace the Web Audio unlock fallback.
Unattended desktop kiosk browsers
RoomGoblin cannot synthesize a trusted browser gesture. If clicking or pressing a
key in the receiver immediately changes the log to AudioContext resumed,
audio unlocked, and ctx=running, the receiver hook is working and the
remaining unattended-start requirement belongs to the browser's managed policy.
For a dedicated Chrome or Edge kiosk profile, use administrator-managed autoplay
policy scoped to the RoomGoblin display origin where the browser supports an
allowlist. Chrome documents
AutoplayAllowed and AutoplayAllowlist for kiosk and unattended systems.
Edge exposes
the same named mandatory policies; on
Windows they are under SOFTWARE\Policies\Microsoft\Edge, with numbered
REG_SZ values beneath AutoplayAllowlist. Use a generic origin pattern such
as http://roomgoblin-host:3000 in documentation and substitute the actual
trusted local origin only during deployment.
On Linux Chrome, machine policy JSON
belongs under
/etc/opt/chrome/policies/managed/. A dedicated kiosk policy can use:
{
"AutoplayAllowed": true,
"AutoplayAllowlist": ["http://roomgoblin-host:3000"]
}
An explicitly managed kiosk launch may alternatively add
--autoplay-policy=no-user-gesture-required; enterprise policy is preferred
because it is visible and auditable. Do not add this flag to ordinary interactive
browsers. After a policy change, fully close and reopen every browser process,
confirm the values and OK status in chrome://policy or edge://policy, and
test a fresh page load without touching the receiver. Keep one unique display ID
per active host.
Policy permits unattended audio; it does not prove speaker output, volume, route,
or Music Assistant transport health. If the context still reports suspended,
the policy did not apply to that executable/profile/origin. Do not add synthetic
clicks, reconnect loops, or repeated page reloads as a workaround.
Preferred managed-TV architecture
Once physically validated for the target hardware, use Native Sendspin for managed Android/Google TV devices:
Music Assistant
-> :8927/sendspin
-> RoomGoblin AgentService
-> sendspin-jvm
-> Android AudioTrack
-> HDMI / TV audio
Native audio is intentionally independent of WebView reloads, kiosk recovery, page navigation, and Chromium autoplay policy. The browser path remains a supported fallback and must not be broken while it is still exposed.
Troubleshooting
- Stream starts + AudioContext warning + silence: browser audio is locked; use a real TV input gesture or validate/migrate Native Sendspin.
Cannot send message, WebSocket not connected: volume/mute was sent too early; recurrence is a regression.- Frequent disconnects or stuttering: investigate Wi-Fi/network stability, Music Assistant's Sendspin listener, and buffer diagnostics separately.
- Native player silent: inspect Agent Native Sendspin
connected,playing,bufferedChunks,droppedChunks,lateChunks,droppedDecodeFrames, andlastError, then verify HDMI/device audio.
Regression protection
Keep test/music-assistant-browser-audio-unlock.test.js, the display browser regression suite, and Android agent validation passing. Also preserve Morning Announcements priority and Background Music pause/reconcile/resume behavior when changing any audio path.
Detailed engineering notes: docs/MUSIC-ASSISTANT-TV-AUDIO-RECOVERY.md and docs/AI-MUSIC-ASSISTANT-ROUTING.md.