Merge branch 'develop'

This commit is contained in:
misyaguziya
2024-06-23 16:02:31 +09:00
22 changed files with 797 additions and 293 deletions

View File

@@ -6,7 +6,7 @@
[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE) [![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE)
[![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325) [![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325)
| [English](./README.md) | **日本語** | [한국어](./README.kr.md) | | [English](./README.md) | **日本語** | [한국어](./README.ko.md) | [繁體中文](./README.zh-Hant.md) |
<h3> <h3>
VRCTは翻訳や文字起こしでVRChatの会話をサポートするソフトウェアです。 VRCTは翻訳や文字起こしでVRChatの会話をサポートするソフトウェアです。

View File

@@ -6,7 +6,7 @@
[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE) [![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE)
[![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325) [![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325)
| [English](./README.md) | [日本語](./README.jp.md) | **한국어** | | [English](./README.md) | [日本語](./README.ja.md) | **한국어** |
<h3> <h3>
VRCT는 음성인식 및 번역 기능을 통해 VRChat의 대화를 지원하는 소프트웨어입니다. VRCT는 음성인식 및 번역 기능을 통해 VRChat의 대화를 지원하는 소프트웨어입니다.

View File

@@ -6,7 +6,7 @@
[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE) [![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE)
[![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325) [![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325)
| **English** | [日本語](./README.jp.md) | [한국어](./README.kr.md) | | **English** | [日本語](./README.ja.md) | [한국어](./README.ko.md) | [繁體中文](./README.zh-Hant.md) |
<h3> <h3>
VRCT is software that supports VRChat conversations with translation and transcription. VRCT is software that supports VRChat conversations with translation and transcription.

View File

@@ -1,17 +0,0 @@
ご購入ありがとうございます。
フィードバックお待ちしております。
# 概要
VRChatで使用されるChatBoxをOSC経由でメッセージを送信するツールになります。
翻訳エンジンを使用してメッセージとその翻訳部分を同時に送信することができます。
# 使用方法
ドキュメント(JP):https://mzsoftware.notion.site/VRCT-Documents-be79b7a165f64442ad8f326d86c22246?pvs=4
# お問い合わせ
Googleフォーム:https://t.co/lSlo4brZwm
Twitter:https://twitter.com/misya_ai
Github:https://github.com/misyaguziya/VRCT
# アップデート履歴
[2023-10-21: 2.0.0] v2.0.0 リリース

64
README.zh-Hant.md Normal file
View File

@@ -0,0 +1,64 @@
<div align="center">
![](docs/vrct_logo.png)
[![GitHub release](https://img.shields.io/github/v/release/misyaguziya/VRCT.svg)](https://github.com/misyaguziya/VRCT/releases)
[![Downloads](https://img.shields.io/github/downloads/misyaguziya/VRCT/total)](https://github.com/misyaguziya/VRCT/releases)
[![Licence](https://img.shields.io/github/license/misyaguziya/VRCT)](https://github.com/misyaguziya/VRCT/blob/master/LICENSE)
[![Booth](https://img.shields.io/badge/Store-Booth.pm-red)](https://misyaguziya.booth.pm/items/5155325)
| [English](./README.md) | [日本語](./README.ja.md) | [한국어](./README.ko.md) | **繁體中文** |
<h3>
VRCT 是一個支援 VRChat 對話翻譯和紀錄的軟體。
</h3>
![](docs/main_window.png)
<div align="left">
# 下載 & 安裝
你可以從這些地方下載 VRCT
- [Github.com](https://github.com/misyaguziya/VRCT/releases/)
- [BOOTH.pm](https://misyaguziya.booth.pm/items/5155325)
你只需要下載並啟動 exe 文件。
# 什麼是 VRCT
VRCT 是一種透過提供聊天或語音翻譯來幫助語言不通的人對話的軟體。
這些功能專為在 VRChat 中使用而設計,但你也可以拿來看電影。
VRCT 可以:
- 💬 **傳送訊息至遊戲內 Chatbox**
- 🌐 **自動翻譯**
- 🎙 **麥克風轉文字**
- 🔈 **喇叭轉文字**
# 文件
解釋了初始設定、基本功能以及其他功能。
- [文件(日語)](https://mzsoftware.notion.site/VRCT-Documents-be79b7a165f64442ad8f326d86c22246?pvs=4)
# YouTube 教學(日語、英文字幕)
<div align="center">
[![](https://img.youtube.com/vi/rUTad037n8Q/0.jpg)](https://www.youtube.com/watch?v=rUTad037n8Q)
<div align="left">
# 原始碼啟動
1. 安裝此版本的 Python。
`python version 3.11.5`
2. 安裝 package 並啟動 main.py。
```bash
./install.bat
python main.py
```
## 作者
- [みしゃ(misyaguzi)](https://github.com/misyaguziya) (主要開發)
- [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI 多語系支援)
- [レラ](https://github.com/soumt-r) (韓語翻譯)
- [どね](https://twitter.com/done_vrc) (Logo 設計)
---
VRCT 未得到 VRChat 的認可,也不反映 VRChat 或正式參與製作或管理 VRChat 財產的任何人的觀點或意見。VRChat 和所有相關財產均為 VRChat Inc. 的商標或註冊商標。

View File

@@ -5,5 +5,5 @@ set local_path=%~dp0
taskkill /im %name% /F taskkill /im %name% /F
ping -n 2 127.0.0.1 > nul ping -n 2 127.0.0.1 > nul
START "" %local_path%%name% START "" "%local_path%%name%"
del /f "%~dp0%~nx0" del /f "%~dp0%~nx0"

View File

@@ -8,13 +8,13 @@ set local_path=%~dp0
taskkill /im %exe_name% /F taskkill /im %exe_name% /F
ping -n 2 127.0.0.1 > nul ping -n 2 127.0.0.1 > nul
del /f %local_path%%exe_name% del /f "%local_path%%exe_name%"
rmdir /s /q %local_path%%folder_name% rmdir /s /q "%local_path%%folder_name%"
xcopy %local_path%%folder_tmp% %local_path% /E /I xcopy "%local_path%%folder_tmp%" "%local_path%" /E /I
rmdir /s /q %local_path%%folder_tmp% rmdir /s /q "%local_path%%folder_tmp%"
if %restart% == True ( if %restart% == True (
START "" %local_path%%exe_name% START "" "%local_path%%exe_name%"
) )
del /f "%~dp0%~nx0" del /f "%~dp0%~nx0"

View File

@@ -546,6 +546,28 @@ class Config:
self._INPUT_MIC_WORD_FILTER = sorted(set(value), key=value.index) self._INPUT_MIC_WORD_FILTER = sorted(set(value), key=value.index)
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('INPUT_MIC_AVG_LOGPROB')
def INPUT_MIC_AVG_LOGPROB(self):
return self._INPUT_MIC_AVG_LOGPROB
@INPUT_MIC_AVG_LOGPROB.setter
def INPUT_MIC_AVG_LOGPROB(self, value):
if isinstance(value, float) or isinstance(value, int):
self._INPUT_MIC_AVG_LOGPROB = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('INPUT_MIC_NO_SPEECH_PROB')
def INPUT_MIC_NO_SPEECH_PROB(self):
return self._INPUT_MIC_NO_SPEECH_PROB
@INPUT_MIC_NO_SPEECH_PROB.setter
def INPUT_MIC_NO_SPEECH_PROB(self, value):
if isinstance(value, float) or isinstance(value, int):
self._INPUT_MIC_NO_SPEECH_PROB = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property @property
@json_serializable('CHOICE_SPEAKER_DEVICE') @json_serializable('CHOICE_SPEAKER_DEVICE')
def CHOICE_SPEAKER_DEVICE(self): def CHOICE_SPEAKER_DEVICE(self):
@@ -612,6 +634,28 @@ class Config:
self._INPUT_SPEAKER_MAX_PHRASES = value self._INPUT_SPEAKER_MAX_PHRASES = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value) saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('INPUT_SPEAKER_AVG_LOGPROB')
def INPUT_SPEAKER_AVG_LOGPROB(self):
return self._INPUT_SPEAKER_AVG_LOGPROB
@INPUT_SPEAKER_AVG_LOGPROB.setter
def INPUT_SPEAKER_AVG_LOGPROB(self, value):
if isinstance(value, float) or isinstance(value, int):
self._INPUT_SPEAKER_AVG_LOGPROB = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property
@json_serializable('INPUT_SPEAKER_NO_SPEECH_PROB')
def INPUT_SPEAKER_NO_SPEECH_PROB(self):
return self._INPUT_SPEAKER_NO_SPEECH_PROB
@INPUT_SPEAKER_NO_SPEECH_PROB.setter
def INPUT_SPEAKER_NO_SPEECH_PROB(self, value):
if isinstance(value, float) or isinstance(value, int):
self._INPUT_SPEAKER_NO_SPEECH_PROB = value
saveJson(self.PATH_CONFIG, inspect.currentframe().f_code.co_name, value)
@property @property
@json_serializable('OSC_IP_ADDRESS') @json_serializable('OSC_IP_ADDRESS')
def OSC_IP_ADDRESS(self): def OSC_IP_ADDRESS(self):
@@ -916,7 +960,7 @@ class Config:
def init_config(self): def init_config(self):
# Read Only # Read Only
self._VERSION = "2.2.4" self._VERSION = "2.2.5"
self._ENABLE_SPEAKER2CHATBOX = False # Speaker2Chatbox self._ENABLE_SPEAKER2CHATBOX = False # Speaker2Chatbox
self._ENABLE_SPEAKER2CHATBOX_PASS_CONFIRMATION = "VRCT=0YEN" self._ENABLE_SPEAKER2CHATBOX_PASS_CONFIRMATION = "VRCT=0YEN"
self._PATH_LOCAL = os_path.dirname(sys.argv[0]) self._PATH_LOCAL = os_path.dirname(sys.argv[0])
@@ -935,7 +979,8 @@ class Config:
self._SELECTABLE_UI_LANGUAGES_DICT = { self._SELECTABLE_UI_LANGUAGES_DICT = {
"en": "English", "en": "English",
"ja": "日本語", "ja": "日本語",
"ko": "한국어" "ko": "한국어",
"zh-Hant": "繁體中文"
# If you want to add a new language and key, please append it here. # If you want to add a new language and key, please append it here.
} }
self._SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT = { self._SELECTABLE_CTRANSLATE2_WEIGHT_TYPE_DICT = {
@@ -1042,12 +1087,16 @@ class Config:
self._INPUT_MIC_PHRASE_TIMEOUT = 3 self._INPUT_MIC_PHRASE_TIMEOUT = 3
self._INPUT_MIC_MAX_PHRASES = 10 self._INPUT_MIC_MAX_PHRASES = 10
self._INPUT_MIC_WORD_FILTER = [] self._INPUT_MIC_WORD_FILTER = []
self._INPUT_MIC_AVG_LOGPROB=-0.8
self._INPUT_MIC_NO_SPEECH_PROB=0.6
self._CHOICE_SPEAKER_DEVICE = getDefaultOutputDevice()["device"]["name"] self._CHOICE_SPEAKER_DEVICE = getDefaultOutputDevice()["device"]["name"]
self._INPUT_SPEAKER_ENERGY_THRESHOLD = 300 self._INPUT_SPEAKER_ENERGY_THRESHOLD = 300
self._INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD = False self._INPUT_SPEAKER_DYNAMIC_ENERGY_THRESHOLD = False
self._INPUT_SPEAKER_RECORD_TIMEOUT = 3 self._INPUT_SPEAKER_RECORD_TIMEOUT = 3
self._INPUT_SPEAKER_PHRASE_TIMEOUT = 3 self._INPUT_SPEAKER_PHRASE_TIMEOUT = 3
self._INPUT_SPEAKER_MAX_PHRASES = 10 self._INPUT_SPEAKER_MAX_PHRASES = 10
self._INPUT_SPEAKER_AVG_LOGPROB=-0.8
self._INPUT_SPEAKER_NO_SPEECH_PROB=0.6
self._OSC_IP_ADDRESS = "127.0.0.1" self._OSC_IP_ADDRESS = "127.0.0.1"
self._OSC_PORT = 9000 self._OSC_PORT = 9000
self._AUTH_KEYS = { self._AUTH_KEYS = {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

@@ -55,10 +55,8 @@ Page custom OptionPage2 OptionPageLeave2
; インターフェース 設定 ; インターフェース 設定
!define MUI_ABORTWARNING !define MUI_ABORTWARNING
; 変数 ; 変数
Var Checkbox_InstallDocs
Var Checkbox_InstallShortcut Var Checkbox_InstallShortcut
Var Dialog_Options Var Dialog_Options
Var InstallDocs
Var InstallShortcut Var InstallShortcut
Var DropList_Language Var DropList_Language
Var Set_Langage Var Set_Langage
@@ -72,7 +70,6 @@ Var subFont
; 初期化時コールバック ; 初期化時コールバック
Function .onInit Function .onInit
; オプション値を初期化します。 ; オプション値を初期化します。
StrCpy $InstallDocs ${BST_CHECKED}
StrCpy $InstallShortcut ${BST_CHECKED} StrCpy $InstallShortcut ${BST_CHECKED}
StrCpy $DropList_Language "English" StrCpy $DropList_Language "English"
StrCpy $DownloadWeight ${BST_CHECKED} StrCpy $DownloadWeight ${BST_CHECKED}
@@ -91,16 +88,9 @@ Function OptionPage1
Abort Abort
${EndIf} ${EndIf}
${NSD_CreateCheckbox} 0 0u 100% 12u "ドキュメントをインストールする (Install documents)" ${NSD_CreateCheckbox} 0 0u 100% 12u "デスクトップにショートカットを作成 (Install shortcut on desktop)"
Pop $Checkbox_InstallDocs
${NSD_CreateCheckbox} 0 13u 100% 12u "デスクトップにショートカットを作成 (Install shortcut on desktop)"
Pop $Checkbox_InstallShortcut Pop $Checkbox_InstallShortcut
${If} $InstallDocs == ${BST_CHECKED}
; チェックが入力済の場合、チェックボックスにチェックを入れます。
${NSD_Check} $Checkbox_InstallDocs
${EndIf}
${If} $InstallShortcut == ${BST_CHECKED} ${If} $InstallShortcut == ${BST_CHECKED}
; チェックが入力済の場合、チェックボックスにチェックを入れます。 ; チェックが入力済の場合、チェックボックスにチェックを入れます。
${NSD_Check} $Checkbox_InstallShortcut ${NSD_Check} $Checkbox_InstallShortcut
@@ -110,7 +100,6 @@ FunctionEnd
; オプション ページ 1 退出コールバック ; オプション ページ 1 退出コールバック
Function OptionPageLeave1 Function OptionPageLeave1
${NSD_GetState} $Checkbox_InstallDocs $InstallDocs
${NSD_GetState} $Checkbox_InstallShortcut $InstallShortcut ${NSD_GetState} $Checkbox_InstallShortcut $InstallShortcut
FunctionEnd FunctionEnd
@@ -195,18 +184,10 @@ Section
; インストールされるファイル ; インストールされるファイル
File /r "..\dist\VRCT\" File /r "..\dist\VRCT\"
${If} $InstallDocs == ${BST_CHECKED}
; ドキュメントをインストールする場合
; 出力先を指定します。
SetOutPath "$INSTDIR\docs"
; インストールされるファイル
File "..\README.txt"
${EndIf}
; アンインストーラを出力 ; アンインストーラを出力
WriteUninstaller "$INSTDIR\Uninstall.exe" WriteUninstaller "$INSTDIR\Uninstall.exe"
${If} $InstallDocs == ${BST_CHECKED} ${If} $InstallShortcut == ${BST_CHECKED}
; デスクトップにショートカットを作成 ; デスクトップにショートカットを作成
CreateShortCut "$DESKTOP\VRCT.lnk" "$INSTDIR\VRCT.exe" CreateShortCut "$DESKTOP\VRCT.lnk" "$INSTDIR\VRCT.exe"
${EndIf} ${EndIf}

View File

@@ -1,193 +0,0 @@
en:
# main window
checkbox_translation: "Translation"
checkbox_transcription_send: "Voice2chatbox"
checkbox_transcription_receive: "Speaker2log"
checkbox_foreground: "Foreground"
# main tabview
main_tab_title_log: "Log"
main_tab_title_send: "Send"
main_tab_title_receive: "Receive"
main_tab_title_system: "System"
# configure window
# config tabview
config_tab_title_ui: "UI"
config_tab_title_translation: "Translation"
config_tab_title_transcription: "Transcription"
config_tab_title_parameter: "Parameter"
config_tab_title_others: "Others"
# tab UI
label_transparency: "Transparency"
label_appearance_theme: "Appearance Theme"
label_ui_scaling: "UI Scaling"
label_font_family: "Font Family"
label_ui_language: "UI Language"
# tab Translation
label_translation_translator: "Select Translator"
label_translation_input_language: "Send Language"
label_translation_output_language: "Receive Language"
# tab Transcription
label_input_mic_host: "Input Mic Host"
label_input_mic_device: "Input Mic Device"
label_input_mic_voice_language: "Input Mic Voice Language"
label_input_mic_energy_threshold: "Input Mic Energy Threshold"
checkbox_input_mic_threshold_check: "Check threshold point"
label_input_mic_dynamic_energy_threshold: "Input Mic Dynamic Energy Threshold"
label_input_mic_record_timeout: "Input Mic Record Timeout"
label_input_mic_phrase_timeout: "Input Mic Phrase Timeout"
label_input_mic_max_phrases: "Input Mic Max Phrases"
label_input_mic_word_filter: "Input Mic Word Filter"
label_input_speaker_device: "Input Speaker Device"
label_input_speaker_voice_language: "Input Speaker Voice Language"
label_input_speaker_energy_threshold: "Input Speaker Energy Threshold"
checkbox_input_speaker_threshold_check: "Check threshold point"
label_input_speaker_dynamic_energy_threshold: "Input Speaker Dynamic Energy Threshold"
label_input_speaker_record_timeout: "Input Speaker Record Timeout"
label_input_speaker_phrase_timeout: "Input Speaker Phrase Timeout"
label_input_speaker_max_phrases: "Input Speaker Max Phrases"
# tab Parameter
label_ip_address: "OSC IP address"
label_port: "OSC Port"
label_auth_key: "DeepL Auth Key"
label_message_format: "Message Format"
# tab Others
label_checkbox_auto_clear_chatbox: "Auto clear chat box"
label_checkbox_notice_xsoverlay: "Notification XSOverlay"
ja:
# main window
checkbox_translation: "翻訳"
checkbox_transcription_send: "マイク->チャットボックス"
checkbox_transcription_receive: "スピーカー->ログ"
checkbox_foreground: "最前面表示"
# main tabview
main_tab_title_log: "ログ"
main_tab_title_send: "送信"
main_tab_title_receive: "受信"
main_tab_title_system: "システム"
# configure window
# config tabview
config_tab_title_ui: "UI"
config_tab_title_translation: "翻訳方法"
config_tab_title_transcription: "音声認識"
config_tab_title_parameter: "パラメーター"
config_tab_title_others: "その他"
# tab UI
label_transparency: "透過度"
label_appearance_theme: "外観テーマを選択"
label_ui_scaling: "UIの拡大縮小"
label_font_family: "使用フォントの変更"
label_ui_language: "UI 言語"
# tab Translation
label_translation_translator: "翻訳エンジンの選択"
label_translation_input_language: "送信言語-->翻訳言語"
label_translation_output_language: "受信言語-->翻訳言語"
# tab Transcription
label_input_mic_host: "マイク入力ホスト"
label_input_mic_device: "マイク入力デバイス"
label_input_mic_voice_language: "マイクで話す言語"
label_input_mic_energy_threshold: "音声取得のしきい値"
checkbox_input_mic_threshold_check: "音声取得のしきい値の視覚化"
label_input_mic_dynamic_energy_threshold: "音声取得のしきい値の自動調整"
label_input_mic_record_timeout: "マイク音声の区切りの無音時間"
label_input_mic_phrase_timeout: "文字起こしする音声時間の上限"
label_input_mic_max_phrases: "保留する単語の上限(マイク)"
label_input_mic_word_filter: "ワードフィルタ"
label_input_speaker_device: "スピーカー(聞き取りたいデバイス)"
label_input_speaker_voice_language: "聞き取る音声の言語"
label_input_speaker_energy_threshold: "音声取得のしきい値"
checkbox_input_speaker_threshold_check: "音声取得のしきい値の視覚化"
label_input_speaker_dynamic_energy_threshold: "音声取得のしきい値の自動調整"
label_input_speaker_record_timeout: "スピーカー音声の区切りの無音時間"
label_input_speaker_phrase_timeout: "文字起こしする音声時間の上限"
label_input_speaker_max_phrases: "保留する単語の上限(スピーカー)"
# tab Parameter
# label_ip_address: ""
# label_port: ""
# label_auth_key: ""
label_message_format: "送信するメッセージのフォーマット"
# tab Others
label_checkbox_auto_clear_chatbox: "送信後はチャットボックスを空にする"
label_checkbox_notice_xsoverlay: "XSOverlayの通知機能を有効"
ko:
# main window
checkbox_translation: "번역"
checkbox_transcription_send: "마이크 -> 챗박스"
checkbox_transcription_receive: "스피커 -> 로그"
checkbox_foreground: "항상 위로"
# main tabview
main_tab_title_log: "로그"
main_tab_title_send: "전송"
main_tab_title_receive: "수신"
main_tab_title_system: "시스템"
# configure window
# config tabview
config_tab_title_ui: "UI"
config_tab_title_translation: "번역"
config_tab_title_transcription: "음성인식"
config_tab_title_parameter: "파라미터"
config_tab_title_others: "기타"
# tab UI
label_transparency: "투명도"
label_appearance_theme: "테마"
label_ui_scaling: "UI 크기"
label_font_family: "폰트"
label_ui_language: "UI 언어"
# tab Translation
label_translation_translator: "번역기 선택"
label_translation_input_language: "전송시 번역 언어"
label_translation_output_language: "수신시 번역 언어"
# tab Transcription
label_input_mic_host: "마이크 호스트"
label_input_mic_device: "마이크 장치"
label_input_mic_voice_language: "입력 언어"
label_input_mic_energy_threshold: "음성 입력 최소 볼륨"
checkbox_input_mic_threshold_check: "임계점 확인"
label_input_mic_dynamic_energy_threshold: "동적 임계값"
label_input_mic_record_timeout: "최대 무음 시간"
label_input_mic_phrase_timeout: "최대 인식 시간"
label_input_mic_max_phrases: "최대 입력 절(phrases) 수"
label_input_mic_word_filter: "단어 필터"
label_input_speaker_device: "스피커 장치"
label_input_speaker_voice_language: "입력 언어"
label_input_speaker_energy_threshold: "음성 입력 최소 볼륨"
checkbox_input_speaker_threshold_check: "임계점 확인"
label_input_speaker_dynamic_energy_threshold: "동적 임계값"
label_input_speaker_record_timeout: "최대 무음 시간"
label_input_speaker_phrase_timeout: "최대 인식 시간"
label_input_speaker_max_phrases: "최대 입력 절(phrases) 수"
# tab Parameter
label_ip_address: "OSC IP 주소"
label_port: "OSC 포트"
label_auth_key: "DeepL 인증키"
label_message_format: "전송 형식"
# tab Others
label_checkbox_auto_clear_chatbox: "챗박스 자동 삭제"

3
locales/readme_first.txt Normal file
View File

@@ -0,0 +1,3 @@
Thank you for considering translating VRCT's UI.
For your information, we are planning to transition VRCT's UI from Python's tkinter to a web-based platform using HTML, CSS, and JavaScript.
This means there might be structural changes to the UI. We apologize if any of the sentences you translated are removed due to these changes.

283
locales/zh-Hant.yml Normal file
View File

@@ -0,0 +1,283 @@
main_window:
translation: 翻譯
transcription_send: 麥克風轉文字
transcription_receive: 喇叭轉文字
foreground: 最上層顯示
language_settings: 語言設定
your_language: 你的語言
translate_each_other_label: 互相翻譯
swap_button_label: 交換語言
target_language: 目標語言
translator: 翻譯器
translator_ctranslate2: 離線翻譯(預設)
textbox_tab_all: 全部
textbox_tab_sent: 已發送
textbox_tab_received: 已接收
textbox_tab_system: 系統
textbox_system_message:
enabled_easter_egg: 你找到了彩蛋!看看你的 VR Overlay 有沒有什麼變化?
enabled_translation: 翻譯功能已啟用。
disabled_translation: 翻譯功能已停用。
enabled_voice2chatbox: 麥克風轉文字已啟用。
disabled_voice2chatbox: 麥克風轉文字已停用。
enabled_speaker2log: 喇叭轉文字已啟用。
disabled_speaker2log: 喇叭轉文字已停用。
enabled_foreground: 最上層顯示已啟用。
disabled_foreground: 最上層顯示已停用。
auth_key_success: 授權金鑰更新完成。
auth_key_error: 授權金鑰錯誤或已達使用上限。
no_mic_device_detected_error: 未偵測到麥克風。
no_speaker_device_detected_error: 未偵測到喇叭。
translation_engine_limit_error: 翻譯引擎已自動變更。由於請求太頻繁,已被這個翻譯引擎暫時受限。如果你想使用相同的翻譯引擎,請稍等片刻,重新啟動 VRCT 並重試。
detected_by_word_filter: 由於詞語過濾器的偵測,「%{detected_message}」未被發送。
selected_your_language: "「你的語言」已設為 %{your_language}。"
selected_target_language: "「目標語言」已設為 %{target_language}。"
switched_language_preset_tab: 已切換到第 %{tab_no} 個語言設定。
latest_language_setting: "目前「你的語言」設為 %{your_language},「目標語言」設為 %{target_language}。"
opened_web_page_booth: 已在瀏覽器中打開 Booth 頁面。
opened_web_page_vrct_documents: "已在瀏覽器中打開VRCT文件頁面。\n如有任何問題、請求或查詢請通過文件頁面底部的連結、「聯絡表單」或 X (Twitter) 聯絡我們!"
update_available: 有新版本可供使用!
state_text_enabled: 啟用
state_text_disabled: 停用
cover_message: VRCT 功能在設定視窗關閉前暫時停用。
confirmation_message:
update_software: "下載新版本並自動更新 VRCT。\n會花一些時間現在更新嗎"
deny_update_software: 稍後再說
accept_update_software: 更新
updating: 正在更新...
detected_over_ui_size: "介面大小:%{current_ui_size}\nVRCT 的視窗大小可能超過你的螢幕大小。"
deny_adjust_ui_size: "保持目前大小"
accept_adjust_ui_size: "縮小介面並重新啟動"
selectable_language_window:
title_your_language: 選擇你的語言
title_target_language: 選擇目標語言
go_back_button: 返回
overlay_settings:
restore_default_settings: 恢復預設設定
opacity: 透明度
ui_scaling: 介面縮放
x_position: X軸左右
y_position: Y軸上下
z_position: Z軸前後
x_rotation: X軸旋轉
y_rotation: Y軸旋轉
z_rotation: Z軸旋轉
display_duration: 顯示持續時間
fadeout_duration: 淡出持續時間
config_window:
config_title: 設定
compact_mode: 精簡模式
version: 版本 %{version}
restart_message: 重新啟動以應用變更。
common_error_message:
invalid_value: 無效值。
side_menu_labels:
appearance: 外觀
translation: 翻譯
transcription: 轉錄
transcription_mic: 麥克風
transcription_speaker: 喇叭
transcription_internal_model: 轉錄模型
vr: VR
others: 其他
others_send_message_formats: 訊息格式(發送)
others_received_message_formats: 訊息格式XSOverlay & 喇叭轉文字)
others_speaker2chatbox: 喇叭轉文字
advanced_settings: 進階設定
transparency:
label: 透明度
desc: 變更主視窗的透明度。
appearance_theme:
label: 主題
desc: 變更配色主題。
ui_size:
label: 介面大小
textbox_ui_size:
label: 訊息框字體大小
desc: 你可以根據介面大小調整記錄中使用的字體大小。
message_box_ratio:
label: 訊息框大小
desc: "你可以依介面比例縮放輸入訊息框。\n*可能不準確。"
font_family:
label: 字型
ui_language:
label: 介面語言
to_restore_main_window_geometry:
label: 記住主視窗位置
desc: 啟動時恢復上次視窗的位置和大小。
use_translation_feature:
label: 使用翻譯功能
desc: 當此功能關閉時,無法使用翻譯功能。但 VRCT 會啟動得更快。適合不需要翻譯功能、只使用VRCT作為聊天框和轉錄工具的使用者。
ctranslate2_weight_type:
label: 選擇離線翻譯模型
desc: 你可以選擇用於離線翻譯引擎的翻譯模型。
small: "基本模型(%{capacity}"
large: "高準確率模型(%{capacity}"
deepl_auth_key:
label: DeepL 授權金鑰
desc: 使用 DeepL API 時請在主螢幕選擇 %{translator}。※可能不支援某些語言。
open_auth_key_webpage: 打開 DeepL 帳號頁面
auth_key_success: 授權金鑰更新完成。
auth_key_error: 授權金鑰錯誤或已達使用上限。
mic_host:
label: 麥克風 Host/Driver
mic_device:
label: 麥克風裝置
mic_dynamic_energy_threshold:
label_for_automatic: "麥克風能量閾值(當前設置:自動)"
desc_for_automatic: "自動判定麥克風輸入靈敏度。"
label_for_manual: "麥克風能量閾值(當前設置:手動)"
desc_for_manual: "使用滑桿調整麥克風輸入靈敏度,你可以按下麥克風圖示來測試。"
error_message: 可以設置 0 到 %{max} 之間的值。
mic_record_timeout:
label: 麥克風音訊 - 判定結束時間
desc: 麥克風未收到音訊後,結束一段話的判定時間(秒)。
error_message: 不能大於「%{mic_phrase_timeout_label}」,應為 0 或更高。
mic_phrase_timeout:
label: 麥克風音訊 - 紀錄間隔時間
desc: 每隔多久要紀錄一次音訊。
error_message: 不能小於「%{mic_record_timeout_label}」,應為 0 或更高。
mic_max_phrase:
label: 麥克風音訊 - 最大單詞數量
desc: 只有在單詞超過此數量時,才會記錄結果並發送到 VRChat。
error_message: 可以設置為 0 或更高的數值。
mic_word_filter:
label: 麥克風單詞過濾器
desc: "如果偵測到清單內的單詞,則不會發送訊息。要一次新增多個詞語,請用「,」(半形逗號)分隔。\n*重複詞語會被忽略。"
add_button_label: 新增
count_desc: "當前註冊詞語數量:%{count}"
speaker_device:
label: 喇叭裝置
speaker_dynamic_energy_threshold:
label_for_automatic: "喇叭能量閾值(當前設置:自動)"
desc_for_automatic: "自動確定喇叭輸入靈敏度。"
label_for_manual: "喇叭能量閾值(當前設置:手動)"
desc_for_manual: "使用滑桿調整喇叭輸入靈敏度,你可以按下喇叭圖示來測試。"
error_message: 可以設置 0 到 %{max} 之間的值。
no_device_error_message: 未偵測到喇叭裝置。
speaker_record_timeout:
label: 喇叭音訊 - 判定結束時間
desc: 偵測到靜音並在指定秒數後認為喇叭輸入已結束。(秒)
error_message: 不能大於「%{speaker_phrase_timeout_label}」,應為 0 或更高。
speaker_phrase_timeout:
label: 喇叭音訊 - 紀錄間隔時間
desc: 以指定秒數間隔進行轉錄處理。
error_message: 不能小於「%{speaker_record_timeout_label}」,應為 0 或更高。
speaker_max_phrase:
label: 喇叭音訊 - 最大單詞數量
desc: 只有在單詞超過此數量時,才會記錄結果並發送到 VRChat。
error_message: 可以設置 0 或更高的數值。
use_whisper_feature:
label: 使用 Whisper 模型進行轉錄
desc: 在某些語言中語音識別的準確性可能會提高。使用語音識別時CPU使用率會增加請根據你的PC規格考慮是否使用此功能。
whisper_weight_type:
label: 選擇 Whisper 模型
desc: "一般來說容量較大的模型往往具有更高的準確性但這也導致轉錄時間較長和CPU使用率增加。請參考文檔了解各模型的說明。\n※特別是超過中等大小的模型根據CPU性能可能難以運行。"
model_template: "%{model_name}模型(%{capacity}"
recommended_model_template: "%{model_name}模型(%{capacity})(推薦)"
enable_overlay_small_log:
label: 啟用 Overlay
open_overlay_settings: 打開 Overlay 自定義設定
auto_clear_the_message_box:
label: 自動清除 Chatbox
send_only_translated_messages:
label: 僅發送翻譯訊息
send_message_button_type:
label: 發送訊息按鈕
hide: 隱藏(使用 Enter 鍵發送)
show: 顯示
show_and_disable_enter_key: 顯示並停用 Enter 鍵發送
notice_xsoverlay:
label: XSOverlay 通知
desc: 從 XSOverlay 的通知功能接收訊息。
auto_export_message_logs:
label: 自動匯出訊息記錄
desc: 自動將對話訊息匯出為文字文件。
vrc_mic_mute_sync:
label: VRC 麥克風靜音同步
desc: "當 VRChat 的麥克風靜音時VRCT 將不會向 VRChat 發送訊息。\n*存在一些延遲且不支援按鍵發話 (PTT)。"
send_message_to_vrc:
label: 發送訊息到 VRChat
desc: 當你打算向 VRChat 發送訊息時啟用此功能。
send_message_format:
label: 發送的訊息格式
desc: "你可以設定要發送的訊息格式。\n[message] 將被替換為訊息。"
example_text: 這是一個範例。字體、換行等可能與實際顯示不同。
error_message: "不能使用 [message] 。"
send_message_format_with_t:
label: 發送的訊息格式(帶翻譯)
desc: "你可以設定要發送的訊息格式。\n[message] 將被替換為訊息,並且 [translation] 將被替換為翻譯訊息。"
example_text: 這是一個範例。字體、換行等可能與實際顯示不同。
error_message: "不能使用 [message] 和 [translation] 。"
received_message_format:
label: 接收的訊息格式
desc: "用於 XSOverlay 的通知接收功能。\n[message] 將被替換為訊息。\n※它也將用於喇叭轉文字功能。"
example_text: 這是一個範例。字體、換行等可能與實際顯示不同。
error_message: "不能使用 [message] 。"
received_message_format_with_t:
label: 接收的訊息格式(附翻譯)
desc: "用於 XSOverlay 的通知接收功能。\n[message] 將被替換為訊息,並且 [translation] 將被替換為翻譯訊息。\n※它也將用於喇叭轉文字功能。"
example_text: 這是一個範例。字體、換行等可能與實際顯示不同。
error_message: "不能使用 [message] 和 [translation] 。"
osc_ip_address:
label: OSC IP 位址
osc_port:
label: OSC 端口
open_config_filepath:
label: 打開設定文件

View File

@@ -377,9 +377,13 @@ class Model:
def getListInputHost(): def getListInputHost():
return [host for host in getInputDevices().keys()] return [host for host in getInputDevices().keys()]
@staticmethod
def getInputDefaultDevice():
return getInputDevices().get(config.CHOICE_MIC_HOST, [{"name": "NoDevice"}])[0]["name"]
@staticmethod @staticmethod
def getListInputDevice(): def getListInputDevice():
return [device["name"] for device in getInputDevices()[config.CHOICE_MIC_HOST]] return [device["name"] for device in getInputDevices().get(config.CHOICE_MIC_HOST, [{"name": "NoDevice"}])]
@staticmethod @staticmethod
def getListOutputDevice(): def getListOutputDevice():
@@ -400,9 +404,9 @@ class Model:
mic_device = choice_mic_device[0] mic_device = choice_mic_device[0]
record_timeout = config.INPUT_MIC_RECORD_TIMEOUT record_timeout = config.INPUT_MIC_RECORD_TIMEOUT
phase_timeout = config.INPUT_MIC_PHRASE_TIMEOUT phrase_timeout = config.INPUT_MIC_PHRASE_TIMEOUT
if record_timeout > phase_timeout: if record_timeout > phrase_timeout:
record_timeout = phase_timeout record_timeout = phrase_timeout
self.mic_audio_recorder = SelectedMicEnergyAndAudioRecorder( self.mic_audio_recorder = SelectedMicEnergyAndAudioRecorder(
device=mic_device, device=mic_device,
@@ -415,7 +419,7 @@ class Model:
self.mic_transcriber = AudioTranscriber( self.mic_transcriber = AudioTranscriber(
speaker=False, speaker=False,
source=self.mic_audio_recorder.source, source=self.mic_audio_recorder.source,
phrase_timeout=phase_timeout, phrase_timeout=phrase_timeout,
max_phrases=config.INPUT_MIC_MAX_PHRASES, max_phrases=config.INPUT_MIC_MAX_PHRASES,
transcription_engine=config.SELECTED_TRANSCRIPTION_ENGINE, transcription_engine=config.SELECTED_TRANSCRIPTION_ENGINE,
root=config.PATH_LOCAL, root=config.PATH_LOCAL,
@@ -423,7 +427,13 @@ class Model:
) )
def sendMicTranscript(): def sendMicTranscript():
try: try:
res = self.mic_transcriber.transcribeAudioQueue(self.mic_audio_queue, config.SOURCE_LANGUAGE, config.SOURCE_COUNTRY) res = self.mic_transcriber.transcribeAudioQueue(
self.mic_audio_queue,
config.SOURCE_LANGUAGE,
config.SOURCE_COUNTRY,
config.INPUT_MIC_AVG_LOGPROB,
config.INPUT_MIC_NO_SPEECH_PROB
)
if res: if res:
message = self.mic_transcriber.getTranscript() message = self.mic_transcriber.getTranscript()
fnc(message) fnc(message)
@@ -554,9 +564,9 @@ class Model:
# speaker_energy_queue = Queue() # speaker_energy_queue = Queue()
speaker_device = choice_speaker_device[0] speaker_device = choice_speaker_device[0]
record_timeout = config.INPUT_SPEAKER_RECORD_TIMEOUT record_timeout = config.INPUT_SPEAKER_RECORD_TIMEOUT
phase_timeout = config.INPUT_SPEAKER_PHRASE_TIMEOUT phrase_timeout = config.INPUT_SPEAKER_PHRASE_TIMEOUT
if record_timeout > phase_timeout: if record_timeout > phrase_timeout:
record_timeout = phase_timeout record_timeout = phrase_timeout
self.speaker_audio_recorder = SelectedSpeakerEnergyAndAudioRecorder( self.speaker_audio_recorder = SelectedSpeakerEnergyAndAudioRecorder(
device=speaker_device, device=speaker_device,
@@ -569,7 +579,7 @@ class Model:
self.speaker_transcriber = AudioTranscriber( self.speaker_transcriber = AudioTranscriber(
speaker=True, speaker=True,
source=self.speaker_audio_recorder.source, source=self.speaker_audio_recorder.source,
phrase_timeout=phase_timeout, phrase_timeout=phrase_timeout,
max_phrases=config.INPUT_SPEAKER_MAX_PHRASES, max_phrases=config.INPUT_SPEAKER_MAX_PHRASES,
transcription_engine=config.SELECTED_TRANSCRIPTION_ENGINE, transcription_engine=config.SELECTED_TRANSCRIPTION_ENGINE,
root=config.PATH_LOCAL, root=config.PATH_LOCAL,
@@ -577,7 +587,13 @@ class Model:
) )
def sendSpeakerTranscript(): def sendSpeakerTranscript():
try: try:
res = self.speaker_transcriber.transcribeAudioQueue(speaker_audio_queue, config.TARGET_LANGUAGE, config.TARGET_COUNTRY) res = self.speaker_transcriber.transcribeAudioQueue(
speaker_audio_queue,
config.TARGET_LANGUAGE,
config.TARGET_COUNTRY,
config.INPUT_SPEAKER_AVG_LOGPROB,
config.INPUT_SPEAKER_NO_SPEECH_PROB
)
if res: if res:
message = self.speaker_transcriber.getTranscript() message = self.speaker_transcriber.getTranscript()
fnc(message) fnc(message)

View File

@@ -5,6 +5,18 @@ transcription_lang = {
"Whisper": "af", "Whisper": "af",
}, },
}, },
"Albanian":{
"Albania":{
"Google": "sq-AL",
"Whisper": "sq",
},
},
"Amharic":{
"Ethiopia":{
"Google": "am-ET",
"Whisper": "am",
},
},
"Arabic":{ "Arabic":{
"Algeria":{ "Algeria":{
"Google": "ar-DZ", "Google": "ar-DZ",
@@ -38,6 +50,10 @@ transcription_lang = {
"Google": "ar-LB", "Google": "ar-LB",
"Whisper": "ar", "Whisper": "ar",
}, },
"Mauritania":{
"Google": "ar-MR",
"Whisper": "ar",
},
"Morocco":{ "Morocco":{
"Google": "ar-MA", "Google": "ar-MA",
"Whisper": "ar", "Whisper": "ar",
@@ -46,10 +62,6 @@ transcription_lang = {
"Google": "ar-OM", "Google": "ar-OM",
"Whisper": "ar", "Whisper": "ar",
}, },
"State of Palestine":{
"Google": "ar-PS",
"Whisper": "ar",
},
"Qatar":{ "Qatar":{
"Google": "ar-QA", "Google": "ar-QA",
"Whisper": "ar", "Whisper": "ar",
@@ -58,6 +70,14 @@ transcription_lang = {
"Google": "ar-SA", "Google": "ar-SA",
"Whisper": "ar", "Whisper": "ar",
}, },
"Palestine":{
"Google": "ar-PS",
"Whisper": "ar",
},
"Syria":{
"Google": "ar-SY",
"Whisper": "ar",
},
"Tunisia":{ "Tunisia":{
"Google": "ar-TN", "Google": "ar-TN",
"Whisper": "ar", "Whisper": "ar",
@@ -66,6 +86,22 @@ transcription_lang = {
"Google": "ar-AE", "Google": "ar-AE",
"Whisper": "ar", "Whisper": "ar",
}, },
"Yemen":{
"Google": "ar-YE",
"Whisper": "ar",
},
},
"Armenian": {
"Armenia": {
"Google": "hy-AM",
"Whisper": "hy",
},
},
"Azerbaijani": {
"Azerbaijan": {
"Google": "az-AZ",
"Whisper": "az",
},
}, },
"Basque":{ "Basque":{
"Spain":{ "Spain":{
@@ -73,12 +109,34 @@ transcription_lang = {
"Whisper": "eu", "Whisper": "eu",
}, },
}, },
"Bengali":{
"Bangladesh":{
"Google": "bn-BD",
"Whisper": "bn",
},
"India":{
"Google": "bn-IN",
"Whisper": "bn",
},
},
"Bosnian":{
"Bosnia and Herzegovina":{
"Google": "bs-BA",
"Whisper": "bs",
}
},
"Bulgarian":{ "Bulgarian":{
"Bulgaria":{ "Bulgaria":{
"Google": "bg-BG", "Google": "bg-BG",
"Whisper": "bg", "Whisper": "bg",
}, },
}, },
"Burmese":{
"Myanmar":{
"Google": "my-MM",
"Whisper": "my",
},
},
"Catalan":{ "Catalan":{
"Spain":{ "Spain":{
"Google": "ca-ES", "Google": "ca-ES",
@@ -124,20 +182,16 @@ transcription_lang = {
}, },
}, },
"Dutch":{ "Dutch":{
"Belgium":{
"Google": "nl-BE",
"Whisper": "nl",
},
"Netherlands":{ "Netherlands":{
"Google": "nl-NL", "Google": "nl-NL",
"Whisper": "nl", "Whisper": "nl",
}, },
}, },
"English": { "English": {
"United States":{
"Google": "en-US",
"Whisper": "en",
},
"United Kingdom":{
"Google": "en-GB",
"Whisper": "en",
},
"Australia":{ "Australia":{
"Google": "en-AU", "Google": "en-AU",
"Whisper": "en", "Whisper": "en",
@@ -146,6 +200,14 @@ transcription_lang = {
"Google": "en-CA", "Google": "en-CA",
"Whisper": "en", "Whisper": "en",
}, },
"Ghana":{
"Google": "en-GH",
"Whisper": "en",
},
"Hong Kong":{
"Google": "en-HK",
"Whisper": "en",
},
"India":{ "India":{
"Google": "en-IN", "Google": "en-IN",
"Whisper": "en", "Whisper": "en",
@@ -154,18 +216,48 @@ transcription_lang = {
"Google": "en-IE", "Google": "en-IE",
"Whisper": "en", "Whisper": "en",
}, },
"Kenya":{
"Google": "en-KE",
"Whisper": "en",
},
"New Zealand":{ "New Zealand":{
"Google": "en-NZ", "Google": "en-NZ",
"Whisper": "en", "Whisper": "en",
}, },
"Nigeria":{
"Google": "en-NG",
"Whisper": "en",
},
"Philippines":{ "Philippines":{
"Google": "en-PH", "Google": "en-PH",
"Whisper": "en", "Whisper": "en",
}, },
"Singapore":{
"Google": "en-SG",
"Whisper": "en",
},
"South Africa":{ "South Africa":{
"Google": "en-ZA", "Google": "en-ZA",
"Whisper": "en", "Whisper": "en",
}, },
"Tanzania":{
"Google": "en-TZ",
"Whisper": "en",
},
"United Kingdom":{
"Google": "en-GB",
"Whisper": "en",
},
"United States":{
"Google": "en-US",
"Whisper": "en",
},
},
"Estonian":{
"Estonia":{
"Google": "et-EE",
"Whisper": "et",
},
}, },
"Filipino":{ "Filipino":{
"Philippines":{ "Philippines":{
@@ -180,10 +272,22 @@ transcription_lang = {
}, },
}, },
"French":{ "French":{
"Belgium":{
"Google": "fr-BE",
"Whisper": "fr",
},
"Canada":{
"Google": "fr-CA",
"Whisper": "fr",
},
"France":{ "France":{
"Google": "fr-FR", "Google": "fr-FR",
"Whisper": "fr", "Whisper": "fr",
}, },
"Switzerland":{
"Google": "fr-CH",
"Whisper": "fr",
},
}, },
"Galician":{ "Galician":{
"Spain":{ "Spain":{
@@ -191,11 +295,25 @@ transcription_lang = {
"Whisper": "gl", "Whisper": "gl",
}, },
}, },
"Georgian":{
"Georgia":{
"Google": "ka-GE",
"Whisper": "ka",
},
},
"German":{ "German":{
"Austria":{
"Google": "de-AT",
"Whisper": "de",
},
"Germany":{ "Germany":{
"Google": "de-DE", "Google": "de-DE",
"Whisper": "de", "Whisper": "de",
}, },
"Switzerland":{
"Google": "de-CH",
"Whisper": "de",
},
}, },
"Greek":{ "Greek":{
"Greece":{ "Greece":{
@@ -203,9 +321,15 @@ transcription_lang = {
"Whisper": "el", "Whisper": "el",
}, },
}, },
"Gujarati":{
"India":{
"Google": "gu-IN",
"Whisper": "gu",
},
},
"Hebrew":{ "Hebrew":{
"Israel":{ "Israel":{
"Google": "he-IL", "Google": "iw-IL",
"Whisper": "he", "Whisper": "he",
}, },
}, },
@@ -221,18 +345,18 @@ transcription_lang = {
"Whisper": "hu", "Whisper": "hu",
}, },
}, },
"Indonesian":{
"Indonesia":{
"Google": "id-ID",
"Whisper": "id",
},
},
"Icelandic":{ "Icelandic":{
"Iceland":{ "Iceland":{
"Google": "is-IS", "Google": "is-IS",
"Whisper": "is", "Whisper": "is",
}, },
}, },
"Indonesian":{
"Indonesia":{
"Google": "id-ID",
"Whisper": "id",
},
},
"Italian":{ "Italian":{
"Italy":{ "Italy":{
"Google": "it-IT", "Google": "it-IT",
@@ -249,27 +373,91 @@ transcription_lang = {
"Whisper": "ja", "Whisper": "ja",
}, },
}, },
# "Javanese":{
# "Indonesia":{
# "Google": "jv-ID",
# },
# },
"Kannada":{
"India":{
"Google": "kn-IN",
"Whisper": "kn",
},
},
"Kazakh":{
"Kazakhstan":{
"Google": "kk-KZ",
"Whisper": "kk",
},
},
"Khmer":{
"Cambodia":{
"Google": "km-KH",
"Whisper": "km",
},
},
# "Kinyarwanda":{
# "rwanda":{
# "Google": "rw-RW",
# },
# },
"Korean":{ "Korean":{
"South Korea":{ "South Korea":{
"Google": "ko-KR", "Google": "ko-KR",
"Whisper": "ko", "Whisper": "ko",
}, },
}, },
"Lao":{
"Laos":{
"Google": "lo-LA",
"Whisper": "lo",
},
},
"Latvian":{
"Latvia":{
"Google": "lv-LV",
"Whisper": "lv",
},
},
"Lithuanian":{ "Lithuanian":{
"Lithuania":{ "Lithuania":{
"Google": "lt-LT", "Google": "lt-LT",
"Whisper": "lt", "Whisper": "lt",
}, },
}, },
"Macedonian":{
"North Macedonia":{
"Google": "mk-MK",
"Whisper": "mk",
},
},
"Malay":{ "Malay":{
"Malaysia":{ "Malaysia":{
"Google": "ms-MY", "Google": "ms-MY",
"Whisper": "ms", "Whisper": "ms",
}, },
}, },
"Malayalam":{
"India":{
"Google": "ml-IN",
"Whisper": "ml",
},
},
"Mongolian":{
"Mongolia":{
"Google": "mn-MN",
"Whisper": "mn",
},
},
"Nepali":{
"Nepal":{
"Google": "ne-NP",
"Whisper": "ne",
},
},
"Norwegian":{ "Norwegian":{
"Norway":{ "Norway":{
"Google": "nb-NO", "Google": "no-NO",
"Whisper": "no", "Whisper": "no",
}, },
}, },
@@ -295,6 +483,11 @@ transcription_lang = {
"Whisper": "pt", "Whisper": "pt",
}, },
}, },
# "Punjabi":{
# "India":{
# "Google": "pa-Guru-IN",
# },
# },
"Romanian":{ "Romanian":{
"Romania":{ "Romania":{
"Google": "ro-RO", "Google": "ro-RO",
@@ -313,6 +506,12 @@ transcription_lang = {
"Whisper": "sr", "Whisper": "sr",
}, },
}, },
"Sinhala":{
"Sri Lanka":{
"Google": "si-LK",
"Whisper": "si",
},
},
"Slovak":{ "Slovak":{
"Slovakia":{ "Slovakia":{
"Google": "sk-SK", "Google": "sk-SK",
@@ -325,6 +524,11 @@ transcription_lang = {
"Whisper": "sl", "Whisper": "sl",
}, },
}, },
# "Sesotho":{
# "South Africa":{
# "Google": "st-ZA",
# },
# },
"Spanish":{ "Spanish":{
"Argentina":{ "Argentina":{
"Google": "es-AR", "Google": "es-AR",
@@ -394,31 +598,86 @@ transcription_lang = {
"Google": "es-ES", "Google": "es-ES",
"Whisper": "es", "Whisper": "es",
}, },
"Uruguay":{
"Google": "es-UY",
"Whisper": "es",
},
"United States":{ "United States":{
"Google": "es-US", "Google": "es-US",
"Whisper": "es", "Whisper": "es",
}, },
"Uruguay":{
"Google": "es-UY",
"Whisper": "es",
},
"Venezuela":{ "Venezuela":{
"Google": "es-VE", "Google": "es-VE",
"Whisper": "es", "Whisper": "es",
}, },
}, },
"Sundanese":{
"Indonesia":{
"Google": "su-ID",
"Whisper": "su",
},
},
"Swahili":{
"Kenya":{
"Google": "sw-KE",
"Whisper": "sw",
},
"Tanzania":{
"Google": "sw-TZ",
"Whisper": "sw",
},
},
# "Swazi":{
# "Eswatini":{
# "Google": "ss-Latn-ZA",
# },
# },
"Swedish":{ "Swedish":{
"Sweden":{ "Sweden":{
"Google": "sv-SE", "Google": "sv-SE",
"Whisper": "sv", "Whisper": "sv",
}, },
}, },
"Tamil":{
"India":{
"Google": "ta-IN",
"Whisper": "ta",
},
"malaysia":{
"Google": "ta-MY",
"Whisper": "ta",
},
"Singapore":{
"Google": "ta-SG",
"Whisper": "ta",
},
"Sri Lanka":{
"Google": "ta-LK",
"Whisper": "ta",
},
},
"Telugu":{
"India":{
"Google": "te-IN",
"Whisper": "te",
},
},
"Thai":{ "Thai":{
"Thailand":{ "Thailand":{
"Google": "th-TH", "Google": "th-TH",
"Whisper": "th", "Whisper": "th",
}, },
}, },
# "Tsonga":{
# "South Africa":{
# "Google": "ts-ZA",
# },
# },
# "Setswana":{
# "South Africa":{
# "Google": "tn-Latn-ZA",
# },
# },
"Turkish":{ "Turkish":{
"Turkey":{ "Turkey":{
"Google": "tr-TR", "Google": "tr-TR",
@@ -431,10 +690,41 @@ transcription_lang = {
"Whisper": "uk", "Whisper": "uk",
}, },
}, },
"Urdu":{
"India":{
"Google": "ur-IN",
"Whisper": "ur",
},
"Pakistan":{
"Google": "ur-PK",
"Whisper": "ur",
},
},
"Uzbek":{
"Uzbekistan":{
"Google": "uz-UZ",
"Whisper": "uz",
},
},
# "Venda":{
# "South Africa":{
# "Google": "ve-ZA",
# },
# },
"Vietnamese":{ "Vietnamese":{
"Vietnam":{ "Vietnam":{
"Google": "vi-VN", "Google": "vi-VN",
"Whisper": "vi", "Whisper": "vi",
}, },
}, },
# "Xhosa":{
# "South Africa":{
# "Google": "xh-ZA",
# },
# },
# "Zulu":{
# "South Africa":{
# "Google": "zu-ZA",
# },
# },
} }

View File

@@ -10,6 +10,7 @@ from .transcription_whisper import getWhisperModel, checkWhisperWeight
import torch import torch
import numpy as np import numpy as np
from pydub import AudioSegment
PHRASE_TIMEOUT = 3 PHRASE_TIMEOUT = 3
MAX_PHRASES = 10 MAX_PHRASES = 10
@@ -38,7 +39,7 @@ class AudioTranscriber:
self.whisper_model = getWhisperModel(root, whisper_weight_type) self.whisper_model = getWhisperModel(root, whisper_weight_type)
self.transcription_engine = "Whisper" self.transcription_engine = "Whisper"
def transcribeAudioQueue(self, audio_queue, language, country): def transcribeAudioQueue(self, audio_queue, language, country, avg_logprob=-0.8, no_speech_prob=0.6):
if audio_queue.empty(): if audio_queue.empty():
time.sleep(0.01) time.sleep(0.01)
return False return False
@@ -68,7 +69,7 @@ class AudioTranscriber:
vad_filter=False, vad_filter=False,
) )
for s in segments: for s in segments:
if s.avg_logprob < -0.8 or s.no_speech_prob > 0.6: if s.avg_logprob < avg_logprob or s.no_speech_prob > no_speech_prob:
continue continue
text += s.text text += s.text
@@ -104,6 +105,14 @@ class AudioTranscriber:
wf.setframerate(self.audio_sources["sample_rate"]) wf.setframerate(self.audio_sources["sample_rate"])
wf.writeframes(self.audio_sources["last_sample"]) wf.writeframes(self.audio_sources["last_sample"])
temp_file.seek(0) temp_file.seek(0)
if self.audio_sources["channels"] > 2:
audio = AudioSegment.from_file(temp_file, format="wav")
mono_audio = audio.set_channels(1)
temp_file = BytesIO()
mono_audio.export(temp_file, format="wav")
temp_file.seek(0)
with AudioFile(temp_file) as source: with AudioFile(temp_file) as source:
audio = self.audio_recognizer.record(source) audio = self.audio_recognizer.record(source)
return audio return audio

View File

@@ -13,6 +13,7 @@ sentencepiece==0.1.99
ctranslate2==4.1.0 ctranslate2==4.1.0
faster-whisper==1.0.1 faster-whisper==1.0.1
openvr==1.26.701 openvr==1.26.701
translators @ git+https://github.com/misyaguziya/translators@5.8.9 pydub==0.25.1
translators @ git+https://github.com/misyaguziya/translators@5.9.2
SpeechRecognition @ git+https://github.com/misyaguziya/custom_speech_recognition@3.10.4 SpeechRecognition @ git+https://github.com/misyaguziya/custom_speech_recognition@3.10.4
tinyoscquery @ git+https://github.com/cyberkitsune/tinyoscquery@0.1.2 tinyoscquery @ git+https://github.com/cyberkitsune/tinyoscquery@0.1.2

View File

@@ -249,6 +249,21 @@ def createSettingBox_AboutVrct(setting_box_wrapper, config_window, settings, vie
section_row+=1
# Localization ----------------------------------
_localization, localization_contents_wrapper = createSectionContainer(
section_row=section_row,
section_title_image_file_name="localization_title.png",
section_bottom_padding=about_vrct_uism.SECTION_BOTTOM_PADY,
section_title_bottom_padding=about_vrct_uism.LOCALIZATION_TITLE_BOTTOM_PADY
)
localization_members = settings.about_vrct.embedImageCTkLabel(localization_contents_wrapper, "localization_members.png")
localization_members.grid(column=0, row=0, padx=0, pady=0, sticky="nsew")
section_row+=1 section_row+=1
# Special Thanks & Supporters ---------------------------------- # Special Thanks & Supporters ----------------------------------
_special_thanks, special_thanks_contents_wrapper = createSectionContainer( _special_thanks, special_thanks_contents_wrapper = createSectionContainer(

View File

@@ -50,6 +50,9 @@ class AboutVrctManager():
self.uism.TELL_US_BUTTON_BORDER_WIDTH = self._calculateUiSize(1) self.uism.TELL_US_BUTTON_BORDER_WIDTH = self._calculateUiSize(1)
self.uism.LOCALIZATION_TITLE_BOTTOM_PADY = self._calculateUiSize(4)
self.uism.SPECIAL_THANKS_SECTION_TITLE_BOTTOM_PADY = self._calculateUiSize(6) self.uism.SPECIAL_THANKS_SECTION_TITLE_BOTTOM_PADY = self._calculateUiSize(6)
self.uism.SPECIAL_THANKS_MEMBERS_BOTTOM_PADY = self._calculateUiSize(4) self.uism.SPECIAL_THANKS_MEMBERS_BOTTOM_PADY = self._calculateUiSize(4)
self.uism.SPECIAL_THANKS_MESSAGE_BOTTOM_PADY = self._calculateUiSize(0) self.uism.SPECIAL_THANKS_MESSAGE_BOTTOM_PADY = self._calculateUiSize(0)