feat: Voice-Auswahl aus ElevenLabs-Account in den TTS-Einstellungen
Dropdown mit den Account-Stimmen (GET /tts-settings/voices/available) plus Warnung, wenn die gespeicherte Voice-ID nicht im Account existiert — so fällt eine ungültige Stimme (Ursache der fehlenden sv-Audios) sofort auf statt still fehlzuschlagen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -66,6 +66,7 @@ function PipelineSettings() {
|
||||
|
||||
export default function Settings() {
|
||||
const [rows, setRows] = useState({}); // language → settings
|
||||
const [voices, setVoices] = useState(null); // null = lädt/nicht verfügbar
|
||||
const [saving, setSaving] = useState(null);
|
||||
const [msg, setMsg] = useState(null);
|
||||
const [error, setError] = useState(null);
|
||||
@@ -78,7 +79,10 @@ export default function Settings() {
|
||||
setRows(map);
|
||||
} catch (e) { setError(e.message); }
|
||||
}
|
||||
useEffect(() => { load(); }, []);
|
||||
useEffect(() => {
|
||||
load();
|
||||
apiFetch('/tts-settings/voices/available').then(setVoices).catch(() => setVoices(null));
|
||||
}, []);
|
||||
|
||||
function update(lang, patch) {
|
||||
setRows(r => ({ ...r, [lang]: { ...(r[lang] || { language: lang }), ...patch } }));
|
||||
@@ -132,8 +136,25 @@ export default function Settings() {
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||
<label className="text-sm">
|
||||
<span className="block text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1">Voice-ID</span>
|
||||
{voices?.length > 0 && (
|
||||
<select value={voices.some(v => v.voice_id === s.voice_id) ? s.voice_id : ''}
|
||||
onChange={e => e.target.value && update(lang.code, { voice_id: e.target.value })}
|
||||
className="w-full border border-slate-300 rounded-lg px-3 py-1.5 text-sm mb-1 focus:outline-none focus:ring-2 focus:ring-indigo-400">
|
||||
<option value="">— Stimme aus dem Account wählen —</option>
|
||||
{voices.map(v => (
|
||||
<option key={v.voice_id} value={v.voice_id}>
|
||||
{v.name}{v.labels?.accent ? ` (${v.labels.accent})` : ''}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
)}
|
||||
<input value={s.voice_id || ''} onChange={e => update(lang.code, { voice_id: e.target.value })}
|
||||
className="w-full border border-slate-300 rounded-lg px-3 py-1.5 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-indigo-400" />
|
||||
{voices?.length > 0 && s.voice_id && !voices.some(v => v.voice_id === s.voice_id) && (
|
||||
<span className="block text-xs text-red-500 mt-1">
|
||||
⚠ Diese Voice-ID existiert nicht im ElevenLabs-Account — Audio-Generierung schlägt fehl.
|
||||
</span>
|
||||
)}
|
||||
</label>
|
||||
<label className="text-sm">
|
||||
<span className="block text-xs font-semibold text-slate-500 uppercase tracking-wide mb-1">Geschwindigkeit</span>
|
||||
|
||||
Reference in New Issue
Block a user