Compare commits

...

1 commit

Author SHA1 Message Date
Khyretos
401c7cc59d Mayor changes 2024-10-18 15:02:25 +02:00
7 changed files with 57 additions and 100 deletions

View file

@ -13,16 +13,16 @@ logger.setLevel(logging.INFO)
gevent.monkey.patch_all() gevent.monkey.patch_all()
# import gevent.queue # import gevent.queue
import configparser
import pyttsx3 import pyttsx3
import sys import sys
import os import os
import queue import queue
import sys
import sounddevice as sd import sounddevice as sd
import fasttext # import fasttext
from lingua import Language, LanguageDetectorBuilder
detector = LanguageDetectorBuilder.from_all_spoken_languages().build()
from deep_translator import ( from deep_translator import (
MyMemoryTranslator, MyMemoryTranslator,
@ -39,7 +39,6 @@ app = Flask(__name__)
if len(sys.argv) > 1: if len(sys.argv) > 1:
settingsPath = os.path.normpath(sys.argv[1]) settingsPath = os.path.normpath(sys.argv[1])
environment = sys.argv[2] environment = sys.argv[2]
q = queue.Queue() q = queue.Queue()
@ -53,31 +52,11 @@ def loadSettings():
# classes # classes
class LanguageDetection: class LanguageDetection:
def __init__(self):
if environment == "dev":
settings_folder = os.path.dirname(settingsPath)
src_folder = os.path.dirname(settings_folder)
main_folder = os.path.dirname(src_folder)
language_detection_model = os.path.join(
main_folder, "language_detection_model", f"lid.176.bin"
)
else:
resources_folder = os.path.dirname(settingsPath)
language_detection_model = os.path.join(
resources_folder, "language_detection_model", f"lid.176.bin"
)
language_detection_model = rf"{language_detection_model}"
self.model = fasttext.load_model(language_detection_model)
def predict_lang(self, text): def predict_lang(self, text):
predictions = self.model.predict(text, k=3) # returns top 2 matching languages language = detector.compute_language_confidence_values(text)
language_codes = [] top_languages = [confidence.language.iso_code_639_1.name.lower() for confidence in language[:5]]
for prediction in predictions[0]: # result = ','.join(top_languages)
language_codes.append(prediction.replace("__label__", "")) return top_languages
return language_codes
class STT: class STT:
samplerate = None samplerate = None
@ -146,9 +125,6 @@ if settings["STT"]["USE_STT"] and settings["STT"]["LANGUAGE"] != '':
class TTS: class TTS:
engine = None
rate = None
def __init__(self): def __init__(self):
self.engine = pyttsx3.init() self.engine = pyttsx3.init()
@ -212,7 +188,8 @@ def terminate_processes():
def shutdown_server(): def shutdown_server():
func = request.environ.get("sever shutdown") # func = request.environ.get("sever shutdown")
func = request.environ.get("werkzeug.server.shutdown")
if func is None: if func is None:
raise RuntimeError("Server is not running") raise RuntimeError("Server is not running")
func() func()
@ -229,28 +206,29 @@ def get_language():
request_data = request.json request_data = request.json
message = request_data.get("message", "") message = request_data.get("message", "")
lang = LanguageDetection().predict_lang(message) lang = LanguageDetection().predict_lang(message)
except Exception as e:
return jsonify({"error": "An error occurred"}), 500
return jsonify({"languages": lang}), 200 return jsonify({"languages": lang}), 200
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.route("/translate", methods=["POST"]) @app.route("/translate", methods=["POST"])
def get_translation(): def get_translation():
try:
loadSettings() loadSettings()
request_data = request.json request_data = request.json
message = request_data.get("message", "") message = request_data.get("message", "")
detectedLanguage = request_data.get("language", "") detectedLanguage = request_data.get("language", "")
try:
# try:
translated = MyMemoryTranslator( translated = MyMemoryTranslator(
source=detectedLanguage, target=settings["LANGUAGE"]["TRANSLATE_TO"] source=detectedLanguage, target=settings["LANGUAGE"]["TRANSLATE_TO"]
).translate(message) ).translate(message)
# except Exception as e:
# return jsonify({"error": str(e), "code":429 }), 429
except Exception as e:
return jsonify({"error": str(e), "code":500 }), 500
return jsonify({"translation": translated}), 200 return jsonify({"translation": translated}), 200
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.route("/audio", methods=["POST"]) @app.route("/audio", methods=["POST"])
def trigger_backend_event(): def trigger_backend_event():
@ -266,7 +244,7 @@ def trigger_backend_event():
count = request_data.get("count") count = request_data.get("count")
text_to_speech_service.say(filteredMessage, voice, count) text_to_speech_service.say(filteredMessage, voice, count)
except Exception as e: except Exception as e:
return jsonify({"error": e}), 500 return jsonify({"error": str(e)}), 500
return jsonify({"message": "Audio triggered"}), 200 return jsonify({"message": "Audio triggered"}), 200
@ -276,16 +254,10 @@ def get_voices():
voices = text_to_speech_service.voices() voices = text_to_speech_service.voices()
return jsonify({"voices": voices}), 200 return jsonify({"voices": voices}), 200
except Exception as e: except Exception as e:
return jsonify({"error": e}), 500 return jsonify({"error": str(e)}), 500
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) > 1:
loadSettings() loadSettings()
port = int(settings["GENERAL"]["PORT"]) port = int(settings["GENERAL"]["PORT"]) if len(sys.argv) > 1 else 9000
else:
environment = "dev"
port = 9000
stream_recognition()
serve(app, host="0.0.0.0", port=port) serve(app, host="0.0.0.0", port=port)

View file

@ -45,6 +45,5 @@ After getting your credentials you can set it in <img src="https://raw.githubuse
* [Speech2Go](https://harposoftware.com/en/spanish-spain-/340-S2G-Jorge-Nuance-Voice.html). * [Speech2Go](https://harposoftware.com/en/spanish-spain-/340-S2G-Jorge-Nuance-Voice.html).
### Linux ### Linux
* WIP * WIP
### Mac ### Mac
* WIP * WIP

BIN
sounds/Internal_17.mp3 Normal file

Binary file not shown.

BIN
sounds/Internal_19.mp3 Normal file

Binary file not shown.

View file

@ -75,16 +75,14 @@ function setTranslatedUserMessage(message) {
function setTranslatedMessage(message) { function setTranslatedMessage(message) {
// this determines if it is a message that is send by a user // this determines if it is a message that is send by a user
const languageBox = document.getElementById(message.messageId).getElementsByClassName('language-icon flag-icon')[0]; const languageBox = document.getElementById(message.messageId).getElementsByClassName('language-icon flag-icon')[0];
// if (false) { // if (!languageBox) {
// twitch.sendMessage( // twitch.sendMessage(
// `[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${settings.TWITCH.USERNAME}: ${message.translation}` // `[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${settings.TWITCH.USERNAME}: ${message.translation}`
// ); // );
// return setTranslatedUserMessage(message); // return setTranslatedUserMessage(message);
// }
if (message.language.selectedLanguage.ISO639 !== message.language.detectedLanguage.ISO639) { if (message.language.selectedLanguage.ISO639 !== message.language.detectedLanguage.ISO639) {
const messageBox = document.getElementById(message.messageId).getElementsByClassName('msg-box')[0]; const messageBox = document.getElementById(message.messageId).getElementsByClassName('msg-box')[0];
languageBox.classList = `fi fi-${message.language.detectedLanguage.ISO3166} fis language-icon flag-icon`; languageBox.classList = `fi fi-${message.language.detectedLanguage.ISO3166} fis language-icon flag-icon`;
languageBox.setAttribute('tip', message.language.detectedLanguage.name); languageBox.setAttribute('tip', message.language.detectedLanguage.name);
@ -113,7 +111,6 @@ function setTranslatedMessage(message) {
lastMessage.scrollIntoView({ block: 'end', behavior: 'smooth' }); lastMessage.scrollIntoView({ block: 'end', behavior: 'smooth' });
} }
console.log(message);
if (settings.LANGUAGE.OUTPUT_TO_TTS) { if (settings.LANGUAGE.OUTPUT_TO_TTS) {
sound.playVoice({ sound.playVoice({
originalMessage: message.originalMessage, originalMessage: message.originalMessage,
@ -129,8 +126,6 @@ function setTranslatedMessage(message) {
async function getTranslatedMessage(message) { async function getTranslatedMessage(message) {
// TODO: translate primary language to // TODO: translate primary language to
console.log(message);
console.log(message.isPrimaryLanguage ? message.language.selectedLanguage.IETF : message.language.detectedLanguage.IETF);
const requestOptions = { const requestOptions = {
method: 'POST', // HTTP method method: 'POST', // HTTP method
headers: { headers: {
@ -146,8 +141,6 @@ async function getTranslatedMessage(message) {
const response = await fetch(`http://127.0.0.1:${settings.GENERAL.PORT}/translate`, requestOptions); const response = await fetch(`http://127.0.0.1:${settings.GENERAL.PORT}/translate`, requestOptions);
const responseData = await response.json(); const responseData = await response.json();
if (response.ok) { if (response.ok) {
console.log('Translated message:', responseData);
if (settings.LANGUAGE.BROADCAST_TRANSLATION) { if (settings.LANGUAGE.BROADCAST_TRANSLATION) {
twitch.sendMessage( twitch.sendMessage(
`[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${message.username}: ${responseData.translation}` `[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${message.username}: ${responseData.translation}`
@ -236,8 +229,6 @@ async function filterLanguage(message) {
const language = selectedPrimaryLanguageIndex < selectedSecondaryLanguageIndex ? selectedPrimaryLanguage : detectedLanguage; const language = selectedPrimaryLanguageIndex < selectedSecondaryLanguageIndex ? selectedPrimaryLanguage : detectedLanguage;
if (settings.LANGUAGE.TRANSLATE_TO !== 'none' && selectedPrimaryLanguage.ISO639 !== language.ISO639) { if (settings.LANGUAGE.TRANSLATE_TO !== 'none' && selectedPrimaryLanguage.ISO639 !== language.ISO639) {
// console.log('1');
console.log('hola');
getTranslatedMessage({ getTranslatedMessage({
message: message.message, message: message.message,
messageId: message.messageId, messageId: message.messageId,
@ -252,8 +243,6 @@ async function filterLanguage(message) {
logoUrl: message.logoUrl logoUrl: message.logoUrl
}); });
} else { } else {
console.log('adios');
// console.log('2');
setTranslatedMessage({ setTranslatedMessage({
originalMessage: message.message, originalMessage: message.message,
translation: message.message, translation: message.message,
@ -266,19 +255,6 @@ async function filterLanguage(message) {
username: message.username, username: message.username,
logoUrl: message.logoUrl logoUrl: message.logoUrl
}); });
// getTranslatedMessage({
// message: message.message,
// messageId: message.messageId,
// remainingDetectedLanguages: [],
// isPrimaryLanguage: true,
// language: {
// selectedLanguage: selectedSecondaryLanguage,
// detectedLanguage: selectedPrimaryLanguage
// },
// username: message.username,
// formattedMessage: message.formattedMessage,
// logoUrl: message.logoUrl
// });
} }
return language; return language;
@ -299,9 +275,8 @@ async function getDetectedLanguage(message) {
try { try {
const response = await fetch(`http://127.0.0.1:${settings.GENERAL.PORT}/detect`, requestOptions); const response = await fetch(`http://127.0.0.1:${settings.GENERAL.PORT}/detect`, requestOptions);
if (response.ok) {
const responseData = await response.json(); const responseData = await response.json();
if (response.ok) {
console.log('Detected Languages:', responseData); console.log('Detected Languages:', responseData);
return await filterLanguage({ return await filterLanguage({
languages: responseData.languages, languages: responseData.languages,
@ -311,7 +286,7 @@ async function getDetectedLanguage(message) {
formattedMessage: message.formattedMessage formattedMessage: message.formattedMessage
}); });
} else { } else {
console.error('Failed to send termination signal to Flask server.'); console.error('error in detect call', responseData);
} }
} catch (error) { } catch (error) {
console.error('Error sending termination signal:', error); console.error('Error sending termination signal:', error);
@ -321,11 +296,11 @@ async function getDetectedLanguage(message) {
async function getBackendServerStatus() { async function getBackendServerStatus() {
try { try {
const response = await fetch(`http://127.0.0.1:${settings.GENERAL.PORT}/status`, { method: 'GET' }); const response = await fetch(`http://127.0.0.1:${settings.GENERAL.PORT}/status`, { method: 'GET' });
if (response.ok) {
const responseData = await response.json(); const responseData = await response.json();
if (response.ok) {
console.log('Status:', responseData); console.log('Status:', responseData);
} else { } else {
console.error('Failed to send termination signal to Flask server.'); console.error('Error in satus call:', responseData);
} }
} catch (error) { } catch (error) {
console.error('Error sending termination signal:', error); console.error('Error sending termination signal:', error);
@ -364,12 +339,12 @@ async function getInternalTTSAudio(requestData) {
try { try {
const response = await fetch(`http://127.0.0.1:${settings.GENERAL.PORT}/audio`, requestOptions); const response = await fetch(`http://127.0.0.1:${settings.GENERAL.PORT}/audio`, requestOptions);
if (response.ok) {
const responseData = await response.json(); const responseData = await response.json();
if (response.ok) {
console.log('Audio:', responseData); console.log('Audio:', responseData);
return ttsRequestCount; return ttsRequestCount;
} else { } else {
console.error('Failed to send termination signal to Flask server.'); console.error('Error in audio call: ', responseData);
} }
} catch (error) { } catch (error) {
console.error('Error sending termination signal:', error); console.error('Error sending termination signal:', error);

View file

@ -6,6 +6,11 @@ let client = null;
let logoUrl = null; let logoUrl = null;
const twitchChannels = []; const twitchChannels = [];
function isTranslatedMessage(inputString) {
const regex = /\[.*>.*\]/; // Adjusted regex to ensure it matches the entire string
return regex.test(inputString);
}
function sendMessage(message) { function sendMessage(message) {
client.say(settings.TWITCH.CHANNEL_NAME, message).catch(console.error); client.say(settings.TWITCH.CHANNEL_NAME, message).catch(console.error);
} }
@ -31,6 +36,10 @@ if (settings.TWITCH.USERNAME && settings.TWITCH.OAUTH_TOKEN) {
if (self || tags['display-name'] === settings.TWITCH.USERNAME) { if (self || tags['display-name'] === settings.TWITCH.USERNAME) {
return; return;
} }
if (isTranslatedMessage(message)) {
return;
}
const emotes = tags.emotes || {}; const emotes = tags.emotes || {};
const emoteValues = Object.entries(emotes); const emoteValues = Object.entries(emotes);
let filteredMessage = message; let filteredMessage = message;
@ -46,8 +55,7 @@ if (settings.TWITCH.USERNAME && settings.TWITCH.OAUTH_TOKEN) {
}); });
const messageObject = parseString(emoteMessage); const messageObject = parseString(emoteMessage);
getProfileImage(tags['username'], tags['display-name'], messageObject, filteredMessage);
getProfileImage(tags['user-id'], tags['display-name'], messageObject, filteredMessage);
}); });
} }
@ -138,7 +146,8 @@ async function displayTwitchMessage(logoUrl, username, messageObject, filteredMe
showChatMessage(article); showChatMessage(article);
}); });
if (settings.LANGUAGE.USE_DETECTION && filteredMessage.length > 20 && countWords(filteredMessage) > 4) { if (settings.LANGUAGE.USE_DETECTION) {
// && filteredMessage.length > 20 && countWords(filteredMessage) > 2
await backend.getDetectedLanguage({ message: filteredMessage, messageId, username, logoUrl, formattedMessage }).then(language => { await backend.getDetectedLanguage({ message: filteredMessage, messageId, username, logoUrl, formattedMessage }).then(language => {
const languageElement = document.createElement('span'); const languageElement = document.createElement('span');
languageElement.classList = `fi fi-${language.ISO3166} fis language-icon flag-icon`; languageElement.classList = `fi fi-${language.ISO3166} fis language-icon flag-icon`;
@ -155,25 +164,21 @@ async function displayTwitchMessage(logoUrl, username, messageObject, filteredMe
language: { selectedLanguage: null, detectedLanguage: language } language: { selectedLanguage: null, detectedLanguage: language }
}); });
} }
// window.article = article;
}); });
} else { } else {
if (filteredMessage) { if (filteredMessage) {
sound.playVoice({ filteredMessage, logoUrl, username, formattedMessage }); sound.playVoice({ filteredMessage, logoUrl, username, formattedMessage });
} }
// window.article = article;
} }
sound.playNotificationSound(); sound.playNotificationSound();
} }
function getProfileImage(userid, username, message, filteredMessage) { function getProfileImage(username, displayname, message, filteredMessage) {
// Get user Logo with access token // Get user Logo with access token
options = { options = {
method: 'GET', method: 'GET',
url: `https://api.twitch.tv/helix/users?id=${userid}`, url: `https://api.twitch.tv/helix/users?username=${username}`,
headers: { 'Client-ID': settings.TWITCH.CLIENT_ID, Authorization: `Bearer ${settings.TWITCH.OAUTH_TOKEN}` } headers: { 'Client-ID': settings.TWITCH.CLIENT_ID, Authorization: `Bearer ${settings.TWITCH.OAUTH_TOKEN}` }
}; };
@ -181,7 +186,7 @@ function getProfileImage(userid, username, message, filteredMessage) {
.request(options) .request(options)
.then(responseLogoUrl => { .then(responseLogoUrl => {
logoUrl = responseLogoUrl.data.data[0].profile_image_url; logoUrl = responseLogoUrl.data.data[0].profile_image_url;
displayTwitchMessage(logoUrl, username, message, filteredMessage); displayTwitchMessage(logoUrl, displayname, message, filteredMessage);
}) })
.catch(error => { .catch(error => {
console.error(error); console.error(error);

6
xxx.py Normal file
View file

@ -0,0 +1,6 @@
from lingua import Language, LanguageDetectorBuilder
detector = LanguageDetectorBuilder.from_all_spoken_languages().build()
language = detector.compute_language_confidence_values("hello there juan")
top_languages = [confidence.language.iso_code_639_1.name.lower() for confidence in language]
print(top_languages)