clappr-bandwidth-analyzerを最新版Clapprに対応させる① の続き。
webpack.config.jsの作成
これもclappr-level-selector-pluginを参考にする。
var path = require('path'); var webpack = require('webpack'); module.exports = { entry: path.resolve(__dirname, './src/index.js'), externals: { 'clappr': 'Clappr', "clappr-zepto": "clappr-zepto" }, module: { loaders: [ { test: /\.js$/, loader: 'babel', query: { compact: true, } }, { test: /\.scss$/, loaders: ['css', 'sass?includePaths[]=' + path.resolve(__dirname, './node_modules/compass-mixins/lib') + '&includePaths[]=' + path.resolve(__dirname, './node_modules/clappr/src/base/scss') + '&includePaths[]=' + path.resolve(__dirname, './src/base/scss') ], include: path.resolve(__dirname, 'src'), }, { test: /\.html/, loader: 'html?minimize=false' }, ], }, resolve: { extensions: ['', '.js', '.html', '.css'] }, output: { path: path.resolve(__dirname, 'dist'), filename: 'clappr-bandwidth-analyzer.js', library: 'ClapprBandwidthAnalyzer', libraryTarget: 'umd' }, };
index.jsを修正
srcフォルダを作成してindex.jsを移動する。index.jsの内容を変更
mkdir src mv index.js ./src/ vi ./src/index.js
内容は以下の通り
①最初の部分の
var UiCorePlugin = Clappr.UICorePlugin var UiContainerPlugin = Clappr.UIContainerPlugin var template = Clappr.template; var Events = Clappr.Events; var Styler = Clappr.Styler; var Player = Clappr.Player; var ejs = require('ejs'); var pluginHtml = '<div class="clappr-bandwidth-analyzer container border"><p><div class="text bandwidth">' +'<span class="icon mif-film" style="color:#00aba9"> </span> <span class="text"></span>' +'</div><div class="text totalPlayTime"><span class="icon mif-film" style="color:#00aba9">' +'</span> <span class="text"></span></div><div class="text totalDownload">' +'<span class="icon mif-film" style="color:#00aba9"> </span> <span class="text"></span>' +'</div><div class="text totalFrames"><span class="icon mif-film" style="color:#00aba9">' +'</span> <span class="text"></span></div><div class="text dropFrames"><span class="icon mif-film" style="color:#00aba9">' +'</span> <span class="text"></span></div></p><div class="clappr-bandwidth-analyzer-bandwidthChart chart"></div></div>' var btn_style = "width: 180px;margin-left: 60px;font-size: 10px;background: transparent;color: #fff;"; var plugin_stover_b_Html = "<button clappr-bandwidth-analyzer class=\"media-control-button media-control-icon\" clappr-bandwidth-analyzer style=\""+btn_style+"\"><span>Graph Analyzer</span></button>";
ここを以下に変更。
import { UICorePlugin, UIContainerPlugin, template, Events, Styler, Player } from 'clappr'; import pluginHtml from './public/bandwidth-analyzer.html' import plugin_stover_b_Html from "./public/plubin_stover_b.html"
②次に
class ClapprBandwidthAnalyzer extends UiCorePlugin {
以下に修正。これに伴い最終行は削除することになる。
export default class ClapprBandwidthAnalyzer extends UICorePlugin {
③this.core.options~以外のoptionsをoptions_baに変更
④try内のcolorを#ffffffから#000000に変更(視認性の向上のため)
⑤最終行の
module.exports = window.ClapprBandwidthAnalyzer = ClapprBandwidthAnalyzer;
を削除。
全て適用したindex.jsは以下のようになった。
import { UICorePlugin, UIContainerPlugin, template, Events, Styler, Player } from 'clappr'; import pluginHtml from './public/bandwidth-analyzer.html' import plugin_stover_b_Html from "./public/plubin_stover_b.html" export default class ClapprBandwidthAnalyzer extends UICorePlugin { get name() { return 'clappr-bandwidth-analyzer' } //get template() { return template(plugin_stover_b_Html) } get attributes() { return {'class': ''} } get events() { return { "click [clappr-bandwidth-analyzer]": "toggleAnalyzer" } } bindEvents() { this.listenTo(this.core, Events.CORE_READY, this.pluginInit); this.listenTo(this.core.mediaControl, Events.MEDIACONTROL_RENDERED, this.render); } pluginInit(){ this.init() } show(){ this.$el.addClass('show') } hide(){ this.$el.removeClass('show') } toggleAnalyzer () { this.$el.toggleClass('show') } reload(){ this.unBindEvents(); this.bindEvents(); } render() { var options_ba = this.core.options.bandwidthAnalyzer if (!options_ba){ options_ba = {} } if (!options_ba.bandwidth){ options_ba.bandwidth = {} } if (!options_ba.averageBandwidth){ options_ba.averageBandwidth = {} } this.options_ba = { 'width': options_ba.width || '50%', 'height': options_ba.height || '40%', 'border' : options_ba.border || '2px solid #00aba9!important', 'background': options_ba.background || 'rgba(60,63,65,.7)', 'y_max':options_ba.y_max || 5000, 'y_min':options_ba.y_min || 0, 'x_timeDuration':options_ba.x_timeDuration || 60, 'bandwidth':{ 'lineWidth':options_ba.bandwidth.lineWidth || 1, 'color':options_ba.bandwidth.color || '#0f0' }, 'averageBandwidth':{ 'lineWidth':options_ba.averageBandwidth.lineWidth ||1, 'color':options_ba.averageBandwidth.color ||'#f00' } }; if (this.shouldRender()) { var that = this; this.core.mediaControl.$(".media-control-left-panel").append(plugin_stover_b_Html); $('button[clappr-bandwidth-analyzer]').on('click',function(e){ that.toggleAnalyzer() }) var pluginStyle = '.clappr-bandwidth-analyzer{top:2%;right:2%;height:'+this.options_ba.height+';width:'+this.options_ba.width+';' +'position:absolute;background-color:'+this.options_ba.background+';z-index:9000;}.clappr-bandwidth-analyzer{' +'color:#fff!important;visibility:hidden}.clappr-bandwidth-analyzer-bandwidthChart{width:100%;height:calc(100% - 40px);' +'font-size:14px;line-height:1.2em}.clappr-bandwidth-analyzer .flot-text{color:#fff!important;}' +'.clappr-bandwidth-analyzer div.text{display:inline;padding-left:10px;font-size:12px;display:table-cell;}.clappr-bandwidth-analyzer.show{visibility:' +'visible;z-index:1}.border{border:'+this.options_ba.border+'}' if (!this.isInit){ this.$el = $(pluginHtml); $(this.core.$el).append(this.$el) var style = Styler.getStyleFor(pluginStyle, { baseUrl: this.core.options.baseUrl} ); this.$el.append(style); this.isInit = true } } //this.$analyzer = $(pluginHtml) //$(this.core.$el).append(this.$analyzer) //var style = Styler.getStyleFor(pluginStyle, {baseUrl: this.core.options.baseUrl}); //this.$analyzer.append(style); //this.show() return this; } shouldRender (){ try{ var playback = this.core.getCurrentPlayback() var video_tag = playback.$el[0] if (!this.core.getCurrentContainer() || !$.plot || (video_tag.webkitVideoDecodedByteCount == null) || (video_tag.webkitDroppedFrameCount == null) || (video_tag.webkitDecodedFrameCount == null)) { return false } }catch(e){ return false } return true } getTitle(){ return "Graph Analyzer" } humanizeDuration ( input ) { var days = Math.floor(input/(60*60*24)); var hours = Math.floor((input-(days*(60*60*24)))/(60*60)); var minutes = Math.floor( (input - ((days*(60*60*24)) + (hours*(60*60))) ) /60); var seconds = (input - ( (days*(60*60*24)) + (hours*(60*60)) + (minutes*60)) ); var result = (days>0?days+' days ':'') + (hours>0?hours+' hours ':'') + (minutes>0?minutes+' minutes ':'') + seconds + ' seconds' return result; } dom_update (){ $('.'+this.container_class+' div.bandwidth span.text').text( ((this.lastByteRate*8)/1000) + ' k/bits' ); $('.'+this.container_class+' div.totalPlayTime span.text').text( this.humanizeDuration(this.totalPlayTime) ) $('.'+this.container_class+' div.totalDownload span.text').text( parseFloat(this.totalLastByteRate/(1024*1024)).toFixed(2) + ' MB' ) $('.'+this.container_class+' div.totalFrames span.text').text( this.totalFrameCounts + ' Decoded frames' ) $('.'+this.container_class+' div.dropFrames span.text').text( (this.droppedFrameCount + this.totalDroppedFrameCount) + ' Dropped frames' ) } update (totalByteRate, droppedFrameCount, totalFrameCounts) { this.totalPlayTime++ if(totalByteRate < this.tmpTotalLastByteRate){ this.tmpTotalLastByteRate = 0; } this.lastByteRate = totalByteRate - this.tmpTotalLastByteRate; this.tmpTotalLastByteRate = this.tmpTotalLastByteRate + this.lastByteRate this.totalLastByteRate = this.totalLastByteRate + this.lastByteRate if(totalFrameCounts < this.tmpTotalFrameCounts){ this.tmpTotalFrameCounts = 0; } this.lastFrameCounts = totalFrameCounts - this.tmpTotalFrameCounts; this.tmpTotalFrameCounts = this.tmpTotalFrameCounts + this.lastFrameCounts; this.totalFrameCounts = this.totalFrameCounts + this.lastFrameCounts; if(droppedFrameCount < this.droppedFrameCount){ this.totalDroppedFrameCount = this.totalDroppedFrameCount + this.droppedFrameCount } this.droppedFrameCount = droppedFrameCount; //this.bandwidth.reverse(); this.bandwidth.push([this.totalPlayTime,(this.lastByteRate*8)/1000]) this.bandwidth.shift(); this.av_bandwidth.push([this.totalPlayTime,((this.totalLastByteRate*8)/1000)/this.totalPlayTime]) this.av_bandwidth.shift(); //this.bandwidth.reverse(); this.dom_update() } init (){ var that = this; this.chart_class = 'clappr-bandwidth-analyzer-bandwidthChart'; this.container_class = 'clappr-bandwidth-analyzer'; this.totalPlayTime = 0; this.lastByteRate = 0; this.tmpTotalLastByteRate = 0; this.totalLastByteRate = 0; this.lastFrameCounts = 0; this.tmpTotalFrameCounts = 0; this.totalFrameCounts = 0; this.droppedFrameCount = 0; this.totalDroppedFrameCount = 0; this.bandwidth = []; this.av_bandwidth = []; this.currentTime = Math.floor(new Date().getTime()/1000) this.chart = { updateInterval:30, plot:null } for (var i=0;i<this.options_ba.x_timeDuration;i++){ this.bandwidth.push([i,null]); this.av_bandwidth.push([i,null]); } try{ this.chart.plot = $.plot('.'+this.chart_class, [{ data: this.bandwidth, label: "Bandwidth"}, { data: this.av_bandwidth, label: "Average Bandwidth"}], { //this.chart.plot = $.plot('#'+this.dom_id, [ this.bandwidth ], { grid: { color: '#000000', // => primary color used for outline and labels backgroundColor: null, // => null for transparent, else color tickColor: '#ffffff', // => color used for the ticks labelMargin: 3, // => margin in pixels verticalLines: true, // => whether to show gridlines in vertical direction horizontalLines: true, // => whether to show gridlines in horizontal direction outlineWidth: 2 // => width of the grid outline/border in pixels }, series: { shadowSize: 0, lines: { show: true, fill: false}, points: { show: false, fill: false } }, yaxis: { min: this.options_ba.y_min, max: this.options_ba.y_max, }, xaxis: { show: true, }, colors: [ this.options_ba.bandwidth.color, this.options_ba.averageBandwidth.color], lineWidth:[ this.options_ba.bandwidth.lineWidth, this.options_ba.averageBandwidth.lineWidth] }); }catch(e){ } function appendContent($div, content) { $div.append(content).trigger($.Event('resize')); } this.listenTo(this.core.getCurrentPlayback(), Events.PLAYBACK_TIMEUPDATE, this.analyzer_update) } analyzer_update(){ var now = Math.floor(new Date().getTime()/1000); if (this.currentTime != now){ this.currentTime = now; try{ var playback = this.core.getCurrentPlayback() var video_tag = playback.$el[0] this.update(video_tag.webkitVideoDecodedByteCount, video_tag.webkitDroppedFrameCount, video_tag.webkitDecodedFrameCount) this.chart_update() }catch(e){ this.update(0, 0, 0) } } } chart_update () { this.bandwidth.forEach(function(obj,index){ obj[0] = index }) this.av_bandwidth.forEach(function(obj,index){ obj[0] = index }) this.chart.plot.setData([this.bandwidth, this.av_bandwidth]); this.chart.plot.draw(); } }
その他の修正
srcファルダにpublicフォルダを作成し、①bandwidth-analyzer.html, ②plubin_stover_b.htmlを作成する。
mkdir ./src/public vi ./src/public/bandwidth-analyzer.html vi ./src/public/plubin_stover_b.html
①bandwidth-analyzer.htmlの内容
<div class="clappr-bandwidth-analyzer container border"> <p> <div class="text bandwidth"> <span class="icon mif-film" style="color:#00aba9"> </span><span class="text"></span> </div> <div class="text totalPlayTime"> <span class="icon mif-film" style="color:#00aba9"></span> <span class="text"></span> </div> <div class="text totalDownload"> <span class="icon mif-film" style="color:#00aba9"> </span> <span class="text"></span> </div> <div class="text totalFrames"> <span class="icon mif-film" style="color:#00aba9"></span> <span class="text"></span> </div> <div class="text dropFrames"> <span class="icon mif-film" style="color:#00aba9"></span> <span class="text"></span> </div> </p> <div class="clappr-bandwidth-analyzer-bandwidthChart chart"></div> </div>
②plubin_stover_b.htmlの内容
<button clappr-bandwidth-analyzer class="media-control-button media-control-icon" clappr-bandwidth-analyzer style="width: 180px;margin-left: 60px;font-size: 10px;background: transparent;color: #fff;"> <span>Graph Analyzer</span> </button>
ビルドと確認
npm run build
ビルドすると
dist/clappr-bandwidth-analyzer.js
が作成される。
これとCDNのjquery, jquery flot, jquery flot resize, clapprを使用して、動作を確認する。
<head> <script type="text/javascript" charset="utf-8" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-rc1/jquery.min.js"></script> <script type="text/javascript" charset="utf-8" src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.js"></script> <script type="text/javascript" charset="utf-8" src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.resize.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/clappr/0.2.73/clappr.js"></script> <script type="text/javascript" charset="utf-8" src="clappr-bandwidth-analyzer.js"></script> </head> <body> <div id="player"></div> <script> var player = new Clappr.Player({ source: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8", parentId: "#player", height: 600, width: 800, plugins: [ClapprBandwidthAnalyzer], 'bandwidthAnalyzer':{ 'width': '50%', //width of chart container 'height': '40%', //height of chart container 'border' : '2px solid #00aba9!important', //border css of chart container 'background': 'rgba(60,63,65,.7)', //background css of chart container 'y_max': 15000, //chart yaxis max value 'y_min': 0, //chart yaxis min value 'x_timeDuration': 60, //chart xaxis is duration in seconds 'bandwidth':{ 'lineWidth': 1, 'color': '#0f0' //bandwidth line color }, 'averageBandwidth':{ 'lineWidth':1, 'color':'#f00' //Average bandwidth line color } } }); </script> </body>