import {serve} from "https://deno.land/std/http/server.ts"; import {EdgeSpeechTTS} from "https://esm.sh/@lobehub/tts@1"; async function synthesizeSpeech(model: string, voice: string, text: string) { let voiceName; let rate = 0; let pitch = 0; if (!model.includes("Neural")) { switch (model) { case "ava": voiceName = "en-US-AvaMultilingualNeural"; break; case "andrew": voiceName = "en-US-AndrewMultilingualNeural"; break; case "emma": voiceName = "en-US-EmmaMultilingualNeural"; break; case "brian": voiceName = "en-US-BrianMultilingualNeural"; break; case "vivienne": voiceName = "fr-FR-VivienneMultilingualNeural"; break; case "remy": voiceName = "fr-FR-RemyMultilingualNeural"; break; case "seraphina": voiceName = "de-DE-SeraphinaMultilingualNeural"; break; case "florian": voiceName = "de-DE-FlorianMultilingualNeural"; break; case "dmitry": voiceName = "ru-RU-DmitryNeural"; break; case "svetlana": voiceName = "ru-RU-SvetlanaNeural"; break; default: voiceName = "en-US-BrianMultilingualNeural"; break; } } else { voiceName = model; const params = Object.fromEntries(voice.split("|").map((p) => p.split(":") as [string, string])); rate = Number(params["rate"] || 0); pitch = Number(params["pitch"] || 0); } const tts = new EdgeSpeechTTS(); const payload = { input: text, options: { rate: rate, pitch: pitch, voice: voiceName }, }; const response = await tts.create(payload); const mp3Buffer = new Uint8Array(await response.arrayBuffer()); return new Response(mp3Buffer, { headers: {"Content-Type": "audio/mpeg"}, }); } function validateContentType(req: Request, expected: string) { const contentType = req.headers.get("Content-Type"); if (contentType !== expected) { console.log(`Invalid Content-Type ${contentType}, expected ${expected}`); return new Response("Bad Request", {status: 400}); } } async function handleDebugRequest() { const voice = "rate:0.0|pitch:0.0"; const model = "en-US-BrianMultilingualNeural"; const text = "Приветик! Надеюсь ты меня хорошо слышишь? Алё?!"; console.log(`model=${model}, voice=${voice}, text=${text}`); return synthesizeSpeech(model, voice, text); } async function handleSynthesisRequest(req: Request) { if (req.method !== "POST") { return new Response("Method Not Allowed", {status: 405}); } const invalidContentType = validateContentType(req, "application/json"); if (invalidContentType) return invalidContentType; const {model, input, voice} = await req.json(); return synthesizeSpeech(model, voice, input); } async function handleDemoRequest(req: Request) { const html = `
получить список голосов:
post-запрос для синтеза голоса из текста: