diff options
Diffstat (limited to 'packages/meshbay-client/src/main.js')
| -rw-r--r-- | packages/meshbay-client/src/main.js | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/packages/meshbay-client/src/main.js b/packages/meshbay-client/src/main.js index 4c8707c..a2a7a86 100644 --- a/packages/meshbay-client/src/main.js +++ b/packages/meshbay-client/src/main.js @@ -20,8 +20,8 @@ 'use strict'; -const { app, BrowserWindow, dialog, ipcMain, Menu, protocol, safeStorage, - shell, Tray } = +const { app, BrowserWindow, dialog, ipcMain, Menu, powerSaveBlocker, protocol, + safeStorage, shell, Tray } = require('electron'); const { execFile, spawn } = require('node:child_process'); const crypto = require('node:crypto'); @@ -2304,6 +2304,19 @@ function registerBridge() { return true; }); + // The screen may sleep while music plays; the machine may not, or the + // connection to the node goes with it. + let playbackBlocker = null; + handle('playback:keep-alive', async (_event, on) => { + if (on === true && playbackBlocker === null) { + playbackBlocker = powerSaveBlocker.start('prevent-app-suspension'); + } else if (on !== true && playbackBlocker !== null) { + powerSaveBlocker.stop(playbackBlocker); + playbackBlocker = null; + } + return true; + }); + handle('cast:status', async () => ({ active: castRelay.active, url: castRelay.url, @@ -2320,16 +2333,31 @@ function registerBridge() { handle('cast:devices', async () => castChromecast.devices()); - handle('cast:chromecast:connect', async (_e, { deviceId, mediaUrl, subtitle }) => { - return castChromecast.connect(deviceId, mediaUrl, - subtitle === undefined ? castRelay.subtitle : subtitle); + // A whole file for the receiver — a photo, a music track — in three steps, + // so that a large one never crosses in a single message. + handle('cast:file:begin', async (_e, f) => castRelay.beginFile(f || {})); + handle('cast:file:write', async (_e, data) => castRelay.writeFile(Buffer.from(data))); + handle('cast:file:end', async () => castRelay.endFile()); + + // The relay's file is loaded as what the relay says it is, anything else as + // the stream; the page does not get to say which. + const loadOf = (mediaUrl, subtitle) => ( + mediaUrl && mediaUrl === castRelay.fileUrl + ? { subtitle: null, file: { contentType: castRelay.fileType, meta: castRelay.fileMeta } } + : { subtitle: subtitle === undefined ? castRelay.subtitle : subtitle, file: null }); + + handle('cast:chromecast:connect', async (_e, { deviceId, mediaUrl, subtitle, startAt }) => { + const l = loadOf(mediaUrl, subtitle); + return castChromecast.connect(deviceId, mediaUrl, l.subtitle, l.file, l.file ? startAt : 0); }); - handle('cast:chromecast:reload', async (_e, { mediaUrl, subtitle }) => { - return castChromecast.reload(mediaUrl, - subtitle === undefined ? castRelay.subtitle : subtitle); + handle('cast:chromecast:reload', async (_e, { mediaUrl, subtitle, startAt }) => { + const l = loadOf(mediaUrl, subtitle); + return castChromecast.reload(mediaUrl, l.subtitle, l.file, l.file ? startAt : 0); }); + handle('cast:chromecast:seek', async (_e, seconds) => castChromecast.seek(seconds)); + // The player becomes a remote while casting: these drive the receiver. handle('cast:chromecast:pause', async () => castChromecast.pause()); handle('cast:chromecast:play', async () => castChromecast.play()); |