Feat : Skills
This commit is contained in:
54
open-sse/handlers/ttsProviders/googleTts.js
Normal file
54
open-sse/handlers/ttsProviders/googleTts.js
Normal file
@@ -0,0 +1,54 @@
|
||||
// Google Translate TTS (no auth) — scrape token + batchexecute RPC
|
||||
import { UA } from "./_base.js";
|
||||
|
||||
const REFRESH_MS = 11 * 60 * 1000;
|
||||
const cache = { token: null, tokenTime: 0 };
|
||||
let _idx = 0;
|
||||
|
||||
async function getToken() {
|
||||
const now = Date.now();
|
||||
if (cache.token && now - cache.tokenTime < REFRESH_MS) return cache.token;
|
||||
const res = await fetch("https://translate.google.com/", { headers: { "User-Agent": UA } });
|
||||
if (!res.ok) throw new Error(`Google translate fetch failed: ${res.status}`);
|
||||
const html = await res.text();
|
||||
const fSid = html.match(/"FdrFJe":"(.*?)"/)?.[1];
|
||||
const bl = html.match(/"cfb2h":"(.*?)"/)?.[1];
|
||||
if (!fSid || !bl) throw new Error("Failed to parse Google token");
|
||||
cache.token = { "f.sid": fSid, bl };
|
||||
cache.tokenTime = now;
|
||||
return cache.token;
|
||||
}
|
||||
|
||||
export default {
|
||||
noAuth: true,
|
||||
async synthesize(text, model) {
|
||||
const lang = model || "en";
|
||||
const token = await getToken();
|
||||
const cleanText = text.replace(/[@^*()\\/\-_+=><"'\u201c\u201d\u3010\u3011]/g, " ").replaceAll(", ", ". ");
|
||||
const rpcId = "jQ1olc";
|
||||
const reqId = (++_idx * 100000) + Math.floor(1000 + Math.random() * 9000);
|
||||
const query = new URLSearchParams({
|
||||
rpcids: rpcId,
|
||||
"f.sid": token["f.sid"],
|
||||
bl: token.bl,
|
||||
hl: lang,
|
||||
"soc-app": 1, "soc-platform": 1, "soc-device": 1,
|
||||
_reqid: reqId,
|
||||
rt: "c",
|
||||
});
|
||||
const payload = [cleanText, lang, null, "undefined", [0]];
|
||||
const body = new URLSearchParams();
|
||||
body.append("f.req", JSON.stringify([[[rpcId, JSON.stringify(payload), null, "generic"]]]));
|
||||
const res = await fetch(`https://translate.google.com/_/TranslateWebserverUi/data/batchexecute?${query}`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded", "Referer": "https://translate.google.com/" },
|
||||
body: body.toString(),
|
||||
});
|
||||
if (!res.ok) throw new Error(`Google TTS failed: ${res.status}`);
|
||||
const data = await res.text();
|
||||
const split = JSON.parse(data.split("\n")[3]);
|
||||
const base64 = JSON.parse(split[0][2])[0];
|
||||
if (!base64 || base64.length < 100) throw new Error("Google TTS returned empty audio");
|
||||
return { base64, format: "mp3" };
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user