HLS と MPEG-DASH でメディアを共通化してみる

新年度になりましたね。 
気温の寒暖差が激しい今日このごろ、皆さまいかがお過ごしでしょうか、 
streampack の木村です。

去年の話しになりますが、Apple が iOS11 と High Sierra でようやっと HEVC コーデックをサポートを開始し、HLS でも HEVC を利用できるようになりました。

コンテナは Fragmented MP4 (fMP4) に限定されますが、これにより MPEG-DASH と HLS でメディアを共通化することが可能になりました。

Bento4 を使うことで同じメディアで MPEG-DASH と HLS 配信に必要なファイル群（MP4、プレイリスト）を一気に作成が可能ですので、手順を書いてみます。


# 用意するもの

- 動画ファイル

今回は自分の iPhone7 Plus で撮影した動画を使用しました。
もちろん、その他のファイルでも良いです。

- Bento4

DASH から HLS　まで、DRM も掛けることができるすぐれものです。
https://www.bento4.com/

# Bento4 のインストール

同じチームの hagi さんが書いてくれているので割愛！
下記ご参照下さい。

https://qiita.com/khagi/items/6e8c8d10c77bee53487b

# フラグメント化

Apple HLS 仕様では HEVC を利用する場合は、フラグメント化されている必要があります。

https://developer.apple.com/library/content/documentation/General/Reference/HLSAuthoringSpec/Requirements.html

もし手持ちのソースが Fragmented MP4(fMP4) ではない場合、Bento4 付属の `mp4fragment` でフラグメント化しておきます。

```
$ mp4fragment IMG_7611.mov IMG_7611_frag.mov
found regular I-frame interval: 997 frames (at 59.940 frames per second)
```

# ソースファイル → HLS/DASH 化

フラグメント化したら、Bento4 の `mp4dash` でマニフェスト、プレイリスト（mpd、m3u8）を書き出します。


```
$ mp4dash --force --hls --no-split --profile=on-demand IMG_7611_frag.mov
Parsing media file 1: IMG_7611_frag.mov
Extracting track 2 from IMG_7611_frag.mov
Extracting track 1 from IMG_7611_frag.mov
Parsing media file 1: tmpaY7qJJ = Extracted[track 2 from IMG_7611_frag.mov]
Parsing media file 2: tmpzr8seI = Extracted[track 1 from IMG_7611_frag.mov]
Processing and Copying media file tmpzr8seI = Extracted[track 1 from IMG_7611_frag.mov]
Processing and Copying media file tmpaY7qJJ = Extracted[track 2 from IMG_7611_frag.mov]
```

デフォルトだと `output` フォルダが作成されて配下にファイル群が出力されます。
ビデオファイル、オーディオファイル、マニフェスト、プレイリストが作成されていますね。


```
$ ls output/
audio-und-mp4a.m3u8		stream.mpd
master.m3u8			video-hev1.m3u8
media-audio-und-mp4a.mp4	video-hev1_iframes.m3u8
media-video-hev1.mp4
```

# ストリーミング

それでは実際に出来上がったファイルをメディアプレイヤーで視聴してみましょう！

## ファイルアップロード

output 以下に生成されたファイルを S3 に放り込みます。

![IMG_1502.JPG](https://qiita-image-store.s3.amazonaws.com/0/172426/e76b78c3-c546-7adb-c63c-56dffbafd44a.jpeg)


## 視聴

### HLS

https://s3-ap-northeast-1.amazonaws.com/{S3 バケット名}/encoded/fMP4/hevc/master.m3u8

iPhone の Safari で再生させてみました。

<img width="414" alt="IMG_1696.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/172426/d87773b3-f650-026a-058f-75faa07837b8.png">

### 4/18 追記

上記の master.m3u8 では Hi Sierra の Safari では再生できないことが判明。
`CODECS` 情報を消すと再生に可能になる模様

```master.m3u8
#EXTM3U
# Created with Bento4 mp4-dash.py, VERSION=1.8.0-621
#
#EXT-X-VERSION:6

# Media Playlists

# Audio
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio/mp4a",LANGUAGE="und",NAME="Unknown",AUTOSELECT=YES,DEFAULT=YES,URI="audio-und-mp4a.m3u8"

# Video
#EXT-X-STREAM-INF:AUDIO="audio/mp4a",AVERAGE-BANDWIDTH=3603386,BANDWIDTH=4306476,CODECS="hev1.1.6.L123.90,mp4a.40.2",RESOLUTION=1920x1080
video-hev1.m3u8

# I-Frame Playlists
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=3505453,BANDWIDTH=4209252,CODECS="hev1.1.6.L123.90",RESOLUTION=1920x1080,URI="video-hev1.m3u8"
```

以下のように `CODECS` 情報を消すと Hi Sierra Safari で再生可能になる

```master_rev.m3u8
#EXTM3U
# Created with Bento4 mp4-dash.py, VERSION=1.8.0-621
#
#EXT-X-VERSION:6

# Media Playlists

# Audio
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio/mp4a",LANGUAGE="und",NAME="Unknown",AUTOSELECT=YES,DEFAULT=YES,URI="audio-und-mp4a.m3u8"

# Video
#EXT-X-STREAM-INF:AUDIO="audio/mp4a",AVERAGE-BANDWIDTH=3603386,BANDWIDTH=4306476,RESOLUTION=1920x1080
video-hev1.m3u8

# I-Frame Playlists
#EXT-X-I-FRAME-STREAM-INF:AVERAGE-BANDWIDTH=3505453,BANDWIDTH=4209252,RESOLUTION=1920x1080,URI="video-hev1.m3u8"
```


### MPEG-DASH

Windows 10 Edge であればそのまま再生できる（はず！）

https://s3-ap-northeast-1.amazonaws.com/{S3 バケット名}/encoded/fMP4/hevc/stream.mpd

こちらも手持ちが無いので Android の ExoPlayer で再生させてみます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/172426/05e7cc4f-1b9d-745b-6f74-c2785e95bda1.jpeg" width=414>

ちなみに ExoPlayer では前述の HLS もそのまま再生可能です。

# まとめ

HLS と MPEG-DASH で共通のメディアファイルを使用することで、手間も減り且つリソースの削減にもつながります。
現時点では古いOSを考慮しなくてはなりませんが、今後はこちらが主流になるのではないでしょうか。