language detection fixes and installer change.
This commit is contained in:
parent
5cfdd498c9
commit
d83c0ad753
28 changed files with 216 additions and 149 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -104,5 +104,7 @@ src/sounds/tts/*
|
||||||
loquendoBot_backend.spec
|
loquendoBot_backend.spec
|
||||||
forge.config.js
|
forge.config.js
|
||||||
backend/*
|
backend/*
|
||||||
src/backend/loquendoBot_backend.exe
|
!backend/loquendoBot_backend.py
|
||||||
|
backend/loquendoBot_backend.exe
|
||||||
src/config/twitch-emotes.json
|
src/config/twitch-emotes.json
|
||||||
|
dist/*
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ logger = logging.getLogger("waitress")
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
gevent.monkey.patch_all()
|
gevent.monkey.patch_all()
|
||||||
import gevent.queue
|
# import gevent.queue
|
||||||
|
|
||||||
import configparser
|
import configparser
|
||||||
import pyttsx3
|
import pyttsx3
|
||||||
|
|
@ -28,8 +28,6 @@ from deep_translator import (
|
||||||
MyMemoryTranslator,
|
MyMemoryTranslator,
|
||||||
)
|
)
|
||||||
|
|
||||||
import emoji
|
|
||||||
|
|
||||||
from vosk import Model, KaldiRecognizer, SetLogLevel
|
from vosk import Model, KaldiRecognizer, SetLogLevel
|
||||||
|
|
||||||
# global variables
|
# global variables
|
||||||
|
|
@ -68,7 +66,7 @@ class LanguageDetection:
|
||||||
self.model = fasttext.load_model(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=5) # returns top 2 matching languages
|
predictions = self.model.predict(text, k=3) # returns top 2 matching languages
|
||||||
language_codes = []
|
language_codes = []
|
||||||
for prediction in predictions[0]:
|
for prediction in predictions[0]:
|
||||||
language_codes.append(prediction.replace("__label__", ""))
|
language_codes.append(prediction.replace("__label__", ""))
|
||||||
|
|
@ -98,6 +96,7 @@ class STT:
|
||||||
vosk_model = os.path.join(
|
vosk_model = os.path.join(
|
||||||
resources_folder, "speech_to_text_models", settings["STT"]["LANGUAGE"]
|
resources_folder, "speech_to_text_models", settings["STT"]["LANGUAGE"]
|
||||||
)
|
)
|
||||||
|
print(vosk_model)
|
||||||
|
|
||||||
self.model = Model(rf"{vosk_model}")
|
self.model = Model(rf"{vosk_model}")
|
||||||
self.dump_fn = None
|
self.dump_fn = None
|
||||||
|
|
@ -137,8 +136,10 @@ class STT:
|
||||||
def stop_recognition(self):
|
def stop_recognition(self):
|
||||||
self.is_running = False
|
self.is_running = False
|
||||||
|
|
||||||
|
settings.read(settingsPath)
|
||||||
speech_recognition_service = STT()
|
print(settingsPath)
|
||||||
|
if settings["STT"]["USE_STT"] and bool(settings["STT"]["LANGUAGE"]):
|
||||||
|
speech_recognition_service = STT()
|
||||||
|
|
||||||
|
|
||||||
class TTS:
|
class TTS:
|
||||||
|
|
@ -156,16 +157,16 @@ class TTS:
|
||||||
break
|
break
|
||||||
self.engine.setProperty("voice", matching_id)
|
self.engine.setProperty("voice", matching_id)
|
||||||
|
|
||||||
|
settings_folder = os.path.dirname(settingsPath)
|
||||||
if environment == "dev":
|
if environment == "dev":
|
||||||
settings_folder = os.path.dirname(settingsPath)
|
|
||||||
src_folder = os.path.dirname(settings_folder)
|
src_folder = os.path.dirname(settings_folder)
|
||||||
|
bot_folder = os.path.dirname(src_folder)
|
||||||
saveLocation = os.path.join(
|
saveLocation = os.path.join(
|
||||||
src_folder, "sounds\\tts", f"Internal_{count}.mp3"
|
bot_folder, "sounds", f"Internal_{count}.mp3"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
resources_folder = os.path.dirname(settingsPath)
|
|
||||||
saveLocation = os.path.join(
|
saveLocation = os.path.join(
|
||||||
resources_folder, "sounds\\tts", f"Internal_{count}.mp3"
|
settings_folder, "sounds", f"Internal_{count}.mp3"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.engine.save_to_file(message, saveLocation)
|
self.engine.save_to_file(message, saveLocation)
|
||||||
|
|
@ -180,8 +181,9 @@ class TTS:
|
||||||
|
|
||||||
return [voice.name for voice in voices]
|
return [voice.name for voice in voices]
|
||||||
|
|
||||||
|
settings.read(settingsPath)
|
||||||
text_to_speech_service = TTS()
|
if settings["TTS"]["USE_TTS"]:
|
||||||
|
text_to_speech_service = TTS()
|
||||||
|
|
||||||
# endpoints
|
# endpoints
|
||||||
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
packagerConfig: {
|
|
||||||
icon: './src/images/icon.ico',
|
|
||||||
asar: true,
|
|
||||||
extraResource: ['./src/config/loquendo.db', './src/sounds', './backend', './language_detection_model', './speech_to_text_models'],
|
|
||||||
},
|
|
||||||
rebuildConfig: {},
|
|
||||||
makers: [
|
|
||||||
{
|
|
||||||
name: '@electron-forge/maker-squirrel',
|
|
||||||
config: {
|
|
||||||
setupIcon: './src/images/icon.ico',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '@electron-forge/maker-zip',
|
|
||||||
platforms: ['darwin'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '@electron-forge/maker-deb',
|
|
||||||
config: {
|
|
||||||
options: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '@electron-forge/maker-rpm',
|
|
||||||
config: {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
{
|
|
||||||
name: '@electron-forge/plugin-auto-unpack-natives',
|
|
||||||
config: {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2021 Khyretis
|
Copyright (c) 2021 Khyretos
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
32
package.json
32
package.json
|
|
@ -1,14 +1,37 @@
|
||||||
{
|
{
|
||||||
"name": "loquendo-bot",
|
"name": "loquendo-bot",
|
||||||
|
"productName": "LoquendoBot",
|
||||||
"version": "2.5.0",
|
"version": "2.5.0",
|
||||||
"description": "Bot assistant for streamers over different platforms",
|
"description": "Bot assistant for streamers over different platforms",
|
||||||
"main": "src/main.js",
|
"main": "src/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "electron-forge start",
|
"start": "electron-forge start",
|
||||||
"package": "npm run backend && electron-forge package",
|
"build": "npm run backend && electron-builder",
|
||||||
"make": "electron-forge make",
|
|
||||||
"publish": "electron-forge publish",
|
"publish": "electron-forge publish",
|
||||||
"backend": "pyinstaller --noconsole --onefile --collect-all vosk --distpath ./backend ./src/backend/loquendoBot_backend.py"
|
"backend": "pyinstaller --noconsole --onefile --collect-all vosk --distpath ./backend ./backend/loquendoBot_backend.py"
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"appId": "LoquendoBot",
|
||||||
|
"win": {
|
||||||
|
"target": [
|
||||||
|
"nsis"
|
||||||
|
],
|
||||||
|
"icon": "./src/images/icon.ico"
|
||||||
|
},
|
||||||
|
"nsis": {
|
||||||
|
"oneClick": false,
|
||||||
|
"installerIcon": "./src/images/icon.ico",
|
||||||
|
"uninstallerIcon": "./src/images/icon.ico",
|
||||||
|
"uninstallDisplayName": "LoquendoBot-uninstaller",
|
||||||
|
"license": "license.md",
|
||||||
|
"allowToChangeInstallationDirectory": "true"
|
||||||
|
},
|
||||||
|
"extraResources": [
|
||||||
|
"speech_to_text_models/Where to get STT models.txt",
|
||||||
|
"backend/loquendoBot_backend.exe",
|
||||||
|
"language_detection_model",
|
||||||
|
"sounds"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": {
|
"author": {
|
||||||
|
|
@ -18,7 +41,6 @@
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"electron-squirrel-startup": "^1.0.0",
|
|
||||||
"emoji-picker-element": "^1.21.0",
|
"emoji-picker-element": "^1.21.0",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"flag-icons": "^7.1.0",
|
"flag-icons": "^7.1.0",
|
||||||
|
|
@ -38,12 +60,12 @@
|
||||||
"@electron-forge/cli": "^6.2.1",
|
"@electron-forge/cli": "^6.2.1",
|
||||||
"@electron-forge/maker-deb": "^6.2.1",
|
"@electron-forge/maker-deb": "^6.2.1",
|
||||||
"@electron-forge/maker-rpm": "^6.2.1",
|
"@electron-forge/maker-rpm": "^6.2.1",
|
||||||
"@electron-forge/maker-squirrel": "^6.2.1",
|
|
||||||
"@electron-forge/maker-zip": "^6.2.1",
|
"@electron-forge/maker-zip": "^6.2.1",
|
||||||
"@electron-forge/plugin-auto-unpack-natives": "^6.2.1",
|
"@electron-forge/plugin-auto-unpack-natives": "^6.2.1",
|
||||||
"@electron-internal/eslint-config": "^1.0.1",
|
"@electron-internal/eslint-config": "^1.0.1",
|
||||||
"@electron-toolkit/eslint-config": "^1.0.2",
|
"@electron-toolkit/eslint-config": "^1.0.2",
|
||||||
"electron": "^25.9.8",
|
"electron": "^25.9.8",
|
||||||
|
"electron-builder": "^24.9.1",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-plugin-prettier": "^5.1.2",
|
"eslint-plugin-prettier": "^5.1.2",
|
||||||
|
|
|
||||||
|
|
@ -1 +1,3 @@
|
||||||
https://alphacephei.com/vosk/models
|
Download the model from here: https://alphacephei.com/vosk/models unzip it
|
||||||
|
and drop the folder in the 'speech_to_text_models' folder. Restart the app
|
||||||
|
to load the changes.
|
||||||
|
|
|
||||||
|
|
@ -36,25 +36,14 @@ html {
|
||||||
box-sizing: inherit;
|
box-sizing: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
html,
|
|
||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
/* border-top-left-radius: 20px; */
|
|
||||||
/* border-top-right-radius: 20px; */
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: 'Segoe UI', sans-serif;
|
font-family: 'Segoe UI', sans-serif;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
position: relative;
|
||||||
|
/* overflow-y: hidden;
|
||||||
/* Styling of window frame and titlebar */
|
overflow-x: hidden; */
|
||||||
|
|
||||||
body {
|
|
||||||
/* border: 1px solid #48545c; */
|
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#titlebar {
|
#titlebar {
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 29 KiB |
|
|
@ -212,6 +212,11 @@
|
||||||
<div class="AdvancedMenuRow inputTTS">
|
<div class="AdvancedMenuRow inputTTS">
|
||||||
<div class="AdvancedMenuLabel">2<sup>nd</sup> Internal Voice</div>
|
<div class="AdvancedMenuLabel">2<sup>nd</sup> Internal Voice</div>
|
||||||
<select class="menu-select" name="secondaryVoice" id="secondaryVoice"></select>
|
<select class="menu-select" name="secondaryVoice" id="secondaryVoice"></select>
|
||||||
|
<i
|
||||||
|
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
||||||
|
id="Info_SECONDARY_TTS"
|
||||||
|
tip="This will only work if Language detection is enabled and a language for this voice has been selected"
|
||||||
|
></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="AdvancedMenuRow inputTTS">
|
<div class="AdvancedMenuRow inputTTS">
|
||||||
<div class="AdvancedMenuLabel">Test 2<sup>nd</sup> Internal Voice</div>
|
<div class="AdvancedMenuLabel">Test 2<sup>nd</sup> Internal Voice</div>
|
||||||
|
|
@ -235,8 +240,13 @@
|
||||||
<select class="menu-select" name="microphone" id="microphone"></select>
|
<select class="menu-select" name="microphone" id="microphone"></select>
|
||||||
</div>
|
</div>
|
||||||
<div class="AdvancedMenuRow voiceLanguageDetection inputSTT">
|
<div class="AdvancedMenuRow voiceLanguageDetection inputSTT">
|
||||||
<div class="AdvancedMenuLabel">Voice Language</div>
|
<div class="AdvancedMenuLabel">Voice Language model</div>
|
||||||
<select class="menu-select" name="sttModel" id="sttModel" tip="Language Service to use"></select>
|
<select class="menu-select" name="sttModel" id="sttModel" tip="Language Service to use"></select>
|
||||||
|
<i
|
||||||
|
class="fa-solid fa-folder-open fa-2x SmallButton option-icon-container"
|
||||||
|
id="Info_VOICE_MODELS_FOLDER"
|
||||||
|
tip="Open Voice models folder"
|
||||||
|
></i>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
|
@ -247,27 +257,42 @@
|
||||||
<label for="USE_DETECTION" class="toggle-small"></label>
|
<label for="USE_DETECTION" class="toggle-small"></label>
|
||||||
<div class="AdvancedMenuLabel3">Enable Language detection</div>
|
<div class="AdvancedMenuLabel3">Enable Language detection</div>
|
||||||
</legend>
|
</legend>
|
||||||
<div class="AdvancedMenuRow languageDetectionInput">
|
|
||||||
<div class="AdvancedMenuLabel">Translate chat messages to</div>
|
|
||||||
<select class="menu-select" name="language" id="TRANSLATE_TO" tip="Language Service to use"></select>
|
|
||||||
</div>
|
|
||||||
<div class="AdvancedMenuRow languageDetectionInput">
|
|
||||||
<div class="AdvancedMenuLabel">Broadcast translation to chat</div>
|
|
||||||
<input type="checkbox" id="BROADCAST_TRANSLATION" class="checkbox" />
|
|
||||||
<label for="BROADCAST_TRANSLATION" class="toggle-small"></label>
|
|
||||||
</div>
|
|
||||||
<div class="AdvancedMenuRow languageDetectionInput">
|
|
||||||
<div class="AdvancedMenuLabel">Output translation to TTS</div>
|
|
||||||
<input type="checkbox" id="OUTPUT_TO_TTS" class="checkbox" />
|
|
||||||
<label for="OUTPUT_TO_TTS" class="toggle-small"></label>
|
|
||||||
</div>
|
|
||||||
<div class="AdvancedMenuRow outputToTtsInput">
|
<div class="AdvancedMenuRow outputToTtsInput">
|
||||||
<div class="AdvancedMenuLabel">Default TTS service language</div>
|
<div class="AdvancedMenuLabel">Default TTS service language</div>
|
||||||
<select class="menu-select" name="defaultLanguage" id="defaultLanguage" tip="Language Service to use"></select>
|
<select class="menu-select" name="defaultLanguage" id="defaultLanguage" tip="Language Service to use"></select>
|
||||||
|
<i
|
||||||
|
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
||||||
|
id="Info_PRIMARY_TTS_LANGUAGE"
|
||||||
|
tip="When the selected language is detected Your Primary TTS voice will sound"
|
||||||
|
></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="AdvancedMenuRow outputToTtsInput">
|
<div class="AdvancedMenuRow outputToTtsInput">
|
||||||
<div class="AdvancedMenuLabel">2<sup>nd</sup> TTS service language</div>
|
<div class="AdvancedMenuLabel">2<sup>nd</sup> TTS service language</div>
|
||||||
<select class="menu-select" name="secondaryLanguage" id="secondaryLanguage" tip="Language Service to use"></select>
|
<select class="menu-select" name="secondaryLanguage" id="secondaryLanguage" tip="Language Service to use"></select>
|
||||||
|
<i
|
||||||
|
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
||||||
|
id="Info_SECONDARY_TTS_LANGUAGE"
|
||||||
|
tip="When the selected language is detected Your Secondary TTS voice will sound"
|
||||||
|
></i>
|
||||||
|
</div>
|
||||||
|
<div class="AdvancedMenuRow languageDetectionInput">
|
||||||
|
<div class="AdvancedMenuLabel">Translate chat messages to</div>
|
||||||
|
<select class="menu-select" name="language" id="TRANSLATE_TO" tip="Language Service to use"></select>
|
||||||
|
</div>
|
||||||
|
<div class="AdvancedMenuRow languageDetectionInput TRANSLATE_TO">
|
||||||
|
<div class="AdvancedMenuLabel">Broadcast translation to chat</div>
|
||||||
|
<input type="checkbox" id="BROADCAST_TRANSLATION" class="checkbox TRANSLATE_TO" />
|
||||||
|
<label for="BROADCAST_TRANSLATION" class="toggle-small"></label>
|
||||||
|
</div>
|
||||||
|
<div class="AdvancedMenuRow languageDetectionInput TRANSLATE_TO">
|
||||||
|
<div class="AdvancedMenuLabel">Output translation to TTS</div>
|
||||||
|
<input type="checkbox" id="OUTPUT_TO_TTS" class="checkbox TRANSLATE_TO" />
|
||||||
|
<label for="OUTPUT_TO_TTS" class="toggle-small"></label>
|
||||||
|
<i
|
||||||
|
class="fa fa-question-circle fa-2x SmallButton option-icon-container"
|
||||||
|
id="Info_OUTPUT_TO_TTS"
|
||||||
|
tip="All translated messages will be send to primary TTS voice but if message is detected in Secondary TTS language it will output it to the Secondary TTS voice"
|
||||||
|
></i>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* global settings, sound, twitch, getLanguageProperties, addSingleTooltip, showChatMessage, languageObject, addVoiceService, internalVoices, ttsRequestCount, main, path, pythonPath, settingsPath, ipcRenderer */
|
/* global settings, resourcesPath, sound, twitch, getLanguageProperties, addSingleTooltip, showChatMessage, languageObject, addVoiceService, internalVoices, ttsRequestCount, main, path, pythonPath, settingsPath, ipcRenderer */
|
||||||
|
|
||||||
const spawn = require('child_process').spawn;
|
const spawn = require('child_process').spawn;
|
||||||
const kill = require('kill-process-by-name');
|
const kill = require('kill-process-by-name');
|
||||||
|
|
@ -45,35 +45,39 @@ async function getInstalledVoices() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setTranslatedMessage(message) {
|
function setTranslatedMessage(message) {
|
||||||
const messageBox = document.getElementById(message.messageId).getElementsByClassName('msg-box')[0];
|
if (message.language.selectedLanguage.ISO639 !== message.language.detectedLanguage.ISO639) {
|
||||||
|
const messageBox = document.getElementById(message.messageId).getElementsByClassName('msg-box')[0];
|
||||||
|
|
||||||
const translationHeader = document.createElement('div');
|
const translationHeader = document.createElement('div');
|
||||||
translationHeader.className = 'translation-header';
|
translationHeader.className = 'translation-header';
|
||||||
translationHeader.innerText = 'Translation';
|
translationHeader.innerText = 'Translation';
|
||||||
messageBox.appendChild(translationHeader);
|
messageBox.appendChild(translationHeader);
|
||||||
|
|
||||||
const translationIcon = document.createElement('div');
|
const translationIcon = document.createElement('div');
|
||||||
translationIcon.className = 'translation-icon';
|
translationIcon.className = 'translation-icon';
|
||||||
const languageElement = document.createElement('span');
|
const languageElement = document.createElement('span');
|
||||||
const language = getLanguageProperties(settings.LANGUAGE.TRANSLATE_TO);
|
const language = getLanguageProperties(settings.LANGUAGE.TRANSLATE_TO);
|
||||||
languageElement.classList = `fi fi-${language.ISO3166} fis`;
|
languageElement.classList = `fi fi-${message.language.selectedLanguage.ISO3166} fis`;
|
||||||
languageElement.setAttribute('tip', language.name);
|
languageElement.setAttribute('tip', message.language.selectedLanguage.name);
|
||||||
addSingleTooltip(languageElement);
|
addSingleTooltip(languageElement);
|
||||||
translationIcon.appendChild(languageElement);
|
translationIcon.appendChild(languageElement);
|
||||||
messageBox.appendChild(translationIcon);
|
messageBox.appendChild(translationIcon);
|
||||||
|
|
||||||
|
const translationMessage = document.createElement('div');
|
||||||
|
translationMessage.className = 'translation-message';
|
||||||
|
translationMessage.innerText = message.translation;
|
||||||
|
messageBox.appendChild(translationMessage);
|
||||||
|
showChatMessage();
|
||||||
|
}
|
||||||
|
|
||||||
const translationMessage = document.createElement('div');
|
|
||||||
translationMessage.className = 'translation-message';
|
|
||||||
translationMessage.innerText = message.translation;
|
|
||||||
messageBox.appendChild(translationMessage);
|
|
||||||
showChatMessage();
|
|
||||||
if (settings.LANGUAGE.OUTPUT_TO_TTS) {
|
if (settings.LANGUAGE.OUTPUT_TO_TTS) {
|
||||||
sound.playVoice({
|
sound.playVoice({
|
||||||
|
originalMessage: message.originalMessage,
|
||||||
filteredMessage: message.translation,
|
filteredMessage: message.translation,
|
||||||
logoUrl: message.logoUrl,
|
logoUrl: message.logoUrl,
|
||||||
username: message.username,
|
username: message.username,
|
||||||
formattedMessage: message.formattedMessage,
|
formattedMessage: message.formattedMessage,
|
||||||
language
|
language: message.language
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +90,7 @@ async function getTranslatedMessage(message) {
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
message: message.message,
|
message: message.message,
|
||||||
language: message.language
|
language: message.language.detectedLanguage.IETF
|
||||||
}) // Convert the data to JSON and include it in the request body
|
}) // Convert the data to JSON and include it in the request body
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -97,15 +101,18 @@ async function getTranslatedMessage(message) {
|
||||||
|
|
||||||
console.log('Translated message:', responseData);
|
console.log('Translated message:', responseData);
|
||||||
setTranslatedMessage({
|
setTranslatedMessage({
|
||||||
|
originalMessage: message.message,
|
||||||
translation: responseData.translation,
|
translation: responseData.translation,
|
||||||
messageId: message.messageId,
|
messageId: message.messageId,
|
||||||
ISO3166: message.ISO3166,
|
language: message.language,
|
||||||
formattedMessage: message.formattedMessage,
|
formattedMessage: message.formattedMessage,
|
||||||
username: message.username,
|
username: message.username,
|
||||||
logoUrl: message.logoUrl
|
logoUrl: message.logoUrl
|
||||||
});
|
});
|
||||||
if (settings.LANGUAGE.BROADCAST_TRANSLATION) {
|
if (settings.LANGUAGE.BROADCAST_TRANSLATION) {
|
||||||
twitch.sendMessage(`[${message.language} > ${settings.LANGUAGE.TRANSLATE_TO}] @${message.username}: ${responseData.translation}`);
|
twitch.sendMessage(
|
||||||
|
`[${message.language.detectedLanguage.name} ${message.language.detectedLanguage.ISO639} > ${message.language.selectedLanguage.name} ${message.language.selectedLanguage.ISO639}] @${message.username}: ${responseData.translation}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.error('Failed to send termination signal to Flask server.');
|
console.error('Failed to send termination signal to Flask server.');
|
||||||
|
|
@ -119,19 +126,40 @@ async function getTranslatedMessage(message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterLanguage(message) {
|
function filterLanguage(message) {
|
||||||
const language = getLanguageProperties(message.language);
|
const selectedPrimaryLanguage = getLanguageProperties(settings.LANGUAGE.TRANSLATE_TO);
|
||||||
|
const selectedPrimaryLanguageIndex =
|
||||||
if (settings.LANGUAGE.TRANSLATE_TO !== 'none') {
|
message.languages.indexOf(selectedPrimaryLanguage.ISO639) === -1 ? 99 : message.languages.indexOf(selectedPrimaryLanguage.ISO639);
|
||||||
|
const selectedSecondaryLanguage = getLanguageProperties(settings.TTS.SECONDARY_TTS_LANGUAGE);
|
||||||
|
const selectedSecondaryLanguageIndex =
|
||||||
|
message.languages.indexOf(selectedSecondaryLanguage.ISO639) === -1 ? 99 : message.languages.indexOf(selectedSecondaryLanguage.ISO639);
|
||||||
|
const detectedLanguage = getLanguageProperties(message.languages[0]);
|
||||||
|
const language = selectedPrimaryLanguageIndex < selectedSecondaryLanguageIndex ? selectedPrimaryLanguage : detectedLanguage;
|
||||||
|
if (settings.LANGUAGE.TRANSLATE_TO !== 'none' && selectedPrimaryLanguage.ISO639 !== detectedLanguage.ISO639) {
|
||||||
getTranslatedMessage({
|
getTranslatedMessage({
|
||||||
message: message.message,
|
message: message.message,
|
||||||
messageId: message.messageId,
|
messageId: message.messageId,
|
||||||
language: language.IETF,
|
language: {
|
||||||
ISO3166: language.ISO3166,
|
selectedLanguage: selectedPrimaryLanguage,
|
||||||
|
detectedLanguage
|
||||||
|
},
|
||||||
username: message.username,
|
username: message.username,
|
||||||
formattedMessage: message.formattedMessage
|
formattedMessage: message.formattedMessage,
|
||||||
|
logoUrl: message.logoUrl
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setTranslatedMessage({
|
||||||
|
originalMessage: message.message,
|
||||||
|
translation: message.message,
|
||||||
|
messageId: message.messageId,
|
||||||
|
language: {
|
||||||
|
selectedLanguage: selectedPrimaryLanguage,
|
||||||
|
detectedLanguage: selectedPrimaryLanguage
|
||||||
|
},
|
||||||
|
formattedMessage: message.formattedMessage,
|
||||||
|
username: message.username,
|
||||||
|
logoUrl: message.logoUrl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return language;
|
return language;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -155,7 +183,7 @@ async function getDetectedLanguage(message) {
|
||||||
|
|
||||||
console.log('Detected Languages:', responseData);
|
console.log('Detected Languages:', responseData);
|
||||||
return filterLanguage({
|
return filterLanguage({
|
||||||
language: responseData.languages[0],
|
languages: responseData.languages,
|
||||||
message: message.message,
|
message: message.message,
|
||||||
messageId: message.messageId,
|
messageId: message.messageId,
|
||||||
username: message.username,
|
username: message.username,
|
||||||
|
|
@ -232,7 +260,7 @@ const createBackendServer = () =>
|
||||||
if (main.isPackaged) {
|
if (main.isPackaged) {
|
||||||
python = spawn(path.join(pythonPath, './loquendoBot_backend.exe'), [settingsPath, 'prod']);
|
python = spawn(path.join(pythonPath, './loquendoBot_backend.exe'), [settingsPath, 'prod']);
|
||||||
} else {
|
} else {
|
||||||
python = spawn('python', ['-u', path.join(pythonPath, './loquendoBot_backend.py'), settingsPath, 'dev']);
|
python = spawn('python', ['-u', path.join(resourcesPath, '../backend/loquendoBot_backend.py'), settingsPath, 'dev']);
|
||||||
}
|
}
|
||||||
// Capture the stdout of the Python process
|
// Capture the stdout of the Python process
|
||||||
python.stdout.on('data', data => {
|
python.stdout.on('data', data => {
|
||||||
|
|
@ -266,7 +294,7 @@ async function initiateBackend() {
|
||||||
createBackendServer().then(() => {
|
createBackendServer().then(() => {
|
||||||
getBackendServerStatus();
|
getBackendServerStatus();
|
||||||
getInstalledVoices();
|
getInstalledVoices();
|
||||||
if (settings.STT.USE_STT) {
|
if (settings.STT.USE_STT && !settings.STT.LANGUAGE === '') {
|
||||||
startSTT();
|
startSTT();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@ const languages = {
|
||||||
'crimean tatar': { IETF: 'crh-RU', ISO639: 'crh', ISO3166: 'tr' },
|
'crimean tatar': { IETF: 'crh-RU', ISO639: 'crh', ISO3166: 'tr' },
|
||||||
'crioulo upper guinea': { IETF: 'pov-GW', ISO639: 'pov', ISO3166: 'gw' },
|
'crioulo upper guinea': { IETF: 'pov-GW', ISO639: 'pov', ISO3166: 'gw' },
|
||||||
croatian: { IETF: 'hr-HR', ISO639: 'hr', ISO3166: 'hr' },
|
croatian: { IETF: 'hr-HR', ISO639: 'hr', ISO3166: 'hr' },
|
||||||
|
'serbo-croatian': { IETF: 'sr-Cyrl-RS', ISO639: 'sh', ISO3166: 'sr' },
|
||||||
czech: { IETF: 'cs-CZ', ISO639: 'cs', ISO3166: 'cz' },
|
czech: { IETF: 'cs-CZ', ISO639: 'cs', ISO3166: 'cz' },
|
||||||
danish: { IETF: 'da-DK', ISO639: 'da', ISO3166: 'dk' },
|
danish: { IETF: 'da-DK', ISO639: 'da', ISO3166: 'dk' },
|
||||||
dari: { IETF: 'prs-AF', ISO639: 'prs', ISO3166: 'af' },
|
dari: { IETF: 'prs-AF', ISO639: 'prs', ISO3166: 'af' },
|
||||||
|
|
@ -108,6 +109,7 @@ const languages = {
|
||||||
garo: { IETF: 'grt-IN', ISO639: 'grt', ISO3166: 'in' },
|
garo: { IETF: 'grt-IN', ISO639: 'grt', ISO3166: 'in' },
|
||||||
georgian: { IETF: 'ka-GE', ISO639: 'ka', ISO3166: 'ge' },
|
georgian: { IETF: 'ka-GE', ISO639: 'ka', ISO3166: 'ge' },
|
||||||
german: { IETF: 'de-DE', ISO639: 'de', ISO3166: 'de' },
|
german: { IETF: 'de-DE', ISO639: 'de', ISO3166: 'de' },
|
||||||
|
'Low German': { IETF: 'nl-NL', ISO639: 'nds', ISO3166: 'nl' },
|
||||||
gilbertese: { IETF: 'gil-KI', ISO639: 'gil', ISO3166: 'ki' },
|
gilbertese: { IETF: 'gil-KI', ISO639: 'gil', ISO3166: 'ki' },
|
||||||
glavda: { IETF: 'glw-NG', ISO639: 'glw', ISO3166: 'ng' },
|
glavda: { IETF: 'glw-NG', ISO639: 'glw', ISO3166: 'ng' },
|
||||||
greek: { IETF: 'el-GR', ISO639: 'el', ISO3166: 'gr' },
|
greek: { IETF: 'el-GR', ISO639: 'el', ISO3166: 'gr' },
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const ini = require('ini');
|
const ini = require('ini');
|
||||||
const path = require('path'); // get directory path
|
const path = require('path'); // get directory path
|
||||||
|
|
@ -49,8 +50,8 @@ const config = require(path.join(__dirname, './js/settings'));
|
||||||
|
|
||||||
const mediaDevices = require(path.join(__dirname, './js/mediaDevices'));
|
const mediaDevices = require(path.join(__dirname, './js/mediaDevices'));
|
||||||
|
|
||||||
const notificationSounds = path.join(__dirname, './sounds/notifications');
|
const notificationSounds = path.join(resourcesPath, main.isPackaged ? './sounds/notifications' : '../sounds/notifications');
|
||||||
const sttModels = path.join(__dirname, '../speech_to_text_models');
|
const sttModels = path.join(resourcesPath, main.isPackaged ? './speech_to_text_models' : '../speech_to_text_models');
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
ipcRenderer.send('restart');
|
ipcRenderer.send('restart');
|
||||||
|
|
@ -233,10 +234,10 @@ function showChatMessage(article) {
|
||||||
document.querySelector('#chatBox').appendChild(article);
|
document.querySelector('#chatBox').appendChild(article);
|
||||||
}
|
}
|
||||||
|
|
||||||
const messages = Array.from(document.body.querySelectorAll('.msg-container'));
|
const messages = document.body.querySelectorAll('.msg-container');
|
||||||
|
|
||||||
const lastMessage = messages[messages.length - 1];
|
const lastMessage = messages[messages.length - 1];
|
||||||
lastMessage.scrollIntoView({ behavior: 'smooth' });
|
lastMessage.scrollIntoView();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPostTime() {
|
function getPostTime() {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* global settings, setZoomLevel, webFrame, theme, fs, settingsPath, ini, startVoiceRecognition,notificationSoundAudioDevices, ttsAudioDevices, notificationSound, path, resourcesPath, ipcRenderer, auth, shell, sound, twitch, server, backend */
|
/* global settings,main sttModels, setZoomLevel, webFrame, theme, fs, settingsPath, ini, startVoiceRecognition,notificationSoundAudioDevices, ttsAudioDevices, notificationSound, path, resourcesPath, ipcRenderer, auth, shell, sound, twitch, server, backend */
|
||||||
|
|
||||||
function getGeneralSettings() {
|
function getGeneralSettings() {
|
||||||
// General
|
// General
|
||||||
|
|
@ -130,10 +130,34 @@ document.body.querySelector('#language').addEventListener('change', () => {
|
||||||
createNotification('Saved language!', 'success');
|
createNotification('Saved language!', 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function setTranslateToOptions() {
|
||||||
|
const options = document.querySelectorAll('.TRANSLATE_TO');
|
||||||
|
const index = parseInt(settings.LANGUAGE.TRANSLATE_TO_INDEX);
|
||||||
|
|
||||||
|
if (index === 0) {
|
||||||
|
settings.LANGUAGE.BROADCAST_TRANSLATION = false;
|
||||||
|
settings.LANGUAGE.OUTPUT_TO_TTS = false;
|
||||||
|
options.forEach(item => {
|
||||||
|
item.style.visibility = 'hidden';
|
||||||
|
item.style.height = '0px';
|
||||||
|
item.checked = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
options.forEach(item => {
|
||||||
|
item.style.visibility = '';
|
||||||
|
item.style.height = '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTranslateToOptions();
|
||||||
|
|
||||||
document.body.querySelector('#TRANSLATE_TO').addEventListener('change', () => {
|
document.body.querySelector('#TRANSLATE_TO').addEventListener('change', () => {
|
||||||
const select = document.querySelector('#TRANSLATE_TO');
|
const select = document.querySelector('#TRANSLATE_TO');
|
||||||
settings.LANGUAGE.TRANSLATE_TO_INDEX = select.selectedIndex;
|
settings.LANGUAGE.TRANSLATE_TO_INDEX = select.selectedIndex;
|
||||||
settings.LANGUAGE.TRANSLATE_TO = select.options[select.selectedIndex].value;
|
settings.LANGUAGE.TRANSLATE_TO = select.options[select.selectedIndex].value;
|
||||||
|
setTranslateToOptions();
|
||||||
|
|
||||||
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification('Saved primary voice!', 'success');
|
createNotification('Saved primary voice!', 'success');
|
||||||
});
|
});
|
||||||
|
|
@ -227,7 +251,9 @@ function createNotification(message = null, type = null) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.AUDIO.USE_NOTIFICATION_SOUNDS) {
|
if (settings.AUDIO.USE_NOTIFICATION_SOUNDS) {
|
||||||
const notfication = new Audio(path.join(resourcesPath, `./sounds/notifications/${alertSound}`));
|
const notfication = new Audio(
|
||||||
|
path.join(resourcesPath, main.isPackaged ? `./sounds/notifications/${alertSound}` : `../sounds/notifications/${alertSound}`)
|
||||||
|
);
|
||||||
notfication.volume = settings.AUDIO.NOTIFICATION_VOLUME / 100;
|
notfication.volume = settings.AUDIO.NOTIFICATION_VOLUME / 100;
|
||||||
notfication.play();
|
notfication.play();
|
||||||
}
|
}
|
||||||
|
|
@ -268,6 +294,10 @@ document.body.querySelector('#OPEN_SETTINGS_FILE').addEventListener('click', ()
|
||||||
shell.openExternal(settingsPath);
|
shell.openExternal(settingsPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.body.querySelector('#Info_VOICE_MODELS_FOLDER').addEventListener('click', () => {
|
||||||
|
shell.openExternal(sttModels);
|
||||||
|
});
|
||||||
|
|
||||||
// #region Use Custom theme toggle logic
|
// #region Use Custom theme toggle logic
|
||||||
document.body.querySelector('#USE_CUSTOM_THEME').addEventListener('click', () => {
|
document.body.querySelector('#USE_CUSTOM_THEME').addEventListener('click', () => {
|
||||||
const toggle = document.getElementById('USE_CUSTOM_THEME').checked;
|
const toggle = document.getElementById('USE_CUSTOM_THEME').checked;
|
||||||
|
|
@ -488,14 +518,6 @@ document.body.querySelector('#USE_STT').addEventListener('change', () => {
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} speech to text!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} speech to text!`, 'success');
|
||||||
});
|
});
|
||||||
|
|
||||||
function toggleOutputToTts() {
|
|
||||||
const toggle = settings.LANGUAGE.OUTPUT_TO_TTS;
|
|
||||||
const inputs = document.getElementsByClassName('outputToTtsInput');
|
|
||||||
toggleRadio(toggle, inputs);
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleOutputToTts();
|
|
||||||
|
|
||||||
document.body.querySelector('#OUTPUT_TO_TTS').addEventListener('change', () => {
|
document.body.querySelector('#OUTPUT_TO_TTS').addEventListener('change', () => {
|
||||||
let toggle = document.getElementById('OUTPUT_TO_TTS').checked;
|
let toggle = document.getElementById('OUTPUT_TO_TTS').checked;
|
||||||
if (!settings.TTS.USE_TTS) {
|
if (!settings.TTS.USE_TTS) {
|
||||||
|
|
@ -505,8 +527,6 @@ document.body.querySelector('#OUTPUT_TO_TTS').addEventListener('change', () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.LANGUAGE.OUTPUT_TO_TTS = toggle;
|
settings.LANGUAGE.OUTPUT_TO_TTS = toggle;
|
||||||
const inputs = document.getElementsByClassName('outputToTtsInput');
|
|
||||||
toggleRadio(toggle, inputs);
|
|
||||||
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
fs.writeFileSync(settingsPath, ini.stringify(settings));
|
||||||
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Outputting translations to TTS!`, 'success');
|
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Outputting translations to TTS!`, 'success');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* global ttsAudioFile, path, getLanguageProperties, resourcesPath, settings, fs, notificationSound, backend, socket, requestData */
|
/* global ttsAudioFile, main, path, getLanguageProperties, resourcesPath, settings, fs, notificationSound, backend, socket, requestData */
|
||||||
|
|
||||||
const voiceSoundArray = [];
|
const voiceSoundArray = [];
|
||||||
let status = 0;
|
let status = 0;
|
||||||
|
|
@ -6,7 +6,10 @@ const counter = 0;
|
||||||
|
|
||||||
const playTTS = data =>
|
const playTTS = data =>
|
||||||
new Promise(resolve => {
|
new Promise(resolve => {
|
||||||
ttsAudioFile = path.join(resourcesPath, `./sounds/tts/${data.service}_${data.count}.mp3`);
|
ttsAudioFile = path.join(
|
||||||
|
resourcesPath,
|
||||||
|
main.isPackaged ? `./sounds/${data.service}_${data.count}.mp3` : `../sounds/${data.service}_${data.count}.mp3`
|
||||||
|
);
|
||||||
const tts = new Audio(ttsAudioFile);
|
const tts = new Audio(ttsAudioFile);
|
||||||
tts.setSinkId(settings.AUDIO.TTS_AUDIO_DEVICE);
|
tts.setSinkId(settings.AUDIO.TTS_AUDIO_DEVICE);
|
||||||
|
|
||||||
|
|
@ -58,7 +61,12 @@ function add(data) {
|
||||||
function playNotificationSound() {
|
function playNotificationSound() {
|
||||||
if (settings.AUDIO.USE_NOTIFICATION_SOUNDS) {
|
if (settings.AUDIO.USE_NOTIFICATION_SOUNDS) {
|
||||||
const notfication = new Audio(
|
const notfication = new Audio(
|
||||||
path.join(resourcesPath, `./sounds/notifications/${notificationSound.options[settings.AUDIO.NOTIFICATION_SOUND].text}`)
|
path.join(
|
||||||
|
resourcesPath,
|
||||||
|
main.isPackaged
|
||||||
|
? `./sounds/notifications/${notificationSound.options[settings.AUDIO.NOTIFICATION_SOUND].text}`
|
||||||
|
: `../sounds/notifications/${notificationSound.options[settings.AUDIO.NOTIFICATION_SOUND].text}`
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
notfication
|
notfication
|
||||||
|
|
@ -93,10 +101,11 @@ async function playVoice(message) {
|
||||||
let voice = settings.TTS.PRIMARY_VOICE;
|
let voice = settings.TTS.PRIMARY_VOICE;
|
||||||
textObject.filtered = `${message.username}: ${message.filteredMessage}`;
|
textObject.filtered = `${message.username}: ${message.filteredMessage}`;
|
||||||
|
|
||||||
if (settings.LANGUAGE.USE_DETECTION && settings.TTS.SECONDARY_VOICE && settings.LANGUAGE.OUTPUT_TO_TTS) {
|
if (settings.LANGUAGE.USE_DETECTION && settings.TTS.SECONDARY_VOICE) {
|
||||||
const secondaryTTSLanguage = getLanguageProperties(settings.TTS.SECONDARY_TTS_LANGUAGE);
|
const secondaryTTSLanguage = getLanguageProperties(settings.TTS.SECONDARY_TTS_LANGUAGE);
|
||||||
if (message.language.ISO639 === secondaryTTSLanguage.ISO639) {
|
if (message.language.detectedLanguage === null || message.language.detectedLanguage.ISO639 === secondaryTTSLanguage.ISO639) {
|
||||||
voice = settings.TTS.SECONDARY_VOICE;
|
voice = settings.TTS.SECONDARY_VOICE;
|
||||||
|
textObject.filtered = message.originalMessage ? message.originalMessage : message.filteredMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ function ping(element) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function displayTwitchMessage(logoUrl, username, messageObject, filteredMessage) {
|
async function displayTwitchMessage(logoUrl, username, messageObject, filteredMessage) {
|
||||||
|
messageId++;
|
||||||
const article = document.createElement('article');
|
const article = document.createElement('article');
|
||||||
article.className = 'msg-container sender';
|
article.className = 'msg-container sender';
|
||||||
article.setAttribute('id', messageId);
|
article.setAttribute('id', messageId);
|
||||||
|
|
@ -144,7 +145,13 @@ async function displayTwitchMessage(logoUrl, username, messageObject, filteredMe
|
||||||
showChatMessage(article);
|
showChatMessage(article);
|
||||||
|
|
||||||
if (filteredMessage && !settings.LANGUAGE.OUTPUT_TO_TTS) {
|
if (filteredMessage && !settings.LANGUAGE.OUTPUT_TO_TTS) {
|
||||||
sound.playVoice({ filteredMessage, logoUrl, username, formattedMessage, language });
|
sound.playVoice({
|
||||||
|
filteredMessage,
|
||||||
|
logoUrl,
|
||||||
|
username,
|
||||||
|
formattedMessage,
|
||||||
|
language: { selectedLanguage: null, detectedLanguage: language }
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
window.article = article;
|
window.article = article;
|
||||||
|
|
@ -159,7 +166,6 @@ async function displayTwitchMessage(logoUrl, username, messageObject, filteredMe
|
||||||
window.article = article;
|
window.article = article;
|
||||||
}
|
}
|
||||||
|
|
||||||
messageId++;
|
|
||||||
sound.playNotificationSound();
|
sound.playNotificationSound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,6 @@ if (app.isPackaged) {
|
||||||
pythonPath = path.join(resourcesPath, './backend');
|
pythonPath = path.join(resourcesPath, './backend');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
|
|
||||||
if (require('electron-squirrel-startup')) {
|
|
||||||
app.quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createWindow() {
|
async function createWindow() {
|
||||||
if (!fs.existsSync(settingsPath)) {
|
if (!fs.existsSync(settingsPath)) {
|
||||||
console.log(resourcesPath);
|
console.log(resourcesPath);
|
||||||
|
|
@ -164,7 +159,7 @@ async function createIniFile() {
|
||||||
MICROPHONE_ID: 'default',
|
MICROPHONE_ID: 'default',
|
||||||
SELECTED_MICROPHONE: 'default',
|
SELECTED_MICROPHONE: 'default',
|
||||||
MICROPHONE: 0,
|
MICROPHONE: 0,
|
||||||
LANGUAGE: 'vosk-model-small-es-0.42'
|
LANGUAGE: ''
|
||||||
},
|
},
|
||||||
AUDIO: {
|
AUDIO: {
|
||||||
USE_NOTIFICATION_SOUNDS: false,
|
USE_NOTIFICATION_SOUNDS: false,
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in a new issue