Commit Graph

9 Commits

Author SHA1 Message Date
Jakub Zych
70a5f64871 Bridge: extend mpd:state with nextTitles[] for queue peek
Adds nextTitles (array of up to 3 display strings) plus mirrored single
nextTitle/nextArtist/nextTrackTitle/nextFile for the immediate next
track. Drives the Music Box overlays' 3-up "coming next" lines without
overlays needing to query MPD themselves.

Reads MPD status.nextsong, walks playlistinfo for the next 3 indices,
applies the existing _flatten_tag + display-string cascade. Fields are
None / [] at end of queue. Backwards-compatible: overlays that don't
read the new keys are unaffected.
2026-04-27 03:44:54 +02:00
Jakub Zych
3d23e24f1d station: bump submodule — clearer offline cues + Midgolem state fix
Picks up live-status improvements in the public rig-spec page so the
status JSON polled by the bot's going-live notifier is accurate.
2026-04-27 03:44:41 +02:00
Jakub Zych
fb5aaed9e7 Scripts, scenes, bridges, bots and more 2026-04-26 23:08:48 +02:00
Jakub Zych
a34cd5fab7 Twitch chat bot: !skip → MPD next-track via IRC
Self-hosted async Python bot, runs as systemd --user unit
(obs-twitch-bot.service, sibling to obs-mpd-bridge). Connects to Twitch IRC
over TLS as vault118, listens in #ophi118, advances MPD on !skip and posts
the new track back to chat. 5s cooldown swallows skip-spam silently.

Strips Unicode Tags-block codepoints (U+E0000–U+E007F) before matching the
command so Twitch's anti-duplicate suffix doesn't break every-other !skip
when the broadcaster fires the same command twice in a row.

Bot account is separate (vault118) to keep the broadcaster's display name
out of bot replies; .env holds access token + refresh token + client id
(refresh + client id stored for future token rotation, unused today).
2026-04-26 17:16:51 +02:00
Jakub Zych
7a5b1df7b6 OBS state snapshot: scene additions, dock geometry, landing tweaks
Captures the current OBS scene/window state after wiring Music Daemon,
Project Loading, and Game scenes through the UI. Untitled.json now
includes the new scenes and their browser sources.

Landing index.html: reverted to the simpler pre-doomguard version
(static signal bars, plain footer rig, no telemetry rotation, no
watermark animation), keeping the SIGNAL grid centering and the small
#rig opacity transition.

OBS rewrites these files on shutdown — expect future commits to show
similar dock-geometry diff noise.
2026-04-26 02:40:24 +02:00
Jakub Zych
3792d61fdb Game scene: HUD + camera frame + status bar with live OBS sync
Streaming overlay for the Game scene. Reads the manifest written by
loading.sh (game name, subtitle, mic state) and pulls live state from
OBS WebSocket on the same connection that delivers music updates.

- Top HUD: TRANSMISSION ID / SIGNAL bars / UTC clock — same vibe as
  Landing/Loading, sized smaller so it doesn't dominate the gameplay.
- Camera frame (top-right, 480×270 with cyan corner ticks): decorative
  drop-target. The actual OBS camera source layers ON TOP; a centered
  placeholder (camcorder SVG + 'PLACE CAMERA HERE' + frame coordinates
  '2008, 100 · 480×270') shows during setup and gets covered when the
  camera source is positioned. Configurable via URL params:
  ?camera=Webcam&scene=Game.
- Status bar (bottom): solid gradient + cyan top edge so it reads on
  any gameplay background. Two lines:
    LIVE · GAME · SUBTITLE
    elapsed timer · mic state · now-playing track
- Live camera-frame sync: queries GetSceneItemEnabled on connect and
  subscribes to SceneItemEnableStateChanged, so toggling the camera's
  eye-icon in OBS hides/shows the frame within ~50ms — overrides the
  manifest's static value.
- Music sync: shares the same WS connection; now-playing line updates
  from mpd:state broadcasts.
- CRT overlays kept lighter than Landing (gameplay must remain readable).
2026-04-26 02:40:24 +02:00
Jakub Zych
0a73f7e254 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.
2026-04-26 02:33:50 +02:00
Jakub Zych
704e126adc Landing: telemetry collector, doomguard watermark, SIGNAL centering
- telemetry.sh: bash collector for static device + OBS profile specs.
  Default mode wraps telemetry.json → telemetry.js (script-tag-loaded
  global, dodging file:// fetch CORS in CEF). --collect re-reads
  hardware + OBS basic.ini / streamEncoder.json.
- index.html: footer subtitle now rotates real CPU/MEM/GPU/OBS data
  with soft 400ms crossfade; SIGNAL group re-centered via 3-col grid;
  doomguard watermark behind everything with periodic "tune-in"
  spikes through the noise canvas.
- telemetry.json: hand-edited cosmetic version of collected specs.
- .gitignore: track telemetry.json (source), ignore telemetry.js
  (build artifact) and *.manual backups.
2026-04-26 00:47:59 +02:00
Jakub Zych
6decec66cc Initial commit: OBS scene collection, profile, landing overlay
Tracked: scene JSON (Untitled + pre-migration backups), landing/
overlay (HTML + static-hum.wav), profile encoder/basic settings,
rtmp-services metadata, modules list, ini files, CLAUDE.md.

Ignored via .gitignore: stream keys (**/service.json), obs-websocket
password (plugin_config/obs-websocket/), logs/, profiler_data/,
.sentinel/, OBS-managed *.bak and *.json.v1 sidecars.
2026-04-25 23:19:57 +02:00