Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

必要パッケージインストール

# yum install pcre pcre-devel

※入ってない場合

yumのnginxを差し替え+RTMPモジュールを入れる

現在のNginx確認

# 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を削除

# cp /etc/init.d/nginx /etc/init.d/nginx.bak
# yum remove nginx

nginxのソースをダウンロードして解凍

# 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をダウンロードして解凍

# wget https://github.com/arut/nginx-rtmp-module/archive/master.zip
# unzip -q master.zip

nginx + nginx-rtmp-module インストール

# cd nginx-1.14.0
# ./configure --add-module=../nginx-rtmp-module-master ←追記&コピーしたconfigure argumentsを貼り付け

# make
# make install

起動スクリプトの復元

さっき取ったバックアップをリネーム

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

確認・起動

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

ffmpeg

# 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.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/

<!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追記

画面と再生ボタンを真ん中にする

#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

nabeyaki
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away