# 検証報告 — 2026-10-23

## 判定

実際の動画圧縮が動作するMVP。一般公開時に「最大2GB対応」「全ブラウザ対応」と表示できる検証水準には未到達。
テスト値を実機や一般的な動画全体の性能として解釈しないこと。

## 実施環境

Linux開発コンテナ / Node.js 24.19.0 / Chromium 154.0.8037.57（headless） / Playwright Core。
WebCodecs H.264エンコーダー、H.264/AACデコーダー、OPFSの利用を確認。
スマートフォン幅のスクリーンショットはデスクトップChromiumの390×844 viewportであり、iOS/Android実機検証ではない。

## ビルド・自動テスト

- `npm run typecheck`: 成功。
- `npm test`: 5件成功。2GBのバイト境界、10進表示、削減目標の数式、音声・MP4予算、実現不能な低ビットレートの拒否、入力値の検証。
- `npm run build`: Next.jsの静的エクスポート成功。robots.txt / sitemap.xml / OGPも生成。
- `tests/browser.mjs`: 初期40%、開始ボタン無効状態、2,000,000,001バイトの拒否、50%へスライダー変更、推定表示、キャンセル、再実行、圧縮・ダウンロード、リセットを確認。
- 390px viewportで横スクロールなし。ページJavaScriptエラー0件。

## 実エンコード結果

いずれもFFmpegで生成した1280×720・30fps・H.264映像＋48kHz AAC音声のテストパターン。映像に動きがあり、音声は440Hz正弦波。実写・高精細・長時間・可変フレームレートの代替試験ではない。

| 入力 | 再生時間 | 入力バイト | 目標削減 | 出力バイト | 実削減率 | 結果 |
|---|---:|---:|---:|---:|---:|---|
| 小規模動画 | 8.02秒 | 6,088,965 | 40% | 3,615,364 | 40.6% | 成功 |
| 約100MB | 28.02秒 | 104,726,246 | 40% | 36,298,665 | 65.3% | 成功 |

100MBケースの最終ブラウザテストは、開始から出力検証完了まで約3.54秒。入力は30Mbps CBR・HRDフィラー付きの低複雑度テストパターンであり、結果が目標40%より小さくなる。実写映像の所要時間・圧縮率を示す値ではない。

### 出力の確認

- ブラウザで先頭フレームをデコードし、出力をMP4としてダウンロード。
- FFprobe: H.264/AAC、映像開始0秒、音声開始0秒。映像8.000/28.000秒、音声8.021333/28.021333秒。
- FFmpegで2ケースとも全フレーム・全音声をデコードしてエラーなし。
- AAC音声のパケットSHA-256を入力と出力で比較。小規模376パケット、100MBケース1,314パケットがすべて一致。
- 音声コピーと開始時刻・長さの確認は行ったが、人による口の動きと音声の同期評価は未実施。
- 画質はテストパターンのプレビューのみ。VMAF/SSIMや実写の主観評価は未実施。
- ピークメモリ・CPU・電池消費の測定は未実施。

### 再生成コマンド（約100MB）

```bash
ffmpeg -f lavfi -i 'testsrc2=size=1280x720:rate=30:duration=28' \
 -f lavfi -i 'sine=frequency=440:sample_rate=48000:duration=28' \
 -c:v libx264 -preset ultrafast -b:v 30000k -minrate 30000k \
 -maxrate 30000k -bufsize 60000k -x264-params nal-hrd=cbr:filler=1 \
 -c:a aac -b:a 128k -shortest work/sample-100mb.mp4
FIXTURE="$PWD/work/sample-100mb.mp4" node tests/browser.mjs
```

## 未完了の受け入れ試験

すべてのセルは実機・対象バージョン・形式別に別途実施する。— は未実施。

| ブラウザ / 実機 | 100MB | 500MB | 1GB | 1.5GB | 2GB |
|---|---|---|---|---|---|
| Chrome / PC実機 | — | — | — | — | — |
| Edge / PC実機 | — | — | — | — | — |
| Safari / macOS | — | — | — | — | — |
| Firefox / PC | — | — | — | — | — |
| iOS Safari | — | — | — | — | — |
| Android Chrome | — | — | — | — | — |
| 開発環境Chromium headless | 成功（104.7MB） | — | — | — | — |

2GBの容量境界の単体テストを、2GB動画の圧縮成功と混同しないこと。

各セルで記録する項目: OS/端末/RAM/ブラウザバージョン、入力コンテナ・映像/音声codec・解像度・FPS・再生時間・正確なバイト数、10/40/80%設定、処理秒数、OSで測ったピークメモリ、出力容量、全デコード、VMAF等と主観画質、冒頭/中間/末尾の音ズレ、キャンセル・再実行・バックグラウンド遷移・画面ロック・容量不足・破損動画・可変FPS・縦動画・HDR・4K。

## 既知の制限

AACエンコーダーを持たないブラウザでも、AAC入力のコピーと映像再エンコードなら処理できる場合がある。AAC以外の入力音声にはAACエンコーダーが必要。ブラウザ非対応時に音声を削除して成功扱いしない。
OPFSが利用できないプライベートモードなどは非対応。2GB入力を許可する仕様はメモリ・空きディスク・サンプルテーブル等の上限を保証しない。ブラウザのクラッシュ時は端末内の一時ファイルが残る可能性がある。

## サブフォルダー設置の確認（追加）

https://makon.tokyo/video-compression/ 向けbasePathビルドを、ローカルHTTPサーバーの同じサブフォルダー構造で確認。JS/CSSの404なし、利用案内への移動と戻るリンク、canonical・OGPの本番URL、ライセンス資料の取得、小規模の実動画の再圧縮とMP4ダウンロードを確認。外部ロゴとGoogleタグへの通信はこのローカルテストでは遮断しており、これらの実配信・GA受信やmakon.tokyoへの実アップロードは未確認。

## ツール一覧トップへの分離（2026年10月24日）

tools.makon.tokyo用の静的出力をローカル配信して確認。ツール一覧→動画圧縮→一覧、利用規約→一覧の往復、トップと動画圧縮ページのcanonical、サイトマップ、GAタグが各ページ1回、390px幅の横溢れなし、移動後の小規模実動画の圧縮・MP4ダウンロードを確認。内部JS/CSS・ページの404なし、JavaScriptエラーなし。外部ロゴ・Googleタグへの通信はローカルQAでは遮断。DNS・本番SSL・エックスサーバーへの実アップロードおよびGoogle側の受信は未確認。

## 画質保護の修正（2026年11月1日）

以前は容量目標から算出したビットレートが小さすぎる場合にも警告だけで実行していた。修正版は元映像のビットレート・コーデック・画素数・フレームレートを考慮し、低すぎる場合は容量削減を控えめにする。保護が適用される場合は見積もりを調整後の値へ変更する。解像度とフレームレートを自動で落とす変更はしていない。

計画の最低ビットレートは `max(80kbps, min(画素数×FPS×0.08, 元映像ビットレート×係数))`。係数はH.264等で0.85、HEVC/AV1/VP9からH.264へ変換する場合は1.25。数値は保守的なヒューリスティックであり、実測の品質保証閾値ではない。推定容量が元サイズ以上になる場合は開始せず、理由を表示する。

### 修正前後の比較

Linux / Chromium 154.0.8037.57。FFmpegで生成した1920×1080・30fps・8秒・H.264 5Mbps＋AAC 128kbps。動くテストパターンにノイズを加えた動画。入力5,117,522バイト。旧版と新版は同一環境・同一入力でブラウザ内エンコード。FFmpegで入力動画に対する全フレームのSSIMを算出した。

| 削減目標 | 旧版出力 | 旧版SSIM | 新版出力 | 新版SSIM |
|---|---:|---:|---:|---:|
| 40% | 3,036,872 B | 0.978829 | 4,314,634 B | 0.984180 |
| 80% | 2,085,093 B | 0.972014 | 4,314,634 B | 0.984180 |

新版の実削減は約15.7%。高い削減目標でも画質保護の計画を下回らないため、40%と80%で同じ出力になった。表示には「画質を優先」と説明を出し、推定も約4.4MBに変更する。出力の解像度1920×1080、フレームレート30fps、映像8秒、AAC音声の存在と全デコードを確認した。

別の1.2Mbps・1080p・8秒の低ビットレートテストでは、40%設定で旧版と新版が同じ出力となり、SSIMも0.985006で改善しなかった。どちらも元ファイルより大きくなった。エンコーダーが設定値どおりの出力量を出すとは限らないこと、すべての映像で改善を保証できないことを示す。元動画より大きい場合は従来どおり結果で警告する。

SSIMの上昇はこのテストパターンの入力に対する一致度の比較であり、実写の主観画質や利用者の動画での改善を保証しない。利用者の元動画は未入手。画質を保証する判定や無劣化圧縮にしたわけではない。

### 再現手順

```bash
ffmpeg -f lavfi -i 'testsrc2=size=1920x1080:rate=30:duration=8,noise=alls=8:allf=t+u:all_seed=123' \
 -f lavfi -i 'sine=frequency=440:sample_rate=48000:duration=8' \
 -c:v libx264 -preset fast -b:v 5000k -c:a aac -b:a 128k -shortest work/quality-high-source.mp4
FIXTURE=work/quality-high-source.mp4 node tests/quality-browser.mjs
ffmpeg -i work/quality-high-source.mp4 -i work/quality-protected-40.mp4 \
 -filter_complex '[0:v]setpts=PTS-STARTPTS[a];[1:v]setpts=PTS-STARTPTS[b];[a][b]ssim' -an -f null -
```

単体テストは9件成功。従来の上限と計算テストに加えて、低ビットレートでの保護、高ビットレートで目標を維持する分岐、低ビットレートHEVCの無理な圧縮の停止、無効なFPSの拒否を確認。
