# アーキテクチャ設計書

## 概要

本ドキュメントは、StaxRip（動画エンコーディングGUIアプリケーション）のアーキテクチャ設計について記載する。StaxRipはWindows向けの動画変換・エンコーディングツールであり、VB.NET / .NET Frameworkで構築されたWindowsフォームアプリケーションである。

## システム全体構成

### アーキテクチャ概要図

[アーキテクチャ構成図.md](./アーキテクチャ構成図.md)を参照

### システム境界と外部連携

| 外部システム | 連携方式 | 用途 |
| --- | --- | --- |
| ffmpeg | コマンドライン実行（Process） | 動画・音声のデコード、エンコード、変換処理 |
| x264/x265 | コマンドライン実行（Process） | H.264/H.265ビデオエンコーディング |
| AviSynth | DLL連携・スクリプト実行 | ビデオフィルタリング・フレームサーバー |
| VapourSynth | DLL連携・スクリプト実行 | ビデオフィルタリング・フレームサーバー |
| mkvmerge | コマンドライン実行（Process） | MKVコンテナへのマルチプレクシング |
| MP4Box | コマンドライン実行（Process） | MP4コンテナへのマルチプレクシング |
| eac3to | コマンドライン実行（Process） | 音声デコード・変換 |
| MediaInfo | DLL連携（MediaInfo.dll） | メディアファイル情報の取得 |
| qaac | コマンドライン実行（Process） | AAC音声エンコーディング |
| OpusEnc | コマンドライン実行（Process） | Opus音声エンコーディング |
| DeeZy/DEE | コマンドライン実行（Process） | Dolbyフォーマット音声エンコーディング |

## レイヤー構成

### アーキテクチャスタイル

**モノリシック型3層アーキテクチャ（レイヤードアーキテクチャ）**

StaxRipは、Windows Formsをベースとした伝統的な3層アーキテクチャを採用している。プレゼンテーション層（UI）、ビジネスロジック層（処理ロジック）、インフラストラクチャ層（外部ツール連携・ファイルI/O）で構成される。

### レイヤー定義

| レイヤー | 責務 | 主なコンポーネント |
| --- | --- | --- |
| Presentation (UI) | ユーザーインターフェース、画面表示、ユーザー入力の受付 | Forms/, UI/ ディレクトリ配下のクラス（MainForm, PreviewForm, CodeEditor, JobsForm等） |
| Application/Business | エンコーディング処理のオーケストレーション、プロジェクト管理、ジョブ管理 | GlobalClass, GlobalCommands, JobManager, Project |
| Domain | ビデオ/オーディオ処理のドメインモデル、プロファイル管理 | VideoEncoder, AudioProfile, Muxer, VideoScript, Demuxer, Package |
| Infrastructure | 外部ツール連携、ファイルシステム操作、プロセス管理 | Proc, MediaInfo, Package（外部ツール管理）, FileHelp |

### レイヤー間の依存関係ルール

1. **Presentationレイヤー → Application/Businessレイヤー**: 許可
2. **Application/Businessレイヤー → Domainレイヤー**: 許可
3. **Domainレイヤー → Infrastructureレイヤー**: 許可
4. **逆方向の依存**: GlobalClassを介したイベント駆動で間接的に許可
5. **禁止される参照**: InfrastructureからPresentationへの直接参照（グローバル変数`g.MainForm`経由での参照は例外）

## モジュール構成

### ドメイン分割

| ドメイン | 責務 | 関連モジュール |
| --- | --- | --- |
| Video | ビデオエンコーディング・フィルタリング | VideoEncoder, VideoScript, VideoFilter, VideoRenderer |
| Audio | オーディオ処理・エンコーディング | Audio, AudioProfile, GUIAudioProfile, NullAudioProfile |
| Muxing | コンテナマルチプレクシング | Muxer, MkvMuxer, MP4Muxer, ffmpegMuxer, WebMMuxer |
| Demuxing | ストリーム抽出・デマルチプレクシング | Demuxer, mkvDemuxer, ffmpegDemuxer, MP4BoxDemuxer, eac3toDemuxer |
| Project | プロジェクト設定・永続化 | Project, Job, JobManager |
| Scripting | フレームサーバースクリプト | VideoScript, TargetVideoScript, SourceVideoScript, VideoFilter |
| Package | 外部ツール管理 | Package, PluginPackage |

### パッケージ構造

```
Source/
├── Encoding/
│   ├── VideoEncoder.vb           # ビデオエンコーダー基底クラス
│   └── VideoEncoderCommandLine.vb # コマンドラインエンコーダー
├── Forms/
│   ├── MainForm.vb              # メインウィンドウ
│   ├── MainForm_*.vb            # メインフォームの部分クラス
│   ├── PreviewForm.vb           # プレビューフォーム
│   ├── ProcessingForm.vb        # 処理中フォーム
│   ├── JobsForm.vb              # ジョブ管理フォーム
│   ├── CodeEditor.vb            # スクリプトエディタ
│   ├── CropForm.vb              # クロップ設定
│   ├── AudioForm.vb             # オーディオ設定
│   ├── MuxerForm.vb             # Muxer設定
│   └── ...
├── General/
│   ├── GlobalClass.vb           # グローバル状態・イベント管理
│   ├── GlobalCommands.vb        # グローバルコマンド
│   ├── Project.vb               # プロジェクトモデル
│   ├── JobManager.vb            # ジョブ管理
│   ├── Audio.vb                 # オーディオ処理
│   ├── AudioProfile.vb          # オーディオプロファイル
│   ├── Demux.vb                 # デマックス処理
│   ├── Muxer.vb                 # マックス処理
│   ├── Package.vb               # 外部ツールパッケージ管理
│   ├── Macro.vb                 # マクロ展開
│   ├── Help.vb                  # ヘルパー関数
│   ├── Extensions.vb            # 拡張メソッド
│   └── ...
├── UI/
│   ├── Controls/                # カスタムUIコントロール
│   ├── Criteria/                # 条件設定UI
│   ├── Templates/               # UIテンプレート
│   ├── Theme.vb                 # テーマ管理
│   ├── ThemeManager.vb          # テーママネージャー
│   ├── Menu.vb                  # メニュー
│   └── ...
├── Video/
│   ├── VideoScript.vb           # ビデオスクリプト（AviSynth/VapourSynth）
│   ├── FrameServer.vb           # フレームサーバー連携
│   ├── VideoRenderer.vb         # ビデオレンダラー
│   └── ...
└── Tools/
    └── AutoCrop/                # 自動クロップツール
```

### コンポーネント依存関係

```
MainForm
    ├── GlobalClass (g)
    │   ├── Project (p)
    │   │   ├── VideoEncoder
    │   │   │   └── Muxer
    │   │   ├── VideoScript
    │   │   │   └── VideoFilter[]
    │   │   ├── AudioProfile[]
    │   │   └── Demuxer
    │   └── JobManager
    │       └── Job[]
    └── Package (外部ツール群)
        ├── ffmpeg
        ├── mkvmerge
        ├── MP4Box
        ├── eac3to
        └── ...
```

## ミドルウェア構成

### データベース

| 種類 | ミドルウェア | バージョン | 用途 |
| --- | --- | --- | --- |
| シリアライズ | BinaryFormatter | .NET標準 | プロジェクト設定・ジョブリストの永続化 |
| ファイル | .srip（バイナリ） | N/A | プロジェクトファイル形式 |
| 設定 | レジストリ/ファイル | N/A | アプリケーション設定の永続化 |

### キャッシュ

| ミドルウェア | バージョン | 用途 | TTL |
| --- | --- | --- | --- |
| インメモリキャッシュ | N/A | フレームサーバー情報（ServerInfo）キャッシュ | セッション中有効 |
| ファイルキャッシュ | N/A | インデックスファイル（.ffindex, .lwi等） | 永続 |

### メッセージキュー

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| N/A | N/A | メッセージキューは使用していない。ジョブはシリアルファイル（Jobs.dat）で管理 |

### 検索エンジン

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| N/A | N/A | 検索エンジンは使用していない |

### その他ミドルウェア

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| MediaInfo.dll | 動的リンク | メディアファイルのメタ情報取得 |
| PowerShell | システム | スクリプト実行・ツール連携 |
| AviSynth.dll | プラグイン | フレームサーバー・ビデオフィルタリング |
| VapourSynth | Python | フレームサーバー・ビデオフィルタリング |

## データフロー

### リクエスト処理の流れ

**ソースファイル読み込みフロー**

1. ユーザーがMainFormでソースファイルを選択
2. GlobalClass.MainFormがSourceファイルパスをProject(p)に設定
3. MediaInfoでソースファイル情報を取得
4. VideoScriptがSource filterを生成（AviSynth/VapourSynth）
5. フレームサーバーを介してプレビュー用フレームを取得
6. MainFormにプレビュー表示・各種設定UIを更新

**エンコーディング実行フロー**

1. ユーザーがエンコード開始を指示
2. ProcessingFormが表示され、処理を開始
3. Demuxer.Demux()でソースからストリーム抽出
4. Audio.Process()で各オーディオトラックを処理
5. VideoEncoder.Encode()でビデオエンコーディング
6. Muxer.Mux()で出力コンテナにマルチプレクシング
7. 処理完了後、ログを出力しUIを更新

### 非同期処理の流れ

**ジョブキュー処理**

1. ユーザーがジョブをJobManagerに追加（AddJob）
2. Jobs.datにシリアライズして永続化
3. ジョブ処理開始時、アクティブジョブをイテレート
4. 各ジョブのProjectファイル（.srip）を読み込み
5. エンコーディングフローを順次実行
6. 完了後、GlobalClass.RaiseAppEvent()でイベント発火

### データ永続化の流れ

**プロジェクト保存**

1. Project(p)オブジェクトをBinaryFormatterでシリアライズ
2. .sripファイルとしてTempDirに保存
3. ジョブとしてJobManagerに登録される場合、Jobs.datも更新

**設定保存**

1. アプリケーション設定（Settings）をシリアライズ
2. ユーザーのAppDataフォルダ配下に保存

## 横断的関心事

### 認証・認可

| 方式 | 実装箇所 | 対象 |
| --- | --- | --- |
| N/A | N/A | 認証・認可機能は実装されていない（スタンドアロンデスクトップアプリ） |
| 管理者権限チェック | GlobalClass.IsAdmin | 特定の操作（レジストリ書き込み等）に使用 |

### ロギング・監査

| 種類 | 実装方式 | 保存先 |
| --- | --- | --- |
| アプリケーションログ | LogBuilder, Log.Write() | テンポラリディレクトリ内の.logファイル |
| 処理ログ | Proc.WriteLog() | 各エンコーディング処理のログに追記 |
| エラーログ | 例外キャッチ + ログ出力 | 同上 |

### エラーハンドリング

**エラーハンドリングの方針**

- カスタム例外クラス（AbortException, ErrorAbortException）による処理中断制御
- Try-Catch による例外捕捉とユーザーへの通知
- g.ShowException() でGUI上にエラー表示

| エラー種別 | ハンドリング方式 | レスポンス |
| --- | --- | --- |
| AbortException | 処理中断（通常終了扱い） | 処理を停止し、UIを初期状態に戻す |
| ErrorAbortException | エラーダイアログ表示後中断 | ユーザーにエラーメッセージを表示し、処理を停止 |
| 一般例外 | g.ShowException() | スタックトレース付きエラーダイアログを表示 |
| 外部プロセスエラー | Proc.AllowedExitCodes チェック | 許可されていない終了コードの場合、エラーとして処理 |

### トランザクション管理

| 範囲 | 管理方式 | 分離レベル |
| --- | --- | --- |
| ファイル操作 | 明示的なロック（FileShare.None） | 排他ロック |
| Jobs.dat | リトライ機構付きファイルロック | 排他ロック（最大10回リトライ） |
| プロジェクト保存 | 一括書き込み | N/A（ファイル単位） |

## 設計原則・コーディング規約

### 適用している設計原則

| 原則 | 適用箇所 | 実装例 |
| --- | --- | --- |
| 継承による多態性 | VideoEncoder, Muxer, AudioProfile | 各種エンコーダー・Muxerが基底クラスを継承 |
| プロファイルパターン | Profile基底クラス | VideoEncoder, Muxer, AudioProfileが継承 |
| シングルトン的グローバル状態 | GlobalClass (g), Project (p) | アプリ全体で共有される状態管理 |
| イベント駆動 | GlobalClass.RaiseAppEvent() | AfterJobAdded, AfterJobProcessed等のイベント |
| ストラテジーパターン | VideoEncoder, Muxer, Demuxer | 具象クラスで処理アルゴリズムを切り替え |
| テンプレートメソッドパターン | VideoEncoder.Encode(), Muxer.Mux() | 基底クラスでフローを定義、派生クラスで詳細実装 |

### コーディング規約

1. **命名規則**:
   - クラス名: PascalCase
   - メソッド名: PascalCase
   - プロパティ名: PascalCase
   - ローカル変数: camelCase
   - グローバル変数: 小文字略称（g, p, s）

2. **ファイル構成**:
   - 1クラス1ファイルを基本とするが、関連クラスは同一ファイルに配置
   - Partial Classでフォームの機能を分割（MainForm_*.vb）

3. **シリアライズ**:
   - `<Serializable()>` 属性を永続化対象クラスに付与
   - `<NonSerialized()>` 属性で一時データを除外

4. **エラーハンドリング**:
   - 外部プロセス実行はProcクラスでラップ
   - ユーザー起因の中断はAbortExceptionを使用

## 備考

1. **レガシー要素**: BinaryFormatterによるシリアライズはセキュリティリスクがあり、.NET 5以降では非推奨。将来的にはJSON/XMLシリアライズへの移行が推奨される。

2. **外部依存性**: 多数の外部ツール（ffmpeg, x264/x265, mkvmerge等）に依存しており、Packageクラスでバージョン管理・パス解決を行っている。

3. **フレームサーバー**: AviSynthとVapourSynthの両方をサポートし、VideoScriptクラスで抽象化している。

4. **拡張性**: 新しいエンコーダーやMuxerを追加する場合は、対応する基底クラスを継承し、必要なメソッドをオーバーライドする設計になっている。
