From e45d79dc8130ababadfc3d72b77c40899aa8dc1d Mon Sep 17 00:00:00 2001 From: Hai Phan Date: Wed, 26 Jun 2024 11:18:43 +0700 Subject: [PATCH] #407 make OpenAI api endpoint url configurable --- custom-voices.html | 1 + js/custom-voices.js | 11 ++++------- js/tts-engines.js | 12 +++++++++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/custom-voices.html b/custom-voices.html index 1c7a670..8fefb5f 100644 --- a/custom-voices.html +++ b/custom-voices.html @@ -143,6 +143,7 @@

Enable Custom Voices

+
diff --git a/js/custom-voices.js b/js/custom-voices.js index a67db33..9dacc8d 100644 --- a/js/custom-voices.js +++ b/js/custom-voices.js @@ -19,6 +19,7 @@ $(function() { } if (items.openaiCreds) { $("#openai-api-key").val(obfuscate(items.openaiCreds.apiKey)) + $("#openai-url").val(items.openaiCreds.url || "") } if (items.azureCreds) { $("#azure-region").val(items.azureCreds.region) @@ -198,11 +199,12 @@ function testRiva(url) { async function openaiSave() { $(".status").hide() const apiKey = $("#openai-api-key").val().trim() + const url = $("#openai-url").val().trim() if (apiKey) { $("#openai-progress").show() try { - await testOpenai(apiKey) - await updateSettings({openaiCreds: {apiKey: apiKey}}) + await openaiTtsEngine.test(apiKey, url) + await updateSettings({openaiCreds: {apiKey, url}}) $("#openai-success").text("ChatGPT voices are enabled.").show() $("#openai-api-key").val(obfuscate(apiKey)) } @@ -219,11 +221,6 @@ async function openaiSave() { } } -async function testOpenai(apiKey) { - const res = await fetch("https://api.openai.com/v1/models", {headers: {"Authorization": "Bearer " + apiKey}}) - if (!res.ok) throw await res.json().then(x => x.error) -} - async function azureSave() { diff --git a/js/tts-engines.js b/js/tts-engines.js index cacfe4e..bdb2eec 100644 --- a/js/tts-engines.js +++ b/js/tts-engines.js @@ -1141,8 +1141,18 @@ function PhoneTtsEngine() { function OpenaiTtsEngine() { + const defaultApiUrl = "https://api.openai.com/v1" var audio, prefetchAudio var isSpeaking = false + this.test = async function(apiKey, url) { + const res = await fetch((url || defaultApiUrl) + "/models", { + headers: {"Authorization": "Bearer " + apiKey} + }) + if (!res.ok) { + const {error} = await res.json() + throw error + } + } this.speak = function(utterance, options, onEvent) { const urlPromise = Promise.resolve() .then(() => { @@ -1192,7 +1202,7 @@ function OpenaiTtsEngine() { const matches = voice.voiceName.match(/^ChatGPT .* \((\w+)\)$/) const voiceName = matches[1] const {openaiCreds} = await getSettings(["openaiCreds"]) - const res = await fetch("https://api.openai.com/v1/audio/speech", { + const res = await fetch((openaiCreds.url || defaultApiUrl) + "/audio/speech", { method: "POST", headers: { "Content-Type": "application/json",