Merge branch 'develop' into plugins_system

# Conflicts:
#	src-tauri/tauri.conf.json
This commit is contained in:
Sakamoto Shiina
2025-04-24 02:20:00 +09:00
42 changed files with 716 additions and 589 deletions

116
README.md
View File

@@ -1,116 +0,0 @@
<div align="center">
<picture>
<source srcset="docs/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="docs/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="docs/vrct_logo.png" alt="VRCT Logo" width="50%">
</picture>
<br>
<br>
[![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)
[![Github Sponsors](https://img.shields.io/badge/GitHub%20Sponsors-30363D?&logo=GitHub-Sponsors&logoColor=EA4AAA)](https://github.com/sponsors/misyaguziya)
<h3>
Become a VRCT Supporter on:
</h3>
<a href="https://vrct-dev.fanbox.cc">
<picture>
<source srcset="docs/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="docs/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="docs/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
</picture>
</a>&emsp;&nbsp;
<a href="https://patreon.com/vrct_dev">
<picture>
<source srcset="docs/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="docs/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="docs/patreon_logo_black.png" alt="Patreon" height="22px">
</picture>
</a>&emsp;&nbsp;
<a href="https://ko-fi.com/vrct_dev">
<picture>
<img src="docs/kofi_logo.png" alt="Ko-fi" height="22px">
</picture>
</a>&emsp;&nbsp;
<br>
<picture>
<source srcset="docs/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="docs/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="docs/supporter_section_border_d.png" alt="Supporter Section Border">
</picture>
<br>
<br>
| **English** | [日本語](./README.ja.md) | [한국어](./README.ko.md) | [繁體中文](./README.zh-Hant.md) |
<h3>
VRCT is software that supports VRChat conversations with translation and transcription.
</h3>
![](docs/main_window.png)
<div align="left">
# Download & Install
Download from anywhere you like.
- [Github.com](https://github.com/misyaguziya/VRCT/releases/)
- [BOOTH.pm](https://misyaguziya.booth.pm/items/5155325)
Just download and run the exe.
# What is VRCT?
VRCT is software that supports conversations between people who speak different languages by providing chat or voice translation.
These features are designed for use within VRChat.
*Although not supported, it is also used for other purposes such as watching movies.
VRCT supports your conversations with
- 💬 **Send chat to VRChat**
- 🌐 **Translation**
- 🎙 **Transcription of audio from microphone**
- 🔈 **Transcription of audio from Speaker**
# Documents
Initial setup, basic functions, and other features are also described.
- [Documents Link](https://mzsoftware.notion.site/VRCT-Documents-be79b7a165f64442ad8f326d86c22246?pvs=4)
# How to Use (YouTube)
<div align="center">
[![](https://img.youtube.com/vi/rUTad037n8Q/0.jpg)](https://www.youtube.com/watch?v=rUTad037n8Q)
<div align="left">
# If you want to run it in python
1. Install the following version of python.
`python version 3.11.5`
2. Install package and run main.py.
```bash
./install.bat
python main.py
```
## Author
- [みしゃ(misyaguzi)](https://github.com/misyaguziya) (Main Development)
- [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI multilingual support)
- [レラ](https://github.com/soumt-r) (Technical Support)
- [どね](https://twitter.com/done_vrc) (Logo Design)
## Thanks to our contributors
<a href="https://github.com/misyaguziya/VRCT/graphs/contributors" target="_blank">
<img src="https://contrib.rocks/image?repo=misyaguziya/VRCT" />
</a>
---
VRCT is not endorsed by VRChat and does not reflect the views or opinions of VRChat or anyone officially involved in producing or managing VRChat properties. VRChat and all associated properties are trademarks or registered trademarks of VRChat Inc. VRChat © VRChat Inc.

1
README.md Symbolic link
View File

@@ -0,0 +1 @@
docs/readmes/README.en.md

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 75 KiB

View File

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 182 B

After

Width:  |  Height:  |  Size: 182 B

View File

Before

Width:  |  Height:  |  Size: 186 B

After

Width:  |  Height:  |  Size: 186 B

View File

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 155 KiB

View File

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 91 KiB

View File

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

107
docs/readmes/README.en.md Normal file
View File

@@ -0,0 +1,107 @@
<div align="center">
<picture>
<source srcset="/docs/img/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="/docs/img/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="/docs/img/vrct_logo.png" alt="VRCT Logo" width="50%">
</picture>
<br>
<br>
[![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)
[![Github Sponsors](https://img.shields.io/badge/GitHub%20Sponsors-30363D?&logo=GitHub-Sponsors&logoColor=EA4AAA)](https://github.com/sponsors/misyaguziya)
<h3>
Become a VRCT Supporter on:
</h3>
<a href="https://vrct-dev.fanbox.cc">
<picture>
<source srcset="/docs/img/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="/docs/img/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="/docs/img/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
</picture>
</a>&emsp;&nbsp;
<a href="https://patreon.com/vrct_dev">
<picture>
<source srcset="/docs/img/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="/docs/img/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="/docs/img/patreon_logo_black.png" alt="Patreon" height="22px">
</picture>
</a>&emsp;&nbsp;
<a href="https://ko-fi.com/vrct_dev">
<picture>
<img src="/docs/img/kofi_logo.png" alt="Ko-fi" height="22px">
</picture>
</a>&emsp;&nbsp;
<br>
<picture>
<source srcset="/docs/img/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="/docs/img/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="/docs/img/supporter_section_border_d.png" alt="Supporter Section Border">
</picture>
<br>
<br>
| **English** | [日本語](/docs/readmes/README.ja.md) | [한국어](/docs/readmes/README.ko.md) | [繁體中文](/docs/readmes/README.zh-Hant.md) |
<h3>
VRCT is software that supports VRChat conversations with translation and transcription.
</h3>
![](/docs/img/main_window.png)
<div align="left">
# Download & Install
Download from anywhere you like.
- [Github.com](https://github.com/misyaguziya/VRCT/releases/)
- [BOOTH.pm](https://misyaguziya.booth.pm/items/5155325)
Just download and run the exe.
# What is VRCT?
VRCT is software that supports conversations between people who speak different languages by providing chat or voice translation.
These features are designed for use within VRChat.
*Although not supported, it is also used for other purposes such as watching movies.
VRCT supports your conversations with
- 💬 **Send chat to VRChat**
- 🌐 **Translation**
- 🎙 **Transcription of audio from microphone**
- 🔈 **Transcription of audio from Speaker**
# Documents
Initial setup, basic functions, and other features are also described.
- [Documents Link](https://mzsoftware.notion.site/VRCT-Documents-be79b7a165f64442ad8f326d86c22246?pvs=4)
# How to Use (YouTube)
<div align="center">
[![](https://img.youtube.com/vi/rUTad037n8Q/0.jpg)](https://www.youtube.com/watch?v=rUTad037n8Q)
<div align="left">
## Author
- [みしゃ(misyaguzi)](https://github.com/misyaguziya) (Main Development)
- [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI multilingual support)
- [レラ](https://github.com/soumt-r) (Technical Support)
- [どね](https://twitter.com/done_vrc) (Logo Design)
## Thanks to our contributors
<a href="https://github.com/misyaguziya/VRCT/graphs/contributors" target="_blank">
<img src="https://contrib.rocks/image?repo=misyaguziya/VRCT" />
</a>
---
VRCT is not endorsed by VRChat and does not reflect the views or opinions of VRChat or anyone officially involved in producing or managing VRChat properties. VRChat and all associated properties are trademarks or registered trademarks of VRChat Inc. VRChat © VRChat Inc.

View File

@@ -1,9 +1,9 @@
<div align="center">
<picture>
<source srcset="docs/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="docs/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="docs/vrct_logo.png" alt="VRCT Logo" width="50%">
<source srcset="/docs/img/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="/docs/img/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="/docs/img/vrct_logo.png" alt="VRCT Logo" width="50%">
</picture>
<br>
@@ -21,44 +21,44 @@ Become a VRCT Supporter on:
<a href="https://vrct-dev.fanbox.cc">
<picture>
<source srcset="docs/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="docs/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="docs/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
<source srcset="/docs/img/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="/docs/img/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="/docs/img/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
</picture>
</a>&emsp;&nbsp;
<a href="https://patreon.com/vrct_dev">
<picture>
<source srcset="docs/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="docs/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="docs/patreon_logo_black.png" alt="Patreon" height="22px">
<source srcset="/docs/img/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="/docs/img/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="/docs/img/patreon_logo_black.png" alt="Patreon" height="22px">
</picture>
</a>&emsp;&nbsp;
<a href="https://ko-fi.com/vrct_dev">
<picture>
<img src="docs/kofi_logo.png" alt="Ko-fi" height="22px">
<img src="/docs/img/kofi_logo.png" alt="Ko-fi" height="22px">
</picture>
</a>&emsp;&nbsp;
<br>
<picture>
<source srcset="docs/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="docs/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="docs/supporter_section_border_d.png" alt="Supporter Section Border">
<source srcset="/docs/img/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="/docs/img/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="/docs/img/supporter_section_border_d.png" alt="Supporter Section Border">
</picture>
<br>
<br>
| [English](./README.md) | **日本語** | [한국어](./README.ko.md) | [繁體中文](./README.zh-Hant.md) |
| [English](/docs/readmes/README.en.md) | **日本語** | [한국어](/docs/readmes/README.ko.md) | [繁體中文](/docs/readmes/README.zh-Hant.md) |
<h3>
VRCTは翻訳や文字起こしでVRChatの会話をサポートするソフトウェアです。
</h3>
![](docs/main_window.png)
![](/docs/img/main_window.png)
<div align="left">
@@ -91,15 +91,6 @@ VRCTはあなたの会話を以下でサポートをします。
<div align="left">
# pythonで実行したい場合
1. 以下のバージョンのpythonをインストールしてください。
`python version 3.11.5`
2. packageのインストールとmain.pyを起動してください。
```bash
./install.bat
python main.py
```
## Author
- [みしゃ(misyaguzi)](https://github.com/misyaguziya) (メイン開発)
- [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI多言語対応)

View File

@@ -1,9 +1,9 @@
<div align="center">
<picture>
<source srcset="docs/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="docs/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="docs/vrct_logo.png" alt="VRCT Logo" width="50%">
<source srcset="/docs/img/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="/docs/img/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="/docs/img/vrct_logo.png" alt="VRCT Logo" width="50%">
</picture>
<br>
@@ -21,44 +21,44 @@ Become a VRCT Supporter on:
<a href="https://vrct-dev.fanbox.cc">
<picture>
<source srcset="docs/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="docs/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="docs/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
<source srcset="/docs/img/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="/docs/img/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="/docs/img/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
</picture>
</a>&emsp;&nbsp;
<a href="https://patreon.com/vrct_dev">
<picture>
<source srcset="docs/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="docs/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="docs/patreon_logo_black.png" alt="Patreon" height="22px">
<source srcset="/docs/img/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="/docs/img/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="/docs/img/patreon_logo_black.png" alt="Patreon" height="22px">
</picture>
</a>&emsp;&nbsp;
<a href="https://ko-fi.com/vrct_dev">
<picture>
<img src="docs/kofi_logo.png" alt="Ko-fi" height="22px">
<img src="/docs/img/kofi_logo.png" alt="Ko-fi" height="22px">
</picture>
</a>&emsp;&nbsp;
<br>
<picture>
<source srcset="docs/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="docs/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="docs/supporter_section_border_d.png" alt="Supporter Section Border">
<source srcset="/docs/img/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="/docs/img/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="/docs/img/supporter_section_border_d.png" alt="Supporter Section Border">
</picture>
<br>
<br>
| [English](./README.md) | [日本語](./README.ja.md) | **한국어** | [繁體中文](./README.zh-Hant.md) |
| [English](/docs/readmes/README.en.md) | [日本語](/docs/readmes/README.ja.md) | **한국어** | [繁體中文](/docs/readmes/README.zh-Hant.md) |
<h3>
VRCT는 음성인식 및 번역 기능을 통해 VRChat의 대화를 지원하는 소프트웨어입니다.
</h3>
![](docs/main_window.png)
![](/docs/img/main_window.png)
<div align="left">
@@ -91,15 +91,6 @@ VRCT는 다음과 같이 당신의 대화를 도와드려요.
<div align="left">
# python으로 실행하고 싶은 경우
1. 다음 버전의 python을 설치합니다.
`python version 3.11.5`
2. 패키지를 설치하고 main.py를 실행합니다.
```bash
./install.bat
python main.py
```
## Author
- [みしゃ(misyaguzi)](https://github.com/misyaguziya) (주요 개발)
- [しいな(Shiina_12siy)](https://twitter.com/Shiina_12siy) (UI/UX, UI 다국어 지원)

View File

@@ -1,9 +1,9 @@
<div align="center">
<picture>
<source srcset="docs/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="docs/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="docs/vrct_logo.png" alt="VRCT Logo" width="50%">
<source srcset="/docs/img/vrct_logo_white.png" media="(prefers-color-scheme: dark)" width="50%">
<source srcset="/docs/img/vrct_logo_black.png" media="(prefers-color-scheme: light)" width="50%">
<img src="/docs/img/vrct_logo.png" alt="VRCT Logo" width="50%">
</picture>
<br>
@@ -21,44 +21,44 @@ Become a VRCT Supporter on:
<a href="https://vrct-dev.fanbox.cc">
<picture>
<source srcset="docs/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="docs/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="docs/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
<source srcset="/docs/img/pixiv_fanbox_white.png" media="(prefers-color-scheme: dark)" height="18px">
<source srcset="/docs/img/pixiv_fanbox_black.png" media="(prefers-color-scheme: light)" height="18px">
<img src="/docs/img/pixiv_fanbox_black.png" alt="PIXIV FANBOX" height="18px">
</picture>
</a>&emsp;&nbsp;
<a href="https://patreon.com/vrct_dev">
<picture>
<source srcset="docs/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="docs/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="docs/patreon_logo_black.png" alt="Patreon" height="22px">
<source srcset="/docs/img/patreon_logo_white.png" media="(prefers-color-scheme: dark)" height="22px">
<source srcset="/docs/img/patreon_logo_black.png" media="(prefers-color-scheme: light)" height="22px">
<img src="/docs/img/patreon_logo_black.png" alt="Patreon" height="22px">
</picture>
</a>&emsp;&nbsp;
<a href="https://ko-fi.com/vrct_dev">
<picture>
<img src="docs/kofi_logo.png" alt="Ko-fi" height="22px">
<img src="/docs/img/kofi_logo.png" alt="Ko-fi" height="22px">
</picture>
</a>&emsp;&nbsp;
<br>
<picture>
<source srcset="docs/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="docs/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="docs/supporter_section_border_d.png" alt="Supporter Section Border">
<source srcset="/docs/img/supporter_section_border_d.png" media="(prefers-color-scheme: dark)">
<source srcset="/docs/img/supporter_section_border_l.png" media="(prefers-color-scheme: light)">
<img src="/docs/img/supporter_section_border_d.png" alt="Supporter Section Border">
</picture>
<br>
<br>
| [English](./README.md) | [日本語](./README.ja.md) | [한국어](./README.ko.md) | **繁體中文** |
| [English](/docs/readmes/README.en.md) | [日本語](/docs/readmes/README.ja.md) | [한국어](/docs/readmes/README.ko.md) | **繁體中文** |
<h3>
VRCT 是一個支援 VRChat 對話翻譯和紀錄的軟體。
</h3>
![](docs/main_window.png)
![](/docs/img/main_window.png)
<div align="left">
@@ -90,15 +90,6 @@ VRCT 可以:
<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 多語系支援)

View File

@@ -8,13 +8,13 @@ common:
common_error:
no_device_mic: "No mic device detected."
no_device_speaker: "No Speaker device detected."
no_device_speaker: "No speaker device detected."
threshold_invalid_value: "You can set it with a value between {{min}} to {{max}}."
failed_download_weight_ctranslate2: "CTranslate2 weight download error."
failed_download_weight_whisper: "Whisper weight download error."
translation_limit: "Translation engine limit error."
translation_limit: "Translation engine limit reached or temporarily restricted."
deepl_auth_key_invalid_length: "DeepL auth key length is not correct."
deepl_auth_key_failed_authentication: "Auth Key is incorrect or Usage limit reached."
deepl_auth_key_failed_authentication: "Auth key is incorrect or API usage limit reached."
invalid_value_mic_record_timeout: "It cannot be greater than '{{mic_phrase_timeout_label}}' with a value of 0 or more."
invalid_value_mic_phrase_timeout: "It cannot be set lower than '{{mic_record_timeout_label}}' with a value of 0 or more."
@@ -28,18 +28,18 @@ main_page:
translation: "Translation"
transcription_send: "Voice2Chatbox"
transcription_receive: "Speaker2Log"
foreground: "Foreground"
foreground: "Set To Stay On Top"
language_settings: "Language Settings"
your_language: "Your Language"
translate_each_other_label: "Translate Each Other"
swap_button_label: "Swap Languages"
translate_each_other_label: "Translate Both Languages"
swap_button_label: "Switch Languages"
target_language: "Target Language"
translator: "Translator"
translator_label_default: "Default"
translator_selector:
is_selected_same_language: "Since the same language is selected for both '{{your_language}}' and '{{target_language}}', only '{{ctranslate2}}' is available."
is_selected_same_language: "You are selecting the same language for '{{your_language}}' and '{{target_language}}' so only '{{ctranslate2}}' is available."
message_log:
all: "All"
@@ -48,7 +48,7 @@ main_page:
system: "System"
show_resend_button: "Show Resend Button"
resend_button_on_hover_desc: "Press and hold to send"
resend_button_on_hover_desc: "Press And Hold To Send"
state_text_enabled: "Enabled"
state_text_disabled: "Disabled"
@@ -57,28 +57,28 @@ main_page:
title_your_language: "Select Your Language"
title_target_language: "Select Target Language"
update_available: "New version is here!"
update_available: "New version is ready!"
updating: "Now updating..."
update_modal:
cpu_desc: "Use CPU only as the compute device."
cuda_desc: "Selectable between CPU and NVIDIA GPUs as compute devices."
cuda_compare_cpu_desc: "With GPU selection, processing is faster compared to a CPU."
cuda_compare_cpu_desc: "GPUs offer faster processing than CPUs."
cuda_disk_space_desc: "Requires approximately {{size}} of disk space."
close_modal: "Close"
download_latest_and_restart: "The latest version will be downloaded,\nand the app will automatically restart."
is_latest_version_already: "Already using the latest version"
is_current_compute_device: "Currently using this version"
is_current_compute_device: "The version currently in use"
config_page:
version: "version {{version}}"
version: "Version {{version}}"
model_download_button_label: "Download"
side_menu_labels:
device: "Device"
appearance: "Appearance"
translation: "Translation"
transcription: "Transcription"
others: "Others"
others: "Other"
hotkeys: "Hotkeys"
advanced_settings: "Advanced Settings"
@@ -90,17 +90,17 @@ config_page:
mic_host_device:
label: "Mic Device"
mic_dynamic_energy_threshold:
label_for_automatic: "Mic Energy Threshold (Current Setting: Automatic)"
desc_for_automatic: "Automatically determine microphone input sensitivity."
label_for_manual: "Mic Energy Threshold (Current Setting: Manual)"
desc_for_manual: "Manually determine the microphone input sensitivity using the slider. Press the microphone icon to input your voice and adjust the sensitivity while monitoring the volume."
label_for_automatic: "Mic Sensitivity Settings (Current Setting: Automatic)"
desc_for_automatic: "Automatically control mic input sensitivity."
label_for_manual: "Mic Sensitivity Settings (Current Setting: Manual)"
desc_for_manual: "Input sensitivity can be manually adjusted using the slider. Click the mic icon to test your voice input and adjust the level while monitoring the volume."
speaker_device:
label: "Speaker Device"
speaker_dynamic_energy_threshold:
label_for_automatic: "Speaker Energy Threshold (Current Setting: Automatic)"
desc_for_automatic: "Automatically determine speaker input sensitivity."
label_for_manual: "Speaker Energy Threshold (Current Setting: Manual)"
desc_for_manual: "Manually determine the speaker input sensitivity using the slider. Press the headphones icon to listen to the audio and adjust the sensitivity while monitoring the volume."
label_for_automatic: "Speaker Input Sensitivity Adjustment (Current Setting: Automatic)"
desc_for_automatic: "Automatically control speaker input sensitivity."
label_for_manual: "Speaker Input Sensitivity Adjustment (Current Setting: Manual)"
desc_for_manual: "Input sensitivity can be manually adjusted using the slider. Click the headphone icon to listen to the audio and adjust the level while checking the volume."
appearance:
transparency:
@@ -110,12 +110,12 @@ config_page:
label: "UI Size"
textbox_ui_size:
label: "Message Logs Font Size"
desc: "You can adjust the font size used in the logs relative to the UI size."
desc: "You can adjust the log font size by changing the scaling factor relative to the UI size."
send_message_button_type:
label: "Send Message Button"
hide: "Hide (Use enter key to send)"
hide: "Hide (Use Enter key to send)"
show: "Show"
show_and_disable_enter_key: "Show and disable to send when pressed enter key"
show_and_disable_enter_key: "Show and disable sending using the Enter key."
font_family:
label: "Font Family"
ui_language:
@@ -124,14 +124,14 @@ config_page:
translation:
ctranslate2_weight_type:
label: "{{ctranslate2}} Model"
desc: "You can choose the translation model to use for the internal translation engine."
small: "Basic model ({{capacity}})"
large: "High accuracy model ({{capacity}})"
desc: "You can choose the translation model when using the {{ctranslate2}} translation engine."
small: "Basic Model ({{capacity}})"
large: "High Accuracy Model ({{capacity}})"
ctranslate2_compute_device:
label: "{{ctranslate2}} Compute Device"
label: "Processing device for AI translation {{ctranslate2}}"
deepl_auth_key:
label: "DeepL Auth Key"
desc: "Please select {{translator}} on the main screen with DeepL_API when using. ※Some languages may not be supported."
desc: "When using it, please change {{translator}} on the main screen to DeepL_API. ※Some languages may not be supported."
open_auth_key_webpage: "Open DeepL Account Webpage"
save: "Save"
edit: "Edit"
@@ -143,7 +143,7 @@ config_page:
section_label_transcription_engines: "Transcription Engines"
mic_record_timeout:
label: "Mic Record Timeout"
desc: "Detects silence and, when the specified number of seconds has passed, considers the mic input to have ended. (Second(s))"
desc: "Detects silence and, when the specified number of seconds passes, the system considers the voice input to have ended. (Second(s))"
mic_phrase_timeout:
label: "Mic Phrase Timeout"
desc: "Transcription processing is performed at intervals of the specified number of seconds."
@@ -152,9 +152,9 @@ config_page:
desc: "It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs and send to VRChat."
mic_word_filter:
label: "Mic Word Filter"
desc: "If a registered word is detected, the text will not be sent. To add multiple words at once, separate them with a ',' (comma).\n*Duplicate words will not be registered."
desc: "If a registered word is detected, the message will not be sent. To add multiple words at once, separate them with ',' (comma).\n*Duplicate words will not be registered."
add_button_label: "Add"
count_desc: "Current registered word count: {{count}}"
count_desc: "Words Currently Registered: {{count}}"
speaker_record_timeout:
label: "Speaker Record Timeout"
desc: "Detects silence and, when the specified number of seconds has passed, considers the speaker input to have ended. (Second(s))"
@@ -165,20 +165,20 @@ config_page:
label: "Speaker Max Words"
desc: "It is the lower limit for the number of transcribed words, and only when this number is exceeded will the transcription results be displayed logs."
select_transcription_engine:
label: "Transcription Engine"
label: "Transcription Engine Used For Speech Recognition"
whisper_weight_type:
label: "Whisper Model"
desc: "Larger models tend to have higher accuracy, but they also consume more CPU or GPU resources.\nEspecially for models larger than medium, it may be difficult or even impossible to use them depending on the performance of your CPU/GPU."
desc: "Larger models have higher accuracy, but they also consume more CPU or GPU resources.\nEspecially for models larger than medium, it may be difficult or even impossible to use them depending on the performance of your CPU/GPU."
model_template: "{{model_name}} model ({{capacity}})"
recommended_model_template: "{{model_name}} model ({{capacity}}) (Recommended)"
whisper_compute_device:
label: "Whisper Compute Device"
label: "Processing Device Used For Whisper"
vr:
single_line: "Single line"
multi_lines: "Multi lines"
multi_lines: "Multiple Lines"
overlay_enable: "Enable"
restore_default_settings: "Restore Default Settings"
restore_default_settings: "Reset to Default Settings"
position: "Position"
rotation: "Rotation"
x_position: "X-axis (left-right)"
@@ -188,46 +188,46 @@ config_page:
y_rotation: "Y-axis rotation"
z_rotation: "Z-axis rotation"
sample_text_button:
start: "Send sample texts\nto Overlay"
start: "Send Sample Texts\nTo Overlay"
stop: "Stop Sending"
sample_text: "Sample text."
sample_text: "Sample Text."
opacity: "Opacity"
ui_scaling: "UI Scaling"
display_duration: "Display duration"
fadeout_duration: "Fadeout duration"
display_duration: "Display Duration"
fadeout_duration: "Fadeout Duration"
common_settings: "Common Settings"
tracker: "Tracker"
hmd: "HMD"
left_hand: "Left hand"
right_hand: "Right hand"
left_hand: "Left Hand"
right_hand: "Right Hand"
overlay_show_only_translated_messages:
label: "Show Only Translated Messages"
others:
section_label_sounds: "Sounds"
auto_clear_the_message_box:
label: "Auto Clear The Message Box"
label: "Auto Clear Message box"
send_only_translated_messages:
label: "Send Only Translated Messages"
auto_export_message_logs:
label: "Auto Export Message Logs"
desc: "Automatically export the conversation messages as a text file."
label: "Auto Save Message Logs"
desc: "Automatically saves the conversation messages as text files."
vrc_mic_mute_sync:
label: "VRC Mic Mute Sync"
desc: "VRCT will not send the message to VRChat while VRChat's mic is muted.\n*There is a bit latency and Push-To-Talk is not supported."
desc: "Messages will not be sent to VRCT while VRChat's mic is muted.\n*There may be a slight delay. Push-To-Talk is not supported."
send_message_to_vrc:
label: "Send Message To VRChat"
desc: "There is a way to use it without sending messages to VRChat, but it is not supported. Enable this feature when you intend to send a message to VRChat."
desc: "This feature is not supported, but there is a way to use it without sending messages to VRChat. Make sure to enable this feature when you wish to send messages to VRChat."
notification_vrc_sfx:
label: "Enable Notification Sound When Sending Chat"
desc: "Disabling this feature will send chats quietly without playing a notification sound that others can hear."
desc: "When this feature is disabled, messages will be sent silently without playing the chatbox notification sound that others can hear."
send_received_message_to_vrc:
label: "Send Received Message To VRChat"
desc: "Send the message you received from the speaker's sound to VRChat's chatbox."
desc: "Send the message you received from the speaker's voice to VRChat's chatbox."
hotkeys:
toggle_vrct_visibility:
label: "Toggle VRCT Visibility"
label: "Toggle VRCT visibility"
toggle_translation:
label: "Toggle {{translation}}"
toggle_transcription_send:
@@ -243,4 +243,4 @@ config_page:
open_config_filepath:
label: "Open Config File"
switch_compute_device:
label: "Switch VRCT to CPU/GPU Version"
label: "Switch VRCT To CPU/GPU Version"

View File

@@ -956,7 +956,7 @@ class Config:
def init_config(self):
# Read Only
self._VERSION = "3.0.4"
self._VERSION = "3.0.5"
if getattr(sys, 'frozen', False):
self._PATH_LOCAL = os_path.dirname(sys.executable)
else:

View File

@@ -6,7 +6,7 @@ import re
from device_manager import device_manager
from config import config
from model import model
from utils import removeLog, printLog, errorLogging, isConnectedNetwork
from utils import removeLog, printLog, errorLogging, isConnectedNetwork, isValidIpAddress
class Controller:
def __init__(self) -> None:
@@ -150,7 +150,7 @@ class Controller:
400,
self.run_mapping["error_device"],
{
"message":"No Speaker device detected",
"message":"No speaker device detected",
"data": None
},
)
@@ -1094,9 +1094,29 @@ class Controller:
@staticmethod
def setOscIpAddress(data, *args, **kwargs) -> dict:
if isValidIpAddress(data) is False:
response = {
"status":400,
"result":{
"message":"Invalid IP address",
"data": config.OSC_IP_ADDRESS
}
}
else:
try:
model.setOscIpAddress(data)
config.OSC_IP_ADDRESS = data
response = {"status":200, "result":config.OSC_IP_ADDRESS}
except Exception:
model.setOscIpAddress(config.OSC_IP_ADDRESS)
return {"status":200, "result":config.OSC_IP_ADDRESS}
response = {
"status":400,
"result":{
"message":"Cannot set IP address",
"data": config.OSC_IP_ADDRESS
}
}
return response
@staticmethod
def getOscPort(*args, **kwargs) -> dict:

View File

@@ -400,9 +400,9 @@ class Model:
mic_device_list = device_manager.getMicDevices().get(mic_host_name, [{"name": "NoDevice"}])
selected_mic_device = [device for device in mic_device_list if device["name"] == mic_device_name]
if len(selected_mic_device) == 0:
return False
if len(selected_mic_device) == 0 or mic_device_name == "NoDevice":
fnc({"text": False, "language": None})
else:
self.mic_audio_queue = Queue()
# self.mic_energy_queue = Queue()
@@ -535,9 +535,9 @@ class Model:
mic_device_list = device_manager.getMicDevices().get(mic_host_name, [{"name": "NoDevice"}])
selected_mic_device = [device for device in mic_device_list if device["name"] == mic_device_name]
if len(selected_mic_device) == 0:
return False
if len(selected_mic_device) == 0 or mic_device_name == "NoDevice":
self.check_mic_energy_fnc(False)
else:
def sendMicEnergy():
if mic_energy_queue.empty() is False:
energy = mic_energy_queue.get()
@@ -566,12 +566,14 @@ class Model:
self.mic_energy_recorder = None
def startSpeakerTranscript(self, fnc):
speaker_device_name = config.SELECTED_SPEAKER_DEVICE
speaker_device_list = device_manager.getSpeakerDevices()
selected_speaker_device = [device for device in speaker_device_list if device["name"] == config.SELECTED_SPEAKER_DEVICE]
if len(selected_speaker_device) == 0:
return False
selected_speaker_device = [device for device in speaker_device_list if device["name"] == speaker_device_name]
if len(selected_speaker_device) == 0 or speaker_device_name == "NoDevice":
fnc({"text": False, "language": None})
else:
speaker_audio_queue = Queue()
# speaker_energy_queue = Queue()
speaker_device = selected_speaker_device[0]
@@ -660,12 +662,13 @@ class Model:
if isinstance(fnc, Callable):
self.check_speaker_energy_fnc = fnc
speaker_device_name = config.SELECTED_SPEAKER_DEVICE
speaker_device_list = device_manager.getSpeakerDevices()
selected_speaker_device = [device for device in speaker_device_list if device["name"] == config.SELECTED_SPEAKER_DEVICE]
if len(selected_speaker_device) == 0:
return False
selected_speaker_device = [device for device in speaker_device_list if device["name"] == speaker_device_name]
if len(selected_speaker_device) == 0 or speaker_device_name == "NoDevice":
self.check_speaker_energy_fnc(False)
else:
def sendSpeakerEnergy():
if speaker_energy_queue.empty() is False:
energy = speaker_energy_queue.get()

View File

@@ -17,6 +17,8 @@ _MODELS = {
"large-v1": "Systran/faster-whisper-large-v1",
"large-v2": "Systran/faster-whisper-large-v2",
"large-v3": "Systran/faster-whisper-large-v3",
"large-v3-turbo-int8": "Zoont/faster-whisper-large-v3-turbo-int8-ct2", #794MB
"large-v3-turbo": "deepdml/faster-whisper-large-v3-turbo-ct2", #1.58GB
}
_FILENAMES = [

View File

@@ -7,14 +7,22 @@ from logging.handlers import RotatingFileHandler
from ctranslate2 import get_supported_compute_types
import requests
import ipaddress
def isConnectedNetwork(url="http://www.google.com", timeout=3):
def isConnectedNetwork(url="http://www.google.com", timeout=3) -> bool:
try:
response = requests.get(url, timeout=timeout)
return response.status_code == 200
except requests.RequestException:
return False
def isValidIpAddress(ip_address: str) -> bool:
try:
ipaddress.ip_address(ip_address)
return True
except ValueError:
return False
def getBestComputeType(device, device_index) -> str:
compute_types = get_supported_compute_types(device, device_index)
compute_types = set(compute_types)

View File

@@ -53,14 +53,11 @@
"open": true,
"sidecar": true,
"scope": [
{
"name": "bin/VRCT-sidecar", "sidecar": true,"args": true
}
{ "name": "bin/VRCT-sidecar", "sidecar": true, "args": true }
]
}
},
"windows": [
{
},
"windows": [{
"title": "VRCT",
"center": true,
"width": 450,
@@ -69,11 +66,8 @@
"minHeight": 200,
"transparent": true,
"decorations": false
}
],
"security": {
"csp": null
},
}],
"security": { "csp": null },
"bundle": {
"active": true,
"targets": "nsis",
@@ -91,7 +85,7 @@
"externalBin": [
"bin/VRCT-sidecar"
],
"resources":{
"resources": {
"bin/_internal": "_internal",
"plugins": "plugins"
},

View File

@@ -24,7 +24,7 @@ const _Entry = forwardRef((props, ref) => {
<div className={styles.entry_container}>
<div
className={input_wrapper_class_names}
style={{width: props.width }}
style={{width: props.width || "20rem" }}
>
<input
ref={inputRef}

View File

@@ -0,0 +1,32 @@
import styles from "./EntryWithSaveButton.module.scss";
import { _Entry } from "../_atoms/_entry/_Entry";
import CircularProgress from "@mui/material/CircularProgress";
import { useTranslation } from "react-i18next";
import { clsx } from "clsx";
export const EntryWithSaveButton = (props) => {
const { t } = useTranslation();
const onChangeFunction = (e) => {
props.onChangeFunction?.(e.target.value);
};
const saveFunction = () => {
props.saveFunction();
};
const is_disabled = props.state === "pending";
const save_button_class_names = clsx(styles.save_button, {
[styles.is_disabled]: is_disabled
});
return (
<div className={styles.container}>
<_Entry width={props.width} onChange={onChangeFunction} ui_variable={props.variable} is_disabled={is_disabled}/>
<button className={save_button_class_names} onClick={saveFunction}>
{is_disabled
? <CircularProgress size="1.4rem" sx={{ color: "var(--dark_basic_text_color)" }}/>
: <p className={styles.save_button_label}>{t("config_page.translation.deepl_auth_key.save")}</p>
}
</button>
</div>
);
};

View File

@@ -0,0 +1,30 @@
.container {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
flex-shrink: 0;
}
.save_button {
padding: 0.8rem 1.2rem;
background-color: var(--primary_600_color);
border-radius: 0.4rem;
text-align: center;
flex-shrink: 0;
min-width: 5.4rem;
&:hover {
background-color: var(--primary_500_color);
}
&:active {
background-color: var(--primary_700_color);
}
&.is_disabled {
pointer-events: none;
background-color: var(--primary_800_color);
}
}
.save_button_label {
font-size: 1.4rem;
}

View File

@@ -3,6 +3,7 @@ export { ComputeDevice } from "./compute_device/ComputeDevice";
export { DeeplAuthKey, OpenWebpage_DeeplAuthKey } from "./deepl_auth_key/DeeplAuthKey";
export { DropdownMenu } from "./dropdown_menu/DropdownMenu";
export { Entry } from "./entry/Entry";
export { EntryWithSaveButton } from "./entry_with_save_button/EntryWithSaveButton";
export { HotkeysEntry } from "./hotkeys_entry/HotkeysEntry";
export { LabelComponent } from "./label_component/LabelComponent";
export { RadioButton } from "./radio_button/RadioButton";

View File

@@ -8,6 +8,7 @@ import {
Slider,
SwitchBox,
Entry,
EntryWithSaveButton,
HotkeysEntry,
RadioButton,
OpenWebpage_DeeplAuthKey,
@@ -75,6 +76,9 @@ export const SwitchBoxContainer = (props) => (
export const EntryContainer = (props) => (
<CommonContainer Component={Entry} {...props} add_break_point={false} />
);
export const EntryWithSaveButtonContainer = (props) => (
<CommonContainer Component={EntryWithSaveButton} {...props} add_break_point={false} />
);
export const HotkeysEntryContainer = (props) => (
<CommonContainer Component={HotkeysEntry} {...props} />

View File

@@ -10,6 +10,7 @@ import contributor_iya from "@images/about_vrct/contributor_iya.png";
import contributor_rera from "@images/about_vrct/contributor_rera.png";
import contributor_poposuke from "@images/about_vrct/contributor_poposuke.png";
import contributor_kumaguma from "@images/about_vrct/contributor_kumaguma.png";
import contributor_riku from "@images/about_vrct/contributor_riku.png";
import localization_section_title from "@images/about_vrct/localization_section_title.png";
import localization_1 from "@images/about_vrct/localization_1.png";
@@ -86,6 +87,10 @@ export const AboutVrct = () => {
<img src={contributor_kumaguma} className={clsx(styles.contributors_img, styles.contributors)} />
<OpenLinkContainer className={styles.contributors_kumaguma_x} href_id="contributors_kumaguma_x" />
</div>
<div className={styles.contributor_card_wrapper}>
<img src={contributor_riku} className={clsx(styles.contributors_img, styles.contributors)} />
<OpenLinkContainer className={styles.contributors_riku_x} href_id="contributors_riku_x" />
</div>
</div>
</div>
@@ -158,6 +163,7 @@ const about_vrct_links = {
contributors_rera_github: { img: contributors_github_icon, href: "https://github.com/soumt-r" },
contributors_poposuke_x: { img: contributors_x_icon, href: "https://twitter.com/sig_popo" },
contributors_kumaguma_x: { img: contributors_x_icon, href: "https://twitter.com/K_kumaguma_A" },
contributors_riku_x: { img: contributors_x_icon, href: "https://twitter.com/Riku7302" },
};
const OpenLinkContainer = ({className, href_id}) => {

View File

@@ -160,6 +160,9 @@ $sns_left_pos: 0.8rem;
.contributors_kumaguma_x {
@include contributors_sns_styles($bottom_pos, $sns_left_pos);
}
.contributors_riku_x {
@include contributors_sns_styles($bottom_pos, $sns_left_pos);
}
.localization_section {
display: flex;

View File

@@ -11,6 +11,7 @@ import {
import {
ActionButtonContainer,
EntryContainer,
EntryWithSaveButtonContainer,
} from "../_templates/Templates";
@@ -30,54 +31,59 @@ export const AdvancedSettings = () => {
const OscIpAddressContainer = () => {
const { t } = useTranslation();
const [ui_variable, setUiVariable] = useState("");
const { currentOscIpAddress, setOscIpAddress } = useOscIpAddress();
const onChangeFunction = (e) => {
const value = e.currentTarget.value;
if (value === "") {
setUiVariable("");
} else {
setUiVariable(value);
setOscIpAddress(value);
}
const [input_value, setInputValue] = useState(currentOscIpAddress.data);
const onChangeFunction = (value) => {
setInputValue(value);
};
const saveFunction = () => {
setOscIpAddress(input_value);
};
useEffect(()=> {
setUiVariable(currentOscIpAddress.data);
setInputValue(currentOscIpAddress.data);
}, [currentOscIpAddress]);
return (
<EntryContainer
<EntryWithSaveButtonContainer
label={t("config_page.advanced_settings.osc_ip_address.label")}
ui_variable={ui_variable}
onChange={onChangeFunction}
variable={input_value}
saveFunction={saveFunction}
onChangeFunction={onChangeFunction}
state={currentOscIpAddress.state}
width="14rem"
/>
);
};
const OscPortContainer = () => {
const { t } = useTranslation();
const [ui_variable, setUiVariable] = useState("");
const { currentOscPort, setOscPort } = useOscPort();
const onChangeFunction = (e) => {
const value = e.currentTarget.value;
if (value === "") {
setUiVariable("");
} else {
setUiVariable(value);
setOscPort(value);
}
const [input_value, setInputValue] = useState(currentOscPort.data);
const onChangeFunction = (value) => {
value = value.replace(/[^0-9]/g, "");
setInputValue(value);
};
const saveFunction = () => {
setOscPort(input_value);
};
useEffect(()=> {
setUiVariable(currentOscPort.data);
setInputValue(currentOscPort.data);
}, [currentOscPort]);
return (
<EntryContainer
<EntryWithSaveButtonContainer
label={t("config_page.advanced_settings.osc_port.label")}
ui_variable={ui_variable}
onChange={onChangeFunction}
variable={input_value}
saveFunction={saveFunction}
onChangeFunction={onChangeFunction}
state={currentOscPort.state}
width="10rem"
/>
);
};

View File

@@ -260,6 +260,8 @@ const WhisperWeightType_Box = () => {
{ id: "large-v1", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v1", capacity: "2.87GB"}) },
{ id: "large-v2", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v2", capacity: "2.87GB"}) },
{ id: "large-v3", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v3", capacity: "2.87GB"}) },
{ id: "large-v3-turbo-int8", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v3-turbo-int8", capacity: "794MB"}) },
{ id: "large-v3-turbo", label: t("config_page.transcription.whisper_weight_type.model_template", {model_name: "large-v3-turbo", capacity: "1.58GB"}) },
];
const whisper_weight_types = updateLabelsById(currentWhisperWeightTypeStatus.data, new_labels);

View File

@@ -62,7 +62,7 @@ const CTranslate2WeightType_Box = () => {
)}
desc={t(
"config_page.translation.ctranslate2_weight_type.desc",
{translator: t("main_page.translator")}
{ctranslate2: "CTranslate2"}
)}
name="ctransalte2_weight_type"
options={c_translate2_weight_types}

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -14,6 +14,8 @@ import {
useSpeakerMaxWords,
useDeepLAuthKey,
useOscIpAddress,
} from "@logics_configs";
import { ui_configs } from "../ui_configs";
@@ -29,14 +31,16 @@ export const _useBackendErrorHandling = () => {
const { updateSpeakerPhraseTimeout } = useSpeakerPhraseTimeout();
const { updateSpeakerMaxWords } = useSpeakerMaxWords();
const { updateDeepLAuthKey } = useDeepLAuthKey();
const { updateDeepLAuthKey, saveErrorDeepLAuthKey } = useDeepLAuthKey();
const errorHandling_Backend = ({message, data, endpoint}) => {
const { updateOscIpAddress } = useOscIpAddress();
const errorHandling_Backend = ({message, data, endpoint, _result}) => {
switch (message) {
case "No mic device detected":
showNotification_Error(t("common_error.no_device_mic"));
break;
case "No Speaker device detected":
case "No speaker device detected":
showNotification_Error(t("common_error.no_device_speaker"));
break;
@@ -110,10 +114,23 @@ export const _useBackendErrorHandling = () => {
showNotification_Error(t("common_error.invalid_value_speaker_max_phrase"));
break;
default:
if (endpoint === "/set/data/deepl_auth_key") updateDeepLAuthKey(data);
// Advanced Settings, error messages are set by Backend (EN only)
case "Invalid IP address":
updateOscIpAddress(data);
showNotification_Error(message);
break;
case "Cannot set IP address":
updateOscIpAddress(data);
showNotification_Error(message);
break;
default:
// determine by endpoint, not message.
if (endpoint === "/set/data/deepl_auth_key") saveErrorDeepLAuthKey({message, data, endpoint, _result});
break;
}
}

View File

@@ -1,7 +1,9 @@
import { useStore_OscPort } from "@store";
import { useStdoutToPython } from "@logics/useStdoutToPython";
import { useNotificationStatus } from "@logics_common";
export const useOscPort = () => {
const { showNotification_Error } = useNotificationStatus();
const { asyncStdoutToPython } = useStdoutToPython();
const { currentOscPort, updateOscPort, pendingOscPort } = useStore_OscPort();
@@ -15,10 +17,17 @@ export const useOscPort = () => {
asyncStdoutToPython("/set/data/osc_port", osc_port);
};
const saveErrorOscPort = ({data, message, _result}) => {
updateOscPort(d => d.data);
showNotification_Error(_result);
};
return {
currentOscPort,
getOscPort,
updateOscPort,
setOscPort,
saveErrorOscPort,
};
};

View File

@@ -18,22 +18,30 @@ export const useDeepLAuthKey = () => {
pendingDeepLAuthKey();
asyncStdoutToPython("/set/data/deepl_auth_key", selected_deepl_auth_key);
};
const saveSuccessDeepLAuthKey = (saved_deepl_auth_key) => {
updateDeepLAuthKey(saved_deepl_auth_key);
showNotification_Success(t("config_page.translation.deepl_auth_key.auth_key_success"));
};
const deleteDeepLAuthKey = () => {
pendingDeepLAuthKey();
asyncStdoutToPython("/delete/data/deepl_auth_key");
};
const savedDeepLAuthKey = (data) => {
updateDeepLAuthKey(data);
showNotification_Success(t("config_page.translation.deepl_auth_key.auth_key_success"));
};
const saveErrorDeepLAuthKey = ({data, message}) => {
updateDeepLAuthKey(data);
showNotification_Error(message);
};
return {
currentDeepLAuthKey,
getDeepLAuthKey,
updateDeepLAuthKey,
setDeepLAuthKey,
saveSuccessDeepLAuthKey,
deleteDeepLAuthKey,
saveErrorDeepLAuthKey,
savedDeepLAuthKey,
};
};

View File

@@ -148,7 +148,7 @@ export const useReceiveRoutes = () => {
const { updateSpeakerPhraseTimeout } = useSpeakerPhraseTimeout();
const { updateSpeakerMaxWords } = useSpeakerMaxWords();
const { updateDeepLAuthKey, saveSuccessDeepLAuthKey } = useDeepLAuthKey();
const { updateDeepLAuthKey, savedDeepLAuthKey } = useDeepLAuthKey();
const { updateSelectedCTranslate2WeightType } = useSelectedCTranslate2WeightType();
const {
updateDownloadedCTranslate2WeightTypeStatus,
@@ -353,7 +353,7 @@ export const useReceiveRoutes = () => {
// Translation
"/get/data/deepl_auth_key": updateDeepLAuthKey,
"/set/data/deepl_auth_key": saveSuccessDeepLAuthKey,
"/set/data/deepl_auth_key": savedDeepLAuthKey,
"/delete/data/deepl_auth_key": () => updateDeepLAuthKey(""),
"/get/data/ctranslate2_weight_type": updateSelectedCTranslate2WeightType,
@@ -528,6 +528,8 @@ export const useReceiveRoutes = () => {
"/set/data/speaker_record_timeout": errorHandling_Backend,
"/set/data/speaker_phrase_timeout": errorHandling_Backend,
"/set/data/speaker_max_phrases": errorHandling_Backend,
"/set/data/osc_ip_address": errorHandling_Backend,
};
@@ -566,11 +568,16 @@ export const useReceiveRoutes = () => {
message: parsed_data.result.message,
data: parsed_data.result.data,
endpoint: parsed_data.endpoint,
_result: parsed_data.result,
});
} else {
handleInvalidEndpoint(parsed_data);
}
break;
case 500:
showNotification_Error(
`An error occurred. Please restart VRCT or contact the developers. ${JSON.stringify(parsed_data.result)}`, { hide_duration: null });
break;
case 348:
// console.log(`from backend: %c ${JSON.stringify(parsed_data)}`, style_348);

View File

@@ -1,8 +1,13 @@
import { Command } from "@tauri-apps/api/shell";
import { store } from "@store";
import { useReceiveRoutes } from "./useReceiveRoutes";
import {
useNotificationStatus,
} from "@logics_common";
export const useStartPython = () => {
const { receiveRoutes } = useReceiveRoutes();
const { showNotification_Success, showNotification_Error } = useNotificationStatus();
const asyncStartPython = async () => {
const command = Command.sidecar("bin/VRCT-sidecar");
@@ -16,7 +21,11 @@ export const useStartPython = () => {
console.log(error, line);
}
});
command.stderr.on("data", line => console.error("stderr:", line));
command.stderr.on("data", line => {
showNotification_Error(
`An error occurred. Please restart VRCT or contact the developers. The last line:${JSON.stringify(line)}`, { hide_duration: null });
console.error("stderr", line)
});
const backend_subprocess = await command.spawn();
store.backend_subprocess = backend_subprocess;
};

View File

@@ -132,37 +132,38 @@ export const { atomInstance: Atom_NotificationStatus, useHook: useStore_Notifica
}, "NotificationStatus");
// Main Page
// Functions
// Common
export const { atomInstance: Atom_IsMainPageCompactMode, useHook: useStore_IsMainPageCompactMode } = createAtomWithHook(false, "IsMainPageCompactMode");
// Sidebar Section
export const { atomInstance: Atom_TranslationStatus, useHook: useStore_TranslationStatus } = createAtomWithHook(false, "TranslationStatus", {is_state_ok: true});
export const { atomInstance: Atom_TranscriptionSendStatus, useHook: useStore_TranscriptionSendStatus } = createAtomWithHook(false, "TranscriptionSendStatus", {is_state_ok: true});
export const { atomInstance: Atom_TranscriptionReceiveStatus, useHook: useStore_TranscriptionReceiveStatus } = createAtomWithHook(false, "TranscriptionReceiveStatus", {is_state_ok: true});
export const { atomInstance: Atom_ForegroundStatus, useHook: useStore_ForegroundStatus } = createAtomWithHook(false, "ForegroundStatus", {is_state_ok: true});
export const { atomInstance: Atom_MessageLogs, useHook: useStore_MessageLogs } = createAtomWithHook([], "MessageLogs");
// export const { atomInstance: Atom_MessageLogs, useHook: useStore_MessageLogs } = createAtomWithHook(generateTestData(20), "MessageLogs"); // For testing
export const { atomInstance: Atom_MessageInputValue, useHook: useStore_MessageInputValue } = createAtomWithHook("", "MessageInputValue");
export const { atomInstance: Atom_IsVisibleResendButton, useHook: useStore_IsVisibleResendButton } = createAtomWithHook(false, "IsVisibleResendButton", {is_state_ok: true});
export const { atomInstance: Atom_IsAppliedInitMessageBoxHeight, useHook: useStore_IsAppliedInitMessageBoxHeight } = createAtomWithHook(false, "IsAppliedInitMessageBoxHeight");
export const { atomInstance: Atom_SelectableLanguageList, useHook: useStore_SelectableLanguageList } = createAtomWithHook([], "SelectableLanguageList");
export const { atomInstance: Atom_SelectedPresetTabNumber, useHook: useStore_SelectedPresetTabNumber } = createAtomWithHook("1", "SelectedPresetTabNumber");
export const { atomInstance: Atom_EnableMultiTranslation, useHook: useStore_EnableMultiTranslation } = createAtomWithHook(false, "EnableMultiTranslation");
export const { atomInstance: Atom_SelectedYourLanguages, useHook: useStore_SelectedYourLanguages } = createAtomWithHook({}, "SelectedYourLanguages");
export const { atomInstance: Atom_SelectedTargetLanguages, useHook: useStore_SelectedTargetLanguages } = createAtomWithHook({}, "SelectedTargetLanguages");
export const { atomInstance: Atom_TranslationEngines, useHook: useStore_TranslationEngines } = createAtomWithHook(translator_status, "TranslationEngines");
export const { atomInstance: Atom_SelectedTranslationEngines, useHook: useStore_SelectedTranslationEngines } = createAtomWithHook({1:"", 2:"", 3:""}, "SelectedTranslationEngines");
export const { atomInstance: Atom_IsOpenedTranslatorSelector, useHook: useStore_IsOpenedTranslatorSelector } = createAtomWithHook(false, "IsOpenedTranslatorSelector");
// Designs
export const { atomInstance: Atom_IsMainPageCompactMode, useHook: useStore_IsMainPageCompactMode } = createAtomWithHook(false, "IsMainPageCompactMode");
export const { atomInstance: Atom_MessageInputBoxRatio, useHook: useStore_MessageInputBoxRatio } = createAtomWithHook(20, "MessageInputBoxRatio");
// Language Selector
export const { atomInstance: Atom_IsOpenedLanguageSelector, useHook: useStore_IsOpenedLanguageSelector } = createAtomWithHook(
{ your_language: false, target_language: false, target_key: "1" },
"IsOpenedLanguageSelector"
);
export const { atomInstance: Atom_SelectableLanguageList, useHook: useStore_SelectableLanguageList } = createAtomWithHook([], "SelectableLanguageList");
// Message Container
export const { atomInstance: Atom_MessageLogs, useHook: useStore_MessageLogs } = createAtomWithHook([], "MessageLogs");
// export const { atomInstance: Atom_MessageLogs, useHook: useStore_MessageLogs } = createAtomWithHook(generateTestData(20), "MessageLogs"); // For testing
export const { atomInstance: Atom_MessageInputBoxRatio, useHook: useStore_MessageInputBoxRatio } = createAtomWithHook(20, "MessageInputBoxRatio");
export const { atomInstance: Atom_MessageInputValue, useHook: useStore_MessageInputValue } = createAtomWithHook("", "MessageInputValue");
export const { atomInstance: Atom_IsVisibleResendButton, useHook: useStore_IsVisibleResendButton } = createAtomWithHook(false, "IsVisibleResendButton", {is_state_ok: true});
// Config Page
@@ -170,8 +171,6 @@ export const { atomInstance: Atom_IsOpenedLanguageSelector, useHook: useStore_Is
export const { atomInstance: Atom_SoftwareVersion, useHook: useStore_SoftwareVersion } = createAtomWithHook("-", "SoftwareVersion");
export const { atomInstance: Atom_SelectedConfigTabId, useHook: useStore_SelectedConfigTabId } = createAtomWithHook("device", "SelectedConfigTabId");
export const { atomInstance: Atom_SettingBoxScrollPosition, useHook: useStore_SettingBoxScrollPosition } = createAtomWithHook(0, "SettingBoxScrollPosition");
// Designs
export const { atomInstance: Atom_IsOpenedDropdownMenu, useHook: useStore_IsOpenedDropdownMenu } = createAtomWithHook("", "IsOpenedDropdownMenu");
// Device
@@ -292,9 +291,9 @@ export const { atomInstance: Atom_OscPort, useHook: useStore_OscPort } = createA
export const { atomInstance: Atom_IsOpenedTranslatorSelector, useHook: useStore_IsOpenedTranslatorSelector } = createAtomWithHook(false, "IsOpenedTranslatorSelector");
// Supporters
export const { atomInstance: Atom_SupportersData, useHook: useStore_SupportersData } = createAtomWithHook(null, "SupportersData", {is_state_ok: true});
// About VRCT
export const { atomInstance: Atom_VrctPosterIndex, useHook: useStore_VrctPosterIndex } = createAtomWithHook(0, "VrctPosterIndex");
export const { atomInstance: Atom_PosterShowcaseWorldPageIndex, useHook: useStore_PosterShowcaseWorldPageIndex } = createAtomWithHook(0, "PosterShowcaseWorldPageIndex");

View File

@@ -89,6 +89,8 @@ export const whisper_weight_type_status = [
{ id: "large-v1", label: "large-v1", is_downloaded: false, progress: null },
{ id: "large-v2", label: "large-v2", is_downloaded: false, progress: null },
{ id: "large-v3", label: "large-v3", is_downloaded: false, progress: null },
{ id: "large-v3-turbo-int8", label: "large-v3-turbo-int8", is_downloaded: false, progress: null },
{ id: "large-v3-turbo", label: "large-v3-turbo", is_downloaded: false, progress: null },
];
export const supporters_data_url = "https://shiinasakamoto.github.io/vrct_supporters/assets/supporters/data.json";