ffmpegとbento4でCMAF規格に対応したファイルを作る

4K・8K映像を配信するために、H.265/HEVCコーデックの動画を使いたい（H.264でも4K配信はできるんだけど）。
H.265/HEVCコーデックの動画を配信するためにCMAFの規格に対応したファイルを生成したかったのですが、日本語の記事が見つからなくて困ったのでメモ。

やり方はこれだけではないと思いますが、参考の一つにしていただければ。
また必要に応じて各コマンドのパラメータは各自調整してください。

※ 用語の間違いなどあれば指摘よろしくお願いします。
# 準備
## 実行環境
* macOS 13.3.1
## インストール
ffmpeg, [bento4](https://formulae.brew.sh/formula/bento4)のインストールはhomebrewを使いました。
※ ffmpegのインストールについてはどこにでもあるのでご自身で調べてください

## 前提
* `IMG_0000.MOV`: エンコード元の動画。iPhoneで撮影した動画で解像度は2160p, コーデックはH.265/HEVC

# CMAFの作成
## シングルビットレート配信に対応したCMAF生成
```
# mp4への変換
ffmpeg -i IMG_0000.MOV -codec copy sample_1080p_h265.mp4
# 動画情報の確認（手順としては必要ない）
mp4info sample_1080p_h265.mp4
# 動画をセグメント化
mp4fragment sample_1080p_h265.mp4 sample_1080p_h265_fragmented.mp4
# CMAF配信用のファイルを出力
mp4dash --mpd-name master.mpd --hls -o output sample_1080p_h265_fragmented.mp4
# outputというフォルダに出力されます
tree -L 1 output
output
├── audio
├── master.m3u8
├── master.mpd
└── video

2 directories, 2 files
```
## マルチビットレート配信に対応したCMAF生成
```
# オリジナルの動画ファイルから音声と映像を切り分ける
ffmpeg -i IMG_0000.MOV -c:v copy -an IMG_0000.video.mp4
ffmpeg -i IMG_0000.MOV -c:a copy -vn IMG_0000.audio.mp4
# 各解像度の映像を生成
ffmpeg -i IMG_0000.video.mp4 -c:v hevc_videotoolbox -tag:v hvc1 -s 640x360 -vf fps=30000/1001 -b:v 800k IMG_0000.video.360p.mp4
ffmpeg -i IMG_0000.video.mp4 -c:v hevc_videotoolbox -tag:v hvc1 -s 1280x720 -vf fps=30000/1001 -b:v 2400k IMG_0000.video.720p.mp4
ffmpeg -i IMG_0000.video.mp4 -c:v hevc_videotoolbox -tag:v hvc1 -s 1920x1080 -vf fps=30000/1001 -b:v 4800k IMG_0000.video.1080p.mp4
ffmpeg -i IMG_0000.video.mp4 -c:v hevc_videotoolbox -tag:v hvc1 -s 3840x2160 -vf fps=30000/1001 -b:v 9600k IMG_0000.video.2160p.mp4
# fragmented MP4を作成
mp4fragment --fragment-duration 2000 --timescale 1000 IMG_0000.video.360p.mp4 IMG_0000.video.360p.frag.mp4
mp4fragment --fragment-duration 2000 --timescale 1000 IMG_0000.video.720p.mp4 IMG_0000.video.720p.frag.mp4
mp4fragment --fragment-duration 2000 --timescale 1000 IMG_0000.video.1080p.mp4 IMG_0000.video.1080p.frag.mp4
mp4fragment --fragment-duration 2000 --timescale 1000 IMG_0000.video.2160p.mp4 IMG_0000.video.2160p.frag.mp4
mp4fragment --fragment-duration 2000 --timescale 1000 IMG_0000.audio.mp4 IMG_0000.audio.frag.mp4
# CMAFに対応したファイルを生成
mp4dash --use-segment-template-number-padding --use-segment-timeline --mpd-name=master.mpd --hls -o output IMG_0000.video.2160p.frag.mp4 IMG_0000.video.1080p.frag.mp4 IMG_0000.video.720p.frag.mp4 IMG_0000.video.360p.frag.mp4 IMG_0000.audio.frag.mp4
# outputというフォルダに出力されます
tree -L 1 output
output
├── audio
├── master.m3u8
├── master.mpd
└── video

2 directories, 2 files
```
# 再生の確認
生成したファイルをS3に置いて確認できる環境があったので、生成したファイルとディレクトリをそのまま置いて、playerのdemo環境で再生してました。
![スクリーンショット 2023-06-30 10.36.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304409/aa9b871c-da2d-2de7-ece3-b3bbedbfc3b6.png)

video.jsでの再生確認がしたかったので、[videojs-http-streaming Demo](https://videojs-http-streaming.netlify.app/?debug=false&autoplay=false&muted=false&fluid=false&minified=false&sync-workers=false&liveui=true&llhls=true&url=https%3A%2F%2Fd2zihajmogu5jn.cloudfront.net%2Fbipbop-advanced%2Fbipbop_16x9_variant.m3u8&type=application%2Fx-mpegurl&keysystems=&buffer-water=false&exact-manifest-timings=false&pixel-diff-selector=false&network-info=false&dts-offset=false&override-native=true&preload=auto&mirror-source=true&forced-subtitles=false)を利用しました。
`Source URL`をS3へのURLに変更して再生できるか確認してください。

※ 生成したファイル・ディレクトリのパスを参照して、ローカル環境でindex.html作って再生を確認するみたいなこともできるのかも。やってない。 
# 参考にした記事
https://ottverse.com/bento4-mp4dash-for-mpeg-dash-packaging/