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>