Merge branch 'getter/setter' into develop

This commit is contained in:
misygauziya
2023-08-15 22:57:55 +09:00
4 changed files with 663 additions and 532 deletions

367
VRCT.py
View File

@@ -1,10 +1,7 @@
from time import sleep from time import sleep
from os import path as os_path from os import path as os_path
from json import load as json_load
from json import dump as json_dump
from requests import get as requests_get from requests import get as requests_get
from queue import Queue from queue import Queue
import tkinter as tk
import customtkinter import customtkinter
from customtkinter import CTk, CTkFrame, CTkCheckBox, CTkFont, CTkButton, CTkImage, CTkTabview, CTkTextbox, CTkEntry from customtkinter import CTk, CTkFrame, CTkCheckBox, CTkFont, CTkButton, CTkImage, CTkTabview, CTkTextbox, CTkEntry
from PIL.Image import open as Image_open from PIL.Image import open as Image_open
@@ -15,11 +12,12 @@ from utils import print_textbox, thread_fnc, get_localized_text, widget_main_win
from osc_tools import send_typing, send_message, send_test_action, receive_osc_parameters from osc_tools import send_typing, send_message, send_test_action, receive_osc_parameters
from window_config import ToplevelWindowConfig from window_config import ToplevelWindowConfig
from window_information import ToplevelWindowInformation from window_information import ToplevelWindowInformation
from languages import transcription_lang, translators, translation_lang, selectable_languages from languages import transcription_lang
from audio_utils import get_input_device_list, get_output_device_list, get_default_input_device, get_default_output_device from audio_utils import get_input_device_list, get_output_device_list
from audio_recorder import SelectedMicRecorder, SelectedSpeakerRecorder from audio_recorder import SelectedMicRecorder, SelectedSpeakerRecorder
from audio_transcriber import AudioTranscriber from audio_transcriber import AudioTranscriber
from translation import Translator from translation import Translator
from config import config
from notification import notification_xsoverlay_for_vrct from notification import notification_xsoverlay_for_vrct
__version__ = "1.3.2" __version__ = "1.3.2"
@@ -32,241 +30,14 @@ class App(CTk):
self.translator = Translator() self.translator = Translator()
self.keyword_processor = KeywordProcessor() self.keyword_processor = KeywordProcessor()
# init config
self.PATH_CONFIG = "./config.json"
## main window
self.ENABLE_TRANSLATION = False
# self.ENABLE_TRANSCRIPTION_SEND = False
# self.ENABLE_TRANSCRIPTION_RECEIVE = False
self.ENABLE_FOREGROUND = False
## UI
self.TRANSPARENCY = 100
self.APPEARANCE_THEME = "System"
self.UI_SCALING = "100%"
self.FONT_FAMILY = "Yu Gothic UI"
self.UI_LANGUAGE = "en"
## Translation
self.CHOICE_TRANSLATOR = translators[0]
self.INPUT_SOURCE_LANG = list(translation_lang[self.CHOICE_TRANSLATOR]["source"].keys())[0]
self.INPUT_TARGET_LANG = list(translation_lang[self.CHOICE_TRANSLATOR]["target"].keys())[1]
self.OUTPUT_SOURCE_LANG = list(translation_lang[self.CHOICE_TRANSLATOR]["source"].keys())[1]
self.OUTPUT_TARGET_LANG = list(translation_lang[self.CHOICE_TRANSLATOR]["target"].keys())[0]
## Transcription Send
self.CHOICE_MIC_HOST = get_default_input_device()["host"]["name"]
self.CHOICE_MIC_DEVICE = get_default_input_device()["device"]["name"]
self.INPUT_MIC_VOICE_LANGUAGE = list(transcription_lang.keys())[0]
self.INPUT_MIC_ENERGY_THRESHOLD = 300
self.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD = True
self.INPUT_MIC_RECORD_TIMEOUT = 3
self.INPUT_MIC_PHRASE_TIMEOUT = 3
self.INPUT_MIC_MAX_PHRASES = 10
self.INPUT_MIC_WORD_FILTER = []
## Transcription Receive
self.CHOICE_SPEAKER_DEVICE = get_default_output_device()["name"]
self.INPUT_SPEAKER_VOICE_LANGUAGE = list(transcription_lang.keys())[1]
self.INPUT_SPEAKER_ENERGY_THRESHOLD = 300
self.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD = True
self.INPUT_SPEAKER_RECORD_TIMEOUT = 3
self.INPUT_SPEAKER_PHRASE_TIMEOUT = 3
self.INPUT_SPEAKER_MAX_PHRASES = 10
## Parameter
self.OSC_IP_ADDRESS = "127.0.0.1"
self.OSC_PORT = 9000
self.AUTH_KEYS = {
"DeepL(web)": None,
"DeepL(auth)": None,
"Bing(web)": None,
"Google(web)": None,
}
self.MESSAGE_FORMAT = "[message]([translation])"
# Others
self.ENABLE_AUTO_CLEAR_CHATBOX = False
self.ENABLE_OSC = False
self.ENABLE_NOTICE_XSOVERLAY =False
self.UPDATE_FLAG = False
# load config
if os_path.isfile(self.PATH_CONFIG) is not False:
with open(self.PATH_CONFIG, 'r') as fp:
config = json_load(fp)
# main window
# main windowは初期はすべてOFFにする
# if "ENABLE_TRANSLATION" in config.keys():
# if type(config["ENABLE_TRANSLATION"]) is bool:
# self.ENABLE_TRANSLATION = config["ENABLE_TRANSLATION"]
# 環境に依ってマイクとスピーカーを同時起動するとエラーが発生するため、起動時は強制的にOFFにする
# if "ENABLE_TRANSCRIPTION_SEND" in config.keys():
# if type(config["ENABLE_TRANSCRIPTION_SEND"]) is bool:
# self.ENABLE_TRANSCRIPTION_SEND = config["ENABLE_TRANSCRIPTION_SEND"]
# if "ENABLE_TRANSCRIPTION_RECEIVE" in config.keys():
# if type(config["ENABLE_TRANSCRIPTION_RECEIVE"]) is bool:
# self.ENABLE_TRANSCRIPTION_RECEIVE = config["ENABLE_TRANSCRIPTION_RECEIVE"]
# if "ENABLE_FOREGROUND" in config.keys():
# if type(config["ENABLE_FOREGROUND"]) is bool:
# self.ENABLE_FOREGROUND = config["ENABLE_FOREGROUND"]
# tab ui
if "TRANSPARENCY" in config.keys():
if type(config["TRANSPARENCY"]) is int:
if 0 <= config["TRANSPARENCY"] <= 100:
self.TRANSPARENCY = config["TRANSPARENCY"]
if "APPEARANCE_THEME" in config.keys():
if config["APPEARANCE_THEME"] in ["Light", "Dark", "System"]:
self.APPEARANCE_THEME = config["APPEARANCE_THEME"]
if "UI_SCALING" in config.keys():
if config["UI_SCALING"] in ["80%", "90%", "100%", "110%", "120%"]:
self.UI_SCALING = config["UI_SCALING"]
if "FONT_FAMILY" in config.keys():
if config["FONT_FAMILY"] in list(tk.font.families()):
self.FONT_FAMILY = config["FONT_FAMILY"]
if "UI_LANGUAGE" in config.keys():
if config["UI_LANGUAGE"] in list(selectable_languages.keys()):
self.UI_LANGUAGE = config["UI_LANGUAGE"]
# translation
if "CHOICE_TRANSLATOR" in config.keys():
if config["CHOICE_TRANSLATOR"] in list(self.translator.translator_status.keys()):
self.CHOICE_TRANSLATOR = config["CHOICE_TRANSLATOR"]
if "INPUT_SOURCE_LANG" in config.keys():
if config["INPUT_SOURCE_LANG"] in list(translation_lang[self.CHOICE_TRANSLATOR]["source"].keys()):
self.INPUT_SOURCE_LANG = config["INPUT_SOURCE_LANG"]
if "INPUT_TARGET_LANG" in config.keys():
if config["INPUT_TARGET_LANG"] in list(translation_lang[self.CHOICE_TRANSLATOR]["target"].keys()):
self.INPUT_TARGET_LANG = config["INPUT_TARGET_LANG"]
if "OUTPUT_SOURCE_LANG" in config.keys():
if config["OUTPUT_SOURCE_LANG"] in list(translation_lang[self.CHOICE_TRANSLATOR]["source"].keys()):
self.OUTPUT_SOURCE_LANG = config["OUTPUT_SOURCE_LANG"]
if "OUTPUT_TARGET_LANG" in config.keys():
if config["OUTPUT_TARGET_LANG"] in list(translation_lang[self.CHOICE_TRANSLATOR]["target"].keys()):
self.OUTPUT_TARGET_LANG = config["OUTPUT_TARGET_LANG"]
# Transcription
if "CHOICE_MIC_HOST" in config.keys():
if config["CHOICE_MIC_HOST"] in [host for host in get_input_device_list().keys()]:
self.CHOICE_MIC_HOST = config["CHOICE_MIC_HOST"]
if "CHOICE_MIC_DEVICE" in config.keys():
if config["CHOICE_MIC_DEVICE"] in [device["name"] for device in get_input_device_list()[self.CHOICE_MIC_HOST]]:
self.CHOICE_MIC_DEVICE = config["CHOICE_MIC_DEVICE"]
if "INPUT_MIC_VOICE_LANGUAGE" in config.keys():
if config["INPUT_MIC_VOICE_LANGUAGE"] in list(transcription_lang.keys()):
self.INPUT_MIC_VOICE_LANGUAGE = config["INPUT_MIC_VOICE_LANGUAGE"]
if "INPUT_MIC_ENERGY_THRESHOLD" in config.keys():
if type(config["INPUT_MIC_ENERGY_THRESHOLD"]) is int:
self.INPUT_MIC_ENERGY_THRESHOLD = config["INPUT_MIC_ENERGY_THRESHOLD"]
if "INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD" in config.keys():
if type(config["INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD"]) is bool:
self.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD = config["INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD"]
if "INPUT_MIC_RECORD_TIMEOUT" in config.keys():
if type(config["INPUT_MIC_RECORD_TIMEOUT"]) is int:
self.INPUT_MIC_RECORD_TIMEOUT = config["INPUT_MIC_RECORD_TIMEOUT"]
if "INPUT_MIC_PHRASE_TIMEOUT" in config.keys():
if type(config["INPUT_MIC_PHRASE_TIMEOUT"]) is int:
self.INPUT_MIC_PHRASE_TIMEOUT = config["INPUT_MIC_PHRASE_TIMEOUT"]
if "INPUT_MIC_MAX_PHRASES" in config.keys():
if type(config["INPUT_MIC_MAX_PHRASES"]) is int:
self.INPUT_MIC_MAX_PHRASES = config["INPUT_MIC_MAX_PHRASES"]
if "INPUT_MIC_WORD_FILTER" in config.keys():
if type(config["INPUT_MIC_WORD_FILTER"]) is list:
self.INPUT_MIC_WORD_FILTER = config["INPUT_MIC_WORD_FILTER"]
if "CHOICE_SPEAKER_DEVICE" in config.keys():
if config["CHOICE_SPEAKER_DEVICE"] in [device["name"] for device in get_output_device_list()]:
speaker_device = [device for device in get_output_device_list() if device["name"] == config["CHOICE_SPEAKER_DEVICE"]][0]
if get_default_output_device()["index"] == speaker_device["index"]:
self.CHOICE_SPEAKER_DEVICE = config["CHOICE_SPEAKER_DEVICE"]
if "INPUT_SPEAKER_VOICE_LANGUAGE" in config.keys():
if config["INPUT_SPEAKER_VOICE_LANGUAGE"] in list(transcription_lang.keys()):
self.INPUT_SPEAKER_VOICE_LANGUAGE = config["INPUT_SPEAKER_VOICE_LANGUAGE"]
if "INPUT_SPEAKER_ENERGY_THRESHOLD" in config.keys():
if type(config["INPUT_SPEAKER_ENERGY_THRESHOLD"]) is int:
self.INPUT_SPEAKER_ENERGY_THRESHOLD = config["INPUT_SPEAKER_ENERGY_THRESHOLD"]
if "INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD" in config.keys():
if type(config["INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD"]) is bool:
self.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD = config["INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD"]
if "INPUT_SPEAKER_RECORD_TIMEOUT" in config.keys():
if type(config["INPUT_SPEAKER_RECORD_TIMEOUT"]) is int:
self.INPUT_SPEAKER_RECORD_TIMEOUT = config["INPUT_SPEAKER_RECORD_TIMEOUT"]
if "INPUT_SPEAKER_PHRASE_TIMEOUT" in config.keys():
if type(config["INPUT_SPEAKER_PHRASE_TIMEOUT"]) is int:
self.INPUT_SPEAKER_PHRASE_TIMEOUT = config["INPUT_SPEAKER_PHRASE_TIMEOUT"]
if "INPUT_SPEAKER_MAX_PHRASES" in config.keys():
if type(config["INPUT_SPEAKER_MAX_PHRASES"]) is int:
self.INPUT_MIC_MAX_PHRASES = config["INPUT_SPEAKER_MAX_PHRASES"]
# Parameter
if "OSC_IP_ADDRESS" in config.keys():
if type(config["OSC_IP_ADDRESS"]) is str:
self.OSC_IP_ADDRESS = config["OSC_IP_ADDRESS"]
if "OSC_PORT" in config.keys():
if type(config["OSC_PORT"]) is int:
self.OSC_PORT = config["OSC_PORT"]
if "AUTH_KEYS" in config.keys():
if type(config["AUTH_KEYS"]) is dict:
if set(config["AUTH_KEYS"].keys()) == set(self.AUTH_KEYS.keys()):
for key, value in config["AUTH_KEYS"].items():
if type(value) is str:
self.AUTH_KEYS[key] = config["AUTH_KEYS"][key]
if "MESSAGE_FORMAT" in config.keys():
if type(config["MESSAGE_FORMAT"]) is str:
self.MESSAGE_FORMAT = config["MESSAGE_FORMAT"]
# Others
if "ENABLE_AUTO_CLEAR_CHATBOX" in config.keys():
if type(config["ENABLE_AUTO_CLEAR_CHATBOX"]) is bool:
self.ENABLE_AUTO_CLEAR_CHATBOX = config["ENABLE_AUTO_CLEAR_CHATBOX"]
if "ENABLE_NOTICE_XSOVERLAY" in config.keys():
if type(config["ENABLE_NOTICE_XSOVERLAY"]) is bool:
self.ENABLE_NOTICE_XSOVERLAY = config["ENABLE_NOTICE_XSOVERLAY"]
with open(self.PATH_CONFIG, 'w') as fp:
config = {
# "ENABLE_TRANSLATION": self.ENABLE_TRANSLATION,
# "ENABLE_TRANSCRIPTION_SEND": self.ENABLE_TRANSCRIPTION_SEND,
# "ENABLE_TRANSCRIPTION_RECEIVE": self.ENABLE_TRANSCRIPTION_RECEIVE,
# "ENABLE_FOREGROUND": self.ENABLE_FOREGROUND,
"TRANSPARENCY": self.TRANSPARENCY,
"APPEARANCE_THEME": self.APPEARANCE_THEME,
"UI_SCALING": self.UI_SCALING,
"UI_LANGUAGE": self.UI_LANGUAGE,
"FONT_FAMILY": self.FONT_FAMILY,
"CHOICE_TRANSLATOR": self.CHOICE_TRANSLATOR,
"INPUT_SOURCE_LANG": self.INPUT_SOURCE_LANG,
"INPUT_TARGET_LANG": self.INPUT_TARGET_LANG,
"OUTPUT_SOURCE_LANG": self.OUTPUT_SOURCE_LANG,
"OUTPUT_TARGET_LANG": self.OUTPUT_TARGET_LANG,
"CHOICE_MIC_HOST": self.CHOICE_MIC_HOST,
"CHOICE_MIC_DEVICE": self.CHOICE_MIC_DEVICE,
"INPUT_MIC_VOICE_LANGUAGE": self.INPUT_MIC_VOICE_LANGUAGE,
"INPUT_MIC_ENERGY_THRESHOLD": self.INPUT_MIC_ENERGY_THRESHOLD,
"INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD": self.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD,
"INPUT_MIC_RECORD_TIMEOUT": self.INPUT_MIC_RECORD_TIMEOUT,
"INPUT_MIC_PHRASE_TIMEOUT": self.INPUT_MIC_PHRASE_TIMEOUT,
"INPUT_MIC_MAX_PHRASES": self.INPUT_MIC_MAX_PHRASES,
"INPUT_MIC_WORD_FILTER": self.INPUT_MIC_WORD_FILTER,
"CHOICE_SPEAKER_DEVICE": self.CHOICE_SPEAKER_DEVICE,
"INPUT_SPEAKER_VOICE_LANGUAGE": self.INPUT_SPEAKER_VOICE_LANGUAGE,
"INPUT_SPEAKER_ENERGY_THRESHOLD": self.INPUT_SPEAKER_ENERGY_THRESHOLD,
"INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD": self.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD,
"INPUT_SPEAKER_RECORD_TIMEOUT": self.INPUT_SPEAKER_RECORD_TIMEOUT,
"INPUT_SPEAKER_PHRASE_TIMEOUT": self.INPUT_SPEAKER_PHRASE_TIMEOUT,
"INPUT_SPEAKER_MAX_PHRASES": self.INPUT_SPEAKER_MAX_PHRASES,
"OSC_IP_ADDRESS": self.OSC_IP_ADDRESS,
"OSC_PORT": self.OSC_PORT,
"AUTH_KEYS": self.AUTH_KEYS,
"MESSAGE_FORMAT": self.MESSAGE_FORMAT,
"ENABLE_AUTO_CLEAR_CHATBOX": self.ENABLE_AUTO_CLEAR_CHATBOX,
"ENABLE_NOTICE_XSOVERLAY": self.ENABLE_NOTICE_XSOVERLAY,
}
json_dump(config, fp, indent=4)
## set UI theme ## set UI theme
customtkinter.set_appearance_mode(self.APPEARANCE_THEME) customtkinter.set_appearance_mode(config.APPEARANCE_THEME)
customtkinter.set_default_color_theme("blue") customtkinter.set_default_color_theme("blue")
## flags
self.ENABLE_OSC = False
self.UPDATE_FLAG = False
# init main window # init main window
self.iconbitmap(os_path.join(os_path.dirname(__file__), "img", "app.ico")) self.iconbitmap(os_path.join(os_path.dirname(__file__), "img", "app.ico"))
self.title("VRCT") self.title("VRCT")
@@ -289,7 +60,7 @@ class App(CTk):
onvalue=True, onvalue=True,
offvalue=False, offvalue=False,
command=self.checkbox_translation_callback, command=self.checkbox_translation_callback,
font=CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=config.FONT_FAMILY)
) )
self.checkbox_translation.grid(row=0, column=0, columnspan=2, padx=10, pady=(5, 5), sticky="we") self.checkbox_translation.grid(row=0, column=0, columnspan=2, padx=10, pady=(5, 5), sticky="we")
@@ -300,7 +71,7 @@ class App(CTk):
onvalue=True, onvalue=True,
offvalue=False, offvalue=False,
command=self.checkbox_transcription_send_callback, command=self.checkbox_transcription_send_callback,
font=CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=config.FONT_FAMILY)
) )
self.checkbox_transcription_send.grid(row=1, column=0, columnspan=2, padx=10, pady=(5, 5), sticky="we") self.checkbox_transcription_send.grid(row=1, column=0, columnspan=2, padx=10, pady=(5, 5), sticky="we")
@@ -311,7 +82,7 @@ class App(CTk):
onvalue=True, onvalue=True,
offvalue=False, offvalue=False,
command=self.checkbox_transcription_receive_callback, command=self.checkbox_transcription_receive_callback,
font=CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=config.FONT_FAMILY)
) )
self.checkbox_transcription_receive.grid(row=2, column=0, columnspan=2, padx=10, pady=(5, 5), sticky="we") self.checkbox_transcription_receive.grid(row=2, column=0, columnspan=2, padx=10, pady=(5, 5), sticky="we")
@@ -322,7 +93,7 @@ class App(CTk):
onvalue=True, onvalue=True,
offvalue=False, offvalue=False,
command=self.checkbox_foreground_callback, command=self.checkbox_foreground_callback,
font=CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=config.FONT_FAMILY)
) )
self.checkbox_foreground.grid(row=3, column=0, columnspan=2, padx=10, pady=(5, 5), sticky="we") self.checkbox_foreground.grid(row=3, column=0, columnspan=2, padx=10, pady=(5, 5), sticky="we")
@@ -347,7 +118,7 @@ class App(CTk):
self.button_config.grid(row=5, column=1, padx=(5, 10), pady=(5, 5), sticky="wse") self.button_config.grid(row=5, column=1, padx=(5, 10), pady=(5, 5), sticky="wse")
# load ui language data # load ui language data
language_yaml_data = get_localized_text(f"{self.UI_LANGUAGE}") language_yaml_data = get_localized_text(f"{config.UI_LANGUAGE}")
# add tabview textbox # add tabview textbox
self.add_tabview_logs(language_yaml_data) self.add_tabview_logs(language_yaml_data)
@@ -355,13 +126,13 @@ class App(CTk):
self.entry_message_box = CTkEntry( self.entry_message_box = CTkEntry(
self, self,
placeholder_text="message", placeholder_text="message",
font=CTkFont(family=self.FONT_FAMILY), font=CTkFont(family=config.FONT_FAMILY),
) )
self.entry_message_box.grid(row=1, column=1, columnspan=2, padx=5, pady=(5, 10), sticky="nsew") self.entry_message_box.grid(row=1, column=1, columnspan=2, padx=5, pady=(5, 10), sticky="nsew")
# set default values # set default values
## set translator ## set translator
if self.translator.authentication(self.CHOICE_TRANSLATOR, self.AUTH_KEYS[self.CHOICE_TRANSLATOR]) is False: if self.translator.authentication(config.CHOICE_TRANSLATOR, config.AUTH_KEYS[config.CHOICE_TRANSLATOR]) is False:
# error update Auth key # error update Auth key
print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR")
print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR")
@@ -395,7 +166,7 @@ class App(CTk):
# self.checkbox_foreground.deselect() # self.checkbox_foreground.deselect()
## set word filter ## set word filter
for f in self.INPUT_MIC_WORD_FILTER: for f in config.INPUT_MIC_WORD_FILTER:
self.keyword_processor.add_keyword(f) self.keyword_processor.add_keyword(f)
## set bind entry message box ## set bind entry message box
@@ -404,10 +175,10 @@ class App(CTk):
self.entry_message_box.bind("<Leave>", self.entry_message_box_leave) self.entry_message_box.bind("<Leave>", self.entry_message_box_leave)
## set transparency for main window ## set transparency for main window
self.wm_attributes("-alpha", self.TRANSPARENCY/100) self.wm_attributes("-alpha", config.TRANSPARENCY/100)
## set UI scale ## set UI scale
new_scaling_float = int(self.UI_SCALING.replace("%", "")) / 100 new_scaling_float = int(config.UI_SCALING.replace("%", "")) / 100
customtkinter.set_widget_scaling(new_scaling_float) customtkinter.set_widget_scaling(new_scaling_float)
# delete window # delete window
@@ -456,8 +227,7 @@ class App(CTk):
self.information_window.focus() self.information_window.focus()
def checkbox_translation_callback(self): def checkbox_translation_callback(self):
self.ENABLE_TRANSLATION = self.checkbox_translation.get() if self.checkbox_translation.get() is True:
if self.ENABLE_TRANSLATION is True:
print_textbox(self.textbox_message_log, "Start translation", "INFO") print_textbox(self.textbox_message_log, "Start translation", "INFO")
print_textbox(self.textbox_message_system_log, "Start translation", "INFO") print_textbox(self.textbox_message_system_log, "Start translation", "INFO")
else: else:
@@ -466,22 +236,22 @@ class App(CTk):
def transcription_send_start(self): def transcription_send_start(self):
self.mic_audio_queue = Queue() self.mic_audio_queue = Queue()
mic_device = [device for device in get_input_device_list()[self.CHOICE_MIC_HOST] if device["name"] == self.CHOICE_MIC_DEVICE][0] mic_device = [device for device in get_input_device_list()[config.CHOICE_MIC_HOST] if device["name"] == config.CHOICE_MIC_DEVICE][0]
self.mic_audio_recorder = SelectedMicRecorder( self.mic_audio_recorder = SelectedMicRecorder(
mic_device, mic_device,
self.INPUT_MIC_ENERGY_THRESHOLD, config.INPUT_MIC_ENERGY_THRESHOLD,
self.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD, config.INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD,
self.INPUT_MIC_RECORD_TIMEOUT, config.INPUT_MIC_RECORD_TIMEOUT,
) )
self.mic_audio_recorder.record_into_queue(self.mic_audio_queue) self.mic_audio_recorder.record_into_queue(self.mic_audio_queue)
self.mic_transcriber = AudioTranscriber( self.mic_transcriber = AudioTranscriber(
speaker=False, speaker=False,
source=self.mic_audio_recorder.source, source=self.mic_audio_recorder.source,
phrase_timeout=self.INPUT_MIC_PHRASE_TIMEOUT, phrase_timeout=config.INPUT_MIC_PHRASE_TIMEOUT,
max_phrases=self.INPUT_MIC_MAX_PHRASES, max_phrases=config.INPUT_MIC_MAX_PHRASES,
) )
def mic_transcript_to_chatbox(): def mic_transcript_to_chatbox():
self.mic_transcriber.transcribe_audio_queue(self.mic_audio_queue, transcription_lang[self.INPUT_MIC_VOICE_LANGUAGE]) self.mic_transcriber.transcribe_audio_queue(self.mic_audio_queue, transcription_lang[config.INPUT_MIC_VOICE_LANGUAGE])
message = self.mic_transcriber.get_transcript() message = self.mic_transcriber.get_transcript()
if len(message) > 0: if len(message) > 0:
# word filter # word filter
@@ -493,23 +263,23 @@ class App(CTk):
# translate # translate
if self.checkbox_translation.get() is False: if self.checkbox_translation.get() is False:
voice_message = f"{message}" voice_message = f"{message}"
elif self.translator.translator_status[self.CHOICE_TRANSLATOR] is False: elif self.translator.translator_status[config.CHOICE_TRANSLATOR] is False:
print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR")
print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR")
voice_message = f"{message}" voice_message = f"{message}"
else: else:
result = self.translator.translate( result = self.translator.translate(
translator_name=self.CHOICE_TRANSLATOR, translator_name=config.CHOICE_TRANSLATOR,
source_language=self.INPUT_SOURCE_LANG, source_language=config.INPUT_SOURCE_LANG,
target_language=self.INPUT_TARGET_LANG, target_language=config.INPUT_TARGET_LANG,
message=message message=message
) )
voice_message = self.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result) voice_message = config.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result)
if self.checkbox_transcription_send.get() is True: if self.checkbox_transcription_send.get() is True:
if self.ENABLE_OSC is True: if self.ENABLE_OSC is True:
# send OSC message # send OSC message
send_message(voice_message, self.OSC_IP_ADDRESS, self.OSC_PORT) send_message(voice_message, config.OSC_IP_ADDRESS, config.OSC_PORT)
else: else:
print_textbox(self.textbox_message_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR") print_textbox(self.textbox_message_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR")
print_textbox(self.textbox_message_system_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR") print_textbox(self.textbox_message_system_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR")
@@ -564,48 +334,48 @@ class App(CTk):
def transcription_receive_start(self): def transcription_receive_start(self):
self.spk_audio_queue = Queue() self.spk_audio_queue = Queue()
spk_device = [device for device in get_output_device_list() if device["name"] == self.CHOICE_SPEAKER_DEVICE][0] spk_device = [device for device in get_output_device_list() if device["name"] == config.CHOICE_SPEAKER_DEVICE][0]
self.spk_audio_recorder = SelectedSpeakerRecorder( self.spk_audio_recorder = SelectedSpeakerRecorder(
spk_device, spk_device,
self.INPUT_SPEAKER_ENERGY_THRESHOLD, config.INPUT_SPEAKER_ENERGY_THRESHOLD,
self.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD, config.INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD,
self.INPUT_SPEAKER_RECORD_TIMEOUT, config.INPUT_SPEAKER_RECORD_TIMEOUT,
) )
self.spk_audio_recorder.record_into_queue(self.spk_audio_queue) self.spk_audio_recorder.record_into_queue(self.spk_audio_queue)
self.spk_transcriber = AudioTranscriber( self.spk_transcriber = AudioTranscriber(
speaker=True, speaker=True,
source=self.spk_audio_recorder.source, source=self.spk_audio_recorder.source,
phrase_timeout=self.INPUT_SPEAKER_PHRASE_TIMEOUT, phrase_timeout=config.INPUT_SPEAKER_PHRASE_TIMEOUT,
max_phrases=self.INPUT_SPEAKER_MAX_PHRASES, max_phrases=config.INPUT_SPEAKER_MAX_PHRASES,
) )
def spk_transcript_to_textbox(): def spk_transcript_to_textbox():
self.spk_transcriber.transcribe_audio_queue(self.spk_audio_queue, transcription_lang[self.INPUT_SPEAKER_VOICE_LANGUAGE]) self.spk_transcriber.transcribe_audio_queue(self.spk_audio_queue, transcription_lang[config.INPUT_SPEAKER_VOICE_LANGUAGE])
message = self.spk_transcriber.get_transcript() message = self.spk_transcriber.get_transcript()
if len(message) > 0: if len(message) > 0:
# translate # translate
if self.checkbox_translation.get() is False: if self.checkbox_translation.get() is False:
voice_message = f"{message}" voice_message = f"{message}"
elif self.translator.translator_status[self.CHOICE_TRANSLATOR] is False: elif self.translator.translator_status[config.CHOICE_TRANSLATOR] is False:
print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR")
print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR")
voice_message = f"{message}" voice_message = f"{message}"
else: else:
result = self.translator.translate( result = self.translator.translate(
translator_name=self.CHOICE_TRANSLATOR, translator_name=config.CHOICE_TRANSLATOR,
source_language=self.OUTPUT_SOURCE_LANG, source_language=config.OUTPUT_SOURCE_LANG,
target_language=self.OUTPUT_TARGET_LANG, target_language=config.OUTPUT_TARGET_LANG,
message=message message=message
) )
voice_message = self.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result) voice_message = config.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result)
# send OSC message # send OSC message
# send_message(voice_message, self.OSC_IP_ADDRESS, self.OSC_PORT) # send_message(voice_message, config.OSC_IP_ADDRESS, self.OSC_PORT)
if self.checkbox_transcription_receive.get() is True: if self.checkbox_transcription_receive.get() is True:
# update textbox message receive log # update textbox message receive log
print_textbox(self.textbox_message_log, f"{voice_message}", "RECEIVE") print_textbox(self.textbox_message_log, f"{voice_message}", "RECEIVE")
print_textbox(self.textbox_message_receive_log, f"{voice_message}", "RECEIVE") print_textbox(self.textbox_message_receive_log, f"{voice_message}", "RECEIVE")
if self.ENABLE_NOTICE_XSOVERLAY is True: if config.ENABLE_NOTICE_XSOVERLAY is True:
notification_xsoverlay_for_vrct(content=f"{voice_message}") notification_xsoverlay_for_vrct(content=f"{voice_message}")
self.spk_print_transcript = thread_fnc(spk_transcript_to_textbox) self.spk_print_transcript = thread_fnc(spk_transcript_to_textbox)
@@ -675,8 +445,7 @@ class App(CTk):
th_transcription_receive_stop.start() th_transcription_receive_stop.start()
def checkbox_foreground_callback(self): def checkbox_foreground_callback(self):
self.ENABLE_FOREGROUND = self.checkbox_foreground.get() if self.checkbox_foreground.get():
if self.ENABLE_FOREGROUND:
self.attributes("-topmost", True) self.attributes("-topmost", True)
print_textbox(self.textbox_message_log, "Start foreground", "INFO") print_textbox(self.textbox_message_log, "Start foreground", "INFO")
print_textbox(self.textbox_message_system_log, "Start foreground", "INFO") print_textbox(self.textbox_message_system_log, "Start foreground", "INFO")
@@ -686,24 +455,22 @@ class App(CTk):
print_textbox(self.textbox_message_system_log, "Stop foreground", "INFO") print_textbox(self.textbox_message_system_log, "Stop foreground", "INFO")
def foreground_start(self): def foreground_start(self):
self.ENABLE_FOREGROUND = self.checkbox_foreground.get() if self.checkbox_foreground.get():
if self.ENABLE_FOREGROUND:
self.attributes("-topmost", True) self.attributes("-topmost", True)
print_textbox(self.textbox_message_log, "Start foreground", "INFO") print_textbox(self.textbox_message_log, "Start foreground", "INFO")
print_textbox(self.textbox_message_system_log, "Start foreground", "INFO") print_textbox(self.textbox_message_system_log, "Start foreground", "INFO")
def foreground_stop(self): def foreground_stop(self):
if self.ENABLE_FOREGROUND: if self.checkbox_foreground.get():
self.attributes("-topmost", False) self.attributes("-topmost", False)
print_textbox(self.textbox_message_log, "Stop foreground", "INFO") print_textbox(self.textbox_message_log, "Stop foreground", "INFO")
print_textbox(self.textbox_message_system_log, "Stop foreground", "INFO") print_textbox(self.textbox_message_system_log, "Stop foreground", "INFO")
self.ENABLE_FOREGROUND = False
def entry_message_box_press_key_enter(self, event): def entry_message_box_press_key_enter(self, event):
# send OSC typing # send OSC typing
send_typing(False, self.OSC_IP_ADDRESS, self.OSC_PORT) send_typing(False, config.OSC_IP_ADDRESS, config.OSC_PORT)
if self.ENABLE_FOREGROUND: if self.checkbox_foreground.get():
self.attributes("-topmost", True) self.attributes("-topmost", True)
message = self.entry_message_box.get() message = self.entry_message_box.get()
@@ -711,22 +478,22 @@ class App(CTk):
# translate # translate
if self.checkbox_translation.get() is False: if self.checkbox_translation.get() is False:
chat_message = f"{message}" chat_message = f"{message}"
elif self.translator.translator_status[self.CHOICE_TRANSLATOR] is False: elif self.translator.translator_status[config.CHOICE_TRANSLATOR] is False:
print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.textbox_message_log, "Auth Key or language setting is incorrect", "ERROR")
print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR") print_textbox(self.textbox_message_system_log, "Auth Key or language setting is incorrect", "ERROR")
chat_message = f"{message}" chat_message = f"{message}"
else: else:
result = self.translator.translate( result = self.translator.translate(
translator_name=self.CHOICE_TRANSLATOR, translator_name=config.CHOICE_TRANSLATOR,
source_language=self.INPUT_SOURCE_LANG, source_language=config.INPUT_SOURCE_LANG,
target_language=self.INPUT_TARGET_LANG, target_language=config.INPUT_TARGET_LANG,
message=message message=message
) )
chat_message = self.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result) chat_message = config.MESSAGE_FORMAT.replace("[message]", message).replace("[translation]", result)
# send OSC message # send OSC message
if self.ENABLE_OSC is True: if self.ENABLE_OSC is True:
send_message(chat_message, self.OSC_IP_ADDRESS, self.OSC_PORT) send_message(chat_message, config.OSC_IP_ADDRESS, config.OSC_PORT)
else: else:
print_textbox(self.textbox_message_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR") print_textbox(self.textbox_message_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR")
print_textbox(self.textbox_message_system_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR") print_textbox(self.textbox_message_system_log, "OSC is not enabled, please enable OSC and rejoin.", "ERROR")
@@ -736,7 +503,7 @@ class App(CTk):
print_textbox(self.textbox_message_send_log, f"{chat_message}", "SEND") print_textbox(self.textbox_message_send_log, f"{chat_message}", "SEND")
# delete message in entry message box # delete message in entry message box
if self.ENABLE_AUTO_CLEAR_CHATBOX is True: if config.ENABLE_AUTO_CLEAR_CHATBOX is True:
self.entry_message_box.delete(0, customtkinter.END) self.entry_message_box.delete(0, customtkinter.END)
BREAK_KEYSYM_LIST = [ BREAK_KEYSYM_LIST = [
@@ -745,8 +512,8 @@ class App(CTk):
] ]
def entry_message_box_press_key_any(self, event): def entry_message_box_press_key_any(self, event):
# send OSC typing # send OSC typing
send_typing(True, self.OSC_IP_ADDRESS, self.OSC_PORT) send_typing(True, config.OSC_IP_ADDRESS, config.OSC_PORT)
if self.ENABLE_FOREGROUND: if self.checkbox_foreground.get():
self.attributes("-topmost", False) self.attributes("-topmost", False)
if event.keysym != "??": if event.keysym != "??":
@@ -756,8 +523,8 @@ class App(CTk):
def entry_message_box_leave(self, event): def entry_message_box_leave(self, event):
# send OSC typing # send OSC typing
send_typing(False, self.OSC_IP_ADDRESS, self.OSC_PORT) send_typing(False, config.OSC_IP_ADDRESS, config.OSC_PORT)
if self.ENABLE_FOREGROUND: if self.checkbox_foreground.get():
self.attributes("-topmost", True) self.attributes("-topmost", True)
def delete_window(self): def delete_window(self):
@@ -783,7 +550,7 @@ class App(CTk):
self.tabview_logs.add(main_tab_title_receive) self.tabview_logs.add(main_tab_title_receive)
self.tabview_logs.add(main_tab_title_system) self.tabview_logs.add(main_tab_title_system)
self.tabview_logs.grid(row=0, column=1, padx=0, pady=0, sticky="nsew") self.tabview_logs.grid(row=0, column=1, padx=0, pady=0, sticky="nsew")
self.tabview_logs._segmented_button.configure(font=CTkFont(family=self.FONT_FAMILY)) self.tabview_logs._segmented_button.configure(font=CTkFont(family=config.FONT_FAMILY))
self.tabview_logs._segmented_button.grid(sticky="W") self.tabview_logs._segmented_button.grid(sticky="W")
self.tabview_logs.tab(main_tab_title_log).grid_rowconfigure(0, weight=1) self.tabview_logs.tab(main_tab_title_log).grid_rowconfigure(0, weight=1)
self.tabview_logs.tab(main_tab_title_log).grid_columnconfigure(0, weight=1) self.tabview_logs.tab(main_tab_title_log).grid_columnconfigure(0, weight=1)
@@ -798,7 +565,7 @@ class App(CTk):
# add textbox message log # add textbox message log
self.textbox_message_log = CTkTextbox( self.textbox_message_log = CTkTextbox(
self.tabview_logs.tab(main_tab_title_log), self.tabview_logs.tab(main_tab_title_log),
font=CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=config.FONT_FAMILY)
) )
self.textbox_message_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew") self.textbox_message_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
self.textbox_message_log.configure(state='disabled') self.textbox_message_log.configure(state='disabled')
@@ -806,7 +573,7 @@ class App(CTk):
# add textbox message send log # add textbox message send log
self.textbox_message_send_log = CTkTextbox( self.textbox_message_send_log = CTkTextbox(
self.tabview_logs.tab(main_tab_title_send), self.tabview_logs.tab(main_tab_title_send),
font=CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=config.FONT_FAMILY)
) )
self.textbox_message_send_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew") self.textbox_message_send_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
self.textbox_message_send_log.configure(state='disabled') self.textbox_message_send_log.configure(state='disabled')
@@ -814,7 +581,7 @@ class App(CTk):
# add textbox message receive log # add textbox message receive log
self.textbox_message_receive_log = CTkTextbox( self.textbox_message_receive_log = CTkTextbox(
self.tabview_logs.tab(main_tab_title_receive), self.tabview_logs.tab(main_tab_title_receive),
font=CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=config.FONT_FAMILY)
) )
self.textbox_message_receive_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew") self.textbox_message_receive_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
self.textbox_message_receive_log.configure(state='disabled') self.textbox_message_receive_log.configure(state='disabled')
@@ -822,7 +589,7 @@ class App(CTk):
# add textbox message system log # add textbox message system log
self.textbox_message_system_log = CTkTextbox( self.textbox_message_system_log = CTkTextbox(
self.tabview_logs.tab(main_tab_title_system), self.tabview_logs.tab(main_tab_title_system),
font=CTkFont(family=self.FONT_FAMILY) font=CTkFont(family=config.FONT_FAMILY)
) )
self.textbox_message_system_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew") self.textbox_message_system_log.grid(row=0, column=0, padx=0, pady=0, sticky="nsew")
self.textbox_message_system_log.configure(state='disabled') self.textbox_message_system_log.configure(state='disabled')

410
config.py Normal file
View File

@@ -0,0 +1,410 @@
import inspect
from os import path as os_path
from json import load as json_load
from json import dump as json_dump
import tkinter as tk
from tkinter import font
from utils import save_json
from languages import transcription_lang, translators, translation_lang, selectable_languages
from audio_utils import get_input_device_list, get_output_device_list, get_default_input_device, get_default_output_device
class Config:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(Config, cls).__new__(cls)
cls._instance.init_config()
cls._instance.load_config()
return cls._instance
@property
def PATH_CONFIG(self):
return self._PATH_CONFIG
@property
def TRANSPARENCY(self):
return self._TRANSPARENCY
@TRANSPARENCY.setter
def TRANSPARENCY(self, value):
if type(value) is int and 0 <= value <= 100:
self._TRANSPARENCY = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def APPEARANCE_THEME(self):
return self._APPEARANCE_THEME
@APPEARANCE_THEME.setter
def APPEARANCE_THEME(self, value):
if value in ["Light", "Dark", "System"]:
self._APPEARANCE_THEME = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def UI_SCALING(self):
return self._UI_SCALING
@UI_SCALING.setter
def UI_SCALING(self, value):
if value in ["80%", "90%", "100%", "110%", "120%"]:
self._UI_SCALING = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def FONT_FAMILY(self):
return self._FONT_FAMILY
@FONT_FAMILY.setter
def FONT_FAMILY(self, value):
root = tk.Tk()
root.withdraw()
if value in list(font.families()):
self._FONT_FAMILY = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
root.destroy()
@property
def UI_LANGUAGE(self):
return self._UI_LANGUAGE
@UI_LANGUAGE.setter
def UI_LANGUAGE(self, value):
if value in list(selectable_languages.keys()):
self._UI_LANGUAGE = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def CHOICE_TRANSLATOR(self):
return self._CHOICE_TRANSLATOR
@CHOICE_TRANSLATOR.setter
def CHOICE_TRANSLATOR(self, value):
if value in translators:
self._CHOICE_TRANSLATOR = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_SOURCE_LANG(self):
return self._INPUT_SOURCE_LANG
@INPUT_SOURCE_LANG.setter
def INPUT_SOURCE_LANG(self, value):
if value in list(translation_lang[self.CHOICE_TRANSLATOR]["source"].keys()):
self._INPUT_SOURCE_LANG = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_TARGET_LANG(self):
return self._INPUT_TARGET_LANG
@INPUT_TARGET_LANG.setter
def INPUT_TARGET_LANG(self, value):
if value in list(translation_lang[self.CHOICE_TRANSLATOR]["target"].keys()):
self._INPUT_TARGET_LANG = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def OUTPUT_SOURCE_LANG(self):
return self._OUTPUT_SOURCE_LANG
@OUTPUT_SOURCE_LANG.setter
def OUTPUT_SOURCE_LANG(self, value):
if value in list(translation_lang[self.CHOICE_TRANSLATOR]["source"].keys()):
self._OUTPUT_SOURCE_LANG = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def OUTPUT_TARGET_LANG(self):
return self._OUTPUT_TARGET_LANG
@OUTPUT_TARGET_LANG.setter
def OUTPUT_TARGET_LANG(self, value):
if value in list(translation_lang[self.CHOICE_TRANSLATOR]["target"].keys()):
self._OUTPUT_TARGET_LANG = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def CHOICE_MIC_HOST(self):
return self._CHOICE_MIC_HOST
@CHOICE_MIC_HOST.setter
def CHOICE_MIC_HOST(self, value):
if value in [host for host in get_input_device_list().keys()]:
self._CHOICE_MIC_HOST = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def CHOICE_MIC_DEVICE(self):
return self._CHOICE_MIC_DEVICE
@CHOICE_MIC_DEVICE.setter
def CHOICE_MIC_DEVICE(self, value):
if value in [device["name"] for device in get_input_device_list()[self.CHOICE_MIC_HOST]]:
self._CHOICE_MIC_DEVICE = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_MIC_VOICE_LANGUAGE(self):
return self._INPUT_MIC_VOICE_LANGUAGE
@INPUT_MIC_VOICE_LANGUAGE.setter
def INPUT_MIC_VOICE_LANGUAGE(self, value):
if value in list(transcription_lang.keys()):
self._INPUT_MIC_VOICE_LANGUAGE = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_MIC_ENERGY_THRESHOLD(self):
return self._INPUT_MIC_ENERGY_THRESHOLD
@INPUT_MIC_ENERGY_THRESHOLD.setter
def INPUT_MIC_ENERGY_THRESHOLD(self, value):
if type(value) is int:
self._INPUT_MIC_ENERGY_THRESHOLD = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD(self):
return self._INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD
@INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD.setter
def INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD(self, value):
if type(value) is bool:
self._INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_MIC_RECORD_TIMEOUT(self):
return self._INPUT_MIC_RECORD_TIMEOUT
@INPUT_MIC_RECORD_TIMEOUT.setter
def INPUT_MIC_RECORD_TIMEOUT(self, value):
if type(value) is int:
self._INPUT_MIC_RECORD_TIMEOUT = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_MIC_PHRASE_TIMEOUT(self):
return self._INPUT_MIC_PHRASE_TIMEOUT
@INPUT_MIC_PHRASE_TIMEOUT.setter
def INPUT_MIC_PHRASE_TIMEOUT(self, value):
if type(value) is int:
self._INPUT_MIC_PHRASE_TIMEOUT = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_MIC_MAX_PHRASES(self):
return self._INPUT_MIC_MAX_PHRASES
@INPUT_MIC_MAX_PHRASES.setter
def INPUT_MIC_MAX_PHRASES(self, value):
if type(value) is int:
self._INPUT_MIC_MAX_PHRASES = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_MIC_WORD_FILTER(self):
return self._INPUT_MIC_WORD_FILTER
@INPUT_MIC_WORD_FILTER.setter
def INPUT_MIC_WORD_FILTER(self, value):
if type(value) is list:
self._INPUT_MIC_WORD_FILTER = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def CHOICE_SPEAKER_DEVICE(self):
return self._CHOICE_SPEAKER_DEVICE
@CHOICE_SPEAKER_DEVICE.setter
def CHOICE_SPEAKER_DEVICE(self, value):
if value in [device["name"] for device in get_output_device_list()]:
speaker_device = [device for device in get_output_device_list() if device["name"] == value][0]
if get_default_output_device()["index"] == speaker_device["index"]:
self._CHOICE_SPEAKER_DEVICE = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_SPEAKER_VOICE_LANGUAGE(self):
return self._INPUT_SPEAKER_VOICE_LANGUAGE
@INPUT_SPEAKER_VOICE_LANGUAGE.setter
def INPUT_SPEAKER_VOICE_LANGUAGE(self, value):
if value in list(transcription_lang.keys()):
self._INPUT_SPEAKER_VOICE_LANGUAGE = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_SPEAKER_ENERGY_THRESHOLD(self):
return self._INPUT_SPEAKER_ENERGY_THRESHOLD
@INPUT_SPEAKER_ENERGY_THRESHOLD.setter
def INPUT_SPEAKER_ENERGY_THRESHOLD(self, value):
if type(value) is int:
self._INPUT_SPEAKER_ENERGY_THRESHOLD = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD(self):
return self._INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD
@INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD.setter
def INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD(self, value):
if type(value) is bool:
self._INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_SPEAKER_RECORD_TIMEOUT(self):
return self._INPUT_SPEAKER_RECORD_TIMEOUT
@INPUT_SPEAKER_RECORD_TIMEOUT.setter
def INPUT_SPEAKER_RECORD_TIMEOUT(self, value):
if type(value) is int:
self._INPUT_SPEAKER_RECORD_TIMEOUT = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_SPEAKER_PHRASE_TIMEOUT(self):
return self._INPUT_SPEAKER_PHRASE_TIMEOUT
@INPUT_SPEAKER_PHRASE_TIMEOUT.setter
def INPUT_SPEAKER_PHRASE_TIMEOUT(self, value):
if type(value) is int:
self._INPUT_SPEAKER_PHRASE_TIMEOUT = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def INPUT_SPEAKER_MAX_PHRASES(self):
return self._INPUT_SPEAKER_MAX_PHRASES
@INPUT_SPEAKER_MAX_PHRASES.setter
def INPUT_SPEAKER_MAX_PHRASES(self, value):
if type(value) is int:
self._INPUT_SPEAKER_MAX_PHRASES = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def OSC_IP_ADDRESS(self):
return self._OSC_IP_ADDRESS
@OSC_IP_ADDRESS.setter
def OSC_IP_ADDRESS(self, value):
if type(value) is str:
self._OSC_IP_ADDRESS = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def OSC_PORT(self):
return self._OSC_PORT
@OSC_PORT.setter
def OSC_PORT(self, value):
if type(value) is int:
self._OSC_PORT = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def AUTH_KEYS(self):
return self._AUTH_KEYS
@AUTH_KEYS.setter
def AUTH_KEYS(self, value):
if type(value) is dict and set(value.keys()) == set(self.AUTH_KEYS.keys()):
for key, value in value.items():
if type(value) is str:
self._AUTH_KEYS[key] = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, self.AUTH_KEYS)
@property
def MESSAGE_FORMAT(self):
return self._MESSAGE_FORMAT
@MESSAGE_FORMAT.setter
def MESSAGE_FORMAT(self, value):
if type(value) is str:
self._MESSAGE_FORMAT = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def ENABLE_AUTO_CLEAR_CHATBOX(self):
return self._ENABLE_AUTO_CLEAR_CHATBOX
@ENABLE_AUTO_CLEAR_CHATBOX.setter
def ENABLE_AUTO_CLEAR_CHATBOX(self, value):
if type(value) is bool:
self._ENABLE_AUTO_CLEAR_CHATBOX = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
def ENABLE_NOTICE_XSOVERLAY(self):
return self._ENABLE_NOTICE_XSOVERLAY
@ENABLE_NOTICE_XSOVERLAY.setter
def ENABLE_NOTICE_XSOVERLAY(self, value):
if type(value) is bool:
self._ENABLE_NOTICE_XSOVERLAY = value
save_json(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
def init_config(self):
self._PATH_CONFIG = "./config.json"
self._TRANSPARENCY = 100
self._APPEARANCE_THEME = "System"
self._UI_SCALING = "100%"
self._FONT_FAMILY = "Yu Gothic UI"
self._UI_LANGUAGE = "en"
self._CHOICE_TRANSLATOR = translators[0]
self._INPUT_SOURCE_LANG = list(translation_lang[self.CHOICE_TRANSLATOR]["source"].keys())[0]
self._INPUT_TARGET_LANG = list(translation_lang[self.CHOICE_TRANSLATOR]["target"].keys())[1]
self._OUTPUT_SOURCE_LANG = list(translation_lang[self.CHOICE_TRANSLATOR]["source"].keys())[1]
self._OUTPUT_TARGET_LANG = list(translation_lang[self.CHOICE_TRANSLATOR]["target"].keys())[0]
self._CHOICE_MIC_HOST = get_default_input_device()["host"]["name"]
self._CHOICE_MIC_DEVICE = get_default_input_device()["device"]["name"]
self._INPUT_MIC_VOICE_LANGUAGE = list(transcription_lang.keys())[0]
self._INPUT_MIC_ENERGY_THRESHOLD = 300
self._INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD = True
self._INPUT_MIC_RECORD_TIMEOUT = 3
self._INPUT_MIC_PHRASE_TIMEOUT = 3
self._INPUT_MIC_MAX_PHRASES = 10
self._INPUT_MIC_WORD_FILTER = []
self._CHOICE_SPEAKER_DEVICE = get_default_output_device()["name"]
self._INPUT_SPEAKER_VOICE_LANGUAGE = list(transcription_lang.keys())[1]
self._INPUT_SPEAKER_ENERGY_THRESHOLD = 300
self._INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD = True
self._INPUT_SPEAKER_RECORD_TIMEOUT = 3
self._INPUT_SPEAKER_PHRASE_TIMEOUT = 3
self._INPUT_SPEAKER_MAX_PHRASES = 10
self._OSC_IP_ADDRESS = "127.0.0.1"
self._OSC_PORT = 9000
self._AUTH_KEYS = {
"DeepL(web)": None,
"DeepL(auth)": None,
"Bing(web)": None,
"Google(web)": None,
}
self._MESSAGE_FORMAT = "[message]([translation])"
self._ENABLE_AUTO_CLEAR_CHATBOX = False
self._ENABLE_NOTICE_XSOVERLAY = False
def load_config(self):
if os_path.isfile(self.PATH_CONFIG) is not False:
with open(self.PATH_CONFIG, 'r') as fp:
config = json_load(fp)
for key in config.keys():
setattr(self, key, config[key])
with open(self.PATH_CONFIG, 'w') as fp:
setter_methods = [
name for name, obj in vars(type(self)).items()
if isinstance(obj, property) and obj.fset is not None
]
config = {}
for method in setter_methods:
config[method] = getattr(self, method)
json_dump(config, fp, indent=4)
config = Config()

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
import os import os
from customtkinter import CTkToplevel, CTkTextbox, CTkFont from customtkinter import CTkToplevel, CTkTextbox, CTkFont
from config import config
class ToplevelWindowInformation(CTkToplevel): class ToplevelWindowInformation(CTkToplevel):
def __init__(self, parent, *args, **kwargs): def __init__(self, parent, *args, **kwargs):
@@ -16,7 +17,7 @@ class ToplevelWindowInformation(CTkToplevel):
# create textbox information # create textbox information
self.textbox_information = CTkTextbox( self.textbox_information = CTkTextbox(
self, self,
font=CTkFont(family=self.parent.FONT_FAMILY) font=CTkFont(family=config.FONT_FAMILY)
) )
self.textbox_information.grid(row=0, column=0, padx=(10, 10), pady=(10, 10), sticky="nsew") self.textbox_information.grid(row=0, column=0, padx=(10, 10), pady=(10, 10), sticky="nsew")
textbox_information_message = """VRCT(v1.3.2) textbox_information_message = """VRCT(v1.3.2)