diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-10-05 02:29:27 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-10-05 02:29:27 +0200 |
| commit | ee9798fe3b88face2fa34f14874770f509c788a5 (patch) | |
| tree | f63e9506882863a885a907796eb977ec69137718 /packages/meshbay-client/src/preload.js | |
| parent | 243bcf017b4957237b3ddf556bd0a37296eb8798 (diff) | |
| download | meshbay-ee9798fe3b88face2fa34f14874770f509c788a5.tar.gz | |
feat(cast): music on the TV, the music bar as its remote
A cast button in Music's toolbar and in the music bar. With a television
chosen, each decrypted track goes to the relay with its cover — found as the
album card finds it — and plays there as music with its title, artist and
album; the bar's play, pause, seek, previous and next drive the receiver, its
clock is the receiver's, and the end of a track there moves the queue on.
A film or a photo taking the television pauses the bar; stopping the cast
carries the track on locally.
Photos and tracks now share one path: a whole file sent to the relay in
pieces (binary frames on Android, written to disk there), served at /file
with byte ranges and its cover at /cover, and loaded as what the relay says
it is. cast:image is gone; cast:chromecast:seek is new.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-client/src/preload.js')
| -rw-r--r-- | packages/meshbay-client/src/preload.js | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/packages/meshbay-client/src/preload.js b/packages/meshbay-client/src/preload.js index f12d68e..0de76db 100644 --- a/packages/meshbay-client/src/preload.js +++ b/packages/meshbay-client/src/preload.js @@ -178,7 +178,18 @@ contextBridge.exposeInMainWorld('meshbay', { push: (data) => ipcRenderer.invoke('cast:push', data), stop: () => ipcRenderer.invoke('cast:stop'), subtitle: (sub) => ipcRenderer.invoke('cast:subtitle', sub), - image: (img) => ipcRenderer.invoke('cast:image', img), + // A file in pieces of a few megabytes, as the Android bridge sends it. + file: async (f) => { + const bytes = f.bytes; + await ipcRenderer.invoke('cast:file:begin', { + type: f.type, size: bytes.length, cover: f.cover || null, + title: f.title, artist: f.artist, album: f.album, + }); + for (let at = 0; at < bytes.length; at += 4 * 1024 * 1024) { + await ipcRenderer.invoke('cast:file:write', bytes.subarray(at, at + 4 * 1024 * 1024)); + } + return ipcRenderer.invoke('cast:file:end'); + }, finish: () => ipcRenderer.invoke('cast:finish'), status: () => ipcRenderer.invoke('cast:status'), scan: () => ipcRenderer.invoke('cast:scan'), @@ -188,6 +199,7 @@ contextBridge.exposeInMainWorld('meshbay', { chromecastDisconnect: () => ipcRenderer.invoke('cast:chromecast:disconnect'), chromecastPause: () => ipcRenderer.invoke('cast:chromecast:pause'), chromecastPlay: () => ipcRenderer.invoke('cast:chromecast:play'), + chromecastSeek: (seconds) => ipcRenderer.invoke('cast:chromecast:seek', seconds), }, // A sink that writes to disk as chunks arrive, never a buffer handed over at |