diff --git a/.gitignore b/.gitignore
index 763e324..87c3a5b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -104,5 +104,7 @@ src/sounds/tts/*
loquendoBot_backend.spec
forge.config.js
backend/*
-src/backend/loquendoBot_backend.exe
+!backend/loquendoBot_backend.py
+backend/loquendoBot_backend.exe
src/config/twitch-emotes.json
+dist/*
diff --git a/src/backend/loquendoBot_backend.py b/backend/loquendoBot_backend.py
similarity index 92%
rename from src/backend/loquendoBot_backend.py
rename to backend/loquendoBot_backend.py
index 919ff58..3bbde06 100644
--- a/src/backend/loquendoBot_backend.py
+++ b/backend/loquendoBot_backend.py
@@ -11,7 +11,7 @@ logger = logging.getLogger("waitress")
logger.setLevel(logging.INFO)
gevent.monkey.patch_all()
-import gevent.queue
+# import gevent.queue
import configparser
import pyttsx3
@@ -28,8 +28,6 @@ from deep_translator import (
MyMemoryTranslator,
)
-import emoji
-
from vosk import Model, KaldiRecognizer, SetLogLevel
# global variables
@@ -68,7 +66,7 @@ class LanguageDetection:
self.model = fasttext.load_model(language_detection_model)
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 = []
for prediction in predictions[0]:
language_codes.append(prediction.replace("__label__", ""))
@@ -98,6 +96,7 @@ class STT:
vosk_model = os.path.join(
resources_folder, "speech_to_text_models", settings["STT"]["LANGUAGE"]
)
+ print(vosk_model)
self.model = Model(rf"{vosk_model}")
self.dump_fn = None
@@ -137,8 +136,10 @@ class STT:
def stop_recognition(self):
self.is_running = False
-
-speech_recognition_service = STT()
+settings.read(settingsPath)
+print(settingsPath)
+if settings["STT"]["USE_STT"] and bool(settings["STT"]["LANGUAGE"]):
+ speech_recognition_service = STT()
class TTS:
@@ -156,16 +157,16 @@ class TTS:
break
self.engine.setProperty("voice", matching_id)
+ settings_folder = os.path.dirname(settingsPath)
if environment == "dev":
- settings_folder = os.path.dirname(settingsPath)
src_folder = os.path.dirname(settings_folder)
+ bot_folder = os.path.dirname(src_folder)
saveLocation = os.path.join(
- src_folder, "sounds\\tts", f"Internal_{count}.mp3"
+ bot_folder, "sounds", f"Internal_{count}.mp3"
)
else:
- resources_folder = os.path.dirname(settingsPath)
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)
@@ -180,8 +181,9 @@ class TTS:
return [voice.name for voice in voices]
-
-text_to_speech_service = TTS()
+settings.read(settingsPath)
+if settings["TTS"]["USE_TTS"]:
+ text_to_speech_service = TTS()
# endpoints
diff --git a/forge.config.js b/forge.config.js
deleted file mode 100644
index 78ea629..0000000
--- a/forge.config.js
+++ /dev/null
@@ -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: {},
- },
- ],
-};
diff --git a/license b/license.md
similarity index 96%
rename from license
rename to license.md
index 7522c81..02cfa3d 100644
--- a/license
+++ b/license.md
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2021 Khyretis
+Copyright (c) 2021 Khyretos
Permission is hereby granted, free of charge, to any person obtaining a copy
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
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
-SOFTWARE.
\ No newline at end of file
+SOFTWARE.
diff --git a/package.json b/package.json
index 22e6cbc..4b8f5c2 100644
--- a/package.json
+++ b/package.json
@@ -1,14 +1,37 @@
{
"name": "loquendo-bot",
+ "productName": "LoquendoBot",
"version": "2.5.0",
"description": "Bot assistant for streamers over different platforms",
"main": "src/main.js",
"scripts": {
"start": "electron-forge start",
- "package": "npm run backend && electron-forge package",
- "make": "electron-forge make",
+ "build": "npm run backend && electron-builder",
"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": [],
"author": {
@@ -18,7 +41,6 @@
"license": "ISC",
"dependencies": {
"axios": "^1.4.0",
- "electron-squirrel-startup": "^1.0.0",
"emoji-picker-element": "^1.21.0",
"express": "^4.18.2",
"flag-icons": "^7.1.0",
@@ -38,12 +60,12 @@
"@electron-forge/cli": "^6.2.1",
"@electron-forge/maker-deb": "^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/plugin-auto-unpack-natives": "^6.2.1",
"@electron-internal/eslint-config": "^1.0.1",
"@electron-toolkit/eslint-config": "^1.0.2",
"electron": "^25.9.8",
+ "electron-builder": "^24.9.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.2",
diff --git a/src/sounds/notifications/Tip Sound.mp3 b/sounds/notifications/Tip Sound.mp3
similarity index 100%
rename from src/sounds/notifications/Tip Sound.mp3
rename to sounds/notifications/Tip Sound.mp3
diff --git a/src/sounds/notifications/coin.mp3 b/sounds/notifications/coin.mp3
similarity index 100%
rename from src/sounds/notifications/coin.mp3
rename to sounds/notifications/coin.mp3
diff --git a/src/sounds/notifications/dice.mp3 b/sounds/notifications/dice.mp3
similarity index 100%
rename from src/sounds/notifications/dice.mp3
rename to sounds/notifications/dice.mp3
diff --git a/src/sounds/notifications/error.mp3 b/sounds/notifications/error.mp3
similarity index 100%
rename from src/sounds/notifications/error.mp3
rename to sounds/notifications/error.mp3
diff --git a/src/sounds/notifications/fail.wav b/sounds/notifications/fail.wav
similarity index 100%
rename from src/sounds/notifications/fail.wav
rename to sounds/notifications/fail.wav
diff --git a/src/sounds/notifications/info.mp3 b/sounds/notifications/info.mp3
similarity index 100%
rename from src/sounds/notifications/info.mp3
rename to sounds/notifications/info.mp3
diff --git a/src/sounds/notifications/pling.mp3 b/sounds/notifications/pling.mp3
similarity index 100%
rename from src/sounds/notifications/pling.mp3
rename to sounds/notifications/pling.mp3
diff --git a/src/sounds/notifications/spinjump.mp3 b/sounds/notifications/spinjump.mp3
similarity index 100%
rename from src/sounds/notifications/spinjump.mp3
rename to sounds/notifications/spinjump.mp3
diff --git a/src/sounds/notifications/success.wav b/sounds/notifications/success.wav
similarity index 100%
rename from src/sounds/notifications/success.wav
rename to sounds/notifications/success.wav
diff --git a/src/sounds/notifications/ting.mp3 b/sounds/notifications/ting.mp3
similarity index 100%
rename from src/sounds/notifications/ting.mp3
rename to sounds/notifications/ting.mp3
diff --git a/speech_to_text_models/Where to get STT models.txt b/speech_to_text_models/Where to get STT models.txt
index d41ac68..21a635e 100644
--- a/speech_to_text_models/Where to get STT models.txt
+++ b/speech_to_text_models/Where to get STT models.txt
@@ -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.
diff --git a/src/css/home.css b/src/css/home.css
index 5dcccf6..07cf50a 100644
--- a/src/css/home.css
+++ b/src/css/home.css
@@ -36,25 +36,14 @@ html {
box-sizing: inherit;
}
-html,
body {
height: 100%;
margin: 0;
- /* border-top-left-radius: 20px; */
- /* border-top-right-radius: 20px; */
- overflow-x: hidden;
-}
-
-body {
font-family: 'Segoe UI', sans-serif;
background: transparent;
-}
-
-/* Styling of window frame and titlebar */
-
-body {
- /* border: 1px solid #48545c; */
- overflow-y: hidden;
+ position: relative;
+ /* overflow-y: hidden;
+ overflow-x: hidden; */
}
#titlebar {
diff --git a/src/images/icon.ico b/src/images/icon.ico
index 84862b2..5c32439 100644
Binary files a/src/images/icon.ico and b/src/images/icon.ico differ
diff --git a/src/index.html b/src/index.html
index d187d26..d922dc8 100644
--- a/src/index.html
+++ b/src/index.html
@@ -212,6 +212,11 @@
@@ -247,27 +257,42 @@
-
-
-
+
+
+
diff --git a/src/js/backend.js b/src/js/backend.js
index 63e692e..751deb5 100644
--- a/src/js/backend.js
+++ b/src/js/backend.js
@@ -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 kill = require('kill-process-by-name');
@@ -45,35 +45,39 @@ async function getInstalledVoices() {
}
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');
- translationHeader.className = 'translation-header';
- translationHeader.innerText = 'Translation';
- messageBox.appendChild(translationHeader);
+ const translationHeader = document.createElement('div');
+ translationHeader.className = 'translation-header';
+ translationHeader.innerText = 'Translation';
+ messageBox.appendChild(translationHeader);
- const translationIcon = document.createElement('div');
- translationIcon.className = 'translation-icon';
- const languageElement = document.createElement('span');
- const language = getLanguageProperties(settings.LANGUAGE.TRANSLATE_TO);
- languageElement.classList = `fi fi-${language.ISO3166} fis`;
- languageElement.setAttribute('tip', language.name);
- addSingleTooltip(languageElement);
- translationIcon.appendChild(languageElement);
- messageBox.appendChild(translationIcon);
+ const translationIcon = document.createElement('div');
+ translationIcon.className = 'translation-icon';
+ const languageElement = document.createElement('span');
+ const language = getLanguageProperties(settings.LANGUAGE.TRANSLATE_TO);
+ languageElement.classList = `fi fi-${message.language.selectedLanguage.ISO3166} fis`;
+ languageElement.setAttribute('tip', message.language.selectedLanguage.name);
+ addSingleTooltip(languageElement);
+ translationIcon.appendChild(languageElement);
+ 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) {
sound.playVoice({
+ originalMessage: message.originalMessage,
filteredMessage: message.translation,
logoUrl: message.logoUrl,
username: message.username,
formattedMessage: message.formattedMessage,
- language
+ language: message.language
});
}
}
@@ -86,7 +90,7 @@ async function getTranslatedMessage(message) {
},
body: JSON.stringify({
message: message.message,
- language: message.language
+ language: message.language.detectedLanguage.IETF
}) // 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);
setTranslatedMessage({
+ originalMessage: message.message,
translation: responseData.translation,
messageId: message.messageId,
- ISO3166: message.ISO3166,
+ language: message.language,
formattedMessage: message.formattedMessage,
username: message.username,
logoUrl: message.logoUrl
});
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 {
console.error('Failed to send termination signal to Flask server.');
@@ -119,19 +126,40 @@ async function getTranslatedMessage(message) {
}
function filterLanguage(message) {
- const language = getLanguageProperties(message.language);
-
- if (settings.LANGUAGE.TRANSLATE_TO !== 'none') {
+ const selectedPrimaryLanguage = getLanguageProperties(settings.LANGUAGE.TRANSLATE_TO);
+ const selectedPrimaryLanguageIndex =
+ 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({
message: message.message,
messageId: message.messageId,
- language: language.IETF,
- ISO3166: language.ISO3166,
+ language: {
+ selectedLanguage: selectedPrimaryLanguage,
+ detectedLanguage
+ },
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;
}
@@ -155,7 +183,7 @@ async function getDetectedLanguage(message) {
console.log('Detected Languages:', responseData);
return filterLanguage({
- language: responseData.languages[0],
+ languages: responseData.languages,
message: message.message,
messageId: message.messageId,
username: message.username,
@@ -232,7 +260,7 @@ const createBackendServer = () =>
if (main.isPackaged) {
python = spawn(path.join(pythonPath, './loquendoBot_backend.exe'), [settingsPath, 'prod']);
} 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
python.stdout.on('data', data => {
@@ -266,7 +294,7 @@ async function initiateBackend() {
createBackendServer().then(() => {
getBackendServerStatus();
getInstalledVoices();
- if (settings.STT.USE_STT) {
+ if (settings.STT.USE_STT && !settings.STT.LANGUAGE === '') {
startSTT();
}
});
diff --git a/src/js/languages.js b/src/js/languages.js
index 2290568..9507f38 100644
--- a/src/js/languages.js
+++ b/src/js/languages.js
@@ -73,6 +73,7 @@ const languages = {
'crimean tatar': { IETF: 'crh-RU', ISO639: 'crh', ISO3166: 'tr' },
'crioulo upper guinea': { IETF: 'pov-GW', ISO639: 'pov', ISO3166: 'gw' },
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' },
danish: { IETF: 'da-DK', ISO639: 'da', ISO3166: 'dk' },
dari: { IETF: 'prs-AF', ISO639: 'prs', ISO3166: 'af' },
@@ -108,6 +109,7 @@ const languages = {
garo: { IETF: 'grt-IN', ISO639: 'grt', ISO3166: 'in' },
georgian: { IETF: 'ka-GE', ISO639: 'ka', ISO3166: 'ge' },
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' },
glavda: { IETF: 'glw-NG', ISO639: 'glw', ISO3166: 'ng' },
greek: { IETF: 'el-GR', ISO639: 'el', ISO3166: 'gr' },
diff --git a/src/js/renderer.js b/src/js/renderer.js
index c1264cd..db95f3a 100644
--- a/src/js/renderer.js
+++ b/src/js/renderer.js
@@ -1,3 +1,4 @@
+/* eslint-disable no-unused-vars */
const fs = require('fs');
const ini = require('ini');
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 notificationSounds = path.join(__dirname, './sounds/notifications');
-const sttModels = path.join(__dirname, '../speech_to_text_models');
+const notificationSounds = path.join(resourcesPath, main.isPackaged ? './sounds/notifications' : '../sounds/notifications');
+const sttModels = path.join(resourcesPath, main.isPackaged ? './speech_to_text_models' : '../speech_to_text_models');
function reset() {
ipcRenderer.send('restart');
@@ -233,10 +234,10 @@ function showChatMessage(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];
- lastMessage.scrollIntoView({ behavior: 'smooth' });
+ lastMessage.scrollIntoView();
}
function getPostTime() {
diff --git a/src/js/settings.js b/src/js/settings.js
index 4f3afb6..40ffea2 100644
--- a/src/js/settings.js
+++ b/src/js/settings.js
@@ -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() {
// General
@@ -130,10 +130,34 @@ document.body.querySelector('#language').addEventListener('change', () => {
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', () => {
const select = document.querySelector('#TRANSLATE_TO');
settings.LANGUAGE.TRANSLATE_TO_INDEX = select.selectedIndex;
settings.LANGUAGE.TRANSLATE_TO = select.options[select.selectedIndex].value;
+ setTranslateToOptions();
+
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification('Saved primary voice!', 'success');
});
@@ -227,7 +251,9 @@ function createNotification(message = null, type = null) {
}
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.play();
}
@@ -268,6 +294,10 @@ document.body.querySelector('#OPEN_SETTINGS_FILE').addEventListener('click', ()
shell.openExternal(settingsPath);
});
+document.body.querySelector('#Info_VOICE_MODELS_FOLDER').addEventListener('click', () => {
+ shell.openExternal(sttModels);
+});
+
// #region Use Custom theme toggle logic
document.body.querySelector('#USE_CUSTOM_THEME').addEventListener('click', () => {
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');
});
-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', () => {
let toggle = document.getElementById('OUTPUT_TO_TTS').checked;
if (!settings.TTS.USE_TTS) {
@@ -505,8 +527,6 @@ document.body.querySelector('#OUTPUT_TO_TTS').addEventListener('change', () => {
}
settings.LANGUAGE.OUTPUT_TO_TTS = toggle;
- const inputs = document.getElementsByClassName('outputToTtsInput');
- toggleRadio(toggle, inputs);
fs.writeFileSync(settingsPath, ini.stringify(settings));
createNotification(`${toggle ? 'Enabled' : 'Disabled'} Outputting translations to TTS!`, 'success');
});
diff --git a/src/js/sound.js b/src/js/sound.js
index ebbd573..6a570b7 100644
--- a/src/js/sound.js
+++ b/src/js/sound.js
@@ -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 = [];
let status = 0;
@@ -6,7 +6,10 @@ const counter = 0;
const playTTS = data =>
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);
tts.setSinkId(settings.AUDIO.TTS_AUDIO_DEVICE);
@@ -58,7 +61,12 @@ function add(data) {
function playNotificationSound() {
if (settings.AUDIO.USE_NOTIFICATION_SOUNDS) {
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
@@ -93,10 +101,11 @@ async function playVoice(message) {
let voice = settings.TTS.PRIMARY_VOICE;
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);
- if (message.language.ISO639 === secondaryTTSLanguage.ISO639) {
+ if (message.language.detectedLanguage === null || message.language.detectedLanguage.ISO639 === secondaryTTSLanguage.ISO639) {
voice = settings.TTS.SECONDARY_VOICE;
+ textObject.filtered = message.originalMessage ? message.originalMessage : message.filteredMessage;
}
}
diff --git a/src/js/twitch.js b/src/js/twitch.js
index f293d2d..6fe09d0 100644
--- a/src/js/twitch.js
+++ b/src/js/twitch.js
@@ -97,6 +97,7 @@ function ping(element) {
}
async function displayTwitchMessage(logoUrl, username, messageObject, filteredMessage) {
+ messageId++;
const article = document.createElement('article');
article.className = 'msg-container sender';
article.setAttribute('id', messageId);
@@ -144,7 +145,13 @@ async function displayTwitchMessage(logoUrl, username, messageObject, filteredMe
showChatMessage(article);
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;
@@ -159,7 +166,6 @@ async function displayTwitchMessage(logoUrl, username, messageObject, filteredMe
window.article = article;
}
- messageId++;
sound.playNotificationSound();
}
diff --git a/src/main.js b/src/main.js
index 499d2b6..fc584ac 100644
--- a/src/main.js
+++ b/src/main.js
@@ -24,11 +24,6 @@ if (app.isPackaged) {
pythonPath = path.join(resourcesPath, './backend');
}
-// Handle creating/removing shortcuts on Windows when installing/uninstalling.
-if (require('electron-squirrel-startup')) {
- app.quit();
-}
-
async function createWindow() {
if (!fs.existsSync(settingsPath)) {
console.log(resourcesPath);
@@ -164,7 +159,7 @@ async function createIniFile() {
MICROPHONE_ID: 'default',
SELECTED_MICROPHONE: 'default',
MICROPHONE: 0,
- LANGUAGE: 'vosk-model-small-es-0.42'
+ LANGUAGE: ''
},
AUDIO: {
USE_NOTIFICATION_SOUNDS: false,
diff --git a/src/sounds/tts/Amazon_audio.mp3 b/src/sounds/tts/Amazon_audio.mp3
deleted file mode 100644
index e69de29..0000000
diff --git a/src/sounds/tts/Google_audio.mp3 b/src/sounds/tts/Google_audio.mp3
deleted file mode 100644
index d7f31c8..0000000
Binary files a/src/sounds/tts/Google_audio.mp3 and /dev/null differ