feat(volume): Live-Volume-API + UI-Range setzt Lautstärke während Wiedergabe
This commit is contained in:
parent
8b0b7c75cd
commit
24de686a54
3 changed files with 45 additions and 2 deletions
|
|
@ -339,6 +339,30 @@ app.post('/api/play', async (req: Request, res: Response) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Lautstärke zur Laufzeit ändern (0..1). Wirken sofort auf aktuelle Resource, sonst als Default für nächste Wiedergabe.
|
||||||
|
app.post('/api/volume', (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
const { guildId, volume } = req.body as { guildId?: string; volume?: number };
|
||||||
|
if (!guildId || typeof volume !== 'number' || !Number.isFinite(volume)) {
|
||||||
|
return res.status(400).json({ error: 'guildId und volume (0..1) erforderlich' });
|
||||||
|
}
|
||||||
|
const safeVolume = Math.max(0, Math.min(1, volume));
|
||||||
|
const state = guildAudioState.get(guildId);
|
||||||
|
if (!state) {
|
||||||
|
return res.status(404).json({ error: 'Kein Voice-State für diese Guild' });
|
||||||
|
}
|
||||||
|
state.currentVolume = safeVolume;
|
||||||
|
if (state.currentResource?.volume) {
|
||||||
|
state.currentResource.volume.setVolume(safeVolume);
|
||||||
|
console.log(`${new Date().toISOString()} | live setVolume(${safeVolume}) guild=${guildId}`);
|
||||||
|
}
|
||||||
|
return res.json({ ok: true, volume: safeVolume });
|
||||||
|
} catch (e: any) {
|
||||||
|
console.error('Volume-Fehler:', e);
|
||||||
|
return res.status(500).json({ error: e?.message ?? 'Unbekannter Fehler' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Static Frontend ausliefern (Vite build)
|
// Static Frontend ausliefern (Vite build)
|
||||||
const webDistPath = path.resolve(__dirname, '../../web/dist');
|
const webDistPath = path.resolve(__dirname, '../../web/dist');
|
||||||
if (fs.existsSync(webDistPath)) {
|
if (fs.existsSync(webDistPath)) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { fetchChannels, fetchSounds, playSound } from './api';
|
import { fetchChannels, fetchSounds, playSound, setVolumeLive } from './api';
|
||||||
import type { VoiceChannelInfo, Sound } from './types';
|
import type { VoiceChannelInfo, Sound } from './types';
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
|
|
@ -88,7 +88,14 @@ export default function App() {
|
||||||
max={1}
|
max={1}
|
||||||
step={0.01}
|
step={0.01}
|
||||||
value={volume}
|
value={volume}
|
||||||
onChange={(e) => setVolume(parseFloat(e.target.value))}
|
onChange={async (e) => {
|
||||||
|
const v = parseFloat(e.target.value);
|
||||||
|
setVolume(v);
|
||||||
|
if (selected) {
|
||||||
|
const [guildId] = selected.split(':');
|
||||||
|
try { await setVolumeLive(guildId, v); } catch {}
|
||||||
|
}
|
||||||
|
}}
|
||||||
aria-label="Lautstärke"
|
aria-label="Lautstärke"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,18 @@ export async function playSound(soundName: string, guildId: string, channelId: s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function setVolumeLive(guildId: string, volume: number): Promise<void> {
|
||||||
|
const res = await fetch(`${API_BASE}/volume`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ guildId, volume })
|
||||||
|
});
|
||||||
|
if (!res.ok) {
|
||||||
|
const data = await res.json().catch(() => ({}));
|
||||||
|
throw new Error(data?.error || 'Volume ändern fehlgeschlagen');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue