diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-18 11:05:47 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-18 11:05:47 +0200 |
| commit | 063c5f0750b775362e45e21a97e0dc2250c89f77 (patch) | |
| tree | 9db3276c691bc1d49621cb144587e3a0be68d281 /packages/meshbay-client | |
| parent | c03512aeab576a06f8d5026e5eb484897ec45f99 (diff) | |
| download | meshbay-063c5f0750b775362e45e21a97e0dc2250c89f77.tar.gz | |
fix(cast): keep the Chromecast progress log out of the terminal
The receiver reports its state on a timer, so `player status: PLAYING` repeats
for as long as a film runs and buries everything else in the terminal the app
was started from. The progress lines now go through Node's own `debuglog`,
which costs nothing when disabled — the message is never formatted — and is
restored with:
NODE_DEBUG=cast-chromecast npm start
The socket error stays on console.error. It fires when the connection to the
receiver dies and is the only trace of why a cast stopped; routing it through
the same switch would make the one failure worth seeing the one that
disappears.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UGY17EPph5LsLzePPXhUVc
Diffstat (limited to 'packages/meshbay-client')
| -rw-r--r-- | packages/meshbay-client/src/cast-chromecast.js | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/packages/meshbay-client/src/cast-chromecast.js b/packages/meshbay-client/src/cast-chromecast.js index 2dd210f..1355cdd 100644 --- a/packages/meshbay-client/src/cast-chromecast.js +++ b/packages/meshbay-client/src/cast-chromecast.js @@ -1,9 +1,27 @@ 'use strict'; +const util = require('node:util'); + const Bonjour = require('bonjour-service').Bonjour; const CastClient = require('castv2-client').Client; const DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver; +/** + * Progress logging, off unless asked for: + * + * NODE_DEBUG=cast-chromecast npm start + * + * The receiver reports its state on a timer, so `player status: PLAYING` + * repeats for as long as a film runs and buries everything else in the + * terminal. Node's own `debuglog` is used rather than a flag of our own: it + * costs nothing when disabled — the message is never even formatted — and it + * is the knob a Node developer already expects to reach for. + * + * Failures do not come through here. A connection that dies silently is a + * connection nobody can diagnose, so those stay on `console.error`. + */ +const debug = util.debuglog('cast-chromecast'); + const SCAN_DURATION_MS = 6000; // The one track the receiver is ever told about. A side-loaded track cannot @@ -78,7 +96,7 @@ class CastChromecast { this._bonjour = new Bonjour(); } - console.log('[cast-chromecast] scanning for devices...'); + debug('[cast-chromecast] scanning for devices...'); return new Promise((resolve) => { this._browser = this._bonjour.find({ type: 'googlecast' }, (service) => { @@ -90,7 +108,7 @@ class CastChromecast { if (host && id) { this._devices.set(id, { id, name, host, port }); - console.log(`[cast-chromecast] discovered: "${name}" at ${host}:${port}`); + debug(`[cast-chromecast] discovered: "${name}" at ${host}:${port}`); } }); @@ -100,7 +118,7 @@ class CastChromecast { this._browser = null; } const devices = Array.from(this._devices.values()); - console.log(`[cast-chromecast] scan complete: ${devices.length} device(s)`); + debug(`[cast-chromecast] scan complete: ${devices.length} device(s)`); resolve(devices); }, SCAN_DURATION_MS); }); @@ -112,13 +130,15 @@ class CastChromecast { await this.disconnect(); - console.log(`[cast-chromecast] connecting to "${device.name}" (${device.host}:${device.port})`); + debug(`[cast-chromecast] connecting to "${device.name}" (${device.host}:${device.port})`); const client = new CastClient(); await new Promise((resolve, reject) => { client.on('error', (err) => { - console.log(`[cast-chromecast] client error: ${err.message}`); + // Not `debug`: this fires when the socket to the receiver dies, and it + // is the only trace of why the cast stopped. + console.error(`[cast-chromecast] client error: ${err.message}`); this._cleanup(); }); client.connect(device.host, () => resolve()); @@ -138,10 +158,10 @@ class CastChromecast { this._player = player; player.on('status', (status) => { - console.log(`[cast-chromecast] player status: ${status.playerState}`); + debug(`[cast-chromecast] player status: ${status.playerState}`); }); - console.log(`[cast-chromecast] loading with ${subtitle?.url ? 'subtitles' : 'no subtitles'}`); + debug(`[cast-chromecast] loading with ${subtitle?.url ? 'subtitles' : 'no subtitles'}`); const status = await new Promise((resolve, reject) => { player.load(mediaFor(mediaUrl, subtitle), loadOptionsFor(subtitle), (err, s) => { @@ -150,13 +170,13 @@ class CastChromecast { }); }); - console.log(`[cast-chromecast] loaded on "${device.name}", state: ${status.playerState}`); + debug(`[cast-chromecast] loaded on "${device.name}", state: ${status.playerState}`); return { deviceName: device.name, playerState: status.playerState }; } async reload(mediaUrl, subtitle) { if (!this._player) throw new Error('Not connected'); - console.log(`[cast-chromecast] reloading stream on "${this._connectedDevice?.name}"` + debug(`[cast-chromecast] reloading stream on "${this._connectedDevice?.name}"` + ` with ${subtitle?.url ? 'subtitles' : 'no subtitles'}`); const status = await new Promise((resolve, reject) => { this._player.load(mediaFor(mediaUrl, subtitle), loadOptionsFor(subtitle), @@ -165,7 +185,7 @@ class CastChromecast { resolve(s); }); }); - console.log(`[cast-chromecast] reloaded, state: ${status.playerState}`); + debug(`[cast-chromecast] reloaded, state: ${status.playerState}`); return { playerState: status.playerState }; } |