8.4 KiB
8.4 KiB
詳細設計書
この文書は主要クラス・関数の詳細、データ構造、例外ケース、スレッドの振る舞いを記載する。
目次
- Model
- Controller
- Main (mainloop)
- DeviceManager
- Utils
- Clipboard(クリップボード機能)
- Telemetry(テレメトリ機能)
- モデルの重みダウンロードと整合性
Model
- シングルトン:
model = Model() - 遅延初期化:
init()とensure_initialized()を備え、init は重いリソース(Overlay, Translator, Watchdog, OSC ハンドラ等)を構築する。 - 主な責務
- 翻訳/文字起こし関連の起動停止ラッパ
- Overlay/OSChandler/WebSocket の操作
- キーワード検出(flashtext)と重複検出
- VRAM エラー検出とフォールバック
- クリップボード操作(copy/paste)
- テレメトリ初期化・シャットダウン
- 重要属性(抜粋)
translator: Translator インスタンスoverlay/overlay_image: Overlay 系mic_*,speaker_*: 録音、トランスクリプタ、energy recorderwatchdog: Watchdogosc_handler,websocket_serverclipboard: Clipboard インスタンス(2026-01-11 追加)telemetry: テレメトリシステム(2026-01-11 追加)
- スレッド制御
- threadFnc を用いて周期処理を回す。stop/pause/resume が可能。
- Clipboard の VR 監視スレッドはデーモンスレッド(アプリ終了時に強制停止可能)
Controller
- GUI からの要求を受け、Model を操作して結果を run() コールバックへ返す。
- 各種設定変更 (/set/ や /get/ エンドポイント) を実装。
- 翻訳/文字起こし/オーバーレイ連携ロジックを持ち、メッセージ整形(messageFormatter)や OSC の送信を行う。
- ダウンロード作業は別スレッドで行い、進捗を run_mapping を通して通知。
- クリップボード/テレメトリ制御エンドポイント追加(2026-01-11)
getClipboard()/setEnableClipboard()/setDisableClipboard()getTelemetry()/setEnableTelemetry()/setDisableTelemetry()
Main (mainloop.Main)
- stdin を readline() で受け取り JSON を parse、endpoint と data をキューへ投入。
- worker_count 個の handler スレッドが queue を取り出し
_call_handlerを実行。 - endpoint ロック正規化:
/set/enable/...と/set/disable/...は同じ正規化キー/lock/set/...を共有して排他制御。 - エラーレスポンスの標準化と再試行ロジック(status==423 は再キュー化)。
DeviceManager
- シングルトン。初期化は軽量で、
init()により内部構造をセット、実デバイスはupdate()で取得。 - Windows 環境では COM イベント (pycaw/MMNotificationClient) を用いた検出か、PyAudio によるポーリングでデバイス一覧を構成。
- コールバック設計: 変更検出時に Controller のコールバックを呼び出して UI 更新を促す。
Utils
validateDictStructure(data, structure): JSON 構造検証。getComputeDeviceList()/getBestComputeType(): CPU/CUDA を列挙し、推奨 compute_type を返す。setupLogger()/printLog()/printResponse()/errorLogging(): ログ、標準出力の整形、エラー記録。- ネットワーク/ソケット/IP アドレス検査ユーティリティ。
Clipboard(クリップボード機能)
概要(2026-01-11 追加)
VRChat 内でのテキスト送信効率向上のため、翻訳結果をクリップボードにコピーし、自動ペースト機能を提供。
設計
- シングルトン:
models.clipboard.clipboard.Clipboardクラス - 初期化:
Model.__init__()でself.clipboard = Clipboard()インスタンス化 - VR監視スレッド: デーモンスレッドで 10 秒間隔 SteamVR 監視、VRChat アプリ名を自動検出
- コピー・ペースト:
setCopyToClipboard(text: str) -> bool: 複数バックエンド対応(Windows clip、pyperclip、tkinter)setPasteFromClipboard() -> bool: PyAutoGUI による Ctrl+V 送信、VRChat ウィンドウ自動フォーカス
依存ライブラリ
pyautogui==0.9.54: キー入力シミュレーション(requirements.txt 追加)openvr: VR アプリ名検出psutil: プロセス検索pyperclip(オプション): クリップボード操作フォールバック
設定・制御
config.ENABLE_CLIPBOARD: True/False で機能制御- Controller エンドポイント
/get/data/clipboard: 状態取得(config.ENABLE_CLIPBOARDの値)/set/enable/clipboard:config.ENABLE_CLIPBOARDを True に設定/set/disable/clipboard:config.ENABLE_CLIPBOARDを False に設定
動作フロー
- Model 初期化時に Clipboard インスタンス生成(VR 監視スレッド起動)
- Controller が
config.ENABLE_CLIPBOARD == Trueをチェック - 有効時のみ
model.setCopyToClipboard(result)とmodel.setPasteFromClipboard()を呼び出し - Clipboard インスタンス自体は常に稼働(
clipboard.is_enabledは常に True)
エラーハンドリング
- コピー失敗: False を返却、リトライなし
- ペースト失敗: False を返却
- VR アプリ名検出失敗: app_name = None、現在フォーカスウィンドウにペースト
- 例外はログ出力し握りつぶし
Telemetry(テレメトリ機能)
概要(2026-01-11 追加)
Aptabase を用いた匿名な使用状況データ収集。デフォルト有効、ユーザー制御可能。
設計
- デフォルト有効:
config.ENABLE_TELEMETRY = True - 初期化:
model.telemetryInit(enabled=config.ENABLE_TELEMETRY, app_version=config.VERSION) - シャットダウン:
model.telemetryShutdown()で app_closed イベント送信 - プライバシー重視: 個人情報・入力内容・音声データ一切送信なし
イベント種別(送信固定)
app_started: アプリ起動app_closed: アプリ終了(最後のイベント)core_feature: 機能開始(translation / mic_speech_to_text / speaker_speech_to_text / text_input)
動作フロー
- アプリ起動時に telemetryInit() 呼び出し
- 機能開始時に track_core_feature() で 1 セッション 1 回のみ送信
- アプリ終了時に telemetryShutdown() で app_closed 送信
- config.ENABLE_TELEMETRY = False で一切の通信・スレッド停止
設定・制御
config.ENABLE_TELEMETRY: True/False で機能制御model.telemetry.enabled: 現在の有効状態- Controller エンドポイント
/get/data/telemetry: 状態取得/set/enable/telemetry: 有効化(telemetryInit 呼び出し)/set/disable/telemetry: 無効化(telemetryShutdown 呼び出し)
エラーハンドリング
- API 通信失敗時: 例外握りつぶし、アプリ動作に影響なし
- オフライン時: 機能停止のみ、再送・バッファリングなし
- 無効化時: 一切の通信・スレッド・処理停止
- Aptabase SDK ログ: CRITICAL レベルのみに制限(ノイズ削減)
モデル重みダウンロード
models.translation.translation_utilsとmodels.transcription.transcription_whisperにダウンロード/チェック関数があり、チェックサムやファイル存在を検証する。- GUI からの要求は Controller により非同期スレッドで実行され、進捗コールバックが run_mapping を介してフロントエンドに渡る。
エッジケース / 例外処理
- 外部 API のレート制限や認証エラーは呼び出し元に 400 系のレスポンスを返し、必要であればフォールバック実装(CTranslate2 への切替)を行う。
- 大きなモデル実行時の VRAM エラーは検出し、当該機能を無効化してユーザへ通知する。
- 音声デバイスが存在しない場合は NoDevice を返し、UI 側で扱う。
テスト観点
- メッセージ受信/送信のエンドツーエンド: stdin -> handler -> Controller -> Model -> printResponse の流れ。
- デバイス挙動: DeviceManager.update() がデバイス一覧を取得できるか(PyAudio 経由)。
- モデルダウンロード: ダウンロード成功・失敗、チェックサム検証。
- ログ/エラー: errorLogging() による例外トレースが error.log に記録されるか。