From 0a73f7e254fa21ebf475cd434725539e9fd70df0 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Sun, 26 Apr 2026 02:30:39 +0200 Subject: [PATCH] Music daemon + cross-source sync via OBS WebSocket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .gitignore | 20 ++ loading/convert.sh | 80 +++++++ loading/index.html | 546 ++++++++++++++++++++++++++++++++++++++++++ loading/loading.sh | 119 +++++++++ loading/playlist.sh | 176 ++++++++++++++ music/index.html | 228 ++++++++++++++++++ setup.sh | 56 +++++ vendor/obs-ws-mini.js | 237 ++++++++++++++++++ 8 files changed, 1462 insertions(+) create mode 100755 loading/convert.sh create mode 100644 loading/index.html create mode 100755 loading/loading.sh create mode 100755 loading/playlist.sh create mode 100644 music/index.html create mode 100755 setup.sh create mode 100644 vendor/obs-ws-mini.js diff --git a/.gitignore b/.gitignore index a2954df..49308ac 100644 --- a/.gitignore +++ b/.gitignore @@ -28,8 +28,28 @@ plugin_config/obs-websocket/ # (The JSON itself is tracked: it's the hand-edited source for the wrapper.) landing/telemetry.js +# Per-session manifest written by loading.sh — ephemeral, not version-controlled. +loading/loading.json +loading/loading.js + +# Playlist manifest — generated from the audio in /playlist/, machine-local. +loading/playlist.json +loading/playlist.js + +# Music daemon command file — written by playlist.sh skip/prev/pause/resume. +loading/cmd.js + +# Audio files for the loading scene (any format). Kept out of git regardless +# of how they got there (yt-dlp, manual copy, etc.). +/playlist/ + +# OBS WebSocket connection details (port + password) — auto-generated by +# setup.sh from your existing plugin_config/obs-websocket/config.json. +vendor/obs-config.js + # Local backups created during edits — keep out of git noise. landing/*.manual +loading/*.manual # ============================================================ # OBS runtime / generated state — no value in version control diff --git a/loading/convert.sh b/loading/convert.sh new file mode 100755 index 0000000..ef5c2da --- /dev/null +++ b/loading/convert.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# loading/convert.sh — strip video tracks out of audio files in +# ~/.config/obs-studio/playlist/ and re-encode to AAC m4a in place. +# +# WHY: yt-dlp .webm downloads include 1080p video. Chromium's