yumで入れたnginxをソースビルドに変更　RTMPモジュールとFFmpegを使ったライブストリームのマルチビットレート配信

#必要パッケージインストール
```bash
# yum install pcre pcre-devel
```
※入ってない場合

#yumのnginxを差し替え+RTMPモジュールを入れる
##現在のNginx確認
```bash
# nginx -V
nginx version: nginx/1.14.0
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: 
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib64/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
...
```
※configure arguments: をコピーしておく

##起動スクリプトだけ残して現在のnginxを削除
```bash
# cp /etc/init.d/nginx /etc/init.d/nginx.bak
# yum remove nginx
```

## nginxのソースをダウンロードして解凍
```bash
# cd /usr/local/src
# wget http://nginx.org/download/nginx-1.14.0.tar.gz
# tar zxvf nginx-1.14.0.tar.gz
# ln -sf nginx-1.14.0 nginx
```
※最新版は http://nginx.org/en/download.html で確認

##nginx-rtmp-moduleをダウンロードして解凍
```bash
# wget https://github.com/arut/nginx-rtmp-module/archive/master.zip
# unzip -q master.zip
```

## nginx + nginx-rtmp-module インストール
```bash
# cd nginx-1.14.0
# ./configure --add-module=../nginx-rtmp-module-master ←追記&コピーしたconfigure argumentsを貼り付け

# make
# make install
```

## 起動スクリプトの復元
さっき取ったバックアップをリネーム

```bash
# mv /etc/init.d/nginx.bak /etc/init.d/nginx
```

##確認・起動
```bash
# nginx -V
 ※configure arguments に--add-module=./nginx-rtmp-module-master があることを確認。
# service nginx start
```

##ffmpeg
```bash
# cd /usr/local/src
# wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-64bit-static.tar.xz
# tar Jxf ffmpeg-git-64bit-static.tar.xz
# ln -s /usr/local/src/ffmpeg-git-201800823-64bit-static/ffmpeg /usr/bin/ffmpeg
```

##rtmp + ABR
```nginx:nginx.conf
rtmp {
  server {
    listen 1935;
    publish_notify on;
    drop_idle_publisher 5s;
    buflen 5s;
    respawn on;
    respawn_timeout 2s;

    application live {
      live on;
      allow play all;

      exec ffmpeg -v verbose -i rtmp://localhost/live/$name
       -c:v libx264 -c:a copy -b:v 256k -vf "scale=360:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 50 -maxrate 512k -bufsize 256k -x264opts keyint=50:min-keyint=50:scenecut=-1 -f flv rtmp://localhost/hls/$name_360
       -c:v libx264 -c:a copy -b:v 512k -vf "scale=480:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 50 -maxrate 1024k -bufsize 512k -x264opts keyint=50:min-keyint=50:scenecut=-1 -f flv rtmp://localhost/hls/$name_480
       -c:v libx264 -c:a copy -b:v 1024k -vf "scale=720:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -g 50 -maxrate 2048k -bufsize 1024k -x264opts keyint=50:min-keyint=50:scenecut=-1 -f flv rtmp://localhost/hls/$name_720
       -c:v copy -c:a copy -f flv rtmp://localhost/hls/$name_src 2>>/var/log/ffmpeg/$name.log;
    }
    application hls {
      live on;
      hls on;
      hls_path /htdocs/live_stream;
      hls_type live;
      hls_nested on;
      hls_continuous on;
      hls_cleanup on;
      hls_variant _360 BANDWIDTH=384000;
      hls_variant _480 BANDWIDTH=640000;
      hls_variant _720 BANDWIDTH=1152000;
    }
  }
}
```

**エンコード：　_360 _480 _720**
**　　無圧縮：　_src**

wikiに載ってるそのままのコードをコピペしただけでは、映像と音声が5秒くらいで固まってしまいうまく配信ができなかった。
githubやstackoverflowを中心にググりつつ試行錯誤した結果、この設定でなんとか途切れず安定するようになった。

- -c:v　映像コーデックを指定
- -c:a　音声コーデックを指定
- -b:v　ビデオのビットレート、単位
- -vf "scale=000:trunc(ow/a/2)*2"　同じ入力アスペクト比を維持しながら、幅と高さを2で割り切れるようにする
- -tune zerolatency　再生時のレイテンシを低くする。動画の頭出しが早くなる。
- -preset　遅いプリセットほどより良い圧縮・画質。速いほうから順に、ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo
- -crf　固定品質でのエンコードモード(x264 のみ)。x264で推奨されるVBR。
- -g　シークのしやすさ。通常は fps × 5～10程度 (5～10秒単位でシーク可能) が目安。
- -maxrate　最大ビットレート
- -bufsize　レートコントロールのバッファサイズ。x264を使う場合は -bufsize を指定しないと maxrate 制限は機能しない
- -x264opts　デフォルトのプリセット設定の上書き。
- keyint=50:min-keyint=50:scenecut=-1　IDRフレーム間の最大間隔、IDRフレーム間の最小間隔、IDRフレームの量

**※エンコード設定を増やすほどCPU負荷が高くなる。CPU使用率が100%を超えない程度で調整しないと音ズレやコマ落ちが発生する。**

#video.js でプレイヤーの作成

https://videojs.com/getting-started/

```html
<!DOCTYPE html>
<html>
  <head>
    <link href="https://vjs.zencdn.net/7.1.0/video-js.css" rel="stylesheet">
  </head>
  <body>
    <video id="player" width="1280" height="720" 
           class="video-js vjs-default-skin vjs-big-play-centered" autoplay preload="auto" onloadstart="this.volume=0.5" controls>
      <source src="http://XXXXXXXX/live_stream/XXXXX_360p/index.m3u8" type="application/x-mpegURL">
      <source src="http://XXXXXXXX/live_stream/XXXXX_480p/index.m3u8" type="application/x-mpegURL">
      <source src="http://XXXXXXXX/live_stream/XXXXX_720p/index.m3u8" type="application/x-mpegURL">
      <source src="http://XXXXXXXX/live_stream/XXXXX_src/index.m3u8" type="application/x-mpegURL">

    </video>
    <script src="https://vjs.zencdn.net/7.1.0/video.js"></script>
  </body>
</html>
```

##css追記
画面と再生ボタンを真ん中にする

```css
#player {
  margin: 0 auto;
}
.vjs-default-skin .vjs-big-play-button {
  margin-left: -@big-play-width/2;
  margin-top: -@big-play-height/2;
  left: 50%;
  top: 50%;
}
```

#今後
- 誰でも配信できてしまうのでストリームキー認証にしたい
- なぜかFirefoxだけ再生できないのでhls.jsも試したい
- 遅延が 5s以下の配信にしたい（現状10s ~ 15sくらい）


#参考
http://www.chaneru.com/Roku/HLS/X264_Settings.htm
http://mobilehackerz.jp/archive/wiki/index.php?%BA%C7%BF%B7ffmpeg%2F%B9%E2%C5%D9%A4%CA%A5%AA%A5%D7%A5%B7%A5%E7%A5%F3
http://technical.live-on.net/archives/1343
https://cloudpack.media/39059