@clappr/hlsjs-playback 0.5.3 → 1.0.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 +49 -0
- package/dist/hlsjs-playback.esm.js +23608 -19209
- package/dist/hlsjs-playback.external.js +228 -268
- package/dist/hlsjs-playback.external.min.js +1 -1
- package/dist/hlsjs-playback.external.min.js.map +1 -1
- package/dist/hlsjs-playback.js +23610 -19211
- package/dist/hlsjs-playback.min.js +268 -72
- package/dist/hlsjs-playback.min.js.map +1 -1
- package/package.json +24 -24
- package/src/hls.js +34 -3
- package/src/hls.test.js +260 -65
|
@@ -1,34 +1,58 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
2
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@clappr/core'), require('hls.js')) :
|
|
3
3
|
typeof define === 'function' && define.amd ? define(['@clappr/core', 'hls.js'], factory) :
|
|
4
|
-
(global = global || self, global.HlsjsPlayback = factory(global.Clappr, global.Hls));
|
|
5
|
-
}(this, (function (core, HLSJS) { 'use strict';
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.HlsjsPlayback = factory(global.Clappr, global.Hls));
|
|
5
|
+
})(this, (function (core, HLSJS) { 'use strict';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
8
|
|
|
9
|
+
var HLSJS__default = /*#__PURE__*/_interopDefaultLegacy(HLSJS);
|
|
10
|
+
|
|
11
|
+
function ownKeys(object, enumerableOnly) {
|
|
12
|
+
var keys = Object.keys(object);
|
|
13
|
+
if (Object.getOwnPropertySymbols) {
|
|
14
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
15
|
+
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
16
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
17
|
+
})), keys.push.apply(keys, symbols);
|
|
18
|
+
}
|
|
19
|
+
return keys;
|
|
20
|
+
}
|
|
21
|
+
function _objectSpread2(target) {
|
|
22
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
23
|
+
var source = null != arguments[i] ? arguments[i] : {};
|
|
24
|
+
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
|
25
|
+
_defineProperty(target, key, source[key]);
|
|
26
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
|
27
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return target;
|
|
31
|
+
}
|
|
9
32
|
function _classCallCheck(instance, Constructor) {
|
|
10
33
|
if (!(instance instanceof Constructor)) {
|
|
11
34
|
throw new TypeError("Cannot call a class as a function");
|
|
12
35
|
}
|
|
13
36
|
}
|
|
14
|
-
|
|
15
37
|
function _defineProperties(target, props) {
|
|
16
38
|
for (var i = 0; i < props.length; i++) {
|
|
17
39
|
var descriptor = props[i];
|
|
18
40
|
descriptor.enumerable = descriptor.enumerable || false;
|
|
19
41
|
descriptor.configurable = true;
|
|
20
42
|
if ("value" in descriptor) descriptor.writable = true;
|
|
21
|
-
Object.defineProperty(target, descriptor.key, descriptor);
|
|
43
|
+
Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
|
|
22
44
|
}
|
|
23
45
|
}
|
|
24
|
-
|
|
25
46
|
function _createClass(Constructor, protoProps, staticProps) {
|
|
26
47
|
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
27
48
|
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
49
|
+
Object.defineProperty(Constructor, "prototype", {
|
|
50
|
+
writable: false
|
|
51
|
+
});
|
|
28
52
|
return Constructor;
|
|
29
53
|
}
|
|
30
|
-
|
|
31
54
|
function _defineProperty(obj, key, value) {
|
|
55
|
+
key = _toPropertyKey(key);
|
|
32
56
|
if (key in obj) {
|
|
33
57
|
Object.defineProperty(obj, key, {
|
|
34
58
|
value: value,
|
|
@@ -39,49 +63,12 @@
|
|
|
39
63
|
} else {
|
|
40
64
|
obj[key] = value;
|
|
41
65
|
}
|
|
42
|
-
|
|
43
66
|
return obj;
|
|
44
67
|
}
|
|
45
|
-
|
|
46
|
-
function ownKeys(object, enumerableOnly) {
|
|
47
|
-
var keys = Object.keys(object);
|
|
48
|
-
|
|
49
|
-
if (Object.getOwnPropertySymbols) {
|
|
50
|
-
var symbols = Object.getOwnPropertySymbols(object);
|
|
51
|
-
if (enumerableOnly) symbols = symbols.filter(function (sym) {
|
|
52
|
-
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
53
|
-
});
|
|
54
|
-
keys.push.apply(keys, symbols);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return keys;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function _objectSpread2(target) {
|
|
61
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
62
|
-
var source = arguments[i] != null ? arguments[i] : {};
|
|
63
|
-
|
|
64
|
-
if (i % 2) {
|
|
65
|
-
ownKeys(Object(source), true).forEach(function (key) {
|
|
66
|
-
_defineProperty(target, key, source[key]);
|
|
67
|
-
});
|
|
68
|
-
} else if (Object.getOwnPropertyDescriptors) {
|
|
69
|
-
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
70
|
-
} else {
|
|
71
|
-
ownKeys(Object(source)).forEach(function (key) {
|
|
72
|
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return target;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
68
|
function _inherits(subClass, superClass) {
|
|
81
69
|
if (typeof superClass !== "function" && superClass !== null) {
|
|
82
70
|
throw new TypeError("Super expression must either be null or a function");
|
|
83
71
|
}
|
|
84
|
-
|
|
85
72
|
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
|
86
73
|
constructor: {
|
|
87
74
|
value: subClass,
|
|
@@ -89,115 +76,95 @@
|
|
|
89
76
|
configurable: true
|
|
90
77
|
}
|
|
91
78
|
});
|
|
79
|
+
Object.defineProperty(subClass, "prototype", {
|
|
80
|
+
writable: false
|
|
81
|
+
});
|
|
92
82
|
if (superClass) _setPrototypeOf(subClass, superClass);
|
|
93
83
|
}
|
|
94
|
-
|
|
95
84
|
function _getPrototypeOf(o) {
|
|
96
|
-
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
|
|
85
|
+
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
|
|
97
86
|
return o.__proto__ || Object.getPrototypeOf(o);
|
|
98
87
|
};
|
|
99
88
|
return _getPrototypeOf(o);
|
|
100
89
|
}
|
|
101
|
-
|
|
102
90
|
function _setPrototypeOf(o, p) {
|
|
103
|
-
_setPrototypeOf = Object.setPrototypeOf
|
|
91
|
+
_setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
|
|
104
92
|
o.__proto__ = p;
|
|
105
93
|
return o;
|
|
106
94
|
};
|
|
107
|
-
|
|
108
95
|
return _setPrototypeOf(o, p);
|
|
109
96
|
}
|
|
110
|
-
|
|
111
97
|
function _isNativeReflectConstruct() {
|
|
112
98
|
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
|
|
113
99
|
if (Reflect.construct.sham) return false;
|
|
114
100
|
if (typeof Proxy === "function") return true;
|
|
115
|
-
|
|
116
101
|
try {
|
|
117
|
-
|
|
102
|
+
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
|
|
118
103
|
return true;
|
|
119
104
|
} catch (e) {
|
|
120
105
|
return false;
|
|
121
106
|
}
|
|
122
107
|
}
|
|
123
|
-
|
|
124
108
|
function _assertThisInitialized(self) {
|
|
125
109
|
if (self === void 0) {
|
|
126
110
|
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
127
111
|
}
|
|
128
|
-
|
|
129
112
|
return self;
|
|
130
113
|
}
|
|
131
|
-
|
|
132
114
|
function _possibleConstructorReturn(self, call) {
|
|
133
115
|
if (call && (typeof call === "object" || typeof call === "function")) {
|
|
134
116
|
return call;
|
|
117
|
+
} else if (call !== void 0) {
|
|
118
|
+
throw new TypeError("Derived constructors may only return object or undefined");
|
|
135
119
|
}
|
|
136
|
-
|
|
137
120
|
return _assertThisInitialized(self);
|
|
138
121
|
}
|
|
139
|
-
|
|
140
122
|
function _createSuper(Derived) {
|
|
141
123
|
var hasNativeReflectConstruct = _isNativeReflectConstruct();
|
|
142
|
-
|
|
143
124
|
return function _createSuperInternal() {
|
|
144
125
|
var Super = _getPrototypeOf(Derived),
|
|
145
|
-
|
|
146
|
-
|
|
126
|
+
result;
|
|
147
127
|
if (hasNativeReflectConstruct) {
|
|
148
128
|
var NewTarget = _getPrototypeOf(this).constructor;
|
|
149
|
-
|
|
150
129
|
result = Reflect.construct(Super, arguments, NewTarget);
|
|
151
130
|
} else {
|
|
152
131
|
result = Super.apply(this, arguments);
|
|
153
132
|
}
|
|
154
|
-
|
|
155
133
|
return _possibleConstructorReturn(this, result);
|
|
156
134
|
};
|
|
157
135
|
}
|
|
158
|
-
|
|
159
136
|
function _superPropBase(object, property) {
|
|
160
137
|
while (!Object.prototype.hasOwnProperty.call(object, property)) {
|
|
161
138
|
object = _getPrototypeOf(object);
|
|
162
139
|
if (object === null) break;
|
|
163
140
|
}
|
|
164
|
-
|
|
165
141
|
return object;
|
|
166
142
|
}
|
|
167
|
-
|
|
168
|
-
function _get(target, property, receiver) {
|
|
143
|
+
function _get() {
|
|
169
144
|
if (typeof Reflect !== "undefined" && Reflect.get) {
|
|
170
|
-
_get = Reflect.get;
|
|
145
|
+
_get = Reflect.get.bind();
|
|
171
146
|
} else {
|
|
172
147
|
_get = function _get(target, property, receiver) {
|
|
173
148
|
var base = _superPropBase(target, property);
|
|
174
|
-
|
|
175
149
|
if (!base) return;
|
|
176
150
|
var desc = Object.getOwnPropertyDescriptor(base, property);
|
|
177
|
-
|
|
178
151
|
if (desc.get) {
|
|
179
|
-
return desc.get.call(receiver);
|
|
152
|
+
return desc.get.call(arguments.length < 3 ? target : receiver);
|
|
180
153
|
}
|
|
181
|
-
|
|
182
154
|
return desc.value;
|
|
183
155
|
};
|
|
184
156
|
}
|
|
185
|
-
|
|
186
|
-
return _get(target, property, receiver || target);
|
|
157
|
+
return _get.apply(this, arguments);
|
|
187
158
|
}
|
|
188
|
-
|
|
189
159
|
function _toConsumableArray(arr) {
|
|
190
160
|
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
|
|
191
161
|
}
|
|
192
|
-
|
|
193
162
|
function _arrayWithoutHoles(arr) {
|
|
194
163
|
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
|
|
195
164
|
}
|
|
196
|
-
|
|
197
165
|
function _iterableToArray(iter) {
|
|
198
|
-
if (typeof Symbol !== "undefined" && Symbol.iterator
|
|
166
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
199
167
|
}
|
|
200
|
-
|
|
201
168
|
function _unsupportedIterableToArray(o, minLen) {
|
|
202
169
|
if (!o) return;
|
|
203
170
|
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
@@ -206,31 +173,90 @@
|
|
|
206
173
|
if (n === "Map" || n === "Set") return Array.from(o);
|
|
207
174
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
208
175
|
}
|
|
209
|
-
|
|
210
176
|
function _arrayLikeToArray(arr, len) {
|
|
211
177
|
if (len == null || len > arr.length) len = arr.length;
|
|
212
|
-
|
|
213
178
|
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
|
|
214
|
-
|
|
215
179
|
return arr2;
|
|
216
180
|
}
|
|
217
|
-
|
|
218
181
|
function _nonIterableSpread() {
|
|
219
182
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
220
183
|
}
|
|
184
|
+
function _toPrimitive(input, hint) {
|
|
185
|
+
if (typeof input !== "object" || input === null) return input;
|
|
186
|
+
var prim = input[Symbol.toPrimitive];
|
|
187
|
+
if (prim !== undefined) {
|
|
188
|
+
var res = prim.call(input, hint || "default");
|
|
189
|
+
if (typeof res !== "object") return res;
|
|
190
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
191
|
+
}
|
|
192
|
+
return (hint === "string" ? String : Number)(input);
|
|
193
|
+
}
|
|
194
|
+
function _toPropertyKey(arg) {
|
|
195
|
+
var key = _toPrimitive(arg, "string");
|
|
196
|
+
return typeof key === "symbol" ? key : String(key);
|
|
197
|
+
}
|
|
221
198
|
|
|
222
199
|
var now = core.Utils.now,
|
|
223
|
-
|
|
224
|
-
|
|
200
|
+
assign = core.Utils.assign,
|
|
201
|
+
listContainsIgnoreCase = core.Utils.listContainsIgnoreCase;
|
|
225
202
|
var AUTO = -1;
|
|
226
203
|
core.Events.register('PLAYBACK_FRAGMENT_CHANGED');
|
|
227
204
|
core.Events.register('PLAYBACK_FRAGMENT_PARSING_METADATA');
|
|
228
|
-
|
|
229
205
|
var HlsjsPlayback = /*#__PURE__*/function (_HTML5Video) {
|
|
230
206
|
_inherits(HlsjsPlayback, _HTML5Video);
|
|
231
|
-
|
|
232
207
|
var _super = _createSuper(HlsjsPlayback);
|
|
233
|
-
|
|
208
|
+
function HlsjsPlayback() {
|
|
209
|
+
var _this;
|
|
210
|
+
_classCallCheck(this, HlsjsPlayback);
|
|
211
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
212
|
+
args[_key] = arguments[_key];
|
|
213
|
+
}
|
|
214
|
+
_this = _super.call.apply(_super, [this].concat(args));
|
|
215
|
+
// backwards compatibility (TODO: remove on 0.3.0)
|
|
216
|
+
_this.options.playback = _objectSpread2(_objectSpread2({}, _this.options), _this.options.playback);
|
|
217
|
+
_this.options.hlsPlayback = _objectSpread2(_objectSpread2({}, _this.defaultOptions), _this.options.hlsPlayback);
|
|
218
|
+
_this._minDvrSize = typeof _this.options.hlsMinimumDvrSize === 'undefined' ? 60 : _this.options.hlsMinimumDvrSize;
|
|
219
|
+
// The size of the start time extrapolation window measured as a multiple of segments.
|
|
220
|
+
// Should be 2 or higher, or 0 to disable. Should only need to be increased above 2 if more than one segment is
|
|
221
|
+
// removed from the start of the playlist at a time. E.g if the playlist is cached for 10 seconds and new chunks are
|
|
222
|
+
// added/removed every 5.
|
|
223
|
+
_this._extrapolatedWindowNumSegments = !_this.options.playback || typeof _this.options.playback.extrapolatedWindowNumSegments === 'undefined' ? 2 : _this.options.playback.extrapolatedWindowNumSegments;
|
|
224
|
+
_this._playbackType = core.Playback.VOD;
|
|
225
|
+
_this._lastTimeUpdate = {
|
|
226
|
+
current: 0,
|
|
227
|
+
total: 0
|
|
228
|
+
};
|
|
229
|
+
_this._lastDuration = null;
|
|
230
|
+
// for hls streams which have dvr with a sliding window,
|
|
231
|
+
// the content at the start of the playlist is removed as new
|
|
232
|
+
// content is appended at the end.
|
|
233
|
+
// this means the actual playable start time will increase as the
|
|
234
|
+
// start content is deleted
|
|
235
|
+
// For streams with dvr where the entire recording is kept from the
|
|
236
|
+
// beginning this should stay as 0
|
|
237
|
+
_this._playableRegionStartTime = 0;
|
|
238
|
+
// {local, remote} remote is the time in the video element that should represent 0
|
|
239
|
+
// local is the system time when the 'remote' measurment took place
|
|
240
|
+
_this._localStartTimeCorrelation = null;
|
|
241
|
+
// {local, remote} remote is the time in the video element that should represents the end
|
|
242
|
+
// local is the system time when the 'remote' measurment took place
|
|
243
|
+
_this._localEndTimeCorrelation = null;
|
|
244
|
+
// if content is removed from the beginning then this empty area should
|
|
245
|
+
// be ignored. "playableRegionDuration" excludes the empty area
|
|
246
|
+
_this._playableRegionDuration = 0;
|
|
247
|
+
// #EXT-X-PROGRAM-DATE-TIME
|
|
248
|
+
_this._programDateTime = 0;
|
|
249
|
+
// true when the actual duration is longer than hlsjs's live sync point
|
|
250
|
+
// when this is false playableRegionDuration will be the actual duration
|
|
251
|
+
// when this is true playableRegionDuration will exclude the time after the sync point
|
|
252
|
+
_this._durationExcludesAfterLiveSyncPoint = false;
|
|
253
|
+
// #EXT-X-TARGETDURATION
|
|
254
|
+
_this._segmentTargetDuration = null;
|
|
255
|
+
// #EXT-X-PLAYLIST-TYPE
|
|
256
|
+
_this._playlistType = null;
|
|
257
|
+
_this._recoverAttemptsRemaining = _this.options.hlsRecoverAttempts || 16;
|
|
258
|
+
return _this;
|
|
259
|
+
}
|
|
234
260
|
_createClass(HlsjsPlayback, [{
|
|
235
261
|
key: "name",
|
|
236
262
|
get: function get() {
|
|
@@ -240,7 +266,7 @@
|
|
|
240
266
|
key: "supportedVersion",
|
|
241
267
|
get: function get() {
|
|
242
268
|
return {
|
|
243
|
-
min: "0.4.
|
|
269
|
+
min: "0.4.27"
|
|
244
270
|
};
|
|
245
271
|
}
|
|
246
272
|
}, {
|
|
@@ -273,21 +299,23 @@
|
|
|
273
299
|
key: "_now",
|
|
274
300
|
get: function get() {
|
|
275
301
|
return now();
|
|
276
|
-
}
|
|
277
|
-
// extrapolated to increase in real time (instead of jumping as the early segments are removed)
|
|
302
|
+
}
|
|
278
303
|
|
|
304
|
+
// the time in the video element which should represent the start of the sliding window
|
|
305
|
+
// extrapolated to increase in real time (instead of jumping as the early segments are removed)
|
|
279
306
|
}, {
|
|
280
307
|
key: "_extrapolatedStartTime",
|
|
281
308
|
get: function get() {
|
|
282
309
|
if (!this._localStartTimeCorrelation) return this._playableRegionStartTime;
|
|
283
310
|
var corr = this._localStartTimeCorrelation;
|
|
284
311
|
var timePassed = this._now - corr.local;
|
|
285
|
-
var extrapolatedWindowStartTime = (corr.remote + timePassed) / 1000;
|
|
286
|
-
|
|
312
|
+
var extrapolatedWindowStartTime = (corr.remote + timePassed) / 1000;
|
|
313
|
+
// cap at the end of the extrapolated window duration
|
|
287
314
|
return Math.min(extrapolatedWindowStartTime, this._playableRegionStartTime + this._extrapolatedWindowDuration);
|
|
288
|
-
}
|
|
289
|
-
// extrapolated to increase in real time (instead of jumping as segments are added)
|
|
315
|
+
}
|
|
290
316
|
|
|
317
|
+
// the time in the video element which should represent the end of the content
|
|
318
|
+
// extrapolated to increase in real time (instead of jumping as segments are added)
|
|
291
319
|
}, {
|
|
292
320
|
key: "_extrapolatedEndTime",
|
|
293
321
|
get: function get() {
|
|
@@ -302,7 +330,9 @@
|
|
|
302
330
|
key: "_duration",
|
|
303
331
|
get: function get() {
|
|
304
332
|
return this._extrapolatedEndTime - this._startTime;
|
|
305
|
-
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Returns the duration (seconds) of the window that the extrapolated start time is allowed
|
|
306
336
|
// to move in before being capped.
|
|
307
337
|
// The extrapolated start time should never reach the cap at the end of the window as the
|
|
308
338
|
// window should slide as chunks are removed from the start.
|
|
@@ -319,7 +349,6 @@
|
|
|
319
349
|
// . . . --> |
|
|
320
350
|
// . . . .
|
|
321
351
|
// extrapolatedStartTime
|
|
322
|
-
|
|
323
352
|
}, {
|
|
324
353
|
key: "_extrapolatedWindowDuration",
|
|
325
354
|
get: function get() {
|
|
@@ -331,120 +360,82 @@
|
|
|
331
360
|
get: function get() {
|
|
332
361
|
return this._hls && this._hls.bandwidthEstimate;
|
|
333
362
|
}
|
|
334
|
-
}
|
|
335
|
-
key: "
|
|
363
|
+
}, {
|
|
364
|
+
key: "defaultOptions",
|
|
336
365
|
get: function get() {
|
|
337
|
-
return
|
|
366
|
+
return {
|
|
367
|
+
preload: true
|
|
368
|
+
};
|
|
338
369
|
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
_classCallCheck(this, HlsjsPlayback);
|
|
345
|
-
|
|
346
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
347
|
-
args[_key] = arguments[_key];
|
|
370
|
+
}, {
|
|
371
|
+
key: "customListeners",
|
|
372
|
+
get: function get() {
|
|
373
|
+
return this.options.hlsPlayback && this.options.hlsPlayback.customListeners || [];
|
|
348
374
|
}
|
|
349
|
-
|
|
350
|
-
_this = _super.call.apply(_super, [this].concat(args)); // backwards compatibility (TODO: remove on 0.3.0)
|
|
351
|
-
|
|
352
|
-
_this.options.playback = _objectSpread2(_objectSpread2({}, _this.options), _this.options.playback);
|
|
353
|
-
_this._minDvrSize = typeof _this.options.hlsMinimumDvrSize === 'undefined' ? 60 : _this.options.hlsMinimumDvrSize; // The size of the start time extrapolation window measured as a multiple of segments.
|
|
354
|
-
// Should be 2 or higher, or 0 to disable. Should only need to be increased above 2 if more than one segment is
|
|
355
|
-
// removed from the start of the playlist at a time. E.g if the playlist is cached for 10 seconds and new chunks are
|
|
356
|
-
// added/removed every 5.
|
|
357
|
-
|
|
358
|
-
_this._extrapolatedWindowNumSegments = !_this.options.playback || typeof _this.options.playback.extrapolatedWindowNumSegments === 'undefined' ? 2 : _this.options.playback.extrapolatedWindowNumSegments;
|
|
359
|
-
_this._playbackType = core.Playback.VOD;
|
|
360
|
-
_this._lastTimeUpdate = {
|
|
361
|
-
current: 0,
|
|
362
|
-
total: 0
|
|
363
|
-
};
|
|
364
|
-
_this._lastDuration = null; // for hls streams which have dvr with a sliding window,
|
|
365
|
-
// the content at the start of the playlist is removed as new
|
|
366
|
-
// content is appended at the end.
|
|
367
|
-
// this means the actual playable start time will increase as the
|
|
368
|
-
// start content is deleted
|
|
369
|
-
// For streams with dvr where the entire recording is kept from the
|
|
370
|
-
// beginning this should stay as 0
|
|
371
|
-
|
|
372
|
-
_this._playableRegionStartTime = 0; // {local, remote} remote is the time in the video element that should represent 0
|
|
373
|
-
// local is the system time when the 'remote' measurment took place
|
|
374
|
-
|
|
375
|
-
_this._localStartTimeCorrelation = null; // {local, remote} remote is the time in the video element that should represents the end
|
|
376
|
-
// local is the system time when the 'remote' measurment took place
|
|
377
|
-
|
|
378
|
-
_this._localEndTimeCorrelation = null; // if content is removed from the beginning then this empty area should
|
|
379
|
-
// be ignored. "playableRegionDuration" excludes the empty area
|
|
380
|
-
|
|
381
|
-
_this._playableRegionDuration = 0; // #EXT-X-PROGRAM-DATE-TIME
|
|
382
|
-
|
|
383
|
-
_this._programDateTime = 0; // true when the actual duration is longer than hlsjs's live sync point
|
|
384
|
-
// when this is false playableRegionDuration will be the actual duration
|
|
385
|
-
// when this is true playableRegionDuration will exclude the time after the sync point
|
|
386
|
-
|
|
387
|
-
_this._durationExcludesAfterLiveSyncPoint = false; // #EXT-X-TARGETDURATION
|
|
388
|
-
|
|
389
|
-
_this._segmentTargetDuration = null; // #EXT-X-PLAYLIST-TYPE
|
|
390
|
-
|
|
391
|
-
_this._playlistType = null;
|
|
392
|
-
_this._recoverAttemptsRemaining = _this.options.hlsRecoverAttempts || 16;
|
|
393
|
-
return _this;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
_createClass(HlsjsPlayback, [{
|
|
375
|
+
}, {
|
|
397
376
|
key: "_setup",
|
|
398
377
|
value: function _setup() {
|
|
399
378
|
var _this2 = this;
|
|
400
|
-
|
|
379
|
+
this._manifestParsed = false;
|
|
401
380
|
this._ccIsSetup = false;
|
|
402
381
|
this._ccTracksUpdated = false;
|
|
403
382
|
this._hls && this._hls.destroy();
|
|
404
|
-
this._hls = new
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
return _this2._hls.loadSource(_this2.options.src);
|
|
383
|
+
this._hls = new HLSJS__default["default"](assign({}, this.options.playback.hlsjsConfig));
|
|
384
|
+
this._hls.once(HLSJS__default["default"].Events.MEDIA_ATTACHED, function () {
|
|
385
|
+
_this2.options.hlsPlayback.preload && _this2._hls.loadSource(_this2.options.src);
|
|
408
386
|
});
|
|
409
|
-
|
|
410
|
-
|
|
387
|
+
this._hls.on(HLSJS__default["default"].Events.MANIFEST_PARSED, function () {
|
|
388
|
+
return _this2._manifestParsed = true;
|
|
389
|
+
});
|
|
390
|
+
this._hls.on(HLSJS__default["default"].Events.LEVEL_LOADED, function (evt, data) {
|
|
411
391
|
return _this2._updatePlaybackType(evt, data);
|
|
412
392
|
});
|
|
413
|
-
|
|
414
|
-
this._hls.on(HLSJS.Events.LEVEL_UPDATED, function (evt, data) {
|
|
393
|
+
this._hls.on(HLSJS__default["default"].Events.LEVEL_UPDATED, function (evt, data) {
|
|
415
394
|
return _this2._onLevelUpdated(evt, data);
|
|
416
395
|
});
|
|
417
|
-
|
|
418
|
-
this._hls.on(HLSJS.Events.LEVEL_SWITCHING, function (evt, data) {
|
|
396
|
+
this._hls.on(HLSJS__default["default"].Events.LEVEL_SWITCHING, function (evt, data) {
|
|
419
397
|
return _this2._onLevelSwitch(evt, data);
|
|
420
398
|
});
|
|
421
|
-
|
|
422
|
-
this._hls.on(HLSJS.Events.FRAG_CHANGED, function (evt, data) {
|
|
399
|
+
this._hls.on(HLSJS__default["default"].Events.FRAG_CHANGED, function (evt, data) {
|
|
423
400
|
return _this2._onFragmentChanged(evt, data);
|
|
424
401
|
});
|
|
425
|
-
|
|
426
|
-
this._hls.on(HLSJS.Events.FRAG_LOADED, function (evt, data) {
|
|
402
|
+
this._hls.on(HLSJS__default["default"].Events.FRAG_LOADED, function (evt, data) {
|
|
427
403
|
return _this2._onFragmentLoaded(evt, data);
|
|
428
404
|
});
|
|
429
|
-
|
|
430
|
-
this._hls.on(HLSJS.Events.FRAG_PARSING_METADATA, function (evt, data) {
|
|
405
|
+
this._hls.on(HLSJS__default["default"].Events.FRAG_PARSING_METADATA, function (evt, data) {
|
|
431
406
|
return _this2._onFragmentParsingMetadata(evt, data);
|
|
432
407
|
});
|
|
433
|
-
|
|
434
|
-
this._hls.on(HLSJS.Events.ERROR, function (evt, data) {
|
|
408
|
+
this._hls.on(HLSJS__default["default"].Events.ERROR, function (evt, data) {
|
|
435
409
|
return _this2._onHLSJSError(evt, data);
|
|
436
410
|
});
|
|
437
|
-
|
|
438
|
-
this._hls.on(HLSJS.Events.SUBTITLE_TRACK_LOADED, function (evt, data) {
|
|
411
|
+
this._hls.on(HLSJS__default["default"].Events.SUBTITLE_TRACK_LOADED, function (evt, data) {
|
|
439
412
|
return _this2._onSubtitleLoaded(evt, data);
|
|
440
413
|
});
|
|
441
|
-
|
|
442
|
-
this._hls.on(HLSJS.Events.SUBTITLE_TRACKS_UPDATED, function () {
|
|
414
|
+
this._hls.on(HLSJS__default["default"].Events.SUBTITLE_TRACKS_UPDATED, function () {
|
|
443
415
|
return _this2._ccTracksUpdated = true;
|
|
444
416
|
});
|
|
445
|
-
|
|
417
|
+
this.bindCustomListeners();
|
|
446
418
|
this._hls.attachMedia(this.el);
|
|
447
419
|
}
|
|
420
|
+
}, {
|
|
421
|
+
key: "bindCustomListeners",
|
|
422
|
+
value: function bindCustomListeners() {
|
|
423
|
+
var _this3 = this;
|
|
424
|
+
this.customListeners.forEach(function (item) {
|
|
425
|
+
var requestedEventName = item.eventName;
|
|
426
|
+
var typeOfListener = item.once ? 'once' : 'on';
|
|
427
|
+
requestedEventName && _this3._hls["".concat(typeOfListener)](requestedEventName, item.callback);
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
}, {
|
|
431
|
+
key: "unbindCustomListeners",
|
|
432
|
+
value: function unbindCustomListeners() {
|
|
433
|
+
var _this4 = this;
|
|
434
|
+
this.customListeners.forEach(function (item) {
|
|
435
|
+
var requestedEventName = item.eventName;
|
|
436
|
+
requestedEventName && _this4._hls.off(requestedEventName, item.callback);
|
|
437
|
+
});
|
|
438
|
+
}
|
|
448
439
|
}, {
|
|
449
440
|
key: "_onFragmentParsingMetadata",
|
|
450
441
|
value: function _onFragmentParsingMetadata(evt, data) {
|
|
@@ -457,12 +448,13 @@
|
|
|
457
448
|
key: "render",
|
|
458
449
|
value: function render() {
|
|
459
450
|
this._ready();
|
|
460
|
-
|
|
461
451
|
return _get(_getPrototypeOf(HlsjsPlayback.prototype), "render", this).call(this);
|
|
462
452
|
}
|
|
463
453
|
}, {
|
|
464
454
|
key: "_ready",
|
|
465
455
|
value: function _ready() {
|
|
456
|
+
if (this._isReadyState) return;
|
|
457
|
+
!this._hls && this._setup();
|
|
466
458
|
this._isReadyState = true;
|
|
467
459
|
this.trigger(core.Events.PLAYBACK_READY, this.name);
|
|
468
460
|
}
|
|
@@ -471,13 +463,10 @@
|
|
|
471
463
|
value: function _recover(evt, data, error) {
|
|
472
464
|
if (!this._recoveredDecodingError) {
|
|
473
465
|
this._recoveredDecodingError = true;
|
|
474
|
-
|
|
475
466
|
this._hls.recoverMediaError();
|
|
476
467
|
} else if (!this._recoveredAudioCodecError) {
|
|
477
468
|
this._recoveredAudioCodecError = true;
|
|
478
|
-
|
|
479
469
|
this._hls.swapAudioCodec();
|
|
480
|
-
|
|
481
470
|
this._hls.recoverMediaError();
|
|
482
471
|
} else {
|
|
483
472
|
core.Log.error('hlsjs: failed to recover', {
|
|
@@ -489,8 +478,9 @@
|
|
|
489
478
|
this.trigger(core.Events.PLAYBACK_ERROR, formattedError);
|
|
490
479
|
this.stop();
|
|
491
480
|
}
|
|
492
|
-
}
|
|
481
|
+
}
|
|
493
482
|
|
|
483
|
+
// override
|
|
494
484
|
}, {
|
|
495
485
|
key: "_setupSrc",
|
|
496
486
|
value: function _setupSrc(srcUrl) {// eslint-disable-line no-unused-vars
|
|
@@ -499,13 +489,11 @@
|
|
|
499
489
|
}, {
|
|
500
490
|
key: "_startTimeUpdateTimer",
|
|
501
491
|
value: function _startTimeUpdateTimer() {
|
|
502
|
-
var
|
|
503
|
-
|
|
492
|
+
var _this5 = this;
|
|
504
493
|
if (this._timeUpdateTimer) return;
|
|
505
494
|
this._timeUpdateTimer = setInterval(function () {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
_this3._onTimeUpdate();
|
|
495
|
+
_this5._onDurationChange();
|
|
496
|
+
_this5._onTimeUpdate();
|
|
509
497
|
}, 100);
|
|
510
498
|
}
|
|
511
499
|
}, {
|
|
@@ -519,10 +507,10 @@
|
|
|
519
507
|
key: "getProgramDateTime",
|
|
520
508
|
value: function getProgramDateTime() {
|
|
521
509
|
return this._programDateTime;
|
|
522
|
-
}
|
|
510
|
+
}
|
|
511
|
+
// the duration on the video element itself should not be used
|
|
523
512
|
// as this does not necesarily represent the duration of the stream
|
|
524
513
|
// https://github.com/clappr/clappr/issues/668#issuecomment-157036678
|
|
525
|
-
|
|
526
514
|
}, {
|
|
527
515
|
key: "getDuration",
|
|
528
516
|
value: function getDuration() {
|
|
@@ -535,10 +523,11 @@
|
|
|
535
523
|
// eventually they will then be kicked to the end by hlsjs if they run out of buffer
|
|
536
524
|
// before the official start time
|
|
537
525
|
return Math.max(0, this.el.currentTime - this._startTime);
|
|
538
|
-
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// the time that "0" now represents relative to when playback started
|
|
539
529
|
// for a stream with a sliding window this will increase as content is
|
|
540
530
|
// removed from the beginning
|
|
541
|
-
|
|
542
531
|
}, {
|
|
543
532
|
key: "getStartTimeOffset",
|
|
544
533
|
value: function getStartTimeOffset() {
|
|
@@ -557,9 +546,8 @@
|
|
|
557
546
|
if (time < 0) {
|
|
558
547
|
core.Log.warn('Attempt to seek to a negative time. Resetting to live point. Use seekToLivePoint() to seek to the live point.');
|
|
559
548
|
time = this.getDuration();
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
|
|
549
|
+
}
|
|
550
|
+
// assume live if time within 3 seconds of end of stream
|
|
563
551
|
this.dvrEnabled && this._updateDvr(time < this.getDuration() - 3);
|
|
564
552
|
time += this._startTime;
|
|
565
553
|
this.el.currentTime = time;
|
|
@@ -593,24 +581,23 @@
|
|
|
593
581
|
raw: data
|
|
594
582
|
};
|
|
595
583
|
var formattedError;
|
|
596
|
-
if (data.response) error.description += ", response: ".concat(JSON.stringify(data.response));
|
|
584
|
+
if (data.response) error.description += ", response: ".concat(JSON.stringify(data.response));
|
|
585
|
+
// only report/handle errors if they are fatal
|
|
597
586
|
// hlsjs should automatically handle non fatal errors
|
|
598
|
-
|
|
599
587
|
if (data.fatal) {
|
|
600
588
|
if (this._recoverAttemptsRemaining > 0) {
|
|
601
589
|
this._recoverAttemptsRemaining -= 1;
|
|
602
|
-
|
|
603
590
|
switch (data.type) {
|
|
604
|
-
case
|
|
591
|
+
case HLSJS__default["default"].ErrorTypes.NETWORK_ERROR:
|
|
605
592
|
switch (data.details) {
|
|
606
593
|
// The following network errors cannot be recovered with HLS.startLoad()
|
|
607
594
|
// For more details, see https://github.com/video-dev/hls.js/blob/master/doc/design.md#error-detection-and-handling
|
|
608
595
|
// For "level load" fatal errors, see https://github.com/video-dev/hls.js/issues/1138
|
|
609
|
-
case
|
|
610
|
-
case
|
|
611
|
-
case
|
|
612
|
-
case
|
|
613
|
-
case
|
|
596
|
+
case HLSJS__default["default"].ErrorDetails.MANIFEST_LOAD_ERROR:
|
|
597
|
+
case HLSJS__default["default"].ErrorDetails.MANIFEST_LOAD_TIMEOUT:
|
|
598
|
+
case HLSJS__default["default"].ErrorDetails.MANIFEST_PARSING_ERROR:
|
|
599
|
+
case HLSJS__default["default"].ErrorDetails.LEVEL_LOAD_ERROR:
|
|
600
|
+
case HLSJS__default["default"].ErrorDetails.LEVEL_LOAD_TIMEOUT:
|
|
614
601
|
core.Log.error('hlsjs: unrecoverable network fatal error.', {
|
|
615
602
|
evt: evt,
|
|
616
603
|
data: data
|
|
@@ -619,32 +606,24 @@
|
|
|
619
606
|
this.trigger(core.Events.PLAYBACK_ERROR, formattedError);
|
|
620
607
|
this.stop();
|
|
621
608
|
break;
|
|
622
|
-
|
|
623
609
|
default:
|
|
624
610
|
core.Log.warn('hlsjs: trying to recover from network error.', {
|
|
625
611
|
evt: evt,
|
|
626
612
|
data: data
|
|
627
613
|
});
|
|
628
614
|
error.level = core.PlayerError.Levels.WARN;
|
|
629
|
-
|
|
630
615
|
this._hls.startLoad();
|
|
631
|
-
|
|
632
616
|
break;
|
|
633
617
|
}
|
|
634
|
-
|
|
635
618
|
break;
|
|
636
|
-
|
|
637
|
-
case HLSJS.ErrorTypes.MEDIA_ERROR:
|
|
619
|
+
case HLSJS__default["default"].ErrorTypes.MEDIA_ERROR:
|
|
638
620
|
core.Log.warn('hlsjs: trying to recover from media error.', {
|
|
639
621
|
evt: evt,
|
|
640
622
|
data: data
|
|
641
623
|
});
|
|
642
624
|
error.level = core.PlayerError.Levels.WARN;
|
|
643
|
-
|
|
644
625
|
this._recover(evt, data, error);
|
|
645
|
-
|
|
646
626
|
break;
|
|
647
|
-
|
|
648
627
|
default:
|
|
649
628
|
core.Log.error('hlsjs: could not recover from error.', {
|
|
650
629
|
evt: evt,
|
|
@@ -679,7 +658,6 @@
|
|
|
679
658
|
this.stop();
|
|
680
659
|
return;
|
|
681
660
|
}
|
|
682
|
-
|
|
683
661
|
error.level = core.PlayerError.Levels.WARN;
|
|
684
662
|
core.Log.warn('hlsjs: non-fatal error occurred', {
|
|
685
663
|
evt: evt,
|
|
@@ -690,7 +668,7 @@
|
|
|
690
668
|
}, {
|
|
691
669
|
key: "_keyIsDenied",
|
|
692
670
|
value: function _keyIsDenied(data) {
|
|
693
|
-
return data.type ===
|
|
671
|
+
return data.type === HLSJS__default["default"].ErrorTypes.NETWORK_ERROR && data.details === HLSJS__default["default"].ErrorDetails.KEY_LOAD_ERROR && data.response && data.response.code >= 400;
|
|
694
672
|
}
|
|
695
673
|
}, {
|
|
696
674
|
key: "_onTimeUpdate",
|
|
@@ -711,7 +689,6 @@
|
|
|
711
689
|
var duration = this.getDuration();
|
|
712
690
|
if (this._lastDuration === duration) return;
|
|
713
691
|
this._lastDuration = duration;
|
|
714
|
-
|
|
715
692
|
_get(_getPrototypeOf(HlsjsPlayback.prototype), "_onDurationChange", this).call(this);
|
|
716
693
|
}
|
|
717
694
|
}, {
|
|
@@ -720,7 +697,6 @@
|
|
|
720
697
|
if (!this.el.buffered.length) return;
|
|
721
698
|
var buffered = [];
|
|
722
699
|
var bufferedPos = 0;
|
|
723
|
-
|
|
724
700
|
for (var i = 0; i < this.el.buffered.length; i++) {
|
|
725
701
|
buffered = [].concat(_toConsumableArray(buffered), [{
|
|
726
702
|
// for a stream with sliding window dvr something that is buffered my slide off the start of the timeline
|
|
@@ -729,7 +705,6 @@
|
|
|
729
705
|
}]);
|
|
730
706
|
if (this.el.currentTime >= buffered[i].start && this.el.currentTime <= buffered[i].end) bufferedPos = i;
|
|
731
707
|
}
|
|
732
|
-
|
|
733
708
|
var progress = {
|
|
734
709
|
start: buffered[bufferedPos].start,
|
|
735
710
|
current: buffered[bufferedPos].end,
|
|
@@ -740,10 +715,9 @@
|
|
|
740
715
|
}, {
|
|
741
716
|
key: "play",
|
|
742
717
|
value: function play() {
|
|
743
|
-
|
|
744
|
-
|
|
718
|
+
!this._hls && this._setup();
|
|
719
|
+
!this._manifestParsed && !this.options.hlsPlayback.preload && this._hls.loadSource(this.options.src);
|
|
745
720
|
_get(_getPrototypeOf(HlsjsPlayback.prototype), "play", this).call(this);
|
|
746
|
-
|
|
747
721
|
this._startTimeUpdateTimer();
|
|
748
722
|
}
|
|
749
723
|
}, {
|
|
@@ -757,12 +731,9 @@
|
|
|
757
731
|
key: "stop",
|
|
758
732
|
value: function stop() {
|
|
759
733
|
this._stopTimeUpdateTimer();
|
|
760
|
-
|
|
761
734
|
if (this._hls) {
|
|
762
735
|
_get(_getPrototypeOf(HlsjsPlayback.prototype), "stop", this).call(this);
|
|
763
|
-
|
|
764
736
|
this._hls.destroy();
|
|
765
|
-
|
|
766
737
|
delete this._hls;
|
|
767
738
|
}
|
|
768
739
|
}
|
|
@@ -770,23 +741,19 @@
|
|
|
770
741
|
key: "destroy",
|
|
771
742
|
value: function destroy() {
|
|
772
743
|
this._stopTimeUpdateTimer();
|
|
773
|
-
|
|
774
744
|
if (this._hls) {
|
|
775
745
|
this._hls.destroy();
|
|
776
|
-
|
|
777
746
|
delete this._hls;
|
|
778
747
|
}
|
|
779
|
-
|
|
780
748
|
_get(_getPrototypeOf(HlsjsPlayback.prototype), "destroy", this).call(this);
|
|
781
749
|
}
|
|
782
750
|
}, {
|
|
783
751
|
key: "_updatePlaybackType",
|
|
784
752
|
value: function _updatePlaybackType(evt, data) {
|
|
785
753
|
this._playbackType = data.details.live ? core.Playback.LIVE : core.Playback.VOD;
|
|
754
|
+
this._onLevelUpdated(evt, data);
|
|
786
755
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
756
|
+
// Live stream subtitle tracks detection hack (may not immediately available)
|
|
790
757
|
if (this._ccTracksUpdated && this._playbackType === core.Playback.LIVE && this.hasClosedCaptionsTracks) this._onSubtitleLoaded();
|
|
791
758
|
}
|
|
792
759
|
}, {
|
|
@@ -811,15 +778,14 @@
|
|
|
811
778
|
var fragments = data.details.fragments;
|
|
812
779
|
var previousPlayableRegionStartTime = this._playableRegionStartTime;
|
|
813
780
|
var previousPlayableRegionDuration = this._playableRegionDuration;
|
|
814
|
-
if (fragments.length === 0) return;
|
|
781
|
+
if (fragments.length === 0) return;
|
|
815
782
|
|
|
783
|
+
// #EXT-X-PROGRAM-DATE-TIME
|
|
816
784
|
if (fragments[0].rawProgramDateTime) this._programDateTime = fragments[0].rawProgramDateTime;
|
|
817
|
-
|
|
818
785
|
if (this._playableRegionStartTime !== fragments[0].start) {
|
|
819
786
|
startTimeChanged = true;
|
|
820
787
|
this._playableRegionStartTime = fragments[0].start;
|
|
821
788
|
}
|
|
822
|
-
|
|
823
789
|
if (startTimeChanged) {
|
|
824
790
|
if (!this._localStartTimeCorrelation) {
|
|
825
791
|
// set the correlation to map to middle of the extrapolation window
|
|
@@ -830,10 +796,9 @@
|
|
|
830
796
|
} else {
|
|
831
797
|
// check if the correlation still works
|
|
832
798
|
var corr = this._localStartTimeCorrelation;
|
|
833
|
-
var timePassed = this._now - corr.local;
|
|
834
|
-
|
|
799
|
+
var timePassed = this._now - corr.local;
|
|
800
|
+
// this should point to a time within the extrapolation window
|
|
835
801
|
var startTime = (corr.remote + timePassed) / 1000;
|
|
836
|
-
|
|
837
802
|
if (startTime < fragments[0].start) {
|
|
838
803
|
// our start time is now earlier than the first chunk
|
|
839
804
|
// (maybe the chunk was removed early)
|
|
@@ -854,17 +819,15 @@
|
|
|
854
819
|
}
|
|
855
820
|
}
|
|
856
821
|
}
|
|
857
|
-
|
|
858
|
-
|
|
822
|
+
var newDuration = data.details.totalduration;
|
|
823
|
+
// if it's a live stream then shorten the duration to remove access
|
|
859
824
|
// to the area after hlsjs's live sync point
|
|
860
825
|
// seeks to areas after this point sometimes have issues
|
|
861
|
-
|
|
862
826
|
if (this._playbackType === core.Playback.LIVE) {
|
|
863
827
|
var fragmentTargetDuration = data.details.targetduration;
|
|
864
828
|
var hlsjsConfig = this.options.playback.hlsjsConfig || {};
|
|
865
|
-
var liveSyncDurationCount = hlsjsConfig.liveSyncDurationCount ||
|
|
829
|
+
var liveSyncDurationCount = hlsjsConfig.liveSyncDurationCount || HLSJS__default["default"].DefaultConfig.liveSyncDurationCount;
|
|
866
830
|
var hiddenAreaDuration = fragmentTargetDuration * liveSyncDurationCount;
|
|
867
|
-
|
|
868
831
|
if (hiddenAreaDuration <= newDuration) {
|
|
869
832
|
newDuration -= hiddenAreaDuration;
|
|
870
833
|
this._durationExcludesAfterLiveSyncPoint = true;
|
|
@@ -872,18 +835,16 @@
|
|
|
872
835
|
this._durationExcludesAfterLiveSyncPoint = false;
|
|
873
836
|
}
|
|
874
837
|
}
|
|
875
|
-
|
|
876
838
|
if (newDuration !== this._playableRegionDuration) {
|
|
877
839
|
durationChanged = true;
|
|
878
840
|
this._playableRegionDuration = newDuration;
|
|
879
|
-
}
|
|
880
|
-
// The end time will always increase even if content is removed from the beginning
|
|
881
|
-
|
|
841
|
+
}
|
|
882
842
|
|
|
843
|
+
// Note the end time is not the playableRegionDuration
|
|
844
|
+
// The end time will always increase even if content is removed from the beginning
|
|
883
845
|
var endTime = fragments[0].start + newDuration;
|
|
884
846
|
var previousEndTime = previousPlayableRegionStartTime + previousPlayableRegionDuration;
|
|
885
847
|
var endTimeChanged = endTime !== previousEndTime;
|
|
886
|
-
|
|
887
848
|
if (endTimeChanged) {
|
|
888
849
|
if (!this._localEndTimeCorrelation) {
|
|
889
850
|
// set the correlation to map to the end
|
|
@@ -894,12 +855,9 @@
|
|
|
894
855
|
} else {
|
|
895
856
|
// check if the correlation still works
|
|
896
857
|
var _corr = this._localEndTimeCorrelation;
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
858
|
+
var _timePassed = this._now - _corr.local;
|
|
859
|
+
// this should point to a time within the extrapolation window from the end
|
|
901
860
|
var extrapolatedEndTime = (_corr.remote + _timePassed) / 1000;
|
|
902
|
-
|
|
903
861
|
if (extrapolatedEndTime > endTime) {
|
|
904
862
|
this._localEndTimeCorrelation = {
|
|
905
863
|
local: this._now,
|
|
@@ -922,10 +880,10 @@
|
|
|
922
880
|
};
|
|
923
881
|
}
|
|
924
882
|
}
|
|
925
|
-
}
|
|
926
|
-
// immediately
|
|
927
|
-
|
|
883
|
+
}
|
|
928
884
|
|
|
885
|
+
// now that the values have been updated call any methods that use on them so they get the updated values
|
|
886
|
+
// immediately
|
|
929
887
|
durationChanged && this._onDurationChange();
|
|
930
888
|
startTimeChanged && this._onProgress();
|
|
931
889
|
}
|
|
@@ -958,7 +916,6 @@
|
|
|
958
916
|
this.trigger(core.Events.PLAYBACK_LEVEL_SWITCH_END);
|
|
959
917
|
this.trigger(core.Events.PLAYBACK_LEVEL_SWITCH, data);
|
|
960
918
|
var currentLevel = this._hls.levels[data.level];
|
|
961
|
-
|
|
962
919
|
if (currentLevel) {
|
|
963
920
|
// TODO should highDefinition be private and maybe have a read only accessor if it's used somewhere
|
|
964
921
|
this.highDefinition = currentLevel.height >= 720 || currentLevel.bitrate / 1000 >= 2000;
|
|
@@ -972,6 +929,15 @@
|
|
|
972
929
|
});
|
|
973
930
|
}
|
|
974
931
|
}
|
|
932
|
+
}, {
|
|
933
|
+
key: "dvrEnabled",
|
|
934
|
+
get: function get() {
|
|
935
|
+
// enabled when:
|
|
936
|
+
// - the duration does not include content after hlsjs's live sync point
|
|
937
|
+
// - the playable region duration is longer than the configured duration to enable dvr after
|
|
938
|
+
// - the playback type is LIVE.
|
|
939
|
+
return this._durationExcludesAfterLiveSyncPoint && this._duration >= this._minDvrSize && this.getPlaybackType() === core.Playback.LIVE;
|
|
940
|
+
}
|
|
975
941
|
}, {
|
|
976
942
|
key: "getPlaybackType",
|
|
977
943
|
value: function getPlaybackType() {
|
|
@@ -982,26 +948,20 @@
|
|
|
982
948
|
value: function isSeekEnabled() {
|
|
983
949
|
return this._playbackType === core.Playback.VOD || this.dvrEnabled;
|
|
984
950
|
}
|
|
985
|
-
}, {
|
|
986
|
-
key: "
|
|
951
|
+
}], [{
|
|
952
|
+
key: "HLSJS",
|
|
987
953
|
get: function get() {
|
|
988
|
-
|
|
989
|
-
// - the duration does not include content after hlsjs's live sync point
|
|
990
|
-
// - the playable region duration is longer than the configured duration to enable dvr after
|
|
991
|
-
// - the playback type is LIVE.
|
|
992
|
-
return this._durationExcludesAfterLiveSyncPoint && this._duration >= this._minDvrSize && this.getPlaybackType() === core.Playback.LIVE;
|
|
954
|
+
return HLSJS__default["default"];
|
|
993
955
|
}
|
|
994
956
|
}]);
|
|
995
|
-
|
|
996
957
|
return HlsjsPlayback;
|
|
997
958
|
}(core.HTML5Video);
|
|
998
|
-
|
|
999
959
|
HlsjsPlayback.canPlay = function (resource, mimeType) {
|
|
1000
960
|
var resourceParts = resource.split('?')[0].match(/.*\.(.*)$/) || [];
|
|
1001
961
|
var isHls = resourceParts.length > 1 && resourceParts[1].toLowerCase() === 'm3u8' || listContainsIgnoreCase(mimeType, ['application/vnd.apple.mpegurl', 'application/x-mpegURL']);
|
|
1002
|
-
return !!(
|
|
962
|
+
return !!(HLSJS__default["default"].isSupported() && isHls);
|
|
1003
963
|
};
|
|
1004
964
|
|
|
1005
965
|
return HlsjsPlayback;
|
|
1006
966
|
|
|
1007
|
-
}))
|
|
967
|
+
}));
|