FFMPEGでライブのCMAF (HLS + MPEG-DASH) の作成方法

##はじめに

こんにちは streampack チームのメディです。
https://cloudpack.jp/service/option/streampack.html

##Copyrights 
**Big Buck Bunny**
© copyright 2008, Blender Foundation | www.bigbuckbunny.org

##What is CMAF ・ CMAFとは
CMAF means ***Common media application format***
In order to simplify let's say that CMAF has support for both MPEG-DASH and HLS. You just need to create your video segments once. Both of the manifests (**MPD** & **m3u8**) will use the same video segments. 

CMAFは「***Common media application format***」を意味します。
単純化するため、CMAFがMPEG-DASHとHLSの両方をサポートしているとしましょう。 あなたは一度あなたのビデオセグメントを作成する必要があります。 両方のマニフェスト（**MPD** ＆ **m3u8**）は同じビデオセグメントを使用します。

##Objective・目的
Learning how to create a CMAF compliant ***Live*** ABR video stream.
ライブのCMAFのABRビデオストリームの簡単な例を学ぶこと。

## Tools ・ツール
#### FFMPEG
FFMPEG will encode the video file.
FFMPEGはビデオファイルをエンコードします。
I am using a static build of FFMPEG v4.1.
FFMPEG「v4.1」の静的ビルドを使用しています。
####FFMPEG static builds ・ FFMPEG静的ビルド
- OSX: https://evermeet.cx/ffmpeg/
- Linux: https://johnvansickle.com/ffmpeg/

## FFMPEG command ・ FFMPEGの使い方


```bash 
./ffmpeg -re -stream_loop -1  -i ~/Documents/videos/BigBuckBunny.mp4 \
-map 0 -map 0 -map 0 -c:a aac -c:v libx264 \
-b:v:0 800k -s:v:0 1280x720 -profile:v:0 main \
-b:v:1 500k -s:v:1 640x340  -profile:v:1 main \
-b:v:2 300k -s:v:2 320x170  -profile:v:2 baseline \
-bf 1 \
-keyint_min 120 -g 120 -sc_threshold 0 -b_strategy 0 -ar:a:1 22050 -use_timeline 1 -use_template 1 \
-window_size 5 -adaptation_sets "id=0,streams=v id=1,streams=a" -hls_playlist 1 -seg_duration 4 -streaming 1 -remove_at_exit 1 -f dash manifest.mpd
```


### Encode faster with a GPU ・ GPUで高速エンコード
If you are using a Mac, you can replace `-c:v libx264` by `-c:v h264_videotoolbox -allow_sw 1` , it will use the GPU when available.
Macを使用している場合、 `-c:v libx264`を` -c:v h264_videotoolbox -allow_sw 1`に置き換えることができます。利用可能な場合はGPUを使用します。

If you have a nvidia card, I wrote [a more derailed article here](https://qiita.com/mehdi/items/9be0653581ffe6ef8722).
Nvidiaグラフィックボードに興味がある場合は、[より詳細な記事](https://qiita.com/mehdi/items/9be0653581ffe6ef8722)。
###Player ・ プレーヤー
In the following examples, I am using **Clappr** player.
次の例では、私は**Clappr**プレーヤーを使っています。

**Clappr** is an open sources javascript media player.
**Clappr** はオープンソースのjavascriptメディアプレーヤーです。

If you are interested in **Clappr**, I wrote [a more detailed article](https://qiita.com/mehdi/items/501c4bd3374ebc298029).
**Clappr** に興味がある場合は、[より詳細な記事](https://qiita.com/mehdi/items/501c4bd3374ebc298029)にあります。

## HLS player

<img width="654" alt="Screen Shot 2019-04-19 at 10.27.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/ccfaee16-ae9e-d28b-9e24-6f49ea959434.png">


```html
<head>
  <title>Clappr Player</title>
  <meta charset="UTF-8">
  <!-- Player -->
  <script type="text/javascript" src="//cdn.jsdelivr.net/npm/clappr@latest/dist/clappr.min.js"></script>
  <!-- Quality selector -->
  <script type="text/javascript" src="//cdn.jsdelivr.net/gh/clappr/clappr-level-selector-plugin@latest/dist/level-selector.min.js"></script>
</head>

<body>
  <div id="player"></div>
  <script>
    Clappr.Log.setLevel(Clappr.Log.LEVEL_DEBUG);
    var player = new Clappr.Player({
      source: "master.m3u8",
      parentId: "#player",
      mute: true,
      autoPlay: true,
      plugins: {
        core: [LevelSelector]
      },
      levelSelectorConfig: {
        title: '動画品質',
      },
    });
  </script>
</body>
```

## DASH player
<img width="654" alt="Screen Shot 2019-04-19 at 10.34.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/befc8951-89b7-60e5-7a5a-bb09d577a493.png">

```html
<head>
  <title>Clappr Player</title>
  <meta charset="UTF-8">
  <!-- Player -->
  <script type="text/javascript" src="//cdn.jsdelivr.net/npm/clappr@latest/dist/clappr.min.js"></script>
  <!-- DASH  -->
  <script type="text/javascript" src="//cdn.jsdelivr.net/npm/dash-shaka-playback@2.2.1/dist/dash-shaka-playback.min.js"></script>
</head>

<body>
  <div id="player"></div>
  <script>
    Clappr.Log.setLevel(Clappr.Log.LEVEL_DEBUG);
    var player = new Clappr.Player({
      source: "manifest.mpd",
      parentId: "#player",
      mute: true,
      autoPlay: true,
      plugins: {
       playback:[DashShakaPlayback]
     },
    });
  </script>
</body>
```

##Information sources ・ 情報元
https://www.ffmpeg.org/ffmpeg-all.html
http://clappr.io/