# 機能設計書 4-mkvextract Demux

## 概要

本ドキュメントは、StaxRipアプリケーションにおけるmkvextract Demux機能の設計仕様を記述する。MKV（Matroska）およびWebMコンテナからビデオ、オーディオ、字幕、チャプター、添付ファイル、タグを抽出する機能である。

### 本機能の処理概要

**業務上の目的・背景**：MKV形式は複数のストリーム（ビデオ、オーディオ、字幕）を格納できる汎用コンテナ形式である。エンコード作業では、これらのストリームを個別に抽出（Demux）し、再エンコードや編集を行う必要がある。本機能はmkvtoolnix（mkvextract/mkvmerge）を使用して、効率的かつ品質を損なわずにストリーム抽出を実現する。

**機能の利用シーン**：
- MKVファイルからビデオストリームを抽出してエンコード
- MKVファイルから複数オーディオトラックを個別抽出
- MKVファイルから字幕を抽出
- MKVファイルからチャプター情報を抽出
- MKVファイルから添付ファイル（フォント等）を抽出
- MKVファイルからタグ情報を抽出

**主要な処理内容**：
1. mkvmerge --identifyでストリーム情報取得
2. StreamDemuxFormダイアログでストリーム選択
3. mkvextract tracksでビデオ/オーディオ/字幕抽出
4. mkvextract chaptersでチャプター抽出（XML/OGG形式）
5. mkvextract timestamps_v2でタイムスタンプ抽出
6. mkvextract attachmentsで添付ファイル抽出
7. mkvextract tagsでタグ抽出

**関連システム・外部連携**：
- mkvtoolnix（mkvextract/mkvmerge）：MKVストリーム抽出
- MediaInfo：メディア情報取得
- ffmpeg：フォールバック用Demux処理

**権限による制御**：特になし。ファイルシステムへの読み書きアクセス権が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | MainForm | 主画面 | Demux処理の起動 |
| - | StreamDemuxForm | ストリーム選択 | 抽出対象ストリームの選択UI |

## 機能種別

Demux処理 / ストリーム抽出

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| sourceFile | String | Yes | MKV/WebMファイルパス | 拡張子チェック（mkv, webm） |
| demuxVideo | Boolean | No | ビデオ抽出有無 | - |
| demuxAudio | DemuxMode | No | オーディオ抽出モード | - |
| demuxChapters | Boolean | No | チャプター抽出有無 | - |
| demuxAttachments | Boolean | No | 添付ファイル抽出有無 | - |
| demuxTags | Boolean | No | タグ抽出有無 | - |

### 入力データソース

- ソースファイル：プロジェクトのSourceFile
- 設定：Project設定（DemuxVideo、DemuxAudio、DemuxChapters等）

### 対応入力形式

- MKV（Matroska Video）
- WebM

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ビデオストリーム | File | .h264/.h265/.hevc/.avi/.mpg等 |
| オーディオストリーム | File | .aac/.ac3/.dts/.flac/.opus等 |
| 字幕ストリーム | File | .srt/.ass/.sup/.mks等 |
| チャプター（XML） | File | _chapters.xml |
| チャプター（OGG） | File | _chapters.txt |
| タイムスタンプ | File | _timestamps.txt |
| 添付ファイル | File | attachment_*.ttf等 |
| タグ | File | _tags.xml |

### 出力先

- プロジェクト一時ディレクトリ（proj.TempDir）

## 処理フロー

### 処理シーケンス

```
1. mkvmerge --identify実行
   └─ ストリーム情報、添付ファイル情報取得
2. StreamDemuxForm表示（Dialog時）
   └─ ストリーム選択
3. Demux実行
   └─ mkvextract tracks（ビデオ/オーディオ/字幕）
4. チャプター抽出
   └─ mkvextract chapters（XML/OGG形式）
5. タイムスタンプ抽出
   └─ mkvextract timestamps_v2（VFR時）
6. 添付ファイル抽出
   └─ mkvextract attachments
7. タグ抽出
   └─ mkvextract tags
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[mkvmerge --identify]
    B --> C{Dialog表示?}
    C -->|Yes| D[StreamDemuxForm]
    C -->|No| E[自動選択]
    D --> F{OK?}
    F -->|No| G[Abort]
    F -->|Yes| H[Demux設定確定]
    E --> H
    H --> I[mkvextract tracks]
    I --> J{チャプター抽出?}
    J -->|Yes| K[mkvextract chapters]
    J -->|No| L{VFR/Always?}
    K --> L
    L -->|Yes| M[mkvextract timestamps_v2]
    L -->|No| N{添付抽出?}
    M --> N
    N -->|Yes| O[mkvextract attachments]
    N -->|No| P{タグ抽出?}
    O --> P
    P -->|Yes| Q[mkvextract tags]
    P -->|No| R[終了]
    Q --> R
    G --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 入力形式制限 | mkv、webm拡張子のみ対応 | 常時 |
| BR-002 | VFRタイムスタンプ | VFRファイルはタイムスタンプ抽出を推奨 | FrameRate_Mode="VFR" |
| BR-003 | フォールバック | mkvextract失敗時はffmpegでリトライ | オーディオ抽出失敗時 |
| BR-004 | BPSタグ除外 | タグ抽出時にBPSタグノードを除外 | タグ抽出時 |

### 計算ロジック

- 添付ファイルパス：cover系はプレフィックスなし、それ以外はattachment_プレフィックス

## データベース操作仕様

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E-001 | UnsupportedFormat | 非対応ファイル形式 | エラーログ出力 |
| E-002 | NoVideoStream | ビデオストリームなし | スキップ |
| E-003 | ExtractFailed | mkvextract失敗 | ffmpegでフォールバック |
| E-004 | DialogCancel | ダイアログキャンセル | AbortException |

### リトライ仕様

- オーディオ抽出失敗時：ffmpegDemuxer.DemuxAudio()でリトライ

## トランザクション仕様

本機能はトランザクション管理を行わない。

## パフォーマンス要件

- ストリーム抽出：ファイルサイズに依存
- mkvmerge --identify：数秒以内

## セキュリティ考慮事項

- ファイルパスのエスケープ処理
- 一時ディレクトリへの書き込み権限確認

## 備考

- mkvtoolnix終了コード0,1,2を許容（警告含む正常終了）
- m4a拡張子はaacとして抽出
- mks字幕はmkvmergeで抽出（mkvextract非対応のため）

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

mkvDemuxerクラスとその継承関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Demux.vb | `Source/General/Demux.vb` | Demuxer基底クラス（7-108行目） |
| 1-2 | Demux.vb | `Source/General/Demux.vb` | mkvDemuxerクラス（711-1024行目） |

**読解のコツ**: VB.NETのMustInheritはabstract、OverridesはoverrideのC#相当。

#### Step 2: エントリーポイントを理解する

mkvDemuxerのRunメソッドを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Demux.vb | `Source/General/Demux.vb` | mkvDemuxer.Run（721-842行目） |

**主要処理フロー**:
1. **724行目**: mkvmerge --identifyでストリーム情報取得
2. **733-744行目**: StreamDemuxFormダイアログ表示（条件付き）
3. **754行目**: Demux()メソッド呼び出し
4. **756-780行目**: チャプター抽出（XML/OGG）
5. **782-797行目**: タイムスタンプ抽出
6. **799-815行目**: 添付ファイル抽出
7. **817-839行目**: タグ抽出

#### Step 3: Demux処理詳細を理解する

Demux共通メソッドの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Demux.vb | `Source/General/Demux.vb` | mkvDemuxer.Demux（852-995行目） |

**主要処理フロー**:
- **876行目**: コマンドライン引数構築開始
- **880-897行目**: ビデオストリーム抽出引数
- **899-943行目**: 字幕ストリーム抽出引数
- **945-963行目**: オーディオストリーム抽出引数
- **969-979行目**: mkvextract実行

#### Step 4: 添付ファイル/タグ処理を理解する

添付ファイルとタグの処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Demux.vb | `Source/General/Demux.vb` | GetAttachments（1003-1017行目） |
| 4-2 | Demux.vb | `Source/General/Demux.vb` | GetAttachmentPath（997-1001行目） |

### プログラム呼び出し階層図

```
mkvDemuxer.Run(proj)
    │
    ├─ ProcessHelp.GetConsoleOutput(mkvmerge --identify)
    │
    ├─ StreamDemuxForm.ShowDialog() [条件付き]
    │
    ├─ mkvDemuxer.Demux()
    │      │
    │      ├─ mkvmerge --identify [ビデオID取得]
    │      │
    │      ├─ mkvextract tracks [ビデオ/オーディオ/字幕]
    │      │
    │      └─ ffmpegDemuxer.DemuxAudio() [フォールバック]
    │
    ├─ mkvextract chapters [XML/OGG]
    │
    ├─ mkvextract timestamps_v2 [VFR時]
    │
    ├─ mkvextract attachments
    │
    └─ mkvextract tags
```

### データフロー図

```
[入力]                      [処理]                        [出力]

MKV/WebMファイル ────▶ mkvmerge --identify
                              │
                              ▼
                     ストリーム情報解析
                              │
                              ▼
                     StreamDemuxForm（選択）
                              │
                              ▼
                     mkvextract tracks ──────────▶ .h264/.h265/.aac/.srt等
                              │
                              ▼
                     mkvextract chapters ────────▶ _chapters.xml/_chapters.txt
                              │
                              ▼
                     mkvextract timestamps_v2 ──▶ _timestamps.txt
                              │
                              ▼
                     mkvextract attachments ────▶ attachment_*.ttf
                              │
                              ▼
                     mkvextract tags ────────────▶ _tags.xml
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Demux.vb | `Source/General/Demux.vb` | ソース | mkvDemuxerクラス定義（711-1024行目） |
| StreamDemuxForm.vb | `Source/Forms/StreamDemuxForm.vb` | ソース | ストリーム選択ダイアログ |
| Package.vb | `Source/General/Package.vb` | ソース | mkvextract/mkvmergeパッケージ定義 |
| Misc.vb | `Source/General/Misc.vb` | ソース | MediaInfoクラス |
