diff --git a/requirements.txt b/requirements.txt index bf32dda5..2b4bc322 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,6 +13,7 @@ faster-whisper==1.0.3 openvr==1.26.701 pydub==0.25.1 psutil==5.9.8 +pykakasi==2.3.0 translators @ git+https://github.com/misyaguziya/translators@5.9.2 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/config.py b/src-python/config.py index 6152eddb..5d4c2cfd 100644 --- a/src-python/config.py +++ b/src-python/config.py @@ -319,6 +319,28 @@ class Config: self._ENABLE_MULTI_LANGUAGE_TRANSLATION = value saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + @property + @json_serializable('ENABLE_CONVERT_MESSAGE_TO_ROMAJI') + def ENABLE_CONVERT_MESSAGE_TO_ROMAJI(self): + return self._ENABLE_CONVERT_MESSAGE_TO_ROMAJI + + @ENABLE_CONVERT_MESSAGE_TO_ROMAJI.setter + def ENABLE_CONVERT_MESSAGE_TO_ROMAJI(self, value): + if isinstance(value, bool): + self._ENABLE_CONVERT_MESSAGE_TO_ROMAJI = value + saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + + @property + @json_serializable('ENABLE_CONVERT_MESSAGE_TO_HIRAGANA') + def ENABLE_CONVERT_MESSAGE_TO_HIRAGANA(self): + return self._ENABLE_CONVERT_MESSAGE_TO_HIRAGANA + + @ENABLE_CONVERT_MESSAGE_TO_HIRAGANA.setter + def ENABLE_CONVERT_MESSAGE_TO_HIRAGANA(self, value): + if isinstance(value, bool): + self._ENABLE_CONVERT_MESSAGE_TO_HIRAGANA = value + saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) + @property @json_serializable('IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE') def IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE(self): @@ -1065,6 +1087,8 @@ class Config: } self._SELECTED_TRANSCRIPTION_ENGINE = "Google" self._ENABLE_MULTI_LANGUAGE_TRANSLATION = False + self._ENABLE_CONVERT_MESSAGE_TO_ROMAJI = False + self._ENABLE_CONVERT_MESSAGE_TO_HIRAGANA = False self._IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE = False ## Config Window diff --git a/src-python/model.py b/src-python/model.py index 29e8d5a4..d17009d8 100644 --- a/src-python/model.py +++ b/src-python/model.py @@ -15,13 +15,13 @@ import webbrowser 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 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 from models.transcription.transcription_transcriber import AudioTranscriber -from models.xsoverlay.notification import xsoverlayForVRCT from models.translation.translation_languages import translation_lang from models.transcription.transcription_languages import transcription_lang from models.translation.translation_utils import checkCTranslate2Weight, downloadCTranslate2Weight @@ -99,6 +99,7 @@ class Model: self.mic_audio_queue = None self.mic_mute_status = None self.mic_mute_status_check = None + self.kks = kakasi() def checkCTranslatorCTranslate2ModelWeight(self): return checkCTranslate2Weight(config.PATH_LOCAL, config.CTRANSLATE2_WEIGHT_TYPE) @@ -270,6 +271,15 @@ class Model: self.previous_receive_message = message return repeat_flag + def convertMessageToTransliteration(self, message: str) -> str: + data_list = self.kks.convert(message) + keys_to_keep = {"orig", "hira", "hepburn"} + filtered_list = [] + for item in data_list: + filtered_item = {key: value for key, value in item.items() if key in keys_to_keep} + filtered_list.append(filtered_item) + return filtered_list + @staticmethod def oscStartSendTyping(): sendTyping(True, config.OSC_IP_ADDRESS, config.OSC_PORT) diff --git a/src-python/webui_controller.py b/src-python/webui_controller.py index 099ff9bd..d15beb03 100644 --- a/src-python/webui_controller.py +++ b/src-python/webui_controller.py @@ -98,6 +98,7 @@ class MicMessage: elif isinstance(message, str) and len(message) > 0: # addSentMessageLog(message) translation = [] + transliteration = [] if model.checkKeywords(message): self.action("word_filter", { "status":200, @@ -121,6 +122,10 @@ class MicMessage: } }) + if config.ENABLE_CONVERT_MESSAGE_TO_ROMAJI is True or config.ENABLE_CONVERT_MESSAGE_TO_HIRAGANA is True: + if config.SELECTED_TAB_TARGET_LANGUAGES[config.SELECTED_TAB_NO]["primary"]["language"] == "Japanese": + transliteration = model.convertMessageToTransliteration(translation[0]) + if config.ENABLE_TRANSCRIPTION_SEND is True: if config.ENABLE_SEND_MESSAGE_TO_VRC is True: if config.ENABLE_SEND_ONLY_TRANSLATED_MESSAGES is True: @@ -136,7 +141,8 @@ class MicMessage: "status":200, "result": { "message":message, - "translation":translation + "translation":translation, + "transliteration":transliteration } }) if config.ENABLE_LOGGER is True: @@ -200,6 +206,7 @@ class SpeakerMessage: }) elif isinstance(message, str) and len(message) > 0: translation = [] + transliteration = [] if model.detectRepeatReceiveMessage(message): return elif config.ENABLE_TRANSLATION is False: @@ -215,6 +222,10 @@ class SpeakerMessage: } }) + if config.ENABLE_CONVERT_MESSAGE_TO_ROMAJI is True or config.ENABLE_CONVERT_MESSAGE_TO_HIRAGANA is True: + if config.SELECTED_TAB_TARGET_LANGUAGES[config.SELECTED_TAB_NO]["primary"]["language"] == "Japanese": + transliteration = model.convertMessageToTransliteration(message) + if config.ENABLE_TRANSCRIPTION_RECEIVE is True: if config.ENABLE_OVERLAY_SMALL_LOG is True: if model.overlay.initialized is True: @@ -236,7 +247,8 @@ class SpeakerMessage: "status":200, "result": { "message":message, - "translation":translation + "translation":translation, + "transliteration":transliteration, } }) if config.ENABLE_LOGGER is True: @@ -290,6 +302,7 @@ class ChatMessage: if len(message) > 0: # addSentMessageLog(message) translation = [] + transliteration = [] if config.ENABLE_TRANSLATION is False: pass else: @@ -303,6 +316,10 @@ class ChatMessage: } }) + if config.ENABLE_CONVERT_MESSAGE_TO_ROMAJI is True or config.ENABLE_CONVERT_MESSAGE_TO_HIRAGANA is True: + if config.SELECTED_TAB_TARGET_LANGUAGES[config.SELECTED_TAB_NO]["primary"]["language"] == "Japanese": + transliteration = model.convertMessageToTransliteration(translation[0]) + # send OSC message if config.ENABLE_SEND_MESSAGE_TO_VRC is True: if config.ENABLE_SEND_ONLY_TRANSLATED_MESSAGES is True: @@ -331,6 +348,7 @@ class ChatMessage: "id":id, "message":message, "translation":translation, + "transliteration":transliteration, }, } @@ -501,6 +519,26 @@ def callbackDisableMultiLanguageTranslation(*args, **kwargs) -> dict: config.ENABLE_MULTI_LANGUAGE_TRANSLATION = False return {"status":200, "result":config.ENABLE_MULTI_LANGUAGE_TRANSLATION} +def callbackEnableConvertMessageToRomaji(*args, **kwargs) -> dict: + printLog("Enable Convert Message To Romaji") + config.ENABLE_CONVERT_MESSAGE_TO_ROMAJI = True + return {"status":200, "result":config.ENABLE_CONVERT_MESSAGE_TO_ROMAJI} + +def callbackDisableConvertMessageToRomaji(*args, **kwargs) -> dict: + printLog("Disable Convert Message To Romaji") + config.ENABLE_CONVERT_MESSAGE_TO_ROMAJI = False + return {"status":200, "result":config.ENABLE_CONVERT_MESSAGE_TO_ROMAJI} + +def callbackEnableConvertMessageToHiragana(*args, **kwargs) -> dict: + printLog("Enable Convert Message To Hiragana") + config.ENABLE_CONVERT_MESSAGE_TO_HIRAGANA = True + return {"status":200, "result":config.ENABLE_CONVERT_MESSAGE_TO_HIRAGANA} + +def callbackDisableConvertMessageToHiragana(*args, **kwargs) -> dict: + printLog("Disable Convert Message To Hiragana") + config.ENABLE_CONVERT_MESSAGE_TO_HIRAGANA = False + return {"status":200, "result":config.ENABLE_CONVERT_MESSAGE_TO_HIRAGANA} + def callbackEnableMainWindowSidebarCompactMode(*args, **kwargs) -> dict: printLog("Enable MainWindow Sidebar Compact Mode") config.IS_MAIN_WINDOW_SIDEBAR_COMPACT_MODE = True diff --git a/src-python/webui_mainloop.py b/src-python/webui_mainloop.py index a061c1a2..3f408a5a 100644 --- a/src-python/webui_mainloop.py +++ b/src-python/webui_mainloop.py @@ -30,6 +30,8 @@ config_mapping = { "/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", @@ -98,6 +100,10 @@ controller_mapping = { "/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, @@ -329,6 +335,7 @@ if __name__ == "__main__": match endpoint: case "/controller/callback_messagebox_send": # handleControllerRequest("/controller/callback_enable_translation") + # handleControllerRequest("/controller/callback_enable_convert_message_to_romaji") data = {"id":"123456", "message":"ใƒ†ใ‚นใƒˆ"} case "/controller/callback_selected_translation_engine": data = "DeepL"