Music daemon + cross-source sync via OBS WebSocket
Music persistence across scene switches by extracting playback into a
separate browser source (music/index.html) — single source instance
shared across scenes via OBS's "Add Existing", so it doesn't restart on
scene change.
Loading and Game overlays subscribe to mpd:state CustomEvents over OBS
WebSocket; the daemon broadcasts at 1 Hz plus on every track change.
File-based command pipeline lets bash control playback without a
WebSocket client of its own:
- vendor/obs-ws-mini.js — minimal WS v5 client with HMAC-SHA256 auth,
hard timeout, close-rejection, and a pure-JS SHA-256 fallback for
CEF file:// origins where crypto.subtle is unavailable.
- setup.sh — generates vendor/obs-config.js from the OBS plugin config;
checks the live socket instead of the (lagging) config file.
- music/index.html — invisible audio worker. Plays through a shuffled
queue with hardened error/stall recovery, polls loading/cmd.js for
bash-issued commands, broadcasts mpd:state via WS. Includes a
diagnostic status block (visible if the source's eye-icon is on).
- loading/index.html — strips local audio playback; subscribes to
mpd:state to drive the now-playing terminal line live. Removes the
redundant trailing prompt; terminal lines anchor at the bottom.
- loading/playlist.sh — rebuilt as subcommand API:
sync (default), skip, prev, pause, resume, status
control commands write loading/cmd.js (id, type, ts), which the
daemon polls every 250ms.
- loading/convert.sh — strips video tracks from .webm music downloads
to audio-only m4a (~95% smaller, ~20× faster decode); fixes the
CPU pegging from CEF decoding 1080p VP9 video for music playback.
- .gitignore — track manifests, ignore generated wrappers + secrets +
the audio cache.
This commit is contained in:
56
setup.sh
Executable file
56
setup.sh
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
# One-time setup: builds vendor/obs-config.js from your existing OBS WebSocket
|
||||
# plugin config so the overlay/daemon pages can connect.
|
||||
#
|
||||
# ./setup.sh
|
||||
#
|
||||
# Re-run if you change the WebSocket port or password in OBS.
|
||||
set -euo pipefail
|
||||
|
||||
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
SRC="$DIR/plugin_config/obs-websocket/config.json"
|
||||
OUT="$DIR/vendor/obs-config.js"
|
||||
|
||||
if [[ ! -f "$SRC" ]]; then
|
||||
echo " ✗ $SRC not found." >&2
|
||||
echo " Open OBS once with the obs-websocket plugin loaded so it generates the config." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Pull port + password out of the JSON
|
||||
read -r PORT PASS ENABLED <<<"$(python3 -c "
|
||||
import json, sys
|
||||
d = json.load(open('$SRC'))
|
||||
print(d.get('server_port', 4455), d.get('server_password', ''), str(d.get('server_enabled', False)).lower())
|
||||
")"
|
||||
|
||||
mkdir -p "$DIR/vendor"
|
||||
cat > "$OUT" <<JS
|
||||
// Auto-generated by setup.sh — gitignored. Reflects the current contents of
|
||||
// plugin_config/obs-websocket/config.json. Re-run setup.sh if it changes.
|
||||
window.__OBSWS = {
|
||||
url: 'ws://localhost:$PORT',
|
||||
password: '$PASS',
|
||||
};
|
||||
JS
|
||||
|
||||
echo " ✓ wrote $OUT"
|
||||
echo " url = ws://localhost:$PORT"
|
||||
if [[ -z "$PASS" ]]; then
|
||||
echo " password = (none)"
|
||||
else
|
||||
echo " password = (set, ${#PASS} chars)"
|
||||
fi
|
||||
|
||||
# Check the live socket, not the config file — OBS lags writes to plugin_config
|
||||
# until shutdown, so server_enabled in JSON often disagrees with reality.
|
||||
echo
|
||||
if ss -lnt 2>/dev/null | grep -q ":$PORT "; then
|
||||
echo " ✓ OBS WebSocket server is listening on :$PORT"
|
||||
elif nc -z localhost "$PORT" 2>/dev/null; then
|
||||
echo " ✓ OBS WebSocket server is listening on :$PORT"
|
||||
else
|
||||
echo " ⚠ Nothing listening on :$PORT yet."
|
||||
echo " In OBS: Tools → WebSocket Server Settings → ✅ Enable WebSocket server → OK"
|
||||
echo " (config.json may already say 'enabled: $ENABLED' — that file lags actual state)"
|
||||
fi
|
||||
Reference in New Issue
Block a user