動画ファイルは正常にアップロードされている。エラーも出ていない。それなのに——
- 再生ボタンを押しても反応がない
- ぐるぐる読み込みのまま止まる
- モバイルだけ再生されない
こんな不可解な現象に遭遇したことはないでしょうか。
筆者は個人開発で動画共有機能を実装した際、まさにこの問題に直面しました。GoのバックエンドからFFmpegで動画を変換し、S3にアップロード。PCのChromeでは問題なく再生できたのに、iPhoneのSafariでは「再生ボタンを押しても何も起きない」という報告が相次ぎました。
原因を調査した結果、たどり着いたのは コーデックでもネットワークでもなく、動画ファイルの内部構造でした。そして、その解決策がFFmpegの +faststart オプションです。
本記事では、この問題の根本原因であるmoovアトムの仕組みから、確実に再生問題を防ぐ方法までを解説します。
再生されない動画に共通する特徴#
まず、筆者が経験した症状も含め、よくあるパターンを整理します。
- ローカルでは再生できるが、Web上では再生されない
- アップロード後、途中まで待てば再生できる
- SafariやiOSだけ再生されない
- シークバーを動かすと止まる
このタイプの不具合は、
ファイルの先頭に再生に必要な情報が存在しない
ことがほぼ原因です。
ここで重要になるのが、動画ファイル内部にある「moovアトム」という概念です。
moovアトムとは何か#

上:moovアトムが末尾にあり、再生情報を取得するまで待たされる構造。
下:faststart適用後、moovアトムが先頭にあり、読み込みながら即再生できる構造。
MP4やMOVファイルは、単なる映像データの塊ではありません。内部には複数のチャンク(アトム)があり、その中で最も重要なのが moov です。
moov には、以下の再生開始に必須の情報がすべて格納されています。
- 動画の再生時間
- トラック構成(映像・音声の分離情報)
- 各フレームの位置情報(どこから何バイト目に何番目のフレームがあるか)
問題は、
多くのエンコーダでは、この
moovがファイルの末尾に配置される
という点です。
エンコーダは動画を先頭から順に書き出していくため、全フレームの情報が確定するのは最後です。そのため、moov は自然とファイルの末尾に置かれます。
この状態でブラウザが動画を読み込むと、
- ファイルの先頭から読み始める
moovが見つからないため再生情報が取得できない- ファイルの末尾まで読み込みを待つ必要がある
- 結果として「再生されない」「再生が遅い」ように見える
という挙動になります。これが、環境依存で起きる再生トラブルの正体です。
ffmpeg +faststart が解決すること#
ここで登場するのが、-movflags +faststart オプションです。
このオプションは、たった一つの処理を行います。
moovアトムをファイルの先頭に移動する
それだけです。しかしこの一手で、挙動は劇的に変わります。
- ブラウザは先頭の数KBを読むだけで再生情報を取得できる
- ダウンロードしながら即座に再生が始まる(プログレッシブダウンロード)
- Safari/iOS を含むすべてのブラウザで安定して再生される
つまり faststart は、
「再生されない動画」を「すぐ再生できる動画」に変える、最小かつ最重要の最適化
なのです。
最も安全な基本コマンド#
すでにMP4が存在する場合、最も安全で高速なのはこのコマンドです。
ffmpeg -i input.mp4 -c copy -movflags +faststart output.mp4各オプションの意味は以下の通りです。
| オプション | 意味 | メリット |
|---|---|---|
-c copy | 映像・音声を再エンコードしない | 画質劣化なし、音ズレなし |
+faststart | moovアトムを先頭に移動 | 即座に再生可能になる |
処理時間もほぼ一瞬(数秒〜十数秒)で完了します。これだけで再生トラブルの大半を解消できるため、まず最初に試すべきコマンドです。
新規エンコード時に入れ忘れやすい罠#
新規に動画をエンコードする場合、faststart を入れ忘れるケースが非常に多いです。
❌ よくある失敗例#
ffmpeg -i input.mov -c:v libx264 -c:a aac output.mp4このコマンドでは、moov が末尾に配置されます。ローカル再生では問題が出ないため、本番環境にデプロイするまで気づけません。
✅ 正しい実務用コマンド#
ffmpeg -i input.mov -c:v libx264 -c:a aac -movflags +faststart output.mp4-movflags +faststart を加えるだけで、将来起きる再生トラブルの多くを事前に防げます。
ffprobeで faststart が適用されているか確認する方法#
実務では「本当に直っているか」を必ず確認する必要があります。ffprobe を使えば、moovアトムの位置を正確に特定できます。
確認コマンド#
ffprobe -v trace output.mp4 2>&1 | grep -E "moov|mdat"出力結果の読み方#
✅ faststart 適用済み(正常)の場合:
type:'moov' ... ← moovが先に出現
type:'mdat' ... ← mdatが後に出現moov が mdat(映像データ本体)より前に表示されていれば、faststartが正しく適用されています。
❌ faststart 未適用(問題あり)の場合:
type:'mdat' ... ← mdatが先に出現
type:'moov' ... ← moovが後に出現(末尾)mdat が先に来ている場合、moovアトムはファイル末尾にあり、Web配信では再生の遅延や失敗が起きる可能性があります。
よくある誤解:faststart はストリーミング配信ではない#
faststart は、HTTPプログレッシブダウンロードを高速化するためのものです。
HLS(HTTP Live Streaming)やDASH(Dynamic Adaptive Streaming)のようなセグメント分割配信・適応ビットレート配信とは根本的に異なります。
| 方式 | 特徴 | faststart の効果 |
|---|---|---|
| プログレッシブダウンロード | 1つのMP4をそのまま配信 | ✅ 効果あり |
| HLS / DASH | 動画を数秒ごとのセグメントに分割 | ❌ 効果なし(そもそも不要) |
大規模な動画配信サービスを構築する場合はHLSへの移行を検討すべきですが、ブログやポートフォリオサイト程度であればfaststartで十分です。
実務でのおすすめ運用ルール#
筆者がチーム開発で実際に運用しているルールを紹介します。
- すべてのMP4に faststart を適用する(例外なし)
- 可能な限り
-c copyで後処理する(再エンコードは最終手段) - アップロード前に ffprobe で検査する(CI/CDに組み込むと理想的)
この3点を守るだけで、「iOSだけ再生されない」「環境によって動かない」といった事故をほぼ根絶できます。
まとめ#
「動画が再生されない」問題の正体は、ネットワークでもコーデックでもなく、moovアトムの配置であることがほとんどです。
要点を整理します。
| ポイント | 内容 |
|---|---|
| 原因 | moovアトムがファイル末尾にある |
| 解決策 | -movflags +faststart を追加する |
| 確認方法 | ffprobe -v trace でmoovの位置をチェック |
| 運用ルール | すべてのMP4に例外なく適用する |
動画をWebで扱うなら、+faststart を入れ忘れない。これだけ覚えておけば、再生トラブルの大半は防げます。
よくある質問(FAQ)#
Q. faststartを適用すると画質は劣化しますか?#
いいえ。-c copy と組み合わせた場合、映像・音声データには一切手を加えず、メタデータの配置のみを変更するため画質は全く変わりません。
Q. faststartを適用するとファイルサイズは変わりますか?#
ほぼ変わりません。moovアトムの位置を移動するだけなので、ファイルサイズの増加は無視できるレベル(通常1KB未満)です。
Q. 既にアップロード済みの動画にも適用できますか?#
はい。動画をダウンロードし、ffmpeg -i input.mp4 -c copy -movflags +faststart output.mp4 で変換してから再アップロードすれば適用できます。
Q. HLS配信でもfaststartは必要ですか?#
不要です。HLSは動画を数秒ごとのセグメント(.tsファイル)に分割するため、moovアトムの位置は関係ありません。











