WebサイトにアップロードしたMP4の再生開始が遅いときは、FFmpegのフラグ1つ(-movflags +faststart)で直せます。サーバーやプレーヤーによっては、ファイルの大部分または全体をダウンロードし終えるまで再生が始まらないこともあります。短いクリップは問題なくても、長いものは最初の1フレームが出るまで読み込み中のままになり、シークも不安定になります。原因のほとんどは、ファイル末尾にあるmoovアトムです。
1. moovアトムと、なぜ位置が重要か
MP4(およびMOV)ファイルは「atom(box とも呼ぶ)」の集まりです。中でも重要なのが moovアトム で、各フレームの位置・長さ・コーデック・シーク方法をプレーヤーに伝える索引です。moovアトムを読まなければ、プレーヤーはメディアデータを解釈できません。
moovアトムが置かれる場所は2通りあります。
- ファイル末尾(FFmpegの既定)。エンコーダは完了するまで最終的な配置がわからないため、索引を最後に書きます。
- ファイル先頭(faststart)。索引がメディアより前にあるため、索引と最初のフレームのデータが届けば再生を開始できます。
ローカル再生では問題になりません。プレーヤーはファイルのどの部分でもすぐに読めるためです。Webでは、再生開始が遅くなるよくある原因になります。
2. 1行で済む修正
次の1行で直せます。再エンコードはせず、画質も変わりません。
ffmpeg -i input.mp4 -c copy -movflags +faststart output.mp4
-c copy… ストリームをそのままコピーするので数秒で完了、画質劣化ゼロ。-movflags +faststart… mux後に追加のパスでmoovアトムを先頭へ移動する。
出力はWebで再生開始が速くなり、ダウンロード中のシークにも対応します。
3. なぜ位置がWeb再生を壊すのか
違いは、ファイルがどう配信されるかにあります。
| シナリオ | ファイルの読まれ方 | faststartが必要か |
|---|---|---|
| ローカル再生(ダブルクリック) | 任意のバイトへランダムアクセス | 不要 |
| Webプログレッシブダウンロード | 先頭から順にバイトが届く | 必要 |
| HTTP疑似ストリーミング | URL で指定した開始時刻(?start=)からサーバーが送る |
推奨(なくてもサーバーが moov を先頭に組み直して送れるが、そのたびに負荷がかかる) |
| HLS/DASHセグメント | 小さなセグメントごとの索引 | 通常はパッケージャが処理 |
ブラウザがHTTP経由でMP4を再生するときは、先頭から読み込みます。moovアトムが末尾にあると、プレーヤーはまず索引を探す必要があり、取得のために追加のHTTP範囲要求を出すことがあります。サーバーやプレーヤーによっては、ファイルの大部分または全体を取得し終えるまで再生を開始できません。faststartなら索引が先頭にあるため、再生もシークもほぼすぐに始まります。これがプログレッシブダウンロードです。
4. ファイルにすでにfaststartが適用済みか確認する
再処理の前に、moovアトムの位置を確認します。ffprobe でアトムの順序を表示できます。
ffprobe -v trace input.mp4 2>&1 | grep "parent:'root'"
ファイル直下のアトムが先頭から順に表示されます。Windowsのコマンドプロンプトや PowerShell では、grep "parent:'root'" の代わりに findstr "parent:'root'" を使います。moov が mdat の前にあればfaststart適用済みです。moov が mdat の後にあれば、第2章の修正が必要です。
5. faststartが必要なケースと不要なケース
faststartを付けるべき場合:
- MP4をWebサイトやCDNから配信し、ブラウザ内で再生する。
- ダウンロード完了前に視聴を開始させたい。
- ダウンロード中にシーク(タイムラインのスクラブ)を動かしたい。
省略してよい場合:
- ローカル再生のみ(デスクトッププレーヤー、NAS、編集)。
- HLS/DASHのアダプティブストリーミングで配信する(セグメンタが索引を処理する)。
- これから再処理する中間ファイル。
Web配信で迷ったら付けておいてください。コストは小さく、害もありません。
6. 再エンコード時にfaststartを適用する
圧縮や変換などで再エンコードする場合は、そのコマンドにフラグを付ければ2回目の実行は不要です。
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac -movflags +faststart output.mp4
H.264/AACにエンコードしつつ、moovアトムを先頭に書き込みます。ファイルを書き直す追加パスの分だけ時間は増えますが、エンコード時間に比べれば小さく済みます。
7. トラブルシューティング
問題1: フラグを付けたのにストリーミングできない
原因: MP4/MOV以外のコンテナで保存し直しています(faststartはMOV/MP4 muxerにのみ適用されます)。
解決策: 出力拡張子が .mp4 か .mov であることを確認します。MKVやWebMにはfaststartは効きません。
問題2: コマンドは動くが想定より時間がかかる
原因: faststartはアトムを移動するためファイルを書き直す必要があり、FFmpegが出力に追加パスを行います。
解決策: 正常です。大きいファイルでは追加パスで多少時間が増えますが、-c copy と併用すれば再エンコードはしません。
問題3: 元ファイル再生時に「moov atom not found」
原因: ソースが途中で切れた、または最終化されていない(録画の中断など)ため、使える索引がありません。 解決策: これは位置ではなく、moovアトムの欠損/破損という別問題です。復旧方法はmoovアトムのガイドを参照してください。
問題4: ダウンロード中のシークが飛ぶ・止まる
原因: プレーヤーまたはサーバーがHTTP範囲要求に対応していません。
解決策: サーバーが Accept-Ranges: bytes を返すことを確認します。faststartは索引を先頭に置いて、再生を早く始められるようにするだけです。まだダウンロードしていない位置へ飛ぶには、サーバーが範囲要求を許可している必要があります。
よくある質問
Q1. faststartで画質は落ちる?ファイルは変わる?
A. 画質は落ちません。-c copy 併用なら音声・映像のビットストリームはそのままです。ファイルとしては、アトムの並び順と、索引に記録された位置情報(オフセット)が書き換わります。
Q2. なぜFFmpegは既定でこれをしない? A. エンコーダは完了するまで最終サイズと配置がわからないため、索引を最後に書くのが自然な既定です。faststartは並べ替えのために追加パスを行います。
Q3. 短いクリップは再生できるのに長いものはできません。なぜ? A. 短いクリップは末尾のmoovアトムもほぼ即座に届くほど速くダウンロードできます。長いファイルはダウンロードに時間がかかるため、遅延が目立ちます。faststartは両方を直します。
Q4. MOVファイルでも効きますか?
A. はい。faststartはMOV/MP4 muxerの機能なので、.mov 出力でも効きます。
Q5. HLS/DASHを使っています。それでも必要? A. 通常は不要です。アダプティブストリーミングはメディアを索引付きの小さなセグメントに分割するので、索引付けはパッケージャ(セグメンタ)が処理します。