From d4a92bb8df56009a7e5520dca0a3ed8f79e92d06 Mon Sep 17 00:00:00 2001 From: Heiner Lohaus Date: Tue, 9 Apr 2024 05:54:47 +0200 Subject: Add text to speech module --- g4f/gui/client/static/js/chat.v1.js | 102 +++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 14 deletions(-) (limited to 'g4f/gui/client/static/js/chat.v1.js') diff --git a/g4f/gui/client/static/js/chat.v1.js b/g4f/gui/client/static/js/chat.v1.js index 87a06aa6..0aa601e8 100644 --- a/g4f/gui/client/static/js/chat.v1.js +++ b/g4f/gui/client/static/js/chat.v1.js @@ -64,6 +64,7 @@ const highlight = (container) => { ); } +let stopped = false; const register_message_buttons = async () => { document.querySelectorAll(".message .fa-xmark").forEach(async (el) => { if (!("click" in el.dataset)) { @@ -90,6 +91,72 @@ const register_message_buttons = async () => { }) } }); + document.querySelectorAll(".message .fa-volume-high").forEach(async (el) => { + if (!("click" in el.dataset)) { + el.dataset.click = "true"; + el.addEventListener("click", async () => { + if ("active" in el.classList || window.doSpeech || stopped) { + stopped = true; + return; + } + el.classList.add("blink") + el.classList.add("active") + const message_el = el.parentElement.parentElement.parentElement; + const content_el = el.parentElement.parentElement; + let speechText = await get_message(window.conversation_id, message_el.dataset.index); + + speechText = speechText.replaceAll(/\[(.+)\]\(.+\)/gm, "($1)"); + speechText = speechText.replaceAll(/\(http.+\)/gm, ""); + speechText = speechText.replaceAll("`", "").replaceAll("#", "") + speechText = speechText.replaceAll( + /[\s\S]+/gm, + "" + ) + + const lines = speechText.trim().split(/\n|\.|;/); + let ended = true; + window.onSpeechResponse = (url) => { + if (url) { + var sound = document.createElement('audio'); + sound.controls = 'controls'; + sound.src = url; + sound.type = 'audio/wav'; + if (ended) { + sound.autoplay = true; + } + sound.onended = function() { + ended = true; + }; + sound.onplay = function() { + ended = false; + }; + var container = document.createElement('div'); + container.classList.add("audio"); + container.appendChild(sound); + content_el.appendChild(container); + } + if (lines.length < 1 || stopped) { + el.classList.remove("blink"); + el.classList.remove("active"); + return; + } + while (lines.length > 0) { + let line = lines.shift(); + var reg = new RegExp('^[0-9]$'); + if (line && !reg.test(line)) { + return handleGenerateSpeech(line); + } + } + if (!line) { + el.classList.remove("blink") + el.classList.remove("active") + } + } + let line = lines.shift(); + return handleGenerateSpeech(line); + }); + } + }); } const delete_conversations = async () => { @@ -145,7 +212,11 @@ const handle_ask = async () => { : '' } -
${count_words_and_tokens(message, get_selected_model())}
+
+ ${count_words_and_tokens(message, get_selected_model())} + + +
`; @@ -479,7 +550,11 @@ const load_conversation = async (conversation_id, scroll=true) => {
${provider}
${markdown_render(item.content)}
-
${count_words_and_tokens(item.content, next_provider?.model)}
+
+ ${count_words_and_tokens(item.content, next_provider?.model)} + + +
`; @@ -1149,10 +1224,12 @@ if (SpeechRecognition) { } let startValue; + let lastValue; let timeoutHandle; recognition.onstart = function() { microLabel.classList.add("recognition"); startValue = messageInput.value; + lastValue = ""; timeoutHandle = window.setTimeout(may_stop, 8000); }; recognition.onend = function() { @@ -1163,25 +1240,22 @@ if (SpeechRecognition) { return; } window.clearTimeout(timeoutHandle); - let notFinal = ""; - event.results.forEach((result) => { - const newText = result[0].transcript; - if (newText) { + let newText; + Array.from(event.results).forEach((result) => { + newText = result[0].transcript; + if (newText && newText != lastValue) { + messageInput.value = `${startValue ? startValue+"\n" : ""}${newText.trim()}`; if (result.isFinal) { - messageInput.value = `${startValue ? startValue+"\n" : ""}${newText.trim()}`; + lastValue = newText; startValue = messageInput.value; - notFinal = ""; messageInput.focus(); - } else { - notFinal += newText; - messageInput.value = `${startValue ? startValue+"\n" : ""}${notFinal.trim()}`; } messageInput.style.height = messageInput.scrollHeight + "px"; messageInput.scrollTop = messageInput.scrollHeight; } }); window.clearTimeout(timeoutHandle); - timeoutHandle = window.setTimeout(may_stop, notFinal ? 5000 : 8000); + timeoutHandle = window.setTimeout(may_stop, newText ? 8000 : 5000); }; microLabel.addEventListener("click", () => { @@ -1189,8 +1263,8 @@ if (SpeechRecognition) { window.clearTimeout(timeoutHandle); recognition.stop(); } else { - const lang = document.getElementById("recognition-language")?.value || navigator.language; - recognition.lang = lang; + const lang = document.getElementById("recognition-language")?.value; + recognition.lang = lang || navigator.language; recognition.start(); } }); -- cgit v1.2.3