update components
This commit is contained in:
parent
047fd2b438
commit
6f96e87248
22 changed files with 472 additions and 303 deletions
|
@ -15,12 +15,12 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
"ignore": [],
|
"ignore": [],
|
||||||
"version": "1.0.20",
|
"version": "1.0.21",
|
||||||
"_release": "1.0.20",
|
"_release": "1.0.21",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "1.0.20",
|
"tag": "1.0.21",
|
||||||
"commit": "b88c3533403d7fc921adb381c81917c80d9c4e77"
|
"commit": "dd73237b9d554d45a664e820042804c6d129d280"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/MediaBrowser/emby-webcomponents.git",
|
"_source": "git://github.com/MediaBrowser/emby-webcomponents.git",
|
||||||
"_target": "~1.0.0",
|
"_target": "~1.0.0",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
define(['browser'], function (browser) {
|
define(['browser'], function (browser) {
|
||||||
|
|
||||||
function canPlayH264() {
|
function canPlayH264() {
|
||||||
var v = document.createElement('video');
|
var v = document.createElement('video');
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
function canPlayHls(src) {
|
function canPlayHls(src) {
|
||||||
|
|
||||||
if (_canPlayHls == null) {
|
if (_canPlayHls == null) {
|
||||||
_canPlayHls = window.MediaSource != null || canPlayNativeHls();
|
_canPlayHls = canPlayNativeHls() || canPlayHlsWithMSE();
|
||||||
}
|
}
|
||||||
return _canPlayHls;
|
return _canPlayHls;
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,15 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function canPlayHlsWithMSE() {
|
||||||
|
if (window.MediaSource != null) {
|
||||||
|
// text tracks don’t work with this in firefox
|
||||||
|
return !browser.firefox;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return function () {
|
return function () {
|
||||||
|
|
||||||
var bitrateSetting = 100000000;
|
var bitrateSetting = 100000000;
|
||||||
|
|
13
dashboard-ui/bower_components/hls.js/.bower.json
vendored
13
dashboard-ui/bower_components/hls.js/.bower.json
vendored
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"name": "hls.js",
|
"name": "hls.js",
|
||||||
"version": "0.4.5",
|
"version": "0.4.6",
|
||||||
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
||||||
"homepage": "https://github.com/dailymotion/hls.js",
|
"homepage": "https://github.com/dailymotion/hls.js",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Guillaume du Pontavice <guillaume.dupontavice@dailymotion.com>"
|
"Guillaume du Pontavice <guillaume.dupontavice@dailymotion.com>"
|
||||||
],
|
],
|
||||||
"main": "dist/hls.js",
|
"main": "dist/hls.js",
|
||||||
"private": true,
|
"private": false,
|
||||||
"ignore": [
|
"ignore": [
|
||||||
"**/.*",
|
"**/.*",
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
@ -15,14 +15,13 @@
|
||||||
"test",
|
"test",
|
||||||
"tests"
|
"tests"
|
||||||
],
|
],
|
||||||
"_release": "0.4.5",
|
"_release": "0.4.6",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "v0.4.5",
|
"tag": "v0.4.6",
|
||||||
"commit": "908ac4a44a182bdbede9c1830828983c18532ca0"
|
"commit": "eb4bfb0ebadda9797d8020e7b3a2d2c699444cab"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/dailymotion/hls.js.git",
|
"_source": "git://github.com/dailymotion/hls.js.git",
|
||||||
"_target": "~0.4.5",
|
"_target": "~0.4.5",
|
||||||
"_originalSource": "dailymotion/hls.js",
|
"_originalSource": "dailymotion/hls.js"
|
||||||
"_direct": true
|
|
||||||
}
|
}
|
18
dashboard-ui/bower_components/hls.js/API.md
vendored
18
dashboard-ui/bower_components/hls.js/API.md
vendored
|
@ -186,6 +186,8 @@ configuration parameters could be provided to hls.js upon instantiation of Hls O
|
||||||
maxBufferLength : 30,
|
maxBufferLength : 30,
|
||||||
maxMaxBufferLength : 600,
|
maxMaxBufferLength : 600,
|
||||||
maxBufferSize : 60*1000*1000,
|
maxBufferSize : 60*1000*1000,
|
||||||
|
maxBufferHole : 0.3,
|
||||||
|
maxSeekHole : 2,
|
||||||
liveSyncDurationCount : 3,
|
liveSyncDurationCount : 3,
|
||||||
liveMaxLatencyDurationCount: 10,
|
liveMaxLatencyDurationCount: 10,
|
||||||
enableWorker : true,
|
enableWorker : true,
|
||||||
|
@ -240,6 +242,20 @@ this is the guaranteed buffer length hls.js will try to reach, regardless of max
|
||||||
|
|
||||||
'minimum' maximum buffer size in bytes. if buffer size upfront is bigger than this value, no fragment will be loaded.
|
'minimum' maximum buffer size in bytes. if buffer size upfront is bigger than this value, no fragment will be loaded.
|
||||||
|
|
||||||
|
#### ```maxBufferHole```
|
||||||
|
(default 0.3s)
|
||||||
|
|
||||||
|
'maximum' inter-fragment buffer hole tolerance that hls.js can cope with.
|
||||||
|
When switching between quality level, fragments might not be perfectly aligned.
|
||||||
|
This could result in small overlapping or hole in media buffer. This tolerance factor helps cope with this.
|
||||||
|
|
||||||
|
#### ```maxSeekHole```
|
||||||
|
(default 2s)
|
||||||
|
|
||||||
|
in case playback is stalled, and a buffered range is available upfront, less than maxSeekHole seconds from current media position,
|
||||||
|
hls.js will jump over this buffer hole to reach the beginning of this following buffered range.
|
||||||
|
```maxSeekHole``` allows to configure this jumpable threshold.
|
||||||
|
|
||||||
#### ```maxMaxBufferLength```
|
#### ```maxMaxBufferLength```
|
||||||
(default 600s)
|
(default 600s)
|
||||||
|
|
||||||
|
@ -499,7 +515,7 @@ full list of Events available below :
|
||||||
- `Hls.Events.LEVEL_PTS_UPDATED` - fired when a level's PTS information has been updated after parsing a fragment
|
- `Hls.Events.LEVEL_PTS_UPDATED` - fired when a level's PTS information has been updated after parsing a fragment
|
||||||
- data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }
|
- data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }
|
||||||
- `Hls.Events.LEVEL_SWITCH` - fired when a level switch is requested
|
- `Hls.Events.LEVEL_SWITCH` - fired when a level switch is requested
|
||||||
- data: { levelId : id of new level }
|
- data: { level : id of new level, it is the index of the array `Hls.levels` }
|
||||||
- `Hls.Events.KEY_LOADING` - fired when a decryption key loading starts
|
- `Hls.Events.KEY_LOADING` - fired when a decryption key loading starts
|
||||||
- data: { frag : fragment object}
|
- data: { frag : fragment object}
|
||||||
- `Hls.Events.KEY_LOADED` - fired when a decryption key loading is completed
|
- `Hls.Events.KEY_LOADED` - fired when a decryption key loading is completed
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"name": "hls.js",
|
"name": "hls.js",
|
||||||
"version": "0.4.5",
|
"version": "0.4.6",
|
||||||
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
||||||
"homepage": "https://github.com/dailymotion/hls.js",
|
"homepage": "https://github.com/dailymotion/hls.js",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Guillaume du Pontavice <guillaume.dupontavice@dailymotion.com>"
|
"Guillaume du Pontavice <guillaume.dupontavice@dailymotion.com>"
|
||||||
],
|
],
|
||||||
"main": "dist/hls.js",
|
"main": "dist/hls.js",
|
||||||
"private": true,
|
"private": false,
|
||||||
"ignore": [
|
"ignore": [
|
||||||
"**/.*",
|
"**/.*",
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
|
|
@ -718,14 +718,6 @@ function timeRangesToString(r) {
|
||||||
events.buffer.push(event);
|
events.buffer.push(event);
|
||||||
refreshCanvas();
|
refreshCanvas();
|
||||||
|
|
||||||
var decodedFrames, droppedFrames;
|
|
||||||
if(navigator.userAgent.toLowerCase().indexOf('firefox') !== -1) {
|
|
||||||
decodedFrames = v.mozDecodedFrames;
|
|
||||||
droppedFrames = v.mozParsedFrames-v.mozPresentedFrames;
|
|
||||||
} else {
|
|
||||||
decodedFrames = v.webkitDecodedFrameCount;
|
|
||||||
droppedFrames = v.webkitDroppedFrameCount;
|
|
||||||
}
|
|
||||||
var log = "Duration:"
|
var log = "Duration:"
|
||||||
+ v.duration + "<br>"
|
+ v.duration + "<br>"
|
||||||
+ "Buffered:"
|
+ "Buffered:"
|
||||||
|
@ -733,11 +725,16 @@ function timeRangesToString(r) {
|
||||||
+ "Seekable:"
|
+ "Seekable:"
|
||||||
+ timeRangesToString(v.seekable) + "<br>"
|
+ timeRangesToString(v.seekable) + "<br>"
|
||||||
+ "Played:"
|
+ "Played:"
|
||||||
+ timeRangesToString(v.played) + "<br>"
|
+ timeRangesToString(v.played) + "<br>";
|
||||||
+ "Decoded Frames:"
|
|
||||||
+ decodedFrames + "<br>"
|
|
||||||
+ "Dropped Frames:"
|
var videoPlaybackQuality = v.getVideoPlaybackQuality;
|
||||||
+ droppedFrames + "<br>";
|
if(videoPlaybackQuality && typeof(videoPlaybackQuality) === typeof(Function)) {
|
||||||
|
log+="Dropped Frames:"+ v.getVideoPlaybackQuality().droppedVideoFrames + "<br>";
|
||||||
|
log+="Corrupted Frames:"+ v.getVideoPlaybackQuality().corruptedVideoFrames + "<br>";
|
||||||
|
} else if(v.webkitDroppedFrameCount) {
|
||||||
|
log+="Dropped Frames:"+ v.webkitDroppedFrameCount + "<br>";
|
||||||
|
}
|
||||||
$("#buffered_log").html(log);
|
$("#buffered_log").html(log);
|
||||||
$("#HlsStats").text(JSON.stringify(sortObject(stats),null,"\t"));
|
$("#HlsStats").text(JSON.stringify(sortObject(stats),null,"\t"));
|
||||||
ctx.fillStyle = "blue";
|
ctx.fillStyle = "blue";
|
||||||
|
|
398
dashboard-ui/bower_components/hls.js/dist/hls.js
vendored
398
dashboard-ui/bower_components/hls.js/dist/hls.js
vendored
|
@ -371,34 +371,42 @@ Object.defineProperty(exports, '__esModule', {
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||||
|
|
||||||
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||||||
|
|
||||||
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||||
|
|
||||||
var _events = require('../events');
|
var _events = require('../events');
|
||||||
|
|
||||||
var _events2 = _interopRequireDefault(_events);
|
var _events2 = _interopRequireDefault(_events);
|
||||||
|
|
||||||
var AbrController = (function () {
|
var _eventHandler = require('../event-handler');
|
||||||
|
|
||||||
|
var _eventHandler2 = _interopRequireDefault(_eventHandler);
|
||||||
|
|
||||||
|
var AbrController = (function (_EventHandler) {
|
||||||
|
_inherits(AbrController, _EventHandler);
|
||||||
|
|
||||||
function AbrController(hls) {
|
function AbrController(hls) {
|
||||||
_classCallCheck(this, AbrController);
|
_classCallCheck(this, AbrController);
|
||||||
|
|
||||||
this.hls = hls;
|
_get(Object.getPrototypeOf(AbrController.prototype), 'constructor', this).call(this, hls, _events2['default'].FRAG_LOAD_PROGRESS);
|
||||||
this.lastfetchlevel = 0;
|
this.lastfetchlevel = 0;
|
||||||
this._autoLevelCapping = -1;
|
this._autoLevelCapping = -1;
|
||||||
this._nextAutoLevel = -1;
|
this._nextAutoLevel = -1;
|
||||||
this.onflp = this.onFragmentLoadProgress.bind(this);
|
|
||||||
hls.on(_events2['default'].FRAG_LOAD_PROGRESS, this.onflp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_createClass(AbrController, [{
|
_createClass(AbrController, [{
|
||||||
key: 'destroy',
|
key: 'destroy',
|
||||||
value: function destroy() {
|
value: function destroy() {
|
||||||
this.hls.off(_events2['default'].FRAG_LOAD_PROGRESS, this.onflp);
|
_eventHandler2['default'].prototype.destroy.call(this);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onFragmentLoadProgress',
|
key: 'onFragLoadProgress',
|
||||||
value: function onFragmentLoadProgress(event, data) {
|
value: function onFragLoadProgress(data) {
|
||||||
var stats = data.stats;
|
var stats = data.stats;
|
||||||
if (stats.aborted === undefined) {
|
if (stats.aborted === undefined) {
|
||||||
this.lastfetchduration = (performance.now() - stats.trequest) / 1000;
|
this.lastfetchduration = (performance.now() - stats.trequest) / 1000;
|
||||||
|
@ -466,12 +474,12 @@ var AbrController = (function () {
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
return AbrController;
|
return AbrController;
|
||||||
})();
|
})(_eventHandler2['default']);
|
||||||
|
|
||||||
exports['default'] = AbrController;
|
exports['default'] = AbrController;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../events":18}],4:[function(require,module,exports){
|
},{"../event-handler":18,"../events":19}],4:[function(require,module,exports){
|
||||||
/*
|
/*
|
||||||
* Level Controller
|
* Level Controller
|
||||||
*/
|
*/
|
||||||
|
@ -484,40 +492,40 @@ Object.defineProperty(exports, '__esModule', {
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||||
|
|
||||||
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||||||
|
|
||||||
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||||
|
|
||||||
var _events = require('../events');
|
var _events = require('../events');
|
||||||
|
|
||||||
var _events2 = _interopRequireDefault(_events);
|
var _events2 = _interopRequireDefault(_events);
|
||||||
|
|
||||||
|
var _eventHandler = require('../event-handler');
|
||||||
|
|
||||||
|
var _eventHandler2 = _interopRequireDefault(_eventHandler);
|
||||||
|
|
||||||
var _utilsLogger = require('../utils/logger');
|
var _utilsLogger = require('../utils/logger');
|
||||||
|
|
||||||
var _errors = require('../errors');
|
var _errors = require('../errors');
|
||||||
|
|
||||||
var LevelController = (function () {
|
var LevelController = (function (_EventHandler) {
|
||||||
|
_inherits(LevelController, _EventHandler);
|
||||||
|
|
||||||
function LevelController(hls) {
|
function LevelController(hls) {
|
||||||
_classCallCheck(this, LevelController);
|
_classCallCheck(this, LevelController);
|
||||||
|
|
||||||
this.hls = hls;
|
_get(Object.getPrototypeOf(LevelController.prototype), 'constructor', this).call(this, hls, _events2['default'].MANIFEST_LOADED, _events2['default'].LEVEL_LOADED, _events2['default'].ERROR);
|
||||||
this.onml = this.onManifestLoaded.bind(this);
|
|
||||||
this.onll = this.onLevelLoaded.bind(this);
|
|
||||||
this.onerr = this.onError.bind(this);
|
|
||||||
this.ontick = this.tick.bind(this);
|
this.ontick = this.tick.bind(this);
|
||||||
hls.on(_events2['default'].MANIFEST_LOADED, this.onml);
|
|
||||||
hls.on(_events2['default'].LEVEL_LOADED, this.onll);
|
|
||||||
hls.on(_events2['default'].ERROR, this.onerr);
|
|
||||||
this._manualLevel = this._autoLevelCapping = -1;
|
this._manualLevel = this._autoLevelCapping = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_createClass(LevelController, [{
|
_createClass(LevelController, [{
|
||||||
key: 'destroy',
|
key: 'destroy',
|
||||||
value: function destroy() {
|
value: function destroy() {
|
||||||
var hls = this.hls;
|
|
||||||
hls.off(_events2['default'].MANIFEST_LOADED, this.onml);
|
|
||||||
hls.off(_events2['default'].LEVEL_LOADED, this.onll);
|
|
||||||
hls.off(_events2['default'].ERROR, this.onerr);
|
|
||||||
if (this.timer) {
|
if (this.timer) {
|
||||||
clearInterval(this.timer);
|
clearInterval(this.timer);
|
||||||
}
|
}
|
||||||
|
@ -525,7 +533,7 @@ var LevelController = (function () {
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onManifestLoaded',
|
key: 'onManifestLoaded',
|
||||||
value: function onManifestLoaded(event, data) {
|
value: function onManifestLoaded(data) {
|
||||||
var levels0 = [],
|
var levels0 = [],
|
||||||
levels = [],
|
levels = [],
|
||||||
bitrateStart,
|
bitrateStart,
|
||||||
|
@ -626,7 +634,7 @@ var LevelController = (function () {
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onError',
|
key: 'onError',
|
||||||
value: function onError(event, data) {
|
value: function onError(data) {
|
||||||
if (data.fatal) {
|
if (data.fatal) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -688,7 +696,7 @@ var LevelController = (function () {
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onLevelLoaded',
|
key: 'onLevelLoaded',
|
||||||
value: function onLevelLoaded(event, data) {
|
value: function onLevelLoaded(data) {
|
||||||
// check if current playlist is a live playlist
|
// check if current playlist is a live playlist
|
||||||
if (data.details.live && !this.timer) {
|
if (data.details.live && !this.timer) {
|
||||||
// if live playlist we will have to reload it periodically
|
// if live playlist we will have to reload it periodically
|
||||||
|
@ -769,12 +777,12 @@ var LevelController = (function () {
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
return LevelController;
|
return LevelController;
|
||||||
})();
|
})(_eventHandler2['default']);
|
||||||
|
|
||||||
exports['default'] = LevelController;
|
exports['default'] = LevelController;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../errors":17,"../events":18,"../utils/logger":28}],5:[function(require,module,exports){
|
},{"../errors":17,"../event-handler":18,"../events":19,"../utils/logger":29}],5:[function(require,module,exports){
|
||||||
/*
|
/*
|
||||||
* MSE Media Controller
|
* MSE Media Controller
|
||||||
*/
|
*/
|
||||||
|
@ -787,10 +795,14 @@ Object.defineProperty(exports, '__esModule', {
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||||
|
|
||||||
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||||||
|
|
||||||
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||||
|
|
||||||
var _demuxDemuxer = require('../demux/demuxer');
|
var _demuxDemuxer = require('../demux/demuxer');
|
||||||
|
|
||||||
var _demuxDemuxer2 = _interopRequireDefault(_demuxDemuxer);
|
var _demuxDemuxer2 = _interopRequireDefault(_demuxDemuxer);
|
||||||
|
@ -799,6 +811,10 @@ var _events = require('../events');
|
||||||
|
|
||||||
var _events2 = _interopRequireDefault(_events);
|
var _events2 = _interopRequireDefault(_events);
|
||||||
|
|
||||||
|
var _eventHandler = require('../event-handler');
|
||||||
|
|
||||||
|
var _eventHandler2 = _interopRequireDefault(_eventHandler);
|
||||||
|
|
||||||
var _utilsLogger = require('../utils/logger');
|
var _utilsLogger = require('../utils/logger');
|
||||||
|
|
||||||
var _utilsBinarySearch = require('../utils/binary-search');
|
var _utilsBinarySearch = require('../utils/binary-search');
|
||||||
|
@ -825,42 +841,27 @@ var State = {
|
||||||
BUFFER_FLUSHING: 8
|
BUFFER_FLUSHING: 8
|
||||||
};
|
};
|
||||||
|
|
||||||
var MSEMediaController = (function () {
|
var MSEMediaController = (function (_EventHandler) {
|
||||||
|
_inherits(MSEMediaController, _EventHandler);
|
||||||
|
|
||||||
function MSEMediaController(hls) {
|
function MSEMediaController(hls) {
|
||||||
_classCallCheck(this, MSEMediaController);
|
_classCallCheck(this, MSEMediaController);
|
||||||
|
|
||||||
|
_get(Object.getPrototypeOf(MSEMediaController.prototype), 'constructor', this).call(this, hls, _events2['default'].MEDIA_ATTACHING, _events2['default'].MEDIA_DETACHING, _events2['default'].MANIFEST_PARSED, _events2['default'].LEVEL_LOADED, _events2['default'].KEY_LOADED, _events2['default'].FRAG_LOADED, _events2['default'].FRAG_PARSING_INIT_SEGMENT, _events2['default'].FRAG_PARSING_DATA, _events2['default'].FRAG_PARSED, _events2['default'].ERROR);
|
||||||
this.config = hls.config;
|
this.config = hls.config;
|
||||||
this.audioCodecSwap = false;
|
this.audioCodecSwap = false;
|
||||||
this.hls = hls;
|
|
||||||
this.ticks = 0;
|
this.ticks = 0;
|
||||||
// Source Buffer listeners
|
// Source Buffer listeners
|
||||||
this.onsbue = this.onSBUpdateEnd.bind(this);
|
this.onsbue = this.onSBUpdateEnd.bind(this);
|
||||||
this.onsbe = this.onSBUpdateError.bind(this);
|
this.onsbe = this.onSBUpdateError.bind(this);
|
||||||
// internal listeners
|
|
||||||
this.onmediaatt0 = this.onMediaAttaching.bind(this);
|
|
||||||
this.onmediadet0 = this.onMediaDetaching.bind(this);
|
|
||||||
this.onmp = this.onManifestParsed.bind(this);
|
|
||||||
this.onll = this.onLevelLoaded.bind(this);
|
|
||||||
this.onfl = this.onFragLoaded.bind(this);
|
|
||||||
this.onkl = this.onKeyLoaded.bind(this);
|
|
||||||
this.onis = this.onInitSegment.bind(this);
|
|
||||||
this.onfpg = this.onFragParsing.bind(this);
|
|
||||||
this.onfp = this.onFragParsed.bind(this);
|
|
||||||
this.onerr = this.onError.bind(this);
|
|
||||||
this.ontick = this.tick.bind(this);
|
this.ontick = this.tick.bind(this);
|
||||||
hls.on(_events2['default'].MEDIA_ATTACHING, this.onmediaatt0);
|
|
||||||
hls.on(_events2['default'].MEDIA_DETACHING, this.onmediadet0);
|
|
||||||
hls.on(_events2['default'].MANIFEST_PARSED, this.onmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_createClass(MSEMediaController, [{
|
_createClass(MSEMediaController, [{
|
||||||
key: 'destroy',
|
key: 'destroy',
|
||||||
value: function destroy() {
|
value: function destroy() {
|
||||||
this.stop();
|
this.stop();
|
||||||
var hls = this.hls;
|
_eventHandler2['default'].prototype.destroy.call(this);
|
||||||
hls.off(_events2['default'].MEDIA_ATTACHING, this.onmediaatt0);
|
|
||||||
hls.off(_events2['default'].MEDIA_DETACHING, this.onmediadet0);
|
|
||||||
hls.off(_events2['default'].MANIFEST_PARSED, this.onmp);
|
|
||||||
this.state = State.IDLE;
|
this.state = State.IDLE;
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
@ -894,13 +895,6 @@ var MSEMediaController = (function () {
|
||||||
this.timer = setInterval(this.ontick, 100);
|
this.timer = setInterval(this.ontick, 100);
|
||||||
this.level = -1;
|
this.level = -1;
|
||||||
this.fragLoadError = 0;
|
this.fragLoadError = 0;
|
||||||
hls.on(_events2['default'].FRAG_LOADED, this.onfl);
|
|
||||||
hls.on(_events2['default'].FRAG_PARSING_INIT_SEGMENT, this.onis);
|
|
||||||
hls.on(_events2['default'].FRAG_PARSING_DATA, this.onfpg);
|
|
||||||
hls.on(_events2['default'].FRAG_PARSED, this.onfp);
|
|
||||||
hls.on(_events2['default'].ERROR, this.onerr);
|
|
||||||
hls.on(_events2['default'].LEVEL_LOADED, this.onll);
|
|
||||||
hls.on(_events2['default'].KEY_LOADED, this.onkl);
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'stop',
|
key: 'stop',
|
||||||
|
@ -935,14 +929,6 @@ var MSEMediaController = (function () {
|
||||||
this.demuxer.destroy();
|
this.demuxer.destroy();
|
||||||
this.demuxer = null;
|
this.demuxer = null;
|
||||||
}
|
}
|
||||||
var hls = this.hls;
|
|
||||||
hls.off(_events2['default'].FRAG_LOADED, this.onfl);
|
|
||||||
hls.off(_events2['default'].FRAG_PARSED, this.onfp);
|
|
||||||
hls.off(_events2['default'].FRAG_PARSING_DATA, this.onfpg);
|
|
||||||
hls.off(_events2['default'].LEVEL_LOADED, this.onll);
|
|
||||||
hls.off(_events2['default'].KEY_LOADED, this.onkl);
|
|
||||||
hls.off(_events2['default'].FRAG_PARSING_INIT_SEGMENT, this.onis);
|
|
||||||
hls.off(_events2['default'].ERROR, this.onerr);
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'tick',
|
key: 'tick',
|
||||||
|
@ -1001,7 +987,7 @@ var MSEMediaController = (function () {
|
||||||
// we are not at playback start, get next load level from level Controller
|
// we are not at playback start, get next load level from level Controller
|
||||||
level = hls.nextLoadLevel;
|
level = hls.nextLoadLevel;
|
||||||
}
|
}
|
||||||
var bufferInfo = this.bufferInfo(pos, 0.3),
|
var bufferInfo = this.bufferInfo(pos, this.config.maxBufferHole),
|
||||||
bufferLen = bufferInfo.len,
|
bufferLen = bufferInfo.len,
|
||||||
bufferEnd = bufferInfo.end,
|
bufferEnd = bufferInfo.end,
|
||||||
fragPrevious = this.fragPrevious,
|
fragPrevious = this.fragPrevious,
|
||||||
|
@ -1020,7 +1006,9 @@ var MSEMediaController = (function () {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
levelDetails = this.levels[level].details;
|
levelDetails = this.levels[level].details;
|
||||||
// if level info not retrieved yet, switch state and wait for level retrieval
|
// if level info not retrieved yet, switch state and wait for level retrieval
|
||||||
if (typeof levelDetails === 'undefined') {
|
// if live playlist, ensure that new playlist has been refreshed to avoid loading/try to load
|
||||||
|
// a useless and outdated fragment (that might even introduce load error if it is already out of the live playlist)
|
||||||
|
if (typeof levelDetails === 'undefined' || levelDetails.live && this.levelLastLoaded !== level) {
|
||||||
this.state = State.WAITING_LEVEL;
|
this.state = State.WAITING_LEVEL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1176,7 +1164,7 @@ var MSEMediaController = (function () {
|
||||||
}
|
}
|
||||||
pos = v.currentTime;
|
pos = v.currentTime;
|
||||||
var fragLoadedDelay = (frag.expectedLen - frag.loaded) / loadRate;
|
var fragLoadedDelay = (frag.expectedLen - frag.loaded) / loadRate;
|
||||||
var bufferStarvationDelay = this.bufferInfo(pos, 0.3).end - pos;
|
var bufferStarvationDelay = this.bufferInfo(pos, this.config.maxBufferHole).end - pos;
|
||||||
var fragLevelNextLoadedDelay = frag.duration * this.levels[hls.nextLoadLevel].bitrate / (8 * loadRate); //bps/Bps
|
var fragLevelNextLoadedDelay = frag.duration * this.levels[hls.nextLoadLevel].bitrate / (8 * loadRate); //bps/Bps
|
||||||
/* if we have less than 2 frag duration in buffer and if frag loaded delay is greater than buffer starvation delay
|
/* if we have less than 2 frag duration in buffer and if frag loaded delay is greater than buffer starvation delay
|
||||||
... and also bigger than duration needed to load fragment at next level ...*/
|
... and also bigger than duration needed to load fragment at next level ...*/
|
||||||
|
@ -1363,6 +1351,7 @@ var MSEMediaController = (function () {
|
||||||
bufferLen = bufferEnd - pos;
|
bufferLen = bufferEnd - pos;
|
||||||
} else if (pos + maxHoleDuration < start) {
|
} else if (pos + maxHoleDuration < start) {
|
||||||
bufferStartNext = start;
|
bufferStartNext = start;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { len: bufferLen, start: bufferStart, end: bufferEnd, nextStart: bufferStartNext };
|
return { len: bufferLen, start: bufferStart, end: bufferEnd, nextStart: bufferStartNext };
|
||||||
|
@ -1605,7 +1594,7 @@ var MSEMediaController = (function () {
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onMediaAttaching',
|
key: 'onMediaAttaching',
|
||||||
value: function onMediaAttaching(event, data) {
|
value: function onMediaAttaching(data) {
|
||||||
var media = this.media = data.media;
|
var media = this.media = data.media;
|
||||||
// setup the media source
|
// setup the media source
|
||||||
var ms = this.mediaSource = new MediaSource();
|
var ms = this.mediaSource = new MediaSource();
|
||||||
|
@ -1680,7 +1669,7 @@ var MSEMediaController = (function () {
|
||||||
if (this.state === State.FRAG_LOADING) {
|
if (this.state === State.FRAG_LOADING) {
|
||||||
// check if currently loaded fragment is inside buffer.
|
// check if currently loaded fragment is inside buffer.
|
||||||
//if outside, cancel fragment loading, otherwise do nothing
|
//if outside, cancel fragment loading, otherwise do nothing
|
||||||
if (this.bufferInfo(this.media.currentTime, 0.3).len === 0) {
|
if (this.bufferInfo(this.media.currentTime, this.config.maxBufferHole).len === 0) {
|
||||||
_utilsLogger.logger.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
|
_utilsLogger.logger.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
|
||||||
var fragCurrent = this.fragCurrent;
|
var fragCurrent = this.fragCurrent;
|
||||||
if (fragCurrent) {
|
if (fragCurrent) {
|
||||||
|
@ -1732,7 +1721,7 @@ var MSEMediaController = (function () {
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onManifestParsed',
|
key: 'onManifestParsed',
|
||||||
value: function onManifestParsed(event, data) {
|
value: function onManifestParsed(data) {
|
||||||
var aac = false,
|
var aac = false,
|
||||||
heaac = false,
|
heaac = false,
|
||||||
codecs;
|
codecs;
|
||||||
|
@ -1761,13 +1750,14 @@ var MSEMediaController = (function () {
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onLevelLoaded',
|
key: 'onLevelLoaded',
|
||||||
value: function onLevelLoaded(event, data) {
|
value: function onLevelLoaded(data) {
|
||||||
var newDetails = data.details,
|
var newDetails = data.details,
|
||||||
newLevelId = data.level,
|
newLevelId = data.level,
|
||||||
curLevel = this.levels[newLevelId],
|
curLevel = this.levels[newLevelId],
|
||||||
duration = newDetails.totalduration;
|
duration = newDetails.totalduration;
|
||||||
|
|
||||||
_utilsLogger.logger.log('level ' + newLevelId + ' loaded [' + newDetails.startSN + ',' + newDetails.endSN + '],duration:' + duration);
|
_utilsLogger.logger.log('level ' + newLevelId + ' loaded [' + newDetails.startSN + ',' + newDetails.endSN + '],duration:' + duration);
|
||||||
|
this.levelLastLoaded = newLevelId;
|
||||||
|
|
||||||
if (newDetails.live) {
|
if (newDetails.live) {
|
||||||
var curDetails = curLevel.details;
|
var curDetails = curLevel.details;
|
||||||
|
@ -1816,7 +1806,7 @@ var MSEMediaController = (function () {
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onFragLoaded',
|
key: 'onFragLoaded',
|
||||||
value: function onFragLoaded(event, data) {
|
value: function onFragLoaded(data) {
|
||||||
var fragCurrent = this.fragCurrent;
|
var fragCurrent = this.fragCurrent;
|
||||||
if (this.state === State.FRAG_LOADING && fragCurrent && data.frag.level === fragCurrent.level && data.frag.sn === fragCurrent.sn) {
|
if (this.state === State.FRAG_LOADING && fragCurrent && data.frag.level === fragCurrent.level && data.frag.sn === fragCurrent.sn) {
|
||||||
if (this.fragBitrateTest === true) {
|
if (this.fragBitrateTest === true) {
|
||||||
|
@ -1854,8 +1844,8 @@ var MSEMediaController = (function () {
|
||||||
this.fragLoadError = 0;
|
this.fragLoadError = 0;
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onInitSegment',
|
key: 'onFragParsingInitSegment',
|
||||||
value: function onInitSegment(event, data) {
|
value: function onFragParsingInitSegment(data) {
|
||||||
if (this.state === State.PARSING) {
|
if (this.state === State.PARSING) {
|
||||||
// check if codecs have been explicitely defined in the master playlist for this level;
|
// check if codecs have been explicitely defined in the master playlist for this level;
|
||||||
// if yes use these ones instead of the ones parsed from the demux
|
// if yes use these ones instead of the ones parsed from the demux
|
||||||
|
@ -1913,8 +1903,8 @@ var MSEMediaController = (function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onFragParsing',
|
key: 'onFragParsingData',
|
||||||
value: function onFragParsing(event, data) {
|
value: function onFragParsingData(data) {
|
||||||
if (this.state === State.PARSING) {
|
if (this.state === State.PARSING) {
|
||||||
this.tparse2 = Date.now();
|
this.tparse2 = Date.now();
|
||||||
var level = this.levels[this.level],
|
var level = this.levels[this.level],
|
||||||
|
@ -1931,7 +1921,7 @@ var MSEMediaController = (function () {
|
||||||
//trigger handler right now
|
//trigger handler right now
|
||||||
this.tick();
|
this.tick();
|
||||||
} else {
|
} else {
|
||||||
_utilsLogger.logger.warn('not in PARSING state, discarding ' + event);
|
_utilsLogger.logger.warn('not in PARSING state, ignoring FRAG_PARSING_DATA event');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
@ -1946,7 +1936,7 @@ var MSEMediaController = (function () {
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onError',
|
key: 'onError',
|
||||||
value: function onError(event, data) {
|
value: function onError(data) {
|
||||||
switch (data.details) {
|
switch (data.details) {
|
||||||
case _errors.ErrorDetails.FRAG_LOAD_ERROR:
|
case _errors.ErrorDetails.FRAG_LOAD_ERROR:
|
||||||
case _errors.ErrorDetails.FRAG_LOAD_TIMEOUT:
|
case _errors.ErrorDetails.FRAG_LOAD_TIMEOUT:
|
||||||
|
@ -1971,7 +1961,7 @@ var MSEMediaController = (function () {
|
||||||
_utilsLogger.logger.error('mediaController: ' + data.details + ' reaches max retry, redispatch as fatal ...');
|
_utilsLogger.logger.error('mediaController: ' + data.details + ' reaches max retry, redispatch as fatal ...');
|
||||||
// redispatch same error but with fatal set to true
|
// redispatch same error but with fatal set to true
|
||||||
data.fatal = true;
|
data.fatal = true;
|
||||||
this.hls.trigger(event, data);
|
this.hls.trigger(_events2['default'].ERROR, data);
|
||||||
this.state = State.ERROR;
|
this.state = State.ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2037,14 +2027,14 @@ var MSEMediaController = (function () {
|
||||||
// playhead moving or media not playing
|
// playhead moving or media not playing
|
||||||
jumpThreshold = 0;
|
jumpThreshold = 0;
|
||||||
} else {
|
} else {
|
||||||
_utilsLogger.logger.trace('playback seems stuck');
|
_utilsLogger.logger.log('playback seems stuck');
|
||||||
}
|
}
|
||||||
// if we are below threshold, try to jump if next buffer range is close
|
// if we are below threshold, try to jump if next buffer range is close
|
||||||
if (bufferInfo.len <= jumpThreshold) {
|
if (bufferInfo.len <= jumpThreshold) {
|
||||||
// no buffer available @ currentTime, check if next buffer is close (more than 5ms diff but within a 300 ms range)
|
// no buffer available @ currentTime, check if next buffer is close (more than 5ms diff but within a config.maxSeekHole second range)
|
||||||
var nextBufferStart = bufferInfo.nextStart,
|
var nextBufferStart = bufferInfo.nextStart,
|
||||||
delta = nextBufferStart - currentTime;
|
delta = nextBufferStart - currentTime;
|
||||||
if (nextBufferStart && delta < 0.3 && delta > 0.005 && !media.seeking) {
|
if (nextBufferStart && delta < this.config.maxSeekHole && delta > 0.005 && !media.seeking) {
|
||||||
// next buffer is close ! adjust currentTime to nextBufferStart
|
// next buffer is close ! adjust currentTime to nextBufferStart
|
||||||
// this will ensure effective video decoding
|
// this will ensure effective video decoding
|
||||||
_utilsLogger.logger.log('adjust currentTime from ' + currentTime + ' to ' + nextBufferStart);
|
_utilsLogger.logger.log('adjust currentTime from ' + currentTime + ' to ' + nextBufferStart);
|
||||||
|
@ -2145,12 +2135,12 @@ var MSEMediaController = (function () {
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
return MSEMediaController;
|
return MSEMediaController;
|
||||||
})();
|
})(_eventHandler2['default']);
|
||||||
|
|
||||||
exports['default'] = MSEMediaController;
|
exports['default'] = MSEMediaController;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../demux/demuxer":13,"../errors":17,"../events":18,"../helper/level-helper":19,"../utils/binary-search":27,"../utils/logger":28}],6:[function(require,module,exports){
|
},{"../demux/demuxer":13,"../errors":17,"../event-handler":18,"../events":19,"../helper/level-helper":20,"../utils/binary-search":28,"../utils/logger":29}],6:[function(require,module,exports){
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* This file contains an adaptation of the AES decryption algorithm
|
* This file contains an adaptation of the AES decryption algorithm
|
||||||
|
@ -2675,7 +2665,7 @@ var Decrypter = (function () {
|
||||||
exports['default'] = Decrypter;
|
exports['default'] = Decrypter;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../errors":17,"../utils/logger":28,"./aes128-decrypter":7}],9:[function(require,module,exports){
|
},{"../errors":17,"../utils/logger":29,"./aes128-decrypter":7}],9:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* AAC demuxer
|
* AAC demuxer
|
||||||
*/
|
*/
|
||||||
|
@ -2804,7 +2794,7 @@ var AACDemuxer = (function () {
|
||||||
exports['default'] = AACDemuxer;
|
exports['default'] = AACDemuxer;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../demux/id3":15,"../utils/logger":28,"./adts":10}],10:[function(require,module,exports){
|
},{"../demux/id3":15,"../utils/logger":29,"./adts":10}],10:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* ADTS parser helper
|
* ADTS parser helper
|
||||||
*/
|
*/
|
||||||
|
@ -2952,7 +2942,7 @@ var ADTS = (function () {
|
||||||
exports['default'] = ADTS;
|
exports['default'] = ADTS;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../errors":17,"../utils/logger":28}],11:[function(require,module,exports){
|
},{"../errors":17,"../utils/logger":29}],11:[function(require,module,exports){
|
||||||
/* inline demuxer.
|
/* inline demuxer.
|
||||||
* probe fragments and instantiate appropriate demuxer depending on content type (TSDemuxer, AACDemuxer, ...)
|
* probe fragments and instantiate appropriate demuxer depending on content type (TSDemuxer, AACDemuxer, ...)
|
||||||
*/
|
*/
|
||||||
|
@ -3024,7 +3014,7 @@ var DemuxerInline = (function () {
|
||||||
exports['default'] = DemuxerInline;
|
exports['default'] = DemuxerInline;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../demux/aacdemuxer":9,"../demux/tsdemuxer":16,"../errors":17,"../events":18}],12:[function(require,module,exports){
|
},{"../demux/aacdemuxer":9,"../demux/tsdemuxer":16,"../errors":17,"../events":19}],12:[function(require,module,exports){
|
||||||
/* demuxer web worker.
|
/* demuxer web worker.
|
||||||
* - listen to worker message, and trigger DemuxerInline upon reception of Fragments.
|
* - listen to worker message, and trigger DemuxerInline upon reception of Fragments.
|
||||||
* - provides MP4 Boxes back to main thread using [transferable objects](https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast) in order to minimize message passing overhead.
|
* - provides MP4 Boxes back to main thread using [transferable objects](https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast) in order to minimize message passing overhead.
|
||||||
|
@ -3131,7 +3121,7 @@ var DemuxerWorker = function DemuxerWorker(self) {
|
||||||
exports['default'] = DemuxerWorker;
|
exports['default'] = DemuxerWorker;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../demux/demuxer-inline":11,"../events":18,"../remux/mp4-remuxer":25,"events":1}],13:[function(require,module,exports){
|
},{"../demux/demuxer-inline":11,"../events":19,"../remux/mp4-remuxer":26,"events":1}],13:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
|
@ -3281,7 +3271,7 @@ var Demuxer = (function () {
|
||||||
exports['default'] = Demuxer;
|
exports['default'] = Demuxer;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../crypt/decrypter":8,"../demux/demuxer-inline":11,"../demux/demuxer-worker":12,"../events":18,"../remux/mp4-remuxer":25,"../utils/logger":28,"webworkify":2}],14:[function(require,module,exports){
|
},{"../crypt/decrypter":8,"../demux/demuxer-inline":11,"../demux/demuxer-worker":12,"../events":19,"../remux/mp4-remuxer":26,"../utils/logger":29,"webworkify":2}],14:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264.
|
* Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264.
|
||||||
*/
|
*/
|
||||||
|
@ -3620,7 +3610,7 @@ var ExpGolomb = (function () {
|
||||||
exports['default'] = ExpGolomb;
|
exports['default'] = ExpGolomb;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../utils/logger":28}],15:[function(require,module,exports){
|
},{"../utils/logger":29}],15:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* ID3 parser
|
* ID3 parser
|
||||||
*/
|
*/
|
||||||
|
@ -3774,7 +3764,7 @@ var ID3 = (function () {
|
||||||
exports['default'] = ID3;
|
exports['default'] = ID3;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../utils/logger":28}],16:[function(require,module,exports){
|
},{"../utils/logger":29}],16:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* highly optimized TS demuxer:
|
* highly optimized TS demuxer:
|
||||||
* parse PAT, PMT
|
* parse PAT, PMT
|
||||||
|
@ -4402,7 +4392,7 @@ var TSDemuxer = (function () {
|
||||||
exports['default'] = TSDemuxer;
|
exports['default'] = TSDemuxer;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../errors":17,"../events":18,"../utils/logger":28,"./adts":10,"./exp-golomb":14}],17:[function(require,module,exports){
|
},{"../errors":17,"../events":19,"../utils/logger":29,"./adts":10,"./exp-golomb":14}],17:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
|
@ -4453,12 +4443,105 @@ var ErrorDetails = {
|
||||||
exports.ErrorDetails = ErrorDetails;
|
exports.ErrorDetails = ErrorDetails;
|
||||||
|
|
||||||
},{}],18:[function(require,module,exports){
|
},{}],18:[function(require,module,exports){
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* All objects in the event handling chain should inherit from this class
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
//import {logger} from './utils/logger';
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
value: true
|
value: true
|
||||||
});
|
});
|
||||||
exports['default'] = {
|
|
||||||
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||||
|
|
||||||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||||||
|
|
||||||
|
var EventHandler = (function () {
|
||||||
|
function EventHandler(hls) {
|
||||||
|
_classCallCheck(this, EventHandler);
|
||||||
|
|
||||||
|
this.hls = hls;
|
||||||
|
this.onEvent = this.onEvent.bind(this);
|
||||||
|
|
||||||
|
for (var _len = arguments.length, events = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
||||||
|
events[_key - 1] = arguments[_key];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.handledEvents = events;
|
||||||
|
this.useGenericHandler = true;
|
||||||
|
|
||||||
|
this.registerListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(EventHandler, [{
|
||||||
|
key: 'destroy',
|
||||||
|
value: function destroy() {
|
||||||
|
this.unregisterListeners();
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'isEventHandler',
|
||||||
|
value: function isEventHandler() {
|
||||||
|
return typeof this.handledEvents === 'object' && this.handledEvents.length && typeof this.onEvent === 'function';
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'registerListeners',
|
||||||
|
value: function registerListeners() {
|
||||||
|
if (this.isEventHandler()) {
|
||||||
|
this.handledEvents.forEach((function (event) {
|
||||||
|
if (event === 'hlsEventGeneric') {
|
||||||
|
throw new Error('Forbidden event name: ' + event);
|
||||||
|
}
|
||||||
|
this.hls.on(event, this.onEvent);
|
||||||
|
}).bind(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'unregisterListeners',
|
||||||
|
value: function unregisterListeners() {
|
||||||
|
if (this.isEventHandler()) {
|
||||||
|
this.handledEvents.forEach((function (event) {
|
||||||
|
this.hls.off(event, this.onEvent);
|
||||||
|
}).bind(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* arguments: event (string), data (any)
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: 'onEvent',
|
||||||
|
value: function onEvent(event, data) {
|
||||||
|
this.onEventGeneric(event, data);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'onEventGeneric',
|
||||||
|
value: function onEventGeneric(event, data) {
|
||||||
|
var eventToFunction = function eventToFunction(event, data) {
|
||||||
|
var funcName = 'on' + event.replace('hls', '');
|
||||||
|
if (typeof this[funcName] !== 'function') {
|
||||||
|
throw new Error('Event ' + event + ' has no generic handler in this ' + this.constructor.name + ' class (tried ' + funcName + ')');
|
||||||
|
}
|
||||||
|
return this[funcName].bind(this, data);
|
||||||
|
};
|
||||||
|
eventToFunction.call(this, event, data).call();
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return EventHandler;
|
||||||
|
})();
|
||||||
|
|
||||||
|
exports['default'] = EventHandler;
|
||||||
|
module.exports = exports['default'];
|
||||||
|
|
||||||
|
},{}],19:[function(require,module,exports){
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
// fired before MediaSource is attaching to media element - data: { media }
|
// fired before MediaSource is attaching to media element - data: { media }
|
||||||
MEDIA_ATTACHING: 'hlsMediaAttaching',
|
MEDIA_ATTACHING: 'hlsMediaAttaching',
|
||||||
// fired when MediaSource has been succesfully attached to media element - data: { }
|
// fired when MediaSource has been succesfully attached to media element - data: { }
|
||||||
|
@ -4480,7 +4563,7 @@ exports['default'] = {
|
||||||
// fired when a level's details have been updated based on previous details, after it has been loaded. - data: { details : levelDetails object, level : id of updated level }
|
// fired when a level's details have been updated based on previous details, after it has been loaded. - data: { details : levelDetails object, level : id of updated level }
|
||||||
LEVEL_UPDATED: 'hlsLevelUpdated',
|
LEVEL_UPDATED: 'hlsLevelUpdated',
|
||||||
// fired when a level's PTS information has been updated after parsing a fragment - data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }
|
// fired when a level's PTS information has been updated after parsing a fragment - data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }
|
||||||
LEVEL_PTS_UPDATED: 'hlsPTSUpdated',
|
LEVEL_PTS_UPDATED: 'hlsLevelPtsUpdated',
|
||||||
// fired when a level switch is requested - data: { level : id of new level }
|
// fired when a level switch is requested - data: { level : id of new level }
|
||||||
LEVEL_SWITCH: 'hlsLevelSwitch',
|
LEVEL_SWITCH: 'hlsLevelSwitch',
|
||||||
// fired when a fragment loading starts - data: { frag : fragment object}
|
// fired when a fragment loading starts - data: { frag : fragment object}
|
||||||
|
@ -4494,7 +4577,7 @@ exports['default'] = {
|
||||||
// fired when Init Segment has been extracted from fragment - data: { moov : moov MP4 box, codecs : codecs found while parsing fragment}
|
// fired when Init Segment has been extracted from fragment - data: { moov : moov MP4 box, codecs : codecs found while parsing fragment}
|
||||||
FRAG_PARSING_INIT_SEGMENT: 'hlsFragParsingInitSegment',
|
FRAG_PARSING_INIT_SEGMENT: 'hlsFragParsingInitSegment',
|
||||||
// fired when parsing id3 is completed - data: { samples : [ id3 samples pes ] }
|
// fired when parsing id3 is completed - data: { samples : [ id3 samples pes ] }
|
||||||
FRAG_PARSING_METADATA: 'hlsFraParsingMetadata',
|
FRAG_PARSING_METADATA: 'hlsFragParsingMetadata',
|
||||||
// fired when moof/mdat have been extracted from fragment - data: { moof : moof MP4 box, mdat : mdat MP4 box}
|
// fired when moof/mdat have been extracted from fragment - data: { moof : moof MP4 box, mdat : mdat MP4 box}
|
||||||
FRAG_PARSING_DATA: 'hlsFragParsingData',
|
FRAG_PARSING_DATA: 'hlsFragParsingData',
|
||||||
// fired when fragment parsing is completed - data: undefined
|
// fired when fragment parsing is completed - data: undefined
|
||||||
|
@ -4504,7 +4587,7 @@ exports['default'] = {
|
||||||
// fired when fragment matching with current media position is changing - data : { frag : fragment object }
|
// fired when fragment matching with current media position is changing - data : { frag : fragment object }
|
||||||
FRAG_CHANGED: 'hlsFragChanged',
|
FRAG_CHANGED: 'hlsFragChanged',
|
||||||
// Identifier for a FPS drop event - data: {curentDropped, currentDecoded, totalDroppedFrames}
|
// Identifier for a FPS drop event - data: {curentDropped, currentDecoded, totalDroppedFrames}
|
||||||
FPS_DROP: 'hlsFPSDrop',
|
FPS_DROP: 'hlsFpsDrop',
|
||||||
// Identifier for an error event - data: { type : error type, details : error details, fatal : if true, hls.js cannot/will not try to recover, if false, hls.js will try to recover,other error specific data}
|
// Identifier for an error event - data: { type : error type, details : error details, fatal : if true, hls.js cannot/will not try to recover, if false, hls.js will try to recover,other error specific data}
|
||||||
ERROR: 'hlsError',
|
ERROR: 'hlsError',
|
||||||
// fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a media to the instance of hls.js to handle mid-rolls for example
|
// fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a media to the instance of hls.js to handle mid-rolls for example
|
||||||
|
@ -4514,9 +4597,8 @@ exports['default'] = {
|
||||||
// fired when a decrypt key loading is completed - data: { frag : fragment object, payload : key payload, stats : { trequest, tfirst, tload, length}}
|
// fired when a decrypt key loading is completed - data: { frag : fragment object, payload : key payload, stats : { trequest, tfirst, tload, length}}
|
||||||
KEY_LOADED: 'hlsKeyLoaded'
|
KEY_LOADED: 'hlsKeyLoaded'
|
||||||
};
|
};
|
||||||
module.exports = exports['default'];
|
|
||||||
|
|
||||||
},{}],19:[function(require,module,exports){
|
},{}],20:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Level Helper class, providing methods dealing with playlist sliding and drift
|
* Level Helper class, providing methods dealing with playlist sliding and drift
|
||||||
*/
|
*/
|
||||||
|
@ -4662,7 +4744,7 @@ var LevelHelper = (function () {
|
||||||
exports['default'] = LevelHelper;
|
exports['default'] = LevelHelper;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../utils/logger":28}],20:[function(require,module,exports){
|
},{"../utils/logger":29}],21:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* HLS interface
|
* HLS interface
|
||||||
*/
|
*/
|
||||||
|
@ -4750,6 +4832,8 @@ var Hls = (function () {
|
||||||
debug: false,
|
debug: false,
|
||||||
maxBufferLength: 30,
|
maxBufferLength: 30,
|
||||||
maxBufferSize: 60 * 1000 * 1000,
|
maxBufferSize: 60 * 1000 * 1000,
|
||||||
|
maxBufferHole: 0.3,
|
||||||
|
maxSeekHole: 2,
|
||||||
liveSyncDurationCount: 3,
|
liveSyncDurationCount: 3,
|
||||||
liveMaxLatencyDurationCount: Infinity,
|
liveMaxLatencyDurationCount: Infinity,
|
||||||
maxMaxBufferLength: 600,
|
maxMaxBufferLength: 600,
|
||||||
|
@ -5016,7 +5100,7 @@ var Hls = (function () {
|
||||||
exports['default'] = Hls;
|
exports['default'] = Hls;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"./controller/abr-controller":3,"./controller/level-controller":4,"./controller/mse-media-controller":5,"./errors":17,"./events":18,"./loader/fragment-loader":21,"./loader/key-loader":22,"./loader/playlist-loader":23,"./utils/logger":28,"./utils/xhr-loader":30,"events":1}],21:[function(require,module,exports){
|
},{"./controller/abr-controller":3,"./controller/level-controller":4,"./controller/mse-media-controller":5,"./errors":17,"./events":19,"./loader/fragment-loader":22,"./loader/key-loader":23,"./loader/playlist-loader":24,"./utils/logger":29,"./utils/xhr-loader":31,"events":1}],22:[function(require,module,exports){
|
||||||
/*
|
/*
|
||||||
* Fragment Loader
|
* Fragment Loader
|
||||||
*/
|
*/
|
||||||
|
@ -5029,23 +5113,31 @@ Object.defineProperty(exports, '__esModule', {
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||||
|
|
||||||
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||||||
|
|
||||||
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||||
|
|
||||||
var _events = require('../events');
|
var _events = require('../events');
|
||||||
|
|
||||||
var _events2 = _interopRequireDefault(_events);
|
var _events2 = _interopRequireDefault(_events);
|
||||||
|
|
||||||
|
var _eventHandler = require('../event-handler');
|
||||||
|
|
||||||
|
var _eventHandler2 = _interopRequireDefault(_eventHandler);
|
||||||
|
|
||||||
var _errors = require('../errors');
|
var _errors = require('../errors');
|
||||||
|
|
||||||
var FragmentLoader = (function () {
|
var FragmentLoader = (function (_EventHandler) {
|
||||||
|
_inherits(FragmentLoader, _EventHandler);
|
||||||
|
|
||||||
function FragmentLoader(hls) {
|
function FragmentLoader(hls) {
|
||||||
_classCallCheck(this, FragmentLoader);
|
_classCallCheck(this, FragmentLoader);
|
||||||
|
|
||||||
this.hls = hls;
|
_get(Object.getPrototypeOf(FragmentLoader.prototype), 'constructor', this).call(this, hls, _events2['default'].FRAG_LOADING);
|
||||||
this.onfl = this.onFragLoading.bind(this);
|
|
||||||
hls.on(_events2['default'].FRAG_LOADING, this.onfl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_createClass(FragmentLoader, [{
|
_createClass(FragmentLoader, [{
|
||||||
|
@ -5055,11 +5147,11 @@ var FragmentLoader = (function () {
|
||||||
this.loader.destroy();
|
this.loader.destroy();
|
||||||
this.loader = null;
|
this.loader = null;
|
||||||
}
|
}
|
||||||
this.hls.off(_events2['default'].FRAG_LOADING, this.onfl);
|
_eventHandler2['default'].prototype.destroy.call(this);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onFragLoading',
|
key: 'onFragLoading',
|
||||||
value: function onFragLoading(event, data) {
|
value: function onFragLoading(data) {
|
||||||
var frag = data.frag;
|
var frag = data.frag;
|
||||||
this.frag = frag;
|
this.frag = frag;
|
||||||
this.frag.loaded = 0;
|
this.frag.loaded = 0;
|
||||||
|
@ -5097,12 +5189,12 @@ var FragmentLoader = (function () {
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
return FragmentLoader;
|
return FragmentLoader;
|
||||||
})();
|
})(_eventHandler2['default']);
|
||||||
|
|
||||||
exports['default'] = FragmentLoader;
|
exports['default'] = FragmentLoader;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../errors":17,"../events":18}],22:[function(require,module,exports){
|
},{"../errors":17,"../event-handler":18,"../events":19}],23:[function(require,module,exports){
|
||||||
/*
|
/*
|
||||||
* Decrypt key Loader
|
* Decrypt key Loader
|
||||||
*/
|
*/
|
||||||
|
@ -5115,25 +5207,33 @@ Object.defineProperty(exports, '__esModule', {
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||||
|
|
||||||
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||||||
|
|
||||||
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||||
|
|
||||||
var _events = require('../events');
|
var _events = require('../events');
|
||||||
|
|
||||||
var _events2 = _interopRequireDefault(_events);
|
var _events2 = _interopRequireDefault(_events);
|
||||||
|
|
||||||
|
var _eventHandler = require('../event-handler');
|
||||||
|
|
||||||
|
var _eventHandler2 = _interopRequireDefault(_eventHandler);
|
||||||
|
|
||||||
var _errors = require('../errors');
|
var _errors = require('../errors');
|
||||||
|
|
||||||
var KeyLoader = (function () {
|
var KeyLoader = (function (_EventHandler) {
|
||||||
|
_inherits(KeyLoader, _EventHandler);
|
||||||
|
|
||||||
function KeyLoader(hls) {
|
function KeyLoader(hls) {
|
||||||
_classCallCheck(this, KeyLoader);
|
_classCallCheck(this, KeyLoader);
|
||||||
|
|
||||||
this.hls = hls;
|
_get(Object.getPrototypeOf(KeyLoader.prototype), 'constructor', this).call(this, hls, _events2['default'].KEY_LOADING);
|
||||||
this.decryptkey = null;
|
this.decryptkey = null;
|
||||||
this.decrypturl = null;
|
this.decrypturl = null;
|
||||||
this.ondkl = this.onDecryptKeyLoading.bind(this);
|
|
||||||
hls.on(_events2['default'].KEY_LOADING, this.ondkl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_createClass(KeyLoader, [{
|
_createClass(KeyLoader, [{
|
||||||
|
@ -5143,11 +5243,11 @@ var KeyLoader = (function () {
|
||||||
this.loader.destroy();
|
this.loader.destroy();
|
||||||
this.loader = null;
|
this.loader = null;
|
||||||
}
|
}
|
||||||
this.hls.off(_events2['default'].KEY_LOADING, this.ondkl);
|
_eventHandler2['default'].prototype.destroy.call(this);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onDecryptKeyLoading',
|
key: 'onKeyLoading',
|
||||||
value: function onDecryptKeyLoading(event, data) {
|
value: function onKeyLoading(data) {
|
||||||
var frag = this.frag = data.frag,
|
var frag = this.frag = data.frag,
|
||||||
decryptdata = frag.decryptdata,
|
decryptdata = frag.decryptdata,
|
||||||
uri = decryptdata.uri;
|
uri = decryptdata.uri;
|
||||||
|
@ -5191,12 +5291,12 @@ var KeyLoader = (function () {
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
return KeyLoader;
|
return KeyLoader;
|
||||||
})();
|
})(_eventHandler2['default']);
|
||||||
|
|
||||||
exports['default'] = KeyLoader;
|
exports['default'] = KeyLoader;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../errors":17,"../events":18}],23:[function(require,module,exports){
|
},{"../errors":17,"../event-handler":18,"../events":19}],24:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Playlist Loader
|
* Playlist Loader
|
||||||
*/
|
*/
|
||||||
|
@ -5209,14 +5309,22 @@ Object.defineProperty(exports, '__esModule', {
|
||||||
|
|
||||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||||
|
|
||||||
|
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||||||
|
|
||||||
|
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||||
|
|
||||||
var _events = require('../events');
|
var _events = require('../events');
|
||||||
|
|
||||||
var _events2 = _interopRequireDefault(_events);
|
var _events2 = _interopRequireDefault(_events);
|
||||||
|
|
||||||
|
var _eventHandler = require('../event-handler');
|
||||||
|
|
||||||
|
var _eventHandler2 = _interopRequireDefault(_eventHandler);
|
||||||
|
|
||||||
var _errors = require('../errors');
|
var _errors = require('../errors');
|
||||||
|
|
||||||
var _utilsUrl = require('../utils/url');
|
var _utilsUrl = require('../utils/url');
|
||||||
|
@ -5229,15 +5337,13 @@ var _utilsAttrList2 = _interopRequireDefault(_utilsAttrList);
|
||||||
|
|
||||||
//import {logger} from '../utils/logger';
|
//import {logger} from '../utils/logger';
|
||||||
|
|
||||||
var PlaylistLoader = (function () {
|
var PlaylistLoader = (function (_EventHandler) {
|
||||||
|
_inherits(PlaylistLoader, _EventHandler);
|
||||||
|
|
||||||
function PlaylistLoader(hls) {
|
function PlaylistLoader(hls) {
|
||||||
_classCallCheck(this, PlaylistLoader);
|
_classCallCheck(this, PlaylistLoader);
|
||||||
|
|
||||||
this.hls = hls;
|
_get(Object.getPrototypeOf(PlaylistLoader.prototype), 'constructor', this).call(this, hls, _events2['default'].MANIFEST_LOADING, _events2['default'].LEVEL_LOADING);
|
||||||
this.onml = this.onManifestLoading.bind(this);
|
|
||||||
this.onll = this.onLevelLoading.bind(this);
|
|
||||||
hls.on(_events2['default'].MANIFEST_LOADING, this.onml);
|
|
||||||
hls.on(_events2['default'].LEVEL_LOADING, this.onll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_createClass(PlaylistLoader, [{
|
_createClass(PlaylistLoader, [{
|
||||||
|
@ -5248,17 +5354,16 @@ var PlaylistLoader = (function () {
|
||||||
this.loader = null;
|
this.loader = null;
|
||||||
}
|
}
|
||||||
this.url = this.id = null;
|
this.url = this.id = null;
|
||||||
this.hls.off(_events2['default'].MANIFEST_LOADING, this.onml);
|
_eventHandler2['default'].prototype.destroy.call(this);
|
||||||
this.hls.off(_events2['default'].LEVEL_LOADING, this.onll);
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onManifestLoading',
|
key: 'onManifestLoading',
|
||||||
value: function onManifestLoading(event, data) {
|
value: function onManifestLoading(data) {
|
||||||
this.load(data.url, null);
|
this.load(data.url, null);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'onLevelLoading',
|
key: 'onLevelLoading',
|
||||||
value: function onLevelLoading(event, data) {
|
value: function onLevelLoading(data) {
|
||||||
this.load(data.url, data.level, data.id);
|
this.load(data.url, data.level, data.id);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
@ -5525,12 +5630,12 @@ var PlaylistLoader = (function () {
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
return PlaylistLoader;
|
return PlaylistLoader;
|
||||||
})();
|
})(_eventHandler2['default']);
|
||||||
|
|
||||||
exports['default'] = PlaylistLoader;
|
exports['default'] = PlaylistLoader;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../errors":17,"../events":18,"../utils/attr-list":26,"../utils/url":29}],24:[function(require,module,exports){
|
},{"../errors":17,"../event-handler":18,"../events":19,"../utils/attr-list":27,"../utils/url":30}],25:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Generate MP4 Box
|
* Generate MP4 Box
|
||||||
*/
|
*/
|
||||||
|
@ -6035,7 +6140,7 @@ var MP4 = (function () {
|
||||||
exports['default'] = MP4;
|
exports['default'] = MP4;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{}],25:[function(require,module,exports){
|
},{}],26:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* fMP4 remuxer
|
* fMP4 remuxer
|
||||||
*/
|
*/
|
||||||
|
@ -6194,6 +6299,7 @@ var MP4Remuxer = (function () {
|
||||||
dts,
|
dts,
|
||||||
ptsnorm,
|
ptsnorm,
|
||||||
dtsnorm,
|
dtsnorm,
|
||||||
|
flags,
|
||||||
samples = [];
|
samples = [];
|
||||||
/* concatenate the video data and construct the mdat in place
|
/* concatenate the video data and construct the mdat in place
|
||||||
(need 8 more bytes to fill length and mpdat type) */
|
(need 8 more bytes to fill length and mpdat type) */
|
||||||
|
@ -6217,7 +6323,7 @@ var MP4Remuxer = (function () {
|
||||||
dts = avcSample.dts - this._initDTS;
|
dts = avcSample.dts - this._initDTS;
|
||||||
// ensure DTS is not bigger than PTS
|
// ensure DTS is not bigger than PTS
|
||||||
dts = Math.min(pts, dts);
|
dts = Math.min(pts, dts);
|
||||||
//logger.log(`Video/PTS/DTS:${pts}/${dts}`);
|
//logger.log(`Video/PTS/DTS:${Math.round(pts/90)}/${Math.round(dts/90)}`);
|
||||||
// if not first AVC sample of video track, normalize PTS/DTS with previous sample value
|
// if not first AVC sample of video track, normalize PTS/DTS with previous sample value
|
||||||
// and ensure that sample duration is positive
|
// and ensure that sample duration is positive
|
||||||
if (lastDTS !== undefined) {
|
if (lastDTS !== undefined) {
|
||||||
|
@ -6267,13 +6373,14 @@ var MP4Remuxer = (function () {
|
||||||
degradPrio: 0
|
degradPrio: 0
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
flags = mp4Sample.flags;
|
||||||
if (avcSample.key === true) {
|
if (avcSample.key === true) {
|
||||||
// the current sample is a key frame
|
// the current sample is a key frame
|
||||||
mp4Sample.flags.dependsOn = 2;
|
flags.dependsOn = 2;
|
||||||
mp4Sample.flags.isNonSync = 0;
|
flags.isNonSync = 0;
|
||||||
} else {
|
} else {
|
||||||
mp4Sample.flags.dependsOn = 1;
|
flags.dependsOn = 1;
|
||||||
mp4Sample.flags.isNonSync = 1;
|
flags.isNonSync = 1;
|
||||||
}
|
}
|
||||||
samples.push(mp4Sample);
|
samples.push(mp4Sample);
|
||||||
lastDTS = dtsnorm;
|
lastDTS = dtsnorm;
|
||||||
|
@ -6288,7 +6395,7 @@ var MP4Remuxer = (function () {
|
||||||
track.len = 0;
|
track.len = 0;
|
||||||
track.nbNalu = 0;
|
track.nbNalu = 0;
|
||||||
if (samples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
|
if (samples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
|
||||||
var flags = samples[0].flags;
|
flags = samples[0].flags;
|
||||||
// chrome workaround, mark first sample as being a Random Access Point to avoid sourcebuffer append issue
|
// chrome workaround, mark first sample as being a Random Access Point to avoid sourcebuffer append issue
|
||||||
// https://code.google.com/p/chromium/issues/detail?id=229412
|
// https://code.google.com/p/chromium/issues/detail?id=229412
|
||||||
flags.dependsOn = 2;
|
flags.dependsOn = 2;
|
||||||
|
@ -6344,7 +6451,7 @@ var MP4Remuxer = (function () {
|
||||||
unit = aacSample.unit;
|
unit = aacSample.unit;
|
||||||
pts = aacSample.pts - this._initDTS;
|
pts = aacSample.pts - this._initDTS;
|
||||||
dts = aacSample.dts - this._initDTS;
|
dts = aacSample.dts - this._initDTS;
|
||||||
//logger.log(`Audio/PTS:${aacSample.pts.toFixed(0)}`);
|
//logger.log(`Audio/PTS:${Math.round(pts/90)}`);
|
||||||
// if not first sample
|
// if not first sample
|
||||||
if (lastDTS !== undefined) {
|
if (lastDTS !== undefined) {
|
||||||
ptsnorm = this._PTSNormalize(pts, lastDTS);
|
ptsnorm = this._PTSNormalize(pts, lastDTS);
|
||||||
|
@ -6490,7 +6597,7 @@ var MP4Remuxer = (function () {
|
||||||
exports['default'] = MP4Remuxer;
|
exports['default'] = MP4Remuxer;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../errors":17,"../events":18,"../remux/mp4-generator":24,"../utils/logger":28}],26:[function(require,module,exports){
|
},{"../errors":17,"../events":19,"../remux/mp4-generator":25,"../utils/logger":29}],27:[function(require,module,exports){
|
||||||
|
|
||||||
// adapted from https://github.com/kanongil/node-m3u8parse/blob/master/attrlist.js
|
// adapted from https://github.com/kanongil/node-m3u8parse/blob/master/attrlist.js
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -6598,7 +6705,7 @@ var AttrList = (function () {
|
||||||
exports['default'] = AttrList;
|
exports['default'] = AttrList;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{}],27:[function(require,module,exports){
|
},{}],28:[function(require,module,exports){
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var BinarySearch = {
|
var BinarySearch = {
|
||||||
|
@ -6643,7 +6750,7 @@ var BinarySearch = {
|
||||||
|
|
||||||
module.exports = BinarySearch;
|
module.exports = BinarySearch;
|
||||||
|
|
||||||
},{}],28:[function(require,module,exports){
|
},{}],29:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
|
@ -6725,7 +6832,7 @@ exports.enableLogs = enableLogs;
|
||||||
var logger = exportedLogger;
|
var logger = exportedLogger;
|
||||||
exports.logger = logger;
|
exports.logger = logger;
|
||||||
|
|
||||||
},{}],29:[function(require,module,exports){
|
},{}],30:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var URLHelper = {
|
var URLHelper = {
|
||||||
|
@ -6806,7 +6913,7 @@ var URLHelper = {
|
||||||
|
|
||||||
module.exports = URLHelper;
|
module.exports = URLHelper;
|
||||||
|
|
||||||
},{}],30:[function(require,module,exports){
|
},{}],31:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* XHR based logger
|
* XHR based logger
|
||||||
*/
|
*/
|
||||||
|
@ -6877,7 +6984,7 @@ var XhrLoader = (function () {
|
||||||
key: 'loadInternal',
|
key: 'loadInternal',
|
||||||
value: function loadInternal() {
|
value: function loadInternal() {
|
||||||
var xhr = this.loader = new XMLHttpRequest();
|
var xhr = this.loader = new XMLHttpRequest();
|
||||||
xhr.onreadystatechange = this.statechange.bind(this);
|
xhr.onloadend = this.loadend.bind(this);
|
||||||
xhr.onprogress = this.loadprogress.bind(this);
|
xhr.onprogress = this.loadprogress.bind(this);
|
||||||
|
|
||||||
xhr.open('GET', this.url, true);
|
xhr.open('GET', this.url, true);
|
||||||
|
@ -6893,14 +7000,13 @@ var XhrLoader = (function () {
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'statechange',
|
key: 'loadend',
|
||||||
value: function statechange(event) {
|
value: function loadend(event) {
|
||||||
var xhr = event.currentTarget,
|
var xhr = event.currentTarget,
|
||||||
status = xhr.status,
|
status = xhr.status,
|
||||||
stats = this.stats;
|
stats = this.stats;
|
||||||
// don't proceed if xhr has been aborted
|
// don't proceed if xhr has been aborted
|
||||||
// 4 = Response from server has been completely loaded.
|
if (!stats.aborted) {
|
||||||
if (!stats.aborted && xhr.readyState === 4) {
|
|
||||||
// http status between 200 to 299 are all successful
|
// http status between 200 to 299 are all successful
|
||||||
if (status >= 200 && status < 300) {
|
if (status >= 200 && status < 300) {
|
||||||
window.clearTimeout(this.timeoutHandle);
|
window.clearTimeout(this.timeoutHandle);
|
||||||
|
@ -6949,6 +7055,6 @@ var XhrLoader = (function () {
|
||||||
exports['default'] = XhrLoader;
|
exports['default'] = XhrLoader;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"../utils/logger":28}]},{},[20])(20)
|
},{"../utils/logger":29}]},{},[21])(21)
|
||||||
});
|
});
|
||||||
//# sourceMappingURL=hls.js.map
|
//# sourceMappingURL=hls.js.map
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "hls.js",
|
"name": "hls.js",
|
||||||
"version": "0.4.5",
|
"version": "0.4.6",
|
||||||
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
"description": "Media Source Extension - HLS library, by/for Dailymotion",
|
||||||
"homepage": "https://github.com/dailymotion/hls.js",
|
"homepage": "https://github.com/dailymotion/hls.js",
|
||||||
"authors": "Guillaume du Pontavice <guillaume.dupontavice@dailymotion.com>",
|
"authors": "Guillaume du Pontavice <guillaume.dupontavice@dailymotion.com>",
|
||||||
|
|
|
@ -3,23 +3,22 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Event from '../events';
|
import Event from '../events';
|
||||||
|
import EventHandler from '../event-handler';
|
||||||
|
|
||||||
class AbrController {
|
class AbrController extends EventHandler {
|
||||||
|
|
||||||
constructor(hls) {
|
constructor(hls) {
|
||||||
this.hls = hls;
|
super(hls, Event.FRAG_LOAD_PROGRESS);
|
||||||
this.lastfetchlevel = 0;
|
this.lastfetchlevel = 0;
|
||||||
this._autoLevelCapping = -1;
|
this._autoLevelCapping = -1;
|
||||||
this._nextAutoLevel = -1;
|
this._nextAutoLevel = -1;
|
||||||
this.onflp = this.onFragmentLoadProgress.bind(this);
|
|
||||||
hls.on(Event.FRAG_LOAD_PROGRESS, this.onflp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.hls.off(Event.FRAG_LOAD_PROGRESS, this.onflp);
|
EventHandler.prototype.destroy.call(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onFragmentLoadProgress(event, data) {
|
onFragLoadProgress(data) {
|
||||||
var stats = data.stats;
|
var stats = data.stats;
|
||||||
if (stats.aborted === undefined) {
|
if (stats.aborted === undefined) {
|
||||||
this.lastfetchduration = (performance.now() - stats.trequest) / 1000;
|
this.lastfetchduration = (performance.now() - stats.trequest) / 1000;
|
||||||
|
|
|
@ -3,35 +3,29 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Event from '../events';
|
import Event from '../events';
|
||||||
|
import EventHandler from '../event-handler';
|
||||||
import {logger} from '../utils/logger';
|
import {logger} from '../utils/logger';
|
||||||
import {ErrorTypes, ErrorDetails} from '../errors';
|
import {ErrorTypes, ErrorDetails} from '../errors';
|
||||||
|
|
||||||
class LevelController {
|
class LevelController extends EventHandler {
|
||||||
|
|
||||||
constructor(hls) {
|
constructor(hls) {
|
||||||
this.hls = hls;
|
super(hls,
|
||||||
this.onml = this.onManifestLoaded.bind(this);
|
Event.MANIFEST_LOADED,
|
||||||
this.onll = this.onLevelLoaded.bind(this);
|
Event.LEVEL_LOADED,
|
||||||
this.onerr = this.onError.bind(this);
|
Event.ERROR);
|
||||||
this.ontick = this.tick.bind(this);
|
this.ontick = this.tick.bind(this);
|
||||||
hls.on(Event.MANIFEST_LOADED, this.onml);
|
|
||||||
hls.on(Event.LEVEL_LOADED, this.onll);
|
|
||||||
hls.on(Event.ERROR, this.onerr);
|
|
||||||
this._manualLevel = this._autoLevelCapping = -1;
|
this._manualLevel = this._autoLevelCapping = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
var hls = this.hls;
|
|
||||||
hls.off(Event.MANIFEST_LOADED, this.onml);
|
|
||||||
hls.off(Event.LEVEL_LOADED, this.onll);
|
|
||||||
hls.off(Event.ERROR, this.onerr);
|
|
||||||
if (this.timer) {
|
if (this.timer) {
|
||||||
clearInterval(this.timer);
|
clearInterval(this.timer);
|
||||||
}
|
}
|
||||||
this._manualLevel = -1;
|
this._manualLevel = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
onManifestLoaded(event, data) {
|
onManifestLoaded(data) {
|
||||||
var levels0 = [], levels = [], bitrateStart, i, bitrateSet = {}, videoCodecFound = false, audioCodecFound = false, hls = this.hls;
|
var levels0 = [], levels = [], bitrateStart, i, bitrateSet = {}, videoCodecFound = false, audioCodecFound = false, hls = this.hls;
|
||||||
|
|
||||||
// regroup redundant level together
|
// regroup redundant level together
|
||||||
|
@ -166,7 +160,7 @@ class LevelController {
|
||||||
this._startLevel = newLevel;
|
this._startLevel = newLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
onError(event, data) {
|
onError(data) {
|
||||||
if(data.fatal) {
|
if(data.fatal) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +218,7 @@ class LevelController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onLevelLoaded(event, data) {
|
onLevelLoaded(data) {
|
||||||
// check if current playlist is a live playlist
|
// check if current playlist is a live playlist
|
||||||
if (data.details.live && !this.timer) {
|
if (data.details.live && !this.timer) {
|
||||||
// if live playlist we will have to reload it periodically
|
// if live playlist we will have to reload it periodically
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
import Demuxer from '../demux/demuxer';
|
import Demuxer from '../demux/demuxer';
|
||||||
import Event from '../events';
|
import Event from '../events';
|
||||||
|
import EventHandler from '../event-handler';
|
||||||
import {logger} from '../utils/logger';
|
import {logger} from '../utils/logger';
|
||||||
import BinarySearch from '../utils/binary-search';
|
import BinarySearch from '../utils/binary-search';
|
||||||
import LevelHelper from '../helper/level-helper';
|
import LevelHelper from '../helper/level-helper';
|
||||||
|
@ -23,39 +24,31 @@ const State = {
|
||||||
BUFFER_FLUSHING : 8
|
BUFFER_FLUSHING : 8
|
||||||
};
|
};
|
||||||
|
|
||||||
class MSEMediaController {
|
class MSEMediaController extends EventHandler {
|
||||||
|
|
||||||
constructor(hls) {
|
constructor(hls) {
|
||||||
|
super(hls, Event.MEDIA_ATTACHING,
|
||||||
|
Event.MEDIA_DETACHING,
|
||||||
|
Event.MANIFEST_PARSED,
|
||||||
|
Event.LEVEL_LOADED,
|
||||||
|
Event.KEY_LOADED,
|
||||||
|
Event.FRAG_LOADED,
|
||||||
|
Event.FRAG_PARSING_INIT_SEGMENT,
|
||||||
|
Event.FRAG_PARSING_DATA,
|
||||||
|
Event.FRAG_PARSED,
|
||||||
|
Event.ERROR);
|
||||||
this.config = hls.config;
|
this.config = hls.config;
|
||||||
this.audioCodecSwap = false;
|
this.audioCodecSwap = false;
|
||||||
this.hls = hls;
|
|
||||||
this.ticks = 0;
|
this.ticks = 0;
|
||||||
// Source Buffer listeners
|
// Source Buffer listeners
|
||||||
this.onsbue = this.onSBUpdateEnd.bind(this);
|
this.onsbue = this.onSBUpdateEnd.bind(this);
|
||||||
this.onsbe = this.onSBUpdateError.bind(this);
|
this.onsbe = this.onSBUpdateError.bind(this);
|
||||||
// internal listeners
|
|
||||||
this.onmediaatt0 = this.onMediaAttaching.bind(this);
|
|
||||||
this.onmediadet0 = this.onMediaDetaching.bind(this);
|
|
||||||
this.onmp = this.onManifestParsed.bind(this);
|
|
||||||
this.onll = this.onLevelLoaded.bind(this);
|
|
||||||
this.onfl = this.onFragLoaded.bind(this);
|
|
||||||
this.onkl = this.onKeyLoaded.bind(this);
|
|
||||||
this.onis = this.onInitSegment.bind(this);
|
|
||||||
this.onfpg = this.onFragParsing.bind(this);
|
|
||||||
this.onfp = this.onFragParsed.bind(this);
|
|
||||||
this.onerr = this.onError.bind(this);
|
|
||||||
this.ontick = this.tick.bind(this);
|
this.ontick = this.tick.bind(this);
|
||||||
hls.on(Event.MEDIA_ATTACHING, this.onmediaatt0);
|
|
||||||
hls.on(Event.MEDIA_DETACHING, this.onmediadet0);
|
|
||||||
hls.on(Event.MANIFEST_PARSED, this.onmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.stop();
|
this.stop();
|
||||||
var hls = this.hls;
|
EventHandler.prototype.destroy.call(this);
|
||||||
hls.off(Event.MEDIA_ATTACHING, this.onmediaatt0);
|
|
||||||
hls.off(Event.MEDIA_DETACHING, this.onmediadet0);
|
|
||||||
hls.off(Event.MANIFEST_PARSED, this.onmp);
|
|
||||||
this.state = State.IDLE;
|
this.state = State.IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,13 +80,6 @@ class MSEMediaController {
|
||||||
this.timer = setInterval(this.ontick, 100);
|
this.timer = setInterval(this.ontick, 100);
|
||||||
this.level = -1;
|
this.level = -1;
|
||||||
this.fragLoadError = 0;
|
this.fragLoadError = 0;
|
||||||
hls.on(Event.FRAG_LOADED, this.onfl);
|
|
||||||
hls.on(Event.FRAG_PARSING_INIT_SEGMENT, this.onis);
|
|
||||||
hls.on(Event.FRAG_PARSING_DATA, this.onfpg);
|
|
||||||
hls.on(Event.FRAG_PARSED, this.onfp);
|
|
||||||
hls.on(Event.ERROR, this.onerr);
|
|
||||||
hls.on(Event.LEVEL_LOADED, this.onll);
|
|
||||||
hls.on(Event.KEY_LOADED, this.onkl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
|
@ -128,14 +114,6 @@ class MSEMediaController {
|
||||||
this.demuxer.destroy();
|
this.demuxer.destroy();
|
||||||
this.demuxer = null;
|
this.demuxer = null;
|
||||||
}
|
}
|
||||||
var hls = this.hls;
|
|
||||||
hls.off(Event.FRAG_LOADED, this.onfl);
|
|
||||||
hls.off(Event.FRAG_PARSED, this.onfp);
|
|
||||||
hls.off(Event.FRAG_PARSING_DATA, this.onfpg);
|
|
||||||
hls.off(Event.LEVEL_LOADED, this.onll);
|
|
||||||
hls.off(Event.KEY_LOADED, this.onkl);
|
|
||||||
hls.off(Event.FRAG_PARSING_INIT_SEGMENT, this.onis);
|
|
||||||
hls.off(Event.ERROR, this.onerr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tick() {
|
tick() {
|
||||||
|
@ -189,7 +167,7 @@ class MSEMediaController {
|
||||||
// we are not at playback start, get next load level from level Controller
|
// we are not at playback start, get next load level from level Controller
|
||||||
level = hls.nextLoadLevel;
|
level = hls.nextLoadLevel;
|
||||||
}
|
}
|
||||||
var bufferInfo = this.bufferInfo(pos,0.3),
|
var bufferInfo = this.bufferInfo(pos,this.config.maxBufferHole),
|
||||||
bufferLen = bufferInfo.len,
|
bufferLen = bufferInfo.len,
|
||||||
bufferEnd = bufferInfo.end,
|
bufferEnd = bufferInfo.end,
|
||||||
fragPrevious = this.fragPrevious,
|
fragPrevious = this.fragPrevious,
|
||||||
|
@ -208,7 +186,9 @@ class MSEMediaController {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
levelDetails = this.levels[level].details;
|
levelDetails = this.levels[level].details;
|
||||||
// if level info not retrieved yet, switch state and wait for level retrieval
|
// if level info not retrieved yet, switch state and wait for level retrieval
|
||||||
if (typeof levelDetails === 'undefined') {
|
// if live playlist, ensure that new playlist has been refreshed to avoid loading/try to load
|
||||||
|
// a useless and outdated fragment (that might even introduce load error if it is already out of the live playlist)
|
||||||
|
if (typeof levelDetails === 'undefined' || levelDetails.live && this.levelLastLoaded !== level) {
|
||||||
this.state = State.WAITING_LEVEL;
|
this.state = State.WAITING_LEVEL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -364,7 +344,7 @@ class MSEMediaController {
|
||||||
}
|
}
|
||||||
pos = v.currentTime;
|
pos = v.currentTime;
|
||||||
var fragLoadedDelay = (frag.expectedLen - frag.loaded) / loadRate;
|
var fragLoadedDelay = (frag.expectedLen - frag.loaded) / loadRate;
|
||||||
var bufferStarvationDelay = this.bufferInfo(pos,0.3).end - pos;
|
var bufferStarvationDelay = this.bufferInfo(pos,this.config.maxBufferHole).end - pos;
|
||||||
var fragLevelNextLoadedDelay = frag.duration * this.levels[hls.nextLoadLevel].bitrate / (8 * loadRate); //bps/Bps
|
var fragLevelNextLoadedDelay = frag.duration * this.levels[hls.nextLoadLevel].bitrate / (8 * loadRate); //bps/Bps
|
||||||
/* if we have less than 2 frag duration in buffer and if frag loaded delay is greater than buffer starvation delay
|
/* if we have less than 2 frag duration in buffer and if frag loaded delay is greater than buffer starvation delay
|
||||||
... and also bigger than duration needed to load fragment at next level ...*/
|
... and also bigger than duration needed to load fragment at next level ...*/
|
||||||
|
@ -545,6 +525,7 @@ class MSEMediaController {
|
||||||
bufferLen = bufferEnd - pos;
|
bufferLen = bufferEnd - pos;
|
||||||
} else if ((pos + maxHoleDuration) < start) {
|
} else if ((pos + maxHoleDuration) < start) {
|
||||||
bufferStartNext = start;
|
bufferStartNext = start;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {len: bufferLen, start: bufferStart, end: bufferEnd, nextStart : bufferStartNext};
|
return {len: bufferLen, start: bufferStart, end: bufferEnd, nextStart : bufferStartNext};
|
||||||
|
@ -797,7 +778,7 @@ class MSEMediaController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMediaAttaching(event, data) {
|
onMediaAttaching(data) {
|
||||||
var media = this.media = data.media;
|
var media = this.media = data.media;
|
||||||
// setup the media source
|
// setup the media source
|
||||||
var ms = this.mediaSource = new MediaSource();
|
var ms = this.mediaSource = new MediaSource();
|
||||||
|
@ -870,7 +851,7 @@ class MSEMediaController {
|
||||||
if (this.state === State.FRAG_LOADING) {
|
if (this.state === State.FRAG_LOADING) {
|
||||||
// check if currently loaded fragment is inside buffer.
|
// check if currently loaded fragment is inside buffer.
|
||||||
//if outside, cancel fragment loading, otherwise do nothing
|
//if outside, cancel fragment loading, otherwise do nothing
|
||||||
if (this.bufferInfo(this.media.currentTime,0.3).len === 0) {
|
if (this.bufferInfo(this.media.currentTime,this.config.maxBufferHole).len === 0) {
|
||||||
logger.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
|
logger.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
|
||||||
var fragCurrent = this.fragCurrent;
|
var fragCurrent = this.fragCurrent;
|
||||||
if (fragCurrent) {
|
if (fragCurrent) {
|
||||||
|
@ -919,7 +900,7 @@ class MSEMediaController {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
onManifestParsed(event, data) {
|
onManifestParsed(data) {
|
||||||
var aac = false, heaac = false, codecs;
|
var aac = false, heaac = false, codecs;
|
||||||
data.levels.forEach(level => {
|
data.levels.forEach(level => {
|
||||||
// detect if we have different kind of audio codecs used amongst playlists
|
// detect if we have different kind of audio codecs used amongst playlists
|
||||||
|
@ -945,13 +926,14 @@ class MSEMediaController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onLevelLoaded(event,data) {
|
onLevelLoaded(data) {
|
||||||
var newDetails = data.details,
|
var newDetails = data.details,
|
||||||
newLevelId = data.level,
|
newLevelId = data.level,
|
||||||
curLevel = this.levels[newLevelId],
|
curLevel = this.levels[newLevelId],
|
||||||
duration = newDetails.totalduration;
|
duration = newDetails.totalduration;
|
||||||
|
|
||||||
logger.log(`level ${newLevelId} loaded [${newDetails.startSN},${newDetails.endSN}],duration:${duration}`);
|
logger.log(`level ${newLevelId} loaded [${newDetails.startSN},${newDetails.endSN}],duration:${duration}`);
|
||||||
|
this.levelLastLoaded = newLevelId;
|
||||||
|
|
||||||
if (newDetails.live) {
|
if (newDetails.live) {
|
||||||
var curDetails = curLevel.details;
|
var curDetails = curLevel.details;
|
||||||
|
@ -998,7 +980,7 @@ class MSEMediaController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onFragLoaded(event, data) {
|
onFragLoaded(data) {
|
||||||
var fragCurrent = this.fragCurrent;
|
var fragCurrent = this.fragCurrent;
|
||||||
if (this.state === State.FRAG_LOADING &&
|
if (this.state === State.FRAG_LOADING &&
|
||||||
fragCurrent &&
|
fragCurrent &&
|
||||||
|
@ -1039,7 +1021,7 @@ class MSEMediaController {
|
||||||
this.fragLoadError = 0;
|
this.fragLoadError = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
onInitSegment(event, data) {
|
onFragParsingInitSegment(data) {
|
||||||
if (this.state === State.PARSING) {
|
if (this.state === State.PARSING) {
|
||||||
// check if codecs have been explicitely defined in the master playlist for this level;
|
// check if codecs have been explicitely defined in the master playlist for this level;
|
||||||
// if yes use these ones instead of the ones parsed from the demux
|
// if yes use these ones instead of the ones parsed from the demux
|
||||||
|
@ -1098,7 +1080,7 @@ class MSEMediaController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onFragParsing(event, data) {
|
onFragParsingData(data) {
|
||||||
if (this.state === State.PARSING) {
|
if (this.state === State.PARSING) {
|
||||||
this.tparse2 = Date.now();
|
this.tparse2 = Date.now();
|
||||||
var level = this.levels[this.level],
|
var level = this.levels[this.level],
|
||||||
|
@ -1115,7 +1097,7 @@ class MSEMediaController {
|
||||||
//trigger handler right now
|
//trigger handler right now
|
||||||
this.tick();
|
this.tick();
|
||||||
} else {
|
} else {
|
||||||
logger.warn(`not in PARSING state, discarding ${event}`);
|
logger.warn(`not in PARSING state, ignoring FRAG_PARSING_DATA event`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1128,7 +1110,7 @@ class MSEMediaController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onError(event, data) {
|
onError(data) {
|
||||||
switch(data.details) {
|
switch(data.details) {
|
||||||
case ErrorDetails.FRAG_LOAD_ERROR:
|
case ErrorDetails.FRAG_LOAD_ERROR:
|
||||||
case ErrorDetails.FRAG_LOAD_TIMEOUT:
|
case ErrorDetails.FRAG_LOAD_TIMEOUT:
|
||||||
|
@ -1153,7 +1135,7 @@ class MSEMediaController {
|
||||||
logger.error(`mediaController: ${data.details} reaches max retry, redispatch as fatal ...`);
|
logger.error(`mediaController: ${data.details} reaches max retry, redispatch as fatal ...`);
|
||||||
// redispatch same error but with fatal set to true
|
// redispatch same error but with fatal set to true
|
||||||
data.fatal = true;
|
data.fatal = true;
|
||||||
this.hls.trigger(event, data);
|
this.hls.trigger(Event.ERROR, data);
|
||||||
this.state = State.ERROR;
|
this.state = State.ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1216,14 +1198,14 @@ _checkBuffer() {
|
||||||
// playhead moving or media not playing
|
// playhead moving or media not playing
|
||||||
jumpThreshold = 0;
|
jumpThreshold = 0;
|
||||||
} else {
|
} else {
|
||||||
logger.trace('playback seems stuck');
|
logger.log('playback seems stuck');
|
||||||
}
|
}
|
||||||
// if we are below threshold, try to jump if next buffer range is close
|
// if we are below threshold, try to jump if next buffer range is close
|
||||||
if(bufferInfo.len <= jumpThreshold) {
|
if(bufferInfo.len <= jumpThreshold) {
|
||||||
// no buffer available @ currentTime, check if next buffer is close (more than 5ms diff but within a 300 ms range)
|
// no buffer available @ currentTime, check if next buffer is close (more than 5ms diff but within a config.maxSeekHole second range)
|
||||||
var nextBufferStart = bufferInfo.nextStart, delta = nextBufferStart-currentTime;
|
var nextBufferStart = bufferInfo.nextStart, delta = nextBufferStart-currentTime;
|
||||||
if(nextBufferStart &&
|
if(nextBufferStart &&
|
||||||
(delta < 0.3) &&
|
(delta < this.config.maxSeekHole) &&
|
||||||
(delta > 0.005) &&
|
(delta > 0.005) &&
|
||||||
!media.seeking) {
|
!media.seeking) {
|
||||||
// next buffer is close ! adjust currentTime to nextBufferStart
|
// next buffer is close ! adjust currentTime to nextBufferStart
|
||||||
|
|
66
dashboard-ui/bower_components/hls.js/src/event-handler.js
vendored
Normal file
66
dashboard-ui/bower_components/hls.js/src/event-handler.js
vendored
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* All objects in the event handling chain should inherit from this class
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
//import {logger} from './utils/logger';
|
||||||
|
|
||||||
|
class EventHandler {
|
||||||
|
|
||||||
|
constructor(hls, ...events) {
|
||||||
|
this.hls = hls;
|
||||||
|
this.onEvent = this.onEvent.bind(this);
|
||||||
|
this.handledEvents = events;
|
||||||
|
this.useGenericHandler = true;
|
||||||
|
|
||||||
|
this.registerListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.unregisterListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
isEventHandler() {
|
||||||
|
return typeof this.handledEvents === 'object' && this.handledEvents.length && typeof this.onEvent === 'function';
|
||||||
|
}
|
||||||
|
|
||||||
|
registerListeners() {
|
||||||
|
if (this.isEventHandler()) {
|
||||||
|
this.handledEvents.forEach(function(event) {
|
||||||
|
if (event === 'hlsEventGeneric') {
|
||||||
|
throw new Error('Forbidden event name: ' + event);
|
||||||
|
}
|
||||||
|
this.hls.on(event, this.onEvent);
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unregisterListeners() {
|
||||||
|
if (this.isEventHandler()) {
|
||||||
|
this.handledEvents.forEach(function(event) {
|
||||||
|
this.hls.off(event, this.onEvent);
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* arguments: event (string), data (any)
|
||||||
|
*/
|
||||||
|
onEvent(event, data) {
|
||||||
|
this.onEventGeneric(event, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
onEventGeneric(event, data) {
|
||||||
|
var eventToFunction = function(event, data) {
|
||||||
|
var funcName = 'on' + event.replace('hls', '');
|
||||||
|
if (typeof this[funcName] !== 'function') {
|
||||||
|
throw new Error(`Event ${event} has no generic handler in this ${this.constructor.name} class (tried ${funcName})`);
|
||||||
|
}
|
||||||
|
return this[funcName].bind(this, data);
|
||||||
|
};
|
||||||
|
eventToFunction.call(this, event, data).call();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EventHandler;
|
|
@ -1,4 +1,4 @@
|
||||||
export default {
|
module.exports = {
|
||||||
// fired before MediaSource is attaching to media element - data: { media }
|
// fired before MediaSource is attaching to media element - data: { media }
|
||||||
MEDIA_ATTACHING: 'hlsMediaAttaching',
|
MEDIA_ATTACHING: 'hlsMediaAttaching',
|
||||||
// fired when MediaSource has been succesfully attached to media element - data: { }
|
// fired when MediaSource has been succesfully attached to media element - data: { }
|
||||||
|
@ -20,7 +20,7 @@ export default {
|
||||||
// fired when a level's details have been updated based on previous details, after it has been loaded. - data: { details : levelDetails object, level : id of updated level }
|
// fired when a level's details have been updated based on previous details, after it has been loaded. - data: { details : levelDetails object, level : id of updated level }
|
||||||
LEVEL_UPDATED: 'hlsLevelUpdated',
|
LEVEL_UPDATED: 'hlsLevelUpdated',
|
||||||
// fired when a level's PTS information has been updated after parsing a fragment - data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }
|
// fired when a level's PTS information has been updated after parsing a fragment - data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }
|
||||||
LEVEL_PTS_UPDATED: 'hlsPTSUpdated',
|
LEVEL_PTS_UPDATED: 'hlsLevelPtsUpdated',
|
||||||
// fired when a level switch is requested - data: { level : id of new level }
|
// fired when a level switch is requested - data: { level : id of new level }
|
||||||
LEVEL_SWITCH: 'hlsLevelSwitch',
|
LEVEL_SWITCH: 'hlsLevelSwitch',
|
||||||
// fired when a fragment loading starts - data: { frag : fragment object}
|
// fired when a fragment loading starts - data: { frag : fragment object}
|
||||||
|
@ -34,7 +34,7 @@ export default {
|
||||||
// fired when Init Segment has been extracted from fragment - data: { moov : moov MP4 box, codecs : codecs found while parsing fragment}
|
// fired when Init Segment has been extracted from fragment - data: { moov : moov MP4 box, codecs : codecs found while parsing fragment}
|
||||||
FRAG_PARSING_INIT_SEGMENT: 'hlsFragParsingInitSegment',
|
FRAG_PARSING_INIT_SEGMENT: 'hlsFragParsingInitSegment',
|
||||||
// fired when parsing id3 is completed - data: { samples : [ id3 samples pes ] }
|
// fired when parsing id3 is completed - data: { samples : [ id3 samples pes ] }
|
||||||
FRAG_PARSING_METADATA: 'hlsFraParsingMetadata',
|
FRAG_PARSING_METADATA: 'hlsFragParsingMetadata',
|
||||||
// fired when moof/mdat have been extracted from fragment - data: { moof : moof MP4 box, mdat : mdat MP4 box}
|
// fired when moof/mdat have been extracted from fragment - data: { moof : moof MP4 box, mdat : mdat MP4 box}
|
||||||
FRAG_PARSING_DATA: 'hlsFragParsingData',
|
FRAG_PARSING_DATA: 'hlsFragParsingData',
|
||||||
// fired when fragment parsing is completed - data: undefined
|
// fired when fragment parsing is completed - data: undefined
|
||||||
|
@ -44,7 +44,7 @@ export default {
|
||||||
// fired when fragment matching with current media position is changing - data : { frag : fragment object }
|
// fired when fragment matching with current media position is changing - data : { frag : fragment object }
|
||||||
FRAG_CHANGED: 'hlsFragChanged',
|
FRAG_CHANGED: 'hlsFragChanged',
|
||||||
// Identifier for a FPS drop event - data: {curentDropped, currentDecoded, totalDroppedFrames}
|
// Identifier for a FPS drop event - data: {curentDropped, currentDecoded, totalDroppedFrames}
|
||||||
FPS_DROP: 'hlsFPSDrop',
|
FPS_DROP: 'hlsFpsDrop',
|
||||||
// Identifier for an error event - data: { type : error type, details : error details, fatal : if true, hls.js cannot/will not try to recover, if false, hls.js will try to recover,other error specific data}
|
// Identifier for an error event - data: { type : error type, details : error details, fatal : if true, hls.js cannot/will not try to recover, if false, hls.js will try to recover,other error specific data}
|
||||||
ERROR: 'hlsError',
|
ERROR: 'hlsError',
|
||||||
// fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a media to the instance of hls.js to handle mid-rolls for example
|
// fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a media to the instance of hls.js to handle mid-rolls for example
|
||||||
|
|
|
@ -41,6 +41,8 @@ class Hls {
|
||||||
debug: false,
|
debug: false,
|
||||||
maxBufferLength: 30,
|
maxBufferLength: 30,
|
||||||
maxBufferSize: 60 * 1000 * 1000,
|
maxBufferSize: 60 * 1000 * 1000,
|
||||||
|
maxBufferHole: 0.3,
|
||||||
|
maxSeekHole: 2,
|
||||||
liveSyncDurationCount:3,
|
liveSyncDurationCount:3,
|
||||||
liveMaxLatencyDurationCount: Infinity,
|
liveMaxLatencyDurationCount: Infinity,
|
||||||
maxMaxBufferLength: 600,
|
maxMaxBufferLength: 600,
|
||||||
|
|
|
@ -3,14 +3,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Event from '../events';
|
import Event from '../events';
|
||||||
|
import EventHandler from '../event-handler';
|
||||||
import {ErrorTypes, ErrorDetails} from '../errors';
|
import {ErrorTypes, ErrorDetails} from '../errors';
|
||||||
|
|
||||||
class FragmentLoader {
|
class FragmentLoader extends EventHandler {
|
||||||
|
|
||||||
constructor(hls) {
|
constructor(hls) {
|
||||||
this.hls = hls;
|
super(hls, Event.FRAG_LOADING);
|
||||||
this.onfl = this.onFragLoading.bind(this);
|
|
||||||
hls.on(Event.FRAG_LOADING, this.onfl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
|
@ -18,10 +17,10 @@ class FragmentLoader {
|
||||||
this.loader.destroy();
|
this.loader.destroy();
|
||||||
this.loader = null;
|
this.loader = null;
|
||||||
}
|
}
|
||||||
this.hls.off(Event.FRAG_LOADING, this.onfl);
|
EventHandler.prototype.destroy.call(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onFragLoading(event, data) {
|
onFragLoading(data) {
|
||||||
var frag = data.frag;
|
var frag = data.frag;
|
||||||
this.frag = frag;
|
this.frag = frag;
|
||||||
this.frag.loaded = 0;
|
this.frag.loaded = 0;
|
||||||
|
|
|
@ -3,16 +3,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Event from '../events';
|
import Event from '../events';
|
||||||
|
import EventHandler from '../event-handler';
|
||||||
import {ErrorTypes, ErrorDetails} from '../errors';
|
import {ErrorTypes, ErrorDetails} from '../errors';
|
||||||
|
|
||||||
class KeyLoader {
|
class KeyLoader extends EventHandler {
|
||||||
|
|
||||||
constructor(hls) {
|
constructor(hls) {
|
||||||
this.hls = hls;
|
super(hls, Event.KEY_LOADING);
|
||||||
this.decryptkey = null;
|
this.decryptkey = null;
|
||||||
this.decrypturl = null;
|
this.decrypturl = null;
|
||||||
this.ondkl = this.onDecryptKeyLoading.bind(this);
|
|
||||||
hls.on(Event.KEY_LOADING, this.ondkl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
|
@ -20,10 +19,10 @@ class KeyLoader {
|
||||||
this.loader.destroy();
|
this.loader.destroy();
|
||||||
this.loader = null;
|
this.loader = null;
|
||||||
}
|
}
|
||||||
this.hls.off(Event.KEY_LOADING, this.ondkl);
|
EventHandler.prototype.destroy.call(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDecryptKeyLoading(event, data) {
|
onKeyLoading(data) {
|
||||||
var frag = this.frag = data.frag,
|
var frag = this.frag = data.frag,
|
||||||
decryptdata = frag.decryptdata,
|
decryptdata = frag.decryptdata,
|
||||||
uri = decryptdata.uri;
|
uri = decryptdata.uri;
|
||||||
|
|
|
@ -3,19 +3,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Event from '../events';
|
import Event from '../events';
|
||||||
|
import EventHandler from '../event-handler';
|
||||||
import {ErrorTypes, ErrorDetails} from '../errors';
|
import {ErrorTypes, ErrorDetails} from '../errors';
|
||||||
import URLHelper from '../utils/url';
|
import URLHelper from '../utils/url';
|
||||||
import AttrList from '../utils/attr-list';
|
import AttrList from '../utils/attr-list';
|
||||||
//import {logger} from '../utils/logger';
|
//import {logger} from '../utils/logger';
|
||||||
|
|
||||||
class PlaylistLoader {
|
class PlaylistLoader extends EventHandler {
|
||||||
|
|
||||||
constructor(hls) {
|
constructor(hls) {
|
||||||
this.hls = hls;
|
super(hls,
|
||||||
this.onml = this.onManifestLoading.bind(this);
|
Event.MANIFEST_LOADING,
|
||||||
this.onll = this.onLevelLoading.bind(this);
|
Event.LEVEL_LOADING);
|
||||||
hls.on(Event.MANIFEST_LOADING, this.onml);
|
|
||||||
hls.on(Event.LEVEL_LOADING, this.onll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
|
@ -24,15 +23,14 @@ class PlaylistLoader {
|
||||||
this.loader = null;
|
this.loader = null;
|
||||||
}
|
}
|
||||||
this.url = this.id = null;
|
this.url = this.id = null;
|
||||||
this.hls.off(Event.MANIFEST_LOADING, this.onml);
|
EventHandler.prototype.destroy.call(this);
|
||||||
this.hls.off(Event.LEVEL_LOADING, this.onll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onManifestLoading(event, data) {
|
onManifestLoading(data) {
|
||||||
this.load(data.url, null);
|
this.load(data.url, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
onLevelLoading(event, data) {
|
onLevelLoading(data) {
|
||||||
this.load(data.url, data.level, data.id);
|
this.load(data.url, data.level, data.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,7 @@ class MP4Remuxer {
|
||||||
mdat, moof,
|
mdat, moof,
|
||||||
firstPTS, firstDTS, lastDTS,
|
firstPTS, firstDTS, lastDTS,
|
||||||
pts, dts, ptsnorm, dtsnorm,
|
pts, dts, ptsnorm, dtsnorm,
|
||||||
|
flags,
|
||||||
samples = [];
|
samples = [];
|
||||||
/* concatenate the video data and construct the mdat in place
|
/* concatenate the video data and construct the mdat in place
|
||||||
(need 8 more bytes to fill length and mpdat type) */
|
(need 8 more bytes to fill length and mpdat type) */
|
||||||
|
@ -152,7 +153,7 @@ class MP4Remuxer {
|
||||||
dts = avcSample.dts - this._initDTS;
|
dts = avcSample.dts - this._initDTS;
|
||||||
// ensure DTS is not bigger than PTS
|
// ensure DTS is not bigger than PTS
|
||||||
dts = Math.min(pts,dts);
|
dts = Math.min(pts,dts);
|
||||||
//logger.log(`Video/PTS/DTS:${pts}/${dts}`);
|
//logger.log(`Video/PTS/DTS:${Math.round(pts/90)}/${Math.round(dts/90)}`);
|
||||||
// if not first AVC sample of video track, normalize PTS/DTS with previous sample value
|
// if not first AVC sample of video track, normalize PTS/DTS with previous sample value
|
||||||
// and ensure that sample duration is positive
|
// and ensure that sample duration is positive
|
||||||
if (lastDTS !== undefined) {
|
if (lastDTS !== undefined) {
|
||||||
|
@ -201,13 +202,14 @@ class MP4Remuxer {
|
||||||
degradPrio: 0
|
degradPrio: 0
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
flags = mp4Sample.flags;
|
||||||
if (avcSample.key === true) {
|
if (avcSample.key === true) {
|
||||||
// the current sample is a key frame
|
// the current sample is a key frame
|
||||||
mp4Sample.flags.dependsOn = 2;
|
flags.dependsOn = 2;
|
||||||
mp4Sample.flags.isNonSync = 0;
|
flags.isNonSync = 0;
|
||||||
} else {
|
} else {
|
||||||
mp4Sample.flags.dependsOn = 1;
|
flags.dependsOn = 1;
|
||||||
mp4Sample.flags.isNonSync = 1;
|
flags.isNonSync = 1;
|
||||||
}
|
}
|
||||||
samples.push(mp4Sample);
|
samples.push(mp4Sample);
|
||||||
lastDTS = dtsnorm;
|
lastDTS = dtsnorm;
|
||||||
|
@ -222,7 +224,7 @@ class MP4Remuxer {
|
||||||
track.len = 0;
|
track.len = 0;
|
||||||
track.nbNalu = 0;
|
track.nbNalu = 0;
|
||||||
if(samples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
|
if(samples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
|
||||||
var flags = samples[0].flags;
|
flags = samples[0].flags;
|
||||||
// chrome workaround, mark first sample as being a Random Access Point to avoid sourcebuffer append issue
|
// chrome workaround, mark first sample as being a Random Access Point to avoid sourcebuffer append issue
|
||||||
// https://code.google.com/p/chromium/issues/detail?id=229412
|
// https://code.google.com/p/chromium/issues/detail?id=229412
|
||||||
flags.dependsOn = 2;
|
flags.dependsOn = 2;
|
||||||
|
@ -270,7 +272,7 @@ class MP4Remuxer {
|
||||||
unit = aacSample.unit;
|
unit = aacSample.unit;
|
||||||
pts = aacSample.pts - this._initDTS;
|
pts = aacSample.pts - this._initDTS;
|
||||||
dts = aacSample.dts - this._initDTS;
|
dts = aacSample.dts - this._initDTS;
|
||||||
//logger.log(`Audio/PTS:${aacSample.pts.toFixed(0)}`);
|
//logger.log(`Audio/PTS:${Math.round(pts/90)}`);
|
||||||
// if not first sample
|
// if not first sample
|
||||||
if (lastDTS !== undefined) {
|
if (lastDTS !== undefined) {
|
||||||
ptsnorm = this._PTSNormalize(pts, lastDTS);
|
ptsnorm = this._PTSNormalize(pts, lastDTS);
|
||||||
|
|
|
@ -49,7 +49,7 @@ class XhrLoader {
|
||||||
|
|
||||||
loadInternal() {
|
loadInternal() {
|
||||||
var xhr = this.loader = new XMLHttpRequest();
|
var xhr = this.loader = new XMLHttpRequest();
|
||||||
xhr.onreadystatechange = this.statechange.bind(this);
|
xhr.onloadend = this.loadend.bind(this);
|
||||||
xhr.onprogress = this.loadprogress.bind(this);
|
xhr.onprogress = this.loadprogress.bind(this);
|
||||||
|
|
||||||
xhr.open('GET', this.url, true);
|
xhr.open('GET', this.url, true);
|
||||||
|
@ -65,13 +65,12 @@ class XhrLoader {
|
||||||
xhr.send();
|
xhr.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
statechange(event) {
|
loadend(event) {
|
||||||
var xhr = event.currentTarget,
|
var xhr = event.currentTarget,
|
||||||
status = xhr.status,
|
status = xhr.status,
|
||||||
stats = this.stats;
|
stats = this.stats;
|
||||||
// don't proceed if xhr has been aborted
|
// don't proceed if xhr has been aborted
|
||||||
// 4 = Response from server has been completely loaded.
|
if (!stats.aborted) {
|
||||||
if (!stats.aborted && xhr.readyState === 4) {
|
|
||||||
// http status between 200 to 299 are all successful
|
// http status between 200 to 299 are all successful
|
||||||
if (status >= 200 && status < 300) {
|
if (status >= 200 && status < 300) {
|
||||||
window.clearTimeout(this.timeoutHandle);
|
window.clearTimeout(this.timeoutHandle);
|
||||||
|
|
|
@ -32,14 +32,14 @@
|
||||||
"iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0"
|
"iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0"
|
||||||
},
|
},
|
||||||
"ignore": [],
|
"ignore": [],
|
||||||
"homepage": "https://github.com/PolymerElements/paper-ripple",
|
"homepage": "https://github.com/polymerelements/paper-ripple",
|
||||||
"_release": "1.0.5",
|
"_release": "1.0.5",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "v1.0.5",
|
"tag": "v1.0.5",
|
||||||
"commit": "d72e7a9a8ab518b901ed18dde492df3b87a93be5"
|
"commit": "d72e7a9a8ab518b901ed18dde492df3b87a93be5"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/PolymerElements/paper-ripple.git",
|
"_source": "git://github.com/polymerelements/paper-ripple.git",
|
||||||
"_target": "^1.0.0",
|
"_target": "^1.0.0",
|
||||||
"_originalSource": "PolymerElements/paper-ripple"
|
"_originalSource": "polymerelements/paper-ripple"
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue