62 lines
2.2 KiB
JavaScript
62 lines
2.2 KiB
JavaScript
import { NextResponse } from "next/server";
|
|
import { getProviderConnections } from "@/lib/localDb";
|
|
|
|
const langNames = new Intl.DisplayNames(["en"], { type: "language" });
|
|
|
|
/**
|
|
* GET /api/media-providers/tts/inworld/voices[?lang=en]
|
|
* Returns { languages, byLang } grouped by language code (same shape as edge-tts/elevenlabs)
|
|
*/
|
|
export async function GET(request) {
|
|
try {
|
|
const { searchParams } = new URL(request.url);
|
|
const langFilter = searchParams.get("lang");
|
|
|
|
const connections = await getProviderConnections({ provider: "inworld", isActive: true });
|
|
const apiKey = connections[0]?.apiKey;
|
|
if (!apiKey) return NextResponse.json({ error: "No Inworld connection found" }, { status: 400 });
|
|
|
|
const res = await fetch("https://api.inworld.ai/tts/v1/voices", {
|
|
headers: { "Authorization": `Basic ${apiKey}` },
|
|
});
|
|
if (!res.ok) {
|
|
const text = await res.text().catch(() => "");
|
|
return NextResponse.json({ error: `Inworld API ${res.status}: ${text || "Failed"}` }, { status: 502 });
|
|
}
|
|
const data = await res.json();
|
|
const voices = data.voices || [];
|
|
|
|
const byLang = {};
|
|
for (const v of voices) {
|
|
// Each voice has `languages: ["en", "es", ...]`
|
|
const langs = Array.isArray(v.languages) && v.languages.length ? v.languages : ["en"];
|
|
for (const code of langs) {
|
|
if (!byLang[code]) {
|
|
byLang[code] = {
|
|
code,
|
|
name: (() => { try { return langNames.of(code); } catch { return code; } })(),
|
|
voices: [],
|
|
};
|
|
}
|
|
if (!byLang[code].voices.find((x) => x.id === v.voiceId)) {
|
|
byLang[code].voices.push({
|
|
id: v.voiceId,
|
|
name: v.displayName || v.voiceId,
|
|
gender: v.gender || "",
|
|
lang: code,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
const languages = Object.values(byLang).sort((a, b) => a.name.localeCompare(b.name));
|
|
|
|
if (langFilter) {
|
|
return NextResponse.json({ voices: byLang[langFilter]?.voices || [] });
|
|
}
|
|
return NextResponse.json({ languages, byLang });
|
|
} catch (err) {
|
|
return NextResponse.json({ error: err.message || "Failed to fetch voices" }, { status: 502 });
|
|
}
|
|
}
|