feat: pod-wide Lyria background music (replaces test-audio drums)
The 'Test audio' button becomes 'Background Music': each pod gets a calm looping track from Gemini Lyria 3 that sings the pod name once up front then stays instrumental. Backend GET /api/pods/:id/music generates via the Gemini interactions endpoint and caches the MP3 per pod in Mongo (pod_music); the frontend fetches and loops it via Web Audio, published pod-wide on the existing podman-beat track. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import { loadPodGraph, reachFrom } from './graph/store.js';
|
||||
import { listPodActivity } from './activity/store.js';
|
||||
import { getMemberWorkHistory } from './activity/member-history.js';
|
||||
import { speakInRoom } from './voice/live.js';
|
||||
import { getPodMusic } from './voice/music.js';
|
||||
import { notifyHermesInterventionInRoom } from './action/hermes.js';
|
||||
import {
|
||||
activeLiveConversation,
|
||||
@@ -406,6 +407,21 @@ app.get('/api/internal/hermes/jobs/:jobId/events/stream', async (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
// Per-pod background music (Lyria), generated once and cached. Streams MP3 the
|
||||
// frontend loops as a pod-wide LiveKit track (replaces the synthesized beat).
|
||||
app.get('/api/pods/:id/music', async (req, res) => {
|
||||
try {
|
||||
const pod = await getPod(req.params.id);
|
||||
if (!pod) return res.status(404).json({ error: 'pod not found' });
|
||||
const mp3 = await getPodMusic(pod.id, pod.name);
|
||||
res.set('Content-Type', 'audio/mpeg');
|
||||
res.set('Cache-Control', 'public, max-age=86400');
|
||||
res.send(mp3);
|
||||
} catch (e) {
|
||||
res.status(500).json({ error: (e as Error).message });
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/pods/:id/hermes/notify', async (req, res) => {
|
||||
const podId = req.params.id;
|
||||
const pod = await getPod(podId);
|
||||
|
||||
Reference in New Issue
Block a user