@clappr/hlsjs-playback 3.0.3 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -36
- package/dist/hlsjs-playback.esm.js +101 -383
- package/dist/hlsjs-playback.esm.js.map +1 -1
- package/dist/hlsjs-playback.js +185 -442
- package/dist/hlsjs-playback.js.map +1 -1
- package/dist/hlsjs-playback.min.js +1 -2
- package/dist/hlsjs-playback.min.js.map +1 -1
- package/package.json +11 -12
- package/src/dist.smoke.test.js +14 -7
- package/src/hls.js +2 -1
- package/src/hls.test.js +140 -62
package/dist/hlsjs-playback.js
CHANGED
|
@@ -1,162 +1,68 @@
|
|
|
1
|
+
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
|
|
2
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
|
|
5
|
+
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
|
|
6
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
7
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
8
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
9
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
10
|
+
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
11
|
+
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
12
|
+
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
13
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
14
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
15
|
+
function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
|
|
16
|
+
function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
|
|
17
|
+
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
18
|
+
function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
|
|
19
|
+
function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
|
|
20
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
21
|
+
function _superPropGet(t, o, e, r) { var p = _get(_getPrototypeOf(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; }
|
|
22
|
+
function _get() { return _get = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) { var p = _superPropBase(e, t); if (p) { var n = Object.getOwnPropertyDescriptor(p, t); return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value; } }, _get.apply(null, arguments); }
|
|
23
|
+
function _superPropBase(t, o) { for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t));); return t; }
|
|
24
|
+
function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
|
|
25
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
1
26
|
(function (global, factory) {
|
|
2
|
-
typeof exports ===
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
function _callSuper(t, o, e) {
|
|
20
|
-
return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
|
|
21
|
-
}
|
|
22
|
-
function _classCallCheck(a, n) {
|
|
23
|
-
if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
|
|
24
|
-
}
|
|
25
|
-
function _defineProperties(e, r) {
|
|
26
|
-
for (var t = 0; t < r.length; t++) {
|
|
27
|
-
var o = r[t];
|
|
28
|
-
o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
function _createClass(e, r, t) {
|
|
32
|
-
return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
|
|
33
|
-
writable: false
|
|
34
|
-
}), e;
|
|
35
|
-
}
|
|
36
|
-
function _defineProperty(e, r, t) {
|
|
37
|
-
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
38
|
-
value: t,
|
|
39
|
-
enumerable: true,
|
|
40
|
-
configurable: true,
|
|
41
|
-
writable: true
|
|
42
|
-
}) : e[r] = t, e;
|
|
43
|
-
}
|
|
44
|
-
function _get() {
|
|
45
|
-
return _get = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) {
|
|
46
|
-
var p = _superPropBase(e, t);
|
|
47
|
-
if (p) {
|
|
48
|
-
var n = Object.getOwnPropertyDescriptor(p, t);
|
|
49
|
-
return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value;
|
|
50
|
-
}
|
|
51
|
-
}, _get.apply(null, arguments);
|
|
52
|
-
}
|
|
53
|
-
function _getPrototypeOf(t) {
|
|
54
|
-
return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
|
|
55
|
-
return t.__proto__ || Object.getPrototypeOf(t);
|
|
56
|
-
}, _getPrototypeOf(t);
|
|
57
|
-
}
|
|
58
|
-
function _inherits(t, e) {
|
|
59
|
-
if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
|
|
60
|
-
t.prototype = Object.create(e && e.prototype, {
|
|
61
|
-
constructor: {
|
|
62
|
-
value: t,
|
|
63
|
-
writable: true,
|
|
64
|
-
configurable: true
|
|
65
|
-
}
|
|
66
|
-
}), Object.defineProperty(t, "prototype", {
|
|
67
|
-
writable: false
|
|
68
|
-
}), e && _setPrototypeOf(t, e);
|
|
69
|
-
}
|
|
70
|
-
function _isNativeReflectConstruct() {
|
|
71
|
-
try {
|
|
72
|
-
var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
|
|
73
|
-
} catch (t) {}
|
|
74
|
-
return (_isNativeReflectConstruct = function () {
|
|
75
|
-
return !!t;
|
|
76
|
-
})();
|
|
77
|
-
}
|
|
78
|
-
function _iterableToArray(r) {
|
|
79
|
-
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
|
|
80
|
-
}
|
|
81
|
-
function _nonIterableSpread() {
|
|
82
|
-
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
83
|
-
}
|
|
84
|
-
function ownKeys(e, r) {
|
|
85
|
-
var t = Object.keys(e);
|
|
86
|
-
if (Object.getOwnPropertySymbols) {
|
|
87
|
-
var o = Object.getOwnPropertySymbols(e);
|
|
88
|
-
r && (o = o.filter(function (r) {
|
|
89
|
-
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
90
|
-
})), t.push.apply(t, o);
|
|
91
|
-
}
|
|
92
|
-
return t;
|
|
93
|
-
}
|
|
94
|
-
function _objectSpread2(e) {
|
|
95
|
-
for (var r = 1; r < arguments.length; r++) {
|
|
96
|
-
var t = null != arguments[r] ? arguments[r] : {};
|
|
97
|
-
r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
|
|
98
|
-
_defineProperty(e, r, t[r]);
|
|
99
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
|
|
100
|
-
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
27
|
+
(typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined" ? module.exports = factory(require("@clappr/core"), require("hls.js")) : typeof define === "function" && define.amd ? define(["@clappr/core", "hls.js"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, global.HlsjsPlayback = factory(global.Clappr, global.Hls));
|
|
28
|
+
})(this, function (_clappr_core, hls_js) {
|
|
29
|
+
//#region \0rolldown/runtime.js
|
|
30
|
+
var __create = Object.create;
|
|
31
|
+
var __defProp = Object.defineProperty;
|
|
32
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
33
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
34
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
35
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
36
|
+
var __copyProps = function __copyProps(to, from, except, desc) {
|
|
37
|
+
if (from && _typeof(from) === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
38
|
+
key = keys[i];
|
|
39
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
40
|
+
get: function (k) {
|
|
41
|
+
return from[k];
|
|
42
|
+
}.bind(null, key),
|
|
43
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
101
44
|
});
|
|
102
45
|
}
|
|
103
|
-
return
|
|
104
|
-
}
|
|
105
|
-
function
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
function _superPropGet(t, o, e, r) {
|
|
120
|
-
var p = _get(_getPrototypeOf(t.prototype ), o, e);
|
|
121
|
-
return 2 & r && "function" == typeof p ? function (t) {
|
|
122
|
-
return p.apply(e, t);
|
|
123
|
-
} : p;
|
|
124
|
-
}
|
|
125
|
-
function _toConsumableArray(r) {
|
|
126
|
-
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
|
|
127
|
-
}
|
|
128
|
-
function _toPrimitive(t, r) {
|
|
129
|
-
if ("object" != typeof t || !t) return t;
|
|
130
|
-
var e = t[Symbol.toPrimitive];
|
|
131
|
-
if (void 0 !== e) {
|
|
132
|
-
var i = e.call(t, r);
|
|
133
|
-
if ("object" != typeof i) return i;
|
|
134
|
-
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
135
|
-
}
|
|
136
|
-
return (String )(t);
|
|
137
|
-
}
|
|
138
|
-
function _toPropertyKey(t) {
|
|
139
|
-
var i = _toPrimitive(t, "string");
|
|
140
|
-
return "symbol" == typeof i ? i : i + "";
|
|
141
|
-
}
|
|
142
|
-
function _unsupportedIterableToArray(r, a) {
|
|
143
|
-
if (r) {
|
|
144
|
-
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
145
|
-
var t = {}.toString.call(r).slice(8, -1);
|
|
146
|
-
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (!HLSJS) {
|
|
151
|
-
throw new Error('@clappr/hlsjs-playback requires hls.js (^1) to be loaded before it');
|
|
152
|
-
}
|
|
153
|
-
var now = core.Utils.now,
|
|
154
|
-
listContainsIgnoreCase = core.Utils.listContainsIgnoreCase;
|
|
46
|
+
return to;
|
|
47
|
+
};
|
|
48
|
+
var __toESM = function __toESM(mod, isNodeMode, target) {
|
|
49
|
+
return target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
50
|
+
value: mod,
|
|
51
|
+
enumerable: true
|
|
52
|
+
}) : target, mod);
|
|
53
|
+
};
|
|
54
|
+
//#endregion
|
|
55
|
+
hls_js = __toESM(hls_js);
|
|
56
|
+
//#region src/hls.js
|
|
57
|
+
if (!hls_js.default) throw new Error("@clappr/hlsjs-playback requires hls.js (^1) to be loaded before it");
|
|
58
|
+
var _clappr_core$Utils = _clappr_core.Utils,
|
|
59
|
+
now = _clappr_core$Utils.now,
|
|
60
|
+
listContainsIgnoreCase = _clappr_core$Utils.listContainsIgnoreCase;
|
|
155
61
|
var AUTO = -1;
|
|
156
62
|
var DEFAULT_RECOVER_ATTEMPTS = 16;
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
var HlsjsPlayback = /*#__PURE__*/function (
|
|
63
|
+
_clappr_core.Events.register("PLAYBACK_FRAGMENT_CHANGED");
|
|
64
|
+
_clappr_core.Events.register("PLAYBACK_FRAGMENT_PARSING_METADATA");
|
|
65
|
+
var HlsjsPlayback = /*#__PURE__*/function (_clappr_core$HTML5Vid) {
|
|
160
66
|
function HlsjsPlayback() {
|
|
161
67
|
var _this;
|
|
162
68
|
_classCallCheck(this, HlsjsPlayback);
|
|
@@ -164,24 +70,24 @@
|
|
|
164
70
|
args[_key] = arguments[_key];
|
|
165
71
|
}
|
|
166
72
|
_this = _callSuper(this, HlsjsPlayback, [].concat(args));
|
|
167
|
-
_this.options.hlsPlayback =
|
|
73
|
+
_this.options.hlsPlayback = _objectSpread(_objectSpread({}, _this.defaultOptions), _this.options.hlsPlayback);
|
|
168
74
|
_this._timeUpdateThrottleDelay = 200;
|
|
169
|
-
_this._timeUpdateFiringRate =
|
|
170
|
-
_this._durationChangeMinOffset =
|
|
75
|
+
_this._timeUpdateFiringRate = .2;
|
|
76
|
+
_this._durationChangeMinOffset = .5;
|
|
171
77
|
_this._setInitialState();
|
|
172
78
|
return _this;
|
|
173
79
|
}
|
|
174
|
-
_inherits(HlsjsPlayback,
|
|
80
|
+
_inherits(HlsjsPlayback, _clappr_core$HTML5Vid);
|
|
175
81
|
return _createClass(HlsjsPlayback, [{
|
|
176
82
|
key: "name",
|
|
177
83
|
get: function get() {
|
|
178
|
-
return
|
|
84
|
+
return "hls";
|
|
179
85
|
}
|
|
180
86
|
}, {
|
|
181
87
|
key: "supportedVersion",
|
|
182
88
|
get: function get() {
|
|
183
89
|
return {
|
|
184
|
-
min: "0.
|
|
90
|
+
min: "0.17.1"
|
|
185
91
|
};
|
|
186
92
|
}
|
|
187
93
|
}, {
|
|
@@ -192,20 +98,12 @@
|
|
|
192
98
|
}, {
|
|
193
99
|
key: "currentLevel",
|
|
194
100
|
get: function get() {
|
|
195
|
-
if (this._currentLevel === null || this._currentLevel ===
|
|
196
|
-
return AUTO;
|
|
197
|
-
} else {
|
|
198
|
-
return this._currentLevel;
|
|
199
|
-
} // 0 is a valid level ID
|
|
101
|
+
if (this._currentLevel === null || this._currentLevel === void 0) return AUTO;else return this._currentLevel;
|
|
200
102
|
},
|
|
201
103
|
set: function set(id) {
|
|
202
104
|
this._currentLevel = id;
|
|
203
|
-
this.trigger(
|
|
204
|
-
if (this.options.playback.hlsUseNextLevel)
|
|
205
|
-
this._hls.nextLevel = this._currentLevel;
|
|
206
|
-
} else {
|
|
207
|
-
this._hls.currentLevel = this._currentLevel;
|
|
208
|
-
}
|
|
105
|
+
this.trigger(_clappr_core.Events.PLAYBACK_LEVEL_SWITCH_START);
|
|
106
|
+
if (this.options.playback.hlsUseNextLevel) this._hls.nextLevel = this._currentLevel;else this._hls.currentLevel = this._currentLevel;
|
|
209
107
|
}
|
|
210
108
|
}, {
|
|
211
109
|
key: "isReady",
|
|
@@ -230,9 +128,7 @@
|
|
|
230
128
|
}, {
|
|
231
129
|
key: "_startTime",
|
|
232
130
|
get: function get() {
|
|
233
|
-
if (this._playbackType ===
|
|
234
|
-
return this._extrapolatedStartTime;
|
|
235
|
-
}
|
|
131
|
+
if (this._playbackType === _clappr_core.Playback.LIVE && this._playlistType !== "EVENT") return this._extrapolatedStartTime;
|
|
236
132
|
return this._playableRegionStartTime;
|
|
237
133
|
}
|
|
238
134
|
}, {
|
|
@@ -240,24 +136,15 @@
|
|
|
240
136
|
get: function get() {
|
|
241
137
|
return now();
|
|
242
138
|
}
|
|
243
|
-
|
|
244
|
-
// the time in the video element which should represent the start of the sliding window
|
|
245
|
-
// extrapolated to increase in real time (instead of jumping as the early segments are removed)
|
|
246
139
|
}, {
|
|
247
140
|
key: "_extrapolatedStartTime",
|
|
248
141
|
get: function get() {
|
|
249
|
-
if (!this._localStartTimeCorrelation)
|
|
250
|
-
return this._playableRegionStartTime;
|
|
251
|
-
}
|
|
142
|
+
if (!this._localStartTimeCorrelation) return this._playableRegionStartTime;
|
|
252
143
|
var corr = this._localStartTimeCorrelation;
|
|
253
144
|
var timePassed = this._now - corr.local;
|
|
254
|
-
var extrapolatedWindowStartTime = (corr.remote + timePassed) /
|
|
255
|
-
// cap at the end of the extrapolated window duration
|
|
145
|
+
var extrapolatedWindowStartTime = (corr.remote + timePassed) / 1e3;
|
|
256
146
|
return Math.min(extrapolatedWindowStartTime, this._playableRegionStartTime + this._extrapolatedWindowDuration);
|
|
257
147
|
}
|
|
258
|
-
|
|
259
|
-
// the time in the video element which should represent the end of the content
|
|
260
|
-
// extrapolated to increase in real time (instead of jumping as segments are added)
|
|
261
148
|
}, {
|
|
262
149
|
key: "_extrapolatedEndTime",
|
|
263
150
|
get: function get() {
|
|
@@ -265,7 +152,7 @@
|
|
|
265
152
|
if (!this._localEndTimeCorrelation) return actualEndTime;
|
|
266
153
|
var correlation = this._localEndTimeCorrelation;
|
|
267
154
|
var timePassed = this._now - correlation.local;
|
|
268
|
-
var extrapolatedEndTime = (correlation.remote + timePassed) /
|
|
155
|
+
var extrapolatedEndTime = (correlation.remote + timePassed) / 1e3;
|
|
269
156
|
return Math.max(actualEndTime - this._extrapolatedWindowDuration, Math.min(extrapolatedEndTime, actualEndTime));
|
|
270
157
|
}
|
|
271
158
|
}, {
|
|
@@ -273,30 +160,10 @@
|
|
|
273
160
|
get: function get() {
|
|
274
161
|
return this._extrapolatedEndTime - this._startTime;
|
|
275
162
|
}
|
|
276
|
-
|
|
277
|
-
// Returns the duration (seconds) of the window that the extrapolated start time is allowed
|
|
278
|
-
// to move in before being capped.
|
|
279
|
-
// The extrapolated start time should never reach the cap at the end of the window as the
|
|
280
|
-
// window should slide as chunks are removed from the start.
|
|
281
|
-
// This also applies to the extrapolated end time in the same way.
|
|
282
|
-
//
|
|
283
|
-
// If chunks aren't being removed for some reason that the start time will reach and remain fixed at
|
|
284
|
-
// playableRegionStartTime + extrapolatedWindowDuration
|
|
285
|
-
//
|
|
286
|
-
// <-- window duration -->
|
|
287
|
-
// I.e playableRegionStartTime |-----------------------|
|
|
288
|
-
// | --> . . .
|
|
289
|
-
// . --> | --> . .
|
|
290
|
-
// . . --> | --> .
|
|
291
|
-
// . . . --> |
|
|
292
|
-
// . . . .
|
|
293
|
-
// extrapolatedStartTime
|
|
294
163
|
}, {
|
|
295
164
|
key: "_extrapolatedWindowDuration",
|
|
296
165
|
get: function get() {
|
|
297
|
-
if (this._segmentTargetDuration === null)
|
|
298
|
-
return 0;
|
|
299
|
-
}
|
|
166
|
+
if (this._segmentTargetDuration === null) return 0;
|
|
300
167
|
return this._extrapolatedWindowNumSegments * this._segmentTargetDuration;
|
|
301
168
|
}
|
|
302
169
|
}, {
|
|
@@ -325,23 +192,15 @@
|
|
|
325
192
|
key: "currentTimestamp",
|
|
326
193
|
get: function get() {
|
|
327
194
|
if (!this._currentFragment) return null;
|
|
328
|
-
|
|
329
|
-
var playbackTime = this.el.currentTime;
|
|
330
|
-
var playTimeOffSet = playbackTime - this._currentFragment.start;
|
|
331
|
-
var currentTimestampInMs = startTime + playTimeOffSet * 1000;
|
|
332
|
-
return currentTimestampInMs / 1000;
|
|
195
|
+
return (this._currentFragment.programDateTime + (this.el.currentTime - this._currentFragment.start) * 1e3) / 1e3;
|
|
333
196
|
}
|
|
334
197
|
}, {
|
|
335
198
|
key: "_setInitialState",
|
|
336
199
|
value: function _setInitialState() {
|
|
337
200
|
var _this$options$hlsReco;
|
|
338
|
-
this._minDvrSize = typeof this.options.hlsMinimumDvrSize ===
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
// removed from the start of the playlist at a time. E.g if the playlist is cached for 10 seconds and new chunks are
|
|
342
|
-
// added/removed every 5.
|
|
343
|
-
this._extrapolatedWindowNumSegments = !this.options.playback || typeof this.options.playback.extrapolatedWindowNumSegments === 'undefined' ? 2 : this.options.playback.extrapolatedWindowNumSegments;
|
|
344
|
-
this._playbackType = core.Playback.VOD;
|
|
201
|
+
this._minDvrSize = typeof this.options.hlsMinimumDvrSize === "undefined" ? 60 : this.options.hlsMinimumDvrSize;
|
|
202
|
+
this._extrapolatedWindowNumSegments = !this.options.playback || typeof this.options.playback.extrapolatedWindowNumSegments === "undefined" ? 2 : this.options.playback.extrapolatedWindowNumSegments;
|
|
203
|
+
this._playbackType = _clappr_core.Playback.VOD;
|
|
345
204
|
this._lastTimeUpdate = {
|
|
346
205
|
current: 0,
|
|
347
206
|
total: 0,
|
|
@@ -349,32 +208,13 @@
|
|
|
349
208
|
};
|
|
350
209
|
this._lastTimeUpdateFiredTime = 0;
|
|
351
210
|
this._lastDuration = null;
|
|
352
|
-
// for hls streams which have dvr with a sliding window,
|
|
353
|
-
// the content at the start of the playlist is removed as new
|
|
354
|
-
// content is appended at the end.
|
|
355
|
-
// this means the actual playable start time will increase as the
|
|
356
|
-
// start content is deleted
|
|
357
|
-
// For streams with dvr where the entire recording is kept from the
|
|
358
|
-
// beginning this should stay as 0
|
|
359
211
|
this._playableRegionStartTime = 0;
|
|
360
|
-
// {local, remote} remote is the time in the video element that should represent 0
|
|
361
|
-
// local is the system time when the 'remote' measurment took place
|
|
362
212
|
this._localStartTimeCorrelation = null;
|
|
363
|
-
// {local, remote} remote is the time in the video element that should represents the end
|
|
364
|
-
// local is the system time when the 'remote' measurment took place
|
|
365
213
|
this._localEndTimeCorrelation = null;
|
|
366
|
-
// if content is removed from the beginning then this empty area should
|
|
367
|
-
// be ignored. "playableRegionDuration" excludes the empty area
|
|
368
214
|
this._playableRegionDuration = 0;
|
|
369
|
-
// #EXT-X-PROGRAM-DATE-TIME
|
|
370
215
|
this._programDateTime = 0;
|
|
371
|
-
// true when the actual duration is longer than hlsjs's live sync point
|
|
372
|
-
// when this is false playableRegionDuration will be the actual duration
|
|
373
|
-
// when this is true playableRegionDuration will exclude the time after the sync point
|
|
374
216
|
this._durationExcludesAfterLiveSyncPoint = false;
|
|
375
|
-
// #EXT-X-TARGETDURATION
|
|
376
217
|
this._segmentTargetDuration = null;
|
|
377
|
-
// #EXT-X-PLAYLIST-TYPE
|
|
378
218
|
this._playlistType = null;
|
|
379
219
|
this._recoverAttemptsRemaining = (_this$options$hlsReco = this.options.hlsRecoverAttempts) !== null && _this$options$hlsReco !== void 0 ? _this$options$hlsReco : DEFAULT_RECOVER_ATTEMPTS;
|
|
380
220
|
}
|
|
@@ -400,8 +240,8 @@
|
|
|
400
240
|
}, {
|
|
401
241
|
key: "_createHLSInstance",
|
|
402
242
|
value: function _createHLSInstance() {
|
|
403
|
-
var config =
|
|
404
|
-
this._hls = new
|
|
243
|
+
var config = _objectSpread({}, this.options.playback.hlsjsConfig);
|
|
244
|
+
this._hls = new hls_js.default(config);
|
|
405
245
|
}
|
|
406
246
|
}, {
|
|
407
247
|
key: "_attachHLSMedia",
|
|
@@ -414,40 +254,40 @@
|
|
|
414
254
|
value: function _listenHLSEvents() {
|
|
415
255
|
var _this2 = this;
|
|
416
256
|
if (!this._hls) return;
|
|
417
|
-
this._hls.once(
|
|
257
|
+
this._hls.once(hls_js.default.Events.MEDIA_ATTACHED, function () {
|
|
418
258
|
_this2.options.hlsPlayback.preload && _this2._hls.loadSource(_this2.options.src);
|
|
419
259
|
});
|
|
420
|
-
this._hls.on(
|
|
260
|
+
this._hls.on(hls_js.default.Events.MANIFEST_LOADING, function () {
|
|
421
261
|
_this2._manifestLoading = true;
|
|
422
262
|
});
|
|
423
|
-
this._hls.on(
|
|
263
|
+
this._hls.on(hls_js.default.Events.LEVEL_LOADED, function (evt, data) {
|
|
424
264
|
return _this2._updatePlaybackType(evt, data);
|
|
425
265
|
});
|
|
426
|
-
this._hls.on(
|
|
266
|
+
this._hls.on(hls_js.default.Events.LEVEL_UPDATED, function (evt, data) {
|
|
427
267
|
return _this2._onLevelUpdated(evt, data);
|
|
428
268
|
});
|
|
429
|
-
this._hls.on(
|
|
269
|
+
this._hls.on(hls_js.default.Events.LEVEL_SWITCHED, function (evt, data) {
|
|
430
270
|
return _this2._onLevelSwitch(evt, data);
|
|
431
271
|
});
|
|
432
|
-
this._hls.on(
|
|
272
|
+
this._hls.on(hls_js.default.Events.FRAG_CHANGED, function (evt, data) {
|
|
433
273
|
return _this2._onFragmentChanged(evt, data);
|
|
434
274
|
});
|
|
435
|
-
this._hls.on(
|
|
275
|
+
this._hls.on(hls_js.default.Events.FRAG_LOADED, function (evt, data) {
|
|
436
276
|
return _this2._onFragmentLoaded(evt, data);
|
|
437
277
|
});
|
|
438
|
-
this._hls.on(
|
|
278
|
+
this._hls.on(hls_js.default.Events.FRAG_BUFFERED, function (evt, data) {
|
|
439
279
|
return _this2._onFragmentBuffered(evt, data);
|
|
440
280
|
});
|
|
441
|
-
this._hls.on(
|
|
281
|
+
this._hls.on(hls_js.default.Events.FRAG_PARSING_METADATA, function (evt, data) {
|
|
442
282
|
return _this2._onFragmentParsingMetadata(evt, data);
|
|
443
283
|
});
|
|
444
|
-
this._hls.on(
|
|
284
|
+
this._hls.on(hls_js.default.Events.ERROR, function (evt, data) {
|
|
445
285
|
return _this2._onHLSJSError(evt, data);
|
|
446
286
|
});
|
|
447
|
-
this._hls.on(
|
|
287
|
+
this._hls.on(hls_js.default.Events.SUBTITLE_TRACK_LOADED, function (evt, data) {
|
|
448
288
|
return _this2._onSubtitleLoaded(evt, data);
|
|
449
289
|
});
|
|
450
|
-
this._hls.on(
|
|
290
|
+
this._hls.on(hls_js.default.Events.SUBTITLE_TRACKS_UPDATED, function () {
|
|
451
291
|
return _this2._ccTracksUpdated = true;
|
|
452
292
|
});
|
|
453
293
|
this.bindCustomListeners();
|
|
@@ -458,7 +298,7 @@
|
|
|
458
298
|
var _this3 = this;
|
|
459
299
|
this.customListeners.forEach(function (item) {
|
|
460
300
|
var requestedEventName = item.eventName;
|
|
461
|
-
var typeOfListener = item.once ?
|
|
301
|
+
var typeOfListener = item.once ? "once" : "on";
|
|
462
302
|
requestedEventName && _this3._hls["".concat(typeOfListener)](requestedEventName, item.callback);
|
|
463
303
|
});
|
|
464
304
|
}
|
|
@@ -474,7 +314,7 @@
|
|
|
474
314
|
}, {
|
|
475
315
|
key: "_onFragmentParsingMetadata",
|
|
476
316
|
value: function _onFragmentParsingMetadata(evt, data) {
|
|
477
|
-
this.trigger(
|
|
317
|
+
this.trigger(_clappr_core.Events.Custom.PLAYBACK_FRAGMENT_PARSING_METADATA, {
|
|
478
318
|
evt: evt,
|
|
479
319
|
data: data
|
|
480
320
|
});
|
|
@@ -491,7 +331,7 @@
|
|
|
491
331
|
if (this._isReadyState) return;
|
|
492
332
|
!this._hls && this._setup();
|
|
493
333
|
this._isReadyState = true;
|
|
494
|
-
this.trigger(
|
|
334
|
+
this.trigger(_clappr_core.Events.PLAYBACK_READY, this.name);
|
|
495
335
|
}
|
|
496
336
|
}, {
|
|
497
337
|
key: "_recover",
|
|
@@ -506,19 +346,16 @@
|
|
|
506
346
|
this._hls.recoverMediaError();
|
|
507
347
|
this.play();
|
|
508
348
|
} else {
|
|
509
|
-
|
|
349
|
+
_clappr_core.Log.error("hlsjs: failed to recover", {
|
|
510
350
|
evt: evt,
|
|
511
351
|
data: data
|
|
512
352
|
});
|
|
513
|
-
error.level =
|
|
353
|
+
error.level = _clappr_core.PlayerError.Levels.FATAL;
|
|
514
354
|
var formattedError = this.createError(error);
|
|
515
|
-
this.trigger(
|
|
355
|
+
this.trigger(_clappr_core.Events.PLAYBACK_ERROR, formattedError);
|
|
516
356
|
this.stop();
|
|
517
357
|
}
|
|
518
358
|
}
|
|
519
|
-
|
|
520
|
-
// override
|
|
521
|
-
// this playback manages the src on the video element itself
|
|
522
359
|
}, {
|
|
523
360
|
key: "_setupSrc",
|
|
524
361
|
value: function _setupSrc(srcUrl) {}
|
|
@@ -544,18 +381,11 @@
|
|
|
544
381
|
value: function getProgramDateTime() {
|
|
545
382
|
return this._programDateTime;
|
|
546
383
|
}
|
|
547
|
-
|
|
548
|
-
// the duration on the video element itself should not be used
|
|
549
|
-
// as this does not necesarily represent the duration of the stream
|
|
550
|
-
// https://github.com/clappr/clappr/issues/668#issuecomment-157036678
|
|
551
384
|
}, {
|
|
552
385
|
key: "getDuration",
|
|
553
386
|
value: function getDuration() {
|
|
554
387
|
return this._duration;
|
|
555
388
|
}
|
|
556
|
-
|
|
557
|
-
// the frame rate should be retrieved from the HLS.js level information
|
|
558
|
-
// as it is not necessarily exposed directly by the video element
|
|
559
389
|
}, {
|
|
560
390
|
key: "getFrameRate",
|
|
561
391
|
value: function getFrameRate() {
|
|
@@ -568,15 +398,8 @@
|
|
|
568
398
|
}, {
|
|
569
399
|
key: "getCurrentTime",
|
|
570
400
|
value: function getCurrentTime() {
|
|
571
|
-
// e.g. can be < 0 if user pauses near the start
|
|
572
|
-
// eventually they will then be kicked to the end by hlsjs if they run out of buffer
|
|
573
|
-
// before the official start time
|
|
574
401
|
return Math.max(0, this.el.currentTime - this._startTime);
|
|
575
402
|
}
|
|
576
|
-
|
|
577
|
-
// the time that "0" now represents relative to when playback started
|
|
578
|
-
// for a stream with a sliding window this will increase as content is
|
|
579
|
-
// removed from the beginning
|
|
580
403
|
}, {
|
|
581
404
|
key: "getStartTimeOffset",
|
|
582
405
|
value: function getStartTimeOffset() {
|
|
@@ -591,7 +414,7 @@
|
|
|
591
414
|
key: "seek",
|
|
592
415
|
value: function seek(time) {
|
|
593
416
|
if (time < 0) {
|
|
594
|
-
|
|
417
|
+
_clappr_core.Log.warn("Attempt to seek to a negative time. Resetting to live point. Use seekToLivePoint() to seek to the live point.");
|
|
595
418
|
time = this.getDuration();
|
|
596
419
|
}
|
|
597
420
|
time += this._startTime;
|
|
@@ -605,15 +428,9 @@
|
|
|
605
428
|
}, {
|
|
606
429
|
key: "_updateSettings",
|
|
607
430
|
value: function _updateSettings() {
|
|
608
|
-
if (this._playbackType ===
|
|
609
|
-
this.settings.left = ['playpause', 'position', 'duration'];
|
|
610
|
-
} else if (this.dvrEnabled) {
|
|
611
|
-
this.settings.left = ['playpause'];
|
|
612
|
-
} else {
|
|
613
|
-
this.settings.left = ['playstop'];
|
|
614
|
-
}
|
|
431
|
+
if (this._playbackType === _clappr_core.Playback.VOD) this.settings.left = ["playpause", "position", "duration"];else if (this.dvrEnabled) this.settings.left = ["playpause"];else this.settings.left = ["playstop"];
|
|
615
432
|
this.settings.seekEnabled = this.isSeekEnabled();
|
|
616
|
-
this.trigger(
|
|
433
|
+
this.trigger(_clappr_core.Events.PLAYBACK_SETTINGSUPDATE);
|
|
617
434
|
}
|
|
618
435
|
}, {
|
|
619
436
|
key: "_onHLSJSError",
|
|
@@ -625,93 +442,83 @@
|
|
|
625
442
|
};
|
|
626
443
|
var formattedError;
|
|
627
444
|
if (data.response) error.description += ", response: ".concat(JSON.stringify(data.response));
|
|
628
|
-
// only report/handle errors if they are fatal
|
|
629
|
-
// hlsjs should automatically handle non fatal errors
|
|
630
445
|
if (data.fatal) {
|
|
631
446
|
if (this._recoverAttemptsRemaining > 0) {
|
|
632
447
|
this._recoverAttemptsRemaining -= 1;
|
|
633
448
|
switch (data.type) {
|
|
634
|
-
case
|
|
449
|
+
case hls_js.default.ErrorTypes.NETWORK_ERROR:
|
|
635
450
|
switch (data.details) {
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
case
|
|
640
|
-
case
|
|
641
|
-
|
|
642
|
-
case HLSJS.ErrorDetails.LEVEL_LOAD_ERROR:
|
|
643
|
-
case HLSJS.ErrorDetails.LEVEL_LOAD_TIMEOUT:
|
|
644
|
-
core.Log.error('hlsjs: unrecoverable network fatal error.', {
|
|
451
|
+
case hls_js.default.ErrorDetails.MANIFEST_LOAD_ERROR:
|
|
452
|
+
case hls_js.default.ErrorDetails.MANIFEST_LOAD_TIMEOUT:
|
|
453
|
+
case hls_js.default.ErrorDetails.MANIFEST_PARSING_ERROR:
|
|
454
|
+
case hls_js.default.ErrorDetails.LEVEL_LOAD_ERROR:
|
|
455
|
+
case hls_js.default.ErrorDetails.LEVEL_LOAD_TIMEOUT:
|
|
456
|
+
_clappr_core.Log.error("hlsjs: unrecoverable network fatal error.", {
|
|
645
457
|
evt: evt,
|
|
646
458
|
data: data
|
|
647
459
|
});
|
|
648
460
|
formattedError = this.createError(error);
|
|
649
|
-
this.trigger(
|
|
461
|
+
this.trigger(_clappr_core.Events.PLAYBACK_ERROR, formattedError);
|
|
650
462
|
this.stop();
|
|
651
463
|
break;
|
|
652
464
|
default:
|
|
653
|
-
|
|
465
|
+
_clappr_core.Log.warn("hlsjs: trying to recover from network error.", {
|
|
654
466
|
evt: evt,
|
|
655
467
|
data: data
|
|
656
468
|
});
|
|
657
|
-
error.level =
|
|
469
|
+
error.level = _clappr_core.PlayerError.Levels.WARN;
|
|
658
470
|
this._hls.startLoad();
|
|
659
|
-
break;
|
|
660
471
|
}
|
|
661
472
|
break;
|
|
662
|
-
case
|
|
663
|
-
|
|
473
|
+
case hls_js.default.ErrorTypes.MEDIA_ERROR:
|
|
474
|
+
_clappr_core.Log.warn("hlsjs: trying to recover from media error.", {
|
|
664
475
|
evt: evt,
|
|
665
476
|
data: data
|
|
666
477
|
});
|
|
667
|
-
error.level =
|
|
478
|
+
error.level = _clappr_core.PlayerError.Levels.WARN;
|
|
668
479
|
this._recover(evt, data, error);
|
|
669
480
|
break;
|
|
670
481
|
default:
|
|
671
|
-
|
|
482
|
+
_clappr_core.Log.error("hlsjs: could not recover from error.", {
|
|
672
483
|
evt: evt,
|
|
673
484
|
data: data
|
|
674
485
|
});
|
|
675
486
|
formattedError = this.createError(error);
|
|
676
|
-
this.trigger(
|
|
487
|
+
this.trigger(_clappr_core.Events.PLAYBACK_ERROR, formattedError);
|
|
677
488
|
this.stop();
|
|
678
|
-
break;
|
|
679
489
|
}
|
|
680
490
|
} else {
|
|
681
|
-
|
|
491
|
+
_clappr_core.Log.error("hlsjs: could not recover from error after maximum number of attempts.", {
|
|
682
492
|
evt: evt,
|
|
683
493
|
data: data
|
|
684
494
|
});
|
|
685
495
|
formattedError = this.createError(error);
|
|
686
|
-
this.trigger(
|
|
496
|
+
this.trigger(_clappr_core.Events.PLAYBACK_ERROR, formattedError);
|
|
687
497
|
this.stop();
|
|
688
498
|
}
|
|
689
499
|
} else {
|
|
690
|
-
// Transforms HLSJS.ErrorDetails.KEY_LOAD_ERROR non-fatal error to
|
|
691
|
-
// playback fatal error if triggerFatalErrorOnResourceDenied playback
|
|
692
|
-
// option is set. HLSJS.ErrorTypes.KEY_SYSTEM_ERROR are fatal errors
|
|
693
|
-
// and therefore already handled.
|
|
694
500
|
if (this.options.playback.triggerFatalErrorOnResourceDenied && this._keyIsDenied(data)) {
|
|
695
|
-
|
|
501
|
+
_clappr_core.Log.error("hlsjs: could not load decrypt key.", {
|
|
696
502
|
evt: evt,
|
|
697
503
|
data: data
|
|
698
504
|
});
|
|
699
505
|
formattedError = this.createError(error);
|
|
700
|
-
this.trigger(
|
|
506
|
+
this.trigger(_clappr_core.Events.PLAYBACK_ERROR, formattedError);
|
|
701
507
|
this.stop();
|
|
702
508
|
return;
|
|
703
509
|
}
|
|
704
|
-
error.level =
|
|
705
|
-
|
|
510
|
+
error.level = _clappr_core.PlayerError.Levels.WARN;
|
|
511
|
+
_clappr_core.Log.warn("hlsjs: non-fatal error occurred", {
|
|
706
512
|
evt: evt,
|
|
707
513
|
data: data
|
|
708
514
|
});
|
|
515
|
+
this.trigger(_clappr_core.Events.PLAYBACK_WARNING, error, this.name);
|
|
709
516
|
}
|
|
710
517
|
}
|
|
711
518
|
}, {
|
|
712
519
|
key: "_keyIsDenied",
|
|
713
520
|
value: function _keyIsDenied(data) {
|
|
714
|
-
return data.type ===
|
|
521
|
+
return data.type === hls_js.default.ErrorTypes.NETWORK_ERROR && data.details === hls_js.default.ErrorDetails.KEY_LOAD_ERROR && data.response && data.response.code >= 400;
|
|
715
522
|
}
|
|
716
523
|
}, {
|
|
717
524
|
key: "_onTimeUpdate",
|
|
@@ -721,11 +528,10 @@
|
|
|
721
528
|
total: this.getDuration(),
|
|
722
529
|
firstFragDateTime: this.getProgramDateTime()
|
|
723
530
|
};
|
|
724
|
-
|
|
725
|
-
if (shouldThrottle) return;
|
|
531
|
+
if (this._shouldThrottleTimeUpdate(update)) return;
|
|
726
532
|
this._lastTimeUpdate = update;
|
|
727
533
|
this._lastTimeUpdateFiredTime = this._now;
|
|
728
|
-
this.trigger(
|
|
534
|
+
this.trigger(_clappr_core.Events.PLAYBACK_TIMEUPDATE, update, this.name);
|
|
729
535
|
}
|
|
730
536
|
}, {
|
|
731
537
|
key: "_shouldThrottleTimeUpdate",
|
|
@@ -741,8 +547,7 @@
|
|
|
741
547
|
key: "_onDurationChange",
|
|
742
548
|
value: function _onDurationChange() {
|
|
743
549
|
var duration = this.getDuration();
|
|
744
|
-
|
|
745
|
-
if (isSameDuration) return;
|
|
550
|
+
if (Math.abs(this._lastDuration - duration) < this._durationChangeMinOffset) return;
|
|
746
551
|
this._lastDuration = duration;
|
|
747
552
|
_superPropGet(HlsjsPlayback, "_onDurationChange", this, 3)([]);
|
|
748
553
|
}
|
|
@@ -754,20 +559,17 @@
|
|
|
754
559
|
var bufferedPos = 0;
|
|
755
560
|
for (var i = 0; i < this.el.buffered.length; i++) {
|
|
756
561
|
buffered = [].concat(_toConsumableArray(buffered), [{
|
|
757
|
-
// for a stream with sliding window dvr something that is buffered my slide off the start of the timeline
|
|
758
562
|
start: Math.max(0, this.el.buffered.start(i) - this._playableRegionStartTime),
|
|
759
563
|
end: Math.max(0, this.el.buffered.end(i) - this._playableRegionStartTime)
|
|
760
564
|
}]);
|
|
761
|
-
if (this.el.currentTime >= buffered[i].start && this.el.currentTime <= buffered[i].end)
|
|
762
|
-
bufferedPos = i;
|
|
763
|
-
}
|
|
565
|
+
if (this.el.currentTime >= buffered[i].start && this.el.currentTime <= buffered[i].end) bufferedPos = i;
|
|
764
566
|
}
|
|
765
567
|
var progress = {
|
|
766
568
|
start: buffered[bufferedPos].start,
|
|
767
569
|
current: buffered[bufferedPos].end,
|
|
768
570
|
total: this.getDuration()
|
|
769
571
|
};
|
|
770
|
-
this.trigger(
|
|
572
|
+
this.trigger(_clappr_core.Events.PLAYBACK_PROGRESS, progress, buffered);
|
|
771
573
|
}
|
|
772
574
|
}, {
|
|
773
575
|
key: "load",
|
|
@@ -807,12 +609,9 @@
|
|
|
807
609
|
}, {
|
|
808
610
|
key: "_updatePlaybackType",
|
|
809
611
|
value: function _updatePlaybackType(evt, data) {
|
|
810
|
-
this._playbackType = data.details.live ?
|
|
612
|
+
this._playbackType = data.details.live ? _clappr_core.Playback.LIVE : _clappr_core.Playback.VOD;
|
|
811
613
|
this._onLevelUpdated(evt, data);
|
|
812
|
-
|
|
813
|
-
if (this._ccTracksUpdated && this._playbackType === core.Playback.LIVE && this.hasClosedCaptionsTracks) {
|
|
814
|
-
this._onSubtitleLoaded();
|
|
815
|
-
}
|
|
614
|
+
if (this._ccTracksUpdated && this._playbackType === _clappr_core.Playback.LIVE && this.hasClosedCaptionsTracks) this._onSubtitleLoaded();
|
|
816
615
|
}
|
|
817
616
|
}, {
|
|
818
617
|
key: "_fillLevels",
|
|
@@ -821,10 +620,10 @@
|
|
|
821
620
|
return {
|
|
822
621
|
id: index,
|
|
823
622
|
level: level,
|
|
824
|
-
label: "".concat(level.bitrate /
|
|
623
|
+
label: "".concat(level.bitrate / 1e3, "Kbps")
|
|
825
624
|
};
|
|
826
625
|
});
|
|
827
|
-
this.trigger(
|
|
626
|
+
this.trigger(_clappr_core.Events.PLAYBACK_LEVELS_AVAILABLE, this._levels);
|
|
828
627
|
}
|
|
829
628
|
}, {
|
|
830
629
|
key: "_onLevelUpdated",
|
|
@@ -837,111 +636,62 @@
|
|
|
837
636
|
var previousPlayableRegionStartTime = this._playableRegionStartTime;
|
|
838
637
|
var previousPlayableRegionDuration = this._playableRegionDuration;
|
|
839
638
|
if (fragments.length === 0) return;
|
|
840
|
-
|
|
841
|
-
if (fragments[0].rawProgramDateTime) {
|
|
842
|
-
this._programDateTime = fragments[0].rawProgramDateTime;
|
|
843
|
-
}
|
|
639
|
+
if (fragments[0].rawProgramDateTime) this._programDateTime = fragments[0].rawProgramDateTime;
|
|
844
640
|
if (this._playableRegionStartTime !== fragments[0].start) {
|
|
845
641
|
startTimeChanged = true;
|
|
846
642
|
this._playableRegionStartTime = fragments[0].start;
|
|
847
643
|
}
|
|
848
644
|
if (startTimeChanged) {
|
|
849
|
-
if (!this._localStartTimeCorrelation) {
|
|
850
|
-
|
|
851
|
-
this.
|
|
852
|
-
|
|
853
|
-
remote: (fragments[0].start + this._extrapolatedWindowDuration / 2) * 1000
|
|
854
|
-
};
|
|
855
|
-
} else {
|
|
856
|
-
// check if the correlation still works
|
|
645
|
+
if (!this._localStartTimeCorrelation) this._localStartTimeCorrelation = {
|
|
646
|
+
local: this._now,
|
|
647
|
+
remote: (fragments[0].start + this._extrapolatedWindowDuration / 2) * 1e3
|
|
648
|
+
};else {
|
|
857
649
|
var corr = this._localStartTimeCorrelation;
|
|
858
650
|
var timePassed = this._now - corr.local;
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
this.
|
|
866
|
-
|
|
867
|
-
remote: fragments[0].start * 1000
|
|
868
|
-
};
|
|
869
|
-
} else if (startTime > previousPlayableRegionStartTime + this._extrapolatedWindowDuration) {
|
|
870
|
-
// start time was past the end of the old extrapolation window (so would have been capped)
|
|
871
|
-
// see if now that time would be inside the window, and if it would be set the correlation
|
|
872
|
-
// so that it resumes from the time it was at at the end of the old window
|
|
873
|
-
// update the correlation so that the time starts counting again from the value it's on now
|
|
874
|
-
this._localStartTimeCorrelation = {
|
|
875
|
-
local: this._now,
|
|
876
|
-
remote: Math.max(fragments[0].start, previousPlayableRegionStartTime + this._extrapolatedWindowDuration) * 1000
|
|
877
|
-
};
|
|
878
|
-
}
|
|
651
|
+
var startTime = (corr.remote + timePassed) / 1e3;
|
|
652
|
+
if (startTime < fragments[0].start) this._localStartTimeCorrelation = {
|
|
653
|
+
local: this._now,
|
|
654
|
+
remote: fragments[0].start * 1e3
|
|
655
|
+
};else if (startTime > previousPlayableRegionStartTime + this._extrapolatedWindowDuration) this._localStartTimeCorrelation = {
|
|
656
|
+
local: this._now,
|
|
657
|
+
remote: Math.max(fragments[0].start, previousPlayableRegionStartTime + this._extrapolatedWindowDuration) * 1e3
|
|
658
|
+
};
|
|
879
659
|
}
|
|
880
660
|
}
|
|
881
661
|
var newDuration = data.details.totalduration;
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
// seeks to areas after this point sometimes have issues
|
|
885
|
-
if (this._playbackType === core.Playback.LIVE) {
|
|
886
|
-
var fragmentTargetDuration = data.details.targetduration;
|
|
887
|
-
var hlsjsConfig = this.options.playback.hlsjsConfig || {};
|
|
888
|
-
var liveSyncDurationCount = hlsjsConfig.liveSyncDurationCount || HLSJS.DefaultConfig.liveSyncDurationCount;
|
|
889
|
-
var hiddenAreaDuration = fragmentTargetDuration * liveSyncDurationCount;
|
|
662
|
+
if (this._playbackType === _clappr_core.Playback.LIVE) {
|
|
663
|
+
var hiddenAreaDuration = data.details.targetduration * ((this.options.playback.hlsjsConfig || {}).liveSyncDurationCount || hls_js.default.DefaultConfig.liveSyncDurationCount);
|
|
890
664
|
if (hiddenAreaDuration <= newDuration) {
|
|
891
665
|
newDuration -= hiddenAreaDuration;
|
|
892
666
|
this._durationExcludesAfterLiveSyncPoint = true;
|
|
893
|
-
} else
|
|
894
|
-
this._durationExcludesAfterLiveSyncPoint = false;
|
|
895
|
-
}
|
|
667
|
+
} else this._durationExcludesAfterLiveSyncPoint = false;
|
|
896
668
|
}
|
|
897
669
|
if (newDuration !== this._playableRegionDuration) {
|
|
898
670
|
durationChanged = true;
|
|
899
671
|
this._playableRegionDuration = newDuration;
|
|
900
672
|
}
|
|
901
|
-
// Note the end time is not the playableRegionDuration
|
|
902
|
-
// The end time will always increase even if content is removed from the beginning
|
|
903
673
|
var endTime = fragments[0].start + newDuration;
|
|
904
674
|
var previousEndTime = previousPlayableRegionStartTime + previousPlayableRegionDuration;
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
local: this._now,
|
|
911
|
-
remote: endTime * 1000
|
|
912
|
-
};
|
|
913
|
-
} else {
|
|
914
|
-
// check if the correlation still works
|
|
675
|
+
if (endTime !== previousEndTime) {
|
|
676
|
+
if (!this._localEndTimeCorrelation) this._localEndTimeCorrelation = {
|
|
677
|
+
local: this._now,
|
|
678
|
+
remote: endTime * 1e3
|
|
679
|
+
};else {
|
|
915
680
|
var _corr = this._localEndTimeCorrelation;
|
|
916
681
|
var _timePassed = this._now - _corr.local;
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
this._localEndTimeCorrelation = {
|
|
929
|
-
local: this._now,
|
|
930
|
-
remote: (endTime - this._extrapolatedWindowDuration) * 1000
|
|
931
|
-
};
|
|
932
|
-
} else if (extrapolatedEndTime > previousEndTime) {
|
|
933
|
-
// end time was past the old end time (so would have been capped)
|
|
934
|
-
// set the correlation so that it resumes from the time it was at at the end of the old window
|
|
935
|
-
this._localEndTimeCorrelation = {
|
|
936
|
-
local: this._now,
|
|
937
|
-
remote: previousEndTime * 1000
|
|
938
|
-
};
|
|
939
|
-
}
|
|
682
|
+
var extrapolatedEndTime = (_corr.remote + _timePassed) / 1e3;
|
|
683
|
+
if (extrapolatedEndTime > endTime) this._localEndTimeCorrelation = {
|
|
684
|
+
local: this._now,
|
|
685
|
+
remote: endTime * 1e3
|
|
686
|
+
};else if (extrapolatedEndTime < endTime - this._extrapolatedWindowDuration) this._localEndTimeCorrelation = {
|
|
687
|
+
local: this._now,
|
|
688
|
+
remote: (endTime - this._extrapolatedWindowDuration) * 1e3
|
|
689
|
+
};else if (extrapolatedEndTime > previousEndTime) this._localEndTimeCorrelation = {
|
|
690
|
+
local: this._now,
|
|
691
|
+
remote: previousEndTime * 1e3
|
|
692
|
+
};
|
|
940
693
|
}
|
|
941
694
|
}
|
|
942
|
-
|
|
943
|
-
// now that the values have been updated call any methods that use on them so they get the updated values
|
|
944
|
-
// immediately
|
|
945
695
|
durationChanged && this._onDurationChange();
|
|
946
696
|
startTimeChanged && this._onProgress();
|
|
947
697
|
}
|
|
@@ -949,26 +699,24 @@
|
|
|
949
699
|
key: "_onFragmentChanged",
|
|
950
700
|
value: function _onFragmentChanged(evt, data) {
|
|
951
701
|
this._currentFragment = data.frag;
|
|
952
|
-
this.trigger(
|
|
702
|
+
this.trigger(_clappr_core.Events.Custom.PLAYBACK_FRAGMENT_CHANGED, data);
|
|
953
703
|
}
|
|
954
704
|
}, {
|
|
955
705
|
key: "_onFragmentLoaded",
|
|
956
706
|
value: function _onFragmentLoaded(evt, data) {
|
|
957
|
-
this.trigger(
|
|
707
|
+
this.trigger(_clappr_core.Events.PLAYBACK_FRAGMENT_LOADED, data);
|
|
958
708
|
}
|
|
959
709
|
}, {
|
|
960
710
|
key: "_onFragmentBuffered",
|
|
961
711
|
value: function _onFragmentBuffered(evt, data) {
|
|
962
|
-
this.trigger(
|
|
712
|
+
this.trigger(_clappr_core.Events.PLAYBACK_FRAGMENT_BUFFERED, data);
|
|
963
713
|
}
|
|
964
714
|
}, {
|
|
965
715
|
key: "_onSubtitleLoaded",
|
|
966
716
|
value: function _onSubtitleLoaded() {
|
|
967
|
-
// This event may be triggered multiple times
|
|
968
|
-
// Setup CC only once (disable CC by default)
|
|
969
717
|
if (!this._ccIsSetup) {
|
|
970
|
-
this.trigger(
|
|
971
|
-
var trackId = this._playbackType ===
|
|
718
|
+
this.trigger(_clappr_core.Events.PLAYBACK_SUBTITLE_AVAILABLE);
|
|
719
|
+
var trackId = this._playbackType === _clappr_core.Playback.LIVE ? -1 : this.closedCaptionsTrackId;
|
|
972
720
|
this.closedCaptionsTrackId = trackId;
|
|
973
721
|
this._ccIsSetup = true;
|
|
974
722
|
}
|
|
@@ -977,14 +725,13 @@
|
|
|
977
725
|
key: "_onLevelSwitch",
|
|
978
726
|
value: function _onLevelSwitch(evt, data) {
|
|
979
727
|
if (!this.levels.length) this._fillLevels();
|
|
980
|
-
this.trigger(
|
|
981
|
-
this.trigger(
|
|
728
|
+
this.trigger(_clappr_core.Events.PLAYBACK_LEVEL_SWITCH_END);
|
|
729
|
+
this.trigger(_clappr_core.Events.PLAYBACK_LEVEL_SWITCH, data);
|
|
982
730
|
var currentLevel = this._hls.levels[data.level];
|
|
983
731
|
if (currentLevel) {
|
|
984
|
-
|
|
985
|
-
this.
|
|
986
|
-
this.trigger(
|
|
987
|
-
this.trigger(core.Events.PLAYBACK_BITRATE, {
|
|
732
|
+
this.highDefinition = currentLevel.height >= 720 || currentLevel.bitrate / 1e3 >= 2e3;
|
|
733
|
+
this.trigger(_clappr_core.Events.PLAYBACK_HIGHDEFINITIONUPDATE, this.highDefinition);
|
|
734
|
+
this.trigger(_clappr_core.Events.PLAYBACK_BITRATE, {
|
|
988
735
|
height: currentLevel.height,
|
|
989
736
|
width: currentLevel.width,
|
|
990
737
|
bandwidth: currentLevel.bitrate,
|
|
@@ -996,11 +743,7 @@
|
|
|
996
743
|
}, {
|
|
997
744
|
key: "dvrEnabled",
|
|
998
745
|
get: function get() {
|
|
999
|
-
|
|
1000
|
-
// - the duration does not include content after hlsjs's live sync point
|
|
1001
|
-
// - the playable region duration is longer than the configured duration to enable dvr after
|
|
1002
|
-
// - the playback type is LIVE.
|
|
1003
|
-
return this._durationExcludesAfterLiveSyncPoint && this._duration >= this._minDvrSize && this.getPlaybackType() === core.Playback.LIVE;
|
|
746
|
+
return this._durationExcludesAfterLiveSyncPoint && this._duration >= this._minDvrSize && this.getPlaybackType() === _clappr_core.Playback.LIVE;
|
|
1004
747
|
}
|
|
1005
748
|
}, {
|
|
1006
749
|
key: "getPlaybackType",
|
|
@@ -1010,22 +753,22 @@
|
|
|
1010
753
|
}, {
|
|
1011
754
|
key: "isSeekEnabled",
|
|
1012
755
|
value: function isSeekEnabled() {
|
|
1013
|
-
return this._playbackType ===
|
|
756
|
+
return this._playbackType === _clappr_core.Playback.VOD || this.dvrEnabled;
|
|
1014
757
|
}
|
|
1015
758
|
}], [{
|
|
1016
759
|
key: "HLSJS",
|
|
1017
760
|
get: function get() {
|
|
1018
|
-
return
|
|
761
|
+
return hls_js.default;
|
|
1019
762
|
}
|
|
1020
763
|
}]);
|
|
1021
|
-
}(
|
|
764
|
+
}(_clappr_core.HTML5Video);
|
|
1022
765
|
HlsjsPlayback.canPlay = function (resource, mimeType) {
|
|
1023
|
-
var resourceParts = resource.split(
|
|
1024
|
-
var isHls = resourceParts.length > 1 && resourceParts[1].toLowerCase() ===
|
|
1025
|
-
return !!(
|
|
766
|
+
var resourceParts = resource.split("?")[0].match(/.*\.(.*)$/) || [];
|
|
767
|
+
var isHls = resourceParts.length > 1 && resourceParts[1].toLowerCase() === "m3u8" || listContainsIgnoreCase(mimeType, ["application/vnd.apple.mpegurl", "application/x-mpegURL"]);
|
|
768
|
+
return !!(hls_js.default.isSupported() && isHls);
|
|
1026
769
|
};
|
|
1027
|
-
|
|
770
|
+
//#endregion
|
|
1028
771
|
return HlsjsPlayback;
|
|
772
|
+
});
|
|
1029
773
|
|
|
1030
|
-
|
|
1031
|
-
//# sourceMappingURL=hlsjs-playback.js.map
|
|
774
|
+
//# sourceMappingURL=hlsjs-playback.js.map
|