本ページは広告が含まれています。気になる広告をクリック頂けますと、サーバ運営費になります(^^
受信速度を自動設定したい
nginx + rtmp-moduleを利用し、hls variant機能を使ってマルチビットレートでhlsを作成します。
プレーヤは、videojsを利用して、
1.今、受信しているビットレートはどれか?
2.明示的に速度選択をする
3.回線速度に合わせて自動的に速度調整
を実現します。
Web PlayerはVideo.jsを利用します。
http://videojs.com/
nginxの準備
HLS配信をnginx rtmp-moduleで行うためには、
application multi_jp { live on; on_publish http://localhost/publishauth/auth.php; notify_method get; on_play http://localhost:8080/on_play; hls on; hls_path /usr/local/nginx/html/hls/jp; hls_nested on; hls_variant _lw BANDWIDTH=320000; hls_variant _md BANDWIDTH=576000; hls_variant _hi BANDWIDTH=2128000; }
という設定を行います。
詳しくはこちらをご参照ください
Video.jsの準備
とりあえず簡単にHLS配信をするためには、jsファイルは準備されているCDNを利用すると楽に始められます。
<link href="http://vjs.zencdn.net/vjs-version/video-js.css" rel="stylesheet"> <script src="http://vjs.zencdn.net/5.16.0/video.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-hls/5.1.0/videojs-contrib-hls.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-hls/5.1.0/videojs-contrib-hls.min.js"></script>
一から始めたい場合はこちらをご参考にしてください。
video.jsインストール時にエラー
npm install --save-dev video.js npm WARN saveError ENOENT: no such file or directory, open '/home/ubuntu/package.json' /home/ubuntu mqw video.js@6.4.0 tqw babel-runtime@6.26.0 x tqq core-js@2.5.2 x mqq regenerator-runtime@0.11.1 tqw global@4.3.2 x tqw min-document@2.19.0 x x mqq dom-walk@0.1.1 x mqq process@0.5.2 tqw safe-json-parse@4.0.0 x mqw rust-result@1.0.0 x mqq individual@2.0.0 tqq tsml@1.0.1 tqq videojs-font@2.0.0 tqw videojs-ie8@1.1.2 x mqq es5-shim@4.5.9 tqq videojs-vtt.js@0.12.4 mqw xhr@2.4.0 tqq is-function@1.0.1 tqw parse-headers@2.0.1 x tqq for-each@0.3.2 x mqq trim@0.0.1 mqq xtend@4.0.1 npm WARN enoent ENOENT: no such file or directory, open '/home/ubuntu/package.json' npm WARN ubuntu No description npm WARN ubuntu No repository field. npm WARN ubuntu No README data npm WARN ubuntu No license field.
気になるエラーが見えますが
no such file or directory, open ‘/home/ubuntu/package.json’
これ気にしなくても大丈夫です。なんで?と言われても説明できないのですが、特に支障なく利用できています。
配信品質コントロールモジュールの設定
こちらのvideojs-contrib-quality-levelsが肝になります。今回回線速度を判断して受信速度を自動調整するためのモジュールです。明示的に速度を選択する事もできるようになります。
videojs-contrib-hlsバージョン4.1以上を使用すると、HLSソースの品質レベルが自動的に設定されます。なので、videojs-contrib-hlsのバージョンにも気を付けてください。ちなみに、私が利用しているvideojs-contrib-hlsのバージョンは
/** * videojs-contrib-hls * @version 5.5.3 * @copyright 2017 Brightcove, Inc * @license Apache-2.0 */
でした。
videojs-contrib-quality-levelsの使い方
git clone https://github.com/videojs/videojs-contrib-quality-levels.git #npm install --save videojs-contrib-quality-levels cd videojs-contrib-quality-levels npm i npm run build
で、videojs-contrib-quality-levels/dist内に作成された
videojs-contrib-quality-levels.min.js
をvideojsフォルダに放り込みます。(ブラウザからアクセスできる位置に配置)
自分で準備したvideo-js類はこんな感じです。
videojs# ls video-js.min.css videojs-contrib-hls.min.js videojs-contrib-media-sources.min.js video.js videojs-contrib-media-sources.js videojs-contrib-quality-levels.min.js
htmlの設定
後は、こちらを参考にHTMLを配置すると速度調整用のボタンができる。
緑色が、現在受信している速度。
赤色は無効にしている速度。
実際の設定と仕組みの説明
映像ソースには .m3u8を設定するのが重要です。こちらのm3u8は、nginx.confで設定した受けたストリーム名になります。
nginx.confの設定部分はここ
application live { live on; record off; on_publish http://localhost/publishauth/auth.php; notify_method get; deny play all; hls on; hls_path /usr/local/nginx/html/hls; hls_type live; hls_variant _lw BANDWIDTH=320000; hls_variant _md BANDWIDTH=576000; hls_variant _hi BANDWIDTH=2128000; }
です。streamという名前は、エンコーダ側で設定したストリーム名になります。エンコーダから3本のストリーム
stream_hi
stream_md
stream_lw
を受け、それぞれhls_variant設定して、BANDWIDTH設定してあります。hls_variant設定の詳細はこちらに記載があります。
variantは標準からわずかに異なるもの。異形といった意味という意味で、上記nginx.confで、hls variantを追加登録している事になります。_から後ろ、(_hi,_md,_lw)は接尾辞という扱いになります。
そこでできるstream.m3u8(接尾辞より前)には、追加されたhls_variantの.m3u8ファイルが示されます。
/usr/local/nginx/html/hls# cat stream.m3u8 #EXTM3U #EXT-X-VERSION:3 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=320000 stream_lw.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=576000 stream_md.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2128000 stream_hi.m3u8
このstream.m3u8ファイルを映像ソースとして設定する事で、videojs-contrib-quality-levelsが判断し、自動的にBANDWIDTHを認識表示・再生します。
<!doctype html> <html> <head> <meta charset="utf-8"> <title>videojs-contrib-quality-levels Demo</title> <link href="../videojs/video-js.css" rel="stylesheet"> <style> button.enabled { background: SkyBlue; } button.selected { background: SpringGreen; } button.disabled { background: red; } </style> </head> <body> <div id="fixture"> </div> <div id="quality-levels"> <h2>映像受信速度:</h2> </div> <script src="../videojs/video.js"></script> <script src="../videojs/videojs-contrib-hls.js"></script> <script src="../videojs/videojs-contrib-quality-levels.min.js"></script> <script> function createQualityButton(qualityLevel, parent) { var button = document.createElement('button'); var classes = button.classList; if (qualityLevel.enabled) { classes.add('enabled'); } else { classes.add('disabled'); } button.innerHTML = qualityLevel.id + ': ' + qualityLevel.bitrate + ' kbps'; button.id = 'quality-level-' + qualityLevel.id; button.onclick = function() { var old = qualityLevel.enabled; qualityLevel.enabled = !old; button.classList.toggle('enabled'); button.classList.toggle('disabled'); } parent.appendChild(button); } function createPlayer(callback) { var video = document.createElement('video'); video.id = 'videojs-contrib-quality-levels-player'; video.className = 'video-js vjs-default-skin'; video.setAttribute('controls', true); video.setAttribute('height', 720); video.setAttribute('width', 1280); document.querySelector('#fixture').appendChild(video); var options = { autoplay: true, qualityLevels: {} }; var url = 'http://video.hanako.jp/hls/stream.m3u8'; var type = 'application/x-mpegURL'; try { window.player = videojs(video.id, options); window.player.src({ src: url, type: type }); callback(window.player); } catch(err) { console.log("caught an error trying to create and add src to player:", err); } } function setup(player) { player.ready(function() { var qualityLevels = player.qualityLevels(); var container = document.getElementById('quality-levels'); qualityLevels.on('addqualitylevel', function(event) { createQualityButton(event.qualityLevel, container); }); qualityLevels.on('change', function(event) { for (var i = 0; i < qualityLevels.length; i++) { var level = qualityLevels[i]; var button = document.getElementById('quality-level-' + level.id); button.classList.remove('selected'); } var selected = qualityLevels[event.selectedIndex]; var button = document.getElementById('quality-level-' + selected.id); button.classList.add('selected'); }) }); } (function(window, videojs) { createPlayer(setup); })(window, window.videojs); </script> </body> </html>