Replaces the per-scene HTML directories (landing/, loading/, game/,
desktop/, goodbye/, music-box/, music/) with a single Laravel app
serving every overlay over HTTP. Supervisord runs `php artisan serve`
on 127.0.0.1:1118 and the OBS scene JSON now references HTTP routes
instead of file:// URLs.
Highlights:
- public/css/hud.css consolidates the duplicated HUD chrome,
scanlines/vignette/flicker, terminal styling, and pulse keyframes
that were copy-pasted across all seven scenes.
- Blade partials own hud-strip, crt-overlays, obs-ws-scripts,
camera-frame, screen-frame; the seven scenes extend a shared
overlay layout.
- Artisan commands (`rig:setup`, `rig:telemetry`, `rig:loading`,
`rig:playlist`, `rig:cmd`) replace the shell scripts that wrote
per-rig JSON snapshots. TwitchHelix + HardwareSnapshot services
handle the work the bash + Python helpers used to.
- ObsWsClient + MusicCommandController kill the 250 ms cmd.js poll
in the music daemon: POST /cmd/{skip|prev|pause|resume} opens a
short-lived Pawl WS, authenticates, and broadcasts mpd:cmd.
- AudioController streams files from the configured music dirs so
CEF can load tracks under the HTTP origin (Chromium blocks
HTTP-origin pages from loading file:// media).
- DataController serves /data/playlist.js (with ETag mtime cache)
and /cover.jpg (no-store) so the existing overlays' window.__PLAYLIST
and cover.jpg cache-bust pattern keeps working.
scripts/obs-webapp.supervisord.conf is the supervisord unit; install
to /etc/supervisor.d/obs-webapp.conf.
scripts/rewrite-scene-urls.py is a one-shot tool that rewrites
basic/scenes/Default_Stream_HUD.json from file:// to HTTP URLs.
basic/scenes/Default_Stream_HUD.json.pre-webapp is the rollback
artifact (made with OBS closed; full pre-migration state).
The seven old scene directories, vendor/, and the bash scripts are
still on disk pending visual verification; the next commit will
prune them.
85 lines
2.9 KiB
PHP
85 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
|
|
class RigSetupCommand extends Command
|
|
{
|
|
protected $signature = 'rig:setup';
|
|
protected $description = 'Generate public/js/obs-config.js and OBS_WS_* env vars from plugin_config/obs-websocket/config.json';
|
|
|
|
public function handle(): int
|
|
{
|
|
$src = (string) config('rig.obs_ws_config_json');
|
|
if (!is_file($src)) {
|
|
$this->error(" ✗ {$src} not found.");
|
|
$this->line(' Open OBS once with obs-websocket loaded so it generates the config.');
|
|
return self::FAILURE;
|
|
}
|
|
$cfg = json_decode((string) file_get_contents($src), true);
|
|
if (!is_array($cfg)) {
|
|
$this->error(" ✗ {$src} did not parse as JSON.");
|
|
return self::FAILURE;
|
|
}
|
|
$port = (int) ($cfg['server_port'] ?? 4455);
|
|
$pass = (string) ($cfg['server_password'] ?? '');
|
|
$url = "ws://localhost:{$port}";
|
|
|
|
$out = (string) config('rig.obs_config_js');
|
|
@mkdir(dirname($out), 0775, true);
|
|
$js = <<<JS
|
|
// Auto-generated by `php artisan rig:setup`. Reflects the current contents of
|
|
// plugin_config/obs-websocket/config.json. Re-run if you rotate the password.
|
|
window.__OBSWS = {
|
|
url: {$this->jsString($url)},
|
|
password: {$this->jsString($pass)},
|
|
};
|
|
|
|
JS;
|
|
file_put_contents($out, $js);
|
|
$this->info(" ✓ wrote {$out}");
|
|
|
|
// Mirror into .env so MusicCommandController / ObsWsClient can authenticate.
|
|
$this->writeEnv('OBS_WS_URL', $url);
|
|
$this->writeEnv('OBS_WS_PASSWORD', $pass);
|
|
$this->info(' ✓ updated .env OBS_WS_URL / OBS_WS_PASSWORD');
|
|
|
|
$this->line('');
|
|
$this->line(" url = {$url}");
|
|
$this->line(' password = ' . ($pass === '' ? '(none)' : '(set, ' . strlen($pass) . ' chars)'));
|
|
$this->line('');
|
|
$this->line(' → if obs-webapp is running under supervisord, restart it so the new env takes effect:');
|
|
$this->line(' sudo supervisorctl restart obs-webapp');
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
private function jsString(string $s): string
|
|
{
|
|
return json_encode($s, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
|
}
|
|
|
|
private function writeEnv(string $key, string $value): void
|
|
{
|
|
$env = base_path('.env');
|
|
$raw = is_file($env) ? file_get_contents($env) : '';
|
|
$line = $key . '=' . $this->escapeEnvValue($value);
|
|
if (preg_match("/^{$key}=.*$/m", $raw)) {
|
|
$raw = preg_replace("/^{$key}=.*$/m", $line, $raw);
|
|
} else {
|
|
$raw = rtrim($raw, "\n") . "\n" . $line . "\n";
|
|
}
|
|
file_put_contents($env, $raw);
|
|
}
|
|
|
|
private function escapeEnvValue(string $v): string
|
|
{
|
|
if ($v === '') return '';
|
|
if (preg_match('/[\s"#=]/', $v)) {
|
|
return '"' . str_replace('"', '\"', $v) . '"';
|
|
}
|
|
return $v;
|
|
}
|
|
}
|