}
*/
function parseAdaptationSets(adaptationsIR, context) {
- var _a, _b, _c, _d, _e, _f, _g, _h;
+ var _a, _b, _c, _d, _e, _f;
var parsedAdaptations = {
video: [],
audio: [],
@@ -20426,14 +20399,6 @@ function parseAdaptationSets(adaptationsIR, context) {
var trickModeAdaptations = [];
var adaptationSwitchingInfos = {};
var parsedAdaptationsIDs = [];
- /**
- * Index of the last parsed Video AdaptationSet with a Role set as "main" in
- * `parsedAdaptations.video`.
- * `-1` if not yet encountered.
- * Used as we merge all main video AdaptationSet due to a comprehension of the
- * DASH-IF IOP.
- */
- var lastMainVideoAdapIdx = -1;
for (var adaptationIdx = 0; adaptationIdx < adaptationsIR.length; adaptationIdx++) {
var adaptation = adaptationsIR[adaptationIdx];
var adaptationChildren = adaptation.children;
@@ -20456,7 +20421,6 @@ function parseAdaptationSets(adaptationsIR, context) {
}
var priority = (_c = adaptation.attributes.selectionPriority) !== null && _c !== void 0 ? _c : 1;
var originalID = adaptation.attributes.id;
- var newID = void 0;
var adaptationSetSwitchingIDs = getAdaptationSetSwitchingIDs(adaptation);
var parentSegmentTemplates = [];
if (context.segmentTemplate !== undefined) {
@@ -20486,123 +20450,118 @@ function parseAdaptationSets(adaptationsIR, context) {
}) : undefined;
var trickModeAttachedAdaptationIds = (_d = trickModeProperty === null || trickModeProperty === void 0 ? void 0 : trickModeProperty.value) === null || _d === void 0 ? void 0 : _d.split(" ");
var isTrickModeTrack = trickModeAttachedAdaptationIds !== undefined;
- if (type === "video" && isMainAdaptation && lastMainVideoAdapIdx >= 0 && parsedAdaptations.video.length > lastMainVideoAdapIdx && !isTrickModeTrack) {
- var _videoMainAdaptation$;
- var videoMainAdaptation = parsedAdaptations.video[lastMainVideoAdapIdx][0];
- reprCtxt.unsafelyBaseOnPreviousAdaptation = (_f = (_e = context.unsafelyBaseOnPreviousPeriod) === null || _e === void 0 ? void 0 : _e.getAdaptation(videoMainAdaptation.id)) !== null && _f !== void 0 ? _f : null;
- var representations = parseRepresentations(representationsIR, adaptation, reprCtxt);
- (_videoMainAdaptation$ = videoMainAdaptation.representations).push.apply(_videoMainAdaptation$, representations);
- newID = videoMainAdaptation.id;
+ var _adaptationChildren = adaptationChildren,
+ accessibilities = _adaptationChildren.accessibilities;
+ var isDub = void 0;
+ if (roles !== undefined && roles.some(function (role) {
+ return role.value === "dub";
+ })) {
+ isDub = true;
+ }
+ var isClosedCaption = void 0;
+ if (type !== "text") {
+ isClosedCaption = false;
} else {
- var _adaptationChildren = adaptationChildren,
- accessibilities = _adaptationChildren.accessibilities;
- var isDub = void 0;
- if (roles !== undefined && roles.some(function (role) {
- return role.value === "dub";
- })) {
- isDub = true;
- }
- var isClosedCaption = void 0;
- if (type !== "text") {
- isClosedCaption = false;
- } else if (accessibilities !== undefined) {
- isClosedCaption = accessibilities.some(isHardOfHearing);
- }
- var isAudioDescription = void 0;
- if (type !== "audio") {
- isAudioDescription = false;
- } else if (accessibilities !== undefined) {
- isAudioDescription = accessibilities.some(isVisuallyImpaired);
- }
- var isSignInterpreted = void 0;
- if (type !== "video") {
- isSignInterpreted = false;
- } else if (accessibilities !== undefined) {
- isSignInterpreted = accessibilities.some(hasSignLanguageInterpretation);
- }
- var adaptationID = getAdaptationID(adaptation, {
- isAudioDescription: isAudioDescription,
- isClosedCaption: isClosedCaption,
- isSignInterpreted: isSignInterpreted,
- isTrickModeTrack: isTrickModeTrack,
- type: type
+ isClosedCaption = isCaptionning(accessibilities, roles);
+ }
+ var isForcedSubtitle = void 0;
+ if (type === "text" && roles !== undefined && roles.some(function (role) {
+ return role.value === "forced-subtitle" || role.value === "forced_subtitle";
+ })) {
+ isForcedSubtitle = true;
+ }
+ var isAudioDescription = void 0;
+ if (type !== "audio") {
+ isAudioDescription = false;
+ } else if (accessibilities !== undefined) {
+ isAudioDescription = accessibilities.some(isVisuallyImpaired);
+ }
+ var isSignInterpreted = void 0;
+ if (type !== "video") {
+ isSignInterpreted = false;
+ } else if (accessibilities !== undefined) {
+ isSignInterpreted = accessibilities.some(hasSignLanguageInterpretation);
+ }
+ var adaptationID = getAdaptationID(adaptation, {
+ isAudioDescription: isAudioDescription,
+ isForcedSubtitle: isForcedSubtitle,
+ isClosedCaption: isClosedCaption,
+ isSignInterpreted: isSignInterpreted,
+ isTrickModeTrack: isTrickModeTrack,
+ type: type
+ });
+ // Avoid duplicate IDs
+ while ((0,array_includes/* default */.Z)(parsedAdaptationsIDs, adaptationID)) {
+ adaptationID += "-dup";
+ }
+ var newID = adaptationID;
+ parsedAdaptationsIDs.push(adaptationID);
+ reprCtxt.unsafelyBaseOnPreviousAdaptation = (_f = (_e = context.unsafelyBaseOnPreviousPeriod) === null || _e === void 0 ? void 0 : _e.getAdaptation(adaptationID)) !== null && _f !== void 0 ? _f : null;
+ var representations = parseRepresentations(representationsIR, adaptation, reprCtxt);
+ var parsedAdaptationSet = {
+ id: adaptationID,
+ representations: representations,
+ type: type,
+ isTrickModeTrack: isTrickModeTrack
+ };
+ if (adaptation.attributes.language != null) {
+ parsedAdaptationSet.language = adaptation.attributes.language;
+ }
+ if (isClosedCaption != null) {
+ parsedAdaptationSet.closedCaption = isClosedCaption;
+ }
+ if (isAudioDescription != null) {
+ parsedAdaptationSet.audioDescription = isAudioDescription;
+ }
+ if (isDub === true) {
+ parsedAdaptationSet.isDub = true;
+ }
+ if (isForcedSubtitle !== undefined) {
+ parsedAdaptationSet.forcedSubtitles = isForcedSubtitle;
+ }
+ if (isSignInterpreted === true) {
+ parsedAdaptationSet.isSignInterpreted = true;
+ }
+ if (label !== undefined) {
+ parsedAdaptationSet.label = label;
+ }
+ if (trickModeAttachedAdaptationIds !== undefined) {
+ trickModeAdaptations.push({
+ adaptation: parsedAdaptationSet,
+ trickModeAttachedAdaptationIds: trickModeAttachedAdaptationIds
});
- // Avoid duplicate IDs
- while ((0,array_includes/* default */.Z)(parsedAdaptationsIDs, adaptationID)) {
- adaptationID += "-dup";
- }
- newID = adaptationID;
- parsedAdaptationsIDs.push(adaptationID);
- reprCtxt.unsafelyBaseOnPreviousAdaptation = (_h = (_g = context.unsafelyBaseOnPreviousPeriod) === null || _g === void 0 ? void 0 : _g.getAdaptation(adaptationID)) !== null && _h !== void 0 ? _h : null;
- var _representations = parseRepresentations(representationsIR, adaptation, reprCtxt);
- var parsedAdaptationSet = {
- id: adaptationID,
- representations: _representations,
- type: type,
- isTrickModeTrack: isTrickModeTrack
- };
- if (adaptation.attributes.language != null) {
- parsedAdaptationSet.language = adaptation.attributes.language;
- }
- if (isClosedCaption != null) {
- parsedAdaptationSet.closedCaption = isClosedCaption;
- }
- if (isAudioDescription != null) {
- parsedAdaptationSet.audioDescription = isAudioDescription;
- }
- if (isDub === true) {
- parsedAdaptationSet.isDub = true;
- }
- if (isSignInterpreted === true) {
- parsedAdaptationSet.isSignInterpreted = true;
- }
- if (label !== undefined) {
- parsedAdaptationSet.label = label;
- }
- if (trickModeAttachedAdaptationIds !== undefined) {
- trickModeAdaptations.push({
- adaptation: parsedAdaptationSet,
- trickModeAttachedAdaptationIds: trickModeAttachedAdaptationIds
- });
- } else {
- // look if we have to merge this into another Adaptation
- var mergedIntoIdx = -1;
- var _loop = function _loop() {
- var id = _step2.value;
- var switchingInfos = adaptationSwitchingInfos[id];
- if (switchingInfos !== undefined && switchingInfos.newID !== newID && (0,array_includes/* default */.Z)(switchingInfos.adaptationSetSwitchingIDs, originalID)) {
- mergedIntoIdx = (0,array_find_index/* default */.Z)(parsedAdaptations[type], function (a) {
- return a[0].id === id;
- });
- var mergedInto = parsedAdaptations[type][mergedIntoIdx];
- if (mergedInto !== undefined && mergedInto[0].audioDescription === parsedAdaptationSet.audioDescription && mergedInto[0].closedCaption === parsedAdaptationSet.closedCaption && mergedInto[0].language === parsedAdaptationSet.language) {
- var _mergedInto$0$represe;
- log/* default.info */.Z.info("DASH Parser: merging \"switchable\" AdaptationSets", originalID, id);
- (_mergedInto$0$represe = mergedInto[0].representations).push.apply(_mergedInto$0$represe, parsedAdaptationSet.representations);
- if (type === "video" && isMainAdaptation && !mergedInto[1].isMainAdaptation) {
- lastMainVideoAdapIdx = Math.max(lastMainVideoAdapIdx, mergedIntoIdx);
- }
- mergedInto[1] = {
- priority: Math.max(priority, mergedInto[1].priority),
- isMainAdaptation: isMainAdaptation || mergedInto[1].isMainAdaptation,
- indexInMpd: Math.min(adaptationIdx, mergedInto[1].indexInMpd)
- };
- }
- }
- };
- for (var _iterator2 = parse_adaptation_sets_createForOfIteratorHelperLoose(adaptationSetSwitchingIDs), _step2; !(_step2 = _iterator2()).done;) {
- _loop();
- }
- if (mergedIntoIdx < 0) {
- parsedAdaptations[type].push([parsedAdaptationSet, {
- priority: priority,
- isMainAdaptation: isMainAdaptation,
- indexInMpd: adaptationIdx
- }]);
- if (type === "video" && isMainAdaptation) {
- lastMainVideoAdapIdx = parsedAdaptations.video.length - 1;
+ } else {
+ // look if we have to merge this into another Adaptation
+ var mergedIntoIdx = -1;
+ var _loop = function _loop() {
+ var id = _step2.value;
+ var switchingInfos = adaptationSwitchingInfos[id];
+ if (switchingInfos !== undefined && switchingInfos.newID !== newID && (0,array_includes/* default */.Z)(switchingInfos.adaptationSetSwitchingIDs, originalID)) {
+ mergedIntoIdx = (0,array_find_index/* default */.Z)(parsedAdaptations[type], function (a) {
+ return a[0].id === id;
+ });
+ var mergedInto = parsedAdaptations[type][mergedIntoIdx];
+ if (mergedInto !== undefined && mergedInto[0].audioDescription === parsedAdaptationSet.audioDescription && mergedInto[0].closedCaption === parsedAdaptationSet.closedCaption && mergedInto[0].language === parsedAdaptationSet.language) {
+ var _mergedInto$0$represe;
+ log/* default.info */.Z.info("DASH Parser: merging \"switchable\" AdaptationSets", originalID, id);
+ (_mergedInto$0$represe = mergedInto[0].representations).push.apply(_mergedInto$0$represe, parsedAdaptationSet.representations);
+ mergedInto[1] = {
+ priority: Math.max(priority, mergedInto[1].priority),
+ isMainAdaptation: isMainAdaptation || mergedInto[1].isMainAdaptation,
+ indexInMpd: Math.min(adaptationIdx, mergedInto[1].indexInMpd)
+ };
}
}
+ };
+ for (var _iterator2 = parse_adaptation_sets_createForOfIteratorHelperLoose(adaptationSetSwitchingIDs), _step2; !(_step2 = _iterator2()).done;) {
+ _loop();
+ }
+ if (mergedIntoIdx < 0) {
+ parsedAdaptations[type].push([parsedAdaptationSet, {
+ priority: priority,
+ isMainAdaptation: isMainAdaptation,
+ indexInMpd: adaptationIdx
+ }]);
}
}
if (originalID != null && adaptationSwitchingInfos[originalID] == null) {
@@ -21827,6 +21786,13 @@ function parseSegmentBase(root) {
dashName: "startNumber"
});
break;
+ case "endNumber":
+ parseValue(attr.value, {
+ asKey: "endNumber",
+ parser: parseMPDInteger,
+ dashName: "endNumber"
+ });
+ break;
}
}
return [attributes, warnings];
@@ -25521,6 +25487,13 @@ function applyGeneralStyle(element, style) {
*/
function applyPStyle(element, style) {
element.style.margin = "0px";
+ // Set on it the default font-size, more specific font sizes may then be set
+ // on children elements.
+ // Doing this on the parent elements seems to fix some CSS issues we had
+ // with too large inner line breaks spacing when the text track element was
+ // too small, for some reasons.
+ addClassName(element, "proportional-style");
+ element.setAttribute("data-proportional-font-size", "1");
// applies to body, div, p, region, span
var paragraphBackgroundColor = style.backgroundColor;
if ((0,is_non_empty_string/* default */.Z)(paragraphBackgroundColor)) {
@@ -28044,7 +28017,7 @@ function generateManifestParser(options) {
* Parse the MPD through the default JS-written parser (as opposed to the
* WebAssembly one).
* If it is not defined, throws.
- * @returns {Observable}
+ * @returns {Object|Promise.}
*/
function runDefaultJsParser() {
if (parsers.js === null) {
@@ -28058,14 +28031,14 @@ function generateManifestParser(options) {
* Process return of one of the MPD parser.
* If it asks for a resource, load it then continue.
* @param {Object} parserResponse - Response returned from a MPD parser.
- * @returns {Observable}
+ * @returns {Object|Promise.}
*/
function processMpdParserResponse(parserResponse) {
if (parserResponse.type === "done") {
if (parserResponse.value.warnings.length > 0) {
onWarnings(parserResponse.value.warnings);
}
- if (cancelSignal.isCancelled) {
+ if (cancelSignal.isCancelled()) {
return Promise.reject(cancelSignal.cancellationError);
}
var manifest = new src_manifest/* default */.ZP(parserResponse.value.parsed, options);
@@ -28494,12 +28467,9 @@ var check_isobmff_integrity = __webpack_require__(4460);
function addSegmentIntegrityChecks(segmentLoader) {
return function (url, content, loaderOptions, initialCancelSignal, callbacks) {
return new Promise(function (resolve, reject) {
- var requestCanceller = new task_canceller/* default */.ZP({
- cancelOn: initialCancelSignal
- });
- // Reject the `CancellationError` when `requestCanceller`'s signal emits
- // `stopRejectingOnCancel` here is a function allowing to stop this mechanism
- var stopRejectingOnCancel = requestCanceller.signal.register(reject);
+ var requestCanceller = new task_canceller/* default */.ZP();
+ var unlinkCanceller = requestCanceller.linkToSignal(initialCancelSignal);
+ requestCanceller.signal.register(reject);
segmentLoader(url, content, loaderOptions, requestCanceller.signal, Object.assign(Object.assign({}, callbacks), {
onNewChunk: function onNewChunk(data) {
try {
@@ -28507,7 +28477,7 @@ function addSegmentIntegrityChecks(segmentLoader) {
callbacks.onNewChunk(data);
} catch (err) {
// Do not reject with a `CancellationError` after cancelling the request
- stopRejectingOnCancel();
+ cleanUpCancellers();
// Cancel the request
requestCanceller.cancel();
// Reject with thrown error
@@ -28515,10 +28485,10 @@ function addSegmentIntegrityChecks(segmentLoader) {
}
}
})).then(function (info) {
- if (requestCanceller.isUsed) {
+ cleanUpCancellers();
+ if (requestCanceller.isUsed()) {
return;
}
- stopRejectingOnCancel();
if (info.resultType === "segment-loaded") {
try {
trowOnIntegrityError(info.resultData.responseData);
@@ -28528,10 +28498,14 @@ function addSegmentIntegrityChecks(segmentLoader) {
}
}
resolve(info);
- }, function (error) {
- stopRejectingOnCancel();
- reject(error);
+ }, function (err) {
+ cleanUpCancellers();
+ reject(err);
});
+ function cleanUpCancellers() {
+ requestCanceller.signal.deregister(reject);
+ unlinkCanceller();
+ }
});
/**
* If the data's seems to be corrupted, throws an `INTEGRITY_ERROR` error.
@@ -28776,7 +28750,7 @@ function lowLatencySegmentLoader(url, content, options, callbacks, cancelSignal)
partialChunk = res[1];
for (var i = 0; i < completeChunks.length; i++) {
callbacks.onNewChunk(completeChunks[i]);
- if (cancelSignal.isCancelled) {
+ if (cancelSignal.isCancelled()) {
return;
}
}
@@ -28785,7 +28759,7 @@ function lowLatencySegmentLoader(url, content, options, callbacks, cancelSignal)
size: info.size,
totalSize: info.totalSize
});
- if (cancelSignal.isCancelled) {
+ if (cancelSignal.isCancelled()) {
return;
}
}
@@ -28877,7 +28851,7 @@ function generateSegmentLoader(_ref) {
return checkMediaSegmentIntegrity !== true ? segmentLoader : addSegmentIntegrityChecks(segmentLoader);
/**
* @param {Object|null} wantedCdn
- * @returns {Observable}
+ * @returns {Promise.}
*/
function segmentLoader(wantedCdn, content, options, cancelSignal, callbacks) {
var url = constructSegmentUrl(wantedCdn, content.segment);
@@ -28908,7 +28882,7 @@ function generateSegmentLoader(_ref) {
* @param {Object} _args
*/
var resolve = function resolve(_args) {
- if (hasFinished || cancelSignal.isCancelled) {
+ if (hasFinished || cancelSignal.isCancelled()) {
return;
}
hasFinished = true;
@@ -28928,7 +28902,7 @@ function generateSegmentLoader(_ref) {
*/
var reject = function reject(err) {
var _a, _b, _c;
- if (hasFinished || cancelSignal.isCancelled) {
+ if (hasFinished || cancelSignal.isCancelled()) {
return;
}
hasFinished = true;
@@ -28940,7 +28914,7 @@ function generateSegmentLoader(_ref) {
rej(emittedErr);
};
var progress = function progress(_args) {
- if (hasFinished || cancelSignal.isCancelled) {
+ if (hasFinished || cancelSignal.isCancelled()) {
return;
}
callbacks.onProgress({
@@ -28954,7 +28928,7 @@ function generateSegmentLoader(_ref) {
* the "regular" implementation
*/
var fallback = function fallback() {
- if (hasFinished || cancelSignal.isCancelled) {
+ if (hasFinished || cancelSignal.isCancelled()) {
return;
}
hasFinished = true;
@@ -29843,7 +29817,7 @@ function getPlainTextTrackData(_ref2, textTrackData, isChunked) {
* @param {boolean} __priv_patchLastSegmentInSidx - Enable ugly Canal+-specific
* fix for an issue people on the content-packaging side could not fix.
* For more information on that, look at the code using it.
- * @returns {Observable.}
+ * @returns {Object}
*/
function parseISOBMFFEmbeddedTextTrack(data, isChunked, content, initTimescale, __priv_patchLastSegmentInSidx) {
var period = content.period,
@@ -29901,7 +29875,7 @@ function parseISOBMFFEmbeddedTextTrack(data, isChunked, content, initTimescale,
* @param {Object} content - Object describing the context of the given
* segment's data: of which segment, `Representation`, `Adaptation`, `Period`,
* `Manifest` it is a part of etc.
- * @returns {Observable.}
+ * @returns {Object}
*/
function parsePlainTextTrack(data, isChunked, content) {
var period = content.period,
@@ -29950,7 +29924,7 @@ function generateTextTrackParser(_ref) {
* @param {Object} loadedSegment
* @param {Object} content
* @param {number|undefined} initTimescale
- * @returns {Observable.}
+ * @returns {Object}
*/
return function textTrackParser(loadedSegment, content, initTimescale) {
var _a;
@@ -32807,7 +32781,7 @@ var generateSegmentLoader = function generateSegmentLoader(_ref) {
* @param {Object} args
*/
var resolve = function resolve(_args) {
- if (hasFinished || cancelSignal.isCancelled) {
+ if (hasFinished || cancelSignal.isCancelled()) {
return;
}
hasFinished = true;
@@ -32840,7 +32814,7 @@ var generateSegmentLoader = function generateSegmentLoader(_ref) {
*/
var reject = function reject(err) {
var _a, _b, _c;
- if (hasFinished || cancelSignal.isCancelled) {
+ if (hasFinished || cancelSignal.isCancelled()) {
return;
}
hasFinished = true;
@@ -32852,7 +32826,7 @@ var generateSegmentLoader = function generateSegmentLoader(_ref) {
rej(emittedErr);
};
var progress = function progress(_args) {
- if (hasFinished || cancelSignal.isCancelled) {
+ if (hasFinished || cancelSignal.isCancelled()) {
return;
}
callbacks.onProgress({
@@ -32862,7 +32836,7 @@ var generateSegmentLoader = function generateSegmentLoader(_ref) {
});
};
var fallback = function fallback() {
- if (hasFinished || cancelSignal.isCancelled) {
+ if (hasFinished || cancelSignal.isCancelled()) {
return;
}
hasFinished = true;
@@ -33585,7 +33559,7 @@ function callCustomManifestLoader(customManifestLoader, fallbackManifestLoader)
* @param {Object} args
*/
var resolve = function resolve(_args) {
- if (hasFinished || cancelSignal.isCancelled) {
+ if (hasFinished || cancelSignal.isCancelled()) {
return;
}
hasFinished = true;
@@ -33607,7 +33581,7 @@ function callCustomManifestLoader(customManifestLoader, fallbackManifestLoader)
*/
var reject = function reject(err) {
var _a, _b, _c;
- if (hasFinished || cancelSignal.isCancelled) {
+ if (hasFinished || cancelSignal.isCancelled()) {
return;
}
hasFinished = true;
@@ -33623,7 +33597,7 @@ function callCustomManifestLoader(customManifestLoader, fallbackManifestLoader)
* the "regular" implementation
*/
var fallback = function fallback() {
- if (hasFinished || cancelSignal.isCancelled) {
+ if (hasFinished || cancelSignal.isCancelled()) {
return;
}
hasFinished = true;
@@ -34475,6 +34449,7 @@ function toUint8Array(input) {
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Z": function() { return /* binding */ cancellableSleep; }
/* harmony export */ });
+/* harmony import */ var _create_cancellable_promise__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7733);
/**
* Copyright 2015 CANAL+ Group
*
@@ -34490,6 +34465,7 @@ function toUint8Array(input) {
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/**
* Wait the given `delay`, resolving the Promise when finished.
*
@@ -34504,296 +34480,76 @@ function toUint8Array(input) {
* cancellation with the corresponding `CancellationError`.
*/
function cancellableSleep(delay, cancellationSignal) {
- return new Promise(function (res, rej) {
+ return (0,_create_cancellable_promise__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(cancellationSignal, function (res) {
var timeout = setTimeout(function () {
- unregisterCancelSignal();
- res();
+ return res();
}, delay);
- var unregisterCancelSignal = cancellationSignal.register(function onCancel(cancellationError) {
- clearTimeout(timeout);
- rej(cancellationError);
- });
+ return function () {
+ return clearTimeout(timeout);
+ };
});
}
/***/ }),
-/***/ 8117:
+/***/ 7733:
/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
"use strict";
-/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1480);
-/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3102);
-/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2817);
-/* harmony import */ var _is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1946);
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ "Z": function() { return /* binding */ createCancellablePromise; }
+/* harmony export */ });
/**
- * Try to cast the given value into an observable.
- * StraightForward - test first for an Observable then for a Promise.
- * @param {Observable|Function|*}
- * @returns {Observable}
- */
-function castToObservable(value) {
- if (value instanceof rxjs__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y) {
- return value;
- } else if (value instanceof Promise || !(0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value) && typeof value.then === "function") {
- return (0,rxjs__WEBPACK_IMPORTED_MODULE_2__/* .from */ .D)(value);
- }
- return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.of)(value);
-}
-/* harmony default export */ __webpack_exports__["Z"] = (castToObservable);
-
-/***/ }),
-
-/***/ 8333:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-
-// EXPORTS
-__webpack_require__.d(__webpack_exports__, {
- "Z": function() { return /* binding */ deferSubscriptions; }
-});
-
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/subscribeOn.js
-var subscribeOn = __webpack_require__(8720);
-// EXTERNAL MODULE: ./node_modules/rxjs/node_modules/tslib/tslib.es6.js
-var tslib_es6 = __webpack_require__(5987);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/AsyncAction.js + 2 modules
-var AsyncAction = __webpack_require__(8337);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/util/Immediate.js
-var nextHandle = 1;
-var resolved;
-var activeHandles = {};
-function findAndClearHandle(handle) {
- if (handle in activeHandles) {
- delete activeHandles[handle];
- return true;
- }
- return false;
-}
-var Immediate = {
- setImmediate: function (cb) {
- var handle = nextHandle++;
- activeHandles[handle] = true;
- if (!resolved) {
- resolved = Promise.resolve();
- }
- resolved.then(function () { return findAndClearHandle(handle) && cb(); });
- return handle;
- },
- clearImmediate: function (handle) {
- findAndClearHandle(handle);
- },
-};
-var TestTools = {
- pending: function () {
- return Object.keys(activeHandles).length;
+ * Returns a Promise linked to a `CancellationSignal`, which will reject the
+ * corresponding `CancellationError` if that signal emits before the wanted
+ * task finishes (either on success or on error).
+ *
+ * The given callback mimicks the Promise interface with the added possibility
+ * of returning a callback which will be called when and if the task is
+ * cancelled before being either resolved or rejected.
+ * In that case, that logic will be called just before the Promise is rejected
+ * with the corresponding `CancellationError`.
+ * The point of this callback is to implement aborting logic, such as for
+ * example aborting a request.
+ *
+ * @param {Object} cancellationSignal - The `CancellationSignal` the returned
+ * Promise will be linked to.
+ * @param {Function} cb - The function implementing the cancellable Promise. Its
+ * arguments follow Promise's semantics but it can also return a function which
+ * will be called when and if `cancellationSignal` emits before either arguments
+ * are called.
+ * @returns {Promise} - The created Promise, which will resolve when and if the
+ * first argument to `cb` is called first and reject either if the second
+ * argument to `cb` is called first or if the given `CancellationSignal` emits
+ * before either of the two previous conditions.
+ */
+function createCancellablePromise(cancellationSignal, cb) {
+ var abortingLogic;
+ return new Promise(function (res, rej) {
+ if (cancellationSignal.cancellationError !== null) {
+ // If the signal was already triggered before, do not even call `cb`
+ return rej(cancellationSignal.cancellationError);
+ }
+ var hasUnregistered = false;
+ abortingLogic = cb(function onCancellablePromiseSuccess(val) {
+ cancellationSignal.deregister(onCancellablePromiseCancellation);
+ hasUnregistered = true;
+ res(val);
+ }, function onCancellablePromiseFailure(err) {
+ cancellationSignal.deregister(onCancellablePromiseCancellation);
+ hasUnregistered = true;
+ rej(err);
+ });
+ if (!hasUnregistered) {
+ cancellationSignal.register(onCancellablePromiseCancellation);
}
-};
-//# sourceMappingURL=Immediate.js.map
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/immediateProvider.js
-
-
-var setImmediate = Immediate.setImmediate, clearImmediate = Immediate.clearImmediate;
-var immediateProvider = {
- setImmediate: function () {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- var delegate = immediateProvider.delegate;
- return ((delegate === null || delegate === void 0 ? void 0 : delegate.setImmediate) || setImmediate).apply(void 0, (0,tslib_es6/* __spreadArray */.ev)([], (0,tslib_es6/* __read */.CR)(args)));
- },
- clearImmediate: function (handle) {
- var delegate = immediateProvider.delegate;
- return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearImmediate) || clearImmediate)(handle);
- },
- delegate: undefined,
-};
-//# sourceMappingURL=immediateProvider.js.map
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/AsapAction.js
-
-
-
-var AsapAction = (function (_super) {
- (0,tslib_es6/* __extends */.ZT)(AsapAction, _super);
- function AsapAction(scheduler, work) {
- var _this = _super.call(this, scheduler, work) || this;
- _this.scheduler = scheduler;
- _this.work = work;
- return _this;
+ function onCancellablePromiseCancellation(error) {
+ if (abortingLogic !== undefined) {
+ abortingLogic();
+ }
+ rej(error);
}
- AsapAction.prototype.requestAsyncId = function (scheduler, id, delay) {
- if (delay === void 0) { delay = 0; }
- if (delay !== null && delay > 0) {
- return _super.prototype.requestAsyncId.call(this, scheduler, id, delay);
- }
- scheduler.actions.push(this);
- return scheduler._scheduled || (scheduler._scheduled = immediateProvider.setImmediate(scheduler.flush.bind(scheduler, undefined)));
- };
- AsapAction.prototype.recycleAsyncId = function (scheduler, id, delay) {
- var _a;
- if (delay === void 0) { delay = 0; }
- if (delay != null ? delay > 0 : this.delay > 0) {
- return _super.prototype.recycleAsyncId.call(this, scheduler, id, delay);
- }
- var actions = scheduler.actions;
- if (id != null && ((_a = actions[actions.length - 1]) === null || _a === void 0 ? void 0 : _a.id) !== id) {
- immediateProvider.clearImmediate(id);
- scheduler._scheduled = undefined;
- }
- return undefined;
- };
- return AsapAction;
-}(AsyncAction/* AsyncAction */.o));
-
-//# sourceMappingURL=AsapAction.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/AsyncScheduler.js + 1 modules
-var AsyncScheduler = __webpack_require__(9682);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/AsapScheduler.js
-
-
-var AsapScheduler = (function (_super) {
- (0,tslib_es6/* __extends */.ZT)(AsapScheduler, _super);
- function AsapScheduler() {
- return _super !== null && _super.apply(this, arguments) || this;
- }
- AsapScheduler.prototype.flush = function (action) {
- this._active = true;
- var flushId = this._scheduled;
- this._scheduled = undefined;
- var actions = this.actions;
- var error;
- action = action || actions.shift();
- do {
- if ((error = action.execute(action.state, action.delay))) {
- break;
- }
- } while ((action = actions[0]) && action.id === flushId && actions.shift());
- this._active = false;
- if (error) {
- while ((action = actions[0]) && action.id === flushId && actions.shift()) {
- action.unsubscribe();
- }
- throw error;
- }
- };
- return AsapScheduler;
-}(AsyncScheduler/* AsyncScheduler */.v));
-
-//# sourceMappingURL=AsapScheduler.js.map
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/asap.js
-
-
-var asapScheduler = new AsapScheduler(AsapAction);
-var asap = (/* unused pure expression or super */ null && (asapScheduler));
-//# sourceMappingURL=asap.js.map
-;// CONCATENATED MODULE: ./src/utils/defer_subscriptions.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * At subscription, instead of "running" the Observable right away, wait until
- * the current task has finished executing before actually running this
- * Observable.
- *
- * This can be important for example when you want in a given function to
- * exploit the same shared Observable which may send synchronous events directly
- * after subscription.
- *
- * Here, you might be left in a situation where the first element subscribing to
- * that Observable will receive those synchronous events immediately on
- * subscription. Further subscriptions on that Observable will miss out on those
- * events - even if those subscriptions happen synchronously after the first
- * one.
- *
- * Calling `deferSubscriptions` in those cases will make sure that all such
- * subscriptions can be registered before the Observable start emitting events
- * (as long as such Subscriptions are done synchronously).
- *
- * @example
- * ```js
- * const myObservable = rxjs.timer(100).pipe(mapTo("ASYNC MSG"),
- * startWith("SYNCHRONOUS MSG"),
- * share());
- *
- * myObservable.subscribe(x => console.log("Sub1:", x));
- * myObservable.subscribe(x => console.log("Sub2:", x));
- *
- * setTimeout(() => {
- * myObservable.subscribe(x => console.log("Sub3:", x));
- * }, 50);
- *
- * // You will get:
- * // Sub1: SYNCHRONOUS MSG
- * // Sub1: ASYNC MSG
- * // Sub2: ASYNC MSG
- * // Sub3: ASYNC MSG
- *
- * // ------------------------------
- *
- * const myObservableDeferred = rxjs.timer(100).pipe(mapTo("ASYNC MSG"),
- * startWith("SYNCHRONOUS MSG"),
- * deferSubscriptions(),
- * // NOTE: the order is important here
- * share());
- *
- * myObservableDeferred.subscribe(x => console.log("Sub1:", x));
- * myObservableDeferred.subscribe(x => console.log("Sub2:", x));
- *
- * setTimeout(() => {
- * myObservableDeferred.subscribe(x => console.log("Sub3:", x));
- * }, 50);
- *
- * // You will get:
- * // Sub1: SYNCHRONOUS MSG
- * // Sub2: SYNCHRONOUS MSG
- * // Sub1: ASYNC MSG
- * // Sub2: ASYNC MSG
- * // Sub3: ASYNC MSG
- * ```
- * @returns {function}
- */
-function deferSubscriptions() {
- return function (source) {
- // TODO asapScheduler seems to not push the subscription in the microtask
- // queue as nextTick does but in a regular event loop queue.
- // This means that the subscription will be run even later that we wish for.
- // This is not dramatic but it could be better.
- // Either this is a problem with RxJS or this was wanted, in which case we
- // may need to add our own scheduler.
- return source.pipe((0,subscribeOn/* subscribeOn */.R)(asapScheduler));
- };
+ });
}
/***/ }),
@@ -34803,10 +34559,8 @@ function deferSubscriptions() {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "R": function() { return /* binding */ fromEvent; },
/* harmony export */ "Z": function() { return /* binding */ EventEmitter; }
/* harmony export */ });
-/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1480);
/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3887);
/* harmony import */ var _is_null_or_undefined__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1946);
/**
@@ -34826,7 +34580,6 @@ function deferSubscriptions() {
*/
-
/**
* Simple but fully type-safe EventEmitter implementation.
* @class EventEmitter
@@ -34911,74 +34664,7 @@ var EventEmitter = /*#__PURE__*/function () {
};
return EventEmitter;
}();
-/**
- * Simple redefinition of the fromEvent from rxjs to also work on our
- * implementation of EventEmitter with type-checked strings
- * @param {Object} target
- * @param {string} eventName
- * @returns {Observable}
- */
-
-function fromEvent(target, eventName) {
- return new rxjs__WEBPACK_IMPORTED_MODULE_2__/* .Observable */ .y(function (obs) {
- function handler(event) {
- obs.next(event);
- }
- target.addEventListener(eventName, handler);
- return function () {
- target.removeEventListener(eventName, handler);
- };
- });
-}
-
-/***/ }),
-
-/***/ 2793:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "Z": function() { return /* binding */ filterMap; }
-/* harmony export */ });
-/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9917);
-/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9127);
-/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4975);
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * Special kind of map which will ignore the result when the value emitted
- * corresponds to a given token.
- *
- * This can also be performed through a `mergeMap` (by returning the `EMPTY`
- * Observable when we want to ignore events) but using `filterMap` is both more
- * straightforward and more performant.
- * @param {function} callback
- * @param {*} filteringToken
- * @returns {function}
- */
-function filterMap(callback, filteringToken) {
- return function (source) {
- return (0,rxjs__WEBPACK_IMPORTED_MODULE_0__/* .defer */ .P)(function () {
- return source.pipe((0,rxjs__WEBPACK_IMPORTED_MODULE_1__/* .map */ .U)(callback), (0,rxjs__WEBPACK_IMPORTED_MODULE_2__/* .filter */ .h)(function (x) {
- return x !== filteringToken;
- }));
- });
- };
-}
/***/ }),
@@ -36236,8 +35922,6 @@ function isTimeInTimeRanges(ranges, time) {
/* harmony export */ "ZP": function() { return /* binding */ createSharedReference; },
/* harmony export */ "lR": function() { return /* binding */ createMappedReference; }
/* harmony export */ });
-/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1480);
-/* harmony import */ var _task_canceller__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(288);
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
@@ -36256,17 +35940,21 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-
/**
* Create an `ISharedReference` object encapsulating the mutable `initialValue`
* value of type T.
*
* @see ISharedReference
* @param {*} initialValue
- * @returns {Observable}
+ * @param {Object|undefined} [cancelSignal] - If set, the created shared
+ * reference will be automatically "finished" once that signal emits.
+ * Finished references won't be able to update their value anymore, and will
+ * also automatically have their listeners (callbacks linked to value change)
+ * removed - as they cannot be triggered anymore, thus providing a security
+ * against memory leaks.
+ * @returns {Object}
*/
-function createSharedReference(initialValue) {
+function createSharedReference(initialValue, cancelSignal) {
/** Current value referenced by this `ISharedReference`. */
var value = initialValue;
/**
@@ -36278,8 +35966,8 @@ function createSharedReference(initialValue) {
* once it changes
* - `complete`: Allows to clean-up the listener, will be called once the
* reference is finished.
- * - `hasBeenCleared`: becomes `true` when the Observable becomes
- * unsubscribed and thus when it is removed from the `cbs` array.
+ * - `hasBeenCleared`: becomes `true` when the reference is
+ * removed from the `cbs` array.
* Adding this property allows to detect when a previously-added
* listener has since been removed e.g. as a side-effect during a
* function call.
@@ -36287,6 +35975,9 @@ function createSharedReference(initialValue) {
*/
var cbs = [];
var isFinished = false;
+ if (cancelSignal !== undefined) {
+ cancelSignal.register(finish);
+ }
return {
/**
* Returns the current value of this shared reference.
@@ -36313,7 +36004,7 @@ function createSharedReference(initialValue) {
var cbObj = _step.value;
try {
if (!cbObj.hasBeenCleared) {
- cbObj.trigger(newVal);
+ cbObj.trigger(newVal, cbObj.complete);
}
} catch (_) {
/* nothing */
@@ -36329,47 +36020,12 @@ function createSharedReference(initialValue) {
this.setValue(newVal);
}
},
- /**
- * Returns an Observable which synchronously emits the current value (unless
- * the `skipCurrentValue` argument has been set to `true`) and then each
- * time a new value is set.
- * @param {boolean} [skipCurrentValue]
- * @returns {Observable}
- */
- asObservable: function asObservable(skipCurrentValue) {
- return new rxjs__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (obs) {
- if (skipCurrentValue !== true) {
- obs.next(value);
- }
- if (isFinished) {
- obs.complete();
- return undefined;
- }
- var cbObj = {
- trigger: obs.next.bind(obs),
- complete: obs.complete.bind(obs),
- hasBeenCleared: false
- };
- cbs.push(cbObj);
- return function () {
- /**
- * Code in here can still be running while this is happening.
- * Set `hasBeenCleared` to `true` to avoid still using the
- * `subscriber` from this object.
- */
- cbObj.hasBeenCleared = true;
- var indexOf = cbs.indexOf(cbObj);
- if (indexOf >= 0) {
- cbs.splice(indexOf, 1);
- }
- };
- });
- },
/**
* Allows to register a callback to be called each time the value inside the
* reference is updated.
* @param {Function} cb - Callback to be called each time the reference is
- * updated. Takes the new value im argument.
+ * updated. Takes as first argument its new value and in second argument a
+ * callback allowing to unregister the callback.
* @param {Object|undefined} [options]
* @param {Object|undefined} [options.clearSignal] - Allows to provide a
* CancellationSignal which will unregister the callback when it emits.
@@ -36377,28 +36033,30 @@ function createSharedReference(initialValue) {
* callback will also be immediately called with the current value.
*/
onUpdate: function onUpdate(cb, options) {
- if ((options === null || options === void 0 ? void 0 : options.emitCurrentValue) === true) {
- cb(value);
- }
- if (isFinished) {
- return;
- }
var cbObj = {
trigger: cb,
complete: unlisten,
hasBeenCleared: false
};
cbs.push(cbObj);
+ if ((options === null || options === void 0 ? void 0 : options.emitCurrentValue) === true) {
+ cb(value, unlisten);
+ }
+ if (isFinished || cbObj.hasBeenCleared) {
+ unlisten();
+ return;
+ }
if ((options === null || options === void 0 ? void 0 : options.clearSignal) === undefined) {
return;
}
options.clearSignal.register(unlisten);
function unlisten() {
- /**
- * Code in here can still be running while this is happening.
- * Set `hasBeenCleared` to `true` to avoid still using the
- * `subscriber` from this object.
- */
+ if ((options === null || options === void 0 ? void 0 : options.clearSignal) !== undefined) {
+ options.clearSignal.deregister(unlisten);
+ }
+ if (cbObj.hasBeenCleared) {
+ return;
+ }
cbObj.hasBeenCleared = true;
var indexOf = cbs.indexOf(cbObj);
if (indexOf >= 0) {
@@ -36406,52 +36064,56 @@ function createSharedReference(initialValue) {
}
}
},
+ /**
+ * Variant of `onUpdate` which will only call the callback once, once the
+ * value inside the reference is different from `undefined`.
+ * The callback is called synchronously if the value already isn't set to
+ * `undefined`.
+ *
+ * This method can be used as a lighter weight alternative to `onUpdate`
+ * when just waiting that the stored value becomes defined.
+ * @param {Function} cb - Callback to be called each time the reference is
+ * updated. Takes the new value in argument.
+ * @param {Object} [options]
+ * @param {Object} [options.clearSignal] - Allows to provide a
+ * CancellationSignal which will unregister the callback when it emits.
+ */
waitUntilDefined: function waitUntilDefined(cb, options) {
- if (value !== undefined) {
- cb(value);
- return;
- }
- if (isFinished) {
- return;
- }
- var childCanceller = new _task_canceller__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .ZP();
- if ((options === null || options === void 0 ? void 0 : options.clearSignal) !== undefined) {
- options.clearSignal.register(function () {
- return childCanceller.cancel();
- });
- }
- this.onUpdate(function (val) {
+ this.onUpdate(function (val, stopListening) {
if (val !== undefined) {
- childCanceller.cancel();
+ stopListening();
cb(value);
- return;
}
}, {
- clearSignal: childCanceller.signal
+ clearSignal: options === null || options === void 0 ? void 0 : options.clearSignal,
+ emitCurrentValue: true
});
},
/**
* Indicate that no new values will be emitted.
- * Allows to automatically close all Observables generated from this shared
- * reference.
+ * Allows to automatically free all listeners linked to this reference.
*/
- finish: function finish() {
- isFinished = true;
- var clonedCbs = cbs.slice();
- for (var _iterator2 = _createForOfIteratorHelperLoose(clonedCbs), _step2; !(_step2 = _iterator2()).done;) {
- var cbObj = _step2.value;
- try {
- if (!cbObj.hasBeenCleared) {
- cbObj.complete();
- }
+ finish: finish
+ };
+ function finish() {
+ if (cancelSignal !== undefined) {
+ cancelSignal.deregister(finish);
+ }
+ isFinished = true;
+ var clonedCbs = cbs.slice();
+ for (var _iterator2 = _createForOfIteratorHelperLoose(clonedCbs), _step2; !(_step2 = _iterator2()).done;) {
+ var cbObj = _step2.value;
+ try {
+ if (!cbObj.hasBeenCleared) {
+ cbObj.complete();
cbObj.hasBeenCleared = true;
- } catch (_) {
- /* nothing */
}
+ } catch (_) {
+ /* nothing */
}
- cbs.length = 0;
}
- };
+ cbs.length = 0;
+ }
}
/**
* Create a new `ISharedReference` based on another one by mapping over its
@@ -36460,12 +36122,12 @@ function createSharedReference(initialValue) {
* over.
* @param {Function} mappingFn - The mapping function which will receives
* `originalRef`'s value and outputs this new reference's value.
- * @param {Object | undefined} [cancellationSignal] - Optionally, a
- * `CancellationSignal` which will finish that reference when it emits.
+ * @param {Object} cancellationSignal - Optionally, a `CancellationSignal` which
+ * will finish that reference when it emits.
* @returns {Object} - The new, mapped, reference.
*/
function createMappedReference(originalRef, mappingFn, cancellationSignal) {
- var newRef = createSharedReference(mappingFn(originalRef.getValue()));
+ var newRef = createSharedReference(mappingFn(originalRef.getValue()), cancellationSignal);
originalRef.onUpdate(function mapOriginalReference(x) {
newRef.setValue(mappingFn(x));
}, {
@@ -36473,11 +36135,6 @@ function createMappedReference(originalRef, mappingFn, cancellationSignal) {
});
// TODO nothing is done if `originalRef` is finished, though the returned
// reference could also be finished in that case. To do?
- if (cancellationSignal !== undefined) {
- cancellationSignal.register(function () {
- newRef.finish();
- });
- }
return newRef;
}
@@ -36575,7 +36232,7 @@ function request(options) {
}
reject(err);
});
- if (cancelSignal.isCancelled) {
+ if (cancelSignal.isCancelled()) {
return;
}
}
@@ -36804,48 +36461,6 @@ function getFilenameIndexInUrl(url) {
}
-/***/ }),
-
-/***/ 5561:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "Z": function() { return /* binding */ tryCatch; }
-/* harmony export */ });
-/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3610);
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @param {Function} func - A function you want to execute
- * @param {*} argsForFunc - The function's argument
- * @returns {*} - If it fails, returns a throwing Observable, else the
- * function's result (which should be, in most cases, an Observable).
- */
-function tryCatch(func, argsForFunc) {
- try {
- return func(argsForFunc);
- } catch (e) {
- return (0,rxjs__WEBPACK_IMPORTED_MODULE_0__/* .throwError */ ._)(function () {
- return e;
- });
- }
-}
-
/***/ }),
/***/ 9252:
@@ -37316,14 +36931,15 @@ function takeFirstSet() {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "FU": function() { return /* binding */ CancellationError; },
+/* harmony export */ "XG": function() { return /* binding */ CancellationSignal; },
/* harmony export */ "ZP": function() { return /* binding */ TaskCanceller; }
/* harmony export */ });
-/* unused harmony export CancellationSignal */
-/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7326);
-/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4578);
-/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2146);
-/* harmony import */ var _assert__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(811);
-/* harmony import */ var _noop__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8894);
+/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7326);
+/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4578);
+/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2146);
+/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3887);
+/* harmony import */ var _assert__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(811);
+/* harmony import */ var _noop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8894);
@@ -37344,6 +36960,7 @@ function takeFirstSet() {
*/
+
/**
* Class facilitating asynchronous task cancellation.
*
@@ -37446,22 +37063,44 @@ var TaskCanceller = /*#__PURE__*/function () {
* Creates a new `TaskCanceller`, with its own `CancellationSignal` created
* as its `signal` provide.
* You can then pass this property to async task you wish to be cancellable.
- * @param {Object|undefined} options
*/
- function TaskCanceller(options) {
- var _this = this;
+ function TaskCanceller() {
var _createCancellationFu = createCancellationFunctions(),
trigger = _createCancellationFu[0],
register = _createCancellationFu[1];
- this.isUsed = false;
+ this._isUsed = false;
this._trigger = trigger;
this.signal = new CancellationSignal(register);
- if ((options === null || options === void 0 ? void 0 : options.cancelOn) !== undefined) {
- var unregisterParent = options.cancelOn.register(function () {
- _this.cancel();
- });
- this.signal.register(unregisterParent);
- }
+ }
+ /**
+ * Returns `true` if this `TaskCanceller` has already been triggered.
+ * `false` otherwise.
+ */
+ var _proto = TaskCanceller.prototype;
+ _proto.isUsed = function isUsed() {
+ return this._isUsed;
+ }
+ /**
+ * Bind this `TaskCanceller` to a `CancellationSignal`, so the former
+ * is automatically cancelled when the latter is triggered.
+ *
+ * Note that this call registers a callback on the given signal, until either
+ * the current `TaskCanceller` is cancelled or until this given
+ * `CancellationSignal` is triggered.
+ * To avoid leaking memory, the returned callback allow to undo this link.
+ * It should be called if/when that link is not needed anymore, such as when
+ * there is no need for this `TaskCanceller` anymore.
+ *
+ * @param {Object} signal
+ * @returns {Function}
+ */;
+ _proto.linkToSignal = function linkToSignal(signal) {
+ var _this = this;
+ var unregister = signal.register(function () {
+ _this.cancel();
+ });
+ this.signal.register(unregister);
+ return unregister;
}
/**
* "Trigger" the `TaskCanceller`, notify through its associated
@@ -37473,13 +37112,12 @@ var TaskCanceller = /*#__PURE__*/function () {
* cancellation is actually triggered as a chain reaction from a previous
* cancellation.
* @param {Error} [srcError]
- */
- var _proto = TaskCanceller.prototype;
+ */;
_proto.cancel = function cancel(srcError) {
- if (this.isUsed) {
+ if (this._isUsed) {
return;
}
- this.isUsed = true;
+ this._isUsed = true;
var cancellationError = srcError !== null && srcError !== void 0 ? srcError : new CancellationError();
this._trigger(cancellationError);
}
@@ -37509,18 +37147,31 @@ var CancellationSignal = /*#__PURE__*/function () {
*/
function CancellationSignal(registerToSource) {
var _this2 = this;
- this.isCancelled = false;
+ this._isCancelled = false;
this.cancellationError = null;
this._listeners = [];
registerToSource(function (cancellationError) {
_this2.cancellationError = cancellationError;
- _this2.isCancelled = true;
+ _this2._isCancelled = true;
while (_this2._listeners.length > 0) {
- var listener = _this2._listeners.splice(_this2._listeners.length - 1, 1)[0];
- listener(cancellationError);
+ try {
+ var listener = _this2._listeners.pop();
+ listener === null || listener === void 0 ? void 0 : listener(cancellationError);
+ } catch (err) {
+ _log__WEBPACK_IMPORTED_MODULE_0__/* ["default"].error */ .Z.error("Error while calling clean up listener", err instanceof Error ? err.toString() : "Unknown error");
+ }
}
});
}
+ /**
+ * Returns `true` when the cancellation order was already triggered, meaning
+ * that the linked task needs to be aborted.
+ * @returns boolean
+ */
+ var _proto2 = CancellationSignal.prototype;
+ _proto2.isCancelled = function isCancelled() {
+ return this._isCancelled;
+ }
/**
* Registers a function that will be called when/if the current task is
* cancelled.
@@ -37541,13 +37192,13 @@ var CancellationSignal = /*#__PURE__*/function () {
* task succeeded or failed).
* You don't need to call that function when cancellation has already been
* performed.
- */
- var _proto2 = CancellationSignal.prototype;
+ */;
_proto2.register = function register(fn) {
var _this3 = this;
- if (this.isCancelled) {
- (0,_assert__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(this.cancellationError !== null);
+ if (this._isCancelled) {
+ (0,_assert__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(this.cancellationError !== null);
fn(this.cancellationError);
+ return _noop__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z;
}
this._listeners.push(fn);
return function () {
@@ -37563,13 +37214,9 @@ var CancellationSignal = /*#__PURE__*/function () {
* @param {Function} fn
*/;
_proto2.deregister = function deregister(fn) {
- if (this.isCancelled) {
- return;
- }
- for (var i = 0; i < this._listeners.length; i++) {
+ for (var i = this._listeners.length - 1; i >= 0; i--) {
if (this._listeners[i] === fn) {
this._listeners.splice(i, 1);
- return;
}
}
};
@@ -37581,25 +37228,25 @@ var CancellationSignal = /*#__PURE__*/function () {
* @extends Error
*/
var CancellationError = /*#__PURE__*/function (_Error) {
- (0,_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(CancellationError, _Error);
+ (0,_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(CancellationError, _Error);
function CancellationError() {
var _this4;
_this4 = _Error.call(this) || this;
// @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class
- Object.setPrototypeOf((0,_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(_this4), CancellationError.prototype);
+ Object.setPrototypeOf((0,_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(_this4), CancellationError.prototype);
_this4.name = "CancellationError";
_this4.message = "This task was cancelled.";
return _this4;
}
return CancellationError;
-}( /*#__PURE__*/(0,_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(Error));
+}( /*#__PURE__*/(0,_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z)(Error));
/**
* Helper function allowing communication between a `TaskCanceller` and a
* `CancellationSignal`.
* @returns {Array.}
*/
function createCancellationFunctions() {
- var listener = _noop__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z;
+ var listener = _noop__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z;
return [function trigger(error) {
listener(error);
}, function register(newListener) {
@@ -37733,5036 +37380,1685 @@ module.exports = (function () {
/***/ }),
-/***/ 1480:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+/***/ 7061:
+/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
-"use strict";
+var _typeof = (__webpack_require__(8698)["default"]);
-// EXPORTS
-__webpack_require__.d(__webpack_exports__, {
- "y": function() { return /* binding */ Observable; }
-});
+function _regeneratorRuntime() {
+ "use strict";
+ /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
+
+ module.exports = _regeneratorRuntime = function _regeneratorRuntime() {
+ return exports;
+ }, module.exports.__esModule = true, module.exports["default"] = module.exports;
+ var exports = {},
+ Op = Object.prototype,
+ hasOwn = Op.hasOwnProperty,
+ $Symbol = "function" == typeof Symbol ? Symbol : {},
+ iteratorSymbol = $Symbol.iterator || "@@iterator",
+ asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
+ toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/Subscriber.js + 1 modules
-var Subscriber = __webpack_require__(6267);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/Subscription.js + 1 modules
-var Subscription = __webpack_require__(5720);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/symbol/observable.js
-var observable = __webpack_require__(6766);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/identity.js
-var identity = __webpack_require__(278);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/util/pipe.js
+ function define(obj, key, value) {
+ return Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: !0,
+ configurable: !0,
+ writable: !0
+ }), obj[key];
+ }
-function pipe() {
- var fns = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- fns[_i] = arguments[_i];
- }
- return pipeFromArray(fns);
-}
-function pipeFromArray(fns) {
- if (fns.length === 0) {
- return identity/* identity */.y;
- }
- if (fns.length === 1) {
- return fns[0];
- }
- return function piped(input) {
- return fns.reduce(function (prev, fn) { return fn(prev); }, input);
+ try {
+ define({}, "");
+ } catch (err) {
+ define = function define(obj, key, value) {
+ return obj[key] = value;
};
-}
-//# sourceMappingURL=pipe.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/config.js
-var config = __webpack_require__(3912);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/isFunction.js
-var isFunction = __webpack_require__(8474);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/errorContext.js
-var errorContext = __webpack_require__(8846);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/Observable.js
+ }
+
+ function wrap(innerFn, outerFn, self, tryLocsList) {
+ var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
+ generator = Object.create(protoGenerator.prototype),
+ context = new Context(tryLocsList || []);
+ return generator._invoke = function (innerFn, self, context) {
+ var state = "suspendedStart";
+ return function (method, arg) {
+ if ("executing" === state) throw new Error("Generator is already running");
+ if ("completed" === state) {
+ if ("throw" === method) throw arg;
+ return doneResult();
+ }
+ for (context.method = method, context.arg = arg;;) {
+ var delegate = context.delegate;
+ if (delegate) {
+ var delegateResult = maybeInvokeDelegate(delegate, context);
+ if (delegateResult) {
+ if (delegateResult === ContinueSentinel) continue;
+ return delegateResult;
+ }
+ }
+ if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
+ if ("suspendedStart" === state) throw state = "completed", context.arg;
+ context.dispatchException(context.arg);
+ } else "return" === context.method && context.abrupt("return", context.arg);
+ state = "executing";
+ var record = tryCatch(innerFn, self, context);
+ if ("normal" === record.type) {
+ if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
+ return {
+ value: record.arg,
+ done: context.done
+ };
+ }
-var Observable = (function () {
- function Observable(subscribe) {
- if (subscribe) {
- this._subscribe = subscribe;
+ "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
}
+ };
+ }(innerFn, self, context), generator;
+ }
+
+ function tryCatch(fn, obj, arg) {
+ try {
+ return {
+ type: "normal",
+ arg: fn.call(obj, arg)
+ };
+ } catch (err) {
+ return {
+ type: "throw",
+ arg: err
+ };
}
- Observable.prototype.lift = function (operator) {
- var observable = new Observable();
- observable.source = this;
- observable.operator = operator;
- return observable;
- };
- Observable.prototype.subscribe = function (observerOrNext, error, complete) {
- var _this = this;
- var subscriber = isSubscriber(observerOrNext) ? observerOrNext : new Subscriber/* SafeSubscriber */.Hp(observerOrNext, error, complete);
- (0,errorContext/* errorContext */.x)(function () {
- var _a = _this, operator = _a.operator, source = _a.source;
- subscriber.add(operator
- ?
- operator.call(subscriber, source)
- : source
- ?
- _this._subscribe(subscriber)
- :
- _this._trySubscribe(subscriber));
- });
- return subscriber;
- };
- Observable.prototype._trySubscribe = function (sink) {
- try {
- return this._subscribe(sink);
- }
- catch (err) {
- sink.error(err);
- }
- };
- Observable.prototype.forEach = function (next, promiseCtor) {
- var _this = this;
- promiseCtor = getPromiseCtor(promiseCtor);
- return new promiseCtor(function (resolve, reject) {
- var subscriber = new Subscriber/* SafeSubscriber */.Hp({
- next: function (value) {
- try {
- next(value);
- }
- catch (err) {
- reject(err);
- subscriber.unsubscribe();
- }
- },
- error: reject,
- complete: resolve,
- });
- _this.subscribe(subscriber);
- });
- };
- Observable.prototype._subscribe = function (subscriber) {
- var _a;
- return (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber);
- };
- Observable.prototype[observable/* observable */.L] = function () {
- return this;
- };
- Observable.prototype.pipe = function () {
- var operations = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- operations[_i] = arguments[_i];
- }
- return pipeFromArray(operations)(this);
- };
- Observable.prototype.toPromise = function (promiseCtor) {
- var _this = this;
- promiseCtor = getPromiseCtor(promiseCtor);
- return new promiseCtor(function (resolve, reject) {
- var value;
- _this.subscribe(function (x) { return (value = x); }, function (err) { return reject(err); }, function () { return resolve(value); });
+ }
+
+ exports.wrap = wrap;
+ var ContinueSentinel = {};
+
+ function Generator() {}
+
+ function GeneratorFunction() {}
+
+ function GeneratorFunctionPrototype() {}
+
+ var IteratorPrototype = {};
+ define(IteratorPrototype, iteratorSymbol, function () {
+ return this;
+ });
+ var getProto = Object.getPrototypeOf,
+ NativeIteratorPrototype = getProto && getProto(getProto(values([])));
+ NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
+ var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
+
+ function defineIteratorMethods(prototype) {
+ ["next", "throw", "return"].forEach(function (method) {
+ define(prototype, method, function (arg) {
+ return this._invoke(method, arg);
+ });
+ });
+ }
+
+ function AsyncIterator(generator, PromiseImpl) {
+ function invoke(method, arg, resolve, reject) {
+ var record = tryCatch(generator[method], generator, arg);
+
+ if ("throw" !== record.type) {
+ var result = record.arg,
+ value = result.value;
+ return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
+ invoke("next", value, resolve, reject);
+ }, function (err) {
+ invoke("throw", err, resolve, reject);
+ }) : PromiseImpl.resolve(value).then(function (unwrapped) {
+ result.value = unwrapped, resolve(result);
+ }, function (error) {
+ return invoke("throw", error, resolve, reject);
});
- };
- Observable.create = function (subscribe) {
- return new Observable(subscribe);
- };
- return Observable;
-}());
+ }
-function getPromiseCtor(promiseCtor) {
- var _a;
- return (_a = promiseCtor !== null && promiseCtor !== void 0 ? promiseCtor : config/* config.Promise */.v.Promise) !== null && _a !== void 0 ? _a : Promise;
-}
-function isObserver(value) {
- return value && (0,isFunction/* isFunction */.m)(value.next) && (0,isFunction/* isFunction */.m)(value.error) && (0,isFunction/* isFunction */.m)(value.complete);
-}
-function isSubscriber(value) {
- return (value && value instanceof Subscriber/* Subscriber */.Lv) || (isObserver(value) && (0,Subscription/* isSubscription */.Nn)(value));
-}
-//# sourceMappingURL=Observable.js.map
+ reject(record.arg);
+ }
-/***/ }),
+ var previousPromise;
-/***/ 3:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+ this._invoke = function (method, arg) {
+ function callInvokeWithMethodAndArg() {
+ return new PromiseImpl(function (resolve, reject) {
+ invoke(method, arg, resolve, reject);
+ });
+ }
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "t": function() { return /* binding */ ReplaySubject; }
-/* harmony export */ });
-/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5987);
-/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6716);
-/* harmony import */ var _scheduler_dateTimestampProvider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4318);
-
-
-
-var ReplaySubject = (function (_super) {
- (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT)(ReplaySubject, _super);
- function ReplaySubject(_bufferSize, _windowTime, _timestampProvider) {
- if (_bufferSize === void 0) { _bufferSize = Infinity; }
- if (_windowTime === void 0) { _windowTime = Infinity; }
- if (_timestampProvider === void 0) { _timestampProvider = _scheduler_dateTimestampProvider__WEBPACK_IMPORTED_MODULE_1__/* .dateTimestampProvider */ .l; }
- var _this = _super.call(this) || this;
- _this._bufferSize = _bufferSize;
- _this._windowTime = _windowTime;
- _this._timestampProvider = _timestampProvider;
- _this._buffer = [];
- _this._infiniteTimeWindow = true;
- _this._infiniteTimeWindow = _windowTime === Infinity;
- _this._bufferSize = Math.max(1, _bufferSize);
- _this._windowTime = Math.max(1, _windowTime);
- return _this;
- }
- ReplaySubject.prototype.next = function (value) {
- var _a = this, isStopped = _a.isStopped, _buffer = _a._buffer, _infiniteTimeWindow = _a._infiniteTimeWindow, _timestampProvider = _a._timestampProvider, _windowTime = _a._windowTime;
- if (!isStopped) {
- _buffer.push(value);
- !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);
- }
- this._trimBuffer();
- _super.prototype.next.call(this, value);
- };
- ReplaySubject.prototype._subscribe = function (subscriber) {
- this._throwIfClosed();
- this._trimBuffer();
- var subscription = this._innerSubscribe(subscriber);
- var _a = this, _infiniteTimeWindow = _a._infiniteTimeWindow, _buffer = _a._buffer;
- var copy = _buffer.slice();
- for (var i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {
- subscriber.next(copy[i]);
- }
- this._checkFinalizedStatuses(subscriber);
- return subscription;
- };
- ReplaySubject.prototype._trimBuffer = function () {
- var _a = this, _bufferSize = _a._bufferSize, _timestampProvider = _a._timestampProvider, _buffer = _a._buffer, _infiniteTimeWindow = _a._infiniteTimeWindow;
- var adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;
- _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);
- if (!_infiniteTimeWindow) {
- var now = _timestampProvider.now();
- var last = 0;
- for (var i = 1; i < _buffer.length && _buffer[i] <= now; i += 2) {
- last = i;
- }
- last && _buffer.splice(0, last + 1);
- }
+ return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
};
- return ReplaySubject;
-}(_Subject__WEBPACK_IMPORTED_MODULE_2__/* .Subject */ .x));
-
-//# sourceMappingURL=ReplaySubject.js.map
+ }
-/***/ }),
+ function maybeInvokeDelegate(delegate, context) {
+ var method = delegate.iterator[context.method];
-/***/ 6716:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+ if (undefined === method) {
+ if (context.delegate = null, "throw" === context.method) {
+ if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel;
+ context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method");
+ }
-"use strict";
+ return ContinueSentinel;
+ }
-// EXPORTS
-__webpack_require__.d(__webpack_exports__, {
- "x": function() { return /* binding */ Subject; }
-});
+ var record = tryCatch(method, delegate.iterator, context.arg);
+ if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
+ var info = record.arg;
+ return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel);
+ }
-// UNUSED EXPORTS: AnonymousSubject
-
-// EXTERNAL MODULE: ./node_modules/rxjs/node_modules/tslib/tslib.es6.js
-var tslib_es6 = __webpack_require__(5987);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/Observable.js + 1 modules
-var Observable = __webpack_require__(1480);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/Subscription.js + 1 modules
-var Subscription = __webpack_require__(5720);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js
-var createErrorClass = __webpack_require__(1819);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/util/ObjectUnsubscribedError.js
-
-var ObjectUnsubscribedError = (0,createErrorClass/* createErrorClass */.d)(function (_super) {
- return function ObjectUnsubscribedErrorImpl() {
- _super(this);
- this.name = 'ObjectUnsubscribedError';
- this.message = 'object unsubscribed';
+ function pushTryEntry(locs) {
+ var entry = {
+ tryLoc: locs[0]
};
-});
-//# sourceMappingURL=ObjectUnsubscribedError.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/arrRemove.js
-var arrRemove = __webpack_require__(3699);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/errorContext.js
-var errorContext = __webpack_require__(8846);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/Subject.js
+ 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
+ }
+ function resetTryEntry(entry) {
+ var record = entry.completion || {};
+ record.type = "normal", delete record.arg, entry.completion = record;
+ }
+ function Context(tryLocsList) {
+ this.tryEntries = [{
+ tryLoc: "root"
+ }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
+ }
+ function values(iterable) {
+ if (iterable) {
+ var iteratorMethod = iterable[iteratorSymbol];
+ if (iteratorMethod) return iteratorMethod.call(iterable);
+ if ("function" == typeof iterable.next) return iterable;
+ if (!isNaN(iterable.length)) {
+ var i = -1,
+ next = function next() {
+ for (; ++i < iterable.length;) {
+ if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;
+ }
+ return next.value = undefined, next.done = !0, next;
+ };
-var Subject = (function (_super) {
- (0,tslib_es6/* __extends */.ZT)(Subject, _super);
- function Subject() {
- var _this = _super.call(this) || this;
- _this.closed = false;
- _this.currentObservers = null;
- _this.observers = [];
- _this.isStopped = false;
- _this.hasError = false;
- _this.thrownError = null;
- return _this;
+ return next.next = next;
+ }
}
- Subject.prototype.lift = function (operator) {
- var subject = new AnonymousSubject(this, this);
- subject.operator = operator;
- return subject;
- };
- Subject.prototype._throwIfClosed = function () {
- if (this.closed) {
- throw new ObjectUnsubscribedError();
- }
- };
- Subject.prototype.next = function (value) {
- var _this = this;
- (0,errorContext/* errorContext */.x)(function () {
- var e_1, _a;
- _this._throwIfClosed();
- if (!_this.isStopped) {
- if (!_this.currentObservers) {
- _this.currentObservers = Array.from(_this.observers);
- }
- try {
- for (var _b = (0,tslib_es6/* __values */.XA)(_this.currentObservers), _c = _b.next(); !_c.done; _c = _b.next()) {
- var observer = _c.value;
- observer.next(value);
- }
- }
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
- finally {
- try {
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
- }
- finally { if (e_1) throw e_1.error; }
- }
- }
- });
- };
- Subject.prototype.error = function (err) {
- var _this = this;
- (0,errorContext/* errorContext */.x)(function () {
- _this._throwIfClosed();
- if (!_this.isStopped) {
- _this.hasError = _this.isStopped = true;
- _this.thrownError = err;
- var observers = _this.observers;
- while (observers.length) {
- observers.shift().error(err);
- }
- }
- });
+
+ return {
+ next: doneResult
};
- Subject.prototype.complete = function () {
- var _this = this;
- (0,errorContext/* errorContext */.x)(function () {
- _this._throwIfClosed();
- if (!_this.isStopped) {
- _this.isStopped = true;
- var observers = _this.observers;
- while (observers.length) {
- observers.shift().complete();
- }
- }
- });
+ }
+
+ function doneResult() {
+ return {
+ value: undefined,
+ done: !0
};
- Subject.prototype.unsubscribe = function () {
- this.isStopped = this.closed = true;
- this.observers = this.currentObservers = null;
+ }
+
+ return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
+ var ctor = "function" == typeof genFun && genFun.constructor;
+ return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
+ }, exports.mark = function (genFun) {
+ return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun;
+ }, exports.awrap = function (arg) {
+ return {
+ __await: arg
};
- Object.defineProperty(Subject.prototype, "observed", {
- get: function () {
- var _a;
- return ((_a = this.observers) === null || _a === void 0 ? void 0 : _a.length) > 0;
- },
- enumerable: false,
- configurable: true
+ }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
+ return this;
+ }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
+ void 0 === PromiseImpl && (PromiseImpl = Promise);
+ var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
+ return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
+ return result.done ? result.value : iter.next();
});
- Subject.prototype._trySubscribe = function (subscriber) {
- this._throwIfClosed();
- return _super.prototype._trySubscribe.call(this, subscriber);
- };
- Subject.prototype._subscribe = function (subscriber) {
- this._throwIfClosed();
- this._checkFinalizedStatuses(subscriber);
- return this._innerSubscribe(subscriber);
- };
- Subject.prototype._innerSubscribe = function (subscriber) {
- var _this = this;
- var _a = this, hasError = _a.hasError, isStopped = _a.isStopped, observers = _a.observers;
- if (hasError || isStopped) {
- return Subscription/* EMPTY_SUBSCRIPTION */.Lc;
- }
- this.currentObservers = null;
- observers.push(subscriber);
- return new Subscription/* Subscription */.w0(function () {
- _this.currentObservers = null;
- (0,arrRemove/* arrRemove */.P)(observers, subscriber);
- });
+ }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
+ return this;
+ }), define(Gp, "toString", function () {
+ return "[object Generator]";
+ }), exports.keys = function (object) {
+ var keys = [];
+
+ for (var key in object) {
+ keys.push(key);
+ }
+
+ return keys.reverse(), function next() {
+ for (; keys.length;) {
+ var key = keys.pop();
+ if (key in object) return next.value = key, next.done = !1, next;
+ }
+
+ return next.done = !0, next;
};
- Subject.prototype._checkFinalizedStatuses = function (subscriber) {
- var _a = this, hasError = _a.hasError, thrownError = _a.thrownError, isStopped = _a.isStopped;
- if (hasError) {
- subscriber.error(thrownError);
- }
- else if (isStopped) {
- subscriber.complete();
+ }, exports.values = values, Context.prototype = {
+ constructor: Context,
+ reset: function reset(skipTempReset) {
+ if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) {
+ "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);
+ }
+ },
+ stop: function stop() {
+ this.done = !0;
+ var rootRecord = this.tryEntries[0].completion;
+ if ("throw" === rootRecord.type) throw rootRecord.arg;
+ return this.rval;
+ },
+ dispatchException: function dispatchException(exception) {
+ if (this.done) throw exception;
+ var context = this;
+
+ function handle(loc, caught) {
+ return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
+ }
+
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i],
+ record = entry.completion;
+ if ("root" === entry.tryLoc) return handle("end");
+
+ if (entry.tryLoc <= this.prev) {
+ var hasCatch = hasOwn.call(entry, "catchLoc"),
+ hasFinally = hasOwn.call(entry, "finallyLoc");
+
+ if (hasCatch && hasFinally) {
+ if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
+ if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
+ } else if (hasCatch) {
+ if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
+ } else {
+ if (!hasFinally) throw new Error("try statement without catch or finally");
+ if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
+ }
}
- };
- Subject.prototype.asObservable = function () {
- var observable = new Observable/* Observable */.y();
- observable.source = this;
- return observable;
- };
- Subject.create = function (destination, source) {
- return new AnonymousSubject(destination, source);
- };
- return Subject;
-}(Observable/* Observable */.y));
-
-var AnonymousSubject = (function (_super) {
- (0,tslib_es6/* __extends */.ZT)(AnonymousSubject, _super);
- function AnonymousSubject(destination, source) {
- var _this = _super.call(this) || this;
- _this.destination = destination;
- _this.source = source;
- return _this;
- }
- AnonymousSubject.prototype.next = function (value) {
- var _a, _b;
- (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.next) === null || _b === void 0 ? void 0 : _b.call(_a, value);
- };
- AnonymousSubject.prototype.error = function (err) {
- var _a, _b;
- (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, err);
- };
- AnonymousSubject.prototype.complete = function () {
- var _a, _b;
- (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.complete) === null || _b === void 0 ? void 0 : _b.call(_a);
- };
- AnonymousSubject.prototype._subscribe = function (subscriber) {
- var _a, _b;
- return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber)) !== null && _b !== void 0 ? _b : Subscription/* EMPTY_SUBSCRIPTION */.Lc;
- };
- return AnonymousSubject;
-}(Subject));
+ }
+ },
+ abrupt: function abrupt(type, arg) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
-//# sourceMappingURL=Subject.js.map
+ if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
+ var finallyEntry = entry;
+ break;
+ }
+ }
-/***/ }),
+ finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
+ var record = finallyEntry ? finallyEntry.completion : {};
+ return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
+ },
+ complete: function complete(record, afterLoc) {
+ if ("throw" === record.type) throw record.arg;
+ return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;
+ },
+ finish: function finish(finallyLoc) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+ if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
+ }
+ },
+ "catch": function _catch(tryLoc) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
-/***/ 6267:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+ if (entry.tryLoc === tryLoc) {
+ var record = entry.completion;
-"use strict";
+ if ("throw" === record.type) {
+ var thrown = record.arg;
+ resetTryEntry(entry);
+ }
-// EXPORTS
-__webpack_require__.d(__webpack_exports__, {
- "Hp": function() { return /* binding */ SafeSubscriber; },
- "Lv": function() { return /* binding */ Subscriber; }
-});
+ return thrown;
+ }
+ }
-// UNUSED EXPORTS: EMPTY_OBSERVER
-
-// EXTERNAL MODULE: ./node_modules/rxjs/node_modules/tslib/tslib.es6.js
-var tslib_es6 = __webpack_require__(5987);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/isFunction.js
-var isFunction = __webpack_require__(8474);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/Subscription.js + 1 modules
-var Subscription = __webpack_require__(5720);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/config.js
-var config = __webpack_require__(3912);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js
-var reportUnhandledError = __webpack_require__(5);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/noop.js
-var noop = __webpack_require__(2967);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/NotificationFactories.js
-var COMPLETE_NOTIFICATION = (function () { return createNotification('C', undefined, undefined); })();
-function errorNotification(error) {
- return createNotification('E', undefined, error);
-}
-function nextNotification(value) {
- return createNotification('N', value, undefined);
-}
-function createNotification(kind, value, error) {
- return {
- kind: kind,
- value: value,
- error: error,
- };
+ throw new Error("illegal catch attempt");
+ },
+ delegateYield: function delegateYield(iterable, resultName, nextLoc) {
+ return this.delegate = {
+ iterator: values(iterable),
+ resultName: resultName,
+ nextLoc: nextLoc
+ }, "next" === this.method && (this.arg = undefined), ContinueSentinel;
+ }
+ }, exports;
}
-//# sourceMappingURL=NotificationFactories.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js
-var timeoutProvider = __webpack_require__(8380);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/errorContext.js
-var errorContext = __webpack_require__(8846);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/Subscriber.js
+module.exports = _regeneratorRuntime, module.exports.__esModule = true, module.exports["default"] = module.exports;
+/***/ }),
+/***/ 8698:
+/***/ (function(module) {
+function _typeof(obj) {
+ "@babel/helpers - typeof";
+ return (module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
+ return typeof obj;
+ } : function (obj) {
+ return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+ }, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(obj);
+}
+module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports;
+/***/ }),
+/***/ 4687:
+/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
-var Subscriber = (function (_super) {
- (0,tslib_es6/* __extends */.ZT)(Subscriber, _super);
- function Subscriber(destination) {
- var _this = _super.call(this) || this;
- _this.isStopped = false;
- if (destination) {
- _this.destination = destination;
- if ((0,Subscription/* isSubscription */.Nn)(destination)) {
- destination.add(_this);
- }
- }
- else {
- _this.destination = EMPTY_OBSERVER;
- }
- return _this;
- }
- Subscriber.create = function (next, error, complete) {
- return new SafeSubscriber(next, error, complete);
- };
- Subscriber.prototype.next = function (value) {
- if (this.isStopped) {
- handleStoppedNotification(nextNotification(value), this);
- }
- else {
- this._next(value);
- }
- };
- Subscriber.prototype.error = function (err) {
- if (this.isStopped) {
- handleStoppedNotification(errorNotification(err), this);
- }
- else {
- this.isStopped = true;
- this._error(err);
- }
- };
- Subscriber.prototype.complete = function () {
- if (this.isStopped) {
- handleStoppedNotification(COMPLETE_NOTIFICATION, this);
- }
- else {
- this.isStopped = true;
- this._complete();
- }
- };
- Subscriber.prototype.unsubscribe = function () {
- if (!this.closed) {
- this.isStopped = true;
- _super.prototype.unsubscribe.call(this);
- this.destination = null;
- }
- };
- Subscriber.prototype._next = function (value) {
- this.destination.next(value);
- };
- Subscriber.prototype._error = function (err) {
- try {
- this.destination.error(err);
- }
- finally {
- this.unsubscribe();
- }
- };
- Subscriber.prototype._complete = function () {
- try {
- this.destination.complete();
- }
- finally {
- this.unsubscribe();
- }
- };
- return Subscriber;
-}(Subscription/* Subscription */.w0));
-
-var _bind = Function.prototype.bind;
-function bind(fn, thisArg) {
- return _bind.call(fn, thisArg);
-}
-var ConsumerObserver = (function () {
- function ConsumerObserver(partialObserver) {
- this.partialObserver = partialObserver;
- }
- ConsumerObserver.prototype.next = function (value) {
- var partialObserver = this.partialObserver;
- if (partialObserver.next) {
- try {
- partialObserver.next(value);
- }
- catch (error) {
- handleUnhandledError(error);
- }
- }
- };
- ConsumerObserver.prototype.error = function (err) {
- var partialObserver = this.partialObserver;
- if (partialObserver.error) {
- try {
- partialObserver.error(err);
- }
- catch (error) {
- handleUnhandledError(error);
- }
- }
- else {
- handleUnhandledError(err);
- }
- };
- ConsumerObserver.prototype.complete = function () {
- var partialObserver = this.partialObserver;
- if (partialObserver.complete) {
- try {
- partialObserver.complete();
- }
- catch (error) {
- handleUnhandledError(error);
- }
- }
- };
- return ConsumerObserver;
-}());
-var SafeSubscriber = (function (_super) {
- (0,tslib_es6/* __extends */.ZT)(SafeSubscriber, _super);
- function SafeSubscriber(observerOrNext, error, complete) {
- var _this = _super.call(this) || this;
- var partialObserver;
- if ((0,isFunction/* isFunction */.m)(observerOrNext) || !observerOrNext) {
- partialObserver = {
- next: (observerOrNext !== null && observerOrNext !== void 0 ? observerOrNext : undefined),
- error: error !== null && error !== void 0 ? error : undefined,
- complete: complete !== null && complete !== void 0 ? complete : undefined,
- };
- }
- else {
- var context_1;
- if (_this && config/* config.useDeprecatedNextContext */.v.useDeprecatedNextContext) {
- context_1 = Object.create(observerOrNext);
- context_1.unsubscribe = function () { return _this.unsubscribe(); };
- partialObserver = {
- next: observerOrNext.next && bind(observerOrNext.next, context_1),
- error: observerOrNext.error && bind(observerOrNext.error, context_1),
- complete: observerOrNext.complete && bind(observerOrNext.complete, context_1),
- };
- }
- else {
- partialObserver = observerOrNext;
- }
- }
- _this.destination = new ConsumerObserver(partialObserver);
- return _this;
- }
- return SafeSubscriber;
-}(Subscriber));
+// TODO(Babel 8): Remove this file.
-function handleUnhandledError(error) {
- if (config/* config.useDeprecatedSynchronousErrorHandling */.v.useDeprecatedSynchronousErrorHandling) {
- (0,errorContext/* captureError */.O)(error);
- }
- else {
- (0,reportUnhandledError/* reportUnhandledError */.h)(error);
- }
-}
-function defaultErrorHandler(err) {
- throw err;
-}
-function handleStoppedNotification(notification, subscriber) {
- var onStoppedNotification = config/* config.onStoppedNotification */.v.onStoppedNotification;
- onStoppedNotification && timeoutProvider/* timeoutProvider.setTimeout */.z.setTimeout(function () { return onStoppedNotification(notification, subscriber); });
+var runtime = __webpack_require__(7061)();
+module.exports = runtime;
+
+// Copied from https://github.com/facebook/regenerator/blob/main/packages/runtime/runtime.js#L736=
+try {
+ regeneratorRuntime = runtime;
+} catch (accidentalStrictMode) {
+ if (typeof globalThis === "object") {
+ globalThis.regeneratorRuntime = runtime;
+ } else {
+ Function("r", "regeneratorRuntime = r")(runtime);
+ }
}
-var EMPTY_OBSERVER = {
- closed: true,
- next: noop/* noop */.Z,
- error: defaultErrorHandler,
- complete: noop/* noop */.Z,
-};
-//# sourceMappingURL=Subscriber.js.map
+
/***/ }),
-/***/ 5720:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+/***/ 7326:
+/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ "Z": function() { return /* binding */ _assertThisInitialized; }
+/* harmony export */ });
+function _assertThisInitialized(self) {
+ if (self === void 0) {
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+ }
-// EXPORTS
-__webpack_require__.d(__webpack_exports__, {
- "Lc": function() { return /* binding */ EMPTY_SUBSCRIPTION; },
- "w0": function() { return /* binding */ Subscription; },
- "Nn": function() { return /* binding */ isSubscription; }
-});
-
-// EXTERNAL MODULE: ./node_modules/rxjs/node_modules/tslib/tslib.es6.js
-var tslib_es6 = __webpack_require__(5987);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/isFunction.js
-var isFunction = __webpack_require__(8474);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js
-var createErrorClass = __webpack_require__(1819);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js
-
-var UnsubscriptionError = (0,createErrorClass/* createErrorClass */.d)(function (_super) {
- return function UnsubscriptionErrorImpl(errors) {
- _super(this);
- this.message = errors
- ? errors.length + " errors occurred during unsubscription:\n" + errors.map(function (err, i) { return i + 1 + ") " + err.toString(); }).join('\n ')
- : '';
- this.name = 'UnsubscriptionError';
- this.errors = errors;
- };
-});
-//# sourceMappingURL=UnsubscriptionError.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/arrRemove.js
-var arrRemove = __webpack_require__(3699);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/Subscription.js
-
-
-
-
-var Subscription = (function () {
- function Subscription(initialTeardown) {
- this.initialTeardown = initialTeardown;
- this.closed = false;
- this._parentage = null;
- this._finalizers = null;
- }
- Subscription.prototype.unsubscribe = function () {
- var e_1, _a, e_2, _b;
- var errors;
- if (!this.closed) {
- this.closed = true;
- var _parentage = this._parentage;
- if (_parentage) {
- this._parentage = null;
- if (Array.isArray(_parentage)) {
- try {
- for (var _parentage_1 = (0,tslib_es6/* __values */.XA)(_parentage), _parentage_1_1 = _parentage_1.next(); !_parentage_1_1.done; _parentage_1_1 = _parentage_1.next()) {
- var parent_1 = _parentage_1_1.value;
- parent_1.remove(this);
- }
- }
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
- finally {
- try {
- if (_parentage_1_1 && !_parentage_1_1.done && (_a = _parentage_1.return)) _a.call(_parentage_1);
- }
- finally { if (e_1) throw e_1.error; }
- }
- }
- else {
- _parentage.remove(this);
- }
- }
- var initialFinalizer = this.initialTeardown;
- if ((0,isFunction/* isFunction */.m)(initialFinalizer)) {
- try {
- initialFinalizer();
- }
- catch (e) {
- errors = e instanceof UnsubscriptionError ? e.errors : [e];
- }
- }
- var _finalizers = this._finalizers;
- if (_finalizers) {
- this._finalizers = null;
- try {
- for (var _finalizers_1 = (0,tslib_es6/* __values */.XA)(_finalizers), _finalizers_1_1 = _finalizers_1.next(); !_finalizers_1_1.done; _finalizers_1_1 = _finalizers_1.next()) {
- var finalizer = _finalizers_1_1.value;
- try {
- execFinalizer(finalizer);
- }
- catch (err) {
- errors = errors !== null && errors !== void 0 ? errors : [];
- if (err instanceof UnsubscriptionError) {
- errors = (0,tslib_es6/* __spreadArray */.ev)((0,tslib_es6/* __spreadArray */.ev)([], (0,tslib_es6/* __read */.CR)(errors)), (0,tslib_es6/* __read */.CR)(err.errors));
- }
- else {
- errors.push(err);
- }
- }
- }
- }
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
- finally {
- try {
- if (_finalizers_1_1 && !_finalizers_1_1.done && (_b = _finalizers_1.return)) _b.call(_finalizers_1);
- }
- finally { if (e_2) throw e_2.error; }
- }
- }
- if (errors) {
- throw new UnsubscriptionError(errors);
- }
- }
- };
- Subscription.prototype.add = function (teardown) {
- var _a;
- if (teardown && teardown !== this) {
- if (this.closed) {
- execFinalizer(teardown);
- }
- else {
- if (teardown instanceof Subscription) {
- if (teardown.closed || teardown._hasParent(this)) {
- return;
- }
- teardown._addParent(this);
- }
- (this._finalizers = (_a = this._finalizers) !== null && _a !== void 0 ? _a : []).push(teardown);
- }
- }
- };
- Subscription.prototype._hasParent = function (parent) {
- var _parentage = this._parentage;
- return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));
- };
- Subscription.prototype._addParent = function (parent) {
- var _parentage = this._parentage;
- this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;
- };
- Subscription.prototype._removeParent = function (parent) {
- var _parentage = this._parentage;
- if (_parentage === parent) {
- this._parentage = null;
- }
- else if (Array.isArray(_parentage)) {
- (0,arrRemove/* arrRemove */.P)(_parentage, parent);
- }
- };
- Subscription.prototype.remove = function (teardown) {
- var _finalizers = this._finalizers;
- _finalizers && (0,arrRemove/* arrRemove */.P)(_finalizers, teardown);
- if (teardown instanceof Subscription) {
- teardown._removeParent(this);
- }
- };
- Subscription.EMPTY = (function () {
- var empty = new Subscription();
- empty.closed = true;
- return empty;
- })();
- return Subscription;
-}());
-
-var EMPTY_SUBSCRIPTION = Subscription.EMPTY;
-function isSubscription(value) {
- return (value instanceof Subscription ||
- (value && 'closed' in value && (0,isFunction/* isFunction */.m)(value.remove) && (0,isFunction/* isFunction */.m)(value.add) && (0,isFunction/* isFunction */.m)(value.unsubscribe)));
-}
-function execFinalizer(finalizer) {
- if ((0,isFunction/* isFunction */.m)(finalizer)) {
- finalizer();
- }
- else {
- finalizer.unsubscribe();
- }
+ return self;
}
-//# sourceMappingURL=Subscription.js.map
/***/ }),
-/***/ 3912:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+/***/ 5861:
+/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "v": function() { return /* binding */ config; }
+/* harmony export */ "Z": function() { return /* binding */ _asyncToGenerator; }
/* harmony export */ });
-var config = {
- onUnhandledError: null,
- onStoppedNotification: null,
- Promise: undefined,
- useDeprecatedSynchronousErrorHandling: false,
- useDeprecatedNextContext: false,
-};
-//# sourceMappingURL=config.js.map
-
-/***/ }),
+function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
+ try {
+ var info = gen[key](arg);
+ var value = info.value;
+ } catch (error) {
+ reject(error);
+ return;
+ }
-/***/ 2034:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+ if (info.done) {
+ resolve(value);
+ } else {
+ Promise.resolve(value).then(_next, _throw);
+ }
+}
-"use strict";
+function _asyncToGenerator(fn) {
+ return function () {
+ var self = this,
+ args = arguments;
+ return new Promise(function (resolve, reject) {
+ var gen = fn.apply(self, args);
-// EXPORTS
-__webpack_require__.d(__webpack_exports__, {
- "z": function() { return /* binding */ concat; }
-});
+ function _next(value) {
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
+ }
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/mergeAll.js
-var mergeAll = __webpack_require__(4367);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/concatAll.js
+ function _throw(err) {
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
+ }
-function concatAll() {
- return (0,mergeAll/* mergeAll */.J)(1);
+ _next(undefined);
+ });
+ };
}
-//# sourceMappingURL=concatAll.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/args.js
-var util_args = __webpack_require__(2457);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/from.js + 8 modules
-var from = __webpack_require__(3102);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/concat.js
+/***/ }),
+/***/ 3144:
+/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
-function concat() {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- return concatAll()((0,from/* from */.D)(args, (0,util_args/* popScheduler */.yG)(args)));
+"use strict";
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ "Z": function() { return /* binding */ _createClass; }
+/* harmony export */ });
+function _defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ("value" in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+}
+
+function _createClass(Constructor, protoProps, staticProps) {
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) _defineProperties(Constructor, staticProps);
+ Object.defineProperty(Constructor, "prototype", {
+ writable: false
+ });
+ return Constructor;
}
-//# sourceMappingURL=concat.js.map
/***/ }),
-/***/ 9917:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+/***/ 4578:
+/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "P": function() { return /* binding */ defer; }
+/* harmony export */ "Z": function() { return /* binding */ _inheritsLoose; }
/* harmony export */ });
-/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1480);
-/* harmony import */ var _innerFrom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7878);
-
+/* harmony import */ var _setPrototypeOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9611);
-function defer(observableFactory) {
- return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) {
- (0,_innerFrom__WEBPACK_IMPORTED_MODULE_1__/* .innerFrom */ .Xf)(observableFactory()).subscribe(subscriber);
- });
+function _inheritsLoose(subClass, superClass) {
+ subClass.prototype = Object.create(superClass.prototype);
+ subClass.prototype.constructor = subClass;
+ (0,_setPrototypeOf_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(subClass, superClass);
}
-//# sourceMappingURL=defer.js.map
/***/ }),
-/***/ 1545:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+/***/ 9611:
+/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "E": function() { return /* binding */ EMPTY; }
+/* harmony export */ "Z": function() { return /* binding */ _setPrototypeOf; }
/* harmony export */ });
-/* unused harmony export empty */
-/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1480);
-
-var EMPTY = new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) { return subscriber.complete(); });
-function empty(scheduler) {
- return scheduler ? emptyScheduled(scheduler) : EMPTY;
-}
-function emptyScheduled(scheduler) {
- return new Observable(function (subscriber) { return scheduler.schedule(function () { return subscriber.complete(); }); });
+function _setPrototypeOf(o, p) {
+ _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
+ o.__proto__ = p;
+ return o;
+ };
+ return _setPrototypeOf(o, p);
}
-//# sourceMappingURL=empty.js.map
/***/ }),
-/***/ 3102:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+/***/ 2146:
+/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
// EXPORTS
__webpack_require__.d(__webpack_exports__, {
- "D": function() { return /* binding */ from; }
+ "Z": function() { return /* binding */ _wrapNativeSuper; }
});
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/innerFrom.js
-var innerFrom = __webpack_require__(7878);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/executeSchedule.js
-var executeSchedule = __webpack_require__(7845);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/lift.js
-var lift = __webpack_require__(6798);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/OperatorSubscriber.js
-var OperatorSubscriber = __webpack_require__(2566);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/observeOn.js
-
-
-
-function observeOn(scheduler, delay) {
- if (delay === void 0) { delay = 0; }
- return (0,lift/* operate */.e)(function (source, subscriber) {
- source.subscribe((0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, function (value) { return (0,executeSchedule/* executeSchedule */.f)(subscriber, scheduler, function () { return subscriber.next(value); }, delay); }, function () { return (0,executeSchedule/* executeSchedule */.f)(subscriber, scheduler, function () { return subscriber.complete(); }, delay); }, function (err) { return (0,executeSchedule/* executeSchedule */.f)(subscriber, scheduler, function () { return subscriber.error(err); }, delay); }));
- });
-}
-//# sourceMappingURL=observeOn.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/subscribeOn.js
-var subscribeOn = __webpack_require__(8720);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduled/scheduleObservable.js
-
-
-
-function scheduleObservable(input, scheduler) {
- return (0,innerFrom/* innerFrom */.Xf)(input).pipe((0,subscribeOn/* subscribeOn */.R)(scheduler), observeOn(scheduler));
-}
-//# sourceMappingURL=scheduleObservable.js.map
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduled/schedulePromise.js
-
-
-
-function schedulePromise(input, scheduler) {
- return (0,innerFrom/* innerFrom */.Xf)(input).pipe((0,subscribeOn/* subscribeOn */.R)(scheduler), observeOn(scheduler));
+;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js
+function _getPrototypeOf(o) {
+ _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
+ return o.__proto__ || Object.getPrototypeOf(o);
+ };
+ return _getPrototypeOf(o);
}
-//# sourceMappingURL=schedulePromise.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/Observable.js + 1 modules
-var Observable = __webpack_require__(1480);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduled/scheduleArray.js
-
-function scheduleArray(input, scheduler) {
- return new Observable/* Observable */.y(function (subscriber) {
- var i = 0;
- return scheduler.schedule(function () {
- if (i === input.length) {
- subscriber.complete();
- }
- else {
- subscriber.next(input[i++]);
- if (!subscriber.closed) {
- this.schedule();
- }
- }
- });
- });
+// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js
+var setPrototypeOf = __webpack_require__(9611);
+;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/isNativeFunction.js
+function _isNativeFunction(fn) {
+ return Function.toString.call(fn).indexOf("[native code]") !== -1;
}
-//# sourceMappingURL=scheduleArray.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/symbol/iterator.js
-var symbol_iterator = __webpack_require__(9768);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/isFunction.js
-var isFunction = __webpack_require__(8474);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduled/scheduleIterable.js
-
-
-
+;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js
+function _isNativeReflectConstruct() {
+ if (typeof Reflect === "undefined" || !Reflect.construct) return false;
+ if (Reflect.construct.sham) return false;
+ if (typeof Proxy === "function") return true;
-function scheduleIterable(input, scheduler) {
- return new Observable/* Observable */.y(function (subscriber) {
- var iterator;
- (0,executeSchedule/* executeSchedule */.f)(subscriber, scheduler, function () {
- iterator = input[symbol_iterator/* iterator */.h]();
- (0,executeSchedule/* executeSchedule */.f)(subscriber, scheduler, function () {
- var _a;
- var value;
- var done;
- try {
- (_a = iterator.next(), value = _a.value, done = _a.done);
- }
- catch (err) {
- subscriber.error(err);
- return;
- }
- if (done) {
- subscriber.complete();
- }
- else {
- subscriber.next(value);
- }
- }, 0, true);
- });
- return function () { return (0,isFunction/* isFunction */.m)(iterator === null || iterator === void 0 ? void 0 : iterator.return) && iterator.return(); };
- });
+ try {
+ Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
+ return true;
+ } catch (e) {
+ return false;
+ }
}
-//# sourceMappingURL=scheduleIterable.js.map
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduled/scheduleAsyncIterable.js
-
+;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/construct.js
-function scheduleAsyncIterable(input, scheduler) {
- if (!input) {
- throw new Error('Iterable cannot be null');
- }
- return new Observable/* Observable */.y(function (subscriber) {
- (0,executeSchedule/* executeSchedule */.f)(subscriber, scheduler, function () {
- var iterator = input[Symbol.asyncIterator]();
- (0,executeSchedule/* executeSchedule */.f)(subscriber, scheduler, function () {
- iterator.next().then(function (result) {
- if (result.done) {
- subscriber.complete();
- }
- else {
- subscriber.next(result.value);
- }
- });
- }, 0, true);
- });
- });
-}
-//# sourceMappingURL=scheduleAsyncIterable.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/isInteropObservable.js
-var isInteropObservable = __webpack_require__(1764);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/isPromise.js
-var isPromise = __webpack_require__(3841);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/isArrayLike.js
-var isArrayLike = __webpack_require__(5685);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/isIterable.js
-var isIterable = __webpack_require__(1837);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/isAsyncIterable.js
-var isAsyncIterable = __webpack_require__(8430);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/throwUnobservableError.js
-var throwUnobservableError = __webpack_require__(8729);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/isReadableStreamLike.js
-var isReadableStreamLike = __webpack_require__(8671);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduled/scheduleReadableStreamLike.js
+function _construct(Parent, args, Class) {
+ if (_isNativeReflectConstruct()) {
+ _construct = Reflect.construct.bind();
+ } else {
+ _construct = function _construct(Parent, args, Class) {
+ var a = [null];
+ a.push.apply(a, args);
+ var Constructor = Function.bind.apply(Parent, a);
+ var instance = new Constructor();
+ if (Class) (0,setPrototypeOf/* default */.Z)(instance, Class.prototype);
+ return instance;
+ };
+ }
-function scheduleReadableStreamLike(input, scheduler) {
- return scheduleAsyncIterable((0,isReadableStreamLike/* readableStreamLikeToAsyncGenerator */.Q)(input), scheduler);
+ return _construct.apply(null, arguments);
}
-//# sourceMappingURL=scheduleReadableStreamLike.js.map
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduled/scheduled.js
-
-
-
-
+;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js
+function _wrapNativeSuper(Class) {
+ var _cache = typeof Map === "function" ? new Map() : undefined;
+ _wrapNativeSuper = function _wrapNativeSuper(Class) {
+ if (Class === null || !_isNativeFunction(Class)) return Class;
+ if (typeof Class !== "function") {
+ throw new TypeError("Super expression must either be null or a function");
+ }
+ if (typeof _cache !== "undefined") {
+ if (_cache.has(Class)) return _cache.get(Class);
+ _cache.set(Class, Wrapper);
+ }
-function scheduled(input, scheduler) {
- if (input != null) {
- if ((0,isInteropObservable/* isInteropObservable */.c)(input)) {
- return scheduleObservable(input, scheduler);
- }
- if ((0,isArrayLike/* isArrayLike */.z)(input)) {
- return scheduleArray(input, scheduler);
- }
- if ((0,isPromise/* isPromise */.t)(input)) {
- return schedulePromise(input, scheduler);
- }
- if ((0,isAsyncIterable/* isAsyncIterable */.D)(input)) {
- return scheduleAsyncIterable(input, scheduler);
- }
- if ((0,isIterable/* isIterable */.T)(input)) {
- return scheduleIterable(input, scheduler);
- }
- if ((0,isReadableStreamLike/* isReadableStreamLike */.L)(input)) {
- return scheduleReadableStreamLike(input, scheduler);
- }
+ function Wrapper() {
+ return _construct(Class, arguments, _getPrototypeOf(this).constructor);
}
- throw (0,throwUnobservableError/* createInvalidObservableTypeError */.z)(input);
-}
-//# sourceMappingURL=scheduled.js.map
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/from.js
+ Wrapper.prototype = Object.create(Class.prototype, {
+ constructor: {
+ value: Wrapper,
+ enumerable: false,
+ writable: true,
+ configurable: true
+ }
+ });
+ return (0,setPrototypeOf/* default */.Z)(Wrapper, Class);
+ };
-function from(input, scheduler) {
- return scheduler ? scheduled(input, scheduler) : (0,innerFrom/* innerFrom */.Xf)(input);
+ return _wrapNativeSuper(Class);
}
-//# sourceMappingURL=from.js.map
-/***/ }),
-
-/***/ 2401:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+/***/ })
+/******/ });
+/************************************************************************/
+/******/ // The module cache
+/******/ var __webpack_module_cache__ = {};
+/******/
+/******/ // The require function
+/******/ function __webpack_require__(moduleId) {
+/******/ // Check if module is in cache
+/******/ var cachedModule = __webpack_module_cache__[moduleId];
+/******/ if (cachedModule !== undefined) {
+/******/ return cachedModule.exports;
+/******/ }
+/******/ // Create a new module (and put it into the cache)
+/******/ var module = __webpack_module_cache__[moduleId] = {
+/******/ // no module.id needed
+/******/ // no module.loaded needed
+/******/ exports: {}
+/******/ };
+/******/
+/******/ // Execute the module function
+/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
+/******/
+/******/ // Return the exports of the module
+/******/ return module.exports;
+/******/ }
+/******/
+/************************************************************************/
+/******/ /* webpack/runtime/compat get default export */
+/******/ !function() {
+/******/ // getDefaultExport function for compatibility with non-harmony modules
+/******/ __webpack_require__.n = function(module) {
+/******/ var getter = module && module.__esModule ?
+/******/ function() { return module['default']; } :
+/******/ function() { return module; };
+/******/ __webpack_require__.d(getter, { a: getter });
+/******/ return getter;
+/******/ };
+/******/ }();
+/******/
+/******/ /* webpack/runtime/define property getters */
+/******/ !function() {
+/******/ // define getter functions for harmony exports
+/******/ __webpack_require__.d = function(exports, definition) {
+/******/ for(var key in definition) {
+/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
+/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
+/******/ }
+/******/ }
+/******/ };
+/******/ }();
+/******/
+/******/ /* webpack/runtime/hasOwnProperty shorthand */
+/******/ !function() {
+/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
+/******/ }();
+/******/
+/************************************************************************/
+var __webpack_exports__ = {};
+// This entry need to be wrapped in an IIFE because it need to be in strict mode.
+!function() {
"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "R": function() { return /* binding */ fromEvent; }
-/* harmony export */ });
-/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5987);
-/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7878);
-/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1480);
-/* harmony import */ var _operators_mergeMap__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7877);
-/* harmony import */ var _util_isArrayLike__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5685);
-/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8474);
-/* harmony import */ var _util_mapOneOrManyArgs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3211);
-
-
-
-
-
+// EXPORTS
+__webpack_require__.d(__webpack_exports__, {
+ "default": function() { return /* binding */ src; }
+});
-var nodeEventEmitterMethods = ['addListener', 'removeListener'];
-var eventTargetMethods = ['addEventListener', 'removeEventListener'];
-var jqueryMethods = ['on', 'off'];
-function fromEvent(target, eventName, options, resultSelector) {
- if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(options)) {
- resultSelector = options;
- options = undefined;
- }
- if (resultSelector) {
- return fromEvent(target, eventName, options).pipe((0,_util_mapOneOrManyArgs__WEBPACK_IMPORTED_MODULE_1__/* .mapOneOrManyArgs */ .Z)(resultSelector));
- }
- var _a = (0,tslib__WEBPACK_IMPORTED_MODULE_2__/* .__read */ .CR)(isEventTarget(target)
- ? eventTargetMethods.map(function (methodName) { return function (handler) { return target[methodName](eventName, handler, options); }; })
- :
- isNodeStyleEventEmitter(target)
- ? nodeEventEmitterMethods.map(toCommonHandlerRegistry(target, eventName))
- : isJQueryStyleEventEmitter(target)
- ? jqueryMethods.map(toCommonHandlerRegistry(target, eventName))
- : [], 2), add = _a[0], remove = _a[1];
- if (!add) {
- if ((0,_util_isArrayLike__WEBPACK_IMPORTED_MODULE_3__/* .isArrayLike */ .z)(target)) {
- return (0,_operators_mergeMap__WEBPACK_IMPORTED_MODULE_4__/* .mergeMap */ .z)(function (subTarget) { return fromEvent(subTarget, eventName, options); })((0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_5__/* .innerFrom */ .Xf)(target));
- }
- }
- if (!add) {
- throw new TypeError('Invalid event target');
+// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/createClass.js
+var createClass = __webpack_require__(3144);
+// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js
+var inheritsLoose = __webpack_require__(4578);
+// EXTERNAL MODULE: ./src/compat/event_listeners.ts
+var event_listeners = __webpack_require__(3038);
+;// CONCATENATED MODULE: ./src/compat/get_start_date.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Calculating a live-offseted media position necessitate to obtain first an
+ * offset, and then adding that offset to the wanted position.
+ *
+ * That offset is in most case present inside the Manifest file, yet in cases
+ * without it or without a Manifest, such as the "directfile" mode, the RxPlayer
+ * won't know that offset.
+ *
+ * Thankfully Safari declares a `getStartDate` method allowing to obtain that
+ * offset when available. This logic is mainly useful when playing HLS contents
+ * in directfile mode on Safari.
+ * @param {HTMLMediaElement} mediaElement
+ * @returns {number|undefined}
+ */
+function getStartDate(mediaElement) {
+ var _mediaElement = mediaElement;
+ if (typeof _mediaElement.getStartDate === "function") {
+ var startDate = _mediaElement.getStartDate();
+ if (typeof startDate === "object" && startDate !== null) {
+ var startDateNum = +startDate;
+ if (!isNaN(startDateNum)) {
+ return startDateNum / 1000;
+ }
+ } else if (typeof startDate === "number" && !isNaN(startDate)) {
+ return startDate;
}
- return new _Observable__WEBPACK_IMPORTED_MODULE_6__/* .Observable */ .y(function (subscriber) {
- var handler = function () {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- return subscriber.next(1 < args.length ? args : args[0]);
- };
- add(handler);
- return function () { return remove(handler); };
- });
-}
-function toCommonHandlerRegistry(target, eventName) {
- return function (methodName) { return function (handler) { return target[methodName](eventName, handler); }; };
+ }
}
-function isNodeStyleEventEmitter(target) {
- return (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(target.addListener) && (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(target.removeListener);
+;// CONCATENATED MODULE: ./src/compat/fullscreen.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Request fullScreen action on a given element.
+ * @param {HTMLElement} elt
+ */
+function requestFullscreen(element) {
+ if (!fullscreen_isFullscreen()) {
+ var elt = element;
+ /* eslint-disable @typescript-eslint/unbound-method */
+ if (typeof elt.requestFullscreen === "function") {
+ /* eslint-enable @typescript-eslint/unbound-method */
+ /* eslint-disable @typescript-eslint/no-floating-promises */
+ elt.requestFullscreen();
+ /* eslint-enable @typescript-eslint/no-floating-promises */
+ } else if (typeof elt.msRequestFullscreen === "function") {
+ elt.msRequestFullscreen();
+ } else if (typeof elt.mozRequestFullScreen === "function") {
+ elt.mozRequestFullScreen();
+ } else if (typeof elt.webkitRequestFullscreen === "function") {
+ elt.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
+ }
+ }
}
-function isJQueryStyleEventEmitter(target) {
- return (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(target.on) && (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(target.off);
+/**
+ * Exit fullscreen if an element is currently in fullscreen.
+ */
+function fullscreen_exitFullscreen() {
+ if (fullscreen_isFullscreen()) {
+ var doc = document;
+ /* eslint-disable @typescript-eslint/unbound-method */
+ if (typeof doc.exitFullscreen === "function") {
+ /* eslint-enable @typescript-eslint/unbound-method */
+ /* eslint-disable @typescript-eslint/no-floating-promises */
+ doc.exitFullscreen();
+ /* eslint-enable @typescript-eslint/no-floating-promises */
+ } else if (typeof doc.msExitFullscreen === "function") {
+ doc.msExitFullscreen();
+ } else if (typeof doc.mozCancelFullScreen === "function") {
+ doc.mozCancelFullScreen();
+ } else if (typeof doc.webkitExitFullscreen === "function") {
+ doc.webkitExitFullscreen();
+ }
+ }
}
-function isEventTarget(target) {
- return (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(target.addEventListener) && (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(target.removeEventListener);
+/**
+ * Returns true if an element in the document is being displayed in fullscreen
+ * mode;
+ * otherwise it's false.
+ * @returns {boolean}
+ */
+function fullscreen_isFullscreen() {
+ var doc = document;
+ return doc.fullscreenElement != null || doc.mozFullScreenElement != null || doc.webkitFullscreenElement != null || doc.msFullscreenElement != null;
}
-//# sourceMappingURL=fromEvent.js.map
-
-/***/ }),
-
-/***/ 7878:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "Xf": function() { return /* binding */ innerFrom; }
-/* harmony export */ });
-/* unused harmony exports fromInteropObservable, fromArrayLike, fromPromise, fromIterable, fromAsyncIterable, fromReadableStreamLike */
-/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(5987);
-/* harmony import */ var _util_isArrayLike__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5685);
-/* harmony import */ var _util_isPromise__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3841);
-/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1480);
-/* harmony import */ var _util_isInteropObservable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1764);
-/* harmony import */ var _util_isAsyncIterable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8430);
-/* harmony import */ var _util_throwUnobservableError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(8729);
-/* harmony import */ var _util_isIterable__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1837);
-/* harmony import */ var _util_isReadableStreamLike__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(8671);
-/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(8474);
-/* harmony import */ var _util_reportUnhandledError__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(5);
-/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(6766);
-
+// EXTERNAL MODULE: ./src/compat/browser_detection.ts
+var browser_detection = __webpack_require__(3666);
+// EXTERNAL MODULE: ./src/log.ts + 1 modules
+var log = __webpack_require__(3887);
+;// CONCATENATED MODULE: ./src/compat/browser_version.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Returns either :
+ * - 'null' when the current browser is not Firefox.
+ * - '-1' when it is impossible to get the Firefox version
+ * - A number above 0 that is the Firefox version number
+ * @returns {number|null}
+ */
+function getFirefoxVersion() {
+ if (!browser_detection/* isFirefox */.vU) {
+ log/* default.warn */.Z.warn("Compat: Can't access Firefox version on no firefox browser.");
+ return null;
+ }
+ var userAgent = navigator.userAgent;
+ var match = /Firefox\/([0-9]+)\./.exec(userAgent);
+ if (match === null) {
+ return -1;
+ }
+ var result = parseInt(match[1], 10);
+ if (isNaN(result)) {
+ return -1;
+ }
+ return result;
+}
+;// CONCATENATED MODULE: ./src/compat/can_rely_on_video_visibility_and_size.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * This functions tells if the RxPlayer can trust on any browser data
+ * about video element visibility and size.
+ *
+ * On Firefox (version >= 67) :
+ * - The PIP feature exists but can be disabled by default according
+ * to the OS and the channel used for updating / getting Firefox binaries.
+ * - There is no API to know if the Picture-in-picture (PIP) is enabled
+ * - There is no API to get the width of the PIP window
+ *
+ * The element clientWidth tells the width of the original video element, and
+ * no PIP window API exists to determine its presence or width. Thus, there are
+ * no way to determine the real width of the video window, as we can't know when
+ * the PIP feature or window is enabled, and we can't have access to the windo
+ * size information.
+ *
+ * Moreover, when the document is considered as hidden (e.g. in case of hidden
+ * tab), as there is no way to know if the PIP feature or window is enabled,
+ * we can't know if the video window is visible or not.
+ * @returns {boolean}
+ */
+function canRelyOnVideoVisibilityAndSize() {
+ if (!browser_detection/* isFirefox */.vU) {
+ return true;
+ }
+ var firefoxVersion = getFirefoxVersion();
+ if (firefoxVersion === null || firefoxVersion < 67) {
+ return true;
+ }
+ var proto = HTMLVideoElement === null || HTMLVideoElement === void 0 ? void 0 : HTMLVideoElement.prototype;
+ return (proto === null || proto === void 0 ? void 0 : proto.requirePictureInPicture) !== undefined;
+}
+// EXTERNAL MODULE: ./src/config.ts + 2 modules
+var config = __webpack_require__(6872);
+// EXTERNAL MODULE: ./src/errors/format_error.ts
+var format_error = __webpack_require__(8750);
+// EXTERNAL MODULE: ./src/errors/media_error.ts
+var media_error = __webpack_require__(3714);
+// EXTERNAL MODULE: ./src/errors/error_codes.ts
+var error_codes = __webpack_require__(5992);
+// EXTERNAL MODULE: ./src/features/index.ts
+var features = __webpack_require__(7874);
+// EXTERNAL MODULE: ./src/utils/are_arrays_of_numbers_equal.ts
+var are_arrays_of_numbers_equal = __webpack_require__(4791);
+// EXTERNAL MODULE: ./src/utils/assert.ts
+var assert = __webpack_require__(811);
+// EXTERNAL MODULE: ./src/utils/event_emitter.ts
+var event_emitter = __webpack_require__(1959);
+// EXTERNAL MODULE: ./src/utils/id_generator.ts
+var id_generator = __webpack_require__(908);
+// EXTERNAL MODULE: ./src/utils/is_null_or_undefined.ts
+var is_null_or_undefined = __webpack_require__(1946);
+// EXTERNAL MODULE: ./src/utils/object_assign.ts
+var object_assign = __webpack_require__(8026);
+// EXTERNAL MODULE: ./src/utils/ranges.ts
+var ranges = __webpack_require__(2829);
+// EXTERNAL MODULE: ./src/utils/reference.ts
+var reference = __webpack_require__(5095);
+// EXTERNAL MODULE: ./src/utils/task_canceller.ts
+var task_canceller = __webpack_require__(288);
+// EXTERNAL MODULE: ./src/utils/warn_once.ts
+var warn_once = __webpack_require__(8806);
+// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js
+var asyncToGenerator = __webpack_require__(5861);
+// EXTERNAL MODULE: ./node_modules/@babel/runtime/regenerator/index.js
+var regenerator = __webpack_require__(4687);
+var regenerator_default = /*#__PURE__*/__webpack_require__.n(regenerator);
+// EXTERNAL MODULE: ./src/compat/eme/custom_media_keys/index.ts + 7 modules
+var custom_media_keys = __webpack_require__(6139);
+// EXTERNAL MODULE: ./src/core/decrypt/utils/media_keys_infos_store.ts
+var media_keys_infos_store = __webpack_require__(770);
+;// CONCATENATED MODULE: ./src/core/decrypt/dispose_decryption_resources.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
-function innerFrom(input) {
- if (input instanceof _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y) {
- return input;
- }
- if (input != null) {
- if ((0,_util_isInteropObservable__WEBPACK_IMPORTED_MODULE_1__/* .isInteropObservable */ .c)(input)) {
- return fromInteropObservable(input);
- }
- if ((0,_util_isArrayLike__WEBPACK_IMPORTED_MODULE_2__/* .isArrayLike */ .z)(input)) {
- return fromArrayLike(input);
- }
- if ((0,_util_isPromise__WEBPACK_IMPORTED_MODULE_3__/* .isPromise */ .t)(input)) {
- return fromPromise(input);
- }
- if ((0,_util_isAsyncIterable__WEBPACK_IMPORTED_MODULE_4__/* .isAsyncIterable */ .D)(input)) {
- return fromAsyncIterable(input);
- }
- if ((0,_util_isIterable__WEBPACK_IMPORTED_MODULE_5__/* .isIterable */ .T)(input)) {
- return fromIterable(input);
- }
- if ((0,_util_isReadableStreamLike__WEBPACK_IMPORTED_MODULE_6__/* .isReadableStreamLike */ .L)(input)) {
- return fromReadableStreamLike(input);
- }
- }
- throw (0,_util_throwUnobservableError__WEBPACK_IMPORTED_MODULE_7__/* .createInvalidObservableTypeError */ .z)(input);
-}
-function fromInteropObservable(obj) {
- return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) {
- var obs = obj[_symbol_observable__WEBPACK_IMPORTED_MODULE_8__/* .observable */ .L]();
- if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_9__/* .isFunction */ .m)(obs.subscribe)) {
- return obs.subscribe(subscriber);
- }
- throw new TypeError('Provided object does not correctly implement Symbol.observable');
- });
-}
-function fromArrayLike(array) {
- return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) {
- for (var i = 0; i < array.length && !subscriber.closed; i++) {
- subscriber.next(array[i]);
- }
- subscriber.complete();
- });
-}
-function fromPromise(promise) {
- return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) {
- promise
- .then(function (value) {
- if (!subscriber.closed) {
- subscriber.next(value);
- subscriber.complete();
- }
- }, function (err) { return subscriber.error(err); })
- .then(null, _util_reportUnhandledError__WEBPACK_IMPORTED_MODULE_10__/* .reportUnhandledError */ .h);
- });
+/**
+ * Free up all ressources taken by the content decryption logic.
+ * @param {HTMLMediaElement} mediaElement
+ * @returns {Promise}
+ */
+function disposeDecryptionResources(_x) {
+ return _disposeDecryptionResources.apply(this, arguments);
}
-function fromIterable(iterable) {
- return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) {
- var e_1, _a;
- try {
- for (var iterable_1 = (0,tslib__WEBPACK_IMPORTED_MODULE_11__/* .__values */ .XA)(iterable), iterable_1_1 = iterable_1.next(); !iterable_1_1.done; iterable_1_1 = iterable_1.next()) {
- var value = iterable_1_1.value;
- subscriber.next(value);
- if (subscriber.closed) {
- return;
- }
- }
- }
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
- finally {
- try {
- if (iterable_1_1 && !iterable_1_1.done && (_a = iterable_1.return)) _a.call(iterable_1);
+function _disposeDecryptionResources() {
+ _disposeDecryptionResources = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(mediaElement) {
+ var currentState, loadedSessionsStore;
+ return regenerator_default().wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ currentState = media_keys_infos_store/* default.getState */.Z.getState(mediaElement);
+ if (!(currentState === null)) {
+ _context.next = 3;
+ break;
}
- finally { if (e_1) throw e_1.error; }
+ return _context.abrupt("return");
+ case 3:
+ log/* default.info */.Z.info("DRM: Disposing of the current MediaKeys");
+ loadedSessionsStore = currentState.loadedSessionsStore;
+ media_keys_infos_store/* default.clearState */.Z.clearState(mediaElement);
+ _context.next = 8;
+ return loadedSessionsStore.closeAllSessions();
+ case 8:
+ (0,custom_media_keys/* setMediaKeys */.Y)(mediaElement, null);
+ case 9:
+ case "end":
+ return _context.stop();
}
- subscriber.complete();
- });
+ }
+ }, _callee);
+ }));
+ return _disposeDecryptionResources.apply(this, arguments);
}
-function fromAsyncIterable(asyncIterable) {
- return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) {
- process(asyncIterable, subscriber).catch(function (err) { return subscriber.error(err); });
- });
+;// CONCATENATED MODULE: ./src/core/decrypt/get_key_system_configuration.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Returns the name of the current key system used as well as its configuration,
+ * as reported by the `MediaKeySystemAccess` itself.
+ * @param {HTMLMediaElement} mediaElement
+ * @returns {Array|null}
+ */
+function get_key_system_configuration_getKeySystemConfiguration(mediaElement) {
+ var currentState = media_keys_infos_store/* default.getState */.Z.getState(mediaElement);
+ if (currentState === null) {
+ return null;
+ }
+ return [currentState.mediaKeySystemAccess.keySystem, currentState.mediaKeySystemAccess.getConfiguration()];
}
-function fromReadableStreamLike(readableStream) {
- return fromAsyncIterable((0,_util_isReadableStreamLike__WEBPACK_IMPORTED_MODULE_6__/* .readableStreamLikeToAsyncGenerator */ .Q)(readableStream));
-}
-function process(asyncIterable, subscriber) {
- var asyncIterable_1, asyncIterable_1_1;
- var e_2, _a;
- return (0,tslib__WEBPACK_IMPORTED_MODULE_11__/* .__awaiter */ .mG)(this, void 0, void 0, function () {
- var value, e_2_1;
- return (0,tslib__WEBPACK_IMPORTED_MODULE_11__/* .__generator */ .Jh)(this, function (_b) {
- switch (_b.label) {
- case 0:
- _b.trys.push([0, 5, 6, 11]);
- asyncIterable_1 = (0,tslib__WEBPACK_IMPORTED_MODULE_11__/* .__asyncValues */ .KL)(asyncIterable);
- _b.label = 1;
- case 1: return [4, asyncIterable_1.next()];
- case 2:
- if (!(asyncIterable_1_1 = _b.sent(), !asyncIterable_1_1.done)) return [3, 4];
- value = asyncIterable_1_1.value;
- subscriber.next(value);
- if (subscriber.closed) {
- return [2];
- }
- _b.label = 3;
- case 3: return [3, 1];
- case 4: return [3, 11];
- case 5:
- e_2_1 = _b.sent();
- e_2 = { error: e_2_1 };
- return [3, 11];
- case 6:
- _b.trys.push([6, , 9, 10]);
- if (!(asyncIterable_1_1 && !asyncIterable_1_1.done && (_a = asyncIterable_1.return))) return [3, 8];
- return [4, _a.call(asyncIterable_1)];
- case 7:
- _b.sent();
- _b.label = 8;
- case 8: return [3, 10];
- case 9:
- if (e_2) throw e_2.error;
- return [7];
- case 10: return [7];
- case 11:
- subscriber.complete();
- return [2];
- }
- });
- });
+/**
+ * Returns the name of the current key system used, as originally indicated by
+ * the user.
+ * @deprecated
+ * @param {HTMLMediaElement} mediaElement
+ * @returns {string|null}
+ */
+function get_key_system_configuration_getCurrentKeySystem(mediaElement) {
+ var currentState = media_keys_infos_store/* default.getState */.Z.getState(mediaElement);
+ return currentState == null ? null : currentState.keySystemOptions.type;
}
-//# sourceMappingURL=innerFrom.js.map
-
-/***/ }),
-
-/***/ 3071:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "T": function() { return /* binding */ merge; }
-/* harmony export */ });
-/* harmony import */ var _operators_mergeAll__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4367);
-/* harmony import */ var _innerFrom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7878);
-/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1545);
-/* harmony import */ var _util_args__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2457);
-/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3102);
-
-
-
-
+;// CONCATENATED MODULE: ./src/compat/should_unset_media_keys.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
-function merge() {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- var scheduler = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__/* .popScheduler */ .yG)(args);
- var concurrent = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__/* .popNumber */ ._6)(args, Infinity);
- var sources = args;
- return !sources.length
- ?
- _empty__WEBPACK_IMPORTED_MODULE_1__/* .EMPTY */ .E
- : sources.length === 1
- ?
- (0,_innerFrom__WEBPACK_IMPORTED_MODULE_2__/* .innerFrom */ .Xf)(sources[0])
- :
- (0,_operators_mergeAll__WEBPACK_IMPORTED_MODULE_3__/* .mergeAll */ .J)(concurrent)((0,_from__WEBPACK_IMPORTED_MODULE_4__/* .from */ .D)(sources, scheduler));
+/**
+ * Returns true if the mediakeys associated to a media element should be
+ * unset once the content is stopped.
+ * Depends on the target.
+ * @returns {Boolean}
+ */
+function shouldUnsetMediaKeys() {
+ return browser_detection/* isIE11 */.fq;
}
-//# sourceMappingURL=merge.js.map
-
-/***/ }),
+;// CONCATENATED MODULE: ./src/core/decrypt/clear_on_stop.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
-/***/ 2817:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "of": function() { return /* binding */ of; }
-/* harmony export */ });
-/* harmony import */ var _util_args__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2457);
-/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3102);
-function of() {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- var scheduler = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__/* .popScheduler */ .yG)(args);
- return (0,_from__WEBPACK_IMPORTED_MODULE_1__/* .from */ .D)(args, scheduler);
+/**
+ * Clear DRM-related resources that should be cleared when the current content
+ * stops its playback.
+ * @param {HTMLMediaElement} mediaElement
+ * @returns {Promise}
+ */
+function clearOnStop(mediaElement) {
+ log/* default.info */.Z.info("DRM: Clearing-up DRM session.");
+ if (shouldUnsetMediaKeys()) {
+ log/* default.info */.Z.info("DRM: disposing current MediaKeys.");
+ return disposeDecryptionResources(mediaElement);
+ }
+ var currentState = media_keys_infos_store/* default.getState */.Z.getState(mediaElement);
+ if (currentState !== null && currentState.keySystemOptions.closeSessionsOnStop === true) {
+ log/* default.info */.Z.info("DRM: closing all current sessions.");
+ return currentState.loadedSessionsStore.closeAllSessions();
+ }
+ log/* default.info */.Z.info("DRM: Nothing to clear. Returning right away. No state =", currentState === null);
+ return Promise.resolve();
}
-//# sourceMappingURL=of.js.map
-
-/***/ }),
-
-/***/ 3610:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "_": function() { return /* binding */ throwError; }
-/* harmony export */ });
-/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1480);
-/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8474);
-
-
-function throwError(errorOrErrorFactory, scheduler) {
- var errorFactory = (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(errorOrErrorFactory) ? errorOrErrorFactory : function () { return errorOrErrorFactory; };
- var init = function (subscriber) { return subscriber.error(errorFactory()); };
- return new _Observable__WEBPACK_IMPORTED_MODULE_1__/* .Observable */ .y(scheduler ? function (subscriber) { return scheduler.schedule(init, 0, subscriber); } : init);
+;// CONCATENATED MODULE: ./src/compat/should_reload_media_source_on_decipherability_update.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Returns true if we have to reload the MediaSource due to an update in the
+ * decipherability status of some segments based on the current key sytem.
+ *
+ * We found that on all Widevine targets tested, a simple seek is sufficient.
+ * As widevine clients make a good chunk of users, we can make a difference
+ * between them and others as it is for the better.
+ * @param {string|undefined} currentKeySystem
+ * @returns {Boolean}
+ */
+function shouldReloadMediaSourceOnDecipherabilityUpdate(currentKeySystem) {
+ return currentKeySystem === undefined || currentKeySystem.indexOf("widevine") < 0;
}
-//# sourceMappingURL=throwError.js.map
-
-/***/ }),
-
-/***/ 6625:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "H": function() { return /* binding */ timer; }
-/* harmony export */ });
-/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1480);
-/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7991);
-/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4865);
-/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1454);
-
-
-
-
-function timer(dueTime, intervalOrScheduler, scheduler) {
- if (dueTime === void 0) { dueTime = 0; }
- if (scheduler === void 0) { scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__/* .async */ .P; }
- var intervalDuration = -1;
- if (intervalOrScheduler != null) {
- if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__/* .isScheduler */ .K)(intervalOrScheduler)) {
- scheduler = intervalOrScheduler;
- }
- else {
- intervalDuration = intervalOrScheduler;
- }
+// EXTERNAL MODULE: ./src/utils/create_cancellable_promise.ts
+var create_cancellable_promise = __webpack_require__(7733);
+// EXTERNAL MODULE: ./src/utils/noop.ts
+var noop = __webpack_require__(8894);
+// EXTERNAL MODULE: ./src/utils/take_first_set.ts
+var take_first_set = __webpack_require__(5278);
+// EXTERNAL MODULE: ./src/utils/array_find_index.ts
+var array_find_index = __webpack_require__(5138);
+;// CONCATENATED MODULE: ./src/core/adaptive/utils/get_buffer_levels.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Return "Buffer Levels" which are steps of available buffers from which we
+ * are normally able switch safely to the next available bitrate.
+ * (Following an algorithm close to BOLA)
+ * @param {Array.} bitrates - All available bitrates, __sorted__ in
+ * ascending order.
+ * @returns {Array.}
+ */
+function getBufferLevels(bitrates) {
+ var logs = bitrates.map(function (b) {
+ return Math.log(b / bitrates[0]);
+ });
+ var utilities = logs.map(function (l) {
+ return l - logs[0] + 1;
+ }); // normalize
+ var gp = (utilities[utilities.length - 1] - 1) / (bitrates.length * 2 + 10);
+ var Vp = 1 / gp;
+ return bitrates.map(function (_, i) {
+ return minBufferLevelForBitrate(i);
+ });
+ /**
+ * Get minimum buffer we should keep ahead to pick this bitrate.
+ * @param {number} index
+ * @returns {number}
+ */
+ function minBufferLevelForBitrate(index) {
+ if (index === 0) {
+ return 0;
}
- return new _Observable__WEBPACK_IMPORTED_MODULE_2__/* .Observable */ .y(function (subscriber) {
- var due = (0,_util_isDate__WEBPACK_IMPORTED_MODULE_3__/* .isValidDate */ .q)(dueTime) ? +dueTime - scheduler.now() : dueTime;
- if (due < 0) {
- due = 0;
- }
- var n = 0;
- return scheduler.schedule(function () {
- if (!subscriber.closed) {
- subscriber.next(n++);
- if (0 <= intervalDuration) {
- this.schedule(undefined, intervalDuration);
- }
- else {
- subscriber.complete();
- }
- }
- }, due);
- });
-}
-//# sourceMappingURL=timer.js.map
-
-/***/ }),
-
-/***/ 2566:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "x": function() { return /* binding */ createOperatorSubscriber; }
-/* harmony export */ });
-/* unused harmony export OperatorSubscriber */
-/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5987);
-/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6267);
-
-
-function createOperatorSubscriber(destination, onNext, onComplete, onError, onFinalize) {
- return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);
-}
-var OperatorSubscriber = (function (_super) {
- (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT)(OperatorSubscriber, _super);
- function OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize, shouldUnsubscribe) {
- var _this = _super.call(this, destination) || this;
- _this.onFinalize = onFinalize;
- _this.shouldUnsubscribe = shouldUnsubscribe;
- _this._next = onNext
- ? function (value) {
- try {
- onNext(value);
- }
- catch (err) {
- destination.error(err);
- }
- }
- : _super.prototype._next;
- _this._error = onError
- ? function (err) {
- try {
- onError(err);
- }
- catch (err) {
- destination.error(err);
- }
- finally {
- this.unsubscribe();
- }
- }
- : _super.prototype._error;
- _this._complete = onComplete
- ? function () {
- try {
- onComplete();
- }
- catch (err) {
- destination.error(err);
- }
- finally {
- this.unsubscribe();
- }
- }
- : _super.prototype._complete;
- return _this;
+ var boundedIndex = Math.min(Math.max(1, index), bitrates.length - 1);
+ if (bitrates[boundedIndex] === bitrates[boundedIndex - 1]) {
+ return minBufferLevelForBitrate(index - 1);
}
- OperatorSubscriber.prototype.unsubscribe = function () {
- var _a;
- if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {
- var closed_1 = this.closed;
- _super.prototype.unsubscribe.call(this);
- !closed_1 && ((_a = this.onFinalize) === null || _a === void 0 ? void 0 : _a.call(this));
- }
- };
- return OperatorSubscriber;
-}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .Lv));
-
-//# sourceMappingURL=OperatorSubscriber.js.map
-
-/***/ }),
-
-/***/ 9878:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "K": function() { return /* binding */ catchError; }
-/* harmony export */ });
-/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7878);
-/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2566);
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6798);
-
-
-
-function catchError(selector) {
- return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__/* .operate */ .e)(function (source, subscriber) {
- var innerSub = null;
- var syncUnsub = false;
- var handledResult;
- innerSub = source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__/* .createOperatorSubscriber */ .x)(subscriber, undefined, undefined, function (err) {
- handledResult = (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__/* .innerFrom */ .Xf)(selector(err, catchError(selector)(source)));
- if (innerSub) {
- innerSub.unsubscribe();
- innerSub = null;
- handledResult.subscribe(subscriber);
- }
- else {
- syncUnsub = true;
- }
- }));
- if (syncUnsub) {
- innerSub.unsubscribe();
- innerSub = null;
- handledResult.subscribe(subscriber);
- }
- });
+ return Vp * (gp + (bitrates[boundedIndex] * utilities[boundedIndex - 1] - bitrates[boundedIndex - 1] * utilities[boundedIndex]) / (bitrates[boundedIndex] - bitrates[boundedIndex - 1])) + 4;
+ }
}
-//# sourceMappingURL=catchError.js.map
-
-/***/ }),
-
-/***/ 4975:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+;// CONCATENATED MODULE: ./src/core/adaptive/buffer_based_chooser.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "h": function() { return /* binding */ filter; }
-/* harmony export */ });
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6798);
-/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2566);
-function filter(predicate, thisArg) {
- return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__/* .operate */ .e)(function (source, subscriber) {
- var index = 0;
- source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__/* .createOperatorSubscriber */ .x)(subscriber, function (value) { return predicate.call(thisArg, value, index++) && subscriber.next(value); }));
+/**
+ * Choose a bitrate based on the currently available buffer.
+ *
+ * This algorithm is based on a deviation of the BOLA algorithm.
+ * It is a hybrid solution that also relies on a given bitrate's
+ * "maintainability".
+ * Each time a chunk is downloaded, from the ratio between the chunk duration
+ * and chunk's request time, we can assume that the representation is
+ * "maintanable" or not.
+ * If so, we may switch to a better quality, or conversely to a worse quality.
+ *
+ * @class BufferBasedChooser
+ */
+var BufferBasedChooser = /*#__PURE__*/function () {
+ /**
+ * @param {Array.} bitrates
+ */
+ function BufferBasedChooser(bitrates) {
+ this._levelsMap = getBufferLevels(bitrates);
+ this._bitrates = bitrates;
+ log/* default.debug */.Z.debug("ABR: Steps for buffer based chooser.", this._levelsMap.map(function (l, i) {
+ return "bufferLevel: " + l + ", bitrate: " + bitrates[i];
+ }).join(" ,"));
+ }
+ /**
+ * @param {Object} playbackObservation
+ * @returns {number|undefined}
+ */
+ var _proto = BufferBasedChooser.prototype;
+ _proto.getEstimate = function getEstimate(playbackObservation) {
+ var bufferLevels = this._levelsMap;
+ var bitrates = this._bitrates;
+ var bufferGap = playbackObservation.bufferGap,
+ currentBitrate = playbackObservation.currentBitrate,
+ currentScore = playbackObservation.currentScore,
+ speed = playbackObservation.speed;
+ if (currentBitrate == null) {
+ return bitrates[0];
+ }
+ var currentBitrateIndex = (0,array_find_index/* default */.Z)(bitrates, function (b) {
+ return b === currentBitrate;
});
-}
-//# sourceMappingURL=filter.js.map
-
-/***/ }),
-
-/***/ 3286:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "x": function() { return /* binding */ finalize; }
-/* harmony export */ });
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6798);
-
-function finalize(callback) {
- return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__/* .operate */ .e)(function (source, subscriber) {
- try {
- source.subscribe(subscriber);
+ if (currentBitrateIndex < 0 || bitrates.length !== bufferLevels.length) {
+ log/* default.error */.Z.error("ABR: Current Bitrate not found in the calculated levels");
+ return bitrates[0];
+ }
+ var scaledScore;
+ if (currentScore != null) {
+ scaledScore = speed === 0 ? currentScore : currentScore / speed;
+ }
+ if (scaledScore != null && scaledScore > 1) {
+ var currentBufferLevel = bufferLevels[currentBitrateIndex];
+ var nextIndex = function () {
+ for (var i = currentBitrateIndex + 1; i < bufferLevels.length; i++) {
+ if (bufferLevels[i] > currentBufferLevel) {
+ return i;
+ }
}
- finally {
- subscriber.add(callback);
+ }();
+ if (nextIndex != null) {
+ var nextBufferLevel = bufferLevels[nextIndex];
+ if (bufferGap >= nextBufferLevel) {
+ return bitrates[nextIndex];
}
- });
-}
-//# sourceMappingURL=finalize.js.map
-
-/***/ }),
-
-/***/ 533:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "l": function() { return /* binding */ ignoreElements; }
-/* harmony export */ });
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6798);
-/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2566);
-/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2967);
-
-
-
-function ignoreElements() {
- return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__/* .operate */ .e)(function (source, subscriber) {
- source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__/* .createOperatorSubscriber */ .x)(subscriber, _util_noop__WEBPACK_IMPORTED_MODULE_2__/* .noop */ .Z));
- });
-}
-//# sourceMappingURL=ignoreElements.js.map
-
-/***/ }),
-
-/***/ 9127:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "U": function() { return /* binding */ map; }
-/* harmony export */ });
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6798);
-/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2566);
-
-
-function map(project, thisArg) {
- return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__/* .operate */ .e)(function (source, subscriber) {
- var index = 0;
- source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__/* .createOperatorSubscriber */ .x)(subscriber, function (value) {
- subscriber.next(project.call(thisArg, value, index++));
- }));
- });
-}
-//# sourceMappingURL=map.js.map
-
-/***/ }),
-
-/***/ 4367:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "J": function() { return /* binding */ mergeAll; }
-/* harmony export */ });
-/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7877);
-/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(278);
-
-
-function mergeAll(concurrent) {
- if (concurrent === void 0) { concurrent = Infinity; }
- return (0,_mergeMap__WEBPACK_IMPORTED_MODULE_0__/* .mergeMap */ .z)(_util_identity__WEBPACK_IMPORTED_MODULE_1__/* .identity */ .y, concurrent);
-}
-//# sourceMappingURL=mergeAll.js.map
-
-/***/ }),
-
-/***/ 7877:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-
-// EXPORTS
-__webpack_require__.d(__webpack_exports__, {
- "z": function() { return /* binding */ mergeMap; }
-});
-
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/map.js
-var map = __webpack_require__(9127);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/innerFrom.js
-var innerFrom = __webpack_require__(7878);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/lift.js
-var lift = __webpack_require__(6798);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/executeSchedule.js
-var executeSchedule = __webpack_require__(7845);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/OperatorSubscriber.js
-var OperatorSubscriber = __webpack_require__(2566);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/mergeInternals.js
-
-
-
-function mergeInternals(source, subscriber, project, concurrent, onBeforeNext, expand, innerSubScheduler, additionalFinalizer) {
- var buffer = [];
- var active = 0;
- var index = 0;
- var isComplete = false;
- var checkComplete = function () {
- if (isComplete && !buffer.length && !active) {
- subscriber.complete();
- }
- };
- var outerNext = function (value) { return (active < concurrent ? doInnerSub(value) : buffer.push(value)); };
- var doInnerSub = function (value) {
- expand && subscriber.next(value);
- active++;
- var innerComplete = false;
- (0,innerFrom/* innerFrom */.Xf)(project(value, index++)).subscribe((0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, function (innerValue) {
- onBeforeNext === null || onBeforeNext === void 0 ? void 0 : onBeforeNext(innerValue);
- if (expand) {
- outerNext(innerValue);
- }
- else {
- subscriber.next(innerValue);
- }
- }, function () {
- innerComplete = true;
- }, undefined, function () {
- if (innerComplete) {
- try {
- active--;
- var _loop_1 = function () {
- var bufferedValue = buffer.shift();
- if (innerSubScheduler) {
- (0,executeSchedule/* executeSchedule */.f)(subscriber, innerSubScheduler, function () { return doInnerSub(bufferedValue); });
- }
- else {
- doInnerSub(bufferedValue);
- }
- };
- while (buffer.length && active < concurrent) {
- _loop_1();
- }
- checkComplete();
- }
- catch (err) {
- subscriber.error(err);
- }
- }
- }));
- };
- source.subscribe((0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, outerNext, function () {
- isComplete = true;
- checkComplete();
- }));
- return function () {
- additionalFinalizer === null || additionalFinalizer === void 0 ? void 0 : additionalFinalizer();
- };
-}
-//# sourceMappingURL=mergeInternals.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/isFunction.js
-var isFunction = __webpack_require__(8474);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/mergeMap.js
-
-
-
-
-
-function mergeMap(project, resultSelector, concurrent) {
- if (concurrent === void 0) { concurrent = Infinity; }
- if ((0,isFunction/* isFunction */.m)(resultSelector)) {
- return mergeMap(function (a, i) { return (0,map/* map */.U)(function (b, ii) { return resultSelector(a, b, i, ii); })((0,innerFrom/* innerFrom */.Xf)(project(a, i))); }, concurrent);
+ }
}
- else if (typeof resultSelector === 'number') {
- concurrent = resultSelector;
+ if (scaledScore == null || scaledScore < 1.15) {
+ var _currentBufferLevel = bufferLevels[currentBitrateIndex];
+ if (bufferGap < _currentBufferLevel) {
+ for (var i = currentBitrateIndex - 1; i >= 0; i--) {
+ if (bitrates[i] < currentBitrate) {
+ return bitrates[i];
+ }
+ }
+ return currentBitrate;
+ }
}
- return (0,lift/* operate */.e)(function (source, subscriber) { return mergeInternals(source, subscriber, project, concurrent); });
-}
-//# sourceMappingURL=mergeMap.js.map
-
-/***/ }),
-
-/***/ 3074:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-
-// EXPORTS
-__webpack_require__.d(__webpack_exports__, {
- "R": function() { return /* binding */ scan; }
-});
-
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/lift.js
-var lift = __webpack_require__(6798);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/OperatorSubscriber.js
-var OperatorSubscriber = __webpack_require__(2566);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/scanInternals.js
-
-function scanInternals(accumulator, seed, hasSeed, emitOnNext, emitBeforeComplete) {
- return function (source, subscriber) {
- var hasState = hasSeed;
- var state = seed;
- var index = 0;
- source.subscribe((0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, function (value) {
- var i = index++;
- state = hasState
- ?
- accumulator(state, value, i)
- :
- ((hasState = true), value);
- emitOnNext && subscriber.next(state);
- }, emitBeforeComplete &&
- (function () {
- hasState && subscriber.next(state);
- subscriber.complete();
- })));
- };
-}
-//# sourceMappingURL=scanInternals.js.map
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/scan.js
-
-
-function scan(accumulator, seed) {
- return (0,lift/* operate */.e)(scanInternals(accumulator, seed, arguments.length >= 2, true));
-}
-//# sourceMappingURL=scan.js.map
-
-/***/ }),
-
-/***/ 5583:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
+ return currentBitrate;
+ };
+ return BufferBasedChooser;
+}();
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "B": function() { return /* binding */ share; }
-/* harmony export */ });
-/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5987);
-/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7878);
-/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6716);
-/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6267);
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6798);
+// EXTERNAL MODULE: ./src/utils/array_find.ts
+var array_find = __webpack_require__(3274);
+;// CONCATENATED MODULE: ./src/core/adaptive/utils/ewma.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Tweaked implementation of an exponential weighted Moving Average.
+ * @class EWMA
+ */
+var EWMA = /*#__PURE__*/function () {
+ /**
+ * @param {number} halfLife
+ */
+ function EWMA(halfLife) {
+ // (half-life = log(1/2) / log(Decay Factor)
+ this._alpha = Math.exp(Math.log(0.5) / halfLife);
+ this._lastEstimate = 0;
+ this._totalWeight = 0;
+ }
+ /**
+ * @param {number} weight
+ * @param {number} value
+ */
+ var _proto = EWMA.prototype;
+ _proto.addSample = function addSample(weight, value) {
+ var adjAlpha = Math.pow(this._alpha, weight);
+ var newEstimate = value * (1 - adjAlpha) + adjAlpha * this._lastEstimate;
+ if (!isNaN(newEstimate)) {
+ this._lastEstimate = newEstimate;
+ this._totalWeight += weight;
+ }
+ }
+ /**
+ * @returns {number} value
+ */;
+ _proto.getEstimate = function getEstimate() {
+ var zeroFactor = 1 - Math.pow(this._alpha, this._totalWeight);
+ return this._lastEstimate / zeroFactor;
+ };
+ return EWMA;
+}();
+;// CONCATENATED MODULE: ./src/core/adaptive/network_analyzer.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
-function share(options) {
- if (options === void 0) { options = {}; }
- var _a = options.connector, connector = _a === void 0 ? function () { return new _Subject__WEBPACK_IMPORTED_MODULE_0__/* .Subject */ .x(); } : _a, _b = options.resetOnError, resetOnError = _b === void 0 ? true : _b, _c = options.resetOnComplete, resetOnComplete = _c === void 0 ? true : _c, _d = options.resetOnRefCountZero, resetOnRefCountZero = _d === void 0 ? true : _d;
- return function (wrapperSource) {
- var connection;
- var resetConnection;
- var subject;
- var refCount = 0;
- var hasCompleted = false;
- var hasErrored = false;
- var cancelReset = function () {
- resetConnection === null || resetConnection === void 0 ? void 0 : resetConnection.unsubscribe();
- resetConnection = undefined;
- };
- var reset = function () {
- cancelReset();
- connection = subject = undefined;
- hasCompleted = hasErrored = false;
- };
- var resetAndUnsubscribe = function () {
- var conn = connection;
- reset();
- conn === null || conn === void 0 ? void 0 : conn.unsubscribe();
- };
- return (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__/* .operate */ .e)(function (source, subscriber) {
- refCount++;
- if (!hasErrored && !hasCompleted) {
- cancelReset();
- }
- var dest = (subject = subject !== null && subject !== void 0 ? subject : connector());
- subscriber.add(function () {
- refCount--;
- if (refCount === 0 && !hasErrored && !hasCompleted) {
- resetConnection = handleReset(resetAndUnsubscribe, resetOnRefCountZero);
- }
- });
- dest.subscribe(subscriber);
- if (!connection &&
- refCount > 0) {
- connection = new _Subscriber__WEBPACK_IMPORTED_MODULE_2__/* .SafeSubscriber */ .Hp({
- next: function (value) { return dest.next(value); },
- error: function (err) {
- hasErrored = true;
- cancelReset();
- resetConnection = handleReset(reset, resetOnError, err);
- dest.error(err);
- },
- complete: function () {
- hasCompleted = true;
- cancelReset();
- resetConnection = handleReset(reset, resetOnComplete);
- dest.complete();
- },
- });
- (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_3__/* .innerFrom */ .Xf)(source).subscribe(connection);
- }
- })(wrapperSource);
- };
-}
-function handleReset(reset, on) {
- var args = [];
- for (var _i = 2; _i < arguments.length; _i++) {
- args[_i - 2] = arguments[_i];
+/**
+ * Get pending segment request(s) starting with the asked segment position.
+ * @param {Object} requests - Every requests pending, in a chronological
+ * order in terms of segment time.
+ * @param {number} neededPosition
+ * @returns {Array.}
+ */
+function getConcernedRequests(requests, neededPosition) {
+ /** Index of the request for the next needed segment, in `requests`. */
+ var nextSegmentIndex = -1;
+ for (var i = 0; i < requests.length; i++) {
+ var segment = requests[i].content.segment;
+ if (segment.duration <= 0) {
+ continue;
}
- if (on === true) {
- reset();
- return;
+ var segmentEnd = segment.time + segment.duration;
+ if (!segment.complete) {
+ if (i === requests.length - 1 && neededPosition - segment.time > -1.2) {
+ nextSegmentIndex = i;
+ break;
+ }
}
- if (on === false) {
- return;
+ if (segmentEnd > neededPosition && neededPosition - segment.time > -1.2) {
+ nextSegmentIndex = i;
+ break;
}
- var onSubscriber = new _Subscriber__WEBPACK_IMPORTED_MODULE_2__/* .SafeSubscriber */ .Hp({
- next: function () {
- onSubscriber.unsubscribe();
- reset();
- },
- });
- return on.apply(void 0, (0,tslib__WEBPACK_IMPORTED_MODULE_4__/* .__spreadArray */ .ev)([], (0,tslib__WEBPACK_IMPORTED_MODULE_4__/* .__read */ .CR)(args))).subscribe(onSubscriber);
-}
-//# sourceMappingURL=share.js.map
-
-/***/ }),
-
-/***/ 8515:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "d": function() { return /* binding */ shareReplay; }
-/* harmony export */ });
-/* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
-/* harmony import */ var _share__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5583);
-
-
-function shareReplay(configOrBufferSize, windowTime, scheduler) {
- var _a, _b, _c;
- var bufferSize;
- var refCount = false;
- if (configOrBufferSize && typeof configOrBufferSize === 'object') {
- (_a = configOrBufferSize.bufferSize, bufferSize = _a === void 0 ? Infinity : _a, _b = configOrBufferSize.windowTime, windowTime = _b === void 0 ? Infinity : _b, _c = configOrBufferSize.refCount, refCount = _c === void 0 ? false : _c, scheduler = configOrBufferSize.scheduler);
- }
- else {
- bufferSize = (configOrBufferSize !== null && configOrBufferSize !== void 0 ? configOrBufferSize : Infinity);
- }
- return (0,_share__WEBPACK_IMPORTED_MODULE_0__/* .share */ .B)({
- connector: function () { return new _ReplaySubject__WEBPACK_IMPORTED_MODULE_1__/* .ReplaySubject */ .t(bufferSize, windowTime, scheduler); },
- resetOnError: true,
- resetOnComplete: false,
- resetOnRefCountZero: refCount,
- });
-}
-//# sourceMappingURL=shareReplay.js.map
-
-/***/ }),
-
-/***/ 6108:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "O": function() { return /* binding */ startWith; }
-/* harmony export */ });
-/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2034);
-/* harmony import */ var _util_args__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2457);
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6798);
-
-
-
-function startWith() {
- var values = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- values[_i] = arguments[_i];
+ }
+ if (nextSegmentIndex < 0) {
+ // Not found
+ return [];
+ }
+ var nextRequest = requests[nextSegmentIndex];
+ var segmentTime = nextRequest.content.segment.time;
+ var filteredRequests = [nextRequest];
+ // Get the possibly multiple requests for that segment's position
+ for (var _i = nextSegmentIndex + 1; _i < requests.length; _i++) {
+ if (requests[_i].content.segment.time === segmentTime) {
+ filteredRequests.push(requests[_i]);
+ } else {
+ break;
}
- var scheduler = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__/* .popScheduler */ .yG)(values);
- return (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__/* .operate */ .e)(function (source, subscriber) {
- (scheduler ? (0,_observable_concat__WEBPACK_IMPORTED_MODULE_2__/* .concat */ .z)(values, source, scheduler) : (0,_observable_concat__WEBPACK_IMPORTED_MODULE_2__/* .concat */ .z)(values, source)).subscribe(subscriber);
- });
-}
-//# sourceMappingURL=startWith.js.map
-
-/***/ }),
-
-/***/ 8720:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "R": function() { return /* binding */ subscribeOn; }
-/* harmony export */ });
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6798);
-
-function subscribeOn(scheduler, delay) {
- if (delay === void 0) { delay = 0; }
- return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__/* .operate */ .e)(function (source, subscriber) {
- subscriber.add(scheduler.schedule(function () { return source.subscribe(subscriber); }, delay));
- });
+ }
+ return filteredRequests;
}
-//# sourceMappingURL=subscribeOn.js.map
-
-/***/ }),
-
-/***/ 4978:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "w": function() { return /* binding */ switchMap; }
-/* harmony export */ });
-/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7878);
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6798);
-/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2566);
-
-
-
-function switchMap(project, resultSelector) {
- return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__/* .operate */ .e)(function (source, subscriber) {
- var innerSubscriber = null;
- var index = 0;
- var isComplete = false;
- var checkComplete = function () { return isComplete && !innerSubscriber && subscriber.complete(); };
- source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__/* .createOperatorSubscriber */ .x)(subscriber, function (value) {
- innerSubscriber === null || innerSubscriber === void 0 ? void 0 : innerSubscriber.unsubscribe();
- var innerIndex = 0;
- var outerIndex = index++;
- (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__/* .innerFrom */ .Xf)(project(value, outerIndex)).subscribe((innerSubscriber = (0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__/* .createOperatorSubscriber */ .x)(subscriber, function (innerValue) { return subscriber.next(resultSelector ? resultSelector(value, innerValue, outerIndex, innerIndex++) : innerValue); }, function () {
- innerSubscriber = null;
- checkComplete();
- })));
- }, function () {
- isComplete = true;
- checkComplete();
- }));
- });
+/**
+ * Estimate the __VERY__ recent bandwidth based on a single unfinished request.
+ * Useful when the current bandwidth seemed to have fallen quickly.
+ *
+ * @param {Object} request
+ * @returns {number|undefined}
+ */
+function estimateRequestBandwidth(request) {
+ if (request.progress.length < 5) {
+ // threshold from which we can consider
+ // progress events reliably
+ return undefined;
+ }
+ // try to infer quickly the current bitrate based on the
+ // progress events
+ var ewma1 = new EWMA(2);
+ var progress = request.progress;
+ for (var i = 1; i < progress.length; i++) {
+ var bytesDownloaded = progress[i].size - progress[i - 1].size;
+ var timeElapsed = progress[i].timestamp - progress[i - 1].timestamp;
+ var reqBitrate = bytesDownloaded * 8 / (timeElapsed / 1000);
+ ewma1.addSample(timeElapsed / 1000, reqBitrate);
+ }
+ return ewma1.getEstimate();
}
-//# sourceMappingURL=switchMap.js.map
-
-/***/ }),
-
-/***/ 4727:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "q": function() { return /* binding */ take; }
-/* harmony export */ });
-/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1545);
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6798);
-/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2566);
-
-
-
-function take(count) {
- return count <= 0
- ?
- function () { return _observable_empty__WEBPACK_IMPORTED_MODULE_0__/* .EMPTY */ .E; }
- : (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__/* .operate */ .e)(function (source, subscriber) {
- var seen = 0;
- source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__/* .createOperatorSubscriber */ .x)(subscriber, function (value) {
- if (++seen <= count) {
- subscriber.next(value);
- if (count <= seen) {
- subscriber.complete();
- }
- }
- }));
- });
+/**
+ * Estimate remaining time for a pending request from a progress event.
+ * @param {Object} lastProgressEvent
+ * @param {number} bandwidthEstimate
+ * @returns {number}
+ */
+function estimateRemainingTime(lastProgressEvent, bandwidthEstimate) {
+ var remainingData = (lastProgressEvent.totalSize - lastProgressEvent.size) * 8;
+ return Math.max(remainingData / bandwidthEstimate, 0);
}
-//# sourceMappingURL=take.js.map
-
-/***/ }),
-
-/***/ 3505:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "R": function() { return /* binding */ takeUntil; }
-/* harmony export */ });
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6798);
-/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2566);
-/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7878);
-/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2967);
-
-
-
-
-function takeUntil(notifier) {
- return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__/* .operate */ .e)(function (source, subscriber) {
- (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_1__/* .innerFrom */ .Xf)(notifier).subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__/* .createOperatorSubscriber */ .x)(subscriber, function () { return subscriber.complete(); }, _util_noop__WEBPACK_IMPORTED_MODULE_3__/* .noop */ .Z));
- !subscriber.closed && source.subscribe(subscriber);
- });
+/**
+ * Check if the request for the most needed segment is too slow.
+ * If that's the case, re-calculate the bandwidth urgently based on
+ * this single request.
+ * @param {Object} pendingRequests - Every requests pending, in a chronological
+ * order in terms of segment time.
+ * @param {Object} playbackInfo - Information on the current playback.
+ * @param {Object|null} currentRepresentation - The Representation being
+ * presently being loaded.
+ * @param {boolean} lowLatencyMode - If `true`, we're playing the content as a
+ * low latency content - where requests might be pending when the segment is
+ * still encoded.
+ * @param {Number} lastEstimatedBitrate - Last bitrate estimate emitted.
+ * @returns {Number|undefined}
+ */
+function estimateStarvationModeBitrate(pendingRequests, playbackInfo, currentRepresentation, lowLatencyMode, lastEstimatedBitrate) {
+ if (lowLatencyMode) {
+ // TODO Skip only for newer segments?
+ return undefined;
+ }
+ var bufferGap = playbackInfo.bufferGap,
+ speed = playbackInfo.speed,
+ position = playbackInfo.position;
+ var realBufferGap = isFinite(bufferGap) ? bufferGap : 0;
+ var nextNeededPosition = position.last + realBufferGap;
+ var concernedRequests = getConcernedRequests(pendingRequests, nextNeededPosition);
+ if (concernedRequests.length !== 1) {
+ // 0 == no request
+ // 2+ == too complicated to calculate
+ return undefined;
+ }
+ var concernedRequest = concernedRequests[0];
+ var now = performance.now();
+ var lastProgressEvent = concernedRequest.progress.length > 0 ? concernedRequest.progress[concernedRequest.progress.length - 1] : undefined;
+ // first, try to do a quick estimate from progress events
+ var bandwidthEstimate = estimateRequestBandwidth(concernedRequest);
+ if (lastProgressEvent !== undefined && bandwidthEstimate !== undefined) {
+ var remainingTime = estimateRemainingTime(lastProgressEvent, bandwidthEstimate);
+ // if the remaining time does seem reliable
+ if ((now - lastProgressEvent.timestamp) / 1000 <= remainingTime) {
+ // Calculate estimated time spent rebuffering if we continue doing that request.
+ var expectedRebufferingTime = remainingTime - realBufferGap / speed;
+ if (expectedRebufferingTime > 2000) {
+ return bandwidthEstimate;
+ }
+ }
+ }
+ if (!concernedRequest.content.segment.complete) {
+ return undefined;
+ }
+ var chunkDuration = concernedRequest.content.segment.duration;
+ var requestElapsedTime = (now - concernedRequest.requestTimestamp) / 1000;
+ var reasonableElapsedTime = requestElapsedTime <= (chunkDuration * 1.5 + 2) / speed;
+ if (currentRepresentation == null || reasonableElapsedTime) {
+ return undefined;
+ }
+ // calculate a reduced bitrate from the current one
+ var factor = chunkDuration / requestElapsedTime;
+ var reducedBitrate = currentRepresentation.bitrate * Math.min(0.7, factor);
+ if (lastEstimatedBitrate === undefined || reducedBitrate < lastEstimatedBitrate) {
+ return reducedBitrate;
+ }
}
-//# sourceMappingURL=takeUntil.js.map
-
-/***/ }),
-
-/***/ 2006:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "b": function() { return /* binding */ tap; }
-/* harmony export */ });
-/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8474);
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6798);
-/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2566);
-/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(278);
-
-
-
-
-function tap(observerOrNext, error, complete) {
- var tapObserver = (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(observerOrNext) || error || complete
- ?
- { next: observerOrNext, error: error, complete: complete }
- : observerOrNext;
- return tapObserver
- ? (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__/* .operate */ .e)(function (source, subscriber) {
- var _a;
- (_a = tapObserver.subscribe) === null || _a === void 0 ? void 0 : _a.call(tapObserver);
- var isUnsub = true;
- source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__/* .createOperatorSubscriber */ .x)(subscriber, function (value) {
- var _a;
- (_a = tapObserver.next) === null || _a === void 0 ? void 0 : _a.call(tapObserver, value);
- subscriber.next(value);
- }, function () {
- var _a;
- isUnsub = false;
- (_a = tapObserver.complete) === null || _a === void 0 ? void 0 : _a.call(tapObserver);
- subscriber.complete();
- }, function (err) {
- var _a;
- isUnsub = false;
- (_a = tapObserver.error) === null || _a === void 0 ? void 0 : _a.call(tapObserver, err);
- subscriber.error(err);
- }, function () {
- var _a, _b;
- if (isUnsub) {
- (_a = tapObserver.unsubscribe) === null || _a === void 0 ? void 0 : _a.call(tapObserver);
- }
- (_b = tapObserver.finalize) === null || _b === void 0 ? void 0 : _b.call(tapObserver);
- }));
- })
- :
- _util_identity__WEBPACK_IMPORTED_MODULE_3__/* .identity */ .y;
+/**
+ * Returns true if, based on the current requests, it seems that the ABR should
+ * switch immediately if a lower bitrate is more adapted.
+ * Returns false if it estimates that you have time before switching to a lower
+ * bitrate.
+ * @param {Object} playbackInfo - Information on the current playback.
+ * @param {Object} requests - Every requests pending, in a chronological
+ * order in terms of segment time.
+ * @param {boolean} lowLatencyMode - If `true`, we're playing the content as a
+ * low latency content, as close to the live edge as possible.
+ * @returns {boolean}
+ */
+function shouldDirectlySwitchToLowBitrate(playbackInfo, requests, lowLatencyMode) {
+ if (lowLatencyMode) {
+ // TODO only when playing close to the live edge?
+ return true;
+ }
+ var realBufferGap = isFinite(playbackInfo.bufferGap) ? playbackInfo.bufferGap : 0;
+ var nextNeededPosition = playbackInfo.position.last + realBufferGap;
+ var nextRequest = (0,array_find/* default */.Z)(requests, function (_ref) {
+ var content = _ref.content;
+ return content.segment.duration > 0 && content.segment.time + content.segment.duration > nextNeededPosition;
+ });
+ if (nextRequest === undefined) {
+ return true;
+ }
+ var now = performance.now();
+ var lastProgressEvent = nextRequest.progress.length > 0 ? nextRequest.progress[nextRequest.progress.length - 1] : undefined;
+ // first, try to do a quick estimate from progress events
+ var bandwidthEstimate = estimateRequestBandwidth(nextRequest);
+ if (lastProgressEvent === undefined || bandwidthEstimate === undefined) {
+ return true;
+ }
+ var remainingTime = estimateRemainingTime(lastProgressEvent, bandwidthEstimate);
+ if ((now - lastProgressEvent.timestamp) / 1000 > remainingTime * 1.2) {
+ return true;
+ }
+ var expectedRebufferingTime = remainingTime - realBufferGap / playbackInfo.speed;
+ return expectedRebufferingTime > -1.5;
}
-//# sourceMappingURL=tap.js.map
-
-/***/ }),
-
-/***/ 3428:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "M": function() { return /* binding */ withLatestFrom; }
-/* harmony export */ });
-/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(5987);
-/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6798);
-/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2566);
-/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7878);
-/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(278);
-/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2967);
-/* harmony import */ var _util_args__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2457);
-
-
-
-
-
-
-
-function withLatestFrom() {
- var inputs = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- inputs[_i] = arguments[_i];
+/**
+ * Analyze the current network conditions and give a bandwidth estimate as well
+ * as a maximum bitrate a Representation should be.
+ * @class NetworkAnalyzer
+ */
+var NetworkAnalyzer = /*#__PURE__*/function () {
+ function NetworkAnalyzer(initialBitrate, lowLatencyMode) {
+ var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
+ ABR_STARVATION_GAP = _config$getCurrent.ABR_STARVATION_GAP,
+ OUT_OF_STARVATION_GAP = _config$getCurrent.OUT_OF_STARVATION_GAP,
+ ABR_STARVATION_FACTOR = _config$getCurrent.ABR_STARVATION_FACTOR,
+ ABR_REGULAR_FACTOR = _config$getCurrent.ABR_REGULAR_FACTOR;
+ this._initialBitrate = initialBitrate;
+ this._inStarvationMode = false;
+ this._lowLatencyMode = lowLatencyMode;
+ if (lowLatencyMode) {
+ this._config = {
+ starvationGap: ABR_STARVATION_GAP.LOW_LATENCY,
+ outOfStarvationGap: OUT_OF_STARVATION_GAP.LOW_LATENCY,
+ starvationBitrateFactor: ABR_STARVATION_FACTOR.LOW_LATENCY,
+ regularBitrateFactor: ABR_REGULAR_FACTOR.LOW_LATENCY
+ };
+ } else {
+ this._config = {
+ starvationGap: ABR_STARVATION_GAP.DEFAULT,
+ outOfStarvationGap: OUT_OF_STARVATION_GAP.DEFAULT,
+ starvationBitrateFactor: ABR_STARVATION_FACTOR.DEFAULT,
+ regularBitrateFactor: ABR_REGULAR_FACTOR.DEFAULT
+ };
}
- var project = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__/* .popResultSelector */ .jO)(inputs);
- return (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__/* .operate */ .e)(function (source, subscriber) {
- var len = inputs.length;
- var otherValues = new Array(len);
- var hasValue = inputs.map(function () { return false; });
- var ready = false;
- var _loop_1 = function (i) {
- (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__/* .innerFrom */ .Xf)(inputs[i]).subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__/* .createOperatorSubscriber */ .x)(subscriber, function (value) {
- otherValues[i] = value;
- if (!ready && !hasValue[i]) {
- hasValue[i] = true;
- (ready = hasValue.every(_util_identity__WEBPACK_IMPORTED_MODULE_4__/* .identity */ .y)) && (hasValue = null);
- }
- }, _util_noop__WEBPACK_IMPORTED_MODULE_5__/* .noop */ .Z));
- };
- for (var i = 0; i < len; i++) {
- _loop_1(i);
- }
- source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__/* .createOperatorSubscriber */ .x)(subscriber, function (value) {
- if (ready) {
- var values = (0,tslib__WEBPACK_IMPORTED_MODULE_6__/* .__spreadArray */ .ev)([value], (0,tslib__WEBPACK_IMPORTED_MODULE_6__/* .__read */ .CR)(otherValues));
- subscriber.next(project ? project.apply(void 0, (0,tslib__WEBPACK_IMPORTED_MODULE_6__/* .__spreadArray */ .ev)([], (0,tslib__WEBPACK_IMPORTED_MODULE_6__/* .__read */ .CR)(values))) : values);
- }
- }));
- });
-}
-//# sourceMappingURL=withLatestFrom.js.map
-
-/***/ }),
-
-/***/ 8337:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-
-// EXPORTS
-__webpack_require__.d(__webpack_exports__, {
- "o": function() { return /* binding */ AsyncAction; }
-});
-
-// EXTERNAL MODULE: ./node_modules/rxjs/node_modules/tslib/tslib.es6.js
-var tslib_es6 = __webpack_require__(5987);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/Subscription.js + 1 modules
-var Subscription = __webpack_require__(5720);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/Action.js
-
-
-var Action = (function (_super) {
- (0,tslib_es6/* __extends */.ZT)(Action, _super);
- function Action(scheduler, work) {
- return _super.call(this) || this;
- }
- Action.prototype.schedule = function (state, delay) {
- if (delay === void 0) { delay = 0; }
- return this;
- };
- return Action;
-}(Subscription/* Subscription */.w0));
-
-//# sourceMappingURL=Action.js.map
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/intervalProvider.js
-
-var intervalProvider = {
- setInterval: function (handler, timeout) {
- var args = [];
- for (var _i = 2; _i < arguments.length; _i++) {
- args[_i - 2] = arguments[_i];
- }
- var delegate = intervalProvider.delegate;
- if (delegate === null || delegate === void 0 ? void 0 : delegate.setInterval) {
- return delegate.setInterval.apply(delegate, (0,tslib_es6/* __spreadArray */.ev)([handler, timeout], (0,tslib_es6/* __read */.CR)(args)));
- }
- return setInterval.apply(void 0, (0,tslib_es6/* __spreadArray */.ev)([handler, timeout], (0,tslib_es6/* __read */.CR)(args)));
- },
- clearInterval: function (handle) {
- var delegate = intervalProvider.delegate;
- return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearInterval) || clearInterval)(handle);
- },
- delegate: undefined,
-};
-//# sourceMappingURL=intervalProvider.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/arrRemove.js
-var arrRemove = __webpack_require__(3699);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/AsyncAction.js
-
-
-
-
-var AsyncAction = (function (_super) {
- (0,tslib_es6/* __extends */.ZT)(AsyncAction, _super);
- function AsyncAction(scheduler, work) {
- var _this = _super.call(this, scheduler, work) || this;
- _this.scheduler = scheduler;
- _this.work = work;
- _this.pending = false;
- return _this;
- }
- AsyncAction.prototype.schedule = function (state, delay) {
- var _a;
- if (delay === void 0) { delay = 0; }
- if (this.closed) {
- return this;
- }
- this.state = state;
- var id = this.id;
- var scheduler = this.scheduler;
- if (id != null) {
- this.id = this.recycleAsyncId(scheduler, id, delay);
- }
- this.pending = true;
- this.delay = delay;
- this.id = (_a = this.id) !== null && _a !== void 0 ? _a : this.requestAsyncId(scheduler, this.id, delay);
- return this;
- };
- AsyncAction.prototype.requestAsyncId = function (scheduler, _id, delay) {
- if (delay === void 0) { delay = 0; }
- return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);
- };
- AsyncAction.prototype.recycleAsyncId = function (_scheduler, id, delay) {
- if (delay === void 0) { delay = 0; }
- if (delay != null && this.delay === delay && this.pending === false) {
- return id;
- }
- if (id != null) {
- intervalProvider.clearInterval(id);
- }
- return undefined;
- };
- AsyncAction.prototype.execute = function (state, delay) {
- if (this.closed) {
- return new Error('executing a cancelled action');
- }
- this.pending = false;
- var error = this._execute(state, delay);
- if (error) {
- return error;
- }
- else if (this.pending === false && this.id != null) {
- this.id = this.recycleAsyncId(this.scheduler, this.id, null);
- }
- };
- AsyncAction.prototype._execute = function (state, _delay) {
- var errored = false;
- var errorValue;
- try {
- this.work(state);
- }
- catch (e) {
- errored = true;
- errorValue = e ? e : new Error('Scheduled action threw falsy error');
- }
- if (errored) {
- this.unsubscribe();
- return errorValue;
- }
- };
- AsyncAction.prototype.unsubscribe = function () {
- if (!this.closed) {
- var _a = this, id = _a.id, scheduler = _a.scheduler;
- var actions = scheduler.actions;
- this.work = this.state = this.scheduler = null;
- this.pending = false;
- (0,arrRemove/* arrRemove */.P)(actions, this);
- if (id != null) {
- this.id = this.recycleAsyncId(scheduler, id, null);
- }
- this.delay = null;
- _super.prototype.unsubscribe.call(this);
- }
- };
- return AsyncAction;
-}(Action));
-
-//# sourceMappingURL=AsyncAction.js.map
-
-/***/ }),
-
-/***/ 9682:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-
-// EXPORTS
-__webpack_require__.d(__webpack_exports__, {
- "v": function() { return /* binding */ AsyncScheduler; }
-});
-
-// EXTERNAL MODULE: ./node_modules/rxjs/node_modules/tslib/tslib.es6.js
-var tslib_es6 = __webpack_require__(5987);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/dateTimestampProvider.js
-var dateTimestampProvider = __webpack_require__(4318);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/Scheduler.js
-
-var Scheduler = (function () {
- function Scheduler(schedulerActionCtor, now) {
- if (now === void 0) { now = Scheduler.now; }
- this.schedulerActionCtor = schedulerActionCtor;
- this.now = now;
- }
- Scheduler.prototype.schedule = function (work, delay, state) {
- if (delay === void 0) { delay = 0; }
- return new this.schedulerActionCtor(this, work).schedule(state, delay);
- };
- Scheduler.now = dateTimestampProvider/* dateTimestampProvider.now */.l.now;
- return Scheduler;
-}());
-
-//# sourceMappingURL=Scheduler.js.map
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/AsyncScheduler.js
-
-
-var AsyncScheduler = (function (_super) {
- (0,tslib_es6/* __extends */.ZT)(AsyncScheduler, _super);
- function AsyncScheduler(SchedulerAction, now) {
- if (now === void 0) { now = Scheduler.now; }
- var _this = _super.call(this, SchedulerAction, now) || this;
- _this.actions = [];
- _this._active = false;
- return _this;
- }
- AsyncScheduler.prototype.flush = function (action) {
- var actions = this.actions;
- if (this._active) {
- actions.push(action);
- return;
- }
- var error;
- this._active = true;
- do {
- if ((error = action.execute(action.state, action.delay))) {
- break;
- }
- } while ((action = actions.shift()));
- this._active = false;
- if (error) {
- while ((action = actions.shift())) {
- action.unsubscribe();
- }
- throw error;
- }
- };
- return AsyncScheduler;
-}(Scheduler));
-
-//# sourceMappingURL=AsyncScheduler.js.map
-
-/***/ }),
-
-/***/ 7991:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "P": function() { return /* binding */ async; },
-/* harmony export */ "z": function() { return /* binding */ asyncScheduler; }
-/* harmony export */ });
-/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8337);
-/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9682);
-
-
-var asyncScheduler = new _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__/* .AsyncScheduler */ .v(_AsyncAction__WEBPACK_IMPORTED_MODULE_1__/* .AsyncAction */ .o);
-var async = asyncScheduler;
-//# sourceMappingURL=async.js.map
-
-/***/ }),
-
-/***/ 4318:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "l": function() { return /* binding */ dateTimestampProvider; }
-/* harmony export */ });
-var dateTimestampProvider = {
- now: function () {
- return (dateTimestampProvider.delegate || Date).now();
- },
- delegate: undefined,
-};
-//# sourceMappingURL=dateTimestampProvider.js.map
-
-/***/ }),
-
-/***/ 8380:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "z": function() { return /* binding */ timeoutProvider; }
-/* harmony export */ });
-/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5987);
-
-var timeoutProvider = {
- setTimeout: function (handler, timeout) {
- var args = [];
- for (var _i = 2; _i < arguments.length; _i++) {
- args[_i - 2] = arguments[_i];
- }
- var delegate = timeoutProvider.delegate;
- if (delegate === null || delegate === void 0 ? void 0 : delegate.setTimeout) {
- return delegate.setTimeout.apply(delegate, (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__spreadArray */ .ev)([handler, timeout], (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__read */ .CR)(args)));
- }
- return setTimeout.apply(void 0, (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__spreadArray */ .ev)([handler, timeout], (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__read */ .CR)(args)));
- },
- clearTimeout: function (handle) {
- var delegate = timeoutProvider.delegate;
- return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearTimeout) || clearTimeout)(handle);
- },
- delegate: undefined,
-};
-//# sourceMappingURL=timeoutProvider.js.map
-
-/***/ }),
-
-/***/ 9768:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "h": function() { return /* binding */ iterator; }
-/* harmony export */ });
-/* unused harmony export getSymbolIterator */
-function getSymbolIterator() {
- if (typeof Symbol !== 'function' || !Symbol.iterator) {
- return '@@iterator';
- }
- return Symbol.iterator;
-}
-var iterator = getSymbolIterator();
-//# sourceMappingURL=iterator.js.map
-
-/***/ }),
-
-/***/ 6766:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "L": function() { return /* binding */ observable; }
-/* harmony export */ });
-var observable = (function () { return (typeof Symbol === 'function' && Symbol.observable) || '@@observable'; })();
-//# sourceMappingURL=observable.js.map
-
-/***/ }),
-
-/***/ 2457:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "_6": function() { return /* binding */ popNumber; },
-/* harmony export */ "jO": function() { return /* binding */ popResultSelector; },
-/* harmony export */ "yG": function() { return /* binding */ popScheduler; }
-/* harmony export */ });
-/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8474);
-/* harmony import */ var _isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4865);
-
-
-function last(arr) {
- return arr[arr.length - 1];
-}
-function popResultSelector(args) {
- return (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(last(args)) ? args.pop() : undefined;
-}
-function popScheduler(args) {
- return (0,_isScheduler__WEBPACK_IMPORTED_MODULE_1__/* .isScheduler */ .K)(last(args)) ? args.pop() : undefined;
-}
-function popNumber(args, defaultValue) {
- return typeof last(args) === 'number' ? args.pop() : defaultValue;
-}
-//# sourceMappingURL=args.js.map
-
-/***/ }),
-
-/***/ 3699:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "P": function() { return /* binding */ arrRemove; }
-/* harmony export */ });
-function arrRemove(arr, item) {
- if (arr) {
- var index = arr.indexOf(item);
- 0 <= index && arr.splice(index, 1);
- }
-}
-//# sourceMappingURL=arrRemove.js.map
-
-/***/ }),
-
-/***/ 1819:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "d": function() { return /* binding */ createErrorClass; }
-/* harmony export */ });
-function createErrorClass(createImpl) {
- var _super = function (instance) {
- Error.call(instance);
- instance.stack = new Error().stack;
- };
- var ctorFunc = createImpl(_super);
- ctorFunc.prototype = Object.create(Error.prototype);
- ctorFunc.prototype.constructor = ctorFunc;
- return ctorFunc;
-}
-//# sourceMappingURL=createErrorClass.js.map
-
-/***/ }),
-
-/***/ 8846:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "O": function() { return /* binding */ captureError; },
-/* harmony export */ "x": function() { return /* binding */ errorContext; }
-/* harmony export */ });
-/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3912);
-
-var context = null;
-function errorContext(cb) {
- if (_config__WEBPACK_IMPORTED_MODULE_0__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling) {
- var isRoot = !context;
- if (isRoot) {
- context = { errorThrown: false, error: null };
- }
- cb();
- if (isRoot) {
- var _a = context, errorThrown = _a.errorThrown, error = _a.error;
- context = null;
- if (errorThrown) {
- throw error;
- }
- }
+ }
+ /**
+ * Gives an estimate of the current bandwidth and of the bitrate that should
+ * be considered for chosing a `representation`.
+ * This estimate is only based on network metrics.
+ * @param {Object} playbackInfo - Gives current information about playback.
+ * @param {Object} bandwidthEstimator - `BandwidthEstimator` allowing to
+ * produce network bandwidth estimates.
+ * @param {Object|null} currentRepresentation - The Representation currently
+ * chosen.
+ * `null` if no Representation has been chosen yet.
+ * @param {Array.} currentRequests - All segment requests by segment's
+ * start chronological order
+ * @param {number|undefined} lastEstimatedBitrate - Bitrate emitted during the
+ * last estimate.
+ * @returns {Object}
+ */
+ var _proto = NetworkAnalyzer.prototype;
+ _proto.getBandwidthEstimate = function getBandwidthEstimate(playbackInfo, bandwidthEstimator, currentRepresentation, currentRequests, lastEstimatedBitrate) {
+ var newBitrateCeil; // bitrate ceil for the chosen Representation
+ var bandwidthEstimate;
+ var localConf = this._config;
+ var bufferGap = playbackInfo.bufferGap,
+ position = playbackInfo.position,
+ duration = playbackInfo.duration;
+ var realBufferGap = isFinite(bufferGap) ? bufferGap : 0;
+ var _config$getCurrent2 = config/* default.getCurrent */.Z.getCurrent(),
+ ABR_STARVATION_DURATION_DELTA = _config$getCurrent2.ABR_STARVATION_DURATION_DELTA;
+ // check if should get in/out of starvation mode
+ if (isNaN(duration) || realBufferGap + position.last < duration - ABR_STARVATION_DURATION_DELTA) {
+ if (!this._inStarvationMode && realBufferGap <= localConf.starvationGap) {
+ log/* default.info */.Z.info("ABR: enter starvation mode.");
+ this._inStarvationMode = true;
+ } else if (this._inStarvationMode && realBufferGap >= localConf.outOfStarvationGap) {
+ log/* default.info */.Z.info("ABR: exit starvation mode.");
+ this._inStarvationMode = false;
+ }
+ } else if (this._inStarvationMode) {
+ log/* default.info */.Z.info("ABR: exit starvation mode.");
+ this._inStarvationMode = false;
}
- else {
- cb();
+ // If in starvation mode, check if a quick new estimate can be done
+ // from the last requests.
+ // If so, cancel previous estimates and replace it by the new one
+ if (this._inStarvationMode) {
+ bandwidthEstimate = estimateStarvationModeBitrate(currentRequests, playbackInfo, currentRepresentation, this._lowLatencyMode, lastEstimatedBitrate);
+ if (bandwidthEstimate != null) {
+ log/* default.info */.Z.info("ABR: starvation mode emergency estimate:", bandwidthEstimate);
+ bandwidthEstimator.reset();
+ newBitrateCeil = currentRepresentation == null ? bandwidthEstimate : Math.min(bandwidthEstimate, currentRepresentation.bitrate);
+ }
}
-}
-function captureError(err) {
- if (_config__WEBPACK_IMPORTED_MODULE_0__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling && context) {
- context.errorThrown = true;
- context.error = err;
+ // if newBitrateCeil is not yet defined, do the normal estimation
+ if (newBitrateCeil == null) {
+ bandwidthEstimate = bandwidthEstimator.getEstimate();
+ if (bandwidthEstimate != null) {
+ newBitrateCeil = bandwidthEstimate * (this._inStarvationMode ? localConf.starvationBitrateFactor : localConf.regularBitrateFactor);
+ } else if (lastEstimatedBitrate != null) {
+ newBitrateCeil = lastEstimatedBitrate * (this._inStarvationMode ? localConf.starvationBitrateFactor : localConf.regularBitrateFactor);
+ } else {
+ newBitrateCeil = this._initialBitrate;
+ }
}
-}
-//# sourceMappingURL=errorContext.js.map
-
-/***/ }),
-
-/***/ 7845:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "f": function() { return /* binding */ executeSchedule; }
-/* harmony export */ });
-function executeSchedule(parentSubscription, scheduler, work, delay, repeat) {
- if (delay === void 0) { delay = 0; }
- if (repeat === void 0) { repeat = false; }
- var scheduleSubscription = scheduler.schedule(function () {
- work();
- if (repeat) {
- parentSubscription.add(this.schedule(null, delay));
- }
- else {
- this.unsubscribe();
- }
- }, delay);
- parentSubscription.add(scheduleSubscription);
- if (!repeat) {
- return scheduleSubscription;
+ if (playbackInfo.speed > 1) {
+ newBitrateCeil /= playbackInfo.speed;
}
-}
-//# sourceMappingURL=executeSchedule.js.map
-
-/***/ }),
-
-/***/ 278:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "y": function() { return /* binding */ identity; }
-/* harmony export */ });
-function identity(x) {
- return x;
-}
-//# sourceMappingURL=identity.js.map
-
-/***/ }),
-
-/***/ 5685:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "z": function() { return /* binding */ isArrayLike; }
-/* harmony export */ });
-var isArrayLike = (function (x) { return x && typeof x.length === 'number' && typeof x !== 'function'; });
-//# sourceMappingURL=isArrayLike.js.map
-
-/***/ }),
-
-/***/ 8430:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "D": function() { return /* binding */ isAsyncIterable; }
-/* harmony export */ });
-/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8474);
-
-function isAsyncIterable(obj) {
- return Symbol.asyncIterator && (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(obj === null || obj === void 0 ? void 0 : obj[Symbol.asyncIterator]);
-}
-//# sourceMappingURL=isAsyncIterable.js.map
-
-/***/ }),
-
-/***/ 1454:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "q": function() { return /* binding */ isValidDate; }
-/* harmony export */ });
-function isValidDate(value) {
- return value instanceof Date && !isNaN(value);
-}
-//# sourceMappingURL=isDate.js.map
-
-/***/ }),
-
-/***/ 8474:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "m": function() { return /* binding */ isFunction; }
-/* harmony export */ });
-function isFunction(value) {
- return typeof value === 'function';
-}
-//# sourceMappingURL=isFunction.js.map
-
-/***/ }),
-
-/***/ 1764:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "c": function() { return /* binding */ isInteropObservable; }
-/* harmony export */ });
-/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6766);
-/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8474);
-
-
-function isInteropObservable(input) {
- return (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(input[_symbol_observable__WEBPACK_IMPORTED_MODULE_1__/* .observable */ .L]);
-}
-//# sourceMappingURL=isInteropObservable.js.map
-
-/***/ }),
-
-/***/ 1837:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "T": function() { return /* binding */ isIterable; }
-/* harmony export */ });
-/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9768);
-/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8474);
-
-
-function isIterable(input) {
- return (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(input === null || input === void 0 ? void 0 : input[_symbol_iterator__WEBPACK_IMPORTED_MODULE_1__/* .iterator */ .h]);
-}
-//# sourceMappingURL=isIterable.js.map
-
-/***/ }),
-
-/***/ 3841:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "t": function() { return /* binding */ isPromise; }
-/* harmony export */ });
-/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8474);
-
-function isPromise(value) {
- return (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(value === null || value === void 0 ? void 0 : value.then);
-}
-//# sourceMappingURL=isPromise.js.map
-
-/***/ }),
-
-/***/ 8671:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "L": function() { return /* binding */ isReadableStreamLike; },
-/* harmony export */ "Q": function() { return /* binding */ readableStreamLikeToAsyncGenerator; }
-/* harmony export */ });
-/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5987);
-/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8474);
-
-
-function readableStreamLikeToAsyncGenerator(readableStream) {
- return (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__asyncGenerator */ .FC)(this, arguments, function readableStreamLikeToAsyncGenerator_1() {
- var reader, _a, value, done;
- return (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__generator */ .Jh)(this, function (_b) {
- switch (_b.label) {
- case 0:
- reader = readableStream.getReader();
- _b.label = 1;
- case 1:
- _b.trys.push([1, , 9, 10]);
- _b.label = 2;
- case 2:
- if (false) {}
- return [4, (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__await */ .qq)(reader.read())];
- case 3:
- _a = _b.sent(), value = _a.value, done = _a.done;
- if (!done) return [3, 5];
- return [4, (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__await */ .qq)(void 0)];
- case 4: return [2, _b.sent()];
- case 5: return [4, (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__await */ .qq)(value)];
- case 6: return [4, _b.sent()];
- case 7:
- _b.sent();
- return [3, 2];
- case 8: return [3, 10];
- case 9:
- reader.releaseLock();
- return [7];
- case 10: return [2];
- }
- });
- });
-}
-function isReadableStreamLike(obj) {
- return (0,_isFunction__WEBPACK_IMPORTED_MODULE_1__/* .isFunction */ .m)(obj === null || obj === void 0 ? void 0 : obj.getReader);
-}
-//# sourceMappingURL=isReadableStreamLike.js.map
-
-/***/ }),
-
-/***/ 4865:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "K": function() { return /* binding */ isScheduler; }
-/* harmony export */ });
-/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8474);
-
-function isScheduler(value) {
- return value && (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(value.schedule);
-}
-//# sourceMappingURL=isScheduler.js.map
-
-/***/ }),
-
-/***/ 6798:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "e": function() { return /* binding */ operate; }
-/* harmony export */ });
-/* unused harmony export hasLift */
-/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8474);
-
-function hasLift(source) {
- return (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__/* .isFunction */ .m)(source === null || source === void 0 ? void 0 : source.lift);
-}
-function operate(init) {
- return function (source) {
- if (hasLift(source)) {
- return source.lift(function (liftedSource) {
- try {
- return init(liftedSource, this);
- }
- catch (err) {
- this.error(err);
- }
- });
- }
- throw new TypeError('Unable to lift unknown Observable type');
- };
-}
-//# sourceMappingURL=lift.js.map
-
-/***/ }),
-
-/***/ 3211:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "Z": function() { return /* binding */ mapOneOrManyArgs; }
-/* harmony export */ });
-/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5987);
-/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9127);
-
-
-var isArray = Array.isArray;
-function callOrApply(fn, args) {
- return isArray(args) ? fn.apply(void 0, (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__spreadArray */ .ev)([], (0,tslib__WEBPACK_IMPORTED_MODULE_0__/* .__read */ .CR)(args))) : fn(args);
-}
-function mapOneOrManyArgs(fn) {
- return (0,_operators_map__WEBPACK_IMPORTED_MODULE_1__/* .map */ .U)(function (args) { return callOrApply(fn, args); });
-}
-//# sourceMappingURL=mapOneOrManyArgs.js.map
-
-/***/ }),
-
-/***/ 2967:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "Z": function() { return /* binding */ noop; }
-/* harmony export */ });
-function noop() { }
-//# sourceMappingURL=noop.js.map
-
-/***/ }),
-
-/***/ 5:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "h": function() { return /* binding */ reportUnhandledError; }
-/* harmony export */ });
-/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3912);
-/* harmony import */ var _scheduler_timeoutProvider__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8380);
-
-
-function reportUnhandledError(err) {
- _scheduler_timeoutProvider__WEBPACK_IMPORTED_MODULE_0__/* .timeoutProvider.setTimeout */ .z.setTimeout(function () {
- var onUnhandledError = _config__WEBPACK_IMPORTED_MODULE_1__/* .config.onUnhandledError */ .v.onUnhandledError;
- if (onUnhandledError) {
- onUnhandledError(err);
- }
- else {
- throw err;
- }
- });
-}
-//# sourceMappingURL=reportUnhandledError.js.map
-
-/***/ }),
-
-/***/ 8729:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "z": function() { return /* binding */ createInvalidObservableTypeError; }
-/* harmony export */ });
-function createInvalidObservableTypeError(input) {
- return new TypeError("You provided " + (input !== null && typeof input === 'object' ? 'an invalid object' : "'" + input + "'") + " where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.");
-}
-//# sourceMappingURL=throwUnobservableError.js.map
-
-/***/ }),
-
-/***/ 5987:
-/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "CR": function() { return /* binding */ __read; },
-/* harmony export */ "FC": function() { return /* binding */ __asyncGenerator; },
-/* harmony export */ "Jh": function() { return /* binding */ __generator; },
-/* harmony export */ "KL": function() { return /* binding */ __asyncValues; },
-/* harmony export */ "XA": function() { return /* binding */ __values; },
-/* harmony export */ "ZT": function() { return /* binding */ __extends; },
-/* harmony export */ "ev": function() { return /* binding */ __spreadArray; },
-/* harmony export */ "mG": function() { return /* binding */ __awaiter; },
-/* harmony export */ "qq": function() { return /* binding */ __await; }
-/* harmony export */ });
-/* unused harmony exports __assign, __rest, __decorate, __param, __metadata, __createBinding, __exportStar, __spread, __spreadArrays, __asyncDelegator, __makeTemplateObject, __importStar, __importDefault, __classPrivateFieldGet, __classPrivateFieldSet */
-/*! *****************************************************************************
-Copyright (c) Microsoft Corporation.
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-***************************************************************************** */
-/* global Reflect, Promise */
-
-var extendStatics = function(d, b) {
- extendStatics = Object.setPrototypeOf ||
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
- return extendStatics(d, b);
-};
-
-function __extends(d, b) {
- if (typeof b !== "function" && b !== null)
- throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
- extendStatics(d, b);
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-}
-
-var __assign = function() {
- __assign = Object.assign || function __assign(t) {
- for (var s, i = 1, n = arguments.length; i < n; i++) {
- s = arguments[i];
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
- }
- return t;
- }
- return __assign.apply(this, arguments);
-}
-
-function __rest(s, e) {
- var t = {};
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
- t[p] = s[p];
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
- t[p[i]] = s[p[i]];
- }
- return t;
-}
-
-function __decorate(decorators, target, key, desc) {
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
- return c > 3 && r && Object.defineProperty(target, key, r), r;
-}
-
-function __param(paramIndex, decorator) {
- return function (target, key) { decorator(target, key, paramIndex); }
-}
-
-function __metadata(metadataKey, metadataValue) {
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
-}
-
-function __awaiter(thisArg, _arguments, P, generator) {
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
-}
-
-function __generator(thisArg, body) {
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
- function verb(n) { return function (v) { return step([n, v]); }; }
- function step(op) {
- if (f) throw new TypeError("Generator is already executing.");
- while (_) try {
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
- if (y = 0, t) op = [op[0] & 2, t.value];
- switch (op[0]) {
- case 0: case 1: t = op; break;
- case 4: _.label++; return { value: op[1], done: false };
- case 5: _.label++; y = op[1]; op = [0]; continue;
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
- default:
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
- if (t[2]) _.ops.pop();
- _.trys.pop(); continue;
- }
- op = body.call(thisArg, _);
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
- }
-}
-
-var __createBinding = Object.create ? (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
-}) : (function(o, m, k, k2) {
- if (k2 === undefined) k2 = k;
- o[k2] = m[k];
-});
-
-function __exportStar(m, o) {
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
-}
-
-function __values(o) {
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
- if (m) return m.call(o);
- if (o && typeof o.length === "number") return {
- next: function () {
- if (o && i >= o.length) o = void 0;
- return { value: o && o[i++], done: !o };
- }
- };
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
-}
-
-function __read(o, n) {
- var m = typeof Symbol === "function" && o[Symbol.iterator];
- if (!m) return o;
- var i = m.call(o), r, ar = [], e;
- try {
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
- }
- catch (error) { e = { error: error }; }
- finally {
- try {
- if (r && !r.done && (m = i["return"])) m.call(i);
- }
- finally { if (e) throw e.error; }
- }
- return ar;
-}
-
-/** @deprecated */
-function __spread() {
- for (var ar = [], i = 0; i < arguments.length; i++)
- ar = ar.concat(__read(arguments[i]));
- return ar;
-}
-
-/** @deprecated */
-function __spreadArrays() {
- for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
- for (var r = Array(s), k = 0, i = 0; i < il; i++)
- for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
- r[k] = a[j];
- return r;
-}
-
-function __spreadArray(to, from) {
- for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
- to[j] = from[i];
- return to;
-}
-
-function __await(v) {
- return this instanceof __await ? (this.v = v, this) : new __await(v);
-}
-
-function __asyncGenerator(thisArg, _arguments, generator) {
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
- var g = generator.apply(thisArg, _arguments || []), i, q = [];
- return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
- function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
- function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
- function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
- function fulfill(value) { resume("next", value); }
- function reject(value) { resume("throw", value); }
- function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
-}
-
-function __asyncDelegator(o) {
- var i, p;
- return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
- function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
-}
-
-function __asyncValues(o) {
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
- var m = o[Symbol.asyncIterator], i;
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
-}
-
-function __makeTemplateObject(cooked, raw) {
- if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
- return cooked;
-};
-
-var __setModuleDefault = Object.create ? (function(o, v) {
- Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
- o["default"] = v;
-};
-
-function __importStar(mod) {
- if (mod && mod.__esModule) return mod;
- var result = {};
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
- __setModuleDefault(result, mod);
- return result;
-}
-
-function __importDefault(mod) {
- return (mod && mod.__esModule) ? mod : { default: mod };
-}
-
-function __classPrivateFieldGet(receiver, privateMap) {
- if (!privateMap.has(receiver)) {
- throw new TypeError("attempted to get private field on non-instance");
- }
- return privateMap.get(receiver);
-}
-
-function __classPrivateFieldSet(receiver, privateMap, value) {
- if (!privateMap.has(receiver)) {
- throw new TypeError("attempted to set private field on non-instance");
- }
- privateMap.set(receiver, value);
- return value;
-}
-
-
-/***/ }),
-
-/***/ 7061:
-/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
-
-var _typeof = (__webpack_require__(8698)["default"]);
-
-function _regeneratorRuntime() {
- "use strict";
- /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
-
- module.exports = _regeneratorRuntime = function _regeneratorRuntime() {
- return exports;
- }, module.exports.__esModule = true, module.exports["default"] = module.exports;
- var exports = {},
- Op = Object.prototype,
- hasOwn = Op.hasOwnProperty,
- $Symbol = "function" == typeof Symbol ? Symbol : {},
- iteratorSymbol = $Symbol.iterator || "@@iterator",
- asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
- toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
-
- function define(obj, key, value) {
- return Object.defineProperty(obj, key, {
- value: value,
- enumerable: !0,
- configurable: !0,
- writable: !0
- }), obj[key];
- }
-
- try {
- define({}, "");
- } catch (err) {
- define = function define(obj, key, value) {
- return obj[key] = value;
+ return {
+ bandwidthEstimate: bandwidthEstimate,
+ bitrateChosen: newBitrateCeil
};
}
-
- function wrap(innerFn, outerFn, self, tryLocsList) {
- var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
- generator = Object.create(protoGenerator.prototype),
- context = new Context(tryLocsList || []);
- return generator._invoke = function (innerFn, self, context) {
- var state = "suspendedStart";
- return function (method, arg) {
- if ("executing" === state) throw new Error("Generator is already running");
-
- if ("completed" === state) {
- if ("throw" === method) throw arg;
- return doneResult();
- }
-
- for (context.method = method, context.arg = arg;;) {
- var delegate = context.delegate;
-
- if (delegate) {
- var delegateResult = maybeInvokeDelegate(delegate, context);
-
- if (delegateResult) {
- if (delegateResult === ContinueSentinel) continue;
- return delegateResult;
- }
- }
-
- if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
- if ("suspendedStart" === state) throw state = "completed", context.arg;
- context.dispatchException(context.arg);
- } else "return" === context.method && context.abrupt("return", context.arg);
- state = "executing";
- var record = tryCatch(innerFn, self, context);
-
- if ("normal" === record.type) {
- if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
- return {
- value: record.arg,
- done: context.done
- };
- }
-
- "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
- }
- };
- }(innerFn, self, context), generator;
- }
-
- function tryCatch(fn, obj, arg) {
- try {
- return {
- type: "normal",
- arg: fn.call(obj, arg)
- };
- } catch (err) {
- return {
- type: "throw",
- arg: err
- };
- }
- }
-
- exports.wrap = wrap;
- var ContinueSentinel = {};
-
- function Generator() {}
-
- function GeneratorFunction() {}
-
- function GeneratorFunctionPrototype() {}
-
- var IteratorPrototype = {};
- define(IteratorPrototype, iteratorSymbol, function () {
- return this;
- });
- var getProto = Object.getPrototypeOf,
- NativeIteratorPrototype = getProto && getProto(getProto(values([])));
- NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
- var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
-
- function defineIteratorMethods(prototype) {
- ["next", "throw", "return"].forEach(function (method) {
- define(prototype, method, function (arg) {
- return this._invoke(method, arg);
- });
- });
- }
-
- function AsyncIterator(generator, PromiseImpl) {
- function invoke(method, arg, resolve, reject) {
- var record = tryCatch(generator[method], generator, arg);
-
- if ("throw" !== record.type) {
- var result = record.arg,
- value = result.value;
- return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
- invoke("next", value, resolve, reject);
- }, function (err) {
- invoke("throw", err, resolve, reject);
- }) : PromiseImpl.resolve(value).then(function (unwrapped) {
- result.value = unwrapped, resolve(result);
- }, function (error) {
- return invoke("throw", error, resolve, reject);
- });
- }
-
- reject(record.arg);
- }
-
- var previousPromise;
-
- this._invoke = function (method, arg) {
- function callInvokeWithMethodAndArg() {
- return new PromiseImpl(function (resolve, reject) {
- invoke(method, arg, resolve, reject);
- });
- }
-
- return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
- };
- }
-
- function maybeInvokeDelegate(delegate, context) {
- var method = delegate.iterator[context.method];
-
- if (undefined === method) {
- if (context.delegate = null, "throw" === context.method) {
- if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel;
- context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method");
- }
-
- return ContinueSentinel;
- }
-
- var record = tryCatch(method, delegate.iterator, context.arg);
- if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
- var info = record.arg;
- return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel);
- }
-
- function pushTryEntry(locs) {
- var entry = {
- tryLoc: locs[0]
- };
- 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
- }
-
- function resetTryEntry(entry) {
- var record = entry.completion || {};
- record.type = "normal", delete record.arg, entry.completion = record;
- }
-
- function Context(tryLocsList) {
- this.tryEntries = [{
- tryLoc: "root"
- }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
- }
-
- function values(iterable) {
- if (iterable) {
- var iteratorMethod = iterable[iteratorSymbol];
- if (iteratorMethod) return iteratorMethod.call(iterable);
- if ("function" == typeof iterable.next) return iterable;
-
- if (!isNaN(iterable.length)) {
- var i = -1,
- next = function next() {
- for (; ++i < iterable.length;) {
- if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;
- }
-
- return next.value = undefined, next.done = !0, next;
- };
-
- return next.next = next;
- }
- }
-
- return {
- next: doneResult
- };
- }
-
- function doneResult() {
- return {
- value: undefined,
- done: !0
- };
- }
-
- return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
- var ctor = "function" == typeof genFun && genFun.constructor;
- return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
- }, exports.mark = function (genFun) {
- return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun;
- }, exports.awrap = function (arg) {
- return {
- __await: arg
- };
- }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
- return this;
- }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
- void 0 === PromiseImpl && (PromiseImpl = Promise);
- var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
- return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
- return result.done ? result.value : iter.next();
- });
- }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
- return this;
- }), define(Gp, "toString", function () {
- return "[object Generator]";
- }), exports.keys = function (object) {
- var keys = [];
-
- for (var key in object) {
- keys.push(key);
- }
-
- return keys.reverse(), function next() {
- for (; keys.length;) {
- var key = keys.pop();
- if (key in object) return next.value = key, next.done = !1, next;
- }
-
- return next.done = !0, next;
- };
- }, exports.values = values, Context.prototype = {
- constructor: Context,
- reset: function reset(skipTempReset) {
- if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) {
- "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);
- }
- },
- stop: function stop() {
- this.done = !0;
- var rootRecord = this.tryEntries[0].completion;
- if ("throw" === rootRecord.type) throw rootRecord.arg;
- return this.rval;
- },
- dispatchException: function dispatchException(exception) {
- if (this.done) throw exception;
- var context = this;
-
- function handle(loc, caught) {
- return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
- }
-
- for (var i = this.tryEntries.length - 1; i >= 0; --i) {
- var entry = this.tryEntries[i],
- record = entry.completion;
- if ("root" === entry.tryLoc) return handle("end");
-
- if (entry.tryLoc <= this.prev) {
- var hasCatch = hasOwn.call(entry, "catchLoc"),
- hasFinally = hasOwn.call(entry, "finallyLoc");
-
- if (hasCatch && hasFinally) {
- if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
- if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
- } else if (hasCatch) {
- if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
- } else {
- if (!hasFinally) throw new Error("try statement without catch or finally");
- if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
- }
- }
- }
- },
- abrupt: function abrupt(type, arg) {
- for (var i = this.tryEntries.length - 1; i >= 0; --i) {
- var entry = this.tryEntries[i];
-
- if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
- var finallyEntry = entry;
- break;
- }
- }
-
- finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
- var record = finallyEntry ? finallyEntry.completion : {};
- return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
- },
- complete: function complete(record, afterLoc) {
- if ("throw" === record.type) throw record.arg;
- return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;
- },
- finish: function finish(finallyLoc) {
- for (var i = this.tryEntries.length - 1; i >= 0; --i) {
- var entry = this.tryEntries[i];
- if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
- }
- },
- "catch": function _catch(tryLoc) {
- for (var i = this.tryEntries.length - 1; i >= 0; --i) {
- var entry = this.tryEntries[i];
-
- if (entry.tryLoc === tryLoc) {
- var record = entry.completion;
-
- if ("throw" === record.type) {
- var thrown = record.arg;
- resetTryEntry(entry);
- }
-
- return thrown;
- }
- }
-
- throw new Error("illegal catch attempt");
- },
- delegateYield: function delegateYield(iterable, resultName, nextLoc) {
- return this.delegate = {
- iterator: values(iterable),
- resultName: resultName,
- nextLoc: nextLoc
- }, "next" === this.method && (this.arg = undefined), ContinueSentinel;
+ /**
+ * For a given wanted bitrate, tells if should switch urgently.
+ * @param {number} bitrate - The new estimated bitrate.
+ * @param {Object|null} currentRepresentation - The Representation being
+ * presently being loaded.
+ * @param {Array.} currentRequests - All segment requests by segment's
+ * start chronological order
+ * @param {Object} playbackInfo - Information on the current playback.
+ * @returns {boolean}
+ */;
+ _proto.isUrgent = function isUrgent(bitrate, currentRepresentation, currentRequests, playbackInfo) {
+ if (currentRepresentation === null) {
+ return true;
+ } else if (bitrate === currentRepresentation.bitrate) {
+ return false;
+ } else if (bitrate > currentRepresentation.bitrate) {
+ return !this._inStarvationMode;
}
- }, exports;
-}
-
-module.exports = _regeneratorRuntime, module.exports.__esModule = true, module.exports["default"] = module.exports;
-
-/***/ }),
-
-/***/ 8698:
-/***/ (function(module) {
-
-function _typeof(obj) {
- "@babel/helpers - typeof";
-
- return (module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
- return typeof obj;
- } : function (obj) {
- return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
- }, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(obj);
-}
-
-module.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports;
-
-/***/ }),
-
-/***/ 4687:
-/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
-
-// TODO(Babel 8): Remove this file.
-
-var runtime = __webpack_require__(7061)();
-module.exports = runtime;
-
-// Copied from https://github.com/facebook/regenerator/blob/main/packages/runtime/runtime.js#L736=
-try {
- regeneratorRuntime = runtime;
-} catch (accidentalStrictMode) {
- if (typeof globalThis === "object") {
- globalThis.regeneratorRuntime = runtime;
- } else {
- Function("r", "regeneratorRuntime = r")(runtime);
- }
-}
-
-
-/***/ }),
-
-/***/ 7326:
-/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "Z": function() { return /* binding */ _assertThisInitialized; }
-/* harmony export */ });
-function _assertThisInitialized(self) {
- if (self === void 0) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
-
- return self;
-}
-
-/***/ }),
-
-/***/ 5861:
-/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "Z": function() { return /* binding */ _asyncToGenerator; }
-/* harmony export */ });
-function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
- try {
- var info = gen[key](arg);
- var value = info.value;
- } catch (error) {
- reject(error);
- return;
- }
-
- if (info.done) {
- resolve(value);
- } else {
- Promise.resolve(value).then(_next, _throw);
- }
-}
-
-function _asyncToGenerator(fn) {
- return function () {
- var self = this,
- args = arguments;
- return new Promise(function (resolve, reject) {
- var gen = fn.apply(self, args);
-
- function _next(value) {
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
- }
-
- function _throw(err) {
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
- }
-
- _next(undefined);
- });
- };
-}
-
-/***/ }),
-
-/***/ 3144:
-/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "Z": function() { return /* binding */ _createClass; }
-/* harmony export */ });
-function _defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
-}
-
-function _createClass(Constructor, protoProps, staticProps) {
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
- if (staticProps) _defineProperties(Constructor, staticProps);
- Object.defineProperty(Constructor, "prototype", {
- writable: false
- });
- return Constructor;
-}
-
-/***/ }),
-
-/***/ 4578:
-/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "Z": function() { return /* binding */ _inheritsLoose; }
-/* harmony export */ });
-/* harmony import */ var _setPrototypeOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9611);
-
-function _inheritsLoose(subClass, superClass) {
- subClass.prototype = Object.create(superClass.prototype);
- subClass.prototype.constructor = subClass;
- (0,_setPrototypeOf_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(subClass, superClass);
-}
-
-/***/ }),
-
-/***/ 9611:
-/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "Z": function() { return /* binding */ _setPrototypeOf; }
-/* harmony export */ });
-function _setPrototypeOf(o, p) {
- _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
- o.__proto__ = p;
- return o;
- };
- return _setPrototypeOf(o, p);
-}
-
-/***/ }),
-
-/***/ 2146:
-/***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-
-// EXPORTS
-__webpack_require__.d(__webpack_exports__, {
- "Z": function() { return /* binding */ _wrapNativeSuper; }
-});
-
-;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js
-function _getPrototypeOf(o) {
- _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
- return o.__proto__ || Object.getPrototypeOf(o);
+ return shouldDirectlySwitchToLowBitrate(playbackInfo, currentRequests, this._lowLatencyMode);
};
- return _getPrototypeOf(o);
-}
-// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js
-var setPrototypeOf = __webpack_require__(9611);
-;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/isNativeFunction.js
-function _isNativeFunction(fn) {
- return Function.toString.call(fn).indexOf("[native code]") !== -1;
-}
-;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/isNativeReflectConstruct.js
-function _isNativeReflectConstruct() {
- if (typeof Reflect === "undefined" || !Reflect.construct) return false;
- if (Reflect.construct.sham) return false;
- if (typeof Proxy === "function") return true;
-
- try {
- Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
- return true;
- } catch (e) {
- return false;
- }
-}
-;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/construct.js
-
-
-function _construct(Parent, args, Class) {
- if (_isNativeReflectConstruct()) {
- _construct = Reflect.construct.bind();
- } else {
- _construct = function _construct(Parent, args, Class) {
- var a = [null];
- a.push.apply(a, args);
- var Constructor = Function.bind.apply(Parent, a);
- var instance = new Constructor();
- if (Class) (0,setPrototypeOf/* default */.Z)(instance, Class.prototype);
- return instance;
- };
- }
-
- return _construct.apply(null, arguments);
-}
-;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js
-
-
-
-
-function _wrapNativeSuper(Class) {
- var _cache = typeof Map === "function" ? new Map() : undefined;
-
- _wrapNativeSuper = function _wrapNativeSuper(Class) {
- if (Class === null || !_isNativeFunction(Class)) return Class;
-
- if (typeof Class !== "function") {
- throw new TypeError("Super expression must either be null or a function");
- }
-
- if (typeof _cache !== "undefined") {
- if (_cache.has(Class)) return _cache.get(Class);
-
- _cache.set(Class, Wrapper);
- }
-
- function Wrapper() {
- return _construct(Class, arguments, _getPrototypeOf(this).constructor);
- }
-
- Wrapper.prototype = Object.create(Class.prototype, {
- constructor: {
- value: Wrapper,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- return (0,setPrototypeOf/* default */.Z)(Wrapper, Class);
- };
-
- return _wrapNativeSuper(Class);
-}
-
-/***/ })
-
-/******/ });
-/************************************************************************/
-/******/ // The module cache
-/******/ var __webpack_module_cache__ = {};
-/******/
-/******/ // The require function
-/******/ function __webpack_require__(moduleId) {
-/******/ // Check if module is in cache
-/******/ var cachedModule = __webpack_module_cache__[moduleId];
-/******/ if (cachedModule !== undefined) {
-/******/ return cachedModule.exports;
-/******/ }
-/******/ // Create a new module (and put it into the cache)
-/******/ var module = __webpack_module_cache__[moduleId] = {
-/******/ // no module.id needed
-/******/ // no module.loaded needed
-/******/ exports: {}
-/******/ };
-/******/
-/******/ // Execute the module function
-/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
-/******/
-/******/ // Return the exports of the module
-/******/ return module.exports;
-/******/ }
-/******/
-/************************************************************************/
-/******/ /* webpack/runtime/compat get default export */
-/******/ !function() {
-/******/ // getDefaultExport function for compatibility with non-harmony modules
-/******/ __webpack_require__.n = function(module) {
-/******/ var getter = module && module.__esModule ?
-/******/ function() { return module['default']; } :
-/******/ function() { return module; };
-/******/ __webpack_require__.d(getter, { a: getter });
-/******/ return getter;
-/******/ };
-/******/ }();
-/******/
-/******/ /* webpack/runtime/define property getters */
-/******/ !function() {
-/******/ // define getter functions for harmony exports
-/******/ __webpack_require__.d = function(exports, definition) {
-/******/ for(var key in definition) {
-/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
-/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
-/******/ }
-/******/ }
-/******/ };
-/******/ }();
-/******/
-/******/ /* webpack/runtime/hasOwnProperty shorthand */
-/******/ !function() {
-/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
-/******/ }();
-/******/
-/************************************************************************/
-var __webpack_exports__ = {};
-// This entry need to be wrapped in an IIFE because it need to be in strict mode.
-!function() {
-"use strict";
-
-// EXPORTS
-__webpack_require__.d(__webpack_exports__, {
- "default": function() { return /* binding */ src; }
-});
-
-// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/createClass.js
-var createClass = __webpack_require__(3144);
-// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js
-var inheritsLoose = __webpack_require__(4578);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/Subject.js + 1 modules
-var Subject = __webpack_require__(6716);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/take.js
-var take = __webpack_require__(4727);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/takeUntil.js
-var takeUntil = __webpack_require__(3505);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/map.js
-var map = __webpack_require__(9127);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/identity.js
-var identity = __webpack_require__(278);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/lift.js
-var lift = __webpack_require__(6798);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/OperatorSubscriber.js
-var OperatorSubscriber = __webpack_require__(2566);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/distinctUntilChanged.js
-
-
-
-function distinctUntilChanged(comparator, keySelector) {
- if (keySelector === void 0) { keySelector = identity/* identity */.y; }
- comparator = comparator !== null && comparator !== void 0 ? comparator : defaultCompare;
- return (0,lift/* operate */.e)(function (source, subscriber) {
- var previousKey;
- var first = true;
- source.subscribe((0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, function (value) {
- var currentKey = keySelector(value);
- if (first || !comparator(previousKey, currentKey)) {
- first = false;
- previousKey = currentKey;
- subscriber.next(value);
- }
- }));
- });
-}
-function defaultCompare(a, b) {
- return a === b;
-}
-//# sourceMappingURL=distinctUntilChanged.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/Observable.js + 1 modules
-var Observable = __webpack_require__(1480);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/of.js
-var of = __webpack_require__(2817);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/mergeMap.js + 1 modules
-var mergeMap = __webpack_require__(7877);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/shareReplay.js
-var shareReplay = __webpack_require__(8515);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/defer.js
-var defer = __webpack_require__(9917);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/connectable.js
-
-
-
-var DEFAULT_CONFIG = {
- connector: function () { return new Subject/* Subject */.x(); },
- resetOnDisconnect: true,
-};
-function connectable(source, config) {
- if (config === void 0) { config = DEFAULT_CONFIG; }
- var connection = null;
- var connector = config.connector, _a = config.resetOnDisconnect, resetOnDisconnect = _a === void 0 ? true : _a;
- var subject = connector();
- var result = new Observable/* Observable */.y(function (subscriber) {
- return subject.subscribe(subscriber);
- });
- result.connect = function () {
- if (!connection || connection.closed) {
- connection = (0,defer/* defer */.P)(function () { return source; }).subscribe(subject);
- if (resetOnDisconnect) {
- connection.add(function () { return (subject = connector()); });
- }
- }
- return connection;
- };
- return result;
-}
-//# sourceMappingURL=connectable.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/filter.js
-var filter = __webpack_require__(4975);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/share.js
-var share = __webpack_require__(5583);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/util/argsArgArrayOrObject.js
-var isArray = Array.isArray;
-var getPrototypeOf = Object.getPrototypeOf, objectProto = Object.prototype, getKeys = Object.keys;
-function argsArgArrayOrObject(args) {
- if (args.length === 1) {
- var first_1 = args[0];
- if (isArray(first_1)) {
- return { args: first_1, keys: null };
- }
- if (isPOJO(first_1)) {
- var keys = getKeys(first_1);
- return {
- args: keys.map(function (key) { return first_1[key]; }),
- keys: keys,
- };
- }
- }
- return { args: args, keys: null };
-}
-function isPOJO(obj) {
- return obj && typeof obj === 'object' && getPrototypeOf(obj) === objectProto;
-}
-//# sourceMappingURL=argsArgArrayOrObject.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/from.js + 8 modules
-var from = __webpack_require__(3102);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/mapOneOrManyArgs.js
-var mapOneOrManyArgs = __webpack_require__(3211);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/args.js
-var util_args = __webpack_require__(2457);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/util/createObject.js
-function createObject(keys, values) {
- return keys.reduce(function (result, key, i) { return ((result[key] = values[i]), result); }, {});
-}
-//# sourceMappingURL=createObject.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/util/executeSchedule.js
-var executeSchedule = __webpack_require__(7845);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/combineLatest.js
-
-
-
-
-
-
-
-
-
-function combineLatest() {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- var scheduler = (0,util_args/* popScheduler */.yG)(args);
- var resultSelector = (0,util_args/* popResultSelector */.jO)(args);
- var _a = argsArgArrayOrObject(args), observables = _a.args, keys = _a.keys;
- if (observables.length === 0) {
- return (0,from/* from */.D)([], scheduler);
- }
- var result = new Observable/* Observable */.y(combineLatestInit(observables, scheduler, keys
- ?
- function (values) { return createObject(keys, values); }
- :
- identity/* identity */.y));
- return resultSelector ? result.pipe((0,mapOneOrManyArgs/* mapOneOrManyArgs */.Z)(resultSelector)) : result;
-}
-function combineLatestInit(observables, scheduler, valueTransform) {
- if (valueTransform === void 0) { valueTransform = identity/* identity */.y; }
- return function (subscriber) {
- maybeSchedule(scheduler, function () {
- var length = observables.length;
- var values = new Array(length);
- var active = length;
- var remainingFirstValues = length;
- var _loop_1 = function (i) {
- maybeSchedule(scheduler, function () {
- var source = (0,from/* from */.D)(observables[i], scheduler);
- var hasFirstValue = false;
- source.subscribe((0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, function (value) {
- values[i] = value;
- if (!hasFirstValue) {
- hasFirstValue = true;
- remainingFirstValues--;
- }
- if (!remainingFirstValues) {
- subscriber.next(valueTransform(values.slice()));
- }
- }, function () {
- if (!--active) {
- subscriber.complete();
- }
- }));
- }, subscriber);
- };
- for (var i = 0; i < length; i++) {
- _loop_1(i);
- }
- }, subscriber);
- };
-}
-function maybeSchedule(scheduler, execute, subscription) {
- if (scheduler) {
- (0,executeSchedule/* executeSchedule */.f)(subscription, scheduler, execute);
- }
- else {
- execute();
- }
-}
-//# sourceMappingURL=combineLatest.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/startWith.js
-var startWith = __webpack_require__(6108);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/concat.js + 1 modules
-var concat = __webpack_require__(2034);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/switchMap.js
-var switchMap = __webpack_require__(4978);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/merge.js
-var merge = __webpack_require__(3071);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/empty.js
-var empty = __webpack_require__(1545);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/skipWhile.js
-
-
-function skipWhile(predicate) {
- return (0,lift/* operate */.e)(function (source, subscriber) {
- var taking = false;
- var index = 0;
- source.subscribe((0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, function (value) { return (taking || (taking = !predicate(value, index++))) && subscriber.next(value); }));
- });
-}
-//# sourceMappingURL=skipWhile.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/tap.js
-var tap = __webpack_require__(2006);
-// EXTERNAL MODULE: ./src/compat/event_listeners.ts + 1 modules
-var event_listeners = __webpack_require__(1381);
-;// CONCATENATED MODULE: ./src/compat/get_start_date.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * Calculating a live-offseted media position necessitate to obtain first an
- * offset, and then adding that offset to the wanted position.
- *
- * That offset is in most case present inside the Manifest file, yet in cases
- * without it or without a Manifest, such as the "directfile" mode, the RxPlayer
- * won't know that offset.
- *
- * Thankfully Safari declares a `getStartDate` method allowing to obtain that
- * offset when available. This logic is mainly useful when playing HLS contents
- * in directfile mode on Safari.
- * @param {HTMLMediaElement} mediaElement
- * @returns {number|undefined}
- */
-function getStartDate(mediaElement) {
- var _mediaElement = mediaElement;
- if (typeof _mediaElement.getStartDate === "function") {
- var startDate = _mediaElement.getStartDate();
- if (typeof startDate === "object" && startDate !== null) {
- var startDateNum = +startDate;
- if (!isNaN(startDateNum)) {
- return startDateNum / 1000;
- }
- } else if (typeof startDate === "number" && !isNaN(startDate)) {
- return startDate;
- }
- }
-}
-;// CONCATENATED MODULE: ./src/compat/fullscreen.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * Request fullScreen action on a given element.
- * @param {HTMLElement} elt
- */
-function requestFullscreen(element) {
- if (!fullscreen_isFullscreen()) {
- var elt = element;
- /* eslint-disable @typescript-eslint/unbound-method */
- if (typeof elt.requestFullscreen === "function") {
- /* eslint-enable @typescript-eslint/unbound-method */
- /* eslint-disable @typescript-eslint/no-floating-promises */
- elt.requestFullscreen();
- /* eslint-enable @typescript-eslint/no-floating-promises */
- } else if (typeof elt.msRequestFullscreen === "function") {
- elt.msRequestFullscreen();
- } else if (typeof elt.mozRequestFullScreen === "function") {
- elt.mozRequestFullScreen();
- } else if (typeof elt.webkitRequestFullscreen === "function") {
- elt.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
- }
- }
-}
-/**
- * Exit fullscreen if an element is currently in fullscreen.
- */
-function fullscreen_exitFullscreen() {
- if (fullscreen_isFullscreen()) {
- var doc = document;
- /* eslint-disable @typescript-eslint/unbound-method */
- if (typeof doc.exitFullscreen === "function") {
- /* eslint-enable @typescript-eslint/unbound-method */
- /* eslint-disable @typescript-eslint/no-floating-promises */
- doc.exitFullscreen();
- /* eslint-enable @typescript-eslint/no-floating-promises */
- } else if (typeof doc.msExitFullscreen === "function") {
- doc.msExitFullscreen();
- } else if (typeof doc.mozCancelFullScreen === "function") {
- doc.mozCancelFullScreen();
- } else if (typeof doc.webkitExitFullscreen === "function") {
- doc.webkitExitFullscreen();
- }
- }
-}
-/**
- * Returns true if an element in the document is being displayed in fullscreen
- * mode;
- * otherwise it's false.
- * @returns {boolean}
- */
-function fullscreen_isFullscreen() {
- var doc = document;
- return doc.fullscreenElement != null || doc.mozFullScreenElement != null || doc.webkitFullscreenElement != null || doc.msFullscreenElement != null;
-}
-
-// EXTERNAL MODULE: ./src/compat/browser_detection.ts
-var browser_detection = __webpack_require__(3666);
-// EXTERNAL MODULE: ./src/log.ts + 1 modules
-var log = __webpack_require__(3887);
-;// CONCATENATED MODULE: ./src/compat/browser_version.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/**
- * Returns either :
- * - 'null' when the current browser is not Firefox.
- * - '-1' when it is impossible to get the Firefox version
- * - A number above 0 that is the Firefox version number
- * @returns {number|null}
- */
-function getFirefoxVersion() {
- if (!browser_detection/* isFirefox */.vU) {
- log/* default.warn */.Z.warn("Compat: Can't access Firefox version on no firefox browser.");
- return null;
- }
- var userAgent = navigator.userAgent;
- var match = /Firefox\/([0-9]+)\./.exec(userAgent);
- if (match === null) {
- return -1;
- }
- var result = parseInt(match[1], 10);
- if (isNaN(result)) {
- return -1;
- }
- return result;
-}
-
-;// CONCATENATED MODULE: ./src/compat/can_rely_on_video_visibility_and_size.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/**
- * This functions tells if the RxPlayer can trust on any browser data
- * about video element visibility and size.
- *
- * On Firefox (version >= 67) :
- * - The PIP feature exists but can be disabled by default according
- * to the OS and the channel used for updating / getting Firefox binaries.
- * - There is no API to know if the Picture-in-picture (PIP) is enabled
- * - There is no API to get the width of the PIP window
- *
- * The element clientWidth tells the width of the original video element, and
- * no PIP window API exists to determine its presence or width. Thus, there are
- * no way to determine the real width of the video window, as we can't know when
- * the PIP feature or window is enabled, and we can't have access to the windo
- * size information.
- *
- * Moreover, when the document is considered as hidden (e.g. in case of hidden
- * tab), as there is no way to know if the PIP feature or window is enabled,
- * we can't know if the video window is visible or not.
- * @returns {boolean}
- */
-function canRelyOnVideoVisibilityAndSize() {
- if (!browser_detection/* isFirefox */.vU) {
- return true;
- }
- var firefoxVersion = getFirefoxVersion();
- if (firefoxVersion === null || firefoxVersion < 67) {
- return true;
- }
- var proto = HTMLVideoElement === null || HTMLVideoElement === void 0 ? void 0 : HTMLVideoElement.prototype;
- return (proto === null || proto === void 0 ? void 0 : proto.requirePictureInPicture) !== undefined;
-}
-// EXTERNAL MODULE: ./src/config.ts + 2 modules
-var config = __webpack_require__(6872);
-// EXTERNAL MODULE: ./src/errors/media_error.ts
-var media_error = __webpack_require__(3714);
-// EXTERNAL MODULE: ./src/errors/format_error.ts
-var format_error = __webpack_require__(8750);
-// EXTERNAL MODULE: ./src/errors/error_codes.ts
-var error_codes = __webpack_require__(5992);
-// EXTERNAL MODULE: ./src/features/index.ts
-var features = __webpack_require__(7874);
-// EXTERNAL MODULE: ./src/manifest/index.ts + 6 modules
-var manifest = __webpack_require__(1989);
-// EXTERNAL MODULE: ./src/utils/are_arrays_of_numbers_equal.ts
-var are_arrays_of_numbers_equal = __webpack_require__(4791);
-// EXTERNAL MODULE: ./src/utils/event_emitter.ts
-var event_emitter = __webpack_require__(1959);
-// EXTERNAL MODULE: ./src/utils/is_null_or_undefined.ts
-var is_null_or_undefined = __webpack_require__(1946);
-// EXTERNAL MODULE: ./src/utils/object_assign.ts
-var object_assign = __webpack_require__(8026);
-// EXTERNAL MODULE: ./src/utils/ranges.ts
-var ranges = __webpack_require__(2829);
-// EXTERNAL MODULE: ./src/utils/reference.ts
-var reference = __webpack_require__(5095);
-// EXTERNAL MODULE: ./src/utils/task_canceller.ts
-var task_canceller = __webpack_require__(288);
-// EXTERNAL MODULE: ./src/utils/warn_once.ts
-var warn_once = __webpack_require__(8806);
-// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js
-var asyncToGenerator = __webpack_require__(5861);
-// EXTERNAL MODULE: ./node_modules/@babel/runtime/regenerator/index.js
-var regenerator = __webpack_require__(4687);
-var regenerator_default = /*#__PURE__*/__webpack_require__.n(regenerator);
-// EXTERNAL MODULE: ./src/compat/eme/custom_media_keys/index.ts + 7 modules
-var custom_media_keys = __webpack_require__(6139);
-// EXTERNAL MODULE: ./src/core/decrypt/utils/media_keys_infos_store.ts
-var media_keys_infos_store = __webpack_require__(770);
-;// CONCATENATED MODULE: ./src/core/decrypt/dispose_decryption_resources.ts
-
-
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-/**
- * Free up all ressources taken by the content decryption logic.
- * @param {HTMLMediaElement} mediaElement
- * @returns {Promise}
- */
-function disposeDecryptionResources(_x) {
- return _disposeDecryptionResources.apply(this, arguments);
-}
-function _disposeDecryptionResources() {
- _disposeDecryptionResources = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(mediaElement) {
- var currentState, loadedSessionsStore;
- return regenerator_default().wrap(function _callee$(_context) {
- while (1) {
- switch (_context.prev = _context.next) {
- case 0:
- currentState = media_keys_infos_store/* default.getState */.Z.getState(mediaElement);
- if (!(currentState === null)) {
- _context.next = 3;
- break;
- }
- return _context.abrupt("return");
- case 3:
- log/* default.info */.Z.info("DRM: Disposing of the current MediaKeys");
- loadedSessionsStore = currentState.loadedSessionsStore;
- media_keys_infos_store/* default.clearState */.Z.clearState(mediaElement);
- _context.next = 8;
- return loadedSessionsStore.closeAllSessions();
- case 8:
- (0,custom_media_keys/* setMediaKeys */.Y)(mediaElement, null);
- case 9:
- case "end":
- return _context.stop();
- }
- }
- }, _callee);
- }));
- return _disposeDecryptionResources.apply(this, arguments);
-}
-;// CONCATENATED MODULE: ./src/core/decrypt/get_current_key_system.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Returns the name of the current key system used.
- * @param {HTMLMediaElement} mediaElement
- * @returns {string|null}
- */
-function get_current_key_system_getCurrentKeySystem(mediaElement) {
- var currentState = media_keys_infos_store/* default.getState */.Z.getState(mediaElement);
- return currentState == null ? null : currentState.keySystemOptions.type;
-}
-;// CONCATENATED MODULE: ./src/compat/should_unset_media_keys.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Returns true if the mediakeys associated to a media element should be
- * unset once the content is stopped.
- * Depends on the target.
- * @returns {Boolean}
- */
-function shouldUnsetMediaKeys() {
- return browser_detection/* isIE11 */.fq;
-}
-;// CONCATENATED MODULE: ./src/core/decrypt/clear_on_stop.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-
-/**
- * Clear DRM-related resources that should be cleared when the current content
- * stops its playback.
- * @param {HTMLMediaElement} mediaElement
- * @returns {Observable}
- */
-function clearOnStop(mediaElement) {
- log/* default.info */.Z.info("DRM: Clearing-up DRM session.");
- if (shouldUnsetMediaKeys()) {
- log/* default.info */.Z.info("DRM: disposing current MediaKeys.");
- return disposeDecryptionResources(mediaElement);
- }
- var currentState = media_keys_infos_store/* default.getState */.Z.getState(mediaElement);
- if (currentState !== null && currentState.keySystemOptions.closeSessionsOnStop === true) {
- log/* default.info */.Z.info("DRM: closing all current sessions.");
- return currentState.loadedSessionsStore.closeAllSessions();
- }
- log/* default.info */.Z.info("DRM: Nothing to clear. Returning right away. No state =", currentState === null);
- return Promise.resolve();
-}
-// EXTERNAL MODULE: ./src/utils/assert.ts
-var assert = __webpack_require__(811);
-// EXTERNAL MODULE: ./src/errors/request_error.ts
-var request_error = __webpack_require__(9105);
-// EXTERNAL MODULE: ./src/errors/network_error.ts
-var network_error = __webpack_require__(9362);
-;// CONCATENATED MODULE: ./src/core/fetchers/utils/error_selector.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Generate a new error from the infos given.
- * @param {string} code
- * @param {Error} error
- * @returns {Error}
- */
-function errorSelector(error) {
- if (error instanceof request_error/* default */.Z) {
- return new network_error/* default */.Z("PIPELINE_LOAD_ERROR", error);
- }
- return (0,format_error/* default */.Z)(error, {
- defaultCode: "PIPELINE_LOAD_ERROR",
- defaultReason: "Unknown error when fetching the Manifest"
- });
-}
-;// CONCATENATED MODULE: ./src/compat/is_offline.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * Some browsers have a builtin API to know if it's connected at least to a
- * LAN network, at most to the internet.
- *
- * /!\ This feature can be dangerous as you can both have false positives and
- * false negatives.
- *
- * False positives:
- * - you can still play local contents (on localhost) if isOffline == true
- * - on some browsers isOffline might be true even if we're connected to a LAN
- * or a router (it would mean we're just not able to connect to the
- * Internet). So we can eventually play LAN contents if isOffline == true
- *
- * False negatives:
- * - in some cases, we even might have isOffline at false when we do not have
- * any connection:
- * - in browsers that do not support the feature
- * - in browsers running in some virtualization softwares where the
- * network adapters are always connected.
- *
- * Use with these cases in mind.
- * @returns {Boolean}
- */
-function isOffline() {
- /* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
- return navigator.onLine === false;
- /* eslint-enable @typescript-eslint/no-unnecessary-boolean-literal-compare */
-}
-// EXTERNAL MODULE: ./src/errors/custom_loader_error.ts
-var custom_loader_error = __webpack_require__(7839);
-// EXTERNAL MODULE: ./src/errors/is_known_error.ts
-var is_known_error = __webpack_require__(9822);
-// EXTERNAL MODULE: ./src/utils/cancellable_sleep.ts
-var cancellable_sleep = __webpack_require__(7864);
-// EXTERNAL MODULE: ./src/utils/get_fuzzed_delay.ts
-var get_fuzzed_delay = __webpack_require__(2572);
-// EXTERNAL MODULE: ./src/utils/noop.ts
-var noop = __webpack_require__(8894);
-;// CONCATENATED MODULE: ./src/core/fetchers/utils/schedule_request.ts
-
-
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-
-
-
-
-/**
- * Called on a loader error.
- * Returns whether the loader request should be retried.
- *
- * TODO the notion of retrying or not could be transport-specific (e.g. 412 are
- * mainly used for Smooth contents) and thus as part of the transport code (e.g.
- * by rejecting with an error always having a `canRetry` property?).
- * Or not, to ponder.
- *
- * @param {Error} error
- * @returns {Boolean} - If true, the request can be retried.
- */
-function shouldRetry(error) {
- if (error instanceof request_error/* default */.Z) {
- if (error.type === error_codes/* NetworkErrorTypes.ERROR_HTTP_CODE */.br.ERROR_HTTP_CODE) {
- return error.status >= 500 || error.status === 404 || error.status === 415 ||
- // some CDN seems to use that code when
- // requesting low-latency segments too much
- // in advance
- error.status === 412;
- }
- return error.type === error_codes/* NetworkErrorTypes.TIMEOUT */.br.TIMEOUT || error.type === error_codes/* NetworkErrorTypes.ERROR_EVENT */.br.ERROR_EVENT;
- } else if (error instanceof custom_loader_error/* default */.Z) {
- if (typeof error.canRetry === "boolean") {
- return error.canRetry;
- }
- if (error.xhr !== undefined) {
- return error.xhr.status >= 500 || error.xhr.status === 404 || error.xhr.status === 415 ||
- // some CDN seems to use that code when
- // requesting low-latency segments too much
- // in advance
- error.xhr.status === 412;
- }
- return false;
- }
- return (0,is_known_error/* default */.Z)(error) && error.code === "INTEGRITY_ERROR";
-}
-/**
- * Returns true if we're pretty sure that the current error is due to the
- * user being offline.
- * @param {Error} error
- * @returns {Boolean}
- */
-function isOfflineRequestError(error) {
- if (error instanceof request_error/* default */.Z) {
- return error.type === error_codes/* NetworkErrorTypes.ERROR_EVENT */.br.ERROR_EVENT && isOffline();
- } else if (error instanceof custom_loader_error/* default */.Z) {
- return error.isOfflineError;
- }
- return false; // under doubt, return false
-}
-/**
- * Guess the type of error obtained.
- * @param {*} error
- * @returns {number}
- */
-function getRequestErrorType(error) {
- return isOfflineRequestError(error) ? 2 /* REQUEST_ERROR_TYPES.Offline */ : 1 /* REQUEST_ERROR_TYPES.Regular */;
-}
-/**
- * Specific algorithm used to perform segment and manifest requests.
- *
- * Here how it works:
- *
- * 1. You give it one or multiple of the CDN available for the resource you
- * want to request (from the most important one to the least important),
- * a callback doing the request with the chosen CDN in argument, and some
- * options.
- *
- * 2. it tries to call the request callback with the most prioritized CDN
- * first:
- * - if it works as expected, it resolves the returned Promise with that
- * request's response.
- * - if it fails, it calls ther `onRetry` callback given with the
- * corresponding error, un-prioritize that CDN and try with the new
- * most prioritized CDN.
- *
- * Each CDN might be retried multiple times, depending on the nature of the
- * error and the Configuration given.
- *
- * Multiple retries of the same CDN are done after a delay to avoid
- * overwhelming it, this is what we call a "backoff". That delay raises
- * exponentially as multiple consecutive errors are encountered on this
- * CDN.
- *
- * @param {Array.|null} cdns - The different CDN on which the
- * wanted resource is available. `scheduleRequestWithCdns` will call the
- * `performRequest` callback with the right element from that array if different
- * from `null`.
- *
- * Can be set to `null` when that resource is not reachable through a CDN, in
- * which case the `performRequest` callback may be called with `null`.
- * @param {Object|null} cdnPrioritizer - Interface allowing to give the priority
- * between multiple CDNs.
- * @param {Function} performRequest - Callback implementing the request in
- * itself. Resolving when the resource request succeed and rejecting with the
- * corresponding error when the request failed.
- * @param {Object} options - Configuration allowing to tweak the number on which
- * the algorithm behind `scheduleRequestWithCdns` bases itself.
- * @param {Object} cancellationSignal - CancellationSignal allowing to cancel
- * the logic of `scheduleRequestWithCdns`.
- * To trigger if the resource is not needed anymore.
- * @returns {Promise} - Promise resolving, with the corresponding
- * `performRequest`'s data, when the resource request succeed and rejecting in
- * the following scenarios:
- * - `scheduleRequestWithCdns` has been cancelled due to `cancellationSignal`
- * being triggered. In that case a `CancellationError` is thrown.
- *
- * - The resource request(s) failed and will not be retried anymore.
- */
-function scheduleRequestWithCdns(_x, _x2, _x3, _x4, _x5) {
- return _scheduleRequestWithCdns.apply(this, arguments);
-}
-/**
- * Lightweight version of the request algorithm, this time with only a simple
- * Promise given.
- * @param {Function} performRequest
- * @param {Object} options
- * @returns {Promise}
- */
-function _scheduleRequestWithCdns() {
- _scheduleRequestWithCdns = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee3(cdns, cdnPrioritizer, performRequest, options, cancellationSignal) {
- var baseDelay, maxDelay, maxRetryRegular, maxRetryOffline, onRetry, missedAttempts, initialCdnToRequest, getCdnToRequest, requestCdn, _requestCdn, retryWithNextCdn, _retryWithNextCdn, waitPotentialBackoffAndRequest, getPrioritaryRequestableCdnFromSortedList;
- return regenerator_default().wrap(function _callee3$(_context3) {
- while (1) {
- switch (_context3.prev = _context3.next) {
- case 0:
- getPrioritaryRequestableCdnFromSortedList = function _getPrioritaryRequest(sortedCdns) {
- var _a;
- if (missedAttempts.size === 0) {
- return sortedCdns[0];
- }
- var now = performance.now();
- return (_a = sortedCdns.filter(function (c) {
- var _a;
- return ((_a = missedAttempts.get(c)) === null || _a === void 0 ? void 0 : _a.isBlacklisted) !== true;
- }).reduce(function (acc, x) {
- var _a;
- var blockedUntil = (_a = missedAttempts.get(x)) === null || _a === void 0 ? void 0 : _a.blockedUntil;
- if (blockedUntil !== undefined && blockedUntil <= now) {
- blockedUntil = undefined;
- }
- if (acc === undefined) {
- return [x, blockedUntil];
- }
- if (blockedUntil === undefined) {
- if (acc[1] === undefined) {
- return acc;
- }
- return [x, undefined];
- }
- return acc[1] === undefined ? acc : blockedUntil < acc[1] ? [x, blockedUntil] : acc;
- }, undefined)) === null || _a === void 0 ? void 0 : _a[0];
- };
- waitPotentialBackoffAndRequest = function _waitPotentialBackoff(nextWantedCdn, prevRequestError) {
- var nextCdnAttemptObj = missedAttempts.get(nextWantedCdn);
- if (nextCdnAttemptObj === undefined || nextCdnAttemptObj.blockedUntil === undefined) {
- return requestCdn(nextWantedCdn);
- }
- var now = performance.now();
- var blockedFor = nextCdnAttemptObj.blockedUntil - now;
- if (blockedFor <= 0) {
- return requestCdn(nextWantedCdn);
- }
- var canceller = new task_canceller/* default */.ZP({
- cancelOn: cancellationSignal
- });
- return new Promise(function (res, rej) {
- /* eslint-disable-next-line @typescript-eslint/no-misused-promises */
- cdnPrioritizer === null || cdnPrioritizer === void 0 ? void 0 : cdnPrioritizer.addEventListener("priorityChange", function () {
- var updatedPrioritaryCdn = getCdnToRequest();
- if (cancellationSignal.isCancelled) {
- throw cancellationSignal.cancellationError;
- }
- if (updatedPrioritaryCdn === undefined) {
- return rej(prevRequestError);
- }
- if (updatedPrioritaryCdn !== nextWantedCdn) {
- canceller.cancel();
- waitPotentialBackoffAndRequest(updatedPrioritaryCdn, prevRequestError).then(res, rej);
- }
- }, canceller.signal);
- (0,cancellable_sleep/* default */.Z)(blockedFor, canceller.signal).then(function () {
- return requestCdn(nextWantedCdn).then(res, rej);
- }, noop/* default */.Z);
- });
- };
- _retryWithNextCdn = function _retryWithNextCdn3() {
- _retryWithNextCdn = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee2(prevRequestError) {
- var nextCdn;
- return regenerator_default().wrap(function _callee2$(_context2) {
- while (1) {
- switch (_context2.prev = _context2.next) {
- case 0:
- nextCdn = getCdnToRequest();
- if (!cancellationSignal.isCancelled) {
- _context2.next = 3;
- break;
- }
- throw cancellationSignal.cancellationError;
- case 3:
- if (!(nextCdn === undefined)) {
- _context2.next = 5;
- break;
- }
- throw prevRequestError;
- case 5:
- onRetry(prevRequestError);
- if (!cancellationSignal.isCancelled) {
- _context2.next = 8;
- break;
- }
- throw cancellationSignal.cancellationError;
- case 8:
- return _context2.abrupt("return", waitPotentialBackoffAndRequest(nextCdn, prevRequestError));
- case 9:
- case "end":
- return _context2.stop();
- }
- }
- }, _callee2);
- }));
- return _retryWithNextCdn.apply(this, arguments);
- };
- retryWithNextCdn = function _retryWithNextCdn2(_x7) {
- return _retryWithNextCdn.apply(this, arguments);
- };
- _requestCdn = function _requestCdn3() {
- _requestCdn = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(cdn) {
- var res, currentErrorType, missedAttemptsObj, maxRetry, errorCounter, delay, fuzzedDelay;
- return regenerator_default().wrap(function _callee$(_context) {
- while (1) {
- switch (_context.prev = _context.next) {
- case 0:
- _context.prev = 0;
- _context.next = 3;
- return performRequest(cdn, cancellationSignal);
- case 3:
- res = _context.sent;
- return _context.abrupt("return", res);
- case 7:
- _context.prev = 7;
- _context.t0 = _context["catch"](0);
- if (!task_canceller/* default.isCancellationError */.ZP.isCancellationError(_context.t0)) {
- _context.next = 11;
- break;
- }
- throw _context.t0;
- case 11:
- if (cdn !== null && cdnPrioritizer !== null) {
- // We failed requesting the resource on this CDN.
- // Globally give priority to the next CDN through the CdnPrioritizer.
- cdnPrioritizer.downgradeCdn(cdn);
- }
- currentErrorType = getRequestErrorType(_context.t0);
- missedAttemptsObj = missedAttempts.get(cdn);
- if (missedAttemptsObj === undefined) {
- missedAttemptsObj = {
- errorCounter: 1,
- lastErrorType: currentErrorType,
- blockedUntil: undefined,
- isBlacklisted: false
- };
- missedAttempts.set(cdn, missedAttemptsObj);
- } else {
- if (currentErrorType !== missedAttemptsObj.lastErrorType) {
- missedAttemptsObj.errorCounter = 1;
- missedAttemptsObj.lastErrorType = currentErrorType;
- } else {
- missedAttemptsObj.errorCounter++;
- }
- }
- if (shouldRetry(_context.t0)) {
- _context.next = 19;
- break;
- }
- missedAttemptsObj.blockedUntil = undefined;
- missedAttemptsObj.isBlacklisted = true;
- return _context.abrupt("return", retryWithNextCdn(_context.t0));
- case 19:
- maxRetry = currentErrorType === 2 /* REQUEST_ERROR_TYPES.Offline */ ? maxRetryOffline : maxRetryRegular;
- if (missedAttemptsObj.errorCounter > maxRetry) {
- missedAttemptsObj.blockedUntil = undefined;
- missedAttemptsObj.isBlacklisted = true;
- } else {
- errorCounter = missedAttemptsObj.errorCounter;
- delay = Math.min(baseDelay * Math.pow(2, errorCounter - 1), maxDelay);
- fuzzedDelay = (0,get_fuzzed_delay/* default */.Z)(delay);
- missedAttemptsObj.blockedUntil = performance.now() + fuzzedDelay;
- }
- return _context.abrupt("return", retryWithNextCdn(_context.t0));
- case 22:
- case "end":
- return _context.stop();
- }
- }
- }, _callee, null, [[0, 7]]);
- }));
- return _requestCdn.apply(this, arguments);
- };
- requestCdn = function _requestCdn2(_x6) {
- return _requestCdn.apply(this, arguments);
- };
- getCdnToRequest = function _getCdnToRequest() {
- if (cdns === null) {
- var nullAttemptObject = missedAttempts.get(null);
- if (nullAttemptObject !== undefined && nullAttemptObject.isBlacklisted) {
- return undefined;
- }
- return null;
- } else if (cdnPrioritizer === null) {
- return getPrioritaryRequestableCdnFromSortedList(cdns);
- } else {
- var prioritized = cdnPrioritizer.getCdnPreferenceForResource(cdns);
- return getPrioritaryRequestableCdnFromSortedList(prioritized);
- }
- };
- if (!(cancellationSignal.cancellationError !== null)) {
- _context3.next = 9;
- break;
- }
- return _context3.abrupt("return", Promise.reject(cancellationSignal.cancellationError));
- case 9:
- baseDelay = options.baseDelay, maxDelay = options.maxDelay, maxRetryRegular = options.maxRetryRegular, maxRetryOffline = options.maxRetryOffline, onRetry = options.onRetry;
- if (cdns !== null && cdns.length === 0) {
- log/* default.warn */.Z.warn("Fetchers: no CDN given to `scheduleRequestWithCdns`.");
- }
- missedAttempts = new Map();
- initialCdnToRequest = getCdnToRequest();
- if (!(initialCdnToRequest === undefined)) {
- _context3.next = 15;
- break;
- }
- throw new Error("No CDN to request");
- case 15:
- return _context3.abrupt("return", requestCdn(initialCdnToRequest));
- case 16:
- case "end":
- return _context3.stop();
- }
- }
- }, _callee3);
- }));
- return _scheduleRequestWithCdns.apply(this, arguments);
-}
-function scheduleRequestPromise(performRequest, options, cancellationSignal) {
- // same than for a single unknown CDN
- return scheduleRequestWithCdns(null, null, performRequest, options, cancellationSignal);
-}
-;// CONCATENATED MODULE: ./src/core/fetchers/manifest/manifest_fetcher.ts
-
+ return NetworkAnalyzer;
+}();
+;// CONCATENATED MODULE: ./src/core/adaptive/guess_based_chooser.ts
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
@@ -42784,337 +39080,224 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
-
-
-
-
-
-
/**
- * Class allowing to facilitate the task of loading and parsing a Manifest.
- * @class ManifestFetcher
- * @example
- * ```js
- * const manifestFetcher = new ManifestFetcher(manifestUrl, pipelines, options);
- * manifestFetcher.fetch().pipe(
- * // Filter only responses (might also receive warning events)
- * filter((evt) => evt.type === "response");
- * // Parse the Manifest
- * mergeMap(res => res.parse({ externalClockOffset }))
- * // (again)
- * filter((evt) => evt.type === "parsed");
- * ).subscribe(({ value }) => {
- * console.log("Manifest:", value.manifest);
- * });
- * ```
+ * Estimate which Representation should be played based on risky "guesses".
+ *
+ * Basically, this `GuessBasedChooser` will attempt switching to the superior
+ * quality when conditions allows this and then check if we're able to maintain
+ * this quality. If we're not, it will rollbacks to the previous, maintaninable,
+ * guess.
+ *
+ * The algorithm behind the `GuessBasedChooser` is very risky in terms of
+ * rebuffering chances. As such, it should only be used when other approach
+ * don't work (e.g. low-latency contents).
+ * @class GuessBasedChooser
*/
-var ManifestFetcher = /*#__PURE__*/function () {
+var GuessBasedChooser = /*#__PURE__*/function () {
/**
- * Construct a new ManifestFetcher.
- * @param {string | undefined} url - Default Manifest url, will be used when
- * no URL is provided to the `fetch` function.
- * `undefined` if unknown or if a Manifest should be retrieved through other
- * means than an HTTP request.
- * @param {Object} pipelines - Transport pipelines used to perform the
- * Manifest loading and parsing operations.
- * @param {Object} settings - Configure the `ManifestFetcher`.
+ * Create a new `GuessBasedChooser`.
+ * @param {Object} scoreCalculator
+ * @param {Object} prevEstimate
*/
- function ManifestFetcher(url, pipelines, settings) {
- this._manifestUrl = url;
- this._pipelines = pipelines.manifest;
- this._settings = settings;
+ function GuessBasedChooser(scoreCalculator, prevEstimate) {
+ this._scoreCalculator = scoreCalculator;
+ this._lastAbrEstimate = prevEstimate;
+ this._consecutiveWrongGuesses = 0;
+ this._blockGuessesUntil = 0;
+ this._lastMaintanableBitrate = null;
}
/**
- * (re-)Load the Manifest.
- * This method does not yet parse it, parsing will then be available through
- * a callback available on the response.
- *
- * You can set an `url` on which that Manifest will be requested.
- * If not set, the regular Manifest url - defined on the `ManifestFetcher`
- * instanciation - will be used instead.
+ * Perform a "guess", which basically indicates which Representation should be
+ * chosen according to the `GuessBasedChooser`.
*
- * @param {string} [url]
- * @returns {Observable}
+ * @param {Array.} representations - Array of all Representation the
+ * GuessBasedChooser can choose from, sorted by bitrate ascending.
+ * /!\ It is very important that Representation in that Array are sorted by
+ * bitrate ascending for this method to work as intented.
+ * @param {Object} observation - Last playback observation performed.
+ * @param {Object} currentRepresentation - The Representation currently
+ * loading.
+ * @param {number} incomingBestBitrate - The bitrate of the Representation
+ * chosen by the more optimistic of the other ABR algorithms currently.
+ * @param {Array.} requests - Information on all pending requests.
+ * @returns {Object|null} - If a guess is made, return that guess, else
+ * returns `null` (in which case you should fallback to another ABR
+ * algorithm).
*/
- var _proto = ManifestFetcher.prototype;
- _proto.fetch = function fetch(url) {
- var _this = this;
- return new Observable/* Observable */.y(function (obs) {
- var settings = _this._settings;
- var pipelines = _this._pipelines;
- var requestUrl = url !== null && url !== void 0 ? url : _this._manifestUrl;
- /** `true` if the loading pipeline is already completely executed. */
- var hasFinishedLoading = false;
- /** Allows to cancel the loading operation. */
- var canceller = new task_canceller/* default */.ZP();
- var backoffSettings = _this._getBackoffSetting(function (err) {
- obs.next({
- type: "warning",
- value: errorSelector(err)
- });
- });
- var loadingPromise = pipelines.resolveManifestUrl === undefined ? callLoaderWithRetries(requestUrl) : callResolverWithRetries(requestUrl).then(callLoaderWithRetries);
- loadingPromise.then(function (response) {
- hasFinishedLoading = true;
- obs.next({
- type: "response",
- parse: function parse(parserOptions) {
- return _this._parseLoadedManifest(response, parserOptions);
- }
- });
- obs.complete();
- })["catch"](function (err) {
- if (canceller.isUsed) {
- // Cancellation has already been handled by RxJS
- return;
+ var _proto = GuessBasedChooser.prototype;
+ _proto.getGuess = function getGuess(representations, observation, currentRepresentation, incomingBestBitrate, requests) {
+ var bufferGap = observation.bufferGap,
+ speed = observation.speed;
+ var lastChosenRep = this._lastAbrEstimate.representation;
+ if (lastChosenRep === null) {
+ return null; // There's nothing to base our guess on
+ }
+
+ if (incomingBestBitrate > lastChosenRep.bitrate) {
+ // ABR estimates are already superior or equal to the guess
+ // we'll be doing here, so no need to guess
+ if (this._lastAbrEstimate.algorithmType === 2 /* ABRAlgorithmType.GuessBased */) {
+ if (this._lastAbrEstimate.representation !== null) {
+ this._lastMaintanableBitrate = this._lastAbrEstimate.representation.bitrate;
}
- hasFinishedLoading = true;
- obs.error(errorSelector(err));
- });
- return function () {
- if (!hasFinishedLoading) {
- canceller.cancel();
+ this._consecutiveWrongGuesses = 0;
+ }
+ return null;
+ }
+ var scoreData = this._scoreCalculator.getEstimate(currentRepresentation);
+ if (this._lastAbrEstimate.algorithmType !== 2 /* ABRAlgorithmType.GuessBased */) {
+ if (scoreData === undefined) {
+ return null; // not enough information to start guessing
+ }
+
+ if (this._canGuessHigher(bufferGap, speed, scoreData)) {
+ var nextRepresentation = getNextRepresentation(representations, currentRepresentation);
+ if (nextRepresentation !== null) {
+ return nextRepresentation;
}
- };
- /**
- * Call the resolver part of the pipeline, retrying if it fails according
- * to the current settings.
- * Returns the Promise of the last attempt.
- * /!\ This pipeline should have a `resolveManifestUrl` function defined.
- * @param {string | undefined} resolverUrl
- * @returns {Promise}
- */
- function callResolverWithRetries(resolverUrl) {
- var resolveManifestUrl = pipelines.resolveManifestUrl;
- (0,assert/* default */.Z)(resolveManifestUrl !== undefined);
- var callResolver = function callResolver() {
- return resolveManifestUrl(resolverUrl, canceller.signal);
- };
- return scheduleRequestPromise(callResolver, backoffSettings, canceller.signal);
}
- /**
- * Call the loader part of the pipeline, retrying if it fails according
- * to the current settings.
- * Returns the Promise of the last attempt.
- * @param {string | undefined} manifestUrl
- * @returns {Promise}
- */
- function callLoaderWithRetries(manifestUrl) {
- var loadManifest = pipelines.loadManifest;
- var requestTimeout = (0,is_null_or_undefined/* default */.Z)(settings.requestTimeout) ? config/* default.getCurrent */.Z.getCurrent().DEFAULT_REQUEST_TIMEOUT : settings.requestTimeout;
- if (requestTimeout < 0) {
- requestTimeout = undefined;
- }
- var callLoader = function callLoader() {
- return loadManifest(manifestUrl, {
- timeout: requestTimeout
- }, canceller.signal);
- };
- return scheduleRequestPromise(callLoader, backoffSettings, canceller.signal);
+ return null;
+ }
+ // If we reached here, we're currently already in guessing mode
+ if (this._isLastGuessValidated(lastChosenRep, incomingBestBitrate, scoreData)) {
+ log/* default.debug */.Z.debug("ABR: Guessed Representation validated", lastChosenRep.bitrate);
+ this._lastMaintanableBitrate = lastChosenRep.bitrate;
+ this._consecutiveWrongGuesses = 0;
+ }
+ if (currentRepresentation.id !== lastChosenRep.id) {
+ return lastChosenRep;
+ }
+ var shouldStopGuess = this._shouldStopGuess(currentRepresentation, scoreData, bufferGap, requests);
+ if (shouldStopGuess) {
+ // Block guesses for a time
+ this._consecutiveWrongGuesses++;
+ this._blockGuessesUntil = performance.now() + Math.min(this._consecutiveWrongGuesses * 15000, 120000);
+ return getPreviousRepresentation(representations, currentRepresentation);
+ } else if (scoreData === undefined) {
+ return currentRepresentation;
+ }
+ if (this._canGuessHigher(bufferGap, speed, scoreData)) {
+ var _nextRepresentation = getNextRepresentation(representations, currentRepresentation);
+ if (_nextRepresentation !== null) {
+ return _nextRepresentation;
}
- });
+ }
+ return currentRepresentation;
}
/**
- * Parse an already loaded Manifest.
- *
- * This method should be reserved for Manifests for which no request has been
- * done.
- * In other cases, it's preferable to go through the `fetch` method, so
- * information on the request can be used by the parsing process.
- * @param {*} manifest
- * @param {Object} parserOptions
- * @returns {Observable}
+ * Returns `true` if we've enough confidence on the current situation to make
+ * a higher guess.
+ * @param {number} bufferGap
+ * @param {number} speed
+ * @param {Array} scoreData
+ * @returns {boolean}
*/;
- _proto.parse = function parse(manifest, parserOptions) {
- return this._parseLoadedManifest({
- responseData: manifest,
- size: undefined,
- requestDuration: undefined
- }, parserOptions);
+ _proto._canGuessHigher = function _canGuessHigher(bufferGap, speed, _ref) {
+ var score = _ref[0],
+ scoreConfidenceLevel = _ref[1];
+ return isFinite(bufferGap) && bufferGap >= 2.5 && performance.now() > this._blockGuessesUntil && scoreConfidenceLevel === 1 /* ScoreConfidenceLevel.HIGH */ && score / speed > 1.01;
}
/**
- * Parse a Manifest.
- *
- * @param {Object} loaded - Information about the loaded Manifest as well as
- * about the corresponding request.
- * @param {Object} parserOptions - Options used when parsing the Manifest.
- * @returns {Observable}
+ * Returns `true` if the pending guess of `lastGuess` seems to not
+ * be maintainable and as such should be stopped.
+ * @param {Object} lastGuess
+ * @param {Array} scoreData
+ * @param {number} bufferGap
+ * @param {Array.} requests
+ * @returns {boolean}
*/;
- _proto._parseLoadedManifest = function _parseLoadedManifest(loaded, parserOptions) {
- var _this2 = this;
- return new Observable/* Observable */.y(function (obs) {
- var parsingTimeStart = performance.now();
- var canceller = new task_canceller/* default */.ZP();
- var sendingTime = loaded.sendingTime,
- receivedTime = loaded.receivedTime;
- var backoffSettings = _this2._getBackoffSetting(function (err) {
- obs.next({
- type: "warning",
- value: errorSelector(err)
- });
- });
- var opts = {
- externalClockOffset: parserOptions.externalClockOffset,
- unsafeMode: parserOptions.unsafeMode,
- previousManifest: parserOptions.previousManifest,
- originalUrl: _this2._manifestUrl
- };
- try {
- var res = _this2._pipelines.parseManifest(loaded, opts, onWarnings, canceller.signal, scheduleRequest);
- if (!isPromise(res)) {
- emitManifestAndComplete(res.manifest);
- } else {
- res.then(function (_ref) {
- var manifest = _ref.manifest;
- return emitManifestAndComplete(manifest);
- })["catch"](function (err) {
- if (canceller.isUsed) {
- // Cancellation is already handled by RxJS
- return;
- }
- emitError(err, true);
- });
- }
- } catch (err) {
- if (canceller.isUsed) {
- // Cancellation is already handled by RxJS
- return undefined;
- }
- emitError(err, true);
- }
- return function () {
- canceller.cancel();
- };
- /**
- * Perform a request with the same retry mechanisms and error handling
- * than for a Manifest loader.
- * @param {Function} performRequest
- * @returns {Function}
- */
- function scheduleRequest(_x) {
- return _scheduleRequest.apply(this, arguments);
- }
- /**
- * Handle minor errors encountered by a Manifest parser.
- * @param {Array.} warnings
- */
- function _scheduleRequest() {
- _scheduleRequest = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(performRequest) {
- var data;
- return regenerator_default().wrap(function _callee$(_context) {
- while (1) {
- switch (_context.prev = _context.next) {
- case 0:
- _context.prev = 0;
- _context.next = 3;
- return scheduleRequestPromise(performRequest, backoffSettings, canceller.signal);
- case 3:
- data = _context.sent;
- return _context.abrupt("return", data);
- case 7:
- _context.prev = 7;
- _context.t0 = _context["catch"](0);
- throw errorSelector(_context.t0);
- case 10:
- case "end":
- return _context.stop();
- }
- }
- }, _callee, null, [[0, 7]]);
- }));
- return _scheduleRequest.apply(this, arguments);
- }
- function onWarnings(warnings) {
- for (var _iterator = _createForOfIteratorHelperLoose(warnings), _step; !(_step = _iterator()).done;) {
- var warning = _step.value;
- if (canceller.isUsed) {
- return;
- }
- emitError(warning, false);
+ _proto._shouldStopGuess = function _shouldStopGuess(lastGuess, scoreData, bufferGap, requests) {
+ if (scoreData !== undefined && scoreData[0] < 1.01) {
+ return true;
+ } else if ((scoreData === undefined || scoreData[0] < 1.2) && bufferGap < 0.6) {
+ return true;
+ }
+ var guessedRepresentationRequests = requests.filter(function (req) {
+ return req.content.representation.id === lastGuess.id;
+ });
+ var now = performance.now();
+ for (var _iterator = _createForOfIteratorHelperLoose(guessedRepresentationRequests), _step; !(_step = _iterator()).done;) {
+ var req = _step.value;
+ var requestElapsedTime = now - req.requestTimestamp;
+ if (req.content.segment.isInit) {
+ if (requestElapsedTime > 1000) {
+ return true;
}
- }
- /**
- * Emit a formatted "parsed" event through `obs`.
- * To call once the Manifest has been parsed.
- * @param {Object} manifest
- */
- function emitManifestAndComplete(manifest) {
- onWarnings(manifest.contentWarnings);
- var parsingTime = performance.now() - parsingTimeStart;
- log/* default.info */.Z.info("MF: Manifest parsed in " + parsingTime + "ms");
- obs.next({
- type: "parsed",
- manifest: manifest,
- sendingTime: sendingTime,
- receivedTime: receivedTime,
- parsingTime: parsingTime
- });
- obs.complete();
- }
- /**
- * Format the given Error and emit it through `obs`.
- * Either through a `"warning"` event, if `isFatal` is `false`, or through
- * a fatal Observable error, if `isFatal` is set to `true`.
- * @param {*} err
- * @param {boolean} isFatal
- */
- function emitError(err, isFatal) {
- var formattedError = (0,format_error/* default */.Z)(err, {
- defaultCode: "PIPELINE_PARSE_ERROR",
- defaultReason: "Unknown error when parsing the Manifest"
- });
- if (isFatal) {
- obs.error(formattedError);
- } else {
- obs.next({
- type: "warning",
- value: formattedError
- });
+ } else if (requestElapsedTime > req.content.segment.duration * 1000 + 200) {
+ return true;
+ } else {
+ var fastBw = estimateRequestBandwidth(req);
+ if (fastBw !== undefined && fastBw < lastGuess.bitrate * 0.8) {
+ return true;
}
}
- });
- }
- /**
- * Construct "backoff settings" that can be used with a range of functions
- * allowing to perform multiple request attempts
- * @param {Function} onRetry
- * @returns {Object}
- */;
- _proto._getBackoffSetting = function _getBackoffSetting(onRetry) {
- var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
- DEFAULT_MAX_MANIFEST_REQUEST_RETRY = _config$getCurrent.DEFAULT_MAX_MANIFEST_REQUEST_RETRY,
- DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE = _config$getCurrent.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE,
- INITIAL_BACKOFF_DELAY_BASE = _config$getCurrent.INITIAL_BACKOFF_DELAY_BASE,
- MAX_BACKOFF_DELAY_BASE = _config$getCurrent.MAX_BACKOFF_DELAY_BASE;
- var _this$_settings = this._settings,
- lowLatencyMode = _this$_settings.lowLatencyMode,
- ogRegular = _this$_settings.maxRetryRegular,
- ogOffline = _this$_settings.maxRetryOffline;
- var baseDelay = lowLatencyMode ? INITIAL_BACKOFF_DELAY_BASE.LOW_LATENCY : INITIAL_BACKOFF_DELAY_BASE.REGULAR;
- var maxDelay = lowLatencyMode ? MAX_BACKOFF_DELAY_BASE.LOW_LATENCY : MAX_BACKOFF_DELAY_BASE.REGULAR;
- var maxRetryRegular = ogRegular !== null && ogRegular !== void 0 ? ogRegular : DEFAULT_MAX_MANIFEST_REQUEST_RETRY;
- var maxRetryOffline = ogOffline !== null && ogOffline !== void 0 ? ogOffline : DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE;
- return {
- onRetry: onRetry,
- baseDelay: baseDelay,
- maxDelay: maxDelay,
- maxRetryRegular: maxRetryRegular,
- maxRetryOffline: maxRetryOffline
- };
+ }
+ return false;
};
- return ManifestFetcher;
+ _proto._isLastGuessValidated = function _isLastGuessValidated(lastGuess, incomingBestBitrate, scoreData) {
+ if (scoreData !== undefined && scoreData[1] === 1 /* ScoreConfidenceLevel.HIGH */ && scoreData[0] > 1.5) {
+ return true;
+ }
+ return incomingBestBitrate >= lastGuess.bitrate && (this._lastMaintanableBitrate === null || this._lastMaintanableBitrate < lastGuess.bitrate);
+ };
+ return GuessBasedChooser;
}();
/**
- * Returns `true` when the returned value seems to be a Promise instance, as
- * created by the RxPlayer.
- * @param {*} val
- * @returns {boolean}
+ * From the array of Representations given, returns the Representation with a
+ * bitrate immediately superior to the current one.
+ * Returns `null` if that "next" Representation is not found.
+ *
+ * /!\ The representations have to be already sorted by bitrate, in ascending
+ * order.
+ * @param {Array.} representations - Available representations to choose
+ * from, sorted by bitrate in ascending order.
+ * @param {Object} currentRepresentation - The Representation currently
+ * considered.
+ * @returns {Object|null}
*/
-function isPromise(val) {
- return val instanceof Promise;
+function getNextRepresentation(representations, currentRepresentation) {
+ var len = representations.length;
+ var index = (0,array_find_index/* default */.Z)(representations, function (_ref2) {
+ var id = _ref2.id;
+ return id === currentRepresentation.id;
+ });
+ if (index < 0) {
+ log/* default.error */.Z.error("ABR: Current Representation not found.");
+ return null;
+ }
+ while (++index < len) {
+ if (representations[index].bitrate > currentRepresentation.bitrate) {
+ return representations[index];
+ }
+ }
+ return null;
}
-;// CONCATENATED MODULE: ./src/core/fetchers/manifest/index.ts
+/**
+ * From the array of Representations given, returns the Representation with a
+ * bitrate immediately inferior.
+ * Returns `null` if that "previous" Representation is not found.
+ * @param {Array.} representations
+ * @param {Object} currentRepresentation
+ * @returns {Object|null}
+ */
+function getPreviousRepresentation(representations, currentRepresentation) {
+ var index = (0,array_find_index/* default */.Z)(representations, function (_ref3) {
+ var id = _ref3.id;
+ return id === currentRepresentation.id;
+ });
+ if (index < 0) {
+ log/* default.error */.Z.error("ABR: Current Representation not found.");
+ return null;
+ }
+ while (--index >= 0) {
+ if (representations[index].bitrate < currentRepresentation.bitrate) {
+ return representations[index];
+ }
+ }
+ return null;
+}
+;// CONCATENATED MODULE: ./src/core/adaptive/utils/bandwidth_estimator.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -43131,12 +39314,68 @@ function isPromise(val) {
* limitations under the License.
*/
-/* harmony default export */ var fetchers_manifest = (ManifestFetcher);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/finalize.js
-var finalize = __webpack_require__(3286);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/ignoreElements.js
-var ignoreElements = __webpack_require__(533);
-;// CONCATENATED MODULE: ./src/compat/should_reload_media_source_on_decipherability_update.ts
+
+/**
+ * Calculate a mean bandwidth based on the bytes downloaded and the amount
+ * of time needed to do so.
+ * @class BandwidthEstimator
+ */
+var BandwidthEstimator = /*#__PURE__*/function () {
+ function BandwidthEstimator() {
+ var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
+ ABR_FAST_EMA = _config$getCurrent.ABR_FAST_EMA,
+ ABR_SLOW_EMA = _config$getCurrent.ABR_SLOW_EMA;
+ this._fastEWMA = new EWMA(ABR_FAST_EMA);
+ this._slowEWMA = new EWMA(ABR_SLOW_EMA);
+ this._bytesSampled = 0;
+ }
+ /**
+ * Takes a bandwidth sample.
+ * @param {number} durationInMs - The amount of time, in milliseconds, for a
+ * particular request.
+ * @param {number} numberOfBytes - The total number of bytes transferred in
+ * that request.
+ */
+ var _proto = BandwidthEstimator.prototype;
+ _proto.addSample = function addSample(durationInMs, numberOfBytes) {
+ var _config$getCurrent2 = config/* default.getCurrent */.Z.getCurrent(),
+ ABR_MINIMUM_CHUNK_SIZE = _config$getCurrent2.ABR_MINIMUM_CHUNK_SIZE;
+ if (numberOfBytes < ABR_MINIMUM_CHUNK_SIZE) {
+ return;
+ }
+ var bandwidth = numberOfBytes * 8000 / durationInMs;
+ var weight = durationInMs / 1000;
+ this._bytesSampled += numberOfBytes;
+ this._fastEWMA.addSample(weight, bandwidth);
+ this._slowEWMA.addSample(weight, bandwidth);
+ }
+ /**
+ * Get estimate of the bandwidth, in bits per seconds.
+ * @returns {Number|undefined}
+ */;
+ _proto.getEstimate = function getEstimate() {
+ var _config$getCurrent3 = config/* default.getCurrent */.Z.getCurrent(),
+ ABR_MINIMUM_TOTAL_BYTES = _config$getCurrent3.ABR_MINIMUM_TOTAL_BYTES;
+ if (this._bytesSampled < ABR_MINIMUM_TOTAL_BYTES) {
+ return undefined;
+ }
+ // Take the minimum of these two estimates.
+ // This should have the effect of adapting down quickly, but up more slowly.
+ return Math.min(this._fastEWMA.getEstimate(), this._slowEWMA.getEstimate());
+ }
+ /** Reset the bandwidth estimation. */;
+ _proto.reset = function reset() {
+ var _config$getCurrent4 = config/* default.getCurrent */.Z.getCurrent(),
+ ABR_FAST_EMA = _config$getCurrent4.ABR_FAST_EMA,
+ ABR_SLOW_EMA = _config$getCurrent4.ABR_SLOW_EMA;
+ this._fastEWMA = new EWMA(ABR_FAST_EMA);
+ this._slowEWMA = new EWMA(ABR_SLOW_EMA);
+ this._bytesSampled = 0;
+ };
+ return BandwidthEstimator;
+}();
+
+;// CONCATENATED MODULE: ./src/core/adaptive/utils/filter_by_bitrate.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -43152,28 +39391,34 @@ var ignoreElements = __webpack_require__(533);
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
/**
- * Returns true if we have to reload the MediaSource due to an update in the
- * decipherability status of some segments based on the current key sytem.
- *
- * We found that on all Widevine targets tested, a simple seek is sufficient.
- * As widevine clients make a good chunk of users, we can make a difference
- * between them and others as it is for the better.
- * @param {string|null} currentKeySystem
- * @returns {Boolean}
+ * Get only representations lower or equal to a given bitrate.
+ * If no representation is lower than the given bitrate, returns an array containing
+ * all Representation(s) with the lowest available bitrate.
+ * @param {Array.} representations - All Representations available
+ * @param {Number} bitrate
+ * @returns {Array.}
*/
-function shouldReloadMediaSourceOnDecipherabilityUpdate(currentKeySystem) {
- return currentKeySystem === null || currentKeySystem.indexOf("widevine") < 0;
+function filterByBitrate(representations, bitrate) {
+ if (representations.length === 0) {
+ return [];
+ }
+ representations.sort(function (ra, rb) {
+ return ra.bitrate - rb.bitrate;
+ });
+ var minimumBitrate = representations[0].bitrate;
+ var bitrateCeil = Math.max(bitrate, minimumBitrate);
+ var firstSuperiorBitrateIndex = (0,array_find_index/* default */.Z)(representations, function (representation) {
+ return representation.bitrate > bitrateCeil;
+ });
+ if (firstSuperiorBitrateIndex === -1) {
+ return representations; // All representations have lower bitrates.
+ }
+
+ return representations.slice(0, firstSuperiorBitrateIndex);
}
-// EXTERNAL MODULE: ./src/utils/defer_subscriptions.ts + 5 modules
-var defer_subscriptions = __webpack_require__(8333);
-// EXTERNAL MODULE: ./src/utils/filter_map.ts
-var filter_map = __webpack_require__(2793);
-// EXTERNAL MODULE: ./src/utils/take_first_set.ts
-var take_first_set = __webpack_require__(5278);
-// EXTERNAL MODULE: ./src/utils/array_find_index.ts
-var array_find_index = __webpack_require__(5138);
-;// CONCATENATED MODULE: ./src/core/adaptive/utils/get_buffer_levels.ts
+;// CONCATENATED MODULE: ./src/core/adaptive/utils/filter_by_width.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -43189,43 +39434,33 @@ var array_find_index = __webpack_require__(5138);
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+
/**
- * Return "Buffer Levels" which are steps of available buffers from which we
- * are normally able switch safely to the next available bitrate.
- * (Following an algorithm close to BOLA)
- * @param {Array.} bitrates - All available bitrates, __sorted__ in
- * ascending order.
- * @returns {Array.}
+ * Filter representations based on their width:
+ * - the highest width considered will be the one linked to the first
+ * representation which has a superior width to the one given.
+ * @param {Array.} representations - The representations array
+ * @param {Number} width
+ * @returns {Array.}
*/
-function getBufferLevels(bitrates) {
- var logs = bitrates.map(function (b) {
- return Math.log(b / bitrates[0]);
+function filterByWidth(representations, width) {
+ var sortedRepsByWidth = representations.slice() // clone
+ .sort(function (a, b) {
+ return (0,take_first_set/* default */.Z)(a.width, 0) - (0,take_first_set/* default */.Z)(b.width, 0);
});
- var utilities = logs.map(function (l) {
- return l - logs[0] + 1;
- }); // normalize
- var gp = (utilities[utilities.length - 1] - 1) / (bitrates.length * 2 + 10);
- var Vp = 1 / gp;
- return bitrates.map(function (_, i) {
- return minBufferLevelForBitrate(i);
+ var repWithMaxWidth = (0,array_find/* default */.Z)(sortedRepsByWidth, function (representation) {
+ return typeof representation.width === "number" && representation.width >= width;
});
- /**
- * Get minimum buffer we should keep ahead to pick this bitrate.
- * @param {number} index
- * @returns {number}
- */
- function minBufferLevelForBitrate(index) {
- if (index === 0) {
- return 0;
- }
- var boundedIndex = Math.min(Math.max(1, index), bitrates.length - 1);
- if (bitrates[boundedIndex] === bitrates[boundedIndex - 1]) {
- return minBufferLevelForBitrate(index - 1);
- }
- return Vp * (gp + (bitrates[boundedIndex] * utilities[boundedIndex - 1] - bitrates[boundedIndex - 1] * utilities[boundedIndex]) / (bitrates[boundedIndex] - bitrates[boundedIndex - 1])) + 4;
+ if (repWithMaxWidth === undefined) {
+ return representations;
}
+ var maxWidth = typeof repWithMaxWidth.width === "number" ? repWithMaxWidth.width : 0;
+ return representations.filter(function (representation) {
+ return typeof representation.width === "number" ? representation.width <= maxWidth : true;
+ });
}
-;// CONCATENATED MODULE: ./src/core/adaptive/buffer_based_chooser.ts
+;// CONCATENATED MODULE: ./src/core/adaptive/utils/last_estimate_storage.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -43241,94 +39476,32 @@ function getBufferLevels(bitrates) {
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-
-
-/**
- * Choose a bitrate based on the currently available buffer.
- *
- * This algorithm is based on a deviation of the BOLA algorithm.
- * It is a hybrid solution that also relies on a given bitrate's
- * "maintainability".
- * Each time a chunk is downloaded, from the ratio between the chunk duration
- * and chunk's request time, we can assume that the representation is
- * "maintanable" or not.
- * If so, we may switch to a better quality, or conversely to a worse quality.
- *
- * @class BufferBasedChooser
- */
-var BufferBasedChooser = /*#__PURE__*/function () {
- /**
- * @param {Array.} bitrates
- */
- function BufferBasedChooser(bitrates) {
- this._levelsMap = getBufferLevels(bitrates);
- this._bitrates = bitrates;
- log/* default.debug */.Z.debug("ABR: Steps for buffer based chooser.", this._levelsMap.map(function (l, i) {
- return "bufferLevel: " + l + ", bitrate: " + bitrates[i];
- }).join(" ,"));
+/** Stores the last estimate made by the `RepresentationEstimator`. */
+var LastEstimateStorage = /*#__PURE__*/function () {
+ function LastEstimateStorage() {
+ this.bandwidth = undefined;
+ this.representation = null;
+ this.algorithmType = 3 /* ABRAlgorithmType.None */;
}
/**
- * @param {Object} playbackObservation
- * @returns {number|undefined}
+ * Update this `LastEstimateStorage` with new values.
+ * @param {Object} representation - Estimated Representation.
+ * @param {number|undefined} bandwidth - Estimated bandwidth.
+ * @param {number} algorithmType - The type of algorithm used to produce that
+ * estimate.
*/
- var _proto = BufferBasedChooser.prototype;
- _proto.getEstimate = function getEstimate(playbackObservation) {
- var bufferLevels = this._levelsMap;
- var bitrates = this._bitrates;
- var bufferGap = playbackObservation.bufferGap,
- currentBitrate = playbackObservation.currentBitrate,
- currentScore = playbackObservation.currentScore,
- speed = playbackObservation.speed;
- if (currentBitrate == null) {
- return bitrates[0];
- }
- var currentBitrateIndex = (0,array_find_index/* default */.Z)(bitrates, function (b) {
- return b === currentBitrate;
- });
- if (currentBitrateIndex < 0 || bitrates.length !== bufferLevels.length) {
- log/* default.error */.Z.error("ABR: Current Bitrate not found in the calculated levels");
- return bitrates[0];
- }
- var scaledScore;
- if (currentScore != null) {
- scaledScore = speed === 0 ? currentScore : currentScore / speed;
- }
- if (scaledScore != null && scaledScore > 1) {
- var currentBufferLevel = bufferLevels[currentBitrateIndex];
- var nextIndex = function () {
- for (var i = currentBitrateIndex + 1; i < bufferLevels.length; i++) {
- if (bufferLevels[i] > currentBufferLevel) {
- return i;
- }
- }
- }();
- if (nextIndex != null) {
- var nextBufferLevel = bufferLevels[nextIndex];
- if (bufferGap >= nextBufferLevel) {
- return bitrates[nextIndex];
- }
- }
- }
- if (scaledScore == null || scaledScore < 1.15) {
- var _currentBufferLevel = bufferLevels[currentBitrateIndex];
- if (bufferGap < _currentBufferLevel) {
- for (var i = currentBitrateIndex - 1; i >= 0; i--) {
- if (bitrates[i] < currentBitrate) {
- return bitrates[i];
- }
- }
- return currentBitrate;
- }
- }
- return currentBitrate;
+ var _proto = LastEstimateStorage.prototype;
+ _proto.update = function update(representation, bandwidth, algorithmType) {
+ this.representation = representation;
+ this.bandwidth = bandwidth;
+ this.algorithmType = algorithmType;
};
- return BufferBasedChooser;
+ return LastEstimateStorage;
}();
-// EXTERNAL MODULE: ./src/utils/array_find.ts
-var array_find = __webpack_require__(3274);
-;// CONCATENATED MODULE: ./src/core/adaptive/utils/ewma.ts
+// EXTERNAL MODULE: ./src/utils/object_values.ts
+var object_values = __webpack_require__(1679);
+;// CONCATENATED MODULE: ./src/core/adaptive/utils/pending_requests_store.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -43344,44 +39517,73 @@ var array_find = __webpack_require__(3274);
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
+
/**
- * Tweaked implementation of an exponential weighted Moving Average.
- * @class EWMA
+ * Store information about pending requests, like information about:
+ * - for which segments they are
+ * - how the request's progress goes
+ * @class PendingRequestsStore
*/
-var EWMA = /*#__PURE__*/function () {
+var PendingRequestsStore = /*#__PURE__*/function () {
+ function PendingRequestsStore() {
+ this._currentRequests = {};
+ }
/**
- * @param {number} halfLife
+ * Add information about a new pending request.
+ * @param {Object} payload
*/
- function EWMA(halfLife) {
- // (half-life = log(1/2) / log(Decay Factor)
- this._alpha = Math.exp(Math.log(0.5) / halfLife);
- this._lastEstimate = 0;
- this._totalWeight = 0;
+ var _proto = PendingRequestsStore.prototype;
+ _proto.add = function add(payload) {
+ var id = payload.id,
+ requestTimestamp = payload.requestTimestamp,
+ content = payload.content;
+ this._currentRequests[id] = {
+ requestTimestamp: requestTimestamp,
+ progress: [],
+ content: content
+ };
}
/**
- * @param {number} weight
- * @param {number} value
- */
- var _proto = EWMA.prototype;
- _proto.addSample = function addSample(weight, value) {
- var adjAlpha = Math.pow(this._alpha, weight);
- var newEstimate = value * (1 - adjAlpha) + adjAlpha * this._lastEstimate;
- if (!isNaN(newEstimate)) {
- this._lastEstimate = newEstimate;
- this._totalWeight += weight;
+ * Notify of the progress of a currently pending request.
+ * @param {Object} progress
+ */;
+ _proto.addProgress = function addProgress(progress) {
+ var request = this._currentRequests[progress.id];
+ if (request == null) {
+ if (false) {}
+ log/* default.warn */.Z.warn("ABR: progress for a request not added");
+ return;
}
+ request.progress.push(progress);
}
/**
- * @returns {number} value
+ * Remove a request previously set as pending.
+ * @param {string} id
*/;
- _proto.getEstimate = function getEstimate() {
- var zeroFactor = 1 - Math.pow(this._alpha, this._totalWeight);
- return this._lastEstimate / zeroFactor;
+ _proto.remove = function remove(id) {
+ if (this._currentRequests[id] == null) {
+ if (false) {}
+ log/* default.warn */.Z.warn("ABR: can't remove unknown request");
+ }
+ delete this._currentRequests[id];
+ }
+ /**
+ * Returns information about all pending requests, in segment's chronological
+ * order.
+ * @returns {Array.}
+ */;
+ _proto.getRequests = function getRequests() {
+ return (0,object_values/* default */.Z)(this._currentRequests).filter(function (x) {
+ return x != null;
+ }).sort(function (reqA, reqB) {
+ return reqA.content.segment.time - reqB.content.segment.time;
+ });
};
- return EWMA;
+ return PendingRequestsStore;
}();
-;// CONCATENATED MODULE: ./src/core/adaptive/network_analyzer.ts
+;// CONCATENATED MODULE: ./src/core/adaptive/utils/representation_score_calculator.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -43399,318 +39601,151 @@ var EWMA = /*#__PURE__*/function () {
*/
-
-
-/**
- * Get pending segment request(s) starting with the asked segment position.
- * @param {Object} requests - Every requests pending, in a chronological
- * order in terms of segment time.
- * @param {number} neededPosition
- * @returns {Array.}
- */
-function getConcernedRequests(requests, neededPosition) {
- /** Index of the request for the next needed segment, in `requests`. */
- var nextSegmentIndex = -1;
- for (var i = 0; i < requests.length; i++) {
- var segment = requests[i].content.segment;
- if (segment.duration <= 0) {
- continue;
- }
- var segmentEnd = segment.time + segment.duration;
- if (!segment.complete) {
- if (i === requests.length - 1 && neededPosition - segment.time > -1.2) {
- nextSegmentIndex = i;
- break;
- }
- }
- if (segmentEnd > neededPosition && neededPosition - segment.time > -1.2) {
- nextSegmentIndex = i;
- break;
- }
- }
- if (nextSegmentIndex < 0) {
- // Not found
- return [];
- }
- var nextRequest = requests[nextSegmentIndex];
- var segmentTime = nextRequest.content.segment.time;
- var filteredRequests = [nextRequest];
- // Get the possibly multiple requests for that segment's position
- for (var _i = nextSegmentIndex + 1; _i < requests.length; _i++) {
- if (requests[_i].content.segment.time === segmentTime) {
- filteredRequests.push(requests[_i]);
- } else {
- break;
- }
- }
- return filteredRequests;
-}
/**
- * Estimate the __VERY__ recent bandwidth based on a single unfinished request.
- * Useful when the current bandwidth seemed to have fallen quickly.
+ * Calculate the "maintainability score" of a given Representation:
+ * - A score higher than 1 means that the Representation can theorically
+ * be downloaded faster than the duration of the media it represents.
+ * (e.g. a segment representing 4 seconds can be downloaded in less than 4
+ * seconds).
+ * - A score lower or equal to 1 means that the Representation cannot be
+ * downloaded
*
- * @param {Object} request
- * @returns {number|undefined}
- */
-function estimateRequestBandwidth(request) {
- if (request.progress.length < 5) {
- // threshold from which we can consider
- // progress events reliably
- return undefined;
- }
- // try to infer quickly the current bitrate based on the
- // progress events
- var ewma1 = new EWMA(2);
- var progress = request.progress;
- for (var i = 1; i < progress.length; i++) {
- var bytesDownloaded = progress[i].size - progress[i - 1].size;
- var timeElapsed = progress[i].timestamp - progress[i - 1].timestamp;
- var reqBitrate = bytesDownloaded * 8 / (timeElapsed / 1000);
- ewma1.addSample(timeElapsed / 1000, reqBitrate);
- }
- return ewma1.getEstimate();
-}
-/**
- * Estimate remaining time for a pending request from a progress event.
- * @param {Object} lastProgressEvent
- * @param {number} bandwidthEstimate
- * @returns {number}
- */
-function estimateRemainingTime(lastProgressEvent, bandwidthEstimate) {
- var remainingData = (lastProgressEvent.totalSize - lastProgressEvent.size) * 8;
- return Math.max(remainingData / bandwidthEstimate, 0);
-}
-/**
- * Check if the request for the most needed segment is too slow.
- * If that's the case, re-calculate the bandwidth urgently based on
- * this single request.
- * @param {Object} pendingRequests - Every requests pending, in a chronological
- * order in terms of segment time.
- * @param {Object} playbackInfo - Information on the current playback.
- * @param {Object|null} currentRepresentation - The Representation being
- * presently being loaded.
- * @param {boolean} lowLatencyMode - If `true`, we're playing the content as a
- * low latency content - where requests might be pending when the segment is
- * still encoded.
- * @param {Number} lastEstimatedBitrate - Last bitrate estimate emitted.
- * @returns {Number|undefined}
- */
-function estimateStarvationModeBitrate(pendingRequests, playbackInfo, currentRepresentation, lowLatencyMode, lastEstimatedBitrate) {
- if (lowLatencyMode) {
- // TODO Skip only for newer segments?
- return undefined;
- }
- var bufferGap = playbackInfo.bufferGap,
- speed = playbackInfo.speed,
- position = playbackInfo.position;
- var realBufferGap = isFinite(bufferGap) ? bufferGap : 0;
- var nextNeededPosition = position.last + realBufferGap;
- var concernedRequests = getConcernedRequests(pendingRequests, nextNeededPosition);
- if (concernedRequests.length !== 1) {
- // 0 == no request
- // 2+ == too complicated to calculate
- return undefined;
- }
- var concernedRequest = concernedRequests[0];
- var now = performance.now();
- var lastProgressEvent = concernedRequest.progress.length > 0 ? concernedRequest.progress[concernedRequest.progress.length - 1] : undefined;
- // first, try to do a quick estimate from progress events
- var bandwidthEstimate = estimateRequestBandwidth(concernedRequest);
- if (lastProgressEvent !== undefined && bandwidthEstimate !== undefined) {
- var remainingTime = estimateRemainingTime(lastProgressEvent, bandwidthEstimate);
- // if the remaining time does seem reliable
- if ((now - lastProgressEvent.timestamp) / 1000 <= remainingTime) {
- // Calculate estimated time spent rebuffering if we continue doing that request.
- var expectedRebufferingTime = remainingTime - realBufferGap / speed;
- if (expectedRebufferingTime > 2000) {
- return bandwidthEstimate;
- }
- }
- }
- if (!concernedRequest.content.segment.complete) {
- return undefined;
- }
- var chunkDuration = concernedRequest.content.segment.duration;
- var requestElapsedTime = (now - concernedRequest.requestTimestamp) / 1000;
- var reasonableElapsedTime = requestElapsedTime <= (chunkDuration * 1.5 + 2) / speed;
- if (currentRepresentation == null || reasonableElapsedTime) {
- return undefined;
- }
- // calculate a reduced bitrate from the current one
- var factor = chunkDuration / requestElapsedTime;
- var reducedBitrate = currentRepresentation.bitrate * Math.min(0.7, factor);
- if (lastEstimatedBitrate === undefined || reducedBitrate < lastEstimatedBitrate) {
- return reducedBitrate;
- }
-}
-/**
- * Returns true if, based on the current requests, it seems that the ABR should
- * switch immediately if a lower bitrate is more adapted.
- * Returns false if it estimates that you have time before switching to a lower
- * bitrate.
- * @param {Object} playbackInfo - Information on the current playback.
- * @param {Object} requests - Every requests pending, in a chronological
- * order in terms of segment time.
- * @param {boolean} lowLatencyMode - If `true`, we're playing the content as a
- * low latency content, as close to the live edge as possible.
- * @returns {boolean}
+ * The score follows a simple linear relation to both variables it is based
+ * on:
+ * - if n seconds of content can be downloaded in 2*n seconds, the score will
+ * be `0.5`.
+ * - if n seconds of content can be downloaded in n seconds, the score will be
+ * `1`.
+ * - if n seconds of content can be downloaded in n/2 seconds, the score will
+ * be `2`.
+ * - ...
+ *
+ * The score is mainly here to tell you when your buffer-based guesses are
+ * actually higher than the quality you should normally reach.
+ *
+ * /!\ Please bear in mind that we don't consider the playback rate in those
+ * operations.
+ * Still, integrating the playback rate a posteriori should not be difficult
+ * (e.g. you can just divide the score by that rate).
+ *
+ * @class RepresentationScoreCalculator
*/
-function shouldDirectlySwitchToLowBitrate(playbackInfo, requests, lowLatencyMode) {
- if (lowLatencyMode) {
- // TODO only when playing close to the live edge?
- return true;
- }
- var realBufferGap = isFinite(playbackInfo.bufferGap) ? playbackInfo.bufferGap : 0;
- var nextNeededPosition = playbackInfo.position.last + realBufferGap;
- var nextRequest = (0,array_find/* default */.Z)(requests, function (_ref) {
- var content = _ref.content;
- return content.segment.duration > 0 && content.segment.time + content.segment.duration > nextNeededPosition;
- });
- if (nextRequest === undefined) {
- return true;
- }
- var now = performance.now();
- var lastProgressEvent = nextRequest.progress.length > 0 ? nextRequest.progress[nextRequest.progress.length - 1] : undefined;
- // first, try to do a quick estimate from progress events
- var bandwidthEstimate = estimateRequestBandwidth(nextRequest);
- if (lastProgressEvent === undefined || bandwidthEstimate === undefined) {
- return true;
- }
- var remainingTime = estimateRemainingTime(lastProgressEvent, bandwidthEstimate);
- if ((now - lastProgressEvent.timestamp) / 1000 > remainingTime * 1.2) {
- return true;
+var RepresentationScoreCalculator = /*#__PURE__*/function () {
+ function RepresentationScoreCalculator() {
+ this._currentRepresentationData = null;
+ this._lastRepresentationWithGoodScore = null;
}
- var expectedRebufferingTime = remainingTime - realBufferGap / playbackInfo.speed;
- return expectedRebufferingTime > -1.5;
-}
-/**
- * Analyze the current network conditions and give a bandwidth estimate as well
- * as a maximum bitrate a Representation should be.
- * @class NetworkAnalyzer
- */
-var NetworkAnalyzer = /*#__PURE__*/function () {
- function NetworkAnalyzer(initialBitrate, lowLatencyMode) {
- var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
- ABR_STARVATION_GAP = _config$getCurrent.ABR_STARVATION_GAP,
- OUT_OF_STARVATION_GAP = _config$getCurrent.OUT_OF_STARVATION_GAP,
- ABR_STARVATION_FACTOR = _config$getCurrent.ABR_STARVATION_FACTOR,
- ABR_REGULAR_FACTOR = _config$getCurrent.ABR_REGULAR_FACTOR;
- this._initialBitrate = initialBitrate;
- this._inStarvationMode = false;
- this._lowLatencyMode = lowLatencyMode;
- if (lowLatencyMode) {
- this._config = {
- starvationGap: ABR_STARVATION_GAP.LOW_LATENCY,
- outOfStarvationGap: OUT_OF_STARVATION_GAP.LOW_LATENCY,
- starvationBitrateFactor: ABR_STARVATION_FACTOR.LOW_LATENCY,
- regularBitrateFactor: ABR_REGULAR_FACTOR.LOW_LATENCY
- };
+ /**
+ * Add new sample data.
+ * @param {Representation} representation
+ * @param {number} requestDuration - duration taken for doing the request for
+ * the whole segment.
+ * @param {number} segmentDuration - media duration of the whole segment, in
+ * seconds.
+ */
+ var _proto = RepresentationScoreCalculator.prototype;
+ _proto.addSample = function addSample(representation, requestDuration, segmentDuration) {
+ var ratio = segmentDuration / requestDuration;
+ var currentRep = this._currentRepresentationData;
+ var currentEWMA;
+ if (currentRep !== null && currentRep.representation.id === representation.id) {
+ currentEWMA = currentRep.ewma;
+ currentRep.ewma.addSample(requestDuration, ratio);
+ currentRep.loadedDuration += segmentDuration;
+ currentRep.loadedSegments++;
} else {
- this._config = {
- starvationGap: ABR_STARVATION_GAP.DEFAULT,
- outOfStarvationGap: OUT_OF_STARVATION_GAP.DEFAULT,
- starvationBitrateFactor: ABR_STARVATION_FACTOR.DEFAULT,
- regularBitrateFactor: ABR_REGULAR_FACTOR.DEFAULT
+ currentEWMA = new EWMA(5);
+ currentEWMA.addSample(requestDuration, ratio);
+ this._currentRepresentationData = {
+ representation: representation,
+ ewma: currentEWMA,
+ loadedDuration: segmentDuration,
+ loadedSegments: 0
};
}
+ if (currentEWMA.getEstimate() > 1 && this._lastRepresentationWithGoodScore !== representation) {
+ log/* default.debug */.Z.debug("ABR: New last stable representation", representation.bitrate);
+ this._lastRepresentationWithGoodScore = representation;
+ }
}
/**
- * Gives an estimate of the current bandwidth and of the bitrate that should
- * be considered for chosing a `representation`.
- * This estimate is only based on network metrics.
- * @param {Object} playbackInfo - Gives current information about playback.
- * @param {Object} bandwidthEstimator - `BandwidthEstimator` allowing to
- * produce network bandwidth estimates.
- * @param {Object|null} currentRepresentation - The Representation currently
- * chosen.
- * `null` if no Representation has been chosen yet.
- * @param {Array.} currentRequests - All segment requests by segment's
- * start chronological order
- * @param {number|undefined} lastEstimatedBitrate - Bitrate emitted during the
- * last estimate.
- * @returns {Object}
- */
- var _proto = NetworkAnalyzer.prototype;
- _proto.getBandwidthEstimate = function getBandwidthEstimate(playbackInfo, bandwidthEstimator, currentRepresentation, currentRequests, lastEstimatedBitrate) {
- var newBitrateCeil; // bitrate ceil for the chosen Representation
- var bandwidthEstimate;
- var localConf = this._config;
- var bufferGap = playbackInfo.bufferGap,
- position = playbackInfo.position,
- duration = playbackInfo.duration;
- var realBufferGap = isFinite(bufferGap) ? bufferGap : 0;
- var _config$getCurrent2 = config/* default.getCurrent */.Z.getCurrent(),
- ABR_STARVATION_DURATION_DELTA = _config$getCurrent2.ABR_STARVATION_DURATION_DELTA;
- // check if should get in/out of starvation mode
- if (isNaN(duration) || realBufferGap + position.last < duration - ABR_STARVATION_DURATION_DELTA) {
- if (!this._inStarvationMode && realBufferGap <= localConf.starvationGap) {
- log/* default.info */.Z.info("ABR: enter starvation mode.");
- this._inStarvationMode = true;
- } else if (this._inStarvationMode && realBufferGap >= localConf.outOfStarvationGap) {
- log/* default.info */.Z.info("ABR: exit starvation mode.");
- this._inStarvationMode = false;
- }
- } else if (this._inStarvationMode) {
- log/* default.info */.Z.info("ABR: exit starvation mode.");
- this._inStarvationMode = false;
- }
- // If in starvation mode, check if a quick new estimate can be done
- // from the last requests.
- // If so, cancel previous estimates and replace it by the new one
- if (this._inStarvationMode) {
- bandwidthEstimate = estimateStarvationModeBitrate(currentRequests, playbackInfo, currentRepresentation, this._lowLatencyMode, lastEstimatedBitrate);
- if (bandwidthEstimate != null) {
- log/* default.info */.Z.info("ABR: starvation mode emergency estimate:", bandwidthEstimate);
- bandwidthEstimator.reset();
- newBitrateCeil = currentRepresentation == null ? bandwidthEstimate : Math.min(bandwidthEstimate, currentRepresentation.bitrate);
- }
- }
- // if newBitrateCeil is not yet defined, do the normal estimation
- if (newBitrateCeil == null) {
- bandwidthEstimate = bandwidthEstimator.getEstimate();
- if (bandwidthEstimate != null) {
- newBitrateCeil = bandwidthEstimate * (this._inStarvationMode ? localConf.starvationBitrateFactor : localConf.regularBitrateFactor);
- } else if (lastEstimatedBitrate != null) {
- newBitrateCeil = lastEstimatedBitrate * (this._inStarvationMode ? localConf.starvationBitrateFactor : localConf.regularBitrateFactor);
- } else {
- newBitrateCeil = this._initialBitrate;
- }
- }
- if (playbackInfo.speed > 1) {
- newBitrateCeil /= playbackInfo.speed;
+ * Get score estimate for the given Representation.
+ * undefined if no estimate is available.
+ * @param {Representation} representation
+ * @returns {number|undefined}
+ */;
+ _proto.getEstimate = function getEstimate(representation) {
+ if (this._currentRepresentationData === null || this._currentRepresentationData.representation.id !== representation.id) {
+ return undefined;
}
- return {
- bandwidthEstimate: bandwidthEstimate,
- bitrateChosen: newBitrateCeil
- };
+ var _this$_currentReprese = this._currentRepresentationData,
+ ewma = _this$_currentReprese.ewma,
+ loadedSegments = _this$_currentReprese.loadedSegments,
+ loadedDuration = _this$_currentReprese.loadedDuration;
+ var estimate = ewma.getEstimate();
+ var confidenceLevel = loadedSegments >= 5 && loadedDuration >= 10 ? 1 /* ScoreConfidenceLevel.HIGH */ : 0 /* ScoreConfidenceLevel.LOW */;
+ return [estimate, confidenceLevel];
}
/**
- * For a given wanted bitrate, tells if should switch urgently.
- * @param {number} bitrate - The new estimated bitrate.
- * @param {Object|null} currentRepresentation - The Representation being
- * presently being loaded.
- * @param {Array.} currentRequests - All segment requests by segment's
- * start chronological order
- * @param {Object} playbackInfo - Information on the current playback.
- * @returns {boolean}
+ * Returns last Representation which had reached a score superior to 1.
+ * This Representation is the last known one which could be maintained.
+ * Useful to know if a current guess is higher than what you should
+ * normally be able to play.
+ * `null` if no Representation ever reach that score.
+ * @returns {Representation|null}
*/;
- _proto.isUrgent = function isUrgent(bitrate, currentRepresentation, currentRequests, playbackInfo) {
- if (currentRepresentation === null) {
- return true;
- } else if (bitrate === currentRepresentation.bitrate) {
- return false;
- } else if (bitrate > currentRepresentation.bitrate) {
- return !this._inStarvationMode;
- }
- return shouldDirectlySwitchToLowBitrate(playbackInfo, currentRequests, this._lowLatencyMode);
+ _proto.getLastStableRepresentation = function getLastStableRepresentation() {
+ return this._lastRepresentationWithGoodScore;
};
- return NetworkAnalyzer;
+ return RepresentationScoreCalculator;
}();
-;// CONCATENATED MODULE: ./src/core/adaptive/guess_based_chooser.ts
-function guess_based_chooser_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = guess_based_chooser_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
-function guess_based_chooser_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return guess_based_chooser_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return guess_based_chooser_arrayLikeToArray(o, minLen); }
-function guess_based_chooser_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
+;// CONCATENATED MODULE: ./src/core/adaptive/utils/select_optimal_representation.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * From the given array of Representations (sorted by bitrate order ascending),
+ * returns the one corresponding to the given optimal, minimum and maximum
+ * bitrates.
+ * @param {Array.} representations - The representations array,
+ * sorted in bitrate ascending order.
+ * @param {Number} optimalBitrate - The optimal bitrate the Representation
+ * should have under the current condition.
+ * @param {Number} minBitrate - The minimum bitrate the chosen Representation
+ * should have. We will take the Representation with the maximum bitrate if none
+ * is found.
+ * @param {Number} maxBitrate - The maximum bitrate the chosen Representation
+ * should have. We will take the Representation with the minimum bitrate if none
+ * is found.
+ * @returns {Representation|undefined}
+ */
+function selectOptimalRepresentation(representations, optimalBitrate, minBitrate, maxBitrate) {
+ var wantedBitrate = optimalBitrate <= minBitrate ? minBitrate : optimalBitrate >= maxBitrate ? maxBitrate : optimalBitrate;
+ var firstIndexTooHigh = (0,array_find_index/* default */.Z)(representations, function (representation) {
+ return representation.bitrate > wantedBitrate;
+ });
+ if (firstIndexTooHigh === -1) {
+ return representations[representations.length - 1];
+ } else if (firstIndexTooHigh === 0) {
+ return representations[0];
+ }
+ return representations[firstIndexTooHigh - 1];
+}
+;// CONCATENATED MODULE: ./src/core/adaptive/adaptive_representation_selector.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -43729,387 +39764,442 @@ function guess_based_chooser_arrayLikeToArray(arr, len) { if (len == null || len
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Create default shared references
+var manualBitrateDefaultRef = (0,reference/* default */.ZP)(-1);
+manualBitrateDefaultRef.finish();
+var minAutoBitrateDefaultRef = (0,reference/* default */.ZP)(0);
+minAutoBitrateDefaultRef.finish();
+var maxAutoBitrateDefaultRef = (0,reference/* default */.ZP)(Infinity);
+maxAutoBitrateDefaultRef.finish();
+var limitWidthDefaultRef = (0,reference/* default */.ZP)(undefined);
+limitWidthDefaultRef.finish();
+var throttleBitrateDefaultRef = (0,reference/* default */.ZP)(Infinity);
+throttleBitrateDefaultRef.finish();
/**
- * Estimate which Representation should be played based on risky "guesses".
- *
- * Basically, this `GuessBasedChooser` will attempt switching to the superior
- * quality when conditions allows this and then check if we're able to maintain
- * this quality. If we're not, it will rollbacks to the previous, maintaninable,
- * guess.
+ * Select the most adapted Representation according to the network and buffer
+ * metrics it receives.
*
- * The algorithm behind the `GuessBasedChooser` is very risky in terms of
- * rebuffering chances. As such, it should only be used when other approach
- * don't work (e.g. low-latency contents).
- * @class GuessBasedChooser
+ * @param {Object} options - Initial configuration (see type definition)
+ * @returns {Object} - Interface allowing to select a Representation.
+ * @see IRepresentationEstimator
*/
-var GuessBasedChooser = /*#__PURE__*/function () {
+function createAdaptiveRepresentationSelector(options) {
/**
- * Create a new `GuessBasedChooser`.
- * @param {Object} scoreCalculator
- * @param {Object} prevEstimate
+ * Allows to estimate the current network bandwidth.
+ * One per active media type.
*/
- function GuessBasedChooser(scoreCalculator, prevEstimate) {
- this._scoreCalculator = scoreCalculator;
- this._lastAbrEstimate = prevEstimate;
- this._consecutiveWrongGuesses = 0;
- this._blockGuessesUntil = 0;
- this._lastMaintanableBitrate = null;
- }
+ var bandwidthEstimators = {};
+ var manualBitrates = options.manualBitrates,
+ minAutoBitrates = options.minAutoBitrates,
+ maxAutoBitrates = options.maxAutoBitrates,
+ initialBitrates = options.initialBitrates,
+ throttlers = options.throttlers,
+ lowLatencyMode = options.lowLatencyMode;
/**
- * Perform a "guess", which basically indicates which Representation should be
- * chosen according to the `GuessBasedChooser`.
+ * Returns Object emitting Representation estimates as well as callbacks
+ * allowing to helping it produce them.
*
- * @param {Array.} representations - Array of all Representation the
- * GuessBasedChooser can choose from, sorted by bitrate ascending.
- * /!\ It is very important that Representation in that Array are sorted by
- * bitrate ascending for this method to work as intented.
- * @param {Object} observation - Last playback observation performed.
- * @param {Object} currentRepresentation - The Representation currently
- * loading.
- * @param {number} incomingBestBitrate - The bitrate of the Representation
- * chosen by the more optimistic of the other ABR algorithms currently.
- * @param {Array.} requests - Information on all pending requests.
- * @returns {Object|null} - If a guess is made, return that guess, else
- * returns `null` (in which case you should fallback to another ABR
- * algorithm).
+ * @see IRepresentationEstimator
+ * @param {Object} context
+ * @param {Object} currentRepresentation
+ * @param {Object} representations
+ * @param {Object} playbackObserver
+ * @param {Object} stopAllEstimates
+ * @returns {Array.}
*/
- var _proto = GuessBasedChooser.prototype;
- _proto.getGuess = function getGuess(representations, observation, currentRepresentation, incomingBestBitrate, requests) {
- var bufferGap = observation.bufferGap,
- speed = observation.speed;
- var lastChosenRep = this._lastAbrEstimate.representation;
- if (lastChosenRep === null) {
- return null; // There's nothing to base our guess on
- }
-
- if (incomingBestBitrate > lastChosenRep.bitrate) {
- // ABR estimates are already superior or equal to the guess
- // we'll be doing here, so no need to guess
- if (this._lastAbrEstimate.algorithmType === 2 /* ABRAlgorithmType.GuessBased */) {
- if (this._lastAbrEstimate.representation !== null) {
- this._lastMaintanableBitrate = this._lastAbrEstimate.representation.bitrate;
- }
- this._consecutiveWrongGuesses = 0;
- }
- return null;
+ return function getEstimates(context, currentRepresentation, representations, playbackObserver, stopAllEstimates) {
+ var type = context.adaptation.type;
+ var bandwidthEstimator = _getBandwidthEstimator(type);
+ var manualBitrate = (0,take_first_set/* default */.Z)(manualBitrates[type], manualBitrateDefaultRef);
+ var minAutoBitrate = (0,take_first_set/* default */.Z)(minAutoBitrates[type], minAutoBitrateDefaultRef);
+ var maxAutoBitrate = (0,take_first_set/* default */.Z)(maxAutoBitrates[type], maxAutoBitrateDefaultRef);
+ var initialBitrate = (0,take_first_set/* default */.Z)(initialBitrates[type], 0);
+ var filters = {
+ limitWidth: (0,take_first_set/* default */.Z)(throttlers.limitWidth[type], limitWidthDefaultRef),
+ throttleBitrate: (0,take_first_set/* default */.Z)(throttlers.throttleBitrate[type], throttlers.throttle[type], throttleBitrateDefaultRef)
+ };
+ return getEstimateReference({
+ bandwidthEstimator: bandwidthEstimator,
+ context: context,
+ currentRepresentation: currentRepresentation,
+ filters: filters,
+ initialBitrate: initialBitrate,
+ manualBitrate: manualBitrate,
+ minAutoBitrate: minAutoBitrate,
+ maxAutoBitrate: maxAutoBitrate,
+ playbackObserver: playbackObserver,
+ representations: representations,
+ lowLatencyMode: lowLatencyMode
+ }, stopAllEstimates);
+ };
+ /**
+ * Returns interface allowing to estimate network throughtput for a given type.
+ * @param {string} bufferType
+ * @returns {Object}
+ */
+ function _getBandwidthEstimator(bufferType) {
+ var originalBandwidthEstimator = bandwidthEstimators[bufferType];
+ if (originalBandwidthEstimator == null) {
+ log/* default.debug */.Z.debug("ABR: Creating new BandwidthEstimator for ", bufferType);
+ var bandwidthEstimator = new BandwidthEstimator();
+ bandwidthEstimators[bufferType] = bandwidthEstimator;
+ return bandwidthEstimator;
}
- var scoreData = this._scoreCalculator.getEstimate(currentRepresentation);
- if (this._lastAbrEstimate.algorithmType !== 2 /* ABRAlgorithmType.GuessBased */) {
- if (scoreData === undefined) {
- return null; // not enough information to start guessing
- }
-
- if (this._canGuessHigher(bufferGap, speed, scoreData)) {
- var nextRepresentation = getNextRepresentation(representations, currentRepresentation);
- if (nextRepresentation !== null) {
- return nextRepresentation;
- }
- }
- return null;
+ return originalBandwidthEstimator;
+ }
+}
+/**
+ * Estimate regularly the current network bandwidth and the best Representation
+ * that can be played according to the current network and playback conditions.
+ *
+ * `getEstimateReference` only does estimations for a given type (e.g.
+ * "audio", "video" etc.) and Period.
+ *
+ * If estimates for multiple types and/or Periods are needed, you should
+ * call `getEstimateReference` as many times.
+ *
+ * This function returns a tuple:
+ * - the first element being the object through which estimates will be produced
+ * - the second element being callbacks that have to be triggered at various
+ * events to help it doing those estimates.
+ *
+ * @param {Object} args
+ * @param {Object} stopAllEstimates
+ * @returns {Array.}
+ */
+function getEstimateReference(_ref, stopAllEstimates) {
+ var bandwidthEstimator = _ref.bandwidthEstimator,
+ context = _ref.context,
+ currentRepresentation = _ref.currentRepresentation,
+ filters = _ref.filters,
+ initialBitrate = _ref.initialBitrate,
+ lowLatencyMode = _ref.lowLatencyMode,
+ manualBitrate = _ref.manualBitrate,
+ maxAutoBitrate = _ref.maxAutoBitrate,
+ minAutoBitrate = _ref.minAutoBitrate,
+ playbackObserver = _ref.playbackObserver,
+ representationsRef = _ref.representations;
+ var scoreCalculator = new RepresentationScoreCalculator();
+ var networkAnalyzer = new NetworkAnalyzer(initialBitrate !== null && initialBitrate !== void 0 ? initialBitrate : 0, lowLatencyMode);
+ var requestsStore = new PendingRequestsStore();
+ var onAddedSegment = noop/* default */.Z;
+ var callbacks = {
+ metrics: onMetric,
+ requestBegin: onRequestBegin,
+ requestProgress: onRequestProgress,
+ requestEnd: onRequestEnd,
+ addedSegment: function addedSegment(val) {
+ onAddedSegment(val);
}
- // If we reached here, we're currently already in guessing mode
- if (this._isLastGuessValidated(lastChosenRep, incomingBestBitrate, scoreData)) {
- log/* default.debug */.Z.debug("ABR: Guessed Representation validated", lastChosenRep.bitrate);
- this._lastMaintanableBitrate = lastChosenRep.bitrate;
- this._consecutiveWrongGuesses = 0;
+ };
+ /**
+ * `TaskCanceller` allowing to stop producing estimate.
+ * This TaskCanceller is used both for restarting estimates with a new
+ * configuration and to cancel them altogether.
+ */
+ var currentEstimatesCanceller = new task_canceller/* default */.ZP();
+ currentEstimatesCanceller.linkToSignal(stopAllEstimates);
+ // Create `ISharedReference` on which estimates will be emitted.
+ var estimateRef = createEstimateReference(manualBitrate.getValue(), representationsRef.getValue(), currentEstimatesCanceller.signal);
+ manualBitrate.onUpdate(restartEstimatesProductionFromCurrentConditions, {
+ clearSignal: stopAllEstimates
+ });
+ representationsRef.onUpdate(restartEstimatesProductionFromCurrentConditions, {
+ clearSignal: stopAllEstimates
+ });
+ return {
+ estimates: estimateRef,
+ callbacks: callbacks
+ };
+ function createEstimateReference(manualBitrateVal, representations, innerCancellationSignal) {
+ if (representations.length === 0) {
+ // No Representation given, return `null` as documented
+ return (0,reference/* default */.ZP)({
+ representation: null,
+ bitrate: undefined,
+ knownStableBitrate: undefined,
+ manual: false,
+ urgent: true
+ });
}
- if (currentRepresentation.id !== lastChosenRep.id) {
- return lastChosenRep;
+ if (manualBitrateVal >= 0) {
+ // A manual bitrate has been set. Just choose Representation according to it.
+ var manualRepresentation = selectOptimalRepresentation(representations, manualBitrateVal, 0, Infinity);
+ return (0,reference/* default */.ZP)({
+ representation: manualRepresentation,
+ bitrate: undefined,
+ knownStableBitrate: undefined,
+ manual: true,
+ urgent: true // a manual bitrate switch should happen immediately
+ });
}
- var shouldStopGuess = this._shouldStopGuess(currentRepresentation, scoreData, bufferGap, requests);
- if (shouldStopGuess) {
- // Block guesses for a time
- this._consecutiveWrongGuesses++;
- this._blockGuessesUntil = performance.now() + Math.min(this._consecutiveWrongGuesses * 15000, 120000);
- return getPreviousRepresentation(representations, currentRepresentation);
- } else if (scoreData === undefined) {
- return currentRepresentation;
+
+ if (representations.length === 1) {
+ // There's only a single Representation. Just choose it.
+ return (0,reference/* default */.ZP)({
+ bitrate: undefined,
+ representation: representations[0],
+ manual: false,
+ urgent: true,
+ knownStableBitrate: undefined
+ });
}
- if (this._canGuessHigher(bufferGap, speed, scoreData)) {
- var _nextRepresentation = getNextRepresentation(representations, currentRepresentation);
- if (_nextRepresentation !== null) {
- return _nextRepresentation;
+ /** If true, Representation estimates based on the buffer health might be used. */
+ var allowBufferBasedEstimates = false;
+ /**
+ * Current optimal Representation's bandwidth choosen by a buffer-based
+ * adaptive algorithm.
+ */
+ var currentBufferBasedEstimate;
+ var bitrates = representations.map(function (r) {
+ return r.bitrate;
+ });
+ /**
+ * Module calculating the optimal Representation based on the current
+ * buffer's health (i.e. whether enough data is buffered, history of
+ * buffer size etc.).
+ */
+ var bufferBasedChooser = new BufferBasedChooser(bitrates);
+ /** Store the previous estimate made here. */
+ var prevEstimate = new LastEstimateStorage();
+ /**
+ * Module calculating the optimal Representation by "guessing it" with a
+ * step-by-step algorithm.
+ * Only used in very specific scenarios.
+ */
+ var guessBasedChooser = new GuessBasedChooser(scoreCalculator, prevEstimate);
+ // get initial observation for initial estimate
+ var lastPlaybackObservation = playbackObserver.getReference().getValue();
+ /** Reference through which estimates are emitted. */
+ var innerEstimateRef = (0,reference/* default */.ZP)(getCurrentEstimate());
+ // Listen to playback observations
+ playbackObserver.listen(function (obs) {
+ lastPlaybackObservation = obs;
+ updateEstimate();
+ }, {
+ includeLastObservation: false,
+ clearSignal: innerCancellationSignal
+ });
+ onAddedSegment = function onAddedSegment(val) {
+ if (lastPlaybackObservation === null) {
+ return;
}
- }
- return currentRepresentation;
- }
- /**
- * Returns `true` if we've enough confidence on the current situation to make
- * a higher guess.
- * @param {number} bufferGap
- * @param {number} speed
- * @param {Array} scoreData
- * @returns {boolean}
- */;
- _proto._canGuessHigher = function _canGuessHigher(bufferGap, speed, _ref) {
- var score = _ref[0],
- scoreConfidenceLevel = _ref[1];
- return isFinite(bufferGap) && bufferGap >= 2.5 && performance.now() > this._blockGuessesUntil && scoreConfidenceLevel === 1 /* ScoreConfidenceLevel.HIGH */ && score / speed > 1.01;
- }
- /**
- * Returns `true` if the pending guess of `lastGuess` seems to not
- * be maintainable and as such should be stopped.
- * @param {Object} lastGuess
- * @param {Array} scoreData
- * @param {number} bufferGap
- * @param {Array.} requests
- * @returns {boolean}
- */;
- _proto._shouldStopGuess = function _shouldStopGuess(lastGuess, scoreData, bufferGap, requests) {
- if (scoreData !== undefined && scoreData[0] < 1.01) {
- return true;
- } else if ((scoreData === undefined || scoreData[0] < 1.2) && bufferGap < 0.6) {
- return true;
- }
- var guessedRepresentationRequests = requests.filter(function (req) {
- return req.content.representation.id === lastGuess.id;
+ var _lastPlaybackObservat = lastPlaybackObservation,
+ position = _lastPlaybackObservat.position,
+ speed = _lastPlaybackObservat.speed;
+ var timeRanges = val.buffered;
+ var bufferGap = (0,ranges/* getLeftSizeOfRange */.L7)(timeRanges, position.last);
+ var representation = val.content.representation;
+ var scoreData = scoreCalculator.getEstimate(representation);
+ var currentScore = scoreData === null || scoreData === void 0 ? void 0 : scoreData[0];
+ var currentBitrate = representation.bitrate;
+ var observation = {
+ bufferGap: bufferGap,
+ currentBitrate: currentBitrate,
+ currentScore: currentScore,
+ speed: speed
+ };
+ currentBufferBasedEstimate = bufferBasedChooser.getEstimate(observation);
+ updateEstimate();
+ };
+ minAutoBitrate.onUpdate(updateEstimate, {
+ clearSignal: innerCancellationSignal
});
- var now = performance.now();
- for (var _iterator = guess_based_chooser_createForOfIteratorHelperLoose(guessedRepresentationRequests), _step; !(_step = _iterator()).done;) {
- var req = _step.value;
- var requestElapsedTime = now - req.requestTimestamp;
- if (req.content.segment.isInit) {
- if (requestElapsedTime > 1000) {
- return true;
- }
- } else if (requestElapsedTime > req.content.segment.duration * 1000 + 200) {
- return true;
- } else {
- var fastBw = estimateRequestBandwidth(req);
- if (fastBw !== undefined && fastBw < lastGuess.bitrate * 0.8) {
- return true;
- }
+ maxAutoBitrate.onUpdate(updateEstimate, {
+ clearSignal: innerCancellationSignal
+ });
+ filters.limitWidth.onUpdate(updateEstimate, {
+ clearSignal: innerCancellationSignal
+ });
+ filters.limitWidth.onUpdate(updateEstimate, {
+ clearSignal: innerCancellationSignal
+ });
+ return innerEstimateRef;
+ function updateEstimate() {
+ innerEstimateRef.setValue(getCurrentEstimate());
+ }
+ /** Returns the actual estimate based on all methods and algorithm available. */
+ function getCurrentEstimate() {
+ var _lastPlaybackObservat2 = lastPlaybackObservation,
+ bufferGap = _lastPlaybackObservat2.bufferGap,
+ position = _lastPlaybackObservat2.position,
+ maximumPosition = _lastPlaybackObservat2.maximumPosition;
+ var widthLimit = filters.limitWidth.getValue();
+ var bitrateThrottle = filters.throttleBitrate.getValue();
+ var currentRepresentationVal = currentRepresentation.getValue();
+ var minAutoBitrateVal = minAutoBitrate.getValue();
+ var maxAutoBitrateVal = maxAutoBitrate.getValue();
+ var filteredReps = getFilteredRepresentations(representations, widthLimit, bitrateThrottle);
+ var requests = requestsStore.getRequests();
+ var _networkAnalyzer$getB = networkAnalyzer.getBandwidthEstimate(lastPlaybackObservation, bandwidthEstimator, currentRepresentationVal, requests, prevEstimate.bandwidth),
+ bandwidthEstimate = _networkAnalyzer$getB.bandwidthEstimate,
+ bitrateChosen = _networkAnalyzer$getB.bitrateChosen;
+ var stableRepresentation = scoreCalculator.getLastStableRepresentation();
+ var knownStableBitrate = stableRepresentation === null ? undefined : stableRepresentation.bitrate / (lastPlaybackObservation.speed > 0 ? lastPlaybackObservation.speed : 1);
+ if (allowBufferBasedEstimates && bufferGap <= 5) {
+ allowBufferBasedEstimates = false;
+ } else if (!allowBufferBasedEstimates && isFinite(bufferGap) && bufferGap > 10) {
+ allowBufferBasedEstimates = true;
+ }
+ /**
+ * Representation chosen when considering only [pessimist] bandwidth
+ * calculation.
+ * This is a safe enough choice but might be lower than what the user
+ * could actually profit from.
+ */
+ var chosenRepFromBandwidth = selectOptimalRepresentation(filteredReps, bitrateChosen, minAutoBitrateVal, maxAutoBitrateVal);
+ var currentBestBitrate = chosenRepFromBandwidth.bitrate;
+ /**
+ * Representation chosen when considering the current buffer size.
+ * If defined, takes precedence over `chosenRepFromBandwidth`.
+ *
+ * This is a very safe choice, yet it is very slow and might not be
+ * adapted to cases where a buffer cannot be build, such as live contents.
+ *
+ * `null` if this buffer size mode is not enabled or if we don't have a
+ * choice from it yet.
+ */
+ var chosenRepFromBufferSize = null;
+ if (allowBufferBasedEstimates && currentBufferBasedEstimate !== undefined && currentBufferBasedEstimate > currentBestBitrate) {
+ chosenRepFromBufferSize = selectOptimalRepresentation(filteredReps, currentBufferBasedEstimate, minAutoBitrateVal, maxAutoBitrateVal);
+ currentBestBitrate = chosenRepFromBufferSize.bitrate;
+ }
+ /**
+ * Representation chosen by the more adventurous `GuessBasedChooser`,
+ * which iterates through Representations one by one until finding one
+ * that cannot be "maintained".
+ *
+ * If defined, takes precedence over both `chosenRepFromBandwidth` and
+ * `chosenRepFromBufferSize`.
+ *
+ * This is the riskiest choice (in terms of rebuffering chances) but is
+ * only enabled when no other solution is adapted (for now, this just
+ * applies for low-latency contents when playing close to the live
+ * edge).
+ *
+ * `null` if not enabled or if there's currently no guess.
+ */
+ var chosenRepFromGuessMode = null;
+ if (lowLatencyMode && currentRepresentationVal !== null && context.manifest.isDynamic && maximumPosition - position.last < 40) {
+ chosenRepFromGuessMode = guessBasedChooser.getGuess(representations, lastPlaybackObservation, currentRepresentationVal, currentBestBitrate, requests);
+ }
+ if (chosenRepFromGuessMode !== null && chosenRepFromGuessMode.bitrate > currentBestBitrate) {
+ log/* default.debug */.Z.debug("ABR: Choosing representation with guess-based estimation.", chosenRepFromGuessMode.bitrate, chosenRepFromGuessMode.id);
+ prevEstimate.update(chosenRepFromGuessMode, bandwidthEstimate, 2 /* ABRAlgorithmType.GuessBased */);
+ return {
+ bitrate: bandwidthEstimate,
+ representation: chosenRepFromGuessMode,
+ urgent: currentRepresentationVal === null || chosenRepFromGuessMode.bitrate < currentRepresentationVal.bitrate,
+ manual: false,
+ knownStableBitrate: knownStableBitrate
+ };
+ } else if (chosenRepFromBufferSize !== null) {
+ log/* default.debug */.Z.debug("ABR: Choosing representation with buffer-based estimation.", chosenRepFromBufferSize.bitrate, chosenRepFromBufferSize.id);
+ prevEstimate.update(chosenRepFromBufferSize, bandwidthEstimate, 0 /* ABRAlgorithmType.BufferBased */);
+ return {
+ bitrate: bandwidthEstimate,
+ representation: chosenRepFromBufferSize,
+ urgent: networkAnalyzer.isUrgent(chosenRepFromBufferSize.bitrate, currentRepresentationVal, requests, lastPlaybackObservation),
+ manual: false,
+ knownStableBitrate: knownStableBitrate
+ };
+ } else {
+ log/* default.debug */.Z.debug("ABR: Choosing representation with bandwidth estimation.", chosenRepFromBandwidth.bitrate, chosenRepFromBandwidth.id);
+ prevEstimate.update(chosenRepFromBandwidth, bandwidthEstimate, 1 /* ABRAlgorithmType.BandwidthBased */);
+ return {
+ bitrate: bandwidthEstimate,
+ representation: chosenRepFromBandwidth,
+ urgent: networkAnalyzer.isUrgent(chosenRepFromBandwidth.bitrate, currentRepresentationVal, requests, lastPlaybackObservation),
+ manual: false,
+ knownStableBitrate: knownStableBitrate
+ };
}
}
- return false;
- };
- _proto._isLastGuessValidated = function _isLastGuessValidated(lastGuess, incomingBestBitrate, scoreData) {
- if (scoreData !== undefined && scoreData[1] === 1 /* ScoreConfidenceLevel.HIGH */ && scoreData[0] > 1.5) {
- return true;
- }
- return incomingBestBitrate >= lastGuess.bitrate && (this._lastMaintanableBitrate === null || this._lastMaintanableBitrate < lastGuess.bitrate);
- };
- return GuessBasedChooser;
-}();
-/**
- * From the array of Representations given, returns the Representation with a
- * bitrate immediately superior to the current one.
- * Returns `null` if that "next" Representation is not found.
- *
- * /!\ The representations have to be already sorted by bitrate, in ascending
- * order.
- * @param {Array.} representations - Available representations to choose
- * from, sorted by bitrate in ascending order.
- * @param {Object} currentRepresentation - The Representation currently
- * considered.
- * @returns {Object|null}
- */
-
-function getNextRepresentation(representations, currentRepresentation) {
- var len = representations.length;
- var index = (0,array_find_index/* default */.Z)(representations, function (_ref2) {
- var id = _ref2.id;
- return id === currentRepresentation.id;
- });
- if (index < 0) {
- log/* default.error */.Z.error("ABR: Current Representation not found.");
- return null;
- }
- while (++index < len) {
- if (representations[index].bitrate > currentRepresentation.bitrate) {
- return representations[index];
- }
- }
- return null;
-}
-/**
- * From the array of Representations given, returns the Representation with a
- * bitrate immediately inferior.
- * Returns `null` if that "previous" Representation is not found.
- * @param {Array.} representations
- * @param {Object} currentRepresentation
- * @returns {Object|null}
- */
-function getPreviousRepresentation(representations, currentRepresentation) {
- var index = (0,array_find_index/* default */.Z)(representations, function (_ref3) {
- var id = _ref3.id;
- return id === currentRepresentation.id;
- });
- if (index < 0) {
- log/* default.error */.Z.error("ABR: Current Representation not found.");
- return null;
- }
- while (--index >= 0) {
- if (representations[index].bitrate < currentRepresentation.bitrate) {
- return representations[index];
- }
- }
- return null;
-}
-;// CONCATENATED MODULE: ./src/core/adaptive/utils/bandwidth_estimator.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/**
- * Calculate a mean bandwidth based on the bytes downloaded and the amount
- * of time needed to do so.
- * @class BandwidthEstimator
- */
-var BandwidthEstimator = /*#__PURE__*/function () {
- function BandwidthEstimator() {
- var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
- ABR_FAST_EMA = _config$getCurrent.ABR_FAST_EMA,
- ABR_SLOW_EMA = _config$getCurrent.ABR_SLOW_EMA;
- this._fastEWMA = new EWMA(ABR_FAST_EMA);
- this._slowEWMA = new EWMA(ABR_SLOW_EMA);
- this._bytesSampled = 0;
}
/**
- * Takes a bandwidth sample.
- * @param {number} durationInMs - The amount of time, in milliseconds, for a
- * particular request.
- * @param {number} numberOfBytes - The total number of bytes transferred in
- * that request.
+ * Stop previous estimate production (if one) and restart it considering new
+ * conditions (such as a manual bitrate and/or a new list of Representations).
*/
- var _proto = BandwidthEstimator.prototype;
- _proto.addSample = function addSample(durationInMs, numberOfBytes) {
- var _config$getCurrent2 = config/* default.getCurrent */.Z.getCurrent(),
- ABR_MINIMUM_CHUNK_SIZE = _config$getCurrent2.ABR_MINIMUM_CHUNK_SIZE;
- if (numberOfBytes < ABR_MINIMUM_CHUNK_SIZE) {
- return;
- }
- var bandwidth = numberOfBytes * 8000 / durationInMs;
- var weight = durationInMs / 1000;
- this._bytesSampled += numberOfBytes;
- this._fastEWMA.addSample(weight, bandwidth);
- this._slowEWMA.addSample(weight, bandwidth);
+ function restartEstimatesProductionFromCurrentConditions() {
+ var manualBitrateVal = manualBitrate.getValue();
+ var representations = representationsRef.getValue();
+ currentEstimatesCanceller.cancel();
+ currentEstimatesCanceller = new task_canceller/* default */.ZP();
+ currentEstimatesCanceller.linkToSignal(stopAllEstimates);
+ var newRef = createEstimateReference(manualBitrateVal, representations, currentEstimatesCanceller.signal);
+ newRef.onUpdate(function onNewEstimate(newEstimate) {
+ estimateRef.setValue(newEstimate);
+ }, {
+ clearSignal: currentEstimatesCanceller.signal,
+ emitCurrentValue: true
+ });
}
/**
- * Get estimate of the bandwidth, in bits per seconds.
- * @returns {Number|undefined}
- */;
- _proto.getEstimate = function getEstimate() {
- var _config$getCurrent3 = config/* default.getCurrent */.Z.getCurrent(),
- ABR_MINIMUM_TOTAL_BYTES = _config$getCurrent3.ABR_MINIMUM_TOTAL_BYTES;
- if (this._bytesSampled < ABR_MINIMUM_TOTAL_BYTES) {
- return undefined;
+ * Callback to call when new metrics are available
+ * @param {Object} value
+ */
+ function onMetric(value) {
+ var requestDuration = value.requestDuration,
+ segmentDuration = value.segmentDuration,
+ size = value.size,
+ content = value.content;
+ // calculate bandwidth
+ bandwidthEstimator.addSample(requestDuration, size);
+ if (!content.segment.isInit) {
+ // calculate "maintainability score"
+ var segment = content.segment,
+ representation = content.representation;
+ if (segmentDuration === undefined && !segment.complete) {
+ // We cannot know the real duration of the segment
+ return;
+ }
+ var segDur = segmentDuration !== null && segmentDuration !== void 0 ? segmentDuration : segment.duration;
+ scoreCalculator.addSample(representation, requestDuration / 1000, segDur);
}
- // Take the minimum of these two estimates.
- // This should have the effect of adapting down quickly, but up more slowly.
- return Math.min(this._fastEWMA.getEstimate(), this._slowEWMA.getEstimate());
}
- /** Reset the bandwidth estimation. */;
- _proto.reset = function reset() {
- var _config$getCurrent4 = config/* default.getCurrent */.Z.getCurrent(),
- ABR_FAST_EMA = _config$getCurrent4.ABR_FAST_EMA,
- ABR_SLOW_EMA = _config$getCurrent4.ABR_SLOW_EMA;
- this._fastEWMA = new EWMA(ABR_FAST_EMA);
- this._slowEWMA = new EWMA(ABR_SLOW_EMA);
- this._bytesSampled = 0;
- };
- return BandwidthEstimator;
-}();
-
-;// CONCATENATED MODULE: ./src/core/adaptive/utils/filter_by_bitrate.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Get only representations lower or equal to a given bitrate.
- * If no representation is lower than the given bitrate, returns an array containing
- * all Representation(s) with the lowest available bitrate.
- * @param {Array.} representations - All Representations available
- * @param {Number} bitrate
- * @returns {Array.}
- */
-function filterByBitrate(representations, bitrate) {
- if (representations.length === 0) {
- return [];
+ /** Callback called when a new request begins. */
+ function onRequestBegin(val) {
+ requestsStore.add(val);
}
- representations.sort(function (ra, rb) {
- return ra.bitrate - rb.bitrate;
- });
- var minimumBitrate = representations[0].bitrate;
- var bitrateCeil = Math.max(bitrate, minimumBitrate);
- var firstSuperiorBitrateIndex = (0,array_find_index/* default */.Z)(representations, function (representation) {
- return representation.bitrate > bitrateCeil;
- });
- if (firstSuperiorBitrateIndex === -1) {
- return representations; // All representations have lower bitrates.
+ /** Callback called when progress information is known on a pending request. */
+ function onRequestProgress(val) {
+ requestsStore.addProgress(val);
+ }
+ /** Callback called when a pending request ends. */
+ function onRequestEnd(val) {
+ requestsStore.remove(val.id);
}
-
- return representations.slice(0, firstSuperiorBitrateIndex);
}
-;// CONCATENATED MODULE: ./src/core/adaptive/utils/filter_by_width.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
/**
- * Filter representations based on their width:
- * - the highest width considered will be the one linked to the first
- * representation which has a superior width to the one given.
- * @param {Array.} representations - The representations array
- * @param {Number} width
- * @returns {Array.}
+ * Filter representations given through filters options.
+ * @param {Array.} representations
+ * @param {number | undefined} widthLimit - Filter Object.
+ * @returns {Array.}
*/
-function filterByWidth(representations, width) {
- var sortedRepsByWidth = representations.slice() // clone
- .sort(function (a, b) {
- return (0,take_first_set/* default */.Z)(a.width, 0) - (0,take_first_set/* default */.Z)(b.width, 0);
- });
- var repWithMaxWidth = (0,array_find/* default */.Z)(sortedRepsByWidth, function (representation) {
- return typeof representation.width === "number" && representation.width >= width;
- });
- if (repWithMaxWidth === undefined) {
- return representations;
+function getFilteredRepresentations(representations, widthLimit, bitrateThrottle) {
+ var filteredReps = representations;
+ if (bitrateThrottle < Infinity) {
+ filteredReps = filterByBitrate(filteredReps, bitrateThrottle);
}
- var maxWidth = typeof repWithMaxWidth.width === "number" ? repWithMaxWidth.width : 0;
- return representations.filter(function (representation) {
- return typeof representation.width === "number" ? representation.width <= maxWidth : true;
- });
+ if (widthLimit !== undefined) {
+ filteredReps = filterByWidth(filteredReps, widthLimit);
+ }
+ return filteredReps;
}
-;// CONCATENATED MODULE: ./src/core/adaptive/utils/last_estimate_storage.ts
+;// CONCATENATED MODULE: ./src/core/adaptive/index.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -44125,32 +40215,15 @@ function filterByWidth(representations, width) {
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/** Stores the last estimate made by the `RepresentationEstimator`. */
-var LastEstimateStorage = /*#__PURE__*/function () {
- function LastEstimateStorage() {
- this.bandwidth = undefined;
- this.representation = null;
- this.algorithmType = 3 /* ABRAlgorithmType.None */;
- }
- /**
- * Update this `LastEstimateStorage` with new values.
- * @param {Object} representation - Estimated Representation.
- * @param {number|undefined} bandwidth - Estimated bandwidth.
- * @param {number} algorithmType - The type of algorithm used to produce that
- * estimate.
- */
- var _proto = LastEstimateStorage.prototype;
- _proto.update = function update(representation, bandwidth, algorithmType) {
- this.representation = representation;
- this.bandwidth = bandwidth;
- this.algorithmType = algorithmType;
- };
- return LastEstimateStorage;
-}();
-// EXTERNAL MODULE: ./src/utils/object_values.ts
-var object_values = __webpack_require__(1679);
-;// CONCATENATED MODULE: ./src/core/adaptive/utils/pending_requests_store.ts
+/* harmony default export */ var adaptive = (createAdaptiveRepresentationSelector);
+// EXTERNAL MODULE: ./src/manifest/index.ts + 6 modules
+var manifest = __webpack_require__(1989);
+// EXTERNAL MODULE: ./src/errors/request_error.ts
+var request_error = __webpack_require__(9105);
+// EXTERNAL MODULE: ./src/errors/network_error.ts
+var network_error = __webpack_require__(9362);
+;// CONCATENATED MODULE: ./src/core/fetchers/utils/error_selector.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -44167,72 +40240,22 @@ var object_values = __webpack_require__(1679);
* limitations under the License.
*/
-
/**
- * Store information about pending requests, like information about:
- * - for which segments they are
- * - how the request's progress goes
- * @class PendingRequestsStore
+ * Generate a new error from the infos given.
+ * @param {string} code
+ * @param {Error} error
+ * @returns {Error}
*/
-var PendingRequestsStore = /*#__PURE__*/function () {
- function PendingRequestsStore() {
- this._currentRequests = {};
- }
- /**
- * Add information about a new pending request.
- * @param {Object} payload
- */
- var _proto = PendingRequestsStore.prototype;
- _proto.add = function add(payload) {
- var id = payload.id,
- requestTimestamp = payload.requestTimestamp,
- content = payload.content;
- this._currentRequests[id] = {
- requestTimestamp: requestTimestamp,
- progress: [],
- content: content
- };
- }
- /**
- * Notify of the progress of a currently pending request.
- * @param {Object} progress
- */;
- _proto.addProgress = function addProgress(progress) {
- var request = this._currentRequests[progress.id];
- if (request == null) {
- if (false) {}
- log/* default.warn */.Z.warn("ABR: progress for a request not added");
- return;
- }
- request.progress.push(progress);
- }
- /**
- * Remove a request previously set as pending.
- * @param {string} id
- */;
- _proto.remove = function remove(id) {
- if (this._currentRequests[id] == null) {
- if (false) {}
- log/* default.warn */.Z.warn("ABR: can't remove unknown request");
- }
- delete this._currentRequests[id];
+function errorSelector(error) {
+ if (error instanceof request_error/* default */.Z) {
+ return new network_error/* default */.Z("PIPELINE_LOAD_ERROR", error);
}
- /**
- * Returns information about all pending requests, in segment's chronological
- * order.
- * @returns {Array.}
- */;
- _proto.getRequests = function getRequests() {
- return (0,object_values/* default */.Z)(this._currentRequests).filter(function (x) {
- return x != null;
- }).sort(function (reqA, reqB) {
- return reqA.content.segment.time - reqB.content.segment.time;
- });
- };
- return PendingRequestsStore;
-}();
-
-;// CONCATENATED MODULE: ./src/core/adaptive/utils/representation_score_calculator.ts
+ return (0,format_error/* default */.Z)(error, {
+ defaultCode: "PIPELINE_LOAD_ERROR",
+ defaultReason: "Unknown error when fetching the Manifest"
+ });
+}
+;// CONCATENATED MODULE: ./src/compat/is_offline.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -44248,108 +40271,45 @@ var PendingRequestsStore = /*#__PURE__*/function () {
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-
/**
- * Calculate the "maintainability score" of a given Representation:
- * - A score higher than 1 means that the Representation can theorically
- * be downloaded faster than the duration of the media it represents.
- * (e.g. a segment representing 4 seconds can be downloaded in less than 4
- * seconds).
- * - A score lower or equal to 1 means that the Representation cannot be
- * downloaded
+ * Some browsers have a builtin API to know if it's connected at least to a
+ * LAN network, at most to the internet.
*
- * The score follows a simple linear relation to both variables it is based
- * on:
- * - if n seconds of content can be downloaded in 2*n seconds, the score will
- * be `0.5`.
- * - if n seconds of content can be downloaded in n seconds, the score will be
- * `1`.
- * - if n seconds of content can be downloaded in n/2 seconds, the score will
- * be `2`.
- * - ...
+ * /!\ This feature can be dangerous as you can both have false positives and
+ * false negatives.
*
- * The score is mainly here to tell you when your buffer-based guesses are
- * actually higher than the quality you should normally reach.
+ * False positives:
+ * - you can still play local contents (on localhost) if isOffline == true
+ * - on some browsers isOffline might be true even if we're connected to a LAN
+ * or a router (it would mean we're just not able to connect to the
+ * Internet). So we can eventually play LAN contents if isOffline == true
*
- * /!\ Please bear in mind that we don't consider the playback rate in those
- * operations.
- * Still, integrating the playback rate a posteriori should not be difficult
- * (e.g. you can just divide the score by that rate).
+ * False negatives:
+ * - in some cases, we even might have isOffline at false when we do not have
+ * any connection:
+ * - in browsers that do not support the feature
+ * - in browsers running in some virtualization softwares where the
+ * network adapters are always connected.
*
- * @class RepresentationScoreCalculator
+ * Use with these cases in mind.
+ * @returns {Boolean}
*/
-var RepresentationScoreCalculator = /*#__PURE__*/function () {
- function RepresentationScoreCalculator() {
- this._currentRepresentationData = null;
- this._lastRepresentationWithGoodScore = null;
- }
- /**
- * Add new sample data.
- * @param {Representation} representation
- * @param {number} requestDuration - duration taken for doing the request for
- * the whole segment.
- * @param {number} segmentDuration - media duration of the whole segment, in
- * seconds.
- */
- var _proto = RepresentationScoreCalculator.prototype;
- _proto.addSample = function addSample(representation, requestDuration, segmentDuration) {
- var ratio = segmentDuration / requestDuration;
- var currentRep = this._currentRepresentationData;
- var currentEWMA;
- if (currentRep !== null && currentRep.representation.id === representation.id) {
- currentEWMA = currentRep.ewma;
- currentRep.ewma.addSample(requestDuration, ratio);
- currentRep.loadedDuration += segmentDuration;
- currentRep.loadedSegments++;
- } else {
- currentEWMA = new EWMA(5);
- currentEWMA.addSample(requestDuration, ratio);
- this._currentRepresentationData = {
- representation: representation,
- ewma: currentEWMA,
- loadedDuration: segmentDuration,
- loadedSegments: 0
- };
- }
- if (currentEWMA.getEstimate() > 1 && this._lastRepresentationWithGoodScore !== representation) {
- log/* default.debug */.Z.debug("ABR: New last stable representation", representation.bitrate);
- this._lastRepresentationWithGoodScore = representation;
- }
- }
- /**
- * Get score estimate for the given Representation.
- * undefined if no estimate is available.
- * @param {Representation} representation
- * @returns {number|undefined}
- */;
- _proto.getEstimate = function getEstimate(representation) {
- if (this._currentRepresentationData === null || this._currentRepresentationData.representation.id !== representation.id) {
- return undefined;
- }
- var _this$_currentReprese = this._currentRepresentationData,
- ewma = _this$_currentReprese.ewma,
- loadedSegments = _this$_currentReprese.loadedSegments,
- loadedDuration = _this$_currentReprese.loadedDuration;
- var estimate = ewma.getEstimate();
- var confidenceLevel = loadedSegments >= 5 && loadedDuration >= 10 ? 1 /* ScoreConfidenceLevel.HIGH */ : 0 /* ScoreConfidenceLevel.LOW */;
- return [estimate, confidenceLevel];
- }
- /**
- * Returns last Representation which had reached a score superior to 1.
- * This Representation is the last known one which could be maintained.
- * Useful to know if a current guess is higher than what you should
- * normally be able to play.
- * `null` if no Representation ever reach that score.
- * @returns {Representation|null}
- */;
- _proto.getLastStableRepresentation = function getLastStableRepresentation() {
- return this._lastRepresentationWithGoodScore;
- };
- return RepresentationScoreCalculator;
-}();
+function isOffline() {
+ /* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
+ return navigator.onLine === false;
+ /* eslint-enable @typescript-eslint/no-unnecessary-boolean-literal-compare */
+}
+// EXTERNAL MODULE: ./src/errors/custom_loader_error.ts
+var custom_loader_error = __webpack_require__(7839);
+// EXTERNAL MODULE: ./src/errors/is_known_error.ts
+var is_known_error = __webpack_require__(9822);
+// EXTERNAL MODULE: ./src/utils/cancellable_sleep.ts
+var cancellable_sleep = __webpack_require__(7864);
+// EXTERNAL MODULE: ./src/utils/get_fuzzed_delay.ts
+var get_fuzzed_delay = __webpack_require__(2572);
+;// CONCATENATED MODULE: ./src/core/fetchers/utils/schedule_request.ts
+
-;// CONCATENATED MODULE: ./src/core/adaptive/utils/select_optimal_representation.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -44366,35 +40326,375 @@ var RepresentationScoreCalculator = /*#__PURE__*/function () {
* limitations under the License.
*/
+
+
+
+
+
+
/**
- * From the given array of Representations (sorted by bitrate order ascending),
- * returns the one corresponding to the given optimal, minimum and maximum
- * bitrates.
- * @param {Array.} representations - The representations array,
- * sorted in bitrate ascending order.
- * @param {Number} optimalBitrate - The optimal bitrate the Representation
- * should have under the current condition.
- * @param {Number} minBitrate - The minimum bitrate the chosen Representation
- * should have. We will take the Representation with the maximum bitrate if none
- * is found.
- * @param {Number} maxBitrate - The maximum bitrate the chosen Representation
- * should have. We will take the Representation with the minimum bitrate if none
- * is found.
- * @returns {Representation|undefined}
+ * Called on a loader error.
+ * Returns whether the loader request should be retried.
+ *
+ * TODO the notion of retrying or not could be transport-specific (e.g. 412 are
+ * mainly used for Smooth contents) and thus as part of the transport code (e.g.
+ * by rejecting with an error always having a `canRetry` property?).
+ * Or not, to ponder.
+ *
+ * @param {Error} error
+ * @returns {Boolean} - If true, the request can be retried.
*/
-function selectOptimalRepresentation(representations, optimalBitrate, minBitrate, maxBitrate) {
- var wantedBitrate = optimalBitrate <= minBitrate ? minBitrate : optimalBitrate >= maxBitrate ? maxBitrate : optimalBitrate;
- var firstIndexTooHigh = (0,array_find_index/* default */.Z)(representations, function (representation) {
- return representation.bitrate > wantedBitrate;
- });
- if (firstIndexTooHigh === -1) {
- return representations[representations.length - 1];
- } else if (firstIndexTooHigh === 0) {
- return representations[0];
+function shouldRetry(error) {
+ if (error instanceof request_error/* default */.Z) {
+ if (error.type === error_codes/* NetworkErrorTypes.ERROR_HTTP_CODE */.br.ERROR_HTTP_CODE) {
+ return error.status >= 500 || error.status === 404 || error.status === 415 ||
+ // some CDN seems to use that code when
+ // requesting low-latency segments too much
+ // in advance
+ error.status === 412;
+ }
+ return error.type === error_codes/* NetworkErrorTypes.TIMEOUT */.br.TIMEOUT || error.type === error_codes/* NetworkErrorTypes.ERROR_EVENT */.br.ERROR_EVENT;
+ } else if (error instanceof custom_loader_error/* default */.Z) {
+ if (typeof error.canRetry === "boolean") {
+ return error.canRetry;
+ }
+ if (error.xhr !== undefined) {
+ return error.xhr.status >= 500 || error.xhr.status === 404 || error.xhr.status === 415 ||
+ // some CDN seems to use that code when
+ // requesting low-latency segments too much
+ // in advance
+ error.xhr.status === 412;
+ }
+ return false;
}
- return representations[firstIndexTooHigh - 1];
+ return (0,is_known_error/* default */.Z)(error) && error.code === "INTEGRITY_ERROR";
}
-;// CONCATENATED MODULE: ./src/core/adaptive/adaptive_representation_selector.ts
+/**
+ * Returns true if we're pretty sure that the current error is due to the
+ * user being offline.
+ * @param {Error} error
+ * @returns {Boolean}
+ */
+function isOfflineRequestError(error) {
+ if (error instanceof request_error/* default */.Z) {
+ return error.type === error_codes/* NetworkErrorTypes.ERROR_EVENT */.br.ERROR_EVENT && isOffline();
+ } else if (error instanceof custom_loader_error/* default */.Z) {
+ return error.isOfflineError;
+ }
+ return false; // under doubt, return false
+}
+/**
+ * Guess the type of error obtained.
+ * @param {*} error
+ * @returns {number}
+ */
+function getRequestErrorType(error) {
+ return isOfflineRequestError(error) ? 2 /* REQUEST_ERROR_TYPES.Offline */ : 1 /* REQUEST_ERROR_TYPES.Regular */;
+}
+/**
+ * Specific algorithm used to perform segment and manifest requests.
+ *
+ * Here how it works:
+ *
+ * 1. You give it one or multiple of the CDN available for the resource you
+ * want to request (from the most important one to the least important),
+ * a callback doing the request with the chosen CDN in argument, and some
+ * options.
+ *
+ * 2. it tries to call the request callback with the most prioritized CDN
+ * first:
+ * - if it works as expected, it resolves the returned Promise with that
+ * request's response.
+ * - if it fails, it calls ther `onRetry` callback given with the
+ * corresponding error, un-prioritize that CDN and try with the new
+ * most prioritized CDN.
+ *
+ * Each CDN might be retried multiple times, depending on the nature of the
+ * error and the Configuration given.
+ *
+ * Multiple retries of the same CDN are done after a delay to avoid
+ * overwhelming it, this is what we call a "backoff". That delay raises
+ * exponentially as multiple consecutive errors are encountered on this
+ * CDN.
+ *
+ * @param {Array.|null} cdns - The different CDN on which the
+ * wanted resource is available. `scheduleRequestWithCdns` will call the
+ * `performRequest` callback with the right element from that array if different
+ * from `null`.
+ *
+ * Can be set to `null` when that resource is not reachable through a CDN, in
+ * which case the `performRequest` callback may be called with `null`.
+ * @param {Object|null} cdnPrioritizer - Interface allowing to give the priority
+ * between multiple CDNs.
+ * @param {Function} performRequest - Callback implementing the request in
+ * itself. Resolving when the resource request succeed and rejecting with the
+ * corresponding error when the request failed.
+ * @param {Object} options - Configuration allowing to tweak the number on which
+ * the algorithm behind `scheduleRequestWithCdns` bases itself.
+ * @param {Object} cancellationSignal - CancellationSignal allowing to cancel
+ * the logic of `scheduleRequestWithCdns`.
+ * To trigger if the resource is not needed anymore.
+ * @returns {Promise} - Promise resolving, with the corresponding
+ * `performRequest`'s data, when the resource request succeed and rejecting in
+ * the following scenarios:
+ * - `scheduleRequestWithCdns` has been cancelled due to `cancellationSignal`
+ * being triggered. In that case a `CancellationError` is thrown.
+ *
+ * - The resource request(s) failed and will not be retried anymore.
+ */
+function scheduleRequestWithCdns(_x, _x2, _x3, _x4, _x5) {
+ return _scheduleRequestWithCdns.apply(this, arguments);
+}
+/**
+ * Lightweight version of the request algorithm, this time with only a simple
+ * Promise given.
+ * @param {Function} performRequest
+ * @param {Object} options
+ * @returns {Promise}
+ */
+function _scheduleRequestWithCdns() {
+ _scheduleRequestWithCdns = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee3(cdns, cdnPrioritizer, performRequest, options, cancellationSignal) {
+ var baseDelay, maxDelay, maxRetryRegular, maxRetryOffline, onRetry, missedAttempts, initialCdnToRequest, getCdnToRequest, requestCdn, _requestCdn, retryWithNextCdn, _retryWithNextCdn, waitPotentialBackoffAndRequest, getPrioritaryRequestableCdnFromSortedList;
+ return regenerator_default().wrap(function _callee3$(_context3) {
+ while (1) {
+ switch (_context3.prev = _context3.next) {
+ case 0:
+ getPrioritaryRequestableCdnFromSortedList = function _getPrioritaryRequest(sortedCdns) {
+ var _a;
+ if (missedAttempts.size === 0) {
+ return sortedCdns[0];
+ }
+ var now = performance.now();
+ return (_a = sortedCdns.filter(function (c) {
+ var _a;
+ return ((_a = missedAttempts.get(c)) === null || _a === void 0 ? void 0 : _a.isBlacklisted) !== true;
+ }).reduce(function (acc, x) {
+ var _a;
+ var blockedUntil = (_a = missedAttempts.get(x)) === null || _a === void 0 ? void 0 : _a.blockedUntil;
+ if (blockedUntil !== undefined && blockedUntil <= now) {
+ blockedUntil = undefined;
+ }
+ if (acc === undefined) {
+ return [x, blockedUntil];
+ }
+ if (blockedUntil === undefined) {
+ if (acc[1] === undefined) {
+ return acc;
+ }
+ return [x, undefined];
+ }
+ return acc[1] === undefined ? acc : blockedUntil < acc[1] ? [x, blockedUntil] : acc;
+ }, undefined)) === null || _a === void 0 ? void 0 : _a[0];
+ };
+ waitPotentialBackoffAndRequest = function _waitPotentialBackoff(nextWantedCdn, prevRequestError) {
+ var nextCdnAttemptObj = missedAttempts.get(nextWantedCdn);
+ if (nextCdnAttemptObj === undefined || nextCdnAttemptObj.blockedUntil === undefined) {
+ return requestCdn(nextWantedCdn);
+ }
+ var now = performance.now();
+ var blockedFor = nextCdnAttemptObj.blockedUntil - now;
+ if (blockedFor <= 0) {
+ return requestCdn(nextWantedCdn);
+ }
+ var canceller = new task_canceller/* default */.ZP();
+ var unlinkCanceller = canceller.linkToSignal(cancellationSignal);
+ return new Promise(function (res, rej) {
+ /* eslint-disable-next-line @typescript-eslint/no-misused-promises */
+ cdnPrioritizer === null || cdnPrioritizer === void 0 ? void 0 : cdnPrioritizer.addEventListener("priorityChange", function () {
+ var updatedPrioritaryCdn = getCdnToRequest();
+ if (cancellationSignal.isCancelled()) {
+ throw cancellationSignal.cancellationError;
+ }
+ if (updatedPrioritaryCdn === undefined) {
+ return cleanAndReject(prevRequestError);
+ }
+ if (updatedPrioritaryCdn !== nextWantedCdn) {
+ canceller.cancel();
+ waitPotentialBackoffAndRequest(updatedPrioritaryCdn, prevRequestError).then(cleanAndResolve, cleanAndReject);
+ }
+ }, canceller.signal);
+ (0,cancellable_sleep/* default */.Z)(blockedFor, canceller.signal).then(function () {
+ return requestCdn(nextWantedCdn).then(cleanAndResolve, cleanAndReject);
+ }, noop/* default */.Z);
+ function cleanAndResolve(response) {
+ unlinkCanceller();
+ res(response);
+ }
+ function cleanAndReject(err) {
+ unlinkCanceller();
+ rej(err);
+ }
+ });
+ };
+ _retryWithNextCdn = function _retryWithNextCdn3() {
+ _retryWithNextCdn = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee2(prevRequestError) {
+ var nextCdn;
+ return regenerator_default().wrap(function _callee2$(_context2) {
+ while (1) {
+ switch (_context2.prev = _context2.next) {
+ case 0:
+ nextCdn = getCdnToRequest();
+ if (!cancellationSignal.isCancelled()) {
+ _context2.next = 3;
+ break;
+ }
+ throw cancellationSignal.cancellationError;
+ case 3:
+ if (!(nextCdn === undefined)) {
+ _context2.next = 5;
+ break;
+ }
+ throw prevRequestError;
+ case 5:
+ onRetry(prevRequestError);
+ if (!cancellationSignal.isCancelled()) {
+ _context2.next = 8;
+ break;
+ }
+ throw cancellationSignal.cancellationError;
+ case 8:
+ return _context2.abrupt("return", waitPotentialBackoffAndRequest(nextCdn, prevRequestError));
+ case 9:
+ case "end":
+ return _context2.stop();
+ }
+ }
+ }, _callee2);
+ }));
+ return _retryWithNextCdn.apply(this, arguments);
+ };
+ retryWithNextCdn = function _retryWithNextCdn2(_x7) {
+ return _retryWithNextCdn.apply(this, arguments);
+ };
+ _requestCdn = function _requestCdn3() {
+ _requestCdn = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(cdn) {
+ var res, currentErrorType, missedAttemptsObj, maxRetry, errorCounter, delay, fuzzedDelay;
+ return regenerator_default().wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ _context.prev = 0;
+ _context.next = 3;
+ return performRequest(cdn, cancellationSignal);
+ case 3:
+ res = _context.sent;
+ return _context.abrupt("return", res);
+ case 7:
+ _context.prev = 7;
+ _context.t0 = _context["catch"](0);
+ if (!task_canceller/* default.isCancellationError */.ZP.isCancellationError(_context.t0)) {
+ _context.next = 11;
+ break;
+ }
+ throw _context.t0;
+ case 11:
+ if (cdn !== null && cdnPrioritizer !== null) {
+ // We failed requesting the resource on this CDN.
+ // Globally give priority to the next CDN through the CdnPrioritizer.
+ cdnPrioritizer.downgradeCdn(cdn);
+ }
+ currentErrorType = getRequestErrorType(_context.t0);
+ missedAttemptsObj = missedAttempts.get(cdn);
+ if (missedAttemptsObj === undefined) {
+ missedAttemptsObj = {
+ errorCounter: 1,
+ lastErrorType: currentErrorType,
+ blockedUntil: undefined,
+ isBlacklisted: false
+ };
+ missedAttempts.set(cdn, missedAttemptsObj);
+ } else {
+ if (currentErrorType !== missedAttemptsObj.lastErrorType) {
+ missedAttemptsObj.errorCounter = 1;
+ missedAttemptsObj.lastErrorType = currentErrorType;
+ } else {
+ missedAttemptsObj.errorCounter++;
+ }
+ }
+ if (shouldRetry(_context.t0)) {
+ _context.next = 19;
+ break;
+ }
+ missedAttemptsObj.blockedUntil = undefined;
+ missedAttemptsObj.isBlacklisted = true;
+ return _context.abrupt("return", retryWithNextCdn(_context.t0));
+ case 19:
+ maxRetry = currentErrorType === 2 /* REQUEST_ERROR_TYPES.Offline */ ? maxRetryOffline : maxRetryRegular;
+ if (missedAttemptsObj.errorCounter > maxRetry) {
+ missedAttemptsObj.blockedUntil = undefined;
+ missedAttemptsObj.isBlacklisted = true;
+ } else {
+ errorCounter = missedAttemptsObj.errorCounter;
+ delay = Math.min(baseDelay * Math.pow(2, errorCounter - 1), maxDelay);
+ fuzzedDelay = (0,get_fuzzed_delay/* default */.Z)(delay);
+ missedAttemptsObj.blockedUntil = performance.now() + fuzzedDelay;
+ }
+ return _context.abrupt("return", retryWithNextCdn(_context.t0));
+ case 22:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee, null, [[0, 7]]);
+ }));
+ return _requestCdn.apply(this, arguments);
+ };
+ requestCdn = function _requestCdn2(_x6) {
+ return _requestCdn.apply(this, arguments);
+ };
+ getCdnToRequest = function _getCdnToRequest() {
+ if (cdns === null) {
+ var nullAttemptObject = missedAttempts.get(null);
+ if (nullAttemptObject !== undefined && nullAttemptObject.isBlacklisted) {
+ return undefined;
+ }
+ return null;
+ } else if (cdnPrioritizer === null) {
+ return getPrioritaryRequestableCdnFromSortedList(cdns);
+ } else {
+ var prioritized = cdnPrioritizer.getCdnPreferenceForResource(cdns);
+ return getPrioritaryRequestableCdnFromSortedList(prioritized);
+ }
+ };
+ if (!(cancellationSignal.cancellationError !== null)) {
+ _context3.next = 9;
+ break;
+ }
+ return _context3.abrupt("return", Promise.reject(cancellationSignal.cancellationError));
+ case 9:
+ baseDelay = options.baseDelay, maxDelay = options.maxDelay, maxRetryRegular = options.maxRetryRegular, maxRetryOffline = options.maxRetryOffline, onRetry = options.onRetry;
+ if (cdns !== null && cdns.length === 0) {
+ log/* default.warn */.Z.warn("Fetchers: no CDN given to `scheduleRequestWithCdns`.");
+ }
+ missedAttempts = new Map();
+ initialCdnToRequest = getCdnToRequest();
+ if (!(initialCdnToRequest === undefined)) {
+ _context3.next = 15;
+ break;
+ }
+ throw new Error("No CDN to request");
+ case 15:
+ return _context3.abrupt("return", requestCdn(initialCdnToRequest));
+ case 16:
+ case "end":
+ return _context3.stop();
+ }
+ }
+ }, _callee3);
+ }));
+ return _scheduleRequestWithCdns.apply(this, arguments);
+}
+function scheduleRequestPromise(performRequest, options, cancellationSignal) {
+ // same than for a single unknown CDN
+ return scheduleRequestWithCdns(null, null, performRequest, options, cancellationSignal);
+}
+;// CONCATENATED MODULE: ./src/core/fetchers/manifest/manifest_fetcher.ts
+
+
+function manifest_fetcher_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = manifest_fetcher_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
+function manifest_fetcher_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return manifest_fetcher_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return manifest_fetcher_arrayLikeToArray(o, minLen); }
+function manifest_fetcher_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
+
/**
* Copyright 2015 CANAL+ Group
*
@@ -44421,415 +40721,590 @@ function selectOptimalRepresentation(representations, optimalBitrate, minBitrate
-
-
-
-
-
/**
- * Select the most adapted Representation according to the network and buffer
- * metrics it receives.
- *
- * @param {Object} options - Initial configuration (see type definition)
- * @returns {Object} - Interface allowing to select a Representation.
- * @see IRepresentationEstimator
+ * Class allowing to facilitate the task of loading and parsing a Manifest, as
+ * well as automatically refreshing it.
+ * @class ManifestFetcher
*/
-function createAdaptiveRepresentationSelector(options) {
+var ManifestFetcher = /*#__PURE__*/function (_EventEmitter) {
+ (0,inheritsLoose/* default */.Z)(ManifestFetcher, _EventEmitter);
/**
- * Allows to estimate the current network bandwidth.
- * One per active media type.
+ * Construct a new ManifestFetcher.
+ * @param {Array. | undefined} urls - Manifest URLs, will be used when
+ * no URL is provided to the `fetch` function.
+ * `undefined` if unknown or if a Manifest should be retrieved through other
+ * means than an HTTP request.
+ * @param {Object} pipelines - Transport pipelines used to perform the
+ * Manifest loading and parsing operations.
+ * @param {Object} settings - Configure the `ManifestFetcher`.
*/
- var bandwidthEstimators = {};
- var manualBitrates = options.manualBitrates,
- minAutoBitrates = options.minAutoBitrates,
- maxAutoBitrates = options.maxAutoBitrates,
- initialBitrates = options.initialBitrates,
- throttlers = options.throttlers,
- lowLatencyMode = options.lowLatencyMode;
+ function ManifestFetcher(urls, pipelines, settings) {
+ var _this;
+ _this = _EventEmitter.call(this) || this;
+ _this.scheduleManualRefresh = noop/* default */.Z;
+ _this._manifestUrls = urls;
+ _this._pipelines = pipelines.manifest;
+ _this._settings = settings;
+ _this._canceller = new task_canceller/* default */.ZP();
+ _this._isStarted = false;
+ _this._isRefreshPending = false;
+ _this._consecutiveUnsafeMode = 0;
+ _this._prioritizedContentUrl = null;
+ return _this;
+ }
/**
- * Returns Object emitting Representation estimates as well as callbacks
- * allowing to helping it produce them.
+ * Free resources and stop refresh mechanism from happening.
*
- * @see IRepresentationEstimator
- * @param {Object} context
- * @param {Object} currentRepresentation
- * @param {Object} representations
- * @param {Object} playbackObserver
- * @param {Object} stopAllEstimates
- * @returns {Array.}
+ * Once `dispose` has been called. This `ManifestFetcher` cannot be relied on
+ * anymore.
*/
- return function getEstimates(context, currentRepresentation, representations, playbackObserver, stopAllEstimates) {
- var type = context.adaptation.type;
- var bandwidthEstimator = _getBandwidthEstimator(type);
- var manualBitrate = (0,take_first_set/* default */.Z)(manualBitrates[type], (0,reference/* default */.ZP)(-1));
- var minAutoBitrate = (0,take_first_set/* default */.Z)(minAutoBitrates[type], (0,reference/* default */.ZP)(0));
- var maxAutoBitrate = (0,take_first_set/* default */.Z)(maxAutoBitrates[type], (0,reference/* default */.ZP)(Infinity));
- var initialBitrate = (0,take_first_set/* default */.Z)(initialBitrates[type], 0);
- var filters = {
- limitWidth: (0,take_first_set/* default */.Z)(throttlers.limitWidth[type], (0,reference/* default */.ZP)(undefined)),
- throttleBitrate: (0,take_first_set/* default */.Z)(throttlers.throttleBitrate[type], throttlers.throttle[type], (0,reference/* default */.ZP)(Infinity))
- };
- return getEstimateReference({
- bandwidthEstimator: bandwidthEstimator,
- context: context,
- currentRepresentation: currentRepresentation,
- filters: filters,
- initialBitrate: initialBitrate,
- manualBitrate: manualBitrate,
- minAutoBitrate: minAutoBitrate,
- maxAutoBitrate: maxAutoBitrate,
- playbackObserver: playbackObserver,
- representations: representations,
- lowLatencyMode: lowLatencyMode
- }, stopAllEstimates);
- };
+ var _proto = ManifestFetcher.prototype;
+ _proto.dispose = function dispose() {
+ this._canceller.cancel();
+ this.removeEventListener();
+ }
/**
- * Returns interface allowing to estimate network throughtput for a given type.
- * @param {string} bufferType
- * @returns {Object}
- */
- function _getBandwidthEstimator(bufferType) {
- var originalBandwidthEstimator = bandwidthEstimators[bufferType];
- if (originalBandwidthEstimator == null) {
- log/* default.debug */.Z.debug("ABR: Creating new BandwidthEstimator for ", bufferType);
- var bandwidthEstimator = new BandwidthEstimator();
- bandwidthEstimators[bufferType] = bandwidthEstimator;
- return bandwidthEstimator;
+ * Start requesting the Manifest as well as the Manifest refreshing logic, if
+ * needed.
+ *
+ * Once `start` has been called, this mechanism can only be stopped by calling
+ * `dispose`.
+ */;
+ _proto.start = function start() {
+ var _this2 = this;
+ if (this._isStarted) {
+ return;
}
- return originalBandwidthEstimator;
- }
-}
-/**
- * Estimate regularly the current network bandwidth and the best Representation
- * that can be played according to the current network and playback conditions.
- *
- * `getEstimateReference` only does estimations for a given type (e.g.
- * "audio", "video" etc.) and Period.
- *
- * If estimates for multiple types and/or Periods are needed, you should
- * call `getEstimateReference` as many times.
- *
- * This function returns a tuple:
- * - the first element being the object through which estimates will be produced
- * - the second element being callbacks that have to be triggered at various
- * events to help it doing those estimates.
- *
- * @param {Object} args
- * @param {Object} stopAllEstimates
- * @returns {Array.}
- */
-function getEstimateReference(_ref, stopAllEstimates) {
- var bandwidthEstimator = _ref.bandwidthEstimator,
- context = _ref.context,
- currentRepresentation = _ref.currentRepresentation,
- filters = _ref.filters,
- initialBitrate = _ref.initialBitrate,
- lowLatencyMode = _ref.lowLatencyMode,
- manualBitrate = _ref.manualBitrate,
- maxAutoBitrate = _ref.maxAutoBitrate,
- minAutoBitrate = _ref.minAutoBitrate,
- playbackObserver = _ref.playbackObserver,
- representationsRef = _ref.representations;
- var scoreCalculator = new RepresentationScoreCalculator();
- var networkAnalyzer = new NetworkAnalyzer(initialBitrate !== null && initialBitrate !== void 0 ? initialBitrate : 0, lowLatencyMode);
- var requestsStore = new PendingRequestsStore();
- var onAddedSegment = noop/* default */.Z;
- var callbacks = {
- metrics: onMetric,
- requestBegin: onRequestBegin,
- requestProgress: onRequestProgress,
- requestEnd: onRequestEnd,
- addedSegment: function addedSegment(val) {
- onAddedSegment(val);
+ this._isStarted = true;
+ var manifestProm;
+ var initialManifest = this._settings.initialManifest;
+ if (initialManifest instanceof manifest/* default */.ZP) {
+ manifestProm = Promise.resolve({
+ manifest: initialManifest
+ });
+ } else if (initialManifest !== undefined) {
+ manifestProm = this.parse(initialManifest, {
+ previousManifest: null,
+ unsafeMode: false
+ }, undefined);
+ } else {
+ manifestProm = this._fetchManifest(undefined).then(function (val) {
+ return val.parse({
+ previousManifest: null,
+ unsafeMode: false
+ });
+ });
}
- };
+ manifestProm.then(function (val) {
+ _this2.trigger("manifestReady", val.manifest);
+ if (!_this2._canceller.isUsed()) {
+ _this2._recursivelyRefreshManifest(val.manifest, val);
+ }
+ })["catch"](function (err) {
+ return _this2._onFatalError(err);
+ });
+ }
/**
- * `TaskCanceller` allowing to stop producing estimate.
- * This TaskCanceller is used both for restarting estimates with a new
- * configuration and to cancel them altogether.
- */
- var currentEstimatesCanceller = new task_canceller/* default */.ZP({
- cancelOn: stopAllEstimates
- });
- // Create `ISharedReference` on which estimates will be emitted.
- var estimateRef = createEstimateReference(manualBitrate.getValue(), representationsRef.getValue(), currentEstimatesCanceller.signal);
- manualBitrate.onUpdate(restartEstimatesProductionFromCurrentConditions, {
- clearSignal: stopAllEstimates
- });
- representationsRef.onUpdate(restartEstimatesProductionFromCurrentConditions, {
- clearSignal: stopAllEstimates
- });
- return {
- estimates: estimateRef,
- callbacks: callbacks
- };
- function createEstimateReference(manualBitrateVal, representations, innerCancellationSignal) {
- if (manualBitrateVal >= 0) {
- // A manual bitrate has been set. Just choose Representation according to it.
- var manualRepresentation = selectOptimalRepresentation(representations, manualBitrateVal, 0, Infinity);
- return (0,reference/* default */.ZP)({
- representation: manualRepresentation,
- bitrate: undefined,
- knownStableBitrate: undefined,
- manual: true,
- urgent: true // a manual bitrate switch should happen immediately
+ * Update URL of the fetched Manifest.
+ * @param {Array. | undefined} urls - New Manifest URLs by order of
+ * priority or `undefined` if there's now no URL.
+ * @param {boolean} refreshNow - If set to `true`, the next Manifest refresh
+ * will be triggered immediately.
+ */;
+ _proto.updateContentUrls = function updateContentUrls(urls, refreshNow) {
+ var _a;
+ this._prioritizedContentUrl = (_a = urls === null || urls === void 0 ? void 0 : urls[0]) !== null && _a !== void 0 ? _a : undefined;
+ if (refreshNow) {
+ this.scheduleManualRefresh({
+ enablePartialRefresh: false,
+ delay: 0,
+ canUseUnsafeMode: false
});
}
-
- if (representations.length === 1) {
- // There's only a single Representation. Just choose it.
- return (0,reference/* default */.ZP)({
- bitrate: undefined,
- representation: representations[0],
- manual: false,
- urgent: true,
- knownStableBitrate: undefined
- });
+ }
+ /**
+ * (re-)Load the Manifest.
+ * This method does not yet parse it, parsing will then be available through
+ * a callback available on the response.
+ *
+ * You can set an `url` on which that Manifest will be requested.
+ * If not set, the regular Manifest url - defined on the `ManifestFetcher`
+ * instanciation - will be used instead.
+ *
+ * @param {string | undefined} url
+ * @returns {Promise}
+ */;
+ _proto._fetchManifest =
+ /*#__PURE__*/
+ function () {
+ var _fetchManifest2 = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(url) {
+ var _this3 = this;
+ var _a, cancelSignal, settings, pipelines, requestUrl, backoffSettings, loadingPromise, response, callResolverWithRetries, callLoaderWithRetries;
+ return regenerator_default().wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ callLoaderWithRetries = function _callLoaderWithRetrie(manifestUrl) {
+ var loadManifest = pipelines.loadManifest;
+ var requestTimeout = (0,is_null_or_undefined/* default */.Z)(settings.requestTimeout) ? config/* default.getCurrent */.Z.getCurrent().DEFAULT_REQUEST_TIMEOUT : settings.requestTimeout;
+ if (requestTimeout < 0) {
+ requestTimeout = undefined;
+ }
+ var callLoader = function callLoader() {
+ return loadManifest(manifestUrl, {
+ timeout: requestTimeout
+ }, cancelSignal);
+ };
+ return scheduleRequestPromise(callLoader, backoffSettings, cancelSignal);
+ };
+ callResolverWithRetries = function _callResolverWithRetr(resolverUrl) {
+ var resolveManifestUrl = pipelines.resolveManifestUrl;
+ (0,assert/* default */.Z)(resolveManifestUrl !== undefined);
+ var callResolver = function callResolver() {
+ return resolveManifestUrl(resolverUrl, cancelSignal);
+ };
+ return scheduleRequestPromise(callResolver, backoffSettings, cancelSignal);
+ };
+ cancelSignal = this._canceller.signal;
+ settings = this._settings;
+ pipelines = this._pipelines; // TODO Better handle multiple Manifest URLs
+ requestUrl = url !== null && url !== void 0 ? url : (_a = this._manifestUrls) === null || _a === void 0 ? void 0 : _a[0];
+ backoffSettings = this._getBackoffSetting(function (err) {
+ _this3.trigger("warning", errorSelector(err));
+ });
+ loadingPromise = pipelines.resolveManifestUrl === undefined ? callLoaderWithRetries(requestUrl) : callResolverWithRetries(requestUrl).then(callLoaderWithRetries);
+ _context.prev = 8;
+ _context.next = 11;
+ return loadingPromise;
+ case 11:
+ response = _context.sent;
+ return _context.abrupt("return", {
+ parse: function parse(parserOptions) {
+ return _this3._parseLoadedManifest(response, parserOptions, requestUrl);
+ }
+ });
+ case 15:
+ _context.prev = 15;
+ _context.t0 = _context["catch"](8);
+ throw errorSelector(_context.t0);
+ case 18:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee, this, [[8, 15]]);
+ }));
+ function _fetchManifest(_x) {
+ return _fetchManifest2.apply(this, arguments);
}
- /** If true, Representation estimates based on the buffer health might be used. */
- var allowBufferBasedEstimates = false;
+ return _fetchManifest;
+ }()
+ /**
+ * Parse an already loaded Manifest.
+ *
+ * This method should be reserved for Manifests for which no request has been
+ * done.
+ * In other cases, it's preferable to go through the `fetch` method, so
+ * information on the request can be used by the parsing process.
+ * @param {*} manifest
+ * @param {Object} parserOptions
+ * @param {string | undefined} originalUrl
+ * @returns {Promise}
+ */
+ ;
+ _proto.parse = function parse(manifest, parserOptions, originalUrl) {
+ return this._parseLoadedManifest({
+ responseData: manifest,
+ size: undefined,
+ requestDuration: undefined
+ }, parserOptions, originalUrl);
+ }
+ /**
+ * Parse a Manifest.
+ *
+ * @param {Object} loaded - Information about the loaded Manifest as well as
+ * about the corresponding request.
+ * @param {Object} parserOptions - Options used when parsing the Manifest.
+ * @param {string | undefined} requestUrl
+ * @returns {Promise}
+ */;
+ _proto._parseLoadedManifest =
+ /*#__PURE__*/
+ function () {
+ var _parseLoadedManifest2 = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee3(loaded, parserOptions, requestUrl) {
+ var _this4 = this;
+ var _a, parsingTimeStart, cancelSignal, trigger, sendingTime, receivedTime, backoffSettings, originalUrl, opts, res, _yield$res, manifest, formattedError, scheduleRequest, _scheduleRequest, onWarnings, finish;
+ return regenerator_default().wrap(function _callee3$(_context3) {
+ while (1) {
+ switch (_context3.prev = _context3.next) {
+ case 0:
+ finish = function _finish(manifest) {
+ onWarnings(manifest.contentWarnings);
+ var parsingTime = performance.now() - parsingTimeStart;
+ log/* default.info */.Z.info("MF: Manifest parsed in " + parsingTime + "ms");
+ return {
+ manifest: manifest,
+ sendingTime: sendingTime,
+ receivedTime: receivedTime,
+ parsingTime: parsingTime
+ };
+ };
+ onWarnings = function _onWarnings(warnings) {
+ for (var _iterator = manifest_fetcher_createForOfIteratorHelperLoose(warnings), _step; !(_step = _iterator()).done;) {
+ var warning = _step.value;
+ if (cancelSignal.isCancelled()) {
+ return;
+ }
+ var _formattedError = (0,format_error/* default */.Z)(warning, {
+ defaultCode: "PIPELINE_PARSE_ERROR",
+ defaultReason: "Unknown error when parsing the Manifest"
+ });
+ trigger("warning", _formattedError);
+ }
+ };
+ _scheduleRequest = function _scheduleRequest3() {
+ _scheduleRequest = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee2(performRequest) {
+ var data;
+ return regenerator_default().wrap(function _callee2$(_context2) {
+ while (1) {
+ switch (_context2.prev = _context2.next) {
+ case 0:
+ _context2.prev = 0;
+ _context2.next = 3;
+ return scheduleRequestPromise(performRequest, backoffSettings, cancelSignal);
+ case 3:
+ data = _context2.sent;
+ return _context2.abrupt("return", data);
+ case 7:
+ _context2.prev = 7;
+ _context2.t0 = _context2["catch"](0);
+ throw errorSelector(_context2.t0);
+ case 10:
+ case "end":
+ return _context2.stop();
+ }
+ }
+ }, _callee2, null, [[0, 7]]);
+ }));
+ return _scheduleRequest.apply(this, arguments);
+ };
+ scheduleRequest = function _scheduleRequest2(_x5) {
+ return _scheduleRequest.apply(this, arguments);
+ };
+ parsingTimeStart = performance.now();
+ cancelSignal = this._canceller.signal;
+ trigger = this.trigger.bind(this);
+ sendingTime = loaded.sendingTime, receivedTime = loaded.receivedTime;
+ backoffSettings = this._getBackoffSetting(function (err) {
+ _this4.trigger("warning", errorSelector(err));
+ });
+ originalUrl = requestUrl !== null && requestUrl !== void 0 ? requestUrl : (_a = this._manifestUrls) === null || _a === void 0 ? void 0 : _a[0];
+ opts = {
+ externalClockOffset: parserOptions.externalClockOffset,
+ unsafeMode: parserOptions.unsafeMode,
+ previousManifest: parserOptions.previousManifest,
+ originalUrl: originalUrl
+ };
+ _context3.prev = 11;
+ res = this._pipelines.parseManifest(loaded, opts, onWarnings, cancelSignal, scheduleRequest);
+ if (isPromise(res)) {
+ _context3.next = 17;
+ break;
+ }
+ return _context3.abrupt("return", finish(res.manifest));
+ case 17:
+ _context3.next = 19;
+ return res;
+ case 19:
+ _yield$res = _context3.sent;
+ manifest = _yield$res.manifest;
+ return _context3.abrupt("return", finish(manifest));
+ case 22:
+ _context3.next = 28;
+ break;
+ case 24:
+ _context3.prev = 24;
+ _context3.t0 = _context3["catch"](11);
+ formattedError = (0,format_error/* default */.Z)(_context3.t0, {
+ defaultCode: "PIPELINE_PARSE_ERROR",
+ defaultReason: "Unknown error when parsing the Manifest"
+ });
+ throw formattedError;
+ case 28:
+ case "end":
+ return _context3.stop();
+ }
+ }
+ }, _callee3, this, [[11, 24]]);
+ }));
+ function _parseLoadedManifest(_x2, _x3, _x4) {
+ return _parseLoadedManifest2.apply(this, arguments);
+ }
+ return _parseLoadedManifest;
+ }()
+ /**
+ * Construct "backoff settings" that can be used with a range of functions
+ * allowing to perform multiple request attempts
+ * @param {Function} onRetry
+ * @returns {Object}
+ */
+ ;
+ _proto._getBackoffSetting = function _getBackoffSetting(onRetry) {
+ var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
+ DEFAULT_MAX_MANIFEST_REQUEST_RETRY = _config$getCurrent.DEFAULT_MAX_MANIFEST_REQUEST_RETRY,
+ DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE = _config$getCurrent.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE,
+ INITIAL_BACKOFF_DELAY_BASE = _config$getCurrent.INITIAL_BACKOFF_DELAY_BASE,
+ MAX_BACKOFF_DELAY_BASE = _config$getCurrent.MAX_BACKOFF_DELAY_BASE;
+ var _this$_settings = this._settings,
+ lowLatencyMode = _this$_settings.lowLatencyMode,
+ ogRegular = _this$_settings.maxRetryRegular,
+ ogOffline = _this$_settings.maxRetryOffline;
+ var baseDelay = lowLatencyMode ? INITIAL_BACKOFF_DELAY_BASE.LOW_LATENCY : INITIAL_BACKOFF_DELAY_BASE.REGULAR;
+ var maxDelay = lowLatencyMode ? MAX_BACKOFF_DELAY_BASE.LOW_LATENCY : MAX_BACKOFF_DELAY_BASE.REGULAR;
+ var maxRetryRegular = ogRegular !== null && ogRegular !== void 0 ? ogRegular : DEFAULT_MAX_MANIFEST_REQUEST_RETRY;
+ var maxRetryOffline = ogOffline !== null && ogOffline !== void 0 ? ogOffline : DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE;
+ return {
+ onRetry: onRetry,
+ baseDelay: baseDelay,
+ maxDelay: maxDelay,
+ maxRetryRegular: maxRetryRegular,
+ maxRetryOffline: maxRetryOffline
+ };
+ }
+ /**
+ * Performs Manifest refresh (recursively) when it judges it is time to do so.
+ * @param {Object} manifest
+ * @param {Object} manifestRequestInfos - Various information linked to the
+ * last Manifest loading and parsing operations.
+ */;
+ _proto._recursivelyRefreshManifest = function _recursivelyRefreshManifest(manifest, _ref) {
+ var _this5 = this;
+ var sendingTime = _ref.sendingTime,
+ parsingTime = _ref.parsingTime,
+ updatingTime = _ref.updatingTime;
+ var _config$getCurrent2 = config/* default.getCurrent */.Z.getCurrent(),
+ MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE = _config$getCurrent2.MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE,
+ MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE = _config$getCurrent2.MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE;
/**
- * Current optimal Representation's bandwidth choosen by a buffer-based
- * adaptive algorithm.
+ * Total time taken to fully update the last Manifest, in milliseconds.
+ * Note: this time also includes possible requests done by the parsers.
*/
- var currentBufferBasedEstimate;
- var bitrates = representations.map(function (r) {
- return r.bitrate;
- });
+ var totalUpdateTime = parsingTime !== undefined ? parsingTime + (updatingTime !== null && updatingTime !== void 0 ? updatingTime : 0) : undefined;
/**
- * Module calculating the optimal Representation based on the current
- * buffer's health (i.e. whether enough data is buffered, history of
- * buffer size etc.).
+ * "unsafeMode" is a mode where we unlock advanced Manifest parsing
+ * optimizations with the added risk to lose some information.
+ * `unsafeModeEnabled` is set to `true` when the `unsafeMode` is enabled.
+ *
+ * Only perform parsing in `unsafeMode` when the last full parsing took a
+ * lot of time and do not go higher than the maximum consecutive time.
*/
- var bufferBasedChooser = new BufferBasedChooser(bitrates);
- /** Store the previous estimate made here. */
- var prevEstimate = new LastEstimateStorage();
+ var unsafeModeEnabled = this._consecutiveUnsafeMode > 0 ? this._consecutiveUnsafeMode < MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE : totalUpdateTime !== undefined ? totalUpdateTime >= MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE : false;
+ /** Time elapsed since the beginning of the Manifest request, in milliseconds. */
+ var timeSinceRequest = sendingTime === undefined ? 0 : performance.now() - sendingTime;
+ /** Minimum update delay we should not go below, in milliseconds. */
+ var minInterval = Math.max(this._settings.minimumManifestUpdateInterval - timeSinceRequest, 0);
/**
- * Module calculating the optimal Representation by "guessing it" with a
- * step-by-step algorithm.
- * Only used in very specific scenarios.
+ * Multiple refresh trigger are scheduled here, but only the first one should
+ * be effectively considered.
+ * `nextRefreshCanceller` will allow to cancel every other when one is triggered.
*/
- var guessBasedChooser = new GuessBasedChooser(scoreCalculator, prevEstimate);
- // get initial observation for initial estimate
- var lastPlaybackObservation = playbackObserver.getReference().getValue();
- /** Reference through which estimates are emitted. */
- var innerEstimateRef = (0,reference/* default */.ZP)(getCurrentEstimate());
- // subscribe to subsequent playback observations
- playbackObserver.listen(function (obs) {
- lastPlaybackObservation = obs;
- updateEstimate();
- }, {
- includeLastObservation: false,
- clearSignal: innerCancellationSignal
- });
- onAddedSegment = function onAddedSegment(val) {
- if (lastPlaybackObservation === null) {
- return;
- }
- var _lastPlaybackObservat = lastPlaybackObservation,
- position = _lastPlaybackObservat.position,
- speed = _lastPlaybackObservat.speed;
- var timeRanges = val.buffered;
- var bufferGap = (0,ranges/* getLeftSizeOfRange */.L7)(timeRanges, position.last);
- var representation = val.content.representation;
- var scoreData = scoreCalculator.getEstimate(representation);
- var currentScore = scoreData === null || scoreData === void 0 ? void 0 : scoreData[0];
- var currentBitrate = representation.bitrate;
- var observation = {
- bufferGap: bufferGap,
- currentBitrate: currentBitrate,
- currentScore: currentScore,
- speed: speed
- };
- currentBufferBasedEstimate = bufferBasedChooser.getEstimate(observation);
- updateEstimate();
+ var nextRefreshCanceller = new task_canceller/* default */.ZP();
+ nextRefreshCanceller.linkToSignal(this._canceller.signal);
+ /* Function to manually schedule a Manifest refresh */
+ this.scheduleManualRefresh = function (settings) {
+ var enablePartialRefresh = settings.enablePartialRefresh,
+ delay = settings.delay,
+ canUseUnsafeMode = settings.canUseUnsafeMode;
+ var unsafeMode = canUseUnsafeMode && unsafeModeEnabled;
+ // The value allows to set a delay relatively to the last Manifest refresh
+ // (to avoid asking for it too often).
+ var timeSinceLastRefresh = sendingTime === undefined ? 0 : performance.now() - sendingTime;
+ var _minInterval = Math.max(_this5._settings.minimumManifestUpdateInterval - timeSinceLastRefresh, 0);
+ var timeoutId = setTimeout(function () {
+ nextRefreshCanceller.cancel();
+ _this5._triggerNextManifestRefresh(manifest, {
+ enablePartialRefresh: enablePartialRefresh,
+ unsafeMode: unsafeMode
+ });
+ }, Math.max((delay !== null && delay !== void 0 ? delay : 0) - timeSinceLastRefresh, _minInterval));
+ nextRefreshCanceller.signal.register(function () {
+ clearTimeout(timeoutId);
+ });
};
- minAutoBitrate.onUpdate(updateEstimate, {
- clearSignal: innerCancellationSignal
- });
- maxAutoBitrate.onUpdate(updateEstimate, {
- clearSignal: innerCancellationSignal
- });
- filters.limitWidth.onUpdate(updateEstimate, {
- clearSignal: innerCancellationSignal
- });
- filters.limitWidth.onUpdate(updateEstimate, {
- clearSignal: innerCancellationSignal
- });
- return innerEstimateRef;
- function updateEstimate() {
- innerEstimateRef.setValue(getCurrentEstimate());
+ /* Handle Manifest expiration. */
+ if (manifest.expired !== null) {
+ var timeoutId = setTimeout(function () {
+ var _a;
+ (_a = manifest.expired) === null || _a === void 0 ? void 0 : _a.then(function () {
+ nextRefreshCanceller.cancel();
+ _this5._triggerNextManifestRefresh(manifest, {
+ enablePartialRefresh: false,
+ unsafeMode: unsafeModeEnabled
+ });
+ }, noop/* default */.Z /* `expired` should not reject */);
+ }, minInterval);
+ nextRefreshCanceller.signal.register(function () {
+ clearTimeout(timeoutId);
+ });
}
- /** Returns the actual estimate based on all methods and algorithm available. */
- function getCurrentEstimate() {
- var _lastPlaybackObservat2 = lastPlaybackObservation,
- bufferGap = _lastPlaybackObservat2.bufferGap,
- position = _lastPlaybackObservat2.position,
- maximumPosition = _lastPlaybackObservat2.maximumPosition;
- var widthLimit = filters.limitWidth.getValue();
- var bitrateThrottle = filters.throttleBitrate.getValue();
- var currentRepresentationVal = currentRepresentation.getValue();
- var minAutoBitrateVal = minAutoBitrate.getValue();
- var maxAutoBitrateVal = maxAutoBitrate.getValue();
- var filteredReps = getFilteredRepresentations(representations, widthLimit, bitrateThrottle);
- var requests = requestsStore.getRequests();
- var _networkAnalyzer$getB = networkAnalyzer.getBandwidthEstimate(lastPlaybackObservation, bandwidthEstimator, currentRepresentationVal, requests, prevEstimate.bandwidth),
- bandwidthEstimate = _networkAnalyzer$getB.bandwidthEstimate,
- bitrateChosen = _networkAnalyzer$getB.bitrateChosen;
- var stableRepresentation = scoreCalculator.getLastStableRepresentation();
- var knownStableBitrate = stableRepresentation === null ? undefined : stableRepresentation.bitrate / (lastPlaybackObservation.speed > 0 ? lastPlaybackObservation.speed : 1);
- if (allowBufferBasedEstimates && bufferGap <= 5) {
- allowBufferBasedEstimates = false;
- } else if (!allowBufferBasedEstimates && isFinite(bufferGap) && bufferGap > 10) {
- allowBufferBasedEstimates = true;
- }
- /**
- * Representation chosen when considering only [pessimist] bandwidth
- * calculation.
- * This is a safe enough choice but might be lower than what the user
- * could actually profit from.
- */
- var chosenRepFromBandwidth = selectOptimalRepresentation(filteredReps, bitrateChosen, minAutoBitrateVal, maxAutoBitrateVal);
- var currentBestBitrate = chosenRepFromBandwidth.bitrate;
- /**
- * Representation chosen when considering the current buffer size.
- * If defined, takes precedence over `chosenRepFromBandwidth`.
- *
- * This is a very safe choice, yet it is very slow and might not be
- * adapted to cases where a buffer cannot be build, such as live contents.
- *
- * `null` if this buffer size mode is not enabled or if we don't have a
- * choice from it yet.
- */
- var chosenRepFromBufferSize = null;
- if (allowBufferBasedEstimates && currentBufferBasedEstimate !== undefined && currentBufferBasedEstimate > currentBestBitrate) {
- chosenRepFromBufferSize = selectOptimalRepresentation(filteredReps, currentBufferBasedEstimate, minAutoBitrateVal, maxAutoBitrateVal);
- currentBestBitrate = chosenRepFromBufferSize.bitrate;
- }
- /**
- * Representation chosen by the more adventurous `GuessBasedChooser`,
- * which iterates through Representations one by one until finding one
- * that cannot be "maintained".
- *
- * If defined, takes precedence over both `chosenRepFromBandwidth` and
- * `chosenRepFromBufferSize`.
- *
- * This is the riskiest choice (in terms of rebuffering chances) but is
- * only enabled when no other solution is adapted (for now, this just
- * applies for low-latency contents when playing close to the live
- * edge).
- *
- * `null` if not enabled or if there's currently no guess.
- */
- var chosenRepFromGuessMode = null;
- if (lowLatencyMode && currentRepresentationVal !== null && context.manifest.isDynamic && maximumPosition - position.last < 40) {
- chosenRepFromGuessMode = guessBasedChooser.getGuess(representations, lastPlaybackObservation, currentRepresentationVal, currentBestBitrate, requests);
- }
- if (chosenRepFromGuessMode !== null && chosenRepFromGuessMode.bitrate > currentBestBitrate) {
- log/* default.debug */.Z.debug("ABR: Choosing representation with guess-based estimation.", chosenRepFromGuessMode.bitrate, chosenRepFromGuessMode.id);
- prevEstimate.update(chosenRepFromGuessMode, bandwidthEstimate, 2 /* ABRAlgorithmType.GuessBased */);
- return {
- bitrate: bandwidthEstimate,
- representation: chosenRepFromGuessMode,
- urgent: currentRepresentationVal === null || chosenRepFromGuessMode.bitrate < currentRepresentationVal.bitrate,
- manual: false,
- knownStableBitrate: knownStableBitrate
- };
- } else if (chosenRepFromBufferSize !== null) {
- log/* default.debug */.Z.debug("ABR: Choosing representation with buffer-based estimation.", chosenRepFromBufferSize.bitrate, chosenRepFromBufferSize.id);
- prevEstimate.update(chosenRepFromBufferSize, bandwidthEstimate, 0 /* ABRAlgorithmType.BufferBased */);
- return {
- bitrate: bandwidthEstimate,
- representation: chosenRepFromBufferSize,
- urgent: networkAnalyzer.isUrgent(chosenRepFromBufferSize.bitrate, currentRepresentationVal, requests, lastPlaybackObservation),
- manual: false,
- knownStableBitrate: knownStableBitrate
- };
+ /*
+ * Trigger Manifest refresh when the Manifest needs to be refreshed
+ * according to the Manifest's internal properties (parsing time is also
+ * taken into account in this operation to avoid refreshing too often).
+ */
+ if (manifest.lifetime !== undefined && manifest.lifetime >= 0) {
+ /** Regular refresh delay as asked by the Manifest. */
+ var regularRefreshDelay = manifest.lifetime * 1000 - timeSinceRequest;
+ /** Actually choosen delay to refresh the Manifest. */
+ var actualRefreshInterval;
+ if (totalUpdateTime === undefined) {
+ actualRefreshInterval = regularRefreshDelay;
+ } else if (manifest.lifetime < 3 && totalUpdateTime >= 100) {
+ // If Manifest update is very frequent and we take time to update it,
+ // postpone it.
+ actualRefreshInterval = Math.min(Math.max(
+ // Take 3 seconds as a default safe value for a base interval.
+ 3000 - timeSinceRequest,
+ // Add update time to the original interval.
+ Math.max(regularRefreshDelay, 0) + totalUpdateTime),
+ // Limit the postponment's higher bound to a very high value relative
+ // to `regularRefreshDelay`.
+ // This avoid perpetually postponing a Manifest update when
+ // performance seems to have been abysmal one time.
+ regularRefreshDelay * 6);
+ log/* default.info */.Z.info("MUS: Manifest update rythm is too frequent. Postponing next request.", regularRefreshDelay, actualRefreshInterval);
+ } else if (totalUpdateTime >= manifest.lifetime * 1000 / 10) {
+ // If Manifest updating time is very long relative to its lifetime,
+ // postpone it:
+ actualRefreshInterval = Math.min(
+ // Just add the update time to the original waiting time
+ Math.max(regularRefreshDelay, 0) + totalUpdateTime,
+ // Limit the postponment's higher bound to a very high value relative
+ // to `regularRefreshDelay`.
+ // This avoid perpetually postponing a Manifest update when
+ // performance seems to have been abysmal one time.
+ regularRefreshDelay * 6);
+ log/* default.info */.Z.info("MUS: Manifest took too long to parse. Postponing next request", actualRefreshInterval, actualRefreshInterval);
} else {
- log/* default.debug */.Z.debug("ABR: Choosing representation with bandwidth estimation.", chosenRepFromBandwidth.bitrate, chosenRepFromBandwidth.id);
- prevEstimate.update(chosenRepFromBandwidth, bandwidthEstimate, 1 /* ABRAlgorithmType.BandwidthBased */);
- return {
- bitrate: bandwidthEstimate,
- representation: chosenRepFromBandwidth,
- urgent: networkAnalyzer.isUrgent(chosenRepFromBandwidth.bitrate, currentRepresentationVal, requests, lastPlaybackObservation),
- manual: false,
- knownStableBitrate: knownStableBitrate
- };
+ actualRefreshInterval = regularRefreshDelay;
}
+ var _timeoutId = setTimeout(function () {
+ nextRefreshCanceller.cancel();
+ _this5._triggerNextManifestRefresh(manifest, {
+ enablePartialRefresh: false,
+ unsafeMode: unsafeModeEnabled
+ });
+ }, Math.max(actualRefreshInterval, minInterval));
+ nextRefreshCanceller.signal.register(function () {
+ clearTimeout(_timeoutId);
+ });
}
}
/**
- * Stop previous estimate production (if one) and restart it considering new
- * conditions (such as a manual bitrate and/or a new list of Representations).
- */
- function restartEstimatesProductionFromCurrentConditions() {
- var manualBitrateVal = manualBitrate.getValue();
- var representations = representationsRef.getValue();
- currentEstimatesCanceller.cancel();
- currentEstimatesCanceller = new task_canceller/* default */.ZP({
- cancelOn: stopAllEstimates
- });
- var newRef = createEstimateReference(manualBitrateVal, representations, currentEstimatesCanceller.signal);
- newRef.onUpdate(function onNewEstimate(newEstimate) {
- estimateRef.setValue(newEstimate);
- }, {
- clearSignal: currentEstimatesCanceller.signal,
- emitCurrentValue: true
- });
- }
- /**
- * Callback to call when new metrics are available
- * @param {Object} value
- */
- function onMetric(value) {
- var requestDuration = value.requestDuration,
- segmentDuration = value.segmentDuration,
- size = value.size,
- content = value.content;
- // calculate bandwidth
- bandwidthEstimator.addSample(requestDuration, size);
- if (!content.segment.isInit) {
- // calculate "maintainability score"
- var segment = content.segment,
- representation = content.representation;
- if (segmentDuration === undefined && !segment.complete) {
- // We cannot know the real duration of the segment
- return;
+ * Refresh the Manifest, performing a full update if a partial update failed.
+ * Also re-call `recursivelyRefreshManifest` to schedule the next refresh
+ * trigger.
+ * @param {Object} manifest
+ * @param {Object} refreshInformation
+ */;
+ _proto._triggerNextManifestRefresh = function _triggerNextManifestRefresh(manifest, _ref2) {
+ var _this6 = this;
+ var enablePartialRefresh = _ref2.enablePartialRefresh,
+ unsafeMode = _ref2.unsafeMode;
+ var manifestUpdateUrl = manifest.updateUrl;
+ var fullRefresh;
+ var refreshURL;
+ if (this._prioritizedContentUrl !== null) {
+ fullRefresh = true;
+ refreshURL = this._prioritizedContentUrl;
+ this._prioritizedContentUrl = null;
+ } else {
+ fullRefresh = !enablePartialRefresh || manifestUpdateUrl === undefined;
+ refreshURL = fullRefresh ? manifest.getUrl() : manifestUpdateUrl;
+ }
+ var externalClockOffset = manifest.clockOffset;
+ if (unsafeMode) {
+ this._consecutiveUnsafeMode += 1;
+ log/* default.info */.Z.info("Init: Refreshing the Manifest in \"unsafeMode\" for the " + String(this._consecutiveUnsafeMode) + " consecutive time.");
+ } else if (this._consecutiveUnsafeMode > 0) {
+ log/* default.info */.Z.info("Init: Not parsing the Manifest in \"unsafeMode\" anymore after " + String(this._consecutiveUnsafeMode) + " consecutive times.");
+ this._consecutiveUnsafeMode = 0;
+ }
+ if (this._isRefreshPending) {
+ return;
+ }
+ this._isRefreshPending = true;
+ this._fetchManifest(refreshURL).then(function (res) {
+ return res.parse({
+ externalClockOffset: externalClockOffset,
+ previousManifest: manifest,
+ unsafeMode: unsafeMode
+ });
+ }).then(function (res) {
+ _this6._isRefreshPending = false;
+ var newManifest = res.manifest,
+ newSendingTime = res.sendingTime,
+ parsingTime = res.parsingTime;
+ var updateTimeStart = performance.now();
+ if (fullRefresh) {
+ manifest.replace(newManifest);
+ } else {
+ try {
+ manifest.update(newManifest);
+ } catch (e) {
+ var message = e instanceof Error ? e.message : "unknown error";
+ log/* default.warn */.Z.warn("MUS: Attempt to update Manifest failed: " + message, "Re-downloading the Manifest fully");
+ var _config$getCurrent3 = config/* default.getCurrent */.Z.getCurrent(),
+ FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY = _config$getCurrent3.FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY;
+ // The value allows to set a delay relatively to the last Manifest refresh
+ // (to avoid asking for it too often).
+ var timeSinceLastRefresh = newSendingTime === undefined ? 0 : performance.now() - newSendingTime;
+ var _minInterval = Math.max(_this6._settings.minimumManifestUpdateInterval - timeSinceLastRefresh, 0);
+ var unregisterCanceller = noop/* default */.Z;
+ var timeoutId = setTimeout(function () {
+ unregisterCanceller();
+ _this6._triggerNextManifestRefresh(manifest, {
+ enablePartialRefresh: false,
+ unsafeMode: false
+ });
+ }, Math.max(FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY - timeSinceLastRefresh, _minInterval));
+ unregisterCanceller = _this6._canceller.signal.register(function () {
+ clearTimeout(timeoutId);
+ });
+ return;
+ }
}
- var segDur = segmentDuration !== null && segmentDuration !== void 0 ? segmentDuration : segment.duration;
- scoreCalculator.addSample(representation, requestDuration / 1000, segDur);
+ var updatingTime = performance.now() - updateTimeStart;
+ _this6._recursivelyRefreshManifest(manifest, {
+ sendingTime: newSendingTime,
+ parsingTime: parsingTime,
+ updatingTime: updatingTime
+ });
+ })["catch"](function (err) {
+ _this6._isRefreshPending = false;
+ _this6._onFatalError(err);
+ });
+ };
+ _proto._onFatalError = function _onFatalError(err) {
+ if (this._canceller.isUsed()) {
+ return;
}
- }
- /** Callback called when a new request begins. */
- function onRequestBegin(val) {
- requestsStore.add(val);
- }
- /** Callback called when progress information is known on a pending request. */
- function onRequestProgress(val) {
- requestsStore.addProgress(val);
- }
- /** Callback called when a pending request ends. */
- function onRequestEnd(val) {
- requestsStore.remove(val.id);
- }
-}
+ this.trigger("error", err);
+ this.dispose();
+ };
+ return ManifestFetcher;
+}(event_emitter/* default */.Z);
/**
- * Filter representations given through filters options.
- * @param {Array.} representations
- * @param {number | undefined} widthLimit - Filter Object.
- * @returns {Array.}
+ * Returns `true` when the returned value seems to be a Promise instance, as
+ * created by the RxPlayer.
+ * @param {*} val
+ * @returns {boolean}
*/
-function getFilteredRepresentations(representations, widthLimit, bitrateThrottle) {
- var filteredReps = representations;
- if (bitrateThrottle < Infinity) {
- filteredReps = filterByBitrate(filteredReps, bitrateThrottle);
- }
- if (widthLimit !== undefined) {
- filteredReps = filterByWidth(filteredReps, widthLimit);
- }
- return filteredReps;
+
+function isPromise(val) {
+ return val instanceof Promise;
}
-;// CONCATENATED MODULE: ./src/core/adaptive/index.ts
+;// CONCATENATED MODULE: ./src/core/fetchers/manifest/index.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -44846,7 +41321,7 @@ function getFilteredRepresentations(representations, widthLimit, bitrateThrottle
* limitations under the License.
*/
-/* harmony default export */ var adaptive = (createAdaptiveRepresentationSelector);
+/* harmony default export */ var fetchers_manifest = (ManifestFetcher);
;// CONCATENATED MODULE: ./src/core/fetchers/cdn_prioritizer.ts
function cdn_prioritizer_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = cdn_prioritizer_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -44871,13 +41346,17 @@ function cdn_prioritizer_arrayLikeToArray(arr, len) { if (len == null || len > a
/**
- * Class signaling the priority between multiple CDN available for any given
- * resource.
+ * Class storing and signaling the priority between multiple CDN available for
+ * any given resource.
*
- * This class might perform requests and schedule timeouts by itself to keep its
- * internal list of CDN priority up-to-date.
- * When it is not needed anymore, you should call the `dispose` method to clear
- * all resources.
+ * This class was first created to implement the complexities behind
+ * Content Steering features, though its handling hasn't been added yet as we
+ * wait for its specification to be both standardized and relied on in the wild.
+ * In the meantime, it acts as an abstraction for the simple concept of
+ * avoiding to request a CDN for any segment when an issue is encountered with
+ * one (e.g. HTTP 500 statuses) and several CDN exist for a given resource. It
+ * should be noted that this is also one of the planified features of the
+ * Content Steering specification.
*
* @class CdnPrioritizer
*/
@@ -45095,8 +41574,6 @@ function applyPrioritizerToSegmentFetcher(prioritizer, fetcher) {
var utils = __webpack_require__(520);
// EXTERNAL MODULE: ./src/utils/array_includes.ts
var array_includes = __webpack_require__(7714);
-// EXTERNAL MODULE: ./src/utils/id_generator.ts
-var id_generator = __webpack_require__(908);
;// CONCATENATED MODULE: ./src/utils/initialization_segment_cache.ts
/**
* Copyright 2015 CANAL+ Group
@@ -45190,10 +41667,22 @@ var generateRequestID = (0,id_generator/* default */.Z)();
* An `ISegmentFetcher` also implements a retry mechanism, based on the given
* `options` argument, which may retry a segment request when it fails.
*
- * @param {string} bufferType
- * @param {Object} pipeline
- * @param {Object} lifecycleCallbacks
- * @param {Object} options
+ * @param {string} bufferType - Type of buffer concerned (e.g. `"audio"`,
+ * `"video"`, `"text" etc.)
+ * @param {Object} pipeline - The transport-specific logic allowing to load
+ * segments of the given buffer type and transport protocol (e.g. DASH).
+ * @param {Object|null} cdnPrioritizer - Abstraction allowing to synchronize,
+ * update and keep track of the priorization of the CDN to use to load any given
+ * segment, in cases where multiple ones are available.
+ *
+ * Can be set to `null` in which case a minimal priorization logic will be used
+ * instead.
+ * @param {Object} lifecycleCallbacks - Callbacks that can be registered to be
+ * informed when new requests are made, ended, new metrics are available etc.
+ * This should be mainly useful to implement an adaptive logic relying on those
+ * metrics and events.
+ * @param {Object} options - Various tweaking options allowing to configure the
+ * behavior of the returned `ISegmentFetcher`.
* @returns {Function}
*/
function segment_fetcher_createSegmentFetcher(bufferType, pipeline, cdnPrioritizer, lifecycleCallbacks, options) {
@@ -45217,7 +41706,7 @@ function segment_fetcher_createSegmentFetcher(bufferType, pipeline, cdnPrioritiz
*/
return /*#__PURE__*/function () {
var _fetchSegment = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(content, fetcherCallbacks, cancellationSignal) {
- var _a, _b, segmentIdString, requestId, requestInfo, parsedChunks, segmentDurationAcc, metricsSent, loaderCallbacks, cached, res, loadedData, callLoaderWithUrl, generateParserFunction, onRetry, sendNetworkMetricsIfAvailable;
+ var _a, _b, _c, segmentIdString, requestId, requestInfo, parsedChunks, segmentDurationAcc, metricsSent, loaderCallbacks, cached, res, loadedData, onCancellation, callLoaderWithUrl, generateParserFunction, onRetry, sendNetworkMetricsIfAvailable;
return regenerator_default().wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
@@ -45269,6 +41758,18 @@ function segment_fetcher_createSegmentFetcher(bufferType, pipeline, cdnPrioritiz
callLoaderWithUrl = function _callLoaderWithUrl(cdnMetadata) {
return loadSegment(cdnMetadata, content, requestOptions, cancellationSignal, loaderCallbacks);
};
+ onCancellation = function _onCancellation() {
+ var _a;
+ if (requestInfo !== undefined) {
+ return; // Request already terminated
+ }
+
+ log/* default.debug */.Z.debug("SF: Segment request cancelled", segmentIdString);
+ requestInfo = null;
+ (_a = lifecycleCallbacks.onRequestEnd) === null || _a === void 0 ? void 0 : _a.call(lifecycleCallbacks, {
+ id: requestId
+ });
+ };
// used by logs
segmentIdString = (0,utils/* getLoggableSegmentId */.K)(content);
requestId = generateRequestID();
@@ -45332,37 +41833,26 @@ function segment_fetcher_createSegmentFetcher(bufferType, pipeline, cdnPrioritiz
}; // Retrieve from cache if it exists
cached = cache !== undefined ? cache.get(content) : null;
if (!(cached !== null)) {
- _context.next = 15;
+ _context.next = 16;
break;
}
log/* default.debug */.Z.debug("SF: Found wanted segment in cache", segmentIdString);
fetcherCallbacks.onChunk(generateParserFunction(cached, false));
return _context.abrupt("return", Promise.resolve());
- case 15:
+ case 16:
log/* default.debug */.Z.debug("SF: Beginning request", segmentIdString);
(_a = lifecycleCallbacks.onRequestBegin) === null || _a === void 0 ? void 0 : _a.call(lifecycleCallbacks, {
requestTimestamp: performance.now(),
id: requestId,
content: content
});
- cancellationSignal.register(function () {
- var _a;
- if (requestInfo !== undefined) {
- return; // Request already terminated
- }
-
- log/* default.debug */.Z.debug("SF: Segment request cancelled", segmentIdString);
- requestInfo = null;
- (_a = lifecycleCallbacks.onRequestEnd) === null || _a === void 0 ? void 0 : _a.call(lifecycleCallbacks, {
- id: requestId
- });
- });
- _context.prev = 18;
- _context.next = 21;
+ cancellationSignal.register(onCancellation);
+ _context.prev = 19;
+ _context.next = 22;
return scheduleRequestWithCdns(content.representation.cdnMetadata, cdnPrioritizer, callLoaderWithUrl, (0,object_assign/* default */.Z)({
onRetry: onRetry
}, options), cancellationSignal);
- case 21:
+ case 22:
res = _context.sent;
if (res.resultType === "segment-loaded") {
loadedData = res.resultData.responseData;
@@ -45381,7 +41871,7 @@ function segment_fetcher_createSegmentFetcher(bufferType, pipeline, cdnPrioritiz
} else {
requestInfo = null;
}
- if (!cancellationSignal.isCancelled) {
+ if (!cancellationSignal.isCancelled()) {
// The current task could have been canceled as a result of one
// of the previous callbacks call. In that case, we don't want to send
// a "requestEnd" again as it has already been sent on cancellation.
@@ -45389,27 +41879,32 @@ function segment_fetcher_createSegmentFetcher(bufferType, pipeline, cdnPrioritiz
id: requestId
});
}
- _context.next = 37;
+ cancellationSignal.deregister(onCancellation);
+ _context.next = 41;
break;
- case 29:
- _context.prev = 29;
- _context.t0 = _context["catch"](18);
+ case 31:
+ _context.prev = 31;
+ _context.t0 = _context["catch"](19);
+ cancellationSignal.deregister(onCancellation);
requestInfo = null;
if (!(_context.t0 instanceof task_canceller/* CancellationError */.FU)) {
- _context.next = 35;
+ _context.next = 38;
break;
}
log/* default.debug */.Z.debug("SF: Segment request aborted", segmentIdString);
throw _context.t0;
- case 35:
+ case 38:
log/* default.debug */.Z.debug("SF: Segment request failed", segmentIdString);
+ (_c = lifecycleCallbacks.onRequestEnd) === null || _c === void 0 ? void 0 : _c.call(lifecycleCallbacks, {
+ id: requestId
+ });
throw errorSelector(_context.t0);
- case 37:
+ case 41:
case "end":
return _context.stop();
}
}
- }, _callee, null, [[18, 29]]);
+ }, _callee, null, [[19, 31]]);
}));
function fetchSegment(_x, _x2, _x3) {
return _fetchSegment.apply(this, arguments);
@@ -45445,6 +41940,7 @@ function getSegmentFetcherOptions(bufferType, _ref) {
+
var TaskPrioritizer = /*#__PURE__*/function () {
/**
* @param {Options} prioritizerOptions
@@ -45485,49 +41981,43 @@ var TaskPrioritizer = /*#__PURE__*/function () {
_proto.create = function create(taskFn, priority, callbacks, cancelSignal) {
var _this = this;
var newTask;
- return new Promise(function (resolve, reject) {
+ return (0,create_cancellable_promise/* default */.Z)(cancelSignal, function (resolve, reject) {
/** Function allowing to start the underlying Promise. */
var trigger = function trigger() {
if (newTask.hasEnded) {
- unregisterCancelSignal();
return;
}
- var interrupter = new task_canceller/* default */.ZP({
- cancelOn: cancelSignal
- });
+ var finishTask = function finishTask() {
+ unlinkInterrupter();
+ _this._endTask(newTask);
+ };
+ var onResolve = function onResolve(value) {
+ callbacks.beforeEnded();
+ finishTask();
+ resolve(value);
+ };
+ var onReject = function onReject(err) {
+ finishTask();
+ reject(err);
+ };
+ var interrupter = new task_canceller/* default */.ZP();
+ var unlinkInterrupter = interrupter.linkToSignal(cancelSignal);
newTask.interrupter = interrupter;
interrupter.signal.register(function () {
newTask.interrupter = null;
- if (!cancelSignal.isCancelled) {
+ if (!cancelSignal.isCancelled()) {
callbacks.beforeInterrupted();
}
});
_this._minPendingPriority = _this._minPendingPriority === null ? newTask.priority : Math.min(_this._minPendingPriority, newTask.priority);
_this._pendingTasks.push(newTask);
newTask.taskFn(interrupter.signal).then(onResolve)["catch"](function (err) {
- if (!cancelSignal.isCancelled && interrupter.isUsed && err instanceof task_canceller/* CancellationError */.FU) {
+ if (!cancelSignal.isCancelled() && interrupter.isUsed() && err instanceof task_canceller/* CancellationError */.FU) {
return;
}
onReject(err);
});
};
- var unregisterCancelSignal = cancelSignal.register(function (cancellationError) {
- _this._endTask(newTask);
- reject(cancellationError);
- });
- var finishTask = function finishTask() {
- unregisterCancelSignal();
- _this._endTask(newTask);
- };
- var onResolve = function onResolve(value) {
- callbacks.beforeEnded();
- finishTask();
- resolve(value);
- };
- var onReject = function onReject(err) {
- finishTask();
- reject(err);
- };
newTask = {
hasEnded: false,
priority: priority,
@@ -45551,6 +42041,9 @@ var TaskPrioritizer = /*#__PURE__*/function () {
_this._interruptCancellableTasks();
}
}
+ return function () {
+ return _this._endTask(newTask);
+ };
});
};
_proto._endTask = function _endTask(task) {
@@ -45786,30 +42279,6 @@ function _findTaskIndex(taskFn, queue) {
* priority.
*
* @class SegmentFetcherCreator
- *
- * @example
- * ```js
- * const creator = new SegmentFetcherCreator(transport, {
- * lowLatencyMode: false,
- * maxRetryRegular: Infinity,
- * maxRetryOffline: Infinity,
- * });
- *
- * // 2 - create a new fetcher with its backoff options
- * const fetcher = creator.createSegmentFetcher("audio", {
- * // ... (lifecycle callbacks if wanted)
- * });
- *
- * // 3 - load a segment with a given priority
- * fetcher.createRequest(myContent, 1)
- * // 4 - parse it
- * .pipe(
- * filter(evt => evt.type === "chunk"),
- * mergeMap(response => response.parse());
- * )
- * // 5 - use it
- * .subscribe((res) => console.log("audio chunk downloaded:", res));
- * ```
*/
var SegmentFetcherCreator = /*#__PURE__*/function () {
/**
@@ -45866,221 +42335,6 @@ var SegmentFetcherCreator = /*#__PURE__*/function () {
*/
/* harmony default export */ var segment = (SegmentFetcherCreator);
-// EXTERNAL MODULE: ./src/compat/clear_element_src.ts
-var clear_element_src = __webpack_require__(5767);
-// EXTERNAL MODULE: ./src/compat/browser_compatibility_types.ts
-var browser_compatibility_types = __webpack_require__(3774);
-// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts
-var is_non_empty_string = __webpack_require__(6923);
-;// CONCATENATED MODULE: ./src/core/init/create_media_source.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-
-
-var onSourceOpen$ = event_listeners/* onSourceOpen$ */.ym;
-/**
- * Dispose of ressources taken by the MediaSource:
- * - Clear the MediaSource' SourceBuffers
- * - Clear the mediaElement's src (stop the mediaElement)
- * - Revoke MediaSource' URL
- * @param {HTMLMediaElement} mediaElement
- * @param {MediaSource|null} mediaSource
- * @param {string|null} mediaSourceURL
- */
-function resetMediaSource(mediaElement, mediaSource, mediaSourceURL) {
- if (mediaSource !== null && mediaSource.readyState !== "closed") {
- var readyState = mediaSource.readyState,
- sourceBuffers = mediaSource.sourceBuffers;
- for (var i = sourceBuffers.length - 1; i >= 0; i--) {
- var sourceBuffer = sourceBuffers[i];
- try {
- if (readyState === "open") {
- log/* default.info */.Z.info("Init: Removing SourceBuffer from mediaSource");
- sourceBuffer.abort();
- }
- mediaSource.removeSourceBuffer(sourceBuffer);
- } catch (e) {
- log/* default.warn */.Z.warn("Init: Error while disposing SourceBuffer", e instanceof Error ? e : "");
- }
- }
- if (sourceBuffers.length > 0) {
- log/* default.warn */.Z.warn("Init: Not all SourceBuffers could have been removed.");
- }
- }
- (0,clear_element_src/* default */.Z)(mediaElement);
- if (mediaSourceURL !== null) {
- try {
- log/* default.debug */.Z.debug("Init: Revoking previous URL");
- URL.revokeObjectURL(mediaSourceURL);
- } catch (e) {
- log/* default.warn */.Z.warn("Init: Error while revoking the media source URL", e instanceof Error ? e : "");
- }
- }
-}
-/**
- * Create, on subscription, a MediaSource instance and attach it to the given
- * mediaElement element's src attribute.
- *
- * Returns an Observable which emits the MediaSource when created and attached
- * to the mediaElement element.
- * This Observable never completes. It can throw if MediaSource is not
- * available in the current environment.
- *
- * On unsubscription, the mediaElement.src is cleaned, MediaSource SourceBuffers
- * are aborted and some minor cleaning is done.
- *
- * @param {HTMLMediaElement} mediaElement
- * @returns {Observable}
- */
-function createMediaSource(mediaElement) {
- return new Observable/* Observable */.y(function (observer) {
- if (browser_compatibility_types/* MediaSource_ */.J == null) {
- throw new media_error/* default */.Z("MEDIA_SOURCE_NOT_SUPPORTED", "No MediaSource Object was found in the current browser.");
- }
- // make sure the media has been correctly reset
- var oldSrc = (0,is_non_empty_string/* default */.Z)(mediaElement.src) ? mediaElement.src : null;
- resetMediaSource(mediaElement, null, oldSrc);
- log/* default.info */.Z.info("Init: Creating MediaSource");
- var mediaSource = new browser_compatibility_types/* MediaSource_ */.J();
- var objectURL = URL.createObjectURL(mediaSource);
- log/* default.info */.Z.info("Init: Attaching MediaSource URL to the media element", objectURL);
- mediaElement.src = objectURL;
- observer.next(mediaSource);
- return function () {
- resetMediaSource(mediaElement, mediaSource, objectURL);
- };
- });
-}
-/**
- * Create and open a new MediaSource object on the given media element.
- * Emit the MediaSource when done.
- * @param {HTMLMediaElement} mediaElement
- * @returns {Observable}
- */
-function openMediaSource(mediaElement) {
- return createMediaSource(mediaElement).pipe((0,mergeMap/* mergeMap */.z)(function (mediaSource) {
- return onSourceOpen$(mediaSource).pipe((0,take/* take */.q)(1), (0,map/* map */.U)(function () {
- return mediaSource;
- }));
- }));
-}
-// EXTERNAL MODULE: ./src/core/init/events_generators.ts
-var events_generators = __webpack_require__(8343);
-;// CONCATENATED MODULE: ./src/core/init/get_initial_time.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-/**
- * Returns the calculated initial time for the content described by the given
- * Manifest:
- * 1. if a start time is defined by user, calculate starting time from the
- * manifest information
- * 2. else if the media is live, use the live edge and suggested delays from
- * it
- * 3. else returns the minimum time announced in the manifest
- * @param {Manifest} manifest
- * @param {boolean} lowLatencyMode
- * @param {Object} startAt
- * @returns {Number}
- */
-function getInitialTime(manifest, lowLatencyMode, startAt) {
- if (!(0,is_null_or_undefined/* default */.Z)(startAt)) {
- var min = manifest.getMinimumSafePosition();
- var max;
- if (manifest.isLive) {
- max = manifest.getLivePosition();
- }
- if (max === undefined) {
- max = manifest.getMaximumSafePosition();
- }
- if (!(0,is_null_or_undefined/* default */.Z)(startAt.position)) {
- log/* default.debug */.Z.debug("Init: using startAt.minimumPosition");
- return Math.max(Math.min(startAt.position, max), min);
- } else if (!(0,is_null_or_undefined/* default */.Z)(startAt.wallClockTime)) {
- log/* default.debug */.Z.debug("Init: using startAt.wallClockTime");
- var ast = manifest.availabilityStartTime === undefined ? 0 : manifest.availabilityStartTime;
- var position = startAt.wallClockTime - ast;
- return Math.max(Math.min(position, max), min);
- } else if (!(0,is_null_or_undefined/* default */.Z)(startAt.fromFirstPosition)) {
- log/* default.debug */.Z.debug("Init: using startAt.fromFirstPosition");
- var fromFirstPosition = startAt.fromFirstPosition;
- return fromFirstPosition <= 0 ? min : Math.min(max, min + fromFirstPosition);
- } else if (!(0,is_null_or_undefined/* default */.Z)(startAt.fromLastPosition)) {
- log/* default.debug */.Z.debug("Init: using startAt.fromLastPosition");
- var fromLastPosition = startAt.fromLastPosition;
- return fromLastPosition >= 0 ? max : Math.max(min, max + fromLastPosition);
- } else if (!(0,is_null_or_undefined/* default */.Z)(startAt.percentage)) {
- log/* default.debug */.Z.debug("Init: using startAt.percentage");
- var percentage = startAt.percentage;
- if (percentage > 100) {
- return max;
- } else if (percentage < 0) {
- return min;
- }
- var ratio = +percentage / 100;
- var extent = max - min;
- return min + extent * ratio;
- }
- }
- var minimumPosition = manifest.getMinimumSafePosition();
- if (manifest.isLive) {
- var suggestedPresentationDelay = manifest.suggestedPresentationDelay,
- clockOffset = manifest.clockOffset;
- var maximumPosition = manifest.getMaximumSafePosition();
- var liveTime;
- var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
- DEFAULT_LIVE_GAP = _config$getCurrent.DEFAULT_LIVE_GAP;
- if (clockOffset === undefined) {
- log/* default.info */.Z.info("Init: no clock offset found for a live content, " + "starting close to maximum available position");
- liveTime = maximumPosition;
- } else {
- log/* default.info */.Z.info("Init: clock offset found for a live content, " + "checking if we can start close to it");
- var _ast = manifest.availabilityStartTime === undefined ? 0 : manifest.availabilityStartTime;
- var clockRelativeLiveTime = (performance.now() + clockOffset) / 1000 - _ast;
- liveTime = Math.min(maximumPosition, clockRelativeLiveTime);
- }
- var diffFromLiveTime = suggestedPresentationDelay !== undefined ? suggestedPresentationDelay : lowLatencyMode ? DEFAULT_LIVE_GAP.LOW_LATENCY : DEFAULT_LIVE_GAP.DEFAULT;
- log/* default.debug */.Z.debug("Init: " + liveTime + " defined as the live time, applying a live gap" + (" of " + diffFromLiveTime));
- return Math.max(liveTime - diffFromLiveTime, minimumPosition);
- }
- log/* default.info */.Z.info("Init: starting at the minimum available position:", minimumPosition);
- return minimumPosition;
-}
-// EXTERNAL MODULE: ./src/core/init/link_drm_and_content.ts + 1 modules
-var link_drm_and_content = __webpack_require__(9607);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/throwError.js
-var throwError = __webpack_require__(3610);
// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js
var assertThisInitialized = __webpack_require__(7326);
;// CONCATENATED MODULE: ./src/compat/change_source_buffer_type.ts
@@ -46158,6 +42412,7 @@ var types = __webpack_require__(9612);
+
/**
* Allows to push and remove new segments to a SourceBuffer in a FIFO queue (not
* doing so can lead to browser Errors) while keeping an inventory of what has
@@ -46353,11 +42608,6 @@ var AudioVideoSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) {
}
}
/**
- * When the returned observable is subscribed:
- * 1. Add your operation to the queue.
- * 2. Begin the queue if not pending.
- *
- * Cancel queued operation on unsubscription.
* @private
* @param {Object} operation
* @param {Object} cancellationSignal
@@ -46365,17 +42615,17 @@ var AudioVideoSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) {
*/;
_proto._addToQueue = function _addToQueue(operation, cancellationSignal) {
var _this2 = this;
- return new Promise(function (resolve, reject) {
- if (cancellationSignal.cancellationError !== null) {
- return reject(cancellationSignal.cancellationError);
- }
+ return (0,create_cancellable_promise/* default */.Z)(cancellationSignal, function (resolve, reject) {
var shouldRestartQueue = _this2._queue.length === 0 && _this2._pendingTask === null;
var queueItem = (0,object_assign/* default */.Z)({
resolve: resolve,
reject: reject
}, operation);
_this2._queue.push(queueItem);
- cancellationSignal.register(function (error) {
+ if (shouldRestartQueue) {
+ _this2._flush();
+ }
+ return function () {
// Remove the corresponding element from the AudioVideoSegmentBuffer's
// queue.
// If the operation was a pending task, it should still continue to not
@@ -46386,11 +42636,7 @@ var AudioVideoSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) {
}
queueItem.resolve = noop/* default */.Z;
queueItem.reject = noop/* default */.Z;
- reject(error);
- });
- if (shouldRestartQueue) {
- _this2._flush();
- }
+ };
});
}
/**
@@ -46630,6 +42876,7 @@ function assertPushedDataIsBufferSource(pushedData) {
+
var POSSIBLE_BUFFER_TYPES = ["audio", "video", "text", "image"];
/**
* Allows to easily create and dispose SegmentBuffers, which are interfaces to
@@ -46754,20 +43001,23 @@ var SegmentBuffersStore = /*#__PURE__*/function () {
if (this._areNativeBuffersUsable()) {
return Promise.resolve();
}
- return new Promise(function (res, rej) {
- var onAddedOrDisabled = function onAddedOrDisabled() {
+ return (0,create_cancellable_promise/* default */.Z)(cancelWaitSignal, function (res) {
+ /* eslint-disable-next-line prefer-const */
+ var onAddedOrDisabled;
+ var removeCallback = function removeCallback() {
+ var indexOf = _this._onNativeBufferAddedOrDisabled.indexOf(onAddedOrDisabled);
+ if (indexOf >= 0) {
+ _this._onNativeBufferAddedOrDisabled.splice(indexOf, 1);
+ }
+ };
+ onAddedOrDisabled = function onAddedOrDisabled() {
if (_this._areNativeBuffersUsable()) {
+ removeCallback();
res();
}
};
_this._onNativeBufferAddedOrDisabled.push(onAddedOrDisabled);
- cancelWaitSignal.register(function (error) {
- var indexOf = _this._onNativeBufferAddedOrDisabled.indexOf(onAddedOrDisabled);
- if (indexOf >= 0) {
- _this._onNativeBufferAddedOrDisabled.splice(indexOf, 1);
- }
- rej(error);
- });
+ return removeCallback;
});
}
/**
@@ -46942,147 +43192,9 @@ function shouldHaveNativeBuffer(bufferType) {
/* harmony default export */ var segment_buffers = (SegmentBuffersStore);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/innerFrom.js
-var innerFrom = __webpack_require__(7878);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/exhaustMap.js
-
-
-
-
-function exhaustMap(project, resultSelector) {
- if (resultSelector) {
- return function (source) {
- return source.pipe(exhaustMap(function (a, i) { return (0,innerFrom/* innerFrom */.Xf)(project(a, i)).pipe((0,map/* map */.U)(function (b, ii) { return resultSelector(a, b, i, ii); })); }));
- };
- }
- return (0,lift/* operate */.e)(function (source, subscriber) {
- var index = 0;
- var innerSub = null;
- var isComplete = false;
- source.subscribe((0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, function (outerValue) {
- if (!innerSub) {
- innerSub = (0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, undefined, function () {
- innerSub = null;
- isComplete && subscriber.complete();
- });
- (0,innerFrom/* innerFrom */.Xf)(project(outerValue, index++)).subscribe(innerSub);
- }
- }, function () {
- isComplete = true;
- !innerSub && subscriber.complete();
- }));
- });
-}
-//# sourceMappingURL=exhaustMap.js.map
-;// CONCATENATED MODULE: ./src/utils/rx-from_cancellable_promise.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Transform a Promise that can be cancelled (through the usage of a
- * `TaskCanceller`) to an Observable, while keeping the cancellation logic
- * between both in sync.
- *
- * @example
- * ```js
- * const canceller = new TaskCanceller();
- * fromCancellablePromise(
- * canceller,
- * () => doSomeCancellableTasks(canceller.signal)
- * ).subscribe(
- * (i) => console.log("Emitted: ", i);
- * (e) => console.log("Error: ", e);
- * () => console.log("Complete.")
- * );
- * ```
- * @param {Object} canceller
- * @param {Function} fn
- * @returns {Observable}
- */
-function fromCancellablePromise(canceller, fn) {
- return new Observable/* Observable */.y(function (obs) {
- var isUnsubscribedFrom = false;
- var isComplete = false;
- fn().then(function (i) {
- if (isUnsubscribedFrom) {
- return;
- }
- isComplete = true;
- obs.next(i);
- obs.complete();
- }, function (err) {
- isComplete = true;
- if (isUnsubscribedFrom) {
- return;
- }
- obs.error(err);
- });
- return function () {
- if (!isComplete) {
- isUnsubscribedFrom = true;
- canceller.cancel();
- }
- };
- });
-}
// EXTERNAL MODULE: ./node_modules/next-tick/index.js
var next_tick = __webpack_require__(7473);
var next_tick_default = /*#__PURE__*/__webpack_require__.n(next_tick);
-;// CONCATENATED MODULE: ./src/utils/rx-next-tick.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/**
- * Create Observable that emits and complete on the next micro-task.
- *
- * This Observable can be useful to prevent race conditions based on
- * synchronous task being performed in the wrong order.
- * By awaiting nextTickObs before performing a task, you ensure that all other
- * tasks that might have run synchronously either before or after it all already
- * ran.
- * @returns {Observable}
- */
-function nextTickObs() {
- return new Observable/* Observable */.y(function (obs) {
- var isFinished = false;
- next_tick_default()(function () {
- if (!isFinished) {
- obs.next();
- obs.complete();
- }
- });
- return function () {
- isFinished = true;
- };
- });
-}
;// CONCATENATED MODULE: ./src/utils/sorted_list.ts
/**
* Copyright 2015 CANAL+ Group
@@ -47188,6 +43300,9 @@ var SortedList = /*#__PURE__*/function () {
throw new Error("Invalid index.");
}
return this._array[index];
+ };
+ _proto.toArray = function toArray() {
+ return this._array.slice();
}
/**
* Find the first element corresponding to the given predicate.
@@ -47379,7 +43494,6 @@ var WeakMapMemory = /*#__PURE__*/function () {
*
* @param {Object} opt
* @param {Object} cancellationSignal
- * @returns {Observable}
*/
function BufferGarbageCollector(_ref, cancellationSignal) {
var segmentBuffer = _ref.segmentBuffer,
@@ -47528,89 +43642,8 @@ function _clearBuffer() {
}));
return _clearBuffer.apply(this, arguments);
}
-// EXTERNAL MODULE: ./src/core/stream/events_generators.ts
-var stream_events_generators = __webpack_require__(8567);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/ReplaySubject.js
-var ReplaySubject = __webpack_require__(3);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/catchError.js
-var catchError = __webpack_require__(9878);
-;// CONCATENATED MODULE: ./src/core/stream/reload_after_switch.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
+;// CONCATENATED MODULE: ./src/core/stream/representation/utils/downloading_queue.ts
-/**
- * Regularly ask to reload the MediaSource on each playback observation
- * performed by the playback observer.
- *
- * If and only if the Period currently played corresponds to `Period`, applies
- * an offset to the reloaded position corresponding to `deltaPos`.
- * This can be useful for example when switching the audio/video track, where
- * you might want to give back some context if that was the currently played
- * track.
- *
- * @param {Object} period - The Period linked to the Adaptation or
- * Representation that you want to switch to.
- * @param {Observable} playbackObserver - emit playback conditions.
- * Has to emit last playback conditions immediately on subscribe.
- * @param {number} deltaPos - If the concerned Period is playing at the time
- * this function is called, we will add this value, in seconds, to the current
- * position to indicate the position we should reload at.
- * This value allows to give back context (by replaying some media data) after
- * a switch.
- * @returns {Observable}
- */
-function reloadAfterSwitch(period, bufferType, playbackObserver, deltaPos) {
- // We begin by scheduling a micro-task to reduce the possibility of race
- // conditions where `reloadAfterSwitch` would be called synchronously before
- // the next observation (which may reflect very different playback conditions)
- // is actually received.
- // It can happen when `reloadAfterSwitch` is called as a side-effect of the
- // same event that triggers the playback observation to be emitted.
- return nextTickObs().pipe((0,mergeMap/* mergeMap */.z)(function () {
- return playbackObserver.getReference().asObservable();
- }), (0,map/* map */.U)(function (observation) {
- var _a, _b;
- var currentTime = playbackObserver.getCurrentTime();
- var pos = currentTime + deltaPos;
- // Bind to Period start and end
- var reloadAt = Math.min(Math.max(period.start, pos), (_a = period.end) !== null && _a !== void 0 ? _a : Infinity);
- var autoPlay = !((_b = observation.paused.pending) !== null && _b !== void 0 ? _b : playbackObserver.getIsPaused());
- return stream_events_generators/* default.waitingMediaSourceReload */.Z.waitingMediaSourceReload(bufferType, period, reloadAt, autoPlay);
- }));
-}
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/withLatestFrom.js
-var withLatestFrom = __webpack_require__(3428);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/takeWhile.js
-
-
-function takeWhile(predicate, inclusive) {
- if (inclusive === void 0) { inclusive = false; }
- return (0,lift/* operate */.e)(function (source, subscriber) {
- var index = 0;
- source.subscribe((0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, function (value) {
- var result = predicate(value, index++);
- (result || inclusive) && subscriber.next(value);
- !result && subscriber.complete();
- }));
- });
-}
-//# sourceMappingURL=takeWhile.js.map
-;// CONCATENATED MODULE: ./src/core/stream/representation/downloading_queue.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -47632,11 +43665,17 @@ function takeWhile(predicate, inclusive) {
+
/**
* Class scheduling segment downloads for a single Representation.
+ *
+ * TODO The request scheduling abstractions might be simplified by integrating
+ * the `DownloadingQueue` in the segment fetchers code, instead of having it as
+ * an utilis of the `RepresentationStream` like here.
* @class DownloadingQueue
*/
-var DownloadingQueue = /*#__PURE__*/function () {
+var DownloadingQueue = /*#__PURE__*/function (_EventEmitter) {
+ (0,inheritsLoose/* default */.Z)(DownloadingQueue, _EventEmitter);
/**
* Create a new `DownloadingQueue`.
*
@@ -47659,17 +43698,20 @@ var DownloadingQueue = /*#__PURE__*/function () {
* media segment.
*/
function DownloadingQueue(content, downloadQueue, segmentFetcher, hasInitSegment) {
- this._content = content;
- this._currentObs$ = null;
- this._downloadQueue = downloadQueue;
- this._initSegmentRequest = null;
- this._mediaSegmentRequest = null;
- this._segmentFetcher = segmentFetcher;
- this._initSegmentInfoRef = (0,reference/* default */.ZP)(undefined);
- this._mediaSegmentsAwaitingInitMetadata = new Set();
+ var _this;
+ _this = _EventEmitter.call(this) || this;
+ _this._content = content;
+ _this._currentCanceller = null;
+ _this._downloadQueue = downloadQueue;
+ _this._initSegmentRequest = null;
+ _this._mediaSegmentRequest = null;
+ _this._segmentFetcher = segmentFetcher;
+ _this._initSegmentInfoRef = (0,reference/* default */.ZP)(undefined);
+ _this._mediaSegmentAwaitingInitMetadata = null;
if (!hasInitSegment) {
- this._initSegmentInfoRef.setValue(null);
+ _this._initSegmentInfoRef.setValue(null);
}
+ return _this;
}
/**
* Returns the initialization segment currently being requested.
@@ -47691,344 +43733,318 @@ var DownloadingQueue = /*#__PURE__*/function () {
/**
* Start the current downloading queue, emitting events as it loads and parses
* initialization and media segments.
- *
- * If it was already started, returns the same - shared - Observable.
- * @returns {Observable}
*/;
_proto.start = function start() {
- var _this = this;
- if (this._currentObs$ !== null) {
- return this._currentObs$;
- }
- var obs = (0,defer/* defer */.P)(function () {
- var mediaQueue$ = _this._downloadQueue.asObservable().pipe((0,filter/* filter */.h)(function (_ref) {
- var segmentQueue = _ref.segmentQueue;
- // First, the first elements of the segmentQueue might be already
- // loaded but awaiting the initialization segment to be parsed.
- // Filter those out.
- var nextSegmentToLoadIdx = 0;
- for (; nextSegmentToLoadIdx < segmentQueue.length; nextSegmentToLoadIdx++) {
- var nextSegment = segmentQueue[nextSegmentToLoadIdx].segment;
- if (!_this._mediaSegmentsAwaitingInitMetadata.has(nextSegment.id)) {
- break;
- }
- }
- var currentSegmentRequest = _this._mediaSegmentRequest;
- if (nextSegmentToLoadIdx >= segmentQueue.length) {
- return currentSegmentRequest !== null;
- } else if (currentSegmentRequest === null) {
- return true;
+ var _this2 = this;
+ if (this._currentCanceller !== null) {
+ return;
+ }
+ this._currentCanceller = new task_canceller/* default */.ZP();
+ // Listen for asked media segments
+ this._downloadQueue.onUpdate(function (queue) {
+ var segmentQueue = queue.segmentQueue;
+ if (segmentQueue.length > 0 && segmentQueue[0].segment.id === _this2._mediaSegmentAwaitingInitMetadata) {
+ // The most needed segment is still the same one, and there's no need to
+ // update its priority as the request already ended, just quit.
+ return;
+ }
+ var currentSegmentRequest = _this2._mediaSegmentRequest;
+ if (segmentQueue.length === 0) {
+ if (currentSegmentRequest === null) {
+ // There's nothing to load but there's already no request pending.
+ return;
}
- var nextItem = segmentQueue[nextSegmentToLoadIdx];
+ log/* default.debug */.Z.debug("Stream: no more media segment to request. Cancelling queue.", _this2._content.adaptation.type);
+ _this2._restartMediaSegmentDownloadingQueue();
+ return;
+ } else if (currentSegmentRequest === null) {
+ // There's no request although there are needed segments: start requests
+ log/* default.debug */.Z.debug("Stream: Media segments now need to be requested. Starting queue.", _this2._content.adaptation.type, segmentQueue.length);
+ _this2._restartMediaSegmentDownloadingQueue();
+ return;
+ } else {
+ var nextItem = segmentQueue[0];
if (currentSegmentRequest.segment.id !== nextItem.segment.id) {
- return true;
+ // The most important request if for another segment, request it
+ log/* default.debug */.Z.debug("Stream: Next media segment changed, cancelling previous", _this2._content.adaptation.type);
+ _this2._restartMediaSegmentDownloadingQueue();
+ return;
}
if (currentSegmentRequest.priority !== nextItem.priority) {
- _this._segmentFetcher.updatePriority(currentSegmentRequest.request, nextItem.priority);
- }
- return false;
- }), (0,switchMap/* switchMap */.w)(function (_ref2) {
- var segmentQueue = _ref2.segmentQueue;
- return segmentQueue.length > 0 ? _this._requestMediaSegments() : empty/* EMPTY */.E;
- }));
- var initSegmentPush$ = _this._downloadQueue.asObservable().pipe((0,filter/* filter */.h)(function (next) {
- var initSegmentRequest = _this._initSegmentRequest;
- if (next.initSegment !== null && initSegmentRequest !== null) {
- if (next.initSegment.priority !== initSegmentRequest.priority) {
- _this._segmentFetcher.updatePriority(initSegmentRequest.request, next.initSegment.priority);
- }
- return false;
- } else {
- return next.initSegment === null || initSegmentRequest === null;
+ // The priority of the most important request has changed, update it
+ log/* default.debug */.Z.debug("Stream: Priority of next media segment changed, updating", _this2._content.adaptation.type, currentSegmentRequest.priority, nextItem.priority);
+ _this2._segmentFetcher.updatePriority(currentSegmentRequest.request, nextItem.priority);
}
- }), (0,switchMap/* switchMap */.w)(function (nextQueue) {
- if (nextQueue.initSegment === null) {
- return empty/* EMPTY */.E;
+ return;
+ }
+ }, {
+ emitCurrentValue: true,
+ clearSignal: this._currentCanceller.signal
+ });
+ // Listen for asked init segment
+ this._downloadQueue.onUpdate(function (next) {
+ var _a;
+ var initSegmentRequest = _this2._initSegmentRequest;
+ if (next.initSegment !== null && initSegmentRequest !== null) {
+ if (next.initSegment.priority !== initSegmentRequest.priority) {
+ _this2._segmentFetcher.updatePriority(initSegmentRequest.request, next.initSegment.priority);
}
- return _this._requestInitSegment(nextQueue.initSegment);
- }));
- return (0,merge/* merge */.T)(initSegmentPush$, mediaQueue$);
- }).pipe((0,share/* share */.B)());
- this._currentObs$ = obs;
- return obs;
+ return;
+ } else if (((_a = next.initSegment) === null || _a === void 0 ? void 0 : _a.segment.id) === (initSegmentRequest === null || initSegmentRequest === void 0 ? void 0 : initSegmentRequest.segment.id)) {
+ return;
+ }
+ if (next.initSegment === null) {
+ log/* default.debug */.Z.debug("Stream: no more init segment to request. Cancelling queue.", _this2._content.adaptation.type);
+ }
+ _this2._restartInitSegmentDownloadingQueue(next.initSegment);
+ }, {
+ emitCurrentValue: true,
+ clearSignal: this._currentCanceller.signal
+ });
+ };
+ _proto.stop = function stop() {
+ var _a;
+ (_a = this._currentCanceller) === null || _a === void 0 ? void 0 : _a.cancel();
+ this._currentCanceller = null;
}
/**
* Internal logic performing media segment requests.
- * @returns {Observable}
*/;
- _proto._requestMediaSegments = function _requestMediaSegments() {
- var _this2 = this;
+ _proto._restartMediaSegmentDownloadingQueue = function _restartMediaSegmentDownloadingQueue() {
+ var _this3 = this;
+ if (this._mediaSegmentRequest !== null) {
+ this._mediaSegmentRequest.canceller.cancel();
+ }
var _this$_downloadQueue$ = this._downloadQueue.getValue(),
segmentQueue = _this$_downloadQueue$.segmentQueue;
var currentNeededSegment = segmentQueue[0];
- /* eslint-disable-next-line @typescript-eslint/no-this-alias */
- var self = this;
- return (0,defer/* defer */.P)(function () {
- return recursivelyRequestSegments(currentNeededSegment);
- }).pipe((0,finalize/* finalize */.x)(function () {
- _this2._mediaSegmentRequest = null;
- }));
- function recursivelyRequestSegments(startingSegment) {
+ var recursivelyRequestSegments = function recursivelyRequestSegments(startingSegment) {
+ if (_this3._currentCanceller !== null && _this3._currentCanceller.isUsed()) {
+ _this3._mediaSegmentRequest = null;
+ return;
+ }
if (startingSegment === undefined) {
- return (0,of.of)({
- type: "end-of-queue",
- value: null
- });
+ _this3._mediaSegmentRequest = null;
+ _this3.trigger("emptyQueue", null);
+ return;
}
+ var canceller = new task_canceller/* default */.ZP();
+ var unlinkCanceller = _this3._currentCanceller === null ? noop/* default */.Z : canceller.linkToSignal(_this3._currentCanceller.signal);
var segment = startingSegment.segment,
priority = startingSegment.priority;
var context = (0,object_assign/* default */.Z)({
segment: segment
- }, self._content);
- return new Observable/* Observable */.y(function (obs) {
- /** TaskCanceller linked to this Observable's lifecycle. */
- var canceller = new task_canceller/* default */.ZP();
- /**
- * If `true` , the Observable has either errored, completed, or was
- * unsubscribed from.
- * This only conserves the Observable for the current segment's request,
- * not the other recursively-created future ones.
- */
- var isComplete = false;
- /**
- * Subscription to request the following segment (as this function is
- * recursive).
- * `undefined` if no following segment has been requested.
- */
- var nextSegmentSubscription;
- /**
- * If true, we're currently waiting for the initialization segment to be
- * parsed before parsing a received chunk.
- *
- * In that case, the `DownloadingQueue` has to remain careful to only
- * send further events and complete the Observable only once the
- * initialization segment has been parsed AND the chunk parsing has been
- * done (this can be done very simply by listening to the same
- * `ISharedReference`, as its callbacks are called in the same order
- * than the one in which they are added.
- */
- var isWaitingOnInitSegment = false;
- /** Scheduled actual segment request. */
- var request = self._segmentFetcher.createRequest(context, priority, {
- /**
- * Callback called when the request has to be retried.
- * @param {Error} error
- */
- onRetry: function onRetry(error) {
- obs.next({
- type: "retry",
- value: {
- segment: segment,
- error: error
- }
- });
- },
- /**
- * Callback called when the request has to be interrupted and
- * restarted later.
- */
- beforeInterrupted: function beforeInterrupted() {
- log/* default.info */.Z.info("Stream: segment request interrupted temporarly.", segment.id, segment.time);
- },
- /**
- * Callback called when a decodable chunk of the segment is available.
- * @param {Function} parse - Function allowing to parse the segment.
- */
- onChunk: function onChunk(parse) {
- var initTimescale = self._initSegmentInfoRef.getValue();
- if (initTimescale !== undefined) {
- emitChunk(parse(initTimescale !== null && initTimescale !== void 0 ? initTimescale : undefined));
- } else {
- isWaitingOnInitSegment = true;
- // We could also technically call `waitUntilDefined` in both cases,
- // but I found it globally clearer to segregate the two cases,
- // especially to always have a meaningful `isWaitingOnInitSegment`
- // boolean which is a very important variable.
- self._initSegmentInfoRef.waitUntilDefined(function (actualTimescale) {
- emitChunk(parse(actualTimescale !== null && actualTimescale !== void 0 ? actualTimescale : undefined));
- }, {
- clearSignal: canceller.signal
- });
- }
- },
- /** Callback called after all chunks have been sent. */onAllChunksReceived: function onAllChunksReceived() {
- if (!isWaitingOnInitSegment) {
- obs.next({
- type: "end-of-segment",
- value: {
- segment: segment
- }
- });
- } else {
- self._mediaSegmentsAwaitingInitMetadata.add(segment.id);
- self._initSegmentInfoRef.waitUntilDefined(function () {
- obs.next({
- type: "end-of-segment",
- value: {
- segment: segment
- }
- });
- self._mediaSegmentsAwaitingInitMetadata["delete"](segment.id);
- isWaitingOnInitSegment = false;
- }, {
- clearSignal: canceller.signal
- });
- }
- },
- /**
- * Callback called right after the request ended but before the next
- * requests are scheduled. It is used to schedule the next segment.
- */
- beforeEnded: function beforeEnded() {
- self._mediaSegmentRequest = null;
- if (isWaitingOnInitSegment) {
- self._initSegmentInfoRef.waitUntilDefined(continueToNextSegment, {
- clearSignal: canceller.signal
- });
- } else {
- continueToNextSegment();
- }
- }
- }, canceller.signal);
- request["catch"](function (error) {
- if (!isComplete) {
- isComplete = true;
- obs.error(error);
- }
- });
- self._mediaSegmentRequest = {
- segment: segment,
- priority: priority,
- request: request
- };
- return function () {
- self._mediaSegmentsAwaitingInitMetadata["delete"](segment.id);
- if (nextSegmentSubscription !== undefined) {
- nextSegmentSubscription.unsubscribe();
- }
- if (isComplete) {
- return;
- }
- isComplete = true;
- isWaitingOnInitSegment = false;
- canceller.cancel();
- };
- function emitChunk(parsed) {
- (0,assert/* default */.Z)(parsed.segmentType === "media", "Should have loaded a media segment.");
- obs.next((0,object_assign/* default */.Z)({}, parsed, {
- type: "parsed-media",
- segment: segment
- }));
- }
- function continueToNextSegment() {
- var lastQueue = self._downloadQueue.getValue().segmentQueue;
- if (lastQueue.length === 0) {
- obs.next({
- type: "end-of-queue",
- value: null
- });
- isComplete = true;
- obs.complete();
- return;
- } else if (lastQueue[0].segment.id === segment.id) {
- lastQueue.shift();
- }
- isComplete = true;
- nextSegmentSubscription = recursivelyRequestSegments(lastQueue[0]).subscribe(obs);
- }
- });
- }
- }
- /**
- * Internal logic performing initialization segment requests.
- * @param {Object} queuedInitSegment
- * @returns {Observable}
- */;
- _proto._requestInitSegment = function _requestInitSegment(queuedInitSegment) {
- var _this3 = this;
- if (queuedInitSegment === null) {
- this._initSegmentRequest = null;
- return empty/* EMPTY */.E;
- }
- /* eslint-disable-next-line @typescript-eslint/no-this-alias */
- var self = this;
- return new Observable/* Observable */.y(function (obs) {
- /** TaskCanceller linked to this Observable's lifecycle. */
- var canceller = new task_canceller/* default */.ZP();
- var segment = queuedInitSegment.segment,
- priority = queuedInitSegment.priority;
- var context = (0,object_assign/* default */.Z)({
- segment: segment
}, _this3._content);
/**
- * If `true` , the Observable has either errored, completed, or was
- * unsubscribed from.
+ * If `true` , the current task has either errored, finished, or was
+ * cancelled.
*/
var isComplete = false;
+ /**
+ * If true, we're currently waiting for the initialization segment to be
+ * parsed before parsing a received chunk.
+ */
+ var isWaitingOnInitSegment = false;
+ canceller.signal.register(function () {
+ _this3._mediaSegmentRequest = null;
+ if (isComplete) {
+ return;
+ }
+ if (_this3._mediaSegmentAwaitingInitMetadata === segment.id) {
+ _this3._mediaSegmentAwaitingInitMetadata = null;
+ }
+ isComplete = true;
+ isWaitingOnInitSegment = false;
+ });
+ var emitChunk = function emitChunk(parsed) {
+ (0,assert/* default */.Z)(parsed.segmentType === "media", "Should have loaded a media segment.");
+ _this3.trigger("parsedMediaSegment", (0,object_assign/* default */.Z)({}, parsed, {
+ segment: segment
+ }));
+ };
+ var continueToNextSegment = function continueToNextSegment() {
+ var lastQueue = _this3._downloadQueue.getValue().segmentQueue;
+ if (lastQueue.length === 0) {
+ isComplete = true;
+ _this3.trigger("emptyQueue", null);
+ return;
+ } else if (lastQueue[0].segment.id === segment.id) {
+ lastQueue.shift();
+ }
+ isComplete = true;
+ recursivelyRequestSegments(lastQueue[0]);
+ };
+ /** Scheduled actual segment request. */
var request = _this3._segmentFetcher.createRequest(context, priority, {
- onRetry: function onRetry(err) {
- obs.next({
- type: "retry",
- value: {
- segment: segment,
- error: err
- }
+ /**
+ * Callback called when the request has to be retried.
+ * @param {Error} error
+ */
+ onRetry: function onRetry(error) {
+ _this3.trigger("requestRetry", {
+ segment: segment,
+ error: error
});
},
+ /**
+ * Callback called when the request has to be interrupted and
+ * restarted later.
+ */
beforeInterrupted: function beforeInterrupted() {
- log/* default.info */.Z.info("Stream: init segment request interrupted temporarly.", segment.id);
- },
- beforeEnded: function beforeEnded() {
- self._initSegmentRequest = null;
- isComplete = true;
- obs.complete();
+ log/* default.info */.Z.info("Stream: segment request interrupted temporarly.", segment.id, segment.time);
},
+ /**
+ * Callback called when a decodable chunk of the segment is available.
+ * @param {Function} parse - Function allowing to parse the segment.
+ */
onChunk: function onChunk(parse) {
- var _a;
- var parsed = parse(undefined);
- (0,assert/* default */.Z)(parsed.segmentType === "init", "Should have loaded an init segment.");
- obs.next((0,object_assign/* default */.Z)({}, parsed, {
- type: "parsed-init",
- segment: segment
- }));
- if (parsed.segmentType === "init") {
- self._initSegmentInfoRef.setValue((_a = parsed.initTimescale) !== null && _a !== void 0 ? _a : null);
+ var initTimescale = _this3._initSegmentInfoRef.getValue();
+ if (initTimescale !== undefined) {
+ emitChunk(parse(initTimescale !== null && initTimescale !== void 0 ? initTimescale : undefined));
+ } else {
+ isWaitingOnInitSegment = true;
+ // We could also technically call `waitUntilDefined` in both cases,
+ // but I found it globally clearer to segregate the two cases,
+ // especially to always have a meaningful `isWaitingOnInitSegment`
+ // boolean which is a very important variable.
+ _this3._initSegmentInfoRef.waitUntilDefined(function (actualTimescale) {
+ emitChunk(parse(actualTimescale !== null && actualTimescale !== void 0 ? actualTimescale : undefined));
+ }, {
+ clearSignal: canceller.signal
+ });
}
},
+ /** Callback called after all chunks have been sent. */
onAllChunksReceived: function onAllChunksReceived() {
- obs.next({
- type: "end-of-segment",
- value: {
- segment: segment
- }
- });
+ if (!isWaitingOnInitSegment) {
+ _this3.trigger("fullyLoadedSegment", segment);
+ } else {
+ _this3._mediaSegmentAwaitingInitMetadata = segment.id;
+ _this3._initSegmentInfoRef.waitUntilDefined(function () {
+ _this3._mediaSegmentAwaitingInitMetadata = null;
+ isWaitingOnInitSegment = false;
+ _this3.trigger("fullyLoadedSegment", segment);
+ }, {
+ clearSignal: canceller.signal
+ });
+ }
+ },
+ /**
+ * Callback called right after the request ended but before the next
+ * requests are scheduled. It is used to schedule the next segment.
+ */
+ beforeEnded: function beforeEnded() {
+ unlinkCanceller();
+ _this3._mediaSegmentRequest = null;
+ if (isWaitingOnInitSegment) {
+ _this3._initSegmentInfoRef.waitUntilDefined(continueToNextSegment, {
+ clearSignal: canceller.signal
+ });
+ } else {
+ continueToNextSegment();
+ }
}
}, canceller.signal);
request["catch"](function (error) {
+ unlinkCanceller();
if (!isComplete) {
isComplete = true;
- obs.error(error);
+ _this3.stop();
+ _this3.trigger("error", error);
}
});
- _this3._initSegmentRequest = {
+ _this3._mediaSegmentRequest = {
segment: segment,
priority: priority,
- request: request
+ request: request,
+ canceller: canceller
};
- return function () {
- _this3._initSegmentRequest = null;
- if (isComplete) {
- return;
+ };
+ recursivelyRequestSegments(currentNeededSegment);
+ }
+ /**
+ * Internal logic performing initialization segment requests.
+ * @param {Object} queuedInitSegment
+ */;
+ _proto._restartInitSegmentDownloadingQueue = function _restartInitSegmentDownloadingQueue(queuedInitSegment) {
+ var _this4 = this;
+ if (this._currentCanceller !== null && this._currentCanceller.isUsed()) {
+ return;
+ }
+ if (this._initSegmentRequest !== null) {
+ this._initSegmentRequest.canceller.cancel();
+ }
+ if (queuedInitSegment === null) {
+ return;
+ }
+ var canceller = new task_canceller/* default */.ZP();
+ var unlinkCanceller = this._currentCanceller === null ? noop/* default */.Z : canceller.linkToSignal(this._currentCanceller.signal);
+ var segment = queuedInitSegment.segment,
+ priority = queuedInitSegment.priority;
+ var context = (0,object_assign/* default */.Z)({
+ segment: segment
+ }, this._content);
+ /**
+ * If `true` , the current task has either errored, finished, or was
+ * cancelled.
+ */
+ var isComplete = false;
+ var request = this._segmentFetcher.createRequest(context, priority, {
+ onRetry: function onRetry(err) {
+ _this4.trigger("requestRetry", {
+ segment: segment,
+ error: err
+ });
+ },
+ beforeInterrupted: function beforeInterrupted() {
+ log/* default.info */.Z.info("Stream: init segment request interrupted temporarly.", segment.id);
+ },
+ beforeEnded: function beforeEnded() {
+ unlinkCanceller();
+ _this4._initSegmentRequest = null;
+ isComplete = true;
+ },
+ onChunk: function onChunk(parse) {
+ var _a;
+ var parsed = parse(undefined);
+ (0,assert/* default */.Z)(parsed.segmentType === "init", "Should have loaded an init segment.");
+ _this4.trigger("parsedInitSegment", (0,object_assign/* default */.Z)({}, parsed, {
+ segment: segment
+ }));
+ if (parsed.segmentType === "init") {
+ _this4._initSegmentInfoRef.setValue((_a = parsed.initTimescale) !== null && _a !== void 0 ? _a : null);
}
+ },
+ onAllChunksReceived: function onAllChunksReceived() {
+ _this4.trigger("fullyLoadedSegment", segment);
+ }
+ }, canceller.signal);
+ request["catch"](function (error) {
+ unlinkCanceller();
+ if (!isComplete) {
isComplete = true;
- canceller.cancel();
- };
+ _this4.stop();
+ _this4.trigger("error", error);
+ }
});
+ canceller.signal.register(function () {
+ _this4._initSegmentRequest = null;
+ if (isComplete) {
+ return;
+ }
+ isComplete = true;
+ });
+ this._initSegmentRequest = {
+ segment: segment,
+ priority: priority,
+ request: request,
+ canceller: canceller
+ };
};
return DownloadingQueue;
-}();
+}(event_emitter/* default */.Z);
-;// CONCATENATED MODULE: ./src/core/stream/representation/check_for_discontinuity.ts
+;// CONCATENATED MODULE: ./src/core/stream/representation/utils/check_for_discontinuity.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -48270,7 +44286,7 @@ function getIndexOfLastChunkInPeriod(bufferedChunks, periodEnd) {
}
return null;
}
-;// CONCATENATED MODULE: ./src/core/stream/representation/get_needed_segments.ts
+;// CONCATENATED MODULE: ./src/core/stream/representation/utils/get_needed_segments.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -48286,7 +44302,6 @@ function getIndexOfLastChunkInPeriod(bufferedChunks, periodEnd) {
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-// eslint-disable-next-line max-len
@@ -48698,7 +44713,7 @@ function shouldReloadSegmentGCedAtTheEnd(segmentEntries, currentBufferedEnd) {
// issue. In that case, don't try to reload.
return Math.abs(prevBufferedEnd - lastBufferedEnd) > 0.01;
}
-;// CONCATENATED MODULE: ./src/core/stream/representation/get_segment_priority.ts
+;// CONCATENATED MODULE: ./src/core/stream/representation/utils/get_segment_priority.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -48738,7 +44753,7 @@ function getSegmentPriority(segmentTime, wantedStartTimestamp) {
}
return SEGMENT_PRIORITIES_STEPS.length;
}
-;// CONCATENATED MODULE: ./src/core/stream/representation/get_buffer_status.ts
+;// CONCATENATED MODULE: ./src/core/stream/representation/utils/get_buffer_status.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -48943,7 +44958,7 @@ function getPlayableBufferedSegments(neededRange, segmentInventory) {
}
return overlappingChunks;
}
-;// CONCATENATED MODULE: ./src/core/stream/representation/force_garbage_collection.ts
+;// CONCATENATED MODULE: ./src/core/stream/representation/utils/force_garbage_collection.ts
function force_garbage_collection_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = force_garbage_collection_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -49079,7 +45094,7 @@ function selectGCedRanges(position, buffered, gcGap) {
}
return cleanedupRanges;
}
-;// CONCATENATED MODULE: ./src/core/stream/representation/append_segment_to_buffer.ts
+;// CONCATENATED MODULE: ./src/core/stream/representation/utils/append_segment_to_buffer.ts
/**
@@ -49102,11 +45117,12 @@ function selectGCedRanges(position, buffered, gcGap) {
*/
+
/**
* Append a segment to the given segmentBuffer.
* If it leads to a QuotaExceededError, try to run our custom range
* _garbage collector_ then retry.
- * @param {Observable} playbackObserver
+ * @param {Object} playbackObserver
* @param {Object} segmentBuffer
* @param {Object} dataInfos
* @param {Object} cancellationSignal
@@ -49126,44 +45142,52 @@ function _appendSegmentToBuffer() {
_context.next = 3;
return segmentBuffer.pushChunk(dataInfos, cancellationSignal);
case 3:
- _context.next = 23;
+ _context.next = 27;
break;
case 5:
_context.prev = 5;
_context.t0 = _context["catch"](0);
+ if (!(cancellationSignal.isCancelled() && _context.t0 instanceof task_canceller/* CancellationError */.FU)) {
+ _context.next = 11;
+ break;
+ }
+ throw _context.t0;
+ case 11:
if (!(!(_context.t0 instanceof Error) || _context.t0.name !== "QuotaExceededError")) {
- _context.next = 10;
+ _context.next = 14;
break;
}
reason = _context.t0 instanceof Error ? _context.t0.toString() : "An unknown error happened when pushing content";
throw new media_error/* default */.Z("BUFFER_APPEND_ERROR", reason);
- case 10:
+ case 14:
_playbackObserver$get = playbackObserver.getReference().getValue(), position = _playbackObserver$get.position;
currentPos = (_a = position.pending) !== null && _a !== void 0 ? _a : position.last;
- _context.prev = 12;
- _context.next = 15;
+ _context.prev = 16;
+ _context.next = 19;
return forceGarbageCollection(currentPos, segmentBuffer, cancellationSignal);
- case 15:
- _context.next = 17;
+ case 19:
+ _context.next = 21;
return segmentBuffer.pushChunk(dataInfos, cancellationSignal);
- case 17:
- _context.next = 23;
+ case 21:
+ _context.next = 27;
break;
- case 19:
- _context.prev = 19;
- _context.t1 = _context["catch"](12);
+ case 23:
+ _context.prev = 23;
+ _context.t1 = _context["catch"](16);
_reason = _context.t1 instanceof Error ? _context.t1.toString() : "Could not clean the buffer";
throw new media_error/* default */.Z("BUFFER_FULL_ERROR", _reason);
- case 23:
+ case 27:
case "end":
return _context.stop();
}
}
- }, _callee, null, [[0, 5], [12, 19]]);
+ }, _callee, null, [[0, 5], [16, 23]]);
}));
return _appendSegmentToBuffer.apply(this, arguments);
}
-;// CONCATENATED MODULE: ./src/core/stream/representation/push_init_segment.ts
+;// CONCATENATED MODULE: ./src/core/stream/representation/utils/push_init_segment.ts
+
+
/**
* Copyright 2015 CANAL+ Group
*
@@ -49180,49 +45204,68 @@ function _appendSegmentToBuffer() {
* limitations under the License.
*/
-
-
-
-
/**
* Push the initialization segment to the SegmentBuffer.
- * The Observable returned:
- * - emit an event once the segment has been pushed.
- * - throws on Error.
* @param {Object} args
- * @returns {Observable}
+ * @param {Object} cancelSignal
+ * @returns {Promise}
*/
-function pushInitSegment(_ref) {
- var playbackObserver = _ref.playbackObserver,
- content = _ref.content,
- segment = _ref.segment,
- segmentData = _ref.segmentData,
- segmentBuffer = _ref.segmentBuffer;
- return (0,defer/* defer */.P)(function () {
- if (segmentData === null) {
- return empty/* EMPTY */.E;
- }
- var codec = content.representation.getMimeTypeString();
- var data = {
- initSegment: segmentData,
- chunk: null,
- timestampOffset: 0,
- appendWindow: [undefined, undefined],
- codec: codec
- };
- var canceller = new task_canceller/* default */.ZP();
- return fromCancellablePromise(canceller, function () {
- return appendSegmentToBuffer(playbackObserver, segmentBuffer, {
- data: data,
- inventoryInfos: null
- }, canceller.signal);
- }).pipe((0,map/* map */.U)(function () {
- var buffered = segmentBuffer.getBufferedRanges();
- return stream_events_generators/* default.addedSegment */.Z.addedSegment(content, segment, buffered, segmentData);
- }));
- });
+function pushInitSegment(_x, _x2) {
+ return _pushInitSegment.apply(this, arguments);
+}
+function _pushInitSegment() {
+ _pushInitSegment = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(_ref, cancelSignal) {
+ var playbackObserver, content, segment, segmentData, segmentBuffer, codec, data, buffered;
+ return regenerator_default().wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ playbackObserver = _ref.playbackObserver, content = _ref.content, segment = _ref.segment, segmentData = _ref.segmentData, segmentBuffer = _ref.segmentBuffer;
+ if (!(segmentData === null)) {
+ _context.next = 3;
+ break;
+ }
+ return _context.abrupt("return", null);
+ case 3:
+ if (!(cancelSignal.cancellationError !== null)) {
+ _context.next = 5;
+ break;
+ }
+ throw cancelSignal.cancellationError;
+ case 5:
+ codec = content.representation.getMimeTypeString();
+ data = {
+ initSegment: segmentData,
+ chunk: null,
+ timestampOffset: 0,
+ appendWindow: [undefined, undefined],
+ codec: codec
+ };
+ _context.next = 9;
+ return appendSegmentToBuffer(playbackObserver, segmentBuffer, {
+ data: data,
+ inventoryInfos: null
+ }, cancelSignal);
+ case 9:
+ buffered = segmentBuffer.getBufferedRanges();
+ return _context.abrupt("return", {
+ content: content,
+ segment: segment,
+ buffered: buffered,
+ segmentData: segmentData
+ });
+ case 11:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee);
+ }));
+ return _pushInitSegment.apply(this, arguments);
}
-;// CONCATENATED MODULE: ./src/core/stream/representation/push_media_segment.ts
+;// CONCATENATED MODULE: ./src/core/stream/representation/utils/push_media_segment.ts
+
+
/**
* Copyright 2015 CANAL+ Group
*
@@ -49241,75 +45284,84 @@ function pushInitSegment(_ref) {
-
-
-
-
/**
* Push a given media segment (non-init segment) to a SegmentBuffer.
- * The Observable returned:
- * - emit an event once the segment has been pushed.
- * - throws on Error.
* @param {Object} args
- * @returns {Observable}
+ * @param {Object} cancelSignal
+ * @returns {Promise}
*/
-function pushMediaSegment(_ref) {
- var playbackObserver = _ref.playbackObserver,
- content = _ref.content,
- initSegmentData = _ref.initSegmentData,
- parsedSegment = _ref.parsedSegment,
- segment = _ref.segment,
- segmentBuffer = _ref.segmentBuffer;
- return (0,defer/* defer */.P)(function () {
- var _a, _b;
- if (parsedSegment.chunkData === null) {
- return empty/* EMPTY */.E;
- }
- var chunkData = parsedSegment.chunkData,
- chunkInfos = parsedSegment.chunkInfos,
- chunkOffset = parsedSegment.chunkOffset,
- chunkSize = parsedSegment.chunkSize,
- appendWindow = parsedSegment.appendWindow;
- var codec = content.representation.getMimeTypeString();
- var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
- APPEND_WINDOW_SECURITIES = _config$getCurrent.APPEND_WINDOW_SECURITIES;
- // Cutting exactly at the start or end of the appendWindow can lead to
- // cases of infinite rebuffering due to how browser handle such windows.
- // To work-around that, we add a small offset before and after those.
- var safeAppendWindow = [appendWindow[0] !== undefined ? Math.max(0, appendWindow[0] - APPEND_WINDOW_SECURITIES.START) : undefined, appendWindow[1] !== undefined ? appendWindow[1] + APPEND_WINDOW_SECURITIES.END : undefined];
- var data = {
- initSegment: initSegmentData,
- chunk: chunkData,
- timestampOffset: chunkOffset,
- appendWindow: safeAppendWindow,
- codec: codec
- };
- var estimatedStart = (_a = chunkInfos === null || chunkInfos === void 0 ? void 0 : chunkInfos.time) !== null && _a !== void 0 ? _a : segment.time;
- var estimatedDuration = (_b = chunkInfos === null || chunkInfos === void 0 ? void 0 : chunkInfos.duration) !== null && _b !== void 0 ? _b : segment.duration;
- var estimatedEnd = estimatedStart + estimatedDuration;
- if (safeAppendWindow[0] !== undefined) {
- estimatedStart = Math.max(estimatedStart, safeAppendWindow[0]);
- }
- if (safeAppendWindow[1] !== undefined) {
- estimatedEnd = Math.min(estimatedEnd, safeAppendWindow[1]);
- }
- var inventoryInfos = (0,object_assign/* default */.Z)({
- segment: segment,
- chunkSize: chunkSize,
- start: estimatedStart,
- end: estimatedEnd
- }, content);
- var canceller = new task_canceller/* default */.ZP();
- return fromCancellablePromise(canceller, function () {
- return appendSegmentToBuffer(playbackObserver, segmentBuffer, {
- data: data,
- inventoryInfos: inventoryInfos
- }, canceller.signal);
- }).pipe((0,map/* map */.U)(function () {
- var buffered = segmentBuffer.getBufferedRanges();
- return stream_events_generators/* default.addedSegment */.Z.addedSegment(content, segment, buffered, chunkData);
- }));
- });
+function pushMediaSegment(_x, _x2) {
+ return _pushMediaSegment.apply(this, arguments);
+}
+function _pushMediaSegment() {
+ _pushMediaSegment = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(_ref, cancelSignal) {
+ var playbackObserver, content, initSegmentData, parsedSegment, segment, segmentBuffer, _a, _b, chunkData, chunkInfos, chunkOffset, chunkSize, appendWindow, codec, _config$getCurrent, APPEND_WINDOW_SECURITIES, safeAppendWindow, data, estimatedStart, estimatedDuration, estimatedEnd, inventoryInfos, buffered;
+ return regenerator_default().wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ playbackObserver = _ref.playbackObserver, content = _ref.content, initSegmentData = _ref.initSegmentData, parsedSegment = _ref.parsedSegment, segment = _ref.segment, segmentBuffer = _ref.segmentBuffer;
+ if (!(parsedSegment.chunkData === null)) {
+ _context.next = 3;
+ break;
+ }
+ return _context.abrupt("return", null);
+ case 3:
+ if (!(cancelSignal.cancellationError !== null)) {
+ _context.next = 5;
+ break;
+ }
+ throw cancelSignal.cancellationError;
+ case 5:
+ chunkData = parsedSegment.chunkData, chunkInfos = parsedSegment.chunkInfos, chunkOffset = parsedSegment.chunkOffset, chunkSize = parsedSegment.chunkSize, appendWindow = parsedSegment.appendWindow;
+ codec = content.representation.getMimeTypeString();
+ _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(), APPEND_WINDOW_SECURITIES = _config$getCurrent.APPEND_WINDOW_SECURITIES; // Cutting exactly at the start or end of the appendWindow can lead to
+ // cases of infinite rebuffering due to how browser handle such windows.
+ // To work-around that, we add a small offset before and after those.
+ safeAppendWindow = [appendWindow[0] !== undefined ? Math.max(0, appendWindow[0] - APPEND_WINDOW_SECURITIES.START) : undefined, appendWindow[1] !== undefined ? appendWindow[1] + APPEND_WINDOW_SECURITIES.END : undefined];
+ data = {
+ initSegment: initSegmentData,
+ chunk: chunkData,
+ timestampOffset: chunkOffset,
+ appendWindow: safeAppendWindow,
+ codec: codec
+ };
+ estimatedStart = (_a = chunkInfos === null || chunkInfos === void 0 ? void 0 : chunkInfos.time) !== null && _a !== void 0 ? _a : segment.time;
+ estimatedDuration = (_b = chunkInfos === null || chunkInfos === void 0 ? void 0 : chunkInfos.duration) !== null && _b !== void 0 ? _b : segment.duration;
+ estimatedEnd = estimatedStart + estimatedDuration;
+ if (safeAppendWindow[0] !== undefined) {
+ estimatedStart = Math.max(estimatedStart, safeAppendWindow[0]);
+ }
+ if (safeAppendWindow[1] !== undefined) {
+ estimatedEnd = Math.min(estimatedEnd, safeAppendWindow[1]);
+ }
+ inventoryInfos = (0,object_assign/* default */.Z)({
+ segment: segment,
+ chunkSize: chunkSize,
+ start: estimatedStart,
+ end: estimatedEnd
+ }, content);
+ _context.next = 18;
+ return appendSegmentToBuffer(playbackObserver, segmentBuffer, {
+ data: data,
+ inventoryInfos: inventoryInfos
+ }, cancelSignal);
+ case 18:
+ buffered = segmentBuffer.getBufferedRanges();
+ return _context.abrupt("return", {
+ content: content,
+ segment: segment,
+ buffered: buffered,
+ segmentData: chunkData
+ });
+ case 20:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee);
+ }));
+ return _pushMediaSegment.apply(this, arguments);
}
;// CONCATENATED MODULE: ./src/core/stream/representation/representation_stream.ts
/**
@@ -49345,54 +45397,79 @@ function pushMediaSegment(_ref) {
-
-
-
-
-
/**
- * Build up buffer for a single Representation.
+ * Perform the logic to load the right segments for the given Representation and
+ * push them to the given `SegmentBuffer`.
*
- * Download and push segments linked to the given Representation according
- * to what is already in the SegmentBuffer and where the playback currently is.
+ * In essence, this is the entry point of the core streaming logic of the
+ * RxPlayer, the one actually responsible for finding which are the current
+ * right segments to load, loading them, and pushing them so they can be decoded.
*
- * Multiple RepresentationStream observables can run on the same SegmentBuffer.
+ * Multiple RepresentationStream can run on the same SegmentBuffer.
* This allows for example smooth transitions between multiple periods.
*
- * @param {Object} args
- * @returns {Observable}
- */
-function RepresentationStream(_ref) {
+ * @param {Object} args - Various arguments allowing to know which segments to
+ * load, loading them and pushing them.
+ * You can check the corresponding type for more information.
+ * @param {Object} callbacks - The `RepresentationStream` relies on a system of
+ * callbacks that it will call on various events.
+ *
+ * Depending on the event, the caller may be supposed to perform actions to
+ * react upon some of them.
+ *
+ * This approach is taken instead of a more classical EventEmitter pattern to:
+ * - Allow callbacks to be called synchronously after the
+ * `RepresentationStream` is called.
+ * - Simplify bubbling events up, by just passing through callbacks
+ * - Force the caller to explicitely handle or not the different events.
+ *
+ * Callbacks may start being called immediately after the `RepresentationStream`
+ * call and may be called until either the `parentCancelSignal` argument is
+ * triggered, until the `terminating` callback has been triggered AND all loaded
+ * segments have been pushed, or until the `error` callback is called, whichever
+ * comes first.
+ * @param {Object} parentCancelSignal - `CancellationSignal` allowing, when
+ * triggered, to immediately stop all operations the `RepresentationStream` is
+ * doing.
+ */
+function RepresentationStream(_ref, callbacks, parentCancelSignal) {
var content = _ref.content,
options = _ref.options,
playbackObserver = _ref.playbackObserver,
segmentBuffer = _ref.segmentBuffer,
segmentFetcher = _ref.segmentFetcher,
- terminate$ = _ref.terminate$;
+ terminate = _ref.terminate;
var period = content.period,
adaptation = content.adaptation,
representation = content.representation;
- var bufferGoal$ = options.bufferGoal$,
- maxBufferSize$ = options.maxBufferSize$,
+ var bufferGoal = options.bufferGoal,
+ maxBufferSize = options.maxBufferSize,
drmSystemId = options.drmSystemId,
- fastSwitchThreshold$ = options.fastSwitchThreshold$;
+ fastSwitchThreshold = options.fastSwitchThreshold;
var bufferType = adaptation.type;
+ /** `TaskCanceller` stopping ALL operations performed by the `RepresentationStream` */
+ var globalCanceller = new task_canceller/* default */.ZP();
+ globalCanceller.linkToSignal(parentCancelSignal);
+ /**
+ * `TaskCanceller` allowing to only stop segment loading and checking operations.
+ * This allows to stop only tasks linked to network resource usage, which is
+ * often a limited resource, while still letting buffer operations to finish.
+ */
+ var segmentsLoadingCanceller = new task_canceller/* default */.ZP();
+ segmentsLoadingCanceller.linkToSignal(globalCanceller.signal);
/** Saved initialization segment state for this representation. */
var initSegmentState = {
segment: representation.index.getInitSegment(),
segmentData: null,
isLoaded: false
};
- /** Allows to manually re-check which segments are needed. */
- var reCheckNeededSegments$ = new Subject/* Subject */.x();
/** Emit the last scheduled downloading queue for segments. */
var lastSegmentQueue = (0,reference/* createSharedReference */.$l)({
initSegment: null,
segmentQueue: []
- });
+ }, segmentsLoadingCanceller.signal);
+ /** If `true`, the current Representation has a linked initialization segment. */
var hasInitSegment = initSegmentState.segment !== null;
- /** Will load every segments in `lastSegmentQueue` */
- var downloadingQueue = new DownloadingQueue(content, lastSegmentQueue, segmentFetcher, hasInitSegment);
if (!hasInitSegment) {
initSegmentState.segmentData = null;
initSegmentState.isLoaded = true;
@@ -49403,7 +45480,6 @@ function RepresentationStream(_ref) {
* Allows to avoid sending multiple times protection events.
*/
var hasSentEncryptionData = false;
- var encryptionEvent$ = empty/* EMPTY */.E;
// If the DRM system id is already known, and if we already have encryption data
// for it, we may not need to wait until the initialization segment is loaded to
// signal required protection data, thus performing License negotiations sooner
@@ -49414,25 +45490,86 @@ function RepresentationStream(_ref) {
if (encryptionData.length > 0 && encryptionData.every(function (e) {
return e.keyIds !== undefined;
})) {
- encryptionEvent$ = of.of.apply(void 0, encryptionData.map(function (d) {
- return stream_events_generators/* default.encryptionDataEncountered */.Z.encryptionDataEncountered(d, content);
- }));
hasSentEncryptionData = true;
+ callbacks.encryptionDataEncountered(encryptionData.map(function (d) {
+ return (0,object_assign/* default */.Z)({
+ content: content
+ }, d);
+ }));
+ if (globalCanceller.isUsed()) {
+ return; // previous callback has stopped everything by side-effect
+ }
}
}
- /** Observable loading and pushing segments scheduled through `lastSegmentQueue`. */
- var queue$ = downloadingQueue.start().pipe((0,mergeMap/* mergeMap */.z)(onQueueEvent));
- /** Observable emitting the stream "status" and filling `lastSegmentQueue`. */
- var status$ = combineLatest([playbackObserver.getReference().asObservable(), bufferGoal$, maxBufferSize$, terminate$.pipe((0,take/* take */.q)(1), (0,startWith/* startWith */.O)(null)), reCheckNeededSegments$.pipe((0,startWith/* startWith */.O)(undefined))]).pipe((0,withLatestFrom/* withLatestFrom */.M)(fastSwitchThreshold$), (0,mergeMap/* mergeMap */.z)(function (_ref2) {
- var _ref2$ = _ref2[0],
- observation = _ref2$[0],
- bufferGoal = _ref2$[1],
- maxBufferSize = _ref2$[2],
- terminate = _ref2$[3],
- fastSwitchThreshold = _ref2[1];
+ /** Will load every segments in `lastSegmentQueue` */
+ var downloadingQueue = new DownloadingQueue(content, lastSegmentQueue, segmentFetcher, hasInitSegment);
+ downloadingQueue.addEventListener("error", function (err) {
+ if (segmentsLoadingCanceller.signal.isCancelled()) {
+ return; // ignore post requests-cancellation loading-related errors,
+ }
+
+ globalCanceller.cancel(); // Stop every operations
+ callbacks.error(err);
+ });
+ downloadingQueue.addEventListener("parsedInitSegment", onParsedChunk);
+ downloadingQueue.addEventListener("parsedMediaSegment", onParsedChunk);
+ downloadingQueue.addEventListener("emptyQueue", checkStatus);
+ downloadingQueue.addEventListener("requestRetry", function (payload) {
+ callbacks.warning(payload.error);
+ if (segmentsLoadingCanceller.signal.isCancelled()) {
+ return; // If the previous callback led to loading operations being stopped, skip
+ }
+
+ var retriedSegment = payload.segment;
+ var index = representation.index;
+ if (index.isSegmentStillAvailable(retriedSegment) === false) {
+ checkStatus();
+ } else if (index.canBeOutOfSyncError(payload.error, retriedSegment)) {
+ callbacks.manifestMightBeOufOfSync();
+ }
+ });
+ downloadingQueue.addEventListener("fullyLoadedSegment", function (segment) {
+ segmentBuffer.endOfSegment((0,object_assign/* default */.Z)({
+ segment: segment
+ }, content), globalCanceller.signal)["catch"](onFatalBufferError);
+ });
+ downloadingQueue.start();
+ segmentsLoadingCanceller.signal.register(function () {
+ downloadingQueue.removeEventListener();
+ downloadingQueue.stop();
+ });
+ playbackObserver.listen(checkStatus, {
+ includeLastObservation: false,
+ clearSignal: segmentsLoadingCanceller.signal
+ });
+ bufferGoal.onUpdate(checkStatus, {
+ emitCurrentValue: false,
+ clearSignal: segmentsLoadingCanceller.signal
+ });
+ maxBufferSize.onUpdate(checkStatus, {
+ emitCurrentValue: false,
+ clearSignal: segmentsLoadingCanceller.signal
+ });
+ terminate.onUpdate(checkStatus, {
+ emitCurrentValue: false,
+ clearSignal: segmentsLoadingCanceller.signal
+ });
+ checkStatus();
+ return;
+ /**
+ * Produce a buffer status update synchronously on call, update the list
+ * of current segments to update and check various buffer and manifest related
+ * issues at the current time, calling the right callbacks if necessary.
+ */
+ function checkStatus() {
var _a, _b;
+ if (segmentsLoadingCanceller.isUsed()) {
+ return; // Stop all buffer status checking if load operations are stopped
+ }
+
+ var observation = playbackObserver.getReference().getValue();
var initialWantedTime = (_a = observation.position.pending) !== null && _a !== void 0 ? _a : observation.position.last;
- var status = getBufferStatus(content, initialWantedTime, playbackObserver, fastSwitchThreshold, bufferGoal, maxBufferSize, segmentBuffer);
+ var status = getBufferStatus(content, initialWantedTime, playbackObserver, fastSwitchThreshold.getValue(), bufferGoal.getValue(), maxBufferSize.getValue(), segmentBuffer);
var neededSegments = status.neededSegments;
var neededInitSegment = null;
// Add initialization segment if required
@@ -49455,19 +45592,22 @@ function RepresentationStream(_ref) {
priority: initSegmentPriority
};
}
- if (terminate === null) {
+ var terminateVal = terminate.getValue();
+ if (terminateVal === null) {
lastSegmentQueue.setValue({
initSegment: neededInitSegment,
segmentQueue: neededSegments
});
- } else if (terminate.urgent) {
+ } else if (terminateVal.urgent) {
log/* default.debug */.Z.debug("Stream: Urgent switch, terminate now.", bufferType);
lastSegmentQueue.setValue({
initSegment: null,
segmentQueue: []
});
lastSegmentQueue.finish();
- return (0,of.of)(stream_events_generators/* default.streamTerminating */.Z.streamTerminating());
+ segmentsLoadingCanceller.cancel();
+ callbacks.terminating();
+ return;
} else {
// Non-urgent termination wanted:
// End the download of the current media segment if pending and
@@ -49485,139 +45625,141 @@ function RepresentationStream(_ref) {
if (nextQueue.length === 0 && nextInit === null) {
log/* default.debug */.Z.debug("Stream: No request left, terminate", bufferType);
lastSegmentQueue.finish();
- return (0,of.of)(stream_events_generators/* default.streamTerminating */.Z.streamTerminating());
+ segmentsLoadingCanceller.cancel();
+ callbacks.terminating();
+ return;
}
}
- var bufferStatusEvt = (0,of.of)({
- type: "stream-status",
- value: {
- period: period,
- position: observation.position.last,
- bufferType: bufferType,
- imminentDiscontinuity: status.imminentDiscontinuity,
- hasFinishedLoading: status.hasFinishedLoading,
- neededSegments: status.neededSegments
- }
+ callbacks.streamStatusUpdate({
+ period: period,
+ position: observation.position.last,
+ bufferType: bufferType,
+ imminentDiscontinuity: status.imminentDiscontinuity,
+ isEmptyStream: false,
+ hasFinishedLoading: status.hasFinishedLoading,
+ neededSegments: status.neededSegments
});
- var bufferRemoval = empty/* EMPTY */.E;
+ if (segmentsLoadingCanceller.signal.isCancelled()) {
+ return; // previous callback has stopped loading operations by side-effect
+ }
+
var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
UPTO_CURRENT_POSITION_CLEANUP = _config$getCurrent.UPTO_CURRENT_POSITION_CLEANUP;
if (status.isBufferFull) {
var gcedPosition = Math.max(0, initialWantedTime - UPTO_CURRENT_POSITION_CLEANUP);
if (gcedPosition > 0) {
- var removalCanceller = new task_canceller/* default */.ZP();
- bufferRemoval = fromCancellablePromise(removalCanceller, function () {
- return segmentBuffer.removeBuffer(0, gcedPosition, removalCanceller.signal);
- }
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
- ).pipe((0,ignoreElements/* ignoreElements */.l)());
+ segmentBuffer.removeBuffer(0, gcedPosition, globalCanceller.signal)["catch"](onFatalBufferError);
}
}
- return status.shouldRefreshManifest ? (0,concat/* concat */.z)((0,of.of)(stream_events_generators/* default.needsManifestRefresh */.Z.needsManifestRefresh()), bufferStatusEvt, bufferRemoval) : (0,concat/* concat */.z)(bufferStatusEvt, bufferRemoval);
- }), takeWhile(function (e) {
- return e.type !== "stream-terminating";
- }, true));
- return (0,merge/* merge */.T)(status$, queue$, encryptionEvent$).pipe((0,share/* share */.B)());
- /**
- * React to event from the `DownloadingQueue`.
- * @param {Object} evt
- * @returns {Observable}
- */
- function onQueueEvent(evt) {
- switch (evt.type) {
- case "retry":
- return (0,concat/* concat */.z)((0,of.of)({
- type: "warning",
- value: evt.value.error
- }), (0,defer/* defer */.P)(function () {
- var retriedSegment = evt.value.segment;
- var index = representation.index;
- if (index.isSegmentStillAvailable(retriedSegment) === false) {
- reCheckNeededSegments$.next();
- } else if (index.canBeOutOfSyncError(evt.value.error, retriedSegment)) {
- return (0,of.of)(stream_events_generators/* default.manifestMightBeOufOfSync */.Z.manifestMightBeOufOfSync());
- }
- return empty/* EMPTY */.E; // else, ignore.
- }));
-
- case "parsed-init":
- case "parsed-media":
- return onParsedChunk(evt);
- case "end-of-segment":
- {
- var segment = evt.value.segment;
- var endOfSegmentCanceller = new task_canceller/* default */.ZP();
- return fromCancellablePromise(endOfSegmentCanceller, function () {
- return segmentBuffer.endOfSegment((0,object_assign/* default */.Z)({
- segment: segment
- }, content), endOfSegmentCanceller.signal);
- })
- // NOTE As of now (RxJS 7.4.0), RxJS defines `ignoreElements` default
- // first type parameter as `any` instead of the perfectly fine `unknown`,
- // leading to linter issues, as it forbids the usage of `any`.
- // This is why we're disabling the eslint rule.
- /* eslint-disable-next-line @typescript-eslint/no-unsafe-argument */.pipe((0,ignoreElements/* ignoreElements */.l)());
- }
- case "end-of-queue":
- reCheckNeededSegments$.next();
- return empty/* EMPTY */.E;
- default:
- (0,assert_unreachable/* default */.Z)(evt);
+ if (status.shouldRefreshManifest) {
+ callbacks.needsManifestRefresh();
}
}
/**
* Process a chunk that has just been parsed by pushing it to the
* SegmentBuffer and emitting the right events.
* @param {Object} evt
- * @returns {Observable}
*/
function onParsedChunk(evt) {
+ if (globalCanceller.isUsed()) {
+ // We should not do anything with segments if the `RepresentationStream`
+ // is not running anymore.
+ return;
+ }
if (evt.segmentType === "init") {
- next_tick_default()(function () {
- reCheckNeededSegments$.next();
- });
initSegmentState.segmentData = evt.initializationData;
initSegmentState.isLoaded = true;
// Now that the initialization segment has been parsed - which may have
// included encryption information - take care of the encryption event
// if not already done.
- var allEncryptionData = representation.getAllEncryptionData();
- var initEncEvt$ = !hasSentEncryptionData && allEncryptionData.length > 0 ? of.of.apply(void 0, allEncryptionData.map(function (p) {
- return stream_events_generators/* default.encryptionDataEncountered */.Z.encryptionDataEncountered(p, content);
- })) : empty/* EMPTY */.E;
- var pushEvent$ = pushInitSegment({
+ if (!hasSentEncryptionData) {
+ var allEncryptionData = representation.getAllEncryptionData();
+ if (allEncryptionData.length > 0) {
+ callbacks.encryptionDataEncountered(allEncryptionData.map(function (p) {
+ return (0,object_assign/* default */.Z)({
+ content: content
+ }, p);
+ }));
+ }
+ }
+ pushInitSegment({
playbackObserver: playbackObserver,
content: content,
segment: evt.segment,
segmentData: evt.initializationData,
segmentBuffer: segmentBuffer
- });
- return (0,merge/* merge */.T)(initEncEvt$, pushEvent$);
+ }, globalCanceller.signal).then(function (result) {
+ if (result !== null) {
+ callbacks.addedSegment(result);
+ }
+ })["catch"](onFatalBufferError);
+ // Sometimes the segment list is only known once the initialization segment
+ // is parsed. Thus we immediately re-check if there's new segments to load.
+ checkStatus();
} else {
var inbandEvents = evt.inbandEvents,
needsManifestRefresh = evt.needsManifestRefresh,
protectionDataUpdate = evt.protectionDataUpdate;
// TODO better handle use cases like key rotation by not always grouping
// every protection data together? To check.
- var segmentEncryptionEvent$ = protectionDataUpdate && !hasSentEncryptionData ? of.of.apply(void 0, representation.getAllEncryptionData().map(function (p) {
- return stream_events_generators/* default.encryptionDataEncountered */.Z.encryptionDataEncountered(p, content);
- })) : empty/* EMPTY */.E;
- var manifestRefresh$ = needsManifestRefresh === true ? (0,of.of)(stream_events_generators/* default.needsManifestRefresh */.Z.needsManifestRefresh()) : empty/* EMPTY */.E;
- var inbandEvents$ = inbandEvents !== undefined && inbandEvents.length > 0 ? (0,of.of)({
- type: "inband-events",
- value: inbandEvents
- }) : empty/* EMPTY */.E;
+ if (!hasSentEncryptionData && protectionDataUpdate) {
+ var _allEncryptionData = representation.getAllEncryptionData();
+ if (_allEncryptionData.length > 0) {
+ callbacks.encryptionDataEncountered(_allEncryptionData.map(function (p) {
+ return (0,object_assign/* default */.Z)({
+ content: content
+ }, p);
+ }));
+ if (globalCanceller.isUsed()) {
+ return; // previous callback has stopped everything by side-effect
+ }
+ }
+ }
+
+ if (needsManifestRefresh === true) {
+ callbacks.needsManifestRefresh();
+ if (globalCanceller.isUsed()) {
+ return; // previous callback has stopped everything by side-effect
+ }
+ }
+
+ if (inbandEvents !== undefined && inbandEvents.length > 0) {
+ callbacks.inbandEvent(inbandEvents);
+ if (globalCanceller.isUsed()) {
+ return; // previous callback has stopped everything by side-effect
+ }
+ }
+
var initSegmentData = initSegmentState.segmentData;
- var pushMediaSegment$ = pushMediaSegment({
+ pushMediaSegment({
playbackObserver: playbackObserver,
content: content,
initSegmentData: initSegmentData,
parsedSegment: evt,
segment: evt.segment,
segmentBuffer: segmentBuffer
- });
- return (0,concat/* concat */.z)(segmentEncryptionEvent$, manifestRefresh$, inbandEvents$, pushMediaSegment$);
+ }, globalCanceller.signal).then(function (result) {
+ if (result !== null) {
+ callbacks.addedSegment(result);
+ }
+ })["catch"](onFatalBufferError);
+ }
+ }
+ /**
+ * Handle Buffer-related fatal errors by cancelling everything the
+ * `RepresentationStream` is doing and calling the error callback with the
+ * corresponding error.
+ * @param {*} err
+ */
+ function onFatalBufferError(err) {
+ if (globalCanceller.isUsed() && err instanceof task_canceller/* CancellationError */.FU) {
+ // The error is linked to cancellation AND we explicitely cancelled buffer
+ // operations.
+ // We can thus ignore it, it is very unlikely to lead to true buffer issues.
+ return;
}
+ globalCanceller.cancel();
+ callbacks.error(err);
}
}
;// CONCATENATED MODULE: ./src/core/stream/representation/index.ts
@@ -49637,8 +45779,9 @@ function RepresentationStream(_ref) {
* limitations under the License.
*/
+
/* harmony default export */ var stream_representation = (RepresentationStream);
-;// CONCATENATED MODULE: ./src/core/stream/adaptation/create_representation_estimator.ts
+;// CONCATENATED MODULE: ./src/core/stream/adaptation/utils/create_representation_estimator.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -49677,7 +45820,7 @@ function RepresentationStream(_ref) {
function getRepresentationEstimate(content, representationEstimator, currentRepresentation, playbackObserver, onFatalError, cancellationSignal) {
var manifest = content.manifest,
adaptation = content.adaptation;
- var representations = (0,reference/* default */.ZP)([]);
+ var representations = (0,reference/* default */.ZP)([], cancellationSignal);
updateRepresentationsReference();
manifest.addEventListener("decipherabilityUpdate", updateRepresentationsReference);
var unregisterCleanUp = cancellationSignal.register(cleanUp);
@@ -49710,7 +45853,6 @@ function getRepresentationEstimate(content, representationEstimator, currentRepr
/** Clean-up all resources taken here. */
function cleanUp() {
manifest.removeEventListener("decipherabilityUpdate", updateRepresentationsReference);
- representations.finish();
// check to protect against the case where it is not yet defined.
if (typeof unregisterCleanUp !== "undefined") {
unregisterCleanUp();
@@ -49733,16 +45875,6 @@ function getRepresentationEstimate(content, representationEstimator, currentRepr
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
- * This file allows to create `AdaptationStream`s.
- *
- * An `AdaptationStream` downloads and push segment for a single Adaptation
- * (e.g. a single audio, video or text track).
- * It chooses which Representation to download mainly thanks to the
- * IRepresentationEstimator, and orchestrates a RepresentationStream,
- * which will download and push segments corresponding to a chosen
- * Representation.
- */
@@ -49755,20 +45887,36 @@ function getRepresentationEstimate(content, representationEstimator, currentRepr
/**
- * Create new AdaptationStream Observable, which task will be to download the
- * media data for a given Adaptation (i.e. "track").
+ * Create new `AdaptationStream` whose task will be to download the media data
+ * for a given Adaptation (i.e. "track").
*
* It will rely on the IRepresentationEstimator to choose at any time the
* best Representation for this Adaptation and then run the logic to download
* and push the corresponding segments in the SegmentBuffer.
*
- * After being subscribed to, it will start running and will emit various events
- * to report its current status.
- *
- * @param {Object} args
- * @returns {Observable}
- */
-function AdaptationStream(_ref) {
+ * @param {Object} args - Various arguments allowing the `AdaptationStream` to
+ * determine which Representation to choose and which segments to load from it.
+ * You can check the corresponding type for more information.
+ * @param {Object} callbacks - The `AdaptationStream` relies on a system of
+ * callbacks that it will call on various events.
+ *
+ * Depending on the event, the caller may be supposed to perform actions to
+ * react upon some of them.
+ *
+ * This approach is taken instead of a more classical EventEmitter pattern to:
+ * - Allow callbacks to be called synchronously after the
+ * `AdaptationStream` is called.
+ * - Simplify bubbling events up, by just passing through callbacks
+ * - Force the caller to explicitely handle or not the different events.
+ *
+ * Callbacks may start being called immediately after the `AdaptationStream`
+ * call and may be called until either the `parentCancelSignal` argument is
+ * triggered, or until the `error` callback is called, whichever comes first.
+ * @param {Object} parentCancelSignal - `CancellationSignal` allowing, when
+ * triggered, to immediately stop all operations the `AdaptationStream` is
+ * doing.
+ */
+function AdaptationStream(_ref, callbacks, parentCancelSignal) {
var playbackObserver = _ref.playbackObserver,
content = _ref.content,
options = _ref.options,
@@ -49781,6 +45929,9 @@ function AdaptationStream(_ref) {
var manifest = content.manifest,
period = content.period,
adaptation = content.adaptation;
+ /** Allows to cancel everything the `AdaptationStream` is doing. */
+ var adapStreamCanceller = new task_canceller/* default */.ZP();
+ adapStreamCanceller.linkToSignal(parentCancelSignal);
/**
* The buffer goal ratio base itself on the value given by `wantedBufferAhead`
* to determine a more dynamic buffer goal for a given Representation.
@@ -49789,14 +45940,16 @@ function AdaptationStream(_ref) {
* buffering and tells us that we should try to bufferize less data :
* https://developers.google.com/web/updates/2017/10/quotaexceedederror
*/
- var bufferGoalRatioMap = {};
- var currentRepresentation = (0,reference/* createSharedReference */.$l)(null);
- /** Errors when the adaptive logic fails with an error. */
- var abrErrorSubject = new Subject/* Subject */.x();
- var adaptiveCanceller = new task_canceller/* default */.ZP();
+ var bufferGoalRatioMap = new Map();
+ /**
+ * Emit the currently chosen `Representation`.
+ * `null` if no Representation is chosen for now.
+ */
+ var currentRepresentation = (0,reference/* createSharedReference */.$l)(null, adapStreamCanceller.signal);
var _createRepresentation = getRepresentationEstimate(content, representationEstimator, currentRepresentation, playbackObserver, function (err) {
- abrErrorSubject.error(err);
- }, adaptiveCanceller.signal),
+ adapStreamCanceller.cancel();
+ callbacks.error(err);
+ }, adapStreamCanceller.signal),
estimateRef = _createRepresentation.estimateRef,
abrCallbacks = _createRepresentation.abrCallbacks;
/** Allows the `RepresentationStream` to easily fetch media segments. */
@@ -49808,85 +45961,111 @@ function AdaptationStream(_ref) {
onMetrics: abrCallbacks.metrics
});
/* eslint-enable @typescript-eslint/unbound-method */
- /**
- * Stores the last estimate emitted through the `abrEstimate$` Observable,
- * starting with `null`.
- * This allows to easily rely on that value in inner Observables which might also
- * need the last already-considered value.
- */
- var lastEstimate = (0,reference/* createSharedReference */.$l)(null);
- /** Emits abr estimates on Subscription. */
- var abrEstimate$ = estimateRef.asObservable().pipe((0,tap/* tap */.b)(function (estimate) {
- lastEstimate.setValue(estimate);
- }), (0,defer_subscriptions/* default */.Z)(), (0,share/* share */.B)());
+ /** Stores the last emitted bitrate. */
+ var previousBitrate;
/** Emit at each bitrate estimate done by the IRepresentationEstimator. */
- var bitrateEstimate$ = abrEstimate$.pipe((0,filter/* filter */.h)(function (_ref2) {
+ estimateRef.onUpdate(function (_ref2) {
var bitrate = _ref2.bitrate;
- return bitrate != null;
- }), distinctUntilChanged(function (old, current) {
- return old.bitrate === current.bitrate;
- }), (0,map/* map */.U)(function (_ref3) {
- var bitrate = _ref3.bitrate;
+ if (bitrate === undefined) {
+ return;
+ }
+ if (bitrate === previousBitrate) {
+ return;
+ }
+ previousBitrate = bitrate;
log/* default.debug */.Z.debug("Stream: new " + adaptation.type + " bitrate estimate", bitrate);
- return stream_events_generators/* default.bitrateEstimationChange */.Z.bitrateEstimationChange(adaptation.type, bitrate);
- }));
- /** Recursively create `RepresentationStream`s according to the last estimate. */
- var representationStreams$ = abrEstimate$.pipe(exhaustMap(function (estimate, i) {
- return recursivelyCreateRepresentationStreams(estimate, i === 0);
- }));
- return (0,merge/* merge */.T)(abrErrorSubject, representationStreams$, bitrateEstimate$,
- // Cancel adaptive logic on unsubscription
- new Observable/* Observable */.y(function () {
- return function () {
- return adaptiveCanceller.cancel();
- };
- }));
+ callbacks.bitrateEstimationChange({
+ type: adaptation.type,
+ bitrate: bitrate
+ });
+ }, {
+ emitCurrentValue: true,
+ clearSignal: adapStreamCanceller.signal
+ });
+ recursivelyCreateRepresentationStreams(true);
/**
- * Create `RepresentationStream`s starting with the Representation indicated in
- * `fromEstimate` argument.
+ * Create `RepresentationStream`s starting with the Representation of the last
+ * estimate performed.
* Each time a new estimate is made, this function will create a new
* `RepresentationStream` corresponding to that new estimate.
- * @param {Object} fromEstimate - The first estimate we should start with
* @param {boolean} isFirstEstimate - Whether this is the first time we're
- * creating a RepresentationStream in the corresponding `AdaptationStream`.
+ * creating a `RepresentationStream` in the corresponding `AdaptationStream`.
* This is important because manual quality switches might need a full reload
* of the MediaSource _except_ if we are talking about the first quality chosen.
- * @returns {Observable}
*/
- function recursivelyCreateRepresentationStreams(fromEstimate, isFirstEstimate) {
- var representation = fromEstimate.representation;
+ function recursivelyCreateRepresentationStreams(isFirstEstimate) {
+ /**
+ * `TaskCanceller` triggered when the current `RepresentationStream` is
+ * terminating and as such the next one might be immediately created
+ * recursively.
+ */
+ var repStreamTerminatingCanceller = new task_canceller/* default */.ZP();
+ repStreamTerminatingCanceller.linkToSignal(adapStreamCanceller.signal);
+ var _estimateRef$getValue = estimateRef.getValue(),
+ representation = _estimateRef$getValue.representation,
+ manual = _estimateRef$getValue.manual;
+ if (representation === null) {
+ return;
+ }
// A manual bitrate switch might need an immediate feedback.
// To do that properly, we need to reload the MediaSource
- if (directManualBitrateSwitching && fromEstimate.manual && !isFirstEstimate) {
+ if (directManualBitrateSwitching && manual && !isFirstEstimate) {
var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
DELTA_POSITION_AFTER_RELOAD = _config$getCurrent.DELTA_POSITION_AFTER_RELOAD;
- return reloadAfterSwitch(period, adaptation.type, playbackObserver, DELTA_POSITION_AFTER_RELOAD.bitrateSwitch);
+ // We begin by scheduling a micro-task to reduce the possibility of race
+ // conditions where the inner logic would be called synchronously before
+ // the next observation (which may reflect very different playback conditions)
+ // is actually received.
+ return next_tick_default()(function () {
+ playbackObserver.listen(function (observation) {
+ var _a, _b;
+ var _estimateRef$getValue2 = estimateRef.getValue(),
+ newManual = _estimateRef$getValue2.manual;
+ if (!newManual) {
+ return;
+ }
+ var currentTime = playbackObserver.getCurrentTime();
+ var pos = currentTime + DELTA_POSITION_AFTER_RELOAD.bitrateSwitch;
+ // Bind to Period start and end
+ var position = Math.min(Math.max(period.start, pos), (_a = period.end) !== null && _a !== void 0 ? _a : Infinity);
+ var autoPlay = !((_b = observation.paused.pending) !== null && _b !== void 0 ? _b : playbackObserver.getIsPaused());
+ return callbacks.waitingMediaSourceReload({
+ bufferType: adaptation.type,
+ period: period,
+ position: position,
+ autoPlay: autoPlay
+ });
+ }, {
+ includeLastObservation: true,
+ clearSignal: repStreamTerminatingCanceller.signal
+ });
+ });
}
/**
* Emit when the current RepresentationStream should be terminated to make
* place for a new one (e.g. when switching quality).
*/
- var terminateCurrentStream$ = lastEstimate.asObservable().pipe((0,filter/* filter */.h)(function (newEstimate) {
- return newEstimate === null || newEstimate.representation.id !== representation.id || newEstimate.manual && !fromEstimate.manual;
- }), (0,take/* take */.q)(1), (0,map/* map */.U)(function (newEstimate) {
- if (newEstimate === null) {
- log/* default.info */.Z.info("Stream: urgent Representation termination", adaptation.type);
- return {
- urgent: true
- };
+ var terminateCurrentStream = (0,reference/* createSharedReference */.$l)(null, repStreamTerminatingCanceller.signal);
+ /** Allows to stop listening to estimateRef on the following line. */
+ estimateRef.onUpdate(function (estimate) {
+ if (estimate.representation === null || estimate.representation.id === representation.id) {
+ return;
}
- if (newEstimate.urgent) {
+ if (estimate.urgent) {
log/* default.info */.Z.info("Stream: urgent Representation switch", adaptation.type);
- return {
+ return terminateCurrentStream.setValue({
urgent: true
- };
+ });
} else {
log/* default.info */.Z.info("Stream: slow Representation switch", adaptation.type);
- return {
+ return terminateCurrentStream.setValue({
urgent: false
- };
+ });
}
- }));
+ }, {
+ clearSignal: repStreamTerminatingCanceller.signal,
+ emitCurrentValue: true
+ });
/**
* "Fast-switching" is a behavior allowing to replace low-quality segments
* (i.e. with a low bitrate) with higher-quality segments (higher bitrate) in
@@ -49898,81 +46077,139 @@ function AdaptationStream(_ref) {
* Set to `undefined` to indicate that there's no threshold (anything can be
* replaced by higher-quality segments).
*/
- var fastSwitchThreshold$ = !options.enableFastSwitching ? (0,of.of)(0) :
- // Do not fast-switch anything
- lastEstimate.asObservable().pipe((0,map/* map */.U)(function (estimate) {
- return estimate === null ? undefined : estimate.knownStableBitrate;
- }), distinctUntilChanged());
- var representationChange$ = (0,of.of)(stream_events_generators/* default.representationChange */.Z.representationChange(adaptation.type, period, representation));
- return (0,concat/* concat */.z)(representationChange$, createRepresentationStream(representation, terminateCurrentStream$, fastSwitchThreshold$)).pipe((0,tap/* tap */.b)(function (evt) {
- if (evt.type === "added-segment") {
- abrCallbacks.addedSegment(evt.value);
- }
- if (evt.type === "representationChange") {
- currentRepresentation.setValue(evt.value.representation);
- }
- }), (0,mergeMap/* mergeMap */.z)(function (evt) {
- if (evt.type === "stream-terminating") {
- var estimate = lastEstimate.getValue();
- if (estimate === null) {
- return empty/* EMPTY */.E;
- }
- return recursivelyCreateRepresentationStreams(estimate, false);
- }
- return (0,of.of)(evt);
- }));
+ var fastSwitchThreshold = (0,reference/* createSharedReference */.$l)(0);
+ if (options.enableFastSwitching) {
+ estimateRef.onUpdate(function (estimate) {
+ fastSwitchThreshold.setValueIfChanged(estimate === null || estimate === void 0 ? void 0 : estimate.knownStableBitrate);
+ }, {
+ clearSignal: repStreamTerminatingCanceller.signal,
+ emitCurrentValue: true
+ });
+ }
+ var repInfo = {
+ type: adaptation.type,
+ period: period,
+ representation: representation
+ };
+ currentRepresentation.setValue(representation);
+ if (adapStreamCanceller.isUsed()) {
+ return; // previous callback has stopped everything by side-effect
+ }
+
+ callbacks.representationChange(repInfo);
+ if (adapStreamCanceller.isUsed()) {
+ return; // previous callback has stopped everything by side-effect
+ }
+
+ var representationStreamCallbacks = {
+ streamStatusUpdate: callbacks.streamStatusUpdate,
+ encryptionDataEncountered: callbacks.encryptionDataEncountered,
+ manifestMightBeOufOfSync: callbacks.manifestMightBeOufOfSync,
+ needsManifestRefresh: callbacks.needsManifestRefresh,
+ inbandEvent: callbacks.inbandEvent,
+ warning: callbacks.warning,
+ error: function error(err) {
+ adapStreamCanceller.cancel();
+ callbacks.error(err);
+ },
+ addedSegment: function addedSegment(segmentInfo) {
+ abrCallbacks.addedSegment(segmentInfo);
+ if (adapStreamCanceller.isUsed()) {
+ return;
+ }
+ callbacks.addedSegment(segmentInfo);
+ },
+ terminating: function terminating() {
+ if (repStreamTerminatingCanceller.isUsed()) {
+ return; // Already handled
+ }
+
+ repStreamTerminatingCanceller.cancel();
+ return recursivelyCreateRepresentationStreams(false);
+ }
+ };
+ createRepresentationStream(representation, terminateCurrentStream, fastSwitchThreshold, representationStreamCallbacks);
}
/**
- * Create and returns a new RepresentationStream Observable, linked to the
+ * Create and returns a new `RepresentationStream`, linked to the
* given Representation.
- * @param {Representation} representation
- * @returns {Observable}
- */
- function createRepresentationStream(representation, terminateCurrentStream$, fastSwitchThreshold$) {
- return (0,defer/* defer */.P)(function () {
- var oldBufferGoalRatio = bufferGoalRatioMap[representation.id];
- var bufferGoalRatio = oldBufferGoalRatio != null ? oldBufferGoalRatio : 1;
- bufferGoalRatioMap[representation.id] = bufferGoalRatio;
- var bufferGoal$ = wantedBufferAhead.asObservable().pipe((0,map/* map */.U)(function (wba) {
- return wba * bufferGoalRatio;
- }));
- // eslint-disable-next-line max-len
- var maxBufferSize$ = adaptation.type === "video" ? maxVideoBufferSize.asObservable() : (0,of.of)(Infinity);
- log/* default.info */.Z.info("Stream: changing representation", adaptation.type, representation.id, representation.bitrate);
- return stream_representation({
- playbackObserver: playbackObserver,
- content: {
- representation: representation,
- adaptation: adaptation,
- period: period,
- manifest: manifest
- },
- segmentBuffer: segmentBuffer,
- segmentFetcher: segmentFetcher,
- terminate$: terminateCurrentStream$,
- options: {
- bufferGoal$: bufferGoal$,
- maxBufferSize$: maxBufferSize$,
- drmSystemId: options.drmSystemId,
- fastSwitchThreshold$: fastSwitchThreshold$
- }
- }).pipe((0,catchError/* catchError */.K)(function (err) {
+ * @param {Object} representation
+ * @param {Object} terminateCurrentStream
+ * @param {Object} fastSwitchThreshold
+ * @param {Object} representationStreamCallbacks
+ */
+ function createRepresentationStream(representation, terminateCurrentStream, fastSwitchThreshold, representationStreamCallbacks) {
+ /**
+ * `TaskCanceller` triggered when the `RepresentationStream` calls its
+ * `terminating` callback.
+ */
+ var terminatingRepStreamCanceller = new task_canceller/* default */.ZP();
+ terminatingRepStreamCanceller.linkToSignal(adapStreamCanceller.signal);
+ var bufferGoal = (0,reference/* createMappedReference */.lR)(wantedBufferAhead, function (prev) {
+ return prev * getBufferGoalRatio(representation);
+ }, terminatingRepStreamCanceller.signal);
+ var maxBufferSize = adaptation.type === "video" ? maxVideoBufferSize : (0,reference/* createSharedReference */.$l)(Infinity);
+ log/* default.info */.Z.info("Stream: changing representation", adaptation.type, representation.id, representation.bitrate);
+ var updatedCallbacks = (0,object_assign/* default */.Z)({}, representationStreamCallbacks, {
+ error: function error(err) {
+ var _a;
var formattedError = (0,format_error/* default */.Z)(err, {
defaultCode: "NONE",
defaultReason: "Unknown `RepresentationStream` error"
});
- if (formattedError.code === "BUFFER_FULL_ERROR") {
+ if (formattedError.code !== "BUFFER_FULL_ERROR") {
+ representationStreamCallbacks.error(err);
+ } else {
var wba = wantedBufferAhead.getValue();
- var lastBufferGoalRatio = bufferGoalRatio;
- if (lastBufferGoalRatio <= 0.25 || wba * lastBufferGoalRatio <= 2) {
+ var lastBufferGoalRatio = (_a = bufferGoalRatioMap.get(representation.id)) !== null && _a !== void 0 ? _a : 1;
+ // 70%, 49%, 34.3%, 24%, 16.81%, 11.76%, 8.24% and 5.76%
+ var newBufferGoalRatio = lastBufferGoalRatio * 0.7;
+ if (newBufferGoalRatio <= 0.05 || wba * newBufferGoalRatio <= 2) {
throw formattedError;
}
- bufferGoalRatioMap[representation.id] = lastBufferGoalRatio - 0.25;
- return createRepresentationStream(representation, terminateCurrentStream$, fastSwitchThreshold$);
+ bufferGoalRatioMap.set(representation.id, newBufferGoalRatio);
+ // We wait 4 seconds to let the situation evolve by itself before
+ // retrying loading segments with a lower buffer goal
+ (0,cancellable_sleep/* default */.Z)(4000, adapStreamCanceller.signal).then(function () {
+ return createRepresentationStream(representation, terminateCurrentStream, fastSwitchThreshold, representationStreamCallbacks);
+ })["catch"](noop/* default */.Z);
}
- throw formattedError;
- }));
+ },
+ terminating: function terminating() {
+ terminatingRepStreamCanceller.cancel();
+ representationStreamCallbacks.terminating();
+ }
});
+ stream_representation({
+ playbackObserver: playbackObserver,
+ content: {
+ representation: representation,
+ adaptation: adaptation,
+ period: period,
+ manifest: manifest
+ },
+ segmentBuffer: segmentBuffer,
+ segmentFetcher: segmentFetcher,
+ terminate: terminateCurrentStream,
+ options: {
+ bufferGoal: bufferGoal,
+ maxBufferSize: maxBufferSize,
+ drmSystemId: options.drmSystemId,
+ fastSwitchThreshold: fastSwitchThreshold
+ }
+ }, updatedCallbacks, adapStreamCanceller.signal);
+ }
+ /**
+ * @param {Object} representation
+ * @returns {number}
+ */
+ function getBufferGoalRatio(representation) {
+ var oldBufferGoalRatio = bufferGoalRatioMap.get(representation.id);
+ var bufferGoalRatio = oldBufferGoalRatio !== undefined ? oldBufferGoalRatio : 1;
+ if (oldBufferGoalRatio === undefined) {
+ bufferGoalRatioMap.set(representation.id, bufferGoalRatio);
+ }
+ return bufferGoalRatio;
}
}
;// CONCATENATED MODULE: ./src/core/stream/adaptation/index.ts
@@ -49992,63 +46229,8 @@ function AdaptationStream(_ref) {
* limitations under the License.
*/
-/* harmony default export */ var stream_adaptation = (AdaptationStream);
-;// CONCATENATED MODULE: ./src/core/stream/period/create_empty_adaptation_stream.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Create empty AdaptationStream Observable, linked to a Period.
- *
- * This observable will never download any segment and just emit a "full"
- * event when reaching the end.
- * @param {Observable} playbackObserver
- * @param {Object} wantedBufferAhead
- * @param {string} bufferType
- * @param {Object} content
- * @returns {Observable}
- */
-function createEmptyAdaptationStream(playbackObserver, wantedBufferAhead, bufferType, content) {
- var period = content.period;
- var hasFinishedLoading = false;
- var wantedBufferAhead$ = wantedBufferAhead.asObservable();
- var observation$ = playbackObserver.getReference().asObservable();
- return combineLatest([observation$, wantedBufferAhead$]).pipe((0,mergeMap/* mergeMap */.z)(function (_ref) {
- var observation = _ref[0],
- wba = _ref[1];
- var position = observation.position.last;
- if (period.end !== undefined && position + wba >= period.end) {
- log/* default.debug */.Z.debug("Stream: full \"empty\" AdaptationStream", bufferType);
- hasFinishedLoading = true;
- }
- return (0,of.of)({
- type: "stream-status",
- value: {
- period: period,
- bufferType: bufferType,
- position: position,
- imminentDiscontinuity: null,
- hasFinishedLoading: hasFinishedLoading,
- neededSegments: [],
- shouldRefreshManifest: false
- }
- });
- }));
-}
+/* harmony default export */ var stream_adaptation = (AdaptationStream);
// EXTERNAL MODULE: ./src/utils/starts_with.ts
var starts_with = __webpack_require__(9252);
;// CONCATENATED MODULE: ./src/utils/are_codecs_compatible.ts
@@ -50104,7 +46286,7 @@ function areCodecsCompatible(a, b) {
return true;
}
/* harmony default export */ var are_codecs_compatible = (areCodecsCompatible);
-;// CONCATENATED MODULE: ./src/core/stream/period/get_adaptation_switch_strategy.ts
+;// CONCATENATED MODULE: ./src/core/stream/period/utils/get_adaptation_switch_strategy.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -50341,6 +46523,11 @@ function getFirstSegmentAfterPeriod(inventory, period) {
return null;
}
;// CONCATENATED MODULE: ./src/core/stream/period/period_stream.ts
+
+
+function period_stream_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = period_stream_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
+function period_stream_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return period_stream_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return period_stream_arrayLikeToArray(o, minLen); }
+function period_stream_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
/**
* Copyright 2015 CANAL+ Group
*
@@ -50367,21 +46554,38 @@ function getFirstSegmentAfterPeriod(inventory, period) {
-
-
-
-
/**
- * Create single PeriodStream Observable:
+ * Create a single PeriodStream:
* - Lazily create (or reuse) a SegmentBuffer for the given type.
* - Create a Stream linked to an Adaptation each time it changes, to
* download and append the corresponding segments to the SegmentBuffer.
* - Announce when the Stream is full or is awaiting new Segments through
* events
- * @param {Object} args
- * @returns {Observable}
- */
-function PeriodStream(_ref) {
+ *
+ * @param {Object} args - Various arguments allowing the `PeriodStream` to
+ * determine which Adaptation and which Representation to choose, as well as
+ * which segments to load from it.
+ * You can check the corresponding type for more information.
+ * @param {Object} callbacks - The `PeriodStream` relies on a system of
+ * callbacks that it will call on various events.
+ *
+ * Depending on the event, the caller may be supposed to perform actions to
+ * react upon some of them.
+ *
+ * This approach is taken instead of a more classical EventEmitter pattern to:
+ * - Allow callbacks to be called synchronously after the
+ * `AdaptationStream` is called.
+ * - Simplify bubbling events up, by just passing through callbacks
+ * - Force the caller to explicitely handle or not the different events.
+ *
+ * Callbacks may start being called immediately after the `AdaptationStream`
+ * call and may be called until either the `parentCancelSignal` argument is
+ * triggered, or until the `error` callback is called, whichever comes first.
+ * @param {Object} parentCancelSignal - `CancellationSignal` allowing, when
+ * triggered, to immediately stop all operations the `PeriodStream` is
+ * doing.
+ */
+function PeriodStream(_ref, callbacks, parentCancelSignal) {
var bufferType = _ref.bufferType,
content = _ref.content,
garbageCollectors = _ref.garbageCollectors,
@@ -50393,96 +46597,217 @@ function PeriodStream(_ref) {
wantedBufferAhead = _ref.wantedBufferAhead,
maxVideoBufferSize = _ref.maxVideoBufferSize;
var period = content.period;
- // Emits the chosen Adaptation for the current type.
- // `null` when no Adaptation is chosen (e.g. no subtitles)
- var adaptation$ = new ReplaySubject/* ReplaySubject */.t(1);
- return adaptation$.pipe((0,switchMap/* switchMap */.w)(function (adaptation, switchNb) {
- /**
- * If this is not the first Adaptation choice, we might want to apply a
- * delta to the current position so we can re-play back some media in the
- * new Adaptation to give some context back.
- * This value contains this relative position, in seconds.
- * @see reloadAfterSwitch
- */
- var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
- DELTA_POSITION_AFTER_RELOAD = _config$getCurrent.DELTA_POSITION_AFTER_RELOAD;
- var relativePosAfterSwitch = switchNb === 0 ? 0 : bufferType === "audio" ? DELTA_POSITION_AFTER_RELOAD.trackSwitch.audio : bufferType === "video" ? DELTA_POSITION_AFTER_RELOAD.trackSwitch.video : DELTA_POSITION_AFTER_RELOAD.trackSwitch.other;
- if (adaptation === null) {
- // Current type is disabled for that Period
- log/* default.info */.Z.info("Stream: Set no " + bufferType + " Adaptation. P:", period.start);
- var segmentBufferStatus = segmentBuffersStore.getStatus(bufferType);
- var cleanBuffer$;
- if (segmentBufferStatus.type === "initialized") {
- log/* default.info */.Z.info("Stream: Clearing previous " + bufferType + " SegmentBuffer");
- if (segment_buffers.isNative(bufferType)) {
- return reloadAfterSwitch(period, bufferType, playbackObserver, 0);
- }
- var canceller = new task_canceller/* default */.ZP();
- cleanBuffer$ = fromCancellablePromise(canceller, function () {
- if (period.end === undefined) {
- return segmentBufferStatus.value.removeBuffer(period.start, Infinity, canceller.signal);
- } else if (period.end <= period.start) {
- return Promise.resolve();
- } else {
- return segmentBufferStatus.value.removeBuffer(period.start, period.end, canceller.signal);
+ /**
+ * Emits the chosen Adaptation for the current type.
+ * `null` when no Adaptation is chosen (e.g. no subtitles)
+ * `undefined` at the beginning (it can be ignored.).
+ */
+ var adaptationRef = (0,reference/* default */.ZP)(undefined, parentCancelSignal);
+ callbacks.periodStreamReady({
+ type: bufferType,
+ period: period,
+ adaptationRef: adaptationRef
+ });
+ if (parentCancelSignal.isCancelled()) {
+ return;
+ }
+ var currentStreamCanceller;
+ var isFirstAdaptationSwitch = true;
+ adaptationRef.onUpdate(function (adaptation) {
+ // As an IIFE to profit from async/await while respecting onUpdate's signature
+ (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee() {
+ var _a, streamCanceller, segmentBufferStatus, periodEnd, _config$getCurrent, DELTA_POSITION_AFTER_RELOAD, relativePosAfterSwitch, readyState, segmentBuffer, playbackInfos, strategy, _iterator, _step, _step$value, start, end;
+ return regenerator_default().wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ if (!(adaptation === undefined)) {
+ _context.next = 2;
+ break;
+ }
+ return _context.abrupt("return");
+ case 2:
+ streamCanceller = new task_canceller/* default */.ZP();
+ streamCanceller.linkToSignal(parentCancelSignal);
+ currentStreamCanceller === null || currentStreamCanceller === void 0 ? void 0 : currentStreamCanceller.cancel(); // Cancel oreviously created stream if one
+ currentStreamCanceller = streamCanceller;
+ if (!(adaptation === null)) {
+ _context.next = 34;
+ break;
+ }
+ // Current type is disabled for that Period
+ log/* default.info */.Z.info("Stream: Set no " + bufferType + " Adaptation. P:", period.start);
+ segmentBufferStatus = segmentBuffersStore.getStatus(bufferType);
+ if (!(segmentBufferStatus.type === "initialized")) {
+ _context.next = 26;
+ break;
+ }
+ log/* default.info */.Z.info("Stream: Clearing previous " + bufferType + " SegmentBuffer");
+ if (!segment_buffers.isNative(bufferType)) {
+ _context.next = 15;
+ break;
+ }
+ return _context.abrupt("return", askForMediaSourceReload(0, streamCanceller.signal));
+ case 15:
+ periodEnd = (_a = period.end) !== null && _a !== void 0 ? _a : Infinity;
+ if (!(period.start > periodEnd)) {
+ _context.next = 20;
+ break;
+ }
+ log/* default.warn */.Z.warn("Stream: Can't free buffer: period's start is after its end");
+ _context.next = 24;
+ break;
+ case 20:
+ _context.next = 22;
+ return segmentBufferStatus.value.removeBuffer(period.start, periodEnd, streamCanceller.signal);
+ case 22:
+ if (!streamCanceller.isUsed()) {
+ _context.next = 24;
+ break;
+ }
+ return _context.abrupt("return");
+ case 24:
+ _context.next = 30;
+ break;
+ case 26:
+ if (!(segmentBufferStatus.type === "uninitialized")) {
+ _context.next = 30;
+ break;
+ }
+ segmentBuffersStore.disableSegmentBuffer(bufferType);
+ if (!streamCanceller.isUsed()) {
+ _context.next = 30;
+ break;
+ }
+ return _context.abrupt("return");
+ case 30:
+ callbacks.adaptationChange({
+ type: bufferType,
+ adaptation: null,
+ period: period
+ });
+ if (!streamCanceller.isUsed()) {
+ _context.next = 33;
+ break;
+ }
+ return _context.abrupt("return");
+ case 33:
+ return _context.abrupt("return", createEmptyAdaptationStream(playbackObserver, wantedBufferAhead, bufferType, {
+ period: period
+ }, callbacks, streamCanceller.signal));
+ case 34:
+ /**
+ * If this is not the first Adaptation choice, we might want to apply a
+ * delta to the current position so we can re-play back some media in the
+ * new Adaptation to give some context back.
+ * This value contains this relative position, in seconds.
+ * @see askForMediaSourceReload
+ */
+ _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(), DELTA_POSITION_AFTER_RELOAD = _config$getCurrent.DELTA_POSITION_AFTER_RELOAD;
+ relativePosAfterSwitch = isFirstAdaptationSwitch ? 0 : bufferType === "audio" ? DELTA_POSITION_AFTER_RELOAD.trackSwitch.audio : bufferType === "video" ? DELTA_POSITION_AFTER_RELOAD.trackSwitch.video : DELTA_POSITION_AFTER_RELOAD.trackSwitch.other;
+ isFirstAdaptationSwitch = false;
+ if (!(segment_buffers.isNative(bufferType) && segmentBuffersStore.getStatus(bufferType).type === "disabled")) {
+ _context.next = 39;
+ break;
+ }
+ return _context.abrupt("return", askForMediaSourceReload(relativePosAfterSwitch, streamCanceller.signal));
+ case 39:
+ log/* default.info */.Z.info("Stream: Updating " + bufferType + " adaptation", "A: " + adaptation.id, "P: " + period.start);
+ callbacks.adaptationChange({
+ type: bufferType,
+ adaptation: adaptation,
+ period: period
+ });
+ if (!streamCanceller.isUsed()) {
+ _context.next = 43;
+ break;
+ }
+ return _context.abrupt("return");
+ case 43:
+ readyState = playbackObserver.getReadyState();
+ segmentBuffer = createOrReuseSegmentBuffer(segmentBuffersStore, bufferType, adaptation, options);
+ playbackInfos = {
+ currentTime: playbackObserver.getCurrentTime(),
+ readyState: readyState
+ };
+ strategy = getAdaptationSwitchStrategy(segmentBuffer, period, adaptation, playbackInfos, options);
+ if (!(strategy.type === "needs-reload")) {
+ _context.next = 49;
+ break;
+ }
+ return _context.abrupt("return", askForMediaSourceReload(relativePosAfterSwitch, streamCanceller.signal));
+ case 49:
+ _context.next = 51;
+ return segmentBuffersStore.waitForUsableBuffers(streamCanceller.signal);
+ case 51:
+ if (!streamCanceller.isUsed()) {
+ _context.next = 53;
+ break;
+ }
+ return _context.abrupt("return");
+ case 53:
+ if (!(strategy.type === "flush-buffer" || strategy.type === "clean-buffer")) {
+ _context.next = 67;
+ break;
+ }
+ _iterator = period_stream_createForOfIteratorHelperLoose(strategy.value);
+ case 55:
+ if ((_step = _iterator()).done) {
+ _context.next = 63;
+ break;
+ }
+ _step$value = _step.value, start = _step$value.start, end = _step$value.end;
+ _context.next = 59;
+ return segmentBuffer.removeBuffer(start, end, streamCanceller.signal);
+ case 59:
+ if (!streamCanceller.isUsed()) {
+ _context.next = 61;
+ break;
+ }
+ return _context.abrupt("return");
+ case 61:
+ _context.next = 55;
+ break;
+ case 63:
+ if (!(strategy.type === "flush-buffer")) {
+ _context.next = 67;
+ break;
+ }
+ callbacks.needsBufferFlush();
+ if (!streamCanceller.isUsed()) {
+ _context.next = 67;
+ break;
+ }
+ return _context.abrupt("return");
+ case 67:
+ garbageCollectors.get(segmentBuffer)(streamCanceller.signal);
+ createAdaptationStream(adaptation, segmentBuffer, streamCanceller.signal);
+ case 69:
+ case "end":
+ return _context.stop();
}
- });
- } else {
- if (segmentBufferStatus.type === "uninitialized") {
- segmentBuffersStore.disableSegmentBuffer(bufferType);
}
- cleanBuffer$ = (0,of.of)(null);
+ }, _callee);
+ }))()["catch"](function (err) {
+ if (err instanceof task_canceller/* CancellationError */.FU) {
+ return;
}
- return (0,concat/* concat */.z)(cleanBuffer$.pipe((0,map/* map */.U)(function () {
- return stream_events_generators/* default.adaptationChange */.Z.adaptationChange(bufferType, null, period);
- })), createEmptyAdaptationStream(playbackObserver, wantedBufferAhead, bufferType, {
- period: period
- }));
- }
- if (segment_buffers.isNative(bufferType) && segmentBuffersStore.getStatus(bufferType).type === "disabled") {
- return reloadAfterSwitch(period, bufferType, playbackObserver, relativePosAfterSwitch);
- }
- log/* default.info */.Z.info("Stream: Updating " + bufferType + " adaptation", "A: " + adaptation.id, "P: " + period.start);
- var newStream$ = (0,defer/* defer */.P)(function () {
- var readyState = playbackObserver.getReadyState();
- var segmentBuffer = createOrReuseSegmentBuffer(segmentBuffersStore, bufferType, adaptation, options);
- var playbackInfos = {
- currentTime: playbackObserver.getCurrentTime(),
- readyState: readyState
- };
- var strategy = getAdaptationSwitchStrategy(segmentBuffer, period, adaptation, playbackInfos, options);
- if (strategy.type === "needs-reload") {
- return reloadAfterSwitch(period, bufferType, playbackObserver, relativePosAfterSwitch);
- }
- var needsBufferFlush$ = strategy.type === "flush-buffer" ? (0,of.of)(stream_events_generators/* default.needsBufferFlush */.Z.needsBufferFlush()) : empty/* EMPTY */.E;
- var cleanBuffer$ = strategy.type === "clean-buffer" || strategy.type === "flush-buffer" ? concat/* concat.apply */.z.apply(void 0, strategy.value.map(function (_ref2) {
- var start = _ref2.start,
- end = _ref2.end;
- var canceller = new task_canceller/* default */.ZP();
- return fromCancellablePromise(canceller, function () {
- return segmentBuffer.removeBuffer(start, end, canceller.signal);
- });
- })).pipe((0,ignoreElements/* ignoreElements */.l)()) : empty/* EMPTY */.E;
- var bufferGarbageCollector$ = garbageCollectors.get(segmentBuffer);
- var adaptationStream$ = createAdaptationStream(adaptation, segmentBuffer);
- var cancelWait = new task_canceller/* default */.ZP();
- return fromCancellablePromise(cancelWait, function () {
- return segmentBuffersStore.waitForUsableBuffers(cancelWait.signal);
- }).pipe((0,mergeMap/* mergeMap */.z)(function () {
- return (0,concat/* concat */.z)(cleanBuffer$, needsBufferFlush$, (0,merge/* merge */.T)(adaptationStream$, bufferGarbageCollector$));
- }));
+ currentStreamCanceller === null || currentStreamCanceller === void 0 ? void 0 : currentStreamCanceller.cancel();
+ callbacks.error(err);
});
- return (0,concat/* concat */.z)((0,of.of)(stream_events_generators/* default.adaptationChange */.Z.adaptationChange(bufferType, adaptation, period)), newStream$);
- }), (0,startWith/* startWith */.O)(stream_events_generators/* default.periodStreamReady */.Z.periodStreamReady(bufferType, period, adaptation$)));
+ }, {
+ clearSignal: parentCancelSignal,
+ emitCurrentValue: true
+ });
/**
* @param {Object} adaptation
* @param {Object} segmentBuffer
- * @returns {Observable}
+ * @param {Object} cancelSignal
*/
- function createAdaptationStream(adaptation, segmentBuffer) {
+ function createAdaptationStream(adaptation, segmentBuffer, cancelSignal) {
var manifest = content.manifest;
var adaptationPlaybackObserver = createAdaptationStreamPlaybackObserver(playbackObserver, segmentBuffer);
- return stream_adaptation({
+ stream_adaptation({
content: {
manifest: manifest,
period: period,
@@ -50495,7 +46820,10 @@ function PeriodStream(_ref) {
segmentFetcherCreator: segmentFetcherCreator,
wantedBufferAhead: wantedBufferAhead,
maxVideoBufferSize: maxVideoBufferSize
- }).pipe((0,catchError/* catchError */.K)(function (error) {
+ }, Object.assign(Object.assign({}, callbacks), {
+ error: onAdaptationStreamError
+ }), cancelSignal);
+ function onAdaptationStreamError(error) {
// Stream linked to a non-native media buffer should not impact the
// stability of the player. ie: if a text buffer sends an error, we want
// to continue playing without any subtitles
@@ -50506,13 +46834,63 @@ function PeriodStream(_ref) {
defaultCode: "NONE",
defaultReason: "Unknown `AdaptationStream` error"
});
- return (0,concat/* concat */.z)((0,of.of)(stream_events_generators/* default.warning */.Z.warning(formattedError)), createEmptyAdaptationStream(playbackObserver, wantedBufferAhead, bufferType, {
+ callbacks.warning(formattedError);
+ if (cancelSignal.isCancelled()) {
+ return; // Previous callback cancelled the Stream by side-effect
+ }
+
+ return createEmptyAdaptationStream(playbackObserver, wantedBufferAhead, bufferType, {
period: period
- }));
+ }, callbacks, cancelSignal);
}
log/* default.error */.Z.error("Stream: " + bufferType + " Stream crashed. Stopping playback.", error instanceof Error ? error : "");
- throw error;
- }));
+ callbacks.error(error);
+ }
+ }
+ /**
+ * Regularly ask to reload the MediaSource on each playback observation
+ * performed by the playback observer.
+ *
+ * If and only if the Period currently played corresponds to the concerned
+ * Period, applies an offset to the reloaded position corresponding to
+ * `deltaPos`.
+ * This can be useful for example when switching the audio/video tracks, where
+ * you might want to give back some context if that was the currently played
+ * track.
+ *
+ * @param {number} deltaPos - If the concerned Period is playing at the time
+ * this function is called, we will add this value, in seconds, to the current
+ * position to indicate the position we should reload at.
+ * This value allows to give back context (by replaying some media data) after
+ * a switch.
+ * @param {Object} cancelSignal
+ */
+ function askForMediaSourceReload(deltaPos, cancelSignal) {
+ // We begin by scheduling a micro-task to reduce the possibility of race
+ // conditions where `askForMediaSourceReload` would be called synchronously before
+ // the next observation (which may reflect very different playback conditions)
+ // is actually received.
+ // It can happen when `askForMediaSourceReload` is called as a side-effect of
+ // the same event that triggers the playback observation to be emitted.
+ next_tick_default()(function () {
+ playbackObserver.listen(function (observation) {
+ var _a, _b;
+ var currentTime = playbackObserver.getCurrentTime();
+ var pos = currentTime + deltaPos;
+ // Bind to Period start and end
+ var position = Math.min(Math.max(period.start, pos), (_a = period.end) !== null && _a !== void 0 ? _a : Infinity);
+ var autoPlay = !((_b = observation.paused.pending) !== null && _b !== void 0 ? _b : playbackObserver.getIsPaused());
+ callbacks.waitingMediaSourceReload({
+ bufferType: bufferType,
+ period: period,
+ position: position,
+ autoPlay: autoPlay
+ });
+ }, {
+ includeLastObservation: true,
+ clearSignal: cancelSignal
+ });
+ });
}
}
/**
@@ -50554,14 +46932,11 @@ function getFirstDeclaredMimeType(adaptation) {
*/
function createAdaptationStreamPlaybackObserver(initialPlaybackObserver, segmentBuffer) {
return initialPlaybackObserver.deriveReadOnlyObserver(function transform(observationRef, cancellationSignal) {
- var newRef = (0,reference/* default */.ZP)(constructAdaptationStreamPlaybackObservation());
+ var newRef = (0,reference/* default */.ZP)(constructAdaptationStreamPlaybackObservation(), cancellationSignal);
observationRef.onUpdate(emitAdaptationStreamPlaybackObservation, {
clearSignal: cancellationSignal,
emitCurrentValue: false
});
- cancellationSignal.register(function () {
- newRef.finish();
- });
return newRef;
function constructAdaptationStreamPlaybackObservation() {
var baseObservation = observationRef.getValue();
@@ -50576,155 +46951,49 @@ function createAdaptationStreamPlaybackObserver(initialPlaybackObserver, segment
}
});
}
-;// CONCATENATED MODULE: ./src/core/stream/period/index.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* harmony default export */ var period = (PeriodStream);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/scan.js + 1 modules
-var scan = __webpack_require__(3074);
-;// CONCATENATED MODULE: ./src/core/stream/orchestrator/active_period_emitter.ts
/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Create empty AdaptationStream, linked to a Period.
+ * This AdaptationStream will never download any segment and just emit a "full"
+ * event when reaching the end.
+ * @param {Object} playbackObserver
+ * @param {Object} wantedBufferAhead
+ * @param {string} bufferType
+ * @param {Object} content
+ * @param {Object} callbacks
+ * @param {Object} cancelSignal
*/
-
-/**
- * Emit the active Period each times it changes.
- *
- * The active Period is the first Period (in chronological order) which has
- * a RepresentationStream associated for every defined BUFFER_TYPES.
- *
- * Emit null if no Period can be considered active currently.
- *
- * @example
- * For 4 BUFFER_TYPES: "AUDIO", "VIDEO", "TEXT" and "IMAGE":
- * ```
- * +-------------+
- * Period 1 | Period 2 | Period 3
- * AUDIO |=========| | |=== | |
- * VIDEO | |===== | |
- * TEXT |(NO TEXT)| | |(NO TEXT)| | |==== |
- * IMAGE |=========| | |= | |
- * +-------------+
- *
- * The active Period here is Period 2 as Period 1 has no video
- * RepresentationStream.
- *
- * If we are missing a or multiple PeriodStreams in the first chronological
- * Period, like that is the case here, it generally means that we are
- * currently switching between Periods.
- *
- * For here we are surely switching from Period 1 to Period 2 beginning by the
- * video PeriodStream. As every PeriodStream is ready for Period 2, we can
- * already inform that it is the current Period.
- * ```
- *
- * @param {Array.} buffers$
- * @returns {Observable}
- */
-function ActivePeriodEmitter(buffers$) {
- var numberOfStreams = buffers$.length;
- return merge/* merge.apply */.T.apply(void 0, buffers$).pipe(
- // not needed to filter, this is an optim
- (0,filter/* filter */.h)(function (_ref) {
- var type = _ref.type;
- return type === "periodStreamCleared" || type === "adaptationChange" || type === "representationChange";
- }), (0,scan/* scan */.R)(function (acc, evt) {
- switch (evt.type) {
- case "periodStreamCleared":
- {
- var _evt$value = evt.value,
- period = _evt$value.period,
- type = _evt$value.type;
- var currentInfos = acc[period.id];
- if (currentInfos !== undefined && currentInfos.buffers.has(type)) {
- currentInfos.buffers["delete"](type);
- if (currentInfos.buffers.size === 0) {
- delete acc[period.id];
- }
- }
- }
- break;
- case "adaptationChange":
- {
- // For Adaptations that are not null, we will receive a
- // `representationChange` event. We can thus skip this event and only
- // listen to the latter.
- if (evt.value.adaptation !== null) {
- return acc;
- }
- }
- // /!\ fallthrough done on purpose
- // Note that we fall-through only when the Adaptation sent through the
- // `adaptationChange` event is `null`. This is because in those cases,
- // we won't receive any "representationChange" event. We however still
- // need to register that Period as active for the current type.
- // eslint-disable-next-line no-fallthrough
- case "representationChange":
- {
- var _evt$value2 = evt.value,
- _period = _evt$value2.period,
- _type = _evt$value2.type;
- var _currentInfos = acc[_period.id];
- if (_currentInfos === undefined) {
- var bufferSet = new Set();
- bufferSet.add(_type);
- acc[_period.id] = {
- period: _period,
- buffers: bufferSet
- };
- } else if (!_currentInfos.buffers.has(_type)) {
- _currentInfos.buffers.add(_type);
- }
- }
- break;
- }
- return acc;
- }, {}), (0,map/* map */.U)(function (list) {
- var activePeriodIDs = Object.keys(list);
- var completePeriods = [];
- for (var i = 0; i < activePeriodIDs.length; i++) {
- var periodInfos = list[activePeriodIDs[i]];
- if (periodInfos !== undefined && periodInfos.buffers.size === numberOfStreams) {
- completePeriods.push(periodInfos.period);
- }
+function createEmptyAdaptationStream(playbackObserver, wantedBufferAhead, bufferType, content, callbacks, cancelSignal) {
+ var period = content.period;
+ var hasFinishedLoading = false;
+ wantedBufferAhead.onUpdate(sendStatus, {
+ emitCurrentValue: false,
+ clearSignal: cancelSignal
+ });
+ playbackObserver.listen(sendStatus, {
+ includeLastObservation: false,
+ clearSignal: cancelSignal
+ });
+ sendStatus();
+ function sendStatus() {
+ var observation = playbackObserver.getReference().getValue();
+ var wba = wantedBufferAhead.getValue();
+ var position = observation.position.last;
+ if (period.end !== undefined && position + wba >= period.end) {
+ log/* default.debug */.Z.debug("Stream: full \"empty\" AdaptationStream", bufferType);
+ hasFinishedLoading = true;
}
- return completePeriods.reduce(function (acc, period) {
- if (acc === null) {
- return period;
- }
- return period.start < acc.start ? period : acc;
- }, null);
- }), distinctUntilChanged(function (a, b) {
- return a === null && b === null || a !== null && b !== null && a.id === b.id;
- }));
+ callbacks.streamStatusUpdate({
+ period: period,
+ bufferType: bufferType,
+ position: position,
+ imminentDiscontinuity: null,
+ isEmptyStream: true,
+ hasFinishedLoading: hasFinishedLoading,
+ neededSegments: []
+ });
+ }
}
-;// CONCATENATED MODULE: ./src/core/stream/orchestrator/are_streams_complete.ts
+;// CONCATENATED MODULE: ./src/core/stream/period/index.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -50741,46 +47010,8 @@ function ActivePeriodEmitter(buffers$) {
* limitations under the License.
*/
-/**
- * Returns an Observable which emits ``true`` when all PeriodStreams given are
- * _complete_.
- * Returns false otherwise.
- *
- * A PeriodStream for a given type is considered _complete_ when both of these
- * conditions are true:
- * - it is the last PeriodStream in the content for the given type
- * - it has finished downloading segments (it is _full_)
- *
- * Simply put a _complete_ PeriodStream for a given type means that every
- * segments needed for this Stream have been downloaded.
- *
- * When the Observable returned here emits, every Stream are finished.
- * @param {...Observable} streams
- * @returns {Observable}
- */
-function areStreamsComplete() {
- for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) {
- streams[_key] = arguments[_key];
- }
- /**
- * Array of Observables linked to the Array of Streams which emit:
- * - true when the corresponding Stream is considered _complete_.
- * - false when the corresponding Stream is considered _active_.
- * @type {Array.}
- */
- var isCompleteArray = streams.map(function (stream) {
- return stream.pipe((0,filter/* filter */.h)(function (evt) {
- return evt.type === "complete-stream" || evt.type === "stream-status" && !evt.value.hasFinishedLoading;
- }), (0,map/* map */.U)(function (evt) {
- return evt.type === "complete-stream";
- }), (0,startWith/* startWith */.O)(false), distinctUntilChanged());
- });
- return combineLatest(isCompleteArray).pipe((0,map/* map */.U)(function (areComplete) {
- return areComplete.every(function (isComplete) {
- return isComplete;
- });
- }), distinctUntilChanged());
-}
+
+/* harmony default export */ var period = (PeriodStream);
;// CONCATENATED MODULE: ./src/core/stream/orchestrator/get_time_ranges_for_content.ts
/**
* Copyright 2015 CANAL+ Group
@@ -50854,6 +47085,11 @@ function getTimeRangesForContent(segmentBuffer, contents) {
return accumulator;
}
;// CONCATENATED MODULE: ./src/core/stream/orchestrator/stream_orchestrator.ts
+
+
+function stream_orchestrator_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = stream_orchestrator_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
+function stream_orchestrator_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return stream_orchestrator_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return stream_orchestrator_arrayLikeToArray(o, minLen); }
+function stream_orchestrator_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
/**
* Copyright 2015 CANAL+ Group
*
@@ -50880,16 +47116,8 @@ function getTimeRangesForContent(segmentBuffer, contents) {
-
-
-
-
-
-
-
-
/**
- * Create and manage the various Stream Observables needed for the content to
+ * Create and manage the various "Streams" needed for the content to
* play:
*
* - Create or dispose SegmentBuffers depending on the chosen Adaptations.
@@ -50901,19 +47129,36 @@ function getTimeRangesForContent(segmentBuffer, contents) {
* - Concatenate Streams for adaptation from separate Periods at the right
* time, to allow smooth transitions between periods.
*
- * - Emit various events to notify of its health and issues
+ * - Call various callbacks to notify of its health and issues
*
* @param {Object} content
- * @param {Observable} playbackObserver - Emit position information
+ * @param {Object} playbackObserver - Emit position information
* @param {Object} representationEstimator - Emit bitrate estimates and best
* Representation to play.
* @param {Object} segmentBuffersStore - Will be used to lazily create
* SegmentBuffer instances associated with the current content.
* @param {Object} segmentFetcherCreator - Allow to download segments.
* @param {Object} options
- * @returns {Observable}
- */
-function StreamOrchestrator(content, playbackObserver, representationEstimator, segmentBuffersStore, segmentFetcherCreator, options) {
+ * @param {Object} callbacks - The `StreamOrchestrator` relies on a system of
+ * callbacks that it will call on various events.
+ *
+ * Depending on the event, the caller may be supposed to perform actions to
+ * react upon some of them.
+ *
+ * This approach is taken instead of a more classical EventEmitter pattern to:
+ * - Allow callbacks to be called synchronously after the
+ * `StreamOrchestrator` is called.
+ * - Simplify bubbling events up, by just passing through callbacks
+ * - Force the caller to explicitely handle or not the different events.
+ *
+ * Callbacks may start being called immediately after the `StreamOrchestrator`
+ * call and may be called until either the `parentCancelSignal` argument is
+ * triggered, or until the `error` callback is called, whichever comes first.
+ * @param {Object} orchestratorCancelSignal - `CancellationSignal` allowing,
+ * when triggered, to immediately stop all operations the `PeriodStream` is
+ * doing.
+ */
+function StreamOrchestrator(content, playbackObserver, representationEstimator, segmentBuffersStore, segmentFetcherCreator, options, callbacks, orchestratorCancelSignal) {
var manifest = content.manifest,
initialPeriod = content.initialPeriod;
var maxBufferAhead = options.maxBufferAhead,
@@ -50929,47 +47174,24 @@ function StreamOrchestrator(content, playbackObserver, representationEstimator,
var bufferType = segmentBuffer.bufferType;
var defaultMaxBehind = MAXIMUM_MAX_BUFFER_BEHIND[bufferType] != null ? MAXIMUM_MAX_BUFFER_BEHIND[bufferType] : Infinity;
var defaultMaxAhead = MAXIMUM_MAX_BUFFER_AHEAD[bufferType] != null ? MAXIMUM_MAX_BUFFER_AHEAD[bufferType] : Infinity;
- return new Observable/* Observable */.y(function () {
- var canceller = new task_canceller/* default */.ZP();
+ return function (gcCancelSignal) {
BufferGarbageCollector({
segmentBuffer: segmentBuffer,
playbackObserver: playbackObserver,
maxBufferBehind: (0,reference/* createMappedReference */.lR)(maxBufferBehind, function (val) {
return Math.min(val, defaultMaxBehind);
- }, canceller.signal),
+ }, gcCancelSignal),
maxBufferAhead: (0,reference/* createMappedReference */.lR)(maxBufferAhead, function (val) {
return Math.min(val, defaultMaxAhead);
- }, canceller.signal)
- }, canceller.signal);
- return function () {
- canceller.cancel();
- };
- });
- });
- // Every PeriodStreams for every possible types
- var streamsArray = segmentBuffersStore.getBufferTypes().map(function (bufferType) {
- return manageEveryStreams(bufferType, initialPeriod).pipe((0,defer_subscriptions/* default */.Z)(), (0,share/* share */.B)());
+ }, gcCancelSignal)
+ }, gcCancelSignal);
+ };
});
- // Emits the activePeriodChanged events every time the active Period changes.
- var activePeriodChanged$ = ActivePeriodEmitter(streamsArray).pipe((0,filter/* filter */.h)(function (period) {
- return period !== null;
- }), (0,map/* map */.U)(function (period) {
- log/* default.info */.Z.info("Stream: New active period", period.start);
- return stream_events_generators/* default.activePeriodChanged */.Z.activePeriodChanged(period);
- }));
- var isLastPeriodKnown$ = (0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,map/* map */.U)(function () {
- return manifest.isLastPeriodKnown;
- }), (0,startWith/* startWith */.O)(manifest.isLastPeriodKnown), distinctUntilChanged());
- // Emits an "end-of-stream" event once every PeriodStream are complete.
- // Emits a 'resume-stream" when it's not
- var endOfStream$ = combineLatest([areStreamsComplete.apply(void 0, streamsArray), isLastPeriodKnown$]).pipe((0,map/* map */.U)(function (_ref) {
- var areComplete = _ref[0],
- isLastPeriodKnown = _ref[1];
- return areComplete && isLastPeriodKnown;
- }), distinctUntilChanged(), (0,map/* map */.U)(function (emitEndOfStream) {
- return emitEndOfStream ? stream_events_generators/* default.endOfStream */.Z.endOfStream() : stream_events_generators/* default.resumeStream */.Z.resumeStream();
- }));
- return merge/* merge.apply */.T.apply(void 0, streamsArray.concat([activePeriodChanged$, endOfStream$]));
+ // Create automatically the right `PeriodStream` for every possible types
+ for (var _iterator = stream_orchestrator_createForOfIteratorHelperLoose(segmentBuffersStore.getBufferTypes()), _step; !(_step = _iterator()).done;) {
+ var bufferType = _step.value;
+ manageEveryStreams(bufferType, initialPeriod);
+ }
/**
* Manage creation and removal of Streams for every Periods for a given type.
*
@@ -50978,49 +47200,100 @@ function StreamOrchestrator(content, playbackObserver, representationEstimator,
* current position goes out of the bounds of these Streams.
* @param {string} bufferType - e.g. "audio" or "video"
* @param {Period} basePeriod - Initial Period downloaded.
- * @returns {Observable}
*/
function manageEveryStreams(bufferType, basePeriod) {
- // Each Period for which there is currently a Stream, chronologically
+ /** Each Period for which there is currently a Stream, chronologically */
var periodList = new SortedList(function (a, b) {
return a.start - b.start;
});
- var destroyStreams$ = new Subject/* Subject */.x();
- // When set to `true`, all the currently active PeriodStream will be destroyed
- // and re-created from the new current position if we detect it to be out of
- // their bounds.
- // This is set to false when we're in the process of creating the first
- // PeriodStream, to avoid interferences while no PeriodStream is available.
+ /**
+ * When set to `true`, all the currently active PeriodStream will be destroyed
+ * and re-created from the new current position if we detect it to be out of
+ * their bounds.
+ * This is set to false when we're in the process of creating the first
+ * PeriodStream, to avoid interferences while no PeriodStream is available.
+ */
var enableOutOfBoundsCheck = false;
+ /** Cancels currently created `PeriodStream`s. */
+ var currentCanceller = new task_canceller/* default */.ZP();
+ currentCanceller.linkToSignal(orchestratorCancelSignal);
+ // Restart the current Stream when the wanted time is in another period
+ // than the ones already considered
+ playbackObserver.listen(function (_ref) {
+ var position = _ref.position;
+ var _a, _b;
+ var time = (_a = position.pending) !== null && _a !== void 0 ? _a : position.last;
+ if (!enableOutOfBoundsCheck || !isOutOfPeriodList(time)) {
+ return;
+ }
+ log/* default.info */.Z.info("Stream: Destroying all PeriodStreams due to out of bounds situation", bufferType, time);
+ enableOutOfBoundsCheck = false;
+ while (periodList.length() > 0) {
+ var period = periodList.get(periodList.length() - 1);
+ periodList.removeElement(period);
+ callbacks.periodStreamCleared({
+ type: bufferType,
+ period: period
+ });
+ }
+ currentCanceller.cancel();
+ currentCanceller = new task_canceller/* default */.ZP();
+ currentCanceller.linkToSignal(orchestratorCancelSignal);
+ var nextPeriod = (_b = manifest.getPeriodForTime(time)) !== null && _b !== void 0 ? _b : manifest.getNextPeriod(time);
+ if (nextPeriod === undefined) {
+ log/* default.warn */.Z.warn("Stream: The wanted position is not found in the Manifest.");
+ return;
+ }
+ launchConsecutiveStreamsForPeriod(nextPeriod);
+ }, {
+ clearSignal: orchestratorCancelSignal,
+ includeLastObservation: true
+ });
+ manifest.addEventListener("decipherabilityUpdate", function (evt) {
+ onDecipherabilityUpdates(evt)["catch"](function (err) {
+ currentCanceller.cancel();
+ callbacks.error(err);
+ });
+ }, orchestratorCancelSignal);
+ return launchConsecutiveStreamsForPeriod(basePeriod);
/**
* @param {Object} period
- * @returns {Observable}
*/
function launchConsecutiveStreamsForPeriod(period) {
- return manageConsecutivePeriodStreams(bufferType, period, destroyStreams$).pipe((0,map/* map */.U)(function (message) {
- switch (message.type) {
- case "waiting-media-source-reload":
- // Only reload the MediaSource when the more immediately required
- // Period is the one asking for it
- var firstPeriod = periodList.head();
- if (firstPeriod === undefined || firstPeriod.id !== message.value.period.id) {
- return stream_events_generators/* default.lockedStream */.Z.lockedStream(message.value.bufferType, message.value.period);
- } else {
- var _message$value = message.value,
- position = _message$value.position,
- autoPlay = _message$value.autoPlay;
- return stream_events_generators/* default.needsMediaSourceReload */.Z.needsMediaSourceReload(position, autoPlay);
- }
- case "periodStreamReady":
- enableOutOfBoundsCheck = true;
- periodList.add(message.value.period);
- break;
- case "periodStreamCleared":
- periodList.removeElement(message.value.period);
- break;
+ var consecutivePeriodStreamCb = Object.assign(Object.assign({}, callbacks), {
+ waitingMediaSourceReload: function waitingMediaSourceReload(payload) {
+ // Only reload the MediaSource when the more immediately required
+ // Period is the one asking for it
+ var firstPeriod = periodList.head();
+ if (firstPeriod === undefined || firstPeriod.id !== payload.period.id) {
+ callbacks.lockedStream({
+ bufferType: payload.bufferType,
+ period: payload.period
+ });
+ } else {
+ var position = payload.position,
+ autoPlay = payload.autoPlay;
+ callbacks.needsMediaSourceReload({
+ position: position,
+ autoPlay: autoPlay
+ });
+ }
+ },
+ periodStreamReady: function periodStreamReady(payload) {
+ enableOutOfBoundsCheck = true;
+ periodList.add(payload.period);
+ callbacks.periodStreamReady(payload);
+ },
+ periodStreamCleared: function periodStreamCleared(payload) {
+ periodList.removeElement(payload.period);
+ callbacks.periodStreamCleared(payload);
+ },
+ error: function error(err) {
+ currentCanceller.cancel();
+ callbacks.error(err);
}
- return message;
- }), (0,share/* share */.B)());
+ });
+ manageConsecutivePeriodStreams(bufferType, period, consecutivePeriodStreamCb, currentCanceller.signal);
}
/**
* Returns true if the given time is either:
@@ -51038,162 +47311,194 @@ function StreamOrchestrator(content, playbackObserver, representationEstimator,
}
return head.start > time || (last.end == null ? Infinity : last.end) < time;
}
- // Restart the current Stream when the wanted time is in another period
- // than the ones already considered
- var observation$ = playbackObserver.getReference().asObservable();
- var restartStreamsWhenOutOfBounds$ = observation$.pipe((0,filter_map/* default */.Z)(function (_ref2) {
- var position = _ref2.position;
- var _a, _b;
- var time = (_a = position.pending) !== null && _a !== void 0 ? _a : position.last;
- if (!enableOutOfBoundsCheck || !isOutOfPeriodList(time)) {
- return null;
- }
- var nextPeriod = (_b = manifest.getPeriodForTime(time)) !== null && _b !== void 0 ? _b : manifest.getNextPeriod(time);
- if (nextPeriod === undefined) {
- return null;
- }
- log/* default.info */.Z.info("SO: Current position out of the bounds of the active periods," + "re-creating Streams.", bufferType, time);
- enableOutOfBoundsCheck = false;
- destroyStreams$.next();
- return nextPeriod;
- }, null), (0,mergeMap/* mergeMap */.z)(function (newInitialPeriod) {
- if (newInitialPeriod == null) {
- throw new media_error/* default */.Z("MEDIA_TIME_NOT_FOUND", "The wanted position is not found in the Manifest.");
- }
- return launchConsecutiveStreamsForPeriod(newInitialPeriod);
- }));
- var handleDecipherabilityUpdate$ = (0,event_emitter/* fromEvent */.R)(manifest, "decipherabilityUpdate").pipe((0,mergeMap/* mergeMap */.z)(onDecipherabilityUpdates));
- return (0,merge/* merge */.T)(restartStreamsWhenOutOfBounds$, handleDecipherabilityUpdate$, launchConsecutiveStreamsForPeriod(basePeriod));
- function onDecipherabilityUpdates(updates) {
- var segmentBufferStatus = segmentBuffersStore.getStatus(bufferType);
- var ofCurrentType = updates.filter(function (update) {
- return update.adaptation.type === bufferType;
- });
- if (ofCurrentType.length === 0 || segmentBufferStatus.type !== "initialized") {
- return empty/* EMPTY */.E; // no need to stop the current Streams.
- }
-
- var segmentBuffer = segmentBufferStatus.value;
- var resettedContent = ofCurrentType.filter(function (update) {
- return update.representation.decipherable === undefined;
- });
- var undecipherableContent = ofCurrentType.filter(function (update) {
- return update.representation.decipherable === false;
- });
- /**
- * Time ranges now containing undecipherable content.
- * Those should first be removed and, depending on the platform, may
- * need Supplementary actions as playback issues may remain even after
- * removal.
- */
- var undecipherableRanges = getTimeRangesForContent(segmentBuffer, undecipherableContent);
- /**
- * Time ranges now containing content whose decipherability status came
- * back to being unknown.
- * To simplify its handling, those are just removed from the buffer.
- * Less considerations have to be taken than for the `undecipherableRanges`.
- */
- var rangesToRemove = getTimeRangesForContent(segmentBuffer, resettedContent);
- // First close all Stream currently active so they don't continue to
- // load and push segments.
- enableOutOfBoundsCheck = false;
- destroyStreams$.next();
- /** Remove from the `SegmentBuffer` all the concerned time ranges. */
- var cleanOperations = [].concat(undecipherableRanges, rangesToRemove).map(function (_ref3) {
- var start = _ref3.start,
- end = _ref3.end;
- if (start >= end) {
- return empty/* EMPTY */.E;
- }
- var canceller = new task_canceller/* default */.ZP();
- return fromCancellablePromise(canceller, function () {
- return segmentBuffer.removeBuffer(start, end, canceller.signal);
- }).pipe((0,ignoreElements/* ignoreElements */.l)());
- });
- return concat/* concat.apply */.z.apply(void 0, cleanOperations.concat([
- // Schedule micro task before checking the last playback observation
- // to reduce the risk of race conditions where the next observation
- // was going to be emitted synchronously.
- nextTickObs().pipe((0,ignoreElements/* ignoreElements */.l)()), playbackObserver.getReference().asObservable().pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.z)(function (observation) {
- var _a;
- var restartStream$ = (0,defer/* defer */.P)(function () {
- var _a;
- var lastPosition = (_a = observation.position.pending) !== null && _a !== void 0 ? _a : observation.position.last;
- var newInitialPeriod = manifest.getPeriodForTime(lastPosition);
- if (newInitialPeriod == null) {
- throw new media_error/* default */.Z("MEDIA_TIME_NOT_FOUND", "The wanted position is not found in the Manifest.");
+ /**
+ * React to a Manifest's decipherability updates.
+ * @param {Array.}
+ * @returns {Promise}
+ */
+ function onDecipherabilityUpdates(_x) {
+ return _onDecipherabilityUpdates.apply(this, arguments);
+ }
+ function _onDecipherabilityUpdates() {
+ _onDecipherabilityUpdates = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(updates) {
+ var segmentBufferStatus, ofCurrentType, segmentBuffer, resettedContent, undecipherableContent, undecipherableRanges, rangesToRemove, period, _i, _arr, _arr$_i, start, end;
+ return regenerator_default().wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ segmentBufferStatus = segmentBuffersStore.getStatus(bufferType);
+ ofCurrentType = updates.filter(function (update) {
+ return update.adaptation.type === bufferType;
+ });
+ if (!(
+ // No update concerns the current type of data
+ ofCurrentType.length === 0 || segmentBufferStatus.type !== "initialized" ||
+ // The update only notifies of now-decipherable streams
+ ofCurrentType.every(function (x) {
+ return x.representation.decipherable === true;
+ }))) {
+ _context.next = 4;
+ break;
+ }
+ return _context.abrupt("return");
+ case 4:
+ segmentBuffer = segmentBufferStatus.value;
+ resettedContent = ofCurrentType.filter(function (update) {
+ return update.representation.decipherable === undefined;
+ });
+ undecipherableContent = ofCurrentType.filter(function (update) {
+ return update.representation.decipherable === false;
+ });
+ /**
+ * Time ranges now containing undecipherable content.
+ * Those should first be removed and, depending on the platform, may
+ * need Supplementary actions as playback issues may remain even after
+ * removal.
+ */
+ undecipherableRanges = getTimeRangesForContent(segmentBuffer, undecipherableContent);
+ /**
+ * Time ranges now containing content whose decipherability status came
+ * back to being unknown.
+ * To simplify its handling, those are just removed from the buffer.
+ * Less considerations have to be taken than for the `undecipherableRanges`.
+ */
+ rangesToRemove = getTimeRangesForContent(segmentBuffer, resettedContent); // First close all Stream currently active so they don't continue to
+ // load and push segments.
+ enableOutOfBoundsCheck = false;
+ log/* default.info */.Z.info("Stream: Destroying all PeriodStreams for decipherability matters", bufferType);
+ while (periodList.length() > 0) {
+ period = periodList.get(periodList.length() - 1);
+ periodList.removeElement(period);
+ callbacks.periodStreamCleared({
+ type: bufferType,
+ period: period
+ });
+ }
+ currentCanceller.cancel();
+ currentCanceller = new task_canceller/* default */.ZP();
+ currentCanceller.linkToSignal(orchestratorCancelSignal);
+ /** Remove from the `SegmentBuffer` all the concerned time ranges. */
+ _i = 0, _arr = [].concat(undecipherableRanges, rangesToRemove);
+ case 16:
+ if (!(_i < _arr.length)) {
+ _context.next = 24;
+ break;
+ }
+ _arr$_i = _arr[_i], start = _arr$_i.start, end = _arr$_i.end;
+ if (!(start < end)) {
+ _context.next = 21;
+ break;
+ }
+ _context.next = 21;
+ return segmentBuffer.removeBuffer(start, end, orchestratorCancelSignal);
+ case 21:
+ _i++;
+ _context.next = 16;
+ break;
+ case 24:
+ // Schedule micro task before checking the last playback observation
+ // to reduce the risk of race conditions where the next observation
+ // was going to be emitted synchronously.
+ next_tick_default()(function () {
+ var _a, _b;
+ if (orchestratorCancelSignal.isCancelled()) {
+ return;
+ }
+ var observation = playbackObserver.getReference().getValue();
+ if (needsFlushingAfterClean(observation, undecipherableRanges)) {
+ var shouldAutoPlay = !((_a = observation.paused.pending) !== null && _a !== void 0 ? _a : playbackObserver.getIsPaused());
+ callbacks.needsDecipherabilityFlush({
+ position: observation.position.last,
+ autoPlay: shouldAutoPlay,
+ duration: observation.duration
+ });
+ if (orchestratorCancelSignal.isCancelled()) {
+ return;
+ }
+ } else if (needsFlushingAfterClean(observation, rangesToRemove)) {
+ callbacks.needsBufferFlush();
+ if (orchestratorCancelSignal.isCancelled()) {
+ return;
+ }
+ }
+ var lastPosition = (_b = observation.position.pending) !== null && _b !== void 0 ? _b : observation.position.last;
+ var newInitialPeriod = manifest.getPeriodForTime(lastPosition);
+ if (newInitialPeriod == null) {
+ callbacks.error(new media_error/* default */.Z("MEDIA_TIME_NOT_FOUND", "The wanted position is not found in the Manifest."));
+ return;
+ }
+ launchConsecutiveStreamsForPeriod(newInitialPeriod);
+ });
+ case 25:
+ case "end":
+ return _context.stop();
+ }
}
- return launchConsecutiveStreamsForPeriod(newInitialPeriod);
- });
- if (needsFlushingAfterClean(observation, undecipherableRanges)) {
- var shouldAutoPlay = !((_a = observation.paused.pending) !== null && _a !== void 0 ? _a : playbackObserver.getIsPaused());
- return (0,concat/* concat */.z)((0,of.of)(stream_events_generators/* default.needsDecipherabilityFlush */.Z.needsDecipherabilityFlush(observation.position.last, shouldAutoPlay, observation.duration)), restartStream$);
- } else if (needsFlushingAfterClean(observation, rangesToRemove)) {
- return (0,concat/* concat */.z)((0,of.of)(stream_events_generators/* default.needsBufferFlush */.Z.needsBufferFlush()), restartStream$);
- }
- return restartStream$;
- }))]));
+ }, _callee);
+ }));
+ return _onDecipherabilityUpdates.apply(this, arguments);
}
}
/**
* Create lazily consecutive PeriodStreams:
*
- * It first creates the PeriodStream for `basePeriod` and - once it becomes
+ * It first creates the `PeriodStream` for `basePeriod` and - once it becomes
* full - automatically creates the next chronological one.
- * This process repeats until the PeriodStream linked to the last Period is
+ * This process repeats until the `PeriodStream` linked to the last Period is
* full.
*
- * If an "old" PeriodStream becomes active again, it destroys all PeriodStream
- * coming after it (from the last chronological one to the first).
+ * If an "old" `PeriodStream` becomes active again, it destroys all
+ * `PeriodStream` coming after it (from the last chronological one to the
+ * first).
*
* To clean-up PeriodStreams, each one of them are also automatically
* destroyed once the current position is superior or equal to the end of
* the concerned Period.
*
- * A "periodStreamReady" event is sent each times a new PeriodStream is
- * created. The first one (for `basePeriod`) should be sent synchronously on
- * subscription.
+ * The "periodStreamReady" callback is alled each times a new `PeriodStream`
+ * is created.
*
- * A "periodStreamCleared" event is sent each times a PeriodStream is
- * destroyed.
+ * The "periodStreamCleared" callback is called each times a PeriodStream is
+ * destroyed (this callback is though not called if it was destroyed due to
+ * the given `cancelSignal` emitting or due to a fatal error).
* @param {string} bufferType - e.g. "audio" or "video"
* @param {Period} basePeriod - Initial Period downloaded.
- * @param {Observable} destroy$ - Emit when/if all created Streams from this
- * point should be destroyed.
- * @returns {Observable}
- */
- function manageConsecutivePeriodStreams(bufferType, basePeriod, destroy$) {
- log/* default.info */.Z.info("SO: Creating new Stream for", bufferType, basePeriod.start);
- // Emits the Period of the next Period Stream when it can be created.
- var createNextPeriodStream$ = new Subject/* Subject */.x();
- // Emits when the Streams for the next Periods should be destroyed, if
- // created.
- var destroyNextStreams$ = new Subject/* Subject */.x();
- // Emits when the current position goes over the end of the current Stream.
- var endOfCurrentStream$ = playbackObserver.getReference().asObservable().pipe((0,filter/* filter */.h)(function (_ref4) {
- var position = _ref4.position;
- var _a;
- return basePeriod.end != null && ((_a = position.pending) !== null && _a !== void 0 ? _a : position.last) >= basePeriod.end;
- }));
- // Create Period Stream for the next Period.
- var nextPeriodStream$ = createNextPeriodStream$.pipe(exhaustMap(function (nextPeriod) {
- return manageConsecutivePeriodStreams(bufferType, nextPeriod, destroyNextStreams$);
- }));
- // Allows to destroy each created Stream, from the newest to the oldest,
- // once destroy$ emits.
- var destroyAll$ = destroy$.pipe((0,take/* take */.q)(1), (0,tap/* tap */.b)(function () {
- // first complete createNextStream$ to allow completion of the
- // nextPeriodStream$ observable once every further Streams have been
- // cleared.
- createNextPeriodStream$.complete();
- // emit destruction signal to the next Stream first
- destroyNextStreams$.next();
- destroyNextStreams$.complete(); // we do not need it anymore
- }), (0,share/* share */.B)() // share side-effects
- );
- // Will emit when the current Stream should be destroyed.
- var killCurrentStream$ = (0,merge/* merge */.T)(endOfCurrentStream$, destroyAll$);
- var periodStream$ = period({
+ * @param {Object} consecutivePeriodStreamCb - Callbacks called on various
+ * events. See type for more information.
+ * @param {Object} cancelSignal - `CancellationSignal` allowing to stop
+ * everything that this function was doing. Callbacks in
+ * `consecutivePeriodStreamCb` might still be sent as a consequence of this
+ * signal emitting.
+ */
+ function manageConsecutivePeriodStreams(bufferType, basePeriod, consecutivePeriodStreamCb, cancelSignal) {
+ log/* default.info */.Z.info("Stream: Creating new Stream for", bufferType, basePeriod.start);
+ /**
+ * Contains properties linnked to the next chronological `PeriodStream` that
+ * may be created here.
+ */
+ var nextStreamInfo = null;
+ /** Emits when the `PeriodStream` linked to `basePeriod` should be destroyed. */
+ var currentStreamCanceller = new task_canceller/* default */.ZP();
+ currentStreamCanceller.linkToSignal(cancelSignal);
+ // Stop current PeriodStream when the current position goes over the end of
+ // that Period.
+ playbackObserver.listen(function (_ref2, stopListeningObservations) {
+ var position = _ref2.position;
+ var _a, _b;
+ if (basePeriod.end !== undefined && ((_a = position.pending) !== null && _a !== void 0 ? _a : position.last) >= basePeriod.end) {
+ log/* default.info */.Z.info("Stream: Destroying PeriodStream as the current playhead moved above it", bufferType, basePeriod.start, (_b = position.pending) !== null && _b !== void 0 ? _b : position.last, basePeriod.end);
+ stopListeningObservations();
+ consecutivePeriodStreamCb.periodStreamCleared({
+ type: bufferType,
+ period: basePeriod
+ });
+ currentStreamCanceller.cancel();
+ }
+ }, {
+ clearSignal: cancelSignal,
+ includeLastObservation: true
+ });
+ var periodStreamArgs = {
bufferType: bufferType,
content: {
manifest: manifest,
@@ -51207,27 +47512,58 @@ function StreamOrchestrator(content, playbackObserver, representationEstimator,
playbackObserver: playbackObserver,
representationEstimator: representationEstimator,
wantedBufferAhead: wantedBufferAhead
- }).pipe((0,mergeMap/* mergeMap */.z)(function (evt) {
- if (evt.type === "stream-status") {
- if (evt.value.hasFinishedLoading) {
+ };
+ var periodStreamCallbacks = Object.assign(Object.assign({}, consecutivePeriodStreamCb), {
+ streamStatusUpdate: function streamStatusUpdate(value) {
+ if (value.hasFinishedLoading) {
var nextPeriod = manifest.getPeriodAfter(basePeriod);
- if (nextPeriod === null) {
- return (0,concat/* concat */.z)((0,of.of)(evt), (0,of.of)(stream_events_generators/* default.streamComplete */.Z.streamComplete(bufferType)));
+ if (nextPeriod !== null) {
+ // current Stream is full, create the next one if not
+ createNextPeriodStream(nextPeriod);
}
- // current Stream is full, create the next one if not
- createNextPeriodStream$.next(nextPeriod);
- } else {
+ } else if (nextStreamInfo !== null) {
// current Stream is active, destroy next Stream if created
- destroyNextStreams$.next();
+ log/* default.info */.Z.info("Stream: Destroying next PeriodStream due to current one being active", bufferType, nextStreamInfo.period.start);
+ consecutivePeriodStreamCb.periodStreamCleared({
+ type: bufferType,
+ period: nextStreamInfo.period
+ });
+ nextStreamInfo.canceller.cancel();
+ nextStreamInfo = null;
}
+ consecutivePeriodStreamCb.streamStatusUpdate(value);
+ },
+ error: function error(err) {
+ if (nextStreamInfo !== null) {
+ nextStreamInfo.canceller.cancel();
+ nextStreamInfo = null;
+ }
+ currentStreamCanceller.cancel();
+ consecutivePeriodStreamCb.error(err);
+ }
+ });
+ period(periodStreamArgs, periodStreamCallbacks, currentStreamCanceller.signal);
+ /**
+ * Create `PeriodStream` for the next Period, specified under `nextPeriod`.
+ * @param {Object} nextPeriod
+ */
+ function createNextPeriodStream(nextPeriod) {
+ if (nextStreamInfo !== null) {
+ log/* default.warn */.Z.warn("Stream: Creating next `PeriodStream` while it was already created.");
+ consecutivePeriodStreamCb.periodStreamCleared({
+ type: bufferType,
+ period: nextStreamInfo.period
+ });
+ nextStreamInfo.canceller.cancel();
}
- return (0,of.of)(evt);
- }), (0,share/* share */.B)());
- // Stream for the current Period.
- var currentStream$ = (0,concat/* concat */.z)(periodStream$.pipe((0,takeUntil/* takeUntil */.R)(killCurrentStream$)), (0,of.of)(stream_events_generators/* default.periodStreamCleared */.Z.periodStreamCleared(bufferType, basePeriod)).pipe((0,tap/* tap */.b)(function () {
- log/* default.info */.Z.info("SO: Destroying Stream for", bufferType, basePeriod.start);
- })));
- return (0,merge/* merge */.T)(currentStream$, nextPeriodStream$, destroyAll$.pipe((0,ignoreElements/* ignoreElements */.l)()));
+ var nextStreamCanceller = new task_canceller/* default */.ZP();
+ nextStreamCanceller.linkToSignal(cancelSignal);
+ nextStreamInfo = {
+ canceller: nextStreamCanceller,
+ period: nextPeriod
+ };
+ manageConsecutivePeriodStreams(bufferType, nextPeriod, consecutivePeriodStreamCb, nextStreamInfo.canceller.signal);
+ }
}
}
/**
@@ -51284,9 +47620,14 @@ function needsFlushingAfterClean(observation, cleanedRanges) {
* limitations under the License.
*/
-
/* harmony default export */ var stream = (orchestrator);
-;// CONCATENATED MODULE: ./src/core/init/content_time_boundaries_observer.ts
+// EXTERNAL MODULE: ./src/core/init/types.ts
+var init_types = __webpack_require__(379);
+;// CONCATENATED MODULE: ./src/core/init/utils/content_time_boundaries_observer.ts
+
+function content_time_boundaries_observer_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = content_time_boundaries_observer_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
+function content_time_boundaries_observer_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return content_time_boundaries_observer_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return content_time_boundaries_observer_arrayLikeToArray(o, minLen); }
+function content_time_boundaries_observer_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
/**
* Copyright 2015 CANAL+ Group
*
@@ -51307,88 +47648,267 @@ function needsFlushingAfterClean(observation, cleanedRanges) {
-
-
-// NOTE As of now (RxJS 7.4.0), RxJS defines `ignoreElements` default
-// first type parameter as `any` instead of the perfectly fine `unknown`,
-// leading to linter issues, as it forbids the usage of `any`.
-// This is why we're disabling the eslint rule.
-/* eslint-disable @typescript-eslint/no-unsafe-argument */
/**
- * Observes the position and Adaptations being played and deduce various events
- * related to the available time boundaries:
- * - Emit when the theoretical duration of the content becomes known or when it
- * changes.
- * - Emit warnings when the duration goes out of what is currently
- * theoretically playable.
- *
- * @param {Object} manifest
- * @param {Object} lastAdaptationChange
- * @param {Object} playbackObserver
- * @returns {Observable}
+ * Observes what's being played and take care of media events relating to time
+ * boundaries:
+ * - Emits a `durationUpdate` when the duration of the current content is
+ * known and every time it changes.
+ * - Emits `endOfStream` API once segments have been pushed until the end and
+ * `resumeStream` if downloads starts back.
+ * - Emits a `periodChange` event when the currently-playing Period seemed to
+ * have changed.
+ * - emit "warning" events when what is being played is outside of the
+ * Manifest range.
+ * @class ContentTimeBoundariesObserver
*/
-function ContentTimeBoundariesObserver(manifest, lastAdaptationChange, playbackObserver) {
+var ContentTimeBoundariesObserver = /*#__PURE__*/function (_EventEmitter) {
+ (0,inheritsLoose/* default */.Z)(ContentTimeBoundariesObserver, _EventEmitter);
/**
- * Allows to calculate the minimum and maximum playable position on the
- * whole content.
+ * @param {Object} manifest
+ * @param {Object} playbackObserver
*/
- var maximumPositionCalculator = new MaximumPositionCalculator(manifest);
- // trigger warnings when the wanted time is before or after the manifest's
- // segments
- var outOfManifest$ = playbackObserver.getReference().asObservable().pipe((0,filter_map/* default */.Z)(function (_ref) {
- var position = _ref.position;
- var _a;
- var wantedPosition = (_a = position.pending) !== null && _a !== void 0 ? _a : position.last;
- if (wantedPosition < manifest.getMinimumSafePosition()) {
- var warning = new media_error/* default */.Z("MEDIA_TIME_BEFORE_MANIFEST", "The current position is behind the " + "earliest time announced in the Manifest.");
- return events_generators/* default.warning */.Z.warning(warning);
- } else if (wantedPosition > maximumPositionCalculator.getMaximumAvailablePosition()) {
- var _warning = new media_error/* default */.Z("MEDIA_TIME_AFTER_MANIFEST", "The current position is after the latest " + "time announced in the Manifest.");
- return events_generators/* default.warning */.Z.warning(_warning);
+ function ContentTimeBoundariesObserver(manifest, playbackObserver, bufferTypes) {
+ var _this;
+ _this = _EventEmitter.call(this) || this;
+ _this._canceller = new task_canceller/* default */.ZP();
+ _this._manifest = manifest;
+ _this._activeStreams = new Map();
+ _this._allBufferTypes = bufferTypes;
+ _this._lastCurrentPeriodId = null;
+ /**
+ * Allows to calculate the minimum and maximum playable position on the
+ * whole content.
+ */
+ var maximumPositionCalculator = new MaximumPositionCalculator(manifest);
+ _this._maximumPositionCalculator = maximumPositionCalculator;
+ var cancelSignal = _this._canceller.signal;
+ playbackObserver.listen(function (_ref) {
+ var position = _ref.position;
+ var _a;
+ var wantedPosition = (_a = position.pending) !== null && _a !== void 0 ? _a : position.last;
+ if (wantedPosition < manifest.getMinimumSafePosition()) {
+ var warning = new media_error/* default */.Z("MEDIA_TIME_BEFORE_MANIFEST", "The current position is behind the " + "earliest time announced in the Manifest.");
+ _this.trigger("warning", warning);
+ } else if (wantedPosition > maximumPositionCalculator.getMaximumAvailablePosition()) {
+ var _warning = new media_error/* default */.Z("MEDIA_TIME_AFTER_MANIFEST", "The current position is after the latest " + "time announced in the Manifest.");
+ _this.trigger("warning", _warning);
+ }
+ }, {
+ includeLastObservation: true,
+ clearSignal: cancelSignal
+ });
+ manifest.addEventListener("manifestUpdate", function () {
+ _this.trigger("durationUpdate", getManifestDuration());
+ if (cancelSignal.isCancelled()) {
+ return;
+ }
+ _this._checkEndOfStream();
+ }, cancelSignal);
+ function getManifestDuration() {
+ return manifest.isDynamic ? maximumPositionCalculator.getMaximumAvailablePosition() : maximumPositionCalculator.getEndingPosition();
}
- return null;
- }, null));
- /**
- * Contains the content duration according to the last audio and video
- * Adaptation chosen for the last Period.
- * `undefined` if unknown yet.
- */
- var contentDuration = (0,reference/* default */.ZP)(undefined);
- var updateDurationOnManifestUpdate$ = (0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,startWith/* startWith */.O)(null), (0,tap/* tap */.b)(function () {
- var duration = manifest.isDynamic ? maximumPositionCalculator.getEndingPosition() : maximumPositionCalculator.getMaximumAvailablePosition();
- contentDuration.setValue(duration);
- }), (0,ignoreElements/* ignoreElements */.l)());
- var updateDurationAndTimeBoundsOnTrackChange$ = lastAdaptationChange.asObservable().pipe((0,tap/* tap */.b)(function (message) {
- if (message === null || !manifest.isLastPeriodKnown) {
+ return _this;
+ }
+ /**
+ * Method to call any time an Adaptation has been selected.
+ *
+ * That Adaptation switch will be considered as active until the
+ * `onPeriodCleared` method has been called for the same `bufferType` and
+ * `Period`, or until `dispose` is called.
+ * @param {string} bufferType - The type of buffer concerned by the Adaptation
+ * switch
+ * @param {Object} period - The Period concerned by the Adaptation switch
+ * @param {Object|null} adaptation - The Adaptation selected. `null` if the
+ * absence of `Adaptation` has been explicitely selected for this Period and
+ * buffer type (e.g. no video).
+ */
+ var _proto = ContentTimeBoundariesObserver.prototype;
+ _proto.onAdaptationChange = function onAdaptationChange(bufferType, period, adaptation) {
+ if (this._manifest.isLastPeriodKnown) {
+ var lastPeriod = this._manifest.periods[this._manifest.periods.length - 1];
+ if (period.id === (lastPeriod === null || lastPeriod === void 0 ? void 0 : lastPeriod.id)) {
+ if (bufferType === "audio" || bufferType === "video") {
+ if (bufferType === "audio") {
+ this._maximumPositionCalculator.updateLastAudioAdaptation(adaptation);
+ } else {
+ this._maximumPositionCalculator.updateLastVideoAdaptation(adaptation);
+ }
+ var newDuration = this._manifest.isDynamic ? this._maximumPositionCalculator.getMaximumAvailablePosition() : this._maximumPositionCalculator.getEndingPosition();
+ this.trigger("durationUpdate", newDuration);
+ }
+ }
+ }
+ if (this._canceller.isUsed()) {
return;
}
- var lastPeriod = manifest.periods[manifest.periods.length - 1];
- if (message.value.period.id === (lastPeriod === null || lastPeriod === void 0 ? void 0 : lastPeriod.id)) {
- if (message.value.type === "audio" || message.value.type === "video") {
- if (message.value.type === "audio") {
- maximumPositionCalculator.updateLastAudioAdaptation(message.value.adaptation);
- } else {
- maximumPositionCalculator.updateLastVideoAdaptation(message.value.adaptation);
+ if (adaptation === null) {
+ this._addActivelyLoadedPeriod(period, bufferType);
+ }
+ }
+ /**
+ * Method to call any time a Representation has been selected.
+ *
+ * That Representation switch will be considered as active until the
+ * `onPeriodCleared` method has been called for the same `bufferType` and
+ * `Period`, or until `dispose` is called.
+ * @param {string} bufferType - The type of buffer concerned by the
+ * Representation switch
+ * @param {Object} period - The Period concerned by the Representation switch
+ */;
+ _proto.onRepresentationChange = function onRepresentationChange(bufferType, period) {
+ this._addActivelyLoadedPeriod(period, bufferType);
+ }
+ /**
+ * Method to call any time a Period and type combination is not considered
+ * anymore.
+ *
+ * Calling this method allows to signal that a previous Adaptation and/or
+ * Representation change respectively indicated by an `onAdaptationChange` and
+ * an `onRepresentationChange` call, are not active anymore.
+ * @param {string} bufferType - The type of buffer concerned
+ * @param {Object} period - The Period concerned
+ */;
+ _proto.onPeriodCleared = function onPeriodCleared(bufferType, period) {
+ this._removeActivelyLoadedPeriod(period, bufferType);
+ }
+ /**
+ * Method to call when the last chronological segment for a given buffer type
+ * is known to have been loaded and is either pushed or in the process of
+ * being pushed to the corresponding MSE `SourceBuffer` or equivalent.
+ *
+ * This method can even be called multiple times in a row as long as the
+ * aforementioned condition is true, if it simplify your code's management.
+ * @param {string} bufferType
+ */;
+ _proto.onLastSegmentFinishedLoading = function onLastSegmentFinishedLoading(bufferType) {
+ var streamInfo = this._lazilyCreateActiveStreamInfo(bufferType);
+ if (!streamInfo.hasFinishedLoadingLastPeriod) {
+ streamInfo.hasFinishedLoadingLastPeriod = true;
+ this._checkEndOfStream();
+ }
+ }
+ /**
+ * Method to call to "cancel" a previous call to
+ * `onLastSegmentFinishedLoading`.
+ *
+ * That is, calling this method indicates that the last chronological segment
+ * of a given buffer type is now either not loaded or it is not known.
+ *
+ * This method can even be called multiple times in a row as long as the
+ * aforementioned condition is true, if it simplify your code's management.
+ * @param {string} bufferType
+ */;
+ _proto.onLastSegmentLoadingResume = function onLastSegmentLoadingResume(bufferType) {
+ var streamInfo = this._lazilyCreateActiveStreamInfo(bufferType);
+ if (streamInfo.hasFinishedLoadingLastPeriod) {
+ streamInfo.hasFinishedLoadingLastPeriod = false;
+ this._checkEndOfStream();
+ }
+ }
+ /**
+ * Free all resources used by the `ContentTimeBoundariesObserver` and cancels
+ * all recurring processes it performs.
+ */;
+ _proto.dispose = function dispose() {
+ this.removeEventListener();
+ this._canceller.cancel();
+ };
+ _proto._addActivelyLoadedPeriod = function _addActivelyLoadedPeriod(period, bufferType) {
+ var streamInfo = this._lazilyCreateActiveStreamInfo(bufferType);
+ if (!streamInfo.activePeriods.has(period)) {
+ streamInfo.activePeriods.add(period);
+ this._checkCurrentPeriod();
+ }
+ };
+ _proto._removeActivelyLoadedPeriod = function _removeActivelyLoadedPeriod(period, bufferType) {
+ var streamInfo = this._activeStreams.get(bufferType);
+ if (streamInfo === undefined) {
+ return;
+ }
+ if (streamInfo.activePeriods.has(period)) {
+ streamInfo.activePeriods.removeElement(period);
+ this._checkCurrentPeriod();
+ }
+ };
+ _proto._checkCurrentPeriod = function _checkCurrentPeriod() {
+ var _this2 = this;
+ if (this._allBufferTypes.length === 0) {
+ return;
+ }
+ var streamInfo = this._activeStreams.get(this._allBufferTypes[0]);
+ if (streamInfo === undefined) {
+ return;
+ }
+ var _loop = function _loop() {
+ var period = _step.value;
+ var wasFoundInAllTypes = true;
+ for (var i = 1; i < _this2._allBufferTypes.length; i++) {
+ var streamInfo2 = _this2._activeStreams.get(_this2._allBufferTypes[i]);
+ if (streamInfo2 === undefined) {
+ return {
+ v: void 0
+ };
+ }
+ var activePeriods = streamInfo2.activePeriods.toArray();
+ var hasPeriod = activePeriods.some(function (p) {
+ return p.id === period.id;
+ });
+ if (!hasPeriod) {
+ wasFoundInAllTypes = false;
+ break;
}
- var newDuration = manifest.isDynamic ? maximumPositionCalculator.getMaximumAvailablePosition() : maximumPositionCalculator.getEndingPosition();
- contentDuration.setValue(newDuration);
}
- }
- }), (0,ignoreElements/* ignoreElements */.l)());
- return (0,merge/* merge */.T)(updateDurationOnManifestUpdate$, updateDurationAndTimeBoundsOnTrackChange$, outOfManifest$, contentDuration.asObservable().pipe(skipWhile(function (val) {
- return val === undefined;
- }), distinctUntilChanged(), (0,map/* map */.U)(function (value) {
- return {
- type: "contentDurationUpdate",
- value: value
+ if (wasFoundInAllTypes) {
+ if (_this2._lastCurrentPeriodId !== period.id) {
+ _this2._lastCurrentPeriodId = period.id;
+ _this2.trigger("periodChange", period);
+ }
+ return {
+ v: void 0
+ };
+ }
};
- })));
-}
+ for (var _iterator = content_time_boundaries_observer_createForOfIteratorHelperLoose(streamInfo.activePeriods.toArray()), _step; !(_step = _iterator()).done;) {
+ var _ret = _loop();
+ if (typeof _ret === "object") return _ret.v;
+ }
+ };
+ _proto._lazilyCreateActiveStreamInfo = function _lazilyCreateActiveStreamInfo(bufferType) {
+ var streamInfo = this._activeStreams.get(bufferType);
+ if (streamInfo === undefined) {
+ streamInfo = {
+ activePeriods: new SortedList(function (a, b) {
+ return a.start - b.start;
+ }),
+ hasFinishedLoadingLastPeriod: false
+ };
+ this._activeStreams.set(bufferType, streamInfo);
+ }
+ return streamInfo;
+ };
+ _proto._checkEndOfStream = function _checkEndOfStream() {
+ var _this3 = this;
+ if (!this._manifest.isLastPeriodKnown) {
+ return;
+ }
+ var everyBufferTypeLoaded = this._allBufferTypes.every(function (bt) {
+ var streamInfo = _this3._activeStreams.get(bt);
+ return streamInfo !== undefined && streamInfo.hasFinishedLoadingLastPeriod;
+ });
+ if (everyBufferTypeLoaded) {
+ this.trigger("endOfStream", null);
+ } else {
+ this.trigger("resumeStream", null);
+ }
+ };
+ return ContentTimeBoundariesObserver;
+}(event_emitter/* default */.Z);
/**
* Calculate the last position from the last chosen audio and video Adaptations
* for the last Period (or a default one, if no Adaptations has been chosen).
* @class MaximumPositionCalculator
*/
+
var MaximumPositionCalculator = /*#__PURE__*/function () {
/**
* @param {Object} manifest
@@ -51406,8 +47926,8 @@ var MaximumPositionCalculator = /*#__PURE__*/function () {
* `getMaximumAvailablePosition` and `getEndingPosition`.
* @param {Object|null} adaptation
*/
- var _proto = MaximumPositionCalculator.prototype;
- _proto.updateLastAudioAdaptation = function updateLastAudioAdaptation(adaptation) {
+ var _proto2 = MaximumPositionCalculator.prototype;
+ _proto2.updateLastAudioAdaptation = function updateLastAudioAdaptation(adaptation) {
this._lastAudioAdaptation = adaptation;
}
/**
@@ -51418,7 +47938,7 @@ var MaximumPositionCalculator = /*#__PURE__*/function () {
* `getMaximumAvailablePosition` and `getEndingPosition`.
* @param {Object|null} adaptation
*/;
- _proto.updateLastVideoAdaptation = function updateLastVideoAdaptation(adaptation) {
+ _proto2.updateLastVideoAdaptation = function updateLastVideoAdaptation(adaptation) {
this._lastVideoAdaptation = adaptation;
}
/**
@@ -51426,7 +47946,7 @@ var MaximumPositionCalculator = /*#__PURE__*/function () {
* segments are available) under the current circumstances.
* @returns {number}
*/;
- _proto.getMaximumAvailablePosition = function getMaximumAvailablePosition() {
+ _proto2.getMaximumAvailablePosition = function getMaximumAvailablePosition() {
var _a;
if (this._manifest.isDynamic) {
return (_a = this._manifest.getLivePosition()) !== null && _a !== void 0 ? _a : this._manifest.getMaximumSafePosition();
@@ -51465,7 +47985,7 @@ var MaximumPositionCalculator = /*#__PURE__*/function () {
* Returns `undefined` if that could not be determined, for various reasons.
* @returns {number|undefined}
*/;
- _proto.getEndingPosition = function getEndingPosition() {
+ _proto2.getEndingPosition = function getEndingPosition() {
var _a, _b;
if (!this._manifest.isDynamic) {
return this.getMaximumAvailablePosition();
@@ -51565,7 +48085,121 @@ function getEndingPositionFromAdaptation(adaptation) {
}
return min;
}
-;// CONCATENATED MODULE: ./src/core/init/create_stream_playback_observer.ts
+// EXTERNAL MODULE: ./src/compat/clear_element_src.ts
+var clear_element_src = __webpack_require__(5767);
+// EXTERNAL MODULE: ./src/compat/browser_compatibility_types.ts
+var browser_compatibility_types = __webpack_require__(3774);
+// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts
+var is_non_empty_string = __webpack_require__(6923);
+;// CONCATENATED MODULE: ./src/core/init/utils/create_media_source.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+
+
+
+/**
+ * Dispose of ressources taken by the MediaSource:
+ * - Clear the MediaSource' SourceBuffers
+ * - Clear the mediaElement's src (stop the mediaElement)
+ * - Revoke MediaSource' URL
+ * @param {HTMLMediaElement} mediaElement
+ * @param {MediaSource|null} mediaSource
+ * @param {string|null} mediaSourceURL
+ */
+function resetMediaSource(mediaElement, mediaSource, mediaSourceURL) {
+ if (mediaSource !== null && mediaSource.readyState !== "closed") {
+ var readyState = mediaSource.readyState,
+ sourceBuffers = mediaSource.sourceBuffers;
+ for (var i = sourceBuffers.length - 1; i >= 0; i--) {
+ var sourceBuffer = sourceBuffers[i];
+ try {
+ if (readyState === "open") {
+ log/* default.info */.Z.info("Init: Removing SourceBuffer from mediaSource");
+ sourceBuffer.abort();
+ }
+ mediaSource.removeSourceBuffer(sourceBuffer);
+ } catch (e) {
+ log/* default.warn */.Z.warn("Init: Error while disposing SourceBuffer", e instanceof Error ? e : "");
+ }
+ }
+ if (sourceBuffers.length > 0) {
+ log/* default.warn */.Z.warn("Init: Not all SourceBuffers could have been removed.");
+ }
+ }
+ (0,clear_element_src/* default */.Z)(mediaElement);
+ if (mediaSourceURL !== null) {
+ try {
+ log/* default.debug */.Z.debug("Init: Revoking previous URL");
+ URL.revokeObjectURL(mediaSourceURL);
+ } catch (e) {
+ log/* default.warn */.Z.warn("Init: Error while revoking the media source URL", e instanceof Error ? e : "");
+ }
+ }
+}
+/**
+ * Create a MediaSource instance and attach it to the given mediaElement element's
+ * src attribute.
+ *
+ * Returns a Promise which resolves with the MediaSource when created and attached
+ * to the `mediaElement` element.
+ *
+ * When the given `unlinkSignal` emits, mediaElement.src is cleaned, MediaSource
+ * SourceBuffers are aborted and some minor cleaning is done.
+ * @param {HTMLMediaElement} mediaElement
+ * @param {Object} unlinkSignal
+ * @returns {MediaSource}
+ */
+function createMediaSource(mediaElement, unlinkSignal) {
+ if (browser_compatibility_types/* MediaSource_ */.J == null) {
+ throw new media_error/* default */.Z("MEDIA_SOURCE_NOT_SUPPORTED", "No MediaSource Object was found in the current browser.");
+ }
+ // make sure the media has been correctly reset
+ var oldSrc = (0,is_non_empty_string/* default */.Z)(mediaElement.src) ? mediaElement.src : null;
+ resetMediaSource(mediaElement, null, oldSrc);
+ log/* default.info */.Z.info("Init: Creating MediaSource");
+ var mediaSource = new browser_compatibility_types/* MediaSource_ */.J();
+ var objectURL = URL.createObjectURL(mediaSource);
+ log/* default.info */.Z.info("Init: Attaching MediaSource URL to the media element", objectURL);
+ mediaElement.src = objectURL;
+ unlinkSignal.register(function () {
+ resetMediaSource(mediaElement, mediaSource, objectURL);
+ });
+ return mediaSource;
+}
+/**
+ * Create and open a new MediaSource object on the given media element.
+ * Resolves with the MediaSource when done.
+ *
+ * When the given `unlinkSignal` emits, mediaElement.src is cleaned, MediaSource
+ * SourceBuffers are aborted and some minor cleaning is done.
+ * @param {HTMLMediaElement} mediaElement
+ * @param {Object} unlinkSignal
+ * @returns {Promise}
+ */
+function openMediaSource(mediaElement, unlinkSignal) {
+ return (0,create_cancellable_promise/* default */.Z)(unlinkSignal, function (resolve) {
+ var mediaSource = createMediaSource(mediaElement, unlinkSignal);
+ event_listeners/* onSourceOpen */.u_(mediaSource, function () {
+ resolve(mediaSource);
+ }, unlinkSignal);
+ });
+}
+;// CONCATENATED MODULE: ./src/core/init/utils/create_stream_playback_observer.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -51596,7 +48230,7 @@ function createStreamPlaybackObserver(manifest, playbackObserver, _ref) {
speed = _ref.speed,
startTime = _ref.startTime;
return playbackObserver.deriveReadOnlyObserver(function transform(observationRef, cancellationSignal) {
- var newRef = (0,reference/* default */.ZP)(constructStreamPlaybackObservation());
+ var newRef = (0,reference/* default */.ZP)(constructStreamPlaybackObservation(), cancellationSignal);
speed.onUpdate(emitStreamPlaybackObservation, {
clearSignal: cancellationSignal,
emitCurrentValue: false
@@ -51605,9 +48239,6 @@ function createStreamPlaybackObserver(manifest, playbackObserver, _ref) {
clearSignal: cancellationSignal,
emitCurrentValue: false
});
- cancellationSignal.register(function () {
- newRef.finish();
- });
return newRef;
function constructStreamPlaybackObservation() {
var observation = observationRef.getValue();
@@ -51648,85 +48279,10 @@ function createStreamPlaybackObserver(manifest, playbackObserver, _ref) {
}
});
}
-// EXTERNAL MODULE: ./src/core/init/emit_loaded_event.ts + 1 modules
-var emit_loaded_event = __webpack_require__(5039);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/util/argsOrArgArray.js
-var argsOrArgArray_isArray = Array.isArray;
-function argsOrArgArray(args) {
- return args.length === 1 && argsOrArgArray_isArray(args[0]) ? args[0] : args;
-}
-//# sourceMappingURL=argsOrArgArray.js.map
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/race.js
-
-
-
-
-function race() {
- var sources = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- sources[_i] = arguments[_i];
- }
- sources = argsOrArgArray(sources);
- return sources.length === 1 ? (0,innerFrom/* innerFrom */.Xf)(sources[0]) : new Observable/* Observable */.y(raceInit(sources));
-}
-function raceInit(sources) {
- return function (subscriber) {
- var subscriptions = [];
- var _loop_1 = function (i) {
- subscriptions.push((0,innerFrom/* innerFrom */.Xf)(sources[i]).subscribe((0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, function (value) {
- if (subscriptions) {
- for (var s = 0; s < subscriptions.length; s++) {
- s !== i && subscriptions[s].unsubscribe();
- }
- subscriptions = null;
- }
- subscriber.next(value);
- })));
- };
- for (var i = 0; subscriptions && !subscriber.closed && i < sources.length; i++) {
- _loop_1(i);
- }
- };
-}
-//# sourceMappingURL=race.js.map
-// EXTERNAL MODULE: ./node_modules/rxjs/node_modules/tslib/tslib.es6.js
-var tslib_es6 = __webpack_require__(5987);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/takeLast.js
-
-
-
-
-function takeLast(count) {
- return count <= 0
- ? function () { return empty/* EMPTY */.E; }
- : (0,lift/* operate */.e)(function (source, subscriber) {
- var buffer = [];
- source.subscribe((0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, function (value) {
- buffer.push(value);
- count < buffer.length && buffer.shift();
- }, function () {
- var e_1, _a;
- try {
- for (var buffer_1 = (0,tslib_es6/* __values */.XA)(buffer), buffer_1_1 = buffer_1.next(); !buffer_1_1.done; buffer_1_1 = buffer_1.next()) {
- var value = buffer_1_1.value;
- subscriber.next(value);
- }
- }
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
- finally {
- try {
- if (buffer_1_1 && !buffer_1_1.done && (_a = buffer_1.return)) _a.call(buffer_1);
- }
- finally { if (e_1) throw e_1.error; }
- }
- subscriber.complete();
- }, undefined, function () {
- buffer = null;
- }));
- });
-}
-//# sourceMappingURL=takeLast.js.map
-;// CONCATENATED MODULE: ./src/core/init/end_of_stream.ts
+;// CONCATENATED MODULE: ./src/core/init/utils/end_of_stream.ts
+function end_of_stream_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = end_of_stream_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
+function end_of_stream_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return end_of_stream_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return end_of_stream_arrayLikeToArray(o, minLen); }
+function end_of_stream_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
/**
* Copyright 2015 CANAL+ Group
*
@@ -51745,9 +48301,9 @@ function takeLast(count) {
-var onRemoveSourceBuffers$ = event_listeners/* onRemoveSourceBuffers$ */.gg,
- end_of_stream_onSourceOpen$ = event_listeners/* onSourceOpen$ */.ym,
- onUpdate$ = event_listeners/* onUpdate$ */._E;
+var onRemoveSourceBuffers = event_listeners/* onRemoveSourceBuffers */.x6,
+ onSourceOpen = event_listeners/* onSourceOpen */.u_,
+ onSourceBufferUpdate = event_listeners/* onSourceBufferUpdate */.y4;
/**
* Get "updating" SourceBuffers from a SourceBufferList.
* @param {SourceBufferList} sourceBuffers
@@ -51770,63 +48326,155 @@ function getUpdatingSourceBuffers(sourceBuffers) {
* If SourceBuffers are updating, wait for them to be updated before closing
* it.
* @param {MediaSource} mediaSource
- * @returns {Observable}
- */
-function triggerEndOfStream(mediaSource) {
- return (0,defer/* defer */.P)(function () {
- log/* default.debug */.Z.debug("Init: Trying to call endOfStream");
- if (mediaSource.readyState !== "open") {
- log/* default.debug */.Z.debug("Init: MediaSource not open, cancel endOfStream");
- return (0,of.of)(null);
- }
- var sourceBuffers = mediaSource.sourceBuffers;
- var updatingSourceBuffers = getUpdatingSourceBuffers(sourceBuffers);
- if (updatingSourceBuffers.length === 0) {
- log/* default.info */.Z.info("Init: Triggering end of stream");
- mediaSource.endOfStream();
- return (0,of.of)(null);
- }
- log/* default.debug */.Z.debug("Init: Waiting SourceBuffers to be updated before calling endOfStream.");
- var updatedSourceBuffers$ = updatingSourceBuffers.map(function (sourceBuffer) {
- return onUpdate$(sourceBuffer).pipe((0,take/* take */.q)(1));
- });
- return race(merge/* merge.apply */.T.apply(void 0, updatedSourceBuffers$).pipe(takeLast(1)), onRemoveSourceBuffers$(sourceBuffers).pipe((0,take/* take */.q)(1))).pipe((0,mergeMap/* mergeMap */.z)(function () {
- return triggerEndOfStream(mediaSource);
- }));
- });
+ * @param {Object} cancelSignal
+ */
+function triggerEndOfStream(mediaSource, cancelSignal) {
+ log/* default.debug */.Z.debug("Init: Trying to call endOfStream");
+ if (mediaSource.readyState !== "open") {
+ log/* default.debug */.Z.debug("Init: MediaSource not open, cancel endOfStream");
+ return;
+ }
+ var sourceBuffers = mediaSource.sourceBuffers;
+ var updatingSourceBuffers = getUpdatingSourceBuffers(sourceBuffers);
+ if (updatingSourceBuffers.length === 0) {
+ log/* default.info */.Z.info("Init: Triggering end of stream");
+ mediaSource.endOfStream();
+ return;
+ }
+ log/* default.debug */.Z.debug("Init: Waiting SourceBuffers to be updated before calling endOfStream.");
+ var innerCanceller = new task_canceller/* default */.ZP();
+ innerCanceller.linkToSignal(cancelSignal);
+ for (var _iterator = end_of_stream_createForOfIteratorHelperLoose(updatingSourceBuffers), _step; !(_step = _iterator()).done;) {
+ var sourceBuffer = _step.value;
+ onSourceBufferUpdate(sourceBuffer, function () {
+ innerCanceller.cancel();
+ triggerEndOfStream(mediaSource, cancelSignal);
+ }, innerCanceller.signal);
+ }
+ onRemoveSourceBuffers(sourceBuffers, function () {
+ innerCanceller.cancel();
+ triggerEndOfStream(mediaSource, cancelSignal);
+ }, innerCanceller.signal);
}
/**
* Trigger the `endOfStream` method of a MediaSource each times it opens.
* @see triggerEndOfStream
* @param {MediaSource} mediaSource
- * @returns {Observable}
+ * @param {Object} cancelSignal
*/
-function maintainEndOfStream(mediaSource) {
- return end_of_stream_onSourceOpen$(mediaSource).pipe((0,startWith/* startWith */.O)(null), (0,switchMap/* switchMap */.w)(function () {
- return triggerEndOfStream(mediaSource);
- }));
+function maintainEndOfStream(mediaSource, cancelSignal) {
+ var endOfStreamCanceller = new task_canceller/* default */.ZP();
+ endOfStreamCanceller.linkToSignal(cancelSignal);
+ onSourceOpen(mediaSource, function () {
+ endOfStreamCanceller.cancel();
+ endOfStreamCanceller = new task_canceller/* default */.ZP();
+ endOfStreamCanceller.linkToSignal(cancelSignal);
+ triggerEndOfStream(mediaSource, endOfStreamCanceller.signal);
+ }, cancelSignal);
+ triggerEndOfStream(mediaSource, endOfStreamCanceller.signal);
}
-// EXTERNAL MODULE: ./src/core/init/initial_seek_and_play.ts + 2 modules
-var initial_seek_and_play = __webpack_require__(7920);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/timer.js
-var timer = __webpack_require__(6625);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/fromEvent.js
-var fromEvent = __webpack_require__(2401);
-// EXTERNAL MODULE: ./node_modules/rxjs/dist/esm5/internal/scheduler/async.js
-var scheduler_async = __webpack_require__(7991);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/observable/interval.js
+;// CONCATENATED MODULE: ./src/core/init/utils/get_initial_time.ts
+/**
+ * Copyright 2015 CANAL+ Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
-function interval(period, scheduler) {
- if (period === void 0) { period = 0; }
- if (scheduler === void 0) { scheduler = scheduler_async/* asyncScheduler */.z; }
- if (period < 0) {
- period = 0;
+
+/**
+ * Returns the calculated initial time for the content described by the given
+ * Manifest:
+ * 1. if a start time is defined by user, calculate starting time from the
+ * manifest information
+ * 2. else if the media is live, use the live edge and suggested delays from
+ * it
+ * 3. else returns the minimum time announced in the manifest
+ * @param {Manifest} manifest
+ * @param {boolean} lowLatencyMode
+ * @param {Object} startAt
+ * @returns {Number}
+ */
+function getInitialTime(manifest, lowLatencyMode, startAt) {
+ if (!(0,is_null_or_undefined/* default */.Z)(startAt)) {
+ var min = manifest.getMinimumSafePosition();
+ var max;
+ if (manifest.isLive) {
+ max = manifest.getLivePosition();
+ }
+ if (max === undefined) {
+ max = manifest.getMaximumSafePosition();
+ }
+ if (!(0,is_null_or_undefined/* default */.Z)(startAt.position)) {
+ log/* default.debug */.Z.debug("Init: using startAt.minimumPosition");
+ return Math.max(Math.min(startAt.position, max), min);
+ } else if (!(0,is_null_or_undefined/* default */.Z)(startAt.wallClockTime)) {
+ log/* default.debug */.Z.debug("Init: using startAt.wallClockTime");
+ var ast = manifest.availabilityStartTime === undefined ? 0 : manifest.availabilityStartTime;
+ var position = startAt.wallClockTime - ast;
+ return Math.max(Math.min(position, max), min);
+ } else if (!(0,is_null_or_undefined/* default */.Z)(startAt.fromFirstPosition)) {
+ log/* default.debug */.Z.debug("Init: using startAt.fromFirstPosition");
+ var fromFirstPosition = startAt.fromFirstPosition;
+ return fromFirstPosition <= 0 ? min : Math.min(max, min + fromFirstPosition);
+ } else if (!(0,is_null_or_undefined/* default */.Z)(startAt.fromLastPosition)) {
+ log/* default.debug */.Z.debug("Init: using startAt.fromLastPosition");
+ var fromLastPosition = startAt.fromLastPosition;
+ return fromLastPosition >= 0 ? max : Math.max(min, max + fromLastPosition);
+ } else if (!(0,is_null_or_undefined/* default */.Z)(startAt.percentage)) {
+ log/* default.debug */.Z.debug("Init: using startAt.percentage");
+ var percentage = startAt.percentage;
+ if (percentage > 100) {
+ return max;
+ } else if (percentage < 0) {
+ return min;
+ }
+ var ratio = +percentage / 100;
+ var extent = max - min;
+ return min + extent * ratio;
+ }
+ }
+ var minimumPosition = manifest.getMinimumSafePosition();
+ if (manifest.isLive) {
+ var suggestedPresentationDelay = manifest.suggestedPresentationDelay,
+ clockOffset = manifest.clockOffset;
+ var maximumPosition = manifest.getMaximumSafePosition();
+ var liveTime;
+ var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
+ DEFAULT_LIVE_GAP = _config$getCurrent.DEFAULT_LIVE_GAP;
+ if (clockOffset === undefined) {
+ log/* default.info */.Z.info("Init: no clock offset found for a live content, " + "starting close to maximum available position");
+ liveTime = maximumPosition;
+ } else {
+ log/* default.info */.Z.info("Init: clock offset found for a live content, " + "checking if we can start close to it");
+ var _ast = manifest.availabilityStartTime === undefined ? 0 : manifest.availabilityStartTime;
+ var clockRelativeLiveTime = (performance.now() + clockOffset) / 1000 - _ast;
+ liveTime = Math.min(maximumPosition, clockRelativeLiveTime);
}
- return (0,timer/* timer */.H)(period, period, scheduler);
+ var diffFromLiveTime = suggestedPresentationDelay !== undefined ? suggestedPresentationDelay : lowLatencyMode ? DEFAULT_LIVE_GAP.LOW_LATENCY : DEFAULT_LIVE_GAP.DEFAULT;
+ log/* default.debug */.Z.debug("Init: " + liveTime + " defined as the live time, applying a live gap" + (" of " + diffFromLiveTime));
+ return Math.max(liveTime - diffFromLiveTime, minimumPosition);
+ }
+ log/* default.info */.Z.info("Init: starting at the minimum available position:", minimumPosition);
+ return minimumPosition;
}
-//# sourceMappingURL=interval.js.map
-;// CONCATENATED MODULE: ./src/core/init/media_duration_updater.ts
+// EXTERNAL MODULE: ./src/core/init/utils/get_loaded_reference.ts + 1 modules
+var get_loaded_reference = __webpack_require__(1757);
+// EXTERNAL MODULE: ./src/core/init/utils/initial_seek_and_play.ts
+var initial_seek_and_play = __webpack_require__(8833);
+// EXTERNAL MODULE: ./src/core/init/utils/initialize_content_decryption.ts + 1 modules
+var initialize_content_decryption = __webpack_require__(8799);
+;// CONCATENATED MODULE: ./src/core/init/utils/media_duration_updater.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -51846,7 +48494,6 @@ function interval(period, scheduler) {
-
/** Number of seconds in a regular year. */
var YEAR_IN_SECONDS = 365 * 24 * 3600;
/**
@@ -51864,25 +48511,59 @@ var MediaDurationUpdater = /*#__PURE__*/function () {
* pushed.
*/
function MediaDurationUpdater(manifest, mediaSource) {
- var _this = this;
- this._lastKnownDuration = (0,reference/* default */.ZP)(undefined);
- this._subscription = isMediaSourceOpened$(mediaSource).pipe((0,switchMap/* switchMap */.w)(function (canUpdate) {
- return canUpdate ? combineLatest([_this._lastKnownDuration.asObservable(), (0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,startWith/* startWith */.O)(null))]) : empty/* EMPTY */.E;
- }), (0,switchMap/* switchMap */.w)(function (_ref) {
- var lastKnownDuration = _ref[0];
- return areSourceBuffersUpdating$(mediaSource.sourceBuffers).pipe((0,switchMap/* switchMap */.w)(function (areSBUpdating) {
- return areSBUpdating ? empty/* EMPTY */.E : recursivelyTryUpdatingDuration();
- function recursivelyTryUpdatingDuration() {
- var res = setMediaSourceDuration(mediaSource, manifest, lastKnownDuration);
- if (res === "success" /* MediaSourceDurationUpdateStatus.Success */) {
- return empty/* EMPTY */.E;
- }
- return (0,timer/* timer */.H)(2000).pipe((0,mergeMap/* mergeMap */.z)(function () {
- return recursivelyTryUpdatingDuration();
- }));
+ var canceller = new task_canceller/* default */.ZP();
+ var currentKnownDuration = (0,reference/* default */.ZP)(undefined, canceller.signal);
+ this._canceller = canceller;
+ this._currentKnownDuration = currentKnownDuration;
+ var isMediaSourceOpened = createMediaSourceOpenReference(mediaSource, this._canceller.signal);
+ /** TaskCanceller triggered each time the MediaSource open status changes. */
+ var msUpdateCanceller = new task_canceller/* default */.ZP();
+ msUpdateCanceller.linkToSignal(this._canceller.signal);
+ isMediaSourceOpened.onUpdate(onMediaSourceOpenedStatusChanged, {
+ emitCurrentValue: true,
+ clearSignal: this._canceller.signal
+ });
+ function onMediaSourceOpenedStatusChanged() {
+ msUpdateCanceller.cancel();
+ if (!isMediaSourceOpened.getValue()) {
+ return;
+ }
+ msUpdateCanceller = new task_canceller/* default */.ZP();
+ msUpdateCanceller.linkToSignal(canceller.signal);
+ /** TaskCanceller triggered each time the content's duration may have changed */
+ var durationChangeCanceller = new task_canceller/* default */.ZP();
+ durationChangeCanceller.linkToSignal(msUpdateCanceller.signal);
+ var reSetDuration = function reSetDuration() {
+ durationChangeCanceller.cancel();
+ durationChangeCanceller = new task_canceller/* default */.ZP();
+ durationChangeCanceller.linkToSignal(msUpdateCanceller.signal);
+ onDurationMayHaveChanged(durationChangeCanceller.signal);
+ };
+ currentKnownDuration.onUpdate(reSetDuration, {
+ emitCurrentValue: false,
+ clearSignal: msUpdateCanceller.signal
+ });
+ manifest.addEventListener("manifestUpdate", reSetDuration, msUpdateCanceller.signal);
+ onDurationMayHaveChanged(durationChangeCanceller.signal);
+ }
+ function onDurationMayHaveChanged(cancelSignal) {
+ var areSourceBuffersUpdating = createSourceBuffersUpdatingReference(mediaSource.sourceBuffers, cancelSignal);
+ /** TaskCanceller triggered each time SourceBuffers' updating status changes */
+ var sourceBuffersUpdatingCanceller = new task_canceller/* default */.ZP();
+ sourceBuffersUpdatingCanceller.linkToSignal(cancelSignal);
+ return areSourceBuffersUpdating.onUpdate(function (areUpdating) {
+ sourceBuffersUpdatingCanceller.cancel();
+ sourceBuffersUpdatingCanceller = new task_canceller/* default */.ZP();
+ sourceBuffersUpdatingCanceller.linkToSignal(cancelSignal);
+ if (areUpdating) {
+ return;
}
- }));
- })).subscribe();
+ recursivelyForceDurationUpdate(mediaSource, manifest, currentKnownDuration.getValue(), cancelSignal);
+ }, {
+ clearSignal: cancelSignal,
+ emitCurrentValue: true
+ });
+ }
}
/**
* By default, the `MediaDurationUpdater` only set a safe estimate for the
@@ -51895,7 +48576,7 @@ var MediaDurationUpdater = /*#__PURE__*/function () {
*/
var _proto = MediaDurationUpdater.prototype;
_proto.updateKnownDuration = function updateKnownDuration(newDuration) {
- this._lastKnownDuration.setValue(newDuration);
+ this._currentKnownDuration.setValueIfChanged(newDuration);
}
/**
* Stop the `MediaDurationUpdater` from updating and free its resources.
@@ -51903,7 +48584,7 @@ var MediaDurationUpdater = /*#__PURE__*/function () {
* `MediaDurationUpdater`.
*/;
_proto.stop = function stop() {
- this._subscription.unsubscribe();
+ this._canceller.cancel();
};
return MediaDurationUpdater;
}();
@@ -51925,18 +48606,20 @@ function setMediaSourceDuration(mediaSource, manifest, knownDuration) {
var newDuration = knownDuration;
if (newDuration === undefined) {
if (manifest.isDynamic) {
- var maxPotentialPos = (_a = manifest.getLivePosition()) !== null && _a !== void 0 ? _a : manifest.getMaximumSafePosition();
- // Some targets poorly support setting a very high number for durations.
- // Yet, in dynamic contents, we would prefer setting a value as high as possible
- // to still be able to seek anywhere we want to (even ahead of the Manifest if
- // we want to). As such, we put it at a safe default value of 2^32 excepted
- // when the maximum position is already relatively close to that value, where
- // we authorize exceptionally going over it.
- newDuration = Math.max(Math.pow(2, 32), maxPotentialPos + YEAR_IN_SECONDS);
+ newDuration = (_a = manifest.getLivePosition()) !== null && _a !== void 0 ? _a : manifest.getMaximumSafePosition();
} else {
newDuration = manifest.getMaximumSafePosition();
}
}
+ if (manifest.isDynamic) {
+ // Some targets poorly support setting a very high number for durations.
+ // Yet, in dynamic contents, we would prefer setting a value as high as possible
+ // to still be able to seek anywhere we want to (even ahead of the Manifest if
+ // we want to). As such, we put it at a safe default value of 2^32 excepted
+ // when the maximum position is already relatively close to that value, where
+ // we authorize exceptionally going over it.
+ newDuration = Math.max(Math.pow(2, 32), newDuration + YEAR_IN_SECONDS);
+ }
var maxBufferedEnd = 0;
for (var i = 0; i < mediaSource.sourceBuffers.length; i++) {
var sourceBuffer = mediaSource.sourceBuffers[i];
@@ -51953,7 +48636,7 @@ function setMediaSourceDuration(mediaSource, manifest, knownDuration) {
if (maxBufferedEnd < mediaSource.duration) {
try {
log/* default.info */.Z.info("Init: Updating duration to what is currently buffered", maxBufferedEnd);
- mediaSource.duration = newDuration;
+ mediaSource.duration = maxBufferedEnd;
} catch (err) {
log/* default.warn */.Z.warn("Duration Updater: Can't update duration on the MediaSource.", err instanceof Error ? err : "");
return "failed" /* MediaSourceDurationUpdateStatus.Failed */;
@@ -51981,68 +48664,91 @@ function setMediaSourceDuration(mediaSource, manifest, knownDuration) {
}
}
/**
- * Returns an Observable which will emit only when all the SourceBuffers ended
- * all pending updates.
+ * Returns an `ISharedReference` wrapping a boolean that tells if all the
+ * SourceBuffers ended all pending updates.
* @param {SourceBufferList} sourceBuffers
- * @returns {Observable}
+ * @param {Object} cancelSignal
+ * @returns {Object}
*/
-function areSourceBuffersUpdating$(sourceBuffers) {
+function createSourceBuffersUpdatingReference(sourceBuffers, cancelSignal) {
if (sourceBuffers.length === 0) {
- return (0,of.of)(false);
+ var notOpenedRef = (0,reference/* default */.ZP)(false);
+ notOpenedRef.finish();
+ return notOpenedRef;
}
- var sourceBufferUpdatingStatuses = [];
+ var areUpdatingRef = (0,reference/* default */.ZP)(false, cancelSignal);
+ reCheck();
var _loop = function _loop(i) {
var sourceBuffer = sourceBuffers[i];
- sourceBufferUpdatingStatuses.push((0,merge/* merge */.T)((0,fromEvent/* fromEvent */.R)(sourceBuffer, "updatestart").pipe((0,map/* map */.U)(function () {
- return true;
- })), (0,fromEvent/* fromEvent */.R)(sourceBuffer, "update").pipe((0,map/* map */.U)(function () {
- return false;
- })), interval(500).pipe((0,map/* map */.U)(function () {
- return sourceBuffer.updating;
- }))).pipe((0,startWith/* startWith */.O)(sourceBuffer.updating), distinctUntilChanged()));
+ sourceBuffer.addEventListener("updatestart", reCheck);
+ sourceBuffer.addEventListener("update", reCheck);
+ cancelSignal.register(function () {
+ sourceBuffer.removeEventListener("updatestart", reCheck);
+ sourceBuffer.removeEventListener("update", reCheck);
+ });
};
for (var i = 0; i < sourceBuffers.length; i++) {
_loop(i);
}
- return combineLatest(sourceBufferUpdatingStatuses).pipe((0,map/* map */.U)(function (areUpdating) {
- return areUpdating.some(function (isUpdating) {
- return isUpdating;
- });
- }), distinctUntilChanged());
+ return areUpdatingRef;
+ function reCheck() {
+ for (var _i = 0; _i < sourceBuffers.length; _i++) {
+ var sourceBuffer = sourceBuffers[_i];
+ if (sourceBuffer.updating) {
+ areUpdatingRef.setValueIfChanged(true);
+ return;
+ }
+ }
+ areUpdatingRef.setValueIfChanged(false);
+ }
}
/**
- * Emit a boolean that tells if the media source is opened or not.
+ * Returns an `ISharedReference` wrapping a boolean that tells if the media
+ * source is opened or not.
* @param {MediaSource} mediaSource
+ * @param {Object} cancelSignal
* @returns {Object}
*/
-function isMediaSourceOpened$(mediaSource) {
- return (0,merge/* merge */.T)((0,event_listeners/* onSourceOpen$ */.ym)(mediaSource).pipe((0,map/* map */.U)(function () {
- return true;
- })), (0,event_listeners/* onSourceEnded$ */.ep)(mediaSource).pipe((0,map/* map */.U)(function () {
- return false;
- })), (0,event_listeners/* onSourceClose$ */.UG)(mediaSource).pipe((0,map/* map */.U)(function () {
- return false;
- }))).pipe((0,startWith/* startWith */.O)(mediaSource.readyState === "open"), distinctUntilChanged());
-}
-// EXTERNAL MODULE: ./src/core/init/rebuffering_controller.ts + 1 modules
-var rebuffering_controller = __webpack_require__(342);
-;// CONCATENATED MODULE: ./node_modules/rxjs/dist/esm5/internal/operators/pairwise.js
-
-
-function pairwise() {
- return (0,lift/* operate */.e)(function (source, subscriber) {
- var prev;
- var hasPrev = false;
- source.subscribe((0,OperatorSubscriber/* createOperatorSubscriber */.x)(subscriber, function (value) {
- var p = prev;
- prev = value;
- hasPrev && subscriber.next([p, value]);
- hasPrev = true;
- }));
- });
+function createMediaSourceOpenReference(mediaSource, cancelSignal) {
+ var isMediaSourceOpen = (0,reference/* default */.ZP)(mediaSource.readyState === "open", cancelSignal);
+ (0,event_listeners/* onSourceOpen */.u_)(mediaSource, function () {
+ isMediaSourceOpen.setValueIfChanged(true);
+ }, cancelSignal);
+ (0,event_listeners/* onSourceEnded */.N8)(mediaSource, function () {
+ isMediaSourceOpen.setValueIfChanged(false);
+ }, cancelSignal);
+ (0,event_listeners/* onSourceClose */.k6)(mediaSource, function () {
+ isMediaSourceOpen.setValueIfChanged(false);
+ }, cancelSignal);
+ return isMediaSourceOpen;
+}
+/**
+ * Immediately tries to set the MediaSource's duration to the most appropriate
+ * one according to the Manifest and duration given.
+ *
+ * If it fails, wait 2 seconds and retries.
+ *
+ * @param {MediaSource} mediaSource
+ * @param {Object} manifest
+ * @param {number|undefined} duration
+ * @param {Object} cancelSignal
+ */
+function recursivelyForceDurationUpdate(mediaSource, manifest, duration, cancelSignal) {
+ var res = setMediaSourceDuration(mediaSource, manifest, duration);
+ if (res === "success" /* MediaSourceDurationUpdateStatus.Success */) {
+ return;
+ }
+ var timeoutId = setTimeout(function () {
+ unregisterClear();
+ recursivelyForceDurationUpdate(mediaSource, manifest, duration, cancelSignal);
+ }, 2000);
+ var unregisterClear = cancelSignal.register(function () {
+ clearTimeout(timeoutId);
+ });
}
-//# sourceMappingURL=pairwise.js.map
-;// CONCATENATED MODULE: ./src/core/init/stream_events_emitter/are_same_stream_events.ts
+// EXTERNAL MODULE: ./src/core/init/utils/rebuffering_controller.ts + 1 modules
+var rebuffering_controller = __webpack_require__(6199);
+;// CONCATENATED MODULE: ./src/core/init/utils/stream_events_emitter/are_same_stream_events.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -52076,7 +48782,7 @@ function areSameStreamEvents(evt1, evt2) {
return evt1.id === evt2.id && evt1.start === evt2.start && evt1.end === evt2.end;
}
/* harmony default export */ var are_same_stream_events = (areSameStreamEvents);
-;// CONCATENATED MODULE: ./src/core/init/stream_events_emitter/refresh_scheduled_events_list.ts
+;// CONCATENATED MODULE: ./src/core/init/utils/stream_events_emitter/refresh_scheduled_events_list.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -52151,7 +48857,10 @@ function refreshScheduledEventsList(oldScheduledEvents, manifest) {
return scheduledEvents;
}
/* harmony default export */ var refresh_scheduled_events_list = (refreshScheduledEventsList);
-;// CONCATENATED MODULE: ./src/core/init/stream_events_emitter/stream_events_emitter.ts
+;// CONCATENATED MODULE: ./src/core/init/utils/stream_events_emitter/stream_events_emitter.ts
+function stream_events_emitter_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = stream_events_emitter_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
+function stream_events_emitter_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return stream_events_emitter_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return stream_events_emitter_arrayLikeToArray(o, minLen); }
+function stream_events_emitter_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
/**
* Copyright 2015 CANAL+ Group
*
@@ -52171,35 +48880,76 @@ function refreshScheduledEventsList(oldScheduledEvents, manifest) {
-/**
- * Tells if a stream event has a duration
- * @param {Object} evt
- * @returns {Boolean}
- */
-function isFiniteStreamEvent(evt) {
- return evt.end !== undefined;
-}
/**
* Get events from manifest and emit each time an event has to be emitted
* @param {Object} manifest
* @param {HTMLMediaElement} mediaElement
- * @returns {Observable}
+ * @param {Object} playbackObserver
+ * @param {Function} onEvent
+ * @param {Function} onEventSkip
+ * @param {Object} cancelSignal
+ * @returns {Object}
*/
-function streamEventsEmitter(manifest, mediaElement, observation$) {
+function streamEventsEmitter(manifest, mediaElement, playbackObserver, onEvent, onEventSkip, cancelSignal) {
var eventsBeingPlayed = new WeakMap();
- var lastScheduledEvents = [];
- var scheduledEvents$ = (0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,startWith/* startWith */.O)(null), (0,scan/* scan */.R)(function (oldScheduledEvents) {
- return refresh_scheduled_events_list(oldScheduledEvents, manifest);
- }, []));
+ var scheduledEventsRef = (0,reference/* default */.ZP)(refresh_scheduled_events_list([], manifest), cancelSignal);
+ manifest.addEventListener("manifestUpdate", function () {
+ var prev = scheduledEventsRef.getValue();
+ scheduledEventsRef.setValue(refresh_scheduled_events_list(prev, manifest));
+ }, cancelSignal);
+ var isPollingEvents = false;
+ var cancelCurrentPolling = new task_canceller/* default */.ZP();
+ cancelCurrentPolling.linkToSignal(cancelSignal);
+ scheduledEventsRef.onUpdate(function (_ref) {
+ var scheduledEventsLength = _ref.length;
+ if (scheduledEventsLength === 0) {
+ if (isPollingEvents) {
+ cancelCurrentPolling.cancel();
+ cancelCurrentPolling = new task_canceller/* default */.ZP();
+ cancelCurrentPolling.linkToSignal(cancelSignal);
+ isPollingEvents = false;
+ }
+ return;
+ } else if (isPollingEvents) {
+ return;
+ }
+ isPollingEvents = true;
+ var oldObservation = constructObservation();
+ var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
+ STREAM_EVENT_EMITTER_POLL_INTERVAL = _config$getCurrent.STREAM_EVENT_EMITTER_POLL_INTERVAL;
+ var intervalId = setInterval(checkStreamEvents, STREAM_EVENT_EMITTER_POLL_INTERVAL);
+ playbackObserver.listen(checkStreamEvents, {
+ includeLastObservation: false,
+ clearSignal: cancelCurrentPolling.signal
+ });
+ cancelCurrentPolling.signal.register(function () {
+ clearInterval(intervalId);
+ });
+ function checkStreamEvents() {
+ var newObservation = constructObservation();
+ emitStreamEvents(scheduledEventsRef.getValue(), oldObservation, newObservation, cancelCurrentPolling.signal);
+ oldObservation = newObservation;
+ }
+ function constructObservation() {
+ var isSeeking = playbackObserver.getReference().getValue().seeking;
+ return {
+ currentTime: mediaElement.currentTime,
+ isSeeking: isSeeking
+ };
+ }
+ }, {
+ emitCurrentValue: true,
+ clearSignal: cancelSignal
+ });
/**
* Examine playback situation from playback observations to emit stream events and
* prepare set onExit callbacks if needed.
* @param {Array.} scheduledEvents
* @param {Object} oldObservation
* @param {Object} newObservation
- * @returns {Observable}
+ * @param {Object} stopSignal
*/
- function emitStreamEvents$(scheduledEvents, oldObservation, newObservation) {
+ function emitStreamEvents(scheduledEvents, oldObservation, newObservation, stopSignal) {
var previousTime = oldObservation.currentTime;
var isSeeking = newObservation.isSeeking,
currentTime = newObservation.currentTime;
@@ -52230,283 +48980,51 @@ function streamEventsEmitter(manifest, mediaElement, observation$) {
value: event.publicEvent
});
} else {
- eventsToSend.push({
- type: "stream-event",
- value: event.publicEvent
- });
- if (isFiniteStreamEvent(event)) {
- eventsToExit.push(event.publicEvent);
- }
- }
- }
- }
- return (0,concat/* concat */.z)(eventsToSend.length > 0 ? of.of.apply(void 0, eventsToSend) : empty/* EMPTY */.E, eventsToExit.length > 0 ? of.of.apply(void 0, eventsToExit).pipe((0,tap/* tap */.b)(function (evt) {
- if (typeof evt.onExit === "function") {
- evt.onExit();
- }
- }),
- // NOTE As of now (RxJS 7.4.0), RxJS defines `ignoreElements` default
- // first type parameter as `any` instead of the perfectly fine `unknown`,
- // leading to linter issues, as it forbids the usage of `any`.
- // This is why we're disabling the eslint rule.
- /* eslint-disable-next-line @typescript-eslint/no-unsafe-argument */
- (0,ignoreElements/* ignoreElements */.l)()) : empty/* EMPTY */.E);
- }
- /**
- * This pipe allows to control wether the polling should occur, if there
- * are scheduledEvents, or not.
- */
- return scheduledEvents$.pipe((0,tap/* tap */.b)(function (scheduledEvents) {
- return lastScheduledEvents = scheduledEvents;
- }), (0,map/* map */.U)(function (evt) {
- return evt.length > 0;
- }), distinctUntilChanged(), (0,switchMap/* switchMap */.w)(function (hasEvents) {
- if (!hasEvents) {
- return empty/* EMPTY */.E;
- }
- var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
- STREAM_EVENT_EMITTER_POLL_INTERVAL = _config$getCurrent.STREAM_EVENT_EMITTER_POLL_INTERVAL;
- return combineLatest([interval(STREAM_EVENT_EMITTER_POLL_INTERVAL).pipe((0,startWith/* startWith */.O)(null)), observation$]).pipe((0,map/* map */.U)(function (_ref) {
- var _ = _ref[0],
- observation = _ref[1];
- var seeking = observation.seeking;
- return {
- isSeeking: seeking,
- currentTime: mediaElement.currentTime
- };
- }), pairwise(), (0,mergeMap/* mergeMap */.z)(function (_ref2) {
- var oldObservation = _ref2[0],
- newObservation = _ref2[1];
- return emitStreamEvents$(lastScheduledEvents, oldObservation, newObservation);
- }));
- }));
-}
-/* harmony default export */ var stream_events_emitter = (streamEventsEmitter);
-;// CONCATENATED MODULE: ./src/core/init/stream_events_emitter/index.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* harmony default export */ var init_stream_events_emitter = (stream_events_emitter);
-;// CONCATENATED MODULE: ./src/core/init/load_on_media_source.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**
- * Returns a function allowing to load or reload the content in arguments into
- * a single or multiple MediaSources.
- * @param {Object} args
- * @returns {Function}
- */
-function createMediaSourceLoader(_ref) {
- var mediaElement = _ref.mediaElement,
- manifest = _ref.manifest,
- speed = _ref.speed,
- bufferOptions = _ref.bufferOptions,
- representationEstimator = _ref.representationEstimator,
- playbackObserver = _ref.playbackObserver,
- segmentFetcherCreator = _ref.segmentFetcherCreator;
- /**
- * Load the content on the given MediaSource.
- * @param {MediaSource} mediaSource
- * @param {number} initialTime
- * @param {boolean} autoPlay
- */
- return function loadContentOnMediaSource(mediaSource, initialTime, autoPlay) {
- var _a;
- /** Maintains the MediaSource's duration up-to-date with the Manifest */
- var mediaDurationUpdater = new MediaDurationUpdater(manifest, mediaSource);
- var initialPeriod = (_a = manifest.getPeriodForTime(initialTime)) !== null && _a !== void 0 ? _a : manifest.getNextPeriod(initialTime);
- if (initialPeriod === undefined) {
- var error = new media_error/* default */.Z("MEDIA_STARTING_TIME_NOT_FOUND", "Wanted starting time not found in the Manifest.");
- return (0,throwError/* throwError */._)(function () {
- return error;
- });
- }
- /** Interface to create media buffers. */
- var segmentBuffersStore = new segment_buffers(mediaElement, mediaSource);
- var _initialSeekAndPlay = (0,initial_seek_and_play/* default */.Z)({
- mediaElement: mediaElement,
- playbackObserver: playbackObserver,
- startTime: initialTime,
- mustAutoPlay: autoPlay
- }),
- seekAndPlay$ = _initialSeekAndPlay.seekAndPlay$,
- initialPlayPerformed = _initialSeekAndPlay.initialPlayPerformed,
- initialSeekPerformed = _initialSeekAndPlay.initialSeekPerformed;
- var observation$ = playbackObserver.getReference().asObservable();
- var streamEvents$ = initialPlayPerformed.asObservable().pipe((0,filter/* filter */.h)(function (hasPlayed) {
- return hasPlayed;
- }), (0,mergeMap/* mergeMap */.z)(function () {
- return init_stream_events_emitter(manifest, mediaElement, observation$);
- }));
- var streamObserver = createStreamPlaybackObserver(manifest, playbackObserver, {
- autoPlay: autoPlay,
- initialPlayPerformed: initialPlayPerformed,
- initialSeekPerformed: initialSeekPerformed,
- speed: speed,
- startTime: initialTime
- });
- /** Cancel endOfStream calls when streams become active again. */
- var cancelEndOfStream$ = new Subject/* Subject */.x();
- /** Emits discontinuities detected by the StreamOrchestrator. */
- var discontinuityUpdate$ = new Subject/* Subject */.x();
- /** Emits event when streams are "locked", meaning they cannot load segments. */
- var lockedStream$ = new Subject/* Subject */.x();
- /** Emit each time a new Adaptation is considered by the `StreamOrchestrator`. */
- var lastAdaptationChange = (0,reference/* default */.ZP)(null);
- // Creates Observable which will manage every Stream for the given Content.
- var streams$ = stream({
- manifest: manifest,
- initialPeriod: initialPeriod
- }, streamObserver, representationEstimator, segmentBuffersStore, segmentFetcherCreator, bufferOptions).pipe((0,mergeMap/* mergeMap */.z)(function (evt) {
- switch (evt.type) {
- case "end-of-stream":
- log/* default.debug */.Z.debug("Init: end-of-stream order received.");
- return maintainEndOfStream(mediaSource).pipe((0,ignoreElements/* ignoreElements */.l)(), (0,takeUntil/* takeUntil */.R)(cancelEndOfStream$));
- case "resume-stream":
- log/* default.debug */.Z.debug("Init: resume-stream order received.");
- cancelEndOfStream$.next(null);
- return empty/* EMPTY */.E;
- case "stream-status":
- var _evt$value = evt.value,
- period = _evt$value.period,
- bufferType = _evt$value.bufferType,
- imminentDiscontinuity = _evt$value.imminentDiscontinuity,
- position = _evt$value.position;
- discontinuityUpdate$.next({
- period: period,
- bufferType: bufferType,
- discontinuity: imminentDiscontinuity,
- position: position
+ eventsToSend.push({
+ type: "stream-event",
+ value: event.publicEvent
});
- return empty/* EMPTY */.E;
- case "locked-stream":
- lockedStream$.next(evt.value);
- return empty/* EMPTY */.E;
- case "adaptationChange":
- lastAdaptationChange.setValue(evt);
- return (0,of.of)(evt);
- default:
- return (0,of.of)(evt);
+ if (isFiniteStreamEvent(event)) {
+ eventsToExit.push(event.publicEvent);
+ }
+ }
}
- }));
- var contentTimeObserver = ContentTimeBoundariesObserver(manifest, lastAdaptationChange, streamObserver).pipe((0,mergeMap/* mergeMap */.z)(function (evt) {
- if (evt.type === "contentDurationUpdate") {
- log/* default.debug */.Z.debug("Init: Duration has to be updated.", evt.value);
- mediaDurationUpdater.updateKnownDuration(evt.value);
- return empty/* EMPTY */.E;
+ }
+ if (eventsToSend.length > 0) {
+ for (var _iterator = stream_events_emitter_createForOfIteratorHelperLoose(eventsToSend), _step; !(_step = _iterator()).done;) {
+ var _event = _step.value;
+ if (_event.type === "stream-event") {
+ onEvent(_event.value);
+ } else {
+ onEventSkip(_event.value);
+ }
+ if (stopSignal.isCancelled()) {
+ return;
+ }
}
- return (0,of.of)(evt);
- }));
- /**
- * Observable trying to avoid various stalling situations, emitting "stalled"
- * events when it cannot, as well as "unstalled" events when it get out of one.
- */
- var rebuffer$ = (0,rebuffering_controller/* default */.Z)(playbackObserver, manifest, speed, lockedStream$, discontinuityUpdate$);
- /**
- * Emit a "loaded" events once the initial play has been performed and the
- * media can begin playback.
- * Also emits warning events if issues arise when doing so.
- */
- var loadingEvts$ = seekAndPlay$.pipe((0,switchMap/* switchMap */.w)(function (evt) {
- return evt.type === "warning" ? (0,of.of)(evt) : (0,emit_loaded_event/* default */.Z)(observation$, mediaElement, segmentBuffersStore, false);
- }));
- return (0,merge/* merge */.T)(loadingEvts$, rebuffer$, streams$, contentTimeObserver, streamEvents$).pipe((0,finalize/* finalize */.x)(function () {
- mediaDurationUpdater.stop();
- // clean-up every created SegmentBuffers
- segmentBuffersStore.disposeAll();
- }));
- };
+ }
+ if (eventsToExit.length > 0) {
+ for (var _iterator2 = stream_events_emitter_createForOfIteratorHelperLoose(eventsToExit), _step2; !(_step2 = _iterator2()).done;) {
+ var _event2 = _step2.value;
+ if (typeof _event2.onExit === "function") {
+ _event2.onExit();
+ }
+ if (stopSignal.isCancelled()) {
+ return;
+ }
+ }
+ }
+ }
}
-;// CONCATENATED MODULE: ./src/utils/rx-throttle.ts
/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Tells if a stream event has a duration
+ * @param {Object} evt
+ * @returns {Boolean}
*/
-
-function throttle(func) {
- var isPending = false;
- return function () {
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
- return new Observable/* Observable */.y(function (obs) {
- if (isPending) {
- obs.complete();
- return undefined;
- }
- isPending = true;
- var funcSubscription = func.apply(void 0, args).subscribe({
- next: function next(i) {
- obs.next(i);
- },
- error: function error(e) {
- isPending = false;
- obs.error(e);
- },
- complete: function complete() {
- isPending = false;
- obs.complete();
- }
- });
- return function () {
- funcSubscription.unsubscribe();
- isPending = false;
- };
- });
- };
+function isFiniteStreamEvent(evt) {
+ return evt.end !== undefined;
}
-;// CONCATENATED MODULE: ./src/core/init/manifest_update_scheduler.ts
+;// CONCATENATED MODULE: ./src/core/init/utils/stream_events_emitter/index.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -52523,250 +49041,16 @@ function throttle(func) {
* limitations under the License.
*/
+/* harmony default export */ var stream_events_emitter = (streamEventsEmitter);
+// EXTERNAL MODULE: ./src/core/init/utils/throw_on_media_error.ts
+var throw_on_media_error = __webpack_require__(4576);
+;// CONCATENATED MODULE: ./src/core/init/media_source_content_initializer.ts
+function media_source_content_initializer_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = media_source_content_initializer_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
+function media_source_content_initializer_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return media_source_content_initializer_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return media_source_content_initializer_arrayLikeToArray(o, minLen); }
+function media_source_content_initializer_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
-/**
- * Refresh the Manifest at the right time.
- * @param {Object} manifestUpdateSchedulerArguments
- * @returns {Observable}
- */
-function manifestUpdateScheduler(_ref) {
- var initialManifest = _ref.initialManifest,
- manifestFetcher = _ref.manifestFetcher,
- minimumManifestUpdateInterval = _ref.minimumManifestUpdateInterval,
- scheduleRefresh$ = _ref.scheduleRefresh$;
- /**
- * Fetch and parse the manifest from the URL given.
- * Throttled to avoid doing multiple simultaneous requests.
- */
- var fetchManifest = throttle(function (manifestURL, options) {
- return manifestFetcher.fetch(manifestURL).pipe((0,mergeMap/* mergeMap */.z)(function (response) {
- return response.type === "warning" ? (0,of.of)(response) :
- // bubble-up warnings
- response.parse(options);
- }), (0,share/* share */.B)());
- });
- // The Manifest always keeps the same reference
- var manifest = initialManifest.manifest;
- /** Number of consecutive times the parsing has been done in `unsafeMode`. */
- var consecutiveUnsafeMode = 0;
- return (0,defer/* defer */.P)(function () {
- return handleManifestRefresh$(initialManifest);
- });
- /**
- * Performs Manifest refresh (recursively) when it judges it is time to do so.
- * @param {Object} manifestRequestInfos - Various information linked to the
- * Manifest loading and parsing operations.
- * @returns {Observable} - Observable which will automatically refresh the
- * Manifest on subscription. Can also emit warnings when minor errors are
- * encountered.
- */
- function handleManifestRefresh$(_ref2) {
- var sendingTime = _ref2.sendingTime,
- parsingTime = _ref2.parsingTime,
- updatingTime = _ref2.updatingTime;
- /**
- * Total time taken to fully update the last Manifest, in milliseconds.
- * Note: this time also includes possible requests done by the parsers.
- */
- var totalUpdateTime = parsingTime !== undefined ? parsingTime + (updatingTime !== null && updatingTime !== void 0 ? updatingTime : 0) : undefined;
- var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
- MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE = _config$getCurrent.MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE,
- MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE = _config$getCurrent.MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE;
- /**
- * "unsafeMode" is a mode where we unlock advanced Manifest parsing
- * optimizations with the added risk to lose some information.
- * `unsafeModeEnabled` is set to `true` when the `unsafeMode` is enabled.
- *
- * Only perform parsing in `unsafeMode` when the last full parsing took a
- * lot of time and do not go higher than the maximum consecutive time.
- */
- var unsafeModeEnabled = consecutiveUnsafeMode > 0 ? consecutiveUnsafeMode < MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE : totalUpdateTime !== undefined ? totalUpdateTime >= MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE : false;
- /** Time elapsed since the beginning of the Manifest request, in milliseconds. */
- var timeSinceRequest = sendingTime === undefined ? 0 : performance.now() - sendingTime;
- /** Minimum update delay we should not go below, in milliseconds. */
- var minInterval = Math.max(minimumManifestUpdateInterval - timeSinceRequest, 0);
- /** Emit when the RxPlayer determined that a refresh should be done. */
- var internalRefresh$ = scheduleRefresh$.pipe((0,mergeMap/* mergeMap */.z)(function (_ref3) {
- var completeRefresh = _ref3.completeRefresh,
- delay = _ref3.delay,
- canUseUnsafeMode = _ref3.canUseUnsafeMode;
- var unsafeMode = canUseUnsafeMode && unsafeModeEnabled;
- return startManualRefreshTimer(delay !== null && delay !== void 0 ? delay : 0, minimumManifestUpdateInterval, sendingTime).pipe((0,map/* map */.U)(function () {
- return {
- completeRefresh: completeRefresh,
- unsafeMode: unsafeMode
- };
- }));
- }));
- /** Emit when the Manifest tells us that it has "expired". */
- var expired$ = manifest.expired === null ? empty/* EMPTY */.E : (0,timer/* timer */.H)(minInterval).pipe((0,mergeMap/* mergeMap */.z)(function () {
- return manifest.expired === null ? empty/* EMPTY */.E : (0,from/* from */.D)(manifest.expired);
- }), (0,map/* map */.U)(function () {
- return {
- completeRefresh: true,
- unsafeMode: unsafeModeEnabled
- };
- }));
- /** Emit when the Manifest should normally be refreshed. */
- var autoRefresh$ = createAutoRefreshObservable();
- return (0,merge/* merge */.T)(autoRefresh$, internalRefresh$, expired$).pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.z)(function (_ref4) {
- var completeRefresh = _ref4.completeRefresh,
- unsafeMode = _ref4.unsafeMode;
- return refreshManifest({
- completeRefresh: completeRefresh,
- unsafeMode: unsafeMode
- });
- }), (0,mergeMap/* mergeMap */.z)(function (evt) {
- if (evt.type === "warning") {
- return (0,of.of)(evt);
- }
- return handleManifestRefresh$(evt);
- }));
- /**
- * Create an Observable that will emit when the Manifest needs to be
- * refreshed according to the Manifest's internal properties (parsing
- * time is also taken into account in this operation to avoid refreshing too
- * often).
- * @returns {Observable}
- */
- function createAutoRefreshObservable() {
- if (manifest.lifetime === undefined || manifest.lifetime < 0) {
- return empty/* EMPTY */.E;
- }
- /** Regular refresh delay as asked by the Manifest. */
- var regularRefreshDelay = manifest.lifetime * 1000 - timeSinceRequest;
- /** Actually choosen delay to refresh the Manifest. */
- var actualRefreshInterval;
- if (totalUpdateTime === undefined) {
- actualRefreshInterval = regularRefreshDelay;
- } else if (manifest.lifetime < 3 && totalUpdateTime >= 100) {
- // If Manifest update is very frequent and we take time to update it,
- // postpone it.
- actualRefreshInterval = Math.min(Math.max(
- // Take 3 seconds as a default safe value for a base interval.
- 3000 - timeSinceRequest,
- // Add update time to the original interval.
- Math.max(regularRefreshDelay, 0) + totalUpdateTime),
- // Limit the postponment's higher bound to a very high value relative
- // to `regularRefreshDelay`.
- // This avoid perpetually postponing a Manifest update when
- // performance seems to have been abysmal one time.
- regularRefreshDelay * 6);
- log/* default.info */.Z.info("MUS: Manifest update rythm is too frequent. Postponing next request.", regularRefreshDelay, actualRefreshInterval);
- } else if (totalUpdateTime >= manifest.lifetime * 1000 / 10) {
- // If Manifest updating time is very long relative to its lifetime,
- // postpone it:
- actualRefreshInterval = Math.min(
- // Just add the update time to the original waiting time
- Math.max(regularRefreshDelay, 0) + totalUpdateTime,
- // Limit the postponment's higher bound to a very high value relative
- // to `regularRefreshDelay`.
- // This avoid perpetually postponing a Manifest update when
- // performance seems to have been abysmal one time.
- regularRefreshDelay * 6);
- log/* default.info */.Z.info("MUS: Manifest took too long to parse. Postponing next request", actualRefreshInterval, actualRefreshInterval);
- } else {
- actualRefreshInterval = regularRefreshDelay;
- }
- return (0,timer/* timer */.H)(Math.max(actualRefreshInterval, minInterval)).pipe((0,map/* map */.U)(function () {
- return {
- completeRefresh: false,
- unsafeMode: unsafeModeEnabled
- };
- }));
- }
- }
- /**
- * Refresh the Manifest.
- * Perform a full update if a partial update failed.
- * @param {boolean} completeRefresh
- * @returns {Observable}
- */
- function refreshManifest(_ref5) {
- var completeRefresh = _ref5.completeRefresh,
- unsafeMode = _ref5.unsafeMode;
- var manifestUpdateUrl = manifest.updateUrl;
- var fullRefresh = completeRefresh || manifestUpdateUrl === undefined;
- var refreshURL = fullRefresh ? manifest.getUrl() : manifestUpdateUrl;
- var externalClockOffset = manifest.clockOffset;
- if (unsafeMode) {
- consecutiveUnsafeMode += 1;
- log/* default.info */.Z.info("Init: Refreshing the Manifest in \"unsafeMode\" for the " + String(consecutiveUnsafeMode) + " consecutive time.");
- } else if (consecutiveUnsafeMode > 0) {
- log/* default.info */.Z.info("Init: Not parsing the Manifest in \"unsafeMode\" anymore after " + String(consecutiveUnsafeMode) + " consecutive times.");
- consecutiveUnsafeMode = 0;
- }
- return fetchManifest(refreshURL, {
- externalClockOffset: externalClockOffset,
- previousManifest: manifest,
- unsafeMode: unsafeMode
- }).pipe((0,mergeMap/* mergeMap */.z)(function (value) {
- if (value.type === "warning") {
- return (0,of.of)(value);
- }
- var newManifest = value.manifest,
- newSendingTime = value.sendingTime,
- receivedTime = value.receivedTime,
- parsingTime = value.parsingTime;
- var updateTimeStart = performance.now();
- if (fullRefresh) {
- manifest.replace(newManifest);
- } else {
- try {
- manifest.update(newManifest);
- } catch (e) {
- var message = e instanceof Error ? e.message : "unknown error";
- log/* default.warn */.Z.warn("MUS: Attempt to update Manifest failed: " + message, "Re-downloading the Manifest fully");
- var _config$getCurrent2 = config/* default.getCurrent */.Z.getCurrent(),
- FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY = _config$getCurrent2.FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY;
- return startManualRefreshTimer(FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY, minimumManifestUpdateInterval, newSendingTime).pipe((0,mergeMap/* mergeMap */.z)(function () {
- return refreshManifest({
- completeRefresh: true,
- unsafeMode: false
- });
- }));
- }
- }
- return (0,of.of)({
- type: "parsed",
- manifest: manifest,
- sendingTime: newSendingTime,
- receivedTime: receivedTime,
- parsingTime: parsingTime,
- updatingTime: performance.now() - updateTimeStart
- });
- }));
- }
-}
-/**
- * Launch a timer Observable which will emit when it is time to refresh the
- * Manifest.
- * The timer's delay is calculated from:
- * - a target delay (`wantedDelay`), which is the minimum time we want to wait
- * in the best scenario
- * - the minimum set possible interval between manifest updates
- * (`minimumManifestUpdateInterval`)
- * - the time at which was done the last Manifest refresh
- * (`lastManifestRequestTime`)
- * @param {number} wantedDelay
- * @param {number} minimumManifestUpdateInterval
- * @param {number|undefined} lastManifestRequestTime
- * @returns {Observable}
- */
-function startManualRefreshTimer(wantedDelay, minimumManifestUpdateInterval, lastManifestRequestTime) {
- return (0,defer/* defer */.P)(function () {
- // The value allows to set a delay relatively to the last Manifest refresh
- // (to avoid asking for it too often).
- var timeSinceLastRefresh = lastManifestRequestTime === undefined ? 0 : performance.now() - lastManifestRequestTime;
- var _minInterval = Math.max(minimumManifestUpdateInterval - timeSinceLastRefresh, 0);
- return (0,timer/* timer */.H)(Math.max(wantedDelay - timeSinceLastRefresh, _minInterval));
- });
-}
-// EXTERNAL MODULE: ./src/core/init/throw_on_media_error.ts
-var throw_on_media_error = __webpack_require__(2447);
-;// CONCATENATED MODULE: ./src/core/init/initialize_media_source.ts
/**
* Copyright 2015 CANAL+ Group
*
@@ -52794,6 +49078,14 @@ var throw_on_media_error = __webpack_require__(2447);
+
+
+
+
+
+
+
+
@@ -52802,227 +49094,583 @@ var throw_on_media_error = __webpack_require__(2447);
/**
- * Begin content playback.
- *
- * Returns an Observable emitting notifications about the content lifecycle.
- * On subscription, it will perform every necessary tasks so the content can
- * play. Among them:
- *
- * - Creates a MediaSource on the given `mediaElement` and attach to it the
- * necessary SourceBuffer instances.
- *
- * - download the content's Manifest and handle its refresh logic
- *
- * - Perform decryption if needed
+ * Allows to load a new content thanks to the MediaSource Extensions (a.k.a. MSE)
+ * Web APIs.
*
- * - ask for the choice of the wanted Adaptation through events (e.g. to
- * choose a language)
+ * Through this `ContentInitializer`, a Manifest will be fetched (and depending
+ * on the situation, refreshed), a `MediaSource` instance will be linked to the
+ * wanted `HTMLMediaElement` and chunks of media data, called segments, will be
+ * pushed on buffers associated to this `MediaSource` instance.
*
- * - requests and push the right segments (according to the Adaptation choice,
- * the current position, the network conditions etc.)
- *
- * This Observable will throw in the case where a fatal error (i.e. which has
- * stopped content playback) is encountered, with the corresponding error as a
- * payload.
- *
- * This Observable will never complete, it will always run until it is
- * unsubscribed from.
- * Unsubscription will stop playback and reset the corresponding state.
- *
- * @param {Object} args
- * @returns {Observable}
+ * @class MediaSourceContentInitializer
*/
-function InitializeOnMediaSource(_ref) {
- var adaptiveOptions = _ref.adaptiveOptions,
- autoPlay = _ref.autoPlay,
- bufferOptions = _ref.bufferOptions,
- keySystems = _ref.keySystems,
- lowLatencyMode = _ref.lowLatencyMode,
- manifest$ = _ref.manifest$,
- manifestFetcher = _ref.manifestFetcher,
- mediaElement = _ref.mediaElement,
- minimumManifestUpdateInterval = _ref.minimumManifestUpdateInterval,
- playbackObserver = _ref.playbackObserver,
- segmentRequestOptions = _ref.segmentRequestOptions,
- speed = _ref.speed,
- startAt = _ref.startAt,
- transport = _ref.transport,
- textTrackOptions = _ref.textTrackOptions;
- /** Choose the right "Representation" for a given "Adaptation". */
- var representationEstimator = adaptive(adaptiveOptions);
- var playbackCanceller = new task_canceller/* default */.ZP();
- /**
- * Create and open a new MediaSource object on the given media element on
- * subscription.
- * Multiple concurrent subscriptions on this Observable will obtain the same
- * created MediaSource.
- * The MediaSource will be closed when subscriptions are down to 0.
- */
- var openMediaSource$ = openMediaSource(mediaElement).pipe((0,shareReplay/* shareReplay */.d)({
- refCount: true
- }));
- /** Send content protection initialization data. */
- var protectedSegments$ = new Subject/* Subject */.x();
- /** Initialize decryption capabilities and MediaSource. */
- var drmEvents$ = (0,link_drm_and_content/* default */.Z)(mediaElement, keySystems, protectedSegments$, openMediaSource$).pipe(
- // Because multiple Observables here depend on this Observable as a source,
- // we prefer deferring Subscription until those Observables are themselves
- // all subscribed to.
- // This is needed because `drmEvents$` might send events synchronously
- // on subscription. In that case, it might communicate those events directly
- // after the first Subscription is done, making the next subscription miss
- // out on those events, even if that second subscription is done
- // synchronously after the first one.
- // By calling `deferSubscriptions`, we ensure that subscription to
- // `drmEvents$` effectively starts after a very short delay, thus
- // ensuring that no such race condition can occur.
- (0,defer_subscriptions/* default */.Z)(), (0,share/* share */.B)());
- /**
- * Translate errors coming from the media element into RxPlayer errors
- * through a throwing Observable.
- */
- var mediaError$ = (0,throw_on_media_error/* default */.Z)(mediaElement);
- var mediaSourceReady$ = drmEvents$.pipe((0,filter/* filter */.h)(function (evt) {
- return evt.type === "decryption-ready" || evt.type === "decryption-disabled";
- }), (0,map/* map */.U)(function (e) {
- return e.value;
- }), (0,take/* take */.q)(1));
- /** Load and play the content asked. */
- var loadContent$ = combineLatest([manifest$, mediaSourceReady$]).pipe((0,mergeMap/* mergeMap */.z)(function (_ref2) {
- var manifestEvt = _ref2[0],
- _ref2$ = _ref2[1],
- drmSystemId = _ref2$.drmSystemId,
- initialMediaSource = _ref2$.mediaSource;
- if (manifestEvt.type === "warning") {
- return (0,of.of)(manifestEvt);
- }
- var manifest = manifestEvt.manifest;
- log/* default.debug */.Z.debug("Init: Calculating initial time");
- var initialTime = getInitialTime(manifest, lowLatencyMode, startAt);
- log/* default.debug */.Z.debug("Init: Initial time calculated:", initialTime);
- var requestOptions = {
- lowLatencyMode: lowLatencyMode,
- requestTimeout: segmentRequestOptions.requestTimeout,
- maxRetryRegular: segmentRequestOptions.regularError,
- maxRetryOffline: segmentRequestOptions.offlineError
- };
- var segmentFetcherCreator = new segment(transport, requestOptions, playbackCanceller.signal);
- var mediaSourceLoader = createMediaSourceLoader({
- bufferOptions: (0,object_assign/* default */.Z)({
- textTrackOptions: textTrackOptions,
- drmSystemId: drmSystemId
- }, bufferOptions),
- manifest: manifest,
- mediaElement: mediaElement,
- playbackObserver: playbackObserver,
- representationEstimator: representationEstimator,
- segmentFetcherCreator: segmentFetcherCreator,
- speed: speed
+var MediaSourceContentInitializer = /*#__PURE__*/function (_ContentInitializer) {
+ (0,inheritsLoose/* default */.Z)(MediaSourceContentInitializer, _ContentInitializer);
+ /**
+ * Create a new `MediaSourceContentInitializer`, associated to the given
+ * settings.
+ * @param {Object} settings
+ */
+ function MediaSourceContentInitializer(settings) {
+ var _this;
+ _this = _ContentInitializer.call(this) || this;
+ _this._settings = settings;
+ _this._initCanceller = new task_canceller/* default */.ZP();
+ _this._initialManifestProm = null;
+ var urls = settings.url === undefined ? undefined : [settings.url];
+ _this._manifestFetcher = new fetchers_manifest(urls, settings.transport, settings.manifestRequestSettings);
+ return _this;
+ }
+ /**
+ * Perform non-destructive preparation steps, to prepare a future content.
+ * For now, this mainly mean loading the Manifest document.
+ */
+ var _proto = MediaSourceContentInitializer.prototype;
+ _proto.prepare = function prepare() {
+ var _this2 = this;
+ if (this._initialManifestProm !== null) {
+ return;
+ }
+ this._initialManifestProm = (0,create_cancellable_promise/* default */.Z)(this._initCanceller.signal, function (res, rej) {
+ _this2._manifestFetcher.addEventListener("warning", function (err) {
+ return _this2.trigger("warning", err);
+ });
+ _this2._manifestFetcher.addEventListener("error", function (err) {
+ _this2.trigger("error", err);
+ rej(err);
+ });
+ _this2._manifestFetcher.addEventListener("manifestReady", function (manifest) {
+ res(manifest);
+ });
+ });
+ this._manifestFetcher.start();
+ this._initCanceller.signal.register(function () {
+ _this2._manifestFetcher.dispose();
+ });
+ }
+ /**
+ * @param {HTMLMediaElement} mediaElement
+ * @param {Object} playbackObserver
+ */;
+ _proto.start = function start(mediaElement, playbackObserver) {
+ var _this3 = this;
+ this.prepare(); // Load Manifest if not already done
+ /** Translate errors coming from the media element into RxPlayer errors. */
+ (0,throw_on_media_error/* default */.Z)(mediaElement, function (error) {
+ return _this3._onFatalError(error);
+ }, this._initCanceller.signal);
+ /** Send content protection initialization data to the decryption logic. */
+ var protectionRef = (0,reference/* default */.ZP)(null, this._initCanceller.signal);
+ this._initializeMediaSourceAndDecryption(mediaElement, protectionRef).then(function (initResult) {
+ return _this3._onInitialMediaSourceReady(mediaElement, initResult.mediaSource, playbackObserver, initResult.drmSystemId, protectionRef, initResult.unlinkMediaSource);
+ })["catch"](function (err) {
+ _this3._onFatalError(err);
});
- // handle initial load and reloads
- var recursiveLoad$ = recursivelyLoadOnMediaSource(initialMediaSource, initialTime, autoPlay);
- // Emit when we want to manually update the manifest.
- var scheduleRefresh$ = new Subject/* Subject */.x();
- var manifestUpdate$ = manifestUpdateScheduler({
- initialManifest: manifestEvt,
- manifestFetcher: manifestFetcher,
- minimumManifestUpdateInterval: minimumManifestUpdateInterval,
- scheduleRefresh$: scheduleRefresh$
+ }
+ /**
+ * Update URL of the Manifest.
+ * @param {Array.|undefined} urls - URLs to reach that Manifest from
+ * the most prioritized URL to the least prioritized URL.
+ * @param {boolean} refreshNow - If `true` the resource in question (e.g.
+ * DASH's MPD) will be refreshed immediately.
+ */;
+ _proto.updateContentUrls = function updateContentUrls(urls, refreshNow) {
+ this._manifestFetcher.updateContentUrls(urls, refreshNow);
+ };
+ _proto.dispose = function dispose() {
+ this._initCanceller.cancel();
+ };
+ _proto._onFatalError = function _onFatalError(err) {
+ if (this._initCanceller.isUsed()) {
+ return;
+ }
+ this._initCanceller.cancel();
+ this.trigger("error", err);
+ };
+ _proto._initializeMediaSourceAndDecryption = function _initializeMediaSourceAndDecryption(mediaElement, protectionRef) {
+ var _this4 = this;
+ var initCanceller = this._initCanceller;
+ return (0,create_cancellable_promise/* default */.Z)(initCanceller.signal, function (resolve) {
+ var keySystems = _this4._settings.keySystems;
+ /** Initialize decryption capabilities. */
+ var drmInitRef = (0,initialize_content_decryption/* default */.Z)(mediaElement, keySystems, protectionRef, {
+ onWarning: function onWarning(err) {
+ return _this4.trigger("warning", err);
+ },
+ onError: function onError(err) {
+ return _this4._onFatalError(err);
+ }
+ }, initCanceller.signal);
+ drmInitRef.onUpdate(function (drmStatus, stopListeningToDrmUpdates) {
+ if (drmStatus.initializationState.type === "uninitialized") {
+ return;
+ }
+ stopListeningToDrmUpdates();
+ var mediaSourceCanceller = new task_canceller/* default */.ZP();
+ mediaSourceCanceller.linkToSignal(initCanceller.signal);
+ openMediaSource(mediaElement, mediaSourceCanceller.signal).then(function (mediaSource) {
+ var lastDrmStatus = drmInitRef.getValue();
+ if (lastDrmStatus.initializationState.type === "awaiting-media-link") {
+ lastDrmStatus.initializationState.value.isMediaLinked.setValue(true);
+ drmInitRef.onUpdate(function (newDrmStatus, stopListeningToDrmUpdatesAgain) {
+ if (newDrmStatus.initializationState.type === "initialized") {
+ stopListeningToDrmUpdatesAgain();
+ resolve({
+ mediaSource: mediaSource,
+ drmSystemId: newDrmStatus.drmSystemId,
+ unlinkMediaSource: mediaSourceCanceller
+ });
+ return;
+ }
+ }, {
+ emitCurrentValue: true,
+ clearSignal: initCanceller.signal
+ });
+ } else if (drmStatus.initializationState.type === "initialized") {
+ resolve({
+ mediaSource: mediaSource,
+ drmSystemId: drmStatus.drmSystemId,
+ unlinkMediaSource: mediaSourceCanceller
+ });
+ return;
+ }
+ })["catch"](function (err) {
+ if (mediaSourceCanceller.isUsed()) {
+ return;
+ }
+ _this4._onFatalError(err);
+ });
+ }, {
+ emitCurrentValue: true,
+ clearSignal: initCanceller.signal
+ });
});
- var manifestEvents$ = (0,merge/* merge */.T)((0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,map/* map */.U)(function () {
- return events_generators/* default.manifestUpdate */.Z.manifestUpdate();
- })), (0,event_emitter/* fromEvent */.R)(manifest, "decipherabilityUpdate").pipe((0,map/* map */.U)(events_generators/* default.decipherabilityUpdate */.Z.decipherabilityUpdate)));
- return (0,merge/* merge */.T)(manifestEvents$, manifestUpdate$, recursiveLoad$).pipe((0,startWith/* startWith */.O)(events_generators/* default.manifestReady */.Z.manifestReady(manifest)), (0,finalize/* finalize */.x)(function () {
- scheduleRefresh$.complete();
+ };
+ _proto._onInitialMediaSourceReady = /*#__PURE__*/function () {
+ var _onInitialMediaSourceReady2 = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(mediaElement, initialMediaSource, playbackObserver, drmSystemId, protectionRef, initialMediaSourceCanceller) {
+ var _this5 = this;
+ var _this$_settings, adaptiveOptions, autoPlay, bufferOptions, lowLatencyMode, segmentRequestOptions, speed, startAt, textTrackOptions, transport, initCanceller, manifestProm, manifest, initialTime, representationEstimator, subBufferOptions, segmentFetcherCreator, bufferOnMediaSource, triggerEvent, onFatalError, recursivelyLoadOnMediaSource;
+ return regenerator_default().wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ recursivelyLoadOnMediaSource = function _recursivelyLoadOnMed(mediaSource, startingPos, shouldPlay, currentCanceller) {
+ var opts = {
+ mediaElement: mediaElement,
+ playbackObserver: playbackObserver,
+ mediaSource: mediaSource,
+ initialTime: startingPos,
+ autoPlay: shouldPlay,
+ manifest: manifest,
+ representationEstimator: representationEstimator,
+ segmentFetcherCreator: segmentFetcherCreator,
+ speed: speed,
+ protectionRef: protectionRef,
+ bufferOptions: subBufferOptions
+ };
+ bufferOnMediaSource(opts, onReloadMediaSource, currentCanceller.signal);
+ function onReloadMediaSource(reloadOrder) {
+ currentCanceller.cancel();
+ if (initCanceller.isUsed()) {
+ return;
+ }
+ triggerEvent("reloadingMediaSource", null);
+ if (initCanceller.isUsed()) {
+ return;
+ }
+ var newCanceller = new task_canceller/* default */.ZP();
+ newCanceller.linkToSignal(initCanceller.signal);
+ openMediaSource(mediaElement, newCanceller.signal).then(function (newMediaSource) {
+ recursivelyLoadOnMediaSource(newMediaSource, reloadOrder.position, reloadOrder.autoPlay, newCanceller);
+ })["catch"](function (err) {
+ if (newCanceller.isUsed()) {
+ return;
+ }
+ onFatalError(err);
+ });
+ }
+ };
+ _this$_settings = this._settings, adaptiveOptions = _this$_settings.adaptiveOptions, autoPlay = _this$_settings.autoPlay, bufferOptions = _this$_settings.bufferOptions, lowLatencyMode = _this$_settings.lowLatencyMode, segmentRequestOptions = _this$_settings.segmentRequestOptions, speed = _this$_settings.speed, startAt = _this$_settings.startAt, textTrackOptions = _this$_settings.textTrackOptions, transport = _this$_settings.transport;
+ initCanceller = this._initCanceller;
+ (0,assert/* default */.Z)(this._initialManifestProm !== null);
+ manifestProm = this._initialManifestProm;
+ _context.prev = 5;
+ _context.next = 8;
+ return manifestProm;
+ case 8:
+ manifest = _context.sent;
+ _context.next = 14;
+ break;
+ case 11:
+ _context.prev = 11;
+ _context.t0 = _context["catch"](5);
+ return _context.abrupt("return");
+ case 14:
+ manifest.addEventListener("manifestUpdate", function () {
+ _this5.trigger("manifestUpdate", null);
+ }, initCanceller.signal);
+ manifest.addEventListener("decipherabilityUpdate", function (args) {
+ _this5.trigger("decipherabilityUpdate", args);
+ }, initCanceller.signal);
+ log/* default.debug */.Z.debug("Init: Calculating initial time");
+ initialTime = getInitialTime(manifest, lowLatencyMode, startAt);
+ log/* default.debug */.Z.debug("Init: Initial time calculated:", initialTime);
+ /** Choose the right "Representation" for a given "Adaptation". */
+ representationEstimator = adaptive(adaptiveOptions);
+ subBufferOptions = (0,object_assign/* default */.Z)({
+ textTrackOptions: textTrackOptions,
+ drmSystemId: drmSystemId
+ }, bufferOptions);
+ segmentFetcherCreator = new segment(transport, segmentRequestOptions, initCanceller.signal);
+ this.trigger("manifestReady", manifest);
+ if (!initCanceller.isUsed()) {
+ _context.next = 25;
+ break;
+ }
+ return _context.abrupt("return");
+ case 25:
+ bufferOnMediaSource = this._startBufferingOnMediaSource.bind(this);
+ triggerEvent = this.trigger.bind(this);
+ onFatalError = this._onFatalError.bind(this); // handle initial load and reloads
+ recursivelyLoadOnMediaSource(initialMediaSource, initialTime, autoPlay, initialMediaSourceCanceller);
+ /**
+ * Load the content defined by the Manifest in the mediaSource given at the
+ * given position and playing status.
+ * This function recursively re-call itself when a MediaSource reload is
+ * wanted.
+ * @param {MediaSource} mediaSource
+ * @param {number} startingPos
+ * @param {Object} currentCanceller
+ * @param {boolean} shouldPlay
+ */
+ case 29:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee, this, [[5, 11]]);
}));
+ function _onInitialMediaSourceReady(_x, _x2, _x3, _x4, _x5, _x6) {
+ return _onInitialMediaSourceReady2.apply(this, arguments);
+ }
+ return _onInitialMediaSourceReady;
+ }()
+ /**
+ * Buffer the content on the given MediaSource.
+ * @param {Object} args
+ * @param {function} onReloadOrder
+ * @param {Object} cancelSignal
+ */
+ ;
+ _proto._startBufferingOnMediaSource = function _startBufferingOnMediaSource(args, onReloadOrder, cancelSignal) {
+ var _this6 = this;
+ var _a;
+ var autoPlay = args.autoPlay,
+ bufferOptions = args.bufferOptions,
+ initialTime = args.initialTime,
+ manifest = args.manifest,
+ mediaElement = args.mediaElement,
+ mediaSource = args.mediaSource,
+ playbackObserver = args.playbackObserver,
+ protectionRef = args.protectionRef,
+ representationEstimator = args.representationEstimator,
+ segmentFetcherCreator = args.segmentFetcherCreator,
+ speed = args.speed;
+ var initialPeriod = (_a = manifest.getPeriodForTime(initialTime)) !== null && _a !== void 0 ? _a : manifest.getNextPeriod(initialTime);
+ if (initialPeriod === undefined) {
+ var error = new media_error/* default */.Z("MEDIA_STARTING_TIME_NOT_FOUND", "Wanted starting time not found in the Manifest.");
+ return this._onFatalError(error);
+ }
+ /** Interface to create media buffers. */
+ var segmentBuffersStore = new segment_buffers(mediaElement, mediaSource);
+ cancelSignal.register(function () {
+ segmentBuffersStore.disposeAll();
+ });
+ var _performInitialSeekAn = (0,initial_seek_and_play/* default */.Z)(mediaElement, playbackObserver, initialTime, autoPlay, function (err) {
+ return _this6.trigger("warning", err);
+ }, cancelSignal),
+ autoPlayResult = _performInitialSeekAn.autoPlayResult,
+ initialPlayPerformed = _performInitialSeekAn.initialPlayPerformed,
+ initialSeekPerformed = _performInitialSeekAn.initialSeekPerformed;
+ if (cancelSignal.isCancelled()) {
+ return;
+ }
+ initialPlayPerformed.onUpdate(function (isPerformed, stopListening) {
+ if (isPerformed) {
+ stopListening();
+ stream_events_emitter(manifest, mediaElement, playbackObserver, function (evt) {
+ return _this6.trigger("streamEvent", evt);
+ }, function (evt) {
+ return _this6.trigger("streamEventSkip", evt);
+ }, cancelSignal);
+ }
+ }, {
+ clearSignal: cancelSignal,
+ emitCurrentValue: true
+ });
+ var streamObserver = createStreamPlaybackObserver(manifest, playbackObserver, {
+ autoPlay: autoPlay,
+ initialPlayPerformed: initialPlayPerformed,
+ initialSeekPerformed: initialSeekPerformed,
+ speed: speed,
+ startTime: initialTime
+ });
+ var rebufferingController = this._createRebufferingController(playbackObserver, manifest, speed, cancelSignal);
+ var contentTimeBoundariesObserver = this._createContentTimeBoundariesObserver(manifest, mediaSource, streamObserver, segmentBuffersStore, cancelSignal);
+ /**
+ * Emit a "loaded" events once the initial play has been performed and the
+ * media can begin playback.
+ * Also emits warning events if issues arise when doing so.
+ */
+ autoPlayResult.then(function () {
+ (0,get_loaded_reference/* default */.Z)(playbackObserver, mediaElement, false, cancelSignal).onUpdate(function (isLoaded, stopListening) {
+ if (isLoaded) {
+ stopListening();
+ _this6.trigger("loaded", {
+ segmentBuffersStore: segmentBuffersStore
+ });
+ }
+ }, {
+ emitCurrentValue: true,
+ clearSignal: cancelSignal
+ });
+ })["catch"](function (err) {
+ if (cancelSignal.isCancelled()) {
+ return; // Current loading cancelled, no need to trigger the error
+ }
+
+ _this6._onFatalError(err);
+ });
+ /* eslint-disable-next-line @typescript-eslint/no-this-alias */
+ var self = this;
+ stream({
+ manifest: manifest,
+ initialPeriod: initialPeriod
+ }, streamObserver, representationEstimator, segmentBuffersStore, segmentFetcherCreator, bufferOptions, handleStreamOrchestratorCallbacks(), cancelSignal);
/**
- * Load the content defined by the Manifest in the mediaSource given at the
- * given position and playing status.
- * This function recursively re-call itself when a MediaSource reload is
- * wanted.
- * @param {MediaSource} mediaSource
- * @param {number} startingPos
- * @param {boolean} shouldPlay
- * @returns {Observable}
+ * Returns Object handling the callbacks from a `StreamOrchestrator`, which
+ * are basically how it communicates about events.
+ * @returns {Object}
*/
- function recursivelyLoadOnMediaSource(mediaSource, startingPos, shouldPlay) {
- var reloadMediaSource$ = new Subject/* Subject */.x();
- var mediaSourceLoader$ = mediaSourceLoader(mediaSource, startingPos, shouldPlay).pipe((0,filter_map/* default */.Z)(function (evt) {
- switch (evt.type) {
- case "needs-manifest-refresh":
- scheduleRefresh$.next({
- completeRefresh: false,
- canUseUnsafeMode: true
- });
- return null;
- case "manifest-might-be-out-of-sync":
- var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
- OUT_OF_SYNC_MANIFEST_REFRESH_DELAY = _config$getCurrent.OUT_OF_SYNC_MANIFEST_REFRESH_DELAY;
- scheduleRefresh$.next({
- completeRefresh: true,
- canUseUnsafeMode: false,
- delay: OUT_OF_SYNC_MANIFEST_REFRESH_DELAY
- });
- return null;
- case "needs-media-source-reload":
- reloadMediaSource$.next(evt.value);
- return null;
- case "needs-decipherability-flush":
- var keySystem = get_current_key_system_getCurrentKeySystem(mediaElement);
- if (shouldReloadMediaSourceOnDecipherabilityUpdate(keySystem)) {
- reloadMediaSource$.next(evt.value);
- return null;
+ function handleStreamOrchestratorCallbacks() {
+ return {
+ needsBufferFlush: function needsBufferFlush() {
+ return playbackObserver.setCurrentTime(mediaElement.currentTime + 0.001);
+ },
+ streamStatusUpdate: function streamStatusUpdate(value) {
+ // Announce discontinuities if found
+ var period = value.period,
+ bufferType = value.bufferType,
+ imminentDiscontinuity = value.imminentDiscontinuity,
+ position = value.position;
+ rebufferingController.updateDiscontinuityInfo({
+ period: period,
+ bufferType: bufferType,
+ discontinuity: imminentDiscontinuity,
+ position: position
+ });
+ if (cancelSignal.isCancelled()) {
+ return; // Previous call has stopped streams due to a side-effect
+ }
+ // If the status for the last Period indicates that segments are all loaded
+ // or on the contrary that the loading resumed, announce it to the
+ // ContentTimeBoundariesObserver.
+ if (manifest.isLastPeriodKnown && value.period.id === manifest.periods[manifest.periods.length - 1].id) {
+ var hasFinishedLoadingLastPeriod = value.hasFinishedLoading || value.isEmptyStream;
+ if (hasFinishedLoadingLastPeriod) {
+ contentTimeBoundariesObserver.onLastSegmentFinishedLoading(value.bufferType);
+ } else {
+ contentTimeBoundariesObserver.onLastSegmentLoadingResume(value.bufferType);
}
+ }
+ },
+ needsManifestRefresh: function needsManifestRefresh() {
+ return self._manifestFetcher.scheduleManualRefresh({
+ enablePartialRefresh: true,
+ canUseUnsafeMode: true
+ });
+ },
+ manifestMightBeOufOfSync: function manifestMightBeOufOfSync() {
+ var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
+ OUT_OF_SYNC_MANIFEST_REFRESH_DELAY = _config$getCurrent.OUT_OF_SYNC_MANIFEST_REFRESH_DELAY;
+ self._manifestFetcher.scheduleManualRefresh({
+ enablePartialRefresh: false,
+ canUseUnsafeMode: false,
+ delay: OUT_OF_SYNC_MANIFEST_REFRESH_DELAY
+ });
+ },
+ lockedStream: function lockedStream(value) {
+ return rebufferingController.onLockedStream(value.bufferType, value.period);
+ },
+ adaptationChange: function adaptationChange(value) {
+ self.trigger("adaptationChange", value);
+ if (cancelSignal.isCancelled()) {
+ return; // Previous call has stopped streams due to a side-effect
+ }
+
+ contentTimeBoundariesObserver.onAdaptationChange(value.type, value.period, value.adaptation);
+ },
+ representationChange: function representationChange(value) {
+ self.trigger("representationChange", value);
+ if (cancelSignal.isCancelled()) {
+ return; // Previous call has stopped streams due to a side-effect
+ }
+
+ contentTimeBoundariesObserver.onRepresentationChange(value.type, value.period);
+ },
+ inbandEvent: function inbandEvent(value) {
+ return self.trigger("inbandEvents", value);
+ },
+ warning: function warning(value) {
+ return self.trigger("warning", value);
+ },
+ periodStreamReady: function periodStreamReady(value) {
+ return self.trigger("periodStreamReady", value);
+ },
+ periodStreamCleared: function periodStreamCleared(value) {
+ contentTimeBoundariesObserver.onPeriodCleared(value.type, value.period);
+ if (cancelSignal.isCancelled()) {
+ return; // Previous call has stopped streams due to a side-effect
+ }
+
+ self.trigger("periodStreamCleared", value);
+ },
+ bitrateEstimationChange: function bitrateEstimationChange(value) {
+ return self.trigger("bitrateEstimationChange", value);
+ },
+ addedSegment: function addedSegment(value) {
+ return self.trigger("addedSegment", value);
+ },
+ needsMediaSourceReload: function needsMediaSourceReload(value) {
+ return onReloadOrder(value);
+ },
+ needsDecipherabilityFlush: function needsDecipherabilityFlush(value) {
+ var keySystem = get_key_system_configuration_getKeySystemConfiguration(mediaElement);
+ if (shouldReloadMediaSourceOnDecipherabilityUpdate(keySystem === null || keySystem === void 0 ? void 0 : keySystem[0])) {
+ onReloadOrder(value);
+ } else {
// simple seek close to the current position
// to flush the buffers
- var position = evt.value.position;
- if (position + 0.001 < evt.value.duration) {
+ if (value.position + 0.001 < value.duration) {
playbackObserver.setCurrentTime(mediaElement.currentTime + 0.001);
} else {
- playbackObserver.setCurrentTime(position);
+ playbackObserver.setCurrentTime(value.position);
}
- return null;
- case "encryption-data-encountered":
- protectedSegments$.next(evt.value);
- return null;
- case "needs-buffer-flush":
- playbackObserver.setCurrentTime(mediaElement.currentTime + 0.001);
- return null;
+ }
+ },
+ encryptionDataEncountered: function encryptionDataEncountered(value) {
+ for (var _iterator = media_source_content_initializer_createForOfIteratorHelperLoose(value), _step; !(_step = _iterator()).done;) {
+ var protectionData = _step.value;
+ protectionRef.setValue(protectionData);
+ if (cancelSignal.isCancelled()) {
+ return; // Previous call has stopped streams due to a side-effect
+ }
+ }
+ },
+
+ error: function error(err) {
+ return self._onFatalError(err);
}
- return evt;
- }, null));
- var currentLoad$ = mediaSourceLoader$.pipe((0,takeUntil/* takeUntil */.R)(reloadMediaSource$));
- var handleReloads$ = reloadMediaSource$.pipe((0,switchMap/* switchMap */.w)(function (reloadOrder) {
- return openMediaSource(mediaElement).pipe((0,mergeMap/* mergeMap */.z)(function (newMS) {
- return recursivelyLoadOnMediaSource(newMS, reloadOrder.position, reloadOrder.autoPlay);
- }), (0,startWith/* startWith */.O)(events_generators/* default.reloadingMediaSource */.Z.reloadingMediaSource()));
- }));
- return (0,merge/* merge */.T)(handleReloads$, currentLoad$);
+ };
}
- }));
- return (0,merge/* merge */.T)(loadContent$, mediaError$, drmEvents$.pipe((0,ignoreElements/* ignoreElements */.l)())).pipe((0,finalize/* finalize */.x)(function () {
- playbackCanceller.cancel();
- }));
-}
-;// CONCATENATED MODULE: ./src/core/init/index.ts
-/**
- * Copyright 2015 CANAL+ Group
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
+ }
+ /**
+ * Creates a `ContentTimeBoundariesObserver`, a class indicating various
+ * events related to media time (such as duration updates, period changes,
+ * warnings about being out of the Manifest time boundaries or "endOfStream"
+ * management), handle those events and returns the class.
+ *
+ * Various methods from that class need then to be called at various events
+ * (see `ContentTimeBoundariesObserver`).
+ * @param {Object} manifest
+ * @param {MediaSource} mediaSource
+ * @param {Object} streamObserver
+ * @param {Object} segmentBuffersStore
+ * @param {Object} cancelSignal
+ * @returns {Object}
+ */;
+ _proto._createContentTimeBoundariesObserver = function _createContentTimeBoundariesObserver(manifest, mediaSource, streamObserver, segmentBuffersStore, cancelSignal) {
+ var _this7 = this;
+ /** Maintains the MediaSource's duration up-to-date with the Manifest */
+ var mediaDurationUpdater = new MediaDurationUpdater(manifest, mediaSource);
+ cancelSignal.register(function () {
+ mediaDurationUpdater.stop();
+ });
+ /** Allows to cancel a pending `end-of-stream` operation. */
+ var endOfStreamCanceller = null;
+ var contentTimeBoundariesObserver = new ContentTimeBoundariesObserver(manifest, streamObserver, segmentBuffersStore.getBufferTypes());
+ cancelSignal.register(function () {
+ contentTimeBoundariesObserver.dispose();
+ });
+ contentTimeBoundariesObserver.addEventListener("warning", function (err) {
+ return _this7.trigger("warning", err);
+ });
+ contentTimeBoundariesObserver.addEventListener("periodChange", function (period) {
+ _this7.trigger("activePeriodChanged", {
+ period: period
+ });
+ });
+ contentTimeBoundariesObserver.addEventListener("durationUpdate", function (newDuration) {
+ log/* default.debug */.Z.debug("Init: Duration has to be updated.", newDuration);
+ mediaDurationUpdater.updateKnownDuration(newDuration);
+ });
+ contentTimeBoundariesObserver.addEventListener("endOfStream", function () {
+ if (endOfStreamCanceller === null) {
+ endOfStreamCanceller = new task_canceller/* default */.ZP();
+ endOfStreamCanceller.linkToSignal(cancelSignal);
+ log/* default.debug */.Z.debug("Init: end-of-stream order received.");
+ maintainEndOfStream(mediaSource, endOfStreamCanceller.signal);
+ }
+ });
+ contentTimeBoundariesObserver.addEventListener("resumeStream", function () {
+ if (endOfStreamCanceller !== null) {
+ log/* default.debug */.Z.debug("Init: resume-stream order received.");
+ endOfStreamCanceller.cancel();
+ endOfStreamCanceller = null;
+ }
+ });
+ return contentTimeBoundariesObserver;
+ }
+ /**
+ * Creates a `RebufferingController`, a class trying to avoid various stalling
+ * situations (such as rebuffering periods), and returns it.
+ *
+ * Various methods from that class need then to be called at various events
+ * (see `RebufferingController` definition).
+ *
+ * This function also handles the `RebufferingController`'s events:
+ * - emit "stalled" events when stalling situations cannot be prevented,
+ * - emit "unstalled" events when we could get out of one,
+ * - emit "warning" on various rebuffering-related minor issues
+ * like discontinuity skipping.
+ * @param {Object} playbackObserver
+ * @param {Object} manifest
+ * @param {Object} speed
+ * @param {Object} cancelSignal
+ * @returns {Object}
+ */;
+ _proto._createRebufferingController = function _createRebufferingController(playbackObserver, manifest, speed, cancelSignal) {
+ var _this8 = this;
+ var rebufferingController = new rebuffering_controller/* default */.Z(playbackObserver, manifest, speed);
+ // Bubble-up events
+ rebufferingController.addEventListener("stalled", function (evt) {
+ return _this8.trigger("stalled", evt);
+ });
+ rebufferingController.addEventListener("unstalled", function () {
+ return _this8.trigger("unstalled", null);
+ });
+ rebufferingController.addEventListener("warning", function (err) {
+ return _this8.trigger("warning", err);
+ });
+ cancelSignal.register(function () {
+ return rebufferingController.destroy();
+ });
+ rebufferingController.start();
+ return rebufferingController;
+ };
+ return MediaSourceContentInitializer;
+}(init_types/* ContentInitializer */.K);
-/* harmony default export */ var init = (InitializeOnMediaSource);
// EXTERNAL MODULE: ./src/utils/languages/normalize.ts + 2 modules
var normalize = __webpack_require__(5553);
;// CONCATENATED MODULE: ./src/core/api/option_utils.ts
@@ -53298,7 +49946,7 @@ function checkReloadOptions(options) {
* @returns {Object}
*/
function parseLoadVideoOptions(options) {
- var _a, _b, _c, _d, _e, _f, _g;
+ var _a, _b, _c, _d, _e, _f, _g, _h;
var url;
var transport;
var keySystems;
@@ -53326,6 +49974,9 @@ function parseLoadVideoOptions(options) {
} else {
transport = String(options.transport);
}
+ if (!(0,is_null_or_undefined/* default */.Z)((_c = options.transportOptions) === null || _c === void 0 ? void 0 : _c.aggressiveMode)) {
+ (0,warn_once/* default */.Z)("`transportOptions.aggressiveMode` is deprecated and won't " + "be present in the next major version. " + "Please open an issue if you still need this.");
+ }
var autoPlay = (0,is_null_or_undefined/* default */.Z)(options.autoPlay) ? DEFAULT_AUTO_PLAY : !!options.autoPlay;
if ((0,is_null_or_undefined/* default */.Z)(options.keySystems)) {
keySystems = [];
@@ -53336,12 +49987,18 @@ function parseLoadVideoOptions(options) {
if (typeof keySystem.type !== "string" || typeof keySystem.getLicense !== "function") {
throw new Error("Invalid key system given: Missing type string or " + "getLicense callback");
}
+ if (!(0,is_null_or_undefined/* default */.Z)(keySystem.onKeyStatusesChange)) {
+ (0,warn_once/* default */.Z)("`keySystems[].onKeyStatusesChange` is deprecated and won't " + "be present in the next major version. " + "Please open an issue if you still need this.");
+ }
+ if (!(0,is_null_or_undefined/* default */.Z)(keySystem.throwOnLicenseExpiration)) {
+ (0,warn_once/* default */.Z)("`keySystems[].throwOnLicenseExpiration` is deprecated and won't " + "be present in the next major version. " + "Please open an issue if you still need this.");
+ }
}
}
var lowLatencyMode = options.lowLatencyMode === undefined ? false : !!options.lowLatencyMode;
var transportOptsArg = typeof options.transportOptions === "object" && options.transportOptions !== null ? options.transportOptions : {};
- var initialManifest = (_c = options.transportOptions) === null || _c === void 0 ? void 0 : _c.initialManifest;
- var minimumManifestUpdateInterval = (_e = (_d = options.transportOptions) === null || _d === void 0 ? void 0 : _d.minimumManifestUpdateInterval) !== null && _e !== void 0 ? _e : 0;
+ var initialManifest = (_d = options.transportOptions) === null || _d === void 0 ? void 0 : _d.initialManifest;
+ var minimumManifestUpdateInterval = (_f = (_e = options.transportOptions) === null || _e === void 0 ? void 0 : _e.minimumManifestUpdateInterval) !== null && _f !== void 0 ? _f : 0;
var audioTrackSwitchingMode = (0,is_null_or_undefined/* default */.Z)(options.audioTrackSwitchingMode) ? DEFAULT_AUDIO_TRACK_SWITCHING_MODE : options.audioTrackSwitchingMode;
if (!(0,array_includes/* default */.Z)(["seamless", "direct", "reload"], audioTrackSwitchingMode)) {
log/* default.warn */.Z.warn("The `audioTrackSwitchingMode` loadVideo option must match one of " + "the following strategy name:\n" + "- `seamless`\n" + "- `direct`\n" + "- `reload`\n" + "If badly set, " + DEFAULT_AUDIO_TRACK_SWITCHING_MODE + " strategy will be used as default");
@@ -53405,7 +50062,7 @@ function parseLoadVideoOptions(options) {
(0,warn_once/* default */.Z)("The `hideNativeSubtitle` loadVideo option is deprecated");
hideNativeSubtitle = !!options.hideNativeSubtitle;
}
- var manualBitrateSwitchingMode = (_f = options.manualBitrateSwitchingMode) !== null && _f !== void 0 ? _f : DEFAULT_MANUAL_BITRATE_SWITCHING_MODE;
+ var manualBitrateSwitchingMode = (_g = options.manualBitrateSwitchingMode) !== null && _g !== void 0 ? _g : DEFAULT_MANUAL_BITRATE_SWITCHING_MODE;
var enableFastSwitching = (0,is_null_or_undefined/* default */.Z)(options.enableFastSwitching) ? DEFAULT_ENABLE_FAST_SWITCHING : options.enableFastSwitching;
if (textTrackMode === "html") {
// TODO Better way to express that in TypeScript?
@@ -53430,7 +50087,7 @@ function parseLoadVideoOptions(options) {
startAt = options.startAt;
}
}
- var networkConfig = (_g = options.networkConfig) !== null && _g !== void 0 ? _g : {};
+ var networkConfig = (_h = options.networkConfig) !== null && _h !== void 0 ? _h : {};
// TODO without cast
/* eslint-disable @typescript-eslint/consistent-type-assertions */
return {
@@ -53495,8 +50152,8 @@ var SCANNED_MEDIA_ELEMENTS_EVENTS = ["canplay", "ended", "play", "pause", "seeki
* `PlaybackObserver` to know the current state of the media being played.
*
* You can use the PlaybackObserver to either get the last observation
- * performed, get the current media state or subscribe to an Observable emitting
- * regularly media conditions.
+ * performed, get the current media state or listen to media observation sent
+ * at a regular interval.
*
* @class {PlaybackObserver}
*/
@@ -53521,8 +50178,7 @@ var PlaybackObserver = /*#__PURE__*/function () {
}
/**
* Stop the `PlaybackObserver` from emitting playback observations and free all
- * resources reserved to emitting them such as event listeners, intervals and
- * subscribing callbacks.
+ * resources reserved to emitting them such as event listeners and intervals.
*
* Once `stop` is called, no new playback observation will ever be emitted.
*
@@ -53591,7 +50247,7 @@ var PlaybackObserver = /*#__PURE__*/function () {
* produced by the `PlaybackObserver` and updated each time a new one is
* produced.
*
- * This value can then be for example subscribed to to be notified of future
+ * This value can then be for example listened to to be notified of future
* playback observations.
*
* @returns {Object}
@@ -53610,7 +50266,7 @@ var PlaybackObserver = /*#__PURE__*/function () {
*/;
_proto.listen = function listen(cb, options) {
var _a;
- if (this._canceller.isUsed || ((_a = options === null || options === void 0 ? void 0 : options.clearSignal) === null || _a === void 0 ? void 0 : _a.isCancelled) === true) {
+ if (this._canceller.isUsed() || ((_a = options === null || options === void 0 ? void 0 : options.clearSignal) === null || _a === void 0 ? void 0 : _a.isCancelled()) === true) {
return noop/* default */.Z;
}
this._observationRef.onUpdate(cb, {
@@ -53638,7 +50294,7 @@ var PlaybackObserver = /*#__PURE__*/function () {
/**
* Creates the `IReadOnlySharedReference` that will generate playback
* observations.
- * @returns {Observable}
+ * @returns {Object}
*/;
_proto._createSharedReference = function _createSharedReference() {
var _this = this;
@@ -53682,7 +50338,7 @@ var PlaybackObserver = /*#__PURE__*/function () {
}
return timings;
};
- var returnedSharedReference = (0,reference/* default */.ZP)(getCurrentObservation("init"));
+ var returnedSharedReference = (0,reference/* default */.ZP)(getCurrentObservation("init"), this._canceller.signal);
var generateObservationForEvent = function generateObservationForEvent(event) {
var newObservation = getCurrentObservation(event);
if (log/* default.hasLevel */.Z.hasLevel("DEBUG")) {
@@ -54027,7 +50683,7 @@ function generateReadOnlyObserver(src, transform, cancellationSignal) {
},
listen: function listen(cb, options) {
var _a;
- if (cancellationSignal.isCancelled || ((_a = options === null || options === void 0 ? void 0 : options.clearSignal) === null || _a === void 0 ? void 0 : _a.isCancelled) === true) {
+ if (cancellationSignal.isCancelled() || ((_a = options === null || options === void 0 ? void 0 : options.clearSignal) === null || _a === void 0 ? void 0 : _a.isCancelled()) === true) {
return;
}
mappedRef.onUpdate(cb, {
@@ -54058,6 +50714,10 @@ var languages = __webpack_require__(7829);
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+/**
+ * This file is used to abstract the notion of text, audio and video tracks
+ * switching for an easier API management.
+ */
@@ -54090,6 +50750,7 @@ function normalizeTextTracks(tracks) {
return tracks.map(function (t) {
return t === null ? t : {
normalized: (0,languages/* default */.ZP)(t.language),
+ forced: t.forced,
closedCaption: t.closedCaption
};
});
@@ -54153,13 +50814,12 @@ var TrackChoiceManager = /*#__PURE__*/function () {
}
}
/**
- * Add Subject to choose Adaptation for new "audio" or "text" Period.
+ * Add shared reference to choose Adaptation for new "audio" or "text" Period.
* @param {string} bufferType - The concerned buffer type
* @param {Period} period - The concerned Period.
- * @param {Subject.} adaptation$ - A subject through which the
- * choice will be given
+ * @param {Object} adaptationRef
*/;
- _proto.addPeriod = function addPeriod(bufferType, period, adaptation$) {
+ _proto.addPeriod = function addPeriod(bufferType, period, adaptationRef) {
var periodItem = getPeriodItem(this._periods, period);
var adaptations = period.getSupportedAdaptations(bufferType);
if (periodItem !== undefined) {
@@ -54169,7 +50829,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
} else {
periodItem[bufferType] = {
adaptations: adaptations,
- adaptation$: adaptation$
+ adaptationRef: adaptationRef
};
}
} else {
@@ -54178,13 +50838,13 @@ var TrackChoiceManager = /*#__PURE__*/function () {
period: period
}, _this$_periods$add[bufferType] = {
adaptations: adaptations,
- adaptation$: adaptation$
+ adaptationRef: adaptationRef
}, _this$_periods$add));
}
}
/**
- * Remove Subject to choose an "audio", "video" or "text" Adaptation for a
- * Period.
+ * Remove shared reference to choose an "audio", "video" or "text" Adaptation
+ * for a Period.
* @param {string} bufferType - The concerned buffer type
* @param {Period} period - The concerned Period.
*/;
@@ -54220,7 +50880,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
this._resetChosenVideoTracks();
}
/**
- * Emit initial audio Adaptation through the given Subject based on:
+ * Emit initial audio Adaptation through the given shared reference based on:
* - the preferred audio tracks
* - the last choice for this period, if one
* @param {Period} period - The concerned Period.
@@ -54235,20 +50895,20 @@ var TrackChoiceManager = /*#__PURE__*/function () {
var chosenAudioAdaptation = this._audioChoiceMemory.get(period);
if (chosenAudioAdaptation === null) {
// If the Period was previously without audio, keep it that way
- audioInfos.adaptation$.next(null);
+ audioInfos.adaptationRef.setValue(null);
} else if (chosenAudioAdaptation === undefined || !(0,array_includes/* default */.Z)(audioAdaptations, chosenAudioAdaptation)) {
// Find the optimal audio Adaptation
var preferredAudioTracks = this._preferredAudioTracks;
var normalizedPref = normalizeAudioTracks(preferredAudioTracks);
var optimalAdaptation = findFirstOptimalAudioAdaptation(audioAdaptations, normalizedPref);
this._audioChoiceMemory.set(period, optimalAdaptation);
- audioInfos.adaptation$.next(optimalAdaptation);
+ audioInfos.adaptationRef.setValue(optimalAdaptation);
} else {
- audioInfos.adaptation$.next(chosenAudioAdaptation); // set last one
+ audioInfos.adaptationRef.setValue(chosenAudioAdaptation); // set last one
}
}
/**
- * Emit initial text Adaptation through the given Subject based on:
+ * Emit initial text Adaptation through the given shared reference based on:
* - the preferred text tracks
* - the last choice for this period, if one
* @param {Period} period - The concerned Period.
@@ -54263,20 +50923,20 @@ var TrackChoiceManager = /*#__PURE__*/function () {
var chosenTextAdaptation = this._textChoiceMemory.get(period);
if (chosenTextAdaptation === null) {
// If the Period was previously without text, keep it that way
- textInfos.adaptation$.next(null);
+ textInfos.adaptationRef.setValue(null);
} else if (chosenTextAdaptation === undefined || !(0,array_includes/* default */.Z)(textAdaptations, chosenTextAdaptation)) {
// Find the optimal text Adaptation
var preferredTextTracks = this._preferredTextTracks;
var normalizedPref = normalizeTextTracks(preferredTextTracks);
- var optimalAdaptation = findFirstOptimalTextAdaptation(textAdaptations, normalizedPref);
+ var optimalAdaptation = findFirstOptimalTextAdaptation(textAdaptations, normalizedPref, this._audioChoiceMemory.get(period));
this._textChoiceMemory.set(period, optimalAdaptation);
- textInfos.adaptation$.next(optimalAdaptation);
+ textInfos.adaptationRef.setValue(optimalAdaptation);
} else {
- textInfos.adaptation$.next(chosenTextAdaptation); // set last one
+ textInfos.adaptationRef.setValue(chosenTextAdaptation); // set last one
}
}
/**
- * Emit initial video Adaptation through the given Subject based on:
+ * Emit initial video Adaptation through the given shared reference based on:
* - the preferred video tracks
* - the last choice for this period, if one
* @param {Period} period - The concerned Period.
@@ -54303,7 +50963,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
}
if (newBaseAdaptation === null) {
this._videoChoiceMemory.set(period, null);
- videoInfos.adaptation$.next(null);
+ videoInfos.adaptationRef.setValue(null);
return;
}
var newVideoAdaptation = getRightVideoTrack(newBaseAdaptation, this.trickModeTrackEnabled);
@@ -54311,7 +50971,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
baseAdaptation: newBaseAdaptation,
adaptation: newVideoAdaptation
});
- videoInfos.adaptation$.next(newVideoAdaptation);
+ videoInfos.adaptationRef.setValue(newVideoAdaptation);
}
/**
* Set audio track based on the ID of its adaptation for a given added Period.
@@ -54336,7 +50996,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
return;
}
this._audioChoiceMemory.set(period, wantedAdaptation);
- audioInfos.adaptation$.next(wantedAdaptation);
+ audioInfos.adaptationRef.setValue(wantedAdaptation);
}
/**
* Set text track based on the ID of its adaptation for a given added Period.
@@ -54361,7 +51021,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
return;
}
this._textChoiceMemory.set(period, wantedAdaptation);
- textInfos.adaptation$.next(wantedAdaptation);
+ textInfos.adaptationRef.setValue(wantedAdaptation);
}
/**
* Set video track based on the ID of its adaptation for a given added Period.
@@ -54390,7 +51050,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
baseAdaptation: wantedBaseAdaptation,
adaptation: newVideoAdaptation
});
- videoInfos.adaptation$.next(newVideoAdaptation);
+ videoInfos.adaptationRef.setValue(newVideoAdaptation);
}
/**
* Disable the current text track for a given period.
@@ -54410,7 +51070,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
return;
}
this._textChoiceMemory.set(period, null);
- textInfos.adaptation$.next(null);
+ textInfos.adaptationRef.setValue(null);
}
/**
* Disable the current video track for a given period.
@@ -54428,7 +51088,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
return;
}
this._videoChoiceMemory.set(period, null);
- videoInfos.adaptation$.next(null);
+ videoInfos.adaptationRef.setValue(null);
};
_proto.disableVideoTrickModeTracks = function disableVideoTrickModeTracks() {
this.trickModeTrackEnabled = false;
@@ -54497,13 +51157,17 @@ var TrackChoiceManager = /*#__PURE__*/function () {
if ((0,is_null_or_undefined/* default */.Z)(chosenTextAdaptation)) {
return null;
}
- return {
+ var formatted = {
language: (0,take_first_set/* default */.Z)(chosenTextAdaptation.language, ""),
normalized: (0,take_first_set/* default */.Z)(chosenTextAdaptation.normalizedLanguage, ""),
closedCaption: chosenTextAdaptation.isClosedCaption === true,
id: chosenTextAdaptation.id,
label: chosenTextAdaptation.label
};
+ if (chosenTextAdaptation.isForcedSubtitles !== undefined) {
+ formatted.forced = chosenTextAdaptation.isForcedSubtitles;
+ }
+ return formatted;
}
/**
* Returns an object describing the chosen video track for the given video
@@ -54600,7 +51264,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
var chosenTextAdaptation = this._textChoiceMemory.get(period);
var currentId = !(0,is_null_or_undefined/* default */.Z)(chosenTextAdaptation) ? chosenTextAdaptation.id : null;
return textInfos.adaptations.map(function (adaptation) {
- return {
+ var formatted = {
language: (0,take_first_set/* default */.Z)(adaptation.language, ""),
normalized: (0,take_first_set/* default */.Z)(adaptation.normalizedLanguage, ""),
closedCaption: adaptation.isClosedCaption === true,
@@ -54608,6 +51272,10 @@ var TrackChoiceManager = /*#__PURE__*/function () {
active: currentId === null ? false : currentId === adaptation.id,
label: adaptation.label
};
+ if (adaptation.isForcedSubtitles !== undefined) {
+ formatted.forced = adaptation.isForcedSubtitles;
+ }
+ return formatted;
});
}
/**
@@ -54713,7 +51381,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
}
var optimalAdaptation = findFirstOptimalAudioAdaptation(audioAdaptations, normalizedPref);
_this._audioChoiceMemory.set(period, optimalAdaptation);
- audioItem.adaptation$.next(optimalAdaptation);
+ audioItem.adaptationRef.setValue(optimalAdaptation);
// previous "next" call could have changed everything, start over
recursiveUpdateAudioTrack(0);
};
@@ -54751,9 +51419,9 @@ var TrackChoiceManager = /*#__PURE__*/function () {
recursiveUpdateTextTrack(index + 1);
return;
}
- var optimalAdaptation = findFirstOptimalTextAdaptation(textAdaptations, normalizedPref);
+ var optimalAdaptation = findFirstOptimalTextAdaptation(textAdaptations, normalizedPref, _this2._audioChoiceMemory.get(period));
_this2._textChoiceMemory.set(period, optimalAdaptation);
- textItem.adaptation$.next(optimalAdaptation);
+ textItem.adaptationRef.setValue(optimalAdaptation);
// previous "next" call could have changed everything, start over
recursiveUpdateTextTrack(0);
};
@@ -54803,7 +51471,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
baseAdaptation: chosenVideoAdaptation.baseAdaptation,
adaptation: wantedVideoAdaptation
});
- videoItem.adaptation$.next(wantedVideoAdaptation);
+ videoItem.adaptationRef.setValue(wantedVideoAdaptation);
// previous "next" call could have changed everything, start over
return recursiveUpdateVideoTrack(0);
}
@@ -54811,7 +51479,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
var optimalAdaptation = findFirstOptimalVideoAdaptation(videoAdaptations, preferredVideoTracks);
if (optimalAdaptation === null) {
_this3._videoChoiceMemory.set(period, null);
- videoItem.adaptation$.next(null);
+ videoItem.adaptationRef.setValue(null);
// previous "next" call could have changed everything, start over
return recursiveUpdateVideoTrack(0);
}
@@ -54820,7 +51488,7 @@ var TrackChoiceManager = /*#__PURE__*/function () {
baseAdaptation: optimalAdaptation,
adaptation: newVideoAdaptation
});
- videoItem.adaptation$.next(newVideoAdaptation);
+ videoItem.adaptationRef.setValue(newVideoAdaptation);
// previous "next" call could have changed everything, start over
return recursiveUpdateVideoTrack(0);
};
@@ -54925,7 +51593,7 @@ function createTextPreferenceMatcher(preferredTextTrack) {
* @returns {boolean}
*/
return function matchTextPreference(textAdaptation) {
- return (0,take_first_set/* default */.Z)(textAdaptation.normalizedLanguage, "") === preferredTextTrack.normalized && (preferredTextTrack.closedCaption ? textAdaptation.isClosedCaption === true : textAdaptation.isClosedCaption !== true);
+ return (0,take_first_set/* default */.Z)(textAdaptation.normalizedLanguage, "") === preferredTextTrack.normalized && (preferredTextTrack.closedCaption ? textAdaptation.isClosedCaption === true : textAdaptation.isClosedCaption !== true) && (preferredTextTrack.forced === true ? textAdaptation.isForcedSubtitles === true : textAdaptation.isForcedSubtitles !== true);
};
}
/**
@@ -54935,9 +51603,11 @@ function createTextPreferenceMatcher(preferredTextTrack) {
* `null` if the most optimal text adaptation is no text adaptation.
* @param {Array.} textAdaptations
* @param {Array.} preferredTextTracks
+ * @param {Object|null|undefined} chosenAudioAdaptation
* @returns {Adaptation|null}
*/
-function findFirstOptimalTextAdaptation(textAdaptations, preferredTextTracks) {
+function findFirstOptimalTextAdaptation(textAdaptations, preferredTextTracks, chosenAudioAdaptation) {
+ var _a;
if (textAdaptations.length === 0) {
return null;
}
@@ -54952,6 +51622,22 @@ function findFirstOptimalTextAdaptation(textAdaptations, preferredTextTracks) {
return foundAdaptation;
}
}
+ var forcedSubtitles = textAdaptations.filter(function (ad) {
+ return ad.isForcedSubtitles === true;
+ });
+ if (forcedSubtitles.length > 0) {
+ if (chosenAudioAdaptation !== null && chosenAudioAdaptation !== undefined) {
+ var sameLanguage = (0,array_find/* default */.Z)(forcedSubtitles, function (f) {
+ return f.normalizedLanguage === chosenAudioAdaptation.normalizedLanguage;
+ });
+ if (sameLanguage !== undefined) {
+ return sameLanguage;
+ }
+ }
+ return (_a = (0,array_find/* default */.Z)(forcedSubtitles, function (f) {
+ return f.normalizedLanguage === undefined;
+ })) !== null && _a !== void 0 ? _a : null;
+ }
// no optimal adaptation
return null;
}
@@ -55113,37 +51799,91 @@ function getRightVideoTrack(adaptation, isTrickModeEnabled) {
*/
+
/**
- * Returns Observable which will emit:
- * - `"seeking"` when we are seeking in the given mediaElement
- * - `"seeked"` when a seek is considered as finished by the given observation$
- * Observable.
* @param {HTMLMediaElement} mediaElement
- * @param {Observable} observation$
- * @returns {Observable}
- */
-function emitSeekEvents(mediaElement, observation$) {
- return (0,defer/* defer */.P)(function () {
- if (mediaElement === null) {
- return empty/* EMPTY */.E;
- }
- var isSeeking$ = observation$.pipe((0,filter/* filter */.h)(function (observation) {
- return observation.event === "seeking";
- }), (0,map/* map */.U)(function () {
- return "seeking";
- }));
- if (mediaElement.seeking) {
- isSeeking$ = isSeeking$.pipe((0,startWith/* startWith */.O)("seeking"));
- }
- var hasSeeked$ = isSeeking$.pipe((0,switchMap/* switchMap */.w)(function () {
- return observation$.pipe((0,filter/* filter */.h)(function (observation) {
- return observation.event === "seeked";
- }), (0,map/* map */.U)(function () {
- return "seeked";
- }), (0,take/* take */.q)(1));
- }));
- return (0,merge/* merge */.T)(isSeeking$, hasSeeked$);
+ * @param {Object} playbackObserver - Observes playback conditions on
+ * `mediaElement`.
+ * @param {function} onSeeking - Callback called when a seeking operation starts
+ * on `mediaElement`.
+ * @param {function} onSeeked - Callback called when a seeking operation ends
+ * on `mediaElement`.
+ * @param {Object} cancelSignal - When triggered, stop calling callbacks and
+ * remove all listeners this function has registered.
+ */
+function emitSeekEvents(mediaElement, playbackObserver, onSeeking, onSeeked, cancelSignal) {
+ if (cancelSignal.isCancelled() || mediaElement === null) {
+ return;
+ }
+ var wasSeeking = playbackObserver.getReference().getValue().seeking;
+ if (wasSeeking) {
+ onSeeking();
+ if (cancelSignal.isCancelled()) {
+ return;
+ }
+ }
+ playbackObserver.listen(function (obs) {
+ if (obs.event === "seeking") {
+ wasSeeking = true;
+ onSeeking();
+ } else if (wasSeeking && obs.event === "seeked") {
+ wasSeeking = false;
+ onSeeked();
+ }
+ }, {
+ includeLastObservation: true,
+ clearSignal: cancelSignal
+ });
+}
+function constructPlayerStateReference(initializer, mediaElement, playbackObserver, cancelSignal) {
+ var playerStateRef = (0,reference/* default */.ZP)("LOADING" /* PLAYER_STATES.LOADING */, cancelSignal);
+ initializer.addEventListener("loaded", function () {
+ if (playerStateRef.getValue() === "LOADING" /* PLAYER_STATES.LOADING */) {
+ playerStateRef.setValue("LOADED" /* PLAYER_STATES.LOADED */);
+ if (!cancelSignal.isCancelled()) {
+ var newState = getLoadedContentState(mediaElement, null);
+ if (newState !== "PAUSED" /* PLAYER_STATES.PAUSED */) {
+ playerStateRef.setValue(newState);
+ }
+ }
+ } else {
+ playerStateRef.setValueIfChanged(getLoadedContentState(mediaElement, null));
+ }
+ }, cancelSignal);
+ initializer.addEventListener("reloadingMediaSource", function () {
+ if (isLoadedState(playerStateRef.getValue())) {
+ playerStateRef.setValueIfChanged("RELOADING" /* PLAYER_STATES.RELOADING */);
+ }
+ }, cancelSignal);
+ /**
+ * Keep track of the last known stalling situation.
+ * `null` if playback is not stalled.
+ */
+ var prevStallReason = null;
+ initializer.addEventListener("stalled", function (s) {
+ if (s !== prevStallReason) {
+ if (isLoadedState(playerStateRef.getValue())) {
+ playerStateRef.setValueIfChanged(getLoadedContentState(mediaElement, s));
+ }
+ prevStallReason = s;
+ }
+ }, cancelSignal);
+ initializer.addEventListener("unstalled", function () {
+ if (prevStallReason !== null) {
+ if (isLoadedState(playerStateRef.getValue())) {
+ playerStateRef.setValueIfChanged(getLoadedContentState(mediaElement, null));
+ }
+ prevStallReason = null;
+ }
+ }, cancelSignal);
+ playbackObserver.listen(function (observation) {
+ if (isLoadedState(playerStateRef.getValue()) && (0,array_includes/* default */.Z)(["seeking", "ended", "play", "pause"], observation.event)) {
+ playerStateRef.setValueIfChanged(getLoadedContentState(mediaElement, prevStallReason));
+ }
+ }, {
+ clearSignal: cancelSignal
});
+ return playerStateRef;
}
/**
* Get state string for a _loaded_ content.
@@ -55175,9 +51915,16 @@ function getLoadedContentState(mediaElement, stalledStatus) {
return mediaElement.paused ? "PAUSED" /* PLAYER_STATES.PAUSED */ : "PLAYING" /* PLAYER_STATES.PLAYING */;
}
+
+function isLoadedState(state) {
+ return state !== "LOADING" /* PLAYER_STATES.LOADING */ && state !== "RELOADING" /* PLAYER_STATES.RELOADING */ && state !== "STOPPED" /* PLAYER_STATES.STOPPED */;
+}
;// CONCATENATED MODULE: ./src/core/api/public_api.ts
+function public_api_createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = public_api_unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
+function public_api_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return public_api_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return public_api_arrayLikeToArray(o, minLen); }
+function public_api_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
/**
* Copyright 2015 CANAL+ Group
*
@@ -55198,7 +51945,6 @@ function getLoadedContentState(mediaElement, stalledStatus) {
* It also starts the different sub-parts of the player on various API calls.
*/
-
/* eslint-disable-next-line max-len */
@@ -55222,12 +51968,14 @@ function getLoadedContentState(mediaElement, stalledStatus) {
/* eslint-disable @typescript-eslint/naming-convention */
+var generateContentId = (0,id_generator/* default */.Z)();
var getPageActivityRef = event_listeners/* getPageActivityRef */.XR,
getPictureOnPictureStateRef = event_listeners/* getPictureOnPictureStateRef */.w0,
getVideoVisibilityRef = event_listeners/* getVideoVisibilityRef */.it,
getVideoWidthRef = event_listeners/* getVideoWidthRef */.O0,
- onFullscreenChange$ = event_listeners/* onFullscreenChange$ */.Q1,
- onTextTrackChanges$ = event_listeners/* onTextTrackChanges$ */.UA;
+ onFullscreenChange = event_listeners/* onFullscreenChange */.zU,
+ onTextTrackAdded = event_listeners/* onTextTrackAdded */.kJ,
+ onTextTrackRemoved = event_listeners/* onTextTrackRemoved */.Q4;
/**
* @class Player
* @extends EventEmitter
@@ -55243,6 +51991,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
if (options === void 0) {
options = {};
}
+ var _a, _b;
_this = _EventEmitter.call(this) || this;
var _parseConstructorOpti = parseConstructorOptions(options),
initialAudioBitrate = _parseConstructorOpti.initialAudioBitrate,
@@ -55268,57 +52017,65 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
// Workaround to support Firefox autoplay on FF 42.
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
videoElement.preload = "auto";
- _this.version = /* PLAYER_VERSION */"3.29.0";
+ _this.version = /* PLAYER_VERSION */"3.30.0";
_this.log = log/* default */.Z;
_this.state = "STOPPED";
_this.videoElement = videoElement;
var destroyCanceller = new task_canceller/* default */.ZP();
- _this._priv_destroy$ = new Subject/* Subject */.x(); // TODO Remove the need for this Subject
- _this._priv_destroy$.pipe((0,take/* take */.q)(1)).subscribe(function () {
- destroyCanceller.cancel();
- });
+ _this._destroyCanceller = destroyCanceller;
_this._priv_pictureInPictureRef = getPictureOnPictureStateRef(videoElement, destroyCanceller.signal);
/** @deprecated */
- onFullscreenChange$(videoElement).pipe((0,takeUntil/* takeUntil */.R)(_this._priv_destroy$))
- /* eslint-disable import/no-deprecated */.subscribe(function () {
- return _this.trigger("fullscreenChange", _this.isFullscreen());
- });
- /* eslint-enable import/no-deprecated */
- /** @deprecated */
- onTextTrackChanges$(videoElement.textTracks).pipe((0,takeUntil/* takeUntil */.R)(_this._priv_destroy$), (0,map/* map */.U)(function (evt) {
+ onFullscreenChange(videoElement, function () {
+ /* eslint-disable import/no-deprecated */
+ _this.trigger("fullscreenChange", _this.isFullscreen());
+ /* eslint-enable import/no-deprecated */
+ }, destroyCanceller.signal);
+ /** Store last known TextTrack array linked to the media element. */
+ var prevTextTracks = [];
+ for (var i = 0; i < ((_a = videoElement.textTracks) === null || _a === void 0 ? void 0 : _a.length); i++) {
+ var textTrack = (_b = videoElement.textTracks) === null || _b === void 0 ? void 0 : _b[i];
+ if (!(0,is_null_or_undefined/* default */.Z)(textTrack)) {
+ prevTextTracks.push(textTrack);
+ }
+ }
+ /** Callback called when a TextTrack element is added or removed. */
+ var onTextTrackChanges = function onTextTrackChanges(_evt) {
+ var evt = _evt;
var target = evt.target;
- var arr = [];
- for (var i = 0; i < target.length; i++) {
- var textTrack = target[i];
- arr.push(textTrack);
- }
- return arr;
- }),
- // We can have two consecutive textTrackChanges with the exact same
- // payload when we perform multiple texttrack operations before the event
- // loop is freed.
- // In that case we only want to fire one time the observable.
- distinctUntilChanged(function (textTracksA, textTracksB) {
- if (textTracksA.length !== textTracksB.length) {
- return false;
+ var textTrackArr = [];
+ for (var _i = 0; _i < target.length; _i++) {
+ var _textTrack = target[_i];
+ textTrackArr.push(_textTrack);
+ }
+ var oldTextTracks = prevTextTracks;
+ prevTextTracks = textTrackArr;
+ // We can have two consecutive textTrackChanges with the exact same
+ // payload when we perform multiple texttrack operations before the event
+ // loop is freed.
+ if (oldTextTracks.length !== textTrackArr.length) {
+ _this._priv_onNativeTextTracksNext(textTrackArr);
+ return;
}
- for (var i = 0; i < textTracksA.length; i++) {
- if (textTracksA[i] !== textTracksB[i]) {
- return false;
+ for (var _i2 = 0; _i2 < oldTextTracks.length; _i2++) {
+ if (oldTextTracks[_i2] !== textTrackArr[_i2]) {
+ _this._priv_onNativeTextTracksNext(textTrackArr);
+ return;
}
}
- return true;
- })).subscribe(function (x) {
- return _this._priv_onNativeTextTracksNext(x);
- });
- _this._priv_speed = (0,reference/* default */.ZP)(videoElement.playbackRate);
+ return;
+ };
+ if (!(0,is_null_or_undefined/* default */.Z)(videoElement.textTracks)) {
+ onTextTrackAdded(videoElement.textTracks, onTextTrackChanges, destroyCanceller.signal);
+ onTextTrackRemoved(videoElement.textTracks, onTextTrackChanges, destroyCanceller.signal);
+ }
+ _this._priv_speed = (0,reference/* default */.ZP)(videoElement.playbackRate, _this._destroyCanceller.signal);
_this._priv_preferTrickModeTracks = false;
- _this._priv_contentLock = (0,reference/* default */.ZP)(false);
+ _this._priv_contentLock = (0,reference/* default */.ZP)(false, _this._destroyCanceller.signal);
_this._priv_bufferOptions = {
- wantedBufferAhead: (0,reference/* default */.ZP)(wantedBufferAhead),
- maxBufferAhead: (0,reference/* default */.ZP)(maxBufferAhead),
- maxBufferBehind: (0,reference/* default */.ZP)(maxBufferBehind),
- maxVideoBufferSize: (0,reference/* default */.ZP)(maxVideoBufferSize)
+ wantedBufferAhead: (0,reference/* default */.ZP)(wantedBufferAhead, _this._destroyCanceller.signal),
+ maxBufferAhead: (0,reference/* default */.ZP)(maxBufferAhead, _this._destroyCanceller.signal),
+ maxBufferBehind: (0,reference/* default */.ZP)(maxBufferBehind, _this._destroyCanceller.signal),
+ maxVideoBufferSize: (0,reference/* default */.ZP)(maxVideoBufferSize, _this._destroyCanceller.signal)
};
_this._priv_bitrateInfos = {
lastBitrates: {
@@ -55326,24 +52083,22 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
video: initialVideoBitrate
},
minAutoBitrates: {
- audio: (0,reference/* default */.ZP)(minAudioBitrate),
- video: (0,reference/* default */.ZP)(minVideoBitrate)
+ audio: (0,reference/* default */.ZP)(minAudioBitrate, _this._destroyCanceller.signal),
+ video: (0,reference/* default */.ZP)(minVideoBitrate, _this._destroyCanceller.signal)
},
maxAutoBitrates: {
- audio: (0,reference/* default */.ZP)(maxAudioBitrate),
- video: (0,reference/* default */.ZP)(maxVideoBitrate)
+ audio: (0,reference/* default */.ZP)(maxAudioBitrate, _this._destroyCanceller.signal),
+ video: (0,reference/* default */.ZP)(maxVideoBitrate, _this._destroyCanceller.signal)
},
manualBitrates: {
- audio: (0,reference/* default */.ZP)(-1),
- video: (0,reference/* default */.ZP)(-1)
+ audio: (0,reference/* default */.ZP)(-1, _this._destroyCanceller.signal),
+ video: (0,reference/* default */.ZP)(-1, _this._destroyCanceller.signal)
}
};
_this._priv_throttleWhenHidden = throttleWhenHidden;
_this._priv_throttleVideoBitrateWhenHidden = throttleVideoBitrateWhenHidden;
_this._priv_limitVideoWidth = limitVideoWidth;
_this._priv_mutedMemory = DEFAULT_UNMUTED_VOLUME;
- _this._priv_trackChoiceManager = null;
- _this._priv_mediaElementTrackChoiceManager = null;
_this._priv_currentError = null;
_this._priv_contentInfos = null;
_this._priv_contentEventsMemory = {};
@@ -55397,22 +52152,8 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
log/* default.error */.Z.error("API: Could not dispose decryption resources: " + message);
});
}
- // free Observables linked to the Player instance
- this._priv_destroy$.next();
- this._priv_destroy$.complete();
- // Complete all subjects and references
- this._priv_speed.finish();
- this._priv_contentLock.finish();
- this._priv_bufferOptions.wantedBufferAhead.finish();
- this._priv_bufferOptions.maxVideoBufferSize.finish();
- this._priv_bufferOptions.maxBufferAhead.finish();
- this._priv_bufferOptions.maxBufferBehind.finish();
- this._priv_bitrateInfos.manualBitrates.video.finish();
- this._priv_bitrateInfos.manualBitrates.audio.finish();
- this._priv_bitrateInfos.minAutoBitrates.video.finish();
- this._priv_bitrateInfos.minAutoBitrates.audio.finish();
- this._priv_bitrateInfos.maxAutoBitrates.video.finish();
- this._priv_bitrateInfos.maxAutoBitrates.audio.finish();
+ // free resources linked to the Player instance
+ this._destroyCanceller.cancel();
this._priv_reloadingMetadata = {};
// un-attach video element
this.videoElement = null;
@@ -55478,6 +52219,18 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
newOptions.autoPlay = autoPlay;
}
this._priv_initializeContentPlayback(newOptions);
+ };
+ _proto.createDebugElement = function createDebugElement(element) {
+ if (features/* default.createDebugElement */.Z.createDebugElement === null) {
+ throw new Error("Feature `DEBUG_ELEMENT` not added to the RxPlayer");
+ }
+ var canceller = new task_canceller/* default */.ZP();
+ features/* default.createDebugElement */.Z.createDebugElement(element, this, canceller.signal);
+ return {
+ dispose: function dispose() {
+ canceller.cancel();
+ }
+ };
}
/**
* From given options, initialize content playback.
@@ -55485,7 +52238,6 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
*/;
_proto._priv_initializeContentPlayback = function _priv_initializeContentPlayback(options) {
var _this2 = this;
- var _a, _b, _c;
var autoPlay = options.autoPlay,
audioTrackSwitchingMode = options.audioTrackSwitchingMode,
defaultAudioTrack = options.defaultAudioTrack,
@@ -55507,42 +52259,11 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
throw new Error("the attached video element is disposed");
}
var isDirectFile = transport === "directfile";
- /** Subject which will emit to stop the current content. */
+ /** Emit to stop the current content. */
var currentContentCanceller = new task_canceller/* default */.ZP();
- // Some logic needs the equivalent of the `currentContentCanceller` under
- // an Observable form
- // TODO remove the need for `stoppedContent$`
- var stoppedContent$ = new Observable/* Observable */.y(function (obs) {
- currentContentCanceller.signal.register(function () {
- obs.next();
- obs.complete();
- });
- });
- /** Future `this._priv_contentInfos` related to this content. */
- var contentInfos = {
- url: url,
- currentContentCanceller: currentContentCanceller,
- isDirectFile: isDirectFile,
- segmentBuffersStore: null,
- thumbnails: null,
- manifest: null,
- currentPeriod: null,
- activeAdaptations: null,
- activeRepresentations: null,
- initialAudioTrack: defaultAudioTrack,
- initialTextTrack: defaultTextTrack
- };
var videoElement = this.videoElement;
- /** Global "playback observer" which will emit playback conditions */
- var playbackObserver = new PlaybackObserver(videoElement, {
- withMediaSource: !isDirectFile,
- lowLatencyMode: lowLatencyMode
- });
- currentContentCanceller.signal.register(function () {
- playbackObserver.stop();
- });
- /** Emit playback events. */
- var playback$;
+ var initializer;
+ var mediaElementTrackChoiceManager = null;
if (!isDirectFile) {
var transportFn = features/* default.transports */.Z.transports[transport];
if (typeof transportFn !== "function") {
@@ -55558,44 +52279,14 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
manifestRequestTimeout = networkConfig.manifestRequestTimeout,
segmentRequestTimeout = networkConfig.segmentRequestTimeout;
/** Interface used to load and refresh the Manifest. */
- var manifestFetcher = new fetchers_manifest(url, transportPipelines, {
+ var manifestRequestSettings = {
lowLatencyMode: lowLatencyMode,
maxRetryRegular: manifestRetry,
maxRetryOffline: offlineRetry,
- requestTimeout: manifestRequestTimeout
- });
- /** Observable emitting the initial Manifest */
- var manifest$;
- if (initialManifest instanceof manifest/* default */.ZP) {
- manifest$ = (0,of.of)({
- type: "parsed",
- manifest: initialManifest
- });
- } else if (initialManifest !== undefined) {
- manifest$ = manifestFetcher.parse(initialManifest, {
- previousManifest: null,
- unsafeMode: false
- });
- } else {
- manifest$ = manifestFetcher.fetch(url).pipe((0,mergeMap/* mergeMap */.z)(function (response) {
- return response.type === "warning" ? (0,of.of)(response) :
- // bubble-up warnings
- response.parse({
- previousManifest: null,
- unsafeMode: false
- });
- }));
- }
- // Load the Manifest right now and share it with every subscriber until
- // the content is stopped
- manifest$ = manifest$.pipe((0,takeUntil/* takeUntil */.R)(stoppedContent$), (0,shareReplay/* shareReplay */.d)());
- manifest$.subscribe();
- // now that the Manifest is loading, stop previous content and reset state
- // This is done after fetching the Manifest as `stop` could technically
- // take time.
- this.stop();
- this._priv_currentError = null;
- this._priv_contentInfos = contentInfos;
+ requestTimeout: manifestRequestTimeout,
+ minimumManifestUpdateInterval: minimumManifestUpdateInterval,
+ initialManifest: initialManifest
+ };
var relyOnVideoVisibilityAndSize = canRelyOnVideoVisibilityAndSize();
var throttlers = {
throttle: {},
@@ -55657,143 +52348,173 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
onCodecSwitch: onCodecSwitch
}, this._priv_bufferOptions);
var segmentRequestOptions = {
- regularError: segmentRetry,
+ lowLatencyMode: lowLatencyMode,
+ maxRetryRegular: segmentRetry,
requestTimeout: segmentRequestTimeout,
- offlineError: offlineRetry
+ maxRetryOffline: offlineRetry
};
- // We've every options set up. Start everything now
- var init$ = init({
+ initializer = new MediaSourceContentInitializer({
adaptiveOptions: adaptiveOptions,
autoPlay: autoPlay,
bufferOptions: bufferOptions,
- playbackObserver: playbackObserver,
keySystems: keySystems,
lowLatencyMode: lowLatencyMode,
- manifest$: manifest$,
- manifestFetcher: manifestFetcher,
- mediaElement: videoElement,
- minimumManifestUpdateInterval: minimumManifestUpdateInterval,
+ manifestRequestSettings: manifestRequestSettings,
+ transport: transportPipelines,
segmentRequestOptions: segmentRequestOptions,
speed: this._priv_speed,
startAt: startAt,
- transport: transportPipelines,
- textTrackOptions: textTrackOptions
- }).pipe((0,takeUntil/* takeUntil */.R)(stoppedContent$));
- playback$ = connectable(init$, {
- connector: function connector() {
- return new Subject/* Subject */.x();
- },
- resetOnDisconnect: false
+ textTrackOptions: textTrackOptions,
+ url: url
});
} else {
- // Stop previous content and reset its state
- this.stop();
- this._priv_currentError = null;
if (features/* default.directfile */.Z.directfile === null) {
+ this.stop();
+ this._priv_currentError = null;
throw new Error("DirectFile feature not activated in your build.");
}
- this._priv_contentInfos = contentInfos;
- this._priv_mediaElementTrackChoiceManager = new features/* default.directfile.mediaElementTrackChoiceManager */.Z.directfile.mediaElementTrackChoiceManager(this.videoElement);
- var preferredAudioTracks = defaultAudioTrack === undefined ? this._priv_preferredAudioTracks : [defaultAudioTrack];
- this._priv_mediaElementTrackChoiceManager.setPreferredAudioTracks(preferredAudioTracks, true);
- var preferredTextTracks = defaultTextTrack === undefined ? this._priv_preferredTextTracks : [defaultTextTrack];
- this._priv_mediaElementTrackChoiceManager.setPreferredTextTracks(preferredTextTracks, true);
- this._priv_mediaElementTrackChoiceManager.setPreferredVideoTracks(this._priv_preferredVideoTracks, true);
- this.trigger("availableAudioTracksChange", this._priv_mediaElementTrackChoiceManager.getAvailableAudioTracks());
- this.trigger("availableVideoTracksChange", this._priv_mediaElementTrackChoiceManager.getAvailableVideoTracks());
- this.trigger("availableTextTracksChange", this._priv_mediaElementTrackChoiceManager.getAvailableTextTracks());
- this.trigger("audioTrackChange", (_a = this._priv_mediaElementTrackChoiceManager.getChosenAudioTrack()) !== null && _a !== void 0 ? _a : null);
- this.trigger("textTrackChange", (_b = this._priv_mediaElementTrackChoiceManager.getChosenTextTrack()) !== null && _b !== void 0 ? _b : null);
- this.trigger("videoTrackChange", (_c = this._priv_mediaElementTrackChoiceManager.getChosenVideoTrack()) !== null && _c !== void 0 ? _c : null);
- this._priv_mediaElementTrackChoiceManager.addEventListener("availableVideoTracksChange", function (val) {
- return _this2.trigger("availableVideoTracksChange", val);
- });
- this._priv_mediaElementTrackChoiceManager.addEventListener("availableAudioTracksChange", function (val) {
- return _this2.trigger("availableAudioTracksChange", val);
- });
- this._priv_mediaElementTrackChoiceManager.addEventListener("availableTextTracksChange", function (val) {
- return _this2.trigger("availableTextTracksChange", val);
- });
- this._priv_mediaElementTrackChoiceManager.addEventListener("audioTrackChange", function (val) {
- return _this2.trigger("audioTrackChange", val);
- });
- this._priv_mediaElementTrackChoiceManager.addEventListener("videoTrackChange", function (val) {
- return _this2.trigger("videoTrackChange", val);
- });
- this._priv_mediaElementTrackChoiceManager.addEventListener("textTrackChange", function (val) {
- return _this2.trigger("textTrackChange", val);
- });
- var directfileInit$ = features/* default.directfile.initDirectFile */.Z.directfile.initDirectFile({
+ mediaElementTrackChoiceManager = this._priv_initializeMediaElementTrackChoiceManager(defaultAudioTrack, defaultTextTrack, currentContentCanceller.signal);
+ if (currentContentCanceller.isUsed()) {
+ return;
+ }
+ initializer = new features/* default.directfile.initDirectFile */.Z.directfile.initDirectFile({
autoPlay: autoPlay,
keySystems: keySystems,
- mediaElement: videoElement,
speed: this._priv_speed,
- playbackObserver: playbackObserver,
startAt: startAt,
url: url
- }).pipe((0,takeUntil/* takeUntil */.R)(stoppedContent$));
- playback$ = connectable(directfileInit$, {
- connector: function connector() {
- return new Subject/* Subject */.x();
- },
- resetOnDisconnect: false
});
}
- /** Emit an object when the player "stalls" and null when it un-stalls */
- var stalled$ = playback$.pipe((0,filter/* filter */.h)(function (evt) {
- return evt.type === "stalled" || evt.type === "unstalled";
- }), (0,map/* map */.U)(function (x) {
- return x.value;
- }), distinctUntilChanged(function (prevStallReason, currStallReason) {
- return prevStallReason === null && currStallReason === null || prevStallReason !== null && currStallReason !== null && prevStallReason === currStallReason;
- }));
- /** Emit when the content is considered "loaded". */
- var loaded$ = playback$.pipe((0,filter/* filter */.h)(function (evt) {
- return evt.type === "loaded";
- }), (0,share/* share */.B)());
- /** Emit when we will "reload" the MediaSource. */
- var reloading$ = playback$.pipe((0,filter/* filter */.h)(function (evt) {
- return evt.type === "reloading-media-source";
- }), (0,share/* share */.B)());
- /** Emit when the media element emits a "seeking" event. */
- var observation$ = playbackObserver.getReference().asObservable();
- var stateChangingEvent$ = observation$.pipe((0,filter/* filter */.h)(function (o) {
- return o.event === "seeking" || o.event === "ended" || o.event === "play" || o.event === "pause";
- }));
- /** Emit state updates once the content is considered "loaded". */
- var loadedStateUpdates$ = combineLatest([stalled$.pipe((0,startWith/* startWith */.O)(null)), stateChangingEvent$.pipe((0,startWith/* startWith */.O)(null))]).pipe((0,takeUntil/* takeUntil */.R)(stoppedContent$), (0,map/* map */.U)(function (_ref) {
- var stalledStatus = _ref[0];
- return getLoadedContentState(videoElement, stalledStatus);
- }));
- /** Emit all player "state" updates. */
- var playerState$ = (0,concat/* concat */.z)((0,of.of)("LOADING" /* PLAYER_STATES.LOADING */),
- // Begin with LOADING
- loaded$.pipe((0,switchMap/* switchMap */.w)(function (_, i) {
- var isFirstLoad = i === 0;
- return (0,merge/* merge */.T)(
- // Purposely subscribed first so a RELOADING triggered synchronously
- // after a LOADED state is catched.
- reloading$.pipe((0,map/* map */.U)(function () {
- return "RELOADING";
- } /* PLAYER_STATES.RELOADING */)),
- // Only switch to LOADED state for the first (i.e. non-RELOADING) load
- isFirstLoad ? (0,of.of)("LOADED" /* PLAYER_STATES.LOADED */) : empty/* EMPTY */.E,
- // Purposely put last so any other state change happens after we've
- // already switched to LOADED
- loadedStateUpdates$.pipe((0,takeUntil/* takeUntil */.R)(reloading$),
- // For the first load, we prefer staying at the LOADED state over
- // PAUSED when autoPlay is disabled.
- // For consecutive loads however, there's no LOADED state.
- skipWhile(function (state) {
- return isFirstLoad && state === "PAUSED";
- } /* PLAYER_STATES.PAUSED */)));
- }))).pipe(distinctUntilChanged());
- var playbackSubscription;
- stoppedContent$.subscribe(function () {
- if (playbackSubscription !== undefined) {
- playbackSubscription.unsubscribe();
+ /** Future `this._priv_contentInfos` related to this content. */
+ var contentInfos = {
+ contentId: generateContentId(),
+ originalUrl: url,
+ currentContentCanceller: currentContentCanceller,
+ initializer: initializer,
+ isDirectFile: isDirectFile,
+ segmentBuffersStore: null,
+ thumbnails: null,
+ manifest: null,
+ currentPeriod: null,
+ activeAdaptations: null,
+ activeRepresentations: null,
+ initialAudioTrack: defaultAudioTrack,
+ initialTextTrack: defaultTextTrack,
+ trackChoiceManager: null,
+ mediaElementTrackChoiceManager: mediaElementTrackChoiceManager
+ };
+ // Bind events
+ initializer.addEventListener("error", function (error) {
+ var formattedError = (0,format_error/* default */.Z)(error, {
+ defaultCode: "NONE",
+ defaultReason: "An unknown error stopped content playback."
+ });
+ formattedError.fatal = true;
+ contentInfos.currentContentCanceller.cancel();
+ _this2._priv_cleanUpCurrentContentState();
+ _this2._priv_currentError = formattedError;
+ log/* default.error */.Z.error("API: The player stopped because of an error", error instanceof Error ? error : "");
+ _this2._priv_setPlayerState("STOPPED" /* PLAYER_STATES.STOPPED */);
+ // TODO This condition is here because the eventual callback called when the
+ // player state is updated can launch a new content, thus the error will not
+ // be here anymore, in which case triggering the "error" event is unwanted.
+ // This is very ugly though, and we should probable have a better solution
+ if (_this2._priv_currentError === formattedError) {
+ _this2.trigger("error", formattedError);
+ }
+ });
+ initializer.addEventListener("warning", function (error) {
+ var formattedError = (0,format_error/* default */.Z)(error, {
+ defaultCode: "NONE",
+ defaultReason: "An unknown error happened."
+ });
+ log/* default.warn */.Z.warn("API: Sending warning:", formattedError);
+ _this2.trigger("warning", formattedError);
+ });
+ initializer.addEventListener("reloadingMediaSource", function () {
+ contentInfos.segmentBuffersStore = null;
+ if (contentInfos.trackChoiceManager !== null) {
+ contentInfos.trackChoiceManager.resetPeriods();
+ }
+ });
+ initializer.addEventListener("inbandEvents", function (inbandEvents) {
+ return _this2.trigger("inbandEvents", inbandEvents);
+ });
+ initializer.addEventListener("streamEvent", function (streamEvent) {
+ return _this2.trigger("streamEvent", streamEvent);
+ });
+ initializer.addEventListener("streamEventSkip", function (streamEventSkip) {
+ return _this2.trigger("streamEventSkip", streamEventSkip);
+ });
+ initializer.addEventListener("decipherabilityUpdate", function (decipherabilityUpdate) {
+ return _this2.trigger("decipherabilityUpdate", decipherabilityUpdate);
+ });
+ initializer.addEventListener("activePeriodChanged", function (periodInfo) {
+ return _this2._priv_onActivePeriodChanged(contentInfos, periodInfo);
+ });
+ initializer.addEventListener("periodStreamReady", function (periodReadyInfo) {
+ return _this2._priv_onPeriodStreamReady(contentInfos, periodReadyInfo);
+ });
+ initializer.addEventListener("periodStreamCleared", function (periodClearedInfo) {
+ return _this2._priv_onPeriodStreamCleared(contentInfos, periodClearedInfo);
+ });
+ initializer.addEventListener("representationChange", function (representationInfo) {
+ return _this2._priv_onRepresentationChange(contentInfos, representationInfo);
+ });
+ initializer.addEventListener("adaptationChange", function (adaptationInfo) {
+ return _this2._priv_onAdaptationChange(contentInfos, adaptationInfo);
+ });
+ initializer.addEventListener("bitrateEstimationChange", function (bitrateEstimationInfo) {
+ return _this2._priv_onBitrateEstimationChange(bitrateEstimationInfo);
+ });
+ initializer.addEventListener("manifestReady", function (manifest) {
+ return _this2._priv_onManifestReady(contentInfos, manifest);
+ });
+ initializer.addEventListener("loaded", function (evt) {
+ contentInfos.segmentBuffersStore = evt.segmentBuffersStore;
+ });
+ initializer.addEventListener("addedSegment", function (evt) {
+ // Manage image tracks
+ // @deprecated
+ var content = evt.content,
+ segmentData = evt.segmentData;
+ if (content.adaptation.type === "image") {
+ if (!(0,is_null_or_undefined/* default */.Z)(segmentData) && segmentData.type === "bif") {
+ var imageData = segmentData.data;
+ /* eslint-disable import/no-deprecated */
+ contentInfos.thumbnails = imageData;
+ _this2.trigger("imageTrackUpdate", {
+ data: contentInfos.thumbnails
+ });
+ /* eslint-enable import/no-deprecated */
+ }
}
});
+ // Now, that most events are linked, prepare the next content.
+ initializer.prepare();
+ // Now that the content is prepared, stop previous content and reset state
+ // This is done after content preparation as `stop` could technically have
+ // a long and synchronous blocking time.
+ // Note that this call is done **synchronously** after all events linking.
+ // This is **VERY** important so:
+ // - the `STOPPED` state is switched to synchronously after loading a new
+ // content.
+ // - we can avoid involontarily catching events linked to the previous
+ // content.
+ this.stop();
+ /** Global "playback observer" which will emit playback conditions */
+ var playbackObserver = new PlaybackObserver(videoElement, {
+ withMediaSource: !isDirectFile,
+ lowLatencyMode: lowLatencyMode
+ });
+ currentContentCanceller.signal.register(function () {
+ playbackObserver.stop();
+ });
+ // Update the RxPlayer's state at the right events
+ var playerStateRef = constructPlayerStateReference(initializer, videoElement, playbackObserver, currentContentCanceller.signal);
+ currentContentCanceller.signal.register(function () {
+ initializer.dispose();
+ });
/**
* Function updating `this._priv_reloadingMetadata` in function of the
* current state and playback conditions.
@@ -55818,52 +52539,64 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
break;
}
};
- playerState$.pipe((0,tap/* tap */.b)(function (newState) {
+ /**
+ * `TaskCanceller` allowing to stop emitting `"seeking"` and `"seeked"`
+ * events.
+ * `null` when such events are not emitted currently.
+ */
+ var seekEventsCanceller = null;
+ // React to player state change
+ playerStateRef.onUpdate(function (newState) {
updateReloadingMetadata(newState);
_this2._priv_setPlayerState(newState);
+ if (currentContentCanceller.isUsed()) {
+ return;
+ }
+ if (seekEventsCanceller !== null) {
+ if (!isLoadedState(_this2.state)) {
+ seekEventsCanceller.cancel();
+ seekEventsCanceller = null;
+ }
+ } else if (isLoadedState(_this2.state)) {
+ seekEventsCanceller = new task_canceller/* default */.ZP();
+ seekEventsCanceller.linkToSignal(currentContentCanceller.signal);
+ emitSeekEvents(videoElement, playbackObserver, function () {
+ return _this2.trigger("seeking", null);
+ }, function () {
+ return _this2.trigger("seeked", null);
+ }, seekEventsCanceller.signal);
+ }
// Previous call could have performed all kind of side-effects, thus,
// we re-check the current state associated to the RxPlayer
- if (_this2.state === "ENDED" && _this2._priv_stopAtEnd) {
- currentContentCanceller.cancel();
- }
- }), (0,map/* map */.U)(function (state) {
- return state !== "RELOADING" && state !== "STOPPED";
- }), distinctUntilChanged(), (0,switchMap/* switchMap */.w)(function (canSendObservation) {
- return canSendObservation ? observation$ : empty/* EMPTY */.E;
- }), (0,takeUntil/* takeUntil */.R)(stoppedContent$)).subscribe(function (o) {
- updateReloadingMetadata(_this2.state);
- _this2._priv_triggerPositionUpdate(o);
+ if (_this2.state === "ENDED" /* PLAYER_STATES.ENDED */ && _this2._priv_stopAtEnd) {
+ _this2.stop();
+ }
+ }, {
+ emitCurrentValue: true,
+ clearSignal: currentContentCanceller.signal
});
- // Link "seeking" and "seeked" events (once the content is loaded)
- loaded$.pipe((0,switchMap/* switchMap */.w)(function () {
- return emitSeekEvents(_this2.videoElement, observation$);
- }), (0,takeUntil/* takeUntil */.R)(stoppedContent$)).subscribe(function (evt) {
- log/* default.info */.Z.info("API: Triggering \"" + evt + "\" event");
- _this2.trigger(evt, null);
+ // React to playback conditions change
+ playbackObserver.listen(function (observation) {
+ updateReloadingMetadata(_this2.state);
+ _this2._priv_triggerPositionUpdate(contentInfos, observation);
+ }, {
+ clearSignal: currentContentCanceller.signal
});
- // Link playback events to the corresponding callbacks
- playback$.subscribe({
- next: function next(x) {
- return _this2._priv_onPlaybackEvent(x);
- },
- error: function error(err) {
- return _this2._priv_onPlaybackError(err);
- },
- complete: function complete() {
- if (!contentInfos.currentContentCanceller.isUsed) {
- log/* default.info */.Z.info("API: Previous playback finished. Stopping and cleaning-up...");
- contentInfos.currentContentCanceller.cancel();
- _this2._priv_cleanUpCurrentContentState();
- _this2._priv_setPlayerState("STOPPED" /* PLAYER_STATES.STOPPED */);
- }
- }
+ this._priv_currentError = null;
+ this._priv_contentInfos = contentInfos;
+ currentContentCanceller.signal.register(function () {
+ initializer.removeEventListener();
});
// initialize the content only when the lock is inactive
- this._priv_contentLock.asObservable().pipe((0,filter/* filter */.h)(function (isLocked) {
- return !isLocked;
- }), (0,take/* take */.q)(1), (0,takeUntil/* takeUntil */.R)(stoppedContent$)).subscribe(function () {
- // start playback!
- playbackSubscription = playback$.connect();
+ this._priv_contentLock.onUpdate(function (isLocked, stopListeningToLock) {
+ if (!isLocked) {
+ stopListeningToLock();
+ // start playback!
+ initializer.start(videoElement, playbackObserver);
+ }
+ }, {
+ emitCurrentValue: true,
+ clearSignal: currentContentCanceller.signal
});
}
/**
@@ -55981,7 +52714,8 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
return this._priv_preferTrickModeTracks;
}
/**
- * Returns the url of the content's manifest
+ * Returns the url of the currently considered Manifest, or of the content for
+ * directfile content.
* @returns {string|undefined} - Current URL. `undefined` if not known or no
* URL yet.
*/;
@@ -55992,15 +52726,30 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
var _this$_priv_contentIn3 = this._priv_contentInfos,
isDirectFile = _this$_priv_contentIn3.isDirectFile,
manifest = _this$_priv_contentIn3.manifest,
- url = _this$_priv_contentIn3.url;
+ originalUrl = _this$_priv_contentIn3.originalUrl;
if (isDirectFile) {
- return url;
+ return originalUrl;
}
if (manifest !== null) {
return manifest.getUrl();
}
return undefined;
}
+ /**
+ * Update URL of the content currently being played (e.g. DASH's MPD).
+ * @param {Array.|undefined} urls - URLs to reach that content /
+ * Manifest from the most prioritized URL to the least prioritized URL.
+ * @param {Object|undefined} [params]
+ * @param {boolean} params.refresh - If `true` the resource in question
+ * (e.g. DASH's MPD) will be refreshed immediately.
+ */;
+ _proto.updateContentUrls = function updateContentUrls(urls, params) {
+ if (this._priv_contentInfos === null) {
+ throw new Error("No content loaded");
+ }
+ var refreshNow = (params === null || params === void 0 ? void 0 : params.refresh) === true;
+ this._priv_contentInfos.initializer.updateContentUrls(urls, refreshNow);
+ }
/**
* Returns the video duration, in seconds.
* NaN if no video is playing.
@@ -56032,6 +52781,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
* @returns {Number}
*/;
_proto.getVideoLoadedTime = function getVideoLoadedTime() {
+ (0,warn_once/* default */.Z)("`getVideoLoadedTime` is deprecated and won't be present in the " + "next major version");
if (this.videoElement === null) {
throw new Error("Disposed player");
}
@@ -56045,6 +52795,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
* @returns {Number}
*/;
_proto.getVideoPlayedTime = function getVideoPlayedTime() {
+ (0,warn_once/* default */.Z)("`getVideoPlayedTime` is deprecated and won't be present in the " + "next major version");
if (this.videoElement === null) {
throw new Error("Disposed player");
}
@@ -56167,6 +52918,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
* @param {Object} opts
*/;
_proto.setPlaybackRate = function setPlaybackRate(rate, opts) {
+ var _a;
if (rate !== this._priv_speed.getValue()) {
this._priv_speed.setValue(rate);
}
@@ -56175,11 +52927,12 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
return;
}
this._priv_preferTrickModeTracks = preferTrickModeTracks;
- if (this._priv_trackChoiceManager !== null) {
- if (preferTrickModeTracks && !this._priv_trackChoiceManager.isTrickModeEnabled()) {
- this._priv_trackChoiceManager.enableVideoTrickModeTracks();
- } else if (!preferTrickModeTracks && this._priv_trackChoiceManager.isTrickModeEnabled()) {
- this._priv_trackChoiceManager.disableVideoTrickModeTracks();
+ var trackChoiceManager = (_a = this._priv_contentInfos) === null || _a === void 0 ? void 0 : _a.trackChoiceManager;
+ if (!(0,is_null_or_undefined/* default */.Z)(trackChoiceManager)) {
+ if (preferTrickModeTracks && !trackChoiceManager.isTrickModeEnabled()) {
+ trackChoiceManager.enableVideoTrickModeTracks();
+ } else if (!preferTrickModeTracks && trackChoiceManager.isTrickModeEnabled()) {
+ trackChoiceManager.disableVideoTrickModeTracks();
}
}
}
@@ -56580,73 +53333,102 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
/**
* Returns type of current keysystem (e.g. playready, widevine) if the content
* is encrypted. null otherwise.
+ * @deprecated
* @returns {string|null}
*/;
_proto.getCurrentKeySystem = function getCurrentKeySystem() {
+ (0,warn_once/* default */.Z)("`getCurrentKeySystem` is deprecated." + "Please use the `getKeySystemConfiguration` method instead.");
if (this.videoElement === null) {
throw new Error("Disposed player");
}
- return get_current_key_system_getCurrentKeySystem(this.videoElement);
+ return get_key_system_configuration_getCurrentKeySystem(this.videoElement);
+ }
+ /**
+ * Returns both the name of the key system (e.g. `"com.widevine.alpha"`) and
+ * the `MediaKeySystemConfiguration` currently associated to the
+ * HTMLMediaElement linked to the RxPlayer.
+ *
+ * Returns `null` if no such capabilities is associated or if unknown.
+ * @returns {Object|null}
+ */;
+ _proto.getKeySystemConfiguration = function getKeySystemConfiguration() {
+ if (this.videoElement === null) {
+ throw new Error("Disposed player");
+ }
+ var values = get_key_system_configuration_getKeySystemConfiguration(this.videoElement);
+ if (values === null) {
+ return null;
+ }
+ return {
+ keySystem: values[0],
+ configuration: values[1]
+ };
}
/**
* Returns every available audio tracks for the current Period.
* @returns {Array.|null}
*/;
_proto.getAvailableAudioTracks = function getAvailableAudioTracks() {
- var _a, _b;
+ var _a;
if (this._priv_contentInfos === null) {
return [];
}
var _this$_priv_contentIn8 = this._priv_contentInfos,
currentPeriod = _this$_priv_contentIn8.currentPeriod,
- isDirectFile = _this$_priv_contentIn8.isDirectFile;
+ isDirectFile = _this$_priv_contentIn8.isDirectFile,
+ trackChoiceManager = _this$_priv_contentIn8.trackChoiceManager,
+ mediaElementTrackChoiceManager = _this$_priv_contentIn8.mediaElementTrackChoiceManager;
if (isDirectFile) {
- return (_b = (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.getAvailableAudioTracks()) !== null && _b !== void 0 ? _b : [];
+ return (_a = mediaElementTrackChoiceManager === null || mediaElementTrackChoiceManager === void 0 ? void 0 : mediaElementTrackChoiceManager.getAvailableAudioTracks()) !== null && _a !== void 0 ? _a : [];
}
- if (this._priv_trackChoiceManager === null || currentPeriod === null) {
+ if (trackChoiceManager === null || currentPeriod === null) {
return [];
}
- return this._priv_trackChoiceManager.getAvailableAudioTracks(currentPeriod);
+ return trackChoiceManager.getAvailableAudioTracks(currentPeriod);
}
/**
* Returns every available text tracks for the current Period.
* @returns {Array.|null}
*/;
_proto.getAvailableTextTracks = function getAvailableTextTracks() {
- var _a, _b;
+ var _a;
if (this._priv_contentInfos === null) {
return [];
}
var _this$_priv_contentIn9 = this._priv_contentInfos,
currentPeriod = _this$_priv_contentIn9.currentPeriod,
- isDirectFile = _this$_priv_contentIn9.isDirectFile;
+ isDirectFile = _this$_priv_contentIn9.isDirectFile,
+ trackChoiceManager = _this$_priv_contentIn9.trackChoiceManager,
+ mediaElementTrackChoiceManager = _this$_priv_contentIn9.mediaElementTrackChoiceManager;
if (isDirectFile) {
- return (_b = (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.getAvailableTextTracks()) !== null && _b !== void 0 ? _b : [];
+ return (_a = mediaElementTrackChoiceManager === null || mediaElementTrackChoiceManager === void 0 ? void 0 : mediaElementTrackChoiceManager.getAvailableTextTracks()) !== null && _a !== void 0 ? _a : [];
}
- if (this._priv_trackChoiceManager === null || currentPeriod === null) {
+ if (trackChoiceManager === null || currentPeriod === null) {
return [];
}
- return this._priv_trackChoiceManager.getAvailableTextTracks(currentPeriod);
+ return trackChoiceManager.getAvailableTextTracks(currentPeriod);
}
/**
* Returns every available video tracks for the current Period.
* @returns {Array.|null}
*/;
_proto.getAvailableVideoTracks = function getAvailableVideoTracks() {
- var _a, _b;
+ var _a;
if (this._priv_contentInfos === null) {
return [];
}
var _this$_priv_contentIn10 = this._priv_contentInfos,
currentPeriod = _this$_priv_contentIn10.currentPeriod,
- isDirectFile = _this$_priv_contentIn10.isDirectFile;
+ isDirectFile = _this$_priv_contentIn10.isDirectFile,
+ trackChoiceManager = _this$_priv_contentIn10.trackChoiceManager,
+ mediaElementTrackChoiceManager = _this$_priv_contentIn10.mediaElementTrackChoiceManager;
if (isDirectFile) {
- return (_b = (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.getAvailableVideoTracks()) !== null && _b !== void 0 ? _b : [];
+ return (_a = mediaElementTrackChoiceManager === null || mediaElementTrackChoiceManager === void 0 ? void 0 : mediaElementTrackChoiceManager.getAvailableVideoTracks()) !== null && _a !== void 0 ? _a : [];
}
- if (this._priv_trackChoiceManager === null || currentPeriod === null) {
+ if (trackChoiceManager === null || currentPeriod === null) {
return [];
}
- return this._priv_trackChoiceManager.getAvailableVideoTracks(currentPeriod);
+ return trackChoiceManager.getAvailableVideoTracks(currentPeriod);
}
/**
* Returns currently chosen audio language for the current Period.
@@ -56658,17 +53440,19 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
}
var _this$_priv_contentIn11 = this._priv_contentInfos,
currentPeriod = _this$_priv_contentIn11.currentPeriod,
- isDirectFile = _this$_priv_contentIn11.isDirectFile;
+ isDirectFile = _this$_priv_contentIn11.isDirectFile,
+ trackChoiceManager = _this$_priv_contentIn11.trackChoiceManager,
+ mediaElementTrackChoiceManager = _this$_priv_contentIn11.mediaElementTrackChoiceManager;
if (isDirectFile) {
- if (this._priv_mediaElementTrackChoiceManager === null) {
+ if (mediaElementTrackChoiceManager === null) {
return undefined;
}
- return this._priv_mediaElementTrackChoiceManager.getChosenAudioTrack();
+ return mediaElementTrackChoiceManager.getChosenAudioTrack();
}
- if (this._priv_trackChoiceManager === null || currentPeriod === null) {
+ if (trackChoiceManager === null || currentPeriod === null) {
return undefined;
}
- return this._priv_trackChoiceManager.getChosenAudioTrack(currentPeriod);
+ return trackChoiceManager.getChosenAudioTrack(currentPeriod);
}
/**
* Returns currently chosen subtitle for the current Period.
@@ -56680,17 +53464,19 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
}
var _this$_priv_contentIn12 = this._priv_contentInfos,
currentPeriod = _this$_priv_contentIn12.currentPeriod,
- isDirectFile = _this$_priv_contentIn12.isDirectFile;
+ isDirectFile = _this$_priv_contentIn12.isDirectFile,
+ trackChoiceManager = _this$_priv_contentIn12.trackChoiceManager,
+ mediaElementTrackChoiceManager = _this$_priv_contentIn12.mediaElementTrackChoiceManager;
if (isDirectFile) {
- if (this._priv_mediaElementTrackChoiceManager === null) {
+ if (mediaElementTrackChoiceManager === null) {
return undefined;
}
- return this._priv_mediaElementTrackChoiceManager.getChosenTextTrack();
+ return mediaElementTrackChoiceManager.getChosenTextTrack();
}
- if (this._priv_trackChoiceManager === null || currentPeriod === null) {
+ if (trackChoiceManager === null || currentPeriod === null) {
return undefined;
}
- return this._priv_trackChoiceManager.getChosenTextTrack(currentPeriod);
+ return trackChoiceManager.getChosenTextTrack(currentPeriod);
}
/**
* Returns currently chosen video track for the current Period.
@@ -56702,17 +53488,19 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
}
var _this$_priv_contentIn13 = this._priv_contentInfos,
currentPeriod = _this$_priv_contentIn13.currentPeriod,
- isDirectFile = _this$_priv_contentIn13.isDirectFile;
+ isDirectFile = _this$_priv_contentIn13.isDirectFile,
+ trackChoiceManager = _this$_priv_contentIn13.trackChoiceManager,
+ mediaElementTrackChoiceManager = _this$_priv_contentIn13.mediaElementTrackChoiceManager;
if (isDirectFile) {
- if (this._priv_mediaElementTrackChoiceManager === null) {
+ if (mediaElementTrackChoiceManager === null) {
return undefined;
}
- return this._priv_mediaElementTrackChoiceManager.getChosenVideoTrack();
+ return mediaElementTrackChoiceManager.getChosenVideoTrack();
}
- if (this._priv_trackChoiceManager === null || currentPeriod === null) {
+ if (trackChoiceManager === null || currentPeriod === null) {
return undefined;
}
- return this._priv_trackChoiceManager.getChosenVideoTrack(currentPeriod);
+ return trackChoiceManager.getChosenVideoTrack(currentPeriod);
}
/**
* Update the audio language for the current Period.
@@ -56721,26 +53509,27 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
* @throws Error - the given id is linked to no audio track.
*/;
_proto.setAudioTrack = function setAudioTrack(audioId) {
- var _a;
if (this._priv_contentInfos === null) {
throw new Error("No content loaded");
}
var _this$_priv_contentIn14 = this._priv_contentInfos,
currentPeriod = _this$_priv_contentIn14.currentPeriod,
- isDirectFile = _this$_priv_contentIn14.isDirectFile;
+ isDirectFile = _this$_priv_contentIn14.isDirectFile,
+ trackChoiceManager = _this$_priv_contentIn14.trackChoiceManager,
+ mediaElementTrackChoiceManager = _this$_priv_contentIn14.mediaElementTrackChoiceManager;
if (isDirectFile) {
try {
- (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.setAudioTrackById(audioId);
+ mediaElementTrackChoiceManager === null || mediaElementTrackChoiceManager === void 0 ? void 0 : mediaElementTrackChoiceManager.setAudioTrackById(audioId);
return;
} catch (e) {
throw new Error("player: unknown audio track");
}
}
- if (this._priv_trackChoiceManager === null || currentPeriod === null) {
+ if (trackChoiceManager === null || currentPeriod === null) {
throw new Error("No compatible content launched.");
}
try {
- this._priv_trackChoiceManager.setAudioTrackByID(currentPeriod, audioId);
+ trackChoiceManager.setAudioTrackByID(currentPeriod, audioId);
} catch (e) {
throw new Error("player: unknown audio track");
}
@@ -56752,26 +53541,27 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
* @throws Error - the given id is linked to no text track.
*/;
_proto.setTextTrack = function setTextTrack(textId) {
- var _a;
if (this._priv_contentInfos === null) {
throw new Error("No content loaded");
}
var _this$_priv_contentIn15 = this._priv_contentInfos,
currentPeriod = _this$_priv_contentIn15.currentPeriod,
- isDirectFile = _this$_priv_contentIn15.isDirectFile;
+ isDirectFile = _this$_priv_contentIn15.isDirectFile,
+ trackChoiceManager = _this$_priv_contentIn15.trackChoiceManager,
+ mediaElementTrackChoiceManager = _this$_priv_contentIn15.mediaElementTrackChoiceManager;
if (isDirectFile) {
try {
- (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.setTextTrackById(textId);
+ mediaElementTrackChoiceManager === null || mediaElementTrackChoiceManager === void 0 ? void 0 : mediaElementTrackChoiceManager.setTextTrackById(textId);
return;
} catch (e) {
throw new Error("player: unknown text track");
}
}
- if (this._priv_trackChoiceManager === null || currentPeriod === null) {
+ if (trackChoiceManager === null || currentPeriod === null) {
throw new Error("No compatible content launched.");
}
try {
- this._priv_trackChoiceManager.setTextTrackByID(currentPeriod, textId);
+ trackChoiceManager.setTextTrackByID(currentPeriod, textId);
} catch (e) {
throw new Error("player: unknown text track");
}
@@ -56780,21 +53570,22 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
* Disable subtitles for the current content.
*/;
_proto.disableTextTrack = function disableTextTrack() {
- var _a;
if (this._priv_contentInfos === null) {
return;
}
var _this$_priv_contentIn16 = this._priv_contentInfos,
currentPeriod = _this$_priv_contentIn16.currentPeriod,
- isDirectFile = _this$_priv_contentIn16.isDirectFile;
+ isDirectFile = _this$_priv_contentIn16.isDirectFile,
+ trackChoiceManager = _this$_priv_contentIn16.trackChoiceManager,
+ mediaElementTrackChoiceManager = _this$_priv_contentIn16.mediaElementTrackChoiceManager;
if (isDirectFile) {
- (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.disableTextTrack();
+ mediaElementTrackChoiceManager === null || mediaElementTrackChoiceManager === void 0 ? void 0 : mediaElementTrackChoiceManager.disableTextTrack();
return;
}
- if (this._priv_trackChoiceManager === null || currentPeriod === null) {
+ if (trackChoiceManager === null || currentPeriod === null) {
return;
}
- return this._priv_trackChoiceManager.disableTextTrack(currentPeriod);
+ return trackChoiceManager.disableTextTrack(currentPeriod);
}
/**
* Update the video track for the current Period.
@@ -56803,26 +53594,27 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
* @throws Error - the given id is linked to no video track.
*/;
_proto.setVideoTrack = function setVideoTrack(videoId) {
- var _a;
if (this._priv_contentInfos === null) {
throw new Error("No content loaded");
}
var _this$_priv_contentIn17 = this._priv_contentInfos,
currentPeriod = _this$_priv_contentIn17.currentPeriod,
- isDirectFile = _this$_priv_contentIn17.isDirectFile;
+ isDirectFile = _this$_priv_contentIn17.isDirectFile,
+ trackChoiceManager = _this$_priv_contentIn17.trackChoiceManager,
+ mediaElementTrackChoiceManager = _this$_priv_contentIn17.mediaElementTrackChoiceManager;
if (isDirectFile) {
try {
- (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.setVideoTrackById(videoId);
+ mediaElementTrackChoiceManager === null || mediaElementTrackChoiceManager === void 0 ? void 0 : mediaElementTrackChoiceManager.setVideoTrackById(videoId);
return;
} catch (e) {
throw new Error("player: unknown video track");
}
}
- if (this._priv_trackChoiceManager === null || currentPeriod === null) {
+ if (trackChoiceManager === null || currentPeriod === null) {
throw new Error("No compatible content launched.");
}
try {
- this._priv_trackChoiceManager.setVideoTrackByID(currentPeriod, videoId);
+ trackChoiceManager.setVideoTrackByID(currentPeriod, videoId);
} catch (e) {
throw new Error("player: unknown video track");
}
@@ -56836,14 +53628,16 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
}
var _this$_priv_contentIn18 = this._priv_contentInfos,
currentPeriod = _this$_priv_contentIn18.currentPeriod,
- isDirectFile = _this$_priv_contentIn18.isDirectFile;
- if (isDirectFile && this._priv_mediaElementTrackChoiceManager !== null) {
- return this._priv_mediaElementTrackChoiceManager.disableVideoTrack();
+ isDirectFile = _this$_priv_contentIn18.isDirectFile,
+ trackChoiceManager = _this$_priv_contentIn18.trackChoiceManager,
+ mediaElementTrackChoiceManager = _this$_priv_contentIn18.mediaElementTrackChoiceManager;
+ if (isDirectFile && mediaElementTrackChoiceManager !== null) {
+ return mediaElementTrackChoiceManager.disableVideoTrack();
}
- if (this._priv_trackChoiceManager === null || currentPeriod === null) {
+ if (trackChoiceManager === null || currentPeriod === null) {
return;
}
- return this._priv_trackChoiceManager.disableVideoTrack(currentPeriod);
+ return trackChoiceManager.disableVideoTrack(currentPeriod);
}
/**
* Returns the current list of preferred audio tracks, in preference order.
@@ -56881,10 +53675,11 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
throw new Error("Invalid `setPreferredAudioTracks` argument. " + "Should have been an Array.");
}
this._priv_preferredAudioTracks = tracks;
- if (this._priv_trackChoiceManager !== null) {
- this._priv_trackChoiceManager.setPreferredAudioTracks(tracks, shouldApply);
- } else if (this._priv_mediaElementTrackChoiceManager !== null) {
- this._priv_mediaElementTrackChoiceManager.setPreferredAudioTracks(tracks, shouldApply);
+ var contentInfos = this._priv_contentInfos;
+ if (!(0,is_null_or_undefined/* default */.Z)(contentInfos === null || contentInfos === void 0 ? void 0 : contentInfos.trackChoiceManager)) {
+ contentInfos === null || contentInfos === void 0 ? void 0 : contentInfos.trackChoiceManager.setPreferredAudioTracks(tracks, shouldApply);
+ } else if (!(0,is_null_or_undefined/* default */.Z)(contentInfos === null || contentInfos === void 0 ? void 0 : contentInfos.mediaElementTrackChoiceManager)) {
+ contentInfos === null || contentInfos === void 0 ? void 0 : contentInfos.mediaElementTrackChoiceManager.setPreferredAudioTracks(tracks, shouldApply);
}
}
/**
@@ -56902,10 +53697,11 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
throw new Error("Invalid `setPreferredTextTracks` argument. " + "Should have been an Array.");
}
this._priv_preferredTextTracks = tracks;
- if (this._priv_trackChoiceManager !== null) {
- this._priv_trackChoiceManager.setPreferredTextTracks(tracks, shouldApply);
- } else if (this._priv_mediaElementTrackChoiceManager !== null) {
- this._priv_mediaElementTrackChoiceManager.setPreferredTextTracks(tracks, shouldApply);
+ var contentInfos = this._priv_contentInfos;
+ if (!(0,is_null_or_undefined/* default */.Z)(contentInfos === null || contentInfos === void 0 ? void 0 : contentInfos.trackChoiceManager)) {
+ contentInfos === null || contentInfos === void 0 ? void 0 : contentInfos.trackChoiceManager.setPreferredTextTracks(tracks, shouldApply);
+ } else if (!(0,is_null_or_undefined/* default */.Z)(contentInfos === null || contentInfos === void 0 ? void 0 : contentInfos.mediaElementTrackChoiceManager)) {
+ contentInfos === null || contentInfos === void 0 ? void 0 : contentInfos.mediaElementTrackChoiceManager.setPreferredTextTracks(tracks, shouldApply);
}
}
/**
@@ -56923,10 +53719,11 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
throw new Error("Invalid `setPreferredVideoTracks` argument. " + "Should have been an Array.");
}
this._priv_preferredVideoTracks = tracks;
- if (this._priv_trackChoiceManager !== null) {
- this._priv_trackChoiceManager.setPreferredVideoTracks(tracks, shouldApply);
- } else if (this._priv_mediaElementTrackChoiceManager !== null) {
- this._priv_mediaElementTrackChoiceManager.setPreferredVideoTracks(tracks, shouldApply);
+ var contentInfos = this._priv_contentInfos;
+ if (!(0,is_null_or_undefined/* default */.Z)(contentInfos === null || contentInfos === void 0 ? void 0 : contentInfos.trackChoiceManager)) {
+ contentInfos === null || contentInfos === void 0 ? void 0 : contentInfos.trackChoiceManager.setPreferredVideoTracks(tracks, shouldApply);
+ } else if (!(0,is_null_or_undefined/* default */.Z)(contentInfos === null || contentInfos === void 0 ? void 0 : contentInfos.mediaElementTrackChoiceManager)) {
+ contentInfos === null || contentInfos === void 0 ? void 0 : contentInfos.mediaElementTrackChoiceManager.setPreferredVideoTracks(tracks, shouldApply);
}
}
/**
@@ -57004,14 +53801,12 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
*/;
_proto._priv_cleanUpCurrentContentState = function _priv_cleanUpCurrentContentState() {
var _this4 = this;
- var _a;
+ var _a, _b;
log/* default.debug */.Z.debug("Locking `contentLock` to clean-up the current content.");
// lock playback of new contents while cleaning up is pending
this._priv_contentLock.setValue(true);
+ (_b = (_a = this._priv_contentInfos) === null || _a === void 0 ? void 0 : _a.mediaElementTrackChoiceManager) === null || _b === void 0 ? void 0 : _b.dispose();
this._priv_contentInfos = null;
- this._priv_trackChoiceManager = null;
- (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.dispose();
- this._priv_mediaElementTrackChoiceManager = null;
this._priv_contentEventsMemory = {};
// DRM-related clean-up
var freeUpContentLock = function freeUpContentLock() {
@@ -57033,153 +53828,57 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
freeUpContentLock();
}
}
- /**
- * Triggered each time the playback Observable emits.
- *
- * React to various events.
- *
- * @param {Object} event - payload emitted
- */;
- _proto._priv_onPlaybackEvent = function _priv_onPlaybackEvent(event) {
- switch (event.type) {
- case "inband-events":
- var inbandEvents = event.value;
- this.trigger("inbandEvents", inbandEvents);
- return;
- case "stream-event":
- this.trigger("streamEvent", event.value);
- break;
- case "stream-event-skip":
- this.trigger("streamEventSkip", event.value);
- break;
- case "activePeriodChanged":
- this._priv_onActivePeriodChanged(event.value);
- break;
- case "periodStreamReady":
- this._priv_onPeriodStreamReady(event.value);
- break;
- case "periodStreamCleared":
- this._priv_onPeriodStreamCleared(event.value);
- break;
- case "reloading-media-source":
- this._priv_onReloadingMediaSource();
- break;
- case "representationChange":
- this._priv_onRepresentationChange(event.value);
- break;
- case "adaptationChange":
- this._priv_onAdaptationChange(event.value);
- break;
- case "bitrateEstimationChange":
- this._priv_onBitrateEstimationChange(event.value);
- break;
- case "manifestReady":
- this._priv_onManifestReady(event.value);
- break;
- case "warning":
- this._priv_onPlaybackWarning(event.value);
- break;
- case "loaded":
- if (this._priv_contentInfos === null) {
- log/* default.error */.Z.error("API: Loaded event while no content is loaded");
- return;
- }
- this._priv_contentInfos.segmentBuffersStore = event.value.segmentBuffersStore;
- break;
- case "decipherabilityUpdate":
- this.trigger("decipherabilityUpdate", event.value);
- break;
- case "added-segment":
- if (this._priv_contentInfos === null) {
- log/* default.error */.Z.error("API: Added segment while no content is loaded");
- return;
- }
- // Manage image tracks
- // @deprecated
- var _event$value = event.value,
- content = _event$value.content,
- segmentData = _event$value.segmentData;
- if (content.adaptation.type === "image") {
- if (!(0,is_null_or_undefined/* default */.Z)(segmentData) && segmentData.type === "bif") {
- var imageData = segmentData.data;
- /* eslint-disable import/no-deprecated */
- this._priv_contentInfos.thumbnails = imageData;
- this.trigger("imageTrackUpdate", {
- data: this._priv_contentInfos.thumbnails
- });
- /* eslint-enable import/no-deprecated */
- }
- }
- }
- }
- /**
- * Triggered when we received a fatal error.
- * Clean-up ressources and signal that the content has stopped on error.
- * @param {Error} error
- */;
- _proto._priv_onPlaybackError = function _priv_onPlaybackError(error) {
- var formattedError = (0,format_error/* default */.Z)(error, {
- defaultCode: "NONE",
- defaultReason: "An unknown error stopped content playback."
- });
- formattedError.fatal = true;
- if (this._priv_contentInfos !== null) {
- this._priv_contentInfos.currentContentCanceller.cancel();
- }
- this._priv_cleanUpCurrentContentState();
- this._priv_currentError = formattedError;
- log/* default.error */.Z.error("API: The player stopped because of an error", error instanceof Error ? error : "");
- this._priv_setPlayerState("STOPPED" /* PLAYER_STATES.STOPPED */);
- // TODO This condition is here because the eventual callback called when the
- // player state is updated can launch a new content, thus the error will not
- // be here anymore, in which case triggering the "error" event is unwanted.
- // This is very ugly though, and we should probable have a better solution
- if (this._priv_currentError === formattedError) {
- this.trigger("error", formattedError);
- }
- }
- /**
- * Triggered when we received a warning event during playback.
- * Trigger the right API event.
- * @param {Error} error
- */;
- _proto._priv_onPlaybackWarning = function _priv_onPlaybackWarning(error) {
- var formattedError = (0,format_error/* default */.Z)(error, {
- defaultCode: "NONE",
- defaultReason: "An unknown error happened."
- });
- log/* default.warn */.Z.warn("API: Sending warning:", formattedError);
- this.trigger("warning", formattedError);
- }
/**
* Triggered when the Manifest has been loaded for the current content.
* Initialize various private properties and emit initial event.
- * @param {Object} value
+ * @param {Object} contentInfos
+ * @param {Object} manifest
*/;
- _proto._priv_onManifestReady = function _priv_onManifestReady(_ref2) {
+ _proto._priv_onManifestReady = function _priv_onManifestReady(contentInfos, manifest) {
var _this5 = this;
- var manifest = _ref2.manifest;
- var contentInfos = this._priv_contentInfos;
- if (contentInfos === null) {
- log/* default.error */.Z.error("API: The manifest is loaded but no content is.");
- return;
+ var _a;
+ if (contentInfos.contentId !== ((_a = this._priv_contentInfos) === null || _a === void 0 ? void 0 : _a.contentId)) {
+ return; // Event for another content
}
+
contentInfos.manifest = manifest;
+ var cancelSignal = contentInfos.currentContentCanceller.signal;
this._priv_reloadingMetadata.manifest = manifest;
var initialAudioTrack = contentInfos.initialAudioTrack,
initialTextTrack = contentInfos.initialTextTrack;
- this._priv_trackChoiceManager = new TrackChoiceManager({
+ contentInfos.trackChoiceManager = new TrackChoiceManager({
preferTrickModeTracks: this._priv_preferTrickModeTracks
});
var preferredAudioTracks = initialAudioTrack === undefined ? this._priv_preferredAudioTracks : [initialAudioTrack];
- this._priv_trackChoiceManager.setPreferredAudioTracks(preferredAudioTracks, true);
+ contentInfos.trackChoiceManager.setPreferredAudioTracks(preferredAudioTracks, true);
var preferredTextTracks = initialTextTrack === undefined ? this._priv_preferredTextTracks : [initialTextTrack];
- this._priv_trackChoiceManager.setPreferredTextTracks(preferredTextTracks, true);
- this._priv_trackChoiceManager.setPreferredVideoTracks(this._priv_preferredVideoTracks, true);
- manifest.addEventListener("manifestUpdate", function () {
+ contentInfos.trackChoiceManager.setPreferredTextTracks(preferredTextTracks, true);
+ contentInfos.trackChoiceManager.setPreferredVideoTracks(this._priv_preferredVideoTracks, true);
+ manifest.addEventListener("manifestUpdate", function (updates) {
+ var _a, _b, _c;
// Update the tracks chosen if it changed
- if (_this5._priv_trackChoiceManager !== null) {
- _this5._priv_trackChoiceManager.update();
+ if (contentInfos.trackChoiceManager !== null) {
+ contentInfos.trackChoiceManager.update();
+ }
+ var currentPeriod = (_b = (_a = _this5._priv_contentInfos) === null || _a === void 0 ? void 0 : _a.currentPeriod) !== null && _b !== void 0 ? _b : undefined;
+ var trackChoiceManager = (_c = _this5._priv_contentInfos) === null || _c === void 0 ? void 0 : _c.trackChoiceManager;
+ if (currentPeriod === undefined || (0,is_null_or_undefined/* default */.Z)(trackChoiceManager)) {
+ return;
+ }
+ for (var _iterator = public_api_createForOfIteratorHelperLoose(updates.updatedPeriods), _step; !(_step = _iterator()).done;) {
+ var update = _step.value;
+ if (update.period.id === currentPeriod.id) {
+ if (update.result.addedAdaptations.length > 0 || update.result.removedAdaptations.length > 0) {
+ // We might have new (or less) tracks, send events just to be sure
+ var audioTracks = trackChoiceManager.getAvailableAudioTracks(currentPeriod);
+ _this5._priv_triggerEventIfNotStopped("availableAudioTracksChange", audioTracks !== null && audioTracks !== void 0 ? audioTracks : [], cancelSignal);
+ var textTracks = trackChoiceManager.getAvailableTextTracks(currentPeriod);
+ _this5._priv_triggerEventIfNotStopped("availableTextTracksChange", textTracks !== null && textTracks !== void 0 ? textTracks : [], cancelSignal);
+ var videoTracks = trackChoiceManager.getAvailableVideoTracks(currentPeriod);
+ _this5._priv_triggerEventIfNotStopped("availableVideoTracksChange", videoTracks !== null && videoTracks !== void 0 ? videoTracks : [], cancelSignal);
+ }
+ }
+ return;
}
}, contentInfos.currentContentCanceller.signal);
}
@@ -57187,114 +53886,136 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
* Triggered each times the current Period Changed.
* Store and emit initial state for the Period.
*
- * @param {Object} value
+ * @param {Object} contentInfos
+ * @param {Object} periodInfo
*/;
- _proto._priv_onActivePeriodChanged = function _priv_onActivePeriodChanged(_ref3) {
- var period = _ref3.period;
- var _a, _b, _c, _d, _e, _f;
- if (this._priv_contentInfos === null) {
- log/* default.error */.Z.error("API: The active period changed but no content is loaded");
- return;
+ _proto._priv_onActivePeriodChanged = function _priv_onActivePeriodChanged(contentInfos, _ref) {
+ var period = _ref.period;
+ var _a, _b, _c, _d, _e, _f, _g, _h;
+ if (contentInfos.contentId !== ((_a = this._priv_contentInfos) === null || _a === void 0 ? void 0 : _a.contentId)) {
+ return; // Event for another content
}
- this._priv_contentInfos.currentPeriod = period;
+
+ contentInfos.currentPeriod = period;
+ var cancelSignal = contentInfos.currentContentCanceller.signal;
if (this._priv_contentEventsMemory.periodChange !== period) {
this._priv_contentEventsMemory.periodChange = period;
- this.trigger("periodChange", period);
+ this._priv_triggerEventIfNotStopped("periodChange", period, cancelSignal);
}
- this.trigger("availableAudioTracksChange", this.getAvailableAudioTracks());
- this.trigger("availableTextTracksChange", this.getAvailableTextTracks());
- this.trigger("availableVideoTracksChange", this.getAvailableVideoTracks());
+ this._priv_triggerEventIfNotStopped("availableAudioTracksChange", this.getAvailableAudioTracks(), cancelSignal);
+ this._priv_triggerEventIfNotStopped("availableTextTracksChange", this.getAvailableTextTracks(), cancelSignal);
+ this._priv_triggerEventIfNotStopped("availableVideoTracksChange", this.getAvailableVideoTracks(), cancelSignal);
+ var trackChoiceManager = (_b = this._priv_contentInfos) === null || _b === void 0 ? void 0 : _b.trackChoiceManager;
// Emit intial events for the Period
- if (this._priv_trackChoiceManager !== null) {
- var audioTrack = this._priv_trackChoiceManager.getChosenAudioTrack(period);
- var textTrack = this._priv_trackChoiceManager.getChosenTextTrack(period);
- var videoTrack = this._priv_trackChoiceManager.getChosenVideoTrack(period);
- this.trigger("audioTrackChange", audioTrack);
- this.trigger("textTrackChange", textTrack);
- this.trigger("videoTrackChange", videoTrack);
+ if (!(0,is_null_or_undefined/* default */.Z)(trackChoiceManager)) {
+ var audioTrack = trackChoiceManager.getChosenAudioTrack(period);
+ this._priv_triggerEventIfNotStopped("audioTrackChange", audioTrack, cancelSignal);
+ var textTrack = trackChoiceManager.getChosenTextTrack(period);
+ this._priv_triggerEventIfNotStopped("textTrackChange", textTrack, cancelSignal);
+ var videoTrack = trackChoiceManager.getChosenVideoTrack(period);
+ this._priv_triggerEventIfNotStopped("videoTrackChange", videoTrack, cancelSignal);
} else {
- this.trigger("audioTrackChange", null);
- this.trigger("textTrackChange", null);
- this.trigger("videoTrackChange", null);
+ this._priv_triggerEventIfNotStopped("audioTrackChange", null, cancelSignal);
+ this._priv_triggerEventIfNotStopped("textTrackChange", null, cancelSignal);
+ this._priv_triggerEventIfNotStopped("videoTrackChange", null, cancelSignal);
+ }
+ this._priv_triggerAvailableBitratesChangeEvent("availableAudioBitratesChange", this.getAvailableAudioBitrates(), cancelSignal);
+ if (contentInfos.currentContentCanceller.isUsed()) {
+ return;
+ }
+ this._priv_triggerAvailableBitratesChangeEvent("availableVideoBitratesChange", this.getAvailableVideoBitrates(), cancelSignal);
+ if (contentInfos.currentContentCanceller.isUsed()) {
+ return;
+ }
+ var audioBitrate = (_e = (_d = (_c = this._priv_getCurrentRepresentations()) === null || _c === void 0 ? void 0 : _c.audio) === null || _d === void 0 ? void 0 : _d.bitrate) !== null && _e !== void 0 ? _e : -1;
+ this._priv_triggerCurrentBitrateChangeEvent("audioBitrateChange", audioBitrate, cancelSignal);
+ if (contentInfos.currentContentCanceller.isUsed()) {
+ return;
}
- this._priv_triggerAvailableBitratesChangeEvent("availableAudioBitratesChange", this.getAvailableAudioBitrates());
- this._priv_triggerAvailableBitratesChangeEvent("availableVideoBitratesChange", this.getAvailableVideoBitrates());
- var audioBitrate = (_c = (_b = (_a = this._priv_getCurrentRepresentations()) === null || _a === void 0 ? void 0 : _a.audio) === null || _b === void 0 ? void 0 : _b.bitrate) !== null && _c !== void 0 ? _c : -1;
- this._priv_triggerCurrentBitrateChangeEvent("audioBitrateChange", audioBitrate);
- var videoBitrate = (_f = (_e = (_d = this._priv_getCurrentRepresentations()) === null || _d === void 0 ? void 0 : _d.video) === null || _e === void 0 ? void 0 : _e.bitrate) !== null && _f !== void 0 ? _f : -1;
- this._priv_triggerCurrentBitrateChangeEvent("videoBitrateChange", videoBitrate);
+ var videoBitrate = (_h = (_g = (_f = this._priv_getCurrentRepresentations()) === null || _f === void 0 ? void 0 : _f.video) === null || _g === void 0 ? void 0 : _g.bitrate) !== null && _h !== void 0 ? _h : -1;
+ this._priv_triggerCurrentBitrateChangeEvent("videoBitrateChange", videoBitrate, cancelSignal);
}
/**
* Triggered each times a new "PeriodStream" is ready.
* Choose the right Adaptation for the Period and emit it.
+ * @param {Object} contentInfos
* @param {Object} value
*/;
- _proto._priv_onPeriodStreamReady = function _priv_onPeriodStreamReady(value) {
+ _proto._priv_onPeriodStreamReady = function _priv_onPeriodStreamReady(contentInfos, value) {
+ var _a;
+ if (contentInfos.contentId !== ((_a = this._priv_contentInfos) === null || _a === void 0 ? void 0 : _a.contentId)) {
+ return; // Event for another content
+ }
+
var type = value.type,
period = value.period,
- adaptation$ = value.adaptation$;
+ adaptationRef = value.adaptationRef;
+ var trackChoiceManager = contentInfos.trackChoiceManager;
switch (type) {
case "video":
- if (this._priv_trackChoiceManager === null) {
+ if ((0,is_null_or_undefined/* default */.Z)(trackChoiceManager)) {
log/* default.error */.Z.error("API: TrackChoiceManager not instanciated for a new video period");
- adaptation$.next(null);
+ adaptationRef.setValue(null);
} else {
- this._priv_trackChoiceManager.addPeriod(type, period, adaptation$);
- this._priv_trackChoiceManager.setInitialVideoTrack(period);
+ trackChoiceManager.addPeriod(type, period, adaptationRef);
+ trackChoiceManager.setInitialVideoTrack(period);
}
break;
case "audio":
- if (this._priv_trackChoiceManager === null) {
+ if ((0,is_null_or_undefined/* default */.Z)(trackChoiceManager)) {
log/* default.error */.Z.error("API: TrackChoiceManager not instanciated for a new " + type + " period");
- adaptation$.next(null);
+ adaptationRef.setValue(null);
} else {
- this._priv_trackChoiceManager.addPeriod(type, period, adaptation$);
- this._priv_trackChoiceManager.setInitialAudioTrack(period);
+ trackChoiceManager.addPeriod(type, period, adaptationRef);
+ trackChoiceManager.setInitialAudioTrack(period);
}
break;
case "text":
- if (this._priv_trackChoiceManager === null) {
+ if ((0,is_null_or_undefined/* default */.Z)(trackChoiceManager)) {
log/* default.error */.Z.error("API: TrackChoiceManager not instanciated for a new " + type + " period");
- adaptation$.next(null);
+ adaptationRef.setValue(null);
} else {
- this._priv_trackChoiceManager.addPeriod(type, period, adaptation$);
- this._priv_trackChoiceManager.setInitialTextTrack(period);
+ trackChoiceManager.addPeriod(type, period, adaptationRef);
+ trackChoiceManager.setInitialTextTrack(period);
}
break;
default:
var adaptations = period.adaptations[type];
if (!(0,is_null_or_undefined/* default */.Z)(adaptations) && adaptations.length > 0) {
- adaptation$.next(adaptations[0]);
+ adaptationRef.setValue(adaptations[0]);
} else {
- adaptation$.next(null);
+ adaptationRef.setValue(null);
}
break;
}
}
/**
* Triggered each times we "remove" a PeriodStream.
+ * @param {Object} contentInfos
* @param {Object} value
*/;
- _proto._priv_onPeriodStreamCleared = function _priv_onPeriodStreamCleared(value) {
+ _proto._priv_onPeriodStreamCleared = function _priv_onPeriodStreamCleared(contentInfos, value) {
+ var _a;
+ if (contentInfos.contentId !== ((_a = this._priv_contentInfos) === null || _a === void 0 ? void 0 : _a.contentId)) {
+ return; // Event for another content
+ }
+
var type = value.type,
period = value.period;
+ var trackChoiceManager = contentInfos.trackChoiceManager;
// Clean-up track choice from TrackChoiceManager
switch (type) {
case "audio":
case "text":
case "video":
- if (this._priv_trackChoiceManager !== null) {
- this._priv_trackChoiceManager.removePeriod(type, period);
+ if (!(0,is_null_or_undefined/* default */.Z)(trackChoiceManager)) {
+ trackChoiceManager.removePeriod(type, period);
}
break;
}
// Clean-up stored Representation and Adaptation information
- if (this._priv_contentInfos === null) {
- return;
- }
- var _this$_priv_contentIn20 = this._priv_contentInfos,
- activeAdaptations = _this$_priv_contentIn20.activeAdaptations,
- activeRepresentations = _this$_priv_contentIn20.activeRepresentations;
+ var activeAdaptations = contentInfos.activeAdaptations,
+ activeRepresentations = contentInfos.activeRepresentations;
if (!(0,is_null_or_undefined/* default */.Z)(activeAdaptations) && !(0,is_null_or_undefined/* default */.Z)(activeAdaptations[period.id])) {
var activePeriodAdaptations = activeAdaptations[period.id];
delete activePeriodAdaptations[type];
@@ -57310,38 +54031,27 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
}
}
}
- /**
- * Triggered each time the content is re-loaded on the MediaSource.
- */;
- _proto._priv_onReloadingMediaSource = function _priv_onReloadingMediaSource() {
- if (this._priv_contentInfos !== null) {
- this._priv_contentInfos.segmentBuffersStore = null;
- }
- if (this._priv_trackChoiceManager !== null) {
- this._priv_trackChoiceManager.resetPeriods();
- }
- }
/**
* Triggered each times a new Adaptation is considered for the current
* content.
* Store given Adaptation and emit it if from the current Period.
+ * @param {Object} contentInfos
* @param {Object} value
*/;
- _proto._priv_onAdaptationChange = function _priv_onAdaptationChange(_ref4) {
- var type = _ref4.type,
- adaptation = _ref4.adaptation,
- period = _ref4.period;
- if (this._priv_contentInfos === null) {
- log/* default.error */.Z.error("API: The adaptations changed but no content is loaded");
- return;
+ _proto._priv_onAdaptationChange = function _priv_onAdaptationChange(contentInfos, _ref2) {
+ var type = _ref2.type,
+ adaptation = _ref2.adaptation,
+ period = _ref2.period;
+ var _a;
+ if (contentInfos.contentId !== ((_a = this._priv_contentInfos) === null || _a === void 0 ? void 0 : _a.contentId)) {
+ return; // Event for another content
}
- // lazily create this._priv_contentInfos.activeAdaptations
- if (this._priv_contentInfos.activeAdaptations === null) {
- this._priv_contentInfos.activeAdaptations = {};
+ // lazily create contentInfos.activeAdaptations
+ if (contentInfos.activeAdaptations === null) {
+ contentInfos.activeAdaptations = {};
}
- var _this$_priv_contentIn21 = this._priv_contentInfos,
- activeAdaptations = _this$_priv_contentIn21.activeAdaptations,
- currentPeriod = _this$_priv_contentIn21.currentPeriod;
+ var activeAdaptations = contentInfos.activeAdaptations,
+ currentPeriod = contentInfos.currentPeriod;
var activePeriodAdaptations = activeAdaptations[period.id];
if ((0,is_null_or_undefined/* default */.Z)(activePeriodAdaptations)) {
var _activeAdaptations$pe;
@@ -57349,23 +54059,25 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
} else {
activePeriodAdaptations[type] = adaptation;
}
- if (this._priv_trackChoiceManager !== null && currentPeriod !== null && !(0,is_null_or_undefined/* default */.Z)(period) && period.id === currentPeriod.id) {
+ var trackChoiceManager = contentInfos.trackChoiceManager;
+ var cancelSignal = contentInfos.currentContentCanceller.signal;
+ if (trackChoiceManager !== null && currentPeriod !== null && !(0,is_null_or_undefined/* default */.Z)(period) && period.id === currentPeriod.id) {
switch (type) {
case "audio":
- var audioTrack = this._priv_trackChoiceManager.getChosenAudioTrack(currentPeriod);
- this.trigger("audioTrackChange", audioTrack);
+ var audioTrack = trackChoiceManager.getChosenAudioTrack(currentPeriod);
+ this._priv_triggerEventIfNotStopped("audioTrackChange", audioTrack, cancelSignal);
var availableAudioBitrates = this.getAvailableAudioBitrates();
- this._priv_triggerAvailableBitratesChangeEvent("availableAudioBitratesChange", availableAudioBitrates);
+ this._priv_triggerAvailableBitratesChangeEvent("availableAudioBitratesChange", availableAudioBitrates, cancelSignal);
break;
case "text":
- var textTrack = this._priv_trackChoiceManager.getChosenTextTrack(currentPeriod);
- this.trigger("textTrackChange", textTrack);
+ var textTrack = trackChoiceManager.getChosenTextTrack(currentPeriod);
+ this._priv_triggerEventIfNotStopped("textTrackChange", textTrack, cancelSignal);
break;
case "video":
- var videoTrack = this._priv_trackChoiceManager.getChosenVideoTrack(currentPeriod);
- this.trigger("videoTrackChange", videoTrack);
+ var videoTrack = trackChoiceManager.getChosenVideoTrack(currentPeriod);
+ this._priv_triggerEventIfNotStopped("videoTrackChange", videoTrack, cancelSignal);
var availableVideoBitrates = this.getAvailableVideoBitrates();
- this._priv_triggerAvailableBitratesChangeEvent("availableVideoBitratesChange", availableVideoBitrates);
+ this._priv_triggerAvailableBitratesChangeEvent("availableVideoBitratesChange", availableVideoBitrates, cancelSignal);
break;
}
}
@@ -57375,24 +54087,23 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
*
* Store given Representation and emit it if from the current Period.
*
+ * @param {Object} contentInfos
* @param {Object} obj
*/;
- _proto._priv_onRepresentationChange = function _priv_onRepresentationChange(_ref5) {
- var type = _ref5.type,
- period = _ref5.period,
- representation = _ref5.representation;
- var _a;
- if (this._priv_contentInfos === null) {
- log/* default.error */.Z.error("API: The representations changed but no content is loaded");
- return;
+ _proto._priv_onRepresentationChange = function _priv_onRepresentationChange(contentInfos, _ref3) {
+ var type = _ref3.type,
+ period = _ref3.period,
+ representation = _ref3.representation;
+ var _a, _b;
+ if (contentInfos.contentId !== ((_a = this._priv_contentInfos) === null || _a === void 0 ? void 0 : _a.contentId)) {
+ return; // Event for another content
}
- // lazily create this._priv_contentInfos.activeRepresentations
- if (this._priv_contentInfos.activeRepresentations === null) {
- this._priv_contentInfos.activeRepresentations = {};
+ // lazily create contentInfos.activeRepresentations
+ if (contentInfos.activeRepresentations === null) {
+ contentInfos.activeRepresentations = {};
}
- var _this$_priv_contentIn22 = this._priv_contentInfos,
- activeRepresentations = _this$_priv_contentIn22.activeRepresentations,
- currentPeriod = _this$_priv_contentIn22.currentPeriod;
+ var activeRepresentations = contentInfos.activeRepresentations,
+ currentPeriod = contentInfos.currentPeriod;
var activePeriodRepresentations = activeRepresentations[period.id];
if ((0,is_null_or_undefined/* default */.Z)(activePeriodRepresentations)) {
var _activeRepresentation;
@@ -57400,12 +54111,13 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
} else {
activePeriodRepresentations[type] = representation;
}
- var bitrate = (_a = representation === null || representation === void 0 ? void 0 : representation.bitrate) !== null && _a !== void 0 ? _a : -1;
+ var bitrate = (_b = representation === null || representation === void 0 ? void 0 : representation.bitrate) !== null && _b !== void 0 ? _b : -1;
if (!(0,is_null_or_undefined/* default */.Z)(period) && currentPeriod !== null && currentPeriod.id === period.id) {
+ var cancelSignal = this._priv_contentInfos.currentContentCanceller.signal;
if (type === "video") {
- this._priv_triggerCurrentBitrateChangeEvent("videoBitrateChange", bitrate);
+ this._priv_triggerCurrentBitrateChangeEvent("videoBitrateChange", bitrate, cancelSignal);
} else if (type === "audio") {
- this._priv_triggerCurrentBitrateChangeEvent("audioBitrateChange", bitrate);
+ this._priv_triggerCurrentBitrateChangeEvent("audioBitrateChange", bitrate, cancelSignal);
}
}
}
@@ -57416,9 +54128,9 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
*
* @param {Object} value
*/;
- _proto._priv_onBitrateEstimationChange = function _priv_onBitrateEstimationChange(_ref6) {
- var type = _ref6.type,
- bitrate = _ref6.bitrate;
+ _proto._priv_onBitrateEstimationChange = function _priv_onBitrateEstimationChange(_ref4) {
+ var type = _ref4.type,
+ bitrate = _ref4.bitrate;
if (bitrate !== undefined) {
this._priv_bitrateInfos.lastBitrates[type] = bitrate;
}
@@ -57456,17 +54168,17 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
*
* Trigger the right Player Event
*
+ * @param {Object} contentInfos
* @param {Object} observation
*/;
- _proto._priv_triggerPositionUpdate = function _priv_triggerPositionUpdate(observation) {
- var _a;
- if (this._priv_contentInfos === null) {
- log/* default.warn */.Z.warn("API: Cannot perform time update: no content loaded.");
- return;
+ _proto._priv_triggerPositionUpdate = function _priv_triggerPositionUpdate(contentInfos, observation) {
+ var _a, _b;
+ if (contentInfos.contentId !== ((_a = this._priv_contentInfos) === null || _a === void 0 ? void 0 : _a.contentId)) {
+ return; // Event for another content
}
- var _this$_priv_contentIn23 = this._priv_contentInfos,
- isDirectFile = _this$_priv_contentIn23.isDirectFile,
- manifest = _this$_priv_contentIn23.manifest;
+
+ var isDirectFile = contentInfos.isDirectFile,
+ manifest = contentInfos.manifest;
if (!isDirectFile && manifest === null || (0,is_null_or_undefined/* default */.Z)(observation)) {
return;
}
@@ -57480,7 +54192,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
bufferGap: observation.bufferGap === undefined || !isFinite(observation.bufferGap) ? 0 : observation.bufferGap
};
if (manifest !== null && manifest.isLive && observation.position > 0) {
- var ast = (_a = manifest.availabilityStartTime) !== null && _a !== void 0 ? _a : 0;
+ var ast = (_b = manifest.availabilityStartTime) !== null && _b !== void 0 ? _b : 0;
positionData.wallClockTime = observation.position + ast;
var livePosition = manifest.getLivePosition();
if (livePosition !== undefined) {
@@ -57499,10 +54211,11 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
* the previously stored value.
* @param {string} event
* @param {Array.} newVal
+ * @param {Object} currentContentCancelSignal
*/;
- _proto._priv_triggerAvailableBitratesChangeEvent = function _priv_triggerAvailableBitratesChangeEvent(event, newVal) {
+ _proto._priv_triggerAvailableBitratesChangeEvent = function _priv_triggerAvailableBitratesChangeEvent(event, newVal, currentContentCancelSignal) {
var prevVal = this._priv_contentEventsMemory[event];
- if (prevVal === undefined || !(0,are_arrays_of_numbers_equal/* default */.Z)(newVal, prevVal)) {
+ if (!currentContentCancelSignal.isCancelled() && (prevVal === undefined || !(0,are_arrays_of_numbers_equal/* default */.Z)(newVal, prevVal))) {
this._priv_contentEventsMemory[event] = newVal;
this.trigger(event, newVal);
}
@@ -57512,9 +54225,10 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
* previously stored value.
* @param {string} event
* @param {number} newVal
+ * @param {Object} currentContentCancelSignal
*/;
- _proto._priv_triggerCurrentBitrateChangeEvent = function _priv_triggerCurrentBitrateChangeEvent(event, newVal) {
- if (newVal !== this._priv_contentEventsMemory[event]) {
+ _proto._priv_triggerCurrentBitrateChangeEvent = function _priv_triggerCurrentBitrateChangeEvent(event, newVal, currentContentCancelSignal) {
+ if (!currentContentCancelSignal.isCancelled() && newVal !== this._priv_contentEventsMemory[event]) {
this._priv_contentEventsMemory[event] = newVal;
this.trigger(event, newVal);
}
@@ -57523,13 +54237,66 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
if (this._priv_contentInfos === null) {
return null;
}
- var _this$_priv_contentIn24 = this._priv_contentInfos,
- currentPeriod = _this$_priv_contentIn24.currentPeriod,
- activeRepresentations = _this$_priv_contentIn24.activeRepresentations;
+ var _this$_priv_contentIn20 = this._priv_contentInfos,
+ currentPeriod = _this$_priv_contentIn20.currentPeriod,
+ activeRepresentations = _this$_priv_contentIn20.activeRepresentations;
if (currentPeriod === null || activeRepresentations === null || (0,is_null_or_undefined/* default */.Z)(activeRepresentations[currentPeriod.id])) {
return null;
}
return activeRepresentations[currentPeriod.id];
+ }
+ /**
+ * @param {string} evt
+ * @param {*} arg
+ * @param {Object} currentContentCancelSignal
+ */;
+ _proto._priv_triggerEventIfNotStopped = function _priv_triggerEventIfNotStopped(evt, arg, currentContentCancelSignal) {
+ if (!currentContentCancelSignal.isCancelled()) {
+ this.trigger(evt, arg);
+ }
+ }
+ /**
+ * @param {Object} defaultAudioTrack
+ * @param {Object} defaultTextTrack
+ * @param {Object} cancelSignal
+ * @returns {Object}
+ */;
+ _proto._priv_initializeMediaElementTrackChoiceManager = function _priv_initializeMediaElementTrackChoiceManager(defaultAudioTrack, defaultTextTrack, cancelSignal) {
+ var _this6 = this;
+ var _a, _b, _c;
+ (0,assert/* default */.Z)(features/* default.directfile */.Z.directfile !== null, "Initializing `MediaElementTrackChoiceManager` without Directfile feature");
+ (0,assert/* default */.Z)(this.videoElement !== null, "Initializing `MediaElementTrackChoiceManager` on a disposed RxPlayer");
+ var mediaElementTrackChoiceManager = new features/* default.directfile.mediaElementTrackChoiceManager */.Z.directfile.mediaElementTrackChoiceManager(this.videoElement);
+ var preferredAudioTracks = defaultAudioTrack === undefined ? this._priv_preferredAudioTracks : [defaultAudioTrack];
+ mediaElementTrackChoiceManager.setPreferredAudioTracks(preferredAudioTracks, true);
+ var preferredTextTracks = defaultTextTrack === undefined ? this._priv_preferredTextTracks : [defaultTextTrack];
+ mediaElementTrackChoiceManager.setPreferredTextTracks(preferredTextTracks, true);
+ mediaElementTrackChoiceManager.setPreferredVideoTracks(this._priv_preferredVideoTracks, true);
+ this._priv_triggerEventIfNotStopped("availableAudioTracksChange", mediaElementTrackChoiceManager.getAvailableAudioTracks(), cancelSignal);
+ this._priv_triggerEventIfNotStopped("availableVideoTracksChange", mediaElementTrackChoiceManager.getAvailableVideoTracks(), cancelSignal);
+ this._priv_triggerEventIfNotStopped("availableTextTracksChange", mediaElementTrackChoiceManager.getAvailableTextTracks(), cancelSignal);
+ this._priv_triggerEventIfNotStopped("audioTrackChange", (_a = mediaElementTrackChoiceManager.getChosenAudioTrack()) !== null && _a !== void 0 ? _a : null, cancelSignal);
+ this._priv_triggerEventIfNotStopped("textTrackChange", (_b = mediaElementTrackChoiceManager.getChosenTextTrack()) !== null && _b !== void 0 ? _b : null, cancelSignal);
+ this._priv_triggerEventIfNotStopped("videoTrackChange", (_c = mediaElementTrackChoiceManager.getChosenVideoTrack()) !== null && _c !== void 0 ? _c : null, cancelSignal);
+ mediaElementTrackChoiceManager.addEventListener("availableVideoTracksChange", function (val) {
+ return _this6.trigger("availableVideoTracksChange", val);
+ });
+ mediaElementTrackChoiceManager.addEventListener("availableAudioTracksChange", function (val) {
+ return _this6.trigger("availableAudioTracksChange", val);
+ });
+ mediaElementTrackChoiceManager.addEventListener("availableTextTracksChange", function (val) {
+ return _this6.trigger("availableTextTracksChange", val);
+ });
+ mediaElementTrackChoiceManager.addEventListener("audioTrackChange", function (val) {
+ return _this6.trigger("audioTrackChange", val);
+ });
+ mediaElementTrackChoiceManager.addEventListener("videoTrackChange", function (val) {
+ return _this6.trigger("videoTrackChange", val);
+ });
+ mediaElementTrackChoiceManager.addEventListener("textTrackChange", function (val) {
+ return _this6.trigger("textTrackChange", val);
+ });
+ return mediaElementTrackChoiceManager;
};
(0,createClass/* default */.Z)(Player, null, [{
key: "ErrorTypes",
@@ -57565,7 +54332,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
}]);
return Player;
}(event_emitter/* default */.Z);
-Player.version = /* PLAYER_VERSION */"3.29.0";
+Player.version = /* PLAYER_VERSION */"3.30.0";
/* harmony default export */ var public_api = (Player);
;// CONCATENATED MODULE: ./src/core/api/index.ts
/**
@@ -57623,7 +54390,7 @@ function initializeFeaturesObject() {
features_object/* default.imageParser */.Z.imageParser = (__webpack_require__(3203)/* ["default"] */ .Z);
}
// Feature switching the Native TextTrack implementation
- var HAS_NATIVE_MODE = 1 || 0 || 0 || 0;
+ var HAS_NATIVE_MODE = true || 0;
if (true) {
features_object/* default.transports.smooth */.Z.transports.smooth = (__webpack_require__(2339)/* ["default"] */ .Z);
}
@@ -57633,7 +54400,8 @@ function initializeFeaturesObject() {
}
if (false) {}
if (false) {}
- if (HAS_NATIVE_MODE === 1) {
+ if (false) {}
+ if (HAS_NATIVE_MODE) {
features_object/* default.nativeTextTracksBuffer */.Z.nativeTextTracksBuffer = (__webpack_require__(9059)/* ["default"] */ .Z);
if (true) {
features_object/* default.nativeTextTracksParsers.vtt */.Z.nativeTextTracksParsers.vtt = (__webpack_require__(9405)/* ["default"] */ .Z);
@@ -57649,8 +54417,8 @@ function initializeFeaturesObject() {
}
}
// Feature switching the HTML TextTrack implementation
- var HAS_HTML_MODE = 1 || 0 || 0 || 0;
- if (HAS_HTML_MODE === 1) {
+ var HAS_HTML_MODE = true || 0;
+ if (HAS_HTML_MODE) {
features_object/* default.htmlTextTracksBuffer */.Z.htmlTextTracksBuffer = (__webpack_require__(5192)/* ["default"] */ .Z);
if (true) {
features_object/* default.htmlTextTracksParsers.sami */.Z.htmlTextTracksParsers.sami = (__webpack_require__(5734)/* ["default"] */ .Z);
@@ -57666,7 +54434,7 @@ function initializeFeaturesObject() {
}
}
if (true) {
- var initDirectFile = (__webpack_require__(8969)/* ["default"] */ .Z);
+ var initDirectFile = (__webpack_require__(9372)/* ["default"] */ .Z);
var mediaElementTrackChoiceManager = (__webpack_require__(6796)/* ["default"] */ .Z);
features_object/* default.directfile */.Z.directfile = {
initDirectFile: initDirectFile,
diff --git a/dist/rx-player.min.js b/dist/rx-player.min.js
index ae25ceec7f..14745795d9 100644
--- a/dist/rx-player.min.js
+++ b/dist/rx-player.min.js
@@ -1,2 +1,2 @@
/*! For license information please see rx-player.min.js.LICENSE.txt */
-!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.RxPlayer=t():e.RxPlayer=t()}(self,(function(){return function(){var e={3774:function(e,t,n){"use strict";n.d(t,{J:function(){return a},c:function(){return o}});var r=n(1946),i=n(2203).Z?void 0:window,a=void 0===i?void 0:(0,r.Z)(i.MediaSource)?(0,r.Z)(i.MozMediaSource)?(0,r.Z)(i.WebKitMediaSource)?i.MSMediaSource:i.WebKitMediaSource:i.MozMediaSource:i.MediaSource,o={HAVE_NOTHING:0,HAVE_METADATA:1,HAVE_CURRENT_DATA:2,HAVE_FUTURE_DATA:3,HAVE_ENOUGH_DATA:4}},3666:function(e,t,n){"use strict";n.d(t,{SB:function(){return m},YM:function(){return s},fq:function(){return o},gM:function(){return v},kD:function(){return u},op:function(){return c},uz:function(){return p},vS:function(){return h},vU:function(){return l},yS:function(){return d}});var r,i,a=n(2203),o=!a.Z&&void 0!==window.MSInputMethodContext&&void 0!==document.documentMode,s=!a.Z&&("Microsoft Internet Explorer"===navigator.appName||"Netscape"===navigator.appName&&/(Trident|Edge)\//.test(navigator.userAgent)),u=!a.Z&&-1!==navigator.userAgent.toLowerCase().indexOf("edg/"),l=!a.Z&&-1!==navigator.userAgent.toLowerCase().indexOf("firefox"),c=!a.Z&&/SamsungBrowser/.test(navigator.userAgent),d=!a.Z&&/Tizen/.test(navigator.userAgent),f=!a.Z&&navigator.userAgent.indexOf("Web0S")>=0,v=f&&(/[Ww]eb[O0]S.TV-2021/.test(navigator.userAgent)||/[Cc]hr[o0]me\/79/.test(navigator.userAgent)),p=f&&(/[Ww]eb[O0]S.TV-2022/.test(navigator.userAgent)||/[Cc]hr[o0]me\/87/.test(navigator.userAgent)),h=!a.Z&&(Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>=0||"[object SafariRemoteNotification]"===(null===(i=null===(r=window.safari)||void 0===r?void 0:r.pushNotification)||void 0===i?void 0:i.toString())),m=!a.Z&&"string"==typeof navigator.platform&&/iPad|iPhone|iPod/.test(navigator.platform)},5767:function(e,t,n){"use strict";n.d(t,{Z:function(){return a}});var r=n(3887),i=n(1946);function a(e){var t=e.textTracks;if(!(0,i.Z)(t)){for(var n=0;n=0;o--)if("track"===a[o].nodeName)try{e.removeChild(a[o])}catch(e){r.Z.warn("Compat: Could not remove text track child from element.")}}e.src="",e.removeAttribute("src")}},6139:function(e,t,n){"use strict";n.d(t,{N:function(){return P},Y:function(){return D}});var r,i=n(3714),a=n(811),o=n(3666),s=n(2203),u=n(5059),l=n(3144),c=function(){function e(e,t,n){this._keyType=e,this._mediaKeys=t,this._configuration=n}var t=e.prototype;return t.createMediaKeys=function(){var e=this;return new Promise((function(t){return t(e._mediaKeys)}))},t.getConfiguration=function(){return this._configuration},(0,l.Z)(e,[{key:"keySystem",get:function(){return this._keyType}}]),e}();if(!s.Z){var d=window.MSMediaKeys;void 0!==d&&void 0!==d.prototype&&"function"==typeof d.isTypeSupported&&"function"==typeof d.prototype.createSession&&(r=d)}var f,v=n(4578),p=n(6716),h=n(3071),m=n(3505),g=n(1959),y=n(1381),_=function(e){function t(t){var n;return(n=e.call(this)||this).expiration=NaN,n.keyStatuses=new Map,n._mk=t,n._closeSession$=new p.x,n.closed=new Promise((function(e){n._closeSession$.subscribe(e)})),n.update=function(e){return new Promise((function(t,r){if(void 0===n._ss)return r("MediaKeySession not set.");try{t(n._ss.update(e,""))}catch(e){r(e)}}))},n}(0,v.Z)(t,e);var n=t.prototype;return n.generateRequest=function(e,t){var n=this;return new Promise((function(e){var r=t instanceof Uint8Array?t:t instanceof ArrayBuffer?new Uint8Array(t):new Uint8Array(t.buffer);n._ss=n._mk.createSession("video/mp4",r),(0,h.T)(y.GJ(n._ss),y.GV(n._ss),y.Xe(n._ss)).pipe((0,m.R)(n._closeSession$)).subscribe((function(e){return n.trigger(e.type,e)})),e()}))},n.close=function(){var e=this;return new Promise((function(t){null!=e._ss&&(e._ss.close(),e._ss=void 0),e._closeSession$.next(),e._closeSession$.complete(),t()}))},n.load=function(){return Promise.resolve(!1)},n.remove=function(){return Promise.resolve()},(0,l.Z)(t,[{key:"sessionId",get:function(){var e,t;return null!==(t=null===(e=this._ss)||void 0===e?void 0:e.sessionId)&&void 0!==t?t:""}}]),t}(g.Z),b=function(){function e(e){if(void 0===r)throw new Error("No MSMediaKeys API.");this._mediaKeys=new r(e)}var t=e.prototype;return t._setVideo=function(e){if(this._videoElement=e,void 0!==this._videoElement.msSetMediaKeys)return this._videoElement.msSetMediaKeys(this._mediaKeys)},t.createSession=function(){if(void 0===this._videoElement||void 0===this._mediaKeys)throw new Error("Video not attached to the MediaKeys");return new _(this._mediaKeys)},t.setServerCertificate=function(){throw new Error("Server certificate is not implemented in your browser")},e}();if(!s.Z){var T=window.MozMediaKeys;void 0!==T&&void 0!==T.prototype&&"function"==typeof T.isTypeSupported&&"function"==typeof T.prototype.createSession&&(f=T)}var E=n(9689),S=n(8894),w=n(3635);function k(e){return"function"==typeof e.webkitGenerateKeyRequest}var A=function(e){function t(t,n){var r;(r=e.call(this)||this)._vid=t,r._key=n,r.sessionId="",r._closeSession=S.Z,r.keyStatuses=new Map,r.expiration=NaN;var i=function(e){r.trigger(e.type,e)};return r.closed=new Promise((function(e){r._closeSession=function(){["keymessage","message","keyadded","ready","keyerror","error"].forEach((function(e){t.removeEventListener(e,i),t.removeEventListener("webkit"+e,i)})),e()}})),["keymessage","message","keyadded","ready","keyerror","error"].forEach((function(e){t.addEventListener(e,i),t.addEventListener("webkit"+e,i)})),r}(0,v.Z)(t,e);var n=t.prototype;return n.update=function(e){var t=this;return new Promise((function(n,r){try{if(t._key.indexOf("clearkey")>=0){var i=e instanceof ArrayBuffer?new Uint8Array(e):e,a=JSON.parse((0,w.uR)(i)),o=(0,E.K)(a.keys[0].k),s=(0,E.K)(a.keys[0].kid);n(t._vid.webkitAddKey(t._key,o,s,""))}else n(t._vid.webkitAddKey(t._key,e,null,""))}catch(e){r(e)}}))},n.generateRequest=function(e,t){var n=this;return new Promise((function(e){n._vid.webkitGenerateKeyRequest(n._key,t),e()}))},n.close=function(){var e=this;return new Promise((function(t){e._closeSession(),t()}))},n.load=function(){return Promise.resolve(!1)},n.remove=function(){return Promise.resolve()},t}(g.Z),x=function(){function e(e){this._keySystem=e}var t=e.prototype;return t._setVideo=function(e){if(!k(e))throw new Error("Video not attached to the MediaKeys");this._videoElement=e},t.createSession=function(){if(null==this._videoElement)throw new Error("Video not attached to the MediaKeys");return new A(this._videoElement,this._keySystem)},t.setServerCertificate=function(){throw new Error("Server certificate is not implemented in your browser")},e}();var I=n(6968);var Z=n(158);function R(e,t){var n=e;if(void 0===n.webkitSetMediaKeys)throw new Error("No webKitMediaKeys API.");return n.webkitSetMediaKeys(t)}var M=function(e){function t(t,n,r){var i;return(i=e.call(this)||this)._serverCertificate=r,i._videoElement=t,i._keyType=n,i._unbindSession=S.Z,i._closeSession=S.Z,i.closed=new Promise((function(e){i._closeSession=e})),i.keyStatuses=new Map,i.expiration=NaN,i}(0,v.Z)(t,e);var n=t.prototype;return n.update=function(e){var t=this;return new Promise((function(n,r){if(void 0===t._nativeSession||void 0===t._nativeSession.update||"function"!=typeof t._nativeSession.update)return r("Unavailable WebKit key session.");try{var i;i=e instanceof ArrayBuffer?new Uint8Array(e):e instanceof Uint8Array?e:new Uint8Array(e.buffer),n(t._nativeSession.update(i))}catch(e){r(e)}}))},n.generateRequest=function(e,t){var n=this;return new Promise((function(e){var r,i,a,o=n._videoElement;if(void 0===(null===(r=o.webkitKeys)||void 0===r?void 0:r.createSession))throw new Error("No WebKitMediaKeys API.");if("com.apple.fps.1_0"===(a=n._keyType)||"com.apple.fps.2_0"===a){if(void 0===n._serverCertificate)throw new Error("A server certificate is needed for creating fairplay session.");i=function(e,t){var n=e instanceof Uint8Array?e:new Uint8Array(e),r=t instanceof Uint8Array?t:new Uint8Array(t);if((0,I.dN)(n,0)+4!==n.length)throw new Error("Unsupported WebKit initData.");var i=(0,w.wV)(n),a=i.indexOf("skd://"),o=a>-1?i.substring(a+6):i,s=(0,w.TZ)(o),u=0,l=new Uint8Array(n.byteLength+4+s.byteLength+4+r.byteLength);return l.set(n),u+=n.length,l.set((0,I.O_)(s.byteLength),u),u+=4,l.set(s,u),u+=s.byteLength,l.set((0,I.O_)(r.byteLength),u),u+=4,l.set(r,u),l}(t,n._serverCertificate)}else i=t;var s=o.webkitKeys.createSession("video/mp4",i);if(null==s)throw new Error("Impossible to get the key sessions");n._listenEvent(s),n._nativeSession=s,e()}))},n.close=function(){var e=this;return new Promise((function(t,n){e._unbindSession(),e._closeSession(),void 0!==e._nativeSession?(e._nativeSession.close(),t()):n("No session to close.")}))},n.load=function(){return Promise.resolve(!1)},n.remove=function(){return Promise.resolve()},n._listenEvent=function(e){var t=this;this._unbindSession();var n=function(e){t.trigger(e.type,e)};["keymessage","message","keyadded","ready","keyerror","error"].forEach((function(t){e.addEventListener(t,n),e.addEventListener("webkit"+t,n)})),this._unbindSession=function(){["keymessage","message","keyadded","ready","keyerror","error"].forEach((function(t){e.removeEventListener(t,n),e.removeEventListener("webkit"+t,n)}))}},(0,l.Z)(t,[{key:"sessionId",get:function(){var e,t;return null!==(t=null===(e=this._nativeSession)||void 0===e?void 0:e.sessionId)&&void 0!==t?t:""}}]),t}(g.Z),C=function(){function e(e){if(void 0===Z.t)throw new Error("No WebKitMediaKeys API.");this._keyType=e,this._mediaKeys=new Z.t(e)}var t=e.prototype;return t._setVideo=function(e){if(this._videoElement=e,void 0===this._videoElement)throw new Error("Video not attached to the MediaKeys");return R(this._videoElement,this._mediaKeys)},t.createSession=function(){if(void 0===this._videoElement||void 0===this._mediaKeys)throw new Error("Video not attached to the MediaKeys");return new M(this._videoElement,this._keyType,this._serverCertificate)},t.setServerCertificate=function(e){return this._serverCertificate=e,Promise.resolve()},e}();var P=null,D=function(e,t){var n=e;return"function"==typeof n.setMediaKeys?n.setMediaKeys(t):"function"==typeof n.webkitSetMediaKeys?n.webkitSetMediaKeys(t):"function"==typeof n.mozSetMediaKeys?n.mozSetMediaKeys(t):"function"==typeof n.msSetMediaKeys&&null!==t?n.msSetMediaKeys(t):void 0};if(s.Z||null!=navigator.requestMediaKeySystemAccess&&!(0,u.Z)())P=function(){var e;return(e=navigator).requestMediaKeySystemAccess.apply(e,arguments)};else{var N,O;if(k(HTMLVideoElement.prototype)){var L={isTypeSupported:function(e){var t=document.querySelector("video");return null==t&&(t=document.createElement("video")),null!=t&&"function"==typeof t.canPlayType&&!!t.canPlayType("video/mp4",e)},createCustomMediaKeys:function(e){return new x(e)},setMediaKeys:function(e,t){if(null!==t){if(!(t instanceof x))throw new Error("Custom setMediaKeys is supposed to be called with old webkit custom MediaKeys.");return t._setVideo(e)}}};N=L.isTypeSupported,O=L.createCustomMediaKeys,D=L.setMediaKeys}else if(void 0!==Z.t){var B=function(){if(void 0===Z.t)throw new Error("No WebKitMediaKeys API.");return{isTypeSupported:Z.t.isTypeSupported,createCustomMediaKeys:function(e){return new C(e)},setMediaKeys:function(e,t){if(null===t)return R(e,t);if(!(t instanceof C))throw new Error("Custom setMediaKeys is supposed to be called with webkit custom MediaKeys.");return t._setVideo(e)}}}();N=B.isTypeSupported,O=B.createCustomMediaKeys,D=B.setMediaKeys}else if(o.fq&&void 0!==r){var U={isTypeSupported:function(e,t){if(void 0===r)throw new Error("No MSMediaKeys API.");return void 0!==t?r.isTypeSupported(e,t):r.isTypeSupported(e)},createCustomMediaKeys:function(e){return new b(e)},setMediaKeys:function(e,t){if(null!==t){if(!(t instanceof b))throw new Error("Custom setMediaKeys is supposed to be called with IE11 custom MediaKeys.");return t._setVideo(e)}}};N=U.isTypeSupported,O=U.createCustomMediaKeys,D=U.setMediaKeys}else if(void 0!==f){var F={isTypeSupported:function(e,t){if(void 0===f)throw new Error("No MozMediaKeys API.");return void 0!==t?f.isTypeSupported(e,t):f.isTypeSupported(e)},createCustomMediaKeys:function(e){if(void 0===f)throw new Error("No MozMediaKeys API.");return new f(e)},setMediaKeys:function(e,t){var n=e;if(void 0===n.mozSetMediaKeys||"function"!=typeof n.mozSetMediaKeys)throw new Error("Can't set video on MozMediaKeys.");return n.mozSetMediaKeys(t)}};N=F.isTypeSupported,O=F.createCustomMediaKeys,D=F.setMediaKeys}else{var z=window.MediaKeys,V=function(){if(void 0===z)throw new i.Z("MEDIA_KEYS_NOT_SUPPORTED","No `MediaKeys` implementation found in the current browser.");if(void 0===z.isTypeSupported){throw new Error("This browser seems to be unable to play encrypted contents currently. Note: Some browsers do not allow decryption in some situations, like when not using HTTPS.")}};N=function(e){return V(),(0,a.Z)("function"==typeof z.isTypeSupported),z.isTypeSupported(e)},O=function(e){return V(),new z(e)}}P=function(e,t){if(!N(e))return Promise.reject(new Error("Unsupported key type"));for(var n=0;n=t)return r.Z.warn("Compat: Invalid cue times: "+e+" - "+t),null;if((0,i.Z)(window.VTTCue)){if((0,i.Z)(window.TextTrackCue))throw new Error("VTT cues not supported in your target");return new TextTrackCue(e,t,n)}return new VTTCue(e,t,n)}},5059:function(e,t,n){"use strict";n.d(t,{Z:function(){return a}});var r=n(3666),i=n(158);function a(){return(r.vS||r.SB)&&void 0!==i.t}},1669:function(e,t,n){"use strict";n.d(t,{Z:function(){return i}});var r=n(3666);function i(){return r.op}},6872:function(e,t,n){"use strict";n.d(t,{Z:function(){return u}});var r={DEFAULT_UNMUTED_VOLUME:.1,DEFAULT_REQUEST_TIMEOUT:3e4,DEFAULT_TEXT_TRACK_MODE:"native",DEFAULT_MANUAL_BITRATE_SWITCHING_MODE:"seamless",DEFAULT_ENABLE_FAST_SWITCHING:!0,DEFAULT_AUDIO_TRACK_SWITCHING_MODE:"seamless",DELTA_POSITION_AFTER_RELOAD:{bitrateSwitch:-.1,trackSwitch:{audio:-.7,video:-.1,other:0}},DEFAULT_CODEC_SWITCHING_BEHAVIOR:"continue",DEFAULT_AUTO_PLAY:!1,DEFAULT_SHOW_NATIVE_SUBTITLE:!0,DEFAULT_STOP_AT_END:!0,DEFAULT_WANTED_BUFFER_AHEAD:30,DEFAULT_MAX_BUFFER_AHEAD:1/0,DEFAULT_MAX_BUFFER_BEHIND:1/0,DEFAULT_MAX_VIDEO_BUFFER_SIZE:1/0,MAXIMUM_MAX_BUFFER_AHEAD:{text:18e3},MAXIMUM_MAX_BUFFER_BEHIND:{text:18e3},DEFAULT_INITIAL_BITRATES:{audio:0,video:0,other:0},DEFAULT_MIN_BITRATES:{audio:0,video:0,other:0},DEFAULT_MAX_BITRATES:{audio:1/0,video:1/0,other:1/0},INACTIVITY_DELAY:6e4,DEFAULT_THROTTLE_WHEN_HIDDEN:!1,DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN:!1,DEFAULT_LIMIT_VIDEO_WIDTH:!1,DEFAULT_LIVE_GAP:{DEFAULT:10,LOW_LATENCY:3.5},BUFFER_DISCONTINUITY_THRESHOLD:.2,FORCE_DISCONTINUITY_SEEK_DELAY:5e3,BITRATE_REBUFFERING_RATIO:1.5,BUFFER_GC_GAPS:{CALM:240,BEEFY:30},DEFAULT_MAX_MANIFEST_REQUEST_RETRY:4,DEFAULT_CDN_DOWNGRADE_TIME:60,DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR:4,DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE:1/0,INITIAL_BACKOFF_DELAY_BASE:{REGULAR:200,LOW_LATENCY:50},MAX_BACKOFF_DELAY_BASE:{REGULAR:3e3,LOW_LATENCY:1e3},SAMPLING_INTERVAL_MEDIASOURCE:1e3,SAMPLING_INTERVAL_LOW_LATENCY:250,SAMPLING_INTERVAL_NO_MEDIASOURCE:500,ABR_MINIMUM_TOTAL_BYTES:15e4,ABR_MINIMUM_CHUNK_SIZE:16e3,ABR_STARVATION_FACTOR:{DEFAULT:.72,LOW_LATENCY:.72},ABR_REGULAR_FACTOR:{DEFAULT:.8,LOW_LATENCY:.8},ABR_STARVATION_GAP:{DEFAULT:5,LOW_LATENCY:5},OUT_OF_STARVATION_GAP:{DEFAULT:7,LOW_LATENCY:7},ABR_STARVATION_DURATION_DELTA:.1,ABR_FAST_EMA:2,ABR_SLOW_EMA:10,RESUME_GAP_AFTER_SEEKING:{DEFAULT:1.5,LOW_LATENCY:.5},RESUME_GAP_AFTER_NOT_ENOUGH_DATA:{DEFAULT:.5,LOW_LATENCY:.5},RESUME_GAP_AFTER_BUFFERING:{DEFAULT:5,LOW_LATENCY:.5},REBUFFERING_GAP:{DEFAULT:.5,LOW_LATENCY:.2},MINIMUM_BUFFER_AMOUNT_BEFORE_FREEZING:2,UNFREEZING_SEEK_DELAY:6e3,FREEZING_STALLED_DELAY:600,UNFREEZING_DELTA_POSITION:.001,MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT:.15,MAX_MANIFEST_BUFFERED_START_END_DIFFERENCE:.4,MAX_MANIFEST_BUFFERED_DURATION_DIFFERENCE:.3,MINIMUM_SEGMENT_SIZE:.005,APPEND_WINDOW_SECURITIES:{START:.2,END:.1},MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL:50,TEXT_TRACK_SIZE_CHECKS_INTERVAL:250,BUFFER_PADDING:{audio:1,video:3,other:1},SEGMENT_PRIORITIES_STEPS:[2,4,8,12,18,25],MAX_HIGH_PRIORITY_LEVEL:1,MIN_CANCELABLE_PRIORITY:3,EME_DEFAULT_WIDEVINE_ROBUSTNESSES:["HW_SECURE_ALL","HW_SECURE_DECODE","HW_SECURE_CRYPTO","SW_SECURE_DECODE","SW_SECURE_CRYPTO"],EME_KEY_SYSTEMS:{clearkey:["webkit-org.w3.clearkey","org.w3.clearkey"],widevine:["com.widevine.alpha"],playready:["com.microsoft.playready","com.chromecast.playready","com.youtube.playready"],fairplay:["com.apple.fps.1_0"]},MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE:10,MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE:200,MIN_DASH_S_ELEMENTS_TO_PARSE_UNSAFELY:300,OUT_OF_SYNC_MANIFEST_REFRESH_DELAY:3e3,FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY:3e3,DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0:3,EME_DEFAULT_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS:15,EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION:1e3,EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES:100,FORCED_ENDED_THRESHOLD:8e-4,ADAPTATION_SWITCH_BUFFER_PADDINGS:{video:{before:5,after:5},audio:{before:2,after:2.5},text:{before:0,after:0},image:{before:0,after:0}},SOURCE_BUFFER_FLUSHING_INTERVAL:500,CONTENT_REPLACEMENT_PADDING:1.2,CACHE_LOAD_DURATION_THRESHOLDS:{video:50,audio:10},STREAM_EVENT_EMITTER_POLL_INTERVAL:250,DEFAULT_MAXIMUM_TIME_ROUNDING_ERROR:.001,BUFFERED_HISTORY_RETENTION_TIME:6e4,BUFFERED_HISTORY_MAXIMUM_ENTRIES:200,MIN_BUFFER_AHEAD:5,UPTO_CURRENT_POSITION_CLEANUP:5},i=n(8026);function a(e){return null!=e&&!Array.isArray(e)&&"object"==typeof e}function o(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r=e.length||(e[t].enabled=!0)}(this._audioTracks.map((function(e){return e.nativeTrack})),e)},t}(a.Z);function f(e){for(var t=0;te.length)return u.Z.warn("Compat: Unrecognized initialization data. Use as is."),[{systemId:void 0,data:e}];var i=e.subarray(n,n+r),a={systemId:(0,l.Y)(i,8),data:i};p(t,a)?u.Z.warn("Compat: Duplicated PSSH found in initialization data, removing it."):t.push(a),n+=r}return n!==e.length?(u.Z.warn("Compat: Unrecognized initialization data. Use as is."),[{systemId:void 0,data:e}]):t}(new Uint8Array(t));return{type:n,values:r}}var m=n(6872),g=n(5157),y=n(5389),_=n(3274),b=n(7714),T=n(1959),E=n(1946),S=n(288),w=n(6139),k=n(770);function A(e){k.Z.setState(e,null),(0,w.Y)(e,null)}function x(){return(x=(0,r.Z)(o().mark((function e(t,n,r){var i,a,s,l,c,d;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return i=n.keySystemOptions,a=n.loadedSessionsStore,s=n.mediaKeySystemAccess,l=n.mediaKeys,c=k.Z.getState(t),d=null!==c&&c.loadedSessionsStore!==a?c.loadedSessionsStore.closeAllSessions():Promise.resolve(),e.next=5,d;case 5:if(!r.isCancelled){e.next=7;break}throw r.cancellationError;case 7:if(k.Z.setState(t,{keySystemOptions:i,mediaKeySystemAccess:s,mediaKeys:l,loadedSessionsStore:a}),t.mediaKeys!==l){e.next=10;break}return e.abrupt("return");case 10:u.Z.info("DRM: Attaching MediaKeys to the media element"),(0,w.Y)(t,l),u.Z.info("DRM: MediaKeys attached with success");case 13:case"end":return e.stop()}}),e)})))).apply(this,arguments)}function I(e){if(""===e.sessionId)return!1;var t=e.keyStatuses,n=[];return t.forEach((function(e){n.push(e)})),n.length<=0?(u.Z.debug("DRM: isSessionUsable: MediaKeySession given has an empty keyStatuses",e.sessionId),!1):(0,b.Z)(n,"expired")?(u.Z.debug("DRM: isSessionUsable: MediaKeySession given has an expired key",e.sessionId),!1):(0,b.Z)(n,"internal-error")?(u.Z.debug("DRM: isSessionUsable: MediaKeySession given has a key with an internal-error",e.sessionId),!1):(u.Z.debug("DRM: isSessionUsable: MediaKeySession is usable",e.sessionId),!0)}function Z(e,t,n,r){var i=e.loadedSessionsStore,a=e.persistentSessionsStore;return"temporary"===n?R(i,t):null===a?(u.Z.warn("DRM: Cannot create persistent MediaKeySession, PersistentSessionsStore not created."),R(i,t)):function(e,t,n,r){return M.apply(this,arguments)}(i,a,t,r)}function R(e,t){u.Z.info("DRM: Creating a new temporary session");var n=e.createSession(t,"temporary");return Promise.resolve({type:"created-session",value:n})}function M(){return M=(0,r.Z)(o().mark((function e(t,n,i,a){var s,l,c,d,f,v;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(v=function(){return v=(0,r.Z)(o().mark((function e(){var r,l;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(null===a.cancellationError){e.next=2;break}throw a.cancellationError;case 2:return u.Z.info("DRM: Removing previous persistent session."),null!==(r=n.get(i))&&n.delete(r.sessionId),e.prev=5,e.next=8,t.closeSession(s.mediaKeySession);case 8:e.next=15;break;case 10:if(e.prev=10,e.t0=e.catch(5),""===s.mediaKeySession.sessionId){e.next=14;break}throw e.t0;case 14:t.removeSessionWithoutClosingIt(s.mediaKeySession);case 15:if(null===a.cancellationError){e.next=17;break}throw a.cancellationError;case 17:return l=t.createSession(i,"persistent-license"),e.abrupt("return",{type:"created-session",value:l});case 19:case"end":return e.stop()}}),e,null,[[5,10]])}))),v.apply(this,arguments)},f=function(){return v.apply(this,arguments)},null===a.cancellationError){e.next=4;break}throw a.cancellationError;case 4:if(u.Z.info("DRM: Creating persistent MediaKeySession"),s=t.createSession(i,"persistent-license"),null!==(l=n.getAndReuse(i))){e.next=9;break}return e.abrupt("return",{type:"created-session",value:s});case 9:return e.prev=9,e.next=12,t.loadPersistentSession(s.mediaKeySession,l.sessionId);case 12:if(c=e.sent){e.next=19;break}return u.Z.warn("DRM: No data stored for the loaded session"),n.delete(l.sessionId),t.removeSessionWithoutClosingIt(s.mediaKeySession),d=t.createSession(i,"persistent-license"),e.abrupt("return",{type:"created-session",value:d});case 19:if(!c||!I(s.mediaKeySession)){e.next=23;break}return n.add(i,i.keyIds,s.mediaKeySession),u.Z.info("DRM: Succeeded to load persistent session."),e.abrupt("return",{type:"loaded-persistent-session",value:s});case 23:return u.Z.warn("DRM: Previous persistent session not usable anymore."),e.abrupt("return",f());case 27:return e.prev=27,e.t0=e.catch(9),u.Z.warn("DRM: Unable to load persistent session: "+(e.t0 instanceof Error?e.t0.toString():"Unknown Error")),e.abrupt("return",f());case 31:case"end":return e.stop()}}),e,null,[[9,27]])}))),M.apply(this,arguments)}function C(e,t){return P.apply(this,arguments)}function P(){return(P=(0,r.Z)(o().mark((function e(t,n){var r,i,a,s,u;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!(n<0||n>=t.getLength())){e.next=2;break}return e.abrupt("return");case 2:for(r=[],i=t.getAll().slice(),a=i.length-n,s=0;s=s.length)){e.next=2;break}throw new g.Z("INCOMPATIBLE_KEYSYSTEMS","No key system compatible with your wanted configuration has been found in the current browser.");case 2:if(null!=w.N){e.next=4;break}throw new Error("requestMediaKeySystemAccess is not implemented in your browser.");case 4:return r=s[t],i=r.keyName,a=r.keyType,c=r.keySystemOptions,d=F(i,c),u.Z.debug("DRM: Request keysystem access "+a+","+(t+1)+" of "+s.length),e.prev=7,e.next=10,(0,w.N)(a,d);case 10:return f=e.sent,u.Z.info("DRM: Found compatible keysystem",a,t+1),e.abrupt("return",{type:"create-media-key-system-access",value:{options:c,mediaKeySystemAccess:f}});case 15:if(e.prev=15,e.t0=e.catch(7),u.Z.debug("DRM: Rejected access to keysystem",a,t+1),null===n.cancellationError){e.next=20;break}throw n.cancellationError;case 20:return e.abrupt("return",l(t+1));case 21:case"end":return e.stop()}}),e,null,[[7,15]])})))).apply(this,arguments)}}var V=n(2297);function K(e,t,n){var r;u.Z.debug("Compat: Calling generateRequest on the MediaKeySession");try{r=function(e){u.Z.info("Compat: Trying to move CENC PSSH from init data at the end of it.");for(var t=!1,n=new Uint8Array,r=new Uint8Array,i=0;ie.length)throw u.Z.warn("Compat: unrecognized initialization data. Cannot patch it."),new Error("Compat: unrecognized initialization data. Cannot patch it.");var o=e.subarray(i,i+a);if(16===e[i+12]&&119===e[i+13]&&239===e[i+14]&&236===e[i+15]&&192===e[i+16]&&178===e[i+17]&&77===e[i+18]&&2===e[i+19]&&172===e[i+20]&&227===e[i+21]&&60===e[i+22]&&30===e[i+23]&&82===e[i+24]&&226===e[i+25]&&251===e[i+26]&&75===e[i+27]){var s=(0,V.Xj)(o),l=null===s?void 0:o[s[1]];u.Z.info("Compat: CENC PSSH found with version",l),void 0===l?u.Z.warn("Compat: could not read version of CENC PSSH"):t===(1===l)?n=(0,d.zo)(n,o):1===l?(u.Z.warn("Compat: cenc version 1 encountered, removing every other cenc pssh box."),n=o,t=!0):u.Z.warn("Compat: filtering out cenc pssh box with wrong version",l)}else r=(0,d.zo)(r,o);i+=a}if(i!==e.length)throw u.Z.warn("Compat: unrecognized initialization data. Cannot patch it."),new Error("Compat: unrecognized initialization data. Cannot patch it.");return(0,d.zo)(r,n)}(n)}catch(e){r=n}var i=null!=t?t:"";return e.generateRequest(i,r).catch((function(t){if(""!==i||!(t instanceof TypeError))throw t;return u.Z.warn('Compat: error while calling `generateRequest` with an empty initialization data type. Retrying with a default "cenc" value.',t),e.generateRequest("cenc",r)}))}function G(e,t){return H.apply(this,arguments)}function H(){return H=(0,r.Z)(o().mark((function e(t,n){var r;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return u.Z.info("Compat/DRM: Load persisted session",n),e.next=3,t.load(n);case 3:if((r=e.sent)&&!(t.keyStatuses.size>0)){e.next=6;break}return e.abrupt("return",r);case 6:return e.abrupt("return",new Promise((function(e){t.addEventListener("keystatuseschange",i);var n=setTimeout(i,100);function i(){clearTimeout(n),t.removeEventListener("keystatuseschange",i),e(r)}})));case 7:case"end":return e.stop()}}),e)}))),H.apply(this,arguments)}var W=n(7864);function j(e){var t=new S.ZP;return Promise.race([e.close().then((function(){t.cancel()})),e.closed.then((function(){t.cancel()})),function(){return n.apply(this,arguments)}()]);function n(){return(n=(0,r.Z)(o().mark((function e(){var n;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,(0,W.Z)(1e3,t.signal);case 3:return e.next=5,i();case 5:e.next=13;break;case 7:if(e.prev=7,e.t0=e.catch(0),!(e.t0 instanceof S.FU)){e.next=11;break}return e.abrupt("return");case 11:n=e.t0 instanceof Error?e.t0.message:"Unknown error made it impossible to close the session",u.Z.error("DRM: "+n);case 13:case"end":return e.stop()}}),e,null,[[0,7]])})))).apply(this,arguments)}function i(){return a.apply(this,arguments)}function a(){return(a=(0,r.Z)(o().mark((function n(){return o().wrap((function(n){for(;;)switch(n.prev=n.next){case 0:return n.prev=0,n.next=3,e.update(new Uint8Array(1));case 3:n.next=13;break;case 5:if(n.prev=5,n.t0=n.catch(0),!t.isUsed){n.next=9;break}return n.abrupt("return");case 9:if(!(n.t0 instanceof Error&&"The session is already closed."===n.t0.message)){n.next=11;break}return n.abrupt("return");case 11:return n.next=13,(0,W.Z)(1e3,t.signal);case 13:if(!t.isUsed){n.next=15;break}return n.abrupt("return");case 15:throw new Error("Compat: Couldn't know if session is closed");case 16:case"end":return n.stop()}}),n,null,[[0,5]])})))).apply(this,arguments)}}var q=n(811);function Y(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return X(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return X(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function X(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function te(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0){if(null!==this._keyIds&&J(t,this._keyIds))return!0;if(void 0!==this._initializationData.keyIds)return J(t,this._initializationData.keyIds)}return this._checkInitializationDataCompatibility(e)},t._checkInitializationDataCompatibility=function(e){return void 0!==e.keyIds&&e.keyIds.length>0&&void 0!==this._initializationData.keyIds?J(e.keyIds,this._initializationData.keyIds):this._initializationData.type===e.type&&this._initializationData.values.isCompatibleWith(e.values)},e}();function re(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return ie(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ie(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function ie(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0&&n._storage[e].mediaKeySession===i&&n._storage.splice(e,1)})).catch((function(e){u.Z.warn("DRM-LSS: MediaKeySession.closed rejected: "+e)})),u.Z.debug("DRM-LSS: Add MediaKeySession",a.sessionType),this._storage.push(Object.assign({},a)),a},t.reuse=function(e){for(var t=this._storage.length-1;t>=0;t--){var n=this._storage[t];if(n.keySessionRecord.isCompatibleWith(e))return this._storage.splice(t,1),this._storage.push(n),Object.assign({},n)}return null},t.getEntryForSession=function(e){for(var t=this._storage.length-1;t>=0;t--){var n=this._storage[t];if(n.mediaKeySession===e)return Object.assign({},n)}return null},t.generateLicenseRequest=function(){var e=(0,r.Z)(o().mark((function e(t,n,r){var i,a,s,l;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:a=re(this._storage);case 1:if((s=a()).done){e.next=8;break}if((l=s.value).mediaKeySession!==t){e.next=6;break}return i=l,e.abrupt("break",8);case 6:e.next=1;break;case 8:if(void 0!==i){e.next=11;break}return u.Z.error("DRM-LSS: generateRequest error. No MediaKeySession found with the given initData and initDataType"),e.abrupt("return",K(t,n,r));case 11:if(i.isGeneratingRequest=!0,"none"===i.closingStatus.type){e.next=14;break}throw new Error("The `MediaKeySession` is being closed.");case 14:return e.prev=14,e.next=17,K(t,n,r);case 17:e.next=26;break;case 19:if(e.prev=19,e.t0=e.catch(14),void 0!==i){e.next=23;break}throw e.t0;case 23:throw i.isGeneratingRequest=!1,"awaiting"===i.closingStatus.type&&i.closingStatus.start(),e.t0;case 26:if(void 0!==i){e.next=28;break}return e.abrupt("return",void 0);case 28:i.isGeneratingRequest=!1,"awaiting"===i.closingStatus.type&&i.closingStatus.start();case 30:case"end":return e.stop()}}),e,this,[[14,19]])})));return function(t,n,r){return e.apply(this,arguments)}}(),t.loadPersistentSession=function(){var e=(0,r.Z)(o().mark((function e(t,n){var r,i,a,s,l;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:i=re(this._storage);case 1:if((a=i()).done){e.next=8;break}if((s=a.value).mediaKeySession!==t){e.next=6;break}return r=s,e.abrupt("break",8);case 6:e.next=1;break;case 8:if(void 0!==r){e.next=11;break}return u.Z.error("DRM-LSS: loadPersistentSession error. No MediaKeySession found with the given initData and initDataType"),e.abrupt("return",G(t,n));case 11:if(r.isLoadingPersistentSession=!0,"none"===r.closingStatus.type){e.next=14;break}throw new Error("The `MediaKeySession` is being closed.");case 14:return e.prev=14,e.next=17,G(t,n);case 17:l=e.sent,e.next=27;break;case 20:if(e.prev=20,e.t0=e.catch(14),void 0!==r){e.next=24;break}throw e.t0;case 24:throw r.isLoadingPersistentSession=!1,"awaiting"===r.closingStatus.type&&r.closingStatus.start(),e.t0;case 27:if(void 0!==r){e.next=29;break}return e.abrupt("return",l);case 29:return r.isLoadingPersistentSession=!1,"awaiting"===r.closingStatus.type&&r.closingStatus.start(),e.abrupt("return",l);case 32:case"end":return e.stop()}}),e,this,[[14,20]])})));return function(t,n){return e.apply(this,arguments)}}(),t.closeSession=function(){var e=(0,r.Z)(o().mark((function e(t){var n,r,i,a;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:r=re(this._storage);case 1:if((i=r()).done){e.next=8;break}if((a=i.value).mediaKeySession!==t){e.next=6;break}return n=a,e.abrupt("break",8);case 6:e.next=1;break;case 8:if(void 0!==n){e.next=11;break}return u.Z.warn("DRM-LSS: No MediaKeySession found with the given initData and initDataType"),e.abrupt("return",Promise.resolve(!1));case 11:return e.abrupt("return",this._closeEntry(n));case 12:case"end":return e.stop()}}),e,this)})));return function(t){return e.apply(this,arguments)}}(),t.getLength=function(){return this._storage.length},t.getAll=function(){return this._storage},t.closeAllSessions=function(){var e=(0,r.Z)(o().mark((function e(){var t,n,r=this;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return t=this._storage,u.Z.debug("DRM-LSS: Closing all current MediaKeySessions",t.length),this._storage=[],n=t.map((function(e){return r._closeEntry(e)})),e.next=6,Promise.all(n);case 6:case"end":return e.stop()}}),e,this)})));return function(){return e.apply(this,arguments)}}(),t.removeSessionWithoutClosingIt=function(e){(0,q.Z)(""===e.sessionId,"Initialized `MediaKeySession`s should always be properly closed");for(var t=this._storage.length-1;t>=0;t--){if(this._storage[t].mediaKeySession===e)return this._storage.splice(t,1),!0}return!1},t.getIndex=function(e){for(var t=0;t=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function he(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0){var o=void 0===t?3:4,s=this._entries[a];if((null!==(r=s.version)&&void 0!==r?r:-1)>=o&&i===s.sessionId)return;u.Z.info("DRM-PSS: Updating session info.",i),this._entries.splice(a,1)}else u.Z.info("DRM-PSS: Add new session",i);var l=e.values.getFormattedValues().map((function(e){var t=e.systemId,n=e.data;return{systemId:t,hash:e.hash,data:new de(n)}}));void 0===t?this._entries.push({version:3,sessionId:i,values:l,initDataType:e.type}):this._entries.push({version:4,sessionId:i,keyIds:t.map((function(e){return new de(e)})),values:l,initDataType:e.type}),this._save()}else u.Z.warn("DRM-PSS: Invalid Persisten Session given.")},t.delete=function(e){for(var t=-1,n=0;n0&&(r=new g.Z("KEY_STATUS_CHANGE_ERROR","One or several problematic key statuses have been encountered",{keyStatuses:c})),{warning:r,blacklistedKeyIds:u,whitelistedKeyIds:l}}var lt=s.Xe,ct=s.GJ,dt=s.eX,ft=function(e){function t(n){var r;return r=e.call(this)||this,Object.setPrototypeOf((0,Ie.Z)(r),t.prototype),r.sessionError=n,r}return(0,i.Z)(t,e),t}((0,Ze.Z)(Error));function vt(e,t,n){u.Z.info("DRM: Binding session events",e.sessionId);var r,i,a=new Re.x,o=t.getLicenseConfig,s=void 0===o?{}:o,l=lt(e).pipe((0,Me.U)((function(e){throw new g.Z("KEY_ERROR",e.type)}))),c=dt(e).pipe((0,Ce.z)((function(r){return function(e,t,n,r){u.Z.info("DRM: keystatuseschange event received",e.sessionId);var i=(0,Pe.P)((function(){return(0,nt.Z)((function(){return"function"!=typeof t.onKeyStatusesChange?je.E:(0,Je.Z)(t.onKeyStatusesChange(r,e))}),void 0)})).pipe((0,Me.U)((function(t){return{type:"key-status-change-handled",value:{session:e,license:t}}})),(0,Ge.K)((function(e){var t=new g.Z("KEY_STATUS_CHANGE_ERROR","Unknown `onKeyStatusesChange` error");throw!(0,E.Z)(e)&&(0,ce.Z)(e.message)&&(t.message=e.message),t})));return(0,He.T)(pt(e,t,n),i)}(e,t,n,r)}))),d=ct(e).pipe((0,Ce.z)((function(n){var r=new Uint8Array(n.message),i=(0,ce.Z)(n.messageType)?n.messageType:"license-request";u.Z.info("DRM: Received message event, type "+i,e.sessionId);var o,l,c,d,f,v,p,h,m=(0,Pe.P)((function(){var e=t.getLicense(r,i),n=(0,E.Z)(s.timeout)?1e4:s.timeout;return(0,Je.Z)(e).pipe(n>=0?function(e,t){var n=(0,Ne.q)(e)?{first:e}:"number"==typeof e?{each:e}:e,r=n.first,i=n.each,a=n.with,o=void 0===a?Ve:a,s=n.scheduler,u=void 0===s?null!=t?t:De.z:s,l=n.meta,c=void 0===l?null:l;if(null==r&&null==i)throw new TypeError("No timeout provided.");return(0,Oe.e)((function(e,t){var n,a,s=null,l=0,d=function(e){a=(0,Fe.f)(t,u,(function(){try{n.unsubscribe(),(0,Le.Xf)(o({meta:c,lastValue:s,seen:l})).subscribe(t)}catch(e){t.error(e)}}),e)};n=e.subscribe((0,Ue.x)(t,(function(e){null==a||a.unsubscribe(),l++,t.next(s=e),i>0&&d(i)}),void 0,void 0,(function(){(null==a?void 0:a.closed)||null==a||a.unsubscribe(),s=null}))),!l&&d(null!=r?"number"==typeof r?r:+r-u.now():i)}))}(n):Ke.y)})),g=function(e,t){return{totalRetry:null!=t?t:2,baseDelay:200,maxDelay:3e3,shouldRetry:function(e){return e instanceof ze||(0,E.Z)(e)||!0!==e.noRetry},onRetry:function(t){return e.next({type:"warning",value:ht(t)})}}}(a,s.retry);return(o=m,l=g,c=l.baseDelay,d=l.maxDelay,f=l.totalRetry,v=l.shouldRetry,p=l.onRetry,h=0,o.pipe((0,Ge.K)((function(e,t){if(!(0,E.Z)(v)&&!v(e)||h++>=f)throw e;"function"==typeof p&&p(e,h);var n=Math.min(c*Math.pow(2,h-1),d),r=(0,tt.Z)(n);return(0,et.H)(r).pipe((0,Ce.z)((function(){return t})))})))).pipe((0,Me.U)((function(t){return{type:"key-message-handled",value:{session:e,license:t}}})),(0,Ge.K)((function(e){var t=ht(e);if(!(0,E.Z)(e)&&!0===e.fallbackOnLastTry)throw u.Z.warn("DRM: Last `getLicense` attempt failed. Blacklisting the current session."),new ft(t);throw t})))}))),f=(0,He.T)(d,c).pipe((r=function(t){switch(t.type){case"key-message-handled":case"key-status-change-handled":return(0,E.Z)(t.value.license)?(u.Z.info("DRM: No message given, skipping session.update"),je.E):function(e,t){return u.Z.info("DRM: Updating MediaKeySession with message"),(0,Je.Z)(e.update(t)).pipe((0,Ge.K)((function(e){var t=e instanceof Error?e.toString():"`session.update` failed";throw new g.Z("KEY_UPDATE_ERROR",t)})),(0,$e.b)((function(){u.Z.info("DRM: MediaKeySession update succeeded.")})),(0,Qe.l)())}(e,t.value.license);default:return(0,qe.of)(t)}},(0,We.m)(i)?(0,Ce.z)(r,i,1):(0,Ce.z)(r,1))),v=(0,He.T)(pt(e,t,n),f,l,a);return(0,E.Z)(e.closed)?v:v.pipe((0,Ye.R)((0,Je.Z)(e.closed)))}function pt(e,t,n){return(0,Pe.P)((function(){if(0===e.keyStatuses.size)return je.E;var r=ut(e,t,n),i=r.warning,a=r.blacklistedKeyIds,o=r.whitelistedKeyIds,s=(0,qe.of)({type:"keys-update",value:{whitelistedKeyIds:o,blacklistedKeyIds:a}});return void 0!==i?(0,Xe.z)((0,qe.of)({type:"warning",value:i}),s):s}))}function ht(e){if(e instanceof ze)return new g.Z("KEY_LOAD_TIMEOUT","The license server took too much time to respond.");var t=new g.Z("KEY_LOAD_ERROR","An error occured when calling `getLicense`.");return!(0,E.Z)(e)&&(0,ce.Z)(e.message)&&(t.message=e.message),t}var mt=n(9822);function gt(e,t){return yt.apply(this,arguments)}function yt(){return(yt=(0,r.Z)(o().mark((function e(t,n){var r,i;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,t.setServerCertificate(n);case 3:return r=e.sent,e.abrupt("return",r);case 7:throw e.prev=7,e.t0=e.catch(0),u.Z.warn("DRM: mediaKeys.setServerCertificate returned an error",e.t0 instanceof Error?e.t0:""),i=e.t0 instanceof Error?e.t0.toString():"`setServerCertificate` error",new g.Z("LICENSE_SERVER_CERTIFICATE_ERROR",i);case 12:case"end":return e.stop()}}),e,null,[[0,7]])})))).apply(this,arguments)}function _t(e,t){return bt.apply(this,arguments)}function bt(){return(bt=(0,r.Z)(o().mark((function e(t,n){var r,i;return o().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!0!==be(t)){e.next=3;break}return u.Z.info("DRM: The MediaKeys already has a server certificate, skipping..."),e.abrupt("return",{type:"already-has-one"});case 3:if("function"==typeof t.setServerCertificate){e.next=6;break}return u.Z.warn("DRM: Could not set the server certificate. mediaKeys.setServerCertificate is not a function"),e.abrupt("return",{type:"method-not-implemented"});case 6:return u.Z.info("DRM: Setting server certificate on the MediaKeys"),ye(t),e.prev=8,e.next=11,gt(t,n);case 11:return r=e.sent,_e(t,n),e.abrupt("return",{type:"success",value:r});case 16:return e.prev=16,e.t0=e.catch(8),i=(0,mt.Z)(e.t0)?e.t0:new g.Z("LICENSE_SERVER_CERTIFICATE_ERROR","Unknown error when setting the server certificate."),e.abrupt("return",{type:"error",value:i});case 20:case"end":return e.stop()}}),e,null,[[8,16]])})))).apply(this,arguments)}function Tt(e,t){if(!(isNaN(t)||t<0||t>=e.getLength())){var n=e.getLength(),r=n-t;u.Z.info("DRM: Too many stored persistent sessions, removing some.",n,r),e.deleteOldSessions(r)}}var Et=n(9252);var St=function(){function e(e){this._innerValues=e,this._lazyFormattedValues=null}var t=e.prototype;return t.constructRequestData=function(){return d.zo.apply(void 0,this._innerValues.map((function(e){return e.data})))},t.isCompatibleWith=function(t){var n=t instanceof e?t.getFormattedValues():t;return fe(this.getFormattedValues(),n)},t.getFormattedValues=function(){return null===this._lazyFormattedValues&&(this._lazyFormattedValues=this._innerValues.slice().sort((function(e,t){return e.systemId===t.systemId?0:void 0===e.systemId?1:void 0===t.systemId||e.systemId=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function kt(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0&&G._currentSessions.splice(r),void 0!==t.content&&Rt(t.content.manifest,[],[],N.record.getAssociatedKeyIds()),null===(n=i.persistentSessionsStore)||void 0===n||n.delete(L.sessionId),i.loadedSessionsStore.closeSession(L).catch((function(e){var t=e instanceof Error?e:"unknown error";u.Z.warn("DRM: failed to close expired session",t)})).then((function(){return G._unlockInitDataQueue()})).catch((function(e){return G._onFatalError(e)})),void(G._isStopped()||G.trigger("warning",e.reason))}if(e instanceof ft){if(N.blacklistedSessionError=e,void 0!==t.content){var a=t.content.manifest;u.Z.info("DRM: blacklisting Representations based on protection data."),Mt(a,t)}G._unlockInitDataQueue()}else G._onFatalError(e)}}),this._canceller.signal.register((function(){F.unsubscribe()})),void 0!==a.singleLicensePer&&"init-data"!==a.singleLicensePer||this._unlockInitDataQueue(),"created-session"!==P.type){e.next=68;break}return z=t.values.constructRequestData(),e.prev=55,e.next=58,i.loadedSessionsStore.generateLicenseRequest(L,t.type,z);case 58:e.next=68;break;case 60:if(e.prev=60,e.t0=e.catch(55),null!==(V=i.loadedSessionsStore.getEntryForSession(L))&&"none"===V.closingStatus.type){e.next=67;break}return(K=this._currentSessions.indexOf(N))>=0&&this._currentSessions.splice(K,1),e.abrupt("return",Promise.resolve());case 67:throw new g.Z("KEY_GENERATE_REQUEST_ERROR",e.t0 instanceof Error?e.t0.toString():"Unknown error");case 68:return e.abrupt("return",Promise.resolve());case 69:case"end":return e.stop()}}),e,this,[[55,60]])})));return function(t,n){return e.apply(this,arguments)}}(),n._tryToUseAlreadyCreatedSession=function(e,t){var n=t.stores,r=t.options,i=(0,_.Z)(this._currentSessions,(function(t){return t.record.isCompatibleWith(e)}));if(void 0===i)return!1;var a=i.blacklistedSessionError;if(!(0,E.Z)(a))return void 0===e.type||void 0===e.content?(u.Z.error("DRM: This initialization data has already been blacklisted but the current content is not known."),!0):(u.Z.info("DRM: This initialization data has already been blacklisted. Blacklisting the related content."),Mt(e.content.manifest,e),!0);if(void 0!==e.keyIds){var o;if(void 0===r.singleLicensePer||"init-data"===r.singleLicensePer){var s=i.keyStatuses.blacklisted;o=function(e,t){for(var n,r=function(){var e=n.value;if(t.some((function(t){return $(t,e)})))return{v:!0}},i=Y(e);!(n=i()).done;){var a=r();if("object"==typeof a)return a.v}return!1}(e.keyIds,s)}else{var l=i.keyStatuses.whitelisted;o=!J(e.keyIds,l)}if(o)return void 0===e.content?(u.Z.error("DRM: Cannot forbid key id, the content is unknown."),!0):(u.Z.info("DRM: Current initialization data is linked to blacklisted keys. Marking Representations as not decipherable"),Rt(e.content.manifest,[],e.keyIds,[]),!0)}if(null!==n.loadedSessionsStore.reuse(e))return u.Z.debug("DRM: Init data already processed. Skipping it."),!0;var c=this._currentSessions.indexOf(i);return-1===c?u.Z.error("DRM: Unable to remove processed init data: not found."):(u.Z.debug("DRM: A session from a processed init data is not available anymore. Re-processing it."),this._currentSessions.splice(c,1)),!1},n._onFatalError=function(e){if(!this._canceller.isUsed){var t=e instanceof Error?e:new y.Z("NONE","Unknown decryption error");this.error=t,this._initDataQueue.length=0,this._stateData={state:At.Error,isMediaKeysAttached:void 0,isInitDataQueueLocked:void 0,data:null},this._canceller.cancel(),this.trigger("error",t),this._stateData.state===At.Error&&this.trigger("stateChange",this._stateData.state)}},n._isStopped=function(){return this._stateData.state===At.Disposed||this._stateData.state===At.Error},n._processCurrentInitDataQueue=function(){for(;!1===this._stateData.isInitDataQueueLocked;){var e=this._initDataQueue.shift();if(void 0===e)return;this.onInitializationData(e)}},n._lockInitDataQueue=function(){!1===this._stateData.isInitDataQueueLocked&&(this._stateData.isInitDataQueueLocked=!0)},n._unlockInitDataQueue=function(){!0===this._stateData.isMediaKeysAttached?(this._stateData.isInitDataQueueLocked=!1,this._processCurrentInitDataQueue()):u.Z.error("DRM: Trying to unlock in the wrong state")},t}(T.Z);function Zt(e){var t=e.getConfiguration().sessionTypes;return void 0!==t&&(0,b.Z)(t,"persistent-license")}function Rt(e,t,n,r){e.updateRepresentationsDeciperability((function(e){if(void 0===e.contentProtections)return e.decipherable;var i=e.contentProtections.keyIds;if(void 0!==i)for(var a,o=wt(i);!(a=o()).done;){for(var s,u=a.value,l=wt(n);!(s=l()).done;){if($(s.value,u.keyId))return!1}for(var c,d=wt(t);!(c=d()).done;){if($(c.value,u.keyId))return!0}for(var f,v=wt(r);!(f=v()).done;){if($(f.value,u.keyId))return}}return e.decipherable}))}function Mt(e,t){e.updateRepresentationsDeciperability((function(e){var n,r;if(!1===e.decipherable)return!1;for(var i,a=function(){var e=i.value;if((void 0===t.type||e.type===t.type)&&t.values.getFormattedValues().every((function(t){return e.values.some((function(e){return(void 0===t.systemId||e.systemId===t.systemId)&&(0,c.Z)(e.data,t.data)}))})))return{v:!1}},o=wt(null!==(r=null===(n=e.contentProtections)||void 0===n?void 0:n.initData)&&void 0!==r?r:[]);!(i=o()).done;){var s=a();if("object"==typeof s)return s.v}return e.decipherable}))}function Ct(e,t,n,r,i,a){for(var o,s,l=[].concat(i,a),c=function(){var e=s.value;l.some((function(t){return $(t,e)}))||(u.Z.hasLevel("DEBUG")&&u.Z.debug("DRM: KeySessionRecord's key missing in the license, blacklisting it",(0,f.ci)(e)),l.push(e))},d=wt(t.getAssociatedKeyIds());!(s=d()).done;)c();if(void 0!==n&&"init-data"!==n){var v=e.keyIds,p=e.content;if(void 0!==v){var h=v.filter((function(e){return!l.some((function(t){return $(t,e)}))}));h.length>0&&(u.Z.hasLevel("DEBUG")&&u.Z.debug("DRM: init data keys missing in the license, blacklisting them",h.map((function(e){return(0,f.ci)(e)})).join(", ")),l.push.apply(l,h))}if(r&&void 0!==p)if("content"===n){for(var m,g=new Set,y=wt(p.manifest.periods);!(m=y()).done;){Dt(g,m.value)}Pt(g,l)}else if("periods"===n)for(var _,b=wt(p.manifest.periods);!(_=b()).done;){var T=_.value,E=new Set;if(Dt(E,T),(null===(o=e.content)||void 0===o?void 0:o.period.id)===T.id)Pt(E,l);else for(var S=Array.from(E),w=function(){var e=A[k];if(l.some((function(t){return $(t,e)})))return Pt(E,l),"break"},k=0,A=S;k=3&&null!==e.currentRange&&(!(0,a.Z)()||t.duration>0)?s.Z.loaded(n):null:t.duration>0?s.Z.loaded(n):null}),null),(0,r.q)(1))}},8343:function(e,t){"use strict";var n={loaded:function(e){return{type:"loaded",value:{segmentBuffersStore:e}}},decipherabilityUpdate:function(e){return{type:"decipherabilityUpdate",value:e}},manifestReady:function(e){return{type:"manifestReady",value:{manifest:e}}},manifestUpdate:function(){return{type:"manifestUpdate",value:null}},nullRepresentation:function(e,t){return{type:"representationChange",value:{type:e,representation:null,period:t}}},reloadingMediaSource:function(){return{type:"reloading-media-source",value:void 0}},stalled:function(e){return{type:"stalled",value:e}},unstalled:function(){return{type:"unstalled",value:null}},warning:function(e){return{type:"warning",value:e}}};t.Z=n},7920:function(e,t,n){"use strict";n.d(t,{Z:function(){return k}});var r=n(4975),i=n(4727),a=n(9127),o=n(9878),s=n(2817),u=n(2006),l=n(8515),c=n(7877),d=n(6108),f=n(2034),v=n(9917),p=n(8117),h=n(5561);var m=n(3774),g=n(1381);var y=n(1669),_=n(3714),b=n(3887),T=n(5095),E=n(8343);function S(e){return e.pipe((0,r.h)((function(e){var t=e.seeking,n=e.rebuffering,r=e.readyState;return!t&&null===n&&r>=1})),(0,i.q)(1),(0,a.U)((function(){})))}function w(e){return function(e){return(0,v.P)((function(){return(0,h.Z)((function(){return(0,p.Z)(e.play())}),void 0)}))}(e).pipe((0,a.U)((function(){return"autoplay"})),(0,o.K)((function(e){if(e instanceof Error&&"NotAllowedError"===e.name)return b.Z.warn("Init: Media element can't play. It may be due to browser auto-play policies."),(0,s.of)("autoplay-blocked");throw e})))}function k(e){var t=e.mediaElement,n=e.playbackObserver,r=e.startTime,a=e.mustAutoPlay,o=(0,T.$l)(!1),v=(0,T.$l)(!1),p=function(e){return e.readyState>=m.c.HAVE_METADATA?(0,s.of)(null):(0,g.K4)(e).pipe((0,i.q)(1))}(t).pipe((0,i.q)(1),(0,u.b)((function(){var e="function"==typeof r?r():r;b.Z.info("Init: Set initial time",e),n.setCurrentTime(e),o.setValue(!0),o.finish()})),(0,l.d)({refCount:!0}));return{seekAndPlay$:p.pipe((0,c.z)((function(){if(!(0,y.Z)()||t.duration>0)return S(n.getReference().asObservable());var e=new _.Z("MEDIA_ERR_NOT_LOADED_METADATA","Cannot load automatically: your browser falsely announced having loaded the content.");return S(n.getReference().asObservable()).pipe((0,d.O)(E.Z.warning(e)))})),(0,c.z)((function(e){return void 0!==e?(0,s.of)(e):(b.Z.info("Init: Can begin to play content"),a?w(t).pipe((0,c.z)((function(e){if(v.setValue(!0),v.finish(),"autoplay"===e)return(0,s.of)({type:"autoplay"});var t=new _.Z("MEDIA_ERR_BLOCKED_AUTOPLAY","Cannot trigger auto-play automatically: your browser does not allow it.");return(0,f.z)((0,s.of)(E.Z.warning(t)),(0,s.of)({type:"autoplay-blocked"}))}))):(t.autoplay&&b.Z.warn("Init: autoplay is enabled on HTML media element. Media will play as soon as possible."),v.setValue(!0),v.finish(),(0,s.of)({type:"skipped"})))})),(0,l.d)({refCount:!0})),initialPlayPerformed:v,initialSeekPerformed:o}}},8969:function(e,t,n){"use strict";n.d(t,{Z:function(){return T}});var r=n(1545),i=n(5583),a=n(4975),o=n(4727),s=n(7877),u=n(4978),l=n(2817),c=n(3071),d=n(533),f=n(5767),v=n(1480),p=n(3887);var h=n(8333),m=n(5039),g=n(7920),y=n(9607),_=n(342),b=n(2447);function T(e){var t=e.autoPlay,n=e.keySystems,T=e.mediaElement,E=e.playbackObserver,S=e.speed,w=e.startAt,k=e.url;if((0,f.Z)(T),null==k)throw new Error("No URL for a DirectFile content");var A=function(e,t){return new v.y((function(n){return p.Z.info("Setting URL to HTMLMediaElement",t),e.src=t,n.next(void 0),function(){(0,f.Z)(e)}}))}(T,k),x=(0,g.Z)({mediaElement:T,playbackObserver:E,startTime:function(){p.Z.debug("Init: Calculating initial time");var e=function(e,t){if(null==t)return 0;if(null!=t.position)return t.position;if(null!=t.wallClockTime)return t.wallClockTime;if(null!=t.fromFirstPosition)return t.fromFirstPosition;var n=e.duration;if(null==n||!isFinite(n))return p.Z.warn("startAt.fromLastPosition set but no known duration, beginning at 0."),0;if("number"==typeof t.fromLastPosition)return Math.max(0,n+t.fromLastPosition);if(null!=t.percentage){var r=t.percentage;return r>=100?n:r<=0?0:n*(+r/100)}return 0}(T,w);return p.Z.debug("Init: Initial time calculated:",e),e},mustAutoPlay:t}),I=x.seekAndPlay$,Z=(0,y.Z)(T,n,r.E,A).pipe((0,h.Z)(),(0,i.B)()),R=(0,b.Z)(T),M=E.getReference().asObservable(),C=(0,_.Z)(E,null,S,r.E,r.E),P=Z.pipe((0,a.h)((function(e){return"decryption-ready"===e.type||"decryption-disabled"===e.type})),(0,o.q)(1),(0,s.z)((function(){return I})),(0,u.w)((function(e){return"warning"===e.type?(0,l.of)(e):(0,m.Z)(M,T,null,!0)})));return(0,c.T)(P,Z.pipe((0,d.l)()),R,C)}},9607:function(e,t,n){"use strict";n.d(t,{Z:function(){return v}});var r=n(3071),i=n(9127),a=n(1480),o=n(1381),s=n(6139);var u=n(5157),l=n(7874),c=n(3887),d=n(7425),f=o.Oh;function v(e,t,n,o){var v=(0,r.T)(f(e),n);if(null==l.Z.ContentDecryptor)return(0,r.T)(v.pipe((0,i.U)((function(){throw c.Z.error("Init: Encrypted event but EME feature not activated"),new u.Z("MEDIA_IS_ENCRYPTED_ERROR","EME feature not activated.")}))),o.pipe((0,i.U)((function(e){return{type:"decryption-disabled",value:{drmSystemId:void 0,mediaSource:e}}}))));if(0===t.length)return(0,r.T)(v.pipe((0,i.U)((function(){throw c.Z.error("Init: Ciphered media and no keySystem passed"),new u.Z("MEDIA_IS_ENCRYPTED_ERROR","Media is encrypted and no `keySystems` given")}))),o.pipe((0,i.U)((function(e){return{type:"decryption-disabled",value:{drmSystemId:void 0,mediaSource:e}}}))));if("function"!=typeof s.N)return(0,r.T)(v.pipe((0,i.U)((function(){throw c.Z.error("Init: Encrypted event but no EME API available"),new u.Z("MEDIA_IS_ENCRYPTED_ERROR","Encryption APIs not found.")}))),o.pipe((0,i.U)((function(e){return{type:"decryption-disabled",value:{drmSystemId:void 0,mediaSource:e}}}))));c.Z.debug("Init: Creating ContentDecryptor");var p=l.Z.ContentDecryptor;return new a.y((function(r){var i,a=new p(e,t);a.addEventListener("stateChange",(function(e){e===d.u.WaitingForAttachment&&(a.removeEventListener("stateChange"),i=o.subscribe((function(e){a.addEventListener("stateChange",(function(t){t===d.u.ReadyForContent&&(r.next({type:"decryption-ready",value:{drmSystemId:a.systemId,mediaSource:e}}),a.removeEventListener("stateChange"))})),a.attach()})))})),a.addEventListener("error",(function(e){r.error(e)})),a.addEventListener("warning",(function(e){r.next({type:"warning",value:e})}));var s=n.subscribe((function(e){a.onInitializationData(e)}));return function(){s.unsubscribe(),null==i||i.unsubscribe(),a.dispose()}}))}},342:function(e,t,n){"use strict";n.d(t,{Z:function(){return y}});var r=n(3428),i=n(3074),a=n(2006),o=n(533),s=n(9127),u=n(3071),l=n(3286),c=n(3666).yS,d=n(6872),f=n(3714),v=n(3887),p=n(2829),h=n(288),m=n(8567),g=1/60;function y(e,t,n,f,h){var y,E=h.pipe((0,r.M)(e.getReference().asObservable()),(0,i.R)((function(e,t){return function(e,t,n){for(;e.length>0&&void 0!==e[0].period.end&&e[0].period.end+10r.start)return _(t)&&e.splice(a,0,t),e;_(t)&&e.push(t);return e}(e,t[0],t[1])}),[])),S=null,w=null,k=f.pipe((0,r.M)(e.getReference().asObservable()),(0,a.b)((function(t){var r,i=t[0],a=t[1];if(!(!a.rebuffering||a.paused||n.getValue()<=0||"audio"!==i.bufferType&&"video"!==i.bufferType)){var o=a.position,s=null!==(r=a.rebuffering.position)&&void 0!==r?r:o,u=i.period.start;ox&&(v.Z.warn("Init: trying to seek to un-freeze player"),e.setCurrentTime(e.getCurrentTime()+I),y={attemptTimestamp:R}),R-h.timestamp>k)return null===f||null!==w?A.stopRebuffering():A.startRebuffering(),{type:"stalled",value:"freezing"}}else y=null;if(null===f)return A.stopRebuffering(),1===l?{type:"stalled",value:a.seeking?null!==a.pendingInternalSeek?"internal-seek":"seeking":"not-ready"}:{type:"unstalled",value:null};var M="seeking"===f.reason&&null!==a.pendingInternalSeek?"internal-seek":f.reason;if(null!==w){var C=performance.now();if(C-w0){var D=function(e,t,n){if(0===e.length)return null;for(var r=null,i=0;in)return r;var o=void 0;if(void 0===a.end||a.end>n){var s=e[i],u=s.discontinuity,l=s.position,c=u.start,d=u.end;if(n>=(null!=c?c:l)-g)if(null===d){var f=t.getPeriodAfter(a);null!==f?o=f.start+g:v.Z.warn("Init: discontinuity at Period's end but no next Period")}else no?r:o)}}return r}(o,t,P);if(null!==D){var N=D+.001;if(!(N<=e.getCurrentTime()))return v.Z.warn("SA: skippable discontinuity found in the stream",u,N),e.setCurrentTime(N),m.Z.warning(b(P,N));v.Z.info("Init: position to seek already reached, no seeking",e.getCurrentTime(),N)}}var O=null!=P?P:u,L=(0,p.XS)(s,O);if(n.getValue()>0&&L=0;U--){var F=t.periods[U];if(void 0!==F.end&&F.end<=O){if(t.periods[U+1].start>O&&t.periods[U+1].start>e.getCurrentTime()){var z=t.periods[U+1];return e.setCurrentTime(z.start),m.Z.warning(b(O,z.start))}break}}return{type:"stalled",value:M}})));return(0,u.T)(k,x).pipe((0,l.x)((function(){A.dispose()})))}function _(e){return null!==e.discontinuity}function b(e,t){return new f.Z("DISCONTINUITY_ENCOUNTERED","A discontinuity has been encountered at position "+String(e)+", seeked at position "+String(t))}var T=function(){function e(e,t){this._speedUpdateCanceller=new h.ZP,this._isRebuffering=!1,this._playbackObserver=e,this._isDisposed=!1,this._speed=t,this._updateSpeed()}var t=e.prototype;return t.startRebuffering=function(){this._isRebuffering||this._isDisposed||(this._isRebuffering=!0,this._speedUpdateCanceller.cancel(),v.Z.info("Init: Pause playback to build buffer"),this._playbackObserver.setPlaybackRate(0))},t.stopRebuffering=function(){this._isRebuffering&&!this._isDisposed&&(this._isRebuffering=!1,this._speedUpdateCanceller=new h.ZP,this._updateSpeed())},t.dispose=function(){this._speedUpdateCanceller.cancel(),this._isDisposed=!0},t._updateSpeed=function(){var e=this;this._speed.onUpdate((function(t){v.Z.info("Init: Resume playback speed",t),e._playbackObserver.setPlaybackRate(t)}),{clearSignal:this._speedUpdateCanceller.signal,emitCurrentValue:!0})},e}()},2447:function(e,t,n){"use strict";n.d(t,{Z:function(){return s}});var r=n(2401),i=n(7877),a=n(3714),o=n(1946);function s(e){return(0,r.R)(e,"error").pipe((0,i.z)((function(){var t,n,r=e.error;switch((0,o.Z)(r)||(t=r.code,n=r.message),t){case 1:throw n=null!=n?n:"The fetching of the associated resource was aborted by the user's request.",new a.Z("MEDIA_ERR_ABORTED",n);case 2:throw n=null!=n?n:"A network error occurred which prevented the media from being successfully fetched",new a.Z("MEDIA_ERR_NETWORK",n);case 3:throw n=null!=n?n:"An error occurred while trying to decode the media resource",new a.Z("MEDIA_ERR_DECODE",n);case 4:throw n=null!=n?n:"The media resource has been found to be unsuitable.",new a.Z("MEDIA_ERR_SRC_NOT_SUPPORTED",n);default:throw n=null!=n?n:"The HTMLMediaElement errored due to an unknown reason.",new a.Z("MEDIA_ERR_UNKNOWN",n)}})))}},7127:function(e,t,n){"use strict";n.d(t,{Z:function(){return s}});var r=n(4578),i=n(3887),a=n(9612),o=n(4309),s=function(e){function t(){var t;return i.Z.debug("ISB: Creating ImageSegmentBuffer"),(t=e.call(this)||this).bufferType="image",t._buffered=new o.Z,t}(0,r.Z)(t,e);var n=t.prototype;return n.pushChunk=function(e){var t,n;if(i.Z.debug("ISB: appending new data."),null===e.data.chunk)return Promise.resolve();var r=e.data,a=r.appendWindow,o=r.chunk,s=o.start,u=o.end,l=o.timescale,c=null!==(t=a[0])&&void 0!==t?t:0,d=null!==(n=a[1])&&void 0!==n?n:1/0,f=s/l,v=u/l,p=Math.max(c,f),h=Math.min(d,v);try{this._buffered.insert(p,h),null!==e.inventoryInfos&&this._segmentInventory.insertChunk(e.inventoryInfos)}catch(e){return Promise.reject(e)}return Promise.resolve()},n.removeBuffer=function(e,t){return i.Z.info("ISB: ignored image data remove order",e,t),Promise.resolve()},n.endOfSegment=function(e){return this._segmentInventory.completeSegment(e,this._buffered),Promise.resolve()},n.getBufferedRanges=function(){return this._buffered},n.dispose=function(){i.Z.debug("ISB: disposing image SegmentBuffer"),this._buffered.remove(0,1/0)},t}(a.C)},5192:function(e,t,n){"use strict";n.d(t,{Z:function(){return w}});var r=n(4578),i=n(1381),a=n(3887),o=n(5095),s=n(2203).Z?void 0:window.ResizeObserver;var u=n(6872),l=n(288),c=n(9612),d=n(4309),f=n(7874);function v(e,t){return Math.abs(e-t)<=.2}function p(e,t){for(var n=e.length-1;n>=0;n--){if(e[n].startt)return e.slice(n,e.length)}return[]}function m(e,t,n){var r=Math.max(e.start,t),i=p(e.cues,t),a={start:e.start,end:r,cues:i},o=Math.min(n,e.end),s=h(e.cues,n);return[a,{start:o,end:e.end,cues:s}]}var g=function(){function e(){this._cuesBuffer=[]}var t=e.prototype;return t.get=function(e){for(var t=this._cuesBuffer,n=[],r=t.length-1;r>=0;r--){var i=t[r];if(e=i.start){for(var a=i.cues,o=0;o=a[o].start&&ee){var a=r[i];if(a.start>=n)return;if(a.end>=n){if(e<=a.start)a.cues=h(a.cues,n),a.start=n;else{var o=m(a,e,n),s=o[0],u=o[1];this._cuesBuffer[i]=s,r.splice(i+1,0,u)}return}a.start>=e?(r.splice(i,1),i--):(a.cues=p(a.cues,e),a.end=Math.max(e,a.start))}},t.insert=function(e,t,n){var r=this._cuesBuffer,i={start:t,end:n,cues:e};function a(e){var t=r[e];void 0===t||v(i.end,t.end)?r[e]=i:(t.start>=i.end||(t.cues=h(t.cues,i.end),t.start=i.end),r.splice(e,0,i))}for(var o=0;os.end);return void a(o)}if(ts.end);return void a(o)}if(v(s.end,n))return s.cues=p(s.cues,t),s.end=t,void r.splice(o+1,0,i);if(s.end>n){var u=m(s,t,n),l=u[0],c=u[1];return this._cuesBuffer[o]=l,r.splice(o+1,0,i),void r.splice(o+2,0,c)}s.cues=p(s.cues,t),s.end=t;var d=o+1;for(s=r[d];void 0!==s&&n>s.end;)r.splice(d,1),s=r[d];return void a(d)}}r.push(i)},e}();function y(e,t,n,r){for(var i=[t/n.columns,e/n.rows],a=r.getElementsByClassName("proportional-style"),o=0;o0}var _=i.M4,b=i.bQ,T=i.Q$;function E(e,t){try{e.removeChild(t)}catch(e){a.Z.warn("HTSB: Can't remove text track: not in the element.")}}function S(e){var t=e.getAttribute("data-resolution-rows"),n=e.getAttribute("data-resolution-columns");if(null===t||null===n)return null;var r=parseInt(t,10),i=parseInt(n,10);return null===r||null===i?null:{rows:r,columns:i}}var w=function(e){function t(t,n){var r;return a.Z.debug("HTSB: Creating HTMLTextSegmentBuffer"),(r=e.call(this)||this).bufferType="text",r._buffered=new d.Z,r._videoElement=t,r._textTrackElement=n,r._sizeUpdateCanceller=new l.ZP,r._canceller=new l.ZP,r._buffer=new g,r._currentCues=[],r.autoRefreshSubtitles(r._canceller.signal),r}(0,r.Z)(t,e);var n=t.prototype;return n.pushChunk=function(e){try{this.pushChunkSync(e)}catch(e){return Promise.reject(e)}return Promise.resolve()},n.removeBuffer=function(e,t){return this.removeBufferSync(e,t),Promise.resolve()},n.endOfSegment=function(e){return this._segmentInventory.completeSegment(e,this._buffered),Promise.resolve()},n.getBufferedRanges=function(){return this._buffered},n.dispose=function(){a.Z.debug("HTSB: Disposing HTMLTextSegmentBuffer"),this._disableCurrentCues(),this._buffer.remove(0,1/0),this._buffered.remove(0,1/0),this._canceller.cancel()},n.pushChunkSync=function(e){var t,n;a.Z.debug("HTSB: Appending new html text tracks");var r=e.data,i=r.timestampOffset,o=r.appendWindow,s=r.chunk;if(null!==s){var u,l,c=s.start,d=s.end,v=s.data,p=s.type,h=s.language,m=null!==(t=o[0])&&void 0!==t?t:0,g=null!==(n=o[1])&&void 0!==n?n:1/0,y=function(e,t,n,r){a.Z.debug("HTSB: Finding parser for html text tracks:",e);var i=f.Z.htmlTextTracksParsers[e];if("function"!=typeof i)throw new Error("no parser found for the given text track");a.Z.debug("HTSB: Parser found, parsing...");var o=i(t,n,r);return a.Z.debug("HTTB: Parsed successfully!",o.length),o}(p,v,i,h);if(0!==m&&g!==1/0){for(var _=0;_=0&&y[_].start>=g;)_--;for(y.splice(_,y.length),_=y.length-1;_>=0&&y[_].end>g;)y[_].end=g,_--}if(void 0!==c)u=Math.max(m,c);else{if(y.length<=0)return void a.Z.warn("HTSB: Current text tracks have no cues nor start time. Aborting");a.Z.warn("HTSB: No start time given. Guessing from cues."),u=y[0].start}if(void 0!==d)l=Math.min(g,d);else{if(y.length<=0)return void a.Z.warn("HTSB: Current text tracks have no cues nor end time. Aborting");a.Z.warn("HTSB: No end time given. Guessing from cues."),l=y[y.length-1].end}l<=u?a.Z.warn("HTSB: Invalid text track appended: ","the start time is inferior or equal to the end time."):(null!==e.inventoryInfos&&this._segmentInventory.insertChunk(e.inventoryInfos),this._buffer.insert(y,u,l),this._buffered.insert(u,l))}},n.removeBufferSync=function(e,t){a.Z.debug("HTSB: Removing html text track data",e,t),this._buffer.remove(e,t),this._buffered.remove(e,t)},n._disableCurrentCues=function(){if(this._sizeUpdateCanceller.cancel(),this._currentCues.length>0){for(var e=0;e0){this._sizeUpdateCanceller=new l.ZP({cancelOn:this._canceller.signal});var d=u.Z.getCurrent().TEXT_TRACK_SIZE_CHECKS_INTERVAL,f=function(e,t,n){var r=e.getBoundingClientRect(),i=r.height,u=r.width,l=(0,o.ZP)({height:i,width:u}),c=i,d=u;if(void 0!==s){var f=new s((function(e){if(0!==e.length){var t=e[0].contentRect,n=t.height,r=t.width;n===c&&r===d||(c=n,d=r,l.setValue({height:n,width:r}))}else a.Z.error("Compat: Resized but no observed element.")}));f.observe(e),n.register((function(){f.disconnect()}))}else{var v=setInterval((function(){var t=e.getBoundingClientRect(),n=t.height,r=t.width;n===c&&r===d||(c=n,d=r,l.setValue({height:n,width:r}))}),t);n.register((function(){clearInterval(v)}))}return l}(this._textTrackElement,d,this._sizeUpdateCanceller.signal);f.onUpdate((function(e){for(var t=e.height,n=e.width,r=0;r0?e.textTracks[u-1]:e.addTextTrack(s)).mode=t?null!==(n=a.HIDDEN)&&void 0!==n?n:"hidden":null!==(r=a.SHOWING)&&void 0!==r?r:"showing"}else o=document.createElement("track"),e.appendChild(o),a=o.track,o.kind=s,a.mode=t?"hidden":"showing";return{track:a,trackElement:o}}(t,n),s=o.track,l=o.trackElement;return r.bufferType="text",r._buffered=new u.Z,r._videoElement=t,r._track=s,r._trackElement=l,r}(0,r.Z)(t,e);var n=t.prototype;return n.pushChunk=function(e){var t,n;if(a.Z.debug("NTSB: Appending new native text tracks"),null===e.data.chunk)return Promise.resolve();var r=e.data,i=r.timestampOffset,o=r.appendWindow,s=r.chunk,u=s.start,c=s.end,d=s.data,f=s.type,v=s.language,p=null!==(t=o[0])&&void 0!==t?t:0,h=null!==(n=o[1])&&void 0!==n?n:1/0;try{var m,g,y=function(e,t,n,r){a.Z.debug("NTSB: Finding parser for native text tracks:",e);var i=l.Z.nativeTextTracksParsers[e];if("function"!=typeof i)throw new Error("no parser found for the given text track");a.Z.debug("NTSB: Parser found, parsing...");var o=i(t,n,r);return a.Z.debug("NTSB: Parsed successfully!",o.length),o}(f,d,i,v);if(0!==p&&h!==1/0){for(var _=0;_=0&&y[_].startTime>=h;)_--;for(y.splice(_,y.length),_=y.length-1;_>=0&&y[_].endTime>h;)y[_].endTime=h,_--}if(void 0!==u)m=Math.max(p,u);else{if(y.length<=0)return a.Z.warn("NTSB: Current text tracks have no cues nor start time. Aborting"),Promise.resolve();a.Z.warn("NTSB: No start time given. Guessing from cues."),m=y[0].startTime}if(void 0!==c)g=Math.min(h,c);else{if(y.length<=0)return a.Z.warn("NTSB: Current text tracks have no cues nor end time. Aborting"),Promise.resolve();a.Z.warn("NTSB: No end time given. Guessing from cues."),g=y[y.length-1].endTime}if(g<=m)return a.Z.warn("NTSB: Invalid text track appended: ","the start time is inferior or equal to the end time."),Promise.resolve();if(y.length>0){var b=y[0],T=this._track.cues;null!==T&&T.length>0&&b.startTime=0;i--){var s=r[i],u=s.startTime,l=s.endTime;u>=e&&u<=t&&l<=t&&o(n,s)}this._buffered.remove(e,t)},t}(s.C)},9612:function(e,t,n){"use strict";n.d(t,{C:function(){return _},f:function(){return g}});var r=n(6872),i=n(3887),a=n(520),o=n(5278);function s(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return u(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return u(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&(this._history=this._history.splice(r)),this._history.length>this._maxHistoryLength){var a=this._history.length-this._maxHistoryLength;this._history=this._history.splice(a)}},e}();function c(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return d(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return d(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0){var _=t[p+y-1];g={end:(0,o.Z)(_.bufferedEnd,_.end),precizeEnd:_.precizeEnd},i.Z.debug("SI: "+y+" segments GCed.",u);for(var b,T=c(t.splice(p,y));!(b=T()).done;){var E=b.value;void 0===E.bufferedStart&&void 0===E.bufferedEnd&&this._bufferedHistory.addBufferedSegment(E.infos,null)}n=p}if(void 0===a)return;if(v-(0,o.Z)(a.bufferedStart,a.start)>=s){if(h(a,f,g,u),n===t.length-1)return void m(a,v,u);a=t[++n];for(var S=(0,o.Z)(a.bufferedStart,a.start),w=(0,o.Z)(a.bufferedEnd,a.end),k=d=s&&(void 0===k||v-S>=w-k);){var A=t[n-1];void 0===A.bufferedEnd&&(A.bufferedEnd=a.precizeStart?a.start:A.end,i.Z.debug("SI: calculating buffered end of contiguous segment",u,A.bufferedEnd,A.end)),a.bufferedStart=A.bufferedEnd,void 0!==(a=t[++n])&&(S=(0,o.Z)(a.bufferedStart,a.start),w=(0,o.Z)(a.bufferedEnd,a.end))}}var x=t[n-1];void 0!==x&&m(x,v,u)}}if(null!=a){i.Z.debug("SI: last segments have been GCed",u,n,t.length);for(var I,Z=c(t.splice(n,t.length-n));!(I=Z()).done;){var R=I.value;void 0===R.bufferedStart&&void 0===R.bufferedEnd&&this._bufferedHistory.addBufferedSegment(R.infos,null)}}void 0!==u&&i.Z.hasLevel("DEBUG")&&i.Z.debug("SI: current "+u+" inventory timeline:\n"+function(e){var t=1/60,n={},r=[],i=null,a=null;function o(e){var t=String.fromCharCode(r.length+65);return r.push({letter:t,periodId:e.period.id,representationId:e.representation.id,bitrate:e.representation.bitrate}),t}for(var s="",u=0;u=u)i.Z.warn("SI: Invalid chunked inserted: starts before it ends",l,s,u);else{for(var c=this._inventory,d={partiallyPushed:!0,chunkSize:o,splitted:!1,start:s,end:u,precizeStart:!1,precizeEnd:!1,bufferedStart:void 0,bufferedEnd:void 0,infos:{segment:a,period:t,adaptation:n,representation:r}},f=c.length-1;f>=0;f--){var v=c[f];if(v.start<=s){if(v.end<=s){for(i.Z.debug("SI: Pushing segment strictly after previous one.",l,s,v.end),this._inventory.splice(f+1,0,d),f+=2;fd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",l,d.end,c[f].start),c[f].start=d.end,c[f].bufferedStart=void 0,void(c[f].precizeStart=c[f].precizeStart&&d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",l,s,u,c[f].start,c[f].end),c.splice(f,1)}return}if(v.start===s){if(v.end<=u){for(i.Z.debug("SI: Segment pushed replace another one",l,s,u,v.end),this._inventory.splice(f,1,d),f+=1;fd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",l,d.end,c[f].start),c[f].start=d.end,c[f].bufferedStart=void 0,void(c[f].precizeStart=c[f].precizeStart&&d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",l,s,u,c[f].start,c[f].end),c.splice(f,1)}return}return i.Z.debug("SI: Segment pushed ends before another with the same start",l,s,u,v.end),c.splice(f,0,d),v.start=d.end,v.bufferedStart=void 0,void(v.precizeStart=v.precizeStart&&d.precizeEnd)}if(v.end<=d.end){for(i.Z.debug("SI: Segment pushed updates end of previous one",l,s,u,v.start,v.end),this._inventory.splice(f+1,0,d),v.end=d.start,v.bufferedEnd=void 0,v.precizeEnd=v.precizeEnd&&d.precizeStart,f+=2;fd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",l,d.end,c[f].start),c[f].start=d.end,c[f].bufferedStart=void 0,void(c[f].precizeStart=c[f].precizeStart&&d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",l,s,u,c[f].start,c[f].end),c.splice(f,1)}return}i.Z.warn("SI: Segment pushed is contained in a previous one",l,s,u,v.start,v.end);var p={partiallyPushed:v.partiallyPushed,chunkSize:v.chunkSize,splitted:!0,start:d.end,end:v.end,precizeStart:v.precizeStart&&v.precizeEnd&&d.precizeEnd,precizeEnd:v.precizeEnd,bufferedStart:void 0,bufferedEnd:v.end,infos:v.infos};return v.end=d.start,v.splitted=!0,v.bufferedEnd=void 0,v.precizeEnd=v.precizeEnd&&d.precizeStart,c.splice(f+1,0,d),void c.splice(f+2,0,p)}}var h=this._inventory[0];if(void 0===h)return i.Z.debug("SI: first segment pushed",l,s,u),void this._inventory.push(d);if(!(h.start>=u)){if(h.end<=u){for(i.Z.debug("SI: Segment pushed starts before and completely recovers the previous first one",l,s,u,h.start,h.end),this._inventory.splice(0,1,d);c.length>1&&c[1].startd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",l,d.end,c[1].start),c[1].start=d.end,c[1].bufferedStart=void 0,void(c[1].precizeStart=d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",l,s,u,c[1].start,c[1].end),c.splice(1,1)}return}return i.Z.debug("SI: Segment pushed start of the next one",l,s,u,h.start,h.end),h.start=u,h.bufferedStart=void 0,h.precizeStart=d.precizeEnd,void this._inventory.splice(0,0,d)}i.Z.debug("SI: Segment pushed comes before all previous ones",l,s,u,h.start),this._inventory.splice(0,0,d)}}},t.completeSegment=function(e,t){if(!e.segment.isInit){for(var n=this._inventory,r=[],o=0;o0&&(s=!0,1===r.length&&(i.Z.warn("SI: Completed Segment is splitted.",e.segment.id,e.segment.time,e.segment.end),r[0].splitted=!0));var u=o,l=n[o].chunkSize;for(o+=1;o0&&(this._inventory.splice(u+1,v),o-=v),this._inventory[u].partiallyPushed=!1,this._inventory[u].chunkSize=l,this._inventory[u].end=p,this._inventory[u].bufferedEnd=h,this._inventory[u].splitted=s,r.push(this._inventory[u])}if(0===r.length)i.Z.warn("SI: Completed Segment not found",e.segment.id,e.segment.time);else{this.synchronizeBuffered(t);for(var m,g=c(r);!(m=g()).done;){var y=m.value;void 0!==y.bufferedStart&&void 0!==y.bufferedEnd?this._bufferedHistory.addBufferedSegment(y.infos,{start:y.bufferedStart,end:y.bufferedEnd}):i.Z.debug("SI: buffered range not known after sync. Skipping history.",y.start,y.end)}}}},t.getInventory=function(){return this._inventory},t.getHistoryFor=function(e){return this._bufferedHistory.getHistoryFor(e)},e}();function v(e){if(void 0===e.bufferedStart||e.partiallyPushed)return!1;var t=e.start,n=e.end-t,i=r.Z.getCurrent(),a=i.MAX_MANIFEST_BUFFERED_START_END_DIFFERENCE,o=i.MAX_MANIFEST_BUFFERED_DURATION_DIFFERENCE;return Math.abs(t-e.bufferedStart)<=a&&(void 0===e.bufferedEnd||e.bufferedEnd>e.bufferedStart&&Math.abs(e.bufferedEnd-e.bufferedStart-n)<=Math.min(o,n/3))}function p(e){if(void 0===e.bufferedEnd||e.partiallyPushed)return!1;var t=e.start,n=e.end,i=n-t,a=r.Z.getCurrent(),o=a.MAX_MANIFEST_BUFFERED_START_END_DIFFERENCE,s=a.MAX_MANIFEST_BUFFERED_DURATION_DIFFERENCE;return Math.abs(n-e.bufferedEnd)<=o&&null!=e.bufferedStart&&e.bufferedEnd>e.bufferedStart&&Math.abs(e.bufferedEnd-e.bufferedStart-i)<=Math.min(s,i/3)}function h(e,t,n,a){var o=r.Z.getCurrent().MAX_MANIFEST_BUFFERED_START_END_DIFFERENCE;void 0!==e.bufferedStart?(e.bufferedStartt&&(n.precizeEnd||e.start-n.end<=o)?(i.Z.debug("SI: buffered start is end of previous segment",a,t,e.start,n.end),e.bufferedStart=n.end,v(e)&&(e.start=n.end,e.precizeStart=!0)):e.start-t<=o?(i.Z.debug("SI: found true buffered start",a,t,e.start),e.bufferedStart=t,v(e)&&(e.start=t,e.precizeStart=!0)):tt&&(i.Z.debug("SI: Segment partially GCed at the end",n,e.bufferedEnd,t),e.bufferedEnd=t),!e.precizeEnd&&t-e.end<=a&&p(e)&&(e.precizeEnd=!0,e.end=t)):e.precizeEnd?(i.Z.debug("SI: buffered end is precize end",n,e.end),e.bufferedEnd=e.end):t-e.end<=a?(i.Z.debug("SI: found true buffered end",n,t,e.end),e.bufferedEnd=t,p(e)&&(e.end=t,e.precizeEnd=!0)):t>e.end?(i.Z.debug("SI: range end too far from expected end",n,t,e.end),e.bufferedEnd=e.end):(i.Z.debug("SI: Segment appears immediately garbage collected at the end",n,e.bufferedEnd,t),e.bufferedEnd=t)}var g,y=f,_=function(){function e(){this._segmentInventory=new y}var t=e.prototype;return t.synchronizeInventory=function(){this._segmentInventory.synchronizeBuffered(this.getBufferedRanges())},t.getInventory=function(){return this._segmentInventory.getInventory()},t.getPendingOperations=function(){return[]},t.getSegmentHistory=function(e){return this._segmentInventory.getHistoryFor(e)},e}();!function(e){e[e.Push=0]="Push",e[e.Remove=1]="Remove",e[e.EndOfSegment=2]="EndOfSegment"}(g||(g={}))},4309:function(e,t,n){"use strict";n.d(t,{Z:function(){return i}});var r=n(2829),i=function(){function e(){this._ranges=[],this.length=0}var t=e.prototype;return t.insert=function(e,t){(0,r.kR)(this._ranges,{start:e,end:t}),this.length=this._ranges.length},t.remove=function(e,t){var n=[];e>0&&n.push({start:0,end:e}),t<1/0&&n.push({start:t,end:1/0}),this._ranges=(0,r.tn)(this._ranges,n),this.length=this._ranges.length},t.start=function(e){if(e>=this._ranges.length)throw new Error("INDEX_SIZE_ERROR");return this._ranges[e].start},t.end=function(e){if(e>=this._ranges.length)throw new Error("INDEX_SIZE_ERROR");return this._ranges[e].end},e}()},8567:function(e,t,n){"use strict";var r=n(8026),i={activePeriodChanged:function(e){return{type:"activePeriodChanged",value:{period:e}}},adaptationChange:function(e,t,n){return{type:"adaptationChange",value:{type:e,adaptation:t,period:n}}},addedSegment:function(e,t,n,r){return{type:"added-segment",value:{content:e,segment:t,segmentData:r,buffered:n}}},bitrateEstimationChange:function(e,t){return{type:"bitrateEstimationChange",value:{type:e,bitrate:t}}},streamComplete:function(e){return{type:"complete-stream",value:{type:e}}},endOfStream:function(){return{type:"end-of-stream",value:void 0}},needsManifestRefresh:function(){return{type:"needs-manifest-refresh",value:void 0}},manifestMightBeOufOfSync:function(){return{type:"manifest-might-be-out-of-sync",value:void 0}},needsMediaSourceReload:function(e,t){return{type:"needs-media-source-reload",value:{position:e,autoPlay:t}}},lockedStream:function(e,t){return{type:"locked-stream",value:{bufferType:e,period:t}}},needsBufferFlush:function(){return{type:"needs-buffer-flush",value:void 0}},needsDecipherabilityFlush:function(e,t,n){return{type:"needs-decipherability-flush",value:{position:e,autoPlay:t,duration:n}}},periodStreamReady:function(e,t,n){return{type:"periodStreamReady",value:{type:e,period:t,adaptation$:n}}},periodStreamCleared:function(e,t){return{type:"periodStreamCleared",value:{type:e,period:t}}},encryptionDataEncountered:function(e,t){return{type:"encryption-data-encountered",value:(0,r.Z)({content:t},e)}},representationChange:function(e,t,n){return{type:"representationChange",value:{type:e,period:t,representation:n}}},streamTerminating:function(){return{type:"stream-terminating",value:void 0}},resumeStream:function(){return{type:"resume-stream",value:void 0}},warning:function(e){return{type:"warning",value:e}},waitingMediaSourceReload:function(e,t,n,r){return{type:"waiting-media-source-reload",value:{bufferType:e,period:t,position:n,autoPlay:r}}}};t.Z=i},7839:function(e,t,n){"use strict";n.d(t,{Z:function(){return a}});var r=n(7326),i=n(4578),a=function(e){function t(n,i,a,o){var s;return s=e.call(this)||this,Object.setPrototypeOf((0,r.Z)(s),t.prototype),s.name="CustomLoaderError",s.message=n,s.canRetry=i,s.isOfflineError=a,s.xhr=o,s}return(0,i.Z)(t,e),t}((0,n(2146).Z)(Error))},5157:function(e,t,n){"use strict";n.d(t,{Z:function(){return u}});var r=n(7326),i=n(4578),a=n(2146),o=n(5992),s=n(7367),u=function(e){function t(n,i,a){var u;return u=e.call(this)||this,Object.setPrototypeOf((0,r.Z)(u),t.prototype),u.name="EncryptedMediaError",u.type=o.ZB.ENCRYPTED_MEDIA_ERROR,u.code=n,u.message=(0,s.Z)(u.name,u.code,i),u.fatal=!1,"string"==typeof(null==a?void 0:a.keyStatuses)&&(u.keyStatuses=a.keyStatuses),u}return(0,i.Z)(t,e),t}((0,a.Z)(Error))},5992:function(e,t,n){"use strict";n.d(t,{SM:function(){return a},ZB:function(){return r},br:function(){return i}});var r={NETWORK_ERROR:"NETWORK_ERROR",MEDIA_ERROR:"MEDIA_ERROR",ENCRYPTED_MEDIA_ERROR:"ENCRYPTED_MEDIA_ERROR",OTHER_ERROR:"OTHER_ERROR"},i={TIMEOUT:"TIMEOUT",ERROR_EVENT:"ERROR_EVENT",ERROR_HTTP_CODE:"ERROR_HTTP_CODE",PARSE_ERROR:"PARSE_ERROR"},a={PIPELINE_LOAD_ERROR:"PIPELINE_LOAD_ERROR",PIPELINE_PARSE_ERROR:"PIPELINE_PARSE_ERROR",INTEGRITY_ERROR:"INTEGRITY_ERROR",MANIFEST_PARSE_ERROR:"MANIFEST_PARSE_ERROR",MANIFEST_INCOMPATIBLE_CODECS_ERROR:"MANIFEST_INCOMPATIBLE_CODECS_ERROR",MANIFEST_UPDATE_ERROR:"MANIFEST_UPDATE_ERROR",MANIFEST_UNSUPPORTED_ADAPTATION_TYPE:"MANIFEST_UNSUPPORTED_ADAPTATION_TYPE",MEDIA_STARTING_TIME_NOT_FOUND:"MEDIA_STARTING_TIME_NOT_FOUND",MEDIA_TIME_BEFORE_MANIFEST:"MEDIA_TIME_BEFORE_MANIFEST",MEDIA_TIME_AFTER_MANIFEST:"MEDIA_TIME_AFTER_MANIFEST",MEDIA_TIME_NOT_FOUND:"MEDIA_TIME_NOT_FOUND",NO_PLAYABLE_REPRESENTATION:"NO_PLAYABLE_REPRESENTATION",MEDIA_IS_ENCRYPTED_ERROR:"MEDIA_IS_ENCRYPTED_ERROR",CREATE_MEDIA_KEYS_ERROR:"CREATE_MEDIA_KEYS_ERROR",KEY_ERROR:"KEY_ERROR",KEY_STATUS_CHANGE_ERROR:"KEY_STATUS_CHANGE_ERROR",KEY_UPDATE_ERROR:"KEY_UPDATE_ERROR",KEY_LOAD_ERROR:"KEY_LOAD_ERROR",KEY_LOAD_TIMEOUT:"KEY_LOAD_TIMEOUT",KEY_GENERATE_REQUEST_ERROR:"KEY_GENERATE_REQUEST_ERROR",INCOMPATIBLE_KEYSYSTEMS:"INCOMPATIBLE_KEYSYSTEMS",INVALID_ENCRYPTED_EVENT:"INVALID_ENCRYPTED_EVENT",INVALID_KEY_SYSTEM:"INVALID_KEY_SYSTEM",LICENSE_SERVER_CERTIFICATE_ERROR:"LICENSE_SERVER_CERTIFICATE_ERROR",MULTIPLE_SESSIONS_SAME_INIT_DATA:"MULTIPLE_SESSIONS_SAME_INIT_DATA",BUFFER_APPEND_ERROR:"BUFFER_APPEND_ERROR",BUFFER_FULL_ERROR:"BUFFER_FULL_ERROR",BUFFER_TYPE_UNKNOWN:"BUFFER_TYPE_UNKNOWN",MEDIA_ERR_BLOCKED_AUTOPLAY:"MEDIA_ERR_BLOCKED_AUTOPLAY",MEDIA_ERR_PLAY_NOT_ALLOWED:"MEDIA_ERR_PLAY_NOT_ALLOWED",MEDIA_ERR_NOT_LOADED_METADATA:"MEDIA_ERR_NOT_LOADED_METADATA",MEDIA_ERR_ABORTED:"MEDIA_ERR_ABORTED",MEDIA_ERR_NETWORK:"MEDIA_ERR_NETWORK",MEDIA_ERR_DECODE:"MEDIA_ERR_DECODE",MEDIA_ERR_SRC_NOT_SUPPORTED:"MEDIA_ERR_SRC_NOT_SUPPORTED",MEDIA_ERR_UNKNOWN:"MEDIA_ERR_UNKNOWN",MEDIA_SOURCE_NOT_SUPPORTED:"MEDIA_SOURCE_NOT_SUPPORTED",MEDIA_KEYS_NOT_SUPPORTED:"MEDIA_KEYS_NOT_SUPPORTED",DISCONTINUITY_ENCOUNTERED:"DISCONTINUITY_ENCOUNTERED",NONE:"NONE"}},7367:function(e,t,n){"use strict";function r(e,t,n){return e+" ("+t+") "+n}n.d(t,{Z:function(){return r}})},8750:function(e,t,n){"use strict";n.d(t,{Z:function(){return a}});var r=n(9822),i=n(5389);function a(e,t){var n=t.defaultCode,a=t.defaultReason;if((0,r.Z)(e))return e;var o=e instanceof Error?e.toString():a;return new i.Z(n,o)}},9822:function(e,t,n){"use strict";n.d(t,{Z:function(){return u}});var r=n(5157),i=n(5992),a=n(3714),o=n(9362),s=n(5389);function u(e){return(e instanceof r.Z||e instanceof a.Z||e instanceof s.Z||e instanceof o.Z)&&Object.keys(i.ZB).indexOf(e.type)>=0}},3714:function(e,t,n){"use strict";n.d(t,{Z:function(){return u}});var r=n(7326),i=n(4578),a=n(2146),o=n(5992),s=n(7367),u=function(e){function t(n,i){var a;return a=e.call(this)||this,Object.setPrototypeOf((0,r.Z)(a),t.prototype),a.name="MediaError",a.type=o.ZB.MEDIA_ERROR,a.code=n,a.message=(0,s.Z)(a.name,a.code,i),a.fatal=!1,a}return(0,i.Z)(t,e),t}((0,a.Z)(Error))},9362:function(e,t,n){"use strict";n.d(t,{Z:function(){return u}});var r=n(7326),i=n(4578),a=n(2146),o=n(5992),s=n(7367),u=function(e){function t(n,i){var a;return a=e.call(this)||this,Object.setPrototypeOf((0,r.Z)(a),t.prototype),a.name="NetworkError",a.type=o.ZB.NETWORK_ERROR,a.xhr=void 0===i.xhr?null:i.xhr,a.url=i.url,a.status=i.status,a.errorType=i.type,a.code=n,a.message=(0,s.Z)(a.name,a.code,i.message),a.fatal=!1,a}return(0,i.Z)(t,e),t.prototype.isHttpError=function(e){return this.errorType===o.br.ERROR_HTTP_CODE&&this.status===e},t}((0,a.Z)(Error))},5389:function(e,t,n){"use strict";n.d(t,{Z:function(){return u}});var r=n(7326),i=n(4578),a=n(2146),o=n(5992),s=n(7367),u=function(e){function t(n,i){var a;return a=e.call(this)||this,Object.setPrototypeOf((0,r.Z)(a),t.prototype),a.name="OtherError",a.type=o.ZB.OTHER_ERROR,a.code=n,a.message=(0,s.Z)(a.name,a.code,i),a.fatal=!1,a}return(0,i.Z)(t,e),t}((0,a.Z)(Error))},9105:function(e,t,n){"use strict";n.d(t,{Z:function(){return a}});var r=n(7326),i=n(4578),a=function(e){function t(n,i,a,o){var s;return s=e.call(this)||this,Object.setPrototypeOf((0,r.Z)(s),t.prototype),s.name="RequestError",s.url=n,void 0!==o&&(s.xhr=o),s.status=i,s.type=a,s.message=a,s}return(0,i.Z)(t,e),t}((0,n(2146).Z)(Error))},7273:function(e,t){"use strict";t.Z={dashParsers:{wasm:null,js:null},directfile:null,ContentDecryptor:null,htmlTextTracksBuffer:null,htmlTextTracksParsers:{},imageBuffer:null,imageParser:null,nativeTextTracksBuffer:null,nativeTextTracksParsers:{},transports:{}}},7874:function(e,t,n){"use strict";var r=n(7273);t.Z=r.Z},3887:function(e,t,n){"use strict";n.d(t,{Z:function(){return i}});var r=n(8894),i=new(function(){function e(){this.error=r.Z,this.warn=r.Z,this.info=r.Z,this.debug=r.Z,this._levels={NONE:0,ERROR:1,WARNING:2,INFO:3,DEBUG:4},this._currentLevel="NONE"}var t=e.prototype;return t.setLevel=function(e){var t,n=this._levels[e];"number"==typeof n?(t=n,this._currentLevel=e):(t=0,this._currentLevel="NONE"),this.error=t>=this._levels.ERROR?console.error.bind(console):r.Z,this.warn=t>=this._levels.WARNING?console.warn.bind(console):r.Z,this.info=t>=this._levels.INFO?console.info.bind(console):r.Z,this.debug=t>=this._levels.DEBUG?console.log.bind(console):r.Z},t.getLevel=function(){return this._currentLevel},t.hasLevel=function(e){return this._levels[e]>=this._levels[this._currentLevel]},e}())},8999:function(e,t,n){"use strict";n.d(t,{r:function(){return v},Z:function(){return p}});var r=n(3274),i=n(1946),a=n(7829);var o="undefined"!=typeof window&&"function"==typeof window.Set&&"function"==typeof Array.from?function(e){return Array.from(new Set(e))}:function(e){return e.filter((function(e,t,n){return n.indexOf(e)===t}))},s=n(3774);var u=n(3887),l=n(4791);function c(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return d(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return d(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&(this.trickModeTracks=r.map((function(t){return new e(t)})));for(var l=t.representations,c=[],d=!1,v=0;v0&&!r.isSupported){var i=new a.Z("MANIFEST_INCOMPATIBLE_CODECS_ERROR","An Adaptation contains only incompatible codecs.");n.contentWarnings.push(i)}return r})).filter((function(e){return e.representations.length>0}));if(s.every((function(e){return!e.isSupported}))&&o.length>0&&("video"===i||"audio"===i))throw new a.Z("MANIFEST_PARSE_ERROR","No supported "+i+" adaptations");return s.length>0&&(r[i]=s),r}),{}),!Array.isArray(this.adaptations.video)&&!Array.isArray(this.adaptations.audio))throw new a.Z("MANIFEST_PARSE_ERROR","No supported audio and video tracks.");this.duration=e.duration,this.start=e.start,null!=this.duration&&null!=this.start&&(this.end=this.start+this.duration),this.streamEvents=void 0===e.streamEvents?[]:e.streamEvents}var t=e.prototype;return t.getAdaptations=function(){var e=this.adaptations;return(0,f.Z)(e).reduce((function(e,t){return null!=t?e.concat(t):e}),[])},t.getAdaptationsForType=function(e){var t=this.adaptations[e];return null==t?[]:t},t.getAdaptation=function(e){return(0,o.Z)(this.getAdaptations(),(function(t){var n=t.id;return e===n}))},t.getSupportedAdaptations=function(e){if(void 0===e)return this.getAdaptations().filter((function(e){return e.isSupported}));var t=this.adaptations[e];return void 0===t?[]:t.filter((function(e){return e.isSupported}))},t.containsTime=function(e){return e>=this.start&&(void 0===this.end||e=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&r._addSupplementaryImageAdaptations(u),o.length>0&&r._addSupplementaryTextAdaptations(o),r}(0,i.Z)(t,e);var n=t.prototype;return n.getPeriod=function(e){return(0,o.Z)(this.periods,(function(t){return e===t.id}))},n.getPeriodForTime=function(e){return(0,o.Z)(this.periods,(function(t){return e>=t.start&&(void 0===t.end||t.end>e)}))},n.getNextPeriod=function(e){return(0,o.Z)(this.periods,(function(t){return t.start>e}))},n.getPeriodAfter=function(e){var t=e.end;if(void 0===t)return null;var n=(0,o.Z)(this.periods,(function(e){return void 0===e.end||t0&&this.trigger("decipherabilityUpdate",t)},n.getAdaptations=function(){(0,c.Z)("manifest.getAdaptations() is deprecated. Please use manifest.period[].getAdaptations() instead");var e=this.periods[0];if(void 0===e)return[];var t=e.adaptations,n=[];for(var r in t)if(t.hasOwnProperty(r)){var i=t[r];n.push.apply(n,i)}return n},n.getAdaptationsForType=function(e){(0,c.Z)("manifest.getAdaptationsForType(type) is deprecated. Please use manifest.period[].getAdaptationsForType(type) instead");var t=this.periods[0];if(void 0===t)return[];var n=t.adaptations[e];return void 0===n?[]:n},n.getAdaptation=function(e){return(0,c.Z)("manifest.getAdaptation(id) is deprecated. Please use manifest.period[].getAdaptation(id) instead"),(0,o.Z)(this.getAdaptations(),(function(t){var n=t.id;return e===n}))},n._addSupplementaryImageAdaptations=function(e){var t=this,n=(Array.isArray(e)?e:[e]).map((function(e){var n=e.mimeType,r=e.url,i="gen-image-ada-"+b(),o="gen-image-rep-"+b(),s=(0,l.$)(r),u=r.substring(0,s),c=r.substring(s),f=new d.Z({id:i,type:"image",representations:[{bitrate:0,cdnMetadata:[{baseUrl:u}],id:o,mimeType:n,index:new h({media:c})}]},{isManuallyAdded:!0});if(f.representations.length>0&&!f.isSupported){var v=new a.Z("MANIFEST_INCOMPATIBLE_CODECS_ERROR","An Adaptation contains only incompatible codecs.");t.contentWarnings.push(v)}return f}));if(n.length>0&&this.periods.length>0){var r=this.periods[0].adaptations;r.image=null!=r.image?r.image.concat(n):n}},n._addSupplementaryTextAdaptations=function(e){var t=this,n=(Array.isArray(e)?e:[e]).reduce((function(e,n){var r=n.mimeType,i=n.codecs,o=n.url,s=n.language,u=n.languages,c=n.closedCaption,f=null!=s?[s]:null!=u?u:[],v=(0,l.$)(o),p=o.substring(0,v),m=o.substring(v);return e.concat(f.map((function(e){var n="gen-text-ada-"+b(),o="gen-text-rep-"+b(),s=new d.Z({id:n,type:"text",language:e,closedCaption:c,representations:[{bitrate:0,cdnMetadata:[{baseUrl:p}],id:o,mimeType:r,codecs:i,index:new h({media:m})}]},{isManuallyAdded:!0});if(s.representations.length>0&&!s.isSupported){var u=new a.Z("MANIFEST_INCOMPATIBLE_CODECS_ERROR","An Adaptation contains only incompatible codecs.");t.contentWarnings.push(u)}return s})))}),[]);if(n.length>0&&this.periods.length>0){var r=this.periods[0].adaptations;r.text=null!=r.text?r.text.concat(n):n}},n._performUpdate=function(e,t){if(this.availabilityStartTime=e.availabilityStartTime,this.expired=e.expired,this.isDynamic=e.isDynamic,this.isLive=e.isLive,this.isLastPeriodKnown=e.isLastPeriodKnown,this.lifetime=e.lifetime,this.contentWarnings=e.contentWarnings,this.suggestedPresentationDelay=e.suggestedPresentationDelay,this.transport=e.transport,this.publishTime=e.publishTime,t===r.Full)this._timeBounds=e._timeBounds,this.uris=e.uris,function(e,t){for(var n=0,i=0;ie.length)p.Z.error("Manifest: error when updating Periods");else{n0&&e.push.apply(e,c)}}(this.periods,e.periods);else{this._timeBounds.maximumTimeData=e._timeBounds.maximumTimeData,this.updateUrl=e.uris[0],function(e,t){if(0!==e.length){if(0!==t.length){var n=e[e.length-1];if(n.starto&&(e.splice(o,l-o),l=o),g(e[l],u,r.Full),o++}o0;){var i=this.periods[0];if(void 0===i.end||i.end>n)break;this.periods.shift()}}this.adaptations=void 0===this.periods[0]?{}:this.periods[0].adaptations,this.trigger("manifestUpdate",null)},t}(s.Z);var S=E},520:function(e,t,n){"use strict";n.d(t,{K:function(){return a},z:function(){return i}});var r=n(1946);function i(e,t){return e.segment.id===t.segment.id&&e.representation.id===t.representation.id&&e.adaptation.id===t.adaptation.id&&e.period.id===t.period.id}function a(e){if((0,r.Z)(e))return"";var t=e.period,n=e.adaptation,i=e.representation,a=e.segment;return n.type+" P: "+t.id+" A: "+n.id+" R: "+i.id+" S: "+(a.isInit?"init":a.complete?a.time+"-"+a.duration:""+a.time)}},2689:function(e,t,n){"use strict";n.d(t,{s:function(){return r}});var r=Math.pow(2,32)-1},2297:function(e,t,n){"use strict";n.d(t,{Qy:function(){return f},Xj:function(){return p},iz:function(){return d},lp:function(){return c},nR:function(){return v},t_:function(){return l},vA:function(){return u}});var r=n(3887),i=n(811),a=n(6968);function o(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return s(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return s(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);ni)return null;s=(0,a.pV)(e,r),r+=8}if(s<0)throw new Error("ISOBMFF: Size out of range");if(n===t)return 1970628964===t&&(r+=16),[o,r,o+s];o+=s}return null}function v(e,t,n,r,i){for(var o,s=e.length,u=0;us)return;o=(0,a.pV)(e,l),l+=8}if(1970628964===c&&l+16<=s&&(0,a.pX)(e,l)===t&&(0,a.pX)(e,l+4)===n&&(0,a.pX)(e,l+8)===r&&(0,a.pX)(e,l+12)===i)return l+=16,e.subarray(l,u+o)}}function p(e){var t=e.length;if(t<8)return r.Z.warn("ISOBMFF: box inferior to 8 bytes, cannot find offsets"),null;var n=0,i=(0,a.pX)(e,n);n+=4;var o=(0,a.pX)(e,n);if(n+=4,0===i)i=t;else if(1===i){if(n+8>t)return r.Z.warn("ISOBMFF: box too short, cannot find offsets"),null;i=(0,a.pV)(e,n),n+=8}if(i<0)throw new Error("ISOBMFF: Size out of range");return 1970628964===o&&(n+=16),[0,n,i]}},6807:function(e,t,n){"use strict";n.d(t,{E3:function(){return u},Le:function(){return o},XA:function(){return i},fs:function(){return s},uq:function(){return a}});var r=n(2297);function i(e){var t=(0,r.t_)(e,1836019558);return null===t?null:(0,r.t_)(t,1953653094)}function a(e){return(0,r.lp)(e,1836019558).reduce((function(e,t){var n=(0,r.t_)(t,1953653094);return null!==n&&e.push(n),e}),[])}function o(e){return(0,r.t_)(e,1835295092)}function s(e){var t=(0,r.t_)(e,1836019574);if(null===t)return null;var n=(0,r.t_)(t,1953653099);return null===n?null:(0,r.t_)(n,1835297121)}function u(e,t){return void 0===t&&(t=0),(0,r.t_)(e.subarray(t),1701671783)}},6490:function(e,t,n){"use strict";n.d(t,{Z:function(){return s},Y:function(){return u}});var r=n(3887);var i="function"==typeof Uint8Array.prototype.slice?function(e,t,n){return e.slice(t,n)}:function(e,t,n){return new Uint8Array(Array.prototype.slice.call(e,t,n))},a=n(3635),o=n(2297);function s(e){var t=0,n=(0,o.t_)(e,1836019574);if(null===n)return[];for(var a=[];t1)r.Z.warn("ISOBMFF: un-handled PSSH version");else{var n=t+4;if(!(n+16>e.length)){var o=i(e,n,n+16);return(0,a.ci)(o)}}}},4644:function(e,t,n){"use strict";n.d(t,{J6:function(){return m},LD:function(){return h},MM:function(){return p},Qx:function(){return f},R0:function(){return y},Wf:function(){return d},s9:function(){return g}});var r=n(3887),i=n(6968),a=n(3635),o=n(2689),s=n(2297),u=n(6807);function l(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return c(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return c(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0;){var v=(0,i.pX)(e,o);o+=4;var p=2147483647&v;if(1===(2147483648&v)>>>31)throw new Error("sidx with reference_type `1` not yet implemented");var h=(0,i.pX)(e,o);o+=4,o+=4,d.push({time:l,duration:h,timescale:c,range:[r,r+p-1]}),l+=h,r+=p}return d}function f(e){var t=(0,u.XA)(e);if(null!==t){var n=(0,s.t_)(t,1952867444);if(null!==n){var r=n[0];return 1===r?(0,i.pV)(n,4):0===r?(0,i.pX)(n,4):void 0}}}function v(e){var t=(0,s.t_)(e,1952868452);if(null!==t){var n=1,r=(0,i.QI)(t,n);if(n+=3,(8&r)>0)return n+=4,(1&r)>0&&(n+=8),(2&r)>0&&(n+=4),(0,i.pX)(t,n)}}function p(e){var t=(0,u.uq)(e);if(0!==t.length){for(var n,r=0,a=l(t);!(n=a()).done;){var o=n.value,c=(0,s.t_)(o,1953658222);if(null===c)return;var d=0,f=c[d];if(d+=1,f>1)return;var p=(0,i.QI)(c,d);d+=3;var h=(256&p)>0,m=0;if(!h&&void 0===(m=v(o)))return;var g=(1&p)>0,y=(4&p)>0,_=(512&p)>0,b=(1024&p)>0,T=(2048&p)>0,E=(0,i.pX)(c,d);d+=4,g&&(d+=4),y&&(d+=4);for(var S=E,w=0;S-- >0;)h?(w+=(0,i.pX)(c,d),d+=4):w+=m,_&&(d+=4),b&&(d+=4),T&&(d+=4);r+=w}return r}}function h(e){var t=(0,u.fs)(e);if(null!==t){var n=(0,s.t_)(t,1835296868);if(null!==n){var r=0,a=n[r];return r+=4,1===a?(0,i.pX)(n,r+16):0===a?(0,i.pX)(n,r+8):void 0}}}function m(e){var t=e.length;if(t<4)throw new Error("Cannot update box length: box too short");var n=(0,i.pX)(e,0);if(0===n){if(t>o.s){var r=new Uint8Array(t+8);return r.set((0,i.kh)(1),0),r.set(e.subarray(4,8),4),r.set((0,i.el)(t+8),8),r.set(e.subarray(8,t),16),r}return e.set((0,i.kh)(t),0),e}if(1===n){if(t<16)throw new Error("Cannot update box length: box too short");return e.set((0,i.el)(t),8),e}if(t<=o.s)return e.set((0,i.kh)(t),0),e;var a=new Uint8Array(t+8);return a.set((0,i.kh)(1),0),a.set(e.subarray(4,8),4),a.set((0,i.el)(t+8),8),a.set(e.subarray(8,t),16),a}function g(e){for(var t=[],n=0;n0)throw new Error("Unhandled version: "+s);var d=(0,r.dN)(e,t);t+=4;var f=(0,r.dN)(e,t);t+=4;var v=(0,i.uR)(e.subarray(t,t+4));t+=4;var p=(0,r.qb)(e,t);t+=2;var h=(0,r.qb)(e,t),m=[e[t+=2],e[t+1]].join(":"),g=1===e[t+=2];t=64;var y=[];if(0===d)throw new Error("bif: no images to parse");for(var _=0,b=null;t0,this._isEMSGWhitelisted=d}var t=e.prototype;return t.getInitSegment=function(){return(0,a.Z)(this._index,this._isEMSGWhitelisted)},t.getSegments=function(e,t){return(0,o.Z)(this._index,e,t,this._isEMSGWhitelisted,this._scaledPeriodEnd)},t.shouldRefresh=function(){return!1},t.getFirstAvailablePosition=function(){var e=this._index;return 0===e.timeline.length?null:(0,i.zG)(Math.max(this._scaledPeriodStart,e.timeline[0].start),e)},t.getLastAvailablePosition=function(){var e,t=this._index.timeline;if(0===t.length)return null;var n=t[t.length-1],r=Math.min((0,i.jH)(n,null,this._scaledPeriodEnd),null!==(e=this._scaledPeriodEnd)&&void 0!==e?e:1/0);return(0,i.zG)(r,this._index)},t.getEnd=function(){return this.getLastAvailablePosition()},t.awaitSegmentBetween=function(){return!1},t.isSegmentStillAvailable=function(){return!0},t.checkDiscontinuity=function(){return null},t.initializeIndex=function(e){for(var t=0;t0?Math.floor(u/s):0),A=T+k*b;A=c)return m;h+=S+1}return m}},4784:function(e,t,n){"use strict";n.d(t,{QB:function(){return o},zA:function(){return a}});var r=n(6923);function i(e){return function(t,n,i){var a,o,s,u=(0,r.Z)(i)?parseInt(i,10):1;return a=String(e),o=u,(s=a.toString()).length>=o?s:(new Array(o+1).join("0")+s).slice(-o)}}function a(e,t,n){return function(e,t,n){return-1===e.indexOf("$")?e:e.replace(/\$\$/g,"$").replace(/\$RepresentationID\$/g,String(t)).replace(/\$Bandwidth(\%0(\d+)d)?\$/g,i(void 0===n?0:n))}(e,t,n)}function o(e,t){return function(n){return-1===n.indexOf("$")?n:n.replace(/\$\$/g,"$").replace(/\$Number(\%0(\d+)d)?\$/g,(function(e,n,r){if(void 0===t)throw new Error("Segment number not defined in a $Number$ scheme");return i(t)(e,n,r)})).replace(/\$Time(\%0(\d+)d)?\$/g,(function(t,n,r){if(void 0===e)throw new Error("Segment time not defined in a $Time$ scheme");return i(e)(t,n,r)}))}}},4541:function(e,t,n){"use strict";n.d(t,{Z:function(){return We}});var r=n(7904),i=n(1946),a=n(6872),o=n(3887),s=n(3274),u=n(9829);function l(e){var t=Date.parse(e)-performance.now();if(!isNaN(t))return t;o.Z.warn("DASH Parser: Invalid clock received: ",e)}function c(e){for(var t=e.representations,n=null,r=0;r=0;t--){var n=e[t].adaptations,r=void 0===n.audio?void 0:n.audio[0],i=void 0===n.video?void 0:n.video[0];if(void 0!==r||void 0!==i){var a=null,s=null;if(void 0!==r){var u=c(r);if(void 0===u)return{safe:void 0,unsafe:void 0};a=u}if(void 0!==i){var l=c(i);if(void 0===l)return{safe:void 0,unsafe:void 0};s=l}if(void 0!==r&&null===a||void 0!==i&&null===s)return o.Z.info("Parser utils: found Period with no segment. ","Going to previous one to calculate last position"),{safe:void 0,unsafe:void 0};if(null!==s)return null!==a?{safe:Math.min(a,s),unsafe:Math.max(a,s)}:{safe:s,unsafe:s};if(null!==a)return{safe:a,unsafe:a}}}return{safe:void 0,unsafe:void 0}}(e);return{minimumSafePosition:t,maximumSafePosition:n.safe,maximumUnsafePosition:n.unsafe}}var v=n(9592),p=n(908),h=n(1679),m=n(3635);var g=function(){function e(e){this._isDynamic=e.isDynamic,this._timeShiftBufferDepth=e.isDynamic&&void 0!==e.timeShiftBufferDepth?e.timeShiftBufferDepth:null}var t=e.prototype;return t.setLastPosition=function(e,t){this._lastPosition=e,this._positionTime=t},t.lastPositionIsKnown=function(){return this._isDynamic?null!=this._positionTime&&null!=this._lastPosition:null!=this._lastPosition},t.estimateMinimumBound=function(){if(!this._isDynamic||null===this._timeShiftBufferDepth)return 0;var e=this.estimateMaximumBound();return void 0!==e?e-this._timeShiftBufferDepth:void 0},t.estimateMaximumBound=function(){return this._isDynamic&&null!=this._positionTime&&null!=this._lastPosition?Math.max(this._lastPosition-this._positionTime+performance.now()/1e3,0):this._lastPosition},e}(),y=n(8999),_=n(5138),b=n(7714),T=n(6923);function E(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return S(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return S(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function S(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0){var s=i-a.start;if(s%a.duration==0&&s/a.duration<=a.repeatCount)return{repeatNumberInPrevSegments:s/a.duration,prevSegmentsIdx:o,newElementsIdx:0,repeatNumberInNewElements:0}}if(++o>=e.length)return null;if((a=e[o]).start===i)return{prevSegmentsIdx:o,newElementsIdx:0,repeatNumberInPrevSegments:0,repeatNumberInNewElements:0};if(a.start>i)return null}else for(var u=0,l=t[0],c=i;;){var d=l.getAttribute("d"),f=null===d?null:parseInt(d,10);if(null===f||Number.isNaN(f))return null;var v=l.getAttribute("r"),p=null===v?null:parseInt(v,10);if(null!==p){if(Number.isNaN(p)||p<0)return null;if(p>0){var h=n-c;if(h%f==0&&h/f<=p)return{repeatNumberInPrevSegments:0,repeatNumberInNewElements:h/f,prevSegmentsIdx:0,newElementsIdx:u}}c+=f*(p+1)}else c+=f;if(++u>=t.length)return null;var m=(l=t[u]).getAttribute("t"),g=null===m?null:parseInt(m,10);if(null!==g){if(Number.isNaN(g))return null;c=g}if(c===n)return{newElementsIdx:u,prevSegmentsIdx:0,repeatNumberInPrevSegments:0,repeatNumberInNewElements:0};if(c>i)return null}}(t,e);if(null===r)return o.Z.warn('DASH: Cannot perform "based" update. Common segment not found.'),V(e);var i=r.prevSegmentsIdx,a=r.newElementsIdx,s=r.repeatNumberInPrevSegments,u=r.repeatNumberInNewElements,l=t.length-i+a-1;if(l>=e.length)return o.Z.info('DASH: Cannot perform "based" update. New timeline too short'),V(e);var c=t.slice(i);if(s>0){var d=c[0];d.start+=d.duration*s,c[0].repeatCount-=s}if(u>0&&0!==a)return o.Z.info('DASH: Cannot perform "based" update. The new timeline has a different form.'),V(e);var f=c[c.length-1],v=z(e[l]),p=(null!==(n=v.repeatCount)&&void 0!==n?n:0)-u;if(v.duration!==f.duration||f.repeatCount>p)return o.Z.info('DASH: Cannot perform "based" update. The new timeline has a different form at the beginning.'),V(e);void 0!==v.repeatCount&&v.repeatCount>f.repeatCount&&(f.repeatCount=v.repeatCount);for(var h=[],m=[],g=l+1;g0){var s=i[i.length-1];if((0,Z.jH)(s,null,this._scaledPeriodEnd)+a>=Math.min(o,null!==(n=this._scaledPeriodEnd)&&void 0!==n?n:1/0))return!1}return void 0===this._scaledPeriodEnd?o+a>this._scaledPeriodStart&&void 0:(0,Z.gT)(e,this._index)-athis._scaledPeriodStart},t.isSegmentStillAvailable=function(e){if(e.isInit)return!0;this._refreshTimeline(),null===this._index.timeline&&(this._index.timeline=this._getTimeline());var t=this._index,n=t.timeline,r=t.timescale,i=t.indexTimeOffset;return(0,O.Z)(e,n,r,i)},t.checkDiscontinuity=function(e){this._refreshTimeline();var t=this._index.timeline;return null===t&&(t=this._getTimeline(),this._index.timeline=t),(0,Z._j)({timeline:t,timescale:this._index.timescale,indexTimeOffset:this._index.indexTimeOffset},e,this._scaledPeriodEnd)},t.canBeOutOfSyncError=function(e){return!!this._isDynamic&&(e instanceof P.Z&&e.isHttpError(404))},t._replace=function(e){this._parseTimeline=e._parseTimeline,this._index=e._index,this._isDynamic=e._isDynamic,this._scaledPeriodStart=e._scaledPeriodStart,this._scaledPeriodEnd=e._scaledPeriodEnd,this._lastUpdate=e._lastUpdate,this._manifestBoundsCalculator=e._manifestBoundsCalculator,this._isLastPeriod=e._isLastPeriod},t._update=function(e){null===this._index.timeline&&(this._index.timeline=this._getTimeline()),null===e._index.timeline&&(e._index.timeline=e._getTimeline()),(0,L.Z)(this._index.timeline,e._index.timeline)&&(this._index.startNumber=e._index.startNumber),this._isDynamic=e._isDynamic,this._scaledPeriodStart=e._scaledPeriodStart,this._scaledPeriodEnd=e._scaledPeriodEnd,this._lastUpdate=e._lastUpdate,this._isLastPeriod=e._isLastPeriod},t.isFinished=function(){if(!this._isDynamic||!this._isLastPeriod)return!0;null===this._index.timeline&&(this._index.timeline=this._getTimeline());var e=this._index.timeline;if(void 0===this._scaledPeriodEnd||0===e.length)return!1;var t=e[e.length-1];return(0,Z.jH)(t,null,this._scaledPeriodEnd)+U(this._index.timescale)>=this._scaledPeriodEnd},t.isInitialized=function(){return!0},e.isTimelineIndexArgument=function(e){return"function"==typeof e.timelineParser||Array.isArray(e.timeline)},t._refreshTimeline=function(){if(null===this._index.timeline&&(this._index.timeline=this._getTimeline()),this._isDynamic){var e=this._manifestBoundsCalculator.estimateMinimumBound();if(null!=e){var t=(0,Z.gT)(e,this._index),n=(0,N.Z)(this._index.timeline,t);void 0!==this._index.startNumber&&(this._index.startNumber+=n)}}},e.getIndexEnd=function(e,t){return e.length<=0?null:Math.min((0,Z.jH)(e[e.length-1],null,t),null!=t?t:1/0)},t._getTimeline=function(){if(null===this._parseTimeline)return null!==this._index.timeline?this._index.timeline:(o.Z.error("DASH: Timeline already lazily parsed."),[]);var e=this._parseTimeline();this._parseTimeline=null;var t,n=a.Z.getCurrent().MIN_DASH_S_ELEMENTS_TO_PARSE_UNSAFELY;return null===this._unsafelyBaseOnPreviousIndex||e.lengthu?u-y:r,T=y+s,E=y+this._index.presentationTimeOffset,S=null===o?null:(0,M.QB)(E,_)(o),w={id:String(_),number:_,time:T/a,end:(T+b)/a,duration:b/a,timescale:1,isInit:!1,scaledDuration:b/a,url:S,timestampOffset:-n.indexTimeOffset/a,complete:!0,privateInfos:{isEMSGWhitelisted:this._isEMSGWhitelisted}};h.push(w),g++}return h},t.getFirstAvailablePosition=function(){var e=this._getFirstSegmentStart();return null==e?e:e/this._index.timescale+this._periodStart},t.getLastAvailablePosition=function(){var e,t=this._getLastSegmentStart();return null==t?t:Math.min(t+this._index.duration,null!==(e=this._scaledRelativePeriodEnd)&&void 0!==e?e:1/0)/this._index.timescale+this._periodStart},t.getEnd=function(){if(!this._isDynamic)return this.getLastAvailablePosition();if(void 0!==this._scaledRelativePeriodEnd){var e=this._index.timescale;return(this._scaledRelativePeriodEnd+this._periodStart*e)/this._index.timescale}},t.awaitSegmentBetween=function(e,t){if((0,D.Z)(e<=t),!this._isDynamic)return!1;var n=this._index.timescale,r=U(n),i=this._periodStart*n,a=t*n-i;return(void 0===this._scaledRelativePeriodEnd||e*n-i-r=0},t.shouldRefresh=function(){return!1},t.checkDiscontinuity=function(){return null},t.isSegmentStillAvailable=function(e){if(e.isInit)return!0;var t=this.getSegments(e.time,.1);return 0!==t.length&&(t[0].time===e.time&&t[0].end===e.end&&t[0].number===e.number)},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){if(!this._isDynamic)return!0;if(void 0===this._scaledRelativePeriodEnd)return!1;var e=this._index.timescale,t=this._getLastSegmentStart();return null!=t&&t+this._index.duration+U(e)>=this._scaledRelativePeriodEnd},t.isInitialized=function(){return!0},t._replace=function(e){this._index=e._index,this._aggressiveMode=e._aggressiveMode,this._isDynamic=e._isDynamic,this._periodStart=e._periodStart,this._scaledRelativePeriodEnd=e._scaledRelativePeriodEnd,this._manifestBoundsCalculator=e._manifestBoundsCalculator},t._update=function(e){this._replace(e)},t._getFirstSegmentStart=function(){if(!this._isDynamic)return 0;if(0===this._scaledRelativePeriodEnd||void 0===this._scaledRelativePeriodEnd){var e=this._manifestBoundsCalculator.estimateMaximumBound();if(void 0!==e&ðis._periodStart?(i-this._periodStart)*r:0;return Math.floor(a/n)*n}},t._getLastSegmentStart=function(){var e,t=this._index,n=t.duration,r=t.timescale;if(this._isDynamic){var i=this._manifestBoundsCalculator.estimateMaximumBound();if(void 0===i)return;var o=this._aggressiveMode?n/r:0;if(null!=this._scaledRelativePeriodEnd&&this._scaledRelativePeriodEnd<(i+o-this._periodStart)*this._index.timescale)return this._scaledRelativePeriodEnda.Z.getCurrent().MINIMUM_SEGMENT_SIZE*r||0===d?f:(d-1)*n},e}();function j(e,t){var n;if(0===t.length)return e;var r=t.map((function(e){return{url:e.value}}));if(0===e.length)return r;for(var i=[],a=0;a=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function Y(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0){var y=t.parentSegmentTemplates.slice(),_=e.children.segmentTemplate;void 0!==_&&y.push(_);var b=x.Z.apply(void 0,[{}].concat(y));h.availabilityTimeComplete=null!==(n=b.availabilityTimeComplete)&&void 0!==n?n:t.availabilityTimeComplete,h.availabilityTimeOffset=(null!==(r=b.availabilityTimeOffset)&&void 0!==r?r:0)+t.availabilityTimeOffset,i=H.isTimelineIndexArgument(b)?new H(b,h):new W(b,h)}else{var T=t.adaptation.children;if(void 0!==T.segmentBase){var E=T.segmentBase;i=new I.Z(E,h)}else if(void 0!==T.segmentList){var S=T.segmentList;i=new C(S,h)}else i=new W({duration:Number.MAX_VALUE,timescale:1,startNumber:0,media:""},h)}return i}(e,(0,x.Z)({},n,{availabilityTimeOffset:h,availabilityTimeComplete:p,unsafelyBaseOnPreviousRepresentation:f,adaptation:t,inbandEventStreams:v})),g=void 0;null==e.attributes.bitrate?(o.Z.warn("DASH: No usable bitrate found in the Representation."),g=0):g=e.attributes.bitrate;var y={bitrate:g,cdnMetadata:j(n.baseURLs,e.children.baseURLs).map((function(e){return{baseUrl:e.url,id:e.serviceLocation}})),index:m,id:d},_=void 0;null!=e.attributes.codecs?_=e.attributes.codecs:null!=t.attributes.codecs&&(_=t.attributes.codecs),null!=_&&(_="mp4a.40.02"===_?"mp4a.40.2":_,y.codecs=_),null!=e.attributes.frameRate?y.frameRate=e.attributes.frameRate:null!=t.attributes.frameRate&&(y.frameRate=t.attributes.frameRate),null!=e.attributes.height?y.height=e.attributes.height:null!=t.attributes.height&&(y.height=t.attributes.height),null!=e.attributes.mimeType?y.mimeType=e.attributes.mimeType:null!=t.attributes.mimeType&&(y.mimeType=t.attributes.mimeType),null!=e.attributes.width?y.width=e.attributes.width:null!=t.attributes.width&&(y.width=t.attributes.width);var b=void 0!==t.children.contentProtections?t.children.contentProtections:[];if(void 0!==e.children.contentProtections&&b.push.apply(b,e.children.contentProtections),b.length>0){var T=b.reduce((function(e,t){var n;if(void 0!==t.attributes.schemeIdUri&&"urn:uuid:"===t.attributes.schemeIdUri.substring(0,9)&&(n=t.attributes.schemeIdUri.substring(9).replace(/-/g,"").toLowerCase()),void 0!==t.attributes.keyId&&t.attributes.keyId.length>0){var r={keyId:t.attributes.keyId,systemId:n};void 0===e.keyIds?e.keyIds=[r]:e.keyIds.push(r)}if(void 0!==n){for(var i,a=[],o=q(t.children.cencPssh);!(i=o()).done;){var u=i.value;a.push({systemId:n,data:u})}if(a.length>0){var l,c=(0,s.Z)(e.initData,(function(e){return"cenc"===e.type}));if(void 0===c)e.initData.push({type:"cenc",values:a});else(l=c.values).push.apply(l,a)}}return e}),{keyIds:void 0,initData:[]});(Object.keys(T.initData).length>0||void 0!==T.keyIds&&T.keyIds.length>0)&&(y.contentProtections=T)}y.hdrInfo=X({adaptationProfiles:t.attributes.profiles,manifestProfiles:n.manifestProfiles,codecs:_}),c.push(y)},f=q(e);!(l=f()).done;)d();return c}function Q(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return J(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return J(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function J(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function se(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0&&f.video.length>m&&!G){var H,W=f.video[m][0];z.unsafelyBaseOnPreviousAdaptation=null!==(l=null===(u=t.unsafelyBaseOnPreviousPeriod)||void 0===u?void 0:u.getAdaptation(W.id))&&void 0!==l?l:null;var q=$(R,E,z);(H=W.representations).push.apply(H,q),B=W.id}else{var Y=S.accessibilities,X=void 0;void 0!==x&&x.some((function(e){return"dub"===e.value}))&&(X=!0);var J=void 0;"text"!==N?J=!1:void 0!==Y&&(J=Y.some(te));var oe=void 0;"audio"!==N?oe=!1:void 0!==Y&&(oe=Y.some(ee));var se=void 0;"video"!==N?se=!1:void 0!==Y&&(se=Y.some(ne));for(var ue=re(E,{isAudioDescription:oe,isClosedCaption:J,isSignInterpreted:se,isTrickModeTrack:G,type:N});(0,b.Z)(h,ue);)ue+="-dup";B=ue,h.push(ue),z.unsafelyBaseOnPreviousAdaptation=null!==(d=null===(c=t.unsafelyBaseOnPreviousPeriod)||void 0===c?void 0:c.getAdaptation(ue))&&void 0!==d?d:null;var le={id:ue,representations:$(R,E,z),type:N,isTrickModeTrack:G};if(null!=E.attributes.language&&(le.language=E.attributes.language),null!=J&&(le.closedCaption=J),null!=oe&&(le.audioDescription=oe),!0===X&&(le.isDub=!0),!0===se&&(le.isSignInterpreted=!0),void 0!==I&&(le.label=I),void 0!==K)v.push({adaptation:le,trickModeAttachedAdaptationIds:K});else{for(var ce,de=-1,fe=function(){var e=ce.value,t=p[e];if(void 0!==t&&t.newID!==B&&(0,b.Z)(t.adaptationSetSwitchingIDs,L)){de=(0,_.Z)(f[N],(function(t){return t[0].id===e}));var n,r=f[N][de];void 0!==r&&r[0].audioDescription===le.audioDescription&&r[0].closedCaption===le.closedCaption&&r[0].language===le.language&&(o.Z.info('DASH Parser: merging "switchable" AdaptationSets',L,e),(n=r[0].representations).push.apply(n,le.representations),"video"===N&&Z&&!r[1].isMainAdaptation&&(m=Math.max(m,de)),r[1]={priority:Math.max(O,r[1].priority),isMainAdaptation:Z||r[1].isMainAdaptation,indexInMpd:Math.min(g,r[1].indexInMpd)})}},ve=Q(U);!(ce=ve()).done;)fe();de<0&&(f[N].push([le,{priority:O,isMainAdaptation:Z,indexInMpd:g}]),"video"===N&&Z&&(m=f.video.length-1))}}null!=L&&null==p[L]&&(p[L]={newID:B,adaptationSetSwitchingIDs:U})}}var pe=y.r.reduce((function(e,t){var n=f[t];return n.length>0&&(n.sort(ae),e[t]=n.map((function(e){return e[0]}))),e}),{});return f.video.sort(ae),w(pe,v),pe}(k.children.adaptations,z),K=(null!==(u=t.xmlNamespaces)&&void 0!==u?u:[]).concat(null!==(l=k.attributes.namespaces)&&void 0!==l?l:[]),G=function(e,t,n){for(var r,i,a,o=[],s=oe(e);!(a=s()).done;)for(var u,l=a.value,c=l.attributes,d=c.schemeIdUri,f=void 0===d?"":d,v=c.timescale,p=void 0===v?1:v,h=n.concat(null!==(r=l.attributes.namespaces)&&void 0!==r?r:[]),g=oe(l.children.events);!(u=g()).done;){var y=u.value;if(void 0!==y.eventStreamData){var _=(null!==(i=y.presentationTime)&&void 0!==i?i:0)/p+t,b=void 0===y.duration?void 0:_+y.duration/p,T=void 0;if(y.eventStreamData instanceof Element)T=y.eventStreamData;else{var E=h.reduce((function(e,t){return e+"xmlns:"+t.key+'="'+t.value+'" '}),"";var S=(0,m.uR)(new Uint8Array(y.eventStreamData));T=(new DOMParser).parseFromString(E+S+" ","application/xml").documentElement.childNodes[0]}o.push({start:_,end:b,id:y.id,data:{type:"dash-event-stream",value:{schemeIdUri:f,timescale:p,element:T}}})}}return o}(k.children.eventStreams,R,K),H={id:P,start:R,end:C,duration:M,adaptations:V,streamEvents:G};if(c.unshift(H),!E.lastPositionIsKnown()){var W=function(e){for(var t,n=null,r=!0,i=(0,h.Z)(e).filter((function(e){return null!=e})),a=oe((0,v.Z)(i,(function(e){return e})));!(t=a()).done;)for(var o,s=oe(t.value.representations);!(o=s()).done;){var u=o.value.index.getLastAvailablePosition();null!==u&&(r=!1,"number"==typeof u&&(n=null==n?u:Math.max(n,u)))}if(null!=n)return n;if(r)return null;return}(V);if(f)if("number"==typeof W){var q=performance.now()/1e3;E.setLastPosition(W,q)}else{var Y=ce(t,R);if(void 0!==Y){var X=Y[0],J=Y[1];E.setLastPosition(X,J)}}else"number"==typeof W&&E.setLastPosition(W)}},k=e.length-1;k>=0;k--)S(k);if(t.isDynamic&&!E.lastPositionIsKnown()){var x=ce(t,0);if(void 0!==x){var I=x[0],Z=x[1];E.setLastPosition(I,Z)}}return function(e){if(0===e.length)return[];for(var t=[e[0]],n=1;nr.start)&&(o.Z.warn("DASH: Updating overlapping Periods.",null==i?void 0:i.start,r.start),i.duration=r.start-i.start,i.end=r.start,!(i.duration>0));)t.pop(),i=t[t.length-1];t.push(r)}return t}(c)}function ce(e,t){if(null!=e.clockOffset){var n=e.clockOffset/1e3-e.availabilityStartTime,r=performance.now()/1e3,i=r+n;if(i>=t)return[i,r]}else{var a=Date.now()/1e3;if(a>=t)return o.Z.warn("DASH Parser: no clock synchronization mechanism found. Using the system clock instead."),[a-e.availabilityStartTime,performance.now()/1e3]}}function de(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(n)return(n=n.call(e)).next.bind(n);if(Array.isArray(e)||(n=function(e,t){if(!e)return;if("string"==typeof e)return fe(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return fe(e,t)}(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var r=0;return function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function fe(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0?t[0].value:void 0}(t);if(null!=y&&y.length>0)return{type:"needs-clock",value:{url:y,continue:function(i){return i.success?(n.externalClockOffset=l(i.data),e(t,n,r,!0)):(r.push(i.error),o.Z.warn("DASH Parser: Error on fetching the clock ressource",i.error),e(t,n,r,!0))}}}}}for(var _=[],b=0;b=0&&(c=0===h.minimumUpdatePeriod?a.Z.getCurrent().DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0:h.minimumUpdatePeriod);var A=f(S),x=A.minimumSafePosition,I=A.maximumSafePosition,Z=A.maximumUnsafePosition,R=performance.now();if(m){var M,C;if(d=x,k=null!=_?_:null,void 0!==Z&&(C=Z),void 0!==I)M=I;else{var P=null!=y?y:0,D=t.externalClockOffset;if(void 0===D)o.Z.warn("DASH Parser: use system clock to define maximum position"),M=Date.now()/1e3-P;else M=(performance.now()+D)/1e3-P}void 0===C&&(C=M),v={isLinear:!0,maximumSafePosition:M,livePosition:C,time:R},null!==k&&void 0!==d&&M-d>k&&(k=M-d)}else{d=void 0!==x?x:void 0!==(null===(i=S[0])||void 0===i?void 0:i.start)?S[0].start:0;var N=null!=w?w:1/0;if(void 0!==S[S.length-1]){var O=S[S.length-1],L=null!==(s=O.end)&&void 0!==s?s:void 0!==O.duration?O.start+O.duration:void 0;void 0!==L&&L=0;o--){var s,u=_[o].index,l=a[o],f=l.parsed,v=l.warnings,p=l.receivedTime,h=l.sendingTime,m=l.url;v.length>0&&r.push.apply(r,v);for(var g,y=de(f);!(g=y()).done;){var b=g.value;c.set(b,{receivedTime:p,sendingTime:h,url:m})}(s=d.periods).splice.apply(s,[u,1].concat(f))}return e(t,n,r,i,c)}}}};function pe(e){var t=e.textContent,n=[];return null===t||0===t.length?[void 0,n]:[{value:t},n]}function he(e){for(var t={},n=0;n0){var s=Ze(a,"cenc:pssh"),u=s[0],l=s[1];null!==l&&(o.Z.warn(l.message),t.push(l)),null!==u&&n.push(u)}}}return[{cencPssh:n},t]}(e.childNodes),n=t[0],r=t[1];return[{children:n,attributes:function(e){for(var t={},n=0;n0&&(r=r.concat(d));break;case"SegmentList":var f=Le(a),v=f[0],p=f[1];r=r.concat(p),t.segmentList=v;break;case"SegmentTemplate":var h=Ue(a),m=h[0],g=h[1];r=r.concat(g),t.segmentTemplate=m;break;case"ContentProtection":var y=Pe(a),_=y[0],b=y[1];b.length>0&&(r=r.concat(b)),void 0!==_&&n.push(_)}}return n.length>0&&(t.contentProtections=n),[t,r]}(e.childNodes),n=t[0],r=t[1],i=function(e){for(var t={},n=[],r=Me(t,n),i=0;i0&&(r=r.concat(u));break;case"ContentComponent":t.contentComponent=he(a);break;case"EssentialProperty":null==t.essentialProperties?t.essentialProperties=[Re(a)]:t.essentialProperties.push(Re(a));break;case"InbandEventStream":void 0===t.inbandEventStreams&&(t.inbandEventStreams=[]),t.inbandEventStreams.push(Re(a));break;case"Label":var l=a.textContent;null!=l&&(t.label=l);break;case"Representation":var c=Fe(a),d=c[0],f=c[1];t.representations.push(d),f.length>0&&(r=r.concat(f));break;case"Role":null==t.roles?t.roles=[Re(a)]:t.roles.push(Re(a));break;case"SupplementalProperty":null==t.supplementalProperties?t.supplementalProperties=[Re(a)]:t.supplementalProperties.push(Re(a));break;case"SegmentBase":var v=Ne(a),p=v[0],h=v[1];t.segmentBase=p,h.length>0&&(r=r.concat(h));break;case"SegmentList":var m=Le(a),g=m[0],y=m[1];t.segmentList=g,y.length>0&&(r=r.concat(y));break;case"SegmentTemplate":var _=Ue(a),b=_[0],T=_[1];t.segmentTemplate=b,T.length>0&&(r=r.concat(T));break;case"ContentProtection":var E=Pe(a),S=E[0],w=E[1];w.length>0&&(r=r.concat(w)),void 0!==S&&n.push(S)}}return n.length>0&&(t.contentProtections=n),[t,r]}(e.childNodes),n=t[0],r=t[1],i=function(e){for(var t={},n=[],r=Me(t,n),i=0;i0&&(n=n.concat(c))}}return[t,n]}function Ke(e){for(var t={eventStreamData:e},n=[],r=Me(t,n),i=0;i0&&(i=i.concat(_))}}return[{baseURLs:n,adaptations:r,eventStreams:a,segmentTemplate:t},i]}(e.childNodes),n=t[0],r=t[1],i=function(e){for(var t={},n=[],r=Me(t,n),i=0;i",d=(new DOMParser).parseFromString(c,"text/xml");if(null==d||0===d.children.length)throw new Error("DASH parser: Invalid external ressources");for(var f=d.children[0].children,v=[],p=[],h=0;h0;){var r=e[0];if(r.start>=t)return n;if(-1===r.repeatCount)return n;if(0===r.repeatCount)e.shift(),n+=1;else{var i=e[1];if(void 0!==i&&i.start<=t)e.shift(),n+=1;else{if(r.duration<=0)return n;for(var a=r.start+r.duration,o=1;ar.repeatCount)){var s=r.repeatCount-o;return r.start=a,r.repeatCount=s,n+=o}e.shift(),n=r.repeatCount+1}}}return n}n.d(t,{Z:function(){return r}})},3911:function(e,t,n){"use strict";n.d(t,{KF:function(){return i},PZ:function(){return u},_j:function(){return l},gT:function(){return o},jH:function(){return a},zG:function(){return s}});var r=n(1946);function i(e,t,n){var i,a=e.repeatCount;return a>=0?a:(i=(0,r.Z)(t)?void 0!==n?n:Number.MAX_VALUE:t.start,Math.ceil((i-e.start)/e.duration)-1)}function a(e,t,n){var r=e.start,a=e.duration;return a<=0?r:r+(i(e,t,n)+1)*a}function o(e,t){var n;return e*t.timescale+(null!==(n=t.indexTimeOffset)&&void 0!==n?n:0)}function s(e,t){var n;return(e-(null!==(n=t.indexTimeOffset)&&void 0!==n?n:0))/t.timescale}function u(e,t,n){return[e*n,(e+t)*n]}function l(e,t,n){var r=e.timeline,i=o(t,e);if(i<0)return null;var u=function(e,t){for(var n=0,r=e.length;n>>1;e[i].start<=t?n=i+1:r=i}return n-1}(r,i);if(u<0||u>=r.length-1)return null;var l=r[u];if(l.duration<=0)return null;var c=r[u+1];if(void 0===c)return null;var d=c.start;return i>=a(l,c,n)&&ie.time)return!1;if(o===e.time)return void 0===a.range?void 0===e.range:null!=e.range&&a.range[0]===e.range[0]&&a.range[1]===e.range[1];if(a.repeatCount>=0&&void 0!==a.duration){var s=(o-a.start)/a.duration-1;return s%1==0&&s<=a.repeatCount}}return!1}n.d(t,{Z:function(){return r}})},5505:function(e,t,n){"use strict";n.d(t,{Z:function(){return o}});var r=n(3714),i=n(3887),a=n(3911);function o(e,t){if(0===e.length)return e.push.apply(e,t),!0;if(0===t.length)return!1;var n=e.length,o=t[0].start,s=e[n-1];if((0,a.jH)(s,t[0])=0;u--){var l=e[u].start;if(l===o){var c=n-u;return e.splice.apply(e,[u,c].concat(t)),!1}if(lo)return i.Z.warn("RepresentationIndex: Manifest update removed all previous segments"),e.splice.apply(e,[0,n].concat(t)),!0;if(void 0===d.repeatCount||d.repeatCount<=0)return d.repeatCount<0&&(d.repeatCount=Math.floor((o-d.start)/d.duration)-1),e.splice.apply(e,[u+1,n-(u+1)].concat(t)),!1;if(d.start+d.duration*(d.repeatCount+1)<=o)return e.splice.apply(e,[u+1,n-(u+1)].concat(t)),!1;var f=(o-d.start)/d.duration-1;if(f%1==0&&d.duration===t[0].duration){var v=t[0].repeatCount<0?-1:t[0].repeatCount+f+1;return e.splice.apply(e,[u,n-u].concat(t)),e[u].start=d.start,e[u].repeatCount=v,!1}return i.Z.warn("RepresentationIndex: Manifest update removed previous segments"),e[u].repeatCount=Math.floor(f),e.splice.apply(e,[u+1,n-(u+1)].concat(t)),!1}}var p=e[e.length-1],h=t[t.length-1];return void 0!==p.repeatCount&&p.repeatCount<0?p.start>h.start?(i.Z.warn("RepresentationIndex: The new index is older than the previous one"),!1):(i.Z.warn('RepresentationIndex: The new index is "bigger" than the previous one'),e.splice.apply(e,[0,n].concat(t)),!0):p.start+p.duration*(p.repeatCount+1)>=h.start+h.duration*(h.repeatCount+1)?(i.Z.warn("RepresentationIndex: The new index is older than the previous one"),!1):(i.Z.warn('RepresentationIndex: The new index is "bigger" than the previous one'),e.splice.apply(e,[0,n].concat(t)),!0)}},5734:function(e,t,n){"use strict";var r=n(6923),i=/([0-9]+);/g,a=/ /gi,o=/