jellyfish-web/dashboard-ui/bower_components/hls.js/src/controller/abr-controller.js

87 lines
2.6 KiB
JavaScript
Raw Normal View History

2015-12-16 00:30:14 -05:00
/*
* simple ABR Controller
*/
import Event from '../events';
2016-01-18 14:07:26 -05:00
import EventHandler from '../event-handler';
2015-12-16 00:30:14 -05:00
2016-01-18 14:07:26 -05:00
class AbrController extends EventHandler {
2015-12-16 00:30:14 -05:00
constructor(hls) {
2016-01-18 14:07:26 -05:00
super(hls, Event.FRAG_LOAD_PROGRESS);
2015-12-16 00:30:14 -05:00
this.lastfetchlevel = 0;
this._autoLevelCapping = -1;
this._nextAutoLevel = -1;
}
destroy() {
2016-01-18 14:07:26 -05:00
EventHandler.prototype.destroy.call(this);
2015-12-16 00:30:14 -05:00
}
2016-01-18 14:07:26 -05:00
onFragLoadProgress(data) {
2015-12-16 00:30:14 -05:00
var stats = data.stats;
2016-02-24 22:15:07 -05:00
// only update stats if first frag loading
// if same frag is loaded multiple times, it might be in browser cache, and loaded quickly
// and leading to wrong bw estimation
if (stats.aborted === undefined && data.frag.loadCounter === 1) {
2015-12-16 00:30:14 -05:00
this.lastfetchduration = (performance.now() - stats.trequest) / 1000;
this.lastfetchlevel = data.frag.level;
this.lastbw = (stats.loaded * 8) / this.lastfetchduration;
//console.log(`fetchDuration:${this.lastfetchduration},bw:${(this.lastbw/1000).toFixed(0)}/${stats.aborted}`);
}
}
/** Return the capping/max level value that could be used by automatic level selection algorithm **/
get autoLevelCapping() {
return this._autoLevelCapping;
}
/** set the capping/max level value that could be used by automatic level selection algorithm **/
set autoLevelCapping(newLevel) {
this._autoLevelCapping = newLevel;
}
get nextAutoLevel() {
var lastbw = this.lastbw, hls = this.hls,adjustedbw, i, maxAutoLevel;
if (this._autoLevelCapping === -1) {
maxAutoLevel = hls.levels.length - 1;
} else {
maxAutoLevel = this._autoLevelCapping;
}
if (this._nextAutoLevel !== -1) {
var nextLevel = Math.min(this._nextAutoLevel,maxAutoLevel);
if (nextLevel === this.lastfetchlevel) {
this._nextAutoLevel = -1;
} else {
return nextLevel;
}
}
// follow algorithm captured from stagefright :
// https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/httplive/LiveSession.cpp
// Pick the highest bandwidth stream below or equal to estimated bandwidth.
for (i = 0; i <= maxAutoLevel; i++) {
// consider only 80% of the available bandwidth, but if we are switching up,
// be even more conservative (70%) to avoid overestimating and immediately
// switching back.
if (i <= this.lastfetchlevel) {
adjustedbw = 0.8 * lastbw;
} else {
adjustedbw = 0.7 * lastbw;
}
if (adjustedbw < hls.levels[i].bitrate) {
return Math.max(0, i - 1);
}
}
return i - 1;
}
set nextAutoLevel(nextLevel) {
this._nextAutoLevel = nextLevel;
}
}
export default AbrController;