FFmpegとは、クロスプラットフォームで動作するメディアを変換するCUIのソフトウェアです。こう書いても分かりやすいとは言えないので、もう少し簡単に書くと、「真っ黒い画面にコマンドを書いて、動画とか音声をどうにかする」ソフトです。
今回はこのFFmpegを用いて、お気持ち程度にネットワーク上で早く見られるMP4ファイルを作っていきましょう。ちなみにこれはストリーミングとは異なる処理なので、その点は注意してください。
MP4は要するに箱
動画や音声の話をする際に、h264/AVC
であったり、AAC
であったりと、あまり聞きなれない言葉が飛び交うと思います。私たちが普段聞きなれている「MP4」であったり「MKV」とかとはどのような関係があるのでしょうか。
実はMP4の中にh264/AVC
であったりAAC
であったりが含まれている、という感じです。つまりMP4は箱という感じで、その中に規格化された圧縮データが含まれているという感じです。もちろんMP4だけではなくMKVなどもあるということは、その箱にもいろいろな種類がある、ということです。
What's "moov"?
MP4ファイルの内部には単にメディアデータが含まれているのではなく、それらの他にもファイルタイプを示す部分やメタデータが含まれている部分が存在します。これらの部分をそれぞれ「Box」といい、それらのうちメタデータを含んでいるものを「moov」といいます。メタデータはメディアデータの処理が終わらないと生成できない(再生時間などが含まれることより)ので、そのままメディアデータの後ろにくっつけられることが多いです。
この図の通り、通常のMP4ファイルは頭にファイルタイプの情報があり、その後にメディアデータが続き、最後にmoovがくっついている、という構造になっています。
問題点
このまま配信した場合、どのような状況になるでしょうか。
ブラウザがMP4を再生しようとする場合、MP4のメタデータ(moov)を読み込んで再生に必要な情報を知る必要があります。しかし、通常配置されているMP4の場合、ファイルの最後にmoovが配置されているため、ダウンロード完了まで再生できない、ということになります。
ちなみに、MP4コンテナの構造に関しては、RFC6381で規定されており、概ねftyp box
mdat box
moov box
の順番で配置されることが多いとされています。ただし、これは必ずしもこの順序でなければならないという規定ではありません。
つまり、moovがファイルの先頭近くに位置していればよいのです。
解決策
というわけで、FFmpegを用いてmoovをファイルの先頭に移動します。具体的には以下のコマンドを実行します。
ffmpeg -i input.mp4 -c copy -movflags faststart output.mp4
-i
: 入力ファイルを指定-c copy
: ストリームを再エンコードせず、そのままコピー-movflags faststart
: moovをファイルの先頭に配置
このコマンドを実行することで、再エンコードすることなくmoov
を先頭に配置でき、ネット上で再生を開始しやすいMP4ファイルを作ることができます。
実行後は上図のようにmoovがファイルの先頭近くに配置されます。これにより、ブラウザがファイルの先頭部分を読み込んだ段階でメタデータを取得でき、ダウンロードの完了を待たずに再生を開始できるようになります。
ちなみに、このオプションに関してFFmpegの公式ドキュメント内で以下のような記載があります。
Run a second pass moving the index (moov atom) to the beginning of the file. This operation can take a while, and will not work in various output formats.
二度目の処理を実行してインデックス(moov atom)をファイルの先頭に移動する。この操作には時間がかかる場合があり、様々な出力フォーマットでは動作しない。
おわりに
記事のタイトルに「お気持ち程度」とありますが、実際にはかなり効果があります。ファイルサイズが大きくなればなるほど効果を実感しやすいと思います。
ウェブサイトでMP4ファイルを配信している方はぜひお試しください。