[MPEG-DASH] Fragmented MP4のファイル構造

# はじめに
MPEG-DASHのセグメントファイル（Fragmented MP4）についてファイル構造を紹介します。

# MP4
- Moving Picture Experts Group（MPEG）で規格化
- 国際標準機関 ISO/IEC で 14496-14 として標準化されている
- Appleの[QuickTime](https://ja.wikipedia.org/wiki/QuickTime)を流用したもの
- BOX（ATOM）と呼ばれるバイナリブロックから構成される

MP4は、[MPEG-4](https://ja.wikipedia.org/wiki/MPEG-4)の1つで映像・音声の記録に用いられているフォーマットです。もともとはMPEG-4動画を再生するためのフォーマットでありましたが、MPEG-4動画だけでなく、様々な映像/音声コーデックに対応しています。
MP4はBOXと呼ばれるバイナリブロックから構成されています。BOXは木構造になっています。このBOXは、Appleの[QuickTime](https://ja.wikipedia.org/wiki/QuickTime)がベースに作られたため、`ATOM`とも呼ばれることがあります。
<img width="25%" alt="MP4" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50563/8bc78494-0a3e-be58-8447-d3017f180524.png">

# BOX
- BoxType
    - 4文字のASCIIで表される型を持っている
- BoxSize
    - 4バイト(32bit)の長さ情報を持っている。
    - 子ノードのBOXの長さを含む（ツリー構造）
- BoxData
    - バイナリデータ

BOXは、`BoxType`、`BoxSize`、`BoxData`の3つから構成されています。BOXの種類は`BoxType`で表されます。

# BOXの種類
- `ftyp` (FileTypeBox)
    - MP4のBOXは、`ftyp`から始まります。
    - http://www.ftyps.com/
- `moov` (MovieBox)
    - メディア毎のヘッダ情報（サイズ、再生時間、etc.）などのメタデータが格納されている
- `mdat` (MovieDataBox)
    - メディアデータ自体が格納されている

上記以外にも、`iods` (ObjectDescriptorBox)、`mvhd` (MovieHeaderBox)、`mvex` (MovieExtendsBox)、`trak` (TrackBox)などがあります。

## BOXのダンプ方法
```bash:実行例
MP4Box -std -diso Bullfinch.mp4 > output.xml
```

```xml:出力例
<?xml version="1.0" encoding="UTF-8"?>
<!--MP4Box dump trace-->
<IsoMediaFile xmlns="urn:mpeg:isobmff:schema:file:2016" Name="Bullfinch.mp4">
<FileTypeBox Size="32" Type="ftyp" Specification="p12" Container="file" MajorBrand="isom" MinorVersion="512">
<BrandEntry AlternateBrand="isom"/>
<BrandEntry AlternateBrand="iso2"/>
<BrandEntry AlternateBrand="avc1"/>
<BrandEntry AlternateBrand="mp41"/>
</FileTypeBox>
...
```

[MP4Box](https://gpac.wp.imt.fr/)というソフトウェアを使うと、MP4のBOX構造をXML形式にダンプすることができます。

## MP4の情報取得
```bash:実行例
ffprobe -i Bullfinch.mp4
```

```text:出力例
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf56.4.101
  Duration: 00:00:14.44, start: 0.000000, bitrate: 4237 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 4106 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 129 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
```

[FFmpeg](https://www.ffmpeg.org/)というソフトウェアに同梱されている`ffprob`を使うと、MP4のコーデックや再生時間などの情報を取得することができます。

# Fragmented MP4
- 国際標準機関 ISO/IEC で 14496-12 として標準化されている
- フラグメント
    - Fragmented MP4 で分割したもの
- セグメント
    - [MPEG-DASH](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP)で使用されているメディアファイルを分割したもの
    - 1つまたは複数のフラグメントから構成される

Fragmented MP4では、1つの「初期セグメントファイル」と複数の「セグメントファイル」に分かれた構造になります。[MPEG-DASH](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP)や[HLS](https://en.wikipedia.org/wiki/HTTP_Live_Streaming)で扱うメディアファイルは、Fragmented MP4である必要があります。
<img width="50%" alt="Fragmented MP4" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50563/3859f162-49b5-110d-45d5-8caa8e786fa9.png">

# おわりに
今回、Fragmented MP4について纏めました。
メディアファイルの作成方法や再生方法については別の投稿で紹介していますので
是非ご覧ください。ありがとうございました。

# 関連リンク
- [[MPEG-DASH] 初心者のためのWEBストリーミング入門](https://qiita.com/yun_bow/items/a97ad78615c6ca3a75bb)
- [MPEG-DASH] Fragmented MP4のファイル構造（本稿）
- [[MPEG-DASH] MPDのファイル構造](https://qiita.com/yun_bow/items/780e49531174272e7c44)
- [[MPEG-DASH] DRMシステムの概要と種類](https://qiita.com/yun_bow/items/e573f4754579d1627a13)
- [[MPEG-DASH] Bento4でDRMパッケージを行う](https://qiita.com/yun_bow/items/77b86d75e15f245f265b)
- [[MPEG-DASH] dashJSでアダプティブストリーミングを再生する](https://qiita.com/yun_bow/items/88582964c113c8499742)
- [[MPEG-DASH] videoJSでアダプティブストリーミングを再生する](https://qiita.com/yun_bow/items/3cdcb0a4f961d6e1e06d)
- [[MPEG-DASH] パフォーマンスチューニングを行う](https://qiita.com/yun_bow/items/e4e37265643a661021ec)

## 参考リンク
- [MP4のデータ構造](https://qiita.com/daisukeoda/items/87f6b5e9427c3feeaabf)
- [MP4のファイル構造を解説](https://qiita.com/satken2/items/d14b4113fe3fb5f5597b)
- [HTML5のvideoタグで利用するmp4の動画を作る時のTips](https://qiita.com/joker1007/items/def9d58ddb00fafc936d)
- [秋茄子を嫁に食わせても良いけど、暗号化されたFragmented mp4はffmpegに食わせない方が良いかもしれない](https://qiita.com/swdkn/items/b28b7a8d7e968de577b2)

以上です。