From 7b39bfd044d86ce498add9030dd9ffd1c43a3e70 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Mon, 16 Sep 2024 00:13:16 +0900 Subject: [PATCH 1/7] =?UTF-8?q?=F0=9F=91=8D=EF=B8=8F[Update]=20Main:=20Han?= =?UTF-8?q?dler=E3=81=AE=E5=87=A6=E7=90=86=E3=82=92=E5=88=86=E5=89=B2?= =?UTF-8?q?=E3=81=97Config=E7=94=A8=E3=81=A8Controller=E7=94=A8=E3=82=92?= =?UTF-8?q?=E5=88=A5=E3=80=85=E3=81=AB=E5=87=A6=E7=90=86=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-python/webui_mainloop.py | 103 ++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 27 deletions(-) diff --git a/src-python/webui_mainloop.py b/src-python/webui_mainloop.py index 1ee43192..7bb9dff5 100644 --- a/src-python/webui_mainloop.py +++ b/src-python/webui_mainloop.py @@ -2,6 +2,8 @@ import sys import json import time from config import config +from threading import Thread +from queue import Queue import webui_controller as controller from utils import printLog, printResponse, encodeBase64 @@ -291,31 +293,83 @@ class Action: result = data.get("result", None) printResponse(status, self.endpoints[key], result) -def main(): - received_data = sys.stdin.readline().strip() - received_data = json.loads(received_data) +class Main: + def __init__(self) -> None: + self.queue_config = Queue() + self.queue_controller = Queue() - if received_data: - endpoint = received_data.get("endpoint", None) - data = received_data.get("data", None) - data = encodeBase64(data) if data is not None else None - printLog(endpoint, {"receive_data":data}) + def receiver(self) -> None: + while True: + received_data = sys.stdin.readline().strip() + received_data = json.loads(received_data) - try: - match endpoint.split("/")[1]: - case "config": + if received_data: + endpoint = received_data.get("endpoint", None) + data = received_data.get("data", None) + data = encodeBase64(data) if data is not None else None + printLog(endpoint, {"receive_data":data}) + + match endpoint.split("/")[1]: + case "config": + self.queue_config.put(endpoint) + case "controller": + self.queue_controller.put((endpoint, data)) + case _: + pass + + def startReceiver(self) -> None: + th_receiver = Thread(target=self.receiver) + th_receiver.daemon = True + th_receiver.start() + + def configHandler(self) -> None: + while True: + if not self.queue_config.empty(): + endpoint = self.queue_config.get() + try: result, status = handleConfigRequest(endpoint) - case "controller": - result, status = handleControllerRequest(endpoint, data) - case _: - pass - except Exception as e: - result = str(e) - status = 500 - printLog(endpoint, {"send_data":result}) - printResponse(status, endpoint, result) + except Exception as e: + import traceback + with open('error.log', 'a') as f: + traceback.print_exc(file=f) + result = str(e) + status = 500 + printLog(endpoint, {"send_data":result}) + printResponse(status, endpoint, result) + + def startConfigHandler(self) -> None: + th_config = Thread(target=self.configHandler) + th_config.daemon = True + th_config.start() + + def controllerHandler(self) -> None: + if not self.queue_controller.empty(): + try: + endpoint, data = self.queue_controller.get() + result, status = handleControllerRequest(endpoint, data) + except Exception as e: + import traceback + with open('error.log', 'a') as f: + traceback.print_exc(file=f) + result = str(e) + status = 500 + printLog(endpoint, {"send_data":result}) + printResponse(status, endpoint, result) + + def startControllerHandler(self) -> None: + th_controller = Thread(target=self.controllerHandler) + th_controller.daemon = True + th_controller.start() + + def loop(self) -> None: + while True: + time.sleep(1) if __name__ == "__main__": + main = Main() + main.startReceiver() + main.startConfigHandler() + controller.init({ "download_ctranslate2": Action(action_mapping["/controller/callback_download_ctranslate2_weight"]).transmit, "download_whisper": Action(action_mapping["/controller/callback_download_whisper_weight"]).transmit, @@ -325,13 +379,8 @@ if __name__ == "__main__": process = "main" match process: case "main": - try: - while True: - main() - except Exception: - import traceback - with open('error.log', 'a') as f: - traceback.print_exc(file=f) + main.startControllerHandler() + main.loop() case "test": for _ in range(100): From 9ceb6bcee2fad81771c41d66f82acf0a1a75a28b Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Mon, 16 Sep 2024 02:25:25 +0900 Subject: [PATCH 2/7] =?UTF-8?q?=F0=9F=91=8D=EF=B8=8F[Update]=20Main:=20map?= =?UTF-8?q?ping=E3=81=ABstatus=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-python/webui_controller.py | 5 +- src-python/webui_mainloop.py | 497 +++++++++++++++++---------------- 2 files changed, 263 insertions(+), 239 deletions(-) diff --git a/src-python/webui_controller.py b/src-python/webui_controller.py index fa3349e4..722130e9 100644 --- a/src-python/webui_controller.py +++ b/src-python/webui_controller.py @@ -1409,10 +1409,11 @@ def init(actions:dict, *args, **kwargs) -> None: model.startReceiveOSC() if config.ENABLE_VRC_MIC_MUTE_SYNC is True: model.startCheckMuteSelfStatus() - printLog("End Initialization") # init Auto device selection printLog("Init Auto Device Selection") if config.ENABLE_MIC_AUTOMATIC_SELECTION is True or config.ENABLE_SPEAKER_AUTOMATIC_SELECTION is True: update_device = UpdateSelectedDevice(actions["update_selected_device"]) - model.startAutomaticDeviceSelection(update_device.set_mic, update_device.set_speaker) \ No newline at end of file + model.startAutomaticDeviceSelection(update_device.set_mic, update_device.set_speaker) + + printLog("End Initialization") \ No newline at end of file diff --git a/src-python/webui_mainloop.py b/src-python/webui_mainloop.py index 7bb9dff5..aac62345 100644 --- a/src-python/webui_mainloop.py +++ b/src-python/webui_mainloop.py @@ -8,198 +8,198 @@ import webui_controller as controller from utils import printLog, printResponse, encodeBase64 config_mapping = { - "/config/version": "VERSION", - "/config/transparency_range": "TRANSPARENCY_RANGE", - "/config/appearance_theme_list": "APPEARANCE_THEME_LIST", - "/config/ui_scaling_list": "UI_SCALING_LIST", - "/config/textbox_ui_scaling_range": "TEXTBOX_UI_SCALING_RANGE", - "/config/message_box_ratio_range": "MESSAGE_BOX_RATIO_RANGE", - "/config/selectable_ctranslate2_weight_type_dict": "SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT", - "/config/selectable_whisper_weight_type_dict": "SELECTABLE_WHISPER_WEIGHT_TYPE_DICT", - "/config/max_mic_energy_threshold": "MAX_MIC_ENERGY_THRESHOLD", - "/config/max_speaker_energy_threshold": "MAX_SPEAKER_ENERGY_THRESHOLD", - "/config/enable_translation": "ENABLE_TRANSLATION", - "/config/enable_transcription_send": "ENABLE_TRANSCRIPTION_SEND", - "/config/enable_transcription_receive": "ENABLE_TRANSCRIPTION_RECEIVE", - "/config/enable_foreground": "ENABLE_FOREGROUND", - "/config/is_reset_button_displayed_for_translation": "IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION", - "/config/is_reset_button_displayed_for_whisper": "IS_RESET_BUTTON_DISPLAYED_FOR_WHISPER", - "/config/selected_tab_no": "SELECTED_TAB_NO", - "/config/selected_tab_your_translator_engines": "SELECTED_TAB_YOUR_TRANSLATOR_ENGINES", - "/config/selected_tab_target_translator_engines": "SELECTED_TAB_TARGET_TRANSLATOR_ENGINES", - "/config/selected_tab_your_languages": "SELECTED_TAB_YOUR_LANGUAGES", - "/config/selected_tab_target_languages": "SELECTED_TAB_TARGET_LANGUAGES", - "/config/selected_transcription_engine": "SELECTED_TRANSCRIPTION_ENGINE", - "/config/enable_multi_translation": "ENABLE_MULTI_LANGUAGE_TRANSLATION", - "/config/enable_convert_message_to_romaji": "ENABLE_CONVERT_MESSAGE_TO_ROMAJI", - "/config/enable_convert_message_to_hiragana": "ENABLE_CONVERT_MESSAGE_TO_HIRAGANA", - "/config/is_main_window_sidebar_compact_mode": "IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE", - "/config/transparency": "TRANSPARENCY", - "/config/appearance_theme": "APPEARANCE_THEME", - "/config/ui_scaling": "UI_SCALING", - "/config/textbox_ui_scaling": "TEXTBOX_UI_SCALING", - "/config/message_box_ratio": "MESSAGE_BOX_RATIO", - "/config/font_family": "FONT_FAMILY", - "/config/ui_language": "UI_LANGUAGE", - "/config/enable_restore_main_window_geometry": "ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY", - "/config/main_window_geometry": "MAIN_WINDOW_GEOMETRY", - "/config/enable_mic_automatic_selection": "ENABLE_MIC_AUTOMATIC_SELECTION", - "/config/choice_mic_host": "CHOICE_MIC_HOST", - "/config/choice_mic_device": "CHOICE_MIC_DEVICE", - "/config/input_mic_energy_threshold": "INPUT_MIC_ENERGY_THRESHOLD", - "/config/input_mic_dynamic_energy_threshold": "INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD", - "/config/input_mic_record_timeout": "INPUT_MIC_RECORD_TIMEOUT", - "/config/input_mic_phrase_timeout": "INPUT_MIC_PHRASE_TIMEOUT", - "/config/input_mic_max_phrases": "INPUT_MIC_MAX_PHRASES", - "/config/input_mic_word_filter": "INPUT_MIC_WORD_FILTER", - "/config/input_mic_avg_logprob": "INPUT_MIC_AVG_LOGPROB", - "/config/input_mic_no_speech_prob": "INPUT_MIC_NO_SPEECH_PROB", - "/config/enable_speaker_automatic_selection": "ENABLE_SPEAKER_AUTOMATIC_SELECTION", - "/config/choice_speaker_device": "CHOICE_SPEAKER_DEVICE", - "/config/input_speaker_energy_threshold": "INPUT_SPEAKER_ENERGY_THRESHOLD", - "/config/input_speaker_dynamic_energy_threshold": "INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD", - "/config/input_speaker_record_timeout": "INPUT_SPEAKER_RECORD_TIMEOUT", - "/config/input_speaker_phrase_timeout": "INPUT_SPEAKER_PHRASE_TIMEOUT", - "/config/input_speaker_max_phrases": "INPUT_SPEAKER_MAX_PHRASES", - "/config/input_speaker_avg_logprob": "INPUT_SPEAKER_AVG_LOGPROB", - "/config/input_speaker_no_speech_prob": "INPUT_SPEAKER_NO_SPEECH_PROB", - "/config/osc_ip_address": "OSC_IP_ADDRESS", - "/config/osc_port": "OSC_PORT", - "/config/auth_keys": "AUTH_KEYS", - "/config/use_translation_feature": "USE_TRANSLATION_FEATURE", - "/config/use_whisper_feature": "USE_WHISPER_FEATURE", - "/config/ctranslate2_weight_type": "CTRANSLATE2_WEIGHT_TYPE", - "/config/whisper_weight_type": "WHISPER_WEIGHT_TYPE", - "/config/enable_auto_clear_message_box": "ENABLE_AUTO_CLEAR_MESSAGE_BOX", - "/config/enable_send_only_translated_messages": "ENABLE_SEND_ONLY_TRANSLATED_MESSAGES", - "/config/send_message_button_type": "SEND_MESSAGE_BUTTON_TYPE", - "/config/overlay_settings": "OVERLAY_SETTINGS", - "/config/enable_overlay_small_log": "ENABLE_OVERLAY_SMALL_LOG", - "/config/overlay_small_log_settings": "OVERLAY_SMALL_LOG_SETTINGS", - "/config/overlay_ui_type": "OVERLAY_UI_TYPE", - "/config/enable_send_message_to_vrc": "ENABLE_SEND_MESSAGE_TO_VRC", - "/config/send_message_format": "SEND_MESSAGE_FORMAT", - "/config/send_message_format_with_t": "SEND_MESSAGE_FORMAT_WITH_T", - "/config/received_message_format": "RECEIVED_MESSAGE_FORMAT", - "/config/received_message_format_with_t": "RECEIVED_MESSAGE_FORMAT_WITH_T", - "/config/enable_speaker2chatbox_pass": "ENABLE_SPEAKER2CHATBOX_PASS", - "/config/enable_send_received_message_to_vrc": "ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC", - "/config/enable_logger": "ENABLE_LOGGER", - "/config/enable_vrc_mic_mute_sync": "ENABLE_VRC_MIC_MUTE_SYNC", + "/config/version": {"status": True, "variable":"VERSION"}, + "/config/transparency_range": {"status": True, "variable":"TRANSPARENCY_RANGE"}, + "/config/appearance_theme_list": {"status": True, "variable":"APPEARANCE_THEME_LIST"}, + "/config/ui_scaling_list": {"status": True, "variable":"UI_SCALING_LIST"}, + "/config/textbox_ui_scaling_range": {"status": True, "variable":"TEXTBOX_UI_SCALING_RANGE"}, + "/config/message_box_ratio_range": {"status": True, "variable":"MESSAGE_BOX_RATIO_RANGE"}, + "/config/selectable_ctranslate2_weight_type_dict": {"status": True, "variable":"SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT"}, + "/config/selectable_whisper_weight_type_dict": {"status": True, "variable":"SELECTABLE_WHISPER_WEIGHT_TYPE_DICT"}, + "/config/max_mic_energy_threshold": {"status": True, "variable":"MAX_MIC_ENERGY_THRESHOLD"}, + "/config/max_speaker_energy_threshold": {"status": True, "variable":"MAX_SPEAKER_ENERGY_THRESHOLD"}, + # "/config/enable_translation": {"status": True, "variable":"ENABLE_TRANSLATION"}, + # "/config/enable_transcription_send": {"status": True, "variable":"ENABLE_TRANSCRIPTION_SEND"}, + # "/config/enable_transcription_receive": {"status": True, "variable":"ENABLE_TRANSCRIPTION_RECEIVE"}, + # "/config/enable_foreground": {"status": True, "variable":"ENABLE_FOREGROUND"}, + # "/config/is_reset_button_displayed_for_translation": {"status": True, "variable":"IS_RESET_BUTTON_DISPLAYED_FOR_TRANSLATION"}, + # "/config/is_reset_button_displayed_for_whisper": {"status": True, "variable":"IS_RESET_BUTTON_DISPLAYED_FOR_WHISPER"}, + "/config/selected_tab_no": {"status": True, "variable":"SELECTED_TAB_NO"}, + "/config/selected_tab_your_translator_engines": {"status": False, "variable":"SELECTED_TAB_YOUR_TRANSLATOR_ENGINES"}, + "/config/selected_tab_target_translator_engines": {"status": False, "variable":"SELECTED_TAB_TARGET_TRANSLATOR_ENGINES"}, + "/config/selected_tab_your_languages": {"status": True, "variable":"SELECTED_TAB_YOUR_LANGUAGES"}, + "/config/selected_tab_target_languages": {"status": True, "variable":"SELECTED_TAB_TARGET_LANGUAGES"}, + "/config/selected_transcription_engine": {"status": False, "variable":"SELECTED_TRANSCRIPTION_ENGINE"}, + "/config/enable_multi_translation": {"status": True, "variable":"ENABLE_MULTI_LANGUAGE_TRANSLATION"}, + "/config/enable_convert_message_to_romaji": {"status": True, "variable":"ENABLE_CONVERT_MESSAGE_TO_ROMAJI"}, + "/config/enable_convert_message_to_hiragana": {"status": True, "variable":"ENABLE_CONVERT_MESSAGE_TO_HIRAGANA"}, + "/config/is_main_window_sidebar_compact_mode": {"status": True, "variable":"IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE"}, + "/config/transparency": {"status": True, "variable":"TRANSPARENCY"}, + "/config/appearance_theme": {"status": True, "variable":"APPEARANCE_THEME"}, + "/config/ui_scaling": {"status": True, "variable":"UI_SCALING"}, + "/config/textbox_ui_scaling": {"status": True, "variable":"TEXTBOX_UI_SCALING"}, + "/config/message_box_ratio": {"status": True, "variable":"MESSAGE_BOX_RATIO"}, + "/config/font_family": {"status": True, "variable":"FONT_FAMILY"}, + "/config/ui_language": {"status": True, "variable":"UI_LANGUAGE"}, + "/config/enable_restore_main_window_geometry": {"status": True, "variable":"ENABLE_RESTORE_MAIN_WINDOW_GEOMETRY"}, + "/config/main_window_geometry": {"status": True, "variable":"MAIN_WINDOW_GEOMETRY"}, + "/config/enable_mic_automatic_selection": {"status": True, "variable":"ENABLE_MIC_AUTOMATIC_SELECTION"}, + "/config/choice_mic_host": {"status": True, "variable":"CHOICE_MIC_HOST"}, + "/config/choice_mic_device": {"status": True, "variable":"CHOICE_MIC_DEVICE"}, + "/config/input_mic_energy_threshold": {"status": True, "variable":"INPUT_MIC_ENERGY_THRESHOLD"}, + "/config/input_mic_dynamic_energy_threshold": {"status": True, "variable":"INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD"}, + "/config/input_mic_record_timeout": {"status": True, "variable":"INPUT_MIC_RECORD_TIMEOUT"}, + "/config/input_mic_phrase_timeout": {"status": True, "variable":"INPUT_MIC_PHRASE_TIMEOUT"}, + "/config/input_mic_max_phrases": {"status": True, "variable":"INPUT_MIC_MAX_PHRASES"}, + "/config/input_mic_word_filter": {"status": True, "variable":"INPUT_MIC_WORD_FILTER"}, + "/config/input_mic_avg_logprob": {"status": True, "variable":"INPUT_MIC_AVG_LOGPROB"}, + "/config/input_mic_no_speech_prob": {"status": True, "variable":"INPUT_MIC_NO_SPEECH_PROB"}, + "/config/enable_speaker_automatic_selection": {"status": True, "variable":"ENABLE_SPEAKER_AUTOMATIC_SELECTION"}, + "/config/choice_speaker_device": {"status": True, "variable":"CHOICE_SPEAKER_DEVICE"}, + "/config/input_speaker_energy_threshold": {"status": True, "variable":"INPUT_SPEAKER_ENERGY_THRESHOLD"}, + "/config/input_speaker_dynamic_energy_threshold": {"status": True, "variable":"INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD"}, + "/config/input_speaker_record_timeout": {"status": True, "variable":"INPUT_SPEAKER_RECORD_TIMEOUT"}, + "/config/input_speaker_phrase_timeout": {"status": True, "variable":"INPUT_SPEAKER_PHRASE_TIMEOUT"}, + "/config/input_speaker_max_phrases": {"status": True, "variable":"INPUT_SPEAKER_MAX_PHRASES"}, + "/config/input_speaker_avg_logprob": {"status": True, "variable":"INPUT_SPEAKER_AVG_LOGPROB"}, + "/config/input_speaker_no_speech_prob": {"status": True, "variable":"INPUT_SPEAKER_NO_SPEECH_PROB"}, + "/config/osc_ip_address": {"status": True, "variable":"OSC_IP_ADDRESS"}, + "/config/osc_port": {"status": True, "variable":"OSC_PORT"}, + "/config/auth_keys": {"status": False, "variable":"AUTH_KEYS"}, + "/config/use_translation_feature": {"status": True, "variable":"USE_TRANSLATION_FEATURE"}, + "/config/use_whisper_feature": {"status": True, "variable":"USE_WHISPER_FEATURE"}, + "/config/ctranslate2_weight_type": {"status": True, "variable":"CTRANSLATE2_WEIGHT_TYPE"}, + "/config/whisper_weight_type": {"status": True, "variable":"WHISPER_WEIGHT_TYPE"}, + "/config/enable_auto_clear_message_box": {"status": True, "variable":"ENABLE_AUTO_CLEAR_MESSAGE_BOX"}, + "/config/enable_send_only_translated_messages": {"status": True, "variable":"ENABLE_SEND_ONLY_TRANSLATED_MESSAGES"}, + "/config/send_message_button_type": {"status": True, "variable":"SEND_MESSAGE_BUTTON_TYPE"}, + "/config/overlay_settings": {"status": True, "variable":"OVERLAY_SETTINGS"}, + "/config/enable_overlay_small_log": {"status": True, "variable":"ENABLE_OVERLAY_SMALL_LOG"}, + "/config/overlay_small_log_settings": {"status": True, "variable":"OVERLAY_SMALL_LOG_SETTINGS"}, + "/config/overlay_ui_type": {"status": True, "variable":"OVERLAY_UI_TYPE"}, + "/config/enable_send_message_to_vrc": {"status": True, "variable":"ENABLE_SEND_MESSAGE_TO_VRC"}, + "/config/send_message_format": {"status": True, "variable":"SEND_MESSAGE_FORMAT"}, + "/config/send_message_format_with_t": {"status": True, "variable":"SEND_MESSAGE_FORMAT_WITH_T"}, + "/config/received_message_format": {"status": True, "variable":"RECEIVED_MESSAGE_FORMAT"}, + "/config/received_message_format_with_t": {"status": True, "variable":"RECEIVED_MESSAGE_FORMAT_WITH_T"}, + "/config/enable_speaker2chatbox_pass": {"status": True, "variable":"ENABLE_SPEAKER2CHATBOX_PASS"}, + "/config/enable_send_received_message_to_vrc": {"status": True, "variable":"ENABLE_SEND_RECEIVED_MESSAGE_TO_VRC"}, + "/config/enable_logger": {"status": True, "variable":"ENABLE_LOGGER"}, + "/config/enable_vrc_mic_mute_sync": {"status": True, "variable":"ENABLE_VRC_MIC_MUTE_SYNC"}, } controller_mapping = { - "/controller/list_language_and_country": controller.getListLanguageAndCountry, - "/controller/list_mic_host": controller.getListInputHost, - "/controller/list_mic_device": controller.getListInputDevice, - "/controller/list_speaker_device": controller.getListOutputDevice, - # "/controller/callback_update_software": controller.callbackUpdateSoftware, - # "/controller/callback_restart_software": controller.callbackRestartSoftware, - "/controller/callback_filepath_logs": controller.callbackFilepathLogs, - "/controller/callback_filepath_config_file": controller.callbackFilepathConfigFile, - # "/controller/callback_enable_easter_egg": controller.callbackEnableEasterEgg, - "/controller/callback_open_config_window": controller.callbackOpenConfigWindow, - "/controller/callback_close_config_window": controller.callbackCloseConfigWindow, - "/controller/callback_enable_multi_language_translation": controller.callbackEnableMultiLanguageTranslation, - "/controller/callback_disable_multi_language_translation": controller.callbackDisableMultiLanguageTranslation, - "/controller/callback_enable_convert_message_to_romaji": controller.callbackEnableConvertMessageToRomaji, - "/controller/callback_disable_convert_message_to_romaji": controller.callbackDisableConvertMessageToRomaji, - "/controller/callback_enable_convert_message_to_hiragana": controller.callbackEnableConvertMessageToHiragana, - "/controller/callback_disable_convert_message_to_hiragana": controller.callbackDisableConvertMessageToHiragana, - "/controller/callback_enable_main_window_sidebar_compact_mode": controller.callbackEnableMainWindowSidebarCompactMode, - "/controller/callback_disable_main_window_sidebar_compact_mode": controller.callbackDisableMainWindowSidebarCompactMode, - "/controller/callback_enable_translation": controller.callbackEnableTranslation, - "/controller/callback_disable_translation": controller.callbackDisableTranslation, - "/controller/callback_enable_transcription_send": controller.callbackEnableTranscriptionSend, - "/controller/callback_disable_transcription_send": controller.callbackDisableTranscriptionSend, - "/controller/callback_enable_transcription_receive": controller.callbackEnableTranscriptionReceive, - "/controller/callback_disable_transcription_receive": controller.callbackDisableTranscriptionReceive, - "/controller/callback_messagebox_send": controller.callbackMessageBoxSend, - "/controller/callback_messagebox_typing": controller.callbackMessageBoxTyping, - "/controller/callback_messagebox_typing_stop": controller.callbackMessageBoxTypingStop, - "/controller/callback_enable_foreground": controller.callbackEnableForeground, - "/controller/callback_disable_foreground": controller.callbackDisableForeground, - "/controller/set_your_language_and_country": controller.setYourLanguageAndCountry, - "/controller/set_target_language_and_country": controller.setTargetLanguageAndCountry, - "/controller/swap_your_language_and_target_language": controller.swapYourLanguageAndTargetLanguage, - "/controller/callback_selected_language_preset_tab": controller.callbackSelectedLanguagePresetTab, - "/controller/list_translation_engines": controller.getTranslationEngines, - "/controller/callback_selected_translation_engine": controller.callbackSelectedTranslationEngine, - "/controller/callback_set_transparency": controller.callbackSetTransparency, - "/controller/callback_set_appearance": controller.callbackSetAppearance, - "/controller/callback_set_ui_scaling": controller.callbackSetUiScaling, - "/controller/callback_set_textbox_ui_scaling": controller.callbackSetTextboxUiScaling, - "/controller/callback_set_message_box_ratio": controller.callbackSetMessageBoxRatio, - "/controller/callback_set_font_family": controller.callbackSetFontFamily, - "/controller/callback_set_ui_language": controller.callbackSetUiLanguage, - "/controller/callback_enable_restore_main_window_geometry": controller.callbackEnableRestoreMainWindowGeometry, - "/controller/callback_disable_restore_main_window_geometry": controller.callbackDisableRestoreMainWindowGeometry, - "/controller/callback_enable_use_translation_feature": controller.callbackEnableUseTranslationFeature, - "/controller/callback_disable_use_translation_feature": controller.callbackDisableUseTranslationFeature, - "/controller/callback_set_ctranslate2_weight_type": controller.callbackSetCtranslate2WeightType, - "/controller/callback_download_ctranslate2_weight": controller.callbackDownloadCtranslate2Weight, - "/controller/callback_set_deepl_auth_key": controller.callbackSetDeeplAuthKey, - "/controller/callback_clear_deepl_auth_key": controller.callbackClearDeeplAuthKey, - "/controller/callback_enable_mic_automatic_selection": controller.callbackEnableMicAutomaticSelection, - "/controller/callback_disable_mic_automatic_selection": controller.callbackDisableMicAutomaticSelection, - "/controller/callback_set_mic_host": controller.callbackSetMicHost, - "/controller/callback_set_mic_device": controller.callbackSetMicDevice, - "/controller/callback_set_mic_energy_threshold": controller.callbackSetMicEnergyThreshold, - "/controller/callback_enable_mic_dynamic_energy_threshold": controller.callbackEnableMicDynamicEnergyThreshold, - "/controller/callback_disable_mic_dynamic_energy_threshold": controller.callbackDisableMicDynamicEnergyThreshold, - "/controller/callback_enable_check_mic_threshold": controller.callbackEnableCheckMicThreshold, - "/controller/callback_disable_check_mic_threshold": controller.callbackDisableCheckMicThreshold, - "/controller/callback_set_mic_record_timeout": controller.callbackSetMicRecordTimeout, - "/controller/callback_set_mic_phrase_timeout": controller.callbackSetMicPhraseTimeout, - "/controller/callback_set_mic_max_phrases": controller.callbackSetMicMaxPhrases, - "/controller/callback_set_mic_word_filter": controller.callbackSetMicWordFilter, - "/controller/callback_delete_mic_word_filter": controller.callbackDeleteMicWordFilter, - "/controller/callback_enable_speaker_automatic_selection": controller.callbackEnableSpeakerAutomaticSelection, - "/controller/callback_disable_speaker_automatic_selection": controller.callbackDisableSpeakerAutomaticSelection, - "/controller/callback_set_speaker_device": controller.callbackSetSpeakerDevice, - "/controller/callback_set_speaker_energy_threshold": controller.callbackSetSpeakerEnergyThreshold, - "/controller/callback_enable_speaker_dynamic_energy_threshold": controller.callbackEnableSpeakerDynamicEnergyThreshold, - "/controller/callback_disable_speaker_dynamic_energy_threshold": controller.callbackDisableSpeakerDynamicEnergyThreshold, - "/controller/callback_enable_check_speaker_threshold": controller.callbackEnableCheckSpeakerThreshold, - "/controller/callback_disable_check_speaker_threshold": controller.callbackDisableCheckSpeakerThreshold, - "/controller/callback_set_speaker_record_timeout": controller.callbackSetSpeakerRecordTimeout, - "/controller/callback_set_speaker_phrase_timeout": controller.callbackSetSpeakerPhraseTimeout, - "/controller/callback_set_speaker_max_phrases": controller.callbackSetSpeakerMaxPhrases, - "/controller/callback_enable_use_whisper_feature": controller.callbackEnableUseWhisperFeature, - "/controller/callback_disable_use_whisper_feature": controller.callbackDisableUseWhisperFeature, - "/controller/callback_set_whisper_weight_type": controller.callbackSetWhisperWeightType, - "/controller/callback_download_whisper_weight": controller.callbackDownloadWhisperWeight, - "/controller/callback_set_overlay_settings_opacity": controller.callbackSetOverlaySettingsOpacity, - "/controller/callback_set_overlay_settings_ui_scaling": controller.callbackSetOverlaySettingsUiScaling, - "/controller/callback_enable_overlay_small_log": controller.callbackEnableOverlaySmallLog, - "/controller/callback_disable_overlay_small_log": controller.callbackDisableOverlaySmallLog, - "/controller/callback_set_overlay_small_log_settings_x_pos": controller.callbackSetOverlaySmallLogSettingsXPos, - "/controller/callback_set_overlay_small_log_settings_y_pos": controller.callbackSetOverlaySmallLogSettingsYPos, - "/controller/callback_set_overlay_small_log_settings_z_pos": controller.callbackSetOverlaySmallLogSettingsZPos, - "/controller/callback_set_overlay_small_log_settings_x_rotation": controller.callbackSetOverlaySmallLogSettingsXRotation, - "/controller/callback_set_overlay_small_log_settings_y_rotation": controller.callbackSetOverlaySmallLogSettingsYRotation, - "/controller/callback_set_overlay_small_log_settings_z_rotation": controller.callbackSetOverlaySmallLogSettingsZRotation, - "/controller/callback_enable_auto_clear_chatbox": controller.callbackEnableAutoClearMessageBox, - "/controller/callback_disable_auto_clear_chatbox": controller.callbackDisableAutoClearMessageBox, - "/controller/callback_enable_send_only_translated_messages": controller.callbackEnableSendOnlyTranslatedMessages, - "/controller/callback_disable_send_only_translated_messages": controller.callbackDisableSendOnlyTranslatedMessages, - "/controller/callback_set_send_message_button_type": controller.callbackSetSendMessageButtonType, - "/controller/callback_enable_auto_export_message_logs": controller.callbackEnableAutoExportMessageLogs, - "/controller/callback_disable_auto_export_message_logs": controller.callbackDisableAutoExportMessageLogs, - "/controller/callback_enable_vrc_mic_mute_sync": controller.callbackEnableVrcMicMuteSync, - "/controller/callback_disable_vrc_mic_mute_sync": controller.callbackDisableVrcMicMuteSync, - "/controller/callback_enable_send_message_to_vrc": controller.callbackEnableSendMessageToVrc, - "/controller/callback_disable_send_message_to_vrc": controller.callbackDisableSendMessageToVrc, - "/controller/callback_set_send_message_format": controller.callbackSetSendMessageFormat, - "/controller/callback_set_send_message_format_with_t": controller.callbackSetSendMessageFormatWithT, - "/controller/callback_set_received_message_format": controller.callbackSetReceivedMessageFormat, - "/controller/callback_set_received_message_format_with_t": controller.callbackSetReceivedMessageFormatWithT, - "/controller/callback_enable_send_received_message_to_vrc": controller.callbackEnableSendReceivedMessageToVrc, - "/controller/callback_disable_send_received_message_to_vrc": controller.callbackDisableSendReceivedMessageToVrc, - "/controller/callback_enable_logger": controller.callbackEnableLogger, - "/controller/callback_disable_logger": controller.callbackDisableLogger, - "/controller/callback_set_osc_ip_address": controller.callbackSetOscIpAddress, - "/controller/callback_set_osc_port": controller.callbackSetOscPort, + "/controller/list_language_and_country": {"status": True, "variable":controller.getListLanguageAndCountry}, + "/controller/list_mic_host": {"status": True, "variable":controller.getListInputHost}, + "/controller/list_mic_device": {"status": True, "variable":controller.getListInputDevice}, + "/controller/list_speaker_device": {"status": True, "variable":controller.getListOutputDevice}, + # "/controller/callback_update_software": {"status": True, "variable":controller.callbackUpdateSoftware}, + # "/controller/callback_restart_software": {"status": True, "variable":controller.callbackRestartSoftware}, + "/controller/callback_filepath_logs": {"status": True, "variable":controller.callbackFilepathLogs}, + "/controller/callback_filepath_config_file": {"status": True, "variable":controller.callbackFilepathConfigFile}, + # "/controller/callback_enable_easter_egg": {"status": True, "variable":controller.callbackEnableEasterEgg}, + "/controller/callback_open_config_window": {"status": True, "variable":controller.callbackOpenConfigWindow}, + "/controller/callback_close_config_window": {"status": True, "variable":controller.callbackCloseConfigWindow}, + "/controller/callback_enable_multi_language_translation": {"status": True, "variable":controller.callbackEnableMultiLanguageTranslation}, + "/controller/callback_disable_multi_language_translation": {"status": True, "variable":controller.callbackDisableMultiLanguageTranslation}, + "/controller/callback_enable_convert_message_to_romaji": {"status": True, "variable":controller.callbackEnableConvertMessageToRomaji}, + "/controller/callback_disable_convert_message_to_romaji": {"status": True, "variable":controller.callbackDisableConvertMessageToRomaji}, + "/controller/callback_enable_convert_message_to_hiragana": {"status": True, "variable":controller.callbackEnableConvertMessageToHiragana}, + "/controller/callback_disable_convert_message_to_hiragana": {"status": True, "variable":controller.callbackDisableConvertMessageToHiragana}, + "/controller/callback_enable_main_window_sidebar_compact_mode": {"status": True, "variable":controller.callbackEnableMainWindowSidebarCompactMode}, + "/controller/callback_disable_main_window_sidebar_compact_mode": {"status": True, "variable":controller.callbackDisableMainWindowSidebarCompactMode}, + "/controller/callback_enable_translation": {"status": False, "variable":controller.callbackEnableTranslation}, + "/controller/callback_disable_translation": {"status": False, "variable":controller.callbackDisableTranslation}, + "/controller/callback_enable_transcription_send": {"status": False, "variable":controller.callbackEnableTranscriptionSend}, + "/controller/callback_disable_transcription_send": {"status": False, "variable":controller.callbackDisableTranscriptionSend}, + "/controller/callback_enable_transcription_receive": {"status": False, "variable":controller.callbackEnableTranscriptionReceive}, + "/controller/callback_disable_transcription_receive": {"status": False, "variable":controller.callbackDisableTranscriptionReceive}, + "/controller/callback_messagebox_send": {"status": False, "variable":controller.callbackMessageBoxSend}, + "/controller/callback_messagebox_typing": {"status": False, "variable":controller.callbackMessageBoxTyping}, + "/controller/callback_messagebox_typing_stop": {"status": False, "variable":controller.callbackMessageBoxTypingStop}, + "/controller/callback_enable_foreground": {"status": True, "variable":controller.callbackEnableForeground}, + "/controller/callback_disable_foreground": {"status": True, "variable":controller.callbackDisableForeground}, + "/controller/set_your_language_and_country": {"status": True, "variable":controller.setYourLanguageAndCountry}, + "/controller/set_target_language_and_country": {"status": True, "variable":controller.setTargetLanguageAndCountry}, + "/controller/swap_your_language_and_target_language": {"status": True, "variable":controller.swapYourLanguageAndTargetLanguage}, + "/controller/callback_selected_language_preset_tab": {"status": True, "variable":controller.callbackSelectedLanguagePresetTab}, + "/controller/list_translation_engines": {"status": True, "variable":controller.getTranslationEngines}, + "/controller/callback_selected_translation_engine": {"status": True, "variable":controller.callbackSelectedTranslationEngine}, + "/controller/callback_set_transparency": {"status": True, "variable":controller.callbackSetTransparency}, + "/controller/callback_set_appearance": {"status": True, "variable":controller.callbackSetAppearance}, + "/controller/callback_set_ui_scaling": {"status": True, "variable":controller.callbackSetUiScaling}, + "/controller/callback_set_textbox_ui_scaling": {"status": True, "variable":controller.callbackSetTextboxUiScaling}, + "/controller/callback_set_message_box_ratio": {"status": True, "variable":controller.callbackSetMessageBoxRatio}, + "/controller/callback_set_font_family": {"status": True, "variable":controller.callbackSetFontFamily}, + "/controller/callback_set_ui_language": {"status": True, "variable":controller.callbackSetUiLanguage}, + "/controller/callback_enable_restore_main_window_geometry": {"status": True, "variable":controller.callbackEnableRestoreMainWindowGeometry}, + "/controller/callback_disable_restore_main_window_geometry": {"status": True, "variable":controller.callbackDisableRestoreMainWindowGeometry}, + "/controller/callback_enable_use_translation_feature": {"status": True, "variable":controller.callbackEnableUseTranslationFeature}, + "/controller/callback_disable_use_translation_feature": {"status": True, "variable":controller.callbackDisableUseTranslationFeature}, + "/controller/callback_set_ctranslate2_weight_type": {"status": True, "variable":controller.callbackSetCtranslate2WeightType}, + "/controller/callback_download_ctranslate2_weight": {"status": True, "variable":controller.callbackDownloadCtranslate2Weight}, + "/controller/callback_set_deepl_auth_key": {"status": True, "variable":controller.callbackSetDeeplAuthKey}, + "/controller/callback_clear_deepl_auth_key": {"status": True, "variable":controller.callbackClearDeeplAuthKey}, + "/controller/callback_enable_mic_automatic_selection": {"status": False, "variable":controller.callbackEnableMicAutomaticSelection}, + "/controller/callback_disable_mic_automatic_selection": {"status": False, "variable":controller.callbackDisableMicAutomaticSelection}, + "/controller/callback_set_mic_host": {"status": True, "variable":controller.callbackSetMicHost}, + "/controller/callback_set_mic_device": {"status": True, "variable":controller.callbackSetMicDevice}, + "/controller/callback_set_mic_energy_threshold": {"status": True, "variable":controller.callbackSetMicEnergyThreshold}, + "/controller/callback_enable_mic_dynamic_energy_threshold": {"status": True, "variable":controller.callbackEnableMicDynamicEnergyThreshold}, + "/controller/callback_disable_mic_dynamic_energy_threshold": {"status": True, "variable":controller.callbackDisableMicDynamicEnergyThreshold}, + "/controller/callback_enable_check_mic_threshold": {"status": True, "variable":controller.callbackEnableCheckMicThreshold}, + "/controller/callback_disable_check_mic_threshold": {"status": True, "variable":controller.callbackDisableCheckMicThreshold}, + "/controller/callback_set_mic_record_timeout": {"status": True, "variable":controller.callbackSetMicRecordTimeout}, + "/controller/callback_set_mic_phrase_timeout": {"status": True, "variable":controller.callbackSetMicPhraseTimeout}, + "/controller/callback_set_mic_max_phrases": {"status": True, "variable":controller.callbackSetMicMaxPhrases}, + "/controller/callback_set_mic_word_filter": {"status": False, "variable":controller.callbackSetMicWordFilter}, + "/controller/callback_delete_mic_word_filter": {"status": False, "variable":controller.callbackDeleteMicWordFilter}, + "/controller/callback_enable_speaker_automatic_selection": {"status": False, "variable":controller.callbackEnableSpeakerAutomaticSelection}, + "/controller/callback_disable_speaker_automatic_selection": {"status": False, "variable":controller.callbackDisableSpeakerAutomaticSelection}, + "/controller/callback_set_speaker_device": {"status": True, "variable":controller.callbackSetSpeakerDevice}, + "/controller/callback_set_speaker_energy_threshold": {"status": True, "variable":controller.callbackSetSpeakerEnergyThreshold}, + "/controller/callback_enable_speaker_dynamic_energy_threshold": {"status": True, "variable":controller.callbackEnableSpeakerDynamicEnergyThreshold}, + "/controller/callback_disable_speaker_dynamic_energy_threshold": {"status": True, "variable":controller.callbackDisableSpeakerDynamicEnergyThreshold}, + "/controller/callback_enable_check_speaker_threshold": {"status": True, "variable":controller.callbackEnableCheckSpeakerThreshold}, + "/controller/callback_disable_check_speaker_threshold": {"status": True, "variable":controller.callbackDisableCheckSpeakerThreshold}, + "/controller/callback_set_speaker_record_timeout": {"status": True, "variable":controller.callbackSetSpeakerRecordTimeout}, + "/controller/callback_set_speaker_phrase_timeout": {"status": True, "variable":controller.callbackSetSpeakerPhraseTimeout}, + "/controller/callback_set_speaker_max_phrases": {"status": True, "variable":controller.callbackSetSpeakerMaxPhrases}, + "/controller/callback_enable_use_whisper_feature": {"status": True, "variable":controller.callbackEnableUseWhisperFeature}, + "/controller/callback_disable_use_whisper_feature": {"status": True, "variable":controller.callbackDisableUseWhisperFeature}, + "/controller/callback_set_whisper_weight_type": {"status": True, "variable":controller.callbackSetWhisperWeightType}, + "/controller/callback_download_whisper_weight": {"status": True, "variable":controller.callbackDownloadWhisperWeight}, + "/controller/callback_set_overlay_settings_opacity": {"status": True, "variable":controller.callbackSetOverlaySettingsOpacity}, + "/controller/callback_set_overlay_settings_ui_scaling": {"status": True, "variable":controller.callbackSetOverlaySettingsUiScaling}, + "/controller/callback_enable_overlay_small_log": {"status": True, "variable":controller.callbackEnableOverlaySmallLog}, + "/controller/callback_disable_overlay_small_log": {"status": True, "variable":controller.callbackDisableOverlaySmallLog}, + "/controller/callback_set_overlay_small_log_settings_x_pos": {"status": True, "variable":controller.callbackSetOverlaySmallLogSettingsXPos}, + "/controller/callback_set_overlay_small_log_settings_y_pos": {"status": True, "variable":controller.callbackSetOverlaySmallLogSettingsYPos}, + "/controller/callback_set_overlay_small_log_settings_z_pos": {"status": True, "variable":controller.callbackSetOverlaySmallLogSettingsZPos}, + "/controller/callback_set_overlay_small_log_settings_x_rotation": {"status": True, "variable":controller.callbackSetOverlaySmallLogSettingsXRotation}, + "/controller/callback_set_overlay_small_log_settings_y_rotation": {"status": True, "variable":controller.callbackSetOverlaySmallLogSettingsYRotation}, + "/controller/callback_set_overlay_small_log_settings_z_rotation": {"status": True, "variable":controller.callbackSetOverlaySmallLogSettingsZRotation}, + "/controller/callback_enable_auto_clear_chatbox": {"status": True, "variable":controller.callbackEnableAutoClearMessageBox}, + "/controller/callback_disable_auto_clear_chatbox": {"status": True, "variable":controller.callbackDisableAutoClearMessageBox}, + "/controller/callback_enable_send_only_translated_messages": {"status": True, "variable":controller.callbackEnableSendOnlyTranslatedMessages}, + "/controller/callback_disable_send_only_translated_messages": {"status": True, "variable":controller.callbackDisableSendOnlyTranslatedMessages}, + "/controller/callback_set_send_message_button_type": {"status": True, "variable":controller.callbackSetSendMessageButtonType}, + "/controller/callback_enable_auto_export_message_logs": {"status": True, "variable":controller.callbackEnableAutoExportMessageLogs}, + "/controller/callback_disable_auto_export_message_logs": {"status": True, "variable":controller.callbackDisableAutoExportMessageLogs}, + "/controller/callback_enable_vrc_mic_mute_sync": {"status": False, "variable":controller.callbackEnableVrcMicMuteSync}, + "/controller/callback_disable_vrc_mic_mute_sync": {"status": False, "variable":controller.callbackDisableVrcMicMuteSync}, + "/controller/callback_enable_send_message_to_vrc": {"status": True, "variable":controller.callbackEnableSendMessageToVrc}, + "/controller/callback_disable_send_message_to_vrc": {"status": True, "variable":controller.callbackDisableSendMessageToVrc}, + "/controller/callback_set_send_message_format": {"status": True, "variable":controller.callbackSetSendMessageFormat}, + "/controller/callback_set_send_message_format_with_t": {"status": True, "variable":controller.callbackSetSendMessageFormatWithT}, + "/controller/callback_set_received_message_format": {"status": True, "variable":controller.callbackSetReceivedMessageFormat}, + "/controller/callback_set_received_message_format_with_t": {"status": True, "variable":controller.callbackSetReceivedMessageFormatWithT}, + "/controller/callback_enable_send_received_message_to_vrc": {"status": True, "variable":controller.callbackEnableSendReceivedMessageToVrc}, + "/controller/callback_disable_send_received_message_to_vrc": {"status": True, "variable":controller.callbackDisableSendReceivedMessageToVrc}, + "/controller/callback_enable_logger": {"status": False, "variable":controller.callbackEnableLogger}, + "/controller/callback_disable_logger": {"status": False, "variable":controller.callbackDisableLogger}, + "/controller/callback_set_osc_ip_address": {"status": True, "variable":controller.callbackSetOscIpAddress}, + "/controller/callback_set_osc_port": {"status": True, "variable":controller.callbackSetOscPort}, } action_mapping = { @@ -252,35 +252,6 @@ action_mapping = { } } -def handleConfigRequest(endpoint): - handler = config_mapping.get(endpoint) - if handler is None: - response = "Invalid endpoint" - status = 404 - else: - response = getattr(config, handler) - status = 200 - return response, status - -def handleControllerRequest(endpoint, data=None): - handler = controller_mapping.get(endpoint) - if handler is None: - response = "Invalid endpoint" - status = 404 - else: - action_endpoint = action_mapping.get(endpoint, None) - try: - if action_endpoint is not None: - response = handler(data, Action(action_endpoint).transmit) - else: - response = handler(data) - status = response.get("status", None) - result = response.get("result", None) - except Exception as e: - result = str(e) - status = 500 - return result, status - class Action: def __init__(self, endpoints:dict) -> None: self.endpoints = endpoints @@ -322,20 +293,60 @@ class Main: th_receiver.daemon = True th_receiver.start() + def handleConfigRequest(self, endpoint): + handler = config_mapping.get(endpoint) + if handler is None: + response = "Invalid endpoint" + status = 404 + elif handler["status"] is False: + response = "Locked endpoint" + status = 423 + else: + response = getattr(config, handler["variable"]) + status = 200 + return response, status + + def handleControllerRequest(self, endpoint, data=None): + handler = controller_mapping.get(endpoint) + if handler is None: + response = "Invalid endpoint" + status = 404 + elif handler["status"] is False: + response = "Locked endpoint" + status = 423 + else: + action_endpoint = action_mapping.get(endpoint, None) + try: + if action_endpoint is not None: + response = handler["variable"](data, Action(action_endpoint).transmit) + else: + response = handler["variable"](data) + status = response.get("status", None) + result = response.get("result", None) + except Exception as e: + result = str(e) + status = 500 + return result, status + def configHandler(self) -> None: while True: if not self.queue_config.empty(): endpoint = self.queue_config.get() try: - result, status = handleConfigRequest(endpoint) + result, status = self.handleConfigRequest(endpoint) except Exception as e: import traceback with open('error.log', 'a') as f: traceback.print_exc(file=f) result = str(e) status = 500 - printLog(endpoint, {"send_data":result}) - printResponse(status, endpoint, result) + + if status == 423: + self.queue_config.put(endpoint) + else: + printLog(endpoint, {"send_data":result}) + printResponse(status, endpoint, result) + time.sleep(0.1) def startConfigHandler(self) -> None: th_config = Thread(target=self.configHandler) @@ -343,18 +354,24 @@ class Main: th_config.start() def controllerHandler(self) -> None: - if not self.queue_controller.empty(): - try: - endpoint, data = self.queue_controller.get() - result, status = handleControllerRequest(endpoint, data) - except Exception as e: - import traceback - with open('error.log', 'a') as f: - traceback.print_exc(file=f) - result = str(e) - status = 500 - printLog(endpoint, {"send_data":result}) - printResponse(status, endpoint, result) + while True: + if not self.queue_controller.empty(): + try: + endpoint, data = self.queue_controller.get() + result, status = self.handleControllerRequest(endpoint, data) + except Exception as e: + import traceback + with open('error.log', 'a') as f: + traceback.print_exc(file=f) + result = str(e) + status = 500 + + if status == 423: + self.queue_controller.put((endpoint, data)) + else: + printLog(endpoint, {"send_data":result}) + printResponse(status, endpoint, result) + time.sleep(0.1) def startControllerHandler(self) -> None: th_controller = Thread(target=self.controllerHandler) @@ -369,6 +386,7 @@ if __name__ == "__main__": main = Main() main.startReceiver() main.startConfigHandler() + main.startControllerHandler() controller.init({ "download_ctranslate2": Action(action_mapping["/controller/callback_download_ctranslate2_weight"]).transmit, @@ -376,23 +394,28 @@ if __name__ == "__main__": "update_selected_device": Action(action_mapping["/controller/callback_enable_mic_automatic_selection"]).transmit, }) + # mappingのすべてのstatusをTrueにする + for key in config_mapping.keys(): + config_mapping[key]["status"] = True + for key in controller_mapping.keys(): + controller_mapping[key]["status"] = True + process = "main" match process: case "main": - main.startControllerHandler() main.loop() case "test": for _ in range(100): time.sleep(0.5) endpoint = "/controller/list_mic_host" - result, status = handleControllerRequest(endpoint) + result, status = main.handleControllerRequest(endpoint) printResponse(status, endpoint, result) case "test_all": import time for endpoint, value in config_mapping.items(): - result, status = handleConfigRequest(endpoint) + result, status = main.handleConfigRequest(endpoint) printResponse(status, endpoint, result) time.sleep(0.1) @@ -507,6 +530,6 @@ if __name__ == "__main__": case _: data = None - result, status = handleControllerRequest(endpoint, data) + result, status = main.handleControllerRequest(endpoint, data) printResponse(status, endpoint, result) time.sleep(0.5) \ No newline at end of file From e751f5ddbdb9f1fd56896014fb9202f83b7e7b0a Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Mon, 16 Sep 2024 03:33:27 +0900 Subject: [PATCH 3/7] =?UTF-8?q?=F0=9F=91=8D=EF=B8=8F[Update]=20Model:=20De?= =?UTF-8?q?vice=E3=81=AE=E3=82=A2=E3=82=AF=E3=82=BB=E3=82=B9=E5=B9=B2?= =?UTF-8?q?=E6=B8=89=E3=81=AE=E5=9B=9E=E9=81=BF=E5=87=A6=E7=90=86=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-python/model.py | 61 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/src-python/model.py b/src-python/model.py index 7c5ebb16..6c7b7acf 100644 --- a/src-python/model.py +++ b/src-python/model.py @@ -69,6 +69,7 @@ class Model: def init(self): self.logger = None + self.device_access = False self.th_check_device = None self.mic_print_transcript = None self.mic_audio_recorder = None @@ -407,33 +408,53 @@ class Model: command = [os_path.join(current_directory, batch_name), program_name] Popen(command, cwd=current_directory) - @staticmethod - def getListInputHost(): - return [host for host in getInputDevices().keys()] + def startAccessDevice(self): + while self.device_access is True: + sleep(0.1) + self.device_access = True - @staticmethod - def getInputDefaultDevice(): - return getInputDevices().get(config.CHOICE_MIC_HOST, [{"name": "NoDevice"}])[0]["name"] + def stopAccessDevice(self): + self.device_access = False - @staticmethod - def getListInputDevice(): - return [device["name"] for device in getInputDevices().get(config.CHOICE_MIC_HOST, [{"name": "NoDevice"}])] + def getListInputHost(self): + self.startAccessDevice() + result = [host for host in getInputDevices().keys()] + self.stopAccessDevice() + return result - @staticmethod - def getListOutputDevice(): - return [device["name"] for device in getOutputDevices()] + def getInputDefaultDevice(self): + self.startAccessDevice() + result = getInputDevices().get(config.CHOICE_MIC_HOST, [{"name": "NoDevice"}])[0]["name"] + self.stopAccessDevice() + return result + + def getListInputDevice(self): + self.startAccessDevice() + result = [device["name"] for device in getInputDevices().get(config.CHOICE_MIC_HOST, [{"name": "NoDevice"}])] + self.stopAccessDevice() + return result + + def getListOutputDevice(self): + self.startAccessDevice() + result = [device["name"] for device in getOutputDevices()] + self.stopAccessDevice() + return result def startAutomaticDeviceSelection(self, fnc_mic, fnc_speaker): def checkDevice(fnc_mic, fnc_speaker): if config.ENABLE_MIC_AUTOMATIC_SELECTION is True: + self.startAccessDevice() default_device = getDefaultInputDevice() + self.stopAccessDevice() mic_host_name = default_device["host"]["name"] mic_device_name = default_device["device"]["name"] if mic_host_name != config.CHOICE_MIC_HOST or mic_device_name != config.CHOICE_MIC_DEVICE: fnc_mic(mic_host_name, mic_device_name) if config.ENABLE_SPEAKER_AUTOMATIC_SELECTION is True: + self.startAccessDevice() default_device = getDefaultOutputDevice() + self.stopAccessDevice() speaker_device_name = default_device["device"]["name"] if speaker_device_name != config.CHOICE_SPEAKER_DEVICE: fnc_speaker(speaker_device_name) @@ -452,14 +473,18 @@ class Model: def startMicTranscript(self, fnc): if config.ENABLE_MIC_AUTOMATIC_SELECTION is True: + self.startAccessDevice() default_device = getDefaultInputDevice() + self.stopAccessDevice() mic_host_name = default_device["host"]["name"] mic_device_name = default_device["device"]["name"] else: mic_host_name = config.CHOICE_MIC_HOST mic_device_name = config.CHOICE_MIC_DEVICE + self.startAccessDevice() mic_device_list = getInputDevices().get(mic_host_name, [{"name": "NoDevice"}]) + self.stopAccessDevice() choice_mic_device = [device for device in mic_device_list if device["name"] == mic_device_name] if len(choice_mic_device) == 0: @@ -586,14 +611,18 @@ class Model: self.check_mic_energy_fnc = fnc if config.ENABLE_MIC_AUTOMATIC_SELECTION is True: + self.startAccessDevice() default_device = getDefaultInputDevice() + self.stopAccessDevice() mic_host_name = default_device["host"]["name"] mic_device_name = default_device["device"]["name"] else: mic_host_name = config.CHOICE_MIC_HOST mic_device_name = config.CHOICE_MIC_DEVICE + self.startAccessDevice() mic_device_list = getInputDevices().get(mic_host_name, [{"name": "NoDevice"}]) + self.stopAccessDevice() choice_mic_device = [device for device in mic_device_list if device["name"] == mic_device_name] if len(choice_mic_device) == 0: @@ -628,12 +657,16 @@ class Model: def startSpeakerTranscript(self, fnc): if config.ENABLE_SPEAKER_AUTOMATIC_SELECTION is True: + self.startAccessDevice() default_device = getDefaultOutputDevice() + self.stopAccessDevice() speaker_device_name = default_device["device"]["name"] else: speaker_device_name = config.CHOICE_SPEAKER_DEVICE + self.startAccessDevice() speaker_device_list = getOutputDevices() + self.stopAccessDevice() choice_speaker_device = [device for device in speaker_device_list if device["name"] == speaker_device_name] if len(choice_speaker_device) == 0: @@ -720,12 +753,16 @@ class Model: self.check_speaker_energy_fnc = fnc if config.ENABLE_SPEAKER_AUTOMATIC_SELECTION is True: + self.startAccessDevice() default_device = getDefaultOutputDevice() + self.stopAccessDevice() speaker_device_name = default_device["device"]["name"] else: speaker_device_name = config.CHOICE_SPEAKER_DEVICE + self.startAccessDevice() speaker_device_list = getOutputDevices() + self.stopAccessDevice() choice_speaker_device = [device for device in speaker_device_list if device["name"] == speaker_device_name] if len(choice_speaker_device) == 0: From d21e0a09fc59f01fd19f53cd82f59fa11bc36693 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Mon, 16 Sep 2024 23:05:30 +0900 Subject: [PATCH 4/7] =?UTF-8?q?=F0=9F=91=8D=EF=B8=8F[Update]=20Model:=20De?= =?UTF-8?q?vice=E3=81=AE=E3=82=A2=E3=82=AF=E3=82=BB=E3=82=B9=E5=B9=B2?= =?UTF-8?q?=E6=B8=89=E3=81=AE=E5=9B=9E=E9=81=BF=E5=87=A6=E7=90=86=E3=82=92?= =?UTF-8?q?=E3=81=99=E3=82=8B=E3=81=9F=E3=82=81=E3=81=ABDevice=E3=81=AE?= =?UTF-8?q?=E6=A4=9C=E5=87=BA=E3=82=92=E5=B8=B8=E3=81=AB=E8=A1=8C=E3=81=86?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-python/config.py | 14 +- src-python/model.py | 67 ++----- .../transcription/transcription_utils.py | 175 ++++++++++++------ 3 files changed, 138 insertions(+), 118 deletions(-) diff --git a/src-python/config.py b/src-python/config.py index d781aacb..18d0e432 100644 --- a/src-python/config.py +++ b/src-python/config.py @@ -5,7 +5,7 @@ from json import load as json_load from json import dump as json_dump import tkinter as tk from tkinter import font -from models.transcription.transcription_utils import getInputDevices, getDefaultInputDevice, getOutputDevices, getDefaultOutputDevice +from models.transcription.transcription_utils import device_manager from models.transcription.transcription_languages import transcription_lang from utils import generatePercentageStringsList, isUniqueStrings @@ -470,7 +470,7 @@ class Config: @CHOICE_MIC_HOST.setter def CHOICE_MIC_HOST(self, value): - if value in [host for host in getInputDevices().keys()]: + if value in [host for host in device_manager.getInputDevices().keys()]: self._CHOICE_MIC_HOST = value saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) @@ -481,7 +481,7 @@ class Config: @CHOICE_MIC_DEVICE.setter def CHOICE_MIC_DEVICE(self, value): - if value in [device["name"] for device in getInputDevices()[self.CHOICE_MIC_HOST]]: + if value in [device["name"] for device in device_manager.getInputDevices()[self.CHOICE_MIC_HOST]]: self._CHOICE_MIC_DEVICE = value saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) @@ -591,7 +591,7 @@ class Config: @CHOICE_SPEAKER_DEVICE.setter def CHOICE_SPEAKER_DEVICE(self, value): - if value in [device["name"] for device in getOutputDevices()]: + if value in [device["name"] for device in device_manager.getOutputDevices()]: self._CHOICE_SPEAKER_DEVICE = value saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) @@ -1117,8 +1117,8 @@ class Config: "height": "654", } self._ENABLE_MIC_AUTOMATIC_SELECTION = True - self._CHOICE_MIC_HOST = getDefaultInputDevice()["host"]["name"] - self._CHOICE_MIC_DEVICE = getDefaultInputDevice()["device"]["name"] + self._CHOICE_MIC_HOST = device_manager.getDefaultInputDevice()["host"]["name"] + self._CHOICE_MIC_DEVICE = device_manager.getDefaultInputDevice()["device"]["name"] self._INPUT_MIC_ENERGY_THRESHOLD = 300 self._INPUT_MIC_DYNAMIC_ENERGY_THRESHOLD = False self._INPUT_MIC_RECORD_TIMEOUT = 3 @@ -1128,7 +1128,7 @@ class Config: self._INPUT_MIC_AVG_LOGPROB=-0.8 self._INPUT_MIC_NO_SPEECH_PROB=0.6 self._ENABLE_SPEAKER_AUTOMATIC_SELECTION = True - self._CHOICE_SPEAKER_DEVICE = getDefaultOutputDevice()["device"]["name"] + self._CHOICE_SPEAKER_DEVICE = device_manager.getDefaultOutputDevice()["device"]["name"] self._INPUT_SPEAKER_ENERGY_THRESHOLD = 300 self._INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD = False self._INPUT_SPEAKER_RECORD_TIMEOUT = 3 diff --git a/src-python/model.py b/src-python/model.py index 6c7b7acf..02aeddc8 100644 --- a/src-python/model.py +++ b/src-python/model.py @@ -17,7 +17,7 @@ from typing import Callable from flashtext import KeywordProcessor from pykakasi import kakasi from models.translation.translation_translator import Translator -from models.transcription.transcription_utils import getInputDevices, getOutputDevices, getDefaultInputDevice, getDefaultOutputDevice +from models.transcription.transcription_utils import device_manager from models.osc.osc_tools import sendTyping, sendMessage, receiveOscParameters, getOSCParameterValue from models.transcription.transcription_recorder import SelectedMicEnergyAndAudioRecorder, SelectedSpeakerEnergyAndAudioRecorder from models.transcription.transcription_recorder import SelectedMicEnergyRecorder, SelectedSpeakerEnergyRecorder @@ -69,7 +69,6 @@ class Model: def init(self): self.logger = None - self.device_access = False self.th_check_device = None self.mic_print_transcript = None self.mic_audio_recorder = None @@ -408,53 +407,33 @@ class Model: command = [os_path.join(current_directory, batch_name), program_name] Popen(command, cwd=current_directory) - def startAccessDevice(self): - while self.device_access is True: - sleep(0.1) - self.device_access = True - - def stopAccessDevice(self): - self.device_access = False - def getListInputHost(self): - self.startAccessDevice() - result = [host for host in getInputDevices().keys()] - self.stopAccessDevice() + result = [host for host in device_manager.getInputDevices().keys()] return result def getInputDefaultDevice(self): - self.startAccessDevice() - result = getInputDevices().get(config.CHOICE_MIC_HOST, [{"name": "NoDevice"}])[0]["name"] - self.stopAccessDevice() + result = device_manager.getInputDevices().get(config.CHOICE_MIC_HOST, [{"name": "NoDevice"}])[0]["name"] return result def getListInputDevice(self): - self.startAccessDevice() - result = [device["name"] for device in getInputDevices().get(config.CHOICE_MIC_HOST, [{"name": "NoDevice"}])] - self.stopAccessDevice() + result = [device["name"] for device in device_manager.getInputDevices().get(config.CHOICE_MIC_HOST, [{"name": "NoDevice"}])] return result def getListOutputDevice(self): - self.startAccessDevice() - result = [device["name"] for device in getOutputDevices()] - self.stopAccessDevice() + result = [device["name"] for device in device_manager.getOutputDevices()] return result def startAutomaticDeviceSelection(self, fnc_mic, fnc_speaker): def checkDevice(fnc_mic, fnc_speaker): if config.ENABLE_MIC_AUTOMATIC_SELECTION is True: - self.startAccessDevice() - default_device = getDefaultInputDevice() - self.stopAccessDevice() + default_device = device_manager.getDefaultInputDevice() mic_host_name = default_device["host"]["name"] mic_device_name = default_device["device"]["name"] if mic_host_name != config.CHOICE_MIC_HOST or mic_device_name != config.CHOICE_MIC_DEVICE: fnc_mic(mic_host_name, mic_device_name) if config.ENABLE_SPEAKER_AUTOMATIC_SELECTION is True: - self.startAccessDevice() - default_device = getDefaultOutputDevice() - self.stopAccessDevice() + default_device = device_manager.getDefaultOutputDevice() speaker_device_name = default_device["device"]["name"] if speaker_device_name != config.CHOICE_SPEAKER_DEVICE: fnc_speaker(speaker_device_name) @@ -473,18 +452,14 @@ class Model: def startMicTranscript(self, fnc): if config.ENABLE_MIC_AUTOMATIC_SELECTION is True: - self.startAccessDevice() - default_device = getDefaultInputDevice() - self.stopAccessDevice() + default_device = device_manager.getDefaultInputDevice() mic_host_name = default_device["host"]["name"] mic_device_name = default_device["device"]["name"] else: mic_host_name = config.CHOICE_MIC_HOST mic_device_name = config.CHOICE_MIC_DEVICE - self.startAccessDevice() - mic_device_list = getInputDevices().get(mic_host_name, [{"name": "NoDevice"}]) - self.stopAccessDevice() + mic_device_list = device_manager.getInputDevices().get(mic_host_name, [{"name": "NoDevice"}]) choice_mic_device = [device for device in mic_device_list if device["name"] == mic_device_name] if len(choice_mic_device) == 0: @@ -611,18 +586,14 @@ class Model: self.check_mic_energy_fnc = fnc if config.ENABLE_MIC_AUTOMATIC_SELECTION is True: - self.startAccessDevice() - default_device = getDefaultInputDevice() - self.stopAccessDevice() + default_device = device_manager.getDefaultInputDevice() mic_host_name = default_device["host"]["name"] mic_device_name = default_device["device"]["name"] else: mic_host_name = config.CHOICE_MIC_HOST mic_device_name = config.CHOICE_MIC_DEVICE - self.startAccessDevice() - mic_device_list = getInputDevices().get(mic_host_name, [{"name": "NoDevice"}]) - self.stopAccessDevice() + mic_device_list = device_manager.getInputDevices().get(mic_host_name, [{"name": "NoDevice"}]) choice_mic_device = [device for device in mic_device_list if device["name"] == mic_device_name] if len(choice_mic_device) == 0: @@ -657,16 +628,12 @@ class Model: def startSpeakerTranscript(self, fnc): if config.ENABLE_SPEAKER_AUTOMATIC_SELECTION is True: - self.startAccessDevice() - default_device = getDefaultOutputDevice() - self.stopAccessDevice() + default_device = device_manager.getDefaultOutputDevice() speaker_device_name = default_device["device"]["name"] else: speaker_device_name = config.CHOICE_SPEAKER_DEVICE - self.startAccessDevice() - speaker_device_list = getOutputDevices() - self.stopAccessDevice() + speaker_device_list = device_manager.getOutputDevices() choice_speaker_device = [device for device in speaker_device_list if device["name"] == speaker_device_name] if len(choice_speaker_device) == 0: @@ -753,16 +720,12 @@ class Model: self.check_speaker_energy_fnc = fnc if config.ENABLE_SPEAKER_AUTOMATIC_SELECTION is True: - self.startAccessDevice() - default_device = getDefaultOutputDevice() - self.stopAccessDevice() + default_device = device_manager.getDefaultOutputDevice() speaker_device_name = default_device["device"]["name"] else: speaker_device_name = config.CHOICE_SPEAKER_DEVICE - self.startAccessDevice() - speaker_device_list = getOutputDevices() - self.stopAccessDevice() + speaker_device_list = device_manager.getOutputDevices() choice_speaker_device = [device for device in speaker_device_list if device["name"] == speaker_device_name] if len(choice_speaker_device) == 0: diff --git a/src-python/models/transcription/transcription_utils.py b/src-python/models/transcription/transcription_utils.py index 4292ba23..2281fa22 100644 --- a/src-python/models/transcription/transcription_utils.py +++ b/src-python/models/transcription/transcription_utils.py @@ -1,70 +1,127 @@ +from time import sleep +from threading import Thread from pyaudiowpatch import PyAudio, paWASAPI -def getInputDevices(): - devices = {} - with PyAudio() as p: - for host_index in range(0, p.get_host_api_count()): - host = p.get_host_api_info_by_index(host_index) - for device_index in range(0, p.get_host_api_info_by_index(host_index)['deviceCount']): - device = p.get_device_info_by_host_api_device_index(host_index, device_index) - if device["maxInputChannels"] > 0 and device["isLoopbackDevice"] is False: - if host["name"] in devices.keys(): - devices[host["name"]].append(device) - else: - devices[host["name"]] = [device] - if len(devices) == 0: - devices = {"NoHost": [{"name": "NoDevice"}]} - return devices +class DeviceManager: + _instance = None -def getDefaultInputDevice(): - with PyAudio() as p: - api_info = p.get_default_host_api_info() - defaultInputDevice = api_info["defaultInputDevice"] + def __new__(cls): + if cls._instance is None: + cls._instance = super(DeviceManager, cls).__new__(cls) + cls._instance.init() + return cls._instance - for host_index in range(0, p.get_host_api_count()): - host = p.get_host_api_info_by_index(host_index) - for device_index in range(0, p.get_host_api_info_by_index(host_index)['deviceCount']): - device = p.get_device_info_by_host_api_device_index(host_index, device_index) - if device["index"] == defaultInputDevice: - return {"host": host, "device": device} - return {"host": {"name": "NoHost"}, "device": {"name": "NoDevice"}} + def init(self): + self.input_devices = {"NoHost": [{"name": "NoDevice"}]} + self.default_input_device = {"host": {"name": "NoHost"}, "device": {"name": "NoDevice"}} + self.output_devices = [{"name": "NoDevice"}] + self.default_output_device = {"device": {"name": "NoDevice"}} + self.update() -def getOutputDevices(): - devices = [] - with PyAudio() as p: - wasapi_info = p.get_host_api_info_by_type(paWASAPI) - for host_index in range(0, p.get_host_api_count()): - host = p.get_host_api_info_by_index(host_index) - if host["name"] == wasapi_info["name"]: - for device_index in range(0, p.get_host_api_info_by_index(host_index)['deviceCount']): + self.monitoring_flag = True + self.th_monitoring = Thread(target=self.startMonitoring) + self.th_monitoring.daemon = True + self.th_monitoring.start() + + def update(self): + buffer_input_devices = {} + buffer_default_input_device = {"host": {"name": "NoHost"}, "device": {"name": "NoDevice"}} + buffer_output_devices = [] + buffer_default_output_device = {"device": {"name": "NoDevice"}} + + with PyAudio() as p: + for host_index in range(p.get_host_api_count()): + host = p.get_host_api_info_by_index(host_index) + device_count = host.get('deviceCount', 0) + for device_index in range(device_count): device = p.get_device_info_by_host_api_device_index(host_index, device_index) - if not device["isLoopbackDevice"]: - for loopback in p.get_loopback_device_info_generator(): - if device["name"] in loopback["name"]: - devices.append(loopback) + if device.get("maxInputChannels", 0) > 0 and not device.get("isLoopbackDevice", True): + buffer_input_devices.setdefault(host["name"], []).append(device) + if not buffer_input_devices: + buffer_input_devices = {"NoHost": [{"name": "NoDevice"}]} - if len(devices) == 0: - devices = [{"name": "NoDevice"}] - else: - devices = [dict(t) for t in {tuple(d.items()) for d in devices}] - return devices + api_info = p.get_default_host_api_info() + default_input_device = api_info["defaultInputDevice"] -def getDefaultOutputDevice(): - with PyAudio() as p: - wasapi_info = p.get_host_api_info_by_type(paWASAPI) - defaultOutputDevice = wasapi_info["defaultOutputDevice"] + for host_index in range(p.get_host_api_count()): + host = p.get_host_api_info_by_index(host_index) + device_count = host.get('deviceCount', 0) + for device_index in range(device_count): + device = p.get_device_info_by_host_api_device_index(host_index, device_index) + if device["index"] == default_input_device: + buffer_default_input_device = {"host": host, "device": device} + break + else: + continue + break - for host_index in range(0, p.get_host_api_count()): - for device_index in range(0, p. get_host_api_info_by_index(host_index)['deviceCount']): - device = p.get_device_info_by_host_api_device_index(host_index, device_index) - if device["index"] == defaultOutputDevice: - default_speakers = device - if not default_speakers["isLoopbackDevice"]: - for loopback in p.get_loopback_device_info_generator(): - if default_speakers["name"] in loopback["name"]: - return {"device": loopback} - return {"device": {"name": "NoDevice"}} + output_devices = [] + wasapi_info = p.get_host_api_info_by_type(paWASAPI) + wasapi_name = wasapi_info["name"] + for host_index in range(p.get_host_api_count()): + host = p.get_host_api_info_by_index(host_index) + if host["name"] == wasapi_name: + device_count = host.get('deviceCount', 0) + for device_index in range(device_count): + device = p.get_device_info_by_host_api_device_index(host_index, device_index) + if not device.get("isLoopbackDevice", True): + for loopback in p.get_loopback_device_info_generator(): + if device["name"] in loopback["name"]: + output_devices.append(loopback) + output_devices = [dict(t) for t in {tuple(d.items()) for d in output_devices}] or [{"name": "NoDevice"}] + buffer_output_devices = sorted(output_devices, key=lambda d: d['index']) + + wasapi_info = p.get_host_api_info_by_type(paWASAPI) + default_output_device_index = wasapi_info["defaultOutputDevice"] + + for host_index in range(p.get_host_api_count()): + host_info = p.get_host_api_info_by_index(host_index) + device_count = host_info.get('deviceCount', 0) + for device_index in range(0, device_count): + device = p.get_device_info_by_host_api_device_index(host_index, device_index) + if device["index"] == default_output_device_index: + default_speakers = device + if not default_speakers.get("isLoopbackDevice", True): + for loopback in p.get_loopback_device_info_generator(): + if default_speakers["name"] in loopback["name"]: + buffer_default_output_device = {"device": loopback} + break + break + + if buffer_default_output_device["device"]["name"] != "NoDevice": + break + + self.input_devices = buffer_input_devices + self.default_input_device = buffer_default_input_device + self.output_devices = buffer_output_devices + self.default_output_device = buffer_default_output_device + + def startMonitoring(self): + self.monitoring_flag = True + while self.monitoring_flag is True: + self.update() + sleep(1) + + def stopMonitoring(self): + self.monitoring_flag = False + self.th_monitoring.join() + + def getInputDevices(self): + return self.input_devices + + def getDefaultInputDevice(self): + return self.default_input_device + + def getOutputDevices(self): + return self.output_devices + + def getDefaultOutputDevice(self): + return self.default_output_device + +device_manager = DeviceManager() if __name__ == "__main__": - print("getOutputDevices()", getOutputDevices()) - print("getDefaultOutputDevice()", getDefaultOutputDevice()) \ No newline at end of file + print("getInputDevices()", device_manager.getInputDevices()) + print("getDefaultInputDevice()", device_manager.getDefaultInputDevice()) + print("getOutputDevices()", device_manager.getOutputDevices()) + print("getDefaultOutputDevice()", device_manager.getDefaultOutputDevice()) \ No newline at end of file From d7d41c2e662a6a76256b6f1bead968f92b35c017 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Wed, 18 Sep 2024 15:54:06 +0900 Subject: [PATCH 5/7] =?UTF-8?q?=F0=9F=91=8D=EF=B8=8F[Update]=20Model:=20De?= =?UTF-8?q?fault=20Audio=20Device=E3=81=AE=E5=A4=89=E6=9B=B4/Device?= =?UTF-8?q?=E3=81=AE=E8=BF=BD=E5=8A=A0/=E5=89=8A=E9=99=A4=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=81=9F=E5=A0=B4=E5=90=88=E3=81=AE=E3=81=BFDevice?= =?UTF-8?q?=E6=83=85=E5=A0=B1=E3=82=92=E6=9B=B4=E6=96=B0=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 1 + .../transcription/transcription_utils.py | 61 +++++++++++++++---- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/requirements.txt b/requirements.txt index d0c6e664..72270760 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,6 +14,7 @@ openvr==1.26.701 pydub==0.25.1 psutil==5.9.8 pykakasi==2.3.0 +pycaw==20240210 translators @ git+https://github.com/misyaguziya/translators@5.9.2.1 SpeechRecognition @ git+https://github.com/misyaguziya/custom_speech_recognition@3.10.4 tinyoscquery @ git+https://github.com/cyberkitsune/tinyoscquery@0.1.2 \ No newline at end of file diff --git a/src-python/models/transcription/transcription_utils.py b/src-python/models/transcription/transcription_utils.py index 2281fa22..5842c89e 100644 --- a/src-python/models/transcription/transcription_utils.py +++ b/src-python/models/transcription/transcription_utils.py @@ -1,6 +1,23 @@ from time import sleep from threading import Thread +import comtypes from pyaudiowpatch import PyAudio, paWASAPI +from pycaw.callbacks import MMNotificationClient +from pycaw.utils import AudioUtilities + +class Client(MMNotificationClient): + def __init__(self): + super().__init__() + self.loop = True + + def on_default_device_changed(self, flow, flow_id, role, role_id, default_device_id): + self.loop = False + + def on_device_added(self, added_device_id): + self.loop = False + + def on_device_removed(self, removed_device_id): + self.loop = False class DeviceManager: _instance = None @@ -18,10 +35,8 @@ class DeviceManager: self.default_output_device = {"device": {"name": "NoDevice"}} self.update() - self.monitoring_flag = True - self.th_monitoring = Thread(target=self.startMonitoring) - self.th_monitoring.daemon = True - self.th_monitoring.start() + self.monitoring_flag = False + self.startMonitoring() def update(self): buffer_input_devices = {} @@ -96,11 +111,32 @@ class DeviceManager: self.output_devices = buffer_output_devices self.default_output_device = buffer_default_output_device + print("default_input_device", self.default_input_device) + + def monitoring(self): + comtypes.CoInitialize() + cb = Client() + enumerator = AudioUtilities.GetDeviceEnumerator() + enumerator.RegisterEndpointNotificationCallback(cb) + try: + while self.monitoring_flag is True: + while cb.loop is True: + sleep(1) + enumerator.UnregisterEndpointNotificationCallback(cb) + self.update() + + cb = Client() + enumerator = AudioUtilities.GetDeviceEnumerator() + enumerator.RegisterEndpointNotificationCallback(cb) + except Exception: + pass + comtypes.CoUninitialize() + def startMonitoring(self): self.monitoring_flag = True - while self.monitoring_flag is True: - self.update() - sleep(1) + self.th_monitoring = Thread(target=self.monitoring) + self.th_monitoring.daemon = True + self.th_monitoring.start() def stopMonitoring(self): self.monitoring_flag = False @@ -121,7 +157,10 @@ class DeviceManager: device_manager = DeviceManager() if __name__ == "__main__": - print("getInputDevices()", device_manager.getInputDevices()) - print("getDefaultInputDevice()", device_manager.getDefaultInputDevice()) - print("getOutputDevices()", device_manager.getOutputDevices()) - print("getDefaultOutputDevice()", device_manager.getDefaultOutputDevice()) \ No newline at end of file + # print("getInputDevices()", device_manager.getInputDevices()) + # print("getDefaultInputDevice()", device_manager.getDefaultInputDevice()) + # print("getOutputDevices()", device_manager.getOutputDevices()) + # print("getDefaultOutputDevice()", device_manager.getDefaultOutputDevice()) + + while True: + sleep(1) \ No newline at end of file From f34d5183d137be00bb223298b06755f22f825628 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Wed, 18 Sep 2024 16:44:56 +0900 Subject: [PATCH 6/7] =?UTF-8?q?=F0=9F=90=9B[bugfix]=20Model=20:=20?= =?UTF-8?q?=E3=83=87=E3=83=90=E3=83=83=E3=82=B0=E7=94=A8=E3=81=AEprint?= =?UTF-8?q?=E6=96=87=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-python/models/transcription/transcription_utils.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src-python/models/transcription/transcription_utils.py b/src-python/models/transcription/transcription_utils.py index 5842c89e..0d0854e5 100644 --- a/src-python/models/transcription/transcription_utils.py +++ b/src-python/models/transcription/transcription_utils.py @@ -111,8 +111,6 @@ class DeviceManager: self.output_devices = buffer_output_devices self.default_output_device = buffer_default_output_device - print("default_input_device", self.default_input_device) - def monitoring(self): comtypes.CoInitialize() cb = Client() From aa30c248d5326c6416f158f571b01d5aaf4b9383 Mon Sep 17 00:00:00 2001 From: misyaguziya Date: Wed, 18 Sep 2024 17:38:32 +0900 Subject: [PATCH 7/7] =?UTF-8?q?=F0=9F=91=8D=EF=B8=8F[Update]=20Model:=20EN?= =?UTF-8?q?ABLE=5FMIC=5FAUTOMATIC=5FSELECTION/ENABLE=5FSPEAKER=5FAUTOMATIC?= =?UTF-8?q?=5FSELECTION=E3=81=AE=E5=87=A6=E7=90=86=E3=82=92device=5Fmanage?= =?UTF-8?q?r=E3=81=AEcallback=E3=81=A7=E5=AE=9F=E8=A1=8C=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-python/model.py | 27 --------------- .../transcription/transcription_utils.py | 20 +++++++++++ src-python/webui_controller.py | 33 ++++++++++++------- src-python/webui_mainloop.py | 5 ++- 4 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src-python/model.py b/src-python/model.py index 02aeddc8..73f11a52 100644 --- a/src-python/model.py +++ b/src-python/model.py @@ -423,33 +423,6 @@ class Model: result = [device["name"] for device in device_manager.getOutputDevices()] return result - def startAutomaticDeviceSelection(self, fnc_mic, fnc_speaker): - def checkDevice(fnc_mic, fnc_speaker): - if config.ENABLE_MIC_AUTOMATIC_SELECTION is True: - default_device = device_manager.getDefaultInputDevice() - mic_host_name = default_device["host"]["name"] - mic_device_name = default_device["device"]["name"] - if mic_host_name != config.CHOICE_MIC_HOST or mic_device_name != config.CHOICE_MIC_DEVICE: - fnc_mic(mic_host_name, mic_device_name) - - if config.ENABLE_SPEAKER_AUTOMATIC_SELECTION is True: - default_device = device_manager.getDefaultOutputDevice() - speaker_device_name = default_device["device"]["name"] - if speaker_device_name != config.CHOICE_SPEAKER_DEVICE: - fnc_speaker(speaker_device_name) - sleep(1) - - if isinstance(self.th_check_device, threadFnc) is False: - self.th_check_device = threadFnc(checkDevice, args=(fnc_mic, fnc_speaker,)) - self.th_check_device.daemon = True - self.th_check_device.start() - - def stopAutomaticDeviceSelection(self): - if config.ENABLE_MIC_AUTOMATIC_SELECTION is False and config.ENABLE_SPEAKER_AUTOMATIC_SELECTION is False: - if isinstance(self.th_check_device, threadFnc): - self.th_check_device.stop() - self.th_check_device = None - def startMicTranscript(self, fnc): if config.ENABLE_MIC_AUTOMATIC_SELECTION is True: default_device = device_manager.getDefaultInputDevice() diff --git a/src-python/models/transcription/transcription_utils.py b/src-python/models/transcription/transcription_utils.py index 0d0854e5..2b51ec31 100644 --- a/src-python/models/transcription/transcription_utils.py +++ b/src-python/models/transcription/transcription_utils.py @@ -35,6 +35,9 @@ class DeviceManager: self.default_output_device = {"device": {"name": "NoDevice"}} self.update() + self.callback_default_input_device = None + self.callback_default_output_device = None + self.monitoring_flag = False self.startMonitoring() @@ -123,6 +126,11 @@ class DeviceManager: enumerator.UnregisterEndpointNotificationCallback(cb) self.update() + if self.callback_default_input_device is not None: + self.callback_default_input_device(self.default_input_device["host"]["name"], self.default_input_device["device"]["name"]) + if self.callback_default_output_device is not None: + self.callback_default_output_device(self.default_output_device["device"]["name"]) + cb = Client() enumerator = AudioUtilities.GetDeviceEnumerator() enumerator.RegisterEndpointNotificationCallback(cb) @@ -140,6 +148,18 @@ class DeviceManager: self.monitoring_flag = False self.th_monitoring.join() + def setCallbackDefaultInputDevice(self, callback): + self.callback_default_input_device = callback + + def clearCallbackDefaultInputDevice(self): + self.callback_default_input_device = None + + def setCallbackDefaultOutputDevice(self, callback): + self.callback_default_output_device = callback + + def clearCallbackDefaultOutputDevice(self): + self.callback_default_output_device = None + def getInputDevices(self): return self.input_devices diff --git a/src-python/webui_controller.py b/src-python/webui_controller.py index 722130e9..b78b92e5 100644 --- a/src-python/webui_controller.py +++ b/src-python/webui_controller.py @@ -6,6 +6,7 @@ import re from config import config from model import model from utils import isUniqueStrings, printLog +from models.transcription.transcription_utils import device_manager # Common class DownloadSoftwareProgressBar: @@ -778,11 +779,11 @@ def callbackClearDeeplAuthKey(*args, **kwargs) -> dict: # Transcription Tab # Transcription (Mic) -class UpdateSelectedDevice: +class UpdateSelectedMicDevice: def __init__(self, action): self.action = action - def set_mic(self, host, device) -> None: + def set(self, host, device) -> None: config.CHOICE_MIC_HOST = host config.CHOICE_MIC_DEVICE = device printLog("Update Host/Mic Device", f"{host}/{device}") @@ -791,7 +792,11 @@ class UpdateSelectedDevice: "result":{"host":host, "device":device} }) - def set_speaker(self, device) -> None: +class UpdateSelectedSpeakerDevice: + def __init__(self, action): + self.action = action + + def set(self, device) -> None: config.CHOICE_SPEAKER_DEVICE = device printLog("Update Speaker Device", device) self.action("speaker", { @@ -801,27 +806,27 @@ class UpdateSelectedDevice: def callbackEnableMicAutomaticSelection(data, action, *args, **kwargs) -> dict: printLog("Enable Mic Automatic Selection") - update_device = UpdateSelectedDevice(action) - model.startAutomaticDeviceSelection(update_device.set_mic, update_device.set_speaker) + update_device = UpdateSelectedMicDevice(action) + device_manager.setCallbackDefaultInputDevice(update_device.set) config.ENABLE_MIC_AUTOMATIC_SELECTION = True return {"status":200, "result":config.ENABLE_MIC_AUTOMATIC_SELECTION} def callbackDisableMicAutomaticSelection(*args, **kwargs) -> dict: printLog("Disable Mic Automatic Selection") - model.stopAutomaticDeviceSelection() + device_manager.clearCallbackDefaultInputDevice() config.ENABLE_MIC_AUTOMATIC_SELECTION = False return {"status":200, "result":config.ENABLE_MIC_AUTOMATIC_SELECTION} def callbackEnableSpeakerAutomaticSelection(data, action, *args, **kwargs) -> dict: printLog("Enable Speaker Automatic Selection") - update_device = UpdateSelectedDevice(action) - model.startAutomaticDeviceSelection(update_device.set_mic, update_device.set_speaker) + update_device = UpdateSelectedSpeakerDevice(action) + device_manager.setCallbackDefaultOutputDevice(update_device.set) config.ENABLE_SPEAKER_AUTOMATIC_SELECTION = True return {"status":200, "result":config.ENABLE_SPEAKER_AUTOMATIC_SELECTION} def callbackDisableSpeakerAutomaticSelection(*args, **kwargs) -> dict: printLog("Disable Speaker Automatic Selection") - model.stopAutomaticDeviceSelection() + device_manager.clearCallbackDefaultInputDevice() config.ENABLE_SPEAKER_AUTOMATIC_SELECTION = False return {"status":200, "result":config.ENABLE_SPEAKER_AUTOMATIC_SELECTION} @@ -1412,8 +1417,12 @@ def init(actions:dict, *args, **kwargs) -> None: # init Auto device selection printLog("Init Auto Device Selection") - if config.ENABLE_MIC_AUTOMATIC_SELECTION is True or config.ENABLE_SPEAKER_AUTOMATIC_SELECTION is True: - update_device = UpdateSelectedDevice(actions["update_selected_device"]) - model.startAutomaticDeviceSelection(update_device.set_mic, update_device.set_speaker) + if config.ENABLE_MIC_AUTOMATIC_SELECTION is True: + update_mic_device = UpdateSelectedMicDevice(actions["update_selected_mic_device"]) + device_manager.setCallbackDefaultInputDevice(update_mic_device.set) + + if config.ENABLE_SPEAKER_AUTOMATIC_SELECTION is True: + update_speaker_device = UpdateSelectedSpeakerDevice(actions["update_selected_speaker_device"]) + device_manager.setCallbackDefaultOutputDevice(update_speaker_device.set) printLog("End Initialization") \ No newline at end of file diff --git a/src-python/webui_mainloop.py b/src-python/webui_mainloop.py index aac62345..0e4b11f3 100644 --- a/src-python/webui_mainloop.py +++ b/src-python/webui_mainloop.py @@ -244,10 +244,8 @@ action_mapping = { }, "/controller/callback_enable_mic_automatic_selection": { "mic":"/controller/callback_set_mic_host", - "speaker":"/controller/callback_set_speaker_device", }, "/controller/callback_enable_speaker_automatic_selection": { - "mic":"/controller/callback_set_mic_host", "speaker":"/controller/callback_set_speaker_device", } } @@ -391,7 +389,8 @@ if __name__ == "__main__": controller.init({ "download_ctranslate2": Action(action_mapping["/controller/callback_download_ctranslate2_weight"]).transmit, "download_whisper": Action(action_mapping["/controller/callback_download_whisper_weight"]).transmit, - "update_selected_device": Action(action_mapping["/controller/callback_enable_mic_automatic_selection"]).transmit, + "update_selected_mic_device": Action(action_mapping["/controller/callback_enable_mic_automatic_selection"]).transmit, + "update_selected_speaker_device": Action(action_mapping["/controller/callback_enable_speaker_automatic_selection"]).transmit, }) # mappingのすべてのstatusをTrueにする