From e28d49c2c52e30b26ca436a54987a077ffbc5133 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Thu, 4 Feb 2021 20:14:43 +0100 Subject: [PATCH 01/75] parsers: parse emsg boxes --- src/parsers/containers/isobmff/read.ts | 15 ++++++ src/parsers/containers/isobmff/utils.ts | 65 ++++++++++++++++++++++++- src/transports/dash/segment_parser.ts | 21 ++++++++ src/utils/string_parsing.ts | 27 ++++++++++ 4 files changed, 127 insertions(+), 1 deletion(-) diff --git a/src/parsers/containers/isobmff/read.ts b/src/parsers/containers/isobmff/read.ts index e32e0cec02..d93a62f107 100644 --- a/src/parsers/containers/isobmff/read.ts +++ b/src/parsers/containers/isobmff/read.ts @@ -60,8 +60,23 @@ function getMDIA(buf : Uint8Array) : Uint8Array|null { return getBoxContent(trak, 0x6D646961 /* "mdia" */); } +/** + * Returns EMSG Box from the while ISOBMFF File. + * Returns null if not found. + * @param {Uint8Array} buffer + * @returns {Uint8Array|null} + */ +function getEMSG(buffer: Uint8Array, offset = 0) : Uint8Array|null { + const emsg = getBoxContent(buffer.subarray(offset), 0x656D7367 /* emsg */); + if (emsg === null) { + return null; + } + return emsg; +} + export { getTRAF, getMDAT, getMDIA, + getEMSG, }; diff --git a/src/parsers/containers/isobmff/utils.ts b/src/parsers/containers/isobmff/utils.ts index 4dbba262f2..ea2e25d13e 100644 --- a/src/parsers/containers/isobmff/utils.ts +++ b/src/parsers/containers/isobmff/utils.ts @@ -24,7 +24,10 @@ import { itobe4, itobe8, } from "../../../utils/byte_parsing"; -import { hexToBytes } from "../../../utils/string_parsing"; +import { + hexToBytes, + readTerminatedString, +} from "../../../utils/string_parsing"; import { MAX_32_BIT_INT } from "./constants"; import { createBox } from "./create_box"; import { getPlayReadyKIDFromPrivateData } from "./drm"; @@ -33,6 +36,7 @@ import { getBoxOffsets, } from "./get_box"; import { + getEMSG, getMDIA, getTRAF, } from "./read"; @@ -45,6 +49,14 @@ export interface IISOBMFFPSSHInfo { privateData : Uint8Array; } +export interface IEMSG { schemeId: string; + value: string; + timescale: number; + presentationTimeDelta: number; + eventDuration: number; + id: number; + messageData: Uint8Array; } + /** Segment information from a parsed sidx. */ export interface ISidxSegment { /** This segment start time, timescaled. */ @@ -409,6 +421,56 @@ function updateBoxLength(buf : Uint8Array) : Uint8Array { } } +/** + * Parse EMSG boxes from ISOBMFF data. + * @param {Uint8Array} buf + * @returns {Array.} + */ +function parseEmsgBoxes(buffer: Uint8Array) : IEMSG[] { + const emsgs: IEMSG[] = []; + let offset = 0; + while (offset < buffer.length) { + const emsg = getEMSG(buffer, offset); + if (emsg === null) { + return emsgs; + } + const length = emsg.length; + offset += length; + + let position = 4; // skip version + flags + + const { end: schemeIdEnd, string: schemeId } = readTerminatedString(emsg, position); + position = schemeIdEnd; // skip schemeId + + const { end: valueEnd, string: value } = readTerminatedString(emsg, position); + position = valueEnd; // skip value + + const timescale = be4toi(emsg, position); + position += 4; // skip timescale + + const presentationTimeDelta = be4toi(emsg, position); + position += 4; // skip presentationTimeDelta + + const eventDuration = be4toi(emsg, position); + position += 4; // skip eventDuration + + const id = be4toi(emsg, position); + position += 4; // skip id + + const messageData = emsg.subarray(position, length); + + const emsgData = { schemeId, + value, + timescale, + presentationTimeDelta, + eventDuration, + id, + messageData }; + emsgs.push(emsgData); + } + return emsgs; +} + export { getMDHDTimescale, getPlayReadyKIDFromPrivateData, @@ -417,4 +479,5 @@ export { getSegmentsFromSidx, patchPssh, updateBoxLength, + parseEmsgBoxes, }; diff --git a/src/transports/dash/segment_parser.ts b/src/transports/dash/segment_parser.ts index 3fb5ee211c..f07ff8781a 100644 --- a/src/transports/dash/segment_parser.ts +++ b/src/transports/dash/segment_parser.ts @@ -15,11 +15,13 @@ */ import { of as observableOf } from "rxjs"; +import log from "../../log"; import { getMDHDTimescale, getSegmentsFromSidx, takePSSHOut, } from "../../parsers/containers/isobmff"; +import { parseEmsgBoxes } from "../../parsers/containers/isobmff/utils"; import { getSegmentsFromCues, getTimeCodeScale, @@ -72,6 +74,25 @@ export default function generateAudioVideoSegmentParser( new Uint8Array(data); const isWEBM = isWEBMEmbeddedTrack(representation); + if (!isWEBM) { + const emsgs = parseEmsgBoxes(chunkData); + if (emsgs.length > 0) { + const streamEvents = emsgs.map((emsg) => { + const start = (emsg.presentationTimeDelta / emsg.timescale) + + segment.time / segment.timescale; + const duration = emsg.eventDuration / emsg.timescale; + const end = start + duration; + const id = emsg.id.toString(); + const streamEvent = { start, + end, + id, + data: { type: "isobmff-emsg" as const, + value: emsg } }; + return streamEvent; + }); + log.info("DASH Pipelines : Encountered stream events", segment, streamEvents); + } + } if (!segment.isInit) { const chunkInfos = isWEBM ? null : // TODO extract time info from webm getISOBMFFTimingInfos(chunkData, diff --git a/src/utils/string_parsing.ts b/src/utils/string_parsing.ts index 5b64d9d464..cbb8f36690 100644 --- a/src/utils/string_parsing.ts +++ b/src/utils/string_parsing.ts @@ -366,6 +366,31 @@ function guidToUuid(guid : Uint8Array) : Uint8Array { return uuid; } +/** + * Decode string from bytes (UTF-8). + * Keeps reading until it reaches a byte that equals to zero. + * @param {Uint8Array} buffer + * @param {number} offset + * @returns {Object} + */ +function readTerminatedString(buffer: Uint8Array, offset: number): { + end: number; + string: string; +} { + let position = offset; + while (position < buffer.length) { + const value = buffer[position]; + if (value === 0) { + break; + } + position += 1; + } + + const bytes = buffer.subarray(offset, position); + return { end: position + 1, + string: utf8ToStr(bytes) }; +} + export { bytesToHex, hexToBytes, @@ -380,4 +405,6 @@ export { beUtf16ToStr, guidToUuid, + + readTerminatedString, }; From d7cf90edc623b5f0eea6715861058696a15ab024 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Thu, 11 Feb 2021 16:54:51 +0100 Subject: [PATCH 02/75] api: emit event messages through an event --- src/core/api/public_api.ts | 10 ++++++++ src/core/init/types.ts | 7 ++++-- .../representation/representation_stream.ts | 14 +++++++++++ src/core/stream/types.ts | 21 ++++++++++++---- src/parsers/containers/isobmff/index.ts | 1 + src/parsers/containers/isobmff/utils.ts | 21 +++++++++------- src/transports/dash/segment_parser.ts | 24 +++---------------- src/transports/types.ts | 2 ++ 8 files changed, 63 insertions(+), 37 deletions(-) diff --git a/src/core/api/public_api.ts b/src/core/api/public_api.ts index 9f450462f2..8e0f8bea30 100644 --- a/src/core/api/public_api.ts +++ b/src/core/api/public_api.ts @@ -73,6 +73,7 @@ import Manifest, { Period, Representation, } from "../../manifest"; +import { IEventMessage } from "../../parsers/containers/isobmff"; import { IBifThumbnail } from "../../parsers/images/bif"; import areArraysOfNumbersEqual from "../../utils/are_arrays_of_numbers_equal"; import EventEmitter, { @@ -219,6 +220,7 @@ interface IPublicAPIEvent { seeked : null; streamEvent : IStreamEvent; streamEventSkip : IStreamEvent; + eventMessage : IEventMessage; } /** @@ -2268,6 +2270,14 @@ class Player extends EventEmitter { */ private _priv_onPlaybackEvent(event : IInitEvent) : void { switch (event.type) { + case "event-messages": + const eventMessages = event.value; + const emsgsNbr = eventMessages.length; + for (let i = 0; i < emsgsNbr; i++) { + const eventMessage = eventMessages[i]; + this.trigger("eventMessage", eventMessage); + } + return; case "stream-event": this.trigger("streamEvent", event.value); break; diff --git a/src/core/init/types.ts b/src/core/init/types.ts index bc7e0cced4..b555e2ee77 100644 --- a/src/core/init/types.ts +++ b/src/core/init/types.ts @@ -38,6 +38,7 @@ import { IAdaptationChangeEvent, IBitrateEstimationChangeEvent, ICompletedStreamEvent, + IEventMessagesEvent, INeedsDecipherabilityFlush, INeedsMediaSourceReload, IPeriodStreamClearedEvent, @@ -149,7 +150,8 @@ export type IMediaSourceLoaderEvent = IStalledEvent | IStreamEventAddedSegment | IProtectedSegmentEvent | IStreamManifestMightBeOutOfSync | - IStreamNeedsManifestRefresh; + IStreamNeedsManifestRefresh | + IEventMessagesEvent; /** Every events emitted by the `Init` module. */ export type IInitEvent = IManifestReadyEvent | @@ -188,7 +190,8 @@ export type IInitEvent = IManifestReadyEvent | IAdaptationChangeEvent | IBitrateEstimationChangeEvent | IRepresentationChangeEvent | - IStreamEventAddedSegment; + IStreamEventAddedSegment | + IEventMessagesEvent; /** Events emitted by the `Init` module for directfile contents. */ export type IDirectfileEvent = IStalledEvent | diff --git a/src/core/stream/representation/representation_stream.ts b/src/core/stream/representation/representation_stream.ts index 630d273fed..e084e8d7f3 100644 --- a/src/core/stream/representation/representation_stream.ts +++ b/src/core/stream/representation/representation_stream.ts @@ -32,6 +32,7 @@ import { merge as observableMerge, Observable, of as observableOf, + of, ReplaySubject, Subject, } from "rxjs"; @@ -79,6 +80,7 @@ import { IStreamManifestMightBeOutOfSync, IStreamNeedsManifestRefresh, IStreamTerminatingEvent, + IEventMessagesEvent, } from "../types"; import getBufferStatus from "./get_buffer_status"; import getSegmentPriority from "./get_segment_priority"; @@ -449,6 +451,7 @@ export default function RepresentationStream({ ) : Observable | ISegmentFetcherWarning | IProtectedSegmentEvent | + IEventMessagesEvent | IStreamManifestMightBeOutOfSync> { switch (evt.type) { @@ -481,6 +484,17 @@ export default function RepresentationStream({ case "parsed-segment": const initSegmentData = initSegmentObject?.initializationData ?? null; + if (evt.value.emsgs !== undefined) { + const emsgsEvent$ = of({ type: "event-messages" as const, + value: evt.value.emsgs }); + return observableConcat(emsgsEvent$, + pushMediaSegment({ clock$, + content, + initSegmentData, + parsedSegment: evt.value, + segment: evt.segment, + segmentBuffer })); + } return pushMediaSegment({ clock$, content, initSegmentData, diff --git a/src/core/stream/types.ts b/src/core/stream/types.ts index 216c89ffee..5676a5aecf 100644 --- a/src/core/stream/types.ts +++ b/src/core/stream/types.ts @@ -22,6 +22,7 @@ import { Period, Representation, } from "../../manifest"; +import { IEventMessage } from "../../parsers/containers/isobmff"; import { IBufferType } from "../segment_buffers"; /** Information about a Segment waiting to be loaded by the Stream. */ @@ -168,6 +169,11 @@ export interface IProtectedSegmentEvent { value : ISegmentProtection; } +export interface IEventMessagesEvent { + type : "event-messages"; + value : IEventMessage[]; +} + /** * Event sent when a `RepresentationStream` is terminating: * @@ -399,7 +405,8 @@ export type IRepresentationStreamEvent = IStreamStatusEvent | IStreamManifestMightBeOutOfSync | IStreamTerminatingEvent | IStreamNeedsManifestRefresh | - IStreamWarningEvent; + IStreamWarningEvent | + IEventMessagesEvent; /** Event sent by an `AdaptationStream`. */ export type IAdaptationStreamEvent = IBitrateEstimationChangeEvent | @@ -414,7 +421,8 @@ export type IAdaptationStreamEvent = IBitrateEstimationChangeEvent | IProtectedSegmentEvent | IStreamManifestMightBeOutOfSync | IStreamNeedsManifestRefresh | - IStreamWarningEvent; + IStreamWarningEvent | + IEventMessagesEvent; /** Event sent by a `PeriodStream`. */ export type IPeriodStreamEvent = IPeriodStreamReadyEvent | @@ -435,7 +443,8 @@ export type IPeriodStreamEvent = IPeriodStreamReadyEvent | IProtectedSegmentEvent | IStreamManifestMightBeOutOfSync | IStreamNeedsManifestRefresh | - IStreamWarningEvent; + IStreamWarningEvent | + IEventMessagesEvent; /** Event coming from function(s) managing multiple PeriodStreams. */ export type IMultiplePeriodStreamsEvent = IPeriodStreamClearedEvent | @@ -461,7 +470,8 @@ export type IMultiplePeriodStreamsEvent = IPeriodStreamClearedEvent | IProtectedSegmentEvent | IStreamManifestMightBeOutOfSync | IStreamNeedsManifestRefresh | - IStreamWarningEvent; + IStreamWarningEvent | + IEventMessagesEvent; /** Every event sent by the `StreamOrchestrator`. */ export type IStreamOrchestratorEvent = IActivePeriodChangedEvent | @@ -490,4 +500,5 @@ export type IStreamOrchestratorEvent = IActivePeriodChangedEvent | IProtectedSegmentEvent | IStreamManifestMightBeOutOfSync | IStreamNeedsManifestRefresh | - IStreamWarningEvent; + IStreamWarningEvent | + IEventMessagesEvent; diff --git a/src/parsers/containers/isobmff/index.ts b/src/parsers/containers/isobmff/index.ts index 0acaeb9f5e..01cba402d3 100644 --- a/src/parsers/containers/isobmff/index.ts +++ b/src/parsers/containers/isobmff/index.ts @@ -38,6 +38,7 @@ export { getTrackFragmentDecodeTime, getDurationFromTrun, getSegmentsFromSidx, + IEventMessage, ISidxSegment, patchPssh, updateBoxLength, diff --git a/src/parsers/containers/isobmff/utils.ts b/src/parsers/containers/isobmff/utils.ts index ea2e25d13e..2a3e16ab24 100644 --- a/src/parsers/containers/isobmff/utils.ts +++ b/src/parsers/containers/isobmff/utils.ts @@ -49,13 +49,13 @@ export interface IISOBMFFPSSHInfo { privateData : Uint8Array; } -export interface IEMSG { schemeId: string; - value: string; - timescale: number; - presentationTimeDelta: number; - eventDuration: number; - id: number; - messageData: Uint8Array; } +export interface IEventMessage { schemeId: string; + value: string; + timescale: number; + presentationTimeDelta: number; + eventDuration: number; + id: number; + messageData: Uint8Array; } /** Segment information from a parsed sidx. */ export interface ISidxSegment { @@ -426,8 +426,8 @@ function updateBoxLength(buf : Uint8Array) : Uint8Array { * @param {Uint8Array} buf * @returns {Array.} */ -function parseEmsgBoxes(buffer: Uint8Array) : IEMSG[] { - const emsgs: IEMSG[] = []; +function parseEmsgBoxes(buffer: Uint8Array) : IEventMessage[] | undefined { + const emsgs: IEventMessage[] = []; let offset = 0; while (offset < buffer.length) { const emsg = getEMSG(buffer, offset); @@ -468,6 +468,9 @@ function parseEmsgBoxes(buffer: Uint8Array) : IEMSG[] { messageData }; emsgs.push(emsgData); } + if (emsgs.length === 0) { + return undefined; + } return emsgs; } diff --git a/src/transports/dash/segment_parser.ts b/src/transports/dash/segment_parser.ts index f07ff8781a..694be50897 100644 --- a/src/transports/dash/segment_parser.ts +++ b/src/transports/dash/segment_parser.ts @@ -15,7 +15,6 @@ */ import { of as observableOf } from "rxjs"; -import log from "../../log"; import { getMDHDTimescale, getSegmentsFromSidx, @@ -74,25 +73,6 @@ export default function generateAudioVideoSegmentParser( new Uint8Array(data); const isWEBM = isWEBMEmbeddedTrack(representation); - if (!isWEBM) { - const emsgs = parseEmsgBoxes(chunkData); - if (emsgs.length > 0) { - const streamEvents = emsgs.map((emsg) => { - const start = (emsg.presentationTimeDelta / emsg.timescale) + - segment.time / segment.timescale; - const duration = emsg.eventDuration / emsg.timescale; - const end = start + duration; - const id = emsg.id.toString(); - const streamEvent = { start, - end, - id, - data: { type: "isobmff-emsg" as const, - value: emsg } }; - return streamEvent; - }); - log.info("DASH Pipelines : Encountered stream events", segment, streamEvents); - } - } if (!segment.isInit) { const chunkInfos = isWEBM ? null : // TODO extract time info from webm getISOBMFFTimingInfos(chunkData, @@ -100,11 +80,13 @@ export default function generateAudioVideoSegmentParser( segment, initTimescale); const chunkOffset = takeFirstSet(segment.timestampOffset, 0); + const emsgs = isWEBM ? undefined : parseEmsgBoxes(chunkData); return observableOf({ type: "parsed-segment", value: { chunkData, chunkInfos, chunkOffset, - appendWindow } }); + appendWindow, + emsgs } }); } // we're handling an initialization segment const { indexRange } = segment; diff --git a/src/transports/types.ts b/src/transports/types.ts index 762bd49373..b136b0a67d 100644 --- a/src/transports/types.ts +++ b/src/transports/types.ts @@ -26,6 +26,7 @@ import Manifest, { Period, Representation, } from "../manifest"; +import { IEventMessage } from "../parsers/containers/isobmff"; import { IBifThumbnail } from "../parsers/images/bif"; import { ILocalManifest } from "../parsers/manifest/local"; import { IMetaPlaylist } from "../parsers/manifest/metaplaylist"; @@ -371,6 +372,7 @@ export interface ISegmentParserParsedSegment { number | undefined ]; // end window for the segment // (part of the segment after that time // will be ignored) + emsgs? : IEventMessage[]; } // What a segment parser returns when parsing an init segment From 34f8267827934188234f6d7637d8931de53afe02 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Thu, 11 Feb 2021 17:08:48 +0100 Subject: [PATCH 03/75] stream: support emsg manifest updates --- .../representation/representation_stream.ts | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/core/stream/representation/representation_stream.ts b/src/core/stream/representation/representation_stream.ts index e084e8d7f3..2f4989ab22 100644 --- a/src/core/stream/representation/representation_stream.ts +++ b/src/core/stream/representation/representation_stream.ts @@ -32,7 +32,6 @@ import { merge as observableMerge, Observable, of as observableOf, - of, ReplaySubject, Subject, } from "rxjs"; @@ -56,6 +55,7 @@ import Manifest, { Period, Representation, } from "../../../manifest"; +import { IEventMessage } from "../../../parsers/containers/isobmff"; import { ISegmentParserInitSegment, ISegmentParserParsedInitSegment, @@ -452,6 +452,7 @@ export default function RepresentationStream({ ISegmentFetcherWarning | IProtectedSegmentEvent | IEventMessagesEvent | + IStreamNeedsManifestRefresh | IStreamManifestMightBeOutOfSync> { switch (evt.type) { @@ -485,9 +486,26 @@ export default function RepresentationStream({ case "parsed-segment": const initSegmentData = initSegmentObject?.initializationData ?? null; if (evt.value.emsgs !== undefined) { - const emsgsEvent$ = of({ type: "event-messages" as const, - value: evt.value.emsgs }); - return observableConcat(emsgsEvent$, + const { needsManifestRefresh, nonInterpretedMessages } = evt.value.emsgs + .reduce((acc, val: IEventMessage) => { + // Scheme that signals manifest update + if (val.schemeId === "urn:mpeg:dash:event:2012") { + acc.needsManifestRefresh = true; + } else { + acc.nonInterpretedMessages.push(val); + } + return acc; + }, { needsManifestRefresh: false, + nonInterpretedMessages: [] as IEventMessage[] }); + const manifestRefresh$ = needsManifestRefresh ? + observableOf(EVENTS.needsManifestRefresh()) : + EMPTY; + const emsgsEvent$ = nonInterpretedMessages.length > 0 ? + observableOf({ type: "event-messages" as const, + value: nonInterpretedMessages }) : + EMPTY; + return observableConcat(manifestRefresh$, + emsgsEvent$, pushMediaSegment({ clock$, content, initSegmentData, From c8d6912eb38918b4f15c7d7ecf0e079e8202f8e3 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Fri, 12 Feb 2021 17:40:54 +0100 Subject: [PATCH 04/75] utils: renamed readNullTerminatedString into readTerminatedString --- src/parsers/containers/isobmff/utils.ts | 7 ++++--- src/utils/string_parsing.ts | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/parsers/containers/isobmff/utils.ts b/src/parsers/containers/isobmff/utils.ts index 2a3e16ab24..c80f78175b 100644 --- a/src/parsers/containers/isobmff/utils.ts +++ b/src/parsers/containers/isobmff/utils.ts @@ -26,7 +26,7 @@ import { } from "../../../utils/byte_parsing"; import { hexToBytes, - readTerminatedString, + readNullTerminatedString, } from "../../../utils/string_parsing"; import { MAX_32_BIT_INT } from "./constants"; import { createBox } from "./create_box"; @@ -439,10 +439,11 @@ function parseEmsgBoxes(buffer: Uint8Array) : IEventMessage[] | undefined { let position = 4; // skip version + flags - const { end: schemeIdEnd, string: schemeId } = readTerminatedString(emsg, position); + const { end: schemeIdEnd, string: schemeId } = + readNullTerminatedString(emsg, position); position = schemeIdEnd; // skip schemeId - const { end: valueEnd, string: value } = readTerminatedString(emsg, position); + const { end: valueEnd, string: value } = readNullTerminatedString(emsg, position); position = valueEnd; // skip value const timescale = be4toi(emsg, position); diff --git a/src/utils/string_parsing.ts b/src/utils/string_parsing.ts index cbb8f36690..8c9eeb9daa 100644 --- a/src/utils/string_parsing.ts +++ b/src/utils/string_parsing.ts @@ -373,7 +373,7 @@ function guidToUuid(guid : Uint8Array) : Uint8Array { * @param {number} offset * @returns {Object} */ -function readTerminatedString(buffer: Uint8Array, offset: number): { +function readNullTerminatedString(buffer: Uint8Array, offset: number): { end: number; string: string; } { @@ -406,5 +406,5 @@ export { guidToUuid, - readTerminatedString, + readNullTerminatedString, }; From f57ac4b0b2e8aa8a63f0a5c2e972e150f0003428 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Fri, 12 Feb 2021 17:49:37 +0100 Subject: [PATCH 05/75] misc: renamed eventmessage into inbandevent --- src/core/api/public_api.ts | 16 ++++++++-------- src/core/init/types.ts | 6 +++--- .../representation/representation_stream.ts | 16 ++++++++-------- src/core/stream/types.ts | 18 +++++++++--------- src/parsers/containers/isobmff/index.ts | 2 +- src/parsers/containers/isobmff/utils.ts | 6 +++--- src/transports/dash/segment_parser.ts | 4 ++-- src/transports/types.ts | 4 ++-- 8 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/core/api/public_api.ts b/src/core/api/public_api.ts index 8e0f8bea30..0c1891e5c9 100644 --- a/src/core/api/public_api.ts +++ b/src/core/api/public_api.ts @@ -73,7 +73,7 @@ import Manifest, { Period, Representation, } from "../../manifest"; -import { IEventMessage } from "../../parsers/containers/isobmff"; +import { IInbandEvent } from "../../parsers/containers/isobmff"; import { IBifThumbnail } from "../../parsers/images/bif"; import areArraysOfNumbersEqual from "../../utils/are_arrays_of_numbers_equal"; import EventEmitter, { @@ -220,7 +220,7 @@ interface IPublicAPIEvent { seeked : null; streamEvent : IStreamEvent; streamEventSkip : IStreamEvent; - eventMessage : IEventMessage; + inbandEvent : IInbandEvent; } /** @@ -2270,12 +2270,12 @@ class Player extends EventEmitter { */ private _priv_onPlaybackEvent(event : IInitEvent) : void { switch (event.type) { - case "event-messages": - const eventMessages = event.value; - const emsgsNbr = eventMessages.length; - for (let i = 0; i < emsgsNbr; i++) { - const eventMessage = eventMessages[i]; - this.trigger("eventMessage", eventMessage); + case "inband-events": + const inbandEvents = event.value; + const eventNbr = inbandEvents.length; + for (let i = 0; i < eventNbr; i++) { + const inbandEvent = inbandEvents[i]; + this.trigger("inbandEvent", inbandEvent); } return; case "stream-event": diff --git a/src/core/init/types.ts b/src/core/init/types.ts index b555e2ee77..b93d05dafb 100644 --- a/src/core/init/types.ts +++ b/src/core/init/types.ts @@ -38,7 +38,7 @@ import { IAdaptationChangeEvent, IBitrateEstimationChangeEvent, ICompletedStreamEvent, - IEventMessagesEvent, + IInbandEventsEvent, INeedsDecipherabilityFlush, INeedsMediaSourceReload, IPeriodStreamClearedEvent, @@ -151,7 +151,7 @@ export type IMediaSourceLoaderEvent = IStalledEvent | IProtectedSegmentEvent | IStreamManifestMightBeOutOfSync | IStreamNeedsManifestRefresh | - IEventMessagesEvent; + IInbandEventsEvent; /** Every events emitted by the `Init` module. */ export type IInitEvent = IManifestReadyEvent | @@ -191,7 +191,7 @@ export type IInitEvent = IManifestReadyEvent | IBitrateEstimationChangeEvent | IRepresentationChangeEvent | IStreamEventAddedSegment | - IEventMessagesEvent; + IInbandEventsEvent; /** Events emitted by the `Init` module for directfile contents. */ export type IDirectfileEvent = IStalledEvent | diff --git a/src/core/stream/representation/representation_stream.ts b/src/core/stream/representation/representation_stream.ts index 2f4989ab22..2b1118f195 100644 --- a/src/core/stream/representation/representation_stream.ts +++ b/src/core/stream/representation/representation_stream.ts @@ -55,7 +55,7 @@ import Manifest, { Period, Representation, } from "../../../manifest"; -import { IEventMessage } from "../../../parsers/containers/isobmff"; +import { IInbandEvent } from "../../../parsers/containers/isobmff"; import { ISegmentParserInitSegment, ISegmentParserParsedInitSegment, @@ -80,7 +80,7 @@ import { IStreamManifestMightBeOutOfSync, IStreamNeedsManifestRefresh, IStreamTerminatingEvent, - IEventMessagesEvent, + IInbandEventsEvent, } from "../types"; import getBufferStatus from "./get_buffer_status"; import getSegmentPriority from "./get_segment_priority"; @@ -451,7 +451,7 @@ export default function RepresentationStream({ ) : Observable | ISegmentFetcherWarning | IProtectedSegmentEvent | - IEventMessagesEvent | + IInbandEventsEvent | IStreamNeedsManifestRefresh | IStreamManifestMightBeOutOfSync> { @@ -487,7 +487,7 @@ export default function RepresentationStream({ const initSegmentData = initSegmentObject?.initializationData ?? null; if (evt.value.emsgs !== undefined) { const { needsManifestRefresh, nonInterpretedMessages } = evt.value.emsgs - .reduce((acc, val: IEventMessage) => { + .reduce((acc, val: IInbandEvent) => { // Scheme that signals manifest update if (val.schemeId === "urn:mpeg:dash:event:2012") { acc.needsManifestRefresh = true; @@ -496,16 +496,16 @@ export default function RepresentationStream({ } return acc; }, { needsManifestRefresh: false, - nonInterpretedMessages: [] as IEventMessage[] }); + nonInterpretedMessages: [] as IInbandEvent[] }); const manifestRefresh$ = needsManifestRefresh ? observableOf(EVENTS.needsManifestRefresh()) : EMPTY; - const emsgsEvent$ = nonInterpretedMessages.length > 0 ? - observableOf({ type: "event-messages" as const, + const inbandEvents$ = nonInterpretedMessages.length > 0 ? + observableOf({ type: "inband-events" as const, value: nonInterpretedMessages }) : EMPTY; return observableConcat(manifestRefresh$, - emsgsEvent$, + inbandEvents$, pushMediaSegment({ clock$, content, initSegmentData, diff --git a/src/core/stream/types.ts b/src/core/stream/types.ts index 5676a5aecf..4711e5d813 100644 --- a/src/core/stream/types.ts +++ b/src/core/stream/types.ts @@ -22,7 +22,7 @@ import { Period, Representation, } from "../../manifest"; -import { IEventMessage } from "../../parsers/containers/isobmff"; +import { IInbandEvent } from "../../parsers/containers/isobmff"; import { IBufferType } from "../segment_buffers"; /** Information about a Segment waiting to be loaded by the Stream. */ @@ -169,9 +169,9 @@ export interface IProtectedSegmentEvent { value : ISegmentProtection; } -export interface IEventMessagesEvent { - type : "event-messages"; - value : IEventMessage[]; +export interface IInbandEventsEvent { + type : "inband-events"; + value : IInbandEvent[]; } /** @@ -406,7 +406,7 @@ export type IRepresentationStreamEvent = IStreamStatusEvent | IStreamTerminatingEvent | IStreamNeedsManifestRefresh | IStreamWarningEvent | - IEventMessagesEvent; + IInbandEventsEvent; /** Event sent by an `AdaptationStream`. */ export type IAdaptationStreamEvent = IBitrateEstimationChangeEvent | @@ -422,7 +422,7 @@ export type IAdaptationStreamEvent = IBitrateEstimationChangeEvent | IStreamManifestMightBeOutOfSync | IStreamNeedsManifestRefresh | IStreamWarningEvent | - IEventMessagesEvent; + IInbandEventsEvent; /** Event sent by a `PeriodStream`. */ export type IPeriodStreamEvent = IPeriodStreamReadyEvent | @@ -444,7 +444,7 @@ export type IPeriodStreamEvent = IPeriodStreamReadyEvent | IStreamManifestMightBeOutOfSync | IStreamNeedsManifestRefresh | IStreamWarningEvent | - IEventMessagesEvent; + IInbandEventsEvent; /** Event coming from function(s) managing multiple PeriodStreams. */ export type IMultiplePeriodStreamsEvent = IPeriodStreamClearedEvent | @@ -471,7 +471,7 @@ export type IMultiplePeriodStreamsEvent = IPeriodStreamClearedEvent | IStreamManifestMightBeOutOfSync | IStreamNeedsManifestRefresh | IStreamWarningEvent | - IEventMessagesEvent; + IInbandEventsEvent; /** Every event sent by the `StreamOrchestrator`. */ export type IStreamOrchestratorEvent = IActivePeriodChangedEvent | @@ -501,4 +501,4 @@ export type IStreamOrchestratorEvent = IActivePeriodChangedEvent | IStreamManifestMightBeOutOfSync | IStreamNeedsManifestRefresh | IStreamWarningEvent | - IEventMessagesEvent; + IInbandEventsEvent; diff --git a/src/parsers/containers/isobmff/index.ts b/src/parsers/containers/isobmff/index.ts index 01cba402d3..300e8f6753 100644 --- a/src/parsers/containers/isobmff/index.ts +++ b/src/parsers/containers/isobmff/index.ts @@ -38,7 +38,7 @@ export { getTrackFragmentDecodeTime, getDurationFromTrun, getSegmentsFromSidx, - IEventMessage, + IInbandEvent, ISidxSegment, patchPssh, updateBoxLength, diff --git a/src/parsers/containers/isobmff/utils.ts b/src/parsers/containers/isobmff/utils.ts index c80f78175b..3638e0af8a 100644 --- a/src/parsers/containers/isobmff/utils.ts +++ b/src/parsers/containers/isobmff/utils.ts @@ -49,7 +49,7 @@ export interface IISOBMFFPSSHInfo { privateData : Uint8Array; } -export interface IEventMessage { schemeId: string; +export interface IInbandEvent { schemeId: string; value: string; timescale: number; presentationTimeDelta: number; @@ -426,8 +426,8 @@ function updateBoxLength(buf : Uint8Array) : Uint8Array { * @param {Uint8Array} buf * @returns {Array.} */ -function parseEmsgBoxes(buffer: Uint8Array) : IEventMessage[] | undefined { - const emsgs: IEventMessage[] = []; +function parseEmsgBoxes(buffer: Uint8Array) : IInbandEvent[] | undefined { + const emsgs: IInbandEvent[] = []; let offset = 0; while (offset < buffer.length) { const emsg = getEMSG(buffer, offset); diff --git a/src/transports/dash/segment_parser.ts b/src/transports/dash/segment_parser.ts index 694be50897..9627382258 100644 --- a/src/transports/dash/segment_parser.ts +++ b/src/transports/dash/segment_parser.ts @@ -80,13 +80,13 @@ export default function generateAudioVideoSegmentParser( segment, initTimescale); const chunkOffset = takeFirstSet(segment.timestampOffset, 0); - const emsgs = isWEBM ? undefined : parseEmsgBoxes(chunkData); + const inbandsEvents = isWEBM ? undefined : parseEmsgBoxes(chunkData); return observableOf({ type: "parsed-segment", value: { chunkData, chunkInfos, chunkOffset, appendWindow, - emsgs } }); + inbandsEvents } }); } // we're handling an initialization segment const { indexRange } = segment; diff --git a/src/transports/types.ts b/src/transports/types.ts index b136b0a67d..a163813965 100644 --- a/src/transports/types.ts +++ b/src/transports/types.ts @@ -26,7 +26,7 @@ import Manifest, { Period, Representation, } from "../manifest"; -import { IEventMessage } from "../parsers/containers/isobmff"; +import { IInbandEvent } from "../parsers/containers/isobmff"; import { IBifThumbnail } from "../parsers/images/bif"; import { ILocalManifest } from "../parsers/manifest/local"; import { IMetaPlaylist } from "../parsers/manifest/metaplaylist"; @@ -372,7 +372,7 @@ export interface ISegmentParserParsedSegment { number | undefined ]; // end window for the segment // (part of the segment after that time // will be ignored) - emsgs? : IEventMessage[]; + emsgs? : IInbandEvent[]; } // What a segment parser returns when parsing an init segment From a42830f294355639010754c25b820cd684598ae9 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Thu, 18 Feb 2021 17:37:46 +0100 Subject: [PATCH 06/75] parsers: parse and exploit InbandEventStreams --- .../representation/representation_stream.ts | 13 +++--- src/manifest/representation.ts | 27 ++++++++++++ .../dash/node_parsers/AdaptationSet.ts | 8 ++++ .../dash/node_parsers/Representation.ts | 9 ++++ .../manifest/dash/parse_representations.ts | 44 +++++++++++++++++++ src/parsers/manifest/types.ts | 4 ++ src/transports/dash/segment_parser.ts | 13 +++++- src/transports/types.ts | 2 +- 8 files changed, 111 insertions(+), 9 deletions(-) diff --git a/src/core/stream/representation/representation_stream.ts b/src/core/stream/representation/representation_stream.ts index 2b1118f195..d5bb9c207a 100644 --- a/src/core/stream/representation/representation_stream.ts +++ b/src/core/stream/representation/representation_stream.ts @@ -485,24 +485,25 @@ export default function RepresentationStream({ case "parsed-segment": const initSegmentData = initSegmentObject?.initializationData ?? null; - if (evt.value.emsgs !== undefined) { - const { needsManifestRefresh, nonInterpretedMessages } = evt.value.emsgs + if (evt.value.inbandEvents !== undefined) { + const { needsManifestRefresh, + nonInterpretedEvents } = evt.value.inbandEvents .reduce((acc, val: IInbandEvent) => { // Scheme that signals manifest update if (val.schemeId === "urn:mpeg:dash:event:2012") { acc.needsManifestRefresh = true; } else { - acc.nonInterpretedMessages.push(val); + acc.nonInterpretedEvents.push(val); } return acc; }, { needsManifestRefresh: false, - nonInterpretedMessages: [] as IInbandEvent[] }); + nonInterpretedEvents: [] as IInbandEvent[] }); const manifestRefresh$ = needsManifestRefresh ? observableOf(EVENTS.needsManifestRefresh()) : EMPTY; - const inbandEvents$ = nonInterpretedMessages.length > 0 ? + const inbandEvents$ = nonInterpretedEvents.length > 0 ? observableOf({ type: "inband-events" as const, - value: nonInterpretedMessages }) : + value: nonInterpretedEvents }) : EMPTY; return observableConcat(manifestRefresh$, inbandEvents$, diff --git a/src/manifest/representation.ts b/src/manifest/representation.ts index 28fd965328..639c0ee8f5 100644 --- a/src/manifest/representation.ts +++ b/src/manifest/representation.ts @@ -16,10 +16,12 @@ import { isCodecSupported } from "../compat"; import log from "../log"; +import { IInbandEvent } from "../parsers/containers/isobmff"; import { IContentProtections, IParsedRepresentation, } from "../parsers/manifest"; +import { IScheme } from "../parsers/manifest/dash/node_parsers/utils"; import areArraysOfNumbersEqual from "../utils/are_arrays_of_numbers_equal"; import { concat } from "../utils/byte_parsing"; import { IRepresentationIndex } from "./representation_index"; @@ -95,6 +97,9 @@ class Representation { /** `true` if the Representation is in a supported codec, false otherwise. */ public isSupported : boolean; + /** List of signaled inband event scheme ids */ + private _signaledInbandEventSchemeIds?: IScheme[]; + /** * @param {Object} args */ @@ -123,6 +128,10 @@ class Representation { this.frameRate = args.frameRate; } + if (args.signaledInbandEventSchemeIds !== undefined) { + this._signaledInbandEventSchemeIds = args.signaledInbandEventSchemeIds; + } + this.index = args.index; this.isSupported = opts.type === "audio" || opts.type === "video" ? @@ -201,6 +210,24 @@ class Representation { } initDataArr.push(newElement); } + + /** + * Some inband events may not be allowed and filtered out. + * Example : MPEG-DASH tells about inband events presence on stream with an + * InbandEventStream tag. Each inband event from stream must have a scheme id + * that is defined in one of the InbandEventStream. If not, the event must be + * ignored. + * @param {Object} inbandEvent + * @returns {boolean} + */ + _isInbandEventAllowed(inbandEvent: IInbandEvent): boolean { + if (this._signaledInbandEventSchemeIds === undefined) { + return false; + } + return this._signaledInbandEventSchemeIds.some(({ schemeIdUri }) => { + return schemeIdUri === inbandEvent.schemeId; + }); + } } export default Representation; diff --git a/src/parsers/manifest/dash/node_parsers/AdaptationSet.ts b/src/parsers/manifest/dash/node_parsers/AdaptationSet.ts index 7472cd8b61..cb5cfee8fc 100644 --- a/src/parsers/manifest/dash/node_parsers/AdaptationSet.ts +++ b/src/parsers/manifest/dash/node_parsers/AdaptationSet.ts @@ -62,6 +62,7 @@ export interface IAdaptationSetChildren { contentComponent? : IParsedContentComponent; contentProtections? : IParsedContentProtection[]; essentialProperties? : IScheme[]; + signaledInbandEventSchemeIds? : IScheme[]; roles? : IScheme[]; supplementalProperties? : IScheme[]; @@ -152,6 +153,13 @@ function parseAdaptationSetChildren( } break; + case "InbandEventStream": + if (children.signaledInbandEventSchemeIds === undefined) { + children.signaledInbandEventSchemeIds = []; + } + children.signaledInbandEventSchemeIds.push(parseScheme(currentElement)); + break; + case "Representation": const [representation, representationWarnings] = createRepresentationIntermediateRepresentation(currentElement); diff --git a/src/parsers/manifest/dash/node_parsers/Representation.ts b/src/parsers/manifest/dash/node_parsers/Representation.ts index 08be0cc593..73b9cc8cac 100644 --- a/src/parsers/manifest/dash/node_parsers/Representation.ts +++ b/src/parsers/manifest/dash/node_parsers/Representation.ts @@ -27,10 +27,12 @@ import parseSegmentTemplate, { IParsedSegmentTemplate, } from "./SegmentTemplate"; import { + IScheme, MPDError, parseBoolean, parseMPDFloat, parseMPDInteger, + parseScheme, ValueParser, } from "./utils"; @@ -44,6 +46,7 @@ export interface IRepresentationChildren { baseURLs : IBaseURL[]; // optional + signaledInbandEventSchemeIds? : IScheme[]; segmentBase? : IParsedSegmentBase; segmentList? : IParsedSegmentList; segmentTemplate? : IParsedSegmentTemplate; @@ -91,6 +94,12 @@ function parseRepresentationChildren( } warnings = warnings.concat(baseURLWarnings); break; + case "InbandEventStream": + if (children.signaledInbandEventSchemeIds === undefined) { + children.signaledInbandEventSchemeIds = []; + } + children.signaledInbandEventSchemeIds.push(parseScheme(currentElement)); + break; case "SegmentBase": const [segmentBase, segmentBaseWarnings] = parseSegmentBase(currentElement); children.segmentBase = segmentBase; diff --git a/src/parsers/manifest/dash/parse_representations.ts b/src/parsers/manifest/dash/parse_representations.ts index 3ce30b968e..915d1ee871 100644 --- a/src/parsers/manifest/dash/parse_representations.ts +++ b/src/parsers/manifest/dash/parse_representations.ts @@ -29,8 +29,49 @@ import { IRepresentationIntermediateRepresentation, } from "./node_parsers/Representation"; import { IParsedSegmentTemplate } from "./node_parsers/SegmentTemplate"; +import { IScheme } from "./node_parsers/utils"; import parseRepresentationIndex from "./parse_representation_index"; +/** + * Combine unique inband event streams from representation and + * adaptation data. + * @param {Object} representation + * @param {Object} adaptation + * @returns {undefined | Array.} + */ +function getAcceptedInbandEventStreams( + representation: IRepresentationIntermediateRepresentation, + adaptation: IAdaptationSetIntermediateRepresentation +): IScheme[] | undefined { + const newSchemeId = []; + if (representation.children.signaledInbandEventSchemeIds !== undefined) { + newSchemeId.push(...representation.children.signaledInbandEventSchemeIds); + } + if (adaptation.children.signaledInbandEventSchemeIds !== undefined) { + if (newSchemeId.length === 0) { + newSchemeId.push(...adaptation.children.signaledInbandEventSchemeIds); + } else { + const len = adaptation.children.signaledInbandEventSchemeIds.length; + for (let i = 0; i < len; i++) { + const signaledInbandEventSchemeId = + adaptation.children.signaledInbandEventSchemeIds[i]; + const isNonDuplicatedInbandEventStream = + !newSchemeId.some(({ schemeIdUri, value }) => { + return schemeIdUri === signaledInbandEventSchemeId.schemeIdUri && + value === signaledInbandEventSchemeId.value; + }); + if (isNonDuplicatedInbandEventStream) { + newSchemeId.push(signaledInbandEventSchemeId); + } + } + } + } + if (newSchemeId.length === 0) { + return undefined; + } + return newSchemeId; +} + /** Supplementary context needed to parse a Representation. */ export interface IAdaptationInfos { /** Whether we should request new segments even if they are not yet finished. */ @@ -174,6 +215,9 @@ export default function parseRepresentations( adaptation.attributes.width; } + parsedRepresentation.signaledInbandEventSchemeIds = + getAcceptedInbandEventStreams(representation, adaptation); + if (adaptation.children.contentProtections != null) { const contentProtections = adaptation.children.contentProtections .reduce((acc, cp) => { diff --git a/src/parsers/manifest/types.ts b/src/parsers/manifest/types.ts index 70822f280f..91e013c087 100644 --- a/src/parsers/manifest/types.ts +++ b/src/parsers/manifest/types.ts @@ -16,6 +16,7 @@ import { IRepresentationIndex } from "../../manifest"; import { IParsedStreamEventData } from "./dash/node_parsers/EventStream"; +import { IScheme } from "./dash/node_parsers/utils"; export interface IManifestStreamEvent { start: number; end?: number; @@ -85,6 +86,9 @@ export interface IParsedRepresentation { * Not set if unknown or if it makes no sense (e.g. for audio). */ width?: number; + + /** List of signaled inband event scheme ids */ + signaledInbandEventSchemeIds?: IScheme[]; } /** Every possible types an Adaptation can have. */ diff --git a/src/transports/dash/segment_parser.ts b/src/transports/dash/segment_parser.ts index 9627382258..559effb3bc 100644 --- a/src/transports/dash/segment_parser.ts +++ b/src/transports/dash/segment_parser.ts @@ -80,13 +80,22 @@ export default function generateAudioVideoSegmentParser( segment, initTimescale); const chunkOffset = takeFirstSet(segment.timestampOffset, 0); - const inbandsEvents = isWEBM ? undefined : parseEmsgBoxes(chunkData); + const parsedInbandEvents = isWEBM ? undefined : parseEmsgBoxes(chunkData); + let inbandEvents; + if (parsedInbandEvents !== undefined) { + const filteredInbandEvents = parsedInbandEvents.filter((evt) => { + return representation._isInbandEventAllowed(evt); + }); + if (filteredInbandEvents.length > 0) { + inbandEvents = filteredInbandEvents; + } + } return observableOf({ type: "parsed-segment", value: { chunkData, chunkInfos, chunkOffset, appendWindow, - inbandsEvents } }); + inbandEvents } }); } // we're handling an initialization segment const { indexRange } = segment; diff --git a/src/transports/types.ts b/src/transports/types.ts index a163813965..788c57829e 100644 --- a/src/transports/types.ts +++ b/src/transports/types.ts @@ -372,7 +372,7 @@ export interface ISegmentParserParsedSegment { number | undefined ]; // end window for the segment // (part of the segment after that time // will be ignored) - emsgs? : IInbandEvent[]; + inbandEvents? : IInbandEvent[]; // Inband events parsed from segment data } // What a segment parser returns when parsing an init segment From 09b189c4e348411db6a1dae75789afffaf456682 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Thu, 18 Feb 2021 17:42:23 +0100 Subject: [PATCH 07/75] tests: add _isInbandEventAllowed in fake reps --- src/utils/__tests__/initialization_segment_cache.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/utils/__tests__/initialization_segment_cache.test.ts b/src/utils/__tests__/initialization_segment_cache.test.ts index 5d80340d94..b8e0b05483 100644 --- a/src/utils/__tests__/initialization_segment_cache.test.ts +++ b/src/utils/__tests__/initialization_segment_cache.test.ts @@ -38,6 +38,7 @@ const representation1 = { }, getProtectionsInitializationData() : [] { return []; }, _addProtectionData() : never { throw new Error("Not implemented"); }, + _isInbandEventAllowed() : true { return true; }, }; const representation2 = { @@ -62,6 +63,7 @@ const representation2 = { }, getProtectionsInitializationData() : [] { return []; }, _addProtectionData() : never { throw new Error("Not implemented"); }, + _isInbandEventAllowed() : true { return true; }, }; const initSegment1 = { From 62be2045b74366f8fbf782d11e55294413e074f1 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Thu, 18 Feb 2021 18:34:29 +0100 Subject: [PATCH 08/75] parsers: simpler inbandeventstream combining --- .../manifest/dash/parse_representations.ts | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/parsers/manifest/dash/parse_representations.ts b/src/parsers/manifest/dash/parse_representations.ts index 915d1ee871..c149e65c57 100644 --- a/src/parsers/manifest/dash/parse_representations.ts +++ b/src/parsers/manifest/dash/parse_representations.ts @@ -33,13 +33,13 @@ import { IScheme } from "./node_parsers/utils"; import parseRepresentationIndex from "./parse_representation_index"; /** - * Combine unique inband event streams from representation and + * Combine inband event streams from representation and * adaptation data. * @param {Object} representation * @param {Object} adaptation * @returns {undefined | Array.} */ -function getAcceptedInbandEventStreams( +function combineAllowedInbandEventStreams( representation: IRepresentationIntermediateRepresentation, adaptation: IAdaptationSetIntermediateRepresentation ): IScheme[] | undefined { @@ -48,23 +48,7 @@ function getAcceptedInbandEventStreams( newSchemeId.push(...representation.children.signaledInbandEventSchemeIds); } if (adaptation.children.signaledInbandEventSchemeIds !== undefined) { - if (newSchemeId.length === 0) { - newSchemeId.push(...adaptation.children.signaledInbandEventSchemeIds); - } else { - const len = adaptation.children.signaledInbandEventSchemeIds.length; - for (let i = 0; i < len; i++) { - const signaledInbandEventSchemeId = - adaptation.children.signaledInbandEventSchemeIds[i]; - const isNonDuplicatedInbandEventStream = - !newSchemeId.some(({ schemeIdUri, value }) => { - return schemeIdUri === signaledInbandEventSchemeId.schemeIdUri && - value === signaledInbandEventSchemeId.value; - }); - if (isNonDuplicatedInbandEventStream) { - newSchemeId.push(signaledInbandEventSchemeId); - } - } - } + newSchemeId.push(...adaptation.children.signaledInbandEventSchemeIds); } if (newSchemeId.length === 0) { return undefined; @@ -216,7 +200,7 @@ export default function parseRepresentations( } parsedRepresentation.signaledInbandEventSchemeIds = - getAcceptedInbandEventStreams(representation, adaptation); + combineAllowedInbandEventStreams(representation, adaptation); if (adaptation.children.contentProtections != null) { const contentProtections = adaptation.children.contentProtections From 399da9498cbfde2bb6a19a5138766be900120596 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Fri, 19 Feb 2021 17:15:27 +0100 Subject: [PATCH 09/75] parsers: add isInbandEventWhitelisted on segments --- src/manifest/representation.ts | 27 ------------- src/manifest/representation_index/types.ts | 2 + src/parsers/manifest/dash/indexes/base.ts | 27 +++++++++++-- src/parsers/manifest/dash/indexes/list.ts | 40 +++++++++++++------ src/parsers/manifest/dash/indexes/template.ts | 21 ++++++++-- .../timeline/timeline_representation_index.ts | 27 +++++++++++-- .../dash/node_parsers/AdaptationSet.ts | 8 ++-- .../dash/node_parsers/Representation.ts | 8 ++-- .../dash/parse_representation_index.ts | 16 +++++++- .../manifest/dash/parse_representations.ts | 19 ++++----- src/transports/dash/segment_parser.ts | 6 ++- 11 files changed, 133 insertions(+), 68 deletions(-) diff --git a/src/manifest/representation.ts b/src/manifest/representation.ts index 639c0ee8f5..28fd965328 100644 --- a/src/manifest/representation.ts +++ b/src/manifest/representation.ts @@ -16,12 +16,10 @@ import { isCodecSupported } from "../compat"; import log from "../log"; -import { IInbandEvent } from "../parsers/containers/isobmff"; import { IContentProtections, IParsedRepresentation, } from "../parsers/manifest"; -import { IScheme } from "../parsers/manifest/dash/node_parsers/utils"; import areArraysOfNumbersEqual from "../utils/are_arrays_of_numbers_equal"; import { concat } from "../utils/byte_parsing"; import { IRepresentationIndex } from "./representation_index"; @@ -97,9 +95,6 @@ class Representation { /** `true` if the Representation is in a supported codec, false otherwise. */ public isSupported : boolean; - /** List of signaled inband event scheme ids */ - private _signaledInbandEventSchemeIds?: IScheme[]; - /** * @param {Object} args */ @@ -128,10 +123,6 @@ class Representation { this.frameRate = args.frameRate; } - if (args.signaledInbandEventSchemeIds !== undefined) { - this._signaledInbandEventSchemeIds = args.signaledInbandEventSchemeIds; - } - this.index = args.index; this.isSupported = opts.type === "audio" || opts.type === "video" ? @@ -210,24 +201,6 @@ class Representation { } initDataArr.push(newElement); } - - /** - * Some inband events may not be allowed and filtered out. - * Example : MPEG-DASH tells about inband events presence on stream with an - * InbandEventStream tag. Each inband event from stream must have a scheme id - * that is defined in one of the InbandEventStream. If not, the event must be - * ignored. - * @param {Object} inbandEvent - * @returns {boolean} - */ - _isInbandEventAllowed(inbandEvent: IInbandEvent): boolean { - if (this._signaledInbandEventSchemeIds === undefined) { - return false; - } - return this._signaledInbandEventSchemeIds.some(({ schemeIdUri }) => { - return schemeIdUri === inbandEvent.schemeId; - }); - } } export default Representation; diff --git a/src/manifest/representation_index/types.ts b/src/manifest/representation_index/types.ts index d970e7ce9d..bdf3c1e380 100644 --- a/src/manifest/representation_index/types.ts +++ b/src/manifest/representation_index/types.ts @@ -20,6 +20,7 @@ import Manifest, { Period, Representation, } from "../../manifest"; +import { IInbandEvent } from "../../parsers/containers/isobmff"; import { ILocalIndexSegment, ILocalManifestInitSegmentLoader, @@ -123,6 +124,7 @@ export interface IPrivateInfos { metaplaylistInfos? : IMetaPlaylistPrivateInfos; localManifestInitSegment? : ILocalManifestInitSegmentPrivateInfos; localManifestSegment? : ILocalManifestSegmentPrivateInfos; + isInbandEventWhitelisted? : (evt: IInbandEvent) => boolean; } /** Represent a single Segment from a Representation. */ diff --git a/src/parsers/manifest/dash/indexes/base.ts b/src/parsers/manifest/dash/indexes/base.ts index 6028a5abd3..0ba36c0325 100644 --- a/src/parsers/manifest/dash/indexes/base.ts +++ b/src/parsers/manifest/dash/indexes/base.ts @@ -19,6 +19,7 @@ import { IRepresentationIndex, ISegment, } from "../../../../manifest"; +import { IInbandEvent } from "../../../containers/isobmff"; import { fromIndexTime, getIndexSegmentEnd, @@ -114,6 +115,8 @@ export interface IBaseIndexContextArgument { representationId? : string; /** Bitrate of the Representation concerned. */ representationBitrate? : number; + /* Function that tells if an inband event is whitelisted by the manifest */ + isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; } /** @@ -167,6 +170,9 @@ export default class BaseRepresentationIndex implements IRepresentationIndex { /** Absolute end of the period, timescaled and converted to index time. */ private _scaledPeriodEnd : number | undefined; + /* Function that tells if an inband event is whitelisted by the manifest */ + private _isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; + /** * @param {Object} index * @param {Object} context @@ -176,7 +182,8 @@ export default class BaseRepresentationIndex implements IRepresentationIndex { periodEnd, representationBaseURLs, representationId, - representationBitrate } = context; + representationBitrate, + isInbandEventWhitelisted } = context; const timescale = index.timescale ?? 1; const presentationTimeOffset = index.presentationTimeOffset != null ? @@ -215,6 +222,7 @@ export default class BaseRepresentationIndex implements IRepresentationIndex { this._scaledPeriodEnd = periodEnd == null ? undefined : toIndexTime(periodEnd, this._index); this._isInitialized = this._index.timeline.length > 0; + this._isInbandEventWhitelisted = isInbandEventWhitelisted; } /** @@ -222,7 +230,12 @@ export default class BaseRepresentationIndex implements IRepresentationIndex { * @returns {Object} */ getInitSegment() : ISegment { - return getInitSegment(this._index); + const initSegment = getInitSegment(this._index); + if (initSegment.privateInfos === undefined) { + initSegment.privateInfos = {}; + } + initSegment.privateInfos.isInbandEventWhitelisted = this._isInbandEventWhitelisted; + return initSegment; } /** @@ -231,7 +244,15 @@ export default class BaseRepresentationIndex implements IRepresentationIndex { * @returns {Array.} */ getSegments(_up : number, _to : number) : ISegment[] { - return getSegmentsFromTimeline(this._index, _up, _to, this._scaledPeriodEnd); + return getSegmentsFromTimeline(this._index, _up, _to, this._scaledPeriodEnd) + .map((segment) => { + if (segment.privateInfos === undefined) { + segment.privateInfos = {}; + } + segment.privateInfos.isInbandEventWhitelisted = + this._isInbandEventWhitelisted; + return segment; + }); } /** diff --git a/src/parsers/manifest/dash/indexes/list.ts b/src/parsers/manifest/dash/indexes/list.ts index 89c17c1338..e6f4a4e479 100644 --- a/src/parsers/manifest/dash/indexes/list.ts +++ b/src/parsers/manifest/dash/indexes/list.ts @@ -19,6 +19,7 @@ import { IRepresentationIndex, ISegment, } from "../../../../manifest"; +import { IInbandEvent } from "../../../containers/isobmff"; import { getTimescaledRange } from "../../utils/index_helpers"; import getInitSegment from "./get_init_segment"; import { createIndexURLs } from "./tokens"; @@ -110,6 +111,8 @@ export interface IListIndexContextArgument { representationId? : string; /** Bitrate of the Representation concerned. */ representationBitrate? : number; + /* Function that tells if an inband event is whitelisted by the manifest */ + isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; } export default class ListRepresentationIndex implements IRepresentationIndex { @@ -117,6 +120,8 @@ export default class ListRepresentationIndex implements IRepresentationIndex { private _index : IListIndex; /** Start of the period concerned by this RepresentationIndex, in seconds. */ protected _periodStart : number; + /* Function that tells if an inband event is whitelisted by the manifest */ + private _isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; /** * @param {Object} index @@ -126,8 +131,9 @@ export default class ListRepresentationIndex implements IRepresentationIndex { const { periodStart, representationBaseURLs, representationId, - representationBitrate } = context; - + representationBitrate, + isInbandEventWhitelisted } = context; + this._isInbandEventWhitelisted = isInbandEventWhitelisted; this._periodStart = periodStart; const presentationTimeOffset = index.presentationTimeOffset != null ? index.presentationTimeOffset : @@ -160,7 +166,12 @@ export default class ListRepresentationIndex implements IRepresentationIndex { * @returns {Object} */ getInitSegment() : ISegment { - return getInitSegment(this._index); + const initSegment = getInitSegment(this._index); + if (initSegment.privateInfos === undefined) { + initSegment.privateInfos = {}; + } + initSegment.privateInfos.isInbandEventWhitelisted = this._isInbandEventWhitelisted; + return initSegment; } /** @@ -182,16 +193,19 @@ export default class ListRepresentationIndex implements IRepresentationIndex { const range = list[i].mediaRange; const mediaURLs = list[i].mediaURLs; const time = i * durationInSeconds + this._periodStart; - const args = { id: String(i), - time, - isInit: false, - range, - duration: durationInSeconds, - timescale: 1 as const, - end: time + durationInSeconds, - mediaURLs, - timestampOffset: -(index.indexTimeOffset / timescale) }; - segments.push(args); + const segment = + { id: String(i), + time, + isInit: false, + range, + duration: durationInSeconds, + timescale: 1 as const, + end: time + durationInSeconds, + mediaURLs, + timestampOffset: -(index.indexTimeOffset / timescale), + privateInfos: { isInbandEventWhitelisted: + this._isInbandEventWhitelisted } }; + segments.push(segment); i++; } return segments; diff --git a/src/parsers/manifest/dash/indexes/template.ts b/src/parsers/manifest/dash/indexes/template.ts index 0b38a02d44..f765a8f07a 100644 --- a/src/parsers/manifest/dash/indexes/template.ts +++ b/src/parsers/manifest/dash/indexes/template.ts @@ -19,6 +19,7 @@ import { IRepresentationIndex, ISegment, } from "../../../../manifest"; +import { IInbandEvent } from "../../../containers/isobmff"; import ManifestBoundsCalculator from "../manifest_bounds_calculator"; import getInitSegment from "./get_init_segment"; import isPeriodFulfilled from "./is_period_fulfilled"; @@ -126,6 +127,8 @@ export interface ITemplateIndexContextArgument { representationId? : string; /** Bitrate of the Representation concerned. */ representationBitrate? : number; + /* Function that tells if an inband event is whitelisted by the manifest */ + isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; } /** @@ -151,6 +154,8 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex private _availabilityTimeOffset? : number; /** Whether the corresponding Manifest can be updated and changed. */ private _isDynamic : boolean; + /* Function that tells if an inband event is whitelisted by the manifest */ + private _isInbandEventWhitelisted : (inbandEvent: IInbandEvent) => boolean; /** * @param {Object} index @@ -168,7 +173,8 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex periodStart, representationBaseURLs, representationId, - representationBitrate } = context; + representationBitrate, + isInbandEventWhitelisted } = context; const timescale = index.timescale ?? 1; this._availabilityTimeOffset = availabilityTimeOffset; @@ -207,6 +213,7 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex this._periodStart = periodStart; this._scaledPeriodEnd = periodEnd == null ? undefined : (periodEnd - periodStart) * timescale; + this._isInbandEventWhitelisted = isInbandEventWhitelisted; } /** @@ -214,7 +221,12 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex * @returns {Object} */ getInitSegment() : ISegment { - return getInitSegment(this._index); + const initSegment = getInitSegment(this._index); + if (initSegment.privateInfos === undefined) { + initSegment.privateInfos = {}; + } + initSegment.privateInfos.isInbandEventWhitelisted = this._isInbandEventWhitelisted; + return initSegment; } /** @@ -285,7 +297,10 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex isInit: false, scaledDuration: realDuration / timescale, mediaURLs: detokenizedURLs, - timestampOffset: -(index.indexTimeOffset / timescale) }; + timestampOffset: -(index.indexTimeOffset / timescale), + privateInfos: { + isInbandEventWhitelisted: this._isInbandEventWhitelisted, + } }; segments.push(args); numberIndexedToZero++; } diff --git a/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts b/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts index 413f693a44..86c4b3fe93 100644 --- a/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts +++ b/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts @@ -25,6 +25,7 @@ import { ISegment, Representation, } from "../../../../../manifest"; +import { IInbandEvent } from "../../../../containers/isobmff"; import clearTimelineFromPosition from "../../../utils/clear_timeline_from_position"; import { checkDiscontinuity, @@ -164,6 +165,8 @@ export interface ITimelineIndexContextArgument { * Use with moderation. */ unsafelyBaseOnPreviousRepresentation : Representation | null; + /* Function that tells if an inband event is whitelisted by the manifest */ + isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; } export interface ILastSegmentInformation { @@ -209,6 +212,9 @@ export default class TimelineRepresentationIndex implements IRepresentationIndex */ private _unsafelyBaseOnPreviousIndex : TimelineRepresentationIndex | null; + /* Function that tells if an inband event is whitelisted by the manifest */ + private _isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; + /** * @param {Object} index * @param {Object} context @@ -224,7 +230,8 @@ export default class TimelineRepresentationIndex implements IRepresentationIndex representationId, representationBitrate, periodStart, - periodEnd } = context; + periodEnd, + isInbandEventWhitelisted } = context; const timescale = index.timescale ?? 1; const presentationTimeOffset = index.presentationTimeOffset != null ? @@ -236,6 +243,7 @@ export default class TimelineRepresentationIndex implements IRepresentationIndex this._manifestBoundsCalculator = manifestBoundsCalculator; + this._isInbandEventWhitelisted = isInbandEventWhitelisted; this._lastUpdate = context.receivedTime == null ? performance.now() : context.receivedTime; @@ -282,7 +290,12 @@ export default class TimelineRepresentationIndex implements IRepresentationIndex * @returns {Object} */ getInitSegment() : ISegment { - return getInitSegment(this._index); + const initSegment = getInitSegment(this._index); + if (initSegment.privateInfos === undefined) { + initSegment.privateInfos = {}; + } + initSegment.privateInfos.isInbandEventWhitelisted = this._isInbandEventWhitelisted; + return initSegment; } /** @@ -310,7 +323,15 @@ export default class TimelineRepresentationIndex implements IRepresentationIndex indexTimeOffset }, from, duration, - this._scaledPeriodEnd); + this._scaledPeriodEnd) + .map((segment) => { + if (segment.privateInfos === undefined) { + segment.privateInfos = {}; + } + segment.privateInfos.isInbandEventWhitelisted = + this._isInbandEventWhitelisted; + return segment; + }); } /** diff --git a/src/parsers/manifest/dash/node_parsers/AdaptationSet.ts b/src/parsers/manifest/dash/node_parsers/AdaptationSet.ts index cb5cfee8fc..2126d078be 100644 --- a/src/parsers/manifest/dash/node_parsers/AdaptationSet.ts +++ b/src/parsers/manifest/dash/node_parsers/AdaptationSet.ts @@ -62,7 +62,7 @@ export interface IAdaptationSetChildren { contentComponent? : IParsedContentComponent; contentProtections? : IParsedContentProtection[]; essentialProperties? : IScheme[]; - signaledInbandEventSchemeIds? : IScheme[]; + inbandEventStreams? : IScheme[]; roles? : IScheme[]; supplementalProperties? : IScheme[]; @@ -154,10 +154,10 @@ function parseAdaptationSetChildren( break; case "InbandEventStream": - if (children.signaledInbandEventSchemeIds === undefined) { - children.signaledInbandEventSchemeIds = []; + if (children.inbandEventStreams === undefined) { + children.inbandEventStreams = []; } - children.signaledInbandEventSchemeIds.push(parseScheme(currentElement)); + children.inbandEventStreams.push(parseScheme(currentElement)); break; case "Representation": diff --git a/src/parsers/manifest/dash/node_parsers/Representation.ts b/src/parsers/manifest/dash/node_parsers/Representation.ts index 73b9cc8cac..68b7a43494 100644 --- a/src/parsers/manifest/dash/node_parsers/Representation.ts +++ b/src/parsers/manifest/dash/node_parsers/Representation.ts @@ -46,7 +46,7 @@ export interface IRepresentationChildren { baseURLs : IBaseURL[]; // optional - signaledInbandEventSchemeIds? : IScheme[]; + inbandEventStreams? : IScheme[]; segmentBase? : IParsedSegmentBase; segmentList? : IParsedSegmentList; segmentTemplate? : IParsedSegmentTemplate; @@ -95,10 +95,10 @@ function parseRepresentationChildren( warnings = warnings.concat(baseURLWarnings); break; case "InbandEventStream": - if (children.signaledInbandEventSchemeIds === undefined) { - children.signaledInbandEventSchemeIds = []; + if (children.inbandEventStreams === undefined) { + children.inbandEventStreams = []; } - children.signaledInbandEventSchemeIds.push(parseScheme(currentElement)); + children.inbandEventStreams.push(parseScheme(currentElement)); break; case "SegmentBase": const [segmentBase, segmentBaseWarnings] = parseSegmentBase(currentElement); diff --git a/src/parsers/manifest/dash/parse_representation_index.ts b/src/parsers/manifest/dash/parse_representation_index.ts index 68f178ca92..fe37f4065b 100644 --- a/src/parsers/manifest/dash/parse_representation_index.ts +++ b/src/parsers/manifest/dash/parse_representation_index.ts @@ -19,6 +19,7 @@ import { Representation, } from "../../../manifest"; import objectAssign from "../../../utils/object_assign"; +import { IInbandEvent } from "../../containers/isobmff"; // eslint-disable-next-line max-len import extractMinimumAvailabilityTimeOffset from "./extract_minimum_availability_time_offset"; import { @@ -35,6 +36,7 @@ import { IRepresentationIntermediateRepresentation, } from "./node_parsers/Representation"; import { IParsedSegmentTemplate } from "./node_parsers/SegmentTemplate"; +import { IScheme } from "./node_parsers/utils"; import resolveBaseURLs from "./resolve_base_urls"; /** Supplementary context needed to parse a RepresentationIndex. */ @@ -75,6 +77,8 @@ export interface IRepresentationInfos { * de-synchronization with what is actually on the server. */ unsafelyBaseOnPreviousRepresentation : Representation | null; + /** List of inband event streams that are present on the representation */ + inbandEventStreams: IScheme[] | undefined; } /** @@ -98,10 +102,20 @@ export default function parseRepresentationIndex( start: periodStart, receivedTime, timeShiftBufferDepth, - unsafelyBaseOnPreviousRepresentation } = representationInfos; + unsafelyBaseOnPreviousRepresentation, + inbandEventStreams } = representationInfos; + + const isInbandEventWhitelisted = (inbandEvent: IInbandEvent): boolean => { + if (inbandEventStreams === undefined) { + return false; + } + return inbandEventStreams + .some(({ schemeIdUri }) => schemeIdUri === inbandEvent.schemeId); + }; const context = { aggressiveMode, availabilityTimeOffset, unsafelyBaseOnPreviousRepresentation, + isInbandEventWhitelisted, manifestBoundsCalculator, isDynamic, periodEnd, diff --git a/src/parsers/manifest/dash/parse_representations.ts b/src/parsers/manifest/dash/parse_representations.ts index c149e65c57..b3a925b6b3 100644 --- a/src/parsers/manifest/dash/parse_representations.ts +++ b/src/parsers/manifest/dash/parse_representations.ts @@ -39,16 +39,16 @@ import parseRepresentationIndex from "./parse_representation_index"; * @param {Object} adaptation * @returns {undefined | Array.} */ -function combineAllowedInbandEventStreams( +function combineInbandEventStreams( representation: IRepresentationIntermediateRepresentation, adaptation: IAdaptationSetIntermediateRepresentation ): IScheme[] | undefined { const newSchemeId = []; - if (representation.children.signaledInbandEventSchemeIds !== undefined) { - newSchemeId.push(...representation.children.signaledInbandEventSchemeIds); + if (representation.children.inbandEventStreams !== undefined) { + newSchemeId.push(...representation.children.inbandEventStreams); } - if (adaptation.children.signaledInbandEventSchemeIds !== undefined) { - newSchemeId.push(...adaptation.children.signaledInbandEventSchemeIds); + if (adaptation.children.inbandEventStreams !== undefined) { + newSchemeId.push(...adaptation.children.inbandEventStreams); } if (newSchemeId.length === 0) { return undefined; @@ -138,9 +138,13 @@ export default function parseRepresentations( .unsafelyBaseOnPreviousAdaptation?.getRepresentation(representationID) ?? null; + const inbandEventStreams = + combineInbandEventStreams(representation, adaptation); + const representationInfos = objectAssign({}, adaptationInfos, { unsafelyBaseOnPreviousRepresentation, - adaptation }); + adaptation, + inbandEventStreams }); const representationIndex = parseRepresentationIndex(representation, representationInfos); @@ -199,9 +203,6 @@ export default function parseRepresentations( adaptation.attributes.width; } - parsedRepresentation.signaledInbandEventSchemeIds = - combineAllowedInbandEventStreams(representation, adaptation); - if (adaptation.children.contentProtections != null) { const contentProtections = adaptation.children.contentProtections .reduce((acc, cp) => { diff --git a/src/transports/dash/segment_parser.ts b/src/transports/dash/segment_parser.ts index 559effb3bc..027f92b286 100644 --- a/src/transports/dash/segment_parser.ts +++ b/src/transports/dash/segment_parser.ts @@ -84,7 +84,11 @@ export default function generateAudioVideoSegmentParser( let inbandEvents; if (parsedInbandEvents !== undefined) { const filteredInbandEvents = parsedInbandEvents.filter((evt) => { - return representation._isInbandEventAllowed(evt); + if (segment.privateInfos === undefined || + segment.privateInfos.isInbandEventWhitelisted === undefined) { + return false; + } + return segment.privateInfos.isInbandEventWhitelisted(evt); }); if (filteredInbandEvents.length > 0) { inbandEvents = filteredInbandEvents; From 5ec7cb3ea2f93c32a25df2f15bd7c2cd97a364d6 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Fri, 19 Feb 2021 18:25:13 +0100 Subject: [PATCH 10/75] tests: update tests --- src/parsers/manifest/types.ts | 4 ---- src/utils/__tests__/initialization_segment_cache.test.ts | 2 -- 2 files changed, 6 deletions(-) diff --git a/src/parsers/manifest/types.ts b/src/parsers/manifest/types.ts index 91e013c087..70822f280f 100644 --- a/src/parsers/manifest/types.ts +++ b/src/parsers/manifest/types.ts @@ -16,7 +16,6 @@ import { IRepresentationIndex } from "../../manifest"; import { IParsedStreamEventData } from "./dash/node_parsers/EventStream"; -import { IScheme } from "./dash/node_parsers/utils"; export interface IManifestStreamEvent { start: number; end?: number; @@ -86,9 +85,6 @@ export interface IParsedRepresentation { * Not set if unknown or if it makes no sense (e.g. for audio). */ width?: number; - - /** List of signaled inband event scheme ids */ - signaledInbandEventSchemeIds?: IScheme[]; } /** Every possible types an Adaptation can have. */ diff --git a/src/utils/__tests__/initialization_segment_cache.test.ts b/src/utils/__tests__/initialization_segment_cache.test.ts index b8e0b05483..5d80340d94 100644 --- a/src/utils/__tests__/initialization_segment_cache.test.ts +++ b/src/utils/__tests__/initialization_segment_cache.test.ts @@ -38,7 +38,6 @@ const representation1 = { }, getProtectionsInitializationData() : [] { return []; }, _addProtectionData() : never { throw new Error("Not implemented"); }, - _isInbandEventAllowed() : true { return true; }, }; const representation2 = { @@ -63,7 +62,6 @@ const representation2 = { }, getProtectionsInitializationData() : [] { return []; }, _addProtectionData() : never { throw new Error("Not implemented"); }, - _isInbandEventAllowed() : true { return true; }, }; const initSegment1 = { From 67034dc91648c9e1bcff88f9c3c58d6c3817b3f3 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Wed, 24 Feb 2021 15:37:14 +0100 Subject: [PATCH 11/75] core: better support for manifest update through EMSG --- src/core/init/initialize_media_source.ts | 5 +- src/core/init/manifest_update_scheduler.ts | 12 +++-- src/core/stream/events_generators.ts | 4 +- .../representation/representation_stream.ts | 52 ++++++++++++++++--- src/core/stream/types.ts | 7 ++- src/manifest/manifest.ts | 9 +++- src/parsers/containers/isobmff/utils.ts | 12 ++--- src/parsers/manifest/dash/parse_mpd.ts | 1 + src/parsers/manifest/types.ts | 5 ++ 9 files changed, 83 insertions(+), 24 deletions(-) diff --git a/src/core/init/initialize_media_source.ts b/src/core/init/initialize_media_source.ts index 102de44d12..c3b789832a 100644 --- a/src/core/init/initialize_media_source.ts +++ b/src/core/init/initialize_media_source.ts @@ -342,13 +342,14 @@ export default function InitializeOnMediaSource( switch (evt.type) { case "needs-manifest-refresh": scheduleRefresh$.next({ completeRefresh: false, - canUseUnsafeMode: true }); + canUseUnsafeMode: true, + getRefreshDelay: evt.value?.getDelay }); return null; case "manifest-might-be-out-of-sync": scheduleRefresh$.next({ completeRefresh: true, canUseUnsafeMode: false, - delay: OUT_OF_SYNC_MANIFEST_REFRESH_DELAY, + getRefreshDelay: () => OUT_OF_SYNC_MANIFEST_REFRESH_DELAY, }); return null; case "needs-media-source-reload": diff --git a/src/core/init/manifest_update_scheduler.ts b/src/core/init/manifest_update_scheduler.ts index 65e5cf22f4..483b851a7d 100644 --- a/src/core/init/manifest_update_scheduler.ts +++ b/src/core/init/manifest_update_scheduler.ts @@ -76,10 +76,10 @@ export interface IManifestRefreshSchedulerEvent { */ completeRefresh : boolean; /** - * Optional wanted refresh delay, which is the minimum time you want to wait - * before updating the Manifest + * Optional function that returns the wanted refresh delay, which is the minimum + * time you want to wait before updating the Manifest */ - delay? : number; + getRefreshDelay? : () => number; /** * Whether the parsing can be done in the more efficient "unsafeMode". * This mode is extremely fast but can lead to de-synchronisation with the @@ -148,9 +148,11 @@ export default function manifestUpdateScheduler({ false; const internalRefresh$ = scheduleRefresh$ - .pipe(mergeMap(({ completeRefresh, delay, canUseUnsafeMode }) => { + .pipe(mergeMap(({ completeRefresh, getRefreshDelay, canUseUnsafeMode }) => { const unsafeMode = canUseUnsafeMode && unsafeModeEnabled; - return startManualRefreshTimer(delay ?? 0, + const delay = getRefreshDelay === undefined ? 0 : + getRefreshDelay(); + return startManualRefreshTimer(delay, minimumManifestUpdateInterval, sendingTime) .pipe(mapTo({ completeRefresh, unsafeMode })); diff --git a/src/core/stream/events_generators.ts b/src/core/stream/events_generators.ts index 96ed183865..0e3fe45c6f 100644 --- a/src/core/stream/events_generators.ts +++ b/src/core/stream/events_generators.ts @@ -93,9 +93,9 @@ const EVENTS = { value: undefined }; }, - needsManifestRefresh() : IStreamNeedsManifestRefresh { + needsManifestRefresh(getDelay?: () => number) : IStreamNeedsManifestRefresh { return { type : "needs-manifest-refresh", - value : undefined }; + value : (getDelay !== undefined) ? { getDelay } : undefined }; }, manifestMightBeOufOfSync() : IStreamManifestMightBeOutOfSync { diff --git a/src/core/stream/representation/representation_stream.ts b/src/core/stream/representation/representation_stream.ts index d5bb9c207a..d62f2350ec 100644 --- a/src/core/stream/representation/representation_stream.ts +++ b/src/core/stream/representation/representation_stream.ts @@ -56,6 +56,7 @@ import Manifest, { Representation, } from "../../../manifest"; import { IInbandEvent } from "../../../parsers/containers/isobmff"; +import { utf8ToStr } from "../../../tools/string_utils"; import { ISegmentParserInitSegment, ISegmentParserParsedInitSegment, @@ -486,21 +487,58 @@ export default function RepresentationStream({ case "parsed-segment": const initSegmentData = initSegmentObject?.initializationData ?? null; if (evt.value.inbandEvents !== undefined) { - const { needsManifestRefresh, + const { manifestRefreshEvent, nonInterpretedEvents } = evt.value.inbandEvents .reduce((acc, val: IInbandEvent) => { // Scheme that signals manifest update - if (val.schemeId === "urn:mpeg:dash:event:2012") { - acc.needsManifestRefresh = true; + if (val.schemeId === "urn:mpeg:dash:event:2012" && + // TODO support value 2 and 3 + val.value === "1") { + acc.manifestRefreshEvent = val; } else { acc.nonInterpretedEvents.push(val); } return acc; - }, { needsManifestRefresh: false, + }, { manifestRefreshEvent: undefined as undefined | IInbandEvent, nonInterpretedEvents: [] as IInbandEvent[] }); - const manifestRefresh$ = needsManifestRefresh ? - observableOf(EVENTS.needsManifestRefresh()) : - EMPTY; + const manifestRefresh$ = clock$.pipe( + take(1), + mergeMap(({ position }) => { + if (manifestRefreshEvent === undefined) { + return EMPTY; + } + const currentManifestPublishTime = content.manifest.publishTime; + const { messageData } = manifestRefreshEvent; + const strPublishTime = utf8ToStr(messageData); + const eventManifestPublishTime = Date.parse(strPublishTime); + if (currentManifestPublishTime === undefined || + eventManifestPublishTime === undefined || + isNaN(eventManifestPublishTime) || + // DASH-if 4.3 tells (4.5.2.1) : + // "The media presentation time beyond the event time (indicated + // time by presentation_time_delta) is correctly described only + // by MPDs with publish time greater than indicated value in the + // message_data field." + // + // Here, if the current manifest has its publish time superior + // to event manifest publish time, then the manifest does not need + // to be updated + eventManifestPublishTime < currentManifestPublishTime) { + return EMPTY; + } + const { timescale, presentationTimeDelta } = manifestRefreshEvent; + const eventPresentationTime = + (evt.segment.time / evt.segment.timescale) + + (presentationTimeDelta / timescale); + const delayComputingTime = performance.now(); + const getDelay = () => { + const now = performance.now(); + const gap = (now - delayComputingTime) / 1000; + return Math.max(0, eventPresentationTime - position - gap); + }; + return observableOf(EVENTS.needsManifestRefresh(getDelay)); + }) + ); const inbandEvents$ = nonInterpretedEvents.length > 0 ? observableOf({ type: "inband-events" as const, value: nonInterpretedEvents }) : diff --git a/src/core/stream/types.ts b/src/core/stream/types.ts index 4711e5d813..c7adedeefe 100644 --- a/src/core/stream/types.ts +++ b/src/core/stream/types.ts @@ -138,7 +138,12 @@ export interface IStreamEventAddedSegment { */ export interface IStreamNeedsManifestRefresh { type : "needs-manifest-refresh"; - value : undefined; + /** + * The function returns a delay that is the wanted delay that the scheduler + * has to wait before refreshing the manifest. It may equals the delay until the + * current used manifest will expire. + */ + value : undefined | { getDelay: () => number }; } /** diff --git a/src/manifest/manifest.ts b/src/manifest/manifest.ts index 134f2ca20c..c87f2cd061 100644 --- a/src/manifest/manifest.ts +++ b/src/manifest/manifest.ts @@ -202,6 +202,13 @@ export default class Manifest extends EventEmitter { */ public availabilityStartTime? : number; + /** + * It specifies the wall-clock time when the manifest was generated and published + * at the origin server. It is present in order to identify different versions + * of manifest instances. + */ + public publishTime?: number; + /** * Array containing every minor errors that happened when the Manifest has * been created, in the order they have happened. @@ -331,7 +338,7 @@ export default class Manifest extends EventEmitter { this.lifetime = parsedManifest.lifetime; this.suggestedPresentationDelay = parsedManifest.suggestedPresentationDelay; this.availabilityStartTime = parsedManifest.availabilityStartTime; - + this.publishTime = parsedManifest.publishTime; if (supplementaryImageTracks.length > 0) { this._addSupplementaryImageAdaptations(supplementaryImageTracks); } diff --git a/src/parsers/containers/isobmff/utils.ts b/src/parsers/containers/isobmff/utils.ts index 3638e0af8a..ad690210b9 100644 --- a/src/parsers/containers/isobmff/utils.ts +++ b/src/parsers/containers/isobmff/utils.ts @@ -50,12 +50,12 @@ export interface IISOBMFFPSSHInfo { } export interface IInbandEvent { schemeId: string; - value: string; - timescale: number; - presentationTimeDelta: number; - eventDuration: number; - id: number; - messageData: Uint8Array; } + value: string; + timescale: number; + presentationTimeDelta: number; + eventDuration: number; + id: number; + messageData: Uint8Array; } /** Segment information from a parsed sidx. */ export interface ISidxSegment { diff --git a/src/parsers/manifest/dash/parse_mpd.ts b/src/parsers/manifest/dash/parse_mpd.ts index 4ad6a1a191..675698db2e 100644 --- a/src/parsers/manifest/dash/parse_mpd.ts +++ b/src/parsers/manifest/dash/parse_mpd.ts @@ -326,6 +326,7 @@ function parseCompleteIntermediateRepresentation( isDynamic, isLive: isDynamic, periods: parsedPeriods, + publishTime: rootAttributes.publishTime, suggestedPresentationDelay: rootAttributes.suggestedPresentationDelay, transportType: "dash", timeBounds: { absoluteMinimumTime: minimumTime, diff --git a/src/parsers/manifest/types.ts b/src/parsers/manifest/types.ts index 70822f280f..858429a80c 100644 --- a/src/parsers/manifest/types.ts +++ b/src/parsers/manifest/types.ts @@ -186,6 +186,11 @@ export interface IParsedManifest { isLive : boolean; /** Periods contained in this manifest. */ periods: IParsedPeriod[]; + /** + * The wall-clock time when the manifest was generated and published at the + * origin server + */ + publishTime?: number; /** Underlying transport protocol: "smooth", "dash", "metaplaylist" etc. */ transportType: string; /** Base time from which the segments are generated. */ From 36fdec095164738f0b29517baa0253597eaaafed Mon Sep 17 00:00:00 2001 From: grenault73 Date: Thu, 25 Feb 2021 17:09:23 +0100 Subject: [PATCH 12/75] stream: consider several emsg manifest validity events --- .../representation/representation_stream.ts | 69 ++++++++++++------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/src/core/stream/representation/representation_stream.ts b/src/core/stream/representation/representation_stream.ts index d62f2350ec..87e3cc6baf 100644 --- a/src/core/stream/representation/representation_stream.ts +++ b/src/core/stream/representation/representation_stream.ts @@ -487,54 +487,71 @@ export default function RepresentationStream({ case "parsed-segment": const initSegmentData = initSegmentObject?.initializationData ?? null; if (evt.value.inbandEvents !== undefined) { - const { manifestRefreshEvent, + const { manifestRefreshEvents, nonInterpretedEvents } = evt.value.inbandEvents .reduce((acc, val: IInbandEvent) => { // Scheme that signals manifest update if (val.schemeId === "urn:mpeg:dash:event:2012" && // TODO support value 2 and 3 val.value === "1") { - acc.manifestRefreshEvent = val; + acc.manifestRefreshEvents.push(val); } else { acc.nonInterpretedEvents.push(val); } return acc; - }, { manifestRefreshEvent: undefined as undefined | IInbandEvent, + }, { manifestRefreshEvents: [] as IInbandEvent[], nonInterpretedEvents: [] as IInbandEvent[] }); const manifestRefresh$ = clock$.pipe( take(1), mergeMap(({ position }) => { - if (manifestRefreshEvent === undefined) { + if (manifestRefreshEvents.length === 0) { return EMPTY; } - const currentManifestPublishTime = content.manifest.publishTime; - const { messageData } = manifestRefreshEvent; - const strPublishTime = utf8ToStr(messageData); - const eventManifestPublishTime = Date.parse(strPublishTime); - if (currentManifestPublishTime === undefined || - eventManifestPublishTime === undefined || - isNaN(eventManifestPublishTime) || - // DASH-if 4.3 tells (4.5.2.1) : - // "The media presentation time beyond the event time (indicated - // time by presentation_time_delta) is correctly described only - // by MPDs with publish time greater than indicated value in the - // message_data field." - // - // Here, if the current manifest has its publish time superior - // to event manifest publish time, then the manifest does not need - // to be updated - eventManifestPublishTime < currentManifestPublishTime) { + let minManifestExpiration: undefined | number; + const len = manifestRefreshEvents.length; + for (let i = 0; i < len; i++) { + const manifestRefreshEvent = manifestRefreshEvents[i]; + const currentManifestPublishTime = content.manifest.publishTime; + const { messageData } = manifestRefreshEvent; + const strPublishTime = utf8ToStr(messageData); + const eventManifestPublishTime = Date.parse(strPublishTime); + if (currentManifestPublishTime === undefined || + eventManifestPublishTime === undefined || + isNaN(eventManifestPublishTime) || + // DASH-if 4.3 tells (4.5.2.1) : + // "The media presentation time beyond the event time (indicated + // time by presentation_time_delta) is correctly described only + // by MPDs with publish time greater than indicated value in the + // message_data field." + // + // Here, if the current manifest has its publish time superior + // to event manifest publish time, then the manifest does not + // need to be updated + eventManifestPublishTime < currentManifestPublishTime) { + break; + } + const { timescale, presentationTimeDelta } = manifestRefreshEvent; + const eventPresentationTime = + (evt.segment.time / evt.segment.timescale) + + (presentationTimeDelta / timescale); + minManifestExpiration = + minManifestExpiration === undefined ? + eventPresentationTime : + Math.min(minManifestExpiration, + eventPresentationTime); + } + if (minManifestExpiration === undefined) { return EMPTY; } - const { timescale, presentationTimeDelta } = manifestRefreshEvent; - const eventPresentationTime = - (evt.segment.time / evt.segment.timescale) + - (presentationTimeDelta / timescale); + // redefine manifest expiration time, as typescript does not + // understand that it can't be undefined when using it in the + // getDelay callback + const manifestExpirationTime = minManifestExpiration; const delayComputingTime = performance.now(); const getDelay = () => { const now = performance.now(); const gap = (now - delayComputingTime) / 1000; - return Math.max(0, eventPresentationTime - position - gap); + return Math.max(0, manifestExpirationTime - position - gap); }; return observableOf(EVENTS.needsManifestRefresh(getDelay)); }) From d949a191c771891a37956c7cf7112517a05bd0a4 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Thu, 25 Feb 2021 17:31:00 +0100 Subject: [PATCH 13/75] parsers: simpler getEMSG --- src/parsers/containers/isobmff/read.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/parsers/containers/isobmff/read.ts b/src/parsers/containers/isobmff/read.ts index d93a62f107..820f9005c2 100644 --- a/src/parsers/containers/isobmff/read.ts +++ b/src/parsers/containers/isobmff/read.ts @@ -67,11 +67,7 @@ function getMDIA(buf : Uint8Array) : Uint8Array|null { * @returns {Uint8Array|null} */ function getEMSG(buffer: Uint8Array, offset = 0) : Uint8Array|null { - const emsg = getBoxContent(buffer.subarray(offset), 0x656D7367 /* emsg */); - if (emsg === null) { - return null; - } - return emsg; + return getBoxContent(buffer.subarray(offset), 0x656D7367 /* emsg */); } export { From 651ab9983b3c36697f1b125ad4ff2b227b26720b Mon Sep 17 00:00:00 2001 From: grenault73 Date: Thu, 25 Feb 2021 17:40:07 +0100 Subject: [PATCH 14/75] parsers: create DASH privateInfos in getSegmentsFromTimeline --- src/parsers/manifest/dash/indexes/base.ts | 14 +++++--------- .../dash/indexes/get_segments_from_timeline.ts | 6 +++++- .../timeline/timeline_representation_index.ts | 11 ++--------- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/parsers/manifest/dash/indexes/base.ts b/src/parsers/manifest/dash/indexes/base.ts index 0ba36c0325..322b8bb058 100644 --- a/src/parsers/manifest/dash/indexes/base.ts +++ b/src/parsers/manifest/dash/indexes/base.ts @@ -244,15 +244,11 @@ export default class BaseRepresentationIndex implements IRepresentationIndex { * @returns {Array.} */ getSegments(_up : number, _to : number) : ISegment[] { - return getSegmentsFromTimeline(this._index, _up, _to, this._scaledPeriodEnd) - .map((segment) => { - if (segment.privateInfos === undefined) { - segment.privateInfos = {}; - } - segment.privateInfos.isInbandEventWhitelisted = - this._isInbandEventWhitelisted; - return segment; - }); + return getSegmentsFromTimeline(this._index, + _up, + _to, + this._isInbandEventWhitelisted, + this._scaledPeriodEnd); } /** diff --git a/src/parsers/manifest/dash/indexes/get_segments_from_timeline.ts b/src/parsers/manifest/dash/indexes/get_segments_from_timeline.ts index b27ace71e2..638f043451 100644 --- a/src/parsers/manifest/dash/indexes/get_segments_from_timeline.ts +++ b/src/parsers/manifest/dash/indexes/get_segments_from_timeline.ts @@ -15,6 +15,7 @@ */ import { ISegment } from "../../../../manifest"; +import { IInbandEvent } from "../../../containers/isobmff"; import { calculateRepeat, IIndexSegment, @@ -46,6 +47,7 @@ function getWantedRepeatIndex( * @param {Object} index - index object, constructed by parsing the manifest. * @param {number} from - starting timestamp wanted, in seconds * @param {number} durationWanted - duration wanted, in seconds + * @param {function} isInbandEventWhitelisted * @param {number|undefined} maximumTime * @returns {Array.} */ @@ -57,6 +59,7 @@ export default function getSegmentsFromTimeline( indexTimeOffset : number; }, from : number, durationWanted : number, + isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean, maximumTime? : number ) : ISegment[] { const scaledUp = toIndexTime(from, index); @@ -102,7 +105,8 @@ export default function getSegmentsFromTimeline( timescale: 1 as const, mediaURLs: detokenizedURLs, number: segmentNumber, - timestampOffset: -(index.indexTimeOffset / timescale) }; + timestampOffset: -(index.indexTimeOffset / timescale), + privateInfos: { isInbandEventWhitelisted } }; segments.push(segment); // update segment number and segment time for the next segment diff --git a/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts b/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts index 86c4b3fe93..504ce7dcde 100644 --- a/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts +++ b/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts @@ -323,15 +323,8 @@ export default class TimelineRepresentationIndex implements IRepresentationIndex indexTimeOffset }, from, duration, - this._scaledPeriodEnd) - .map((segment) => { - if (segment.privateInfos === undefined) { - segment.privateInfos = {}; - } - segment.privateInfos.isInbandEventWhitelisted = - this._isInbandEventWhitelisted; - return segment; - }); + this._isInbandEventWhitelisted, + this._scaledPeriodEnd); } /** From fdf4d006949a7eea2f057adb0e0b58fd9895e392 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Fri, 26 Feb 2021 17:50:35 +0100 Subject: [PATCH 15/75] parsers: create DASH privateInfos in getInitSegment --- src/parsers/manifest/dash/indexes/get_init_segment.ts | 10 +++++++++- src/parsers/manifest/dash/indexes/template.ts | 7 +------ .../indexes/timeline/timeline_representation_index.ts | 7 +------ 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/parsers/manifest/dash/indexes/get_init_segment.ts b/src/parsers/manifest/dash/indexes/get_init_segment.ts index 14b29a5190..b6896bdc09 100644 --- a/src/parsers/manifest/dash/indexes/get_init_segment.ts +++ b/src/parsers/manifest/dash/indexes/get_init_segment.ts @@ -15,19 +15,26 @@ */ import { ISegment } from "../../../../manifest"; +import { IInbandEvent } from "../../../containers/isobmff"; /** * Construct init segment for the given index. * @param {Object} index + * @param {function} isInbandEventWhitelisted * @returns {Object} */ export default function getInitSegment( index: { timescale: number; initialization?: { mediaURLs: string[] | null; range?: [number, number] }; indexRange?: [number, number]; - indexTimeOffset : number; } + indexTimeOffset : number; }, + isInbandEventWhitelisted?: (inbandEvent: IInbandEvent) => boolean ) : ISegment { const { initialization } = index; + let privateInfos; + if (isInbandEventWhitelisted !== undefined) { + privateInfos = { isInbandEventWhitelisted }; + } return { id: "init", isInit: true, time: 0, @@ -38,5 +45,6 @@ export default function getInitSegment( undefined, indexRange: index.indexRange, mediaURLs: initialization?.mediaURLs ?? null, + privateInfos, timestampOffset: -(index.indexTimeOffset / index.timescale) }; } diff --git a/src/parsers/manifest/dash/indexes/template.ts b/src/parsers/manifest/dash/indexes/template.ts index f765a8f07a..d242b33862 100644 --- a/src/parsers/manifest/dash/indexes/template.ts +++ b/src/parsers/manifest/dash/indexes/template.ts @@ -221,12 +221,7 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex * @returns {Object} */ getInitSegment() : ISegment { - const initSegment = getInitSegment(this._index); - if (initSegment.privateInfos === undefined) { - initSegment.privateInfos = {}; - } - initSegment.privateInfos.isInbandEventWhitelisted = this._isInbandEventWhitelisted; - return initSegment; + return getInitSegment(this._index, this._isInbandEventWhitelisted); } /** diff --git a/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts b/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts index 504ce7dcde..ec8d9618ea 100644 --- a/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts +++ b/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts @@ -290,12 +290,7 @@ export default class TimelineRepresentationIndex implements IRepresentationIndex * @returns {Object} */ getInitSegment() : ISegment { - const initSegment = getInitSegment(this._index); - if (initSegment.privateInfos === undefined) { - initSegment.privateInfos = {}; - } - initSegment.privateInfos.isInbandEventWhitelisted = this._isInbandEventWhitelisted; - return initSegment; + return getInitSegment(this._index, this._isInbandEventWhitelisted); } /** From 7a7af213e79ca485488c34b5983a90173ad229bc Mon Sep 17 00:00:00 2001 From: grenault73 Date: Tue, 2 Mar 2021 18:07:47 +0100 Subject: [PATCH 16/75] misc: handle emgs in segment parser --- src/core/api/public_api.ts | 2 +- .../representation/representation_stream.ts | 62 +--------- src/core/stream/types.ts | 14 ++- src/manifest/representation_index/types.ts | 4 +- src/parsers/containers/isobmff/index.ts | 2 +- src/parsers/containers/isobmff/utils.ts | 18 +-- src/parsers/manifest/dash/indexes/base.ts | 18 +-- .../manifest/dash/indexes/get_init_segment.ts | 10 +- .../indexes/get_segments_from_timeline.ts | 8 +- src/parsers/manifest/dash/indexes/list.ts | 20 ++-- src/parsers/manifest/dash/indexes/template.ts | 18 +-- .../timeline/timeline_representation_index.ts | 18 +-- .../dash/parse_representation_index.ts | 6 +- src/transports/dash/segment_parser.ts | 106 ++++++++++++++++-- src/transports/types.ts | 6 +- 15 files changed, 176 insertions(+), 136 deletions(-) diff --git a/src/core/api/public_api.ts b/src/core/api/public_api.ts index 0c1891e5c9..1eb8e8b452 100644 --- a/src/core/api/public_api.ts +++ b/src/core/api/public_api.ts @@ -73,7 +73,6 @@ import Manifest, { Period, Representation, } from "../../manifest"; -import { IInbandEvent } from "../../parsers/containers/isobmff"; import { IBifThumbnail } from "../../parsers/images/bif"; import areArraysOfNumbersEqual from "../../utils/are_arrays_of_numbers_equal"; import EventEmitter, { @@ -112,6 +111,7 @@ import SegmentBuffersStore, { IBufferedChunk, IBufferType, } from "../segment_buffers"; +import { IInbandEvent } from "../stream"; import createClock, { IClockTick, } from "./clock"; diff --git a/src/core/stream/representation/representation_stream.ts b/src/core/stream/representation/representation_stream.ts index 87e3cc6baf..fc47007e5e 100644 --- a/src/core/stream/representation/representation_stream.ts +++ b/src/core/stream/representation/representation_stream.ts @@ -55,8 +55,6 @@ import Manifest, { Period, Representation, } from "../../../manifest"; -import { IInbandEvent } from "../../../parsers/containers/isobmff"; -import { utf8ToStr } from "../../../tools/string_utils"; import { ISegmentParserInitSegment, ISegmentParserParsedInitSegment, @@ -487,66 +485,18 @@ export default function RepresentationStream({ case "parsed-segment": const initSegmentData = initSegmentObject?.initializationData ?? null; if (evt.value.inbandEvents !== undefined) { - const { manifestRefreshEvents, - nonInterpretedEvents } = evt.value.inbandEvents - .reduce((acc, val: IInbandEvent) => { - // Scheme that signals manifest update - if (val.schemeId === "urn:mpeg:dash:event:2012" && - // TODO support value 2 and 3 - val.value === "1") { - acc.manifestRefreshEvents.push(val); - } else { - acc.nonInterpretedEvents.push(val); - } - return acc; - }, { manifestRefreshEvents: [] as IInbandEvent[], - nonInterpretedEvents: [] as IInbandEvent[] }); + const { inbandEvents, + manifestRefreshEvent } = evt.value; const manifestRefresh$ = clock$.pipe( take(1), mergeMap(({ position }) => { - if (manifestRefreshEvents.length === 0) { - return EMPTY; - } - let minManifestExpiration: undefined | number; - const len = manifestRefreshEvents.length; - for (let i = 0; i < len; i++) { - const manifestRefreshEvent = manifestRefreshEvents[i]; - const currentManifestPublishTime = content.manifest.publishTime; - const { messageData } = manifestRefreshEvent; - const strPublishTime = utf8ToStr(messageData); - const eventManifestPublishTime = Date.parse(strPublishTime); - if (currentManifestPublishTime === undefined || - eventManifestPublishTime === undefined || - isNaN(eventManifestPublishTime) || - // DASH-if 4.3 tells (4.5.2.1) : - // "The media presentation time beyond the event time (indicated - // time by presentation_time_delta) is correctly described only - // by MPDs with publish time greater than indicated value in the - // message_data field." - // - // Here, if the current manifest has its publish time superior - // to event manifest publish time, then the manifest does not - // need to be updated - eventManifestPublishTime < currentManifestPublishTime) { - break; - } - const { timescale, presentationTimeDelta } = manifestRefreshEvent; - const eventPresentationTime = - (evt.segment.time / evt.segment.timescale) + - (presentationTimeDelta / timescale); - minManifestExpiration = - minManifestExpiration === undefined ? - eventPresentationTime : - Math.min(minManifestExpiration, - eventPresentationTime); - } - if (minManifestExpiration === undefined) { + if (manifestRefreshEvent === undefined) { return EMPTY; } // redefine manifest expiration time, as typescript does not // understand that it can't be undefined when using it in the // getDelay callback - const manifestExpirationTime = minManifestExpiration; + const { manifestExpirationTime } = manifestRefreshEvent.value; const delayComputingTime = performance.now(); const getDelay = () => { const now = performance.now(); @@ -556,9 +506,9 @@ export default function RepresentationStream({ return observableOf(EVENTS.needsManifestRefresh(getDelay)); }) ); - const inbandEvents$ = nonInterpretedEvents.length > 0 ? + const inbandEvents$ = inbandEvents.length > 0 ? observableOf({ type: "inband-events" as const, - value: nonInterpretedEvents }) : + value: inbandEvents }) : EMPTY; return observableConcat(manifestRefresh$, inbandEvents$, diff --git a/src/core/stream/types.ts b/src/core/stream/types.ts index c7adedeefe..d8a5e0ba8f 100644 --- a/src/core/stream/types.ts +++ b/src/core/stream/types.ts @@ -22,7 +22,7 @@ import { Period, Representation, } from "../../manifest"; -import { IInbandEvent } from "../../parsers/containers/isobmff"; +import { IEMSG } from "../../parsers/containers/isobmff"; import { IBufferType } from "../segment_buffers"; /** Information about a Segment waiting to be loaded by the Stream. */ @@ -174,10 +174,14 @@ export interface IProtectedSegmentEvent { value : ISegmentProtection; } -export interface IInbandEventsEvent { - type : "inband-events"; - value : IInbandEvent[]; -} +export interface IInbandEvent { type: "dash-emsg"; + value: IEMSG; } + +export interface IManifestRefreshEvent { type: "manifest-refresh"; + value: { manifestExpirationTime: number }; } + +export interface IInbandEventsEvent { type : "inband-events"; + value : IInbandEvent[]; } /** * Event sent when a `RepresentationStream` is terminating: diff --git a/src/manifest/representation_index/types.ts b/src/manifest/representation_index/types.ts index bdf3c1e380..916e26ad6a 100644 --- a/src/manifest/representation_index/types.ts +++ b/src/manifest/representation_index/types.ts @@ -20,7 +20,7 @@ import Manifest, { Period, Representation, } from "../../manifest"; -import { IInbandEvent } from "../../parsers/containers/isobmff"; +import { IEMSG } from "../../parsers/containers/isobmff"; import { ILocalIndexSegment, ILocalManifestInitSegmentLoader, @@ -124,7 +124,7 @@ export interface IPrivateInfos { metaplaylistInfos? : IMetaPlaylistPrivateInfos; localManifestInitSegment? : ILocalManifestInitSegmentPrivateInfos; localManifestSegment? : ILocalManifestSegmentPrivateInfos; - isInbandEventWhitelisted? : (evt: IInbandEvent) => boolean; + isEMSGWhitelisted? : (evt: IEMSG) => boolean; } /** Represent a single Segment from a Representation. */ diff --git a/src/parsers/containers/isobmff/index.ts b/src/parsers/containers/isobmff/index.ts index 300e8f6753..0bdf182024 100644 --- a/src/parsers/containers/isobmff/index.ts +++ b/src/parsers/containers/isobmff/index.ts @@ -38,7 +38,7 @@ export { getTrackFragmentDecodeTime, getDurationFromTrun, getSegmentsFromSidx, - IInbandEvent, + IEMSG, ISidxSegment, patchPssh, updateBoxLength, diff --git a/src/parsers/containers/isobmff/utils.ts b/src/parsers/containers/isobmff/utils.ts index ad690210b9..d46cdc0941 100644 --- a/src/parsers/containers/isobmff/utils.ts +++ b/src/parsers/containers/isobmff/utils.ts @@ -49,13 +49,13 @@ export interface IISOBMFFPSSHInfo { privateData : Uint8Array; } -export interface IInbandEvent { schemeId: string; - value: string; - timescale: number; - presentationTimeDelta: number; - eventDuration: number; - id: number; - messageData: Uint8Array; } +export interface IEMSG { schemeId: string; + value: string; + timescale: number; + presentationTimeDelta: number; + eventDuration: number; + id: number; + messageData: Uint8Array; } /** Segment information from a parsed sidx. */ export interface ISidxSegment { @@ -426,8 +426,8 @@ function updateBoxLength(buf : Uint8Array) : Uint8Array { * @param {Uint8Array} buf * @returns {Array.} */ -function parseEmsgBoxes(buffer: Uint8Array) : IInbandEvent[] | undefined { - const emsgs: IInbandEvent[] = []; +function parseEmsgBoxes(buffer: Uint8Array) : IEMSG[] | undefined { + const emsgs: IEMSG[] = []; let offset = 0; while (offset < buffer.length) { const emsg = getEMSG(buffer, offset); diff --git a/src/parsers/manifest/dash/indexes/base.ts b/src/parsers/manifest/dash/indexes/base.ts index 322b8bb058..3071bc105c 100644 --- a/src/parsers/manifest/dash/indexes/base.ts +++ b/src/parsers/manifest/dash/indexes/base.ts @@ -19,7 +19,7 @@ import { IRepresentationIndex, ISegment, } from "../../../../manifest"; -import { IInbandEvent } from "../../../containers/isobmff"; +import { IEMSG } from "../../../containers/isobmff"; import { fromIndexTime, getIndexSegmentEnd, @@ -115,8 +115,8 @@ export interface IBaseIndexContextArgument { representationId? : string; /** Bitrate of the Representation concerned. */ representationBitrate? : number; - /* Function that tells if an inband event is whitelisted by the manifest */ - isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; + /* Function that tells if an EMSG is whitelisted by the manifest */ + isEMSGWhitelisted: (inbandEvent: IEMSG) => boolean; } /** @@ -170,8 +170,8 @@ export default class BaseRepresentationIndex implements IRepresentationIndex { /** Absolute end of the period, timescaled and converted to index time. */ private _scaledPeriodEnd : number | undefined; - /* Function that tells if an inband event is whitelisted by the manifest */ - private _isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; + /* Function that tells if an EMSG is whitelisted by the manifest */ + private _isEMSGWhitelisted: (inbandEvent: IEMSG) => boolean; /** * @param {Object} index @@ -183,7 +183,7 @@ export default class BaseRepresentationIndex implements IRepresentationIndex { representationBaseURLs, representationId, representationBitrate, - isInbandEventWhitelisted } = context; + isEMSGWhitelisted } = context; const timescale = index.timescale ?? 1; const presentationTimeOffset = index.presentationTimeOffset != null ? @@ -222,7 +222,7 @@ export default class BaseRepresentationIndex implements IRepresentationIndex { this._scaledPeriodEnd = periodEnd == null ? undefined : toIndexTime(periodEnd, this._index); this._isInitialized = this._index.timeline.length > 0; - this._isInbandEventWhitelisted = isInbandEventWhitelisted; + this._isEMSGWhitelisted = isEMSGWhitelisted; } /** @@ -234,7 +234,7 @@ export default class BaseRepresentationIndex implements IRepresentationIndex { if (initSegment.privateInfos === undefined) { initSegment.privateInfos = {}; } - initSegment.privateInfos.isInbandEventWhitelisted = this._isInbandEventWhitelisted; + initSegment.privateInfos.isEMSGWhitelisted = this._isEMSGWhitelisted; return initSegment; } @@ -247,7 +247,7 @@ export default class BaseRepresentationIndex implements IRepresentationIndex { return getSegmentsFromTimeline(this._index, _up, _to, - this._isInbandEventWhitelisted, + this._isEMSGWhitelisted, this._scaledPeriodEnd); } diff --git a/src/parsers/manifest/dash/indexes/get_init_segment.ts b/src/parsers/manifest/dash/indexes/get_init_segment.ts index b6896bdc09..23274cd130 100644 --- a/src/parsers/manifest/dash/indexes/get_init_segment.ts +++ b/src/parsers/manifest/dash/indexes/get_init_segment.ts @@ -15,12 +15,12 @@ */ import { ISegment } from "../../../../manifest"; -import { IInbandEvent } from "../../../containers/isobmff"; +import { IEMSG } from "../../../containers/isobmff"; /** * Construct init segment for the given index. * @param {Object} index - * @param {function} isInbandEventWhitelisted + * @param {function} isEMSGWhitelisted * @returns {Object} */ export default function getInitSegment( @@ -28,12 +28,12 @@ export default function getInitSegment( initialization?: { mediaURLs: string[] | null; range?: [number, number] }; indexRange?: [number, number]; indexTimeOffset : number; }, - isInbandEventWhitelisted?: (inbandEvent: IInbandEvent) => boolean + isEMSGWhitelisted?: (inbandEvent: IEMSG) => boolean ) : ISegment { const { initialization } = index; let privateInfos; - if (isInbandEventWhitelisted !== undefined) { - privateInfos = { isInbandEventWhitelisted }; + if (isEMSGWhitelisted !== undefined) { + privateInfos = { isEMSGWhitelisted }; } return { id: "init", isInit: true, diff --git a/src/parsers/manifest/dash/indexes/get_segments_from_timeline.ts b/src/parsers/manifest/dash/indexes/get_segments_from_timeline.ts index 638f043451..6315c926d2 100644 --- a/src/parsers/manifest/dash/indexes/get_segments_from_timeline.ts +++ b/src/parsers/manifest/dash/indexes/get_segments_from_timeline.ts @@ -15,7 +15,7 @@ */ import { ISegment } from "../../../../manifest"; -import { IInbandEvent } from "../../../containers/isobmff"; +import { IEMSG } from "../../../containers/isobmff"; import { calculateRepeat, IIndexSegment, @@ -47,7 +47,7 @@ function getWantedRepeatIndex( * @param {Object} index - index object, constructed by parsing the manifest. * @param {number} from - starting timestamp wanted, in seconds * @param {number} durationWanted - duration wanted, in seconds - * @param {function} isInbandEventWhitelisted + * @param {function} isEMSGWhitelisted * @param {number|undefined} maximumTime * @returns {Array.} */ @@ -59,7 +59,7 @@ export default function getSegmentsFromTimeline( indexTimeOffset : number; }, from : number, durationWanted : number, - isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean, + isEMSGWhitelisted: (inbandEvent: IEMSG) => boolean, maximumTime? : number ) : ISegment[] { const scaledUp = toIndexTime(from, index); @@ -106,7 +106,7 @@ export default function getSegmentsFromTimeline( mediaURLs: detokenizedURLs, number: segmentNumber, timestampOffset: -(index.indexTimeOffset / timescale), - privateInfos: { isInbandEventWhitelisted } }; + privateInfos: { isEMSGWhitelisted } }; segments.push(segment); // update segment number and segment time for the next segment diff --git a/src/parsers/manifest/dash/indexes/list.ts b/src/parsers/manifest/dash/indexes/list.ts index e6f4a4e479..89926ce579 100644 --- a/src/parsers/manifest/dash/indexes/list.ts +++ b/src/parsers/manifest/dash/indexes/list.ts @@ -19,7 +19,7 @@ import { IRepresentationIndex, ISegment, } from "../../../../manifest"; -import { IInbandEvent } from "../../../containers/isobmff"; +import { IEMSG } from "../../../containers/isobmff"; import { getTimescaledRange } from "../../utils/index_helpers"; import getInitSegment from "./get_init_segment"; import { createIndexURLs } from "./tokens"; @@ -111,8 +111,8 @@ export interface IListIndexContextArgument { representationId? : string; /** Bitrate of the Representation concerned. */ representationBitrate? : number; - /* Function that tells if an inband event is whitelisted by the manifest */ - isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; + /* Function that tells if an EMSG is whitelisted by the manifest */ + isEMSGWhitelisted: (inbandEvent: IEMSG) => boolean; } export default class ListRepresentationIndex implements IRepresentationIndex { @@ -120,8 +120,8 @@ export default class ListRepresentationIndex implements IRepresentationIndex { private _index : IListIndex; /** Start of the period concerned by this RepresentationIndex, in seconds. */ protected _periodStart : number; - /* Function that tells if an inband event is whitelisted by the manifest */ - private _isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; + /* Function that tells if an EMSG is whitelisted by the manifest */ + private _isEMSGWhitelisted: (inbandEvent: IEMSG) => boolean; /** * @param {Object} index @@ -132,8 +132,8 @@ export default class ListRepresentationIndex implements IRepresentationIndex { representationBaseURLs, representationId, representationBitrate, - isInbandEventWhitelisted } = context; - this._isInbandEventWhitelisted = isInbandEventWhitelisted; + isEMSGWhitelisted } = context; + this._isEMSGWhitelisted = isEMSGWhitelisted; this._periodStart = periodStart; const presentationTimeOffset = index.presentationTimeOffset != null ? index.presentationTimeOffset : @@ -170,7 +170,7 @@ export default class ListRepresentationIndex implements IRepresentationIndex { if (initSegment.privateInfos === undefined) { initSegment.privateInfos = {}; } - initSegment.privateInfos.isInbandEventWhitelisted = this._isInbandEventWhitelisted; + initSegment.privateInfos.isEMSGWhitelisted = this._isEMSGWhitelisted; return initSegment; } @@ -203,8 +203,8 @@ export default class ListRepresentationIndex implements IRepresentationIndex { end: time + durationInSeconds, mediaURLs, timestampOffset: -(index.indexTimeOffset / timescale), - privateInfos: { isInbandEventWhitelisted: - this._isInbandEventWhitelisted } }; + privateInfos: { isEMSGWhitelisted: + this._isEMSGWhitelisted } }; segments.push(segment); i++; } diff --git a/src/parsers/manifest/dash/indexes/template.ts b/src/parsers/manifest/dash/indexes/template.ts index d242b33862..53b2a094ef 100644 --- a/src/parsers/manifest/dash/indexes/template.ts +++ b/src/parsers/manifest/dash/indexes/template.ts @@ -19,7 +19,7 @@ import { IRepresentationIndex, ISegment, } from "../../../../manifest"; -import { IInbandEvent } from "../../../containers/isobmff"; +import { IEMSG } from "../../../containers/isobmff"; import ManifestBoundsCalculator from "../manifest_bounds_calculator"; import getInitSegment from "./get_init_segment"; import isPeriodFulfilled from "./is_period_fulfilled"; @@ -127,8 +127,8 @@ export interface ITemplateIndexContextArgument { representationId? : string; /** Bitrate of the Representation concerned. */ representationBitrate? : number; - /* Function that tells if an inband event is whitelisted by the manifest */ - isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; + /* Function that tells if an EMSG is whitelisted by the manifest */ + isEMSGWhitelisted: (inbandEvent: IEMSG) => boolean; } /** @@ -154,8 +154,8 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex private _availabilityTimeOffset? : number; /** Whether the corresponding Manifest can be updated and changed. */ private _isDynamic : boolean; - /* Function that tells if an inband event is whitelisted by the manifest */ - private _isInbandEventWhitelisted : (inbandEvent: IInbandEvent) => boolean; + /* Function that tells if an EMSG is whitelisted by the manifest */ + private _isEMSGWhitelisted : (inbandEvent: IEMSG) => boolean; /** * @param {Object} index @@ -174,7 +174,7 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex representationBaseURLs, representationId, representationBitrate, - isInbandEventWhitelisted } = context; + isEMSGWhitelisted } = context; const timescale = index.timescale ?? 1; this._availabilityTimeOffset = availabilityTimeOffset; @@ -213,7 +213,7 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex this._periodStart = periodStart; this._scaledPeriodEnd = periodEnd == null ? undefined : (periodEnd - periodStart) * timescale; - this._isInbandEventWhitelisted = isInbandEventWhitelisted; + this._isEMSGWhitelisted = isEMSGWhitelisted; } /** @@ -221,7 +221,7 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex * @returns {Object} */ getInitSegment() : ISegment { - return getInitSegment(this._index, this._isInbandEventWhitelisted); + return getInitSegment(this._index, this._isEMSGWhitelisted); } /** @@ -294,7 +294,7 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex mediaURLs: detokenizedURLs, timestampOffset: -(index.indexTimeOffset / timescale), privateInfos: { - isInbandEventWhitelisted: this._isInbandEventWhitelisted, + isEMSGWhitelisted: this._isEMSGWhitelisted, } }; segments.push(args); numberIndexedToZero++; diff --git a/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts b/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts index ec8d9618ea..54c586b316 100644 --- a/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts +++ b/src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts @@ -25,7 +25,7 @@ import { ISegment, Representation, } from "../../../../../manifest"; -import { IInbandEvent } from "../../../../containers/isobmff"; +import { IEMSG } from "../../../../containers/isobmff"; import clearTimelineFromPosition from "../../../utils/clear_timeline_from_position"; import { checkDiscontinuity, @@ -165,8 +165,8 @@ export interface ITimelineIndexContextArgument { * Use with moderation. */ unsafelyBaseOnPreviousRepresentation : Representation | null; - /* Function that tells if an inband event is whitelisted by the manifest */ - isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; + /* Function that tells if an EMSG is whitelisted by the manifest */ + isEMSGWhitelisted: (inbandEvent: IEMSG) => boolean; } export interface ILastSegmentInformation { @@ -212,8 +212,8 @@ export default class TimelineRepresentationIndex implements IRepresentationIndex */ private _unsafelyBaseOnPreviousIndex : TimelineRepresentationIndex | null; - /* Function that tells if an inband event is whitelisted by the manifest */ - private _isInbandEventWhitelisted: (inbandEvent: IInbandEvent) => boolean; + /* Function that tells if an EMSG is whitelisted by the manifest */ + private _isEMSGWhitelisted: (inbandEvent: IEMSG) => boolean; /** * @param {Object} index @@ -231,7 +231,7 @@ export default class TimelineRepresentationIndex implements IRepresentationIndex representationBitrate, periodStart, periodEnd, - isInbandEventWhitelisted } = context; + isEMSGWhitelisted } = context; const timescale = index.timescale ?? 1; const presentationTimeOffset = index.presentationTimeOffset != null ? @@ -243,7 +243,7 @@ export default class TimelineRepresentationIndex implements IRepresentationIndex this._manifestBoundsCalculator = manifestBoundsCalculator; - this._isInbandEventWhitelisted = isInbandEventWhitelisted; + this._isEMSGWhitelisted = isEMSGWhitelisted; this._lastUpdate = context.receivedTime == null ? performance.now() : context.receivedTime; @@ -290,7 +290,7 @@ export default class TimelineRepresentationIndex implements IRepresentationIndex * @returns {Object} */ getInitSegment() : ISegment { - return getInitSegment(this._index, this._isInbandEventWhitelisted); + return getInitSegment(this._index, this._isEMSGWhitelisted); } /** @@ -318,7 +318,7 @@ export default class TimelineRepresentationIndex implements IRepresentationIndex indexTimeOffset }, from, duration, - this._isInbandEventWhitelisted, + this._isEMSGWhitelisted, this._scaledPeriodEnd); } diff --git a/src/parsers/manifest/dash/parse_representation_index.ts b/src/parsers/manifest/dash/parse_representation_index.ts index fe37f4065b..a457eecb4f 100644 --- a/src/parsers/manifest/dash/parse_representation_index.ts +++ b/src/parsers/manifest/dash/parse_representation_index.ts @@ -19,7 +19,7 @@ import { Representation, } from "../../../manifest"; import objectAssign from "../../../utils/object_assign"; -import { IInbandEvent } from "../../containers/isobmff"; +import { IEMSG } from "../../containers/isobmff"; // eslint-disable-next-line max-len import extractMinimumAvailabilityTimeOffset from "./extract_minimum_availability_time_offset"; import { @@ -105,7 +105,7 @@ export default function parseRepresentationIndex( unsafelyBaseOnPreviousRepresentation, inbandEventStreams } = representationInfos; - const isInbandEventWhitelisted = (inbandEvent: IInbandEvent): boolean => { + const isEMSGWhitelisted = (inbandEvent: IEMSG): boolean => { if (inbandEventStreams === undefined) { return false; } @@ -115,7 +115,7 @@ export default function parseRepresentationIndex( const context = { aggressiveMode, availabilityTimeOffset, unsafelyBaseOnPreviousRepresentation, - isInbandEventWhitelisted, + isEMSGWhitelisted, manifestBoundsCalculator, isDynamic, periodEnd, diff --git a/src/transports/dash/segment_parser.ts b/src/transports/dash/segment_parser.ts index 027f92b286..b89eb08587 100644 --- a/src/transports/dash/segment_parser.ts +++ b/src/transports/dash/segment_parser.ts @@ -15,17 +15,22 @@ */ import { of as observableOf } from "rxjs"; +import { + IInbandEvent, + IManifestRefreshEvent, +} from "../../core/stream"; import { getMDHDTimescale, getSegmentsFromSidx, takePSSHOut, } from "../../parsers/containers/isobmff"; -import { parseEmsgBoxes } from "../../parsers/containers/isobmff/utils"; +import { IEMSG, parseEmsgBoxes } from "../../parsers/containers/isobmff/utils"; import { getSegmentsFromCues, getTimeCodeScale, } from "../../parsers/containers/matroska"; import { BaseRepresentationIndex } from "../../parsers/manifest/dash"; +import { utf8ToStr } from "../../tools/string_utils"; import isNullOrUndefined from "../../utils/is_null_or_undefined"; import takeFirstSet from "../../utils/take_first_set"; import { @@ -50,7 +55,7 @@ export default function generateAudioVideoSegmentParser( ArrayBuffer | null > ) : IAudioVideoParserObservable { - const { period, representation, segment } = content; + const { period, representation, segment, manifest } = content; const { data, isChunked } = response; const appendWindow : [number, number | undefined] = [ period.start, period.end ]; @@ -80,26 +85,103 @@ export default function generateAudioVideoSegmentParser( segment, initTimescale); const chunkOffset = takeFirstSet(segment.timestampOffset, 0); - const parsedInbandEvents = isWEBM ? undefined : parseEmsgBoxes(chunkData); - let inbandEvents; - if (parsedInbandEvents !== undefined) { - const filteredInbandEvents = parsedInbandEvents.filter((evt) => { + const parsedEMSGs = isWEBM ? undefined : parseEmsgBoxes(chunkData); + let whitelistedEMSGs; + if (parsedEMSGs !== undefined) { + const filteredEMSGs = parsedEMSGs.filter((evt) => { if (segment.privateInfos === undefined || - segment.privateInfos.isInbandEventWhitelisted === undefined) { + segment.privateInfos.isEMSGWhitelisted === undefined) { return false; } - return segment.privateInfos.isInbandEventWhitelisted(evt); + return segment.privateInfos.isEMSGWhitelisted(evt); }); - if (filteredInbandEvents.length > 0) { - inbandEvents = filteredInbandEvents; + if (filteredEMSGs.length > 0) { + whitelistedEMSGs = filteredEMSGs; + } + } + if (whitelistedEMSGs !== undefined && + whitelistedEMSGs.length > 0) { + const { manifestRefreshEventsFromEMSGs, + EMSGs } = whitelistedEMSGs + .reduce((acc, val: IEMSG) => { + // Scheme that signals manifest update + if (val.schemeId === "urn:mpeg:dash:event:2012" && + // TODO support value 2 and 3 + val.value === "1") { + acc.manifestRefreshEventsFromEMSGs.push(val); + } else { + acc.EMSGs.push(val); + } + return acc; + }, { manifestRefreshEventsFromEMSGs: [] as IEMSG[], + EMSGs: [] as IEMSG[] }); + let manifestRefreshEvent: IManifestRefreshEvent|undefined; + if (manifestRefreshEventsFromEMSGs.length > 0) { + let minManifestExpiration: undefined | number; + const len = manifestRefreshEventsFromEMSGs.length; + for (let i = 0; i < len; i++) { + const manifestRefreshEventFromEMSGs = manifestRefreshEventsFromEMSGs[i]; + const currentManifestPublishTime = manifest.publishTime; + const { messageData } = manifestRefreshEventFromEMSGs; + const strPublishTime = utf8ToStr(messageData); + const eventManifestPublishTime = Date.parse(strPublishTime); + if (currentManifestPublishTime === undefined || + eventManifestPublishTime === undefined || + isNaN(eventManifestPublishTime) || + // DASH-if 4.3 tells (4.5.2.1) : + // "The media presentation time beyond the event time (indicated + // time by presentation_time_delta) is correctly described only + // by MPDs with publish time greater than indicated value in the + // message_data field." + // + // Here, if the current manifest has its publish time superior + // to event manifest publish time, then the manifest does not need + // to be updated + eventManifestPublishTime < currentManifestPublishTime) { + break; + } + const { timescale, presentationTimeDelta } = manifestRefreshEventFromEMSGs; + const eventPresentationTime = + (segment.time / segment.timescale) + + (presentationTimeDelta / timescale); + minManifestExpiration = + minManifestExpiration === undefined ? + eventPresentationTime : + Math.min(minManifestExpiration, + eventPresentationTime); + } + if (minManifestExpiration !== undefined) { + // redefine manifest expiration time, as typescript does not understand + // that it can't be undefined when using it in the getDelay callback + const manifestExpirationTime = minManifestExpiration; + // const delayComputingTime = performance.now(); + // const getDelay = () => { + // const now = performance.now(); + // const gap = (now - delayComputingTime) / 1000; + // return Math.max(0, manifestExpirationTime - position - gap); + // }; + manifestRefreshEvent = { type: "manifest-refresh", + value: { manifestExpirationTime } }; + } } + + const inbandEvents: IInbandEvent[] = + EMSGs.map((evt) => ({ type: "dash-emsg", + value: evt })); + + return observableOf({ type: "parsed-segment", + value: { chunkData, + chunkInfos, + chunkOffset, + appendWindow, + inbandEvents, + manifestRefreshEvent } }); } return observableOf({ type: "parsed-segment", value: { chunkData, chunkInfos, chunkOffset, - appendWindow, - inbandEvents } }); + appendWindow } }); } // we're handling an initialization segment const { indexRange } = segment; diff --git a/src/transports/types.ts b/src/transports/types.ts index 788c57829e..d782345b98 100644 --- a/src/transports/types.ts +++ b/src/transports/types.ts @@ -17,6 +17,10 @@ import { Observable, } from "rxjs"; +import { + IInbandEvent, + IManifestRefreshEvent, +} from "../core/stream"; import Manifest, { Adaptation, IRepresentationFilter, @@ -26,7 +30,6 @@ import Manifest, { Period, Representation, } from "../manifest"; -import { IInbandEvent } from "../parsers/containers/isobmff"; import { IBifThumbnail } from "../parsers/images/bif"; import { ILocalManifest } from "../parsers/manifest/local"; import { IMetaPlaylist } from "../parsers/manifest/metaplaylist"; @@ -373,6 +376,7 @@ export interface ISegmentParserParsedSegment { // (part of the segment after that time // will be ignored) inbandEvents? : IInbandEvent[]; // Inband events parsed from segment data + manifestRefreshEvent?: IManifestRefreshEvent; // Inband Manifest refresh events } // What a segment parser returns when parsing an init segment From f1c3f7aa5370631dce54e1e88aafd094dfee960c Mon Sep 17 00:00:00 2001 From: grenault73 Date: Wed, 3 Mar 2021 16:29:02 +0100 Subject: [PATCH 17/75] transports: isolate into own function inband event generation for DASH --- .../dash/get_events_out_of_emsgs.ts | 124 ++++++++++++++++++ src/transports/dash/segment_parser.ts | 119 ++++------------- 2 files changed, 149 insertions(+), 94 deletions(-) create mode 100644 src/transports/dash/get_events_out_of_emsgs.ts diff --git a/src/transports/dash/get_events_out_of_emsgs.ts b/src/transports/dash/get_events_out_of_emsgs.ts new file mode 100644 index 0000000000..0ebe610827 --- /dev/null +++ b/src/transports/dash/get_events_out_of_emsgs.ts @@ -0,0 +1,124 @@ +/** + * 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. + */ + +import { IInbandEvent, IManifestRefreshEvent } from "../../core/stream"; +import { ISegment } from "../../manifest"; +import { IEMSG } from "../../parsers/containers/isobmff"; +import { utf8ToStr } from "../../tools/string_utils"; + +/** + * Transform multiple EMSGs with manifest validity scheme id + * into one manifest refresh event + * @param {Array.} emsgs + * @param {Object} segment + * @param {number} manifestPublishTime + * @returns {undefined | Object} + */ +function getManifestRefreshEvent(emsgs: IEMSG[], + segment: ISegment, + manifestPublishTime: number +): IManifestRefreshEvent|undefined { + if (emsgs.length <= 0) { + return undefined; + } + let minManifestExpiration: undefined | number; + const len = emsgs.length; + for (let i = 0; i < len; i++) { + const manifestRefreshEventFromEMSGs = emsgs[i]; + const currentManifestPublishTime = manifestPublishTime; + const { messageData } = manifestRefreshEventFromEMSGs; + const strPublishTime = utf8ToStr(messageData); + const eventManifestPublishTime = Date.parse(strPublishTime); + if (currentManifestPublishTime === undefined || + eventManifestPublishTime === undefined || + isNaN(eventManifestPublishTime) || + // DASH-if 4.3 tells (4.5.2.1) : + // "The media presentation time beyond the event time (indicated + // time by presentation_time_delta) is correctly described only + // by MPDs with publish time greater than indicated value in the + // message_data field." + // + // Here, if the current manifest has its publish time superior + // to event manifest publish time, then the manifest does not need + // to be updated + eventManifestPublishTime < currentManifestPublishTime) { + break; + } + const { timescale, presentationTimeDelta } = manifestRefreshEventFromEMSGs; + const eventPresentationTime = + (segment.time / segment.timescale) + + (presentationTimeDelta / timescale); + minManifestExpiration = + minManifestExpiration === undefined ? + eventPresentationTime : + Math.min(minManifestExpiration, + eventPresentationTime); + } + if (minManifestExpiration === undefined) { + return undefined; + } + return { type: "manifest-refresh", + value: { manifestExpirationTime: minManifestExpiration } }; +} + +/** + * Get wrapped inband events and manifest refresh event from + * parsed ISOBMFF EMSG boxes. + * @param {Array.} parsedEMSGs + * @param {Object} segment + * @param {undefined | number} manifestPublishTime + * @returns {Object} + */ +export default function getEventsOutOfEMSGs( + parsedEMSGs: IEMSG[], + segment: ISegment, + manifestPublishTime?: number +): { manifestRefreshEvent: IManifestRefreshEvent | undefined; + inbandEvents: IInbandEvent[] | undefined; } | undefined { + if (parsedEMSGs.length === 0) { + return undefined; + } + const { manifestRefreshEventsFromEMSGs, + EMSGs } = parsedEMSGs + .reduce((acc, val: IEMSG) => { + // Scheme that signals manifest update + if (val.schemeId === "urn:mpeg:dash:event:2012" && + // TODO support value 2 and 3 + val.value === "1") { + if (acc.manifestRefreshEventsFromEMSGs === undefined) { + acc.manifestRefreshEventsFromEMSGs = []; + } + acc.manifestRefreshEventsFromEMSGs.push(val); + } else { + if (acc.EMSGs === undefined) { + acc.EMSGs = []; + } + acc.EMSGs.push(val); + } + return acc; + }, { manifestRefreshEventsFromEMSGs: undefined as IEMSG[]|undefined, + EMSGs: undefined as IEMSG[]|undefined }); + const inbandEvents = EMSGs?.map((evt) => ({ type: "dash-emsg" as const, + value: evt })); + const manifestRefreshEvent = + (manifestPublishTime === undefined || + manifestRefreshEventsFromEMSGs === undefined) ? + undefined : + getManifestRefreshEvent(manifestRefreshEventsFromEMSGs, + segment, + manifestPublishTime); + return { inbandEvents, manifestRefreshEvent }; +} diff --git a/src/transports/dash/segment_parser.ts b/src/transports/dash/segment_parser.ts index b89eb08587..13926626a5 100644 --- a/src/transports/dash/segment_parser.ts +++ b/src/transports/dash/segment_parser.ts @@ -15,22 +15,17 @@ */ import { of as observableOf } from "rxjs"; -import { - IInbandEvent, - IManifestRefreshEvent, -} from "../../core/stream"; import { getMDHDTimescale, getSegmentsFromSidx, takePSSHOut, } from "../../parsers/containers/isobmff"; -import { IEMSG, parseEmsgBoxes } from "../../parsers/containers/isobmff/utils"; +import { parseEmsgBoxes } from "../../parsers/containers/isobmff/utils"; import { getSegmentsFromCues, getTimeCodeScale, } from "../../parsers/containers/matroska"; import { BaseRepresentationIndex } from "../../parsers/manifest/dash"; -import { utf8ToStr } from "../../tools/string_utils"; import isNullOrUndefined from "../../utils/is_null_or_undefined"; import takeFirstSet from "../../utils/take_first_set"; import { @@ -40,6 +35,7 @@ import { } from "../types"; import getISOBMFFTimingInfos from "../utils/get_isobmff_timing_infos"; import isWEBMEmbeddedTrack from "../utils/is_webm_embedded_track"; +import getEventsOutOfEMSGs from "./get_events_out_of_emsgs"; /** * @param {Object} config @@ -85,98 +81,33 @@ export default function generateAudioVideoSegmentParser( segment, initTimescale); const chunkOffset = takeFirstSet(segment.timestampOffset, 0); - const parsedEMSGs = isWEBM ? undefined : parseEmsgBoxes(chunkData); - let whitelistedEMSGs; - if (parsedEMSGs !== undefined) { - const filteredEMSGs = parsedEMSGs.filter((evt) => { - if (segment.privateInfos === undefined || - segment.privateInfos.isEMSGWhitelisted === undefined) { - return false; - } - return segment.privateInfos.isEMSGWhitelisted(evt); - }); - if (filteredEMSGs.length > 0) { - whitelistedEMSGs = filteredEMSGs; - } - } - if (whitelistedEMSGs !== undefined && - whitelistedEMSGs.length > 0) { - const { manifestRefreshEventsFromEMSGs, - EMSGs } = whitelistedEMSGs - .reduce((acc, val: IEMSG) => { - // Scheme that signals manifest update - if (val.schemeId === "urn:mpeg:dash:event:2012" && - // TODO support value 2 and 3 - val.value === "1") { - acc.manifestRefreshEventsFromEMSGs.push(val); - } else { - acc.EMSGs.push(val); - } - return acc; - }, { manifestRefreshEventsFromEMSGs: [] as IEMSG[], - EMSGs: [] as IEMSG[] }); - let manifestRefreshEvent: IManifestRefreshEvent|undefined; - if (manifestRefreshEventsFromEMSGs.length > 0) { - let minManifestExpiration: undefined | number; - const len = manifestRefreshEventsFromEMSGs.length; - for (let i = 0; i < len; i++) { - const manifestRefreshEventFromEMSGs = manifestRefreshEventsFromEMSGs[i]; - const currentManifestPublishTime = manifest.publishTime; - const { messageData } = manifestRefreshEventFromEMSGs; - const strPublishTime = utf8ToStr(messageData); - const eventManifestPublishTime = Date.parse(strPublishTime); - if (currentManifestPublishTime === undefined || - eventManifestPublishTime === undefined || - isNaN(eventManifestPublishTime) || - // DASH-if 4.3 tells (4.5.2.1) : - // "The media presentation time beyond the event time (indicated - // time by presentation_time_delta) is correctly described only - // by MPDs with publish time greater than indicated value in the - // message_data field." - // - // Here, if the current manifest has its publish time superior - // to event manifest publish time, then the manifest does not need - // to be updated - eventManifestPublishTime < currentManifestPublishTime) { - break; + + if (!isWEBM) { + const parsedEMSGs = parseEmsgBoxes(chunkData); + if (parsedEMSGs !== undefined) { + const whitelistedEMSGs = parsedEMSGs.filter((evt) => { + if (segment.privateInfos === undefined || + segment.privateInfos.isEMSGWhitelisted === undefined) { + return false; } - const { timescale, presentationTimeDelta } = manifestRefreshEventFromEMSGs; - const eventPresentationTime = - (segment.time / segment.timescale) + - (presentationTimeDelta / timescale); - minManifestExpiration = - minManifestExpiration === undefined ? - eventPresentationTime : - Math.min(minManifestExpiration, - eventPresentationTime); - } - if (minManifestExpiration !== undefined) { - // redefine manifest expiration time, as typescript does not understand - // that it can't be undefined when using it in the getDelay callback - const manifestExpirationTime = minManifestExpiration; - // const delayComputingTime = performance.now(); - // const getDelay = () => { - // const now = performance.now(); - // const gap = (now - delayComputingTime) / 1000; - // return Math.max(0, manifestExpirationTime - position - gap); - // }; - manifestRefreshEvent = { type: "manifest-refresh", - value: { manifestExpirationTime } }; + return segment.privateInfos.isEMSGWhitelisted(evt); + }); + const events = getEventsOutOfEMSGs(whitelistedEMSGs, + segment, + manifest.publishTime); + if (events !== undefined) { + const { manifestRefreshEvent, inbandEvents } = events; + return observableOf({ type: "parsed-segment", + value: { chunkData, + chunkInfos, + chunkOffset, + appendWindow, + inbandEvents, + manifestRefreshEvent } }); } } - - const inbandEvents: IInbandEvent[] = - EMSGs.map((evt) => ({ type: "dash-emsg", - value: evt })); - - return observableOf({ type: "parsed-segment", - value: { chunkData, - chunkInfos, - chunkOffset, - appendWindow, - inbandEvents, - manifestRefreshEvent } }); } + return observableOf({ type: "parsed-segment", value: { chunkData, chunkInfos, From 0a41495d6dbb3128eaa4b02c9b5578dd19fef3f7 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Tue, 9 Mar 2021 17:33:23 +0100 Subject: [PATCH 18/75] parsers: DASH base - add isEMSG... in init segment function --- src/parsers/manifest/dash/indexes/base.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/parsers/manifest/dash/indexes/base.ts b/src/parsers/manifest/dash/indexes/base.ts index 3071bc105c..f84bae8cb8 100644 --- a/src/parsers/manifest/dash/indexes/base.ts +++ b/src/parsers/manifest/dash/indexes/base.ts @@ -230,12 +230,7 @@ export default class BaseRepresentationIndex implements IRepresentationIndex { * @returns {Object} */ getInitSegment() : ISegment { - const initSegment = getInitSegment(this._index); - if (initSegment.privateInfos === undefined) { - initSegment.privateInfos = {}; - } - initSegment.privateInfos.isEMSGWhitelisted = this._isEMSGWhitelisted; - return initSegment; + return getInitSegment(this._index, this._isEMSGWhitelisted); } /** From a46fb9b9cdaea36c04b6ad1db9819286e541633c Mon Sep 17 00:00:00 2001 From: grenault73 Date: Tue, 9 Mar 2021 17:34:17 +0100 Subject: [PATCH 19/75] manifest: update publishTime when updating manifest --- src/manifest/manifest.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/manifest/manifest.ts b/src/manifest/manifest.ts index c87f2cd061..64dc04013e 100644 --- a/src/manifest/manifest.ts +++ b/src/manifest/manifest.ts @@ -690,6 +690,7 @@ export default class Manifest extends EventEmitter { this.parsingErrors = newManifest.parsingErrors; this.suggestedPresentationDelay = newManifest.suggestedPresentationDelay; this.transport = newManifest.transport; + this.publishTime = newManifest.publishTime; if (updateType === MANIFEST_UPDATE_TYPE.Full) { this._timeBounds = newManifest._timeBounds; From 1b08d136dfca57a69d9b6c60e506ddd9b2bbd8ef Mon Sep 17 00:00:00 2001 From: grenault73 Date: Tue, 9 Mar 2021 17:52:40 +0100 Subject: [PATCH 20/75] stream: update manifest right after having received manifest validity emsg --- src/core/init/initialize_media_source.ts | 5 ++-- src/core/init/manifest_update_scheduler.ts | 11 ++++---- src/core/stream/events_generators.ts | 4 +-- .../representation/representation_stream.ts | 22 +++------------ src/core/stream/types.ts | 2 +- .../dash/get_events_out_of_emsgs.ts | 27 +++---------------- src/transports/dash/segment_parser.ts | 1 - 7 files changed, 17 insertions(+), 55 deletions(-) diff --git a/src/core/init/initialize_media_source.ts b/src/core/init/initialize_media_source.ts index c3b789832a..102de44d12 100644 --- a/src/core/init/initialize_media_source.ts +++ b/src/core/init/initialize_media_source.ts @@ -342,14 +342,13 @@ export default function InitializeOnMediaSource( switch (evt.type) { case "needs-manifest-refresh": scheduleRefresh$.next({ completeRefresh: false, - canUseUnsafeMode: true, - getRefreshDelay: evt.value?.getDelay }); + canUseUnsafeMode: true }); return null; case "manifest-might-be-out-of-sync": scheduleRefresh$.next({ completeRefresh: true, canUseUnsafeMode: false, - getRefreshDelay: () => OUT_OF_SYNC_MANIFEST_REFRESH_DELAY, + delay: OUT_OF_SYNC_MANIFEST_REFRESH_DELAY, }); return null; case "needs-media-source-reload": diff --git a/src/core/init/manifest_update_scheduler.ts b/src/core/init/manifest_update_scheduler.ts index 483b851a7d..37e9a0af77 100644 --- a/src/core/init/manifest_update_scheduler.ts +++ b/src/core/init/manifest_update_scheduler.ts @@ -76,10 +76,10 @@ export interface IManifestRefreshSchedulerEvent { */ completeRefresh : boolean; /** - * Optional function that returns the wanted refresh delay, which is the minimum + * Optional number that is the wanted refresh delay, which is the minimum * time you want to wait before updating the Manifest */ - getRefreshDelay? : () => number; + delay? : number; /** * Whether the parsing can be done in the more efficient "unsafeMode". * This mode is extremely fast but can lead to de-synchronisation with the @@ -148,11 +148,10 @@ export default function manifestUpdateScheduler({ false; const internalRefresh$ = scheduleRefresh$ - .pipe(mergeMap(({ completeRefresh, getRefreshDelay, canUseUnsafeMode }) => { + .pipe(mergeMap(({ completeRefresh, delay, canUseUnsafeMode }) => { const unsafeMode = canUseUnsafeMode && unsafeModeEnabled; - const delay = getRefreshDelay === undefined ? 0 : - getRefreshDelay(); - return startManualRefreshTimer(delay, + const wantedDelay = delay === undefined ? 0 : delay; + return startManualRefreshTimer(wantedDelay, minimumManifestUpdateInterval, sendingTime) .pipe(mapTo({ completeRefresh, unsafeMode })); diff --git a/src/core/stream/events_generators.ts b/src/core/stream/events_generators.ts index 0e3fe45c6f..494f63726e 100644 --- a/src/core/stream/events_generators.ts +++ b/src/core/stream/events_generators.ts @@ -93,9 +93,9 @@ const EVENTS = { value: undefined }; }, - needsManifestRefresh(getDelay?: () => number) : IStreamNeedsManifestRefresh { + needsManifestRefresh() : IStreamNeedsManifestRefresh { return { type : "needs-manifest-refresh", - value : (getDelay !== undefined) ? { getDelay } : undefined }; + value : undefined }; }, manifestMightBeOufOfSync() : IStreamManifestMightBeOutOfSync { diff --git a/src/core/stream/representation/representation_stream.ts b/src/core/stream/representation/representation_stream.ts index fc47007e5e..f89be94929 100644 --- a/src/core/stream/representation/representation_stream.ts +++ b/src/core/stream/representation/representation_stream.ts @@ -487,25 +487,9 @@ export default function RepresentationStream({ if (evt.value.inbandEvents !== undefined) { const { inbandEvents, manifestRefreshEvent } = evt.value; - const manifestRefresh$ = clock$.pipe( - take(1), - mergeMap(({ position }) => { - if (manifestRefreshEvent === undefined) { - return EMPTY; - } - // redefine manifest expiration time, as typescript does not - // understand that it can't be undefined when using it in the - // getDelay callback - const { manifestExpirationTime } = manifestRefreshEvent.value; - const delayComputingTime = performance.now(); - const getDelay = () => { - const now = performance.now(); - const gap = (now - delayComputingTime) / 1000; - return Math.max(0, manifestExpirationTime - position - gap); - }; - return observableOf(EVENTS.needsManifestRefresh(getDelay)); - }) - ); + const manifestRefresh$ = manifestRefreshEvent === undefined ? + EMPTY : + observableOf(EVENTS.needsManifestRefresh()); const inbandEvents$ = inbandEvents.length > 0 ? observableOf({ type: "inband-events" as const, value: inbandEvents }) : diff --git a/src/core/stream/types.ts b/src/core/stream/types.ts index d8a5e0ba8f..e835e48ee9 100644 --- a/src/core/stream/types.ts +++ b/src/core/stream/types.ts @@ -178,7 +178,7 @@ export interface IInbandEvent { type: "dash-emsg"; value: IEMSG; } export interface IManifestRefreshEvent { type: "manifest-refresh"; - value: { manifestExpirationTime: number }; } + value: undefined; } export interface IInbandEventsEvent { type : "inband-events"; value : IInbandEvent[]; } diff --git a/src/transports/dash/get_events_out_of_emsgs.ts b/src/transports/dash/get_events_out_of_emsgs.ts index 0ebe610827..5730490467 100644 --- a/src/transports/dash/get_events_out_of_emsgs.ts +++ b/src/transports/dash/get_events_out_of_emsgs.ts @@ -15,7 +15,6 @@ */ import { IInbandEvent, IManifestRefreshEvent } from "../../core/stream"; -import { ISegment } from "../../manifest"; import { IEMSG } from "../../parsers/containers/isobmff"; import { utf8ToStr } from "../../tools/string_utils"; @@ -28,13 +27,11 @@ import { utf8ToStr } from "../../tools/string_utils"; * @returns {undefined | Object} */ function getManifestRefreshEvent(emsgs: IEMSG[], - segment: ISegment, manifestPublishTime: number ): IManifestRefreshEvent|undefined { if (emsgs.length <= 0) { return undefined; } - let minManifestExpiration: undefined | number; const len = emsgs.length; for (let i = 0; i < len; i++) { const manifestRefreshEventFromEMSGs = emsgs[i]; @@ -51,27 +48,13 @@ function getManifestRefreshEvent(emsgs: IEMSG[], // by MPDs with publish time greater than indicated value in the // message_data field." // - // Here, if the current manifest has its publish time superior - // to event manifest publish time, then the manifest does not need + // Here, if the current manifest has its publish time inferior or + // identical to the event manifest publish time, then the manifest needs // to be updated - eventManifestPublishTime < currentManifestPublishTime) { - break; + eventManifestPublishTime >= currentManifestPublishTime) { + return { type: "manifest-refresh", value: undefined }; } - const { timescale, presentationTimeDelta } = manifestRefreshEventFromEMSGs; - const eventPresentationTime = - (segment.time / segment.timescale) + - (presentationTimeDelta / timescale); - minManifestExpiration = - minManifestExpiration === undefined ? - eventPresentationTime : - Math.min(minManifestExpiration, - eventPresentationTime); } - if (minManifestExpiration === undefined) { - return undefined; - } - return { type: "manifest-refresh", - value: { manifestExpirationTime: minManifestExpiration } }; } /** @@ -84,7 +67,6 @@ function getManifestRefreshEvent(emsgs: IEMSG[], */ export default function getEventsOutOfEMSGs( parsedEMSGs: IEMSG[], - segment: ISegment, manifestPublishTime?: number ): { manifestRefreshEvent: IManifestRefreshEvent | undefined; inbandEvents: IInbandEvent[] | undefined; } | undefined { @@ -118,7 +100,6 @@ export default function getEventsOutOfEMSGs( manifestRefreshEventsFromEMSGs === undefined) ? undefined : getManifestRefreshEvent(manifestRefreshEventsFromEMSGs, - segment, manifestPublishTime); return { inbandEvents, manifestRefreshEvent }; } diff --git a/src/transports/dash/segment_parser.ts b/src/transports/dash/segment_parser.ts index 13926626a5..0d31f1fee6 100644 --- a/src/transports/dash/segment_parser.ts +++ b/src/transports/dash/segment_parser.ts @@ -93,7 +93,6 @@ export default function generateAudioVideoSegmentParser( return segment.privateInfos.isEMSGWhitelisted(evt); }); const events = getEventsOutOfEMSGs(whitelistedEMSGs, - segment, manifest.publishTime); if (events !== undefined) { const { manifestRefreshEvent, inbandEvents } = events; From 92f73aa2e8b26310c057cdd51a4e07bbb6110d32 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Wed, 10 Mar 2021 17:46:40 +0100 Subject: [PATCH 21/75] various fixes --- src/core/init/manifest_update_scheduler.ts | 7 +++---- src/core/stream/types.ts | 7 +------ 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/core/init/manifest_update_scheduler.ts b/src/core/init/manifest_update_scheduler.ts index 37e9a0af77..65e5cf22f4 100644 --- a/src/core/init/manifest_update_scheduler.ts +++ b/src/core/init/manifest_update_scheduler.ts @@ -76,8 +76,8 @@ export interface IManifestRefreshSchedulerEvent { */ completeRefresh : boolean; /** - * Optional number that is the wanted refresh delay, which is the minimum - * time you want to wait before updating the Manifest + * Optional wanted refresh delay, which is the minimum time you want to wait + * before updating the Manifest */ delay? : number; /** @@ -150,8 +150,7 @@ export default function manifestUpdateScheduler({ const internalRefresh$ = scheduleRefresh$ .pipe(mergeMap(({ completeRefresh, delay, canUseUnsafeMode }) => { const unsafeMode = canUseUnsafeMode && unsafeModeEnabled; - const wantedDelay = delay === undefined ? 0 : delay; - return startManualRefreshTimer(wantedDelay, + return startManualRefreshTimer(delay ?? 0, minimumManifestUpdateInterval, sendingTime) .pipe(mapTo({ completeRefresh, unsafeMode })); diff --git a/src/core/stream/types.ts b/src/core/stream/types.ts index e835e48ee9..df3d468528 100644 --- a/src/core/stream/types.ts +++ b/src/core/stream/types.ts @@ -138,12 +138,7 @@ export interface IStreamEventAddedSegment { */ export interface IStreamNeedsManifestRefresh { type : "needs-manifest-refresh"; - /** - * The function returns a delay that is the wanted delay that the scheduler - * has to wait before refreshing the manifest. It may equals the delay until the - * current used manifest will expire. - */ - value : undefined | { getDelay: () => number }; + value: undefined; } /** From 35411135af1e455a5ccfa1a3aad517102fef0b75 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Tue, 16 Mar 2021 15:58:16 +0100 Subject: [PATCH 22/75] transports: manifest refresh event is know needsManifestRefresh --- .../representation/representation_stream.ts | 8 ++--- src/core/stream/types.ts | 3 -- .../dash/get_events_out_of_emsgs.ts | 31 ++++++++++--------- src/transports/dash/segment_parser.ts | 4 +-- src/transports/types.ts | 8 ++--- 5 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/core/stream/representation/representation_stream.ts b/src/core/stream/representation/representation_stream.ts index f89be94929..d79f78408e 100644 --- a/src/core/stream/representation/representation_stream.ts +++ b/src/core/stream/representation/representation_stream.ts @@ -486,10 +486,10 @@ export default function RepresentationStream({ const initSegmentData = initSegmentObject?.initializationData ?? null; if (evt.value.inbandEvents !== undefined) { const { inbandEvents, - manifestRefreshEvent } = evt.value; - const manifestRefresh$ = manifestRefreshEvent === undefined ? - EMPTY : - observableOf(EVENTS.needsManifestRefresh()); + needsManifestRefresh } = evt.value; + const manifestRefresh$ = needsManifestRefresh === true ? + observableOf(EVENTS.needsManifestRefresh()) : + EMPTY; const inbandEvents$ = inbandEvents.length > 0 ? observableOf({ type: "inband-events" as const, value: inbandEvents }) : diff --git a/src/core/stream/types.ts b/src/core/stream/types.ts index df3d468528..c1b33c830d 100644 --- a/src/core/stream/types.ts +++ b/src/core/stream/types.ts @@ -172,9 +172,6 @@ export interface IProtectedSegmentEvent { export interface IInbandEvent { type: "dash-emsg"; value: IEMSG; } -export interface IManifestRefreshEvent { type: "manifest-refresh"; - value: undefined; } - export interface IInbandEventsEvent { type : "inband-events"; value : IInbandEvent[]; } diff --git a/src/transports/dash/get_events_out_of_emsgs.ts b/src/transports/dash/get_events_out_of_emsgs.ts index 5730490467..3bdff0a24f 100644 --- a/src/transports/dash/get_events_out_of_emsgs.ts +++ b/src/transports/dash/get_events_out_of_emsgs.ts @@ -14,23 +14,23 @@ * limitations under the License. */ -import { IInbandEvent, IManifestRefreshEvent } from "../../core/stream"; +import { IInbandEvent } from "../../core/stream"; import { IEMSG } from "../../parsers/containers/isobmff"; import { utf8ToStr } from "../../tools/string_utils"; /** - * Transform multiple EMSGs with manifest validity scheme id - * into one manifest refresh event + * From an array of EMSGs with manifest validity scheme id, + * tells if the manifest needs to be refreshed. * @param {Array.} emsgs * @param {Object} segment * @param {number} manifestPublishTime - * @returns {undefined | Object} + * @returns {boolean} */ -function getManifestRefreshEvent(emsgs: IEMSG[], - manifestPublishTime: number -): IManifestRefreshEvent|undefined { +function manifestNeedsToBeRefreshed(emsgs: IEMSG[], + manifestPublishTime: number +): boolean { if (emsgs.length <= 0) { - return undefined; + return false; } const len = emsgs.length; for (let i = 0; i < len; i++) { @@ -52,9 +52,10 @@ function getManifestRefreshEvent(emsgs: IEMSG[], // identical to the event manifest publish time, then the manifest needs // to be updated eventManifestPublishTime >= currentManifestPublishTime) { - return { type: "manifest-refresh", value: undefined }; + return true; } } + return false; } /** @@ -68,7 +69,7 @@ function getManifestRefreshEvent(emsgs: IEMSG[], export default function getEventsOutOfEMSGs( parsedEMSGs: IEMSG[], manifestPublishTime?: number -): { manifestRefreshEvent: IManifestRefreshEvent | undefined; +): { needsManifestRefresh: boolean; inbandEvents: IInbandEvent[] | undefined; } | undefined { if (parsedEMSGs.length === 0) { return undefined; @@ -95,11 +96,11 @@ export default function getEventsOutOfEMSGs( EMSGs: undefined as IEMSG[]|undefined }); const inbandEvents = EMSGs?.map((evt) => ({ type: "dash-emsg" as const, value: evt })); - const manifestRefreshEvent = + const needsManifestRefresh = (manifestPublishTime === undefined || manifestRefreshEventsFromEMSGs === undefined) ? - undefined : - getManifestRefreshEvent(manifestRefreshEventsFromEMSGs, - manifestPublishTime); - return { inbandEvents, manifestRefreshEvent }; + false : + manifestNeedsToBeRefreshed(manifestRefreshEventsFromEMSGs, + manifestPublishTime); + return { inbandEvents, needsManifestRefresh }; } diff --git a/src/transports/dash/segment_parser.ts b/src/transports/dash/segment_parser.ts index 0d31f1fee6..671cdbbdd8 100644 --- a/src/transports/dash/segment_parser.ts +++ b/src/transports/dash/segment_parser.ts @@ -95,14 +95,14 @@ export default function generateAudioVideoSegmentParser( const events = getEventsOutOfEMSGs(whitelistedEMSGs, manifest.publishTime); if (events !== undefined) { - const { manifestRefreshEvent, inbandEvents } = events; + const { needsManifestRefresh, inbandEvents } = events; return observableOf({ type: "parsed-segment", value: { chunkData, chunkInfos, chunkOffset, appendWindow, inbandEvents, - manifestRefreshEvent } }); + needsManifestRefresh } }); } } } diff --git a/src/transports/types.ts b/src/transports/types.ts index d782345b98..db6064ac08 100644 --- a/src/transports/types.ts +++ b/src/transports/types.ts @@ -17,10 +17,7 @@ import { Observable, } from "rxjs"; -import { - IInbandEvent, - IManifestRefreshEvent, -} from "../core/stream"; +import { IInbandEvent } from "../core/stream"; import Manifest, { Adaptation, IRepresentationFilter, @@ -376,7 +373,8 @@ export interface ISegmentParserParsedSegment { // (part of the segment after that time // will be ignored) inbandEvents? : IInbandEvent[]; // Inband events parsed from segment data - manifestRefreshEvent?: IManifestRefreshEvent; // Inband Manifest refresh events + needsManifestRefresh?: boolean; // Tells if the result of the parsing shows + // that the manifest should be refreshed } // What a segment parser returns when parsing an init segment From dadf6a51b57a4b6328b9a1a0be9734d6704e47cf Mon Sep 17 00:00:00 2001 From: grenault73 Date: Tue, 16 Mar 2021 16:03:55 +0100 Subject: [PATCH 23/75] api: added event 'inbandEvents' --- src/core/api/public_api.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/core/api/public_api.ts b/src/core/api/public_api.ts index 1eb8e8b452..a294e123db 100644 --- a/src/core/api/public_api.ts +++ b/src/core/api/public_api.ts @@ -220,7 +220,7 @@ interface IPublicAPIEvent { seeked : null; streamEvent : IStreamEvent; streamEventSkip : IStreamEvent; - inbandEvent : IInbandEvent; + inbandEvents : IInbandEvent[]; } /** @@ -2272,11 +2272,7 @@ class Player extends EventEmitter { switch (event.type) { case "inband-events": const inbandEvents = event.value; - const eventNbr = inbandEvents.length; - for (let i = 0; i < eventNbr; i++) { - const inbandEvent = inbandEvents[i]; - this.trigger("inbandEvent", inbandEvent); - } + this.trigger("inbandEvents", inbandEvents); return; case "stream-event": this.trigger("streamEvent", event.value); From b75365c92f1add00f95f9aaae62c8e0c1b5bc328 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Mon, 22 Mar 2021 15:29:48 +0100 Subject: [PATCH 24/75] transports: import string parsing from utils --- src/transports/dash/get_events_out_of_emsgs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transports/dash/get_events_out_of_emsgs.ts b/src/transports/dash/get_events_out_of_emsgs.ts index 3bdff0a24f..0a587910e7 100644 --- a/src/transports/dash/get_events_out_of_emsgs.ts +++ b/src/transports/dash/get_events_out_of_emsgs.ts @@ -16,7 +16,7 @@ import { IInbandEvent } from "../../core/stream"; import { IEMSG } from "../../parsers/containers/isobmff"; -import { utf8ToStr } from "../../tools/string_utils"; +import { utf8ToStr } from "../../utils/string_parsing"; /** * From an array of EMSGs with manifest validity scheme id, From 8ec5098bb0ced51252a17c8f94c55611a0f3eef5 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Mon, 22 Mar 2021 15:53:51 +0100 Subject: [PATCH 25/75] parsers: break when no more emsgs instead of returning --- src/parsers/containers/isobmff/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parsers/containers/isobmff/utils.ts b/src/parsers/containers/isobmff/utils.ts index d46cdc0941..b2fa9d964d 100644 --- a/src/parsers/containers/isobmff/utils.ts +++ b/src/parsers/containers/isobmff/utils.ts @@ -432,7 +432,7 @@ function parseEmsgBoxes(buffer: Uint8Array) : IEMSG[] | undefined { while (offset < buffer.length) { const emsg = getEMSG(buffer, offset); if (emsg === null) { - return emsgs; + break; } const length = emsg.length; offset += length; From f56a308f7d54befe852543b0e3aba0678fa64cdf Mon Sep 17 00:00:00 2001 From: grenault73 Date: Tue, 23 Mar 2021 18:28:29 +0100 Subject: [PATCH 26/75] stream: fixed no needsmanifestrefresh when no inband events --- .../representation/representation_stream.ts | 44 ++++++++----------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/src/core/stream/representation/representation_stream.ts b/src/core/stream/representation/representation_stream.ts index d79f78408e..208a952b7b 100644 --- a/src/core/stream/representation/representation_stream.ts +++ b/src/core/stream/representation/representation_stream.ts @@ -484,32 +484,24 @@ export default function RepresentationStream({ case "parsed-segment": const initSegmentData = initSegmentObject?.initializationData ?? null; - if (evt.value.inbandEvents !== undefined) { - const { inbandEvents, - needsManifestRefresh } = evt.value; - const manifestRefresh$ = needsManifestRefresh === true ? - observableOf(EVENTS.needsManifestRefresh()) : - EMPTY; - const inbandEvents$ = inbandEvents.length > 0 ? - observableOf({ type: "inband-events" as const, - value: inbandEvents }) : - EMPTY; - return observableConcat(manifestRefresh$, - inbandEvents$, - pushMediaSegment({ clock$, - content, - initSegmentData, - parsedSegment: evt.value, - segment: evt.segment, - segmentBuffer })); - } - return pushMediaSegment({ clock$, - content, - initSegmentData, - parsedSegment: evt.value, - segment: evt.segment, - segmentBuffer }); - + const { inbandEvents, + needsManifestRefresh } = evt.value; + const manifestRefresh$ = needsManifestRefresh === true ? + observableOf(EVENTS.needsManifestRefresh()) : + EMPTY; + const inbandEvents$ = inbandEvents !== undefined && + inbandEvents.length > 0 ? + observableOf({ type: "inband-events" as const, + value: inbandEvents }) : + EMPTY; + return observableConcat(manifestRefresh$, + inbandEvents$, + pushMediaSegment({ clock$, + content, + initSegmentData, + parsedSegment: evt.value, + segment: evt.segment, + segmentBuffer })); case "end-of-segment": { const { segment } = evt.value; return segmentBuffer.endOfSegment(objectAssign({ segment }, content)) From 252ef52cd06295d088965869727c73a0624adf90 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Tue, 23 Mar 2021 18:29:10 +0100 Subject: [PATCH 27/75] parsers: update isobmff utils jsdoc --- src/parsers/containers/isobmff/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parsers/containers/isobmff/utils.ts b/src/parsers/containers/isobmff/utils.ts index b2fa9d964d..88a3f3e3bf 100644 --- a/src/parsers/containers/isobmff/utils.ts +++ b/src/parsers/containers/isobmff/utils.ts @@ -424,7 +424,7 @@ function updateBoxLength(buf : Uint8Array) : Uint8Array { /** * Parse EMSG boxes from ISOBMFF data. * @param {Uint8Array} buf - * @returns {Array.} + * @returns {Array. | undefined} */ function parseEmsgBoxes(buffer: Uint8Array) : IEMSG[] | undefined { const emsgs: IEMSG[] = []; From d0c1f738610b93f5d2090c197f6c5904d0d17e52 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Tue, 23 Mar 2021 18:57:09 +0100 Subject: [PATCH 28/75] doc: add inbandEvents doc --- doc/api/player_events.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/doc/api/player_events.md b/doc/api/player_events.md index d8c09f6641..dd46d580b1 100644 --- a/doc/api/player_events.md +++ b/doc/api/player_events.md @@ -27,6 +27,7 @@ - [Playback information](#events-playback-infos) - [periodChange](#events-periodChange) - [decipherabilityUpdate](#events-decipherabilityUpdate) + - [inbandEvents](#events-inbandEvents) - [streamEvent](events-streamEvent) - [streamEventSkip](events-streamEventSkip) - [Deprecated](#events-deprecated) @@ -560,6 +561,27 @@ You can then know if any of those Representations are becoming decipherable or not through their `decipherable` property. + +### inbandEvents ############################################################### + +_payload type_: ``Object`` + +--- + +:warning: This event is not sent in _DirectFile_ mode (see [loadVideo +options](./loadVideo_options.md#prop-transport)). + +--- + +Event triggered when the player encounters inband events in the stream. These +events are included in the loaded and parsed chunks, and are often used to carry +content metadata. + +Each event contains : + - type (_type_: ``String``) : defines the type of the message, specific to an + inband event from a streaming protocol. + - value (_type_: ``Object``) : the actual parsed content of the message. + ### streamEvent ################################################################ From 0d58507e1a6eaf7de9f509b3ccc79b5407f0ba86 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Thu, 25 Mar 2021 16:36:38 +0100 Subject: [PATCH 29/75] parsers: EMSG contains standard schemeIdUri --- src/core/stream/types.ts | 2 +- src/parsers/containers/isobmff/utils.ts | 8 ++++---- src/parsers/manifest/dash/parse_representation_index.ts | 2 +- src/transports/dash/get_events_out_of_emsgs.ts | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/core/stream/types.ts b/src/core/stream/types.ts index c1b33c830d..5c4c77f561 100644 --- a/src/core/stream/types.ts +++ b/src/core/stream/types.ts @@ -169,7 +169,7 @@ export interface IProtectedSegmentEvent { value : ISegmentProtection; } -export interface IInbandEvent { type: "dash-emsg"; +export interface IInbandEvent { type: "emsg"; value: IEMSG; } export interface IInbandEventsEvent { type : "inband-events"; diff --git a/src/parsers/containers/isobmff/utils.ts b/src/parsers/containers/isobmff/utils.ts index 88a3f3e3bf..0cd729e918 100644 --- a/src/parsers/containers/isobmff/utils.ts +++ b/src/parsers/containers/isobmff/utils.ts @@ -49,7 +49,7 @@ export interface IISOBMFFPSSHInfo { privateData : Uint8Array; } -export interface IEMSG { schemeId: string; +export interface IEMSG { schemeIdUri: string; value: string; timescale: number; presentationTimeDelta: number; @@ -439,9 +439,9 @@ function parseEmsgBoxes(buffer: Uint8Array) : IEMSG[] | undefined { let position = 4; // skip version + flags - const { end: schemeIdEnd, string: schemeId } = + const { end: schemeIdEnd, string: schemeIdUri } = readNullTerminatedString(emsg, position); - position = schemeIdEnd; // skip schemeId + position = schemeIdEnd; // skip schemeIdUri const { end: valueEnd, string: value } = readNullTerminatedString(emsg, position); position = valueEnd; // skip value @@ -460,7 +460,7 @@ function parseEmsgBoxes(buffer: Uint8Array) : IEMSG[] | undefined { const messageData = emsg.subarray(position, length); - const emsgData = { schemeId, + const emsgData = { schemeIdUri, value, timescale, presentationTimeDelta, diff --git a/src/parsers/manifest/dash/parse_representation_index.ts b/src/parsers/manifest/dash/parse_representation_index.ts index a457eecb4f..21cf012747 100644 --- a/src/parsers/manifest/dash/parse_representation_index.ts +++ b/src/parsers/manifest/dash/parse_representation_index.ts @@ -110,7 +110,7 @@ export default function parseRepresentationIndex( return false; } return inbandEventStreams - .some(({ schemeIdUri }) => schemeIdUri === inbandEvent.schemeId); + .some(({ schemeIdUri }) => schemeIdUri === inbandEvent.schemeIdUri); }; const context = { aggressiveMode, availabilityTimeOffset, diff --git a/src/transports/dash/get_events_out_of_emsgs.ts b/src/transports/dash/get_events_out_of_emsgs.ts index 0a587910e7..e5da04f833 100644 --- a/src/transports/dash/get_events_out_of_emsgs.ts +++ b/src/transports/dash/get_events_out_of_emsgs.ts @@ -78,7 +78,7 @@ export default function getEventsOutOfEMSGs( EMSGs } = parsedEMSGs .reduce((acc, val: IEMSG) => { // Scheme that signals manifest update - if (val.schemeId === "urn:mpeg:dash:event:2012" && + if (val.schemeIdUri === "urn:mpeg:dash:event:2012" && // TODO support value 2 and 3 val.value === "1") { if (acc.manifestRefreshEventsFromEMSGs === undefined) { @@ -94,7 +94,7 @@ export default function getEventsOutOfEMSGs( return acc; }, { manifestRefreshEventsFromEMSGs: undefined as IEMSG[]|undefined, EMSGs: undefined as IEMSG[]|undefined }); - const inbandEvents = EMSGs?.map((evt) => ({ type: "dash-emsg" as const, + const inbandEvents = EMSGs?.map((evt) => ({ type: "emsg" as const, value: evt })); const needsManifestRefresh = (manifestPublishTime === undefined || From 6891c2045296717cd55175c48fd17ec9e102bd69 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Thu, 25 Mar 2021 16:55:35 +0100 Subject: [PATCH 30/75] doc: add EMSG specific documentation --- doc/api/player_events.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/api/player_events.md b/doc/api/player_events.md index dd46d580b1..29d4a9445b 100644 --- a/doc/api/player_events.md +++ b/doc/api/player_events.md @@ -578,9 +578,23 @@ events are included in the loaded and parsed chunks, and are often used to carry content metadata. Each event contains : - - type (_type_: ``String``) : defines the type of the message, specific to an + - type (_type_: ``String``) : defines the type of the event, specific to an inband event from a streaming protocol. - - value (_type_: ``Object``) : the actual parsed content of the message. + - value (_type_: ``Object``) : the actual parsed content of the event. + +The supported inband event types are : +- "emsg" : The emsg (Event message box) provides inband signaling for generic + or MPEG-DASH specific events. +One ISOBMFF media segment may contain one or several boxes. The parsed event contains : + - schemeIdUri (``String``) + - value (``String``) + - timescale (``Number``) + - presentationTimeDelta (``Number``) + - eventDuration (``Number``) + - id (``Number``) + - messageData (``Uint8Array``) + +These attributes are documented into the ISOBMFF specification. ### streamEvent ################################################################ From c5c83c3ef7cf5f3ce74ec042f359da588a90e4c3 Mon Sep 17 00:00:00 2001 From: grenault73 Date: Mon, 29 Mar 2021 16:45:43 +0200 Subject: [PATCH 31/75] doc: minor fixes --- doc/api/player_events.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/doc/api/player_events.md b/doc/api/player_events.md index 29d4a9445b..54419d0e6a 100644 --- a/doc/api/player_events.md +++ b/doc/api/player_events.md @@ -585,16 +585,17 @@ Each event contains : The supported inband event types are : - "emsg" : The emsg (Event message box) provides inband signaling for generic or MPEG-DASH specific events. -One ISOBMFF media segment may contain one or several boxes. The parsed event contains : - - schemeIdUri (``String``) - - value (``String``) - - timescale (``Number``) - - presentationTimeDelta (``Number``) - - eventDuration (``Number``) - - id (``Number``) - - messageData (``Uint8Array``) - -These attributes are documented into the ISOBMFF specification. + One ISOBMFF media segment may contain one or several boxes. The parsed event + contains : + - schemeIdUri (``String``) + - value (``String``) + - timescale (``Number``) + - presentationTimeDelta (``Number``) + - eventDuration (``Number``) + - id (``Number``) + - messageData (``Uint8Array``) + + These attributes are documented in the ISOBMFF specification. ### streamEvent ################################################################ From 58306cc8e0ac51db0d02f36f4a7617fd28190bef Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Wed, 17 Feb 2021 15:30:56 +0100 Subject: [PATCH 32/75] Single license per content implementation ## The need ### What is this? This commit implements a `singleLicensePer` option, which allows an application to tell the RxPlayer that the current content only has a single license for the whole content, even when it has multiple keys associated to different tracks or qualities. The RxPlayer will then be able to perform a single license request and, if the right options are set, to fallback from non-decryptable contents, which will be both: 1. keys which have the wrong key-status ("output-restricted" if `fallbackOn.keyOutputRestricted` is set and "internal-error" if `fallbackOn.keyInternalError` is set). 2. keys which were not included in that license. Those will be fallbacked from, without needing to set any API. The idea is also to be able to make evolutions to that API to implement for example a single license per Period in the future. ### Why doing that? The idea here is to perform a single license request, initially for a single quality, which will in response return a license (technically it could be multiple concatenated licenses in the CDM's point of view depending of the key system, but it is still a single request and data structure in the player's point of view) allowing to decrypt all encrypted media from that same content. The advantages of doing that are multiple. Most of all: 1. it allows to only perform a single license request instead of multiple ones. Reducing possible server loads but also reducing network latencies. 2. We could be able to tell much sooner which key are not supported and thus avoid switching to an undecipherable Representation to only later fallback from it. 3. some other players not being compatible with contents necessitating multiple license requests, putting all keys in a single license can improve compatibility for when streams are used with multiple players. 4. it reduces interactions with EME APIs, which we found to be very slow on some devices (we for example found out that generating a challenge can take more than 1 second on some embedded devices). And surely many others. Before that commit, the RxPlayer would already play those contents, but would still perform multiple license requests reducing the potential gains. ### What it means technically Technically, the description of this feature is simple: When `singleLicensePer` is set to `"content"`: - we should only perform a single license request, event when there's multiple initialization data encountered in the MPD and initialization segments - we should fallback from `Representation`s whose corresponding key ids are either: 1. Not signaled in the license 2. Signaled in the license but have to be fallbacked from according to the `fallbackOn` options ## Implementation ### Re-purposing `handledInitData` To implement that, the main idea is to re-purpose the `handledInitData` cache (in the `EMEManager`), which stores initialization data that has already been encountered. The only goal of that structure before being to avoid creating multiple MediaKeySessions for the same initialization data, it isn't a stretch to redefine it as a structure avoiding creating multiple MediaKeySessions linked to the same key ids. I changed the way it is used in two ways: 1. When `singleLicensePer` is set to `"content"` we can simply check when it's empty to only create a session on the first initialization data encountered (we can imagine also adding several IDs to that structure to easily implement `"period"` etc.). 2. As we still need to fallback from any initialization data that has no corresponding key in the license when the latter is loaded, I had to add to that structure an Observable emitting `"blacklisted"` key ids from the corresponding `MediaKeySession` and the other key ids, now considered by opposition as `"whitelisted"`. Simply said, every key ids linked to a MediaKeySession which are not present blacklisted (because of the usual `fallbackOn` options) will be whitelisted. By listening to that Observable everytime new initialization data is encountered, we can just compare the linked key id with whitelisted key ids that Observable emits - which will be once the license is pushed. If the license has already been pushed, the Observable will emit immediately. ### Adding the key id to `contentProtections$` event Because we are using key ids here to detect which keys are not in a given license, we have to emit those alongside the initialization data to the `EMEManager`. This is done through the already-existing `contentProtections$` Observable. In the hypothesis that no key id is anounced in the Manifest, we may thus have to parse initialization data to extract it from there, so we can support multi-key per license mode with such contents. This is not done here for the moment, but I'm working on it now. In the meantime, initialization data for which the corresponding key id is not known will still lead to another license request, which I felt was a good compromise. ## Does it work? I tested it with success on: - Widevine L1 on STBs - Widevine L3 on Linux - Chrome - Widevine L3 on Linux - Firefox - Widevine L3 on Mac - Chrome - Widevine L3 on Windows - Edge - PlayReady SL3000 on Windows - Edge I know it doesn't work yet on some set-top boxes, but this seems more an exception than the norm. We've still scheduled a meeting to learn more about this issue. Depending on the result, we may want to perform updates on that code. --- src/core/eme/check_key_statuses.ts | 17 +++- src/core/eme/eme_manager.ts | 91 ++++++++++++----- src/core/eme/session_events_listener.ts | 37 +++---- src/core/eme/types.ts | 106 +++++++++++++++++--- src/core/eme/utils/loaded_sessions_store.ts | 17 +++- src/core/init/initialize_media_source.ts | 4 +- src/core/init/types.ts | 6 +- src/manifest/index.ts | 7 +- src/manifest/representation.ts | 28 +++--- 9 files changed, 225 insertions(+), 88 deletions(-) diff --git a/src/core/eme/check_key_statuses.ts b/src/core/eme/check_key_statuses.ts index ddb9239cae..1e9aa092bf 100644 --- a/src/core/eme/check_key_statuses.ts +++ b/src/core/eme/check_key_statuses.ts @@ -48,22 +48,26 @@ export interface IKeyStatusesCheckingOptions { /** * Look at the current key statuses in the sessions and construct the - * appropriate warnings and blacklisted key ids. + * appropriate warnings, whitelisted and blacklisted key ids. * * Throws if one of the keyID is on an error. * @param {MediaKeySession} session - The MediaKeySession from which the keys * will be checked. * @param {Object} options * @param {String} keySystem - The configuration keySystem used for deciphering - * @returns {Array} - Warnings to send and blacklisted key ids. + * @returns {Array} - Warnings to send, whitelisted and blacklisted key ids. */ export default function checkKeyStatuses( session : MediaKeySession | ICustomMediaKeySession, options: IKeyStatusesCheckingOptions, keySystem: string -) : [IEMEWarningEvent[], Uint8Array[]] { +) : { warnings : IEMEWarningEvent[]; + blacklistedKeyIDs : Uint8Array[]; + whitelistedKeyIds : Uint8Array[]; } +{ const warnings : IEMEWarningEvent[] = []; const blacklistedKeyIDs : Uint8Array[] = []; + const whitelistedKeyIds : Uint8Array[] = []; const { fallbackOn = {}, throwOnLicenseExpiration } = options; /* eslint-disable @typescript-eslint/no-unsafe-member-access */ @@ -90,6 +94,7 @@ export default function checkKeyStatuses( throw error; } warnings.push({ type: "warning", value: error }); + whitelistedKeyIds.push(keyId); break; } @@ -116,7 +121,11 @@ export default function checkKeyStatuses( blacklistedKeyIDs.push(keyId); break; } + + default: + whitelistedKeyIds.push(keyId); + break; } }); - return [warnings, blacklistedKeyIDs]; + return { warnings, blacklistedKeyIDs, whitelistedKeyIds }; } diff --git a/src/core/eme/eme_manager.ts b/src/core/eme/eme_manager.ts index 63b0779720..0b8706fee4 100644 --- a/src/core/eme/eme_manager.ts +++ b/src/core/eme/eme_manager.ts @@ -20,6 +20,7 @@ import { merge as observableMerge, Observable, of as observableOf, + ReplaySubject, throwError, } from "rxjs"; import { @@ -41,6 +42,7 @@ import { import config from "../../config"; import { EncryptedMediaError } from "../../errors"; import log from "../../log"; +import areArraysOfNumbersEqual from "../../utils/are_arrays_of_numbers_equal"; import arrayIncludes from "../../utils/array_includes"; import assertUnreachable from "../../utils/assert_unreachable"; import { concat } from "../../utils/byte_parsing"; @@ -59,6 +61,7 @@ import { IEMEManagerEvent, IInitializationDataInfo, IKeySystemOption, + IKeyUpdateValue, } from "./types"; import InitDataStore from "./utils/init_data_store"; @@ -86,15 +89,19 @@ export default function EMEManager( log.debug("EME: Starting EMEManager logic."); /** - * Keep track of all initialization data handled for the current `EMEManager` - * instance. - * This allows to avoid handling multiple times the same encrypted events. + * Keep track of all decryption keys currently handled by the `EMEManager`. + * This allows to avoid creating multiple MediaKeySessions handling the same + * decryption keys. */ - const handledInitData = new InitDataStore(); + const handledSessions = new InitDataStore<{ + /** Initialization data which triggered the creation of this session. */ + initializationData : IInitializationDataInfo; + /** Last key update event received for that session. */ + lastKeyUpdate$ : ReplaySubject; + }>(); /** - * Keep track of which initialization data have been blacklisted (linked to - * non-decypherable content). + * Keep track of which initialization data have been blacklisted. * If the same initialization data is encountered again, we can directly emit * the same `BlacklistedSessionError`. */ @@ -168,7 +175,33 @@ export default function EMEManager( value: initializationData }); } - if (!handledInitData.storeIfNone(initializationData, true)) { + const lastKeyUpdate$ = new ReplaySubject(1); + + // First, check that this initialization data is not already handled + const keyIds = initializationData.keyIds; + if (options.singleLicensePer === "content" && + handledSessions.getLength() > 0 && + keyIds !== undefined) + { + const firstSession = handledSessions.getAll()[0]; + return firstSession.lastKeyUpdate$.pipe(mergeMap((evt) => { + for (let i = 0; i < evt.whitelistedKeyIds.length; i++) { + for (let j = 0; j < keyIds.length; j++) { + if (areArraysOfNumbersEqual(evt.whitelistedKeyIds[i], keyIds[j])) { + // Move corresponding session on top of the cache if it exists + const { loadedSessionsStore } = mediaKeysEvent.value.stores; + loadedSessionsStore.moveOnTop(firstSession.initializationData); + return observableOf({ type: "init-data-ignored" as const, + value: { initializationData } }); + } + } + } + return observableOf({ type: "keys-update" as const, + value: { blacklistedKeyIDs: keyIds, + whitelistedKeyIds: [] } }); + })); + } else if (!handledSessions.storeIfNone(initializationData, { initializationData, + lastKeyUpdate$ })) { log.debug("EME: Init data already received. Skipping it."); return observableOf({ type: "init-data-ignored" as const, value: { initializationData } }); @@ -188,7 +221,7 @@ export default function EMEManager( .pipe(mergeMap((sessionEvt) => { switch (sessionEvt.type) { case "cleaning-old-session": - handledInitData.remove(sessionEvt.value.initializationData); + handledSessions.remove(sessionEvt.value.initializationData); return EMPTY; case "cleaned-old-session": @@ -240,27 +273,33 @@ export default function EMEManager( mediaKeySystemAccess.keySystem, initializationData), generateRequest$) - .pipe(catchError(err => { - if (!(err instanceof BlacklistedSessionError)) { - throw err; - } + .pipe( + tap((evt) => { + if (evt.type === "keys-update") { + lastKeyUpdate$.next(evt.value); + } + }), + catchError(err => { + if (!(err instanceof BlacklistedSessionError)) { + throw err; + } - blacklistedInitData.store(initializationData, err); + blacklistedInitData.store(initializationData, err); - const { sessionError } = err; - if (initializationData.type === undefined) { - log.error("EME: Current session blacklisted and content not known. " + - "Throwing."); - sessionError.fatal = true; - throw sessionError; - } + const { sessionError } = err; + if (initializationData.type === undefined) { + log.error("EME: Current session blacklisted and content not known. " + + "Throwing."); + sessionError.fatal = true; + throw sessionError; + } - log.warn("EME: Current session blacklisted. Blacklisting content."); - return observableOf({ type: "warning" as const, - value: sessionError }, - { type: "blacklist-protection-data" as const, - value: initializationData }); - })); + log.warn("EME: Current session blacklisted. Blacklisting content."); + return observableOf({ type: "warning" as const, + value: sessionError }, + { type: "blacklist-protection-data" as const, + value: initializationData }); + })); })); })); diff --git a/src/core/eme/session_events_listener.ts b/src/core/eme/session_events_listener.ts index 0e9711c2b3..08609a3cd2 100644 --- a/src/core/eme/session_events_listener.ts +++ b/src/core/eme/session_events_listener.ts @@ -56,12 +56,12 @@ import checkKeyStatuses, { IKeyStatusesCheckingOptions, } from "./check_key_statuses"; import { - IBlacklistKeysEvent, IInitializationDataInfo, IEMEWarningEvent, IKeyMessageHandledEvent, IKeyStatusChangeHandledEvent, IKeySystemOption, + IKeysUpdateEvent, INoUpdateEvent, ISessionMessageEvent, ISessionUpdatedEvent, @@ -106,8 +106,8 @@ export default function SessionEventsListener( ) : Observable + IKeysUpdateEvent | + ISessionUpdatedEvent> { log.info("EME: Binding session events", session); const sessionWarningSubject$ = new Subject(); @@ -174,13 +174,13 @@ export default function SessionEventsListener( evt : IEMEWarningEvent | ISessionMessageEvent | IKeyMessageHandledEvent | - IKeyStatusChangeHandledEvent | - IBlacklistKeysEvent + IKeysUpdateEvent | + IKeyStatusChangeHandledEvent ) : Observable< IEMEWarningEvent | ISessionMessageEvent | INoUpdateEvent | ISessionUpdatedEvent | - IBlacklistKeysEvent > => { + IKeysUpdateEvent > => { switch (evt.type) { case "key-message-handled": case "key-status-change-handled": @@ -218,19 +218,20 @@ function getKeyStatusesEvents( session : MediaKeySession | ICustomMediaKeySession, options : IKeyStatusesCheckingOptions, keySystem : string -) : Observable { +) : Observable { return observableDefer(() => { - const [warnings, blacklistedKeyIDs] = + if (session.keyStatuses.size === 0) { + return EMPTY; + } + const { warnings, blacklistedKeyIDs, whitelistedKeyIds } = checkKeyStatuses(session, options, keySystem); const warnings$ = warnings.length > 0 ? observableOf(...warnings) : - EMPTY; - - const blackListUpdate$ = blacklistedKeyIDs.length > 0 ? - observableOf({ type: "blacklist-keys" as const, - value: blacklistedKeyIDs }) : - EMPTY; - return observableConcat(warnings$, blackListUpdate$); + EMPTY; + const keysUpdate$ = observableOf({ type : "keys-update" as const, + value : { whitelistedKeyIds, + blacklistedKeyIDs } }); + return observableConcat(warnings$, keysUpdate$); }); } @@ -300,7 +301,7 @@ function handleKeyStatusesChangeEvent( keySystemOptions : IKeySystemOption, keySystem : string, keyStatusesEvent : Event -) : Observable { +) : Observable { log.info("EME: keystatuseschange event received", session, keyStatusesEvent); const callback$ = observableDefer(() => { return tryCatch(() => { @@ -324,8 +325,8 @@ function handleKeyStatusesChangeEvent( throw err; }) ); - return observableConcat(getKeyStatusesEvents(session, keySystemOptions, keySystem), - callback$); + return observableMerge(getKeyStatusesEvents(session, keySystemOptions, keySystem), + callback$); } /** diff --git a/src/core/eme/types.ts b/src/core/eme/types.ts index cd341f5794..c708d9e2a9 100644 --- a/src/core/eme/types.ts +++ b/src/core/eme/types.ts @@ -20,19 +20,42 @@ import { ICustomMediaKeySession, ICustomMediaKeySystemAccess, } from "../../compat"; -import { IEncryptedEventData } from "../../compat/eme/"; import { ICustomError } from "../../errors"; import LoadedSessionsStore from "./utils/loaded_sessions_store"; import PersistentSessionsStore from "./utils/persistent_sessions_store"; -/** - * Information about the encryption initialization data. - * Here equal to `IEncryptedEventData` because it is the one with the most - * restrictions when compared to `IContentProtection`. - * Using a union type between the two would be best, but it is poorly handled - * by TypeScript. - */ -export type IInitializationDataInfo = IEncryptedEventData; +/** Information about the encryption initialization data. */ +export interface IInitializationDataInfo { + /** + * The initialization data type - or the format of the `data` attribute (e.g. + * "cenc"). + * `undefined` if unknown. + */ + type : string | undefined; + /** + * The key ids linked to those initialization data. + * This should be the key ids for the key concerned by the media which have + * the present initialization data. + * + * `undefined` when not known (different from an empty array - which would + * just mean that there's no key id involved). + */ + keyIds? : Uint8Array[]; + /** Every initialization data for that type. */ + values: Array<{ + /** + * Hex encoded system id, which identifies the key system. + * https://dashif.org/identifiers/content_protection/ + */ + systemId: string | undefined; + /** + * The initialization data itself for that type and systemId. + * For example, with "cenc" initialization data found in an ISOBMFF file, + * this will be the whole PSSH box. + */ + data: Uint8Array; + }>; +} /** Event emitted when a minor - recoverable - error happened. */ export interface IEMEWarningEvent { type : "warning"; @@ -159,6 +182,51 @@ export interface INoUpdateEvent { value : { initializationData: IInitializationDataInfo }; } +/** + * Some key ids have updated their status. + * + * We put them in two different list: + * + * - `blacklistedKeyIDs`: Those key ids won't be used for decryption and the + * corresponding media it decrypts should not be pushed to the buffer + * Note that a blacklisted key id can become whitelisted in the future. + * + * - `whitelistedKeyIds`: Those key ids were found and their corresponding + * keys are now being considered for decryption. + * Note that a whitelisted key id can become blacklisted in the future. + * + * Note that each `IKeysUpdateEvent` is independent of any other. + * + * A new `IKeysUpdateEvent` does not completely replace a previously emitted + * one, as it can for example be linked to a whole other decryption session. + * + * However, if a key id is encountered in both an older and a newer + * `IKeysUpdateEvent`, only the older status should be considered. + */ +export interface IKeysUpdateEvent { + type: "keys-update"; + value: IKeyUpdateValue; +} + +/** Information on key ids linked to a MediaKeySession. */ +export interface IKeyUpdateValue { + /** + * The list of key ids that are blacklisted. + * As such, their corresponding keys won't be used by that session, despite + * the fact that they were part of the pushed license. + * + * Reasons for blacklisting a keys depend on options, but mainly involve unmet + * output restrictions and CDM internal errors linked to that key id. + */ + blacklistedKeyIDs : Uint8Array[]; + /* + * The list of key id linked to that session which are not blacklisted. + * Together with `blacklistedKeyIDs` it regroups all key ids linked to the + * session. + */ + whitelistedKeyIds : Uint8Array[]; +} + /** * Emitted after the `MediaKeySession.prototype.update` function resolves. * This function is called when the `getLicense` callback resolves with a data @@ -173,12 +241,6 @@ export interface ISessionUpdatedEvent { initializationData : IInitializationDataInfo; }; } -// Emitted when individual keys are considered undecipherable and are thus -// blacklisted. -// Emit the corresponding keyIDs as payload. -export interface IBlacklistKeysEvent { type : "blacklist-keys"; - value: Uint8Array[]; } - /** * Event Emitted when specific "protection data" cannot be deciphered and is thus * blacklisted. @@ -197,8 +259,8 @@ export type IEMEManagerEvent = IEMEWarningEvent | // minor error IInitDataIgnoredEvent | // initData already handled ISessionMessageEvent | // MediaKeySession event INoUpdateEvent | // `getLicense` returned `null` + IKeysUpdateEvent | // Status of keys changed ISessionUpdatedEvent | // `update` call resolved - IBlacklistKeysEvent | // keyIDs undecipherable IBlacklistProtectionDataEvent; // initData undecipherable export type ILicense = BufferSource | @@ -213,6 +275,15 @@ export interface IContentProtection { * https://www.w3.org/TR/eme-initdata-registry/ */ type: string; + /** + * The key ids linked to those initialization data. + * This should be the key ids for the key concerned by the media which have + * the present initialization data. + * + * `undefined` when not known (different from an empty array - which would + * just mean that there's no key id involved). + */ + keyIds? : Uint8Array[]; /** Every initialization data for that type. */ values: Array<{ /** @@ -465,6 +536,9 @@ export interface IKeySystemOption { * closed when the current playback stops. */ closeSessionsOnStop? : boolean; + + singleLicensePer? : "content" | + "init-data"; /** Callback called when one of the key's status change. */ onKeyStatusesChange? : (evt : Event, session : MediaKeySession | ICustomMediaKeySession) diff --git a/src/core/eme/utils/loaded_sessions_store.ts b/src/core/eme/utils/loaded_sessions_store.ts index cffecb7f52..ea1b0d1886 100644 --- a/src/core/eme/utils/loaded_sessions_store.ts +++ b/src/core/eme/utils/loaded_sessions_store.ts @@ -99,7 +99,7 @@ export default class LoadedSessionsStore { * its internal storage, as returned by the `getAll` method. * * This can be used for example to tell when a previously-stored - * MediaKeySession is re-used to then be able to implement a caching + * initialization data is re-used to then be able to implement a caching * replacement algorithm based on the least-recently-used values by just * evicting the first values returned by `getAll`. * @param {Uint8Array} initData @@ -115,6 +115,21 @@ export default class LoadedSessionsStore { sessionType: entry.sessionType }; } + /** + * Moves the corresponding MediaKeySession to the end of its internal storage, + * as returned by the `getAll` method. + * + * This can be used to signal that a previously-stored initialization data is + * re-used to then be able to implement a caching replacement algorithm based + * on the least-recently-used values by just evicting the first values + * returned by `getAll`. + */ + public moveOnTop( + initializationData : IInitializationDataInfo + ) : boolean { + return this._storage.getAndReuse(initializationData) !== undefined; + } + /** * Create a new MediaKeySession and store it in this store. * @throws {EncryptedMediaError} diff --git a/src/core/init/initialize_media_source.ts b/src/core/init/initialize_media_source.ts index 1bd5a08aa2..1a4d1fd85e 100644 --- a/src/core/init/initialize_media_source.ts +++ b/src/core/init/initialize_media_source.ts @@ -327,9 +327,9 @@ export default function InitializeOnMediaSource( const setUndecipherableRepresentations$ = emeManager$.pipe( tap((evt) => { - if (evt.type === "blacklist-keys") { + if (evt.type === "keys-update") { log.info("Init: blacklisting Representations based on keyIDs"); - manifest.addUndecipherableKIDs(evt.value); + manifest.addUndecipherableKIDs(evt.value.blacklistedKeyIDs); } else if (evt.type === "blacklist-protection-data") { log.info("Init: blacklisting Representations based on protection data."); manifest.addUndecipherableProtectionData(evt.value); diff --git a/src/core/init/types.ts b/src/core/init/types.ts index f0260fc442..cf177e0128 100644 --- a/src/core/init/types.ts +++ b/src/core/init/types.ts @@ -26,11 +26,11 @@ import { } from "../api"; import { IAttachedMediaKeysEvent, - IBlacklistKeysEvent, IBlacklistProtectionDataEvent, ICreatedMediaKeysEvent, IEncryptedEvent, IInitDataIgnoredEvent, + IKeysUpdateEvent, INoUpdateEvent, ISessionMessageEvent, ISessionUpdatedEvent, @@ -171,9 +171,9 @@ export type IInitEvent = IManifestReadyEvent | IAttachedMediaKeysEvent | IInitDataIgnoredEvent | ISessionMessageEvent | + IKeysUpdateEvent | INoUpdateEvent | ISessionUpdatedEvent | - IBlacklistKeysEvent | IBlacklistProtectionDataEvent | // Coming from the `MediaSourceLoader` @@ -210,7 +210,7 @@ export type IDirectfileEvent = IStalledEvent | IAttachedMediaKeysEvent | IInitDataIgnoredEvent | ISessionMessageEvent | + IKeysUpdateEvent | INoUpdateEvent | ISessionUpdatedEvent | - IBlacklistKeysEvent | IBlacklistProtectionDataEvent; diff --git a/src/manifest/index.ts b/src/manifest/index.ts index 4241ef8d0c..bc4e6547bc 100644 --- a/src/manifest/index.ts +++ b/src/manifest/index.ts @@ -25,10 +25,7 @@ import Manifest, { ISupplementaryTextTrack, } from "./manifest"; import Period from "./period"; -import Representation, { - IContentProtections, - IContentProtectionInitData, -} from "./representation"; +import Representation from "./representation"; import { IBaseContentInfos, IMetaPlaylistPrivateInfos, @@ -51,8 +48,6 @@ export { // types IAdaptationType, IBaseContentInfos, - IContentProtections, - IContentProtectionInitData, IManifestParsingOptions, IMetaPlaylistPrivateInfos, IRepresentationFilter, diff --git a/src/manifest/representation.ts b/src/manifest/representation.ts index d1ad765a54..33fa6d8805 100644 --- a/src/manifest/representation.ts +++ b/src/manifest/representation.ts @@ -15,23 +15,16 @@ */ import { isCodecSupported } from "../compat"; +import { IContentProtection } from "../core/eme"; import log from "../log"; import { IContentProtections, - IContentProtectionInitData, - IContentProtectionKID, IParsedRepresentation, } from "../parsers/manifest"; import areArraysOfNumbersEqual from "../utils/are_arrays_of_numbers_equal"; import { IRepresentationIndex } from "./representation_index"; import { IAdaptationType } from "./types"; -export { - IContentProtectionInitData, - IContentProtectionKID, - IContentProtections, -}; - /** * Normalized Representation structure. * @class Representation @@ -161,7 +154,7 @@ class Representation { * @param {string} drmSystemId - The hexa-encoded DRM system ID * @returns {Array.} */ - public getEncryptionData(drmSystemId : string) : IContentProtectionInitData[] { + public getEncryptionData(drmSystemId : string) : IContentProtection[] { const allInitData = this.getAllEncryptionData(); const filtered = []; for (let i = 0; i < allInitData.length; i++) { @@ -170,7 +163,9 @@ class Representation { for (let j = 0; j < initData.values.length; j++) { if (initData.values[j].systemId.toLowerCase() === drmSystemId.toLowerCase()) { if (!createdObjForType) { + const keyIds = this.contentProtections?.keyIds.map(val => val.keyId); filtered.push({ type: initData.type, + keyIds, values: [initData.values[j]] }); createdObjForType = true; } else { @@ -209,9 +204,18 @@ class Representation { * after parsing this Representation's initialization segment, if one exists. * @returns {Array.} */ - public getAllEncryptionData() : IContentProtectionInitData[] { - return this.contentProtections === undefined ? [] : - this.contentProtections.initData; + public getAllEncryptionData() : IContentProtection[] { + if (this.contentProtections === undefined || + this.contentProtections.initData.length === 0) + { + return []; + } + const keyIds = this.contentProtections?.keyIds.map(val => val.keyId); + return this.contentProtections.initData.map((x) => { + return { type: x.type, + keyIds, + values: x.values }; + }); } /** From c11d349c2e529a5324a7d211a6a13e6135f57ed8 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Thu, 18 Feb 2021 11:34:23 +0100 Subject: [PATCH 33/75] eme: in singleLicensePerContent mode do not another request for key-id-less init data --- src/core/eme/eme_manager.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/eme/eme_manager.ts b/src/core/eme/eme_manager.ts index 0b8706fee4..6250dd0762 100644 --- a/src/core/eme/eme_manager.ts +++ b/src/core/eme/eme_manager.ts @@ -178,11 +178,14 @@ export default function EMEManager( const lastKeyUpdate$ = new ReplaySubject(1); // First, check that this initialization data is not already handled - const keyIds = initializationData.keyIds; - if (options.singleLicensePer === "content" && - handledSessions.getLength() > 0 && - keyIds !== undefined) - { + if (options.singleLicensePer === "content" && handledSessions.getLength() > 0) { + const keyIds = initializationData.keyIds; + if (keyIds === undefined) { + log.warn("EME: Initialization data linked to unknown key id, we'll" + + "not able to fallback from it."); + return observableOf({ type: "init-data-ignored" as const, + value: { initializationData } }); + } const firstSession = handledSessions.getAll()[0]; return firstSession.lastKeyUpdate$.pipe(mergeMap((evt) => { for (let i = 0; i < evt.whitelistedKeyIds.length; i++) { From 31b130732429bbeef08a20a939ce6c19e3fd3e8e Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Thu, 18 Feb 2021 11:35:45 +0100 Subject: [PATCH 34/75] EME: rename LoadedSessionsStore.moveOnTop to LoadedSessionsStore.reuse --- src/core/eme/eme_manager.ts | 2 +- src/core/eme/utils/loaded_sessions_store.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/eme/eme_manager.ts b/src/core/eme/eme_manager.ts index 6250dd0762..5475b37338 100644 --- a/src/core/eme/eme_manager.ts +++ b/src/core/eme/eme_manager.ts @@ -193,7 +193,7 @@ export default function EMEManager( if (areArraysOfNumbersEqual(evt.whitelistedKeyIds[i], keyIds[j])) { // Move corresponding session on top of the cache if it exists const { loadedSessionsStore } = mediaKeysEvent.value.stores; - loadedSessionsStore.moveOnTop(firstSession.initializationData); + loadedSessionsStore.reuse(firstSession.initializationData); return observableOf({ type: "init-data-ignored" as const, value: { initializationData } }); } diff --git a/src/core/eme/utils/loaded_sessions_store.ts b/src/core/eme/utils/loaded_sessions_store.ts index ea1b0d1886..e1c24fdc27 100644 --- a/src/core/eme/utils/loaded_sessions_store.ts +++ b/src/core/eme/utils/loaded_sessions_store.ts @@ -124,7 +124,7 @@ export default class LoadedSessionsStore { * on the least-recently-used values by just evicting the first values * returned by `getAll`. */ - public moveOnTop( + public reuse( initializationData : IInitializationDataInfo ) : boolean { return this._storage.getAndReuse(initializationData) !== undefined; From 6fa2c8a3aaac51bdf4473e91ed0d456d7be8d37a Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Thu, 18 Feb 2021 13:33:55 +0100 Subject: [PATCH 35/75] eme: update outdated JSDoc in loaded_sessions_store.ts --- src/core/eme/utils/loaded_sessions_store.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/core/eme/utils/loaded_sessions_store.ts b/src/core/eme/utils/loaded_sessions_store.ts index e1c24fdc27..440e4ff4e6 100644 --- a/src/core/eme/utils/loaded_sessions_store.ts +++ b/src/core/eme/utils/loaded_sessions_store.ts @@ -83,8 +83,7 @@ export default class LoadedSessionsStore { * Returns the stored MediaKeySession information related to the * given initDataType and initData if found. * Returns `null` if no such MediaKeySession is stored. - * @param {Uint8Array} initData - * @param {string|undefined} initDataType + * @param {Object} initializationData * @returns {Object|null} */ public get(initializationData : IInitializationDataInfo) : IStoredSessionData | null { @@ -102,8 +101,7 @@ export default class LoadedSessionsStore { * initialization data is re-used to then be able to implement a caching * replacement algorithm based on the least-recently-used values by just * evicting the first values returned by `getAll`. - * @param {Uint8Array} initData - * @param {string|undefined} initDataType + * @param {Object} initializationData * @returns {Object|null} */ public getAndReuse( @@ -123,6 +121,11 @@ export default class LoadedSessionsStore { * re-used to then be able to implement a caching replacement algorithm based * on the least-recently-used values by just evicting the first values * returned by `getAll`. + * + * Returns `true` if the corresponding session was found in the store, `false` + * otherwise. + * @param {Object} initializationData + * @returns {boolean} */ public reuse( initializationData : IInitializationDataInfo @@ -133,8 +136,7 @@ export default class LoadedSessionsStore { /** * Create a new MediaKeySession and store it in this store. * @throws {EncryptedMediaError} - * @param {Uint8Array} initData - * @param {string|undefined} initDataType + * @param {Object} initializationData * @param {string} sessionType * @returns {MediaKeySession} */ @@ -174,8 +176,7 @@ export default class LoadedSessionsStore { * Close a MediaKeySession corresponding to an initialization data and remove * its related stored information from the LoadedSessionsStore. * Emit when done. - * @param {Uint8Array} initData - * @param {string|undefined} initDataType + * @param {Object} initializationData * @returns {Observable} */ public closeSession( From 3049c570d2701be4ae547f20a71f6c71b5f146b5 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Wed, 24 Feb 2021 14:55:04 +0100 Subject: [PATCH 36/75] eme: add forgotten space in log in eme_manager.ts --- src/core/eme/eme_manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/eme/eme_manager.ts b/src/core/eme/eme_manager.ts index 5475b37338..fe3c1b38ba 100644 --- a/src/core/eme/eme_manager.ts +++ b/src/core/eme/eme_manager.ts @@ -181,7 +181,7 @@ export default function EMEManager( if (options.singleLicensePer === "content" && handledSessions.getLength() > 0) { const keyIds = initializationData.keyIds; if (keyIds === undefined) { - log.warn("EME: Initialization data linked to unknown key id, we'll" + + log.warn("EME: Initialization data linked to unknown key id, we'll " + "not able to fallback from it."); return observableOf({ type: "init-data-ignored" as const, value: { initializationData } }); From 7253e2ed616fac0c93ec2e0c60bd4b96b8db14e6 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Fri, 5 Mar 2021 13:57:24 +0100 Subject: [PATCH 37/75] eme: rename variable and add isEmpty method to improve readability --- src/core/eme/eme_manager.ts | 16 +++++++++------- src/core/eme/utils/init_data_store.ts | 10 ++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/core/eme/eme_manager.ts b/src/core/eme/eme_manager.ts index fe3c1b38ba..5e65349ca7 100644 --- a/src/core/eme/eme_manager.ts +++ b/src/core/eme/eme_manager.ts @@ -89,11 +89,12 @@ export default function EMEManager( log.debug("EME: Starting EMEManager logic."); /** - * Keep track of all decryption keys currently handled by the `EMEManager`. + * Keep track of all decryption keys handled by this instance of the + * `EMEManager`. * This allows to avoid creating multiple MediaKeySessions handling the same * decryption keys. */ - const handledSessions = new InitDataStore<{ + const contentSessions = new InitDataStore<{ /** Initialization data which triggered the creation of this session. */ initializationData : IInitializationDataInfo; /** Last key update event received for that session. */ @@ -101,7 +102,8 @@ export default function EMEManager( }>(); /** - * Keep track of which initialization data have been blacklisted. + * Keep track of which initialization data have been blacklisted in the + * current instance of the `EMEManager`. * If the same initialization data is encountered again, we can directly emit * the same `BlacklistedSessionError`. */ @@ -178,7 +180,7 @@ export default function EMEManager( const lastKeyUpdate$ = new ReplaySubject(1); // First, check that this initialization data is not already handled - if (options.singleLicensePer === "content" && handledSessions.getLength() > 0) { + if (options.singleLicensePer === "content" && !contentSessions.isEmpty()) { const keyIds = initializationData.keyIds; if (keyIds === undefined) { log.warn("EME: Initialization data linked to unknown key id, we'll " + @@ -186,7 +188,7 @@ export default function EMEManager( return observableOf({ type: "init-data-ignored" as const, value: { initializationData } }); } - const firstSession = handledSessions.getAll()[0]; + const firstSession = contentSessions.getAll()[0]; return firstSession.lastKeyUpdate$.pipe(mergeMap((evt) => { for (let i = 0; i < evt.whitelistedKeyIds.length; i++) { for (let j = 0; j < keyIds.length; j++) { @@ -203,7 +205,7 @@ export default function EMEManager( value: { blacklistedKeyIDs: keyIds, whitelistedKeyIds: [] } }); })); - } else if (!handledSessions.storeIfNone(initializationData, { initializationData, + } else if (!contentSessions.storeIfNone(initializationData, { initializationData, lastKeyUpdate$ })) { log.debug("EME: Init data already received. Skipping it."); return observableOf({ type: "init-data-ignored" as const, @@ -224,7 +226,7 @@ export default function EMEManager( .pipe(mergeMap((sessionEvt) => { switch (sessionEvt.type) { case "cleaning-old-session": - handledSessions.remove(sessionEvt.value.initializationData); + contentSessions.remove(sessionEvt.value.initializationData); return EMPTY; case "cleaned-old-session": diff --git a/src/core/eme/utils/init_data_store.ts b/src/core/eme/utils/init_data_store.ts index f0091939cd..f43802c2af 100644 --- a/src/core/eme/utils/init_data_store.ts +++ b/src/core/eme/utils/init_data_store.ts @@ -68,6 +68,16 @@ export default class InitDataStore { return this._storage.length; } + /** + * Returns `true` if no initialization data is stored yet in this + * InitDataStore. + * Returns `false` otherwise. + * @returns {boolean} + */ + public isEmpty() : boolean { + return this._storage.length === 0; + } + /** * Returns the element associated with the given initData and initDataType. * Returns `undefined` if not found. From b3a2af24d934305c57b6748a2b8d850b7defae10 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Fri, 12 Mar 2021 14:27:49 +0100 Subject: [PATCH 38/75] eme: fix global eme tests by sending key updates after the update --- src/core/eme/__tests__/__global__/utils.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/core/eme/__tests__/__global__/utils.ts b/src/core/eme/__tests__/__global__/utils.ts index c41e3e301b..249ddc4ab7 100644 --- a/src/core/eme/__tests__/__global__/utils.ts +++ b/src/core/eme/__tests__/__global__/utils.ts @@ -196,10 +196,12 @@ export class MediaKeySessionImpl extends EventEmitter { this.keyStatuses._setKeyStatus(new Uint8Array([0, 1, 2, this._currentKeyId++]), "usable"); const event = new CustomEvent("keystatuseschange"); - this.trigger("keyStatusesChange", event); - if (this.onkeystatuseschange !== null && this.onkeystatuseschange !== undefined) { - this.onkeystatuseschange(event); - } + setTimeout(() => { + this.trigger("keyStatusesChange", event); + if (this.onkeystatuseschange !== null && this.onkeystatuseschange !== undefined) { + this.onkeystatuseschange(event); + } + }, 0); return Promise.resolve(); } } From 640b89bde902d2949703422bfbf1e2349746b669 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Fri, 19 Mar 2021 18:22:43 +0100 Subject: [PATCH 39/75] eme: only persist MediaKeySessions once its keys are known Before this commit, persistent MediaKeySessions were added to the `PersistentSessionsStore` (for later retrieval) as soon as possible: when their `sessionId` property was known (meaning as soon as the `generateRequest` answered). This worked pretty well, but we found a persistence-related issue that could profit from taking another strategy: After loading a persistent MediaKeySessions (that has previously been added to the `PersistentSessionsStore`), the RxPlayer immediately checks the status of its keys through the `keyStatuses` property. However, on some platforms, the `keyStatuses` property is not directly populated once the `load` call is done, but only after a difficult-to-predict delay (sometimes immediately after, sometimes more than 10 milliseconds after). This imply that we might now have to wait after loading a persistent session just to be sure that all keys information have been added to it. We limited that by only waiting a delay if the `keyStatuses` property is empty, yet this pre-condition was frequent: any time the user loaded a new content before the license request succeeded (but after the `generateRequest` call) we would be legitimately in a case where the `keyStatuses` property is actually empty. To avoid penalizing too much legitimate cases, this commit adds a persistent session to the `PersistentSessionsStore` only once at least one key is added to its `keyStatuses` property. This ensures that having an empty `keyStatuses` property will now be unusual enough. In that case, incurring a delay (let's say up to 100ms) will be much less penalizing. --- src/core/eme/eme_manager.ts | 38 ++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/core/eme/eme_manager.ts b/src/core/eme/eme_manager.ts index 5e65349ca7..7721c7a2cf 100644 --- a/src/core/eme/eme_manager.ts +++ b/src/core/eme/eme_manager.ts @@ -245,6 +245,13 @@ export default function EMEManager( const { mediaKeySession, sessionType } = sessionEvt.value; + /** + * We only store persistent sessions once its keys are known. + * This boolean allows to know if this session has already been + * persisted or not. + */ + let isSessionPersisted = false; + // `generateKeyRequest` awaits a single Uint8Array containing all // initialization data. const concatInitData = concat(...initializationData.values.map(i => i.data)); @@ -254,17 +261,6 @@ export default function EMEManager( generateKeyRequest(mediaKeySession, initializationData.type, concatInitData).pipe( - tap(() => { - const { persistentSessionsStore } = stores; - if (sessionType === "persistent-license" && - persistentSessionsStore !== null) - { - cleanOldStoredPersistentInfo( - persistentSessionsStore, - EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION - 1); - persistentSessionsStore.add(initializationData, mediaKeySession); - } - }), catchError((error: unknown) => { throw new EncryptedMediaError( "KEY_GENERATE_REQUEST_ERROR", @@ -280,9 +276,25 @@ export default function EMEManager( generateRequest$) .pipe( tap((evt) => { - if (evt.type === "keys-update") { - lastKeyUpdate$.next(evt.value); + if (evt.type !== "keys-update") { + return; + } + lastKeyUpdate$.next(evt.value); + + if ((evt.value.whitelistedKeyIds.length === 0 && + evt.value.blacklistedKeyIDs.length === 0) || + sessionType === "temporary" || + stores.persistentSessionsStore === null || + isSessionPersisted) + { + return; } + const { persistentSessionsStore } = stores; + cleanOldStoredPersistentInfo( + persistentSessionsStore, + EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION - 1); + persistentSessionsStore.add(initializationData, mediaKeySession); + isSessionPersisted = true; }), catchError(err => { if (!(err instanceof BlacklistedSessionError)) { From d74bd6176b1d700320fdaaf1743c1c0bfb292e8f Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Tue, 23 Mar 2021 15:12:19 +0100 Subject: [PATCH 40/75] tests: raise-up delay for a key update to work-around subtle test race conditions --- src/core/eme/__tests__/__global__/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/eme/__tests__/__global__/utils.ts b/src/core/eme/__tests__/__global__/utils.ts index 249ddc4ab7..aa151e3428 100644 --- a/src/core/eme/__tests__/__global__/utils.ts +++ b/src/core/eme/__tests__/__global__/utils.ts @@ -201,7 +201,7 @@ export class MediaKeySessionImpl extends EventEmitter { if (this.onkeystatuseschange !== null && this.onkeystatuseschange !== undefined) { this.onkeystatuseschange(event); } - }, 0); + }, 50); return Promise.resolve(); } } From eb6f07e3a7fa4275ca0ea1e6f9f823ed12ee92fc Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Mon, 29 Mar 2021 17:30:35 +0200 Subject: [PATCH 41/75] eme: check that all keyIds for the current encrypted event are handled by a single session in content mode --- src/core/eme/eme_manager.ts | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/core/eme/eme_manager.ts b/src/core/eme/eme_manager.ts index 7721c7a2cf..f8829dce86 100644 --- a/src/core/eme/eme_manager.ts +++ b/src/core/eme/eme_manager.ts @@ -190,20 +190,27 @@ export default function EMEManager( } const firstSession = contentSessions.getAll()[0]; return firstSession.lastKeyUpdate$.pipe(mergeMap((evt) => { - for (let i = 0; i < evt.whitelistedKeyIds.length; i++) { - for (let j = 0; j < keyIds.length; j++) { - if (areArraysOfNumbersEqual(evt.whitelistedKeyIds[i], keyIds[j])) { - // Move corresponding session on top of the cache if it exists - const { loadedSessionsStore } = mediaKeysEvent.value.stores; - loadedSessionsStore.reuse(firstSession.initializationData); - return observableOf({ type: "init-data-ignored" as const, - value: { initializationData } }); + const hasAllNeededKeyIds = keyIds.every(keyId => { + for (let i = 0; i < evt.whitelistedKeyIds.length; i++) { + if (areArraysOfNumbersEqual(evt.whitelistedKeyIds[i], keyId)) { + return true; } } + }); + + if (!hasAllNeededKeyIds) { + // Not all keys are available in the current session, blacklist those + return observableOf({ type: "keys-update" as const, + value: { blacklistedKeyIDs: keyIds, + whitelistedKeyIds: [] } }); } - return observableOf({ type: "keys-update" as const, - value: { blacklistedKeyIDs: keyIds, - whitelistedKeyIds: [] } }); + + // Already handled by the current session. + // Move corresponding session on top of the cache if it exists + const { loadedSessionsStore } = mediaKeysEvent.value.stores; + loadedSessionsStore.reuse(firstSession.initializationData); + return observableOf({ type: "init-data-ignored" as const, + value: { initializationData } }); })); } else if (!contentSessions.storeIfNone(initializationData, { initializationData, lastKeyUpdate$ })) { From 5a653e61980f22724c47119fccd0294988eb032f Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Thu, 18 Feb 2021 13:34:26 +0100 Subject: [PATCH 42/75] Mark decipherable Representation as decipherable even if they were un-decipherable before This commit is based on the multiple-keys-per-license commits (in #904) and add on top of it a new behavior. Representations which have their key-id added to one of the `MediaKeyStatusMap` linked to the current content and which are not fallbacked from, will now have their `decipherable` property updated to `true` - even if it was set to `false` before (and thus even if we had fallbacked from it in the past). This development was made a lot easier by the work done to support the `singleLicensePer` option (#904) with now the concept of "whitelisted key ids", in opposition of the "blacklisted key ids" we fallback from. When a key id is found to be whitelisted (technically this means currently that its `MediaKeyStatus` is not either: `"internal-error"`, `"output-restricted"` or `"expired"`, the last one depending on `keySystems options) we will now: - update the related `Representation`'s `decipherable` property to `true` - regardless of its previous state - schedule a `decipherabilityUpdate` event with that update through the API (and through the `Manifest` object with the event of the same name) - In the `AdaptationStream` - only if the updates changed the list of available Representations for that Adaptation, re-construct the list of the Representations the ABR has to choose from --- To note that this has never been tested in real conditions. --- src/core/init/initialize_media_source.ts | 3 +- .../stream/adaptation/adaptation_stream.ts | 2 +- .../create_representation_estimator.ts | 58 +++++++++++++----- .../orchestrator/get_blacklisted_ranges.ts | 3 + .../orchestrator/stream_orchestrator.ts | 14 ++++- src/manifest/adaptation.ts | 12 ---- src/manifest/manifest.ts | 60 +++++++++++-------- 7 files changed, 96 insertions(+), 56 deletions(-) diff --git a/src/core/init/initialize_media_source.ts b/src/core/init/initialize_media_source.ts index 1a4d1fd85e..313c66317d 100644 --- a/src/core/init/initialize_media_source.ts +++ b/src/core/init/initialize_media_source.ts @@ -328,8 +328,7 @@ export default function InitializeOnMediaSource( const setUndecipherableRepresentations$ = emeManager$.pipe( tap((evt) => { if (evt.type === "keys-update") { - log.info("Init: blacklisting Representations based on keyIDs"); - manifest.addUndecipherableKIDs(evt.value.blacklistedKeyIDs); + manifest.updateDeciperabilitiesBasedOnKeyIds(evt.value); } else if (evt.type === "blacklist-protection-data") { log.info("Init: blacklisting Representations based on protection data."); manifest.addUndecipherableProtectionData(evt.value); diff --git a/src/core/stream/adaptation/adaptation_stream.ts b/src/core/stream/adaptation/adaptation_stream.ts index 4109fbe3ab..edc23e755a 100644 --- a/src/core/stream/adaptation/adaptation_stream.ts +++ b/src/core/stream/adaptation/adaptation_stream.ts @@ -197,7 +197,7 @@ export default function AdaptationStream({ const bufferGoalRatioMap: Partial> = {}; const { estimator$, requestFeedback$, streamFeedback$ } = - createRepresentationEstimator(adaptation, abrManager, clock$); + createRepresentationEstimator(content, abrManager, clock$); /** Allows the `RepresentationStream` to easily fetch media segments. */ const segmentFetcher = segmentFetcherCreator.createSegmentFetcher(adaptation.type, diff --git a/src/core/stream/adaptation/create_representation_estimator.ts b/src/core/stream/adaptation/create_representation_estimator.ts index a372831415..c5536ebd95 100644 --- a/src/core/stream/adaptation/create_representation_estimator.ts +++ b/src/core/stream/adaptation/create_representation_estimator.ts @@ -15,12 +15,23 @@ */ import { + concat as observableConcat, merge as observableMerge, Observable, + of as observableOf, Subject, } from "rxjs"; +import { + distinctUntilChanged, + map, + switchMap, +} from "rxjs/operators"; import { MediaError } from "../../../errors"; -import { Adaptation } from "../../../manifest"; +import Manifest, { + Adaptation, + Representation, +} from "../../../manifest"; +import { fromEvent } from "../../../utils/event_emitter"; import ABRManager, { IABREstimate, IABRManagerClockTick, @@ -52,13 +63,14 @@ import { * information on what data is expected. The idea is to provide as much data as * possible so the estimation is as adapted as possible. * - * @param {Object} adaptation + * @param {Object} content * @param {Object} abrManager * @param {Observable} clock$ * @returns {Object} */ export default function createRepresentationEstimator( - adaptation : Adaptation, + { manifest, adaptation } : { manifest : Manifest; + adaptation : Adaptation; }, abrManager : ABRManager, clock$ : Observable ) : { estimator$ : Observable; @@ -77,19 +89,35 @@ export default function createRepresentationEstimator( IABRRequestEndEvent>(); const abrEvents$ = observableMerge(streamFeedback$, requestFeedback$); - /** Representations for which a `RepresentationStream` can be created. */ - const playableRepresentations = adaptation.getPlayableRepresentations(); - if (playableRepresentations.length <= 0) { - const noRepErr = new MediaError("NO_PLAYABLE_REPRESENTATION", - "No Representation in the chosen " + - "Adaptation can be played"); - throw noRepErr; - } + const estimator$ = observableConcat( + observableOf(null), // Emit directly a first time on subscription + fromEvent(manifest, "decipherabilityUpdate") // then each time this event is triggered + ).pipe( + map(() : Representation[] => { + /** Representations for which a `RepresentationStream` can be created. */ + const playableRepresentations = adaptation.getPlayableRepresentations(); + if (playableRepresentations.length <= 0) { + const noRepErr = new MediaError("NO_PLAYABLE_REPRESENTATION", + "No Representation in the chosen " + + "Adaptation can be played"); + throw noRepErr; + } + return playableRepresentations; + }), + distinctUntilChanged((prevRepr, newRepr) => { + if (prevRepr.length !== newRepr.length) { + return false; + } + for (let i = 0; i < newRepr.length; i++) { + if (prevRepr[i].id !== newRepr[i].id) { + return false; + } + } + return true; + }), + switchMap((playableRepresentations) => + abrManager.get$(adaptation.type, playableRepresentations, clock$, abrEvents$))); - const estimator$ = abrManager.get$(adaptation.type, - playableRepresentations, - clock$, - abrEvents$); return { estimator$, streamFeedback$, requestFeedback$ }; diff --git a/src/core/stream/orchestrator/get_blacklisted_ranges.ts b/src/core/stream/orchestrator/get_blacklisted_ranges.ts index 1598fc4fe9..ad32145b10 100644 --- a/src/core/stream/orchestrator/get_blacklisted_ranges.ts +++ b/src/core/stream/orchestrator/get_blacklisted_ranges.ts @@ -36,6 +36,9 @@ export default function getBlacklistedRanges( period : Period; representation : Representation; }> ) : IRange[] { + if (contents.length === 0) { + return []; + } segmentBuffer.synchronizeInventory(); const accumulator : IRange[] = []; const inventory = segmentBuffer.getInventory(); diff --git a/src/core/stream/orchestrator/stream_orchestrator.ts b/src/core/stream/orchestrator/stream_orchestrator.ts index 95436d8900..dae281ad30 100644 --- a/src/core/stream/orchestrator/stream_orchestrator.ts +++ b/src/core/stream/orchestrator/stream_orchestrator.ts @@ -299,6 +299,7 @@ export default function StreamOrchestrator( }) ); + // Free the buffer of undecipherable data const handleDecipherabilityUpdate$ = fromEvent(manifest, "decipherabilityUpdate") .pipe(mergeMap((updates) => { const segmentBufferStatus = segmentBuffersStore.getStatus(bufferType); @@ -306,10 +307,21 @@ export default function StreamOrchestrator( if (!hasType || segmentBufferStatus.type !== "initialized") { return EMPTY; // no need to stop the current Streams. } + const undecipherableUpdates = updates.filter(update => + update.representation.decipherable === false); const segmentBuffer = segmentBufferStatus.value; - const rangesToClean = getBlacklistedRanges(segmentBuffer, updates); + const rangesToClean = getBlacklistedRanges(segmentBuffer, undecipherableUpdates); + if (rangesToClean.length === 0) { + // Nothing to clean => no buffer to flush. + return EMPTY; + } + + // We have to remove the undecipherable media data and then ask the + // current media element to be "flushed" + enableOutOfBoundsCheck = false; destroyStreams$.next(); + return observableConcat( ...rangesToClean.map(({ start, end }) => segmentBuffer.removeBuffer(start, end).pipe(ignoreElements())), diff --git a/src/manifest/adaptation.ts b/src/manifest/adaptation.ts index 09907260d4..4bb810eb10 100644 --- a/src/manifest/adaptation.ts +++ b/src/manifest/adaptation.ts @@ -110,13 +110,6 @@ export default class Adaptation { */ public manuallyAdded? : boolean; - /** - * `false` if from all Representation from this Adaptation, none is decipherable. - * `true` if at least one is known to be decipherable. - * `undefined` if this is not known for at least a single Representation. - */ - public decipherable? : boolean; - /** `true` if at least one Representation is in a supported codec. `false` otherwise. */ public isSupported : boolean; @@ -169,7 +162,6 @@ export default class Adaptation { const argsRepresentations = parsedAdaptation.representations; const representations : Representation[] = []; - let decipherable : boolean | undefined = false; let isSupported : boolean = false; for (let i = 0; i < argsRepresentations.length; i++) { const representation = new Representation(argsRepresentations[i], @@ -186,9 +178,6 @@ export default class Adaptation { isSignInterpreted: this.isSignInterpreted }); if (shouldAdd) { representations.push(representation); - if (decipherable === false && representation.decipherable !== false) { - decipherable = representation.decipherable; - } if (!isSupported && representation.isSupported) { isSupported = true; } @@ -197,7 +186,6 @@ export default class Adaptation { representations.sort((a, b) => a.bitrate - b.bitrate); this.representations = representations; - this.decipherable = decipherable; this.isSupported = isSupported; // for manuallyAdded adaptations (not in the manifest) diff --git a/src/manifest/manifest.ts b/src/manifest/manifest.ts index 6ffad8bb49..4997432e5e 100644 --- a/src/manifest/manifest.ts +++ b/src/manifest/manifest.ts @@ -487,27 +487,36 @@ export default class Manifest extends EventEmitter { /** * Look in the Manifest for Representations linked to the given key ID, * and mark them as being impossible to decrypt. - * Then trigger a "blacklist-update" event to notify everyone of the changes - * performed. - * @param {Array.} keyIDs - */ - public addUndecipherableKIDs(keyIDs : Uint8Array[]) : void { + * Then trigger a "decipherabilityUpdate" event to notify everyone of the + * changes performed. + * @param {Object} keyUpdates + */ + public updateDeciperabilitiesBasedOnKeyIds( + { whitelistedKeyIds, + blacklistedKeyIDs } : { whitelistedKeyIds : Uint8Array[]; + blacklistedKeyIDs : Uint8Array[]; } + ) : void { const updates = updateDeciperability(this, (representation) => { if (representation.decipherable === false || representation.contentProtections === undefined) { - return true; + return representation.decipherable; } const contentKIDs = representation.contentProtections.keyIds; for (let i = 0; i < contentKIDs.length; i++) { const elt = contentKIDs[i]; - for (let j = 0; j < keyIDs.length; j++) { - if (areArraysOfNumbersEqual(keyIDs[j], elt.keyId)) { + for (let j = 0; j < blacklistedKeyIDs.length; j++) { + if (areArraysOfNumbersEqual(blacklistedKeyIDs[j], elt.keyId)) { return false; } } + for (let j = 0; j < whitelistedKeyIds.length; j++) { + if (areArraysOfNumbersEqual(whitelistedKeyIds[j], elt.keyId)) { + return true; + } + } } - return true; + return representation.decipherable; }); if (updates.length > 0) { @@ -519,16 +528,14 @@ export default class Manifest extends EventEmitter { * Look in the Manifest for Representations linked to the given content * protection initialization data and mark them as being impossible to * decrypt. - * Then trigger a "blacklist-update" event to notify everyone of the changes - * performed. - * @param {Array.} keyIDs + * Then trigger a "decipherabilityUpdate" event to notify everyone of the + * changes performed. + * @param {Object} initData */ - public addUndecipherableProtectionData( - initData : IInitializationDataInfo - ) : void { + public addUndecipherableProtectionData(initData : IInitializationDataInfo) : void { const updates = updateDeciperability(this, (representation) => { if (representation.decipherable === false) { - return true; + return false; } const segmentProtections = representation.contentProtections?.initData ?? []; for (let i = 0; i < segmentProtections.length; i++) { @@ -548,7 +555,7 @@ export default class Manifest extends EventEmitter { } } } - return true; + return representation.decipherable; }); if (updates.length > 0) { @@ -751,17 +758,19 @@ export default class Manifest extends EventEmitter { } /** - * Update decipherability based on a predicate given. - * Do nothing for a Representation when the predicate returns false, mark as - * undecipherable when the predicate returns false. Returns every updates in - * an array. + * Update `decipherable` property of every `Representation` found in the + * Manifest based on the result of a `isDecipherable` callback: + * - When that callback returns `true`, update `decipherable` to `true` + * - When that callback returns `false`, update `decipherable` to `false` + * - When that callback returns `undefined`, update `decipherable` to + * `undefined` * @param {Manifest} manifest - * @param {Function} predicate + * @param {Function} isDecipherable * @returns {Array.} */ function updateDeciperability( manifest : Manifest, - predicate : (rep : Representation) => boolean + isDecipherable : (rep : Representation) => boolean | undefined ) : IDecipherabilityUpdateElement[] { const updates : IDecipherabilityUpdateElement[] = []; for (let i = 0; i < manifest.periods.length; i++) { @@ -772,9 +781,10 @@ function updateDeciperability( const representations = adaptation.representations; for (let k = 0; k < representations.length; k++) { const representation = representations[k]; - if (!predicate(representation)) { + const result = isDecipherable(representation); + if (result !== representation.decipherable) { updates.push({ manifest, period, adaptation, representation }); - representation.decipherable = false; + representation.decipherable = result; } } } From 6a7e324aaef5c872eb60508d0b86e48008957782 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Tue, 30 Mar 2021 13:03:34 +0200 Subject: [PATCH 43/75] doc/eme: update JSDoc in EME-related code --- src/core/eme/check_key_statuses.ts | 2 +- src/core/eme/types.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/eme/check_key_statuses.ts b/src/core/eme/check_key_statuses.ts index 1e9aa092bf..e6c052dd21 100644 --- a/src/core/eme/check_key_statuses.ts +++ b/src/core/eme/check_key_statuses.ts @@ -55,7 +55,7 @@ export interface IKeyStatusesCheckingOptions { * will be checked. * @param {Object} options * @param {String} keySystem - The configuration keySystem used for deciphering - * @returns {Array} - Warnings to send, whitelisted and blacklisted key ids. + * @returns {Object} - Warnings to send, whitelisted and blacklisted key ids. */ export default function checkKeyStatuses( session : MediaKeySession | ICustomMediaKeySession, diff --git a/src/core/eme/types.ts b/src/core/eme/types.ts index c708d9e2a9..e948edf706 100644 --- a/src/core/eme/types.ts +++ b/src/core/eme/types.ts @@ -46,6 +46,10 @@ export interface IInitializationDataInfo { /** * Hex encoded system id, which identifies the key system. * https://dashif.org/identifiers/content_protection/ + * + * If `undefined`, we don't know the system id for that initialization data. + * In that case, the initialization data might even be a concatenation of + * the initialization data from multiple system ids. */ systemId: string | undefined; /** From 55b1419063f110907455a955f822b55d0cdc9add Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Tue, 23 Mar 2021 15:19:07 +0100 Subject: [PATCH 44/75] Fix Period.getPlayableAdaptations --- src/manifest/period.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/manifest/period.ts b/src/manifest/period.ts index e74a6733df..bc9336c20e 100644 --- a/src/manifest/period.ts +++ b/src/manifest/period.ts @@ -175,7 +175,7 @@ export default class Period { getPlayableAdaptations(type? : IAdaptationType) : Adaptation[] { if (type === undefined) { return this.getAdaptations().filter(ada => { - return ada.isSupported && ada.decipherable !== false; + return ada.getPlayableRepresentations().length > 0; }); } const adaptationsForType = this.adaptations[type]; @@ -183,7 +183,7 @@ export default class Period { return []; } return adaptationsForType.filter(ada => { - return ada.isSupported && ada.decipherable !== false; + return ada.getPlayableRepresentations().length > 0; }); } } From efa7a44ca3366ddd98cfc7776f56808389559ccd Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Thu, 25 Mar 2021 14:58:38 +0100 Subject: [PATCH 45/75] update rxjs, typescript, and other dependencies --- package-lock.json | 4748 ++++++++++--------- package.json | 66 +- scripts/doc-generator/convert_MD_to_HMTL.js | 2 +- 3 files changed, 2499 insertions(+), 2317 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4ecef443bb..324d292cfa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,329 +5,358 @@ "requires": true, "packages": { "": { - "name": "rx-player", "version": "3.23.1", "license": "Apache-2.0", "dependencies": { "next-tick": "1.1.0", "pinkie": "2.0.4", - "rxjs": "6.6.3" + "rxjs": "6.6.7" }, "devDependencies": { - "@babel/core": "7.12.10", - "@babel/plugin-transform-runtime": "7.12.10", - "@babel/preset-env": "7.12.11", - "@babel/preset-react": "7.12.10", - "@types/chai": "4.2.14", - "@types/jest": "26.0.20", - "@types/mocha": "8.2.0", - "@types/node": "14.14.22", - "@types/sinon": "9.0.10", - "@typescript-eslint/eslint-plugin": "4.14.0", - "@typescript-eslint/eslint-plugin-tslint": "4.14.0", - "@typescript-eslint/parser": "4.14.0", + "@babel/core": "7.13.14", + "@babel/plugin-transform-runtime": "7.13.10", + "@babel/preset-env": "7.13.12", + "@babel/preset-react": "7.13.13", + "@types/chai": "4.2.15", + "@types/jest": "26.0.22", + "@types/mocha": "8.2.2", + "@types/node": "14.14.37", + "@types/sinon": "9.0.11", + "@typescript-eslint/eslint-plugin": "4.20.0", + "@typescript-eslint/eslint-plugin-tslint": "4.20.0", + "@typescript-eslint/parser": "4.20.0", "arraybuffer-loader": "1.0.8", "babel-loader": "8.2.2", - "chai": "4.2.0", + "chai": "4.3.4", "chart.js": "2.9.4", "cheerio": "1.0.0-rc.5", - "core-js": "3.8.3", + "core-js": "3.9.1", "cross-env": "7.0.3", - "css-loader": "5.0.1", - "eslint": "7.18.0", + "css-loader": "5.2.0", + "eslint": "7.23.0", "eslint-plugin-import": "2.22.1", - "eslint-plugin-jsdoc": "31.0.8", - "eslint-plugin-react": "7.22.0", + "eslint-plugin-jsdoc": "32.3.0", + "eslint-plugin-react": "7.23.1", "esm": "3.2.25", "express": "4.17.1", "file-loader": "6.2.0", - "highlight.js": "10.5.0", + "highlight.js": "10.7.1", "istanbul-instrumenter-loader": "3.0.1", "jest": "26.6.3", - "karma": "6.0.1", + "karma": "6.3.2", "karma-chrome-launcher": "3.1.0", "karma-coverage-istanbul-reporter": "3.0.3", "karma-firefox-launcher": "2.1.0", "karma-mocha": "2.0.1", "karma-mocha-reporter": "2.2.5", - "karma-webpack": "5.0.0-alpha.5", + "karma-webpack": "5.0.0", "markdown-it": "12.0.4", "markdown-it-emoji": "2.0.0", - "mocha": "8.2.1", + "mocha": "8.3.2", "mocha-loader": "5.1.5", "npm-scripts-info": "0.3.9", "raw-loader": "4.0.2", - "react": "17.0.1", - "react-dom": "17.0.1", + "react": "17.0.2", + "react-dom": "17.0.2", "regenerator-runtime": "0.13.7", - "sanitize-html": "2.3.1", - "semver": "7.3.4", - "sinon": "9.2.3", + "sanitize-html": "2.3.3", + "semver": "7.3.5", + "sinon": "10.0.0", "style-loader": "2.0.0", "terser-webpack-plugin": "5.1.1", - "ts-jest": "26.4.4", - "ts-loader": "8.0.14", + "ts-jest": "26.5.4", + "ts-loader": "8.1.0", "tslint": "6.1.3", - "typescript": "4.1.3", + "typescript": "4.2.3", "url-loader": "4.1.1", - "webpack": "5.17.0", + "webpack": "5.28.0", "webpack-bundle-analyzer": "4.4.0", - "webpack-cli": "4.4.0" + "webpack-cli": "4.6.0" } }, "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "dependencies": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, "node_modules/@babel/compat-data": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.7.tgz", - "integrity": "sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.12.tgz", + "integrity": "sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ==", "dev": true }, "node_modules/@babel/core": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", - "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.10", + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.14.tgz", + "integrity": "sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-compilation-targets": "^7.13.13", + "@babel/helper-module-transforms": "^7.13.14", + "@babel/helpers": "^7.13.10", + "@babel/parser": "^7.13.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", + "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "lodash": "^4.17.19", - "semver": "^5.4.1", + "semver": "^6.3.0", "source-map": "^0.5.0" }, "engines": { "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, "node_modules/@babel/core/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "version": "7.13.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", + "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", "dev": true, "dependencies": { - "@babel/types": "^7.12.11", + "@babel/types": "^7.13.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", - "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", + "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", "dev": true, "dependencies": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", - "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz", + "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==", "dev": true, "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-explode-assignable-expression": "^7.12.13", + "@babel/types": "^7.12.13" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz", - "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==", + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz", + "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.12.5", - "@babel/helper-validator-option": "^7.12.1", + "@babel/compat-data": "^7.13.12", + "@babel/helper-validator-option": "^7.12.17", "browserslist": "^4.14.5", - "semver": "^5.5.0" + "semver": "^6.3.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz", - "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==", + "version": "7.13.11", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", + "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.10.4" + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-member-expression-to-functions": "^7.13.0", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-split-export-declaration": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", - "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz", + "integrity": "sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-annotate-as-pure": "^7.12.13", "regexpu-core": "^4.7.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-define-map": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", - "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz", + "integrity": "sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.10.4", - "@babel/types": "^7.10.5", - "lodash": "^4.17.19" + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz", - "integrity": "sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz", + "integrity": "sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==", "dev": true, "dependencies": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.13.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", "dev": true, "dependencies": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz", - "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz", + "integrity": "sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g==", "dev": true, "dependencies": { - "@babel/types": "^7.10.4" + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", "dev": true, "dependencies": { - "@babel/types": "^7.12.7" + "@babel/types": "^7.13.12" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", "dev": true, "dependencies": { - "@babel/types": "^7.12.5" + "@babel/types": "^7.13.12" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "lodash": "^4.17.19" + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", + "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", "dev": true, "dependencies": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", + "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", "dev": true }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz", - "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz", + "integrity": "sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-wrap-function": "^7.10.4", - "@babel/types": "^7.12.1" + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-wrap-function": "^7.13.0", + "@babel/types": "^7.13.0" } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", "dev": true, "dependencies": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.13.12" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { @@ -340,12 +369,12 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", "dev": true, "dependencies": { - "@babel/types": "^7.12.11" + "@babel/types": "^7.12.13" } }, "node_modules/@babel/helper-validator-identifier": { @@ -355,49 +384,49 @@ "dev": true }, "node_modules/@babel/helper-validator-option": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz", - "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", "dev": true }, "node_modules/@babel/helper-wrap-function": { - "version": "7.12.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz", - "integrity": "sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz", + "integrity": "sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-function-name": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" } }, "node_modules/@babel/helpers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", - "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", + "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", "dev": true, "dependencies": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" } }, "node_modules/@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", + "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "node_modules/@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz", + "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -406,140 +435,195 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz", + "integrity": "sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.13.12" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz", - "integrity": "sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.8.tgz", + "integrity": "sha512-rPBnhj+WgoSmgq+4gQUtXx/vOcU+UYtjy1AA/aeD61Hwj410fwYyqfUcRP3lR8ucgliVJL/G7sXcNUecC75IXA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.12.1", - "@babel/plugin-syntax-async-generators": "^7.8.0" + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-remap-async-to-generator": "^7.13.0", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz", - "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", + "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", - "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", + "integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-dynamic-import": "^7.8.0" + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz", - "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", + "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz", - "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz", + "integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.0" + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz", - "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz", + "integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz", - "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz", + "integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz", - "integrity": "sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", + "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", - "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz", + "integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.12.1" + "@babel/compat-data": "^7.13.8", + "@babel/helper-compilation-targets": "^7.13.8", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz", - "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz", + "integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz", - "integrity": "sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz", + "integrity": "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz", - "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz", + "integrity": "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==", "dev": true, "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz", - "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz", + "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" }, "engines": { "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-async-generators": { @@ -561,12 +645,15 @@ } }, "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", - "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-dynamic-import": { @@ -576,6 +663,9 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-export-namespace-from": { @@ -585,6 +675,9 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-import-meta": { @@ -606,12 +699,15 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", - "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.13.tgz", + "integrity": "sha512-d4HM23Q1K7oq/SLNmG6mRt85l2csmQ0cHRaxRXjKW0YFdEXqlZ5kzFQKH5Uc3rDJECgu+yCRgPkG04Mm98R/1g==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { @@ -669,273 +765,353 @@ } }, "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", - "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", + "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz", - "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", + "integrity": "sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz", - "integrity": "sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz", + "integrity": "sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.12.1" + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-remap-async-to-generator": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz", - "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz", + "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz", - "integrity": "sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz", + "integrity": "sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz", - "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz", + "integrity": "sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-define-map": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-split-export-declaration": "^7.12.13", "globals": "^11.1.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz", - "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz", + "integrity": "sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz", - "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz", + "integrity": "sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz", - "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz", + "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz", - "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz", + "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz", - "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz", + "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==", "dev": true, "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz", - "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz", + "integrity": "sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz", - "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz", + "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz", - "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz", + "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz", - "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz", + "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz", - "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz", + "integrity": "sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz", - "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz", + "integrity": "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-simple-access": "^7.12.13", "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz", - "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz", + "integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==", "dev": true, "dependencies": { - "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-hoist-variables": "^7.13.0", + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-identifier": "^7.12.11", "babel-plugin-dynamic-import-node": "^2.3.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz", - "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz", + "integrity": "sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw==", "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz", - "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz", + "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1" + "@babel/helper-create-regexp-features-plugin": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz", - "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz", + "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz", - "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz", + "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1" + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz", - "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz", + "integrity": "sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz", - "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz", + "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz", - "integrity": "sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.13.tgz", + "integrity": "sha512-MprESJzI9O5VnJZrL7gg1MpdqmiFcUv41Jc7SahxYsNP2kDkFqClxxTZq+1Qv4AFCamm+GXMRDQINNn+qrxmiA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.12.tgz", - "integrity": "sha512-JDWGuzGNWscYcq8oJVCtSE61a5+XAOos+V0HrxnDieUus4UMnBEosDnY1VJqU5iZ4pA04QY7l0+JvHL1hZEfsw==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.13.12.tgz", + "integrity": "sha512-jcEI2UqIcpCqB5U5DRxIl0tQEProI2gcu+g8VTIqxLO5Iidojb4d77q+fwGseCvd8af/lJ9masp4QWzBXFE2xA==", "dev": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.12.10", - "@babel/helper-module-imports": "^7.12.5", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.12.1", - "@babel/types": "^7.12.12" + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-jsx": "^7.12.13", + "@babel/types": "^7.13.12" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.12.tgz", - "integrity": "sha512-i1AxnKxHeMxUaWVXQOSIco4tvVvvCxMSfeBMnMM06mpaJt3g+MpxYQQrDfojUQldP1xxraPSJYSMEljoWM/dCg==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.17.tgz", + "integrity": "sha512-BPjYV86SVuOaudFhsJR1zjgxxOhJDt6JHNoD48DxWEIxUCAMjV1ys6DYw4SDYZh0b1QsS2vfIA9t/ZsQGsDOUQ==", "dev": true, "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.12.12" + "@babel/plugin-transform-react-jsx": "^7.12.17" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-react-pure-annotations": { @@ -949,189 +1125,228 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz", - "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz", + "integrity": "sha512-lxb2ZAvSLyJ2PEe47hoGWPmW22v7CtSl9jW8mingV4H2sEX/JOcrAj2nPuGWi56ERUm2bUpjKzONAuT6HCn2EA==", "dev": true, "dependencies": { "regenerator-transform": "^0.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz", - "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz", + "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.10.tgz", - "integrity": "sha512-xOrUfzPxw7+WDm9igMgQCbO3cJKymX7dFdsgRr1eu9n3KjjyU4pptIXbXPseQDquw+W+RuJEJMHKHNsPNNm3CA==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.10.tgz", + "integrity": "sha512-Y5k8ipgfvz5d/76tx7JYbKQTcgFSU6VgJ3kKQv4zGTKr+a9T/KBvfRvGtSFgKDQGt/DBykQixV0vNWKIdzWErA==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.12.5", - "@babel/helper-plugin-utils": "^7.10.4", - "semver": "^5.5.1" + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "babel-plugin-polyfill-corejs2": "^0.1.4", + "babel-plugin-polyfill-corejs3": "^0.1.3", + "babel-plugin-polyfill-regenerator": "^0.1.2", + "semver": "^6.3.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz", - "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", + "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz", - "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz", + "integrity": "sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz", - "integrity": "sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz", + "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz", - "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz", + "integrity": "sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.13.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz", - "integrity": "sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz", + "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz", - "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", + "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz", - "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz", + "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==", "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/preset-env": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.11.tgz", - "integrity": "sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.12.7", - "@babel/helper-compilation-targets": "^7.12.5", - "@babel/helper-module-imports": "^7.12.5", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-validator-option": "^7.12.11", - "@babel/plugin-proposal-async-generator-functions": "^7.12.1", - "@babel/plugin-proposal-class-properties": "^7.12.1", - "@babel/plugin-proposal-dynamic-import": "^7.12.1", - "@babel/plugin-proposal-export-namespace-from": "^7.12.1", - "@babel/plugin-proposal-json-strings": "^7.12.1", - "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", - "@babel/plugin-proposal-numeric-separator": "^7.12.7", - "@babel/plugin-proposal-object-rest-spread": "^7.12.1", - "@babel/plugin-proposal-optional-catch-binding": "^7.12.1", - "@babel/plugin-proposal-optional-chaining": "^7.12.7", - "@babel/plugin-proposal-private-methods": "^7.12.1", - "@babel/plugin-proposal-unicode-property-regex": "^7.12.1", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.12.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.12.tgz", + "integrity": "sha512-JzElc6jk3Ko6zuZgBtjOd01pf9yYDEIH8BcqVuYIuOkzOwDesoa/Nz4gIo4lBG6K861KTV9TvIgmFuT6ytOaAA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.13.12", + "@babel/helper-compilation-targets": "^7.13.10", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-option": "^7.12.17", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-async-generator-functions": "^7.13.8", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-dynamic-import": "^7.13.8", + "@babel/plugin-proposal-export-namespace-from": "^7.12.13", + "@babel/plugin-proposal-json-strings": "^7.13.8", + "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", + "@babel/plugin-proposal-numeric-separator": "^7.12.13", + "@babel/plugin-proposal-object-rest-spread": "^7.13.8", + "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-private-methods": "^7.13.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.12.1", - "@babel/plugin-transform-arrow-functions": "^7.12.1", - "@babel/plugin-transform-async-to-generator": "^7.12.1", - "@babel/plugin-transform-block-scoped-functions": "^7.12.1", - "@babel/plugin-transform-block-scoping": "^7.12.11", - "@babel/plugin-transform-classes": "^7.12.1", - "@babel/plugin-transform-computed-properties": "^7.12.1", - "@babel/plugin-transform-destructuring": "^7.12.1", - "@babel/plugin-transform-dotall-regex": "^7.12.1", - "@babel/plugin-transform-duplicate-keys": "^7.12.1", - "@babel/plugin-transform-exponentiation-operator": "^7.12.1", - "@babel/plugin-transform-for-of": "^7.12.1", - "@babel/plugin-transform-function-name": "^7.12.1", - "@babel/plugin-transform-literals": "^7.12.1", - "@babel/plugin-transform-member-expression-literals": "^7.12.1", - "@babel/plugin-transform-modules-amd": "^7.12.1", - "@babel/plugin-transform-modules-commonjs": "^7.12.1", - "@babel/plugin-transform-modules-systemjs": "^7.12.1", - "@babel/plugin-transform-modules-umd": "^7.12.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1", - "@babel/plugin-transform-new-target": "^7.12.1", - "@babel/plugin-transform-object-super": "^7.12.1", - "@babel/plugin-transform-parameters": "^7.12.1", - "@babel/plugin-transform-property-literals": "^7.12.1", - "@babel/plugin-transform-regenerator": "^7.12.1", - "@babel/plugin-transform-reserved-words": "^7.12.1", - "@babel/plugin-transform-shorthand-properties": "^7.12.1", - "@babel/plugin-transform-spread": "^7.12.1", - "@babel/plugin-transform-sticky-regex": "^7.12.7", - "@babel/plugin-transform-template-literals": "^7.12.1", - "@babel/plugin-transform-typeof-symbol": "^7.12.10", - "@babel/plugin-transform-unicode-escapes": "^7.12.1", - "@babel/plugin-transform-unicode-regex": "^7.12.1", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.12.11", - "core-js-compat": "^3.8.0", - "semver": "^5.5.0" + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.12.13", + "@babel/plugin-transform-arrow-functions": "^7.13.0", + "@babel/plugin-transform-async-to-generator": "^7.13.0", + "@babel/plugin-transform-block-scoped-functions": "^7.12.13", + "@babel/plugin-transform-block-scoping": "^7.12.13", + "@babel/plugin-transform-classes": "^7.13.0", + "@babel/plugin-transform-computed-properties": "^7.13.0", + "@babel/plugin-transform-destructuring": "^7.13.0", + "@babel/plugin-transform-dotall-regex": "^7.12.13", + "@babel/plugin-transform-duplicate-keys": "^7.12.13", + "@babel/plugin-transform-exponentiation-operator": "^7.12.13", + "@babel/plugin-transform-for-of": "^7.13.0", + "@babel/plugin-transform-function-name": "^7.12.13", + "@babel/plugin-transform-literals": "^7.12.13", + "@babel/plugin-transform-member-expression-literals": "^7.12.13", + "@babel/plugin-transform-modules-amd": "^7.13.0", + "@babel/plugin-transform-modules-commonjs": "^7.13.8", + "@babel/plugin-transform-modules-systemjs": "^7.13.8", + "@babel/plugin-transform-modules-umd": "^7.13.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", + "@babel/plugin-transform-new-target": "^7.12.13", + "@babel/plugin-transform-object-super": "^7.12.13", + "@babel/plugin-transform-parameters": "^7.13.0", + "@babel/plugin-transform-property-literals": "^7.12.13", + "@babel/plugin-transform-regenerator": "^7.12.13", + "@babel/plugin-transform-reserved-words": "^7.12.13", + "@babel/plugin-transform-shorthand-properties": "^7.12.13", + "@babel/plugin-transform-spread": "^7.13.0", + "@babel/plugin-transform-sticky-regex": "^7.12.13", + "@babel/plugin-transform-template-literals": "^7.13.0", + "@babel/plugin-transform-typeof-symbol": "^7.12.13", + "@babel/plugin-transform-unicode-escapes": "^7.12.13", + "@babel/plugin-transform-unicode-regex": "^7.12.13", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.13.12", + "babel-plugin-polyfill-corejs2": "^0.1.4", + "babel-plugin-polyfill-corejs3": "^0.1.3", + "babel-plugin-polyfill-regenerator": "^0.1.2", + "core-js-compat": "^3.9.0", + "semver": "^6.3.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/preset-env/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, "bin": { - "semver": "bin/semver" + "semver": "bin/semver.js" } }, "node_modules/@babel/preset-modules": { @@ -1148,59 +1363,62 @@ } }, "node_modules/@babel/preset-react": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.12.10.tgz", - "integrity": "sha512-vtQNjaHRl4DUpp+t+g4wvTHsLQuye+n0H/wsXIZRn69oz/fvNC7gQ4IK73zGJBaxvHoxElDvnYCthMcT7uzFoQ==", + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.13.13.tgz", + "integrity": "sha512-gx+tDLIE06sRjKJkVtpZ/t3mzCDOnPG+ggHZG9lffUbX8+wC739x20YQc9V35Do6ZAxaUc/HhVHIiOzz5MvDmA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-transform-react-display-name": "^7.12.1", - "@babel/plugin-transform-react-jsx": "^7.12.10", - "@babel/plugin-transform-react-jsx-development": "^7.12.7", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-option": "^7.12.17", + "@babel/plugin-transform-react-display-name": "^7.12.13", + "@babel/plugin-transform-react-jsx": "^7.13.12", + "@babel/plugin-transform-react-jsx-development": "^7.12.17", "@babel/plugin-transform-react-pure-annotations": "^7.12.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "dev": true, "dependencies": { "regenerator-runtime": "^0.13.4" } }, "node_modules/@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "node_modules/@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.13.tgz", + "integrity": "sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.13", + "@babel/types": "^7.13.13", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" + "globals": "^11.1.0" } }, "node_modules/@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", + "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.12.11", @@ -1240,9 +1458,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz", - "integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", + "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -1252,7 +1470,6 @@ "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", - "lodash": "^4.17.20", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, @@ -1270,15 +1487,9 @@ }, "engines": { "node": ">=8" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@istanbuljs/load-nyc-config": { @@ -2049,9 +2260,9 @@ } }, "node_modules/@types/chai": { - "version": "4.2.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.14.tgz", - "integrity": "sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==", + "version": "4.2.15", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.15.tgz", + "integrity": "sha512-rYff6FI+ZTKAPkJUoyz7Udq3GaoDZnxYDEvdEdFZASiA7PoErltHezDishqQiSDWrGxvxmplH304jyzQmjp0AQ==", "dev": true }, "node_modules/@types/component-emitter": { @@ -2132,9 +2343,9 @@ } }, "node_modules/@types/jest": { - "version": "26.0.20", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.20.tgz", - "integrity": "sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA==", + "version": "26.0.22", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.22.tgz", + "integrity": "sha512-eeWwWjlqxvBxc4oQdkueW5OF/gtfSceKk4OnOAGlUSwS/liBRtZppbJuz1YkgbrbfGOoeBHun9fOvXnjNwrSOw==", "dev": true, "dependencies": { "jest-diff": "^26.0.0", @@ -2154,15 +2365,15 @@ "dev": true }, "node_modules/@types/mocha": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.0.tgz", - "integrity": "sha512-/Sge3BymXo4lKc31C8OINJgXLaw+7vL1/L1pGiBNpGrBiT8FQiaFpSYV0uhTaG4y78vcMBTMFsWaHDvuD+xGzQ==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", + "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", "dev": true }, "node_modules/@types/node": { - "version": "14.14.22", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz", - "integrity": "sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==", + "version": "14.14.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz", + "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==", "dev": true }, "node_modules/@types/normalize-package-data": { @@ -2178,9 +2389,9 @@ "dev": true }, "node_modules/@types/sinon": { - "version": "9.0.10", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.10.tgz", - "integrity": "sha512-/faDC0erR06wMdybwI/uR8wEKV/E83T0k4sepIpB7gXuy2gzx2xiOjmztq6a2Y6rIGJ04D+6UU0VBmWy+4HEMA==", + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.11.tgz", + "integrity": "sha512-PwP4UY33SeeVKodNE37ZlOsR9cReypbMJOhZ7BVE0lB+Hix3efCOxiJWiE5Ia+yL9Cn2Ch72EjFTRze8RZsNtg==", "dev": true, "dependencies": { "@types/sinonjs__fake-timers": "*" @@ -2214,13 +2425,13 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.14.0.tgz", - "integrity": "sha512-IJ5e2W7uFNfg4qh9eHkHRUCbgZ8VKtGwD07kannJvM5t/GU8P8+24NX8gi3Hf5jST5oWPY8kyV1s/WtfiZ4+Ww==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.20.0.tgz", + "integrity": "sha512-sw+3HO5aehYqn5w177z2D82ZQlqHCwcKSMboueo7oE4KU9QiC0SAgfS/D4z9xXvpTc8Bt41Raa9fBR8T2tIhoQ==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "4.14.0", - "@typescript-eslint/scope-manager": "4.14.0", + "@typescript-eslint/experimental-utils": "4.20.0", + "@typescript-eslint/scope-manager": "4.20.0", "debug": "^4.1.1", "functional-red-black-tree": "^1.0.1", "lodash": "^4.17.15", @@ -2230,105 +2441,162 @@ }, "engines": { "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/eslint-plugin-tslint": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin-tslint/-/eslint-plugin-tslint-4.14.0.tgz", - "integrity": "sha512-d14sju1LLPvzyZItiXw7WhqKUkiJaf2Y2g5JlAx90NhNseTyElcTmZW5vo6gqLDPLb2VsKQ4KYMYKZNTXXJGpw==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin-tslint/-/eslint-plugin-tslint-4.20.0.tgz", + "integrity": "sha512-9fFZGUzWrFjlw2P5cBytXVtXiOkPo/hgmqvm9vE9NCs9rfiRDbKMaDiPA6OlfPWZhtZKdsS8GyOdPDBtU3VLsA==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "4.14.0", + "@typescript-eslint/experimental-utils": "4.20.0", "lodash": "^4.17.15" }, "engines": { "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0", + "tslint": "^5.0.0 || ^6.0.0", + "typescript": "*" } }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.14.0.tgz", - "integrity": "sha512-6i6eAoiPlXMKRbXzvoQD5Yn9L7k9ezzGRvzC/x1V3650rUk3c3AOjQyGYyF9BDxQQDK2ElmKOZRD0CbtdkMzQQ==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.20.0.tgz", + "integrity": "sha512-sQNlf6rjLq2yB5lELl3gOE7OuoA/6IVXJUJ+Vs7emrQMva14CkOwyQwD7CW+TkmOJ4Q/YGmoDLmbfFrpGmbKng==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.14.0", - "@typescript-eslint/types": "4.14.0", - "@typescript-eslint/typescript-estree": "4.14.0", + "@typescript-eslint/scope-manager": "4.20.0", + "@typescript-eslint/types": "4.20.0", + "@typescript-eslint/typescript-estree": "4.20.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" }, "engines": { "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" } }, "node_modules/@typescript-eslint/parser": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.14.0.tgz", - "integrity": "sha512-sUDeuCjBU+ZF3Lzw0hphTyScmDDJ5QVkyE21pRoBo8iDl7WBtVFS+WDN3blY1CH3SBt7EmYCw6wfmJjF0l/uYg==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.20.0.tgz", + "integrity": "sha512-m6vDtgL9EABdjMtKVw5rr6DdeMCH3OA1vFb0dAyuZSa3e5yw1YRzlwFnm9knma9Lz6b2GPvoNSa8vOXrqsaglA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "4.14.0", - "@typescript-eslint/types": "4.14.0", - "@typescript-eslint/typescript-estree": "4.14.0", + "@typescript-eslint/scope-manager": "4.20.0", + "@typescript-eslint/types": "4.20.0", + "@typescript-eslint/typescript-estree": "4.20.0", "debug": "^4.1.1" }, "engines": { "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.14.0.tgz", - "integrity": "sha512-/J+LlRMdbPh4RdL4hfP1eCwHN5bAhFAGOTsvE6SxsrM/47XQiPSgF5MDgLyp/i9kbZV9Lx80DW0OpPkzL+uf8Q==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.20.0.tgz", + "integrity": "sha512-/zm6WR6iclD5HhGpcwl/GOYDTzrTHmvf8LLLkwKqqPKG6+KZt/CfSgPCiybshmck66M2L5fWSF/MKNuCwtKQSQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.14.0", - "@typescript-eslint/visitor-keys": "4.14.0" + "@typescript-eslint/types": "4.20.0", + "@typescript-eslint/visitor-keys": "4.20.0" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/types": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.14.0.tgz", - "integrity": "sha512-VsQE4VvpldHrTFuVPY1ZnHn/Txw6cZGjL48e+iBxTi2ksa9DmebKjAeFmTVAYoSkTk7gjA7UqJ7pIsyifTsI4A==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.20.0.tgz", + "integrity": "sha512-cYY+1PIjei1nk49JAPnH1VEnu7OYdWRdJhYI5wiKOUMhLTG1qsx5cQxCUTuwWCmQoyriadz3Ni8HZmGSofeC+w==", "dev": true, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.14.0.tgz", - "integrity": "sha512-wRjZ5qLao+bvS2F7pX4qi2oLcOONIB+ru8RGBieDptq/SudYwshveORwCVU4/yMAd4GK7Fsf8Uq1tjV838erag==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.20.0.tgz", + "integrity": "sha512-Knpp0reOd4ZsyoEJdW8i/sK3mtZ47Ls7ZHvD8WVABNx5Xnn7KhenMTRGegoyMTx6TiXlOVgMz9r0pDgXTEEIHA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.14.0", - "@typescript-eslint/visitor-keys": "4.14.0", + "@typescript-eslint/types": "4.20.0", + "@typescript-eslint/visitor-keys": "4.20.0", "debug": "^4.1.1", "globby": "^11.0.1", "is-glob": "^4.0.1", - "lodash": "^4.17.15", "semver": "^7.3.2", "tsutils": "^3.17.1" }, "engines": { "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.14.0.tgz", - "integrity": "sha512-MeHHzUyRI50DuiPgV9+LxcM52FCJFYjJiWHtXlbyC27b80mfOwKeiKI+MHOTEpcpfmoPFm/vvQS88bYIx6PZTA==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.20.0.tgz", + "integrity": "sha512-NXKRM3oOVQL8yNFDNCZuieRIwZ5UtjNLYtmMx2PacEAGmbaEYtGgVHUHVyZvU/0rYZcizdrWjDo+WBtRPSgq+A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.14.0", + "@typescript-eslint/types": "4.20.0", "eslint-visitor-keys": "^2.0.0" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@ungap/promise-all-settled": { @@ -2484,25 +2752,40 @@ } }, "node_modules/@webpack-cli/configtest": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.0.tgz", - "integrity": "sha512-Un0SdBoN1h4ACnIO7EiCjWuyhNI0Jl96JC+63q6xi4HDUYRZn8Auluea9D+v9NWKc5J4sICVEltdBaVjLX39xw==", - "dev": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.2.tgz", + "integrity": "sha512-3OBzV2fBGZ5TBfdW50cha1lHDVf9vlvRXnjpVbJBa20pSZQaSkMJZiwA8V2vD9ogyeXn8nU5s5A6mHyf5jhMzA==", + "dev": true, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x", + "webpack-cli": "4.x.x" + } }, "node_modules/@webpack-cli/info": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.1.tgz", - "integrity": "sha512-fLnDML5HZ5AEKzHul8xLAksoKN2cibu6MgonkUj8R9V7bbeVRkd1XbGEGWrAUNYHbX1jcqCsDEpBviE5StPMzQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.3.tgz", + "integrity": "sha512-lLek3/T7u40lTqzCGpC6CAbY6+vXhdhmwFRxZLMnRm6/sIF/7qMpT8MocXCRQfz0JAh63wpbXLMnsQ5162WS7Q==", "dev": true, "dependencies": { "envinfo": "^7.7.3" + }, + "peerDependencies": { + "webpack-cli": "4.x.x" } }, "node_modules/@webpack-cli/serve": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.2.2.tgz", - "integrity": "sha512-03GkWxcgFfm8+WIwcsqJb9agrSDNDDoxaNnexPnCCexP5SCE4IgFd9lNpSy+K2nFqVMpgTFw6SwbmVAVTndVew==", - "dev": true + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.1.tgz", + "integrity": "sha512-0qXvpeYO6vaNoRBI52/UsbcaBydJCggoBBnIo/ovQQdn6fug0BgwsjorV1hVS7fMqGVTZGcVxv8334gjmbj5hw==", + "dev": true, + "peerDependencies": { + "webpack-cli": "4.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", @@ -2561,7 +2844,10 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, "node_modules/acorn-walk": { "version": "7.2.0", @@ -2706,19 +2992,22 @@ "dev": true }, "node_modules/array-includes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.2.tgz", - "integrity": "sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "get-intrinsic": "^1.0.1", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", "is-string": "^1.0.5" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array-union": { @@ -3144,6 +3433,54 @@ "node": ">= 10.14.2" } }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.1.10.tgz", + "integrity": "sha512-DO95wD4g0A8KRaHKi0D51NdGXzvpqVLnLu5BTvDlpqUEpTmeEtypgC1xqesORaWmiUOQI14UHKlzNd9iZ2G3ZA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.13.0", + "@babel/helper-define-polyfill-provider": "^0.1.5", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz", + "integrity": "sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.1.5", + "core-js-compat": "^3.8.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.1.6.tgz", + "integrity": "sha512-OUrYG9iKPKz8NxswXbRAdSwF0GhRdIEMTloQATJi4bDuFqrXaXcCUT/VGNrr8pBcjMh1RxZ7Xt9cytVJTJfvMg==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.1.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", @@ -3479,22 +3816,26 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz", - "integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==", + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001173", + "caniuse-lite": "^1.0.30001181", "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.634", + "electron-to-chromium": "^1.3.649", "escalade": "^3.1.1", - "node-releases": "^1.1.69" + "node-releases": "^1.1.70" }, "bin": { "browserslist": "cli.js" }, "engines": { "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" } }, "node_modules/bs-logger": { @@ -3614,9 +3955,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001179", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001179.tgz", - "integrity": "sha512-blMmO0QQujuUWZKyVrD1msR4WNDAqb/UPO1Sw2WWsQ7deoM5bJiicKnWJ1Y0NS/aGINSnKPIWBMw5luX+NDUCA==", + "version": "1.0.30001204", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001204.tgz", + "integrity": "sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ==", "dev": true }, "node_modules/capture-exit": { @@ -3638,16 +3979,16 @@ "dev": true }, "node_modules/chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", "deep-eql": "^3.0.1", "get-func-name": "^2.0.0", - "pathval": "^1.1.0", + "pathval": "^1.1.1", "type-detect": "^4.0.5" }, "engines": { @@ -3888,9 +4229,9 @@ "dev": true }, "node_modules/colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, "node_modules/colors": { @@ -3921,9 +4262,9 @@ "dev": true }, "node_modules/comment-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.1.tgz", - "integrity": "sha512-vue7cRi1ZO5/72FJ+wZ5+siTSBlUv3ZksTk8bWD2IkaA6obitzMZP3yI65azTJLckwmi8lxfPP5Sd9oGuZ8e2g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.2.tgz", + "integrity": "sha512-AOdq0i8ghZudnYv8RUnHrhTgafUGs61Rdz9jemU5x2lnZwAWyOq7vySo626K59e1fVKH1xSRorJwPVRLSWOoAQ==", "dev": true, "engines": { "node": ">= 10.0.0" @@ -4041,19 +4382,28 @@ } }, "node_modules/core-js": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz", - "integrity": "sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q==", - "dev": true + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.9.1.tgz", + "integrity": "sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } }, "node_modules/core-js-compat": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.3.tgz", - "integrity": "sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.9.1.tgz", + "integrity": "sha512-jXAirMQxrkbiiLsCx9bQPJFA6llDadKMpYrBJQJ3/c4/vsPP/fAf29h24tviRlvwUL6AmY5CHLu2GvjuYviQqA==", "dev": true, "dependencies": { - "browserslist": "^4.16.1", + "browserslist": "^4.16.3", "semver": "7.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, "node_modules/core-js-compat/node_modules/semver": { @@ -4117,26 +4467,33 @@ } }, "node_modules/css-loader": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.0.1.tgz", - "integrity": "sha512-cXc2ti9V234cq7rJzFKhirb2L2iPy8ZjALeVJAozXYz9te3r4eqLSixNAbMDJSgJEQywqXzs8gonxaboeKqwiw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.0.tgz", + "integrity": "sha512-MfRo2MjEeLXMlUkeUwN71Vx5oc6EJnx5UQ4Yi9iUtYQvrPtwLUucYptz0hc6n++kdNcyF5olYBS4vPjJDAcLkw==", "dev": true, "dependencies": { "camelcase": "^6.2.0", "cssesc": "^3.0.0", - "icss-utils": "^5.0.0", + "icss-utils": "^5.1.0", "loader-utils": "^2.0.0", - "postcss": "^8.1.4", + "postcss": "^8.2.8", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.1.0", "schema-utils": "^3.0.0", - "semver": "^7.3.2" + "semver": "^7.3.4" }, "engines": { "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.27.0 || ^5.0.0" } }, "node_modules/css-loader/node_modules/loader-utils": { @@ -4615,9 +4972,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.3.643", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.643.tgz", - "integrity": "sha512-TGomM4gj8adt/uqRgPbu9F0yhUVAR1deww5X0fvbQgpGr9suSMjLgc4IwQ9YKGkp1t03cDbZum20OfAkiTYjAg==", + "version": "1.3.698", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.698.tgz", + "integrity": "sha512-VEXDzYblnlT+g8Q3gedwzgKOso1evkeJzV8lih7lV8mL8eAnGVnKyC3KsFT6S+R5PQO4ffdr1PI16/ElibY/kQ==", "dev": true }, "node_modules/emittery": { @@ -4753,9 +5110,9 @@ "dev": true }, "node_modules/envinfo": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.7.3.tgz", - "integrity": "sha512-46+j5QxbPWza0PB1i15nZx0xQ4I/EfQxg9J8Had3b408SV63nEtor2e+oiY63amTo9KTuh2a3XLObNwduxYwwA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.7.4.tgz", + "integrity": "sha512-TQXTYFVVwwluWSFis6K2XKxgrD22jEv0FTuLCQI+OjH7rn93+iY0fSSFM5lrSxFY+H1+B0/cvvlamr3UsBivdQ==", "dev": true, "bin": { "envinfo": "dist/cli.js" @@ -4811,9 +5168,9 @@ } }, "node_modules/es-module-lexer": { - "version": "0.3.26", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.3.26.tgz", - "integrity": "sha512-Va0Q/xqtrss45hWzP8CZJwzGSZJjDM5/MJRE3IXXnUCcVLElR9BRaE9F62BopysASyc4nM3uwhSW7FFB9nlWAA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", + "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", "dev": true }, "node_modules/es-to-primitive": { @@ -4938,13 +5295,13 @@ } }, "node_modules/eslint": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz", - "integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.23.0.tgz", + "integrity": "sha512-kqvNVbdkjzpFy0XOszNwjkKzZ+6TcwCQ/h+ozlcIWwaimBBuhlQ4nN6kbiM2L+OjDcznkTJxzYfRFH92sx4a0Q==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.3.0", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -4955,12 +5312,12 @@ "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", - "esquery": "^1.2.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^6.0.0", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", - "globals": "^12.1.0", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -4968,7 +5325,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.20", + "lodash": "^4.17.21", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -4986,6 +5343,9 @@ }, "engines": { "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-import-resolver-node": { @@ -5173,12 +5533,12 @@ "dev": true }, "node_modules/eslint-plugin-jsdoc": { - "version": "31.0.8", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-31.0.8.tgz", - "integrity": "sha512-tB/+QfKXbV1CUqIwpRdZACt7dv1xDjqEjoJpc07EGqLgydJokT43fsZWPfj2mPbiMXYhZQiJXaKhk1x8lgUDQg==", + "version": "32.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-32.3.0.tgz", + "integrity": "sha512-zyx7kajDK+tqS1bHuY5sapkad8P8KT0vdd/lE55j47VPG2MeenSYuIY/M/Pvmzq5g0+3JB+P3BJGUXmHxtuKPQ==", "dev": true, "dependencies": { - "comment-parser": "1.1.1", + "comment-parser": "1.1.2", "debug": "^4.3.1", "jsdoctypeparser": "^9.0.0", "lodash": "^4.17.20", @@ -5188,28 +5548,35 @@ }, "engines": { "node": ">=10" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0" } }, "node_modules/eslint-plugin-react": { - "version": "7.22.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz", - "integrity": "sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==", + "version": "7.23.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.23.1.tgz", + "integrity": "sha512-MvFGhZjI8Z4HusajmSw0ougGrq3Gs4vT/0WgwksZgf5RrLrRa2oYAw56okU4tZJl8+j7IYNuTM+2RnFEuTSdRQ==", "dev": true, "dependencies": { - "array-includes": "^3.1.1", - "array.prototype.flatmap": "^1.2.3", + "array-includes": "^3.1.3", + "array.prototype.flatmap": "^1.2.4", "doctrine": "^2.1.0", "has": "^1.0.3", "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "object.entries": "^1.1.2", - "object.fromentries": "^2.0.2", - "object.values": "^1.1.1", + "minimatch": "^3.0.4", + "object.entries": "^1.1.3", + "object.fromentries": "^2.0.4", + "object.values": "^1.1.3", "prop-types": "^15.7.2", - "resolve": "^1.18.1", - "string.prototype.matchall": "^4.0.2" + "resolve": "^2.0.0-next.3", + "string.prototype.matchall": "^4.0.4" }, "engines": { "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7" } }, "node_modules/eslint-plugin-react/node_modules/doctrine": { @@ -5224,6 +5591,19 @@ "node": ">=0.10.0" } }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -5267,6 +5647,15 @@ "node": ">=10" } }, + "node_modules/eslint/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -5311,15 +5700,18 @@ "dev": true }, "node_modules/eslint/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.7.0.tgz", + "integrity": "sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA==", "dev": true, "dependencies": { - "type-fest": "^0.8.1" + "type-fest": "^0.20.2" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint/node_modules/has-flag": { @@ -5331,15 +5723,6 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5352,6 +5735,18 @@ "node": ">=8" } }, + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/esm": { "version": "3.2.25", "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", @@ -5398,9 +5793,9 @@ } }, "node_modules/esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -5904,9 +6299,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz", - "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -5922,9 +6317,9 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", - "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { "flat-cache": "^3.0.4" @@ -6218,14 +6613,17 @@ } }, "node_modules/get-intrinsic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", - "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-package-type": { @@ -6312,9 +6710,9 @@ } }, "node_modules/globby": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", - "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", "dev": true, "dependencies": { "array-union": "^2.1.0", @@ -6326,6 +6724,18 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" } }, "node_modules/graceful-fs": { @@ -6508,9 +6918,9 @@ } }, "node_modules/highlight.js": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.5.0.tgz", - "integrity": "sha512-xTmvd9HiIHR6L53TMC7TKolEj65zG1XU+Onr8oi86mYa+nLcIbxTTWkpW7CsEwv/vK7u1zb8alZIMLDqqN6KTw==", + "version": "10.7.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.1.tgz", + "integrity": "sha512-S6G97tHGqJ/U8DsXcEdnACbirtbx58Bx9CzIVeYli8OuswCfYI/LsXH2EiGcoGio1KAC3x4mmUwulOllJ2ZyRA==", "dev": true, "engines": { "node": "*" @@ -6634,9 +7044,9 @@ } }, "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, "engines": { "node": ">= 4" @@ -6653,6 +7063,9 @@ }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/import-local": { @@ -6712,36 +7125,14 @@ "dev": true }, "node_modules/internal-slot": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", - "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", - "dev": true, - "dependencies": { - "es-abstract": "^1.17.0-next.1", - "has": "^1.0.3", - "side-channel": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/internal-slot/node_modules/es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, "dependencies": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.0", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "side-channel": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -9045,9 +9436,9 @@ "dev": true }, "node_modules/karma": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.0.1.tgz", - "integrity": "sha512-LHE8Ywfeji6Sk3jt072j7gUAYZrpw7tCzvQWpgJqwCC9inW4eA3g1yl6srTtC0xiOvZDqXIzx8tgBPm0qhfYkg==", + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.2.tgz", + "integrity": "sha512-fo4Wt0S99/8vylZMxNj4cBFyOBBnC1bewZ0QOlePij/2SZVWxqbyLeIddY13q6URa2EpLRW8ixvFRUMjkmo1bw==", "dev": true, "dependencies": { "body-parser": "^1.19.0", @@ -9068,7 +9459,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^3.0.4", + "socket.io": "^3.1.0", "source-map": "^0.6.1", "tmp": "0.2.1", "ua-parser-js": "^0.7.23", @@ -9253,9 +9644,9 @@ } }, "node_modules/karma-webpack": { - "version": "5.0.0-alpha.5", - "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-5.0.0-alpha.5.tgz", - "integrity": "sha512-K+JmYbljzIK4tos98Wg1Z1unn1ymU0IF7o0U5CAAQzAORxzqI74YpjjrOp+7mfmR+2wfZxEogk3t0AKLa37EMw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-5.0.0.tgz", + "integrity": "sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA==", "dev": true, "dependencies": { "glob": "^7.1.3", @@ -9264,6 +9655,9 @@ }, "engines": { "node": ">= 6" + }, + "peerDependencies": { + "webpack": "^5.0.0" } }, "node_modules/karma-webpack/node_modules/webpack-merge": { @@ -9514,9 +9908,15 @@ } }, "node_modules/lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, "node_modules/lodash.get": { @@ -9525,12 +9925,6 @@ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, "node_modules/lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -10043,35 +10437,35 @@ } }, "node_modules/mocha": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", - "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", + "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", "dev": true, "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.4.3", - "debug": "4.2.0", - "diff": "4.0.2", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.1.6", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.14.0", + "js-yaml": "4.0.0", "log-symbols": "4.0.0", "minimatch": "3.0.4", - "ms": "2.1.2", - "nanoid": "3.1.12", + "ms": "2.1.3", + "nanoid": "3.1.20", "serialize-javascript": "5.0.1", "strip-json-comments": "3.1.1", - "supports-color": "7.2.0", + "supports-color": "8.1.1", "which": "2.0.2", "wide-align": "1.1.3", - "workerpool": "6.0.2", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "bin": { @@ -10080,6 +10474,10 @@ }, "engines": { "node": ">= 10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" } }, "node_modules/mocha-loader": { @@ -10125,15 +10523,6 @@ "node": ">= 10.13.0" } }, - "node_modules/mocha/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/mocha/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -10146,14 +10535,11 @@ "node": ">=8" } }, - "node_modules/mocha/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "node_modules/mocha/node_modules/chalk": { "version": "4.1.0", @@ -10168,36 +10554,27 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "node_modules/mocha/node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.2" + "node": ">=8" } }, "node_modules/mocha/node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, "node_modules/mocha/node_modules/color-convert": { @@ -10218,24 +10595,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/mocha/node_modules/debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "node_modules/mocha/node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, - "dependencies": { - "ms": "2.1.2" - }, "engines": { - "node": ">=6.0" + "node": ">=0.3.1" } }, - "node_modules/mocha/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, "node_modules/mocha/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -10251,280 +10619,154 @@ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/mocha/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/nanoid": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", - "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || >=13.7" - } - }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "engines": { "node": ">=8" } }, - "node_modules/mocha/node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "argparse": "^2.0.1" }, - "engines": { - "node": ">=6" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/mocha/node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" } }, - "node_modules/mocha/node_modules/wrap-ansi/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/mocha/node_modules/log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", "dev": true, "dependencies": { - "color-name": "1.1.3" + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/mocha/node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node_modules/mocha/node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" } }, - "node_modules/mocha/node_modules/yargs/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "locate-path": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/mocha/node_modules/yargs/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/mocha/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/mocha/node_modules/yargs/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/mocha/node_modules/y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/mocha/node_modules/yargs/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "dependencies": { - "p-limit": "^2.0.0" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/mocha/node_modules/yargs/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, "engines": { - "node": ">=4" + "node": ">=10" } }, "node_modules/moment": { @@ -10609,9 +10851,9 @@ "dev": true }, "node_modules/nise": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", - "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.7.0", @@ -10866,18 +11108,21 @@ } }, "node_modules/object.fromentries": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.3.tgz", - "integrity": "sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", + "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", + "es-abstract": "^1.18.0-next.2", "has": "^1.0.3" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object.pick": { @@ -10893,18 +11138,21 @@ } }, "node_modules/object.values": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz", - "integrity": "sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", + "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", + "es-abstract": "^1.18.0-next.2", "has": "^1.0.3" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/on-finished": { @@ -11129,9 +11377,9 @@ } }, "node_modules/pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, "engines": { "node": "*" @@ -11203,17 +11451,21 @@ } }, "node_modules/postcss": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.4.tgz", - "integrity": "sha512-kRFftRoExRVXZlwUuay9iC824qmXPcQQVzAjbCCgjpXnkdMCJYBu2gTwAaFBzv8ewND6O8xFb3aELmEkh9zTzg==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.8.tgz", + "integrity": "sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw==", "dev": true, "dependencies": { - "colorette": "^1.2.1", + "colorette": "^1.2.2", "nanoid": "^3.1.20", "source-map": "^0.6.1" }, "engines": { "node": "^10 || ^12 || >=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" } }, "node_modules/postcss-modules-extract-imports": { @@ -11454,6 +11706,26 @@ "node": ">=0.6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/quick-lru": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", @@ -11538,9 +11810,9 @@ } }, "node_modules/react": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", - "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "dev": true, "dependencies": { "loose-envify": "^1.1.0", @@ -11551,14 +11823,17 @@ } }, "node_modules/react-dom": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz", - "integrity": "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "dev": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "scheduler": "^0.20.1" + "scheduler": "^0.20.2" + }, + "peerDependencies": { + "react": "17.0.2" } }, "node_modules/react-is": { @@ -11782,6 +12057,9 @@ }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/regexpp": { @@ -11826,9 +12104,9 @@ "dev": true }, "node_modules/regjsparser": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.6.tgz", - "integrity": "sha512-jjyuCp+IEMIm3N1H1LLTJW1EISEJV9+5oHdEyrt43Pg9cDSb6rrLZei2cVWpl0xTjmmlpec/lEQGYgM7xfpGCQ==", + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", + "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", "dev": true, "dependencies": { "jsesc": "~0.5.0" @@ -12106,15 +12384,32 @@ } }, "node_modules/run-parallel": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", - "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } }, "node_modules/rxjs": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", - "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dependencies": { "tslib": "^1.9.0" }, @@ -12310,9 +12605,9 @@ } }, "node_modules/sanitize-html": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.3.1.tgz", - "integrity": "sha512-JYziKrrtCEGhrsUAZK1mL0RdEcRxBGZ+ptgppv7ulAsan7MZVL+oVKRSPCIcYinfM1rVOMYh5dHLydMuHaQOUA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.3.3.tgz", + "integrity": "sha512-DCFXPt7Di0c6JUnlT90eIgrjs6TsJl/8HYU3KLdmrVclFN4O0heTcVbJiMa23OKVr6aR051XYtsgd8EWwEBwUA==", "dev": true, "dependencies": { "deepmerge": "^4.2.2", @@ -12355,9 +12650,9 @@ } }, "node_modules/scheduler": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.1.tgz", - "integrity": "sha512-LKTe+2xNJBNxu/QhHvDR14wUXHRQbVY5ZOYpOGWRzhydZUqrLb2JBvLPY7cAqFmqrWuDED0Mjk7013SZiOz6Bw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "dev": true, "dependencies": { "loose-envify": "^1.1.0", @@ -12379,9 +12674,9 @@ } }, "node_modules/semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -12550,6 +12845,9 @@ "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/signal-exit": { @@ -12559,17 +12857,21 @@ "dev": true }, "node_modules/sinon": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.3.tgz", - "integrity": "sha512-m+DyAWvqVHZtjnjX/nuShasykFeiZ+nPuEfD4G3gpvKGkXRhkF/6NSt2qN2FjZhfrcHXFzUzI+NLnk+42fnLEw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-10.0.0.tgz", + "integrity": "sha512-XAn5DxtGVJBlBWYrcYKEhWCz7FLwZGdyvANRyK06419hyEpdT0dMc5A8Vcxg5SCGHc40CsqoKsc1bt1CbJPfNw==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.8.1", "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/samsam": "^5.3.0", + "@sinonjs/samsam": "^5.3.1", "diff": "^4.0.2", - "nise": "^4.0.4", + "nise": "^4.1.0", "supports-color": "^7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" } }, "node_modules/sinon/node_modules/has-flag": { @@ -13111,18 +13413,21 @@ } }, "node_modules/string.prototype.matchall": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz", - "integrity": "sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.4.tgz", + "integrity": "sha512-pknFIWVachNcyqRfaQSeu/FUfpvJTe4uskUSZ9Wc1RijsPuzbZ8TyYT8WCNnntCjUEqQ3vUHMAfVj2+wLAisPQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", + "es-abstract": "^1.18.0-next.2", "has-symbols": "^1.0.1", - "internal-slot": "^1.0.2", - "regexp.prototype.flags": "^1.3.0", - "side-channel": "^1.0.3" + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimend": { @@ -13595,18 +13900,17 @@ } }, "node_modules/ts-jest": { - "version": "26.4.4", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.4.4.tgz", - "integrity": "sha512-3lFWKbLxJm34QxyVNNCgXX1u4o/RV0myvA2y2Bxm46iGIjKlaY0own9gIckbjZJPn+WaJEnfPPJ20HHGpoq4yg==", + "version": "26.5.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.4.tgz", + "integrity": "sha512-I5Qsddo+VTm94SukBJ4cPimOoFZsYTeElR2xy6H2TOVs+NsvgYglW8KuQgKoApOKuaU/Ix/vrF9ebFZlb5D2Pg==", "dev": true, "dependencies": { - "@types/jest": "26.x", "bs-logger": "0.x", "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", "jest-util": "^26.1.0", "json5": "2.x", - "lodash.memoize": "4.x", + "lodash": "4.x", "make-error": "1.x", "mkdirp": "1.x", "semver": "7.x", @@ -13617,6 +13921,10 @@ }, "engines": { "node": ">= 10" + }, + "peerDependencies": { + "jest": ">=26 <27", + "typescript": ">=3.8 <5.0" } }, "node_modules/ts-jest/node_modules/mkdirp": { @@ -13641,9 +13949,9 @@ } }, "node_modules/ts-loader": { - "version": "8.0.14", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.14.tgz", - "integrity": "sha512-Jt/hHlUnApOZjnSjTmZ+AbD5BGlQFx3f1D0nYuNKwz0JJnuDGHJas6az+FlWKwwRTu+26GXpv249A8UAnYUpqA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz", + "integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==", "dev": true, "dependencies": { "chalk": "^4.1.0", @@ -13654,6 +13962,10 @@ }, "engines": { "node": ">=10.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "*" } }, "node_modules/ts-loader/node_modules/ansi-styles": { @@ -13891,9 +14203,9 @@ } }, "node_modules/typescript": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", - "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", + "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -14266,9 +14578,9 @@ } }, "node_modules/webpack": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.17.0.tgz", - "integrity": "sha512-R+IdNEaYcYaACpXZOt7reyc8txBK7J06lOPkX1SbgmeoAnUbyBZivJIksrDBnmMA3wlTWvPcX7DubxELyPB8rA==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.28.0.tgz", + "integrity": "sha512-1xllYVmA4dIvRjHzwELgW4KjIU1fW4PEuEnjsylz7k7H5HgPOctIq7W1jrt3sKH9yG5d72//XWzsHhfoWvsQVg==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.0", @@ -14280,7 +14592,7 @@ "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.7.0", - "es-module-lexer": "^0.3.26", + "es-module-lexer": "^0.4.0", "eslint-scope": "^5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -14289,7 +14601,6 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "pkg-dir": "^5.0.0", "schema-utils": "^3.0.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.1.1", @@ -14301,6 +14612,15 @@ }, "engines": { "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } } }, "node_modules/webpack-bundle-analyzer": { @@ -14421,17 +14741,17 @@ } }, "node_modules/webpack-cli": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.4.0.tgz", - "integrity": "sha512-/Qh07CXfXEkMu5S8wEpjuaw2Zj/CC0hf/qbTDp6N8N7JjdGuaOjZ7kttz+zhuJO/J5m7alQEhNk9lsc4rC6xgQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.6.0.tgz", + "integrity": "sha512-9YV+qTcGMjQFiY7Nb1kmnupvb1x40lfpj8pwdO/bom+sQiP4OBMKjHq29YQrlDWDPZO9r/qWaRRywKaRDKqBTA==", "dev": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.0", - "@webpack-cli/info": "^1.2.1", - "@webpack-cli/serve": "^1.2.2", + "@webpack-cli/configtest": "^1.0.2", + "@webpack-cli/info": "^1.2.3", + "@webpack-cli/serve": "^1.3.1", "colorette": "^1.2.1", - "commander": "^6.2.0", + "commander": "^7.0.0", "enquirer": "^2.3.6", "execa": "^5.0.0", "fastest-levenshtein": "^1.0.12", @@ -14446,15 +14766,32 @@ }, "engines": { "node": ">=10.13.0" + }, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "@webpack-cli/migrate": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } } }, "node_modules/webpack-cli/node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true, "engines": { - "node": ">= 6" + "node": ">= 10" } }, "node_modules/webpack-cli/node_modules/execa": { @@ -14545,96 +14882,35 @@ "node_modules/webpack-sources/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack/node_modules/acorn": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", - "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/webpack/node_modules/enhanced-resolve": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz", - "integrity": "sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/webpack/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/webpack/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/webpack/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/webpack/node_modules/acorn": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", + "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==", "dev": true, - "dependencies": { - "p-limit": "^3.0.2" + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=10" + "node": ">=0.4.0" } }, - "node_modules/webpack/node_modules/pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "node_modules/webpack/node_modules/enhanced-resolve": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz", + "integrity": "sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==", "dev": true, "dependencies": { - "find-up": "^5.0.0" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, "engines": { - "node": ">=10" + "node": ">=10.13.0" } }, "node_modules/webpack/node_modules/schema-utils": { @@ -14778,9 +15054,9 @@ } }, "node_modules/workerpool": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", - "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", "dev": true }, "node_modules/wrap-ansi": { @@ -14958,253 +15234,266 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, "@babel/compat-data": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.7.tgz", - "integrity": "sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.12.tgz", + "integrity": "sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ==", "dev": true }, "@babel/core": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", - "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.10", + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.14.tgz", + "integrity": "sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-compilation-targets": "^7.13.13", + "@babel/helper-module-transforms": "^7.13.14", + "@babel/helpers": "^7.13.10", + "@babel/parser": "^7.13.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", + "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "lodash": "^4.17.19", - "semver": "^5.4.1", + "semver": "^6.3.0", "source-map": "^0.5.0" }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "version": "7.13.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", + "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", "dev": true, "requires": { - "@babel/types": "^7.12.11", + "@babel/types": "^7.13.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-annotate-as-pure": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", - "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", + "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", - "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz", + "integrity": "sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-explode-assignable-expression": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/helper-compilation-targets": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz", - "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==", + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz", + "integrity": "sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.12.5", - "@babel/helper-validator-option": "^7.12.1", + "@babel/compat-data": "^7.13.12", + "@babel/helper-validator-option": "^7.12.17", "browserslist": "^4.14.5", - "semver": "^5.5.0" + "semver": "^6.3.0" }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "@babel/helper-create-class-features-plugin": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz", - "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==", + "version": "7.13.11", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", + "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.12.1", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.10.4" + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-member-expression-to-functions": "^7.13.0", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-split-export-declaration": "^7.12.13" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", - "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz", + "integrity": "sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-annotate-as-pure": "^7.12.13", "regexpu-core": "^4.7.1" } }, - "@babel/helper-define-map": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz", - "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==", + "@babel/helper-define-polyfill-provider": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz", + "integrity": "sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/types": "^7.10.5", - "lodash": "^4.17.19" + "@babel/helper-compilation-targets": "^7.13.0", + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/traverse": "^7.13.0", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "@babel/helper-explode-assignable-expression": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz", - "integrity": "sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz", + "integrity": "sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.13.0" } }, "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-hoist-variables": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz", - "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz", + "integrity": "sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", "dev": true, "requires": { - "@babel/types": "^7.12.7" + "@babel/types": "^7.13.12" } }, "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", "dev": true, "requires": { - "@babel/types": "^7.12.5" + "@babel/types": "^7.13.12" } }, "@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "lodash": "^4.17.19" + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz", + "integrity": "sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.12.11", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.13", + "@babel/types": "^7.13.14" } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.12.13" } }, "@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", + "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", "dev": true }, "@babel/helper-remap-async-to-generator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz", - "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz", + "integrity": "sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-wrap-function": "^7.10.4", - "@babel/types": "^7.12.1" + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-wrap-function": "^7.13.0", + "@babel/types": "^7.13.0" } }, "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" } }, "@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.13.12" } }, "@babel/helper-skip-transparent-expression-wrappers": { @@ -15217,12 +15506,12 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", "dev": true, "requires": { - "@babel/types": "^7.12.11" + "@babel/types": "^7.12.13" } }, "@babel/helper-validator-identifier": { @@ -15232,182 +15521,195 @@ "dev": true }, "@babel/helper-validator-option": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz", - "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", "dev": true }, "@babel/helper-wrap-function": { - "version": "7.12.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz", - "integrity": "sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz", + "integrity": "sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-function-name": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" } }, "@babel/helpers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", - "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", + "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", "dev": true, "requires": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.0" } }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", + "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.13.tgz", + "integrity": "sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==", "dev": true }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz", + "integrity": "sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.13.12" + } + }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz", - "integrity": "sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.8.tgz", + "integrity": "sha512-rPBnhj+WgoSmgq+4gQUtXx/vOcU+UYtjy1AA/aeD61Hwj410fwYyqfUcRP3lR8ucgliVJL/G7sXcNUecC75IXA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.12.1", - "@babel/plugin-syntax-async-generators": "^7.8.0" + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-remap-async-to-generator": "^7.13.0", + "@babel/plugin-syntax-async-generators": "^7.8.4" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz", - "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", + "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", - "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", + "integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-dynamic-import": "^7.8.0" + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz", - "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", + "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" } }, "@babel/plugin-proposal-json-strings": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz", - "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz", + "integrity": "sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.0" + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-json-strings": "^7.8.3" } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz", - "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz", + "integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.13.0", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz", - "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz", + "integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz", - "integrity": "sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", + "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.12.13", "@babel/plugin-syntax-numeric-separator": "^7.10.4" } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", - "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz", + "integrity": "sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.12.1" + "@babel/compat-data": "^7.13.8", + "@babel/helper-compilation-targets": "^7.13.8", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.13.0" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz", - "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz", + "integrity": "sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz", - "integrity": "sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz", + "integrity": "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", - "@babel/plugin-syntax-optional-chaining": "^7.8.0" + "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz", - "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz", + "integrity": "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" } }, "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz", - "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz", + "integrity": "sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-syntax-async-generators": { @@ -15429,12 +15731,12 @@ } }, "@babel/plugin-syntax-class-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", - "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-syntax-dynamic-import": { @@ -15474,12 +15776,12 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", - "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.13.tgz", + "integrity": "sha512-d4HM23Q1K7oq/SLNmG6mRt85l2csmQ0cHRaxRXjKW0YFdEXqlZ5kzFQKH5Uc3rDJECgu+yCRgPkG04Mm98R/1g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -15537,273 +15839,272 @@ } }, "@babel/plugin-syntax-top-level-await": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", - "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz", + "integrity": "sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz", - "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", + "integrity": "sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.13.0" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz", - "integrity": "sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz", + "integrity": "sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.12.1" + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-remap-async-to-generator": "^7.13.0" } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz", - "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz", + "integrity": "sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz", - "integrity": "sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz", + "integrity": "sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-classes": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz", - "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz", + "integrity": "sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-define-map": "^7.10.4", - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-replace-supers": "^7.13.0", + "@babel/helper-split-export-declaration": "^7.12.13", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz", - "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz", + "integrity": "sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.13.0" } }, "@babel/plugin-transform-destructuring": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz", - "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz", + "integrity": "sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.13.0" } }, "@babel/plugin-transform-dotall-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz", - "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz", + "integrity": "sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz", - "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz", + "integrity": "sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz", - "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz", + "integrity": "sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-for-of": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz", - "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz", + "integrity": "sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.13.0" } }, "@babel/plugin-transform-function-name": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz", - "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz", + "integrity": "sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz", - "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz", + "integrity": "sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz", - "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz", + "integrity": "sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz", - "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz", + "integrity": "sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz", - "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz", + "integrity": "sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-simple-access": "^7.12.13", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz", - "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==", + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz", + "integrity": "sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-hoist-variables": "^7.13.0", + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-identifier": "^7.12.11", "babel-plugin-dynamic-import-node": "^2.3.3" } }, "@babel/plugin-transform-modules-umd": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz", - "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz", + "integrity": "sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-module-transforms": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz", - "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz", + "integrity": "sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1" + "@babel/helper-create-regexp-features-plugin": "^7.12.13" } }, "@babel/plugin-transform-new-target": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz", - "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz", + "integrity": "sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-object-super": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz", - "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz", + "integrity": "sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.12.1" + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/helper-replace-supers": "^7.12.13" } }, "@babel/plugin-transform-parameters": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz", - "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz", + "integrity": "sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.13.0" } }, "@babel/plugin-transform-property-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz", - "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz", + "integrity": "sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-react-display-name": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz", - "integrity": "sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.13.tgz", + "integrity": "sha512-MprESJzI9O5VnJZrL7gg1MpdqmiFcUv41Jc7SahxYsNP2kDkFqClxxTZq+1Qv4AFCamm+GXMRDQINNn+qrxmiA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-react-jsx": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.12.tgz", - "integrity": "sha512-JDWGuzGNWscYcq8oJVCtSE61a5+XAOos+V0HrxnDieUus4UMnBEosDnY1VJqU5iZ4pA04QY7l0+JvHL1hZEfsw==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.13.12.tgz", + "integrity": "sha512-jcEI2UqIcpCqB5U5DRxIl0tQEProI2gcu+g8VTIqxLO5Iidojb4d77q+fwGseCvd8af/lJ9masp4QWzBXFE2xA==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.12.10", - "@babel/helper-module-imports": "^7.12.5", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.12.1", - "@babel/types": "^7.12.12" + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-jsx": "^7.12.13", + "@babel/types": "^7.13.12" } }, "@babel/plugin-transform-react-jsx-development": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.12.tgz", - "integrity": "sha512-i1AxnKxHeMxUaWVXQOSIco4tvVvvCxMSfeBMnMM06mpaJt3g+MpxYQQrDfojUQldP1xxraPSJYSMEljoWM/dCg==", + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.17.tgz", + "integrity": "sha512-BPjYV86SVuOaudFhsJR1zjgxxOhJDt6JHNoD48DxWEIxUCAMjV1ys6DYw4SDYZh0b1QsS2vfIA9t/ZsQGsDOUQ==", "dev": true, "requires": { - "@babel/plugin-transform-react-jsx": "^7.12.12" + "@babel/plugin-transform-react-jsx": "^7.12.17" } }, "@babel/plugin-transform-react-pure-annotations": { @@ -15817,185 +16118,191 @@ } }, "@babel/plugin-transform-regenerator": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz", - "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz", + "integrity": "sha512-lxb2ZAvSLyJ2PEe47hoGWPmW22v7CtSl9jW8mingV4H2sEX/JOcrAj2nPuGWi56ERUm2bUpjKzONAuT6HCn2EA==", "dev": true, "requires": { "regenerator-transform": "^0.14.2" } }, "@babel/plugin-transform-reserved-words": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz", - "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz", + "integrity": "sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-runtime": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.10.tgz", - "integrity": "sha512-xOrUfzPxw7+WDm9igMgQCbO3cJKymX7dFdsgRr1eu9n3KjjyU4pptIXbXPseQDquw+W+RuJEJMHKHNsPNNm3CA==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.10.tgz", + "integrity": "sha512-Y5k8ipgfvz5d/76tx7JYbKQTcgFSU6VgJ3kKQv4zGTKr+a9T/KBvfRvGtSFgKDQGt/DBykQixV0vNWKIdzWErA==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.12.5", - "@babel/helper-plugin-utils": "^7.10.4", - "semver": "^5.5.1" + "@babel/helper-module-imports": "^7.12.13", + "@babel/helper-plugin-utils": "^7.13.0", + "babel-plugin-polyfill-corejs2": "^0.1.4", + "babel-plugin-polyfill-corejs3": "^0.1.3", + "babel-plugin-polyfill-regenerator": "^0.1.2", + "semver": "^6.3.0" }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "@babel/plugin-transform-shorthand-properties": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz", - "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", + "integrity": "sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz", - "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz", + "integrity": "sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-plugin-utils": "^7.13.0", "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" } }, "@babel/plugin-transform-sticky-regex": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz", - "integrity": "sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz", + "integrity": "sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-template-literals": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz", - "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz", + "integrity": "sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.13.0" } }, "@babel/plugin-transform-typeof-symbol": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz", - "integrity": "sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz", + "integrity": "sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-unicode-escapes": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz", - "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", + "integrity": "sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/plugin-transform-unicode-regex": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz", - "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz", + "integrity": "sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==", "dev": true, "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.12.1", - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-create-regexp-features-plugin": "^7.12.13", + "@babel/helper-plugin-utils": "^7.12.13" } }, "@babel/preset-env": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.11.tgz", - "integrity": "sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.12.7", - "@babel/helper-compilation-targets": "^7.12.5", - "@babel/helper-module-imports": "^7.12.5", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-validator-option": "^7.12.11", - "@babel/plugin-proposal-async-generator-functions": "^7.12.1", - "@babel/plugin-proposal-class-properties": "^7.12.1", - "@babel/plugin-proposal-dynamic-import": "^7.12.1", - "@babel/plugin-proposal-export-namespace-from": "^7.12.1", - "@babel/plugin-proposal-json-strings": "^7.12.1", - "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", - "@babel/plugin-proposal-numeric-separator": "^7.12.7", - "@babel/plugin-proposal-object-rest-spread": "^7.12.1", - "@babel/plugin-proposal-optional-catch-binding": "^7.12.1", - "@babel/plugin-proposal-optional-chaining": "^7.12.7", - "@babel/plugin-proposal-private-methods": "^7.12.1", - "@babel/plugin-proposal-unicode-property-regex": "^7.12.1", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.12.1", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.13.12.tgz", + "integrity": "sha512-JzElc6jk3Ko6zuZgBtjOd01pf9yYDEIH8BcqVuYIuOkzOwDesoa/Nz4gIo4lBG6K861KTV9TvIgmFuT6ytOaAA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.12", + "@babel/helper-compilation-targets": "^7.13.10", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-option": "^7.12.17", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-async-generator-functions": "^7.13.8", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-dynamic-import": "^7.13.8", + "@babel/plugin-proposal-export-namespace-from": "^7.12.13", + "@babel/plugin-proposal-json-strings": "^7.13.8", + "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", + "@babel/plugin-proposal-numeric-separator": "^7.12.13", + "@babel/plugin-proposal-object-rest-spread": "^7.13.8", + "@babel/plugin-proposal-optional-catch-binding": "^7.13.8", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-private-methods": "^7.13.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.12.13", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.12.1", - "@babel/plugin-transform-arrow-functions": "^7.12.1", - "@babel/plugin-transform-async-to-generator": "^7.12.1", - "@babel/plugin-transform-block-scoped-functions": "^7.12.1", - "@babel/plugin-transform-block-scoping": "^7.12.11", - "@babel/plugin-transform-classes": "^7.12.1", - "@babel/plugin-transform-computed-properties": "^7.12.1", - "@babel/plugin-transform-destructuring": "^7.12.1", - "@babel/plugin-transform-dotall-regex": "^7.12.1", - "@babel/plugin-transform-duplicate-keys": "^7.12.1", - "@babel/plugin-transform-exponentiation-operator": "^7.12.1", - "@babel/plugin-transform-for-of": "^7.12.1", - "@babel/plugin-transform-function-name": "^7.12.1", - "@babel/plugin-transform-literals": "^7.12.1", - "@babel/plugin-transform-member-expression-literals": "^7.12.1", - "@babel/plugin-transform-modules-amd": "^7.12.1", - "@babel/plugin-transform-modules-commonjs": "^7.12.1", - "@babel/plugin-transform-modules-systemjs": "^7.12.1", - "@babel/plugin-transform-modules-umd": "^7.12.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1", - "@babel/plugin-transform-new-target": "^7.12.1", - "@babel/plugin-transform-object-super": "^7.12.1", - "@babel/plugin-transform-parameters": "^7.12.1", - "@babel/plugin-transform-property-literals": "^7.12.1", - "@babel/plugin-transform-regenerator": "^7.12.1", - "@babel/plugin-transform-reserved-words": "^7.12.1", - "@babel/plugin-transform-shorthand-properties": "^7.12.1", - "@babel/plugin-transform-spread": "^7.12.1", - "@babel/plugin-transform-sticky-regex": "^7.12.7", - "@babel/plugin-transform-template-literals": "^7.12.1", - "@babel/plugin-transform-typeof-symbol": "^7.12.10", - "@babel/plugin-transform-unicode-escapes": "^7.12.1", - "@babel/plugin-transform-unicode-regex": "^7.12.1", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.12.11", - "core-js-compat": "^3.8.0", - "semver": "^5.5.0" + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.12.13", + "@babel/plugin-transform-arrow-functions": "^7.13.0", + "@babel/plugin-transform-async-to-generator": "^7.13.0", + "@babel/plugin-transform-block-scoped-functions": "^7.12.13", + "@babel/plugin-transform-block-scoping": "^7.12.13", + "@babel/plugin-transform-classes": "^7.13.0", + "@babel/plugin-transform-computed-properties": "^7.13.0", + "@babel/plugin-transform-destructuring": "^7.13.0", + "@babel/plugin-transform-dotall-regex": "^7.12.13", + "@babel/plugin-transform-duplicate-keys": "^7.12.13", + "@babel/plugin-transform-exponentiation-operator": "^7.12.13", + "@babel/plugin-transform-for-of": "^7.13.0", + "@babel/plugin-transform-function-name": "^7.12.13", + "@babel/plugin-transform-literals": "^7.12.13", + "@babel/plugin-transform-member-expression-literals": "^7.12.13", + "@babel/plugin-transform-modules-amd": "^7.13.0", + "@babel/plugin-transform-modules-commonjs": "^7.13.8", + "@babel/plugin-transform-modules-systemjs": "^7.13.8", + "@babel/plugin-transform-modules-umd": "^7.13.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.13", + "@babel/plugin-transform-new-target": "^7.12.13", + "@babel/plugin-transform-object-super": "^7.12.13", + "@babel/plugin-transform-parameters": "^7.13.0", + "@babel/plugin-transform-property-literals": "^7.12.13", + "@babel/plugin-transform-regenerator": "^7.12.13", + "@babel/plugin-transform-reserved-words": "^7.12.13", + "@babel/plugin-transform-shorthand-properties": "^7.12.13", + "@babel/plugin-transform-spread": "^7.13.0", + "@babel/plugin-transform-sticky-regex": "^7.12.13", + "@babel/plugin-transform-template-literals": "^7.13.0", + "@babel/plugin-transform-typeof-symbol": "^7.12.13", + "@babel/plugin-transform-unicode-escapes": "^7.12.13", + "@babel/plugin-transform-unicode-regex": "^7.12.13", + "@babel/preset-modules": "^0.1.4", + "@babel/types": "^7.13.12", + "babel-plugin-polyfill-corejs2": "^0.1.4", + "babel-plugin-polyfill-corejs3": "^0.1.3", + "babel-plugin-polyfill-regenerator": "^0.1.2", + "core-js-compat": "^3.9.0", + "semver": "^6.3.0" }, "dependencies": { "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } @@ -16014,59 +16321,59 @@ } }, "@babel/preset-react": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.12.10.tgz", - "integrity": "sha512-vtQNjaHRl4DUpp+t+g4wvTHsLQuye+n0H/wsXIZRn69oz/fvNC7gQ4IK73zGJBaxvHoxElDvnYCthMcT7uzFoQ==", + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.13.13.tgz", + "integrity": "sha512-gx+tDLIE06sRjKJkVtpZ/t3mzCDOnPG+ggHZG9lffUbX8+wC739x20YQc9V35Do6ZAxaUc/HhVHIiOzz5MvDmA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-transform-react-display-name": "^7.12.1", - "@babel/plugin-transform-react-jsx": "^7.12.10", - "@babel/plugin-transform-react-jsx-development": "^7.12.7", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-option": "^7.12.17", + "@babel/plugin-transform-react-display-name": "^7.12.13", + "@babel/plugin-transform-react-jsx": "^7.13.12", + "@babel/plugin-transform-react-jsx-development": "^7.12.17", "@babel/plugin-transform-react-pure-annotations": "^7.12.1" } }, "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "version": "7.13.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.13.tgz", + "integrity": "sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.9", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.13", + "@babel/types": "^7.13.13", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" + "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.13.14", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", + "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", @@ -16097,9 +16404,9 @@ "dev": true }, "@eslint/eslintrc": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz", - "integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz", + "integrity": "sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -16109,7 +16416,6 @@ "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", - "lodash": "^4.17.20", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, @@ -16122,12 +16428,6 @@ "requires": { "type-fest": "^0.8.1" } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true } } }, @@ -16764,9 +17064,9 @@ } }, "@types/chai": { - "version": "4.2.14", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.14.tgz", - "integrity": "sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==", + "version": "4.2.15", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.15.tgz", + "integrity": "sha512-rYff6FI+ZTKAPkJUoyz7Udq3GaoDZnxYDEvdEdFZASiA7PoErltHezDishqQiSDWrGxvxmplH304jyzQmjp0AQ==", "dev": true }, "@types/component-emitter": { @@ -16847,9 +17147,9 @@ } }, "@types/jest": { - "version": "26.0.20", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.20.tgz", - "integrity": "sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA==", + "version": "26.0.22", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.22.tgz", + "integrity": "sha512-eeWwWjlqxvBxc4oQdkueW5OF/gtfSceKk4OnOAGlUSwS/liBRtZppbJuz1YkgbrbfGOoeBHun9fOvXnjNwrSOw==", "dev": true, "requires": { "jest-diff": "^26.0.0", @@ -16869,15 +17169,15 @@ "dev": true }, "@types/mocha": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.0.tgz", - "integrity": "sha512-/Sge3BymXo4lKc31C8OINJgXLaw+7vL1/L1pGiBNpGrBiT8FQiaFpSYV0uhTaG4y78vcMBTMFsWaHDvuD+xGzQ==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", + "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", "dev": true }, "@types/node": { - "version": "14.14.22", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz", - "integrity": "sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==", + "version": "14.14.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz", + "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw==", "dev": true }, "@types/normalize-package-data": { @@ -16893,9 +17193,9 @@ "dev": true }, "@types/sinon": { - "version": "9.0.10", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.10.tgz", - "integrity": "sha512-/faDC0erR06wMdybwI/uR8wEKV/E83T0k4sepIpB7gXuy2gzx2xiOjmztq6a2Y6rIGJ04D+6UU0VBmWy+4HEMA==", + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.11.tgz", + "integrity": "sha512-PwP4UY33SeeVKodNE37ZlOsR9cReypbMJOhZ7BVE0lB+Hix3efCOxiJWiE5Ia+yL9Cn2Ch72EjFTRze8RZsNtg==", "dev": true, "requires": { "@types/sinonjs__fake-timers": "*" @@ -16929,13 +17229,13 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.14.0.tgz", - "integrity": "sha512-IJ5e2W7uFNfg4qh9eHkHRUCbgZ8VKtGwD07kannJvM5t/GU8P8+24NX8gi3Hf5jST5oWPY8kyV1s/WtfiZ4+Ww==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.20.0.tgz", + "integrity": "sha512-sw+3HO5aehYqn5w177z2D82ZQlqHCwcKSMboueo7oE4KU9QiC0SAgfS/D4z9xXvpTc8Bt41Raa9fBR8T2tIhoQ==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.14.0", - "@typescript-eslint/scope-manager": "4.14.0", + "@typescript-eslint/experimental-utils": "4.20.0", + "@typescript-eslint/scope-manager": "4.20.0", "debug": "^4.1.1", "functional-red-black-tree": "^1.0.1", "lodash": "^4.17.15", @@ -16945,80 +17245,79 @@ } }, "@typescript-eslint/eslint-plugin-tslint": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin-tslint/-/eslint-plugin-tslint-4.14.0.tgz", - "integrity": "sha512-d14sju1LLPvzyZItiXw7WhqKUkiJaf2Y2g5JlAx90NhNseTyElcTmZW5vo6gqLDPLb2VsKQ4KYMYKZNTXXJGpw==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin-tslint/-/eslint-plugin-tslint-4.20.0.tgz", + "integrity": "sha512-9fFZGUzWrFjlw2P5cBytXVtXiOkPo/hgmqvm9vE9NCs9rfiRDbKMaDiPA6OlfPWZhtZKdsS8GyOdPDBtU3VLsA==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.14.0", + "@typescript-eslint/experimental-utils": "4.20.0", "lodash": "^4.17.15" } }, "@typescript-eslint/experimental-utils": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.14.0.tgz", - "integrity": "sha512-6i6eAoiPlXMKRbXzvoQD5Yn9L7k9ezzGRvzC/x1V3650rUk3c3AOjQyGYyF9BDxQQDK2ElmKOZRD0CbtdkMzQQ==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.20.0.tgz", + "integrity": "sha512-sQNlf6rjLq2yB5lELl3gOE7OuoA/6IVXJUJ+Vs7emrQMva14CkOwyQwD7CW+TkmOJ4Q/YGmoDLmbfFrpGmbKng==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.14.0", - "@typescript-eslint/types": "4.14.0", - "@typescript-eslint/typescript-estree": "4.14.0", + "@typescript-eslint/scope-manager": "4.20.0", + "@typescript-eslint/types": "4.20.0", + "@typescript-eslint/typescript-estree": "4.20.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" } }, "@typescript-eslint/parser": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.14.0.tgz", - "integrity": "sha512-sUDeuCjBU+ZF3Lzw0hphTyScmDDJ5QVkyE21pRoBo8iDl7WBtVFS+WDN3blY1CH3SBt7EmYCw6wfmJjF0l/uYg==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.20.0.tgz", + "integrity": "sha512-m6vDtgL9EABdjMtKVw5rr6DdeMCH3OA1vFb0dAyuZSa3e5yw1YRzlwFnm9knma9Lz6b2GPvoNSa8vOXrqsaglA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.14.0", - "@typescript-eslint/types": "4.14.0", - "@typescript-eslint/typescript-estree": "4.14.0", + "@typescript-eslint/scope-manager": "4.20.0", + "@typescript-eslint/types": "4.20.0", + "@typescript-eslint/typescript-estree": "4.20.0", "debug": "^4.1.1" } }, "@typescript-eslint/scope-manager": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.14.0.tgz", - "integrity": "sha512-/J+LlRMdbPh4RdL4hfP1eCwHN5bAhFAGOTsvE6SxsrM/47XQiPSgF5MDgLyp/i9kbZV9Lx80DW0OpPkzL+uf8Q==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.20.0.tgz", + "integrity": "sha512-/zm6WR6iclD5HhGpcwl/GOYDTzrTHmvf8LLLkwKqqPKG6+KZt/CfSgPCiybshmck66M2L5fWSF/MKNuCwtKQSQ==", "dev": true, "requires": { - "@typescript-eslint/types": "4.14.0", - "@typescript-eslint/visitor-keys": "4.14.0" + "@typescript-eslint/types": "4.20.0", + "@typescript-eslint/visitor-keys": "4.20.0" } }, "@typescript-eslint/types": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.14.0.tgz", - "integrity": "sha512-VsQE4VvpldHrTFuVPY1ZnHn/Txw6cZGjL48e+iBxTi2ksa9DmebKjAeFmTVAYoSkTk7gjA7UqJ7pIsyifTsI4A==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.20.0.tgz", + "integrity": "sha512-cYY+1PIjei1nk49JAPnH1VEnu7OYdWRdJhYI5wiKOUMhLTG1qsx5cQxCUTuwWCmQoyriadz3Ni8HZmGSofeC+w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.14.0.tgz", - "integrity": "sha512-wRjZ5qLao+bvS2F7pX4qi2oLcOONIB+ru8RGBieDptq/SudYwshveORwCVU4/yMAd4GK7Fsf8Uq1tjV838erag==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.20.0.tgz", + "integrity": "sha512-Knpp0reOd4ZsyoEJdW8i/sK3mtZ47Ls7ZHvD8WVABNx5Xnn7KhenMTRGegoyMTx6TiXlOVgMz9r0pDgXTEEIHA==", "dev": true, "requires": { - "@typescript-eslint/types": "4.14.0", - "@typescript-eslint/visitor-keys": "4.14.0", + "@typescript-eslint/types": "4.20.0", + "@typescript-eslint/visitor-keys": "4.20.0", "debug": "^4.1.1", "globby": "^11.0.1", "is-glob": "^4.0.1", - "lodash": "^4.17.15", "semver": "^7.3.2", "tsutils": "^3.17.1" } }, "@typescript-eslint/visitor-keys": { - "version": "4.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.14.0.tgz", - "integrity": "sha512-MeHHzUyRI50DuiPgV9+LxcM52FCJFYjJiWHtXlbyC27b80mfOwKeiKI+MHOTEpcpfmoPFm/vvQS88bYIx6PZTA==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.20.0.tgz", + "integrity": "sha512-NXKRM3oOVQL8yNFDNCZuieRIwZ5UtjNLYtmMx2PacEAGmbaEYtGgVHUHVyZvU/0rYZcizdrWjDo+WBtRPSgq+A==", "dev": true, "requires": { - "@typescript-eslint/types": "4.14.0", + "@typescript-eslint/types": "4.20.0", "eslint-visitor-keys": "^2.0.0" } }, @@ -17175,25 +17474,27 @@ } }, "@webpack-cli/configtest": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.0.tgz", - "integrity": "sha512-Un0SdBoN1h4ACnIO7EiCjWuyhNI0Jl96JC+63q6xi4HDUYRZn8Auluea9D+v9NWKc5J4sICVEltdBaVjLX39xw==", - "dev": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.2.tgz", + "integrity": "sha512-3OBzV2fBGZ5TBfdW50cha1lHDVf9vlvRXnjpVbJBa20pSZQaSkMJZiwA8V2vD9ogyeXn8nU5s5A6mHyf5jhMzA==", + "dev": true, + "requires": {} }, "@webpack-cli/info": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.1.tgz", - "integrity": "sha512-fLnDML5HZ5AEKzHul8xLAksoKN2cibu6MgonkUj8R9V7bbeVRkd1XbGEGWrAUNYHbX1jcqCsDEpBviE5StPMzQ==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.3.tgz", + "integrity": "sha512-lLek3/T7u40lTqzCGpC6CAbY6+vXhdhmwFRxZLMnRm6/sIF/7qMpT8MocXCRQfz0JAh63wpbXLMnsQ5162WS7Q==", "dev": true, "requires": { "envinfo": "^7.7.3" } }, "@webpack-cli/serve": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.2.2.tgz", - "integrity": "sha512-03GkWxcgFfm8+WIwcsqJb9agrSDNDDoxaNnexPnCCexP5SCE4IgFd9lNpSy+K2nFqVMpgTFw6SwbmVAVTndVew==", - "dev": true + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.3.1.tgz", + "integrity": "sha512-0qXvpeYO6vaNoRBI52/UsbcaBydJCggoBBnIo/ovQQdn6fug0BgwsjorV1hVS7fMqGVTZGcVxv8334gjmbj5hw==", + "dev": true, + "requires": {} }, "@xtuc/ieee754": { "version": "1.2.0", @@ -17243,7 +17544,8 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "7.2.0", @@ -17357,15 +17659,15 @@ "dev": true }, "array-includes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.2.tgz", - "integrity": "sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "get-intrinsic": "^1.0.1", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", "is-string": "^1.0.5" } }, @@ -17707,6 +18009,44 @@ "@types/babel__traverse": "^7.0.6" } }, + "babel-plugin-polyfill-corejs2": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.1.10.tgz", + "integrity": "sha512-DO95wD4g0A8KRaHKi0D51NdGXzvpqVLnLu5BTvDlpqUEpTmeEtypgC1xqesORaWmiUOQI14UHKlzNd9iZ2G3ZA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.0", + "@babel/helper-define-polyfill-provider": "^0.1.5", + "semver": "^6.1.1" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz", + "integrity": "sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.1.5", + "core-js-compat": "^3.8.1" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.1.6.tgz", + "integrity": "sha512-OUrYG9iKPKz8NxswXbRAdSwF0GhRdIEMTloQATJi4bDuFqrXaXcCUT/VGNrr8pBcjMh1RxZ7Xt9cytVJTJfvMg==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.1.5" + } + }, "babel-preset-current-node-syntax": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", @@ -18007,16 +18347,16 @@ "dev": true }, "browserslist": { - "version": "4.16.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz", - "integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==", + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001173", + "caniuse-lite": "^1.0.30001181", "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.634", + "electron-to-chromium": "^1.3.649", "escalade": "^3.1.1", - "node-releases": "^1.1.69" + "node-releases": "^1.1.70" } }, "bs-logger": { @@ -18114,9 +18454,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001179", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001179.tgz", - "integrity": "sha512-blMmO0QQujuUWZKyVrD1msR4WNDAqb/UPO1Sw2WWsQ7deoM5bJiicKnWJ1Y0NS/aGINSnKPIWBMw5luX+NDUCA==", + "version": "1.0.30001204", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001204.tgz", + "integrity": "sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ==", "dev": true }, "capture-exit": { @@ -18135,16 +18475,16 @@ "dev": true }, "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", "dev": true, "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", "deep-eql": "^3.0.1", "get-func-name": "^2.0.0", - "pathval": "^1.1.0", + "pathval": "^1.1.1", "type-detect": "^4.0.5" } }, @@ -18348,9 +18688,9 @@ "dev": true }, "colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, "colors": { @@ -18375,9 +18715,9 @@ "dev": true }, "comment-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.1.tgz", - "integrity": "sha512-vue7cRi1ZO5/72FJ+wZ5+siTSBlUv3ZksTk8bWD2IkaA6obitzMZP3yI65azTJLckwmi8lxfPP5Sd9oGuZ8e2g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.1.2.tgz", + "integrity": "sha512-AOdq0i8ghZudnYv8RUnHrhTgafUGs61Rdz9jemU5x2lnZwAWyOq7vySo626K59e1fVKH1xSRorJwPVRLSWOoAQ==", "dev": true }, "commondir": { @@ -18476,18 +18816,18 @@ "dev": true }, "core-js": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.3.tgz", - "integrity": "sha512-KPYXeVZYemC2TkNEkX/01I+7yd+nX3KddKwZ1Ww7SKWdI2wQprSgLmrTddT8nw92AjEklTsPBoSdQBhbI1bQ6Q==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.9.1.tgz", + "integrity": "sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg==", "dev": true }, "core-js-compat": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.3.tgz", - "integrity": "sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.9.1.tgz", + "integrity": "sha512-jXAirMQxrkbiiLsCx9bQPJFA6llDadKMpYrBJQJ3/c4/vsPP/fAf29h24tviRlvwUL6AmY5CHLu2GvjuYviQqA==", "dev": true, "requires": { - "browserslist": "^4.16.1", + "browserslist": "^4.16.3", "semver": "7.0.0" }, "dependencies": { @@ -18536,23 +18876,23 @@ } }, "css-loader": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.0.1.tgz", - "integrity": "sha512-cXc2ti9V234cq7rJzFKhirb2L2iPy8ZjALeVJAozXYz9te3r4eqLSixNAbMDJSgJEQywqXzs8gonxaboeKqwiw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.0.tgz", + "integrity": "sha512-MfRo2MjEeLXMlUkeUwN71Vx5oc6EJnx5UQ4Yi9iUtYQvrPtwLUucYptz0hc6n++kdNcyF5olYBS4vPjJDAcLkw==", "dev": true, "requires": { "camelcase": "^6.2.0", "cssesc": "^3.0.0", - "icss-utils": "^5.0.0", + "icss-utils": "^5.1.0", "loader-utils": "^2.0.0", - "postcss": "^8.1.4", + "postcss": "^8.2.8", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.1.0", "schema-utils": "^3.0.0", - "semver": "^7.3.2" + "semver": "^7.3.4" }, "dependencies": { "loader-utils": { @@ -18942,9 +19282,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.643", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.643.tgz", - "integrity": "sha512-TGomM4gj8adt/uqRgPbu9F0yhUVAR1deww5X0fvbQgpGr9suSMjLgc4IwQ9YKGkp1t03cDbZum20OfAkiTYjAg==", + "version": "1.3.698", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.698.tgz", + "integrity": "sha512-VEXDzYblnlT+g8Q3gedwzgKOso1evkeJzV8lih7lV8mL8eAnGVnKyC3KsFT6S+R5PQO4ffdr1PI16/ElibY/kQ==", "dev": true }, "emittery": { @@ -19057,9 +19397,9 @@ "dev": true }, "envinfo": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.7.3.tgz", - "integrity": "sha512-46+j5QxbPWza0PB1i15nZx0xQ4I/EfQxg9J8Had3b408SV63nEtor2e+oiY63amTo9KTuh2a3XLObNwduxYwwA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.7.4.tgz", + "integrity": "sha512-TQXTYFVVwwluWSFis6K2XKxgrD22jEv0FTuLCQI+OjH7rn93+iY0fSSFM5lrSxFY+H1+B0/cvvlamr3UsBivdQ==", "dev": true }, "errno": { @@ -19103,9 +19443,9 @@ } }, "es-module-lexer": { - "version": "0.3.26", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.3.26.tgz", - "integrity": "sha512-Va0Q/xqtrss45hWzP8CZJwzGSZJjDM5/MJRE3IXXnUCcVLElR9BRaE9F62BopysASyc4nM3uwhSW7FFB9nlWAA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", + "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", "dev": true }, "es-to-primitive": { @@ -19199,13 +19539,13 @@ } }, "eslint": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz", - "integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.23.0.tgz", + "integrity": "sha512-kqvNVbdkjzpFy0XOszNwjkKzZ+6TcwCQ/h+ozlcIWwaimBBuhlQ4nN6kbiM2L+OjDcznkTJxzYfRFH92sx4a0Q==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.3.0", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -19216,12 +19556,12 @@ "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", - "esquery": "^1.2.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^6.0.0", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", - "globals": "^12.1.0", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -19229,7 +19569,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.20", + "lodash": "^4.17.21", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -19243,6 +19583,15 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -19278,12 +19627,12 @@ "dev": true }, "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.7.0.tgz", + "integrity": "sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "type-fest": "^0.20.2" } }, "has-flag": { @@ -19292,12 +19641,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -19306,6 +19649,12 @@ "requires": { "has-flag": "^4.0.0" } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true } } }, @@ -19470,12 +19819,12 @@ } }, "eslint-plugin-jsdoc": { - "version": "31.0.8", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-31.0.8.tgz", - "integrity": "sha512-tB/+QfKXbV1CUqIwpRdZACt7dv1xDjqEjoJpc07EGqLgydJokT43fsZWPfj2mPbiMXYhZQiJXaKhk1x8lgUDQg==", + "version": "32.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-32.3.0.tgz", + "integrity": "sha512-zyx7kajDK+tqS1bHuY5sapkad8P8KT0vdd/lE55j47VPG2MeenSYuIY/M/Pvmzq5g0+3JB+P3BJGUXmHxtuKPQ==", "dev": true, "requires": { - "comment-parser": "1.1.1", + "comment-parser": "1.1.2", "debug": "^4.3.1", "jsdoctypeparser": "^9.0.0", "lodash": "^4.17.20", @@ -19485,22 +19834,23 @@ } }, "eslint-plugin-react": { - "version": "7.22.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz", - "integrity": "sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==", + "version": "7.23.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.23.1.tgz", + "integrity": "sha512-MvFGhZjI8Z4HusajmSw0ougGrq3Gs4vT/0WgwksZgf5RrLrRa2oYAw56okU4tZJl8+j7IYNuTM+2RnFEuTSdRQ==", "dev": true, "requires": { - "array-includes": "^3.1.1", - "array.prototype.flatmap": "^1.2.3", + "array-includes": "^3.1.3", + "array.prototype.flatmap": "^1.2.4", "doctrine": "^2.1.0", "has": "^1.0.3", "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "object.entries": "^1.1.2", - "object.fromentries": "^2.0.2", - "object.values": "^1.1.1", + "minimatch": "^3.0.4", + "object.entries": "^1.1.3", + "object.fromentries": "^2.0.4", + "object.values": "^1.1.3", "prop-types": "^15.7.2", - "resolve": "^1.18.1", - "string.prototype.matchall": "^4.0.2" + "resolve": "^2.0.0-next.3", + "string.prototype.matchall": "^4.0.4" }, "dependencies": { "doctrine": { @@ -19511,6 +19861,16 @@ "requires": { "esutils": "^2.0.2" } + }, + "resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } } } }, @@ -19579,9 +19939,9 @@ "dev": true }, "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -20002,9 +20362,9 @@ "dev": true }, "fastq": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz", - "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -20020,9 +20380,9 @@ } }, "file-entry-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", - "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { "flat-cache": "^3.0.4" @@ -20251,9 +20611,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", - "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -20327,9 +20687,9 @@ "dev": true }, "globby": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.2.tgz", - "integrity": "sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -20338,6 +20698,14 @@ "ignore": "^5.1.4", "merge2": "^1.3.0", "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } } }, "graceful-fs": { @@ -20481,9 +20849,9 @@ "dev": true }, "highlight.js": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.5.0.tgz", - "integrity": "sha512-xTmvd9HiIHR6L53TMC7TKolEj65zG1XU+Onr8oi86mYa+nLcIbxTTWkpW7CsEwv/vK7u1zb8alZIMLDqqN6KTw==", + "version": "10.7.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.1.tgz", + "integrity": "sha512-S6G97tHGqJ/U8DsXcEdnACbirtbx58Bx9CzIVeYli8OuswCfYI/LsXH2EiGcoGio1KAC3x4mmUwulOllJ2ZyRA==", "dev": true }, "hosted-git-info": { @@ -20584,9 +20952,9 @@ "dev": true }, "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "import-fresh": { @@ -20644,35 +21012,14 @@ "dev": true }, "internal-slot": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", - "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, "requires": { - "es-abstract": "^1.17.0-next.1", + "get-intrinsic": "^1.1.0", "has": "^1.0.3", - "side-channel": "^1.0.2" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "side-channel": "^1.0.4" } }, "interpret": { @@ -22523,9 +22870,9 @@ "dev": true }, "karma": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.0.1.tgz", - "integrity": "sha512-LHE8Ywfeji6Sk3jt072j7gUAYZrpw7tCzvQWpgJqwCC9inW4eA3g1yl6srTtC0xiOvZDqXIzx8tgBPm0qhfYkg==", + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.2.tgz", + "integrity": "sha512-fo4Wt0S99/8vylZMxNj4cBFyOBBnC1bewZ0QOlePij/2SZVWxqbyLeIddY13q6URa2EpLRW8ixvFRUMjkmo1bw==", "dev": true, "requires": { "body-parser": "^1.19.0", @@ -22546,7 +22893,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^3.0.4", + "socket.io": "^3.1.0", "source-map": "^0.6.1", "tmp": "0.2.1", "ua-parser-js": "^0.7.23", @@ -22787,9 +23134,9 @@ } }, "karma-webpack": { - "version": "5.0.0-alpha.5", - "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-5.0.0-alpha.5.tgz", - "integrity": "sha512-K+JmYbljzIK4tos98Wg1Z1unn1ymU0IF7o0U5CAAQzAORxzqI74YpjjrOp+7mfmR+2wfZxEogk3t0AKLa37EMw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-5.0.0.tgz", + "integrity": "sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA==", "dev": true, "requires": { "glob": "^7.1.3", @@ -22907,9 +23254,15 @@ } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, "lodash.get": { @@ -22918,12 +23271,6 @@ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -23331,44 +23678,38 @@ } }, "mocha": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", - "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", + "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.4.3", - "debug": "4.2.0", - "diff": "4.0.2", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.1.6", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.14.0", + "js-yaml": "4.0.0", "log-symbols": "4.0.0", "minimatch": "3.0.4", - "ms": "2.1.2", - "nanoid": "3.1.12", + "ms": "2.1.3", + "nanoid": "3.1.20", "serialize-javascript": "5.0.1", "strip-json-comments": "3.1.1", - "supports-color": "7.2.0", + "supports-color": "8.1.1", "which": "2.0.2", "wide-align": "1.1.3", - "workerpool": "6.0.2", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -23378,10 +23719,10 @@ "color-convert": "^2.0.1" } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, "chalk": { @@ -23392,33 +23733,28 @@ "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" - } - }, - "chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, "color-convert": { @@ -23436,19 +23772,10 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "escape-string-regexp": { @@ -23467,33 +23794,19 @@ "path-exists": "^4.0.0" } }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, "locate-path": { @@ -23514,10 +23827,10 @@ "chalk": "^4.0.0" } }, - "nanoid": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", - "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "p-limit": { @@ -23538,144 +23851,52 @@ "p-limit": "^3.0.2" } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" } }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - } + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, + "y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "dev": true + }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true } } }, @@ -23782,9 +24003,9 @@ "dev": true }, "nise": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", - "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0", @@ -24002,14 +24223,14 @@ } }, "object.fromentries": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.3.tgz", - "integrity": "sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", + "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", + "es-abstract": "^1.18.0-next.2", "has": "^1.0.3" } }, @@ -24023,14 +24244,14 @@ } }, "object.values": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz", - "integrity": "sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", + "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", + "es-abstract": "^1.18.0-next.2", "has": "^1.0.3" } }, @@ -24205,9 +24426,9 @@ "dev": true }, "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true }, "performance-now": { @@ -24258,12 +24479,12 @@ "dev": true }, "postcss": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.4.tgz", - "integrity": "sha512-kRFftRoExRVXZlwUuay9iC824qmXPcQQVzAjbCCgjpXnkdMCJYBu2gTwAaFBzv8ewND6O8xFb3aELmEkh9zTzg==", + "version": "8.2.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.8.tgz", + "integrity": "sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw==", "dev": true, "requires": { - "colorette": "^1.2.1", + "colorette": "^1.2.2", "nanoid": "^3.1.20", "source-map": "^0.6.1" }, @@ -24464,6 +24685,12 @@ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "quick-lru": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", @@ -24532,9 +24759,9 @@ } }, "react": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.1.tgz", - "integrity": "sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "dev": true, "requires": { "loose-envify": "^1.1.0", @@ -24542,14 +24769,14 @@ } }, "react-dom": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.1.tgz", - "integrity": "sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "scheduler": "^0.20.1" + "scheduler": "^0.20.2" } }, "react-is": { @@ -24767,9 +24994,9 @@ "dev": true }, "regjsparser": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.6.tgz", - "integrity": "sha512-jjyuCp+IEMIm3N1H1LLTJW1EISEJV9+5oHdEyrt43Pg9cDSb6rrLZei2cVWpl0xTjmmlpec/lEQGYgM7xfpGCQ==", + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", + "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", "dev": true, "requires": { "jsesc": "~0.5.0" @@ -24991,15 +25218,18 @@ "dev": true }, "run-parallel": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", - "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } }, "rxjs": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", - "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "requires": { "tslib": "^1.9.0" } @@ -25167,9 +25397,9 @@ } }, "sanitize-html": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.3.1.tgz", - "integrity": "sha512-JYziKrrtCEGhrsUAZK1mL0RdEcRxBGZ+ptgppv7ulAsan7MZVL+oVKRSPCIcYinfM1rVOMYh5dHLydMuHaQOUA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.3.3.tgz", + "integrity": "sha512-DCFXPt7Di0c6JUnlT90eIgrjs6TsJl/8HYU3KLdmrVclFN4O0heTcVbJiMa23OKVr6aR051XYtsgd8EWwEBwUA==", "dev": true, "requires": { "deepmerge": "^4.2.2", @@ -25205,9 +25435,9 @@ } }, "scheduler": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.1.tgz", - "integrity": "sha512-LKTe+2xNJBNxu/QhHvDR14wUXHRQbVY5ZOYpOGWRzhydZUqrLb2JBvLPY7cAqFmqrWuDED0Mjk7013SZiOz6Bw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "dev": true, "requires": { "loose-envify": "^1.1.0", @@ -25226,9 +25456,9 @@ } }, "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -25385,16 +25615,16 @@ "dev": true }, "sinon": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.3.tgz", - "integrity": "sha512-m+DyAWvqVHZtjnjX/nuShasykFeiZ+nPuEfD4G3gpvKGkXRhkF/6NSt2qN2FjZhfrcHXFzUzI+NLnk+42fnLEw==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-10.0.0.tgz", + "integrity": "sha512-XAn5DxtGVJBlBWYrcYKEhWCz7FLwZGdyvANRyK06419hyEpdT0dMc5A8Vcxg5SCGHc40CsqoKsc1bt1CbJPfNw==", "dev": true, "requires": { "@sinonjs/commons": "^1.8.1", "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/samsam": "^5.3.0", + "@sinonjs/samsam": "^5.3.1", "diff": "^4.0.2", - "nise": "^4.0.4", + "nise": "^4.1.0", "supports-color": "^7.1.0" }, "dependencies": { @@ -25852,18 +26082,18 @@ } }, "string.prototype.matchall": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz", - "integrity": "sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.4.tgz", + "integrity": "sha512-pknFIWVachNcyqRfaQSeu/FUfpvJTe4uskUSZ9Wc1RijsPuzbZ8TyYT8WCNnntCjUEqQ3vUHMAfVj2+wLAisPQ==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", + "es-abstract": "^1.18.0-next.2", "has-symbols": "^1.0.1", - "internal-slot": "^1.0.2", - "regexp.prototype.flags": "^1.3.0", - "side-channel": "^1.0.3" + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" } }, "string.prototype.trimend": { @@ -26240,18 +26470,17 @@ "dev": true }, "ts-jest": { - "version": "26.4.4", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.4.4.tgz", - "integrity": "sha512-3lFWKbLxJm34QxyVNNCgXX1u4o/RV0myvA2y2Bxm46iGIjKlaY0own9gIckbjZJPn+WaJEnfPPJ20HHGpoq4yg==", + "version": "26.5.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.4.tgz", + "integrity": "sha512-I5Qsddo+VTm94SukBJ4cPimOoFZsYTeElR2xy6H2TOVs+NsvgYglW8KuQgKoApOKuaU/Ix/vrF9ebFZlb5D2Pg==", "dev": true, "requires": { - "@types/jest": "26.x", "bs-logger": "0.x", "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", "jest-util": "^26.1.0", "json5": "2.x", - "lodash.memoize": "4.x", + "lodash": "4.x", "make-error": "1.x", "mkdirp": "1.x", "semver": "7.x", @@ -26273,9 +26502,9 @@ } }, "ts-loader": { - "version": "8.0.14", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.14.tgz", - "integrity": "sha512-Jt/hHlUnApOZjnSjTmZ+AbD5BGlQFx3f1D0nYuNKwz0JJnuDGHJas6az+FlWKwwRTu+26GXpv249A8UAnYUpqA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.1.0.tgz", + "integrity": "sha512-YiQipGGAFj2zBfqLhp28yUvPP9jUGqHxRzrGYuc82Z2wM27YIHbElXiaZDc93c3x0mz4zvBmS6q/DgExpdj37A==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -26478,9 +26707,9 @@ } }, "typescript": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", - "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.3.tgz", + "integrity": "sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==", "dev": true }, "ua-parser-js": { @@ -26776,9 +27005,9 @@ "dev": true }, "webpack": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.17.0.tgz", - "integrity": "sha512-R+IdNEaYcYaACpXZOt7reyc8txBK7J06lOPkX1SbgmeoAnUbyBZivJIksrDBnmMA3wlTWvPcX7DubxELyPB8rA==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.28.0.tgz", + "integrity": "sha512-1xllYVmA4dIvRjHzwELgW4KjIU1fW4PEuEnjsylz7k7H5HgPOctIq7W1jrt3sKH9yG5d72//XWzsHhfoWvsQVg==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.0", @@ -26790,7 +27019,7 @@ "browserslist": "^4.14.5", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.7.0", - "es-module-lexer": "^0.3.26", + "es-module-lexer": "^0.4.0", "eslint-scope": "^5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -26799,7 +27028,6 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "pkg-dir": "^5.0.0", "schema-utils": "^3.0.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.1.1", @@ -26823,52 +27051,6 @@ "tapable": "^2.2.0" } }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "pkg-dir": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", - "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", - "dev": true, - "requires": { - "find-up": "^5.0.0" - } - }, "schema-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", @@ -26975,17 +27157,17 @@ } }, "webpack-cli": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.4.0.tgz", - "integrity": "sha512-/Qh07CXfXEkMu5S8wEpjuaw2Zj/CC0hf/qbTDp6N8N7JjdGuaOjZ7kttz+zhuJO/J5m7alQEhNk9lsc4rC6xgQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.6.0.tgz", + "integrity": "sha512-9YV+qTcGMjQFiY7Nb1kmnupvb1x40lfpj8pwdO/bom+sQiP4OBMKjHq29YQrlDWDPZO9r/qWaRRywKaRDKqBTA==", "dev": true, "requires": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.0", - "@webpack-cli/info": "^1.2.1", - "@webpack-cli/serve": "^1.2.2", + "@webpack-cli/configtest": "^1.0.2", + "@webpack-cli/info": "^1.2.3", + "@webpack-cli/serve": "^1.3.1", "colorette": "^1.2.1", - "commander": "^6.2.0", + "commander": "^7.0.0", "enquirer": "^2.3.6", "execa": "^5.0.0", "fastest-levenshtein": "^1.0.12", @@ -26997,9 +27179,9 @@ }, "dependencies": { "commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true }, "execa": { @@ -27172,9 +27354,9 @@ "dev": true }, "workerpool": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", - "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", "dev": true }, "wrap-ansi": { diff --git a/package.json b/package.json index cc3c568c1e..a8e86266fc 100644 --- a/package.json +++ b/package.json @@ -115,67 +115,67 @@ "dependencies": { "next-tick": "1.1.0", "pinkie": "2.0.4", - "rxjs": "6.6.3" + "rxjs": "6.6.7" }, "devDependencies": { - "@babel/core": "7.12.10", - "@babel/plugin-transform-runtime": "7.12.10", - "@babel/preset-env": "7.12.11", - "@babel/preset-react": "7.12.10", - "@types/chai": "4.2.14", - "@types/jest": "26.0.20", - "@types/mocha": "8.2.0", - "@types/node": "14.14.22", - "@types/sinon": "9.0.10", - "@typescript-eslint/eslint-plugin": "4.14.0", - "@typescript-eslint/eslint-plugin-tslint": "4.14.0", - "@typescript-eslint/parser": "4.14.0", + "@babel/core": "7.13.14", + "@babel/plugin-transform-runtime": "7.13.10", + "@babel/preset-env": "7.13.12", + "@babel/preset-react": "7.13.13", + "@types/chai": "4.2.15", + "@types/jest": "26.0.22", + "@types/mocha": "8.2.2", + "@types/node": "14.14.37", + "@types/sinon": "9.0.11", + "@typescript-eslint/eslint-plugin": "4.20.0", + "@typescript-eslint/eslint-plugin-tslint": "4.20.0", + "@typescript-eslint/parser": "4.20.0", "arraybuffer-loader": "1.0.8", "babel-loader": "8.2.2", - "chai": "4.2.0", + "chai": "4.3.4", "chart.js": "2.9.4", "cheerio": "1.0.0-rc.5", - "core-js": "3.8.3", + "core-js": "3.9.1", "cross-env": "7.0.3", - "css-loader": "5.0.1", - "eslint": "7.18.0", + "css-loader": "5.2.0", + "eslint": "7.23.0", "eslint-plugin-import": "2.22.1", - "eslint-plugin-jsdoc": "31.0.8", - "eslint-plugin-react": "7.22.0", + "eslint-plugin-jsdoc": "32.3.0", + "eslint-plugin-react": "7.23.1", "esm": "3.2.25", "express": "4.17.1", "file-loader": "6.2.0", - "highlight.js": "10.5.0", + "highlight.js": "10.7.1", "istanbul-instrumenter-loader": "3.0.1", "jest": "26.6.3", - "karma": "6.0.1", + "karma": "6.3.2", "karma-chrome-launcher": "3.1.0", "karma-coverage-istanbul-reporter": "3.0.3", "karma-firefox-launcher": "2.1.0", "karma-mocha": "2.0.1", "karma-mocha-reporter": "2.2.5", - "karma-webpack": "5.0.0-alpha.5", + "karma-webpack": "5.0.0", "markdown-it": "12.0.4", "markdown-it-emoji": "2.0.0", - "mocha": "8.2.1", + "mocha": "8.3.2", "mocha-loader": "5.1.5", "npm-scripts-info": "0.3.9", "raw-loader": "4.0.2", - "react": "17.0.1", - "react-dom": "17.0.1", + "react": "17.0.2", + "react-dom": "17.0.2", "regenerator-runtime": "0.13.7", - "sanitize-html": "2.3.1", - "semver": "7.3.4", - "sinon": "9.2.3", + "sanitize-html": "2.3.3", + "semver": "7.3.5", + "sinon": "10.0.0", "style-loader": "2.0.0", "terser-webpack-plugin": "5.1.1", - "ts-jest": "26.4.4", - "ts-loader": "8.0.14", + "ts-jest": "26.5.4", + "ts-loader": "8.1.0", "tslint": "6.1.3", - "typescript": "4.1.3", + "typescript": "4.2.3", "url-loader": "4.1.1", - "webpack": "5.17.0", + "webpack": "5.28.0", "webpack-bundle-analyzer": "4.4.0", - "webpack-cli": "4.4.0" + "webpack-cli": "4.6.0" } } diff --git a/scripts/doc-generator/convert_MD_to_HMTL.js b/scripts/doc-generator/convert_MD_to_HMTL.js index 1b9e98f3d2..96a91d7345 100644 --- a/scripts/doc-generator/convert_MD_to_HMTL.js +++ b/scripts/doc-generator/convert_MD_to_HMTL.js @@ -4,7 +4,7 @@ const md = require("markdown-it")({ highlight: function (str, lang) { if (lang && hljs.getLanguage(lang)) { try { - return hljs.highlight(lang, str).value; + return hljs.highlight(str, { language: lang }).value; } catch (_) {} } return ""; From 8d87a9de57038a1cb985254bc493e7f0cd2f38c1 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Thu, 25 Mar 2021 15:46:50 +0100 Subject: [PATCH 46/75] add generated doc to .gitignore --- .gitignore | 2 + doc/generated/list.html | 89 - .../pages/api/TextTrackRenderer.html | 305 -- .../pages/api/assets/text_track_example.png | Bin 888305 -> 0 bytes .../pages/api/createMetaplaylist.html | 91 - doc/generated/pages/api/deprecated.html | 446 --- doc/generated/pages/api/errors.html | 340 --- doc/generated/pages/api/exported_types.html | 277 -- doc/generated/pages/api/images.html | 86 - doc/generated/pages/api/index.html | 2720 ----------------- .../pages/api/loadVideo_options.html | 1237 -------- doc/generated/pages/api/local_manifest.html | 656 ---- .../pages/api/local_manifest_v0.1.html | 612 ---- doc/generated/pages/api/low_latency.html | 179 -- doc/generated/pages/api/manifest.html | 312 -- .../pages/api/mediaCapabilitiesProber.html | 502 --- doc/generated/pages/api/metaplaylist.html | 316 -- doc/generated/pages/api/minimal_player.html | 348 --- .../pages/api/parseBifThumbnails.html | 68 - doc/generated/pages/api/player_events.html | 619 ---- doc/generated/pages/api/player_options.html | 602 ---- doc/generated/pages/api/plugins.html | 305 -- doc/generated/pages/api/states.html | 385 --- doc/generated/pages/api/text_tracks.html | 155 - .../architecture/abr/bandwidth_estimator.html | 50 - .../abr/buffer_based_chooser.html | 52 - .../pages/architecture/abr/index.html | 34 - .../pages/architecture/api/index.html | 79 - .../pages/architecture/eme/index.html | 16 - .../pages/architecture/fetchers/index.html | 84 - doc/generated/pages/architecture/files.html | 287 -- doc/generated/pages/architecture/index.html | 171 -- .../pages/architecture/init/index.html | 128 - .../architecture/segment_buffers/index.html | 153 - .../segment_buffers/segment_inventory.html | 74 - .../pages/architecture/stream/index.html | 53 - .../stream/representation_stream.html | 105 - .../stream/stream_orchestrator.html | 301 -- .../pages/architecture/transports/index.html | 60 - .../architecture/transports/metaplaylist.html | 87 - .../architecture/transports/pipeline.html | 232 -- .../dash_rxplayer_adaptation_difference.html | 64 - doc/generated/pages/index.html | 56 - .../infos/dash/presentationTimeOffset.html | 240 -- .../pages/infos/initial_position.html | 107 - doc/generated/pages/terms.html | 205 -- .../pages/tutorials/contents_with_DRM.html | 654 ---- doc/generated/pages/tutorials/index.html | 13 - .../pages/tutorials/quick_start.html | 146 - .../pages/tutorials/stream_events.html | 289 -- .../pages/tutorials/track_selection.html | 583 ---- doc/generated/pages/v2_to_v3.html | 1259 -------- doc/generated/pages/why_typescript.html | 134 - doc/generated/styles/code.css | 99 - doc/generated/styles/style.css | 267 -- 55 files changed, 2 insertions(+), 16732 deletions(-) delete mode 100644 doc/generated/list.html delete mode 100644 doc/generated/pages/api/TextTrackRenderer.html delete mode 100644 doc/generated/pages/api/assets/text_track_example.png delete mode 100644 doc/generated/pages/api/createMetaplaylist.html delete mode 100644 doc/generated/pages/api/deprecated.html delete mode 100644 doc/generated/pages/api/errors.html delete mode 100644 doc/generated/pages/api/exported_types.html delete mode 100644 doc/generated/pages/api/images.html delete mode 100644 doc/generated/pages/api/index.html delete mode 100644 doc/generated/pages/api/loadVideo_options.html delete mode 100644 doc/generated/pages/api/local_manifest.html delete mode 100644 doc/generated/pages/api/local_manifest_v0.1.html delete mode 100644 doc/generated/pages/api/low_latency.html delete mode 100644 doc/generated/pages/api/manifest.html delete mode 100644 doc/generated/pages/api/mediaCapabilitiesProber.html delete mode 100644 doc/generated/pages/api/metaplaylist.html delete mode 100644 doc/generated/pages/api/minimal_player.html delete mode 100644 doc/generated/pages/api/parseBifThumbnails.html delete mode 100644 doc/generated/pages/api/player_events.html delete mode 100644 doc/generated/pages/api/player_options.html delete mode 100644 doc/generated/pages/api/plugins.html delete mode 100644 doc/generated/pages/api/states.html delete mode 100644 doc/generated/pages/api/text_tracks.html delete mode 100644 doc/generated/pages/architecture/abr/bandwidth_estimator.html delete mode 100644 doc/generated/pages/architecture/abr/buffer_based_chooser.html delete mode 100644 doc/generated/pages/architecture/abr/index.html delete mode 100644 doc/generated/pages/architecture/api/index.html delete mode 100644 doc/generated/pages/architecture/eme/index.html delete mode 100644 doc/generated/pages/architecture/fetchers/index.html delete mode 100644 doc/generated/pages/architecture/files.html delete mode 100644 doc/generated/pages/architecture/index.html delete mode 100644 doc/generated/pages/architecture/init/index.html delete mode 100644 doc/generated/pages/architecture/segment_buffers/index.html delete mode 100644 doc/generated/pages/architecture/segment_buffers/segment_inventory.html delete mode 100644 doc/generated/pages/architecture/stream/index.html delete mode 100644 doc/generated/pages/architecture/stream/representation_stream.html delete mode 100644 doc/generated/pages/architecture/stream/stream_orchestrator.html delete mode 100644 doc/generated/pages/architecture/transports/index.html delete mode 100644 doc/generated/pages/architecture/transports/metaplaylist.html delete mode 100644 doc/generated/pages/architecture/transports/pipeline.html delete mode 100644 doc/generated/pages/dash_rxplayer_adaptation_difference.html delete mode 100644 doc/generated/pages/index.html delete mode 100644 doc/generated/pages/infos/dash/presentationTimeOffset.html delete mode 100644 doc/generated/pages/infos/initial_position.html delete mode 100644 doc/generated/pages/terms.html delete mode 100644 doc/generated/pages/tutorials/contents_with_DRM.html delete mode 100644 doc/generated/pages/tutorials/index.html delete mode 100644 doc/generated/pages/tutorials/quick_start.html delete mode 100644 doc/generated/pages/tutorials/stream_events.html delete mode 100644 doc/generated/pages/tutorials/track_selection.html delete mode 100644 doc/generated/pages/v2_to_v3.html delete mode 100644 doc/generated/pages/why_typescript.html delete mode 100644 doc/generated/styles/code.css delete mode 100644 doc/generated/styles/style.css diff --git a/.gitignore b/.gitignore index e70b07c7ce..8aa31016e0 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,8 @@ /dist/_esm5.processed /dist/_esm5.raw +/doc/generated + /features /logger /minimal diff --git a/doc/generated/list.html b/doc/generated/list.html deleted file mode 100644 index 4daa1c015a..0000000000 --- a/doc/generated/list.html +++ /dev/null @@ -1,89 +0,0 @@ -Page List - RxPlayer Documentation \ No newline at end of file diff --git a/doc/generated/pages/api/TextTrackRenderer.html b/doc/generated/pages/api/TextTrackRenderer.html deleted file mode 100644 index 6c93074dc0..0000000000 --- a/doc/generated/pages/api/TextTrackRenderer.html +++ /dev/null @@ -1,305 +0,0 @@ -TextTrackRenderer - RxPlayer Documentation

-

TextTrackRenderer

-

-

Overview

-

The TextTrackRenderer is a tool allowing to render subtitles synchronized with -a video element (or any HTMLMediaElement).

-

For now it supports the following formats:

-
    -
  • TTML
  • -
  • webVTT
  • -
  • srt
  • -
  • sami
  • -
-

The video does not need to be played through the RxPlayer for the -TextTrackRenderer to work. It is a completely independent tool which just -rely on the video element for synchronization information.

-

-

Brief summary

-

If you don’t want to read all this documentation, here is a complete example of -how it can be used:

-
// import TextTrackRenderer and the parsers we want
-import TextTrackRenderer, {
-  TTML_PARSER,
-  VTT_PARSER,
-  SRT_PARSER,
-  SAMI_PARSER,
-} from "rx-player/tools/TextTrackRenderer";
-
-// Add the needed parsers to the TextTrackRenderer
-TextTrackRenderer.addParsers([ TTML_PARSER, VTT_PARSER, SRT_PARSER, SAMI_PARSER ]);
-
-
-// get video element the subtitles has to be synchronized to
-const videoElement = document.querySelector("video");
-
-// get HTML element in which the text track will be displayed
-// Should generally be on top of the video, with the same size than it (but can
-// also be in any shape, corresponding to your UI needs).
-const textTrackElement = document.querySelector(".text-track-container");
-
-const textTrackRenderer = new TextTrackRenderer({
-  videoElement,
-  textTrackElement,
-});
-
-// example: a ".srt" track
-const exampleSRT = `1
-00:00:01,600 --> 00:00:04,200
-English (US)
-
-2
-00:00:05,900 --> 00:00:07,999
-This is a subtitle in American English
-
-3
-00:00:10,000 --> 00:00:14,000
-Adding subtitles is very easy to do
-`;
-
-try {
-  textTrackRenderer.setTextTrack({
-    data: exampleSRT,
-    type: "srt", // or "ttml" / "vtt" / "sami"
-    // timeOffset: 2.3, // optional offset in seconds to add to the subtitles
-  });
-} catch (e) {
-  console.error(`Could not parse the subtitles: ${e}`);
-}
-
-

-

How to import it

-

The TextTrackRenderer alone can be imported as such:

-
import TextTrackRenderer from "rx-player/tools/TextTrackRenderer";
-
-

But just importing the TextTrackRenderer alone is pointless, you also have to -import the text track parsers you want to use manually (this is a choice we -made to avoid wasting space for subtitles formats you might not want).

-

To import the parsers you want, you just have to do something along the line -of:

-
// Add two parsers to the TextTrackRenderer: one for TTML subtitles and one for
-// srt subtitles
-import TextTrackRenderer, {
-  TTML_PARSER,
-  SRT_PARSER,
-} from "rx-player/tools/TextTrackRenderer";
-TextTrackRenderer.addParsers([ TTML_PARSER, SRT_PARSER ]);
-
-

Here are the different available parsers:

- - - - - - - - - - - - - - - - - - - - - - - - - -
Import nameSubtitles format parsed
TTML_PARSERTTML
VTT_PARSERWebVTT
SRT_PARSERSubRip (.srt)
SAMI_PARSERSAMI
-

-

How to use it

-

-

Preamble

-

Now that it is imported, we can begin to use it.

-

We will need three items:

-
    -
  1. -

    The video element our subtitles has to be synchronized to.

    -
  2. -
  3. -

    Another HTML element, in which the various subtitles will be rendered by -the TextTrackRenderer. In general, you want that element to be on top of -the video element, with the same dimensions. You might however set it in -the shape and size you want.

    -

    It can even be reduced dynamically at any time (for example, to reduce this -element’s height when a UI element appear at the bottom of the screen, -thus avoiding the subtitles from overlapping that new element).

    -
  4. -
  5. -

    The whole text track data, as a string (you will have to download the -subtitles yourself).

    -
  6. -
-

To simplify, let’s give a name to all those 3 elements:

-
    -
  1. the videoElement
  2. -
  3. the textTrackElement
  4. -
  5. the textTrackData
  6. -
-

-

Creating a TextTrackRenderer

-

We first have to create a new TextTrackRenderer with the first two items:

-
const textTrackRenderer = new TextTrackRenderer({
-  videoElement,
-  textTrackElement,
-});
-
-

-

Setting a text track on it

-

With textTrackRenderer, the TextTrackRenderer instance, we can now add at -any time a text track through its setTextTrack method:

-
try {
-  textTrackRenderer.setTextTrack({
-    data: textTrackData,
-    type: SUBTITLES_FORMAT,
-  });
-} catch (e) {
-  console.error(`Could not parse the subtitles: ${e}`);
-}
-
-

Here, SUBTITLES_FORMAT is a string indicating in which format the subtitles -are. It can be any of those strings:

- - - - - - - - - - - - - - - - - - - - - - - - - -
typeCorresponding subtitles format
"ttml"TTML
"vtt"WebVTT
"srt"SubRip (.srt)
"sami"SAMI
-

(Each format needs the corresponding parser to be imported. See the previous -chapter for more information.)

-

Note that the setTextTrack method can throw if the subtitles are found to be -invalid.

-

Any subsequent call to setTextTrack will remove the current text track and -replace them with the new text track instead:

-
// Add TTML subtitles
-textTrackRenderer.setTextTrack({
-  data: textTrackData1,
-  type: "ttml",
-});
-
-// Completely removes the TTML subtitles and replace them by other subtitles, in
-// webVTT this time
-textTrackRenderer.setTextTrack({
-  data: textTrackData2,
-  type: "vtt",
-});
-
-

If your subtitles have a delay or are in advance relatively to the video, you -can also set an offset in seconds through the timeOffset property.

-

For example, this will display each subtitles 1.3 seconds later (for when -subtitles appear and disappear too much in advance):

-
textTrackRenderer.setTextTrack({
-  data: textTrackData,
-  type: "srt",
-  timeOffset: 1.3,
-});
-
-

And this will display each subtitles 1.3 seconds before they normally appear -and disappear (for when subtitles are too late):

-
textTrackRenderer.setTextTrack({
-  data: textTrackData,
-  type: "srt",
-  timeOffset: -1.3,
-});
-
-

-

Removing the current text track

-

If you just want to completely remove the current text track, you can call the -removeTextTrack method:

-
textTrackRenderer.removeTextTrack();
-
-

-

Disposing of the TextTrackRenderer

-

If you’re sure that you won’t need the TextTrackRenderer anymore, you can -dispose of most ressources (which is not much) it took on your page by calling -the dispose method:

-
textTrackRenderer.dispose();
-
-

That TextTrackRenderer instance won’t be usable once you’ve call this method, -so be sure you don’t need it anymore before calling it.

-

-

Notes on the SAMI format

-

The SAMI subtitles format might necessitate you to specify the language you want -to parse.

-

This can be done on the setTextTrack call like this:

-
textTrackRenderer.setTextTrack({
-  data: textTrackData,
-  type: "sami",
-  language: "en-US", // or fr-FR...
-});
-
-

-

About logs

-

The TextTrackRenderer can display logs to the console. It relies on the exact -same logger instance than the RxPlayer.

-

This logger can be independently imported from "rx-player/logger":

-
import logger from "rx-player/logger";
-
-

You can then set its verbosity through its setLevel method:

-
logger.setLevel(LOGGER_LEVEL);
-
-

LOGGER_LEVEL can be any of those strings (from the less verbose to the most):

-
    -
  • -

    "NONE": no log

    -
  • -
  • -

    "ERROR": unexpected errors (via console.error)

    -
  • -
  • -

    "WARNING": The previous level + minor problems encountered (via -console.warn)

    -
  • -
  • -

    "INFO": The previous levels + noteworthy events (via console.info)

    -
  • -
  • -

    "DEBUG": The previous levels + regular events (via console.log)

    -
  • -
-

⚠️ Updating the logger level will also update the RxPlayer’s logger -level as it is the exact same logger that is used there.

-
\ No newline at end of file diff --git a/doc/generated/pages/api/assets/text_track_example.png b/doc/generated/pages/api/assets/text_track_example.png deleted file mode 100644 index 167cdc968e20165bbd6c6407967fe4b52048ad47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 888305 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�m@_eTa3gx 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

XY*O0 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 Y0VD~6dp~acp#T5?07*qoM6N<$f|onVHvj+t diff --git a/doc/generated/pages/api/createMetaplaylist.html b/doc/generated/pages/api/createMetaplaylist.html deleted file mode 100644 index f3b0270e56..0000000000 --- a/doc/generated/pages/api/createMetaplaylist.html +++ /dev/null @@ -1,91 +0,0 @@ -createMetaplaylist - RxPlayer Documentation

-

createMetaplaylist

-

createMetaplaylist is a function that allows to build a [metaplaylist] -(./metaplaylist.md) object from given contents information.

-

You may need to use this function because not all information about contents -are known by the user when wanting to create a metaplaylist. For example, -the end of a content will be found thanks to the content duration, that can be -parsed from the content manifest.

-

-

How to import it

-

createMetaplaylist is for now considered an “experimental” tool. This means -that its API could change at any new version of the RxPlayer (don’t worry, we -would still document all changes made to it in the corresponding release note).

-

As an experimental tool, it is imported as such:

-
import { createMetaplaylist } from "rx-player/experimental/tools";
-
-

You can then begin to use it right away.

-

-

How to use it

-

createMetaplaylist takes two arguments :

-
    -
  • -

    contentInfos (Array<Object>) : The list of content information, in the -playback order they should have in the metaplaylist.

    -

    The list is an array of objects with this attributes :

    -
      -
    • url (string): The URL of the source content
    • -
    • transport (string): The transport type of the content (dash, smooth -or even metaplaylist)
    • -
    -
  • -
  • -

    timeOffset (number|undefined) : the optionnal time offset that -applies to the metaplaylist start time (default is 0).

    -
  • -
-

Example:

-
createMetaplaylist(
-    [
-        // dash content, 10mn long
-        {
-            url: "https://somedashcontent.mpd",
-            transport: "dash",
-        },
-        // smooth content, 35s long
-        {
-            url: "https://somesmoothcontent.ism",
-            transport: "smooth",
-        },
-        // metaplaylist content, 100mn long
-        {
-            url: "https://somemetaplaylistcontent",
-            transport: "metaplaylist",
-        }
-    ],
-    1000
-)
-
-

The returned metaplaylist will look like :

-
    {
-        type: "MPL",
-        version: "0.1",
-        dynamic: false,
-        contents: [
-            {
-                url: "https://somedashcontent.mpd",
-                transport: "dash",
-                startTime: 1000,
-                endTime: 1600,
-            },
-            {
-                url: "https://somesmoothcontent.ism",
-                transport: "smooth",
-                startTime: 1600,
-                endTime: 1635,
-            },
-            {
-                url: "https://somemetaplaylistcontent",
-                transport: "metaplaylist",
-                startTime: 1635,
-                endTime: 7635,
-            },
-        ],
-    }
-
-
\ No newline at end of file diff --git a/doc/generated/pages/api/deprecated.html b/doc/generated/pages/api/deprecated.html deleted file mode 100644 index 99125a5ad8..0000000000 --- a/doc/generated/pages/api/deprecated.html +++ /dev/null @@ -1,446 +0,0 @@ -Deprecated APIs - RxPlayer Documentation

-

Deprecated APIs

-

This documentation lists APIs deprecated in the v3.x.x.

-

As we guarantee API compatibility in the v3.x.x, those API won’t disappear until -we switch to a v4.x.x version.

-

You will find here which APIs are deprecated, why, and depending on the -concerned API, how to replace it.

-

-

-

Fullscreen APIs

-

All fullscreen APIs have been deprecated, namely:

-
    -
  • the isFullscreen method
  • -
  • the setFullscreen method
  • -
  • the exitFullscreen method
  • -
  • the fullscreenChange event
  • -
-

This is because of several things:

-
    -
  • -

    fullscreen management has now become a lot more complex with features such -as advanced subtitles management, were the text track HTMLElement is -controlled by the application.

    -
  • -
  • -

    most application developpers also wants to put their own controls into -fullscreen mode. Those APIs only put the media element into fullscreen mode -and not any other element. This can be misleading.

    -
  • -
-

The fullscreen logic should now be entirely on the application-side. Replacement -code is provided for each of those APIs below.

-

-

-

Image (BIF) APIs

-

The following properties methods and events have been deprecated:

-
    -
  • the imageTrackUpdate event
  • -
  • the getImageTrackData method
  • -
  • the supplementaryImageTracks loadVideo option
  • -
-

This is because most code linked to image management will be moved outside the -RxPlayer. Doing that will both be more flexible for users and much easier to -maintain for us (albeit with a small time of transition for the application).

-

You can replace those API by this new exported function: -parseBifThumbnails.

-

To give more details about why those APIs have been deprecated, there are -multiple reasons:

-
    -
  1. How it should be specified for live contents of for multi-Period DASH -contents is not clear enough.
  2. -
  3. Integrating it in the RxPlayer’s API means that it had to take multiple -choices that we prefer to let to the application: whether to retry the -request if the it fails or if it is unavailable, whether to do the request -at all for users with a low bitrate…
  4. -
  5. The task of displaying those thumbnails is ultimately on the UI-side (the -part that know where the user wants to seek)
  6. -
  7. The biggest part of the code related to it was a simple BIF parser, that -can easily be re-implemented by any application.
  8. -
-

-

RxPlayer Methods

-

The following RxPlayer methods are deprecated.

-

-

getManifest

-

getManifest returns our internal representation we have of a given “manifest” -document.

-

Though it was first exposed to allow users to have access to more precize -information on the current content, this method also limited us on the possible -evolutions we could do, as changing what this function returns would mean -breaking the API.

-

We also realized that that method was not used for now by the implementation we -know of.

-

For now, we decided we will simply remove that API in the next major version. If -that’s a problem for you, please open an issue.

-

-

getCurrentAdaptations

-

getCurrentAdaptations returns an object describing each tracks available for -the current Period in the current content.

-

Like getManifest, we found that this API was not much used and limited us on -the possible evolutions we can do on the RxPlayer.

-

Again like getManifest, we plan to remove that API completely without -replacing it. -If that’s a problem for you, please open an issue.

-

-

getCurrentRepresentations

-

getCurrentRepresentations returns an object describing each “qualities” -available in the current chosen tracks.

-

Exactly like getCurrentAdaptations and getManifest, we found that this API:

-
    -
  • was not used as far as we know
  • -
  • limited the evolutions we could do on the RxPlayer’s code without breaking -the API.
  • -
-

We thus plan to remove that API completely without replacing it. -If that’s a problem for you, please open an issue.

-

-

getNativeTextTrack

-

getNativeTextTrack returned the first TextTrack element attached to the -media element or null if it did not exist.

-

This API was originally created to allow users to manipulate the TextTrack -element themselves. For example, to “catch” cues as they appear and display them -differently.

-

What changed is that we now have two text track modes:

-
    -
  • html, which allow advanced subtitle management
  • -
  • native, the old mode, which display subtitles natively through a -TextTrack element.
  • -
-

This API will only return an element for the native mode, but none for the -html mode because its element is not attached to the media element.

-

We heavily insist on people wanting advanced usecases to use the html mode, as -many formatting options do not work in native mode.

-

As we considered that getNativeTextTrack API was more confusing than it was -helpful in our current API, we decided to deprecate it. Do not hesitate to open -an issue if you use this API.

-

-

isFullscreen

-

isFullscreen has been deprecated as it is part of our Fullscreen APIs, see -the related chapter for more information.

-

isFullscreen just checked that ANY element was fullscreen. As such, it can -easily be replace for the majority of browsers with the following code:

-
function isFullscreen() {
-  return !!(
-    document.fullscreenElement ||
-    document.mozFullScreenElement ||
-    document.webkitFullscreenElement ||
-    document.msFullscreenElement
-  );
-}
-
-

-

setFullscreen

-

setFullscreen has been deprecated as it is part of our Fullscreen APIs, see -the related chapter for more information.

-

setFullscreen allowed to set the media element in fullscreen mode (or exit -fullscreen mode, if false was given as argument).

-

If you want to just put the media element on fullscreen mode, you can use the -following code:

-
function setFullscreen(goFull) {
-  if (goFull === "false") {
-    exitFullscreen();
-    return;
-  }
-  if (isFullscreen()) { // see code above
-    return;
-  }
-
-  const mediaElement = player.getVideoElement();
-  if (!mediaElement) {
-    throw new Error("No media element");
-  }
-  if (mediaElement.requestFullscreen) {
-    mediaElement.requestFullscreen();
-  } else if (mediaElement.msRequestFullscreen) {
-    mediaElement.msRequestFullscreen();
-  } else if (mediaElement.mozRequestFullScreen) {
-    mediaElement.mozRequestFullScreen();
-  } else if (mediaElement.webkitRequestFullscreen) {
-    mediaElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
-  }
-}
-
-

Please consider however that this function will only put the media element in -full screen mode, without the eventual controls and HTML text tracks you might -also want to set in fullscreen. The code is easily adaptable however to put -your own element into fullscreen mode instead.

-

-

exitFullscreen

-

exitFullscreen has been deprecated as it is part of our Fullscreen APIs, see -the related chapter for more information.

-

exitFullscreen just exited any element put in fullscreen mode. As such, -its code can easily be replaced by:

-
function exitFullscreen() {
-  if (isFullscreen()) {
-    if (document.exitFullscreen) {
-      document.exitFullscreen();
-    } else if (document.msExitFullscreen) {
-      document.msExitFullscreen();
-    } else if (document.mozCancelFullScreen) {
-      document.mozCancelFullScreen();
-    } else if (document.webkitExitFullscreen) {
-      document.webkitExitFullscreen();
-    }
-  }
-}
-
-

-

getImageTrackData

-

getImageTrackData has been deprecated like most API related to BIF thumbnail -parsing. -You can read the related chapter for more information.

-

You can replace this API by using the -parseBifThumbnails tool.

-

-

RxPlayer Events

-

The following RxPlayer events has been deprecated.

-

-

nativeTextTracksChange

-

nativeTextTracksChange events are deprecated. Which means they probably -won’t be sent in a v4.x.x version.

-

The reasons are basically the same than for the getNativeTextTracks method. -It should not be needed anymore as most advanced needs should be better answered -by an html text track mode.

-

-

fullscreenChange

-

fullscreenChange events have been deprecated as it is part of our Fullscreen -APIs, see the related chapter for more information.

-

The fullscreenChange event was sent when the media element got in or out of -fullscreen mode, with agg boolean as a payload:

-
    -
  • if true, the element entered fullscreen mode
  • -
  • if false, the element exited fullscreen mode
  • -
-

This behavior can easily be recreated through the following code:

-
const mediaElement = player.getVideoElement();
-mediaElement.addEventListener("fullscreenChange", () => {
-  if (isFullscreen()) { // see isFullscreen implementation above
-    // do things
-  } else {
-    // do other things
-  }
-});
-
-

-

imageTrackUpdate

-

imageTrackUpdate events have been deprecated like most API related to BIF -thumbnail parsing. -You can read the related chapter for more information.

-

You can replace this API by using the -parseBifThumbnails tool.

-

-

loadVideo options

-

The following loadVideo options are deprecated.

-

-

defaultAudioTrack

-

The preferredAudioTracks loadVideo -option is now the preferred -(no pun intended) solution to set the default audio track. -This new option allows to handle much more complex use cases and can even be -updated at any time through the setPreferredAudioTracks -method.

-

How to replace that option

-

It is very easy to replace defaultAudioTrack by preferredAudioTracks.

-

For example, if you want to have a default french audio language, you probably -previously did:

-
player.loadVideo({
-  url: myURL,
-  transport: myTransport,
-
-  defaultAudioTrack: { language: "fra", audioDescription: false },
-  // or just `defaultAudioTrack: "fra"`, both are equivalent
-})
-
-

Now you will have to set it through an array either when creating a new -RxPlayer:

-
const player = new RxPlayer({
-  preferredAudioTracks: [{ language: "fra", audioDescription: false }],
-})
-
-

Or at any time, through the setPreferredAudioTracks method:

-
player.setPreferredAudioTracks([{ language: "fra", audioDescription: false }]);
-
-

-

defaultTextTrack

-

defaultTextTrack is replaced by the preferredTextTracks constructor -option for the same reason -than defaultAudioTrack.

-

How to replace that option

-

It is very easy to replace defaultTextTrack by preferredTextTracks.

-

For example, if you want to have a default swedish subtitle language, you -probably previously did:

-
player.loadVideo({
-  url: myURL,
-  transport: myTransport,
-
-  defaultTextTrack: { language: "swe", closedCaption: false },
-  // or just `defaultTextTrack: "swe"`, both are equivalent
-})
-
-

Now you will have to set it through an array either when creating a new -RxPlayer:

-
const player = new RxPlayer({
-  preferredTextTracks: [{ language: "swe", closedCaption: false }],
-})
-
-

Or at any time, through the setPreferredTextTracks method:

-
player.setPreferredTextTracks([{ language: "fra", closedCaption: false }]);
-
-

-

supplementaryTextTracks

-

The supplementaryTextTracks has been deprecated for multiple reasons:

-
    -
  1. -

    The main reason is that the behavior of this API is not defined for -multi-Period DASH contents (nor for MetaPlaylist contents): Should we only -add the subtitles for the first Period or should it be for every Period? -How to define a different subtitles track for the first and for the second -Period?

    -

    Adding an external tool much less coupled to the RxPlayer move those -questions entirely to the application, which should know more than us what -to do in those different cases.

    -
  2. -
  3. -

    Its API was a little arcane because we had to make it compatible with every -possible type of contents (i.e. DASH, Smooth, MetaPlaylist etc.) out there.

    -
  4. -
  5. -

    It did not work for Directfile contents yet. Although we could have made it -compatible with them, we thought that this was the occasion to define a -better API to replace it.

    -
  6. -
  7. -

    Its behavior was more complex that you would initially think of. For -example, we could have to re-download multiple times the same subtitles -file if manual garbage collecting was enabled.

    -
  8. -
  9. -

    All usages of that API that we know of were for Smooth or DASH VoD contents -which sadly just omitted those subtitles tracks in their Manifest. The true -“clean” way to fix the problem in that case is to do it at the source: the -content. -In this case, fixing it on the player-side should only be a temporary -work-around (don’t be scared, we still have an API replacement).

    -
  10. -
-

The new TextTrackRenderer tool which replace it is much more straightforward. -As an external tool which just reads and renders already-downloaded text -subtitles, its API and the extent of what it does should be much more simple.

-

It’s also compatible with any type of contents, even when playing through an -other player.

-

How to replace that option

-

Every supplementaryTextTracks feature can be replaced by the -TextTrackRenderer tool. -Please bear in mind however that they are two completely different APIs, doing -the transition might take some time.

-

The TextTrackRenderer tool is documented here.

-

-

supplementaryImageTracks

-

The supplementaryImageTracks events have been deprecated like most API related -to BIF thumbnail parsing. -You can read the related chapter for more information.

-

You can replace this API by using the -parseBifThumbnails tool.

-

-

hideNativeSubtitle

-

The hideNativeSubtitle option is deprecated and won’t be replaced.

-

This is because it was added at a time when our text track API was much less -advanced. Some applications wanted to handle subtitles themselves and thus hid -the true “native” subtitles to display them themselves in a better way.

-

However, this API seems to not be used anymore. Please open an issue if you need -it.

-

-

RxPlayer constructor options

-

The following RxPlayer constructor options are deprecated.

-

-

throttleWhenHidden

-

throttleWhenHiddenhas been deprecated as video visibility relies only on -page visibility API and document hiddenness.

-

A video should be visible if the Picture-In-Picture mode is activated, even -if the hidden attribute of document is set to true.

-

throttleVideoBitrateWhenHidden relies on both and can be used like this :

-
const rxPlayer = new RxPlayer({
-  // ... RxPlayer options
-  // throttleWhenHidden: true [deprecated]
-  throttleVideoBitrateWhenHidden: true,
-});
-
-

-

Other properties

-

Some very specific properties from various methods are deprecated. -You will find them here.

-

-

Manifest

-

The adaptations property returned by the Manifest object you can obtain -through the getManifest call is deprecated.

-

This corresponds to the adaptations property of the first element in the -periods object from the same Manifest object, so it’s very easy to -replace:

-
const manifest = player.getManifest();
-
-if (manifest && manifest.periods.length) {
-  console.log(manifest.adaptations === manifest.periods[0].adaptations); // true
-}
-
-

-

Smooth

-

Setting a *.wsx, a *.ism or a *.isml URL as an url property in -loadVideo is now deprecated when we’re talking about a Smooth Streaming -content.

-

We recommend to only set a Manifest URL in that property when the transport is -equal to smooth.

-

-

NetworkError

-

The xhr property from a NetworkError is deprecated.

-

This is to prepare the support of low-latency streaming, with -CMAF, -where the fetch API has to be used instead of an XMLHttpRequest.

-

We recommend to not rely on this property anymore. You still should have access -to the status and url properties.

-
\ No newline at end of file diff --git a/doc/generated/pages/api/errors.html b/doc/generated/pages/api/errors.html deleted file mode 100644 index 2c95c6d0c2..0000000000 --- a/doc/generated/pages/api/errors.html +++ /dev/null @@ -1,340 +0,0 @@ -Player errors and warnings - RxPlayer Documentation

-

Player errors and warnings

-

-

-

Overview

-

Various errors can be triggered when playing a media content. Those can happen -when:

-
    -
  • The network is unreachable
  • -
  • The codecs are not supported
  • -
  • We have no mean to decrypt the data
  • -
  • -
-

Some errors can be fatal to content playback in which case they will stop the -player, others act more as warnings and are more along the line of a minor -problem notification.

-

You can know if a fatal error interrupted your playback by:

-
    -
  • -

    adding an event listener to the "error" event (see the player events -documentation). This event listener will take the error -directly in argument.

    -
  • -
  • -

    calling the getError API if the current state is STOPPED. If -different from null, it means that a fatal error happened (see the -documentation for getError).

    -
  • -
-

You can also be warned of any non-fatal error by:

-
    -
  • adding an event listener to the "warning" event (see the player events -documentation). The event listener will take the -non-fatal error directly in argument.
  • -
-

All of those are in essence Error instances with added information.

-

Those supplementary information are described in this page.

-

-

-

Structure of an Error

-

Each of RxPlayer’s error objects have at least those properties:

-
    -
  • -

    type (string): A large category for the error -(e.g. NETWORK_ERROR, ENCRYPTED_MEDIA_ERROR …)

    -
  • -
  • -

    code (string): A set identification “code” for the error encountered

    -
  • -
  • -

    message (string): A displayable, human-readable, summary of the -error.

    -
  • -
  • -

    fatal (boolean): If true, the error was fatal. Meaning that the -playback was interrupted by it

    -
  • -
-

-

-

Types

-

The types are the different strings you can have as the type property of an -error.

-

This chapter provides an exhaustive list of the possible type of error -encountered.

-

-

-

NETWORK_ERROR

-

A NetworkError is any Network-related error (HTTP 404, request timeout…), they -all have a type property equal to "NETWORK_ERROR".

-

codes

-

A NetworkError can only have the following code (code property):

-
    -
  • "PIPELINE_LOAD_ERROR": the Manifest or segment -request failed.
  • -
-

more information

-

A NetworkError provide much more infos than this code.

-

Among its properties, you have:

-
    -
  • -

    url (string): The url the request has been on

    -
  • -
  • -

    status (Number): Shortcut to the status code of the xhr.

    -
  • -
  • -

    errorType (string): Further precision about what went wrong.

    -

    This string can either be:

    -
      -
    • "TIMEOUT": The request timeouted.
    • -
    • "ERROR_EVENT": The XMLHttpRequest has sent an error event
    • -
    • "PARSE_ERROR": No data could have been extracted from this request
    • -
    • "ERROR_HTTP_CODE": The request finished with a status code not in -the 2xx range.
    • -
    -
  • -
  • -

    code (number): The HTTP code of the request at the time of the -error (0 if no request has been done yet)

    -
  • -
  • -

    xhr (XMLHttpRequest|undefined): The xhr associated with the request. -Not defined if the current content has been launched in lowLatencyMode.

    -

    Note: This last property is deprecated. It will disappear in the next major -release, the v4.0.0 (see Deprecated APIs).

    -
  • -
-

-

-

MEDIA_ERROR

-

Error related to the media itself. It can both come from the player itself -(Manifest parsing) or from the browser itself (content -playback).

-

They all have a type property equal to "MEDIA_ERROR".

-

codes

-

A MediaError can have the following codes (code property):

-
    -
  • -

    "BUFFER_APPEND_ERROR": A media segment could not have been added to the -corresponding media buffer. This often happens with malformed segments.

    -
  • -
  • -

    "BUFFER_FULL_ERROR": The needed segment could not have been added -because the corresponding media buffer was full.

    -
  • -
  • -

    "BUFFER_TYPE_UNKNOWN": The type of buffer considered (e.g. “audio” / -“video” / “text”) has no media buffer implementation in your build.

    -
  • -
  • -

    "MANIFEST_INCOMPATIBLE_CODECS_ERROR": An -Adaptation (or track) has none of its -Representations (read quality) in a supported -codec.

    -
  • -
  • -

    "MANIFEST_PARSE_ERROR": Generic error to signal than the -Manifest could not be parsed.

    -
  • -
  • -

    "MANIFEST_UNSUPPORTED_ADAPTATION_TYPE": One of the -Adaptation has a type (e.g. “audio”, “text” or -“video” which is not managed by the RxPlayer).

    -
  • -
  • -

    "MEDIA_ERR_ABORTED": A crucial browser-side fetching operation was -aborted.

    -
  • -
  • -

    "MEDIA_ERR_BLOCKED_AUTOPLAY": The current browser has a policy which -forbids us to autoPlay the content. As a consequence, the rx-player stays -in a "LOADED" state. -This code is always a warning and it never causes playback interruption.

    -
  • -
  • -

    "MEDIA_ERR_PLAY_NOT_ALLOWED": A play call on our API (coming from you) -failed because the current browser does not allow it. -The content should still be in a paused state. -This is in almost any case due a browser policy which prevents a content to -play without any user interaction. -In those cases, we recommend to display a UI element on your page inviting -the final user to manually play the content.

    -
  • -
  • -

    "MEDIA_ERR_NOT_LOADED_METADATA": The current browser falsely announce -having loaded the content’s metadata. -In that case, we cannot switch to the LOADED state directly (we will -be blocked in either a LOADING or a RELOADING state) and you’re -encouraged to call play manually when you want to play the content. -This is a case only encountered in the Samsung browser (as found in -Android) when loading a content in “directfile” mode.

    -
  • -
  • -

    "MEDIA_ERR_DECODE": A pushed segment/media could not be decoded by the -browser. This happens most-of-all with malformed segments.

    -
  • -
  • -

    "MEDIA_ERR_NETWORK": A browser-side request failed.

    -
  • -
  • -

    "MEDIA_ERR_SRC_NOT_SUPPORTED": The media associated to the video element -is not valid.

    -
  • -
  • -

    "MEDIA_ERR_UNKNOWN": Media error impossible to characterize.

    -
  • -
  • -

    "MEDIA_KEYS_NOT_SUPPORTED": The current browser has no MediaKeys -implementation and the content is encrypted.

    -
  • -
  • -

    "MEDIA_SOURCE_NOT_SUPPORTED": No known MediaSource API is supported by -your browser and we need to create one.

    -
  • -
  • -

    "MEDIA_STARTING_TIME_NOT_FOUND": The provided or calculated starting -time was not found in the corresponding media.

    -
  • -
  • -

    "MEDIA_TIME_BEFORE_MANIFEST": The current time in the media is behind -what is currently declared in the Manifest. -This can lead to stalling indefinitely as the player won’t be able to -download new segments arround the current time.

    -
  • -
  • -

    "MEDIA_TIME_AFTER_MANIFEST": The current time in the media is after what -is currently declared in the Manifest. -This can lead to stalling indefinitely as the player won’t be able to -download new segments arround the current time.

    -
  • -
  • -

    "DISCONTINUITY_ENCOUNTERED": A discontinuity (i.e. a hole in the media -buffer) has been encontered and seeked over.

    -

    This is rarely a problem and may be encountered at a very start of a content -when the initial segment’s start is much later than expected.

    -
  • -
  • -

    "NO_PLAYABLE_REPRESENTATION": The currently chosen Adaptation does not -contain any playable Representation. This usually happen when every -Representation has been blacklisted due to encryption limitations.

    -
  • -
  • -

    "MANIFEST_UPDATE_ERROR": This error should never be emitted as it is -handled internally by the RxPlayer. Please open an issue if you encounter -it.

    -

    This error is triggered when an incoherent version of the Manifest was -received during a partial update. The RxPlayer should catch the error and -trigger a full update instead when that happens.

    -
  • -
  • -

    "MEDIA_TIME_NOT_FOUND": This error should never be emitted by the -RxPlayer. Please open an issue if you encounter it.

    -

    It is triggered when a time we initially thought to be in the bounds of the -Manifest actually does not link to any “Period” of the Manifest.

    -
  • -
-

-

-

ENCRYPTED_MEDIA_ERROR

-

Those errors are linked to the Encrypted Media Extensions. They concern various -DRM-related problems.

-

They all have a type property equal to "ENCRYPTED_MEDIA_ERROR".

-

codes

-

An EncryptedMediaError can have the following codes (code property):

-
    -
  • -

    "INCOMPATIBLE_KEYSYSTEMS": None of the provided key systems was -compatible with the current browser.

    -
  • -
  • -

    "INVALID_ENCRYPTED_EVENT": An encountered encrypted event was not -valid.

    -
  • -
  • -

    "INVALID_KEY_SYSTEM": One of the given key system was not accepted by -the RxPlayer.

    -
  • -
  • -

    "KEY_ERROR": The MediaKeySession emitted an error.

    -
  • -
  • -

    "KEY_GENERATE_REQUEST_ERROR": An error happened when calling the -generateRequest API to generate a challenge.

    -
  • -
  • -

    "KEY_LOAD_ERROR": An error was returned by the code fetching the -license.

    -
  • -
  • -

    "KEY_LOAD_TIMEOUT": The request for fetching the license had a duration -of more than 10 seconds.

    -
  • -
  • -

    "KEY_STATUS_CHANGE_ERROR": An error was detected when the -MediaKeySession emitted a keyStatuseschange event (e.g. the key -became "expired").

    -
  • -
  • -

    "KEY_UPDATE_ERROR": An error was detected after a message (like a -license was given to the CDM).

    -
  • -
  • -

    "LICENSE_SERVER_CERTIFICATE_ERROR": The server certificate of a -MediaKeys could not be set.

    -
  • -
  • -

    "MEDIA_IS_ENCRYPTED_ERROR": The media is encrypted and no key system -was given to the RxPlayer’s APIs.

    -
  • -
  • -

    "MULTIPLE_SESSIONS_SAME_INIT_DATA": This error should never be emitted -by the RxPlayer. Please open an issue if you encounter it.

    -

    It is emitted when the RxPlayer try to open multiple MediaKeySession for -the same initialization data (instead of using the exact same -MediaKeySession).

    -
  • -
-

-

-

OTHER_ERROR

-

Those errors are various other errors which does not belong to other types.

-

They all have a type property equal to "OTHER_ERROR".

-

codes

-

An OtherError can have the following codes (code property):

-
    -
  • -

    "PIPELINE_LOAD_ERROR": The Manifest or segment -request failed and the request has been done through a given callback (i.e. -not the RxPlayer’s XMLHttpRequest implementation).

    -
  • -
  • -

    "PIPELINE_PARSE_ERROR": The RxPlayer’s Manifest -or segment parsing logic failed. This is most likely due to a malformed -Manifest or segment.

    -
  • -
  • -

    "INTEGRITY_ERROR": An integrity-checking mechanism in the RxPlayer -detected that there was an error with some loaded data. Such mechanism can -be triggered for example when the checkMediaSegmentIntegrity -transportOptions is set to loadVideo.

    -
  • -
  • -

    "NONE": The error cannot be characterized.

    -
  • -
-
\ No newline at end of file diff --git a/doc/generated/pages/api/exported_types.html b/doc/generated/pages/api/exported_types.html deleted file mode 100644 index b28960c3d1..0000000000 --- a/doc/generated/pages/api/exported_types.html +++ /dev/null @@ -1,277 +0,0 @@ -Exported Types - RxPlayer Documentation

-

Exported Types

-

The RxPlayer being written in TypeScript, it has type definitions attached to -its source code that can be helpful if you develop an application in TypeScript -yourself.

-

-

“Using” types

-

Because we follow the usual way of adding definition files (as d.ts file -alongside our sources), those typings should be auto-exported when importing our -library in your favorite editor (as long as it is linked to a TSServer of some -sort).

-

-

Importing specific types

-

As some APIs can have pretty complicated arguments, you might also want to -import some of our internal type definitions into your code.

-

To simplify this process, we export some type definitions which can be imported -through the following line in your file:

-
import { SOME_TYPE } from "rx-player/types"
-
-

Here are the list of exported types, per category.

-

-

RxPlayer Constructor

-

The type IConstructorOptions corresponds to the interface that the -RxPlayer constructor accepts as an argument.

-

Example:

-
import RxPlayer from "rx-player";
-import { IConstructorOptions } from "rx-player/types";
-
-function generateConstructorOptions() : IConstructorOptions {
-  const videoElement = document.querySelector("video");
-  return {
-    stopAtEnd: false,
-    videoElement,
-  };
-}
-
-const options = generateConstructorOptions();
-const player = new RxPlayer(options);
-
-export default player;
-
-

Two constructor options have also their type definition exported, those are:

-
    -
  • -

    IAudioTrackPreference: which is the type of a single element in the -preferredAudioTracks array.

    -
  • -
  • -

    ITextTrackPreference: which is the type of a single element in the -preferredTextTracks array.

    -
  • -
-

-

loadVideo

-

The ILoadVideoOptions type corresponds to the argument to give to the -RxPlayer’s method loadVideo.

-

Example:

-
// the type(s) wanted
-import { ILoadVideoOptions } from "rx-player/types";
-
-// hypothetical file exporting an RxPlayer instance
-import rxPlayer from "./player";
-
-// hypothetical file exporting a configuration object
-import config from "./config"; // define a global config
-
-function generateLoadVideoOptions(url : string) : ILoadVideoOptions {
-  return {
-    url,
-    transport: "dash",
-    autoPlay: true,
-  };
-}
-
-const loadVideoOpts = generateLoadVideoOptions(config.DEFAULT_URL);
-rxPlayer.loadVideo(loadVideoOpts);
-
-

Speaking of loadVideo, some subparts of ILoadVideoOptions are also -exported:

-
    -
  • -

    ITransportOptions: type for the transportOptions property -optionally given to loadVideo.

    -
  • -
  • -

    IKeySystemOption: type for an element of the keySystems array, -which is an optional property given to loadVideo.

    -

    To clarify, the keySystems property in a loadVideo call is an -optional array of one or multiple IKeySystemOption.

    -
  • -
  • -

    ISupplementaryTextTrackOption: type for an element of the -supplementaryTextTracks array, which is an optional property given to -loadVideo.

    -
  • -
  • -

    ISupplementaryImageTrackOption: type for an element of the -supplementaryImageTracks array, which is an optional property given to -loadVideo.

    -
  • -
  • -

    IDefaultAudioTrackOption: type for the defaultAudioTrack property -optionally given to loadVideo.

    -
  • -
  • -

    IDefaultTextTrackOption: type for the defaultAudioTrack property -optionally given to loadVideo.

    -
  • -
  • -

    INetworkConfigOption: type for the networkConfig property -optionally given to loadVideo.

    -
  • -
  • -

    IStartAtOption: type for the startAt property optionally given to -loadVideo.

    -
  • -
-

-

getAvailableAudioTracks method / availableAudioTracksChange event

-

The return type of the getAvailableAudioTracks method is an array of objects. -Each of this objects corresponds to the IAvailableAudioTrack interface.

-

Example:

-
// the type(s) wanted
-import { IAvailableAudioTrack } from "rx-player/types";
-
-// hypothetical file exporting an RxPlayer instance
-import rxPlayer from "./player";
-
-// hypothetical file exporting a configuration object
-import config from "./config"; // define a global config
-
-function getAvailableAudioTracks() : IAvailableAudioTrack[] {
-  return rxPlayer.getAvailableAudioTracks();
-}
-
-

-

getAvailableTextTracks method / availabletextTracksChange event

-

The return type of the getAvailableTextTracks method is an array of objects. -Each of this objects corresponds to the IAvailableTextTrack interface.

-

Example:

-
// the type(s) wanted
-import { IAvailableTextTrack } from "rx-player/types";
-
-// hypothetical file exporting an RxPlayer instance
-import rxPlayer from "./player";
-
-// hypothetical file exporting a configuration object
-import config from "./config"; // define a global config
-
-function getAvailableTextTracks() : IAvailableTextTrack[] {
-  return rxPlayer.getAvailableTextTracks();
-}
-
-

-

getAvailableVideoTracks method / availableVideoTracksChange event

-

The return type of the getAvailableVideoTracks method is an array of objects. -Each of this objects corresponds to the IAvailableVideoTrack interface.

-

Example:

-
// the type(s) wanted
-import { IAvailableVideoTrack } from "rx-player/types";
-
-// hypothetical file exporting an RxPlayer instance
-import rxPlayer from "./player";
-
-// hypothetical file exporting a configuration object
-import config from "./config"; // define a global config
-
-function getAvailableVideoTracks() : IAvailableVideoTrack[] {
-  return rxPlayer.getAvailableVideoTracks();
-}
-
-

-

getAudioTrack method /audioTrackChange event

-

The IAudioTrack corresponds to both the type returned by the getAudioTrack -method and emitted as the payload of the audioTrackChange event.

-

Example:

-
// the type(s) wanted
-import { IAudioTrack } from "rx-player/types";
-
-// hypothetical file exporting an RxPlayer instance
-import rxPlayer from "./player";
-
-// hypothetical file exporting a configuration object
-import config from "./config"; // define a global config
-
-rxPlayer.addEventListener("audioTrackChange", (track : IAudioTrack) => {
-  console.log("current track:", track);
-});
-
-function getCurrentlyDownloadedAudioTrack() : IAudioTrack {
-  return rxPlayer.getAudioTrack();
-}
-
-

-

getTextTrack method / textTrackChange event

-

The ITextTrack corresponds to both the type returned by the getTextTrack -method and emitted as the payload of the textTrackChange event.

-

Example:

-
// the type(s) wanted
-import { ITextTrack } from "rx-player/types";
-
-// hypothetical file exporting an RxPlayer instance
-import rxPlayer from "./player";
-
-// hypothetical file exporting a configuration object
-import config from "./config"; // define a global config
-
-rxPlayer.addEventListener("textTrackChange", (track : ITextTrack) => {
-  console.log("current track:", track);
-});
-
-function getCurrentlyDownloadedTextTrack() : ITextTrack {
-  return rxPlayer.getTextTrack();
-}
-
-

-

getVideoTrack method / videoTrackChange event

-

The IVideoTrack corresponds to both the type returned by the getVideoTrack -method and emitted as the payload of the videoTrackChange event.

-

Example:

-
// the type(s) wanted
-import { IVideoTrack } from "rx-player/types";
-
-// hypothetical file exporting an RxPlayer instance
-import rxPlayer from "./player";
-
-// hypothetical file exporting a configuration object
-import config from "./config"; // define a global config
-
-rxPlayer.addEventListener("videoTrackChange", (track : IVideoTrack) => {
-  console.log("current track:", track);
-});
-
-function getCurrentlyDownloadedVideoTrack() : IVideoTrack {
-  return rxPlayer.getVideoTrack();
-}
-
-

-

streamEvent / streamEventSkip events

-

The type IStreamEvent corresponds to the payload of either a streamEvent or -a streamEventSkip event.

-

The type IStreamEventData is the type of its data property.

-

Example:

-
// the type(s) wanted
-import { IStreamEvent, IStreamEventData } from "rx-player/types";
-
-// hypothetical file exporting an RxPlayer instance
-import rxPlayer from "./player";
-
-function processEventData(eventData : IStreamEventData) {
-  if (eventData.type === "dash-event-stream") {
-    console.log("DASH EventStream's event received!");
-  }
-}
-
-rxPlayer.addEventListener("streamEvent", (evt : IStreamEvent) {
-  processEventData(evt.data);
-});
-
-
\ No newline at end of file diff --git a/doc/generated/pages/api/images.html b/doc/generated/pages/api/images.html deleted file mode 100644 index 5bd20a8815..0000000000 --- a/doc/generated/pages/api/images.html +++ /dev/null @@ -1,86 +0,0 @@ -Images - RxPlayer Documentation

-

Images

-

-

-

Overview

-

The RxPlayer defines its own image playlist format, the bif format.

-

This format allows to transmit playlist of thumbnails for linear (live) and -non-linear (VOD) contents. The usecase is mostly to allow an improved “seeking” -experience.

-

It is understood and parsed by the player, which offers API to easily integrate -those features in an application.

-

-

-

Format specification

-

This documentation is not yet finished. It will be very soon.

-

-

-

Using bif for DASH and smooth contents

-

This documentation is not yet finished. It will be very soon.

-

-

-

APIs

-

Images can be retreived through two APIs for now:

-
    -
  • -

    getImageTrackData, which returns directly an array of objects describing -the images in the playlist.

    -
  • -
  • -

    the imageTrackUpdate event, which emits each time the image playlist is -updated with the complete playlist as an array of objects in its data -property.

    -
  • -
-

-

-

Structure

-

In both of those cases you receive an array of Objects, each defining a single -image.

-

An image object has the following property:

-
    -
  • -

    data (Uint8Array): the raw data for the image object. You can -display the corresponding image on your page thanks to the browser -window.URL.createObjectURL API.

    -
  • -
  • -

    ts (Number): the position (relatively to the player’s -getPosition API) the image should be displayed at, in milliseconds.

    -
  • -
  • -

    duration (Number): the duration, in s, until a new image can be -considered.

    -
  • -
-

This array should be ordered by position.

-

-

-

Example

-

Here is an example of setting the image corresponding to the current position, -considering a player instance player and an image element with the id -current-image:

-
const position = player.getPosition();
-const imagePlaylist = player.getImageTrackData();
-
-const currentImage = imagePlaylist.find(p => (p.ts / 1000) > position);
-
-if (currentImage) {
-  const blob = new Blob([currentImage], {type: "image/jpeg"});
-  const url = URL.createObjectURL(blob);
-  document.getElementById("current-image").src = url;
-}
-
-
\ No newline at end of file diff --git a/doc/generated/pages/api/index.html b/doc/generated/pages/api/index.html deleted file mode 100644 index 7ee6039500..0000000000 --- a/doc/generated/pages/api/index.html +++ /dev/null @@ -1,2720 +0,0 @@ -RxPlayer API - RxPlayer Documentation

-

RxPlayer API

-

-

-

Overview

-

The RxPlayer has a complete API allowing you to:

-
    -
  • load and stop contents containing video and/or audio media data
  • -
  • control playback (play, pause, seek, etc.) when a content is loaded.
  • -
  • get multiple information on the current content and on the player’s state.
  • -
  • choose a specific audio language, subtitles track video track
  • -
  • force a given bitrate
  • -
  • update the wanted buffer length to reach
  • -
  • and more
  • -
-

The following pages define the entire API.

-

⚠️ Only variables and methods defined here are considered as part of the -API. Any other property or method you might find in any other way are not -considered as part of the API and can thus change without notice.

-

Note: As some terms used here might be too foreign or slightly different than -the one you’re used to, we also wrote a list of terms and definitions used by -the RxPlayer here.

-

-

-

Instantiation

-

Instantiating a new RxPlayer is necessary before being able to load a content. -Doing so is straightforward:

-
import RxPlayer from "rx-player";
-const player = new RxPlayer(options);
-
-

The options are all… optional. They are all defined in the Player Options -page.

-

-

-

Basic methods

-

In this chapter, we will go through the basic methods you will need to use when -playing a content through the RxPlayer.

-

-

-

loadVideo

-

-

syntax: player.loadVideo(options)

-

arguments:

-
    -
  • options (Object): Content you want to load and associated options.
  • -
-

-

Loads the content described in the argument.

-

This is the central method to use when you want to play a new content. -The options possible as arguments are all defined in this -page.

-

Despite its name, this method can also load audio-only content.

-

Example

-
player.loadVideo({
-  url: "http://vm2.dashif.org/livesim-dev/segtimeline_1/testpic_6s/Manifest.mpd",
-  transport: "dash",
-  autoPlay: true,
-});
-
-

-

-

reload

-

-

syntax: player.reload() / player.reload(options)

-

arguments:

-
    -
  • options (Object | undefined): Optional requirements, e.g. at which -position the player should reload.
  • -
-

-

Re-load the last loaded content as fast as possible.

-

This API can be called at any time after a content has been loaded (the LOADED -state has been reached), even if the player has been stopped since and even if -it was due to a fatal error.

-

The user may need to call this API in several cases. For example, it may be used -in case of an error that will not reproduce or inversely when the error is -consistent at a certain playback time (e.g. due to a specific chunk defect).

-

The options argument is an object containing :

-
    -
  • reloadAt (Object | undefined): The object contain directives about -the starting playback position : -
      -
    • relative (string | undefined) : start playback relatively from the -last playback position (last played position before entering into STOPPED or -ENDED state).
    • -
    • position (string|undefined) : absolute position at which we should -start playback
    • -
    -
  • -
-

If no reload position is defined, start playback at the last playback position.

-

Note that despite this method’s name, the player will not go through the -RELOADING state while reloading the content but through the regular LOADING -state - as if loadVideo was called on that same content again.

-

Example

-
player.addEventListener("error", (error) => {
-  if (error.code === "BUFFER_APPEND_ERROR") {
-    // Try to reload after the last playback position, in case of defectuous
-    // media content at current time.
-    player.reload({ reloadAt: { relative: +5 }});
-  } else {
-    // Try to reload at the last playback position
-    player.reload();
-  }
-});
-
-

-

-

getPlayerState

-

-

syntax: const state = player.getPlayerState()

-

return value: string

-

-

Returns the “state” the player is currently in. -Can be either one of those strings:

-
    -
  • -

    "STOPPED": The player is idle. No content is loading nor is loaded.

    -
  • -
  • -

    "LOADING": The player is loading a new content. -Most APIs related to the current content are not yet available while the -content is loading.

    -
  • -
  • -

    "LOADED": The player has loaded the new content, it is now ready to -play. -From this point onward you can use APIs interacting with the current content -such as seekTo or setAudioTrack.

    -
  • -
  • -

    "PLAYING": The player is currently playing the content.

    -
  • -
  • -

    "PAUSED": The player has paused.

    -
  • -
  • -

    "ENDED": The player has reached the end of the current content.

    -
  • -
  • -

    "BUFFERING": the player has reached the end of the buffer and is waiting -for data to be appended.

    -
  • -
  • -

    "SEEKING": The player has reached the end of the buffer because a seek -has been performed, new segments are being loaded.

    -
  • -
  • -

    "RELOADING": The player needs to reload its current (for example, when -switching the current video track). -While this state is active, most API related to the currently playing -content are not available. This state should be treated like the LOADING -state.

    -
  • -
-

As it is a central part of our API and can be difficult concept to understand, -we have a special page of documentation on player states.

-

Example

-
switch (player.getPlayerState()) {
-  case "STOPPED":
-    console.log("No content is/will be playing");
-    break;
-  case "LOADING":
-    console.log("A new content is currently loading");
-    break;
-  case "LOADED":
-    console.log("The new content is loaded and ready to be played");
-    break;
-  case "PLAYING":
-    console.log("The content is currently playing");
-    break;
-  case "PAUSED":
-    console.log("The content is currently paused");
-    break;
-  case "BUFFERING":
-    console.log("The content is buffering new data");
-    break;
-  case "SEEKING":
-    console.log("The content is still seeking, waiting for new data");
-    break;
-  case "ENDED":
-    console.log("The content has reached the end.");
-    break;
-  case "RELOADING":
-    console.log("The content is currently reloading");
-    break;
-  default:
-    console.log("This is impossible (issue material!).")
-    break;
-}
-
-

-

-

addEventListener

-

-

syntax: player.addEventListener(event, callback)

-

arguments:

-
    -
  • -

    event (string): The event name.

    -
  • -
  • -

    callback (Function): The callback for the event. -The same callback may be used again when calling removeEventListener.

    -
  • -
-

-

Add an event listener to trigger a callback as it happens. The callback will -have the event payload as a single argument.

-

The RxPlayer API is heavily event-based. As an example: to know when a content -is loaded, the most straightforward way is to add an event listener for the -"playerStateChange" event. This can be done only through this method.

-

To have the complete list of player events, consult the Player events -page.

-

Example

-
player.addEventListener("error", function(err) {
-  console.log(`The player crashed: ${err.message}`);
-});
-
-

-

-

removeEventListener

-

-

syntax: player.removeEventListener(event) / -player.removeEventListener(event, callback)

-

arguments:

-
    -
  • -

    event (string): The event name.

    -
  • -
  • -

    callback (optional) (Function): The callback given when calling the -corresponding addEventListener API.

    -
  • -
-

-

Remove an event listener. -That is, remove a callback previously registered with addEventListener from -being triggered on the corresponding event. This also free-up the corresponding -ressources.

-

The callback given is optional: if not given, every registered callback to -that event will be removed.

-

Example

-
player.removeEventListener("playerStateChange", listenerCallback);
-
-

-

-

play

-

-

syntax: player.play()

-

return value: Promise.<void>

-

-

Play/resume the current loaded video. Equivalent to a video element’s play -method.

-

You might want to call that method either to start playing (when the content is -in the "LOADED" state and auto-play has not been enabled in the last -loadVideo call) or to resume when the content has been paused.

-

The returned Promise informs you on the result:

-
    -
  • -

    if playback succeeds, the Promise is fulfilled

    -
  • -
  • -

    if playback fails, the Promise is rejected along with an error message -explaining the failure - coming directly from the browser.

    -

    Such failure can for example be due to your browser’s policy, which may -forbid to call play on a media element without any user interaction. -Please note that in that case, you will also receive a -warning event containing a MEDIA_ERROR with the code: -MEDIA_ERR_PLAY_NOT_ALLOWED.

    -
  • -
-

Note: On browsers which do not support Promises natively (such as Internet -Explorer 11), a JavaScript implementation is provided instead. This -implementation has the exact same implementation than ES2015 -Promises.

-

You might want for a content to be loaded before being able to play (the -current state has to be different than LOADING, RELOADING or STOPPED).

-

Example

-
const resumeContent = () => {
-  player.play();
-};
-
-

-

-

pause

-

-

syntax: player.pause()

-

-

Pause the current loaded video. Equivalent to a video element’s pause method.

-

Note that a content can be paused even if its current state is BUFFERING or -SEEKING.

-

You might want for a content to be loaded before being able to pause (the -current state has to be different than LOADING, RELOADING or STOPPED).

-

Example

-
const pauseContent = () => {
-  player.pause();
-};
-
-

-

-

stop

-

-

syntax: player.stop()

-

-

Stop playback of the current content if one.

-

This will totaly un-load the current content. -To re-start playing the same content, you can either call the reload method -or just call loadVideo again.

-

Example

-
const stopVideo = () => {
-  player.stop();
-};
-
-

-

-

getPosition

-

-

syntax: const position = player.getPosition()

-

return value: Number

-

-

Returns the current media element’s playing position, in seconds.

-

For live contents, the returned position will not be re-scaled to correspond to -a live timestamp. If you want that behavior, you can call getWallClockTime -instead.

-

This is the only difference between the two. Generally, you can follow the -following rule:

-
    -
  • -

    if you want to use that current position to use it with the other APIs -(like seekTo, getMinimumPosition, getMaximumPosition -etc.) use getPosition - as this is the real position in the media.

    -
  • -
  • -

    if you want to display the current position to the viewer/listener, use -getWallClockTime instead - as it will be set in the proper scale for -live contents to display the right live time.

    -
  • -
-

Example

-
const pos = player.getPosition();
-console.log(`The video element's current position is: ${pos} second(s)`);
-
-

-

-

getWallClockTime

-

-

syntax: const wallClockTime = player.getWallClockTime()

-

return value: Number

-

-

Returns the current “wall-clock” playing position in seconds.

-

That is:

-
    -
  • -

    for live contents, this is the current position scaled to correspond to a -live timestamp, in seconds.

    -
  • -
  • -

    for non-live contents, returns the position from the absolute beginning time -of the content, also in seconds. In the absolute majority of cases this will -be equal to the value returned by getPosition.

    -
  • -
-

Use this method to display the current position to the user.

-

Example

-
const wallClockTime = player.getWallClockTime();
-const nowInSeconds = Date.now() / 1000;
-const delta = nowInSeconds - wallClockTime;
-
-if (delta < 5) { // (5 seconds of margin)
-  console.log("You're playing live");
-} else {
-  console.log(`You're playing ${delta} seconds behind the live content`);
-}
-
-

-

-

seekTo

-

-

syntax: player.seekTo(position)

-

arguments:

-
    -
  • position (Object|Number): The position you want to seek to.
  • -
-

__

-

Seek in the current content (i.e. change the current position).

-

The argument can be an object with a single Number property, either:

-
    -
  • -

    relative: seek relatively to the current position

    -
  • -
  • -

    position: seek to the given absolute position (equivalent to -player.getVideoElement().currentTime = newPosition)

    -
  • -
  • -

    wallClockTime: seek to the given wallClock position, as returned by -getWallClockTime.

    -
  • -
-

The argument can also just be a Number property, which will have the same -effect than the position property (absolute position).

-

Seeking should only be done when a content is loaded (i.e. the player isn’t -in the STOPPED, LOADING or RELOADING state).

-

The seek operation will start as soon as possible, in almost every cases -directly after this method is called.

-

You will know when the seek is being performed and has been performed -respectively by listening to the seeking and seeked player events (see the -player events page). While seeking, the RxPlayer might -also switch to the SEEKING state.

-

Examples

-
// seeking to 54 seconds from the start of the content
-player.seekTo({ position: 54 });
-
-// equivalent to just:
-player.seekTo(54);
-
-// seeking 5 seconds after the current position
-player.seekTo({ relative: 5 });
-
-// seeking 5 seconds before the current position
-player.seekTo({ relative: -5 });
-
-// seeking to live content
-player.seekTo({ wallClockTime: Date.now() / 1000 });
-
-

-

-

getMinimumPosition

-

-

syntax: const minimumPosition = player.getMinimumPosition()

-

return value: Number|null

-

-

Returns the minimum seekable player position. -Returns null if no content is loaded.

-

This is useful for live contents, where the earliest time at which it is -possible to seek usually evolves over time. -This method allows to know the earliest possible time a seek can be performed -at any point in time.

-

As the given position is the absolute minimum position, you might add a security -margin (like a few seconds) when seeking to this position in a live content. -Not doing so could led to the player being behind the minimum position after -some time (e.g. because of buffering or decoding issues), and thus unable to -continue playing.

-

You will be alerted if the player’s position fell behind the minimum possible -position by receiving a warning event (see the player events -page) with an error having a MEDIA_TIME_BEFORE_MANIFEST -code property (see the player errors page). -Note that you can also have those warnings without any seek operation, e.g. due -to buffering for too long.

-

For VoD contents, as the minimum position normally doesn’t change, seeking at -the minimum position should not cause any issue.

-

Example

-
// Seeking close to the minimum position (with a 5 seconds security margin)
-player.seekTo({ position: player.getMinimumPosition() + 5 });
-
-

-

-

getMaximumPosition

-

-

syntax: const maximumPosition = player.getMaximumPosition()

-

return value: Number|null

-

-

Returns the maximum seekable player position. -Returns null if no content is loaded.

-

This is useful for live contents, where this position might be updated -continously as new content is generated. -This method allows thus to seek directly at the live edge of the content.

-

Please bear in mind that seeking exactly at the maximum position is rarely a -good idea:

-
    -
  • for VoD contents, the playback will end
  • -
  • for live contents, the player will then need to wait until it can build -enough buffer.
  • -
-

As such, we advise to remove a few seconds from that position when seeking.

-

Example

-
// seeking 5 seconds before the end (or the live edge for live contents)
-player.seekTo({
-  position: player.getMaximumPosition() - 5
-});
-
-

-

-

getVideoDuration

-

-

syntax: const duration = player.getVideoDuration()

-

return value: Number

-

-

Returns the duration of the current content as taken from the media element.

-

⚠️ This duration is in fact the maximum position possible for the -content. As such, for contents not starting at 0, this value will not be equal -to the difference between the maximum and minimum possible position, as would -normally be expected from a property named “duration”.

-

Example

-
const pos = player.getPosition();
-const dur = player.getVideoDuration();
-
-console.log(`current position: ${pos} / ${dur}`);
-
-

-

-

getError

-

-

syntax: const currentError = player.getError()

-

return value: Error|null

-

-

Returns the current “fatal error” if one happenned for the last loaded content. -Returns null otherwise.

-

A “fatal error” is an error which led the current loading/loaded content to -completely stop. -Such errors are usually also sent through the "error" event when they happen.

-

See the Player Error documentation for more information.

-

Example

-
const error = player.getError();
-
-if (!error) {
-  console.log("The player did not crash");
-} else if (error.code === "PIPELINE_LOAD_ERROR") {
-  console.error("The player crashed due to a failing request");
-} else {
-  console.error(`The player crashed: ${error.code}`);
-}
-
-

-

-

getVideoElement

-

-

syntax: const elt = player.getVideoElement()

-

return value: HTMLMediaElement

-

-

Returns the media element used by the RxPlayer.

-

You’re not encouraged to use its APIs as they can enter in conflict with the -RxPlayer’s API.

-

Despite its name, this method can also return an audio element if the RxPlayer -was instantiated with one.

-

Example

-
const videoElement = player.getVideoElement();
-videoElement.className = "my-video-element";
-
-

-

-

dispose

-

-

syntax: player.dispose()

-

-

Free the ressources used by the player.

-

You can call this method if you know you won’t need the RxPlayer anymore.

-

⚠️ The player won’t work correctly after calling this method.

-

-

-

Speed control

-

The following methods allows to update the current speed of playback (also -called the “playback rate”).

-

-

-

setPlaybackRate

-

-

syntax: player.setPlaybackRate(speed)

-

arguments:

-
    -
  • speed (Number): The speed / playback rate you want to set.
  • -
-

-

Updates the current playback rate, i.e. the speed at which contents are played.

-

As its name hints at, the value indicates the rate at which contents play:

-
    -
  • -

    Setting it to 2 allows to play at a speed multiplied by 2 relatively to -regular playback.

    -
  • -
  • -

    Setting that value to 1 reset the playback rate to its “normal” rythm.

    -
  • -
  • -

    Setting it to 0.5 allows to play at half the speed relatively to regular -playback.

    -
  • -
  • -

    etc.

    -
  • -
-

This method can be called at any time, even when no content is loaded and is -persisted from content to content.

-

You can set it to 1 to reset its value to the “regular” default.

-

Example

-
// plays three times faster than normal
-player.setPlaybackRate(3);
-
-

-

-

getPlaybackRate

-

-

syntax: const rate = player.getPlaybackRate()

-

return value: Number

-

-

Returns the current playback rate. 1 for normal playback, 2 when -playing at double the speed, etc.

-

Example

-
const currentPlaybackRate = player.getPlaybackRate();
-console.log(`Playing at a x${currentPlaybackRate}} speed`);
-
-

-

-

Volume control

-

Those methods allows to have control over the current audio volume of playing -contents.

-

-

-

setVolume

-

-

syntax: player.setVolume(volume)

-

arguments:

-
    -
  • volume (Number): Volume from 0 to 1.
  • -
-

-

Set the current volume, from 0 (no sound) to 1 (the maximum sound level).

-

Note that the volume set here is persisted even when loading another content. -As such, this method can also be called when no content is currently playing.

-

Example

-
// set the full volume
-player.setVolume(1);
-
-

-

-

getVolume

-

-

syntax: const volume = player.getVolume()

-

return value: Number

-

-

Current volume of the player, from 0 (no sound) to 1 (maximum sound). -0 if muted through the mute API.

-

As the volume is not dependent on a single content (it is persistent), this -method can also be called when no content is playing.

-

Example

-
const volume = player.getVolume();
-
-if (volume === 1) {
-  console.log("You're playing at maximum volume");
-} else if (volume === 0) {
-  console.log("You're playing at no volume");
-} else if (volume > 0.5) {
-  console.log("You're playing at a high volume");
-} else {
-  console.log("You're playing at a low volume");
-}
-
-

-

-

mute

-

-

syntax: player.mute()

-

-

Mute the volume.

-

Basically set the volume to 0 while keeping in memory the previous volume to -reset it at the next unMute call.

-

As the volume is not dependent on a single content (it is persistent), this -method can also be called when no content is playing.

-

Example

-
// mute the current volume
-player.mute();
-
-

-

-

unMute

-

-

syntax: player.unMute()

-

-

When muted, restore the volume to the one previous to the last mute call.

-

When the volume is already superior to 0, this call won’t do anything.

-

As the volume is not dependent on a single content (it is persistent), this -method can also be called when no content is playing.

-

Example

-
// mute the current volume
-player.mute();
-
-// unmute and restore the previous volume
-player.unMute();
-
-

-

-

isMute

-

-

syntax: const isMute = player.isMute()

-

return value: Boolean

-

-

Returns true if the volume is set to 0.

-

Example

-
if (player.isMute()) {
-  console.log("The content plays with no sound.");
-}
-
-

-

-

Track selection

-

The following methods allows to choose the right video audio or text track and -to obtain information about the currently playing tracks.

-

-

-

getAudioTrack

-

-

syntax: const audioTrack = player.getAudioTrack()

-

return value: Object|null|undefined

-

-

Get information about the audio track currently set. -null if no audio track is enabled right now.

-

If an audio track is set and information about it is known, this method will -return an object with the following properties:

-
    -
  • -

    id (Number|string): The id used to identify this track. No other -audio track for the same Period will have the -same id.

    -

    This can be useful when setting the track through the setAudioTrack -method.

    -
  • -
  • -

    language (string): The language the audio track is in, as set in the -Manifest.

    -
  • -
  • -

    normalized (string): An attempt to translate the language -property into an ISO 639-3 language code (for now only support translations -from ISO 639-1 and ISO 639-3 language codes). If the translation attempt -fails (no corresponding ISO 639-3 language code is found), it will equal the -value of language

    -
  • -
  • -

    audioDescription (Boolean): Whether the track is an audio -description of what is happening at the screen.

    -
  • -
  • -

    dub (Boolean|undefined): If set to true, this audio track is a -“dub”, meaning it was recorded in another language than the original. -If set to false, we know that this audio track is in an original language. -This property is undefined if we do not known whether it is in an original -language.

    -
  • -
  • -

    representations (Array.<Object>): -Representations of this video track, with -attributes:

    -
      -
    • -

      id (string): The id used to identify this Representation. -No other Representation from this track will have the same id.

      -
    • -
    • -

      bitrate (Number): The bitrate of this Representation, in bits per -seconds.

      -
    • -
    • -

      codec (string|undefined): The audio codec the Representation is -in, as announced in the corresponding Manifest.

      -
    • -
    -
  • -
-

undefined if no audio content has been loaded yet or if its information is -unknown.

-

-

Note for multi-Period contents:

-

This method will only return the chosen audio track for the -Period that is currently playing.

-

__

-

In DirectFile mode -(see loadVideo options), if there is -no audio tracks API in the browser, this method will return undefined.

-

-

-

getTextTrack

-

-

syntax: const textTrack = player.getTextTrack()

-

return value: Object|null|undefined

-

-

Get information about the text track currently set. -null if no audio track is enabled right now.

-

If a text track is set and information about it is known, this method will -return an object with the following properties:

-
    -
  • -

    id (Number|string): The id used to identify this track. No other -text track for the same Period will have the same -id.

    -

    This can be useful when setting the track through the setTextTrack method.

    -
  • -
  • -

    language (string): The language the text track is in, as set in the -Manifest.

    -
  • -
  • -

    normalized (string): An attempt to translate the language -property into an ISO 639-3 language code (for now only support translations -from ISO 639-1 and ISO 639-3 language codes). If the translation attempt -fails (no corresponding ISO 639-3 language code is found), it will equal the -value of language

    -
  • -
  • -

    closedCaption (Boolean): Whether the track is specially adapted for -the hard of hearing or not.

    -
  • -
-

undefined if no text content has been loaded yet or if its information is -unknown.

-

-

Note for multi-Period contents:

-

This method will only return the chosen text track for the -Period that is currently playing.

-

__

-

In DirectFile mode -(see loadVideo options), if there is -no text tracks API in the browser, this method will return undefined.

-

-

-

getVideoTrack

-

-

syntax: const videoTrack = player.getVideoTrack()

-

return value: Object|null|undefined

-

-

Get information about the video track currently set. -null if no video track is enabled right now.

-

If a video track is set and information about it is known, this method will -return an object with the following properties:

-
    -
  • -

    id (Number|string): The id used to identify this track. No other -video track for the same Period will have the same -id.

    -

    This can be useful when setting the track through the setVideoTrack -method.

    -
  • -
  • -

    representations (Array.<Object>): -Representations of this video track, with -attributes:

    -
      -
    • -

      id (string): The id used to identify this Representation. -No other Representation from this track will have the same id.

      -
    • -
    • -

      bitrate (Number): The bitrate of this Representation, in bits per -seconds.

      -
    • -
    • -

      width (Number|undefined): The width of video, in pixels.

      -
    • -
    • -

      height (Number|undefined): The height of video, in pixels.

      -
    • -
    • -

      codec (string|undefined): The video codec the Representation is -in, as announced in the corresponding Manifest.

      -
    • -
    • -

      frameRate (string|undefined): The video frame rate.

      -
    • -
    -
  • -
  • -

    signInterpreted (Boolean|undefined): If set to true, the track is -known to contain an interpretation in sign language. -If set to false, the track is known to not contain that type of content. -If not set or set to undefined we don’t know whether that video track -contains an interpretation in sign language.

    -
  • -
-

undefined if no video content has been loaded yet or if its information is -unknown.

-

-

Note for multi-Period contents:

-

This method will only return the chosen video track for the -Period that is currently playing.

-

-

In DirectFile mode -(see loadVideo options), if there is -no video tracks API in the browser, this method will return undefined.

-

-

-

getAvailableAudioTracks

-

-

syntax: const audioTracks = player.getAvailableAudioTracks()

-

return value: Array.<Object>

-

-

Returns the list of available audio tracks for the current content.

-

Each of the objects in the returned array have the following properties:

-
    -
  • -

    active (Boolean): Whether the track is the one currently active or -not. Only maximum one audio track can be active at a time.

    -
  • -
  • -

    id (string): The id used to identify the track. Use it for -setting the track via setAudioTrack.

    -
  • -
  • -

    language (string): The language the audio track is in, as set in -the Manifest.

    -
  • -
  • -

    normalized (string): An attempt to translate the language -property into an ISO 639-3 language code (for now only support translations -from ISO 639-1 and ISO 639-2 language codes). If the translation attempt -fails (no corresponding ISO 639-3 language code is found), it will equal the -value of language

    -
  • -
  • -

    audioDescription (Boolean): Whether the track is an audio -description of what is happening at the screen.

    -
  • -
  • -

    dub (Boolean|undefined): If set to true, this audio track is a -“dub”, meaning it was recorded in another language than the original. -If set to false, we know that this audio track is in an original language. -This property is undefined if we do not known whether it is in an original -language.

    -
  • -
  • -

    representations (Array.<Object>): -Representations of this video track, with -attributes:

    -
      -
    • -

      id (string): The id used to identify this Representation.

      -
    • -
    • -

      bitrate (Number): The bitrate of this Representation, in bits per -seconds.

      -
    • -
    • -

      codec (string|undefined): The audio codec the Representation is -in, as announced in the corresponding Manifest.

      -
    • -
    -
  • -
-

-

Note for multi-Period contents:

-

This method will only return the available tracks of the -Period that is currently playing.

-

-

In DirectFile mode (see loadVideo -options), if there are no supported -tracks in the file or no track management API this method will return an empty -Array.

-

-

-

getAvailableTextTracks

-

-

syntax: const textTracks = player.getAvailableTextTracks()

-

return value: Array.<Object>

-

-

Returns the list of available text tracks (subtitles) for the current content.

-

Each of the objects in the returned array have the following properties:

-
    -
  • -

    id (string): The id used to identify the track. Use it for -setting the track via setTextTrack.

    -
  • -
  • -

    language (string): The language the text track is in, as set in the -Manifest.

    -
  • -
  • -

    normalized (string): An attempt to translate the language -property into an ISO 639-3 language code (for now only support translations -from ISO 639-1 and ISO 639-2 language codes). If the translation attempt -fails (no corresponding ISO 639-3 language code is found), it will equal the -value of language

    -
  • -
  • -

    closedCaption (Boolean): Whether the track is specially adapted for -the hard of hearing or not.

    -
  • -
  • -

    active (Boolean): Whether the track is the one currently active or -not.

    -
  • -
-

-

Note for multi-Period contents:

-

This method will only return the available tracks of the -Period that is currently playing.

-

-

In DirectFile mode (see loadVideo -options), if there are no supported -tracks in the file or no track management API this method will return an empty -Array.

-

-

-

getAvailableVideoTracks

-

-

syntax: const videoTracks = player.getAvailableVideoTracks()

-

return value: Array.<Object>

-

-

Returns the list of available video tracks for the current content.

-

Each of the objects in the returned array have the following properties:

-
    -
  • -

    id (string): The id used to identify the track. Use it for -setting the track via setVideoTrack.

    -
  • -
  • -

    active (Boolean): Whether this track is the one currently -active or not.

    -
  • -
  • -

    representations (Array.<Object>): -Representations of this video track, with -attributes:

    -
      -
    • -

      id (string): The id used to identify this Representation.

      -
    • -
    • -

      bitrate (Number): The bitrate of this Representation, in bits per -seconds.

      -
    • -
    • -

      width (Number|undefined): The width of video, in pixels.

      -
    • -
    • -

      height (Number|undefined): The height of video, in pixels.

      -
    • -
    • -

      codec (string|undefined): The video codec the Representation is -in, as announced in the corresponding Manifest.

      -
    • -
    • -

      frameRate (string|undefined): The video framerate.

      -
    • -
    -
  • -
  • -

    signInterpreted (Boolean|undefined): If set to true, the track is -known to contain an interpretation in sign language. -If set to false, the track is known to not contain that type of content. -If not set or set to undefined we don’t know whether that video track -contains an interpretation in sign language.

    -
  • -
-

-

Note for multi-Period contents:

-

This method will only return the available tracks of the -Period that is currently playing.

-

-

In DirectFile mode (see loadVideo -options), if there are no supported -tracks in the file or no track management API this method will return an empty -Array.

-

-

-

setAudioTrack

-

-

syntax: player.setAudioTrack(audioTrackId)

-

arguments:

-
    -
  • audioTrackId (string|Number): The id of the track you want to set
  • -
-

-

Change the current audio track.

-

The argument to this method is the wanted track’s id property. This id can -for example be obtained on the corresponding track object returned by the -getAvailableAudioTracks method.

-

-

Note for multi-Period contents:

-

This method will only have an effect on the Period that is -currently playing. -If you want to update the track for other Periods as well, you might want to -either:

-
    -
  • update the current audio track once a "periodChange" event has been -received.
  • -
  • update first the preferred audio tracks through the -setPreferredAudioTracks method.
  • -
-

-

⚠️ If used on Safari, in DirectFile mode, the track change may change -the track on other track type (e.g. changing video track may change subtitle -track too). -This has two potential reasons :

-
    -
  • The HLS defines variants, groups of tracks that may be read together
  • -
  • Safari may decide to enable a track for accessibility or user language -convenience (e.g. Safari may switch subtitle to your OS language if you pick -another audio language) -You can know if another track has changed by listening to the corresponding -events that the tracks have changed.
  • -
-

-

-

setTextTrack

-

-

syntax: player.setTextTrack(textTrackId)

-

arguments:

-
    -
  • textTrackId (string|Number): The id of the track you want to set
  • -
-

-

Change the current text (subtitles) track.

-

The argument to this method is the wanted track’s id property. This id can -for example be obtained on the corresponding track object returned by the -getAvailableTextTracks method.

-

-

Note for multi-Period contents:

-

This method will only have an effect on the Period that is -currently playing. -If you want to update the track for other Periods as well, you might want to -either:

-
    -
  • update the current text track once a "periodChange" event has been -received.
  • -
  • update first the preferred text tracks through the -setPreferredTextTracks method.
  • -
-

-

⚠️ If used on Safari, in DirectFile mode, the track change may change -the track on other track type (e.g. changing video track may change subtitle -track too). -This has two potential reasons :

-
    -
  • The HLS defines variants, groups of tracks that may be read together
  • -
  • Safari may decide to enable a track for accessibility or user language -convenience (e.g. Safari may switch subtitle to your OS language if you pick -another audio language) -You can know if another track has changed by listening to the corresponding -events that the tracks have changed.
  • -
-

-

-

disableTextTrack

-

-

syntax: player.disableTextTrack()

-

-

Disable the current text track, if one.

-

After calling that method, no subtitles track will be displayed until -setTextTrack is called.

-

-

Note for multi-Period contents:

-

This method will only have an effect on the Period that is -currently playing.

-

If you want to disable the text track for other Periods as well, you might want -to call setPreferredVideoTracks instead. With -this method, you can globally apply a null text track preference - which means -that you would prefer having no text track - by setting its second argument to -true.

-

More information can be found on that API’s documentation.

-

-

-

setVideoTrack

-

-

syntax: player.setVideoTrack(videoTrackId)

-

arguments:

-
    -
  • videoTrackId (string|Number): The id of the track you want to set
  • -
-

-

Change the current video track.

-

The argument to this method is the wanted track’s id property. This id can -for example be obtained on the corresponding track object returned by the -getAvailableVideoTracks method.

-

Setting a new video track when a previous one was already playing can lead the -rx-player to “reload” this content.

-

During this period of time:

-
    -
  • the player will have the state RELOADING
  • -
  • Multiple APIs linked to the current content might not work. -Most notably: -
      -
    • play will not work
    • -
    • pause will not work
    • -
    • seekTo will not work
    • -
    • getPosition will return 0
    • -
    • getWallClockTime will return 0
    • -
    • getVideoDuration will return NaN
    • -
    • getAvailableAudioTracks will return an empty array
    • -
    • getAvailableTextTracks will return an empty array
    • -
    • getAvailableVideoTracks will return an empty array
    • -
    • getTextTrack will return null
    • -
    • getAudioTrack will return null
    • -
    • setAudioTrack will throw
    • -
    • setTextTrack will throw
    • -
    -
  • -
-

-

Note for multi-Period contents:

-

This method will only have an effect on the Period that is -currently playing. -If you want to update the track for other Periods as well, you might want to -either:

-
    -
  • update the current video track once a "periodChange" event has been -received.
  • -
  • update first the preferred video tracks through the -setPreferredVideoTracks method.
  • -
-

-

⚠️ This option will have no effect in DirectFile mode -(see loadVideo options) when either :

-
    -
  • No video track API is supported on the current browser
  • -
  • The media file tracks are not supported on the browser
  • -
-

-

-

disableVideoTrack

-

-

syntax: player.disableVideoTrack()

-

-

Disable the current video track, if one.

-

Might enter in RELOADING state for a short period after calling this API.

-

-

Note for multi-Period contents:

-

This method will only have an effect on the Period that is -currently playing.

-

If you want to disable the video track for other Periods as well, you might want -to call setPreferredVideoTracks instead. With -this method, you can globally apply a null video track preference - which means -that you would prefer having no video track - by setting its second argument to -true.

-

More information can be found on that API’s documentation.

-

-

⚠️ This option may have no effect in DirectFile mode -(see loadVideo options). -The directfile mode is a special case here because when in it, the RxPlayer -depends for track selection on the corresponding HTML -standard as implemented by -the different browsers. -Though this standard says nothing about not being able to disable the video -track (or to stay more in line with their terms: to not select any video track), -no browser implementation actually seem to be able to do it, even when the -corresponding browser APIs show that no video track is currently selected. -This might be a bug on their parts.

-

Due to this fact, we do not recommend using this API in directfile mode for -now. You might even receive a reassuring videoTrackChange event (with a null -payload) while the video track is still actually active.

-

-

-

setPreferredAudioTracks

-

-

syntax: player.setPreferredAudioTracks(preferences) / -player.setPreferredAudioTracks(preferences, shouldApply)

-

arguments:

-
    -
  • -

    preferences (Array.<Object>): wanted audio track configurations by -order of preference.

    -
  • -
  • -

    shouldApply (Boolean | undefined): Whether this should be applied to the -content being played.

    -
  • -
-

-

Allows the RxPlayer to choose an initial audio track, based on language -preferences, codec preferences or both.

-

This method can be called at any time - even when no content is loaded, and will -apply to every future loaded content in the current RxPlayer instance.

-

-

The first argument should be set as an array of objects, each object describing -constraints an audio track should respect.

-

Here is all the possible constraints you can set in any one of those objects -(note that all properties are optional here, only those set will have an effect -on which tracks will be filtered):

-
{
-  language: "fra", // {string|undefined} The language the track should be in
-                   // (in preference as an ISO 639-1, ISO 639-2 or ISO 639-3
-                   // language code).
-                   // If not set or set to `undefined`, the RxPlayer won't
-                   // filter based on the language of the track.
-
-  audioDescription: false // {Boolean|undefined} Whether the audio track should
-                          // be an audio description for the visually impaired
-                          // or not.
-                          // If not set or set to `undefined`, the RxPlayer
-                          // won't filter based on that status.
-
-  codec: { // {Object|undefined} Constraints about the codec wanted.
-           // if not set or set to `undefined` we won't filter based on codecs.
-
-    test: /ec-3/, // {RegExp} RegExp validating the type of codec you want.
-
-    all: true, // {Boolean} Whether all the profiles (i.e. Representation) in a
-               // track should be checked against the RegExp given in `test`.
-               // If `true`, we will only choose a track if EVERY profiles for
-               // it have a codec information that is validated by that RegExp.
-               // If `false`, we will choose a track if we know that at least
-               // A SINGLE profile from it has codec information validated by
-               // that RegExp.
-  }
-}
-
-

When encountering a new content or a new choice of tracks in a given content, -the RxPlayer will look at each object in that array. -If the first object in it defines constaints that cannot be respected under the -currently available audio tracks, the RxPlayer will consider the second object -in the array and so on.

-

As such, this array should be sorted by order of preference: from the most -wanted constraints to the least.

-

-

The second argument to that function is an optional boolean which - when set -to true - will apply that preference to the content and Period that have -already been playing.

-

By setting it to true, you might thus change the currently-active track and -the active track of Periods (in DASH) or sub-contents (in MetaPlaylist) that -have already been played in the current content.

-

By setting it to false, undefined or not setting it, those preferences will -only be applied each time a new Period or sub-content is loaded by the -RxPlayer.

-

Simply put, if you don’t set the second argument to true those preferences -won’t be applied to:

-
    -
  • -

    the content being currently played. -Here, the current audio preference will stay in place.

    -
  • -
  • -

    the Periods or sub-contents which have already been loaded for the current -content. -Those will keep the audio track chosen at the last time they were loaded.

    -
  • -
-

If you want the preferences to also be applied to those, you can set the second -argument to true.

-

Examples

-

Let’s imagine that you prefer to have french or italian over all other audio -languages. If not found, you want to fallback to english:

-
player.setPreferredAudioTracks([
-  { language: "fra", audioDescription: false },
-  { language: "ita", audioDescription: false },
-  { language: "eng", audioDescription: false }
-])
-
-

Now let’s imagine that you want to have in priority a track that contain at -least one profile in Dolby Digital Plus (ec-3 codec) without caring about the -language:

-
player.setPreferredAudioTracks([ { codec: { all: false, test: /ec-3/ } ]);
-
-

At last, let’s combine both examples by preferring french over itialian, italian -over english while preferring it to be in Dolby Digital Plus:

-

-player.setPreferredAudioTracks([
-  {
-    language: "fra",
-    audioDescription: false,
-    codec: { all: false, test: /ec-3/ }
-  },
-
-  // We still prefer non-DD+ french over DD+ italian
-  { language: "fra", audioDescription: false },
-
-  {
-    language: "ita",
-    audioDescription: false,
-    codec: { all: false, test: /ec-3/ }
-  },
-  { language: "ita", audioDescription: false },
-
-  {
-    language: "eng",
-    audioDescription: false,
-    codec: { all: false, test: /ec-3/ }
-  },
-  { language: "eng", audioDescription: false }
-]);
-
-

-

⚠️ This option will have no effect in DirectFile mode -(see loadVideo options) when either :

-
    -
  • No audio track API is supported on the current browser
  • -
  • The media file tracks are not supported on the browser
  • -
-

-

-

getPreferredAudioTracks

-

-

syntax: const preferences = player.getPreferredAudioTracks()

-

return value: Array.<Object>

-

-

Returns the current list of preferred audio tracks - by order of preference.

-

This returns the data in the same format that it was given to either the -preferredAudioTracks constructor option or the last setPreferredAudioTracks -if it was called.

-

It will return an empty Array if none of those two APIs were used until now.

-

-

-

setPreferredTextTracks

-

-

syntax: player.setPreferredTextTracks(preferences) / -player.setPreferredTextTracks(preferences, shouldApply)

-

arguments:

-
    -
  • -

    preferences (Array.<Object>): wanted text track configurations by -order of preference.

    -
  • -
  • -

    shouldApply (Boolean | undefined): Whether this should be applied to the -content being played.

    -
  • -
-

-

Allows the RxPlayer to choose an initial text track, based on language -and accessibility preferences.

-

This method can be called at any time - even when no content is loaded, and will -apply to every future loaded content in the current RxPlayer instance.

-

-

The first argument should be set as an array of objects, each object describing -constraints a text track should respect.

-

Here is all the properties that should be set in a single object of that array.

-
{
-  language: "fra", // {string} The wanted language
-                   // (ISO 639-1, ISO 639-2 or ISO 639-3 language code)
-  closedCaption: false // {Boolean} Whether the text track should be a closed
-                       // caption for the hard of hearing
-}
-
-

When encountering a new content or a new choice of tracks in a given content, -the RxPlayer will look at each object in that array. -If the first object in it defines constaints that cannot be respected under the -currently available text tracks, the RxPlayer will consider the second object -in the array and so on.

-

As such, this array should be sorted by order of preference: from the most -wanted constraints to the least.

-

You can set null instead of an object to mean that you want no subtitles. -When reaching that point of the array, the RxPlayer will just disable the -current text track.

-

As such, if you never want any subtitles, you can just set this argument to -[null] (an array with only the value null at the first position).

-

-

The second argument to that function is an optional boolean which - when set -to true - will apply that preference to the content and Period that have -already been playing.

-

By setting it to true, you might thus change the currently-active text track -and the active text track of Periods (in DASH) or sub-contents (in -MetaPlaylist) that have already been played in the current content.

-

By setting it to false, undefined or not setting it, those preferences will -only be applied each time a new Period or sub-content is loaded by the -RxPlayer.

-

Simply put, if you don’t set the second argument to true those preferences -won’t be applied to:

-
    -
  • -

    the content being currently played. -Here, the current text track preference will stay in place.

    -
  • -
  • -

    the Periods or sub-contents which have already been loaded for the current -content. -Those will keep the text track chosen at the last time they were loaded.

    -
  • -
-

If you want the preferences to also be applied to those, you can set the second -argument to true.

-

Example

-

Let’s imagine that you prefer to have french or italian subtitles.If not found, -you want no subtitles at all.

-

You will thus call setPreferredTextTracks that way.

-
player.setPreferredTextTracks([
-  { language: "fra", closedCaption: false },
-  { language: "ita", closedCaption: false },
-  null
-]);
-
-

This won’t apply on the currently loaded content(s), if you also want that, you -can add true as a second argument:

-
player.setPreferredTextTracks([
-  { language: "fra", closedCaption: false },
-  { language: "ita", closedCaption: false },
-  null
-], true);
-
-

-

⚠️ This option will have no effect in DirectFile mode -(see loadVideo options) when either :

-
    -
  • No text track API is supported on the current browser
  • -
  • The media file tracks are not supported on the browser
  • -
-

-

-

getPreferredTextTracks

-

-

syntax: const preferences = player.getPreferredTextTracks()

-

return value: Array.<Object|null>

-

-

Returns the current list of preferred text tracks - by order of preference.

-

This returns the data in the same format that it was given to either the -preferredTextTracks constructor option or the last setPreferredTextTracks if -it was called:

-
{
-  language: "fra", // {string} The wanted language
-                   // (ISO 639-1, ISO 639-2 or ISO 639-3 language code)
-  closedCaption: false // {Boolean} Whether the text track should be a closed
-                       // caption for the hard of hearing
-}
-
-

-

-

setPreferredVideoTracks

-

-

syntax: player.setPreferredVideoTracks(preferences) / -player.setPreferredVideoTracks(preferences, shouldApply)

-

arguments:

-
    -
  • -

    preferences (Array.<Object>): wanted video track configurations by -order of preference.

    -
  • -
  • -

    shouldApply (Boolean | undefined): Whether this should be applied to the -content being played.

    -
  • -
-

-

Allows the RxPlayer to choose an initial video track, based on codec -preferences, accessibility preferences or both.

-

This method can be called at any time - even when no content is loaded, and will -apply to every future loaded content in the current RxPlayer instance.

-

-

The first argument should be set as an array of objects, each object describing -constraints a video track should respect.

-

Here is all the possible constraints you can set in any one of those objects -(note that all properties are optional here, only those set will have an effect -on which tracks will be filtered):

-
{
-  codec: { // {Object|undefined} Constraints about the codec wanted.
-           // if not set or set to `undefined` we won't filter based on codecs.
-
-    test: /hvc/, // {RegExp} RegExp validating the type of codec you want.
-
-    all: true, // {Boolean} Whether all the profiles (i.e. Representation) in a
-               // track should be checked against the RegExp given in `test`.
-               // If `true`, we will only choose a track if EVERY profiles for
-               // it have a codec information that is validated by that RegExp.
-               // If `false`, we will choose a track if we know that at least
-               // A SINGLE profile from it has codec information validated by
-               // that RegExp.
-  }
-  signInterpreted: true, // {Boolean|undefined} If set to `true`, only tracks
-                         // which are known to contains a sign language
-                         // interpretation will be considered.
-                         // If set to `false`, only tracks which are known
-                         // to not contain it will be considered.
-                         // if not set or set to `undefined` we won't filter
-                         // based on that status.
-}
-
-

If the first defined object in that array - defining the first set of -constraints - cannot be respected under the currently available video tracks, -the RxPlayer will check with the second object instead and so on.

-

As such, this array should be sorted by order of preference: from the most -wanted constraints to the least.

-

When the next encountered constraint is set to null, the player will simply -disable the video track. If you want to disable the video track by default, -you can just set null as the first element of this array (e.g. like [null]).

-

-

The second argument to that function is an optional boolean which - when set -to true - will apply that preference to the content and Period that have -already been playing.

-

By setting it to true, you might thus change the currently-active track and -the active track of Periods (in DASH) or sub-contents (in MetaPlaylist) that -have already been played in the current content.

-

By setting it to false, undefined or not setting it, those preferences will -only be applied each time a new Period (or sub-content) is loaded by the -RxPlayer.

-

Simply put, if you don’t set the second argument to true those preferences -won’t be applied to:

-
    -
  • -

    the content being currently played. -Here, the current video preference will stay in place.

    -
  • -
  • -

    the Periods or sub-contents which have already been loaded for the current -content. -Those will keep the video track chosen at the last time they were loaded.

    -
  • -
-

If you want the preferences to also be applied to those, you can set the second -argument to true.

-

Examples

-

Let’s imagine that you prefer to have a track which contains only H265 -profiles. You can do:

-
player.setPreferredVideoTracks([ { codec: { all: false, test: /^hvc/ } } ]);
-
-

With that same constraint, let’s no consider that the current user prefer in any -case to have a sign language interpretation on screen:

-
player.setPreferredVideoTracks([
-  // first let's consider the best case: H265 + sign language interpretation
-  {
-    codec: { all: false, test: /^hvc/ }
-    signInterpreted: true,
-  },
-
-  // If not available, we still prefer a sign interpreted track without H265
-  { signInterpreted: true },
-
-  // If not available either, we would prefer an H265 content
-  { codec: { all: false, test: /^hvc/ } },
-
-  // Note: If this is also available, we will here still have a video track
-  // but which do not respect any of the constraints set here.
-]);
-would thus prefer the video to contain a sign language interpretation.
-We could set both the previous and that new constraint that way:
-
----
-
-For a totally different example, let's imagine you want to play without any
-video track enabled (e.g. to start in an audio-only mode). To do that, you can
-simply do:
-```js
-player.setPreferredVideoTracks([null], true);
-
-
-

⚠️ This option will have no effect in DirectFile mode -(see loadVideo options) when either :

-
    -
  • No video track API is supported on the current browser
  • -
  • The media file tracks are not supported on the browser
  • -
-
-

-

-

getPreferredVideoTracks

-

-

syntax: const preferences = player.getPreferredVideoTracks()

-

return value: Array.<Object|null>

-

-

Returns the current list of preferred video tracks - by order of preference.

-

This returns the data in the same format that it was given to either the -preferredVideoTracks constructor option or the last setPreferredVideoTracks -if it was called.

-

It will return an empty Array if none of those two APIs were used until now.

-

-

-

Bitrate selection

-

The following methods allows to choose a given bitrate for audio or video -content. It can also enable or disable an adaptive bitrate logic or influence -it.

-

-

-

getAvailableVideoBitrates

-

-

syntax: const bitrates = player.getAvailableVideoBitrates()

-

return value: Array.<Number>

-

-

The different bitrates available for the current video track in bits per -seconds.

-

-

Note for multi-Period contents:

-

This method will only return the available video bitrates of the -Period that is currently playing.

-

-

In DirectFile mode (see loadVideo -options), returns an empty Array.

-

Example

-
const videoBitrates = player.getAvailableVideoBitrates();
-if (videoBitrates.length) {
-  console.log(
-    "The current video is available in the following bitrates",
-    videoBitrates.join(", ")
-  );
-}
-
-

-

-

getAvailableAudioBitrates

-

-

syntax: const bitrates = player.getAvailableAudioBitrates()

-

return value: Array.<Number>

-

-

The different bitrates available for the current audio track in bits per -seconds.

-

-

Note for multi-Period contents:

-

This method will only return the available audio bitrates of the -Period that is currently playing.

-

-

In DirectFile mode (see loadVideo -options), returns an empty Array.

-

Example

-
const audioBitrates = player.getAvailableAudioBitrates();
-if (audioBitrates.length) {
-  console.log(
-    "The current audio is available in the following bitrates",
-    audioBitrates.join(", ")
-  );
-}
-
-

-

-

getVideoBitrate

-

-

syntax: const bitrate = player.getVideoBitrate()

-

return value: Number|undefined

-

-

Returns the bitrate of the video quality currently chosen, in bits per second.

-

Returns undefined if no content is loaded.

-

-

Note for multi-Period contents:

-

This method will only return the chosen video bitrate for the -Period that is currently playing.

-

-

In DirectFile mode (see loadVideo -options), returns undefined.

-

-

-

getAudioBitrate

-

-

syntax: const bitrate = player.getAudioBitrate()

-

return value: Number|undefined

-

-

Returns the bitrate of the audio quality currently chosen, in bits per second.

-

Returns undefined if no content is loaded.

-

-

Note for multi-Period contents:

-

This method will only return the chosen audio bitrate for the -Period that is currently playing.

-

-

In DirectFile mode (see loadVideo -options), returns undefined.

-

-

-

setMinVideoBitrate

-

-

syntax: player.setMinVideoBitrate(minBitrate)

-

arguments:

-
    -
  • minBitrate (Number): Lower video bitrate limit when adaptive streaming -is enabled.
  • -
-

-

Set a minimum video bitrate reachable through adaptive streaming.

-

When the bitrate is chosen through adaptive streaming (i.e., not enforced -manually through APIs such as setVideoBitrate), the player will never switch -to a video quality with a bitrate lower than that value.

-

The exception being when no quality has a higher bitrate, in which case the -maximum quality will always be chosen instead.

-

For example, if you want that video qualities chosen automatically never have -a bitrate below 100 kilobits per second you can call:

-
player.setMinVideoBitrate(100000);
-
-

Any limit can be removed just by setting that value to 0:

-
// remove video bitrate lower limit
-player.setMinVideoBitrate(0);
-
-

The effect of this method is persisted from content to content. As such, it can -even be called when no content is currently loaded.

-

Note that this only affects adaptive strategies. Forcing the bitrate manually -(for example by calling setVideoBitrate) bypass this limit completely.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

setMinAudioBitrate

-

-

syntax: player.setMinAudioBitrate(minBitrate)

-

arguments:

-
    -
  • minBitrate (Number): Lower audio bitrate limit when adaptive streaming -is enabled.
  • -
-

-

Set a minimum audio bitrate reachable through adaptive streaming.

-

When the bitrate is chosen through adaptive streaming (i.e., not enforced -manually through APIs such as setAudioBitrate), the player will never switch -to an audio quality with a bitrate lower than that value.

-

The exception being when no quality has a higher bitrate, in which case the -maximum quality will always be chosen instead.

-

For example, if you want that audio qualities chosen automatically never have -a bitrate below 100 kilobits per second you can call:

-
player.setMinAudioBitrate(100000);
-
-

Any limit can be removed just by setting that value to 0:

-
// remove audio bitrate lower limit
-player.setMinAudioBitrate(0);
-
-

The effect of this method is persisted from content to content. As such, it can -even be called when no content is currently loaded.

-

Note that this only affects adaptive strategies. Forcing the bitrate manually -(for example by calling setAudioBitrate) bypass this limit completely.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

getMinVideoBitrate

-

-

syntax: const minBitrate = player.getMinVideoBitrate()

-

return value: Number

-

-

Returns the minimum video bitrate reachable through adaptive streaming, in bits -per second.

-

This minimum limit has usually been set either through the setMinVideoBitrate -method or through the minVideoBitrate constructor option.

-

This limit can be further updated by calling the -setMinVideoBitrate method.

-

Note that this only affects adaptive strategies. Forcing the bitrate manually -(for example by calling setVideoBitrate) bypass this limit completely.

-

-

-

getMinAudioBitrate

-

-

syntax: const minBitrate = player.getMinAudioBitrate()

-

return value: Number

-

-

Returns the minimum audio bitrate reachable through adaptive streaming, in bits -per second.

-

This minimum limit has usually been set either through the setMinAudioBitrate -method or through the minAudioBitrate constructor option.

-

This limit can be further updated by calling the -setMinAudioBitrate method.

-

Note that this only affects adaptive strategies. Forcing the bitrate manually -(for example by calling setAudioBitrate) bypass this limit completely.

-

-

-

setMaxVideoBitrate

-

-

syntax: player.setMaxVideoBitrate(maxBitrate)

-

arguments:

-
    -
  • maxBitrate (Number): Upper video bitrate limit when adaptive streaming -is enabled.
  • -
-

-

Set a maximum video bitrate reachable through adaptive streaming.

-

When the bitrate is chosen through adaptive streaming (i.e., not enforced -manually through APIs such as setVideoBitrate), the player will never switch -to a video quality with a bitrate higher than that value.

-

The exception being when no quality has a lower bitrate, in which case the -minimum quality will always be chosen instead.

-

For example, if you want that video qualities chosen automatically never have -a bitrate higher than 1 Megabits per second you can call:

-
player.setMaxVideoBitrate(1e6);
-
-

Any limit can be removed just by setting that value to Infinity:

-
// remove video bitrate higher limit
-player.setMaxVideoBitrate(Infinity);
-
-

The effect of this method is persisted from content to content. As such, it can -even be called when no content is currently loaded.

-

Note that this only affects adaptive strategies. Forcing the bitrate manually -(for example by calling setVideoBitrate) bypass this limit completely.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

setMaxAudioBitrate

-

-

syntax: player.setMaxAudioBitrate(maxBitrate)

-

arguments:

-
    -
  • maxBitrate (Number): Upper audio bitrate limit when adaptive streaming -is enabled.
  • -
-

-

Set a maximum audio bitrate reachable through adaptive streaming.

-

When the bitrate is chosen through adaptive streaming (i.e., not enforced -manually through APIs such as setAudioBitrate), the player will never switch -to an audio quality with a bitrate higher than that value.

-

The exception being when no quality has a lower bitrate, in which case the -minimum quality will always be chosen instead.

-

For example, if you want that audio qualities chosen automatically never have -a bitrate higher than 1 Megabits per second you can call:

-
player.setMaxAudioBitrate(1e6);
-
-

Any limit can be removed just by setting that value to Infinity:

-
// remove audio bitrate higher limit
-player.setMaxAudioBitrate(Infinity);
-
-

The effect of this method is persisted from content to content. As such, it can -even be called when no content is currently loaded.

-

Note that this only affects adaptive strategies. Forcing the bitrate manually -(for example by calling setAudioBitrate) bypass this limit completely.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

getMaxVideoBitrate

-

-

syntax: const maxBitrate = player.getMaxVideoBitrate()

-

return value: Number

-

-

Returns the maximum video bitrate reachable through adaptive streaming, in bits -per second.

-

This maximum limit has usually been set either through the setMaxVideoBitrate -method or through the maxVideoBitrate constructor option.

-

This limit can be further updated by calling the -setMaxVideoBitrate method.

-

Note that this only affects adaptive strategies. Forcing the bitrate manually -(for example by calling setVideoBitrate) bypass this limit completely.

-

-

-

getMaxAudioBitrate

-

-

syntax: const maxBitrate = player.getMaxAudioBitrate()

-

return value: Number

-

-

Returns the maximum audio bitrate reachable through adaptive streaming, in bits -per second.

-

This maximum limit has usually been set either through the setMaxAudioBitrate -method or through the maxAudioBitrate constructor option.

-

This limit can be further updated by calling the -setMaxAudioBitrate method.

-

Note that this only affects adaptive strategies. Forcing the bitrate manually -(for example by calling setAudioBitrate) bypass this limit completely.

-

-

-

setVideoBitrate

-

-

syntax: player.setVideoBitrate(bitrate)

-

arguments:

-
    -
  • bitrate (Number): Optimal video bitrate (the quality with the maximum -bitrate inferior to this value will be chosen if it exists).
  • -
-

-

Force the current video track to be of a certain bitrate.

-

If a video quality in the current track is found with the exact same bitrate, -this quality will be set.

-

If no video quality is found with the exact same bitrate, either:

-
    -
  • -

    the video quality with the closest bitrate inferior to that value will be -chosen.

    -
  • -
  • -

    if no video quality has a bitrate lower than that value, the video -quality with the lowest bitrate will be chosen instead.

    -
  • -
-

By calling this method with an argument set to -1, this setting will be -disabled and the RxPlayer will chose the right quality according to its adaptive -logic.

-

You can use getAvailableVideoBitrates to get the list of available bitrates -for the current video track.

-

Note that the value set is persistent between loadVideo calls. -As such, this method can also be called when no content is playing (the same -rules apply for future contents).

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

setAudioBitrate

-

-

syntax: player.setAudioBitrate(bitrate)

-

arguments:

-
    -
  • bitrate (Number): Optimal audio bitrate (the quality with the maximum -bitrate inferior to this value will be chosen if it exists).
  • -
-

-

Force the current audio track to be of a certain bitrate.

-

If an audio quality in the current track is found with the exact same bitrate, -this quality will be set.

-

If no audio quality is found with the exact same bitrate, either:

-
    -
  • -

    the audio quality with the closest bitrate inferior to that value will be -chosen.

    -
  • -
  • -

    if no audio quality has a bitrate lower than that value, the audio -quality with the lowest bitrate will be chosen instead.

    -
  • -
-

By calling this method with an argument set to -1, this setting will be -disabled and the RxPlayer will chose the right quality according to its adaptive -logic.

-

You can use getAvailableAudioBitrates to get the list of available bitrates -for the current audio track.

-

Note that the value set is persistent between loadVideo calls. -As such, this method can also be called when no content is playing (the same -rules apply for future contents).

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

getManualVideoBitrate

-

-

syntax: const currentManualVideoBitrate = player.getManualVideoBitrate()

-

return value: Number

-

-

Get the last video bitrate manually set. Either via setVideoBitrate or via -the initialVideoBitrate constructor option.

-

This value can be different than the one returned by getVideoBitrate:

-
    -
  • getManualVideoBitrate returns the last bitrate set manually by the user
  • -
  • getVideoBitrate returns the actual bitrate of the current video track
  • -
-

-1 when no video bitrate is forced.

-

-

-

getManualAudioBitrate

-

-

syntax: const currentManualAudioBitrate = player.getManualAudioBitrate()

-

return value: Number

-

-

Get the last audio bitrate manually set. Either via setAudioBitrate or via -the initialAudioBitrate constructor option.

-

This value can be different than the one returned by getAudioBitrate:

-
    -
  • getManualAudioBitrate returns the last bitrate set manually by the user
  • -
  • getAudioBitrate returns the actual bitrate of the current audio track
  • -
-

-1 when no audio bitrate is forced.

-

-

-

Buffer control

-

The methods in this chapter allow to get and set limits on how the current -buffer can grow.

-

-

-

setWantedBufferAhead

-

-

syntax: player.setWantedBufferAhead(bufferGoal)

-

arguments:

-
    -
  • bufferGoal (Number): Ideal amount of buffer that should be pre-loaded, -in seconds.
  • -
-

-

Set the buffering goal, as a duration ahead of the current position, in seconds.

-

Once this size of buffer reached, the player won’t try to download new segments -anymore.

-

By default, this value is set to 30.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

getWantedBufferAhead

-

-

syntax: const bufferGoal = player.getWantedBufferAhead()

-

return value: Number

-

-

returns the buffering goal, as a duration ahead of the current position, in -seconds.

-

By default, this value is set to 30.

-

-

-

setMaxBufferBehind

-

-

syntax: player.setMaxBufferBehind(bufferSize)

-

arguments:

-
    -
  • bufferSize (Number): Maximum amount of buffer behind the current -position, in seconds.
  • -
-

-

Set the maximum kept buffer before the current position, in seconds.

-

Everything before that limit (currentPosition - maxBufferBehind) will be -automatically garbage collected.

-

This feature is not necessary as the browser should by default correctly -remove old segments from memory if/when the memory is scarce.

-

However on some custom targets, or just to better control the memory footprint -of the player, you might want to set this limit.

-

You can set it to Infinity to remove this limit and just let the browser do -this job instead.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

getMaxBufferBehind

-

-

syntax: const bufferSize = player.getMaxBufferBehind()

-

return value: Number

-

-

Returns the maximum kept buffer before the current position, in seconds.

-

This setting can be updated either by:

-
    -
  • calling the setMaxBufferBehind method.
  • -
  • instanciating an RxPlayer with a maxBufferBehind property set.
  • -
-

-

-

setMaxBufferAhead

-

-

syntax: player.setMaxBufferAhead(bufferSize)

-

arguments:

-
    -
  • bufferSize (Number): Maximum amount of buffer ahead of the current -position, in seconds.
  • -
-

-

Set the maximum kept buffer ahead of the current position, in seconds.

-

Everything superior to that limit (currentPosition + maxBufferAhead) will -be automatically garbage collected.

-

This feature is not necessary as the browser should by default correctly -remove old segments from memory if/when the memory is scarce.

-

However on some custom targets, or just to better control the memory footprint -of the player, you might want to set this limit.

-

You can set it to Infinity to remove any limit and just let the browser do -this job instead.

-

The minimum value between this one and the one returned by -getWantedBufferAhead will be considered when downloading new segments.

-

⚠️ Bear in mind that a too-low configuration there (e.g. inferior to -10) might prevent the browser to play the content at all.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

getMaxBufferAhead

-

-

syntax: const bufferSize = player.getMaxBufferAhead()

-

return value: Number

-

-

Returns the maximum kept buffer ahead of the current position, in seconds.

-

This setting can be updated either by:

-
    -
  • calling the setMaxBufferAhead method.
  • -
  • instanciating an RxPlayer with a maxBufferAhead property set.
  • -
-

-

-

Buffer information

-

The methods in this chapter allows to retrieve information about what is -currently buffered.

-

-

-

getVideoLoadedTime

-

-

syntax: const loadedTime = player.getVideoLoadedTime()

-

return value: Number

-

-

Returns in seconds the difference between:

-
    -
  • the start of the current contiguous loaded range.
  • -
  • the end of it.
  • -
-

In other words, this is the duration of the current contiguous range of media -data the player is currently playing: -If we’re currently playing at the position at 51 seconds, and there is media -data from the second 40 to the second 60, then getVideoLoadedTime() will -return 20 (60 - 40).

-

0 if there’s no data loaded for the current position.

-

-

-

getVideoPlayedTime

-

-

syntax: const playedTime = player.getVideoPlayedTime()

-

return value: Number

-

-

Returns in seconds the difference between:

-
    -
  • the start of the current contiguous loaded range.
  • -
  • the current time.
  • -
-

In other words, this is the amount of time in the current contiguous range of -media data the player has already played. -If we’re currently playing at the position at 51 seconds, and there is media -data from the second 40 to the second 60, then getVideoPlayedTime() will -return 11 (51 - 40).

-

0 if there’s no data loaded for the current position.

-

-

-

getVideoBufferGap

-

-

syntax: const bufferGap = player.getVideoBufferGap()

-

return value: Number

-

-

Returns in seconds the difference between:

-
    -
  • the current time.
  • -
  • the end of the current contiguous loaded range.
  • -
-

In other words, this is the amount of seconds left in the buffer before the end -of the current contiguous range of media data. -If we’re currently playing at the position at 51 seconds, and there is media -data from the second 40 to the second 60, then getVideoPlayedTime() will -return 9 (60 - 51).

-

-

-

Content information

-

The methods documented in this chapter allows to obtain general information -about the current loaded content.

-

-

-

isLive

-

-

syntax: const isLive = player.isLive()

-

return value: Boolean

-

-

Returns true if the content is a “live” content (e.g. a live TV Channel). -false otherwise.

-

Also false if no content is loaded yet.

-

Example

-
if (player.isLive()) {
-  console.log("We're playing a live content");
-}
-
-

-

-

getUrl

-

-

syntax: const url = player.getUrl()

-

return value: string

-

-

Returns the URL of the downloaded Manifest.

-

In DirectFile mode (see loadVideo -options), returns the URL of the content -being played.

-

Returns undefined if no content is loaded yet.

-

Example

-
const url = player.getUrl();
-if (url) {
-  console.log("We are playing the following content:", url);
-}
-
-

-

-

getCurrentKeySystem

-

-

syntax: const keySystemName = player.getCurrentKeySystem()

-

return value: string|undefined

-

-

Returns the type of keySystem used for DRM-protected contents.

-

-

-

Deprecated

-

The following methods are deprecated. They are still supported but we advise -users to not use those as they might become not supported in the future.

-

-

-

getManifest

-

-

⚠️ This method is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-

-

-

syntax: const manifest = player.getManifest()

-

return value: Manifest|null

-

-

Returns the current loaded Manifest if one. -The Manifest object structure is relatively complex and is described in the -Manifest Object structure page.

-

null if the player is either stopped or not loaded.

-

null in DirectFile mode (see loadVideo -options).

-

The Manifest will be available before the player reaches the "LOADED" state.

-

-

-

getCurrentAdaptations

-

-

⚠️ This method is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-

-

-

syntax: const adaptations = player.getCurrentAdaptations()

-

return value: Object|null

-

-

Returns the Adaptations being loaded per type if a -Manifest is loaded. The returned object will have at -most a key for each type (“video”, “audio”, “text” and “image”) which will each -contain an array of Adaptation Objects.

-

The Adaptation object structure is relatively complex and is described in the -Manifest Object structure page.

-

null if the current Adaptations are not known yet.

-

null in DirectFile mode (see loadVideo -options).

-

-

-

getCurrentRepresentations

-

-

⚠️ This method is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-

-

-

syntax: const representations = player.getCurrentRepresentations()

-

return value: Object|null

-

-

Returns the Representations being loaded per type -if a Manifest is loaded. The returned object will have -at most a key for each type (“video”, “audio”, “text” and “image”) which will -each contain an array of Representation Objects.

-

An Representation object structure is relatively complex and is described in the -Manifest Object structure page.

-

null if the current Representations are not known yet.

-

null in DirectFile mode (see loadVideo -options).

-

-

-

getImageTrackData

-

-

⚠️ This method is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-

-

-

syntax: const data = player.getImageTrackData()

-

return value: Array.<Object>|null

-

-

The current image track’s data, null if no content is loaded / no image track -data is available.

-

The returned array follows the usual image playlist structure, defined -here.

-

null in DirectFile mode (see loadVideo -options).

-

-

-

setFullscreen

-

-

⚠️ This method is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-

-

arguments: Boolean

-

Switch or exit the <video> element to fullscreen mode. The argument is an -optional boolean:

-
    -
  • -

    if set:

    -
      -
    • true: enters fullscreen
    • -
    • false: exit fullscreen
    • -
    -
  • -
  • -

    if not set: enter fullscreen

    -
  • -
-

Note that only the video element will be set to fullscreen mode. You might -prefer to implement your own method to include your controls in the final UI.

-

-

-

exitFullscreen

-

-

⚠️ This method is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-

-

Exit fullscreen mode. Same than setFullscreen(false).

-

-

-

isFullscreen

-

-

⚠️ This method is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-

-

return value: Boolean

-

Returns true if the video element is in fullscreen mode, false -otherwise.

-

Example

-
if (player.isFullscreen()) {
-  console.log("The player is in fullscreen mode");
-}
-
-

-

-

getNativeTextTrack

-

-

⚠️ This method is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-

-

-

syntax: const textTrack = player.getNativeTextTrack()

-

return value: TextTrack|null

-

-

Returns the first text track of the video’s element, null if none.

-

This is equivalent to:

-
const el = player.getVideoElement();
-const textTrack = el.textTracks.length ? el.textTracks[0] : null;
-
-

-

-

Static properties

-

This chapter documents the static properties that can be found on the RxPlayer -class.

-

-

-

version

-

type: Number

-

The current version of the RxPlayer.

-

-

-

ErrorTypes

-

type: Object

-

The different “types” of Error you can get on playback error,

-

See the Player Error documentation for more information.

-

-

-

ErrorCodes

-

type: Object

-

The different Error “codes” you can get on playback error,

-

See the Player Error documentation for more information.

-

-

-

LogLevel

-

type: string

-

default: "NONE"

-

The current level of verbosity for the RxPlayer logs. Those logs all use the -console.

-

From the less verbose to the most:

-
    -
  • -

    "NONE": no log

    -
  • -
  • -

    "ERROR": unexpected errors (via console.error)

    -
  • -
  • -

    "WARNING": The previous level + minor problems encountered (via -console.warn)

    -
  • -
  • -

    "INFO": The previous levels + noteworthy events (via console.info)

    -
  • -
  • -

    "DEBUG": The previous levels + normal events of the player (via -console.log)

    -
  • -
-

If the value set to this property is different than those, it will be -automatically set to "NONE".

-

Example

-
import RxPlayer from "rx-player";
-RxPlayer.LogLevel = "WARNING";
-
-

-

-

Tools

-

The RxPlayer has several “tools”, which are utils which can be imported without -importing the whole RxPlayer itself.

-

They are all documented here.

-

-

-

StringUtils

-

Tools to convert strings into bytes and vice-versa.

-

The RxPlayer internally has a lot of code dealing with strings to bytes -conversion (and vice-versa). This tool exports that logic so you don’t have to -rewrite it yourself.

-

You might need one of those functions for example when dealing with challenge -and licenses, which are often under a binary format.

-

How to import it

-

The simplest way to import the StringUtils is by importing it as a named export -from “rx-player/tools”, like so:

-
import { StringUtils } from "rx-player/tools";
-
-console.log(StringUtils.strToUtf8("hello😀"));
-
-

You can also import only the function(s) you want to use by importing it -directly from “rx-player/tools/string-utils”:

-
import { strToUtf8 } from "rx-player/tools/string-utils";
-console.log(strToUtf8("hello😀"));
-
-

StringUtils functions

-

StringUtils is an object containing the following functions:

-
    -
  • -

    strToUtf8: Convert a JS string passed as argument to an Uint8Array of its -corresponding representation in UTF-8.

    -

    Example:

    -
    import { StringUtils } from "rx-player/tools";
    -StringUtils.strToUtf8("hello😀");
    -// => Uint8Array(9) [ 104, 101, 108, 108, 111, 240, 159, 152, 128 ]
    -//                    "h"  "e"  "l"  "l"  "o"  "grinning face" emoji
    -
    -
  • -
  • -

    utf8ToStr: Convert a Uint8Array containing a string encoded with UTF-8 -into a JS string.

    -

    Example:

    -
    import { StringUtils } from "rx-player/tools";
    -const uint8Arr = new Uint8Array([104, 101, 108, 108, 111, 240, 159, 152, 128]);
    -StringUtils.utf8ToStr(uint8Arr);
    -// => "hello😀"
    -
    -

    Note: if what you have is an ArrayBuffer, you have to convert it to an -Uint8Array first:

    -
    import { StringUtils } from "rx-player/tools";
    -const toUint8Array = new Uint8Array(myArrayBuffer);
    -console.log(StringUtils.utf8ToStr(toUint8Array));
    -
    -
  • -
  • -

    strToUtf16LE: Convert a JS string passed as argument to an Uint8Array -containing its corresponding representation in UTF-16-LE (little endian -UTF-16).

    -

    Example:

    -
    import { StringUtils } from "rx-player/tools";
    -StringUtils.strToUtf16LE("hi😀");
    -// => Uint8Array(9) [ 104, 0, 105, 0, 61, 216, 0, 222 ]
    -//                    "h"     "i"     "grinning face" emoji
    -
    -
  • -
  • -

    utf16LEToStr: Convert a Uint8Array containing a string encoded with -UTF-16-LE (little endian UTF-16) into a JS string.

    -

    Example:

    -
    import { StringUtils } from "rx-player/tools";
    -const uint8Arr = new Uint8Array([104, 0, 105, 0, 61, 216, 0, 222]);
    -StringUtils.utf16LEToStr(uint8Arr);
    -// => "hi😀"
    -
    -

    Note: if what you have is an ArrayBuffer, you have to convert it to an -Uint8Array first:

    -
    import { StringUtils } from "rx-player/tools";
    -const toUint8Array = new Uint8Array(myArrayBuffer);
    -console.log(StringUtils.utf16LEToStr(toUint8Array));
    -
    -
  • -
  • -

    strToUtf16BE: Convert a JS string passed as argument to an Uint8Array -containing its corresponding representation in UTF-16-BE (big endian -UTF-16).

    -

    Example:

    -
    import { StringUtils } from "rx-player/tools";
    -StringUtils.strToUtf16BE("hi😀");
    -// => Uint8Array(9) [ 0, 104, 0, 105, 216, 61, 222, 0 ]
    -//                    "h"     "i"     "grinning face" emoji
    -
    -
  • -
  • -

    utf16BEToStr: Convert a Uint8Array containing a string encoded with -UTF-16-BE (big endian UTF-16) into a JS string.

    -

    Example:

    -
    import { StringUtils } from "rx-player/tools";
    -const uint8Arr = new Uint8Array([0, 104, 0, 105, 216, 61, 222, 0]);
    -StringUtils.utf16BEToStr(uint8Arr);
    -// => "hi😀"
    -
    -

    Note: if what you have is an ArrayBuffer, you have to convert it to an -Uint8Array first:

    -
    import { StringUtils } from "rx-player/tools";
    -const toUint8Array = new Uint8Array(myArrayBuffer);
    -console.log(StringUtils.utf16BEToStr(toUint8Array));
    -
    -
  • -
-

-

-

TextTrackRenderer

-

The TextTrackRenderer allows to easily render subtitles synchronized to a video -element.

-

It allows easily to dynamically add subtitles (as long as it is in one of the -following format: srt, ttml, webVTT or SAMI) to a played video.

-

This tool is documented here.

-

-

-

MediaCapabilitiesProber

-

-

⚠️ This tool is experimental. This only means that its API can change at -any new RxPlayer version (with all the details in the corresponding release -note).

-

-

An experimental tool to probe browser media capabilities:

-
    -
  • Decoding capabilities
  • -
  • DRM support
  • -
  • HDCP support
  • -
  • Display capabilities
  • -
-

You can find its documentation here.

-

-

-

parseBifThumbnails

-

-

⚠️ This tool is experimental. This only means that its API can change at -any new RxPlayer version (with all the details in the corresponding release -note).

-

-

The parseBifThumbnails function parses BIF files, which is a format used -to declare thumbnails linked to a given content.

-

This tool is documented here.

-

-

-

createMetaplaylist

-

-

⚠️ This tool is experimental. This only means that its API can change at -any new RxPlayer version (with all the details in the corresponding release -note).

-

-

The createMetaplaylist function build a metaplaylist object from given -informations about contents.

-

This tool is documented here.

-
\ No newline at end of file diff --git a/doc/generated/pages/api/loadVideo_options.html b/doc/generated/pages/api/loadVideo_options.html deleted file mode 100644 index b2da53309d..0000000000 --- a/doc/generated/pages/api/loadVideo_options.html +++ /dev/null @@ -1,1237 +0,0 @@ -loadVideo options - RxPlayer Documentation

-

loadVideo options

-

-

-

Overview

-

This page describes the options given to the loadVideo method, which is the -method to use to load a new video.

-

These options take the form of a single objects with multiple properties, like -this:

-
// Simply loading a DASH MPD
-const options = {
-  transport: "dash",
-  url: myManifestUrl
-};
-player.loadVideo(options);
-
-

-

-

Properties

-

-

-

transport

-

type: string|undefined

-

The transport protocol used for this content. -This property is mandatory.

-

Can be either:

-
    -
  • -

    "dash" - for DASH contents

    -
  • -
  • -

    "smooth" - for Microsoft Smooth Streaming contents

    -
  • -
  • -

    "directfile" - for loading a video in DirectFile mode, which allows to -directly play media files (example: .mp4 or .webm files) without -using a transport protocol. With that option, you can even play HLS -contents on multiple browsers (mainly safari and iOS browsers).

    -

    ⚠️ In that mode, multiple APIs won’t have any effect. -This is documented in the documentation of each concerned method, option or -event in the API.

    -
  • -
  • -

    "metaplaylist" for MetaPlaylist streams, which are -a concatenation of multiple smooth and DASH contents

    -
  • -
  • -

    "local" for local manifests, which allows to play -downloaded DASH, Smooth or MetaPlaylist contents (when offline for example).

    -
  • -
-

Example:

-
// play some dash content
-rxPlayer.loadVideo({
-  transport: "dash",
-  url: https://www.example.com/dash.mpd
-})
-
-

-

-

url

-

type: string|undefined

-

For Smooth, DASH or MetaPlaylist contents, the URL to the -Manifest (or equivalent)

-

For DirectFile mode contents, the URL of the content (the supported contents -depends on the current browser).

-

This property is mandatory unless either:

-
    -
  • -

    a manifestLoader is defined in the -transportOptions, in which case that callback will -be called instead any time we want to load the Manifest.

    -
  • -
  • -

    an initialManifest is defined in the -transportOptions, in which case this will be used -as the first version of the Manifest. -Note however that if the Manifest needs to be refreshed and no url nor -manifestLoader has been set, the RxPlayer will most likely fail and stop -playback.

    -
  • -
-

Example:

-
// play some dash content
-rxPlayer.loadVideo({
-  url: https://www.example.com/dash.mpd,
-  transport: "dash"
-})
-
-

-

-

keySystems

-

type: Array.<Object>|undefined

-

This property is mandatory if the content uses DRM.

-

It is here that is defined every options relative to the encryption of your -content. There’s a lot of configuration possible here. In the case you find -this documentation hard to grasp, we’ve written a tutorial on DRM configuration -here.

-

This property is an array of objects with the following properties (only -type and getLicense are mandatory here):

-
    -
  • -

    type (string): name of the DRM system used. Can be either -"widevine", "playready" or clearkey or the type (reversed domain -name) of the keySystem (e.g. "com.widevine.alpha", -"com.microsoft.playready" …).

    -
  • -
  • -

    getLicense (Function): Callback which will be triggered everytime a -message is sent by the Content Decryption Module (CDM), usually to -fetch/renew the license.

    -

    Gets two arguments when called:

    -
      -
    1. the message (Uint8Array): The message, formatted to an Array of -bytes.
    2. -
    3. the messageType (string): String describing the type of message -received. -There is only 4 possible message types, all defined in the w3c -specification.
    4. -
    -

    This function should return either synchronously the license, null to -not set a license for this message event or a Promise which should -either: -- resolves if the license was fetched, with the licence in argument -- resolve with null if you do not want to set a license for this -message event -- reject if an error was encountered.

    -

    Note: We set a 10 seconds timeout by default on this request (configurable -through the getLicenseConfig object). -If the returned Promise do not resolve or reject under this limit, the -player will stop with an error.

    -

    In any case, the license provided by this function should be of a -BufferSource type (example: an Uint8Array or an ArrayBuffer).

    -

    Even in case of an error, you can (this is not mandatory) set any of the -following properties on the rejected value which will be interpreted by -the RxPlayer:

    -
    - `noRetry` (`Boolean`): If set to `true`, we will throw directly a
    -  `KEY_LOAD_ERROR` to call `getLicense`. If not set or set to `false`,
    -  the current retry parameters will be applied (see `getLicenseConfig`)
    -
    -- `message` (`string`): If the `message` property is set as a "string",
    -  this message will be set as the `message` property of the
    -  corresponding `EncryptedMediaError` (either communicated through an
    -  `"error"` event if we're not retrying or through a `"warning"` event
    -  if we're retrying).
    -  As every other `getLicense`-related errors, this error will have the
    -  `KEY_LOAD_ERROR` `code` property.
    -
    -- `fallbackOnLastTry`: If this getLicense is the last retry (if the
    -  `noRetry` property is set to `true`, this is always true), we will not
    -  throw immediately but rather try to fallback on other Representations
    -  (e.g. qualities) which might have a different decryption key. If no
    -  Representation is left, we will throw a MediaError with a
    -  `NO_PLAYABLE_REPRESENTATION` code, as documented [in the errors
    -  documentation](./errors.md#types-media_error).
    -
    -  You will receive a `decipherabilityUpdate` event when we fallback from
    -  a given Representation. You can find documentation on this event [in
    -  the corresponding chapter of the events
    -  documentation](./player_events.md#events-decipherabilityUpdate).
    -
    -  This option is thus only useful for contents depending on multiple
    -  licenses.
    -
    -  When fallbacking, we might need to reload the current MediaSource,
    -  leading to a black screen during a brief instant. When reloading, the
    -  RxPlayer will have the `"reloading"` [player state](./states.md).
    -  on most situations, we will however not reload the media source but
    -  only perform a very little seek (of some milliseconds). you might see
    -  the stream stutter for a very brief instant at that point.
    -
    -  On the Edge browser, we found an issue that can arise when this option
    -  is set if PlayReady is used. This issue can make the player loads the
    -  content indefinitely.
    -  Sadly, no work-around has been found for now for this issue. We're
    -  currently trying to create a reproducible scenario and document that
    -  issue so it can hopefully be fixed in the future. In the meantime,
    -  you're encouraged either to use Widevine (only on Chromium-based Edge)
    -  or to not make use of the `fallBackOnLastTry` option on that browser.
    -
    -
  • -
  • -

    getLicenseConfig (Object|undefined): Optional configuration for the -getLicense callback. Can contain the following properties:

    -
      -
    • -

      retry (Number|undefined) (default: 2): number of time -getLicense is retried on error or on timeout before we fail on a -KEY_LOAD_ERROR

      -
    • -
    • -

      timeout (Number|undefined) (default: 10000): timeout, in ms, -after which we consider the getLicense callback to have failed.

      -

      Set it to -1 to disable any timeout.

      -
    • -
    -
  • -
  • -

    serverCertificate (BufferSource|undefined): Eventual certificate -used to encrypt messages to the license server. -If set, we will try to set this certificate on the CDM. If it fails, we will -still continue to try deciphering the content (albeit a -warning will be emitted in that case with the code -"LICENSE_SERVER_CERTIFICATE_ERROR").

    -
  • -
  • -

    persistentLicense (Boolean|undefined): Set it to true if you -want the ability to persist the license for later retrieval. -In that case, you will also need to set the licenseStorage attribute to -be able to persist the license through your preferred method. This is not -needed for most usecases.

    -
  • -
  • -

    licenseStorage (Object|undefined): Required only if -persistentLicense has been set to true. It’s an object containing -two functions load and save:

    -
      -
    • save: take into argument an Array.<Object> which will be the set -of sessionId to save. No return value needed.
    • -
    • load: take no argument and returns the stored Array.<Object> -(the last given to save) synchronously.
    • -
    -
  • -
  • -

    persistentStateRequired (Boolean|undefined): Set it to true if -the chosen CDM should have the ability to persist a license, false if -you don’t care. This is not needed for most usecases. false by default. -You do not have to set it to true if the persistentLicense option is -set.

    -
  • -
  • -

    distinctiveIdentifierRequired (Boolean|undefined): When set to -true, the use of -Distinctive Indentifier(s) -or -Distinctive Permanent Identifier(s) -will be required. This is not needed for most usecases. false if you do -not care. false by default.

    -
  • -
  • -

    throwOnLicenseExpiration (Boolean|undefined): true by default.

    -

    If set to true or not set, the playback will be interrupted as soon as one -of the current licenses expires. In that situation, you will be warned with -an error event with, as a payload, an error with the code -KEY_STATUS_CHANGE_ERROR.

    -

    If set to false, the playback of the current content will not be -interrupted even if one of the current licenses is expired. It might however -stop decoding in that situation. -It’s then up to you to update the problematic license, usually through the -usual getLicense callback.

    -

    You may want to set this value to false if a session expiration leads to -a license renewal. -In that case, content may continue to play once the license has been -updated.

    -
  • -
  • -

    fallbackOn (Object): This advanced option allows to fallback on other -Representations (e.g. qualities) when one of them has its decription key -refused.

    -

    This option is thus only useful for contents depending on multiple -keys.

    -

    This object can have two properties: -- keyInternalError: fallback when the corresponding key has the -status -"internal-error". We found that most widevine implementation use -this error when a key is refused. -- keyOutputRestricted: fallback when the corresponding key has the -status -"output-restricted". This is the proper status for a key refused due -to output restrictions.

    -

    For most cases where you want to fallback in case of a refused key, we -recommend setting both properties to true.

    -

    You will receive a decipherabilityUpdate event when we fallback from -a given Representation. You can find documentation on this event -in the corresponding chapter of the events -documentation.

    -

    When fallbacking, we might need to reload the current MediaSource, leading -to a black screen during a brief instant. When reloading, the RxPlayer -will have the "reloading" player state. -on most situations, we will however not reload the media source but only -perform a very little seek (of some milliseconds). you might see the -stream twitch for a very brief instant at that point.

    -

    If we have no Representation to fallback to anymore, we will throw a -MediaError with a NO_PLAYABLE_REPRESENTATION code, as documented in -the errors documentation.

    -
  • -
  • -

    onKeyStatusesChange (Function|undefined): Not needed for most -usecases.

    -

    Triggered each time the key statuses of the current session -changes, except for the following statuses (which throws immediately):

    -
      -
    • expired if (and only if) throwOnLicenseExpiration is not set to -false
    • -
    • internal-error
    • -
    -

    Takes 2 arguments:

    -
      -
    1. The keystatuseschange event {Event}
    2. -
    3. The session associated with the event {MediaKeySession}
    4. -
    -

    Like getLicense, this function should return a promise which emit a -license or null (for no license) when resolved. It can also return -directly the license or null if it can be done synchronously.

    -

    In case of an error, you can set the message property on the -rejected value as a “string”. This message will be set as the message -property of the corresponding EncryptedMediaError communicated through -an "error" event. -As every other onKeyStatusesChange-related errors, this error will have -the KEY_STATUS_CHANGE_ERROR code property.

    -
  • -
  • -

    closeSessionsOnStop (Boolean|undefined): If set to true, the -MediaKeySession created for a content will be immediately closed when -the content stops its playback. This might be required by your key system -implementation (most often, it is not).

    -

    If set to false or not set, the MediaKeySession can be reused if the -same content needs to be re-decrypted.

    -
  • -
  • -

    disableMediaKeysAttachmentLock (Boolean|undefined): -In regular conditions, we might want to wait for the media element to have -decryption capabilities (what we call here “MediaKeys attachment”) before -beginning to load the actual content.

    -

    Waiting for that capability validation allows for example to play a content -which contains both encrypted and unencrypted data on the Chrome browser.

    -

    However, we found that in some peculiar devices (like some set-top boxes) -this can create a deadlock: the browser sometimes wait for some -content to be loaded before validating the media element’s decryption -capabilities.

    -

    Because we didn’t find a good enough compromise for now, we added the -disableMediaKeysAttachmentLock boolean. -By setting it to true, we won’t wait for “MediaKeys attachment” before -pushing the first content. The downside being that content of mixed -unencrypted/encrypted data might not be playable with that configuration.

    -

    You can try that property if your encrypted contents seems to load -indefinitely on peculiar targets.

    -
  • -
-

Example

-

Example of a simple DRM configuration for widevine and playready DRMs:

-
player.loadVideo({
-  url: manifestURL,
-  transport: "dash",
-  keySystems: [{
-    type: "widevine",
-    getLicense(challenge) {
-      // ajaxPromise is here an AJAX implementation doing a POST request on the
-      // widevineLicenseServer with the challenge in its body.
-      return ajaxPromise(widevineLicenseServer, challenge);
-    }
-  }, {
-    type: "playready",
-    getLicense(challenge) {
-      // idem
-      // Note: you may need to format the challenge before doing the request
-      // depending on the server configuration.
-      return ajaxPromise(playreadyLicenseServer, challenge);
-    }
-  }]
-})
-
-

-

-

autoPlay

-

type: Boolean|undefined

-

defaults: false

-

If set to true, the video will play immediately after being loaded.

-

Note: On some browsers, auto-playing a media without user interaction is blocked -due to the browser’s policy. -In that case, the player won’t be able to play (it will stay in a "LOADED" -state) and you will receive a warning event containing a -MEDIA_ERROR with the code: MEDIA_ERR_BLOCKED_AUTOPLAY. -A solution in that case would be to propose to your users an UI element to -trigger the play with an interaction.

-

-

-

startAt

-

type: Object|undefined

-

startAt allows to define a starting position in the played content whether -it is a live content or not.

-

This option is only defining the starting position, not the beginning of the -content. The user will then be able to navigate anywhere in the content through -the seekTo API.

-

If defined, this property must be an object containing a single key. This key -can be either:

-
    -
  • -

    position (Number): The starting position, in seconds.

    -
  • -
  • -

    wallClockTime (Number|Date): The starting wall-clock time (re-scaled -position from Manifest information to obtain a -timestamp on live contents), in seconds. -Useful to use the type of time returned by the getWallClockTime API for -live contents. If a Date object is given, it will automatically be converted -into seconds.

    -
  • -
  • -

    fromFirstPosition (Number): relative position from the minimum -possible one, in seconds. -That is:

    -
      -
    • for dynamic (live) contents, from the beginning of the buffer depth (as -defined by the Manifest).
    • -
    • for non-dynamic (vod) contents, from the position 0 (this option -should be equivalent to position)
    • -
    -
  • -
  • -

    fromLastPosition (Number): relative position from the maximum -possible one, in seconds. Should be a negative number:

    -
      -
    • for dynamic (e.g. live) contents, it is the difference between the -starting position and the currently last possible position, as defined -by the manifest.
    • -
    • for VoD contents, it is the difference between the starting position and -the end position of the content.
    • -
    -
  • -
  • -

    percentage (Number): percentage of the wanted position. 0 being -the minimum position possible (0 for static content, buffer depth for -dynamic contents) and 100 being the maximum position possible -(duration for VoD content, last currently possible position for dynamic -contents).

    -
  • -
-

Note: Only one of those properties will be considered, in the same order of -priority they are written here.

-

If the value set is inferior to the minimum possible position, the minimum -possible position will be used instead. If it is superior to the maximum -possible position, the maximum will be used instead as well.

-

More information on how the initial position is chosen can be found in the -specific documentation page on this subject.

-

Notes for dynamic contents

-

For dynamic contents, startAt could work not as expected:

-
    -
  • -

    Depending on the type of Manifest, it will be more or less precize to guess -the current last position of the content. This will mostly affect the -fromLastPosition option.

    -
  • -
  • -

    If the Manifest does not allow to go far enough in the past (not enough -buffer, server-side) to respect the position wanted, the maximum buffer -depth will be used as a starting time instead.

    -
  • -
  • -

    If the Manifest does not allow to go far enough in the future to respect the -position wanted, the current last available position will be used to define -the starting time instead.

    -
  • -
-

If startAt is not set on live contents, the time suggested by the Manifest -will be considered. If it is also not set, the initial position will be based on -the real live edge.

-

Example

-
// using position
-player.loadVideo({
-  // ...
-  startAt: {
-    position: 10 // start at position == 10 (in seconds)
-  }
-});
-
-// using wall-clock time
-player.loadVideo({
-  // ...
-  startAt: {
-    wallClockTime: Date.now() / 1000 - 60 // 1 minute before what's broadcasted
-                                          // now
-  }
-});
-
-// using fromFirstPosition
-player.loadVideo({
-  // ...
-  startAt: {
-    fromFirstPosition: 30 // 30 seconds after the beginning of the buffer
-  }
-})
-
-// using fromLastPosition
-player.loadVideo({
-  // ...
-  startAt: {
-    fromLastPosition: -60 // 1 minute before the end
-  }
-})
-
-

-

-

transportOptions

-

type: Object|undefined

-
-

⚠️ This option has no effect in DirectFile mode (see transport -option).

-
-

Options concerning the “transport”.

-

That is, the part of the code:

-
    -
  • performing Manifest and segment requests
  • -
  • parsing the Manifest
  • -
  • parsing/updating/creating segments
  • -
-

This Object can contain multiple properties. Only those documented here are -considered stable:

-
    -
  • -

    minimumManifestUpdateInterval (number|undefined):

    -

    Set the minimum time, in milliseconds, we have to wait between Manifest -updates.

    -

    A Manifest may need to be updated in regular intervals (e.g. many DASH -dynamic contents depend on that behavior).

    -

    The frequency at which we normally update a Manifest depends on multiple -factors: the information taken from the Manifest, the transport chosen or -the current playback conditions. You might want to use -minimumManifestUpdateInterval to limit that frequency to a minimum.

    -

    This option is principally useful on some embedded devices where resources -are scarce. The request and data decompression done at each Manifest update -might be too heavy for some and reducing the interval at which they are done -might help.

    -

    Please note however than reducing that frequency can raise the chance of -rebuffering, as we might be aware of newly generated segments later than we -would be without that option.

    -

    Example:

    -
    rxPlayer.loadVideo({
    -  // ...
    -  transportOptions: {
    -    minimumManifestUpdateInterval: 5000, // Perform Manifest updates at most
    -                                         // every 5 seconds
    -  }
    -});
    -
    -
  • -
  • -

    initialManifest (string|Document|Object):

    -

    Manifest that will be initially used (before any potential Manifest -refresh).

    -

    Some applications pre-load the Manifest to parse some information from it -before calling loadVideo. -As in that case the Manifest has already been loaded, an application can -optimize content loading time by giving to the RxPlayer that already-loaded -Manifest so the latter can avoid doing another request for it.

    -

    The format accepted for that option depends on the current chosen -transport:

    -
      -
    • -

      for "dash" and "smooth" contents either a string (of the whole -Manifest’s xml data) or a corresponding Document format is accepted.

      -
    • -
    • -

      for "metaplaylist", either a string (for the whole JSON) or the -corresponding JS Object is accepted.

      -
    • -
    • -

      for "local", only the corresponding local Manifest as a JS object is -accepted.

      -
    • -
    -

    Note that using this option could have implications for live contents. -Depending on the content, the initial playing position and maximum position -could be calculated based on that option’s value.

    -

    In a case where the corresponding Manifest request was performed long before -the loadVideo call, the RxPlayer could be for example initially playing -far from the real live edge. -Because of that, it is recommended to only set that options for live/dynamic -contents if its request was done immediately before the loadVideo -call.

    -
  • -
  • -

    manifestUpdateUrl (string|undefined):

    -

    Set a custom Manifest URL for Manifest updates. -This URL can point to another version of the Manifest with a shorter -timeshift window, to lighten the CPU, memory and bandwidth impact of -Manifest updates.

    -

    Example:

    -
    rxPlayer.loadVideo({
    -  transport: "dash",
    -  url: "https://example.com/full-content.mpd",
    -  transportOptions: {
    -    manifestUpdateUrl: "https://example.com/content-with-shorter-window.mpd"
    -  }
    -});
    -
    -

    When the RxPlayer plays a live content, it may have to refresh frequently -the Manifest to be aware of where to find new media segments. -It generally uses the regular Manifest URL when doing so, meaning that the -information about the whole content is downloaded again.

    -

    This is generally not a problem though: The Manifest is generally short -enough meaning that this process won’t waste much bandwidth memory or -parsing time. -However, we found that for huge Manifests (multiple MB uncompressed), this -behavior could be a problem on some low-end devices (some set-top-boxes, -chromecasts) where slowdowns can be observed when Manifest refresh are -taking place.

    -

    The manifestUpdateUrl will thus allow an application to provide a second -URL, specifically used for Manifest updates, which can represent the same -content with a shorter timeshift window (e.g. using only 5 minutes of -timeshift window instead of 10 hours for the full Manifest). The content -will keep its original timeshift window and the RxPlayer will be able to get -information about new segments at a lower cost.

    -
  • -
  • -

    representationFilter (Function|undefined):

    -

    Allows to filter out Representations (i.e. media qualities) from the -Manifest to avoid playing them.

    -
    rxPlayer.loadVideo({
    -  // ...
    -  transportOptions: {
    -    representationFilter(representations, infos) {
    -      // ...
    -    }
    -  }
    -});
    -
    -

    More infos on it can be found here.

    -
  • -
  • -

    segmentLoader (Function|undefined):

    -

    Defines a custom segment loader for when you want to perform the requests -yourself.

    -
    rxPlayer.loadVideo({
    -  // ...
    -  transportOptions: {
    -    segmentLoader(infos, callbacks) {
    -      // logic to download a segment
    -    }
    -  }
    -});
    -
    -

    More info on it can be found here.

    -
  • -
  • -

    manifestLoader (function|undefined):

    -

    Defines a custom Manifest loader (allows to set a custom logic for the -Manifest request).

    -
    rxPlayer.loadVideo({
    -  // ...
    -  transportOptions: {
    -    manifestLoader(url, callbacks) {
    -      // logic to fetch the Manifest
    -    }
    -  }
    -});
    -
    -

    More info on it can be found here.

    -
  • -
  • -

    checkMediaSegmentIntegrity (boolean|undefined):

    -

    If set to true, the RxPlayer will retry a media segment request if that -segment seems corrupted.

    -

    If not set or set to false, the RxPlayer might interrupt playback in the -same situation.

    -

    You can set this option if you suspect the CDN providing your contents to -sometimes send you incomplete/corrupted segments.

    -

    Example:

    -
    rxPlayer.loadVideo({
    -  // ...
    -  transportOptions: {
    -    checkMediaSegmentIntegrity: true,
    -  }
    -});
    -
    -
  • -
  • -

    serverSyncInfos (Object|undefined):

    -

    Allows to provide a time synchronization mechanism between the client and -the server.

    -

    This value is mainly useful for live DASH contents based on a -SegmentTemplate scheme without SegmentTimeline elements as those rely on -having a synchronized clock on the client side.

    -

    The serverSyncInfos object contains two keys:

    -
      -
    • -

      serverTimestamp (number): Unix timestamp of the server at a given -point in time, in milliseconds.

      -
    • -
    • -

      clientTime (number): Value of the performance.now() API at the time -the serverTimestamp value was true. Please note that if your page contains -multiple worker, the performance.now() call should be done on the same -worker than the one in which loadVideo is called.

      -

      The performance.now() API is used here because it is the main API to -obtain a monotically increasing clock on the client-side.

      -
    • -
    -

    Example:

    -
    const timeResponse = await fetch(timeServerURL);
    -const clientTime = performance.now();
    -const serverTimestamp = await timeResponse.text();
    -const serverSyncInfos = { serverTimestamp, clientTime };
    -rxPlayer.loadVideo({
    -  // ...
    -  transportOptions: { serverSyncInfos }
    -})
    -
    -

    If indicated, we will ignore any time indication on the MPD and only consider -serverSyncInfos to calculate the time on the server side.

    -

    This value is also very useful for low-latency contents, as some of them do not -indicate any server’s time, relying on the client one instead.

    -

    Note that there is a risk of us losing synchronization when leap seconds are -added/substracted to unix time. However we consider those situations rare enough -(and the effect should be relatively weak) to let this as is for the moment. For -a complete explanation, you can look at the corresponding chapter of the -low-latency documentation.

    -
  • -
  • -

    aggressiveMode (boolean|undefined):

    -

    If set to true, we will try to download segments very early, even if we are -not sure they had time to be completely generated.

    -

    For the moment, this mode has only an effect for all Smooth contents and -some DASH contents relying on a number-based SegmentTemplate segment -indexing scheme.

    -

    The upside is that you might have the last segments sooner. -The downside is that requests for segments which did not had time to -generate might trigger a NetworkError. Depending on your other settings -(especially the networkConfig loadVideo options), those errors might just -be sent as warnings and the corresponding requests be retried.

    -

    Example:

    -
    rxPlayer.loadVideo({
    -  // ...
    -  transportOptions: {
    -    aggressiveMode: true,
    -  }
    -});
    -
    -
  • -
  • -

    referenceDateTime (number|undefined):

    -

    Only useful for live contents. This is the default amount of time, in -seconds, to add as an offset to a given media content’s time, to obtain the -real live time.

    -

    For example, if the media has it’s 0 time corresponding to the 30th of -January 2010 at midnight, you can set the referenceDateTime to new Date(2010-01-30) / 1000. This value is useful to communicate back to you -the “live time”, for example through the getWallClockTime method.

    -

    This will only be taken into account for live contents, and if the Manifest -/ MPD does not already contain an offset (example: an -“availabilityStartTime” attribute in a DASH MPD).

    -

    Example:

    -
    rxPlayer.loadVideo({
    -  // ...
    -  transportOptions: {
    -    referenceDateTime: new Date(2015-05-29) / 1000,
    -  }
    -});
    -
    -
  • -
-

-

-

textTrackMode

-

type: string

-

defaults: "native"

-
-

⚠️ This option has no effect in DirectFile mode (see transport -option).

-
-

This option allows to specify how the text tracks should be displayed.

-

There is two possible values:

-
    -
  • "native"
  • -
  • "html"
  • -
-

In the default "native" mode, a <track> element will be created on the -video and the subtitles will be displayed by it, with a minimal style. -There is no action on your side, the subtitles will be correctly displayed at -the right time.

-

In "html" mode, the text tracks will be displayed on a specific HTML -element. This mode allows us to do much more stylisation, such as the one -defined by TTML styling attributes or SAMI’s CSS. It is particularly useful to -correctly manage complex closed captions (with multiple colors, positionning -etc.). -With this mode, you will need to provide a wrapper HTML element with the -textTrackElement option.

-

All text track formats supported in "native" mode also work in "html" -mode.

-

More infos on supported text tracks can be found in the text track -documentation.

-

-

-

textTrackElement

-

type: HTMLElement

-
-

⚠️ This option has no effect in DirectFile mode (see transport -option).

-
-

textTrackElement is only required and used if you provided a "html" -textTrackMode.

-

This property will be the element on which text tracks will be set, as child -elements, at the right time. We expect that this element is the exact same size -than the media element it applies to (this allows us to properly place the -subtitles position without polling where the video is in your UI). -You can however re-size or update the style of it as you wish, to better suit -your UI needs.

-

-

-

audioTrackSwitchingMode

-

type: string

-

defaults: "seamless"

-
-

⚠️ This option has no effect in DirectFile mode (see transport -option).

-
-

Behavior taken by the player when switching to a different audio track, through -the setAudioTrack method.

-

There are two possible values:

-
    -
  • -

    "seamless": The transition between the old audio track and the new one -happens seamlessly, without interruption. -This is the default behavior.

    -

    As an inconvenient, you might have at worst a few seconds in the previous -audio track before the new one can be heard.

    -
  • -
  • -

    "direct": The player will try to switch to the new audio track as soon -as possible, which might lead to an interruption while it is doing so.

    -

    Note that while switching audio track with a "direct" -audioTrackSwitchingMode, it is possible that the player goes into the -"RELOADING" state (during which the video will disappear and many APIs -will become unavailable) to be able to switch to the new track.

    -

    More information about the "RELOADING" state can be found in the -player states documentation.

    -
  • -
-

-

-

manualBitrateSwitchingMode

-

type: string

-

defaults: "seamless"

-
-

⚠️ This option has no effect in DirectFile mode (see transport -option).

-
-

Strategy you want to adopt when updating “manually” the video and audio quality -through respectively the setVideoBitrate and setAudioBitrate API while -the content is playing.

-

There is two possible values:

-
    -
  • -

    "seamless": Manual quality updates will be only visible after a little -time. This gives the advantage of a very smooth “seamless” transition.

    -

    In this mode, you will have the following behavior:

    -
      -
    • there will be no visual “cut” between the previous and new quality
    • -
    • parts of the content with a better (or the same) quality won’t be -replaced.
    • -
    • parts of the content with a lower quality will be only replaced when the -better quality is downloaded.
    • -
    -
  • -
  • -

    "direct": Manual quality updates will be visible more directly, but with -a complete reload of the current content. You might encounter a black screen -while the player go through the "RELOADING" state [1].

    -

    In this mode, you will have the following behavior:

    -
      -
    • there will be a black screen between the previous and new quality
    • -
    • the previous content will be entirely removed
    • -
    • you will only have content with the new quality
    • -
    -

    [1] More information about the "RELOADING" state can be found in the -player states documentation.

    -
  • -
-

-

-

onCodecSwitch

-

type: string

-

defaults: "continue"

-
-

⚠️ This option has no effect in DirectFile mode (see transport -option).

-
-

Behavior taken by the player when switching to either an audio or video track -which has a codec “incompatible” with the previous one (for example going from -avc, a.k.a h264 to hevc, a.k.a. h265).

-

This switch can either after the user switches from one track to another or -after encountering a new Period in some transport technologies (concept existing -for DASH, “local” and MetaPlaylist contents).

-

Can be set to one of those two values:

-
    -
  • -

    "continue": try to have a seamless transition between both codecs. -This behavior works on most modern browsers but might lead to problems like -infinite buffering and decoding errors on older browsers and peculiar -platforms. -This is the default behavior.

    -
  • -
  • -

    "reload": When switching from one codec to another - incompatible - one, -the RxPlayer will “reload” the content: the player will go into the -"RELOADING" state for a small amount of time, during which the video will -disappear and many APIs will become unavailable, before playing the track -with the new codec. -That behavior has the advantage of working on any platform but disadvantage -of having a visible transition when those type of codec switches happen.

    -

    Use it if you have issues with codec switching on some platforms.

    -

    More information about the "RELOADING" state can be found in the -player states documentation.

    -
  • -
-

-

-

lowLatencyMode

-

type: Boolean

-

defaults: false

-

Allow to play DASH low-latency contents (with Chunk-encoded and -chunk-transferred CMAF segments) with a low latency efficiently.

-

In the some rare browsers who do not support the fetch API (like IE11 or the -BlackBerry browser), we might be more prone to rebuffering in that mode the -first few seconds. If you want to have a better experience on those browsers, -you might want to begin to play further from the live edge in those cases -through the startAt option.

-

More information on playing low-latency DASH contents can be found in the -corresponding documentation page.

-

-

-

networkConfig

-

type: Object

-

defaults: {}

-
-

⚠️ This option has no effect in DirectFile mode (see transport -option).

-
-

Configuration linked to Manifest and segment requests. -This object can take the following properties (all are optional):

-
    -
  • -

    segmentRetry (Number): Maximum number of times a segment request -will be retried when an error happen - only on some condition [1].

    -

    Those retry will be done with a progressive delay, to avoid overloading a -CDN. When this count is reached, the player will stop and throw a fatal -error.

    -

    Defaults to 4.

    -
  • -
  • -

    manifestRetry (Number): Maximum number of times a Manifest request -will be retried when a request error happen - only on some condition [1]. -Defaults to 4.

    -

    Those retry will be done with a progressive delay, to avoid overloading a -CDN. When this count is reached, the player will stop and throw a fatal -error.

    -

    Defaults to 4.

    -
  • -
  • -

    offlineRetry (Number): Maximum number of times a request will be -retried when the request fails because the user is offline.

    -

    Those retry will be done with a progressive delay, to avoid overloading the -user’s ressources. When this count is reached, the player will stop and -throw a fatal error.

    -

    Defaults to Infinity.

    -
  • -
-

[1] To retry a request, one of the following condition should be met:

-
    -
  • -

    The request failed because of a 404 HTTP code

    -
  • -
  • -

    The request failed because of an HTTP code in the 500 family

    -
  • -
  • -

    The request failed because of a timeout

    -
  • -
  • -

    the request failed because of an unknown XHR error (might be a -parsing/interface error)

    -
  • -
-

-

-

enableFastSwitching

-

type: boolean

-

defaults: true

-
-

⚠️ This option has no effect in DirectFile mode (see transport -option).

-
-

Enable (when set to true and by default) or disable (when set to false) the -“fast-switching” feature.

-

“Fast-switching” is an optimization which allows the RxPlayer to replace -low-quality segments (i.e. with a low bitrate) with higher-quality segments -(higher bitrate) in the buffer in some situations.

-

This is used for example to obtain a faster quality transition when the user’s -network bandwidth raise up: instead of pushing the new high-quality segments at -the end of the current buffer, we push them much sooner - “on top” of already -pushed low-quality segments - so the user can quickly see the better quality.

-

In most cases, this is a feature you want. On some rare devices however, -replacing segments is poorly supported. -We’ve for example seen on a few devices that old replaced segments were still -decoded (and not the new better-quality segments that should have replaced -them). On other devices, replacing segments resulted in visible small decoding -issues.

-

Setting enableFastSwitching to false thus allows to disable the -fast-switching behavior. Note that it is - sadly - difficult to know when you -need to disable it. -In the great majority of cases, enabling fast-switching (the default behavior) -won’t lead to any problem. So we advise to only disable it when you suspect that -segment replacement when the quality raises is at the source of some issues -you’re having (in which case it will help to see if that’s really the case).

-

It is also important to add that setting enableFastSwitching to false only -disable the fast-switching feature and not all the logic where the RxPlayer is -replacing segments it already pushed to the buffer. -Forbiding the RxPlayer to replace segments altogether is today not possible and -would even break playback in some situations: when multi-Period DASH contents -have overlapping segments, when the browser garbage-collect partially a -segment…

-

-

-

hideNativeSubtitle

-
-

⚠️ This option is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-
-

type: Boolean

-

defaults: false

-
-

⚠️ This option has no effect in DirectFile mode (see transport -option).

-
-

If set to true, the eventual element will be put on mode hidden -when added to the video element, so it won’t actually display the subtitles the -rx-player add to it.

-

This has an effect only if:

-
    -
  • -

    the current textTrackMode is equal to "native" (see textTrackMode -option)

    -
  • -
  • -

    a text track is currently active

    -
  • -
  • -

    the text track format is understood by the rx-player

    -
  • -
-

-

-

supplementaryImageTracks

-
-

⚠️ This option is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-

If you want to parse and display a BIF image track, you can use the -parseBifThumbnails tool, which will also work for -Directfile contents.

-
-

type: Array.<Object>|Object|undefined -defaults: []

-
-

⚠️ This option has no effect in DirectFile mode (see transport -option).

-
-

This option allows to specify information about supplementary image tracks you -might want to add to those already declared in the -Manifest.

-

This only work under the following conditions:

-
    -
  • -

    the image track is not fragmented

    -
  • -
  • -

    the image track can be retrieved by fetching a single URL

    -
  • -
  • -

    the image track is in an understood format and enough information has been -given to infer it.

    -
  • -
-

Each of those can have the following properties:

-
const supplementaryImageTracks = [{
-  url: ImageTrackURL, // {string} The url on which the complete image track can
-                      // be obtained
-
-  mimeType: "application/bif", // {string} A mimeType used to describe
-                               // the image format.
-}];
-
-

-

-

supplementaryTextTracks

-
-

⚠️ This option is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-

If you want to use supplementary text tracks not defined in the content itself, -you can use the TextTrackRenderer(./TextTrackRenderer.md) tool, which will -also work for Directfile contents.

-
-

type: Array.<Object>|Object|undefined -defaults: []

-
-

⚠️ This option has no effect in DirectFile mode (see transport -option).

-
-

This option allows to specify information about supplementary text tracks you -might want to add to those already declared in the -Manifest.

-

This only work under the following conditions:

-
    -
  • -

    the text track is not fragmented

    -
  • -
  • -

    the text track can be retrieved by fetching a single URL

    -
  • -
  • -

    the text track is in an understood format and enough information has been -given to infer it.

    -
  • -
-

Each of those can have the following properties:

-
const supplementaryTextTracks = [{
-  url: textTrackURL, // {string} The url on which the complete text track can be
-                     // obtained
-
-  language: "eng", // {string} The language the text track is in
-                   // (ISO 639-1, ISO 639-2 or ISO 639-3 language code)
-
-                   // Note for SAMI subtitles:
-                   // For SAMI subtitles, you have to provide the same language
-                   // string than the one indicated in the CSS and p elements.
-                   // It usually follows the ISO639-ISO3166 naming conventions
-                   // (e.g. en-US or fr-FR).
-                   // If we cannot find the provided language in the downloaded
-                   // SAMI text track, it won't be displayed.
-
-  closedCaption: false // {Boolean} Whether the text track is a closed caption
-                       // for the hard of hearing
-
-  mimeType: "application/mp4", // {string} A mimeType used to describe
-                               // the text format. Can be "application/mp4" when
-                               // encapsulated in an mp4 file. In that case, the
-                               // "codecs" argument will be needed.
-
-  codecs: "stpp"               // {string|undefined} Depending on the mimeType,
-                               // you might need to add codec information.
-                               // Here the mimeType is too generic, the codec
-                               // helps us understand this is ttml in an mp4
-                               // container
-}];
-
-

To know which type of formats are supported and how to add them, you can read -the text track documentation.

-

-

-

defaultAudioTrack

-
-

⚠️ This option is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-

Please use the preferredAudioTracks constructor -option or the -setPreferredAudioTracks method -instead.

-
-

type: Object|string|undefined

-

The starting default audio track.

-

This can be under the form of an object with the following properties:

-
const defaultAudioTrack = {
-  language: "fra", // {string} The wanted language
-                   // (ISO 639-1, ISO 639-2 or ISO 639-3 language code)
-  audioDescription: false // {Boolean} Whether the audio track should be an
-                          // audio description for the visually impaired
-};
-
-

or under the form of the language string directly, in which case the -"audioDescription" option is inferred to be false.

-
// equivalent to the previous example
-const defaultAudioTrack = "fra";
-
-

If the corresponding audio track is not found, the first track defined will be -taken instead.

-
-

⚠️ This option might have no effect in DirectFile mode (see transport -option).

-
-

-

-

defaultTextTrack

-
-

⚠️ This option is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-

Please use the preferredTextTracks constructor -option or the -setPreferredTextTracks method -instead.

-
-

type: Object|string|undefined

-

The starting default text track.

-

This can be under the form of an object with the following properties:

-
const defaultTextTrack = {
-  language: "fra", // {string} The wanted language
-                   // (ISO 639-1, ISO 639-2 or ISO 639-3 language code)
-  closedCaption: false // {Boolean} Whether the text track should be a closed
-                       // caption for the hard of hearing
-};
-
-

or under the form of the language string directly, in which case the -"closedCaption" option is inferred to be false:

-
// equivalent to the previous example
-const defaultTextTrack = "fra";
-
-

If the corresponding text track is not found, the first track defined will be -taken instead.

-
-

⚠️ This option might have no effect in DirectFile mode (see transport -option).

-
-
\ No newline at end of file diff --git a/doc/generated/pages/api/local_manifest.html b/doc/generated/pages/api/local_manifest.html deleted file mode 100644 index 5213ac6dfe..0000000000 --- a/doc/generated/pages/api/local_manifest.html +++ /dev/null @@ -1,656 +0,0 @@ -Local contents (offline playback) - RxPlayer Documentation

-

Local contents (offline playback)

-

-

Preamble

-

The RxPlayer is also able to load downloaded DASH, Smooth, MetaPlaylist or even -HLS (CMAF-based) contents, whether it is for offline playback or just for an -online seamless playback without buffering.

-

This documentation page will be about how to load already downloaded contents. -We suppose the content is already downloaded and that you just want to play it -through the RxPlayer.

-

However, a tool to download DASH/Smooth/MetaPlaylist contents compatible to this -API is under way.

-

-

Overview

-

To play contents stored locally, the RxPlayer uses its own Manifest format - the -“local manifest” which is close in semantics to DASH’s own Manifest file, the -MPD.

-

This new Manifest format will be the only element you will need to generate on -your side to play stored contents. As such, this what most of this documentation -page is about.

-

Note that the wanted content does not need to be completely downloaded before -creating this local manifest. Playback can even begin while the content is -still downloading.

-

You will just need to:

-
    -
  1. indicate that this is a “local” content by setting the transport option -in loadVideo to "local"
  2. -
  3. As the generated Manifest object most likely won’t be available through an -URL but directly as a JavaScript object, you will need to communicate it -through the manifestLoader property in the transportOptions loadVideo -option.
  4. -
-

Here is an example:

-
rxPlayer.loadVideo({
-  transport: "local",
-  transportOptions: {
-    // Note: `_url` here will be `undefined`
-    manifestLoader(_url, callbacks) {
-      // where `localManifest` is the local Manifest in object form
-      callbacks.resolve({ data: localManifest });
-    }
-  }
-  // ...
-});
-
-

More infos on the manifestLoader can be found -here.

-

-

How to import this feature

-

The "LOCAL_MANIFEST" feature is not included in the default RxPlayer build.

-

There’s two way you can import it, depending on if you’re relying on the minimal -version or if you prefer to make use of environment variables and build the -player manually.

-

Through the minimal version of the RxPlayer

-

If you’re using the “minimal” version of the RxPlayer (through the -"rx-player/minimal" import), you will need to import the LOCAL_MANIFEST -experimental feature:

-
import RxPlayer from "rx-player/minimal";
-import { LOCAL_MANIFEST } from "rx-player/experimental/features";
-
-RxPlayer.addFeatures([LOCAL_MANIFEST]);
-
-

Through environment variables

-

If you don’t want to go the minimal version’s route and you have no problem with -building yourself a new version of the RxPlayer, you can make use of environment -variables to activate it.

-

This can be done through the RXP_LOCAL_MANIFEST environment variable, which -you have to set to true:

-
RXP_LOCAL_MANIFEST=true npm run build:min
-
-

More information about any of that can be found in the minimal player -documentation.

-

-

The Manifest format

-

As explained in the overview, offline playback by the RxPlayer mainly rely on a -specific sort of manifest, called the “local manifest”.

-

It is not the task of the RxPlayer to download and store the content here (a -tool to do just that is on its way), this page only explains how to play a -stored content once it has been stored.

-

The local manifest looks like a DASH MPD in its structure and as such is very -hierarchical.

-

It has the following structure:

-
manifest Object
-  ...manifest properties
-  period Object
-    ...period properties
-    adaptation Object
-      ...adaptation properties
-      representation Object
-        ...representation properties
-
-

We will go progressively from the elements higher in the hierarchy (the manifest -object) to the lower ones (the representation Object).

-

-

The manifest Object

-

The manifest object describes information about the whole local content:

-
    -
  • its duration
  • -
  • whether it is still downloading or if its completely available
  • -
  • the different “parts” (or “periods”) the content is divided in
  • -
-

First, let’s go into an example, before describing what each property is for:

-
{
-  type: "local", // always set to "local"
-  version: "0.2", // version number, in a MAJOR.MINOR form
-  minimumPosition: 0, // Minimum possible reachable position in the content,
-                      // in seconds
-  maximumPosition: 120, // Maximum possible reachable position in the content,
-                        // in seconds
-  isFinished: true, // if `false`, the content is still downloading
-  periods: [ // different "periods" in the content - see below
-    // ...
-  ],
-}
-
-

As you can see, it is a simple JavaScript object with few properties we’re going -to dive into just now.

-

-

properties

-

Here is the description about all the properties encountered in a local manifest -object:

-
    -
  • -

    type (string): Must be set to "local". This property indicates to the -RxPlayer that the current content is a local manifest.

    -
  • -
  • -

    version (string): Version number, in a MAJOR.MINOR form. -The present documentation is for the "0.2" version.

    -

    A parser for a version with the a given MAJOR version should be able to -parse and play contents for any of the corresponding MINOR versions.

    -

    The exception is the 0 MAJOR version (i.e. experimental versions). -A parser for a version with that major (let’s say 0.1) might be unable to -parse local Manifests of another version (e.g. 0.2).

    -
  • -
  • -

    minimumPosition (number|undefined): Optional minimum position reachable in -this content once it has been fully loaded, in seconds.

    -

    If not set or set to undefined, the RxPlayer will assume that the content -starts at a 0 position.

    -
  • -
  • -

    maximumPosition (number): Maximum position reachable in this content once -it has been fully loaded, in seconds.

    -
  • -
  • -

    isFinished (boolean): true indicates that the content has been -completely downloaded and can now be played as a whole. false indicates -that the whole content is not available yet and that the RxPlayer may have -to refresh the local manifest while playing (to get the new data).

    -
  • -
  • -

    periods (Array.<Object>): The different “periods” available in the -content. We will explain what a “period” is in the following chapter.

    -
  • -
  • -

    expired (Promise.<undefined>|undefined): Optional Promise which should -resolve when a newer local manifest is available.

    -

    This is for example useful when playing a content which is still -downloading. Here expired could resolve once a new segment is available, -the RxPlayer would then request the new local manifest (through the same API -than for the initial request, e.g. through the manifestLoader property -indicated in loadVideo) and would obtain a new local manifest with this -new segment included and a new expired property set. -This can go on until the content is completely downloaded at which time -expired can be set to undefined or just omitted from the last local -manifest.

    -
  • -
-

-

The period object

-

As seen in the previous chapter, the local manifest contains a periods -property. The concept of period comes from DASH and allow to separate a content -into multiple sub-parts, each with their own configurations.

-

For example, you could have in the same content a TV Show in german followed by -an american film, each with its own language choices and qualities.

-

If you don’t need that kind of granularity, you can just create a single period -for your local manifest.

-

Here’s an example of a period object:

-
{
-  start: 10, // starting position in the whole content, in seconds
-  end: 20, // ending position, in seconds
-  adaptations: [ // available tracks for this period
-    // ***
-  ]
-}
-
-

In the context of a local manifest with multiple periods, here is how it can -look like:

-
{
-  type: "local",
-  version: "0.2",
-  minimumPosition: 0,
-  maximumPosition: 60,
-  isFinished: true,
-  periods: [ // Here we have 3 consecutive periods:
-    {
-      start: 0,
-      end: 10,
-      adaptations: [ /* ... */ ]
-    },
-    {
-      start: 10,
-      end: 30,
-      adaptations: [ /* ... */ ]
-    },
-    {
-      start: 30,
-      end: 60,
-      adaptations: [ /* ... */ ]
-    },
-  ],
-}
-
-

-

properties

-

The following properties are found in a period object:

-
    -
  • -

    start (number): The position in seconds at which the period starts.

    -
  • -
  • -

    end (number): The position in seconds at which the period ends.

    -
  • -
  • -

    adaptations (Array.<Object>): The different tracks available. See below -for more information.

    -
  • -
-

-

the adaptation object

-

An adaptation is roughly a “track” of the content. It can for the moment be one -of those three types:

-
    -
  • “audio”
  • -
  • “video”
  • -
  • “text” (subtitles)
  • -
-

The form of the adaptation object depends on the type of track. Let’s just start -with a simple video track example:

-
{
-  type: "video",
-  language: "eng", // optional language code
-  representations: [ // describes the different available qualities
-    // ...
-  ]
-}
-
-

Let’s continue with an audio track example:

-
{
-  type: "audio",
-  language: "fra", // language code for this audio track
-  audioDescription: false, // if `true`, that audio track is a track adapted for
-                           // the visually impaired
-  representations: [ /* ... */ ]
-}
-
-

We’ll finish with a text track example:

-
{
-  type: "text",
-  language: "fra", // language code for this audio track
-  closedCaption: false, // if `true`, that text track contains supplementary
-                        // cues about the audio content (generally used for the
-                        // hard of hearing)
-  representations: [ /* ... */ ]
-}
-
-

Here how it looks when adaptations are integrated in a given period:

-
{
-  start: 0,
-  end: 10,
-  adaptations: [
-    {
-      type: "video",
-      representations: [ /* ... */ ],
-    },
-    {
-      type: "audio",
-      language: "eng",
-      audioDescription: false,
-      representations: [ /* ... */ ]
-    },
-    {
-      type: "audio",
-      language: "fra",
-      audioDescription: false,
-      representations: [ /* ... */ ]
-    },
-    {
-      type: "audio",
-      language: "fra",
-      audioDescription: true,
-      representations: [ /* ... */ ]
-    },
-    {
-      type: "text",
-      language: "fra",
-      closedCaption: false,
-      representations: [ /* ... */ ]
-    },
-    {
-      type: "text",
-      language: "fra",
-      closedCaption: true,
-      representations: [ /* ... */ ]
-    }
-  ]
-},
-
-

Let’s now describes precizely every properties encountered here.

-

-

properties

-

The following properties are found in an adaptation object:

-
    -
  • -

    type (string): The “type” of the current adaptation. Can be one of three -strings:

    -
      -
    1. audio
    2. -
    3. video
    4. -
    5. text -The two first ones are straightforward to understand, the third one -designates subtitles.
    6. -
    -
  • -
  • -

    language (string|undefined): When relevant, this string allows to define -the language code for the language the track is in. This is mostly useful -for audio and text adaptations but can also be defined for video tracks.

    -
  • -
  • -

    audioDescription (boolean|undefined): If true, the track contains audio -indications helping to understand what’s on the screen. Mostly useful for -the visually impaired, this property is generally only relevant for audio -tracks.

    -
  • -
  • -

    closedCaption (boolean|undefined): If true, that text track contains -supplementary text cues about the audio content. Mostly useful for the hard -of hearing, this property is generally only relevant for text tracks -helping to understand what’s on the screen. Mostly useful for the visually -impaired, this property is generally only relevant for audio tracks.

    -
  • -
  • -

    representations (Array.<Object>): The different available qualities for -this track. Will be described below.

    -
  • -
-

-

The representation object

-

The representation object will describe the different qualities for a given -track (or adaptation). It will also contains logic to fetch segments -corresponding to that quality. The representation object is very similar to the -Representation element in a DASH MPD.

-

As usual, let’s look into an example.

-
{
-  bitrate: 5000000, // bitrate of the quality, in bits per seconds
-  mimeType: "video/mp4",
-  codecs: "avc1.64001f",
-  width: 1280, // default width of the quality, in pixels.
-               // Mostly relevant for video tracks
-  height: 720, // default height of the quality, in pixels.
-               // Mostly relevant for video tracks
-  index: { // declaration of all the linked segments as well as methods to
-           // retrieve them
-    loadInitSegment(callbacks) { /* ... */  },
-    loadSegment(segment, callbacks) { /* ... */,
-    segments: [ /* ... */ ]
-  }
-}
-
-

For audio tracks, it can looks like:

-
{
-  bitrate: 200000,
-  mimeType: "audio/mp4",
-  codecs: "mp4a.40.5",
-  index: {
-    loadInitSegment(callbacks) { /* ... */  },
-    loadSegment(segment, callbacks) { /* ... */,
-    segments: [ /* ... */ ]
-  }
-}
-
-

At last, an example for text tracks (here ttml in an mp4 container):

-
{
-  bitrate: 3000, // bitrate of the quality, in bits per seconds
-  mimeType: "application/mp4",
-  codecs: "stpp",
-  index: {
-    loadInitSegment(callbacks) { /* ... */  },
-    loadSegment(segment, callbacks) { /* ... */,
-    segments: [ /* ... */ ]
-  }
-}
-
-

We’ll now explain what each property is for, before going deeper into the -index attribute, which allows the RxPlayer to fetch the media segments.

-

-

properties

-
    -
  • -

    bitrate (number): The bitrate the quality is in, in bits per seconds. For -example, a bitrate of 5000000 (5.10^6 == 5 MegaBit) would indicate that each -second of the content does on average a size of 5 MegaBit.

    -
  • -
  • -

    mimeType (string): As its name suggests, this is the appropriate mime-type -for the media. Generally, it is either:

    -
      -
    • "video/mp4" or "video/webm" for a video content (depending on the -container)
    • -
    • "audio/mp4" or "audio/webm" for an audio content (depending on the -container)
    • -
    • "application/mp4" or "text/plain" for a text content (depending on -the container / the absence of container)
    • -
    -
  • -
  • -

    codecs (string): The codec necessary to be able to play the content. The -syntax here is taken from the RFC6381.

    -
  • -
  • -

    width (number|undefined): When relevant (mostly video contents), the width -of the media, in pixels

    -
  • -
  • -

    height (number|undefined): When relevant (mostly video contents), the -height of the media, in pixels

    -
  • -
  • -

    index (object): Object allowing the RxPlayer to know the list of segments -as well as to fetch them. Described in the next chapter.

    -
  • -
-

-

the index object

-

As just seen, the index object is a property of a given representation.

-

it contains itself three properties:

-
    -
  • -

    segments (Array.<Object>): the list of every available media segments for -that representation. Does not include the initialization segment.

    -

    Do not include in this Array the segments that are not downloaded yet.

    -
  • -
  • -

    loadInitSegment (function): Returns the initialization segment or null -if this notion is not relevant, like for subtitles.

    -
  • -
  • -

    loadSegment (function): Returns a specific media segment.

    -
  • -
-

-

the segments array

-

Let’s start by the first one, segments. segments is an array of objects, -each object describing a single segment of media data. Each object has the -following properties:

-
    -
  • time (number): starting position of the segment, in seconds
  • -
  • duration (number): duration of the segment, in seconds
  • -
  • timestampOffset (number|undefined): optional time offset to add to the -segment’s internal time in seconds to convert its media time to its -presentation time, in seconds. -If you don’t know what it is, you will most likely not need it.
  • -
-

Let’s see a simple example with four segments of 2 seconds:

-
[
-  {
-    time: 0,
-    duration: 2
-  },
-  {
-    time: 2,
-    duration: 2
-  },
-  {
-    time: 4,
-    duration: 2
-  },
-  {
-    time: 6,
-    duration: 2
-  }
-]
-
-

-

the loadInitSegment callback

-

The loadInitSegment callback allows the RxPlayer to request the initialization -segment of this representation.

-

Most audio and video representation have an initialization segment which allows -to obtain information about the representation’s data without containing data in -itself. -For text representations, where it is most likely not needed, this callback can -emit null instead of the segment.

-

This callback is given a single argument, which is an object containing -callbacks the function should call either when it has fetched the content or -when it failed on error. There is two callbacks in that object:

-
    -
  • -

    resolve: allows loadInitSegment to communicate the initialization segment -in an ArrayBuffer form. Can call resolve with null if no initialization -segment is available for that representation.

    -
  • -
  • -

    reject: allows loadInitSegment to communicate an error which made the -fetching of the initialization segment impossible.

    -
  • -
-

The loadInitSegment callback can also returns a function which will be called -if the caller want to abort the fetch operation.

-

Here is an example of how a loadInitSegment function can look like:

-
async function loadInitSegment(callbacks) {
-  try {
-    const initSegment = await getStoredInitSegmentForTheCurrentRepresentation();
-    callbacks.resolve(initSegment);
-  } catch (e) {
-    callbacks.reject(e);
-  }
-
-  // Note: in this example, there is no mean to abort the operation, as a result
-  // we do not return a function here
-
-  // // Here is how it would look like if we could:
-  // return function abort() {
-  //   abortStoredInitSegmentRequest();
-  // }
-}
-
-

-

the loadSegment callback

-

The loadSegment callback is the callback called by the RxPlayer when it wants -any segment in the content.

-

Note that the segment data returned by loadSegment should contain all the data -and metadata necessary to play them on the browser. Downloaded DASH segments - -for example - are generally sufficient but segments linked to Smooth contents -should be updated before being returned by loadSegment.

-

This callback is very similar to loadInitSegment with two differences:

-
    -
  • -

    it receives two arguments:

    -
      -
    1. The first being the segment object (from the segments array) of the -segment we want to recuperate. You can generally discriminate which -segment we want from the time property of the given segment, which -should be unique for that representation.
    2. -
    3. The second being the callbacks object, which has the exact same form -than the one in loadInitSegment (two properties resolve and -reject).
    4. -
    -
  • -
  • -

    it cannot return null. It has to return an ArrayBuffer corresponding to -the wanted segment.

    -
  • -
-

Here is an example of how a loadSegment function can look like:

-
async function loadSegment(segment, callbacks) {
-  try {
-    const segmentData = await getStoredSegment(segment);
-    callbacks.resolve(segmentData);
-  } catch (e) {
-    callbacks.reject(e);
-  }
-
-  // Note: in this example, there is no mean to abort the operation, as a result
-  // we do not return a function here
-
-  // // Here is how it would look like if we could:
-  // return function abort() {
-  //   abortStoredSegmentRequest();
-  // }
-}
-
-

-

About DRMs

-

Content with DRMs should be supported as long as the encryption information is -specified in the corresponding containers (e.g. in PSSH boxes for mp4 and other -ISOBMFF containers).

-

We also look into adding supplementary encryption information into the local -manifest format, but this is not available for now.

-

-

Difference with the 0.1 format

-

The previous 0.1 version of the local Manifest is now obsolete and is not -compatible with the new versions of the RxPlayer. -Its documentation can be found here.

-

If you were relying on this version before and would like to switch the the -0.2 version, to be able to play it on newer versions of the RxPlayer, here -is the exhaustive list of what changed:

-
    -
  • -

    a minimumPosition has been added to the “period object”

    -
  • -
  • -

    a maximumPosition has been added to the “period object”

    -
  • -
  • -

    the duration property of the “period object” has been removed

    -
  • -
  • -

    the start property from a “period object” is now expressed in seconds -instead of in milliseconds.

    -
  • -
  • -

    the end property from a “period object” is now expressed in seconds -instead of in milliseconds.

    -
  • -
  • -

    the time property from a segment in the “segments array” is now expressed -in seconds instead of in milliseconds.

    -
  • -
  • -

    the duration property from a segment in the “segments array” is now -expressed in seconds instead of in milliseconds.

    -
  • -
  • -

    the timestampOffset property from a segment in the “segments array” is now -expressed in seconds. In the 0.1 version the unit of time was unclear.

    -
  • -
-
\ No newline at end of file diff --git a/doc/generated/pages/api/local_manifest_v0.1.html b/doc/generated/pages/api/local_manifest_v0.1.html deleted file mode 100644 index f5f8cc445a..0000000000 --- a/doc/generated/pages/api/local_manifest_v0.1.html +++ /dev/null @@ -1,612 +0,0 @@ -Local Manifest format version 0.1 - RxPlayer Documentation

-

Local Manifest format version 0.1

-
-

⚠️ The 0.1 version of the local Manifest format is an old version which -is not properly understood by the RxPlayer anymore.

-

The last version of this specification can be found here.

-
-

-

Preamble

-

The RxPlayer is also able to load downloaded DASH, Smooth, MetaPlaylist or even -HLS (CMAF-based) contents, whether it is for offline playback or just for an -online seamless playback without buffering.

-

This documentation page will be about how to load already downloaded contents. -We suppose the content is already downloaded and that you just want to play it -through the RxPlayer.

-

However, a tool to download DASH/Smooth/MetaPlaylist contents compatible to this -API is under way.

-

-

Overview

-

To play contents stored locally, the RxPlayer uses its own Manifest format - the -“local manifest” which is close in semantics to DASH’s own Manifest file, the -MPD.

-

This new Manifest format will be the only element you will need to generate on -your side to play stored contents. As such, this what most of this documentation -page is about.

-

Note that the wanted content does not need to be completely downloaded before -creating this local manifest. Playback can even begin while the content is -still downloading.

-

You will just need to:

-
    -
  1. indicate that this is a “local” content by setting the transport option -in loadVideo to "local"
  2. -
  3. As the generated Manifest object most likely won’t be available through an -URL but directly as a JavaScript object, you will need to communicate it -through the manifestLoader property in the transportOptions loadVideo -option.
  4. -
-

Here is an example:

-
rxPlayer.loadVideo({
-  transport: "local",
-  transportOptions: {
-    // Note: `_url` here will be `undefined`
-    manifestLoader(_url, callbacks) {
-      // where `localManifest` is the local Manifest in object form
-      callbacks.resolve({ data: localManifest });
-    }
-  }
-  // ...
-});
-
-

More infos on the manifestLoader can be found -here.

-

-

How to import this feature

-

The "LOCAL_MANIFEST" feature is not included in the default RxPlayer build.

-

There’s two way you can import it, depending on if you’re relying on the minimal -version or if you prefer to make use of environment variables and build the -player manually.

-

Through the minimal version of the RxPlayer

-

If you’re using the “minimal” version of the RxPlayer (through the -"rx-player/minimal" import), you will need to import the LOCAL_MANIFEST -experimental feature:

-
import RxPlayer from "rx-player/minimal";
-import { LOCAL_MANIFEST } from "rx-player/experimental/features";
-
-RxPlayer.addFeatures([LOCAL_MANIFEST]);
-
-

Through environment variables

-

If you don’t want to go the minimal version’s route and you have no problem with -building yourself a new version of the RxPlayer, you can make use of environment -variables to activate it.

-

This can be done through the RXP_LOCAL_MANIFEST environment variable, which -you have to set to true:

-
RXP_LOCAL_MANIFEST=true npm run build:min
-
-

More information about any of that can be found in the minimal player -documentation.

-

-

The Manifest format

-

As explained in the overview, offline playback by the RxPlayer mainly rely on a -specific sort of manifest, called the “local manifest”.

-

It is not the task of the RxPlayer to download and store the content here (a -tool to do just that is on its way), this page only explains how to play a -stored content once it has been stored.

-

The local manifest looks like a DASH MPD in its structure and as such is very -hierarchical.

-

It has the following structure:

-
manifest Object
-  ...manifest properties
-  period Object
-    ...period properties
-    adaptation Object
-      ...adaptation properties
-      representation Object
-        ...representation properties
-
-

We will go progressively from the elements higher in the hierarchy (the manifest -object) to the lower ones (the representation Object).

-

-

The manifest Object

-

The manifest object describes information about the whole local content:

-
    -
  • its duration
  • -
  • whether it is still downloading or if its completely available
  • -
  • the different “parts” (or “periods”) the content is divided in
  • -
-

First, let’s go into an example, before describing what each property is for:

-
{
-  type: "local", // always set to "local"
-  version: "0.1", // version number, in a MAJOR.MINOR form
-  duration: 60000, // duration of the whole content, in ms
-  isFinished: true, // if `false`, the content is still downloading
-  periods: [ // different "periods" in the content - see below
-    // ...
-  ],
-}
-
-

As you can see, it is a simple JavaScript object with few properties we’re going -to dive into just now.

-

-

properties

-

Here is the description about all the properties encountered in a local manifest -object:

-
    -
  • -

    type (string): Must be set to "local". This property indicates to the -RxPlayer that the current content is a local manifest.

    -
  • -
  • -

    version (string): Version number, in a MAJOR.MINOR form. -The present documentation is for the "0.1" version.

    -

    A parser for a version with the a given MAJOR version should be able to -parse and play contents for any of the corresponding MINOR versions.

    -

    The exception is the 0 MAJOR version (i.e. experimental versions). -A parser for a version with that major (let’s say 0.1) might be unable to -parse local Manifests of another version (e.g. 0.2).

    -
  • -
  • -

    duration (number): duration of the whole content, in milliseconds. This -means the difference between the absolute maximum position and the absolute -minimum position.

    -
  • -
  • -

    isFinished (boolean): true indicates that the content has been -completely downloaded and can now be played as a whole. false indicates -that the whole content is not available yet and that the RxPlayer may have -to refresh the local manifest while playing (to get the new data).

    -
  • -
  • -

    periods (Array.<Object>): The different “periods” available in the -content. We will explain what a “period” is in the following chapter.

    -
  • -
  • -

    expired (Promise.<undefined>|undefined): Optional Promise which should -resolve when a newer local manifest is available.

    -

    This is for example useful when playing a content which is still -downloading. Here expired could resolve once a new segment is available, -the RxPlayer would then request the new local manifest (through the same API -than for the initial request, e.g. through the manifestLoader property -indicated in loadVideo) and would obtain a new local manifest with this -new segment included and a new expired property set. -This can go on until the content is completely downloaded at which time -expired can be set to undefined or just omitted from the last local -manifest.

    -
  • -
-

-

The period object

-

As seen in the previous chapter, the local manifest contains a periods -property. The concept of period comes from DASH and allow to separate a content -into multiple sub-parts, each with their own configurations.

-

For example, you could have in the same content a TV Show in german followed by -an american film, each with its own language choices and qualities.

-

If you don’t need that kind of granularity, you can just create a single period -for your local manifest.

-

Here’s an example of a period object:

-
{
-  start: 10000, // starting position in the whole content, in ms
-  end: 20000, // ending position, in ms
-  adaptations: [ // available tracks for this period
-    // ***
-  ]
-}
-
-

In the context of a local manifest with multiple periods, here is how it can -look like:

-
{
-  type: "local",
-  version: "0.1",
-  duration: 60000,
-  isFinished: true,
-  periods: [ // Here we have 3 consecutive periods:
-    {
-      start: 0,
-      end: 10000,
-      adaptations: [ /* ... */ ]
-    },
-    {
-      start: 10000,
-      end: 30000,
-      adaptations: [ /* ... */ ]
-    },
-    {
-      start: 30000,
-      end: 60000,
-      adaptations: [ /* ... */ ]
-    },
-  ],
-}
-
-

-

properties

-

The following properties are found in a period object:

-
    -
  • -

    start (number): The position in milliseconds at which the period starts.

    -
  • -
  • -

    end (number): The position in milliseconds at which the period ends.

    -
  • -
  • -

    adaptations (Array.<Object>): The different tracks available. See below -for more information.

    -
  • -
-

-

the adaptation object

-

An adaptation is roughly a “track” of the content. It can for the moment be one -of those three types:

-
    -
  • “audio”
  • -
  • “video”
  • -
  • “text” (subtitles)
  • -
-

The form of the adaptation object depends on the type of track. Let’s just start -with a simple video track example:

-
{
-  type: "video",
-  language: "eng", // optional language code
-  representations: [ // describes the different available qualities
-    // ...
-  ]
-}
-
-

Let’s continue with an audio track example:

-
{
-  type: "audio",
-  language: "fra", // language code for this audio track
-  audioDescription: false, // if `true`, that audio track is a track adapted for
-                           // the visually impaired
-  representations: [ /* ... */ ]
-}
-
-

We’ll finish with a text track example:

-
{
-  type: "text",
-  language: "fra", // language code for this audio track
-  closedCaption: false, // if `true`, that text track contains supplementary
-                        // cues about the audio content (generally used for the
-                        // hard of hearing)
-  representations: [ /* ... */ ]
-}
-
-

Here how it looks when adaptations are integrated in a given period:

-
{
-  start: 0,
-  end: 10000,
-  adaptations: [
-    {
-      type: "video",
-      representations: [ /* ... */ ],
-    },
-    {
-      type: "audio",
-      language: "eng",
-      audioDescription: false,
-      representations: [ /* ... */ ]
-    },
-    {
-      type: "audio",
-      language: "fra",
-      audioDescription: false,
-      representations: [ /* ... */ ]
-    },
-    {
-      type: "audio",
-      language: "fra",
-      audioDescription: true,
-      representations: [ /* ... */ ]
-    },
-    {
-      type: "text",
-      language: "fra",
-      closedCaption: false,
-      representations: [ /* ... */ ]
-    },
-    {
-      type: "text",
-      language: "fra",
-      closedCaption: true,
-      representations: [ /* ... */ ]
-    }
-  ]
-},
-
-

Let’s now describes precizely every properties encountered here.

-

-

properties

-

The following properties are found in an adaptation object:

-
    -
  • -

    type (string): The “type” of the current adaptation. Can be one of three -strings:

    -
      -
    1. audio
    2. -
    3. video
    4. -
    5. text -The two first ones are straightforward to understand, the third one -designates subtitles.
    6. -
    -
  • -
  • -

    language (string|undefined): When relevant, this string allows to define -the language code for the language the track is in. This is mostly useful -for audio and text adaptations but can also be defined for video tracks.

    -
  • -
  • -

    audioDescription (boolean|undefined): If true, the track contains audio -indications helping to understand what’s on the screen. Mostly useful for -the visually impaired, this property is generally only relevant for audio -tracks.

    -
  • -
  • -

    closedCaption (boolean|undefined): If true, that text track contains -supplementary text cues about the audio content. Mostly useful for the hard -of hearing, this property is generally only relevant for text tracks -helping to understand what’s on the screen. Mostly useful for the visually -impaired, this property is generally only relevant for audio tracks.

    -
  • -
  • -

    representations (Array.<Object>): The different available qualities for -this track. Will be described below.

    -
  • -
-

-

The representation object

-

The representation object will describe the different qualities for a given -track (or adaptation). It will also contains logic to fetch segments -corresponding to that quality. The representation object is very similar to the -Representation element in a DASH MPD.

-

As usual, let’s look into an example.

-
{
-  bitrate: 5000000, // bitrate of the quality, in bits per seconds
-  mimeType: "video/mp4",
-  codecs: "avc1.64001f",
-  width: 1280, // default width of the quality, in pixels.
-               // Mostly relevant for video tracks
-  height: 720, // default height of the quality, in pixels.
-               // Mostly relevant for video tracks
-  index: { // declaration of all the linked segments as well as methods to
-           // retrieve them
-    loadInitSegment(callbacks) { /* ... */  },
-    loadSegment(segment, callbacks) { /* ... */,
-    segments: [ /* ... */ ]
-  }
-}
-
-

For audio tracks, it can looks like:

-
{
-  bitrate: 200000,
-  mimeType: "audio/mp4",
-  codecs: "mp4a.40.5",
-  index: {
-    loadInitSegment(callbacks) { /* ... */  },
-    loadSegment(segment, callbacks) { /* ... */,
-    segments: [ /* ... */ ]
-  }
-}
-
-

At last, an example for text tracks (here ttml in an mp4 container):

-
{
-  bitrate: 3000, // bitrate of the quality, in bits per seconds
-  mimeType: "application/mp4",
-  codecs: "stpp",
-  index: {
-    loadInitSegment(callbacks) { /* ... */  },
-    loadSegment(segment, callbacks) { /* ... */,
-    segments: [ /* ... */ ]
-  }
-}
-
-

We’ll now explain what each property is for, before going deeper into the -index attribute, which allows the RxPlayer to fetch the media segments.

-

-

properties

-
    -
  • -

    bitrate (number): The bitrate the quality is in, in bits per seconds. For -example, a bitrate of 5000000 (5.10^6 == 5 MegaBit) would indicate that each -second of the content does on average a size of 5 MegaBit.

    -
  • -
  • -

    mimeType (string): As its name suggests, this is the appropriate mime-type -for the media. Generally, it is either:

    -
      -
    • "video/mp4" or "video/webm" for a video content (depending on the -container)
    • -
    • "audio/mp4" or "audio/webm" for an audio content (depending on the -container)
    • -
    • "application/mp4" or "text/plain" for a text content (depending on -the container / the absence of container)
    • -
    -
  • -
  • -

    codecs (string): The codec necessary to be able to play the content. The -syntax here is taken from the RFC6381.

    -
  • -
  • -

    width (number|undefined): When relevant (mostly video contents), the width -of the media, in pixels

    -
  • -
  • -

    height (number|undefined): When relevant (mostly video contents), the -height of the media, in pixels

    -
  • -
  • -

    index (object): Object allowing the RxPlayer to know the list of segments -as well as to fetch them. Described in the next chapter.

    -
  • -
-

-

the index object

-

As just seen, the index object is a property of a given representation.

-

it contains itself three properties:

-
    -
  • -

    segments (Array.<Object>): the list of every available media segments for -that representation. Does not include the initialization segment.

    -

    Do not include in this Array the segments that are not downloaded yet.

    -
  • -
  • -

    loadInitSegment (function): Returns the initialization segment or null -if this notion is not relevant, like for subtitles.

    -
  • -
  • -

    loadSegment (function): Returns a specific media segment.

    -
  • -
-

-

the segments array

-

Let’s start by the first one, segments. segments is an array of objects, -each object describing a single segment of media data. Each object has the -following properties:

-
    -
  • time (number): starting position of the segment, in milliseconds
  • -
  • duration (number): duration of the segment, in milliseconds
  • -
  • timestampOffset (number|undefined): optional time offset to add to the -segment’s internal time to convert its media time to its presentation time, -in milliseconds. -If you don’t know what it is, you will most likely not need it.
  • -
-

Let’s see a simple example with four segments of 2 seconds:

-
[
-  {
-    time: 0,
-    duration: 2000
-  },
-  {
-    time: 2000,
-    duration: 2000
-  },
-  {
-    time: 4000,
-    duration: 2000
-  },
-  {
-    time: 6000,
-    duration: 2000
-  }
-]
-
-

-

the loadInitSegment callback

-

The loadInitSegment callback allows the RxPlayer to request the initialization -segment of this representation.

-

Most audio and video representation have an initialization segment which allows -to obtain information about the representation’s data without containing data in -itself. -For text representations, where it is most likely not needed, this callback can -emit null instead of the segment.

-

This callback is given a single argument, which is an object containing -callbacks the function should call either when it has fetched the content or -when it failed on error. There is two callbacks in that object:

-
    -
  • -

    resolve: allows loadInitSegment to communicate the initialization segment -in an ArrayBuffer form. Can call resolve with null if no initialization -segment is available for that representation.

    -
  • -
  • -

    reject: allows loadInitSegment to communicate an error which made the -fetching of the initialization segment impossible.

    -
  • -
-

The loadInitSegment callback can also returns a function which will be called -if the caller want to abort the fetch operation.

-

Here is an example of how a loadInitSegment function can look like:

-
async function loadInitSegment(callbacks) {
-  try {
-    const initSegment = await getStoredInitSegmentForTheCurrentRepresentation();
-    callbacks.resolve(initSegment);
-  } catch (e) {
-    callbacks.reject(e);
-  }
-
-  // Note: in this example, there is no mean to abort the operation, as a result
-  // we do not return a function here
-
-  // // Here is how it would look like if we could:
-  // return function abort() {
-  //   abortStoredInitSegmentRequest();
-  // }
-}
-
-

-

the loadSegment callback

-

The loadSegment callback is the callback called by the RxPlayer when it wants -any segment in the content.

-

Note that the segment data returned by loadSegment should contain all the data -and metadata necessary to play them on the browser. Downloaded DASH segments - -for example - are generally sufficient but segments linked to Smooth contents -should be updated before being returned by loadSegment.

-

This callback is very similar to loadInitSegment with two differences:

-
    -
  • -

    it receives two arguments:

    -
      -
    1. The first being the segment object (from the segments array) of the -segment we want to recuperate. You can generally discriminate which -segment we want from the time property of the given segment, which -should be unique for that representation.
    2. -
    3. The second being the callbacks object, which has the exact same form -than the one in loadInitSegment (two properties resolve and -reject).
    4. -
    -
  • -
  • -

    it cannot return null. It has to return an ArrayBuffer corresponding to -the wanted segment.

    -
  • -
-

Here is an example of how a loadSegment function can look like:

-
async function loadSegment(segment, callbacks) {
-  try {
-    const segmentData = await getStoredSegment(segment);
-    callbacks.resolve(segmentData);
-  } catch (e) {
-    callbacks.reject(e);
-  }
-
-  // Note: in this example, there is no mean to abort the operation, as a result
-  // we do not return a function here
-
-  // // Here is how it would look like if we could:
-  // return function abort() {
-  //   abortStoredSegmentRequest();
-  // }
-}
-
-

-

About DRMs

-

Content with DRMs should be supported as long as the encryption information is -specified in the corresponding containers (e.g. in PSSH boxes for mp4 and other -ISOBMFF containers).

-

We also look into adding supplementary encryption information into the local -manifest format, but this is not available for now.

-
\ No newline at end of file diff --git a/doc/generated/pages/api/low_latency.html b/doc/generated/pages/api/low_latency.html deleted file mode 100644 index 4ea2e8f987..0000000000 --- a/doc/generated/pages/api/low_latency.html +++ /dev/null @@ -1,179 +0,0 @@ -Playing Low-Latency contents - RxPlayer Documentation

-

Playing Low-Latency contents

-

-

Overview

-

The RxPlayer can play DASH contents specifically crafted to be played with a -low latency (read close to the live edge) through a technology called something -along the lines of “Chunked-encoded CMAF and Chunked transfer encoding”.

-

Such contents are backward-compatible DASH contents (meaning they can be played -in a regular non-low-latency way) which serves CMAF segment with an HTTP 1.1 -transfer mechanism called “Chunked transfer encoding”.

-

To vulgarize, such segments are divided into multiple chunks which can be -requested while the whole segment is still being encoded - through Chunked -transfer encoding HTTP requests.

-

If you want more information on this technology, the best for us is probably to -redirect you to the multiple resources you can probably find with your favorite -search engine!

-

-

How to play a low latency content

-

-

lowLatencyMode option

-

To play a low-latency DASH content with - well - a low latency, you will need -to set the lowLatencyMode loadVideo option.

-
rxPlayer.loadVideo({
-  url: "https://www.example.com/low-latency-content.mpd",
-  transport: "dash",
-  lowLatencyMode: true,
-})
-
-

When set, this option will perform multiple optimizations specific to -low-latency contents. For live contents:

-
    -
  • -

    it will by default play much closer to the live edge

    -
  • -
  • -

    it will begin to play faster and seek in non-buffered parts faster

    -
  • -
  • -

    it will do safer choices when choosing the right video / audio quality (to -avoid the higher chances of rebuffering)

    -
  • -
  • -

    the delay we use when retrying a failed segment or manifest request will be -lower

    -
  • -
  • -

    and multiple other minor optimizations

    -
  • -
-

Note that you can also set the lowLatencyMode mode for VoD (non-live) -contents. -In that case, the main advantage would be to be able to play and seek faster as -long as the content is compatible (again, with CMAF and Chunked Transfer -Encoding).

-

-

Playing even closer to the live edge!

-

By default, we set a distance of 3.5 seconds relative to the live edge when we -start a low latency content.

-

We found that value to be just at the right boundary between rebuffering risks, -and delay to the live edge.

-

However, you can still provide a lower distance through the startAt -loadVideo option (documented here):

-
rxPlayer.loadVideo({
-  url: "https://www.example.com/content.mpd",
-  transport: "dash",
-  lowLatencyMode: true,
-  startAt: { fromLastPosition: 2 }, // Play 2 seconds from the live edge instead
-                                    // (beware of much more frequent rebuffering
-                                    // risks)
-})
-
-

-

-

Note about time synchronization

-

In most cases, DASH low-latency contents rely on time synchronization between -the server and the client without providing a synchronization mechanism.

-

This means that, on poorly configurated client (with bad clock settings), you -could lose latency or worse: obtain playback issues.

-

To work around that problem, the RxPlayer allows you to provide a -synchronization mechanism to loadVideo. This is done through the -serverSyncInfos transportOptions. Which itself is a loadVideo option.

-

TL;DR You can look at the API -documentation for a quick -explanation of what to put in it.

-
-

Here how it works:

-

Imagine you have an URL allowing you to know the UTC time on the server’s side. -Let’s call it serverTimeURL.

-

Now you can have the server’s time at a particular point in time (!). The -problem is that time continously changes: a time synchronization mechanism will -have to be aware of how much time passed since the last request to obtain that -time.

-

We could asks for the client’s timestamp - obtained thanks to the Date.now() -API - at the time of the request. -This would allow us to know how much time have passed since that event by -calling Date.now() again in the future and calculating the difference. -The problem however is that Date.now() will instantly change if the user -updates its system clock. If that happens, we will lose the ability to know how -much time has elapsed since the request.

-

To workaround this issue, we can use instead performance.now(), which does not -rely on the system’s clock. -However, we are still left with two other issues:

-
    -
  1. -

    performance.now() comparisons are useful only if both values were -obtained in the same JS worker. -So we have to make sure each performance.now() call is done in the same -worker.

    -
  2. -
  3. -

    performance.now() doesn’t integrate the notion of leap seconds whereas -unix time (the server’s time) does. This could mean small time -de-synchronization when leap seconds are added or substracted.

    -
  4. -
-

We however consider those last two problems minor when compared to -Date.now()'s problem (which is the fact that it “breaks” if the system clock -is updated). If you would prefer to provide Date.now() anyway, you can open -an issue and we will think about a possible implementation.

-

So we now have two values:

-
    -
  • serverTimestamp (number): Unix timestamp of the server at a given -point in time.
  • -
  • clientTime (number): Value of the performance.now() API at the -time the serverTimestamp value was true. Please note that if your page -contains multiple worker, the performance.now() call should be done on -the same worker than the one in which loadVideo is called.
  • -
-

Those two values can be combined in the serverSyncInfos option like this:

-
const timeResponse = await fetch(serverTimeURL);
-const serverTimestamp = await timeResponse.text();
-const clientTime = performance.now();
-const serverSyncInfos = { serverTimestamp, clientTime };
-rxPlayer.loadVideo({
-  // ...
-  transportOptions: { serverSyncInfos }
-})
-
-

-

Note about rebuffering and other delay-creating situations

-

When playing in low latency mode, it is still possible to rebuffer or pause the -content, which could lead the user to being far from the live edge.

-

As several applications could want several workaround to that possible issue -(like updating the speed, seeking or just signaling the delay to the user), we -choose to let that happen by default with the RxPlayer.

-

As an example, ou demo page choose the following strategy for now:

-
    -
  • -

    When falling between 6 to 15 seconds behind the live edge, the playback rate -is updated proportionally to our delay until we reach 3 seconds behind the -live edge.

    -
  • -
  • -

    When falling to 15 seconds behind the live edge or more, we will simply seek -to 3 seconds behind the live edge.

    -
  • -
  • -

    When seeking manually or pausing, this logic is disabled (with the -possibility to re-enable it).

    -
  • -
-

The live edge is obtainable through the rxPlayer.getMaximumPosition() API, -the current position thanks to the rxPlayer.getPosition() API. The distance to -the live edge is thus easily computable:

-
rxPlayer.getMaximumPosition() - rxPlayer.getPosition()
-
-
\ No newline at end of file diff --git a/doc/generated/pages/api/manifest.html b/doc/generated/pages/api/manifest.html deleted file mode 100644 index 32f87e4244..0000000000 --- a/doc/generated/pages/api/manifest.html +++ /dev/null @@ -1,312 +0,0 @@ -Manifest Object - RxPlayer Documentation

-

Manifest Object

-

-

-

Overview

-

A Manifest Object and its sub-parts are data structures returned by multiple -APIs of the player.

-

Its data represents the corresponding streaming protocol’s -Manifest equivalent (MPD for DASH, Manifest for -Microsoft Smooth Streaming etc.).

-

Basically, the structure of a Manifest file has the following hierarchy:

-
Manifest Object
-  ...Manifest data and methods
-  Period Object
-    ...Period properties
-    Adaptation Object
-      ...Adaptation data and methods
-      Representation Object
-        ...Representation data and methods
-        RepresentationIndex Object
-          ...RepresentationIndex data and methods
-            SegmentObject
-            ...SegmentObject data
-
-

Due to this highly hierachical structure, each level will be described in its -own chapter here.

-

⚠️ Like in the rest of this documentation, any variable or method not -defined here can change without notice.

-

Only use the documented variables and open an issue if you think it’s not -enough.

-

-

-

Structure of a Manifest Object

-

The manifest Object represents the Manifest file of the -content loaded.

-

-

-

properties

-

The manifest Object has the following properties.

-

periods

-

type: Array.<Period>

-

A single Manifest instance can contain multiple Periods, -which are periods of time for which the list of available type of contents -(audio tracks, subtitles, video tracks…) can be different.

-

Such example of Periods could be multiple Programs of a live contents, which can -be each in different languages, for example.

-

The player will switch smoothly across subsequent Periods within playback.

-

Most Streaming technologies (e.g. HLS and Smooth) do not have a “Period” -concept. For those, the Manifest will only have one Period for the whole -content.

-

adaptations

-
-

⚠️ This property is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-
-

type: Object

-

Adaptation objects for the first Period.

-

Both of those lines have the same effect:

-
console.log(manifest.adaptations);
-console.log(manifest.periods[0].adaptations);
-
-

See the Period chapter for more information on Adaptations.

-

isLive

-

type: Boolean

-

true if the content is a “live” content (e.g. a live TV Channel). -false otherwise.

-

uris

-

type: Array.<string>

-

The list of uris that can be used to refer to the Manifest file.

-

transport

-

type: string

-

The type of transport used. For now, this can only be equal to either dash -or smooth.

-

-

-

Structure of a Period Object

-

A Period is an object describing what to play during a certain time periods.

-

A Manifest can have a single Period, which means that the played content do not -change its characteristics (same languages, same bitrates etc.) or multiple -ones.

-

A good example of a content with multiple Periods would be a live channel -broadcasting multiple foreign films. Each film, being in a different language, -will need to be part of a new Period.

-

-

-

properties

-

id

-

type: string

-

This id should be a string unique to that Period. It serves identifications -purpose, when updating the Manifest for example.

-

start

-

type: Number

-

Start time at which the Period begins in the whole content, in seconds.

-

end

-

type: Number|undefined

-

End time at which the Period ends in the whole content, in seconds.

-

If not set or set to undefined, it means that the end is unknown, in which case -it is the current last content of the current Manifest.

-

adaptations

-

type: Object

-

The Adaptations (tracks if you want) for the current -content, per-type (audio/video/text/image).

-

See the Adaptation chapter for more info about an Adaptation’s -structure.

-

The Adaptation object can contain any of the following keys:

-
    -
  • audio (Array.<Adaptation>): The audio Adaptation(s) available.
  • -
  • video (Array.<Adaptation>): The video Adaptation(s) available.
  • -
  • text (Array.<Adaptation>): The text Adaptation(s) available.
  • -
  • image (Array.<Adaptation>): The image Adaptation(s) available.
  • -
-

-

-

Structure of an Adaptation Object

-

An Adaptation is a set of streams representing the -exact same contents in multiple forms (different sizes, different bitrates…). -Concretely, a frequent usecase is to have a single video Adaptation and multiple -audio ones, one for each language available.

-

As such, it is also often called in the API a track.

-

-

-

properties

-

id

-

type: string

-

This id should be a string unique to that Adaptation. It serves -identifications purpose, when updating the Manifest for example.

-

type

-

type: string

-

The type of the Adaptation. The possible types are:

-
    -
  • "video"
  • -
  • "audio"
  • -
  • "text"
  • -
  • "image"
  • -
-

language

-

type: string|undefined

-

The language of the Adaptation. This is particularly useful for audio and text -Adaptations.

-

Note that this property is not always present in an Adaptation.

-

normalizedLanguage

-

type: string|undefined

-

An attempt to translate the language of the Adaptation into an ISO 639-3 code. -If the translation attempt fails (no corresponding ISO 639-3 language code is -found), it will equal the value of language

-

Note that this property is not always present in an Adaptation.

-

isAudioDescription

-

type: Boolean|undefined

-

This property only makes sense for audio Adaptations. In this case, if true -it means that the audio track has added commentaries for the visually impaired.

-

isClosedCaption

-

type: Boolean|undefined

-

This property only makes sense for text Adaptations. In this case, if true -it means that the text track has added hints for the hard of hearing.

-

representations

-

type: Array.<Representation>

-

The Represesentations for this Adaptation.

-

See the Representation chapter for more info about a -Representation’s structure.

-

-

-

methods

-

getAvailableBitrates

-

return value: Array.<Number>

-

Returns every bitrates available for this Adaptation.

-

-

-

Structure of a Representation Object

-

A Representation is an -Adaptation encoded in a certain way. It is defined by -multiple values (a codec, a bitrate). Only some of them are documented here (as -stated before, open an issue if you would like to access other properties).

-

-

-

properties

-

id

-

type: string

-

This id should be a string unique to that Representation.

-

bitrate

-

type: Number

-

The bitrate of the Representation.

-

codec

-

type: string|undefined

-

The codec of the Representation.

-

decipherable

-

type: boolean|undefined

-

Whether we are able to decrypt this Representation / unable to decrypt it or -if we don’t know yet:

-
    -
  • if true, it means that we know we were able to decrypt this -Representation in the current content.
  • -
  • if false, it means that we know we were unable to decrypt this -Representation
  • -
  • if undefined there is no certainty on this matter
  • -
-

height

-

type: Number|undefined

-

This property makes the most sense for video Representations. -It defines the height of the video, in pixels.

-

width

-

type: Number|undefined

-

This property makes the most sense for video Representations. -It defines the width of the video, in pixels.

-

index

-

type: RepresentationIndex

-

The represesentation index for this Representation.

-

See the RepresentationIndex chapter for more info about -a RepresentationIndex’s structure.

-

frameRate

-

type: string|undefined

-

The represesentation frame rate for this Representation. It defines either the -number of frames per second as an integer (24), or as a ratio (24000 / 1000).

-

-

-

Structure of a RepresentationIndex Object

-

A RepresentationIndex is an uniform way of declaring the segment index in any -Manifest.

-

That’s the part that calculates which segments will be needed. Because the index -can be different depending on the type of contents/transport most interactions -here are done through few methods which hide the complexity underneath.

-

-

-

methods

-

getSegments

-

arguments:

-
    -
  • -

    up (Number): The position, in seconds from which you want to get the -segment.

    -
  • -
  • -

    duration (Number): The duration in seconds from the asked position

    -
  • -
-

return value: Array.<Segment>

-

Returns the needed segments as defined by the current Manifest during an asked -timeframe.

-

See the Segment chapter for more info about a Segment’s structure.

-

-

-

Structure of a Segment Object

-

A Segment object defines a segment, as generated by the RepresentationIndex.

-

Those segments can have multiple useful properties which for the most part are -described here.

-

-

-

properties

-

id

-

type: string

-

This id should be a string unique to that segment.

-

timescale

-

type: Number

-

The timescale in which the duration and time are expressed.

-

Basically, divide any of those by the timescale to obtain seconds.

-

duration

-

type: Number|undefined

-

The duration, timescaled, of the Segments in s.

-

time

-

type: Number

-

The start time, timescaled, of the Segments in s.

-

isInit

-

type: Boolean|undefined

-

If true, the segment concerned is an init segment.

-

range

-

type: Array.<Number>|null|undefined

-

If defined, it means that the segment is defined in a certain byte range -remotely. In this case, the array contains two elements, the start byte and the -end byte.

-

indexRange

-

type: Array.<Number>|null|undefined

-

If defined, it means that a segment index is defined in a certain byte range -remotely. In this case, the array contains two elements, the start byte and the -end byte.

-

number

-

type: Number|undefined

-

The number of the segment (if numbered), useful with certain types of index.

-
\ No newline at end of file diff --git a/doc/generated/pages/api/mediaCapabilitiesProber.html b/doc/generated/pages/api/mediaCapabilitiesProber.html deleted file mode 100644 index e51419b8a6..0000000000 --- a/doc/generated/pages/api/mediaCapabilitiesProber.html +++ /dev/null @@ -1,502 +0,0 @@ -MediaCapabilitiesProber - RxPlayer Documentation

-

MediaCapabilitiesProber

-

-

Overview

-

The MediaCapabilitiesProber is a tool probing what your browser can do, -especially:

-
    -
  • -

    Which DRM system is supported

    -
  • -
  • -

    Check for HDCP support

    -
  • -
  • -

    which codecs are available

    -
  • -
  • -

    Check the color space support

    -
  • -
-

⚠️ This tool is still in an experimental phase, meaning that its API can -change at any new release. This is not because it is not stable (it is actually) -or should not be used in production. This is just because we want to receive -your feedbacks before locking definitely the API.

-

We can for example add supplementary information of even explode the -MediaCapabilitiesProber into several tools to lower the size of the import. -We’re waiting for your feedbacks!

-

-

How to use it

-

As an experimental tool, the MediaCapabilitiesProber won’t be included in a -default RxPlayer build.

-

Instead, it should be imported by adding the RxPlayer through a dependency -trough the npm registry (e.g. by doing something like npm install rx-player) and then specifically importing this tool from -"rx-player/experimental/tools":

-
import { mediaCapabilitiesProber } from "rx-player/experimental/tools";
-
-mediaCapabilitiesProber.getStatusForHDCP("1.1")
-  .then((hdcp11Status) => {
-    if (hdcp11Status === "Supported") {
-      console.log("HDCP 1.1 is supported");
-    }
-  });
-
-

-

Properties

-

-

LogLevel

-

type: string

-

default: "WARNING"

-

The current level of verbosity for this prober logs. Those logs all use the -console.

-

From the less verbose to the most:

-
    -
  • -

    "NONE": no log

    -
  • -
  • -

    "ERROR": unexpected errors (via console.error)

    -
  • -
  • -

    "WARNING": The previous level + minor problems encountered (via -console.warn)

    -
  • -
  • -

    "INFO": The previous levels + noteworthy events (via console.info)

    -
  • -
  • -

    "DEBUG": The previous levels + normal events of the prober (via -console.log)

    -
  • -
-

If the value set to this property is different than those, it will be -automatically set to "NONE".

-

It is set to "WARNING" by default as it allows you to know if you forgot to -set required information on each APIs, if some APIs are missing in your -browser, etc.

-

You might want to set it to "NONE" when in production.

-

Example

-
import { mediaCapabilitiesProber } from "rx-player/experimental/tools";
-mediaCapabilitiesProber.LogLevel = "NONE";
-
-

-

Functions

-

-

getCompatibleDRMConfigurations

-

arguments:

-
    -
  • -

    keySystems (Array.<Object>): An array of key system -configurations. Those objects have the following properties:

    -
      -
    • -

      type (string): Key system string identifying it in the browser. -Always a reverse domain name (e.g. “org.w3.clearkey”).

      -
    • -
    • -

      configuration (Object): Wanted MediaKeySystemConfiguration for this -key system, as defined in the EME w3c -specification.

      -
    • -
    -
  • -
-

return value: Array.<Object>

-

Probe the support of various key sytems and for each compatible ones, returns -the corresponding configuration that will be used.

-

Return value

-

The returned value is an array of object with the same number of elements than -the one given in argument.

-

It indicates the support for each Key System given in argument in the same -order.

-

Due to that, the objects in this array look like the ones given in argument (but -with an added property):

-
    -
  • -

    type (string): Corresponding key system string given in input.

    -
  • -
  • -

    configuration (Object): Corresponding wanted -MediaKeySystemConfiguration given in input.

    -
  • -
  • -

    compatibleConfiguration (undefined|Object):

    -

    if the type and configuration are both compatible with the browser, this -is the corresponding actual MediaKeySystemConfiguration that will be -effectively used. -It will often correspond to a subset of the inputted configuration -object (for example, you might have there fewer videoCapabilities that -in the configuration object).

    -

    If the type and/or the configuration are not compatible, this property -will not be defined.

    -
  • -
-

Example

-
import { mediaCapabilitiesProber } from "rx-player/experimental/tools";
-
-const mksConfiguration = {
-  initDataTypes: ["cenc"],
-  videoCapabilities: [
-    {
-      contentType: "video/mp4;codecs=\"avc1.4d401e\"", // standard mp4 codec
-      robustness: "HW_SECURE_CRYPTO",
-    },
-    {
-      contentType: "video/mp4;codecs=\"avc1.4d401e\"",
-      robustness: "SW_SECURE_DECODE",
-    }
-  ]
-};
-
-const keySystems = [
-  // Let's consider this one as a compatible key system configuration
-  { type: "com.widevine.alpha", configuration: mksConfiguration },
-
-  // Let's consider this one as not compatible
-  { type: "com.microsoft.playready", configuration: mksConfiguration },
-];
-
-mediaCapabilitiesProber.getCompatibleDRMConfigurations(keySystems)
-  .then((drmConfigs) => {
-    drmConfigs.forEach((config) => {
-      const {
-        type,
-        configuration,
-        compatibleConfiguration
-      } = config;
-
-      if (compatibleConfiguration !== undefined) {
-        console.log("# Compatible configuration #############################");
-        console.log("Key System:", type);
-        console.log("Wanted configuration:", configuration);
-        console.log("Compatible configuration:", compatibleConfiguration);
-        console.log("########################################################");
-        console.log("");
-      } else {
-        console.log("# Incompatible configuration ###########################");
-        console.log("Key System:", type);
-        console.log("Wanted configuration:", configuration);
-        console.log("########################################################");
-        console.log("");
-      }
-    });
-  });
-
-// Example output (please note that in this example, one of the widevine
-// robustness is not supported):
-//
-// # Compatible configuration #############################
-// Key System: com.widevine.alpha
-// Wanted configuration:
-// {
-//   "initDataTypes":["cenc"],
-//   "videoCapabilities": [
-//     {
-//       "contentType": "video/mp4;codecs=\"avc1.4d401e\"",
-//       "robustness": "HW_SECURE_CRYPTO"
-//     },
-//     {
-//       "contentType": "video/mp4;codecs=\"avc1.4d401e\"",
-//       "robustness": "SW_SECURE_DECODE"
-//     }
-//   ]
-// }
-// Compatible configuration:
-// {
-//   "audioCapabilities": [],
-//   "distinctiveIdentifier": "not-allowed",
-//   "initDataTypes": ["cenc"],
-//   "label": "",
-//   "persistentState": "not-allowed",
-//   "sessionTypes": ["temporary"],
-//   "videoCapabilities": [
-//     {
-//       "contentType": "video/mp4;codecs=\"avc1.4d401e\"",
-//       "robustness":"SW_SECURE_DECODE"
-//     }
-//   ]
-// }
-// ########################################################
-//
-// # Incompatible configuration ###########################
-// Key System: com.microsoft.playready
-// Wanted configuration:
-// {
-//   "initDataTypes":["cenc"],
-//   "videoCapabilities": [
-//     {
-//       "contentType": "video/mp4;codecs=\"avc1.4d401e\"",
-//       "robustness": "HW_SECURE_CRYPTO"
-//     },
-//     {
-//       "contentType": "video/mp4;codecs=\"avc1.4d401e\"",
-//       "robustness": "SW_SECURE_DECODE"
-//     }
-//   ]
-// }
-// ########################################################
-
-

-

getStatusForHDCP

-

arguments:

-
    -
  • type (string): The HDCP type (e.g. “1.0”, “1.1” or “2.0”)
  • -
-

return value: string

-

Test for an HDCP configuration.

-

The returned string of this function is either:

-
    -
  • -

    "Supported": This HDCP configuration is supported.

    -
  • -
  • -

    "NotSupported": The HDCP configuration is not supported.

    -
  • -
  • -

    "Unknown": The API is not available or it is but could not check if the -HDCP type is supported.

    -
  • -
-

⚠️ As of the 2018-july-03, this feature is very poorly supported (with only -some support on the EDGE browser). -We should have a real support of it in the coming months on -Chrome and -Firefox.

-

Example

-
import { mediaCapabilitiesProber } from "rx-player/experimental/tools";
-
-mediaCapabilitiesProber.getStatusForHDCP("1.1")
-  .then((hdcpStatus) => {
-    switch (hdcpStatus) {
-      case "Supported":
-        console.log("This HDCP version is supported");
-        break;
-
-      case "NotSupported":
-        console.log("This HDCP version is not supported");
-        break;
-
-      case "Unknown":
-        console.log("We could'nt tell if this HDCP version is supported.");
-        break;
-    }
-  });
-
-

-

getDecodingCapabilities

-

arguments:

-
    -
  • config (Object): Object with type, video and audio configuration.
  • -
-

return value: string

-

Probe for audio/video decoding capabilities.

-

Argument

-

The object in argument is inspired from the concerned API configurations. -All its properties are optional, here are what you can set.

-
    -
  • -

    type (string): The media is either buffered in MediaSource, or -directly as a file. -As such, you can specify which one you want to probe through one of the -following strings:

    -
      -
    • “media-source”
    • -
    • “file”.
    • -
    -
  • -
  • -

    video (Object): The video capabilities you want to probe.

    -
      -
    • contentType (string): Media codec in mimeType format.
    • -
    • width (number): Video width.
    • -
    • height (number): Video Height.
    • -
    • bitrate (number): Bitrate of the video (in bits per second).
    • -
    • framerate (string): Number of frames used in one second.
    • -
    • bitsPerComponent (number): Number of bits used to encode one -component par pixel.
    • -
    -
  • -
  • -

    audio (Object): The video capabilities you want to probe.

    -
      -
    • contentType (string): Media codec in mimeType format.
    • -
    • channels (string): Audio channels used by the track.
    • -
    • bitrate (number): Bitrate from stream (bits/second).
    • -
    • samplerate (number): Number of samples of audio carried per second.
    • -
    -
  • -
-

Return value

-

The returned string of this function is either:

-
    -
  • -

    "Supported": This configuration is supported.

    -
  • -
  • -

    "MaybeSupported": Some set configuration could not be probed because -not enough information was provided, but what has been probed is supported.

    -
  • -
  • -

    "NotSupported": The configuration is not supported.

    -
  • -
-

Example

-
import { mediaCapabilitiesProber } from "rx-player/experimental/tools";
-
-mediaCapabilitiesProber.getDecodingCapabilities({
-  type: "media-source",
-  video: {
-    contentType: "video/webm; codecs=\"vp09.00.10.08\"",
-    width: 1920,
-    height: 1080,
-    bitrate: 3450000,
-    framerate: '25',
-    bitsPerComponent: 8,
-  },
-  audio: {
-    contentType: "audio/webm; codecs=\"opus\"",
-    channels: 6,
-    bitrate: 1200,
-    samplerate: 44100,
-  },
-}).then((status) => {
-  switch (status) {
-    case "Supported":
-      console.log("The configuration is supported");
-      break;
-
-    case "MaybeSupported":
-      console.log("The configuration may be supported");
-      break;
-
-    case "NotSupported":
-      console.log("The configuration is not supported");
-      break;
-  }
-});
-
-

-

getDisplayCapabilities

-

arguments:

-
    -
  • config (Object): Object with display configuration.
  • -
-

return value: string

-

Probe what can be displayed on the screen.

-

Argument

-

The object in argument is inspired from the concerned API configurations. -All its properties are optional, here are what you can set.

-
    -
  • colorSpace (string): Wanted color space (“srgb”, “p3”, etc).
  • -
  • width (number): Wanted display horizontal resolution.
  • -
  • height (number): Wanted display vertical resolution.
  • -
  • bitsPerComponent (number): Wanted display bpc capability.
  • -
-

Return Value

-

The returned string of this function is either:

-
    -
  • -

    "Supported": This configuration is supported.

    -
  • -
  • -

    "MaybeSupported": Some set configuration could not be probed because -not enough information was provided, but what has been probed is supported.

    -
  • -
  • -

    "NotSupported": The configuration is not supported.

    -
  • -
-

Example

-
import { mediaCapabilitiesProber } from "rx-player/experimental/tools";
-
-mediaCapabilitiesProber.getDisplayCapabilities({
-  colorSpace: "p3",
-  width: 3840,
-  height: 2160,
-  bitsPerComponent: 10,
-}).then((status) => {
-  switch (status) {
-    case "Supported":
-      console.log("The configuration is supported");
-      break;
-
-    case "MaybeSupported":
-      console.log("The configuration may be supported");
-      break;
-
-    case "NotSupported":
-      console.log("The configuration is not supported");
-      break;
-  }
-});
-
-

-

Exploited browser APIs

-

The tool probes media capabilities from browsers (Chrome, Firefox, etc.) -exploiting current available media API:

- -
\ No newline at end of file diff --git a/doc/generated/pages/api/metaplaylist.html b/doc/generated/pages/api/metaplaylist.html deleted file mode 100644 index 7d7d7773fd..0000000000 --- a/doc/generated/pages/api/metaplaylist.html +++ /dev/null @@ -1,316 +0,0 @@ -MetaPlaylist v0.1 - RxPlayer Documentation

-

MetaPlaylist v0.1

-

-

Overview

-

The MetaPlaylist is a file allowing to define a content composed of multiple -DASH or Smooth contents played one after another.

-

It allows advanced use cases for an extremely low cost for the server -infrastructure, the main one being creating a linear (live) contents from -multiple non-linear (VOD) ones, without touching the original contents.

-

You can also construct a new non-linear contents as a concatenation of multiple -non-linear contents put one after the other. This method allows for example for -a completely smooth streaming between multiple programs (e.g. when -binge-watching a serie).

-

-

Differences with plain DASH contents

-

The same result could be approximated with some advanced DASH features, but the -MetaPlaylist has several advantages. Some of them are:

-
    -
  • -

    it supports DASH and HSS contents (technically HLS would also be possible) -without modifying the original MPD/Manifest nor segments.

    -
  • -
  • -

    the Manifest/MPD/Playlist corresponding to the original contents can -be lazy-loaded (loaded only when the content will play).

    -

    This is also possible in DASH with a feature called XLinks but it’s not -always doable on the client-side, depending on the other elements present in -that MPD.

    -

    A MetaPlaylist file is much more strict in this regard.

    -

    This is still a work-in-progress.

    -
  • -
  • -

    it’s a format especially intended to be a concatenation of multiple -contents to be played on the web.

    -

    As such, advanced features such as declaring segments before they -should be played or avoiding many customers doing the same manifest -request at the exact same time are much easier to implement.

    -
  • -
  • -

    this file rarely needs to be updated, improving the caching of this -ressource.

    -
  • -
  • -

    its format is very simple and in JSON, which is easy to integrate with -JavaScript codebases. The file can even be very easily generated directly on -the client’s page. This paves the way for contents personalized to a single -customer.

    -
  • -
  • -

    Digital right management is also much more flexible than with a DASH MPD. -For example, different license servers for different contents could be -integrated. This is still a work-in-progress.

    -
  • -
  • -

    the specification is simple, try to allow no interpretation and is strict on -what is permitted.

    -
  • -
  • -

    All its features have been tested on web applications, meaning that you have -the guarantee everything will work on most MSE-compatible browsers, even -IE11.

    -
  • -
-

-

Structure of a MetaPlaylist

-

A MetaPlaylist file is a simple JSON file.

-

To jump into it right away, let me introduce some examples.

-

For a VOD content:

-
{
-  "type": "MPL",
-  "version": "0.1",
-  "contents": [
-    {
-      "url": "http://url.to.some/DASH/first_content.mpd",
-      "startTime": 0,
-      "endTime": 100.38,
-      "transport": "dash"
-    },
-    {
-      "url": "http://url.to.some/DASH/second_content.Manifest",
-      "startTime": 100.38,
-      "endTime": 372,
-      "transport": "smooth"
-    },
-    {
-      "url": "http://url.to.some/Smooth/third_content.mpd",
-      "startTime": 372,
-      "endTime": 450.787,
-      "transport": "dash"
-    }
-  ]
-}
-
-

For a live content:

-
{
-  "type": "MPL",
-  "version": "0.1",
-  "dynamic": true,
-  "pollInterval": 5,
-  "contents": [
-    {
-      "url": "http://url.to.some/DASH/content.mpd",
-      "startTime": 1545845950.176,
-      "endTime": 1545845985.571,
-      "transport": "dash"
-    },
-    {
-      "url": "http://url.to.some/other/DASH/content.mpd",
-      "startTime": 1545845985.571,
-      "endTime": 1545845998.710,
-      "transport": "dash"
-    },
-    {
-      "url": "http://url.to.some/Smooth/content.Manifest",
-      "startTime": 1545845998.710,
-      "endTime": 1545845117,
-      "transport": "smooth"
-    }
-  ]
-}
-
-

You may already have a basic understanding of it how works. -Let’s define nonetheless every property in that JSON file.

-

-

the header

-

What I call the “header” here is roughly all root properties but “contents”.

-

Here is an exhaustive list of what you should put there:

-
    -
  • -

    type (string): should always be equal to "MPL", for “MetaPlayList”.

    -

    The purpose of this value is to facilitate the checks a player might want to -perform to verify that it is handling a MetaPlaylist file. -The end goal would be for example to improve error reporting for very -frequent mistakes like not providing the URL of the right content.

    -
  • -
  • -

    version (string): version of the MetaPlaylist file. Separated in two parts -by a point (‘.’).

    -

    The first part indicates the major version. If its number is higher than -what the client presently manage, the client should not try to read that -file.

    -

    The last part indicates the minor version: -A new feature or fix have been added but its support is not needed by a -client (a client written for the 1.0 version can be used even for the -1.99 version).

    -

    Please note that there is an exception for 0.x versions, where each minor -versions could have a breaking change (as it is in that case considered an -experimental format).

    -

    At the moment, there is only one version the version "0.1". Thus, this is -what you have to set in your JSON if you integrate this specification.

    -
  • -
  • -

    dynamic (boolean|undefined): If true, the MetaPlaylist file is not -finished, and might need to be updated. If false, the MetaPlaylist could -still need to be updated but its current content indicates a finished -content: A player should end when the end of the last content has been -reached.

    -

    This property is not mandatory and as such can be omitted. By default, it is -considered as not dynamic (so false).

    -
  • -
  • -

    pollInterval (number|undefined): If not set or set to a negative number, -the MetaPlaylist file does not need to be reloaded.

    -

    If set to a positive number, this is the maximum interval in seconds at -which the MetaPlaylist file should be fetched from the server (which means -that the MetaPlaylist could be refreshed more often depending on the current -conditions).

    -

    This should only be defined for dynamic contents.

    -

    This property is not mandatory and as such can be omitted. By default, it is -equivalent to -1 (which means no reload).

    -
  • -
-

-

The contents

-

The contents are all defined as a property called contents at the top level of -our MetaPlaylist file.

-

It is an array of one or multiple objects (an empty contents array is not a -valid MetaPlaylist file).

-

Each of its objects are linked to a single content, here are the exhaustive -list of its properties:

-
    -
  • -

    url (string): the URL to the original DASH’s MPD or Smooth’s Manifest. -For now, only a subset of such contents is supported, mainly:

    -
      -
    • DASH contents that have their MPD@type set to "static"
    • -
    • Smooth content that have their isLive attribute not set to true -(Simply put, only on-demand contents are supported for the moment).
    • -
    -
  • -
  • -

    startTime (number): time, in seconds, at which the beginning of this -content should be played. -This will correspond to the start time of the first Period in DASH or the -first Chunk defined for Smooth content.

    -
  • -
  • -

    endTime (number): time, in seconds, at which the content should end. It -the original content is longer, it will be finished at that time instead. -The original content should not be shorter.

    -
  • -
  • -

    transport (string): indicates the original streaming protocol. -Can be either of those values for now:

    -
      -
    • "dash": the URL points to a DASH’s MPD
    • -
    • "smooth": the URL points to a Microsoft Smooth Streaming’s Manifest.
    • -
    • "metaplaylist": Yes, it is possible to put MetaPlaylist files inside -other MetaPlaylist files!
    • -
    -
  • -
-

All those contents should be contiguous (meaning that the endTime of one -should be the same value than the startTime of the following one).

-

-

How to actually play a MetaPlaylist content

-

-

Importing the METAPLAYLIST feature

-

The "METAPLAYLIST" feature is not included in the default RxPlayer build.

-

There’s two way you can import it, depending on if you’re relying on the minimal -version or if you prefer to make use of environment variables and build the -player manually.

-

Through the minimal version of the RxPlayer

-

If you’re using the “minimal” version of the RxPlayer (through the -"rx-player/minimal" import), you will need to import:

-
    -
  • the METAPLAYLIST experimental feature
  • -
  • every transport protocol you might want to use.
  • -
-

For example if you need to use MetaPlaylist with both Smooth and DASH contents, -you have to import at least all three as such:

-
import RxPlayer from "rx-player/minimal";
-import { METAPLAYLIST } from "rx-player/experimental/features";
-import { DASH, SMOOTH } from "rx-player/features";
-
-RxPlayer.addFeatures([METAPLAYLIST, DASH, SMOOTH]);
-
-

Through environment variables

-

If you don’t want to go the minimal version’s route and you have no problem with -building yourself a new version of the RxPlayer, you can make use of environment -variables to activate it.

-

This can be done through the RXP_METAPLAYLIST environment variable, which you -have to set to true:

-
RXP_METAPLAYLIST=true npm run build:min
-
-

More information about any of that can be found in the minimal player -documentation.

-

-

Loading a MetaPlaylist content

-

A MetaPlaylist content can simply be played by setting a "metaplaylist" -transport in loadVideo:

-
player.loadVideo({
-  url: "http://www.example.com/metaplaylist.json",
-  transport: "metaplaylist"
-});
-
-

If you declare locally your MetaPlaylist file and do not want to set a URL for -it, you can serve directly the file through the use of a Manifest Loader:

-
player.loadVideo({
-  transport: "metaplaylist",
-  transportOptions: {
-    // Note: `_url` here will be `undefined`
-    manifestLoader(_url, callbacks) {
-      // where `myMetaPlaylistObject` is the MetaPlaylist in either Object or
-      // String form
-      callbacks.resolve({ data: myMetaPlaylistObject });
-    }
-  }
-});
-
-

More infos on the manifestLoader can be found -here.

-

-

Defining an initial position for a dynamic MetaPlaylist

-

As already explained, a MetaPlaylist can either be dynamic or static.

-

For calculating the initial position of those contents, the RxPlayer will obey -the same rules than for other contents.

-

As such, dynamic MetaPlaylist contents will by default start just before the end -of the last defined content which might not be what you want.

-

In those cases, you can make usage of the serverSyncInfos transport options -when calling loadVideo to indicate the current time and construct the -MetaPlaylist by using unix time for each content’s startTime and endTime.

-

The serverSyncInfos option is explained in the transportOptions -documentation.

-

For example, if you trust the user’s system clock to indicate the current live -time (in most cases this is risky however), you can use the Date.now() api:

-
const serverSyncInfos = {
-  serverTimestamp: Date.now(),
-  clientTime: performance.now(),
-};
-
-player.loadVideo({
-  transport: "metaplaylist",
-  url: "https://www.example.com/metaplaylist",
-  transportOptions: { serverSyncInfos },
-});
-
-
\ No newline at end of file diff --git a/doc/generated/pages/api/minimal_player.html b/doc/generated/pages/api/minimal_player.html deleted file mode 100644 index 4a16f9ebbb..0000000000 --- a/doc/generated/pages/api/minimal_player.html +++ /dev/null @@ -1,348 +0,0 @@ -Minimal player with Feature selection - RxPlayer Documentation

-

Minimal player with Feature selection

-

-

Overview

-

The RxPlayer comes with many features, even some you might never need. -For example, you may only care for DASH with TTML subtitles and not about -Smooth streaming, VTT or SRT parsing.

-

Because each implementation has its need, we permit multiple ways to import -the player with limited features. -This principally leads to a smaller file size.

-

This customization can be done through two principal ways:

-
    -
  • -

    by importing a minimal version and then adding only the features your want

    -
  • -
  • -

    by setting environment variables at build time

    -
  • -
-

The first solution is the most straightforward and should be used in most -usecases. The main disadvantages of this solution are that to reduce file size:

-
    -
  • -

    you will need to use a module-bundler or minifier which performs -tree-shaking, like webpack’s -production mode or rollup.

    -
  • -
  • -

    you will need to use the package published on npm (as opposed to the git -repository directly).

    -
  • -
-

The second solution will always work but needs you to build the bundle yourself -through our npm scripts.

-

-

Importing a minimal version

-

-

How it works

-

If you imported the RxPlayer library through the npm package (like via the npm install rx-player command), you can import a minimal version of the player by -importing it from "rx-player/minimal":

-
import MinimalRxPlayer from "rx-player/minimal";
-
-// This player has the same API than the RxPlayer, but with no feature
-// (e.g. no DASH, Smooth or Directfile playback)
-const player = new MinimalRxPlayer();
-
-// use the regular APIs...
-player.setVolume(0.5);
-
-

You then will need to add the features you want on it. Those can be accessed -through the path "rx-player/features":

-
// import the DASH and Smooth features, which will be added to the RxPlayer
-import { DASH, SMOOTH } from "rx-player/features";
-
-

At last you can add those features to the imported RxPlayer class by calling the -special addFeatures static method, which is only present on the minimal -version of the Player:

-
// addFeatures takes an array of features as argument
-MinimalRxPlayer.addFeatures([DASH, SMOOTH]);
-
-

Here is the complete example:

-
import MinimalRxPlayer from "rx-player/minimal";
-import { DASH, SMOOTH } from "rx-player/features";
-
-MinimalRxPlayer.addFeatures([DASH, SMOOTH]);
-
-

There is also “experimental” features. Such features can completely change from -one version to the next - unlike regular features which just follows semantic -versioning. This means that you may have to keep the concerned code up-to-date -each time you depend on a new RxPlayer version. -Such features are imported from "rx-player/experimental/features" instead:

-
import MinimalRxPlayer from "rx-player/minimal";
-import { METAPLAYLIST } from "rx-player/experimental/features";
-
-MinimalRxPlayer.addFeatures([METAPLAYLIST]);
-
-

You can of course depend on both experimental and regular features:

-
import MinimalRxPlayer from "rx-player/minimal";
-import { DASH, SMOOTH } from "rx-player/features";
-import { METAPLAYLIST } from "rx-player/experimental/features";
-
-MinimalRxPlayer.addFeatures([DASH, SMOOTH, METAPLAYLIST]);
-
-

By using the minimal version, you will reduce the final bundle file if -tree-shaking is performed on the final code (like in webpack’s production -mode).

-

The key is just to know which feature does what. The next chapter will list -and explain the role of every one of them.

-

-

List of features

-

Features, which are variables imported from the "rx-player/features" path, -are all objects declared in upper-case.

-

Here is the anotated exhaustive list (notes are at the bottom of the table):

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureDescription of the feature
SMOOTHEnable Smooth streaming (HSS) playback
DASHEnable DASH playback
DIRECTFILEEnable playback of “directfile” contents
EMEEnable playback of encrypted contents
NATIVE_TEXT_BUFFER [1]Allow to display text tracks through <tracks> elements
HTML_TEXT_BUFFER [1]Allow to display richer text tracks through HTML elements
IMAGE_BUFFER [1]Allow to display thumbnails through the images buffer
NATIVE_SRT_PARSER [2]Parse SRT text tracks for the native text buffer
NATIVE_VTT_PARSER [2]Parse VTT text tracks for the native text buffer
NATIVE_TTML_PARSER [2]Parse TTML text tracks for the native text buffer
NATIVE_SAMI_PARSER [2]Parse SAMI text tracks for the native text buffer
HTML_SRT_PARSER [3]Parse SRT text tracks for the HTML text buffer
HTML_VTT_PARSER [3]Parse VTT text tracks for the HTML text buffer
HTML_TTML_PARSER [3]Parse TTML text tracks for the HTML text buffer
HTML_SAMI_PARSER [3]Parse SAMI text tracks for the HTML text buffer
BIF_PARSER [4]Parse BIF image tracks for the image buffer
LOCAL_MANIFEST [5]Enable playback of “local” contents
METAPLAYLIST [5]Enable playback of “metaplaylist” contents
-
-

Notes:

-

[1]: You will need to also add at least one parser for this type of buffer -for those features to be useful. -(example: NATIVE_SRT_PARSER will parse srt subtitles for the -NATIVE_TEXT_BUFFER)

-

[2]: Those features will only be used if NATIVE_TEXT_BUFFER is an added -feature.

-

[3]: Those features will only be used if HTML_TEXT_BUFFER is an added -feature.

-

[4]: This feature will only be used if IMAGE_BUFFER is an added feature.

-

[5]: Those type of contents are experimental. They should be imported -from rx-player/experimental/features.

-
-

-

Examples

-

To help you choose your features, are some examples that represents common -usecases.

-

unencrypted DASH contents with native webVTT subtitles

-
import RxPlayer from "rx-player/minimal";
-import {
-  DASH,
-  NATIVE_TEXT_BUFFER,
-  NATIVE_VTT_PARSER
-} from "rx-player/features";
-
-RxPlayer.addFeatures([DASH, NATIVE_TEXT_BUFFER, NATIVE_VTT_PARSER]);
-
-

possibly-encrypted DASH contents with HMTL webVTT and TTML subtitles

-
import RxPlayer from "rx-player/minimal";
-import {
-  DASH,
-  EME,
-  HTML_TEXT_BUFFER,
-  HTML_VTT_PARSER,
-  HTML_HTML_PARSER
-} from "rx-player/features";
-
-RxPlayer.addFeatures([
-  DASH,
-  EME,
-  HTML_TEXT_BUFFER,
-  HTML_VTT_PARSER,
-  HTML_TTML_PARSER
-]);
-
-

Smooth contents with thumbnails (BIF) support

-
import RxPlayer from "rx-player/minimal";
-import {
-  SMOOTH,
-  IMAGE_BUFFER,
-  BIF_PARSER
-} from "rx-player/features";
-
-RxPlayer.addFeatures([ SMOOTH, IMAGE_BUFFER, BIF_PARSER ]);
-
-

-

Building with environment variables

-

-

How it works

-

You can also include only the features you need on the RxPlayer library by -building it while having specific environment variables.

-

The code related to the unwanted features should be removed when the final code -is minified (as the corresponding code is made unreachable).

-

To avoid any conflict with other environment variables, they all are named -RXP_<FEATURE-NAME>.

-

For example, the following will remove all code related to Microsoft Smooth -Streaming from the build:

-
RXP_SMOOTH=false npm run build:min
-
-

-

List of environment variables

-

-

RXP_SMOOTH

-

True by default. If set to “false”, all code relative to HSS streaming will be -ignored during a build.

-

-

RXP_DASH

-

True by default. If set to “false”, all code relative to DASH streaming will be -ignored during a build.

-

-

RXP_DIRECTFILE

-

True by default. If set to “false”, all code relative to directfile streaming -will be ignored during a build.

-

-

RXP_LOCAL_MANIFEST

-

False by default. If set to “true”, all code relative to the “local” transport -(to be able to play content offline for example) will be included during a -build.

-

-

RXP_METAPLAYLIST

-

False by default. If set to “true”, all code relative to metaplaylist streaming -will be included during a build.

-

-

RXP_EME

-

True by default. If set to “false”, all code relative to encrypted contents will -be ignored during a build.

-

-

RXP_NATIVE_TTML

-

True by default. If set to “false”, all code relative to TTML parsing for native -text tracks will be ignored during a build.

-

-

RXP_NATIVE_SAMI

-

True by default. If set to “false”, all code relative to SAMI parsing for native -text tracks will be ignored during a build.

-

-

RXP_NATIVE_VTT

-

True by default. If set to “false”, all code relative to VTT parsing for native -text tracks will be ignored during a build.

-

-

RXP_NATIVE_SRT

-

True by default. If set to “false”, all code relative to SRT parsing for native -text tracks will be ignored during a build.

-

-

RXP_HTML_TTML

-

True by default. If set to “false”, all code relative to TTML parsing for html -text tracks[1] will be ignored during a build.

-

-

RXP_HTML_SAMI

-

True by default. If set to “false”, all code relative to SAMI parsing for html -text tracks[1] will be ignored during a build.

-

-

RXP_HTML_VTT

-

True by default. If set to “false”, all code relative to VTT parsing for html -text tracks[1] will be ignored during a build.

-

-

RXP_HTML_SRT

-

True by default. If set to “false”, all code relative to SRT parsing for html -text tracks[1] will be ignored during a build.

-

-

RXP_BIF_PARSER

-

True by default. If set to “false”, all code relative to BIF image parsing will -be ignored during a build.

-

-

RXP_BAREBONE

-

If set to true, no feature is activated by default and all other environment -variables are considered as false by default (unless set).

-

For example, to only activate DASH, you could do:

-
RXP_BAREBONE=true RXP_DASH=true npm run build:min
-
-

-

RXP_ENV

-

Either “production” or “development”. “production” as a default. -In the “development” case:

-
    -
  • logs will be activated
  • -
  • the code will be less tolerant towards unwanted behavior
  • -
  • the code will be less optimized
  • -
-
-

Notes:

-

[1] html text tracks are tracks which are added to a -DOM element instead of a <track> (the latter here being called “native”) tag -for a richer formatting.

-
-
\ No newline at end of file diff --git a/doc/generated/pages/api/parseBifThumbnails.html b/doc/generated/pages/api/parseBifThumbnails.html deleted file mode 100644 index bdab0a591d..0000000000 --- a/doc/generated/pages/api/parseBifThumbnails.html +++ /dev/null @@ -1,68 +0,0 @@ -parseBifThumbnails - RxPlayer Documentation

-

parseBifThumbnails

-

parseBifThumbnails is a function allowing to easily parse BIF files, which -is a file format crafted to contain video thumbnails.

-

Those are usually used to give a visual indication of where in a given media you -will seek to when hovering a progress bar.

-

-

About BIF files

-

The BIF format is straightforward. It contains several metadata and then all the -images for the whole content, in their original format (e.g. “jpeg”), -concatenated.

-

-

How to import it

-

parseBifThumbnails is for now considered an “experimental” tool. This means -that its API could change at any new version of the RxPlayer (don’t worry, we -would still document all changes made to it in the corresponding release note).

-

As an experimental tool, it is imported as such:

-
import { parseBifThumbnails } from "rx-player/experimental/tools";
-
-

You can then begin to use it right away.

-

-

How to use it

-

As a simple parser, parseBifThumbnails takes the downloaded BIF file in an -ArrayBuffer form and returns its content under an object format, like this:

-
import { parseBifThumbnails } from "rx-player/experimental/tools";
-
-// optionally, fetch the BIF resource through the usual APIs
-fetch("http://www.example.com/thumbnails.bif").then(function(response) {
-  return response.arrayBuffer(); // obtain an ArrayBuffer response
-}).then(function(buffer) {
-  const parsedBif = parseBifThumbnails(buffer);
-  console.log("parsed BIF:", parsedBif);
-};
-
-

Here is an example of the returned data:

-
{
-  version: "0.0.0.0", // BIF version. For the moment, only "0.0.0.0" is
-                      // specified.
-  images: [    // Array of thumbnails for this content
-    {
-      startTime: 0, // Start position at which the thumbnail should be applied
-                    // to, in milliseconds.
-                    // For example, a time of `5000`, indicates that this
-                    // thumbnail should be shown from the 5 second mark in the
-                    // content (until the next image is displayed instead)
-      image: ArrayBuffer() // The thumbnail itself, in an ArrayBuffer form.
-    },
-    {
-      startTime: 10000,
-      endTime: 20000,
-      thumbnail: ArrayBuffer()
-    },
-    {
-      startTime: 20000,
-      endTime: 30000,
-      thumbnail: ArrayBuffer()
-    },
-    // ...
-  ],
-}
-
-
\ No newline at end of file diff --git a/doc/generated/pages/api/player_events.html b/doc/generated/pages/api/player_events.html deleted file mode 100644 index a7f8cb6b82..0000000000 --- a/doc/generated/pages/api/player_events.html +++ /dev/null @@ -1,619 +0,0 @@ -Player events - RxPlayer Documentation

-

Player events

-

-

-

Overview

-

To communicate about events (like an error or the update of the current video -bitrate) the player use the event listener pattern.

-

As documented in the API, you can call -addEventListener to register a callback for a particular event, like:

-
player.addEventListener("videoBitrateChange", (newVideoBitrate) => {
-  console.log("the video bitrate changed to:", newVideoBitrate)
-});
-
-

You can unregister a callback through the removeEventListener API, -documented here.

-

-

-

Basic events

-

This chapter describes the most important events sent by the player.

-

-

-

playerStateChange

-

payload type: string

-

Emit the current state of the player, every time it changes.

-

This is the event to catch if you want to know when the player is playing, is -paused, is rebuffering, is ended or is stopped.

-

As it is a central part of our API and can be difficult concept to understand, -we have a special page of documentation on player states.

-

-

-

error

-

payload type: Error

-

Triggered when a fatal error happened.

-

A fatal error is an error that led the player to stop playing the current -content.

-

The payload is the corresponding error. See the Player Error -documentation for more information.

-

-

-

warning

-

payload type: Error

-

Triggered each time a minor error happened.

-

This error won’t lead the RxPlayer to stop the content. It can for example be -an HTTP request error, some minor error detected in the content or the current -position being to far below the minimum playable position.

-

The payload is the corresponding error. See the Player Error -documentation for more information.

-

-

-

positionUpdate

-

payload type: Object

-

Emit information about the current position at most every seconds (also emits -every time various player events are received).

-

The object emitted as the following properties:

-
    -
  • -

    position (Number): The current position in the video, in seconds.

    -
  • -
  • -

    duration (Number): The duration of the content.

    -
  • -
  • -

    bufferGap (Number): The gap, in seconds, between the current -position and the end of the current buffered range.

    -
  • -
  • -

    playbackRate (Number): The current playback rate the content is on.

    -
  • -
  • -

    liveGap (Number|undefined): Only for live contents. The gap between -the current position and the “live edge”.

    -
  • -
  • -

    maximumBufferTime (Number|undefined): The maximum time until which -the buffer can currently be filled. That is:

    -
      -
    • -

      for static contents (like VoD), the duration.

      -
    • -
    • -

      for dynamic contents (like live contents), the current maximum available -position (live edge for live contents) minus a security margin we added to -avoid buffering ahead of it.

      -
    • -
    -
  • -
  • -

    wallClockTime (Number|undefined): Only for live contents. The -current time converted to wall-clock time in seconds. -That is the real live position (and not the position as announced by the -video element).

    -
  • -
-

-

-

seeking

-

Emitted when a “seek” operation (to “move”/“skip” to another position) begins -on the currently loaded content.

-

-

-

seeked

-

Emitted when a “seek” operation (to “move”/“skip” to another position) on the -currently loaded content has finished

-

-

-

Track selection events

-

This chapter describes events linked to the current audio, video or text track.

-

-

-

availableAudioTracksChange

-

payload type: Array.<Object>

-
-

Triggered when the currently available audio tracks change (e.g.: at the -beginning of the content, when period changes…).

-

The array emitted contains object describing each available audio track:

-
    -
  • -

    active (Boolean): Whether the track is the one currently active or -not.

    -
  • -
  • -

    id (string): The id used to identify the track. Use it for -setting the track via setAudioTrack.

    -
  • -
  • -

    language (string): The language the audio track is in, as set in -the Manifest.

    -
  • -
  • -

    normalized (string): An attempt to translate the language -property into an ISO 639-3 language code (for now only support translations -from ISO 639-1 and ISO 639-2 language codes). If the translation attempt -fails (no corresponding ISO 639-3 language code is found), it will equal the -value of language

    -
  • -
  • -

    audioDescription (Boolean): Whether the track is an audio -description of what is happening at the screen.

    -
  • -
  • -

    dub (Boolean|undefined): If set to true, this audio track is a -“dub”, meaning it was recorded in another language than the original. -If set to false, we know that this audio track is in an original language. -This property is undefined if we do not known whether it is in an original -language.

    -
  • -
-

This event only concerns the currently-playing Period.

-

-

-

availableVideoTracksChange

-

payload type: Array.<Object>

-
-

Triggered when the currently available video tracks change (e.g.: at the -beginning of the content, when period changes…).

-

The array emitted contains object describing each available video track:

-
    -
  • -

    id (string): The id used to identify the track. Use it for -setting the track via setVideoTrack.

    -
  • -
  • -

    active (Boolean): Whether this track is the one currently -active or not.

    -
  • -
  • -

    representations (Array.<Object>): -Representations of this video track, with -attributes:

    -
      -
    • -

      id (string): The id used to identify this Representation.

      -
    • -
    • -

      bitrate (Number): The bitrate of this Representation, in bits per -seconds.

      -
    • -
    • -

      width (Number|undefined): The width of video, in pixels.

      -
    • -
    • -

      height (Number|undefined): The height of video, in pixels.

      -
    • -
    • -

      codec (string|undefined): The codec given in standard MIME type -format.

      -
    • -
    • -

      frameRate (string|undefined): The video framerate.

      -
    • -
    -
  • -
-

This event only concerns the currently-playing Period.

-

-

-

availableTextTracksChange

-

payload type: Array.<Object>

-
-

Triggered when the currently available text tracks change (e.g.: at the -beginning of the content, when period changes…).

-

The array emitted contains object describing each available text track:

-
    -
  • -

    id (string): The id used to identify the track. Use it for -setting the track via setTextTrack.

    -
  • -
  • -

    language (string): The language the text track is in, as set in the -Manifest.

    -
  • -
  • -

    normalized (string): An attempt to translate the language -property into an ISO 639-3 language code (for now only support translations -from ISO 639-1 and ISO 639-2 language codes). If the translation attempt -fails (no corresponding ISO 639-3 language code is found), it will equal the -value of language

    -
  • -
  • -

    closedCaption (Boolean): Whether the track is specially adapted for -the hard of hearing or not.

    -
  • -
  • -

    active (Boolean): Whether the track is the one currently active or -not.

    -
  • -
-

This event only concerns the currently-playing Period.

-

-

-

audioTrackChange

-

payload type: Object|null

-
-

Information about the current audio track, each time it changes (the last -received segment got a new one).

-

The payload is an object describing the new track, with the following -properties:

-
    -
  • id (Number|string): The id used to identify the track.
  • -
  • language (string): The language the audio track is in.
  • -
  • audioDescription (Boolean): Whether the track is an audio -description of what is happening at the screen.
  • -
  • dub (Boolean|undefined): If set to true, this audio track is a -“dub”, meaning it was recorded in another language than the original. -If set to false, we know that this audio track is in an original language. -This property is undefined if we do not known whether it is in an original -language.
  • -
-

This event only concerns the currently-playing Period.

-

-

-

textTrackChange

-

payload type: Object|null

-
-

Information about the current text track, each time it changes (the last -received segment got a new one).

-

The payload is an object describing the new track, with the following -properties:

-
    -
  • id (Number|string): The id used to identify the track.
  • -
  • language (string): The language the text track is in.
  • -
  • closedCaption (Boolean): Whether the track is specially adapted for -the hard of hearing or not.
  • -
-

This event only concerns the currently-playing Period.

-

-

-

videoTrackChange

-

payload type: Object|null

-
-

Information about the current video track, each time it changes (the last -received segment got a new one).

-

The payload is an object describing the new track, with the following -properties:

-
    -
  • -

    id (string): The id used to identify the track. Use it for setting -the track via setVideoTrack.

    -
  • -
  • -

    representations (Array.<Object>): -Representations of this video track, with -attributes:

    -
      -
    • -

      id (string): The id used to identify this Representation.

      -
    • -
    • -

      bitrate (Number): The bitrate of this Representation, in bits per -seconds.

      -
    • -
    • -

      width (Number|undefined): The width of video, in pixels.

      -
    • -
    • -

      height (Number|undefined): The height of video, in pixels.

      -
    • -
    • -

      codec (string|undefined): The codec given in standard MIME type -format.

      -
    • -
    • -

      frameRate (string|undefined): The video framerate.

      -
    • -
    -
  • -
-

A null payload means that video track has been disabled.

-

This event only concerns the currently-playing Period.

-

⚠️ In DirectFile mode, a null payload may be received even if the -video track is still visually active. -This seems due to difficult-to-detect browser bugs. We recommend not disabling -the video track when in directfile mode to avoid that case (this is documented -in the corresponding APIs).

-

-

-

Bitrate selection events

-

This chapter describes events linked to audio and/or video bitrates and quality.

-

-

-

availableAudioBitratesChange

-

payload type: Array.<Number>

-
-

⚠️ This event is not sent in DirectFile mode (see loadVideo -options).

-
-

Triggered when the currently available audio bitrates change (e.g.: at the -beginning of the content, when switching the current audio track, when period -changes…).

-

The payload is an array of the different bitrates available, in bits per -seconds.

-

This event only concerns the currently-playing Period.

-

-

-

availableVideoBitratesChange

-

payload type: Array.<Number>

-
-

⚠️ This event is not sent in DirectFile mode (see loadVideo -options).

-
-

Triggered when the currently available video bitrates change (e.g.: at the -beginning of the content, when switching the current video track, when period -changes…).

-

The payload is an array of the different bitrates available, in bits per -seconds.

-

This event only concerns the currently-playing Period.

-

-

-

audioBitrateChange

-

payload type: Number

-
-

⚠️ This event is not sent in DirectFile mode (see loadVideo -options).

-
-

The payload is the new audio bitrate, in bits per seconds. It is emitted every -time it changes (based on the last received segment).

-

-1 when the bitrate is not known.

-

This event only concerns the currently-playing Period.

-

-

-

videoBitrateChange

-

payload type: Number

-
-

⚠️ This event is not sent in DirectFile mode (see loadVideo -options).

-
-

The payload is the new video bitrate, in bits per seconds. It is emitted every -time it changes (based on the last received segment).

-

-1 when the bitrate is not known.

-

This event only concerns the currently-playing Period.

-

-

-

bitrateEstimationChange

-

payload type: Object

-
-

⚠️ This event is not sent in DirectFile mode (see loadVideo -options).

-
-

Information about the last bitrate estimation performed, by type of buffer -(audio, video etc.).

-

Note that this event is sent only if the corresponding buffer type has multiple -Representations for the given content (as bitrate -estimations are only useful in that case).

-

The payload is an object with the following properties:

-
    -
  • -

    type (string): The buffer type

    -
  • -
  • -

    bitrate (Number): The last estimated bandwidth for this buffer type, -in bits per seconds. -This bitrate is smoothed by doing a (complex) mean on an extended period of -time, so it often does not link directly to the current calculated bitrate.

    -
  • -
-

-

-

Playback information

-

This chapter describes events describing miscellaneous information about the -current content.

-

-

-

periodChange

-

payload type: Object

-
-

⚠️ This event is not sent in DirectFile mode (see loadVideo -options).

-
-

Triggered when the current Period being seen changes.

-

The payload is the corresponding Period. See the Manifest -documentation for more information.

-

-

-

decipherabilityUpdate

-

payload type: Array.<Object>

-
-

⚠️ This event is not sent in DirectFile mode (see loadVideo -options).

-
-

Triggered when a or multiple Representation’s decipherability status were -updated. Which means either:

-
    -
  • A Representation is found to be undecipherable (e.g. the key or license -request is refused)
  • -
  • A Representation is found to be decipherable
  • -
  • A Representation’s decipherability becomes undefined
  • -
-

At this time, this event is only triggered if:

-
    -
  • the current content is an encrypted content
  • -
  • Either the fallbackOnLastTry property was set to true on a rejected -getLicense call or one of the fallbackOn properties was set to true in -the keySystems loadVideo option.
  • -
-

Following this event, the RxPlayer might remove from the current buffers any -data linked to undecipherable Representation(s) (the video might twitch a little -or reload) and update the list of available bitrates.

-

The payload of this event is an Array of objects, each representating a -Representation whose decipherability’s status has been updated.

-

Each of those objects have the following properties:

- -

You can then know if any of those Representations are becoming decipherable or -not through their decipherable property.

-

-

-

streamEvent

-

payload type: Object

-
-

⚠️ This event is not sent in DirectFile mode (see loadVideo -options).

-
-

Event triggered when the player enters the time boundaries of a “stream event”.

-

“Stream events” are metadata that can be defined in various streaming protocols, -which indicates that an application should trigger some action when a specific -time is reached in the content.

-

Those events can either have only a start time or both a start time and an end -time:

-
    -
  • -

    in the case where an event only has a start time, the RxPlayer will trigger -a streamEvent right when the user reaches that time.

    -

    If we return multiple time at that position (for example, when a user seeks -back to it), you will receive a streamEvent as many times for that same -event.

    -
  • -
  • -

    in the case where an event has both a start and end time, the RxPlayer will -trigger a streamEvent when the current position goes inside these time -boundaries (between the start and end time). -This can happen while reaching the start during regular playback but also -when seeking at a position contained between the start and end time.

    -

    The streamEvent event will not be re-sent until the current position -“exits” those time boundaries. If the current position goes out of the -boundaries of that event and then goes into it again (most likely due to the -user seeking back into it), you will again receive a streamEvent for that -same event.

    -
  • -
-

The payload of a streamEvent depends on the source of the event. For example, -it will not have the same format when it comes from a Manifest than when it -comes from the media container. -All possible formats are described in the stream event -tutorial.

-

Note: When an event has both a start and an end time, you can define a onExit -callback on the payload. That callback will automatically be triggered when the -current position goes after the end time or before the start time of that event. -The onExit callback will only be called a single time at most and will only -concern this iteration of the event (and not possible subsequent ones).

-

-

-

streamEventSkip

-

payload type: Object

-
-

⚠️ This event is not sent in DirectFile mode (see loadVideo -options).

-
-

Event triggered when the player skipped the time boundaries of a “stream event” -(you can refer to the streamEvent event for a -definition of what a “stream event” is).

-

This means that the current position the player plays at, immediately changed -from a time before the start time of a “stream event” to after its end time (or -just after its end time for “stream event” without an end time).

-

This is most likely due to the user seeking in the content. A “regular” content -playback which continuously plays the content without seeking shouldn’t trigger -any streamEventSkip event.

-

The payload of a streamEventSkip is the same than for a streamEvent and as -such depends on the source of the event. -All possible formats are described in the stream event -tutorial.

-

Note that unlike streamEvent events, there’s no point to define an onExit -callback on the payload of a streamEventSkip event. This is because this event -was not entered, and will thus not be exited.

-

-

-

Deprecated

-

The following events are deprecated. They are still supported but we advise -users to not use those as they might become not supported in the future.

-

-

-

imageTrackUpdate

-
-

⚠️ This event is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-
-

payload type: Object

-
-

⚠️ This event is not sent in DirectFile mode (see loadVideo -options).

-
-

Triggered each time the current image playlist changes (has new images).

-

Has the following property in its payload: -data (Array.<Object>): Every image data.

-

Each image has a structure as defined in the Images structure -page.

-

-

-

fullscreenChange

-
-

⚠️ This event is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-
-

payload type: Boolean

-

Triggered each time the video player goes/exits fullscreen mode.

-

The payload is true if the player entered fullscreen, false if it exited -it.

-

-

-

nativeTextTracksChange

-
-

⚠️ This event is deprecated, it will disappear in the next major -release v4.0.0 (see Deprecated APIs).

-
-

payload type: Array.<TextTrackElement>

-
-

⚠️ This event is not sent in DirectFile mode (see loadVideo -options).

-
-

Triggered each times a new <track> element is removed or added to the video -element.

-

The payload is the array of TextTrack elements. The RxPlayer will only set -a single <track> when a text track is set.

-
\ No newline at end of file diff --git a/doc/generated/pages/api/player_options.html b/doc/generated/pages/api/player_options.html deleted file mode 100644 index 2f0ab1734a..0000000000 --- a/doc/generated/pages/api/player_options.html +++ /dev/null @@ -1,602 +0,0 @@ -Player Options - RxPlayer Documentation

-

Player Options

-

-

-

Overview

-

Player options are options given to the player on instantiation.

-

It’s an object with multiple properties. None of them are mandatory. -For most usecase though, you might want to set at least the associated video -element via the videoElement property.

-

-

-

Properties

-

-

-

videoElement

-

type: HTMLMediaElement|undefined

-

The media element the player will use.

-

Note that this can be a <video> or an <audio> element.

-
// Instantiate the player with the first video element in the DOM
-const player = new Player({
-  videoElement: document.getElementsByTagName("VIDEO")[0]
-});
-
-

If not defined, a <video> element will be created without being inserted in -the document. You will have to do it yourself through the getVideoElement -method to add it yourself:

-
const player = new Player();
-
-const videoElement = player.getVideoElement();
-document.body.appendChild(videoElement);
-
-

-

-

initialVideoBitrate

-

type: Number|undefined

-

defaults: 0

-

This is a ceil value for the initial video bitrate chosen.

-

That is, the first video Representation chosen -will be both:

-
    -
  • inferior or equal to this value.
  • -
  • the closest possible to this value (after filtering out the ones with a -superior bitrate).
  • -
-

If no Representation is found to respect those rules, the Representation with -the lowest bitrate will be chosen instead. Thus, the default value - 0 - -will lead to the lowest bitrate being chosen at first.

-
// Begin either by the video bitrate just below or equal to 700000 bps if found
-// or the lowest bitrate available if not.
-const player = new Player({
-  initialVideoBitrate: 700000
-});
-
-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

initialAudioBitrate

-

type: Number|undefined

-

defaults: 0

-

This is a ceil value for the initial audio bitrate chosen.

-

That is, the first audio Representation chosen -will be:

-
    -
  • inferior or equal to this value.
  • -
  • the closest possible to this value (after filtering out the ones with a -superior bitrate).
  • -
-

If no Representation is found to respect those rules, the Representation with -the lowest bitrate will be chosen instead. Thus, the default value - 0 - -will lead to the lowest bitrate being chosen at first.

-
// Begin either by the audio bitrate just below or equal to 5000 bps if found
-// or the lowest bitrate available if not.
-const player = new Player({
-  initialAudioBitrate: 5000
-});
-
-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

minVideoBitrate

-

type: Number|undefined

-

defaults: 0

-

Minimum video bitrate reachable through adaptive streaming.

-

When the bitrate is chosen through adaptive streaming (i.e., not enforced -manually through APIs such as setVideoBitrate), the player will never switch -to a video quality with a bitrate lower than that value.

-

The exception being when no quality has a higher bitrate, in which case the -maximum quality will always be chosen instead.

-

For example, if you want that video qualities chosen automatically never have -a bitrate lower than 100 kilobits per second you can call:

-
const player = new Player({
-  minVideoBitrate: 100000
-});
-
-

Any limit can be removed just by setting that value to 0:

-
// remove video bitrate lower limit
-player.setMinVideoBitrate(0);
-
-

You can update this limit at any moment with the setMinVideoBitrate API -call.

-

Note that this only affects adaptive strategies. Forcing the bitrate manually -(for example by calling setVideoBitrate) bypass this limit completely.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

minAudioBitrate

-

type: Number|undefined

-

defaults: 0

-

Minimum audio bitrate reachable through adaptive streaming.

-

When the bitrate is chosen through adaptive streaming (i.e., not enforced -manually through APIs such as setAudioBitrate), the player will never switch -to an audio quality with a bitrate higher than that value.

-

The exception being when no quality has a higher bitrate, in which case the -minimum quality will always be chosen instead.

-

For example, if you want that audio qualities chosen automatically never have -a bitrate higher than 100 kilobits per second you can call:

-
const player = new Player({
-  minAudioBitrate: 100000
-});
-
-

Any limit can be removed just by setting that value to 0:

-
// remove audio bitrate lower limit
-player.setMinAudioBitrate(0);
-
-

You can update this limit at any moment with the setMinAudioBitrate API -call.

-

Note that this only affects adaptive strategies. Forcing the bitrate manually -(for example by calling setAudioBitrate) bypass this limit completely.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

maxVideoBitrate

-

type: Number|undefined

-

defaults: Infinity

-

Maximum video bitrate reachable through adaptive streaming.

-

When the bitrate is chosen through adaptive streaming (i.e., not enforced -manually through APIs such as setVideoBitrate), the player will never switch -to a video quality with a bitrate higher than that value.

-

The exception being when no quality has a lower bitrate, in which case the -minimum quality will always be chosen instead.

-

For example, if you want that video qualities chosen automatically never have -a bitrate higher than 1 Megabits per second you can call:

-
const player = new Player({
-  maxVideoBitrate: 1e6
-});
-
-

Any limit can be removed just by setting that value to Infinity:

-
// remove video bitrate higher limit
-player.setMaxVideoBitrate(Infinity);
-
-

You can update this limit at any moment with the setMaxVideoBitrate API -call.

-

Note that this only affects adaptive strategies. Forcing the bitrate manually -(for example by calling setVideoBitrate) bypass this limit completely.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

maxAudioBitrate

-

type: Number|undefined

-

defaults: Infinity

-

Maximum audio bitrate reachable through adaptive streaming.

-

When the bitrate is chosen through adaptive streaming (i.e., not enforced -manually through APIs such as setAudioBitrate), the player will never switch -to an audio quality with a bitrate higher than that value.

-

The exception being when no quality has a lower bitrate, in which case the -minimum quality will always be chosen instead.

-

For example, if you want that audio qualities chosen automatically never have -a bitrate higher than 1 Megabits per second you can call:

-
const player = new Player({
-  maxAudioBitrate: 1e6
-});
-
-

Any limit can be removed just by setting that value to Infinity:

-
// remove audio bitrate higher limit
-player.setMaxAudioBitrate(Infinity);
-
-

You can update this limit at any moment with the setMaxAudioBitrate API -call.

-

Note that this only affects adaptive strategies. Forcing the bitrate manually -(for example by calling setAudioBitrate) bypass this limit completely.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

wantedBufferAhead

-

type: Number|undefined

-

defaults: 30

-

Set the default buffering goal, as a duration ahead of the current position, in -seconds.

-

Once this size of buffer is reached, the player won’t try to download new -segments anymore.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

preferredAudioTracks

-

type: Array.<Object|null>

-

defaults: []

-

This option allows to help the RxPlayer choose an initial audio track based on -either language preferences, codec preferences or both.

-

It is defined as an array of objects, each object describing constraints a -track should respect.

-

If the first object - defining the first set of constraints - cannot be -respected under the currently available audio tracks, the RxPlayer will skip -it and check with the second object and so on. -As such, this array should be sorted by order of preference: from the most -wanted constraints to the least.

-

Here is all the possible constraints you can set in any one of those objects -(note that all properties are optional here, only those set will have an effect -on which tracks will be filtered):

-
{
-  language: "fra", // {string|undefined} The language the track should be in
-                   // (in preference as an ISO 639-1, ISO 639-2 or ISO 639-3
-                   // language code).
-                   // If not set or set to `undefined`, the RxPlayer won't
-                   // filter based on the language of the track.
-
-  audioDescription: false // {Boolean|undefined} Whether the audio track should
-                          // be an audio description for the visually impaired
-                          // or not.
-                          // If not set or set to `undefined`, the RxPlayer
-                          // won't filter based on that status.
-
-  codec: { // {Object|undefined} Constraints about the codec wanted.
-           // if not set or set to `undefined` we won't filter based on codecs.
-
-    test: /ec-3/, // {RegExp} RegExp validating the type of codec you want.
-
-    all: true, // {Boolean} Whether all the profiles (i.e. Representation) in a
-               // track should be checked against the RegExp given in `test`.
-               // If `true`, we will only choose a track if EVERY profiles for
-               // it have a codec information that is validated by that RegExp.
-               // If `false`, we will choose a track if we know that at least
-               // A SINGLE profile from it has codec information validated by
-               // that RegExp.
-  }
-}
-
-

This array of preferrences can be updated at any time through the -setPreferredAudioTracks method, documented -here.

-

Examples

-

Let’s imagine that you prefer to have french or italian over all other audio -languages. If not found, you want to fallback to english:

-
const player = new RxPlayer({
-  preferredAudioTracks: [
-    { language: "fra", audioDescription: false },
-    { language: "ita", audioDescription: false },
-    { language: "eng", audioDescription: false }
-  ]
-});
-
-

Now let’s imagine that you want to have in priority a track that contain at -least one profile in Dolby Digital Plus (ec-3 codec) without caring about the -language:

-
const player = new RxPlayer({
-  preferredAudioTracks: [ { codec: { all: false, test: /ec-3/ } ]
-});
-
-

At last, let’s combine both examples by preferring french over itialian, italian -over english while preferring it to be in Dolby Digital Plus:

-
const player = new RxPlayer({
-  preferredAudioTracks: [
-    {
-      language: "fra",
-      audioDescription: false,
-      codec: { all: false, test: /ec-3/ }
-    },
-
-    // We still prefer non-DD+ french over DD+ italian
-    { language: "fra", audioDescription: false },
-
-    {
-      language: "ita",
-      audioDescription: false,
-      codec: { all: false, test: /ec-3/ }
-    },
-    { language: "ita", audioDescription: false },
-
-    {
-      language: "eng",
-      audioDescription: false,
-      codec: { all: false, test: /ec-3/ }
-    },
-    { language: "eng", audioDescription: false }
-  ]
-
-

-

⚠️ This option will have no effect in DirectFile mode -(see loadVideo options) when either :

-
    -
  • No audio track API is supported on the current browser
  • -
  • The media file tracks are not supported on the browser
  • -
-

-

-

preferredTextTracks

-

type: Array.<Object|null>

-

defaults: []

-

Set the initial text track languages preferences.

-

This option takes an array of objects describing the languages wanted for -subtitles:

-
{
-  language: "fra", // {string} The wanted language
-                   // (ISO 639-1, ISO 639-2 or ISO 639-3 language code)
-  closedCaption: false // {Boolean} Whether the text track should be a closed
-                       // caption for the hard of hearing
-}
-
-

All elements in that Array should be set in preference order: from the most -preferred to the least preferred. You can set null in that array for no -subtitles.

-

When loading a content, the RxPlayer will then try to choose its text track by -comparing what is available with your current preferences (i.e. if the most -preferred is not available, it will look if the second one etc.).

-

This array of preferrences can be updated at any time through the -setPreferredTextTracks method, documented -here.

-

Example

-

Let’s imagine that you prefer to have french or italian subtitles.If not found, -you want no subtitles at all.

-
const player = new RxPlayer({
-  preferredTextTracks: [
-    { language: "fra", closedCaption: false },
-    { language: "ita", closedCaption: false },
-    null
-  ]
-});
-
-

-

⚠️ This option will have no effect in DirectFile mode -(see loadVideo options) when either :

-
    -
  • No text track API is supported on the current browser
  • -
  • The media file tracks are not supported on the browser
  • -
-
-

-

-

preferredVideoTracks

-

type: Array.<Object|null>

-

defaults: []

-

This option allows to help the RxPlayer choose an initial video track.

-

It is defined as an array of objects, each object describing constraints a -track should respect.

-

If the first object - defining the first set of constraints - cannot be -respected under the currently available video tracks, the RxPlayer will skip -it and check with the second object and so on. -As such, this array should be sorted by order of preference: from the most -wanted constraints to the least.

-

When the next encountered constraint is set to null, the player will simply -disable the video track. If you want to disable the video track by default, -you can just set null as the first element of this array (e.g. [null]).

-

Here is all the possible constraints you can set in any one of those objects -(note that all properties are optional here, only those set will have an effect -on which tracks will be filtered):

-
{
-  codec: { // {Object|undefined} Constraints about the codec wanted.
-           // if not set or set to `undefined` we won't filter based on codecs.
-
-    test: /hvc/, // {RegExp} RegExp validating the type of codec you want.
-
-    all: true, // {Boolean} Whether all the profiles (i.e. Representation) in a
-               // track should be checked against the RegExp given in `test`.
-               // If `true`, we will only choose a track if EVERY profiles for
-               // it have a codec information that is validated by that RegExp.
-               // If `false`, we will choose a track if we know that at least
-               // A SINGLE profile from it has codec information validated by
-               // that RegExp.
-  }
-  signInterpreted: true, // {Boolean|undefined} If set to `true`, only tracks
-                         // which are known to contains a sign language
-                         // interpretation will be considered.
-                         // If set to `false`, only tracks which are known
-                         // to not contain it will be considered.
-                         // if not set or set to `undefined` we won't filter
-                         // based on that status.
-}
-
-

This array of preferrences can be updated at any time through the -setPreferredVideoTracks method, documented -here.

-

Examples

-

Let’s imagine that you prefer to have a track which contains at least one H265 -profile. You can do:

-
const player = new RxPlayer({
-  preferredVideoTracks: [ { codec: { all: false, test: /^hvc/ } } ]
-});
-
-

With that same constraint, let’s no consider that the current user is deaf and -would thus prefer the video to contain a sign language interpretation. -We could set both the previous and that new constraint that way:

-
const player = new RxPlayer({
-  preferredVideoTracks: [
-    // first let's consider the best case: H265 + sign language interpretation
-    {
-      codec: { all: false, test: /^hvc/ }
-      signInterpreted: true,
-    },
-
-    // If not available, we still prefer a sign interpreted track without H265
-    { signInterpreted: true },
-
-    // If not available either, we would prefer an H265 content
-    { codec: { all: false, test: /^hvc/ } },
-
-    // Note: If this is also unavailable, we will here still have a video track
-    // but which do not respect any of the constraints set here.
-  ]
-});
-
-
-

For a totally different example, let’s imagine you want to start without any -video track enabled (e.g. to start in an audio-only mode). To do that, you can -simply do:

-
const player = new RxPlayer({
-  preferredVideoTracks: [null]
-});
-
-
-

⚠️ This option will have no effect in DirectFile mode -(see loadVideo options) when either :

-
    -
  • No video track API is supported on the current browser
  • -
  • The media file tracks are not supported on the browser
  • -
-

-

-

maxBufferAhead

-

type: Number|undefined

-

defaults: Infinity

-

Set the maximum kept buffer ahead of the current position, in seconds.

-

Everything superior to that limit (currentPosition + maxBufferAhead) will -be automatically garbage collected.

-

This feature is not necessary as the browser should by default correctly -remove old segments from memory if/when the memory is scarce.

-

However on some custom targets, or just to better control the memory footprint -of the player, you might want to set this limit.

-

Its default value, Infinity, will remove this limit and just let the browser -do this job instead.

-

The minimum value between this one and the one returned by -getWantedBufferAhead will be considered when downloading new segments.

-

⚠️ Bear in mind that a too-low configuration there (e.g. inferior to -10) might prevent the browser to play the content at all.

-

You can update that limit at any time through the setMaxBufferAhead -method.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

maxBufferBehind

-

type: Number|undefined

-

defaults: Infinity

-

Set the maximum kept buffer before the current position, in seconds.

-

Everything before that limit (currentPosition - maxBufferBehind) will be -automatically garbage collected.

-

This feature is not necessary as the browser should by default correctly -remove old segments from memory if/when the memory is scarce.

-

However on some custom targets, or just to better control the memory footprint -of the player, you might want to set this limit.

-

Its default value, Infinity, will remove this limit and just let the browser -do this job instead.

-

You can update that limit at any time through the setMaxBufferBehind -method.

-

-

⚠️ This option will have no effect for contents loaded in DirectFile -mode (see loadVideo options).

-

-

-

limitVideoWidth

-

type: Boolean

-

defaults: false

-

With this feature, the possible video -Representations considered are filtered by width:

-

The maximum width considered is the closest superior or equal to the video -element’s width.

-

This is done because the other, “superior” Representations will not have any -difference in terms of pixels (as in most case, the display limits the maximum -resolution displayable). It thus save bandwidth with no visible difference.

-

To activate this feature, set it to true.

-
const player = Player({
-  limitVideoWidth: true
-});
-
-

For some reasons (displaying directly a good quality when switching to -fullscreen, specific environments), you might not want to activate this limit.

-

-

⚠️ This option will have no effect for contents loaded :

-
    -
  • In DirectFile mode (see [loadVideo options] -(./loadVideo_options.md#prop-transport)).
  • -
  • On Firefox browsers (version >= 67) : We can’t know if the Picture-In-Picture -feature or window is enabled and we can’t know PIP window size. Thus we can’t -rely on video element size attributes, that may not reflect the real video size -when PIP is enabled.
  • -
-

-

-

throttleVideoBitrateWhenHidden

-

type: Boolean

-

defaults: false

-

The player has a specific feature which throttle the video to the minimum -bitrate when the current video element is considered hidden (e.g. the containing -page is hidden and the Picture-In-Picture mode is disabled) for more than a -minute.

-

To activate this feature, set it to true.

-
const player = Player({
-  throttleVideoBitrateWhenHidden: true
-});
-
-

-

⚠️ This option will have no effect for contents loaded :

-
    -
  • In DirectFile mode (see [loadVideo options] -(./loadVideo_options.md#prop-transport)).
  • -
  • On Firefox browsers (version >= 67) : We can’t know if the Picture-In-Picture -feature or window is enabled. Thus we can’t rely on document hiddenness -attributes, as the video may be visible, through the PIP window.
  • -
-

-

-

stopAtEnd

-

type: Boolean

-

defaults: true

-

By default, the player automatically unload the content once it reaches its -end (the player goes to the "ENDED" state).

-

In that case, the only way to play the content again is to (re-)call the -loadVideo API, which will trigger another download of the -Manifest and segments.

-

If you want to be able to seek back in the content after it ended, you may want -to deactivate this behavior. To do so, set stopAtEnd to false.

-
const player = Player({
-  stopAtEnd: false
-});
-
-

-

-

throttleWhenHidden

-

-

⚠️ This option is deprecated, it will disappear in the next major release -v4.0.0 (see Deprecated APIs).

-

Please use the -throttleVideoBitrateWhenHidden property -instead, which is better defined for advanced cases, such as Picture-In-Picture.

-

-

type: Boolean

-

defaults: false

-

The player has a specific feature which throttle the video to the minimum -bitrate when the current page is hidden for more than a minute.

-

To activate this feature, set it to true.

-
const player = Player({
-  throttleWhenHidden: true
-});
-
-

-

⚠️ This option will have no effect for contents loaded :

-
    -
  • In DirectFile mode (see [loadVideo options] -(./loadVideo_options.md#prop-transport)).
  • -
  • On Firefox browsers (version >= 67) : We can’t know if the Picture-In-Picture -feature or window is enabled. Thus we can’t rely on document hiddenness -attributes, as the video may be visible, through the PIP window.
  • -
-
\ No newline at end of file diff --git a/doc/generated/pages/api/plugins.html b/doc/generated/pages/api/plugins.html deleted file mode 100644 index 6c24bc7cef..0000000000 --- a/doc/generated/pages/api/plugins.html +++ /dev/null @@ -1,305 +0,0 @@ -Plugins - RxPlayer Documentation

-

Plugins

-

-

Overview

-

To allow the player to be extended, a system of “plugins” has been added.

-

Those plugins are often under the form of functions passed as an argument to the -loadVideo API call.

-

-

-

segmentLoader

-

The segmentLoader is a function that can be included in the transportOptions -of the loadVideo API call.

-

A segmentLoader allows to define a custom audio/video segment loader (it might -on the future work for other types of segments, so always check the type if you -only want those two).

-

The segment loader is the part performing the segment request. One usecase where -you might want to set your own segment loader is to integrate Peer-to-Peer -segment downloading through the player.

-

To give a complete example, here is a segment loader which uses an XHR (it has -no use, as our implementation does the same thing and more):

-
/**
- * @param {Object} infos - infos about the segment to download
- * @param {string} infos.url - the url the segment request should normally be on
- * @param {Object} infos.adaptation - the Adaptation containing the segment.
- * More information on its structure can be found on the documentation linked
- * below [1]
- * @param {Object} infos.representation - the Representation containing the
- * segment.
- * More information on its structure can be found on the documentation linked
- * below [2]
- * @param {Object} infos.segment - the segment itself
- * More information on its structure can be found on the documentation linked
- * below [3]
-
- * @param {Object} callbacks
- * @param {Function} callbacks.resolve - Callback to call when the request is
- * finished with success. It should be called with an object with at least 3
- * properties:
- *   - data {ArrayBuffer} - the segment data
- *   - duration {Number|undefined} - the duration of the request, in
- *     milliseconds.
- *   - size {Number|undefined} - size, in bytes, of the total downloaded
- *     response.
- * @param {Function} callbacks.progress - Callback to call when progress
- * information is available on the current request. This callback allows to
- * improve our adaptive streaming logic by better predicting the bandwidth
- * before the request is finished.
- * This function should be called with the following properties:
- *   - duration {Number} - the duration since the beginning of the request
- *   - size {Number} - the current size, in bytes, downloaded
- *   - totalSize {Number|undefined} - the whole size of the wanted data, in
- *     bytes. Can be let to undefined when not known.
- * our default implementation instead for this segment. No argument is needed.
- * @param {Function} callbacks.reject - Callback to call when an error is
- * encountered. If you relied on an XHR, it is recommended to include it as an
- * object property named "xhr" in the argument.
- * @param {Function} callbacks.fallback - Callback to call if you want to call
- * our default implementation instead for this segment. No argument is needed.
-
- * @returns {Function|undefined} - If a function is defined in the return value,
- * it will be called if and when the request is canceled.
- */
-const customSegmentLoader = (infos, callbacks) => {
-
-  // we will only use this custom loader for videos segments.
-  if (infos.adaptation.type !== "video") {
-    callbacks.fallback();
-    return;
-  }
-
-  const xhr = new XMLHttpRequest();
-  const sendingTime = performance.now();
-
-  xhr.onload = function onXHRLoaded(r) {
-    if (200 <= xhr.status && xhr.status < 300) {
-      const duration = performance.now() - sendingTime;
-      const size = r.total;
-      const data = xhr.response;
-      callbacks.resolve({ duration, size, data });
-    } else {
-      const err = new Error("didn't work");
-      err.xhr = xhr;
-      callbacks.reject(err);
-    }
-  };
-
-  xhr.onprogress = function onXHRProgress(event) {
-    const currentTime = performance.now();
-    callbacks.progress({ type: "progress",
-                         value: { duration: currentTime - sendingTime,
-                                  size: event.loaded,
-                                  totalSize: event.total } });
-  };
-
-  xhr.onerror = function onXHRError() {
-    const err = new Error("didn't work");
-    err.xhr = xhr;
-    callbacks.reject(err);
-  };
-
-  xhr.open("GET", infos.url);
-  xhr.responseType = "arraybuffer";
-
-  const range = infos.segment.range;
-  if (range) {
-    if (range[1] && range[1] !== Infinity) {
-      xhr.setRequestHeader("Range", `bytes=${range[0]}-${range[1]}`);
-    } else {
-      xhr.setRequestHeader("Range", `bytes=${range[0]}-`);
-    }
-  }
-
-  xhr.send();
-
-  return () => {
-    xhr.abort();
-  };
-};
-
-

[1] Adaptation structure

-

[2] Representation structure

-

[3] Segment structure

-

-

-

manifestLoader

-

The manifestLoader is a function that can be included in the -transportOptions of the loadVideo API call.

-

A manifestLoader allows to define a custom Manifest -loader.

-

The Manifest loader is the part performing the Manifest request.

-

Here is a Manifest loader which uses an XHR (it has no use, as our -implementation does the same thing and more):

-
/**
- * @param {string|undefined} url - the url the Manifest request should normally
- * be on.
- * Can be undefined in very specific conditions, like in cases when the
- * `loadVideo` call had no defined URL (e.g. "local" manifest, playing a locally
- * crafted "Metaplaylist" content).
- * @param {Object} callbacks
- * @param {Function} callbacks.resolve - Callback to call when the request is
- * finished with success. It should be called with an object with at least 3
- * properties:
- *   - data {*} - the Manifest data
- *   - duration {Number|undefined} - the duration of the request, in
- *     milliseconds.
- *   - size {Number|undefined} - size, in bytes, of the total downloaded
- *     response.
- *   - url {string|undefined} - url of the Manifest (post redirection if one).
- *   - sendingTime {number|undefined} - Time at which the manifest request was
- *     done as a unix timestamp in milliseconds.
- *   - receivingTime {number|undefined} - Time at which the manifest request was
- *     finished as a unix timestamp in milliseconds.
- * @param {Function} callbacks.reject - Callback to call when an error is
- * encountered. If you relied on an XHR, it is recommended to include it as an
- * object property named "xhr" in the argument.
- * @param {Function} callbacks.fallback - Callback to call if you want to call
- * our default implementation instead for this segment. No argument is needed.
-
- * @returns {Function|undefined} - If a function is defined in the return value,
- * it will be called if and when the request is canceled.
- */
-const customManifestLoader = (url, callbacks) => {
-  const xhr = new XMLHttpRequest();
-  const baseTime = performance.now();
-
-  xhr.onload = (r) => {
-    if (200 <= xhr.status && xhr.status < 300) {
-      const duration = performance.now() - baseTime;
-
-      const now = Date.now();
-      const receivingTime = now
-
-      // Note: We could have calculated `sendingTime` before the request, but
-      // that date would be wrong if the user updated the clock while the
-      // request was pending.
-      // `performance.now` doesn't depend on the user's clock. It is thus a
-      // better candidate here.
-      // This is why we re-calculate the sendingTime a posteriori, we are now
-      // sure to be aligned with the current clock.
-      const sendingTime = now - duration;
-
-      // the request could have been redirected,
-      // we have to feed back the real URL
-      const _url = xhr.responseURL || url;
-
-      const size = r.total;
-      const data = xhr.response;
-      callbacks.resolve({
-        url: _url,
-        sendingTime,
-        receivingTime,
-        duration,
-        size,
-        data,
-      });
-    } else {
-      const err = new Error("didn't work");
-      err.xhr = xhr;
-      callbacks.reject(err);
-    }
-  };
-
-  xhr.onerror = () => {
-    const err = new Error("didn't work");
-    err.xhr = xhr;
-    callbacks.reject(err);
-  };
-
-  xhr.open("GET", url);
-  xhr.responseType = "document";
-
-  xhr.send();
-
-  return () => {
-    xhr.abort();
-  };
-};
-
-

-

-

representationFilter

-

The representationFilter is a function that can be included in the -transportOptions of the loadVideo API call.

-

A representationFilter allows you to filter out -Representations (i.e. media qualities) based on -its attributes.

-

The representationFilter will be called each time we load a -Manifest with two arguments:

-
    -
  • -

    representation {Representation}: The concerned Representation. -A Representation structure’s is described in the Manifest structure -documentation.

    -
  • -
  • -

    representationInfos {Object}: Basic information about this -Representation. Contains the following keys:

    -
      -
    • -

      bufferType {string}: The concerned type of buffer. Can be -"video", "audio", "text" (for subtitles) or "image" -(for thumbnail).

      -
    • -
    • -

      language {string|undefined}: The language the Representation -is in, as announced by the Manifest.

      -
    • -
    • -

      normalizedLanguage {string|undefined}: An attempt to translate the -language into an ISO 639-3 code. -If the translation attempt fails (no corresponding ISO 639-3 language -code is found), it will equal the value of language

      -
    • -
    • -

      isClosedCaption {Boolean|undefined}: If true, the Representation -links to subtitles with added hints for the hard of hearing.

      -
    • -
    • -

      isAudioDescription {Boolean|undefined}: If true, the -Representation links to an audio track with added commentary for -the visually impaired.

      -
    • -
    • -

      isDub {Boolean|undefined}): If set to true, this audio track is a -“dub”, meaning it was recorded in another language than the original. -If set to false, we know that this audio track is in an original -language. -This property is undefined if we do not known whether it is in an -original language.

      -
    • -
    -
  • -
-

This function should then returns true if the Representation should be -kept or false if it should be removed.

-

For example, here is a representationFilter that removes video -Representations with a video resolution higher than HD (1920x1080):

-
/**
- * @param {Object} representation - The Representation object, as defined in
- * the documentation linked bellow [1]
- * @param {Object} infos - supplementary information about the given
- * Representation.
- * @returns {boolean}
- */
-function representationFilter(representation, infos) {
-  if (infos.bufferType === "video") {
-    // If video representation, allows only those for which the height and width
-    // is known to be below our 1920x1080 limit
-    const { width, height } = representation;
-    return width != null && height != null && width <= 1920 && height <= 1080;
-  }
-
-  // Otherwise, allow all non-video representations
-  return true;
-}
-
-

[1] Representation structure

-
\ No newline at end of file diff --git a/doc/generated/pages/api/states.html b/doc/generated/pages/api/states.html deleted file mode 100644 index eb00f662fa..0000000000 --- a/doc/generated/pages/api/states.html +++ /dev/null @@ -1,385 +0,0 @@ -Player states - RxPlayer Documentation

-

Player states

-

The player state, that you can obtain either with the -getPlayerState method or through the -playerStateChange -player event, is a central part of our API: it is from -this value that you will know:

-
    -
  • when a new content finished loading
  • -
  • when the content is paused to build buffer
  • -
  • when the content is ended
  • -
  • as a generality, in what “state” is the player currently
  • -
-

As such, it is important this concept is understood when developping with the -rx-player, which is exactly the point of this page.

-

-

List of possible states

-

Today the player can have one of these 9 possible states:

-
    -
  • STOPPED
  • -
  • LOADING
  • -
  • LOADED
  • -
  • PLAYING
  • -
  • PAUSED
  • -
  • BUFFERING
  • -
  • SEEKING
  • -
  • ENDED
  • -
  • RELOADING
  • -
-

-

The STOPPED state

-

STOPPED is the default state of the player. It indicates that no content is -playing.

-

To simplify state exploitation, STOPPED is also emitted as a transition state -when loading a new content while another one was currently loaded (or loading). -That way, you can just listen to the STOPPED state to know when the current -content is not loaded anymore.

-

When the player encounters an error, it will also stop and switch -to the STOPPED state.

-

-

The LOADING state

-

The LOADING state indicates that a new content is currently loading. -It appears only after the STOPPED state.

-

That means that the player is currently downloading enough of the content to be -able to play it.

-

While this state is active, most of the content-related APIs (like -setAudioTrack) are not available. You have to wait for the LOADED state for -that.

-

-

The LOADED state

-

LOADED appears only after a LOADING state, and indicates that the current -content can now be played.

-

From this point onward, most of the content-related APIs (like setAudioTrack) -are now available.

-

If the autoPlay loadVideo option has been set to -true, the state will then switch to PLAYING directly. Else, the player will -usually be paused and stay in the LOADED state (there is some edge cases, see -the “Possible state transitions” chapter for more information).

-

-

The PLAYING state

-

Indicates that the player is currently playing the content.

-

-

The PAUSED state

-

Indicates that the player is currently paused in the content.

-

-

The BUFFERING state

-

The content is paused because it needs to build buffer.

-

The player will not play until it gets out of this state.

-

-

The SEEKING state

-

The content is paused because it needs to build buffer after seeking in the -content (this can be seen as a special BUFFERING case).

-

The player will not play until it gets out of this state.

-

-

The ENDED state

-

The player reached the end of the content.

-

If the stopAtEnd player option has been set to -true or not set, the player will immediately stop the content. In that case, -the ENDED state can be considered like the STOPPED state - in terms of what -you can do.

-

Else, it should now be paused at the last frame if a video content is available -at this time and this state acts like what you can expect from HTML5 playback:

-
    -
  • -

    when seeking when the content is ended, you will be paused (even if you -were playing before)

    -
  • -
  • -

    after calling play, you will play back from the beginning

    -
  • -
-

-

The RELOADING state

-

This state indicates that the player needs to “re-load” then content.

-

This can happen for different reasons:

-
    -
  • -

    When you switch the video track for another one, when the previous one was -currently decoding.

    -
  • -
  • -

    When you update manually the audio and video bitrate through respectively -the setAudioBitrate and setVideoBitrate APIs -(Only if you set the manualBitrateSwitchingMode loadVideo option to -"direct").

    -
  • -
-

In those cases, we need to stop and reload the content on the browser-side, due -to browser limitation.

-

While this state is active, multiple player API are unavailable:

-
    -
  • you cannot play or pause
  • -
  • you cannot seek
  • -
  • you cannot obtain the position or duration
  • -
  • you cannot get or switch the available video, text or audio tracks.
  • -
  • you cannot get or switch the available video or audio bitrates.
  • -
-

This is why we sometime recommend to manage this state as if it was the -LOADING state (where those APIs - and other - are also not available).

-

However, the player won’t go to the LOADED state after RELOADING, you will -instead know that it had finished reloading simply when it goes out of this -state (see the “Possible state transitions” chapter for more information).

-

-

Possible state transitions

-

The player goes from one state to another during runtime but those changes does -not happen at random. There is actually possible state transitions (like from -STOPPED to LOADING) and impossible ones (like from LOADING to SEEKING).

-

We will list here every possible state transitions. -Note that we can never have two times the same state consecutively.

-

From STOPPED:

-
    -
  • LOADING: a new content begin to load
  • -
-

From LOADING:

-
    -
  • -

    LOADED: the loading content was loaded succesfully and can now be played -(most of the content-related APIs can also be used from this point)

    -
  • -
  • -

    STOPPED: Either:

    -
      -
    • You stopped the current through the stop method.
    • -
    • You are loading a new content.
    • -
    • An error happened which made it impossible to load the content. -The corresponding error can be found either through the -getError method method or through the -playerStateChange -player event.
    • -
    -
  • -
-

From LOADED:

-
    -
  • -

    PLAYING: The content started to play.

    -
  • -
  • -

    SEEKING: A user seeked in the content.

    -
  • -
  • -

    ENDED: You are at the end of the content. -Calling play will play back from the beginning.

    -
  • -
  • -

    RELOADING: The content needs to be reloaded.

    -
  • -
  • -

    STOPPED: Either:

    -
      -
    • You stopped the current through the stop method.
    • -
    • You are loading a new content.
    • -
    • An error happened which made it impossible to play the content. -The corresponding error can be found either through the -getError method method or through the -playerStateChange -player event.
    • -
    -
  • -
-

From PLAYING:

-
    -
  • -

    PAUSED: The content is paused.

    -
  • -
  • -

    SEEKING: A user seeked in the content.

    -
  • -
  • -

    BUFFERING: The player needs to pause to download content.

    -
  • -
  • -

    ENDED: You are at the end of the content. -Calling play will play back from the beginning.

    -
  • -
  • -

    RELOADING: The content needs to be reloaded.

    -
  • -
  • -

    STOPPED: Either:

    -
      -
    • You stopped the current through the stop method.
    • -
    • You are loading a new content.
    • -
    • An error happened which made it impossible to play the content. -The corresponding error can be found either through the -getError method method or through the -playerStateChange -player event.
    • -
    -
  • -
-

From PAUSED:

-
    -
  • -

    PLAYING: The content plays (is un-paused).

    -
  • -
  • -

    SEEKING: A user seeked in the content.

    -
  • -
  • -

    BUFFERING: The player needs to pause to download content.

    -
  • -
  • -

    ENDED: You are at the end of the content. -Calling play will play back from the beginning.

    -
  • -
  • -

    RELOADING: The content needs to be reloaded.

    -
  • -
  • -

    STOPPED: Either:

    -
      -
    • You stopped the current through the stop method.
    • -
    • You are loading a new content.
    • -
    • An error happened which made it impossible to play the content. -The corresponding error can be found either through the -getError method method or through the -playerStateChange -player event.
    • -
    -
  • -
-

From BUFFERING:

-
    -
  • -

    PLAYING: The content plays (and finished buffering)

    -
  • -
  • -

    PAUSED: The content is paused (and finished buffering)

    -
  • -
  • -

    ENDED: You are at the end of the content. -Calling play will play back from the beginning.

    -
  • -
  • -

    RELOADING: The content needs to be reloaded.

    -
  • -
  • -

    STOPPED: Either:

    -
      -
    • You stopped the current through the stop method.
    • -
    • You are loading a new content.
    • -
    • An error happened which made it impossible to play the content. -The corresponding error can be found either through the -getError method method or through the -playerStateChange -player event.
    • -
    -
  • -
-

From SEEKING:

-
    -
  • -

    PLAYING: The content plays (and finished to seek)

    -
  • -
  • -

    PAUSED: The content is paused (and finished to seek)

    -
  • -
  • -

    ENDED: You are at the end of the content. -Calling play will play back from the beginning.

    -
  • -
  • -

    RELOADING: The content needs to be reloaded.

    -
  • -
  • -

    STOPPED: Either:

    -
      -
    • You stopped the current through the stop method.
    • -
    • You are loading a new content.
    • -
    • An error happened which made it impossible to play the content. -The corresponding error can be found either through the -getError method method or through the -playerStateChange -player event.
    • -
    -
  • -
-

From ENDED if the stopAtEnd player option has been -set to true or not set:

-
    -
  • STOPPED: Only state transition possible here. Happens if either: -
      -
    • You stopped the current through the stop method.
    • -
    • You are loading a new content.
    • -
    -
  • -
-

From ENDED if the stopAtEnd player option has been -set to false:

-
    -
  • -

    PLAYING: The play method was called. -The content plays back from the beginning.

    -
  • -
  • -

    PAUSED: A user seeked into a part of the content already-downloaded. -The content is paused after the seek, regardless of if you were paused -before reaching the ENDED state.

    -
  • -
  • -

    SEEKING: A user seeked in the content.

    -
  • -
  • -

    RELOADING: The content needs to be reloaded.

    -
  • -
  • -

    STOPPED: Either:

    -
      -
    • You stopped the current through the stop method.
    • -
    • You are loading a new content.
    • -
    • An error happened which made it impossible to play the content. -The corresponding error can be found either through the -getError method method or through the -playerStateChange -player event.
    • -
    -
  • -
-

From RELOADING:

-
    -
  • -

    PLAYING: The content finished to reload and was not paused before -reloading.

    -
  • -
  • -

    PAUSED: The content finished to reload and was paused before -reloading.

    -
  • -
  • -

    ENDED: The content finished to reload and you are at the end of the -content. -Calling play will play back from the beginning.

    -
  • -
  • -

    STOPPED: Either:

    -
      -
    • You stopped the current through the stop method.
    • -
    • You are loading a new content.
    • -
    • An error happened which made it impossible to reload the content. -The corresponding error can be found either through the -getError method method or through the -playerStateChange -player event.
    • -
    -
  • -
-
\ No newline at end of file diff --git a/doc/generated/pages/api/text_tracks.html b/doc/generated/pages/api/text_tracks.html deleted file mode 100644 index 836fe66523..0000000000 --- a/doc/generated/pages/api/text_tracks.html +++ /dev/null @@ -1,155 +0,0 @@ -Text tracks - RxPlayer Documentation

-

Text tracks

-

-

-

Overview

-

The rx-player allows to display text tracks - such as subtitles or closed -captions - directly over your content:

-

Example of a textrack on acontent

-

Adding text tracks to contents can be done by two means:

-
    -
  • by using a Manifest declaring those text tracks
  • -
  • by manually adding text track(s) when you call the loadVideo API
  • -
-

You can then choose the right track through the different text track-related -API, all documented in the general API documentation.

-

-

-

Supported text track formats

-

The rx-player supports the following formats:

-
    -
  • TTML (TTML1, EBU-TT and IMSC1)
  • -
  • WebVTT
  • -
  • SAMI
  • -
  • SRT
  • -
  • TTML embedded in an MP4 file
  • -
  • WebVTT embedded in an MP4 file
  • -
-

-

-

Text tracks indicated in a manifest

-

Each streaming technology supported by the Manifest defines a way to add text -track directly in their Manifests files.

-

This chapter explains what is supported by the RxPlayer.

-

-

-

In DASH

-

In DASH, text tracks are defined by AdaptationSet elements, which have a -contentType attribute equal to text.

-

Those AdaptationSet can also define a lang, codecs and mimeType, -which are then exploited by the RxPlayer.

-
-

The lang attribute is used to know the language the track is in.

-

The RxPlayer understands the following standards:

-
    -
  • ISO 639-1 (2 letters)
  • -
  • ISO 639-2 (3 letters)
  • -
  • ISO 639-3 (3 letters)
  • -
-

More complex combined formats are also understood, as long as it begins by one -of the understood standards, followed by a dash (“-”).

-

For example “en-US” is translated into just “en”, and then inferred to be -english.

-
-

The mimeType attribute is used to know in which format the track is in.

-

The RxPlayer understands the following ones:

-
    -
  • application/ttml+xml: TTML in plain text
  • -
  • text/vtt: WebVTT in plain text
  • -
  • application/x-sami: SAMI in plain text
  • -
  • application/mp4: Text track embedded in an MP4 container.
  • -
  • text/plain: Generic plain text mimeType
  • -
-

For the last two, the codecs attribute of the AdaptationSet will be -exploited to know the exact format.

-
-

The rx-player uses the codecs attribute for text tracks in only two cases:

-
    -
  • the mimeType is equal to application/mp4
  • -
  • the mimeType is equal to text/plain
  • -
-

For the first case, both WebVTT and TTML can be embedded in an MP4 file. To know -which one we’re dealing with, the codecs attribute should be equal to:

-
    -
  • stpp for TTML
  • -
  • wvtt for WebVTT
  • -
-

For the second case ("text/plain"), this is specifically to support plain -SubRip (SRT) subtitles. To use them you need to set codecs simply to -srt.

-
-

To know if we’re dealing with a closed caption text track, the RxPlayer uses the -DVB-DASH specification.

-

That is, an AdaptationSet is inferred to be a closed caption for the hard of -hearing, if it contains an Accessibility descriptor with the following -attributes:

-
    -
  • SchemeIdUri set to urn:tva:metadata:cs:AudioPurposeCS:2007
  • -
  • value set to 2
  • -
-

-

-

In Microsoft Smooth Streaming

-

In Smooth Manifests, a StreamIndex is inferred to be for a text track if its -Type attribute is equal to text.

-
-

The FourCC attribute is used to infer the format of the text track. Only -TTML is understood, and is translated to be a TTML track embedded in an MP4 -container.

-

Adding support for other formats is very simple, open an issue if you want us to -add a standardized FourCC code for another supported format.

-
-

The Language is used to know the language the track is in. The rules are the -same than for DASH:

-

The rx-player understand the following standards:

-
    -
  • ISO 639-1 (2 letters)
  • -
  • ISO 639-2 (3 letters)
  • -
  • ISO 639-3 (3 letters) -More complex combined formats are also understood, as long as it begins by one -of the understood standards, followed by a dash (“-”).
  • -
-

For example “en-US” is translated into just “en”, and then inferred to be -english.

-
-

The Subtype attribute is used to know if the language is a closed caption or -not.

-

At the moment, the RxPlayer infers the track to be a closed caption only if its -value is DESC.

-

-

-

Text tracks added manually

-

It is also possible to add a supplementary text track dynamically, by using the -TextTrackRenderer tool. You can read its documentation -here.

-

-

-

Text track display modes

-

There is two ways the text track can be displayed:

-
    -
  • -

    "native": The text track is displayed in <track> elements, which are -directly in the linked videoElement.

    -
  • -
  • -

    "html": The text track is displayed in a separate <div> element.

    -
  • -
-

The second ones allows for a better track stylisation. The distinction between -those two is pretty simple and is explained -here, in the loadVideo options -documentation.

-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/abr/bandwidth_estimator.html b/doc/generated/pages/architecture/abr/bandwidth_estimator.html deleted file mode 100644 index bf70845db1..0000000000 --- a/doc/generated/pages/architecture/abr/bandwidth_estimator.html +++ /dev/null @@ -1,50 +0,0 @@ -ABRManager - Bandwidth estimator - RxPlayer Documentation

-

ABRManager - Bandwidth estimator

-
                 Long
-                 (normal mode) [2]
-                         +----------+ Buffer Gap [1] +-------+
-                         |                                   |
-                         v                                   |Short
-                     Request(s)                              |(starvation mode)
-                     datas                                   |[4]
-                         +                                   |
-                         |                                   |
-                         |                                   |
-    Request time length  |                                   |
-    Data size            |                                   |
-                         |                                   |
-+- - - - - - - - - - - + v +- - - - - - - - - - -+           v
-| Short term EWMA [2a] |   | Long term EWMA [2b] |     Last request
-+- - - - - - - - + - - +   +- - -+- - - - - - - -+           +
-                 |               |                           |
-             + - + - - - - - - - + - +       +- - - - - - - -v- - - - - - +
-             | Ceil bitrate (minimum |       | Ceil bitrate               |
-             | between both) [3]     |       | (bandwidth estimation from |
-             + - - - - - + - - - - - +       | last request [5]           |
-                         |        ^          + - - - - - - - - - -+- - - -+
-                         |        |                   ^           |
-                         v        |                   |           v
-                      Ceiled      +---+ Available +---+      Ceiled
-                      bitrate           qualities            bitrate
-                         +                                       +
-                         |                                       |
-                         |                                       |
-                         +---------> Chosen quality <------------+
-
-

[1] The buffer gap is the distance between the current time and the buffer time -edge.

-

[2] If the buffer gap is long (more than 5 seconds in default configuration): -From requests computed bandwidths (data size / request time), calculate two -EWMA.

-

[2a] The first, a fast-moving average, falls quickly when estimated bandwidth -falls suddenly.

-

[2b] The second, a slow-moving average, is a bandwidth mean.

-

[3] For quality of service, the player should adapt down quickly, to avoid -buffering situations, and grow up slowly, in order to smoothly change quality. -For this reason, the minimum between the two estimated is considered as a -bitrate threshold. The chosen quality is a quality’s bitrate ceiling.

-

[4] If the buffer gap is too short, it is considered as “starving”:

-

[5] An immediate bandwidth is computed from last or current request. -The quality’s bitrate ceiling relies on it to return the chosen quality.

-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/abr/buffer_based_chooser.html b/doc/generated/pages/architecture/abr/buffer_based_chooser.html deleted file mode 100644 index 6dd91b4ad3..0000000000 --- a/doc/generated/pages/architecture/abr/buffer_based_chooser.html +++ /dev/null @@ -1,52 +0,0 @@ -ABRManager - Buffer based estimator - RxPlayer Documentation

-

ABRManager - Buffer based estimator

-
                              Qualities
-                                  |
-                                  |
-                                  v
-                       +- - - - - + - - - - - - +
-    buffer gap [2]     | compute BOLA steps [1] |   maintainability score [3]
-         |             +- - - - - - - - - - - - +           +
-         |                        |                         |
-         |                        v                         |
-         |            +- - - - - - - - - - - - -+           |
-         +----------> | Compute optimal quality | <---------+
-                      +- - - - - - - - - - - - -+
-
-

BOLA Algorithm finds optimal quality -value to minimize playback buffering and maximize buffered quality.

-

[1] BOLA broadly defines minimum buffer steps for which we can allow to download -a quality:

-
                ^
-Bitrates (kb/s) |
-                |
-           3200 |                           +-------------------------+
-                |                           |
-           1500 |                    +------+
-                |                    |
-            750 |             +------+
-                |             |
-            300 |      +------+
-                |      |
-                +------+------------------------------------------------->
-                       5      10     15     20
-
-                                 Buffer gap (s)
-
-

[2] The BOLA estimation is computed each time a segment is appended (thus buffer -gap is updated).

-

The RxPlayer has a mecanism that allows to replace low-quality buffered segments -by higher quality ones if the current conditions improve. -That leads to the buffer gap not increasing when a chunk is added. -That could mislead BOLA, and cause oscillations between chosen qualities.

-

[3] In order to avoid this trend, we compute a maintainability score for the -currently downloaded quality. It is an EWMA - of the ratio between segment duration and -segment download time. If the score points that a quality is “maintainable”, the -algorithm shall not decide to decrease quality and is “allowed” to pick an upper -quality. Conversely, when a quality may not be downloadable fast enough, the -BOLA is “allowed” to decrease the estimated quality, and shall not decide to -increase it.

-

If no maintanaibility score is computed, then BOLA works the regular way.

-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/abr/index.html b/doc/generated/pages/architecture/abr/index.html deleted file mode 100644 index bde5b4dec3..0000000000 --- a/doc/generated/pages/architecture/abr/index.html +++ /dev/null @@ -1,34 +0,0 @@ -ABRManager - RxPlayer Documentation

-

ABRManager

-

-

Overview

-

The ABRManager (ABR for Adaptive BitRate) is a class which facilitates the -choice between multiple audio/video qualities in function of the current -bandwidth, the network capacities and other specific settings set by the client.

-

It does so by receiving various values such as:

-
    -
  • when network requests begin, progresses or end
  • -
  • stats about the bandwidth of the user
  • -
  • the current status of the buffer (how much of the buffer is left etc.)
  • -
  • DOM events
  • -
  • user settings (maximum authorized bitrate/width etc.)
  • -
  • the available qualities
  • -
-

With all those variables at hand, it then proposes the quality which seems to -be the most adapted, that is the quality which:

-
    -
  • will respect user settings (example: a Maximum bitrate is set)
  • -
  • will maximize the user experience (example: a quality too high for the -network to handle would lead to excessive re-bufferings, but a too low would -be not as pleasant to watch)
  • -
-

In order to estimate the quality that maximizes the playback experience, the ABR -relies on two “estimators”. The bandwidth estimator -picks a quality from network conditions. The -buffer based chooser relies on buffering conditions -to make his choices.

-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/api/index.html b/doc/generated/pages/architecture/api/index.html deleted file mode 100644 index 2fab160576..0000000000 --- a/doc/generated/pages/architecture/api/index.html +++ /dev/null @@ -1,79 +0,0 @@ -The API - RxPlayer Documentation

-

The API

-

-

Overview

-

The API is the front-facing part of the code. -It will be the only layer used by applications integrating the RxPlayer library.

-

As such, its main roles are to:

-
    -
  • -

    provide a comprehensive API for the user

    -
  • -
  • -

    translate user order into actions in the player

    -
  • -
  • -

    redirecting events to the user

    -
  • -
-

-

Why is it so big?

-

core/api/public_api.ts is at the time of writing the longest file in all the -RxPlayer, with more than 2000 lines!

-

So why is that, isn’t that a signal that we should split up its role into -multiple files?

-

Well, yes and no. -The reason why it ends up so big is mainly because of the following reasons:

-
    -
  • -

    our API is itself pretty big!

    -
  • -
  • -

    The API needs to have a considerable state because most of the other modules -rely on Observables.

    -

    I’ll explain: -The API can’t just interogate at any time the concerned module as if it was -a class with methods. Here most modules are functions which send events.

    -

    The problem is that a library user might want to have an information at any -given moment (for example, the current bitrate), which internally is only -sent as an event by some module. -It is thus the role of the API to store that information when it receives -this event to then communicate it back to the user.

    -
  • -
-

A huge part of what is defined in that file is actually the entire API, as -small functions. We found that having the whole API in a single file was -actually useful.

-

Likewise, as the API is a single class with a huge private state, being able -to see those state mutations in a single file allows us to better think about -how it all works.

-

Still, we did some efforts to reduce the size of that file. For example, some -long argument-parsing code has been moved out of this file, into -core/api/option_parsers. We might find other ways to reduce that size in the -future, but that’s not a main concern for now.

-

-

Subparts

-

To facilitate those actions, the API relies on multiple building blocks:

-
    -
  • -

    the Clock

    -

    Provide an Observable emitting regularly the current viewing conditions for -the Player. Many RxPlayer modules rely on that clock.

    -
  • -
  • -

    the TrackChoiceManager

    -

    Ease up text/audio/video track switching to provide a simple-to-use API.

    -
  • -
  • -

    the option parsers

    -

    Parse options given to some RxPlayer API calls, to add default parameters -and provide inteligible warnings/errors

    -
  • -
-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/eme/index.html b/doc/generated/pages/architecture/eme/index.html deleted file mode 100644 index 26c4a0b015..0000000000 --- a/doc/generated/pages/architecture/eme/index.html +++ /dev/null @@ -1,16 +0,0 @@ -The EMEManager - RxPlayer Documentation

-

The EMEManager

-

-

Overview

-

The EMEManager in the core/eme directory allows to easily interface with -the browser APIs for decrypting a crypted content, it follows the Encrypted -Media Extensions recommandations.

-

Like most modules in the RxPlayer, the EMEManager is just a function - called -a single time - returning an Observable.

-

This Observable then return event corresponding to different milestones related -to decrypting the content.

-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/fetchers/index.html b/doc/generated/pages/architecture/fetchers/index.html deleted file mode 100644 index e977f333f8..0000000000 --- a/doc/generated/pages/architecture/fetchers/index.html +++ /dev/null @@ -1,84 +0,0 @@ -The fetchers - RxPlayer Documentation

-

The fetchers

-

-

Overview

-

The fetchers is the part of the code interacting with the transport protocol, -defined in transports, to download and parse:

-
    -
  • the Manifest
  • -
  • media Segments
  • -
-

Each of those task is performed by a discrete component of the fetchers:

-
    -
  • -

    The Manifest fetcher is used to download and parse the manifest file.

    -
  • -
  • -

    The SegmentFetcherCreator is used to create Segment fetchers, -allowing to download and parse media segments.

    -
  • -
-

-

The Manifest fetcher

-

The Manifest fetcher allows to download and parse the Manifest/Playlist of the -current transport protocol to return an unified Manifest object.

-

This is the part of the code that interacts with transports to perform the -request and parsing of the Manifest file.

-

-

The SegmentFetcherCreator

-

The SegmentFetcherCreator allows to easily perform segment downloads for the -rest of the code. -This is the part of the code that interacts with the transport protocols - -defined in transports - to load and parse media segments.

-

To do so, the SegmentFetcherCreator creates “segment fetchers” of different -types (example: a video or audio segment fetcher) when you ask for it. -Through those fetchers, you can then schedule various segment requests with a -given priority.

-

The priority of this request is then corroborated with the priority of all -requests currently pending in the SegmentFetcherCreator (and not only with -those on the current segment fetcher) to know when the request should -effectively be done - more prioritary requests will be done first.

-

During the lifecycle of the request, the segment fetcher will communicate about -data and metrics through several means - documented in the code.

-

-

Priorization

-

Each Segment request can be linked to a priorization number. -Such number will indicate which segment is needed more immediately than other -(the lower it is, the higher the priority of the segment is).

-

This is for example used to indicate that a very close video segment has a -higher priority than some distant audio segment (both might be scheduled at the -same time depending on the situation).

-

If the request has no priorization number, the lowest priorization number -(the highest priority) will be set on it: 0

-

Basically, any new request will have their priorization number compared to the -one of the current request(s) done by the SegmentFetcherCreator:

-
    -
  • -

    if no request is already pending, we perform the request immediately

    -
  • -
  • -

    if (and only if) this priorization number is higher (so lower priority) than -all current requests, this new request will be postponed to let the -higher-priority ones finish.

    -
  • -
  • -

    If a new request has a priorization number lower or equal than all current -downloads, we perform the request immediately without interrupting the -current, lower-priority ones.

    -
  • -
-

The priority of a download can be updated at any time, until this request either -has finished, was canceled or failed. The same rules apply when the priorization -number is updated (if this request is already pending, we keep it going in any -case).

-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/files.html b/doc/generated/pages/architecture/files.html deleted file mode 100644 index ab5b77002b..0000000000 --- a/doc/generated/pages/architecture/files.html +++ /dev/null @@ -1,287 +0,0 @@ -File architecture - RxPlayer Documentation

-

File architecture

-

This page describes how the player files are organized. Each chapter go through -a single directory or subdirectory, in alphabetical order.

-

-

-

The demo/ directory: Demos of rx-player implementations

-

Demonstration of functional codebases implementing the rx-player.

-

At the time of writing, there are two demos:

-
    -
  • -

    full: Demo with a graphic interface, written with the React library, to -showcase what the player can do

    -
  • -
  • -

    standalone: Just expose the rx-player in window, to allow scripted -interactions with it in the console. The player is linked to a video tag in -the displayed page.

    -
  • -
-

-

-

The dist/ directory: Player builds

-

Store the player builds of the last version released.

-

Contains two files: the minified (rx-player.min.js) and the non-minified -files (rx-player.js). Both are automatically generated with scripts at every -new release.

-

Two directories, namely _esm5.raw and _esm5.processed can also be -generated in here if the right scripts are called. -These allow to publish more modular codebases to npm.

-

-

-

The doc/ directory: Player documentation

-

Documentation, mostly in markdown, of various subjects related to the rx-player:

-
    -
  • -

    API documentation

    -
  • -
  • -

    code architecture documentation

    -
  • -
  • -

    documentation to help developpers (to use APIs, switch versions, know which -APIs are deprecated)

    -
  • -
-

-

-

The scripts/ directory: scripts

-

Contains various scripts used to help the test and the management of the player -code.

-

For example:

-
    -
  • generating one of the demo and starting the server to run it
  • -
  • deploying the demo or doc to github pages
  • -
  • updating the player version
  • -
  • generating the rx-player build before publishing on npm
  • -
-

-

-

The src/ directory: the source code

-

The src contains the entire source code of the rx-player.

-

It is subdivized into subdirectories which are defined here.

-

-

-

src/compat/: The compatibility files

-

src/compat contains functions allowing to use browser APIs in a -cross-browser manner.

-

For example, if an event does not have the same name depending on the browser, -the compat files will expose a simple function allowing to make sure the event -is catched, taking the task of registering the right event on the callback -given.

-

Every functions needed in the rest of the code are exported in -compat/index.js, making it easier to import (e.g. by just doing -import { whatINeed } from "../compat";)

-

-

-

src/core/: The core files

-

Defines the logic and behavior of the player, regardless of the browser and of -the streaming technology used.

-

That’s where:

-
    -
  • the api is defined
  • -
  • the MSE and EME APIs are called and managed
  • -
  • the segments are downloaded and pushed to then be decoded by the browser
  • -
  • adaptive bitrate strategies are set
  • -
-

This directory contains other subdirectories which are listed in the next -chapter.

-

-

-

src/errors/: Error definitions

-

Contains the definition of the error classes used in the rx-player and -accessible through the API.

-

-

-

src/experimental/: Experimental features

-

You will find here experimental features. Those are tested features who might -completely change their API in new player versions.

-

-

-

src/features/: Feature switching

-

This manage activated or deactivated features (e.g. DASH, TTML subtitles -parsing).

-

It exports an object defining the different activated features and provide utils -to initialize and update them.

-

-

-

src/manifest/: The Manifest class

-

Defines a common Manifest class, regardless of the streaming technology (DASH, -HSS…). This class is then used by the rest of the RxPlayer, to allow -interaction with it without considering the underlying technology used.

-

-

-

src/transports/: The transport protocols

-

Defines a common interface for multiple streaming technologies (DASH, HSS).

-

What is exported there are functions to load:

-
    -
  • Manifests/MPDs
  • -
  • video/audio segments
  • -
  • subtitles tracks
  • -
  • image tracks
  • -
-

For different streaming technologies.

-

As in most of the code of the rx-player, everything used in the other parts of -the code is exported in the index.js file at the root of this directory.

-

-

-

src/parsers/: The parsers

-

Functions to parse various formats into the same interface.

-

The parsed data being either:

-
    -
  • Manifest documents: DASH’s MPD, HSS’s Manifest…
  • -
  • containers: ISOBMFF (CMAF, fMP4, MP4), Matroska (MKV, WEBM)
  • -
  • text tracks: TTML, SAMI, SRT, WebVTT
  • -
  • image containers: BIF
  • -
-

-

-

src/typings/: Typescript typings

-

This directory contains only declaration files for TypeScript. It is -automatically added as a typeRoots when the TypeScript code is transpiled.

-

-

-

src/utils/: The utils

-

This directory contains general helpers which are used in different parts of the -rx-player code.

-

-

-

The src/core/ directory

-

As written in the previous chapter, this is the “core” of the player, where the -logic is defined.

-

As this directory is versatile and complicated, it also deserves its own chapter.

-

-

-

src/core/abr/: The adaptive bitrate code

-

Defines an ABRManager class which manages the adaptive streaming part of the -player.

-

This manager takes various observables/options as inputs to record the current -situation of the player, give an opinion about the best media tracks to choose, -and provide methods allowing to get/set various ABR-related options.

-

Despite containing several files and using several classes, only the ABRManager -defined in abr/index.js should be needed by the rest of the core. -This allows to isolate this complex part and facilitate future refactoring and -improvements.

-

-

-

src/core/api/: The API definition

-

Defines the rx-player API. This is the part the library user will directly -interact with.

-

-

-

src/core/stream/: Load the right segments

-

The code there calculate which segments should be downloaded, ask for their -download and push the segments into the SegmentBuffers.

-

-

-

src/core/eme/: Encryption management

-

Defines functions allowing to handle encrypted contents through the EME APIs.

-

-

-

src/core/fetchers/: The fetchers

-

Handle the segments and Manifest downloading pipelines (load and parse) as -defined in the src/transports/ directory.

-

This is the layer directly interacting with the transport part (HSS, DASH). -It facilitates the role of loading the Manifest and new segments for the rest of -the core.

-

-

-

src/core/segment_buffers/: The media buffers

-

Code allowing to interact with the media buffers called SegmentBuffers.

-

Those are the Objects to which segments are pushed so they can be decoded at the -right time.

-

For Audio and Video, SegmentBuffers rely on a native SourceBuffer object, -already provided by the browser, -for other type of contents (like subtitles), we rely on completely custom media -buffers implementations.

-

-

-

src/core/init/: Content initialization

-

This is the central part which download manifests, initialize MSE and EME APIs, -instanciate the central StreamOrchestrator (which will allow to download and -push segments so the content can play) and link together many subparts of the -player.

-

-

-

src/**/tests: the unit tests directories

-

You will find multiple directories named __tests__ in the RxPlayer. -Those contain unit tests and are put in the same directory than the code it -tests.

-

Most unit tests files contain only tests for a single source file. Those will -be put directly at the root of __tests__ under the name -<ORIGINAL_SRC_FILE>.test.ts (where <ORIGINAL_SRC_FILE> is the filename of -the tested file).

-

__tests__ directories can also contain files defining tests for multiple files -contained in the tested directory. -Those can be quicker to write and easier to maintain at the expense of being -less thorough.

-

Those type of “global” unit tests are put in a special __global__ directory, -itself directly at the root of the corresponding __tests__ directory. -Their filename don’t follow the same convention than single-source unit tests -but should still be suffixed by .test.ts.

-

-

-

The tests/ directory: the player’s tests

-

This directory contains most testing code for the RxPlayer.

-

The rx-player contains multiple type of tests:

-
    -
  • -

    integration tests: test the whole player API and its behavior when playing -different contents. The main goal of those tests is to quickly detect -regressions.

    -

    Those are entirely written in the tests/integration sub-directory.

    -
  • -
  • -

    conformance tests: Provide standalone page which allows to quickly test the -support of various media-related API on a given device and/or browser.

    -

    The html documents you will find here are basic templates that can be easily -modified and deployed for quick testing.

    -
  • -
  • -

    unit tests: test specific parts of the code. The main goal here is to check -the implementation of smaller units of code.

    -

    They are written alongside the code, in __tests__ -directories. All its configuration can be found at the root of the project, -in jest.config.js (we use the jest library for unit tests).

    -
  • -
  • -

    memory tests: test the memory usage of the player.

    -

    They are entirely written in the tests/memory subdirectory.

    -
  • -
-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/index.html b/doc/generated/pages/architecture/index.html deleted file mode 100644 index fc3ebb8fb1..0000000000 --- a/doc/generated/pages/architecture/index.html +++ /dev/null @@ -1,171 +0,0 @@ -RxPlayer Architecture documentation - RxPlayer Documentation

-

RxPlayer Architecture documentation

-

-

Overview

-

The files in this directory and subdirectories establish a documentation about -the RxPlayer’s architecture.

-

They are here to help you understand the way the player works, by describing -the different bricks and algorithms that come into play.

-

Note: As some terms used here might be too foreign or slightly different than -the one you’re used to, we also wrote a list of terms and definitions used by -the RxPlayer here.

-

-

Organization of the documentation

-

The RxPlayer is heavily modularized.

-

This helps us maintaining the code and providing evolutions more quickly, as the -various modules use few well-defined interfaces with the rest of the code.

-

Like the code, the documentation is also divided in multiple parts, which link -one by one to a module in the code.

-

Such modules are (with link to their respective documentation, if one):

-
    -
  • -

    the API

    -

    Defines the public API of the RxPlayer and provides abstractions to help -implementing it.

    -
  • -
  • -

    the Init

    -

    Initialize playback and connects the different modules between one another.

    -
  • -
  • -

    the EMEManager

    -

    Negotiate content decryption.

    -

    Only used for contents with DRM (Digital Right Management).

    -
  • -
  • -

    the ABRManager

    -

    Helps to choose the best quality in the current content by analyzing the -current network, user settings and viewing conditions.

    -
  • -
  • -

    the Stream

    -

    Choose which media segments to download and push them to media buffers (here -called the SegmentBuffers) to then be able to decode them.

    -

    Various files documenting the Stream architecture should be available in -the doc/architecture/stream directory.

    -
  • -
  • -

    the SegmentBuffers

    -

    Implement media buffers on which loaded segments will be pushed. -The corresponding media data contained in them will then be decoded at the -right time.

    -

    Those buffers can depend on browser implementations (for example for audio -and video contents, we rely on SourceBuffer JS objects) or may be -completely defined in the code (for example, text track buffers in the -"html" textTrackMode are entirely defined in the RxPlayer).

    -

    Those SegmentBuffers have added niceties over just being simple data -buffers. For example, they include an inventory which allows to retrieve the -metadata about every segments that is still contained within it.

    -
  • -
  • -

    the transports

    -

    Perform manifest/segment requests, and parse them.

    -

    transports in essence abstracts the transport protocol used (example: -Smooth Streaming/DASH) to provide an unified definition of a segment or -manifest to the other modules. -In theory, it should be the only directory to update when adding / -modifying / deleting a transport protocol

    -
  • -
  • -

    the fetchers

    -

    Link the transports module with the rest of the code, to download -segments, download/refresh the manifest and collect data (such as the -user’s bandwidth) for the other modules.

    -
  • -
-

The RxPlayer also has a multitude of isolated helpers (for manifest management, -segment parsing, browser compatibility, feature switching, error handling etc.) -which are used by these different modules.

-

A documentation about the file organization of the project is available -here.

-

-

Global architecture

-

To better understand the player’s architecture, you can find below a -(simplified!) schema of it:

-
               +---------------------------------------------+              ,,,,,,,
-               |                                             |             (  CDN  )
-               |               Application/UI                |              ```````
-               |                                             |                 ^
-               +---------------------------------------------+                 |
-                          | ^                                                  |
-                          | ~                                                  |
------RxPlayer------------------------------------------------------------------|----------
-                          | ~                          +-------------------+   |
-                          V ~     Front-facing API     |  ---> Call        |   |
-     +-------------------------------------------+     |  ~~~> Send events |   |
-     |                    API                    |     +-------------------+   |
-     +-------------------------------------------+                             |
- +--------------------+    |      | ^                                          |
- | TrackChoiceManager | <--+      | ~                                          |
- +--------------------+           | ~                                          |
- Facilitate track                 | ~                                          |
- switching for                    V ~                                          |
- the API                  +---------------+                                    |
-                          |               |           +----------+ ------> +------------+
- +------------+ <-------- |               | --------> | Manifest | <~~~~~~ | transports |
- | EMEManager | ~~~~~~~~> |     Init      | <~~~~~~~~ | fetcher  |         +------------+
- +------------+           |               |           +----------+         Abstract   ^ ~
- Negotiate content        |               |           Download the         the        | ~
- decryption               +---------------+           manifest             streaming  | ~
-                                 | ^  Initialize                           protocol   | ~
-                                 | ~  playback and                                    | ~
-                                 | ~  create/connect                                  | ~
-                                 | ~  modules                                         | ~
-Stream                           | ~                                                  | ~
-+--------------------------------|-~-----------------------------+                    | ~
-|                                V ~                             |                    | ~
-|  Create the right         +-------------------------------+    |                    | ~
-|  PeriodStreams depending  |       StreamOrchestrator      |    |                    | ~
-|  on the current position, +-------------------------------+    |                    | ~
-|  and settings              | ^          | ^            | ^     |                    | ~
-|                            | ~          | ~            | ~     |                    | ~
-|                            | ~          | ~            | ~     |                    | ~
-|                            | ~          | ~            | ~     |                    | ~
-|                  (audio)   v ~  (video) V ~     (text) v ~     |                    | ~
-| Create the right +----------+   +----------+    +----------+   |  +--------------+  | ~
-| AdaptationStream |          |   |          |    |          |----> |SegmentBuffers|  | ~
-| depending on the |  Period  |-+ |  Period  |-+  |  Period  |-+ |  |   Store (1)  |  | ~
-| wanted track     |  Stream  | | |  Stream  | |  |  Stream  | | |  +--------------+  | ~
-| (One per Period  |          | | |          | |  |          | | |  Create one        | ~
-| and one per type +----------+ | +----------+ |  +----------+ | |  media buffer per  | ~
-| of media)         |           |  |           |   |           | |  type of media     | ~
-|                   +-----------+  +-----------+   +-----------+ |                    | ~
-|                          | ^            | ^            | ^     |                    | ~
-|                          | ~            | ~            | ~     |                    | ~
-|                          | ~            | ~            | ~     |                    | ~
-|                          | ~            | ~            | ~     |                    | ~
-|                  (audio) v ~    (video) V ~     (text) v ~     |                    | ~
-|                  +----------+   +----------+    +----------+ ---> +--------------+  | ~
-| Create the right |          |   |          |    |          | <~~~ |ABRManager (1)|  | ~
-| Representation-  |Adaptation|-+ |Adaptation|-+  |Adaptation|-+ |  +--------------+  | ~
-| Stream depending |  Stream  | | |  Stream  | |  |  Stream  | | |  Find the best     | ~
-| on the current   |          | | |          | |  |          | | |  bitrate           | ~
-| network,         +----------+ | +----------+ |  +----------+ | |                    | ~
-| settings...       |           |  |           |   |           | |                    | ~
-|                   +-----------+  +-----------+   +-----------+ |                    | ~
-|                          | ^            | ^            | ^     |                    | ~
-|                          | ~            | ~            | ~     |                    | ~
-|                          | ~            | ~            | ~     |                    | ~
-|                          | ~            | ~            | ~     |                    | ~
-|                  (audio) v ~    (video) V ~     (text) v ~     |                    | ~
-|                  +----------+   +----------+    +----------+ ----> +------------+   | ~
-| (Representation- |          |   |          |    |          | <~~~~ |  Segment   | --+ ~
-| Stream).         |Represe...|-+ |Represe...|-+  |Represe...|-+ |   | fetcher (1)| <~~~+
-| Download and push|  Stream  | | |  Stream  | |  |  Stream  | | |   +------------+
-| segments based on|          | | |          | |  |          | | |   Download media
-| the current      +----------+ | +----------+ |  +----------+ | |   segments
-| position and      |           |  |           |   |           | |
-| buffer state      +-----------+  +-----------+   +-----------+ |
-|                                                                |
-+----------------------------------------------------------------+
-
-(1) The SegmentBuffersStore, Segment fetcher and ABRManager are actually created by the
-Init and then used by the Stream.
-
-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/init/index.html b/doc/generated/pages/architecture/init/index.html deleted file mode 100644 index a81f09f244..0000000000 --- a/doc/generated/pages/architecture/init/index.html +++ /dev/null @@ -1,128 +0,0 @@ -The Init - RxPlayer Documentation

-

The Init

-

-

Overview

-

The Init is the part of the code starting the logic behind playing a content.

-

Its code is written in the src/core/init directory.

-

Every time you’re calling the API to load a new video, the init is called by it -(with multiple options).

-

The Init then starts loading the content and communicate back its progress to -the API through events.

-
                 +-----------+
- 1. LOAD VIDEO   |           |      2. CALLS
----------------> |    API    | -------------------+
-                 |           |                    |
-                 +-----------+                    |
-                       ^                          v
-                       |                    +--------------+
-                       |   3. EMIT EVENTS   |              |
-                       +------------------- |     Init     |
-                                            |              |
-                                            +--------------+
-
-

During the various events happening on content playback, the Init will create / -destroy / update various player blocks. Example of such blocks are:

-
    -
  • -

    Adaptive streaming management

    -
  • -
  • -

    DRM management

    -
  • -
  • -

    Manifest loading, parsing and refreshing

    -
  • -
  • -

    Buffer management

    -
  • -
  • -

    -
  • -
-

-

Usage

-

Concretely, the Init is a function which returns an Observable. -This Observable:

-
    -
  • -

    will automatically load the described content on subscription

    -
  • -
  • -

    will automatically stop and clean-up infos related to the content on -unsubscription

    -
  • -
  • -

    communicate on various streaming events through emitted notifications

    -
  • -
  • -

    throw in the case of a fatal error (i.e. an error interrupting playback)

    -
  • -
-

-

Communication between the API and the Init

-

Objects emitted by the Observable is the only way the Init should be able to -communicate with the API.

-

The API is then able to communicate back to the Init, either:

-
    -
  • -

    by Observable provided by the API as arguments when the Init function was -called

    -
  • -
  • -

    by emitting through Subject provided by the Init, as a payload of one of -its event

    -
  • -
-

Thus, there is three ways the API and Init can communicate:

-
    -
  • -

    API -> Init: When the Init function is called (so a single time)

    -
  • -
  • -

    Init -> API: Through events emitted by the returned Observable

    -
  • -
  • -

    API -> Init: Through Observables/Subjects the Init function is in possession -of.

    -
  • -
-

-

Emitted Events

-

Events allows the Init to reports milestones of the content playback, such as -when the content is ready to play.

-

It’s also a way for the Init to communicate information about the content and -give some controls to the user.

-

For example, as available audio languages are only known after the manifest has -been downloaded and parsed, and as it is most of all a user preference, the -Init can emit to the API, RxJS Subjects allowing the API to “choose” at any -time the wanted language.

-

-

Playback rate management

-

The playback rate (or speed) is updated by the Init.

-

There can be three occasions for these updates:

-
    -
  • -

    the API set a new Speed (speed$ Observable).

    -
  • -
  • -

    the content needs to build its buffer.

    -

    In which case, the playback speed will be set to 0 (paused) even if the -API set another speed.

    -
  • -
  • -

    the content has built enough buffer to un-pause. -The regular speed set by the user will be set again in that case.

    -
  • -
-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/segment_buffers/index.html b/doc/generated/pages/architecture/segment_buffers/index.html deleted file mode 100644 index e89ead592e..0000000000 --- a/doc/generated/pages/architecture/segment_buffers/index.html +++ /dev/null @@ -1,153 +0,0 @@ -The SegmentBuffers - RxPlayer Documentation

-

The SegmentBuffers

-

-

Overview

-

The core/segment_buffers directory contains the part of the code directly -related to the insertion and removal of media segments to a buffer for later -decoding.

-

This is either done through native SourceBuffers, which are JavaScript objects -implemented by the browser or a custom buffer implementation entirely defined -in the code of the RxPlayer.

-

The interface through which the RxPlayer’s code push segment is called the -SegmentBuffer, it comes on top of the buffer implementation (regardless if it -comes from native SourceBuffer objects or if it is a custom one).

-

A SegmentBuffer is defined for a type of media (e.g. “video”, “audio”, -“text”…) they are defined in the src/core/segment_buffers/implementations -directory.

-

Here’s a simplified architecture schema of the code in that directory:

-
   +--------------------------------------------------------------------------+
-   |                        Rest of the RxPlayer's code                       |
-   +--------------------------------------------------------------------------+
-                                |       ^
- Ask to get / create / remove   |       | Returns created SegmentBuffer or
- SegmentBuffer for a given type |       | wanted information
- or get information about the   |       |
- available types                |       |
-                                |       |
-                                V       |
-   +--------------------------------------------------------------------------+
-   |                         SegmentBuffersStore                              |
-   +--------------------------------------------------------------------------+
-          |                  |                  |                  |
-          | creates          | creates          | creates          | creates
-          | (if needed)      | (if needed)      | (if needed)      | (if needed)
-          |                  |                  |                  |
-          V                  V                  V                  V
-  +-------------+    +-------------+     +-------------+     +-------------+
-  |  AudioVideo |    |  AudioVideo |     |             |     |             |
-  |SegmentBuffer|    |SegmentBuffer|     |    Text     |     |    Image    |
-  |   (video)   |    |   (audio)   |     |SegmentBuffer|     |SegmentBuffer|
-  |             |    |             |     |             |     |             |
-  +-------------+    +-------------+     +-------------+     +-------------+
-     Uses both          Uses both             Uses                Uses
-      |      |           |      |               |                   |
-      |      |           |      |               |                   |
-      V      V           V      V               V                   V
-  +-----+ +-----+    +-----+ +-----+         +-----+             +-----+
-  | SI* | | SB* |    | SI* | | SB* |         | SI* |             | SI* |
-  +-----+ +-----+    +-----+ +-----+         +-----+             +-----+
-
-  SI*: SegmentInventory. Store the metadata on every segments currently
-       available in the associated media buffer.
-
-  SB*: SourceBuffer (browser implementation of a media buffer).
-
-

-

SegmentBuffersStore

-

The SegmentBuffersStore is the main export from there. -It facilitates the creation and destruction of these SegmentBuffers.

-

Its roles are to:

-
    -
  • -

    announce which types of SegmentBuffer can be currently created on the -HTMLMediaElement (example of a type of buffer would be “audio”, “video” or -“text”).

    -

    For example, no “video” SegmentBuffer should be created on an <audio> -element (though it wouldn’t cause any problem, it would be useless -as video cannot be rendered here). To give another example, you should not -create a “text” SegmentBuffer if no text track parser has been added to -the RxPlayer.

    -
  • -
  • -

    Create only one SegmentBuffer instance per type of buffer.

    -

    Multiple SegmentBuffer for a single type could lead to browser issues -and to conflicts in the RxPlayer code.

    -
  • -
  • -

    Provide a synchronization mechanism to announce when all SourceBuffers are -ready to receive segments.

    -

    I’ll explain:

    -

    SourceBuffers are browser implementations for media data buffers. -They typically are used by the “video” and “audio” SegmentBuffer.

    -

    Among several other constraints, all SourceBuffers needed to play a -given content should be created before we can start pushing segments to any -of them. This is a browser limitation.

    -

    This is where this synchronization mechanism can become useful. The -SegmentBuffersStore will signal when all of the SourceBuffers -needed for the given contents are created, so that the rest of the RxPlayer -knows when it can begin to push segments to those.

    -

    Note that this means that SourceBuffers for an un-needed type (e.g. an -audio content won’t need a video SourceBuffer) have to be explicitely -“disabled” here, as the SegmentBuffersStore cannot know whether it should -wait until those SourceBuffers are created of if you just don’t need it.

    -
  • -
-

-

SegmentBuffers implementations

-

A SegmentBuffer is an Object maintaining a media buffer for a given type (e.g. -“audio”, “video”, “text” etc.) used for later decoding.

-

There exists several SegmentBuffer implementations in the RxPlayer’s code -depending on the type concerned. -An implementation takes the form of a class with a well-defined API shared with -every other implementations. It allows to push segments, remove data and -retrieve information about the data that is contained within it.

-

At its core, it can either rely on a browser-defined SourceBuffer Object or -can be entirely defined in the code of the RxPlayer.

-

A SegmentBuffer also keeps an inventory containing the metadata of all -segments currently contained in it, with the help of a SegmentInventory -Object (see corresponding chapter).

-

It is the main interface the rest of the RxPlayer code has with media buffers.

-

-

BufferGarbageCollector

-

The BufferGarbageCollector is a function used by the RxPlayer to -periodically perform “garbage collection” manually on a given -SegmentBuffer.

-

It is based on the following building bricks:

-
    -
  • -

    A clock, which is an observable emitting the current time (in seconds) when -the garbage collection task should be performed

    -
  • -
  • -

    The SegmentBuffer on which the garbage collection task should run

    -
  • -
  • -

    The maximum time margin authorized for the buffer behind the current -position

    -
  • -
  • -

    The maximum time margin authorized for the buffer ahead of the current -position

    -
  • -
-

Basically, each times the given clock ticks, the BufferGarbageCollector will -ensure that the volume of data before and ahead of the current position does not -grow into a larger value than what is configured.

-

For now, its code is completely decoupled for the rest of the code in that -directory. This is why it is not included in the schema included on the top of -this page.

-

-

The SegmentInventory

-

The SegmentInventory keeps track of which segments are currently bufferized -to avoid unnecessary re-downloads.

-

You can have more information on it in the SegmentInventory -documentation.

-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/segment_buffers/segment_inventory.html b/doc/generated/pages/architecture/segment_buffers/segment_inventory.html deleted file mode 100644 index d7700433f5..0000000000 --- a/doc/generated/pages/architecture/segment_buffers/segment_inventory.html +++ /dev/null @@ -1,74 +0,0 @@ -SegmentInventory - RxPlayer Documentation

-

SegmentInventory

-

-

Overview

-

The SegmentInventory is a class which registers some information about every -segments currently present in a SegmentBuffer.

-

One of them is created for every new SegmentBuffer.

-

This helps the RxPlayer to avoid re-downloading segments unnecessarily and know -when old one have been garbage collected. -For example, we could decide not to re-download a segment in any of the -following cases:

-
    -
  • -

    The same segment is already completely present in the SegmentBuffer

    -
  • -
  • -

    The same segment is partially present in the SegmentBuffer (read: a part -has been removed or garbage collected), but enough is still there for what -we want to play

    -
  • -
  • -

    Another segment is in the SegmentBuffer at the wanted time, but it is the -same content in a better or samey quality

    -
  • -
-

On the contrary, we need to download the segment in the following cases:

-
    -
  • -

    No segment has been pushed at the given time

    -
  • -
  • -

    A segment has been pushed, but at a lower quality than what we currently -want

    -
  • -
  • -

    A segment has been pushed at a sufficient quality, but we miss to much of it -for our needs (too much has been garbage collected, removed or the segment -is just too short).

    -
  • -
  • -

    A segment has been pushed but is not exactly the content we want -(example: it is in another language)

    -
  • -
-

Thanks to the SegmentInventory, we can infer on which situation we are at any time.

-

-

Implementation

-

The SegmentInventory is merely a “Store”, meaning it will just store and -process the data you give to it, without searching for the information itself.

-

It contains in its state an array, the inventory, which stores every segments -which should be present in the SegmentBuffer in a chronological order.

-

To construct this inventory, three methods can be used:

-
    -
  • -

    one to add information about a new chunk (part of a segment or the whole -segment), which should have been pushed to the SegmentBuffer.

    -
  • -
  • -

    one to indicate that every chunks from a given segment have been pushed.

    -
  • -
  • -

    one to synchronize the currently pushed segments with what the -SegmentBuffer says it has buffered (which can be different for example -after an automatic garbage collection).

    -
  • -
-

After calling the synchronization one, you should be able to tell which parts of -which segments are currently living in your SegmentBuffer.

-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/stream/index.html b/doc/generated/pages/architecture/stream/index.html deleted file mode 100644 index 8a32cc5b6b..0000000000 --- a/doc/generated/pages/architecture/stream/index.html +++ /dev/null @@ -1,53 +0,0 @@ -The Stream - RxPlayer Documentation

-

The Stream

-

-

Overview

-

The Stream is the part of the RxPlayer choosing the right segments to -download, to then push them to the corresponding media buffers (called -SegmentBuffers) so they can later be decoded.

-

To do so, they receive inputs on both what the chosen track should be and on the -estimated optimal quality for those tracks. By then monitoring what has already -been buffered and the current playback conditions, they can make an educated -guess on what segments should be loaded and pushed at any given time.

-

-

The StreamOrchestrator

-

The StreamOrchestrator is the main entry point to interact with the -Stream.

-

It completely takes care of segment downloading and pushing for a whole content.

-

To do so, it creates the right PeriodStreams depending on the current -playback conditions. -For more information on it, you can look at the StreamOrchestrator -documentation.

-

-

The PeriodStream

-

The PeriodStream creates and destroys AdaptationStreams for a single -Manifest’s Period and a single type of buffer (e.g. “audio”, “video”, “text” -etc.).

-

It does so after asking through an event which Adaptation has to be chosen for -that Period and type.

-

It also takes care of creating the right “SegmentBuffer” for its associated -type, if none was already created for it.

-

-

The AdaptationStream

-

The AdaptationStream creates and destroys RepresentationStreams for a -single manifest’s Adaptation (such as a particular audio language, a video track -etc.) based on the current conditions (network bandwidth, browser -conditions…).

-

The RepresentationStream will then have the task to do the -segment downloading and pushing itself.

-

-

The RepresentationStream

-

The RepresentationStream is the part that actually monitors the buffer to -deduce which segments should be downloaded, ask to download them and then give -the order to push them to the SegmentBuffer.

-

You can have more information on it in the RepresentationStream -documentation.

-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/stream/representation_stream.html b/doc/generated/pages/architecture/stream/representation_stream.html deleted file mode 100644 index 1c0930bff2..0000000000 --- a/doc/generated/pages/architecture/stream/representation_stream.html +++ /dev/null @@ -1,105 +0,0 @@ -RepresentationStream - RxPlayer Documentation

-

RepresentationStream

-

-

Overview

-

The RepresentationStream download and push segments linked to a given -Representation.

-

It constructs a list of segments to download, which depend on the current -playback conditions. -It then download and push them to a linked SegmentBuffer (the media buffer -containing the segments for later decoding).

-

Multiple RepresentationStream observables can be ran on the same -SegmentBuffer without problems, as long as they are linked to different -Periods of the Manifest. -This allows for example smooth transitions between multiple periods.

-

-

Return value

-

The RepresentationStream returns an Observable which emits multiple -notifications depending on what is happening at its core, like:

-
    -
  • -

    when segments are scheduled for download

    -
  • -
  • -

    when segments are pushed to the associated SegmentBuffer

    -
  • -
  • -

    when the Manifest needs to be refreshed to obtain information on possible

    -
  • -
  • -

    whether the RepresentationStream finished to load segments until the end -of the current Period. This can for example allow the creation of a -RepresentationStream for the next Period for pre-loading purposes.

    -
  • -
  • -

    whether there are discontinuities: holes in the stream that won’t be filled -by segments and can thus be skipped

    -
  • -
-

-

Queue Algorithm

-

The RepresentationStream depends on a central algorithm to make sure that the -right segments are scheduled for download at any time.

-

This algorithm constructs a queue of segments to download at any time, and -regularly checks that the segment currently downloaded still corresponds to the -currently most needed Segment.

-

This list of segments is based on a simple calculation between the current -position and the buffer size we want to achieve. -This list goes then through multiple filters to ensure we’re not queueing them -unnecessarly. Such cases would be, for example, if the segment is already -present in the SegmentBuffer at a better quality.

-

For a clock based on various video events, the strategy is the following:

-
    -
  1. -

    let segmentQueue be an empty array.

    -
  2. -
  3. -

    On each clock tick, calculate segmentsNeeded, an Array of needed -segments (read: not yet downloaded) from the current time to the buffer -size goal.

    -

    Note that the steps 2 to 5 can run multiple times while waiting for -a request - happening in step 5 and 8. If that happens, -segmentQueue should equal the last value it has been given.

    -
  4. -
  5. -

    check if there’s a segment currently downloaded (launched in step 8)

    -

    3-1. If there is none, let segmentQueue be equal to segmentsNeeded

    -

    3-2. If there is one but for a segment different than the first element -in segmentsNeeded or if segmentsNeeded is empty, abort -this request and let segmentQueue be equal to segmentsNeeded.

    -

    3-3. If there is one and is for the same segment than the first element -in segmentsNeeded, let segmentQueue be equal to -segmentsNeeded without its first element.

    -
  6. -
  7. -

    if segmentQueue is empty, go back to 2.

    -
  8. -
  9. -

    check if there’s a pending segment request (happening in step 8):

    -

    5-1. if there’s no segment request, continue

    -

    5-1. if there’s a pending segment request, go back to 2

    -
  10. -
  11. -

    Let currentSegment be the first segment of segmentQueue

    -
  12. -
  13. -

    Remove the first segment from segmentQueue (a.k.a. currentSegment)

    -
  14. -
  15. -

    perform a request for currentSegment and wait for it to finish. -During this time, step 2 to 5 can run in parallel, and as such -SegmentQueue can be mutated during this process.

    -
  16. -
  17. -

    Once the request is finished, run those tasks in parallel:

    -

    9-1. Append the segment to the corresponding SegmentBuffer

    -

    9-1. go back to step 4.

    -
  18. -
-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/stream/stream_orchestrator.html b/doc/generated/pages/architecture/stream/stream_orchestrator.html deleted file mode 100644 index 939a0b1879..0000000000 --- a/doc/generated/pages/architecture/stream/stream_orchestrator.html +++ /dev/null @@ -1,301 +0,0 @@ -StreamOchestrator - RxPlayer Documentation

-

StreamOchestrator

-

-

Overview

-

To be able to play a content, the player has to be able to download chunks of -media data - called segments - and has to push them to media buffers, called -SegmentBuffers in the RxPlayer code.

-

In the RxPlayer, the StreamOrchestrator is the entry point for performing all -those tasks.

-

Basically, the StreamOrchestrator:

-
    -
  • -

    dynamically creates various SegmentBuffers depending on the needs of the -given content

    -
  • -
  • -

    orchestrates segment downloading and “pushing” to allow the content to -play in the best conditions possible.

    -
  • -
-

-

Multiple types handling

-

More often than not, content are divised into multiple “types”: “audio”, “video” -and “text” segments, for example. They are often completely distinct in a -Manifest and as such, have to be downloaded and decoded separately.

-

Each type has its own media buffer. For “audio”/“video” contents, we use -regular browser-defined MSE SourceBuffers. -For any other types, such as “text” and “image”, those buffers are entirely -defined in the code of the RxPlayer.

-

We then create a different Stream for each type. Each will progressively -download and push content of their respective type to their respective -media buffer:

-
- AUDIO STREAM -
-|======================    |
-
-- VIDEO STREAM -
-|==================        |
-
-- TEXT STREAM -
-|========================  |
-
-- IMAGE STREAM -
-|====================      |
-
-

(the | sign delimits the temporal start and end of the buffer linked to a -given Stream, the = sign represent a pushed segment in the corresponding -buffer)

-

-

A special case: SourceBuffers

-

Media buffers created for the audio and/or video types rely on a native -(implemented by the browser) SourceBuffer Object implementation.

-

Media buffers relying on native SourceBuffers have several differences with the -other “custom” (entirely defined in the RxPlayer) types of media buffers:

-
    -
  • -

    They are managed by the browser where custom ones are implemented in JS. -As such, they must obey to various browser rules, among which:

    -
      -
    1. -

      They cannot be lazily created as the content plays. We have to -initialize all of them beforehand.

      -
    2. -
    3. -

      They have to be linked to a specific codec.

      -
    4. -
    5. -

      The SourceBuffer has to be linked to the MediaSource, and they have -to the MediaSource after the media HTMLElement has been linked to the -MediaSource

      -
    6. -
    -
  • -
  • -

    They are in a way more “important” than custom ones. If a problem happens -with a SourceBuffer, we interrupt playback. For a custom media buffer, we -can just deactivate it for the rest of the content.

    -

    For example, a problem with subtitles would just disable those with a -warning. For a video problem however, we fail immediately.

    -
  • -
  • -

    They affect buffering when custom media buffers do not (no text segment for -a part of the content means we will just not have subtitles, no audio -segment means we will completely stop, to await them)

    -
  • -
  • -

    They affect various API linked to the media element in the DOM. Such as -HTMLMediaElement.prototype.buffered. -Custom media buffers do not.

    -
  • -
-

Due to these differences, media buffers relying on SourceBuffers are often -managed in a less permissive way than custom ones:

-
    -
  • -

    They will be created at the very start of the content

    -
  • -
  • -

    An error coming from one of them will lead us to completely stop the content -on a fatal error

    -
  • -
-

-

PeriodStreams

-

The DASH streaming technology has a concept called Period. Simply put, it -allows to set various types of content successively in the same manifest.

-

For example, let’s take a manifest describing a live content with -chronologically:

-
    -
  1. an english TV Show
  2. -
  3. an old italian film with subtitles
  4. -
  5. an American film with closed captions.
  6. -
-

Example:

-
08h05              09h00                       10h30                now
-  |==================|===========================|===================|
-        TV Show               Italian Film            American film
-
-

Those contents are drastically different (they have different languages, the -american film might have more available bitrates than the old italian one).

-

Moreover, even a library user might want to be able to know when the italian -film is finished, to report about it immediately in a graphical interface.

-

As such, they have to be considered separately - in a different Period:

-
        Period 1                Period 2                Period 3
-08h05              09h00                       10h30                now
-  |==================|===========================|===================|
-        TV Show               Italian Film            American film
-
-

In the RxPlayer, we create one PeriodStream per Period and per type.

-

PeriodStreams are automatically created/destroyed during playback. The job of -a single PeriodStream is to process and download optimally the content linked -to a single Period and to a single type:

-
- VIDEO BUFFER -
-
-     PERIOD STREAM
-08h05              09h00
-  |=========         |
-        TV Show
-
-
-- AUDIO BUFFER -
-
-     PERIOD STREAM
-08h05              09h00
-  |=============     |
-        TV Show
-
-
-- TEXT BUFFER -
-
-     PERIOD STREAM
-08h05              09h00
-  |======            |
-        TV Show
-
-

To allow smooth transitions between them, we also might want to preload content -defined by a subsequent Period once we lean towards the end of the content -described by the previous one. -Thus, multiple PeriodStreams might be active at the same time:

-
+----------------------------   AUDIO   ----------------------------------+
-|                                                                         |
-|      PERIOD STREAM 1        PERIOD STREAM 2         PERIOD STREAM 3     |
-| 08h05              09h00                       10h30                now |
-|   |=============     |=================          |================   |  |
-|         TV Show               Italian Film            American film     |
-+-------------------------------------------------------------------------+
-
-+------------------------------   VIDEO   --------------------------------+
-|                                                                         |
-|      PERIOD STREAM 1        PERIOD STREAM 2         PERIOD STREAM 3     |
-| 08h05              09h00                       10h30                now |
-|   |=====             |===                        |===                |  |
-|         TV Show               Italian Film            American film     |
-+-------------------------------------------------------------------------+
-
-+------------------------------   TEXT   ---------------------------------+
-|                                                                         |
-|      PERIOD STREAM 1        PERIOD STREAM 2         PERIOD STREAM 3     |
-| 08h05              09h00                       10h30                now |
-|     (NO SUBTITLES)   |=========================  |=================  |  |
-|         TV Show               Italian Film            American film     |
-+-------------------------------------------------------------------------+
-
-

-

Multi-Period management

-

The creation/destruction of PeriodStreams is actually done in a very precize -and optimal way, which gives a higher priority to immediate content.

-

To better grasp how it works, let’s imagine a regular use-case, with two periods -for a single type of buffer:

-
-

Let’s say that the PeriodStream for the first Period (named P1) is currently -actively downloading segments (the “^” sign is the current position):

-
   P1
-|====  |
-   ^
-
-

Once P1 is full (it has no segment left to download):

-
   P1
-|======|
-   ^
-
-

We will be able to create a new PeriodStream, P2, for the second Period:

-
   P1     P2
-|======|      |
-   ^
-
-

Which will then also download segments:

-
   P1     P2
-|======|==    |
-   ^
-
-

If P1 needs segments again however (e.g. when the bitrate or the language is -changed):

-
   P1     P2
-|===   |==    |
-   ^
-
-

Then we will destroy P2, to keep it from downloading segments:

-
   P1
-|===   |
-   ^
-
-
-

Once P1, goes full again, we re-create P2:

-
   P1     P2
-|======|==    |
-   ^
-
-

Note that we still have the segment pushed to P2 available in the corresponding -media buffer

-

When the current position go ahead of a PeriodStream (here ahead of P1):

-
   P1     P2
-|======|===   |
-        ^
-
-

This PeriodStream is destroyed to free up ressources:

-
          P2
-       |===   |
-        ^
-
-
-

When the current position goes behind the first currently defined PeriodStream:

-
          P2
-       |===   |
-    ^
-
-

Then we destroy all previous PeriodStreams and [re-]create the one needed:

-
   P1
-|======|
-    ^
-
-

In this example, P1 is full (as we already downloaded its segments) so we also -can re-create P2, which will also keep its already-pushed segments:

-
   P1     P2
-|======|===   |
-    ^
-
-
-

For multiple types of buffers (example: audio and video) the same logic is -repeated (and separated) as many times. An audio PeriodStream will not -influence a video one:

-
---------------------------   AUDIO   --------------------------------
-     Period 1         Period 2
-|================|=============   |
-     ^
-
----------------------------   VIDEO   --------------------------------
-     Period 1
-|=======         |
-     ^
-
-----------------------------   TEXT   --------------------------------
-     Period 1         Period 2          Period 3
-|================| (NO SUBTITLES) |================   |
-     ^
-
-

At the end, we should only have PeriodStream[s] for consecutive Period[s]:

-
    -
  • The first chronological one is the one currently seen by the user.
  • -
  • The last chronological one is the only one downloading content.
  • -
  • In between, we only have full consecutive PeriodStreams.
  • -
-

-

Communication with the API

-

Any “Stream” communicates to the API about creations and destructions of -PeriodStreams respectively through "periodStreamReady" and -"periodStreamCleared" events.

-

When the currently seen Period changes, an activePeriodChanged event is -sent.

-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/transports/index.html b/doc/generated/pages/architecture/transports/index.html deleted file mode 100644 index 867f9e4fda..0000000000 --- a/doc/generated/pages/architecture/transports/index.html +++ /dev/null @@ -1,60 +0,0 @@ -Transport code - RxPlayer Documentation

-

Transport code

-

-

Overview

-

The transports code in the transports/ directory is the code translating -the streaming protocols available into a unified API.

-

Its roles are to:

-
    -
  • -

    download the Manifest and parse it into an object that can be understood -by the core of the rx-player

    -
  • -
  • -

    download segments, convert them into a decodable format if needed, and -report important information about them (like the duration of a segment)

    -
  • -
  • -

    give networking metrics to allow the core to better adapt to poor networking -conditions

    -
  • -
-

As such, most network request needed by the player are directly performed by -the transports code.

-

Note: the only HTTP request which might be done elsewhere would be the request -for a directfile content. That request is not done explicely with a JavaScript -API but implicitely by the browser (inclusion of an src attribute).

-

-

Implementation

-

This code is completely divided by streaming protocols used. -E.g. DASH streaming is entirely defined in its own directory and the same -thing is true for Smooth Streaming or MetaPlaylist contents.

-

When playing a DASH content only the DASH-related code will be called. When -switching to a Smooth Streaming content, only the Smooth Streaming code -will be used instead.

-

To allow this logic, any streaming protocol exposed in transports exposes -the same interface and abstracts the difference to the rest of the code. -For the core of the rx-player, we do not have any difference between playing -any of the streaming protocols available.

-

This also means that the code relative to a specific streaming technology is -within the transports directory. -This allows to greatly simplify code maintenance and evolutivity. For example, -managing a new streaming protocol would mainly just need us to add some code -there (you might also need to add parsers in the parsers directory). Same -thing for adding a new feature to e.g. DASH or Smooth.

-

Each streaming protocol implementation present in the transports code exports -a single transport function.

-

The object returned by that function is often referenced as the transport pipelines. It is documented here.

-

-

MetaPlaylist implementation

-

A MetaPlaylist is a specific case, as it wraps other streaming protocols.

-

More documentation about it can be found in the corresponding API -documentation.

-

Architecture information on it can also be found here.

-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/transports/metaplaylist.html b/doc/generated/pages/architecture/transports/metaplaylist.html deleted file mode 100644 index 48ab201368..0000000000 --- a/doc/generated/pages/architecture/transports/metaplaylist.html +++ /dev/null @@ -1,87 +0,0 @@ -MetaPlaylist - RxPlayer Documentation

-

MetaPlaylist

-

The MetaPlaylist is a specific kind of transport: a playlist of different -Manifest. -Its principle and usage is defined here.

-

-

How the original Manifest files are considered

-

To play a MetaPlaylist content, each manifest it depends on has to be -downloaded and parsed through their original logic (a MPD through DASH’s -logic and a Smooth Manifest through Smooth’s logic).

-

We then merge each of these Manifest, to construct an internal -Manifest object with the same structure and properties -than we would have with a DASH or Smooth manifest.

-

The trick is to consider each of those original Manifest as different Periods -(like DASH Periods). The trick works here because the RxPlayer’s definition of a -transport (and of the underlying properties) is much more flexible than in DASH. -If an original MPD already has multiple Periods, each of them are also -converted as different RxPlayer’s Period so that no feature from the original -content is lost.

-

Each of those Period is then concatenated one after the other thanks to the time -information announced in the MetaPlaylist file.

-

-

How about the segments

-

The exploitation of segment metadata is even trickier.

-

In DASH or Smooth, the URL of each segment could be constructed from the -starting time of each of those segments.

-

The problem here is that a MetaPlaylist player has to mutate those to place -them at the position indicated in the MetaPlaylist’s JSON instead.

-

To simplify everything, we choose to rely on a simple but effective wrapper on -top of the original transport protocol.

-

When the core logic of the player wants to load a segment from the network, that -wrapper translate back the data as if we’re just playing the original content at -its original position. -How it works: the wrapper removes a specific time offset from the wanted -segment’s metadata, before contacting the transport’s logic.

-

When giving back the segment to the core logic of the player, the wrapper first -update those loaded segment with the wanted position data. -How it works: the wrapper adds back the time offset it previously substracted -from the wanted segment’s metadata before giving it back to the core logic.

-

To illustrate, it kind of goes like this:

-
+----------------+ 1. Ask for segments infos from t to t+n  +--------------+
-|                | ---------------------------------------> |              |
-|                |                                          |              |
-|                | <--------------------------------------- |              |
-|                |  4. Gives segment infos asked (offseted) |              |
-|                |                                          |              |
-|      CORE      |                                          | METAPLAYLIST |
-|                |                                          |    WRAPPER   |
-|                | 5. Ask to download segment (offseted)    |              |
-|                | ---------------------------------------> |              |
-|                |                                          |              |
-|                | <--------------------------------------- |              |
-+----------------+              8. Gives segment (offseted) +--------------+
-                                                             | ^     |  ^
-                                                             | |     |  |
-                                                             | |     |  |
-   +------------+   2. get segment infos from t-offset to t+n-offset |  |
-   | +--------+ | <------------------------------------------+ |     |  |
-   | |        | |                                              |     |  |
-   | |  DASH  | |                                              |     |  |
-   | |        | |  3. Gives segment infos asked                |     |  |
-   | +--------+ | ---------------------------------------------+     |  |
-   | +-------+  |                                                    |  |
-   | |       |  |                                                    |  |
-   | |  HSS  |  |                                                    |  |
-   | |       |  |                                                    |  |
-   | +-------+  |                                                    |  |
-   | +-------+  |  6. Ask to download non-offseted (normal) segments |  |
-   | |       |  | <--------------------------------------------------+  |
-   | |  ...  |  |                                                       |
-   | |       |  |  7. Gives normal segment                              |
-   | +-------+  | ------------------------------------------------------+
-   +------------+
-
-

To make sure the segment is pushed at the right moment and doesn’t overlap other -contents, we make heavy use of some specific SourceBuffer properties:

-
    -
  • the timestampOffset property allows to set a specific offset
  • -
  • appendWindowStart allows to limit the starting time of the pushed segment
  • -
  • appendWindowEnd allows to limit the ending time of the pushed segment
  • -
-
\ No newline at end of file diff --git a/doc/generated/pages/architecture/transports/pipeline.html b/doc/generated/pages/architecture/transports/pipeline.html deleted file mode 100644 index b29d47a345..0000000000 --- a/doc/generated/pages/architecture/transports/pipeline.html +++ /dev/null @@ -1,232 +0,0 @@ -Transport pipeline - RxPlayer Documentation

-

Transport pipeline

-

-

Definition

-

Each streaming protocol defines a function that takes some options in arguments -and returns an object. This object is often referenced as the transport pipelines of the streaming protocol.

-

This object then contains the following functions:

-
    -
  • a Manifest “loader”
  • -
  • a Manifest “parser”
  • -
  • multiple segment “loaders” (one per type of buffer, like “audio”, “video”, -“text”…).
  • -
  • multiple segment “parsers”
  • -
-

As you can see, there’s two recurrent concepts here: the loader and the parser.

-

-

A loader

-

A loader in the transport pipeline is a function whose role is to “load” the -resource.

-

Depending on the streaming technology, this can mean doing a request or just -creating it from the information given.

-

Its concept can be illustrated as such:

-
  INPUT:                                 OUTPUT:
-  ------                                 -------
-  URL and other information  +--------+  loaded resource
-  about the wanted resource  |        |
-============================>| LOADER |==============================>
-                             |        |
-                             +--------+
-
-

As the wanted resource could be obtained asynchronously (like when an HTTP -request has to be performed), the loader returns an Observable and the resource -is then emitted through it.

-

This Observable will throw on any problem arising during that step, such as an -HTTP error.

-

In some specific conditions, the loader can also emit the wanted resource in -multiple sub-parts. This allows for example to play a media file while still -downloading it and is at the basis of low-latency streaming. -To allow such use cases, the segment loaders can also emit the wanted resource -by cutting it into chunks and emitting them through the Observable as they are -available. -This is better explained in the related chapter below.

-

-

A parser

-

A parser’s role is to extract the data and other important information from a -loaded resource. -It is connected in some ways to the response of the loader (which gives the -loaded resource) and will be the last step before that resource is actually -handled by the rest of the player.

-

Its concept can be illustrated as such:

-
  INPUT:                                OUTPUT:
-  ------                                -------
-  loaded resource +                     exploitable resource and
-  resource information +     +--------+ parsed information from it
-  request scheduler [1]      |        |
-============================>| PARSER |==============================>
-                             |        |
-                             +--------+
-
-

The parser returns an Observable which will emit the parsed resource when done.

-

This Observable will throw if the resource is corrupted or miss crucial -information.

-

[1] the parser could also need to perform requests (e.g. it needs to fetch the -current time from a server). -In such cases, the parser is given a special callback, which allows it to -receive the same error-handling perks than a loader, such as multiple retries, -just for those requests.

-

-

Manifest loader

-

The Manifest loader is the “loader” downloading the Manifest (or MPD) file.

-

It is a function which receives as argument the URL of the manifest and then -returns an Observable emitting a single time the corresponding Manifest when it -finished downloading it:

-
  INPUT:                              OUTPUT:
-  ------                              -------
-  Manifest/MPD URL      +----------+  Manifest in a generic format
-                        |          |  (e.g. string, Document...)
-=======================>| MANIFEST |=================================>
-                        |  LOADER  |
-                        |          |
-                        +----------+
-
-

-

Manifest parser

-

The Manifest parser is a function whose role is to parse the Manifest in its -original form to convert it to the RxPlayer’s internal representation of it.

-

It receives in argument the downloaded Manifest, some Manifest-related -information (e.g. its URL) and a specific function called scheduleRequest, -allowing it to ask for supplementary requests before completing (e.g. to fetch -the current time from an URL or to load sub-parts of the Manifests only known -at parse-time).

-

This function returns an Observable wich emits a single time the parsed -Manifest:

-
 INPUT:                                       OUTPUT:
- ------                                       -------
- Manifest in a generic format +  +----------+ RxPlayer's `Manifest`
- URL + request scheduler         |          | structure
- ===============================>| MANIFEST |===========================>
-                                 |  PARSER  |
-                                 |          |
-                                 +----------+
-
-

-

Segment loader

-

A Transport pipeline declares one Segment loader per type of buffer (e.g. audio, -text, video…)

-

A segment loader is the “loader” for any segment. Its role is to retrieve a given -segment’s data.

-

It receives information linked to the segment you want to download:

-
    -
  • The related Manifest data structure
  • -
  • The Period it is linked to
  • -
  • The Adaptation it is linked to
  • -
  • The Representation it is linked to
  • -
  • The Segment object it is linked to
  • -
-

It then return an Observable which send events as it loads the corresponding -segment.

-
  INPUT:                              OUTPUT:
-  ------                              -------
-  Segment information   +----------+  Segment in a generic format
-                        |          |  (e.g. ArrayBuffer, string...)
-=======================>| SEGMENT  |=================================>
-                        |  LOADER  |
-                        |          |
-                        +----------+
-
-

The events sent in output depend on the “mode” chosen by the loader to download -the segment. There are two possible modes:

-
    -
  • -

    the regular mode, where the loader wait for the segments to be completely -downloaded before sending it

    -
  • -
  • -

    the low-latency mode, where the loader emits segments by chunks at the same -time they are downloaded.

    -
  • -
-

The latter mode is usually active under the following conditions:

-
    -
  • low-latency streaming is enabled through the corresponding loadVideo -option
  • -
  • we’re loading a DASH content.
  • -
  • we’re not loading an initialization segment.
  • -
  • the segment is in a CMAF container
  • -
  • the Fetch JS API is available
  • -
-

In most other cases, it will be in the regular mode.

-

You can deduce which mode we are in simply by looking a the events the loader -sends.

-

In the regular mode, any of the following events can be sent through the -Observable:

-
    -
  • -

    "progress": We have new metrics on the current download (e.g. the amount -currently downloaded, the time since the beginning of the request…)

    -
  • -
  • -

    "data-created": The segment is available without needing to perform a -network request. This is usually the case when segments are generated like -Smooth Streaming’s initialization segments. -The segment’s data is also communicated via this event.

    -

    The "data-created" event, when sent, is the last event sent from the -loader. The loader will complete just after emitting it.

    -
  • -
  • -

    "data-loaded": The segment has been compeletely downloaded from the -network. The segment’s data is also communicated via this event.

    -

    Like "data-created", the "data-loaded" will be the last event sent by -the loader. -This means that you will either have a single "data-created" event or a -single "data-loaded" event with the data when the segment has been loaded -succesfully.

    -
  • -
-

In the low-latency mode, the following events can be sent instead:

-
    -
  • -

    "progress": We have new metrics on the current download (e.g. the amount -currently downloaded, the time since the beginning of the request…)

    -
  • -
  • -

    "data-chunk": A sub-segment (or chunk) of the data is currently available. -The corresponding sub-segment is communicated in the payload of this event.

    -

    This event can be communicated multiple times until a -"data-chunk-complete" event is received.

    -
  • -
  • -

    "data-chunk-complete": The segment request just finished. All -corresponding data has been sent through "data-chunk" events.

    -

    If sent, this is the last event sent by a segment loader. The loader will -complete just after emitting it.

    -
  • -
-

-

Segment parser

-

A segment parser is a function whose role is to extract some information from -the segment’s data:

-
    -
  • what its precize start time and duration is
  • -
  • whether the segment should be offseted when decoded and by what amount
  • -
  • the decodable data (which can be wrapped in a container e.g. subtitles in an -ISOBMFF container).
  • -
  • the attached protection information and data to be able to decrypt that -segment.
  • -
-

It receives the segment or sub-segment as argument and related information:

-
 INPUT:                                       OUTPUT:
- ------                                       -------
- Segment in a generic format +                Decodable data + time
- isChunked? [1] + Segment        +----------+ information + segment protection
- information                     |          | information
- ===============================>| SEGMENT  |===========================>
-                                 |  PARSER  |
-                                 |          |
-                                 +----------+
-
-

[1] The parser can make different guess on the time information of the -segment depending on if the loaded segment corresponds to the whole segment or -just a small chunk of it. The isChunked boolean allows it to be aware of that.

-
\ No newline at end of file diff --git a/doc/generated/pages/dash_rxplayer_adaptation_difference.html b/doc/generated/pages/dash_rxplayer_adaptation_difference.html deleted file mode 100644 index d8af5abd69..0000000000 --- a/doc/generated/pages/dash_rxplayer_adaptation_difference.html +++ /dev/null @@ -1,64 +0,0 @@ -Differences between DASH' AdaptationSets and the rx-player "Adaptation" - RxPlayer Documentation

-

Differences between DASH’ AdaptationSets and the rx-player “Adaptation”

-

The RxPlayer defines an Adaptation object (also sometimes called Track) -which follow as close as possible the concept of the AdaptationSet in -the DASH protocol.

-

However, to answer practically to some of the features allowed by DASH while -still respecting the DASH-IF “IOP”, we had to -take some (minor) freedom with our interpretation of it.

-

-

Merging of multiple AdaptationSets into a single Adaptation

-

The main difference is that all similar AdaptationSet which are marked as -“seamlessly switchable” between one another are merged into a single -Adaptation in the player.

-

-

Why do we do that

-

This “switchable” concept is for example used in cases were multiple encryption -keys are present for different Representation (e.g. due to limitations coming -from right holders).

-

The problem is that the DASH-IF tells us that all Representation in a given -AdaptationSet have to use the same license. -This means that in the aforementioned case, the concerned Representation -have to be divided into multiple AdaptationSet. In a player, different -AdaptationSet means different “tracks” and thus a player won’t try to -automatically switch between them.

-

This means that our adaptive algorithm won’t be able to set the right quality -and that the library user would have to manually manage that instead.

-

Fortunately, the DASH-IF IOP planned a work-around for that kind of situation: -To allow a player to seamlessly switch between multiple AdaptationSets, the -DASH-IF allows a specific node, called SupplementalProperty to be added as -children of the concerned AdaptationSets (with a specific value).

-

However, this brings another set of issues in the rx-player, where this -separation would lead to an excessively complicated API.

-

-

What do we do

-

We thus decided to “merge” the AdaptationSets into a single Adaptation if -all those conditions are filled:

-
    -
  • -

    they both support seamless-switching between one-another (i.e. they both -contain a SupplementalProperty node with the right values)

    -
  • -
  • -

    they represent the same type of content (“audio”, “video” or “text”)

    -
  • -
  • -

    they are of the same language, if one (letter-for-letter in the manifest)

    -
  • -
  • -

    they have the same accessibility information (e.g. both are closed -captions or audio description for the visually impaired).

    -
  • -
-

If any of these conditions is not filled, the concerned AdaptationSets stay -separated and the player will not try to switch between them.

-
\ No newline at end of file diff --git a/doc/generated/pages/index.html b/doc/generated/pages/index.html deleted file mode 100644 index 702610bad1..0000000000 --- a/doc/generated/pages/index.html +++ /dev/null @@ -1,56 +0,0 @@ -RxPlayer documentation - RxPlayer Documentation

-

RxPlayer documentation

-

-

Overview

-

You can find here various documentation pages about the RxPlayer.

-

If you wish to use the RxPlayer as a library, you can directly check the API -Documentation.

-

For those wanting to contribute, we also began documenting the code -architecture.

-

-

API Documentation

-

The general API Documentation can be found here:

- -

For a shortcut, here are some other quick links you might want to check:

- -

-

Tutorials

-

We’re under the process of writing tutorials to facilitate the usage of the -RxPlayer.

-

Those are all linked here.

-

To quickly start using the player, you can directly refer to the quick start -tutorial.

-

-

Architecture Documentation

-

An architecture documentation is in progress.

-

The main page can be found here:

- -

-

Other pages

-

You can also find other pages on various subjects related to the RxPlayer here:

- -
\ No newline at end of file diff --git a/doc/generated/pages/infos/dash/presentationTimeOffset.html b/doc/generated/pages/infos/dash/presentationTimeOffset.html deleted file mode 100644 index 95b0813aab..0000000000 --- a/doc/generated/pages/infos/dash/presentationTimeOffset.html +++ /dev/null @@ -1,240 +0,0 @@ -presentationTimeOffset - RxPlayer Documentation

-

presentationTimeOffset

-

The presentationTimeOffset is an attribute which can be encountered in an MPD -(the “manifest” of the DASH streaming technology).

-

-

Overview

-

Simply put, this attribute allows to correct an offset present in the media -segments once those are decoded.

-

One of the possible usecase would be creating an on demand MPD from a subsection -of an already-existing content, without modifying directly the concerned -segments nor their (possibly time-based) URLs.

-

Another main usecase is when handling multi-Periods MPDs. -Segments in newer Periods already need to consider an offset, corresponding to -the start of the given Period. -In those cases, the presentationTimeOffset might allows to “cancel” out this -offset. This can be useful if the corresponding segments already define the -right time.

-

-

Simple example

-

For example, let’s imagine some on-demand content with a duration of 2 hours. -To stay simple, this content begins at 00:00:00.000 and ends at -01:08:00.000 (1 hour and 8 minutes).

-
CONTENT:
-
-00:00:00.000                                                        01:08:00.000
-    |====================================================================|
-
-
-

Now let’s say that we want to create a new on-demand content, which is only a -sub-part from this content. -For example, we will take the subpart going from 00:05:24.000 to -00:12:54.000 (for a duration of 00:07:30.000).

-

-00:00:00.000                                                        02:00:00.000
-    |====|------|========================================================|
-            ^
-      Subpart going from 00:05:24 to 00:12:54.000
-
-
-

Because we might not want to use money uselessly, we want to create this new -content simply by creating a new MPD, and without touching the already created -segments, nor their URLs.

-

In that condition, we will still need the client to know that this content -actually have an offset of 00:05:24.000. If it does not know that, we will -just think that the content begins at a default 00:00:00.000 time.

-

Letting the client think that the content begins at the default 00:00:00.000 -time could lead to several issues:

-
    -
  • -

    it might not be able to request the right first segments (as the URLs could -be time-based)

    -
  • -
  • -

    even if it does, it might not be able to actually play the content, as we’re -pushing segments corresponding to a 00:05:24.000 while the browser is -still waiting for the 00:00:00.000 ones (in that case, we would just have -an infinite buffering state).

    -
  • -
  • -

    even if it does, the client timeline will announce a wrong time, offseted 5 -minutes and 24 seconds too late.

    -
  • -
-

This is where the presentationTimeOffset comes into play. In our simple -example, this value will just announce an offset of 00:05:24.000 (under the -form of an integer with a timescale to convert it into seconds), and the client -will know what to do.

-

What the client has to do here is:

-
    -
  • begin to play at 0 secods
  • -
  • ask the right segments, by adding this offset to the one it thinks it needs
  • -
  • remove the offset from the segment before decoding it
  • -
-

-

Time conversions

-

The presentationTimeOffset is linked to multiple other time attributes of an -MPD, especially the start of the Period concerned, and of course the time -of the segment.

-

We will enounce below a simple equation which put their relation into -perspective.

-

To understand this equation, we will need to define some variables:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VariableDefinition
PTOThe “presentationTimeOffset” attribute of the MPD
mediaTimeThe start time announced in the segment
TSTimescale used by PTO and segmentTime, to transform them into seconds
periodStartStart time of the given period, in seconds
presentationTimeThe time at which the segment will be shown, in seconds
-
    mediaTime        PTO
-  -------------  -  -----  +  periodStart  =  presentationTime
-       TS            TS
-
-

-

Easier conversion: the timestampOffset

-

As seen in the previous chapter, to convert the media time (time announced in -the segments) into the presentation time (time that will be shown to the user), -you will need to use both also include three other variables:

-
    -
  • -

    the start of the period

    -
  • -
  • -

    the presentationTimeOffset

    -
  • -
  • -

    the timescale used by the presentationTimeOffset and the media time

    -
  • -
-

As a convenient plus, those three variables rarely change for a given period.

-

To simplify the conversion, we can thus define a new variable using those three. -This is what the timestampOffset is all about.

-

Let’s go back to the equations in the previous chapters, to isolate those three -into the really simple equation: -mediaTime/TS + timestampOffset = presentationTime (you can refer to the -previous chapter to understand what those variables means)

-

-  mediaTime       PTO
- -----------  -  -----  +  periodStart  =  presentationTime
-     TS           TS
-
-  mediaTime           PTO
- -----------  + ( -  -----  +  periodStart ) =  presentationTime
-     TS               TS
-
-                          PTO                                       PTO
-  timestampOffset  =  -  -----  +  periodStart  =  periodStart  -  -----
-                          TS                                        TS
-
-
-

With timestampOffset defined, it becomes easy to go back and forth between -the mediaTime and the presentationTime:

-
                       mediaTime
-presentationTime  =   -----------  +  timestampOffset
-                          TS
-
-mediaTime  =  (  presentationTime  -  timestampOffset  )  *  TS
-
-
-

As an added bonus, SourceBuffers defined in the HTML5 MediaSource Extentions -also have a timestampOffset property -, which -means exactly the same thing as defined here!

-

-

In the RxPlayer

-

Now that we have all of those concepts out of the way, how are we going to use -it, in the RxPlayer?

-

The RxPlayer has A LOT of time-related values defined for a given segment:

-
    -
  • -

    the time defined in the segment itself (mediaTime)

    -
  • -
  • -

    the time displayed when playing it in the HTMLMediaElement -(presentationTime)

    -
  • -
  • -

    the time possibly set in the request (requestSegmentTime)

    -
  • -
  • -

    the time as announced in the corresponding attribute of the manifest -(manifestTime)

    -
  • -
  • -

    the time used in the corresponding Segment Object in the RxPlayer -(playerTime)

    -
  • -
  • -

    the time used in the buffered APIs of a HTMLMediaElement or SourceBuffer -(bufferedTime)

    -
  • -
  • -

    -
  • -
-

As it turns out it’s a lot simpler once you make two isolated groups:

-
    -
  • -

    the manifest group, which uses the non-offseted mediaTime.

    -

    In this group you have:

    -
      -
    • the mediaTime (duh)
    • -
    • the manifestTime
    • -
    • the requestSegmentTime
    • -
    -
  • -
  • -

    the real time group, which uses the offseted presentationTime.

    -

    In this group you have:

    -
      -
    • the presentationTime
    • -
    • the playerTime
    • -
    • the bufferedTime
    • -
    -
  • -
-

The manifest group is then only used in the transports code of the -RxPlayer. -Meanwhile, the real time group is used everywhere else.

-

It’s actually the transports code that does most of the conversion for the -rest of the code (removing the offset when requesting new segments, re-adding it -once the segment is downloaded.

-

To be able to offset those segments in the SourceBuffer, those are still -informed of course of the timestampOffset by the transports code. -Then, this timestampOffset will be exploited only by the final decoding -code.

-
\ No newline at end of file diff --git a/doc/generated/pages/infos/initial_position.html b/doc/generated/pages/infos/initial_position.html deleted file mode 100644 index ccd86bee5a..0000000000 --- a/doc/generated/pages/infos/initial_position.html +++ /dev/null @@ -1,107 +0,0 @@ -At what position does the RxPlayer start a content - RxPlayer Documentation

-

At what position does the RxPlayer start a content

-

-

Overview

-

When you give it a content to load, the RxPlayer has to set at one point the -starting playback position.

-

This documentation page explain how that position is calculated.

-

Basically, we can be in one of those four different situations:

-
    -
  • -

    a valid startAt option has been set to loadVideo, in which case we use -it to define the initial position.

    -
  • -
  • -

    no startAt option has been set and we’re playing a VoD content.

    -
  • -
  • -

    no startAt option has been set and we’re playing a live content.

    -
  • -
  • -

    no startAt option has been set and we’re playing a directfile content.

    -
  • -
-

-

About the minimum and maximum position

-

Regardless of your current situation, the minimum and maximum position of the -content might be calculated and used when defining that starting position.

-

Those positions are inferred directly from the Manifest (when not playing a -directfile content). -Most Manifests declare every segments currently available. In that case, we can -simply use the start of the first announced segment as a minimum position and the -end of the last one as a maximum.

-

In some other Manifest files, segment availability is not clearly announced. -In those cases, the minimum and maximum positions use other properties declared -in the Manifest, often by making usage of a synchronized clock between the -client and the server.

-

For “directfile” contents, we directly interrogate the browser to obtain the -duration of the content. The minimum position here is always inferred to be 0 -(for the moment at least).

-

-

When a startAt option has been set

-

You can define yourself the start position at which we should play. This is -configurable thanks to the startAt option, documented -here in the API documentation.

-

Please note however that there is a catch: every of the possible values you -will set will be “bounded” to the maximum and minimum position actually detected -for the content.

-

This means that if your startAt indicate that we should start at a position of -10 seconds but the content starts at 15 seconds, we will actually start -at 15 seconds instead.

-

You can check at which position we actually loaded when the player’s state -(accessible either through the getPlayerState method or through the -playerStateChanged event) changed to "LOADED".

-

-

When no startAt option has been set and we’re playing a VoD content

-

For VoD contents, we will just start to play at the minimum detected position in -the Manifest.

-

-

When no startAt option has been set and we’re playing a live content

-

For live contents, we have here three cases:

-
    -
  • -

    In the case where we have a clock synchronization mechanism with the -server[1] and if the current date can be seeked to (i.e. segments are -available for that position), we will try to play close to[2] that date.

    -
  • -
  • -

    if either we do not have a clock synchronization mechanism[1] or if we have -one but no segment is defined for the current date, we will play close to[2] -the maximum calculated position instead.

    -
  • -
  • -

    Third case, if we do not have any clock synchronization mechanism[1] and if -the Manifest does not announce clearly a maximum position, we will use the -system clock and play close to[2] that time instead.

    -
  • -
-

[1] We can obtain a synchronized clock allowing us to to know which content -should be broadcasted at which time by either of those means:

-
    -
  • the Manifest document defines one (e.g. UTCTiming elements for DASH -contents).
  • -
  • One was provided to loadVideo thanks to the serverSyncInfos transport -option see loadVideo -documentation.
  • -
-

[2] I wrote “close to” in every cases as we might substract some seconds from -that value. How much we might do, depends on:

-
    -
  • if the manifest suggest us a delay relative to the live, in which case we -apply it
  • -
  • if not, we set it to the default: 10 seconds
  • -
-

-

When no startAt option has been set and we’re playing a directfile content

-

For directfile contents, we for now just start at 0 if no startAt is -defined.

-
\ No newline at end of file diff --git a/doc/generated/pages/terms.html b/doc/generated/pages/terms.html deleted file mode 100644 index 88c50bb7a0..0000000000 --- a/doc/generated/pages/terms.html +++ /dev/null @@ -1,205 +0,0 @@ -Terms and definitions - RxPlayer Documentation

-

Terms and definitions

-

-

-

Overview

-

As the RxPlayer manages multiple type of streaming technologies, which can use -their own definition and terminology, we had to find a compromise and use our -own terminology, which try to take the best from these.

-

We here define various terms used in the documentation which might not be -obvious right along.

-

-

-

Definitions

-

-

-

Adaptation

-

Simply put, what we call an “Adaptation” is just an audio, video or text track.

-

More technically, it is an element of a Period (and by extension of -the Manifest) which represents a single type of media.

-

An adaptation can be for example any of those things:

-
    -
  • A video track
  • -
  • A french audio track
  • -
  • An italian text track
  • -
  • A thumbnail track
  • -
  • -
-

Many Streaming Technology have this concept even though their name can change, -an Adaptation is equivalent to:

-
    -
  • DASH’s AdaptationSet
  • -
  • Microsoft Smooth Streaming’s StreamIndex
  • -
-

Note: There is minor differences between the RxPlayer’s Adaptation and DASH’ -AdaptationSet. Namely multiple AdaptationSets can be merged into a single -Adaptation in very specific cases. -You can find more infos on it here.

-

-

-

Bitrate

-

In the RxPlayer, a bitrate of a Representation indicates the -number of bits per second of content described by that Representation.

-

For example, let’s imagine a video Adaptation with two -Representation:

-
    -
  1. one with a bitrate at 1,000,000 (which is 1 Megabit)
  2. -
  3. the other with a bitrate at 500,000 (which is 500 kilobits)
  4. -
-

Each seconds of content described by the first Representation will be -represented by 1 megabit of data

-

Each seconds for the second Representation will be represented by 500 kilobits.

-

Both will represent the same data, but the first one will need that the RxPlayer -fetch more data to show the same amount of content.

-

In most cases, a higher bitrate means a higher quality. That’s why the RxPlayer -has to compromise between having the best quality and choosing a Representation -having a low-enough bitrate to be able to play on the user’s computer without -needing to pause due to poor network conditions.

-

-

-

Buffer

-

When we talk about the “buffer” in the RxPlayer, we most likely refer to the -structures in the browser holding media data, waiting to be decoded.

-

Several layers of buffers can be defined in the browser-side to allow to have a -smooth playback, fast seeking etc.

-

-

-

Buffer type

-

RxPlayer’s buffer types describe a single “type” of media.

-

Example of such types are:

-
    -
  • “video”: which represents only the video content
  • -
  • “audio”: the audio content without the video
  • -
  • “text”: the subtitles, for example
  • -
-

-

-

Chunk

-

Depending on the context, a chunk can be either a sub-part of a Media -Segment or the Media segment itself.

-

-

-

Initialization segment

-

An initialization segment is a specific type of media segment, which -includes metadata necessary to initialize the browser’s internal decoder.

-

Those are sometimes needed before we can actually begin to push any “real” media -segment from the corresponding Representation.

-

As such, when one is needed, the initialization segment is the first segment -downloaded for a given Representation.

-

-

-

Manifest

-

The Manifest is the generic name for the document which describes the content -you want to play.

-

This is equivalent to the DASH’s Media Presentation Description (or MPD), -the Microsoft Smooth Streaming’s Manifest and the HLS’ Master Playlist.

-

Such document can describe for example:

-
    -
  • multiple qualities for the same video or audio tracks
  • -
  • multiple audio tracks in different languages
  • -
  • presence of subtitles
  • -
-

Note that this concept is only used in Streaming technologies. -You won’t interact with a Manifest if you’re directly playing a MP4 or webM -file.

-

-

-

Media segment

-

A media segment (or simply segment), is a small chunk of media data.

-

In many streaming technologies, a content is separated into multiple chunks of -small duration (usually between 2 and 10 seconds).

-

This allows, for reasons to long to detail here, to easily implements many -features:

-
    -
  • live streaming,
  • -
  • language switching
  • -
  • adaptive streaming
  • -
-

When you play a content with the RxPlayer, it will most of the time download -media segments of different types (audio, video, text…) progressively rather -than the whole content at a single time.

-

-

-

Period

-

Simply put, a Period defines what the content will be from a starting time to -an ending time. It is an element contained in the Manifest) and it -will contain the Adaptations available for the corresponding -time period.

-

Depending on the transport used, they correspond to different concepts:

-
    -
  • for DASH contents, it is more or less the same thing than an MPD’s -<Period> element
  • -
  • for “local” contents, it corresponds to a single object from the periods -array.
  • -
  • for “MetaPlaylist” contents, it corresponds to all the Period elements we -retrieved after parsing the corresponding Manifest from the -elements of the contents array.
  • -
  • any other transport will have a single Period, describing the whole content.
  • -
-

-

As an example, let’s take a manifest describing a live content with -chronologically:

-
    -
  1. an english TV Show
  2. -
  3. an old italian film with subtitles
  4. -
  5. an American blockbuster with closed captions.
  6. -
-

Let’s say that those sub-contents are drastically different:

-
    -
  • they are all in different languages
  • -
  • the american blockbuster has more available video bitrates than the old -italian one
  • -
-

Because the available tracks and available qualities are different from -sub-content to sub-content, we cannot just give a single list of Adaptations -valid for all of them. They have to be in some way separated in the Manifest -object.

-

That’s a case where Periods will be used. -Here is a visual representation of how the Periods would be divided here:

-
        Period 1                Period 2                Period 3
-08h05              09h00                       10h30                 now
-  |==================|===========================|====================|
-        TV Show               Italian Film        American Blockbuster
-
-

Each of these Periods will be linked to different audio, video and text -Adaptations, themselves linked to different Representations.

-

-

-

Representation

-

A Representation is an element of an Adaptation, and by extension -of the Manifest) that describes an interchangeable way to represent -the parent Adaptation.

-

For example, a video Adaptation can have several Representations, each having -its own bitrate, its own width or its own height. -The idea behind a Representation is that it can be changed by any other one in -the same Adaptation as the content plays.

-

This is most often implemented to allow multiple bitrates for the same -Adaptation, to be more flexible to poor network (low bandwidth) or computing -(slow computer) conditions.

-

A Representation has its equivalent in multiple Streaming technologies. It is -roughly the same as:

-
    -
  • DASH’s Representation
  • -
  • Microsoft Smooth Streaming’s QualityIndex
  • -
  • HLS’ variant (the notion of variant is actually a little more complex, -so here it’s not an exact comparison)
  • -
-
\ No newline at end of file diff --git a/doc/generated/pages/tutorials/contents_with_DRM.html b/doc/generated/pages/tutorials/contents_with_DRM.html deleted file mode 100644 index 5d18023418..0000000000 --- a/doc/generated/pages/tutorials/contents_with_DRM.html +++ /dev/null @@ -1,654 +0,0 @@ -Tutorial: Playing contents with DRMs - RxPlayer Documentation

-

Tutorial: Playing contents with DRMs

-

Because different applications and different devices can work completely -differently when it comes to DRM, and because it is a complex feature, we have -a large API allowing to manage it.

-

This tutorial page is specifically there to help you navigate through this API.

-

We will begin from the simplest of use cases to dive into the more complex ones.

-

We recommend you to read the quick start tutorial first if -you haven’t, to have a general grasp on how to basically run a content.

-

-

Playing a simple encrypted content

-

To be able to play a simple encrypted content, we will need at least two -parameters:

-
    -
  1. type: the name of the “key system” you want to use.
  2. -
  3. getLicense: the license-fetching logic
  4. -
-

This chapter will explain both and provide examples on how to load a video with -both of these properties.

-

-

The key system

-

The key system, also known as “DRM name”, will designate which Content -Decryption Module (or CDM) to use. You might have heard of “Widevine”, -“PlayReady” or “FairPlay”, that’s the name what we want to know: which system -you want to use.

-

Which of them you want to use depend on several factors, among which:

-
    -
  • what the content allows
  • -
  • what the content right holder wants
  • -
  • what you/your company wants
  • -
  • what the browser can do
  • -
-

In the RxPlayer’s API, we more especially expect the whole “reverse domain name” -for that key systems (e.g. com.widevine.alpha or com.microsoft.playready).

-

We also have shortcuts for Widevine or PlayReady, where you can just tell us -respectively widevine or playready as the key system and we will try -several corresponding reverse domain names.

-

In any case, you can ask for several key systems, even including ones that are -not available in the current browser. Those will be detected and automatically -filtered out.

-
rxPlayer.loadVideo({
-  // ...
-  keySystems: [
-    {
-      type: "com.widevine.alpha"
-      // ...
-    },
-    {
-      type: "com.microsoft.playready"
-      // ...
-    },
-  ]
-})
-
-

-

The license-fetching logic

-

The second needed argument is a callback allowing to fetch the content license.

-

An encrypted content will need one or several keys to be able to decrypt a -content. Those keys are contained in one or several license files.

-

Those files usually need to be downloaded from a license server.

-

As that logic sometimes depends on your application (i.e. you might want to -add authentification to that request to know which user made that request), the -RxPlayer team made the choice to let you write your logic entirely.

-

This logic takes the form of a callback named getLicense.

-

This function is in fact triggered everytime a message is sent by the Content -Decryption Module (what is sometimes known as “Widevine” or “PlayReady”), which -is usually a request to fetch or renew the license.

-

It gets two arguments when called:

-
    -
  1. message (Uint8Array): The “message”
  2. -
  3. messageType (string): String describing the type of message received. -There is only 4 possible message types, all defined in the w3c -specification.
  4. -
-

In most cases, this function is triggered for license requests. -You’re encouraged to read what the messageType can be, but don’t be scared by -it, you’ll most likely never need to check it.

-

What you will most likely need to do, is simply sending the first argument, -message, to the license server to fetch the license. That message generally -contains information about the license you want to fetch.

-

You will then need to return a Promise, which resolves with the license in an -ArrayBuffer or Uint8Array form. -If you don’t want to communicate a license based on this message, you can just -return null or a Promise resolving with null.

-

Here is an example of a valid and simple getLicense implementation:

-
function getLicense(challenge) {
-  return new Promise((resolve, reject) => {
-    const xhr = new XMLHttpRequest();
-    xhr.open("POST", LICENSE_SERVER_URL, true);
-    xhr.onerror = (err) => {
-      reject(err);
-    };
-    xhr.onload = (evt) => {
-      if (xhr.status >= 200 && xhr.status < 300) {
-        const license = evt.target.response;
-        resolve(license);
-      } else {
-        const error = new Error("getLicense's request finished with a " +
-                                `${xhr.status} HTTP error`);
-        reject(error);
-      }
-    };
-    xhr.responseType = "arraybuffer";
-    xhr.send(challenge);
-  });
-}
-
-

-

Example with both properties

-

Now that all that has been explained here’s an example to play a simple -encrypted DASH content with either PlayReady or Widevine.

-
// We will use the same logic for both PlayReady and Widevine
-function getLicense(challenge) {
-  return new Promise((resolve, reject) => {
-    const xhr = new XMLHttpRequest();
-    xhr.open("POST", LICENSE_SERVER_URL, true);
-    xhr.onerror = (err) => {
-      reject(err);
-    };
-    xhr.onload = (evt) => {
-      if (xhr.status >= 200 && xhr.status < 300) {
-        const license = evt.target.response;
-        resolve(license);
-      } else {
-        const error = new Error("getLicense's request finished with a " +
-                                `${xhr.status} HTTP error`);
-        reject(error);
-      }
-    };
-    xhr.responseType = "arraybuffer";
-    xhr.send(challenge);
-  });
-}
-
-rxPlayer.loadVideo({
-  url: MANIFEST_URL,
-  transport: "dash",
-  keySystems: [
-    {
-      type: "widevine",
-      getLicense,
-    },
-    {
-      type: "playready",
-      getLicense,
-    }
-  ]
-});
-
-

This code is sufficient for a majority of encrypted contents.

-

-

More control over the license-fetching logic

-

There’s a lot of things that can go wrong during the license request:

-
    -
  • The user could be temporarly disconnected
  • -
  • The license server might be down
  • -
  • The license server might refuse to deliver a license based on your rights
  • -
  • The license server might refuse to deliver a license based on your CDM -capabilities
  • -
  • And like any request a lot of other errors can happen
  • -
-

From this, you could want to have a different behavior based on what happened:

-
    -
  • When a user is temporarly disconnected, you could chose to retry -indefinitely (the RxPlayer retry after a delay to not overload the client or -the server).
  • -
  • When the license server is down, you might want to fail directly.
  • -
  • When the license server refuse to deliver a license based on your rights, -you might want to throw an explicit error message that you will be able to -display.
  • -
  • If there’s a problem with your CDM capabilities, you might want to just -fallback to another media quality with a different license.
  • -
-

All of this is possible with more advanced APIs that we will see in this -chapter.

-

-

getLicenseConfig

-

getLicenseConfig is an object allowing to configure two parameters:

-
    -
  • -

    retry, which will set the maximum number of retry. -When setting 1, for example, we will try two times the request: A first -original time and one retry.

    -

    You can decide to by default retry indefinitely by setting it to Infinity -(yes, that’s a valid number in JS and some other -languages). Don’t worry, you will -still be able to retry less time on some other events (explained in -the getLicense error configuration chapter).

    -
  • -
  • -

    timeout, which is the maximum time in milliseconds the RxPlayer will wait -until it considers a getLicense call to have failed. -By default it is set to 10000 (10 seconds). You can set it to -1 to -disable any timeout.

    -
  • -
-

For example, for infinite retry and no timeout, you can set:

-
rxPlayer.loadVideo({
-  url: MANIFEST_URL,
-  transport: "dash",
-  keySystems: [
-    {
-      type: "widevine",
-      getLicense,
-      getLicenseConfig: {
-        retry: Infinity,
-        timeout: -1,
-      },
-    },
-    // ...
-  ]
-});
-
-

-

getLicense error configuration

-

getLicenseConfig handle general configurations about every getLicense calls, -but you can also have more specific configuration when a specific license -request fails.

-

This is done thanks to the rejected Promise returned by getLicense. -You can reject an error (or just an object), with the following properties:

-
    -
  • -

    noRetry: when set to true, the getLicense call will not be retried.

    -
  • -
  • -

    message: a custom message string we will communicate through a warning or -error event (depending if we will retry or not the call)

    -
  • -
  • -

    fallbackOnLastTry: When set to true and if we are doing or last -try or retry (to be sure you can set noRetry to true), we will try to -fallback to another quality, which might have a different license.

    -

    This is only useful for contents which have a different license depending on -the quality (for example having different rights for 4k video content than -for 480p video content). It is also only useful if the license server can -refuse to deliver a license for a particular quality but accept for another -quality.

    -
  • -
-

Here is an example showcasing all of those properties:

-
rxPlayer.loadVideo({
-  url: MANIFEST_URL,
-  transport: "dash",
-  keySystems: [
-    {
-      type: "widevine",
-      getLicense(challenge) {
-        return new Promise((resolve, reject) => {
-          const xhr = new XMLHttpRequest();
-          xhr.open("POST", LICENSE_SERVER_URL, true);
-          xhr.onerror = (err) => {
-            // Keep retrying on XHR errors.
-            // Instanciating an Error like that automatically set the
-            // message attribute to this Error's message. That way, the
-            // linked "error" or "warning" event sent by the RxPlayer
-            // will have the same message.
-            const error = new Error("Request error: " + err.toString())
-            reject(err);
-          };
-          xhr.onload = (evt) => {
-            if (xhr.status >= 200 && xhr.status < 300) {
-              const license = evt.target.response;
-              resolve(license);
-            } else if (xhr.status >= 500 && xhr.status < 600) {
-              // Directly fails + fallbacks on a server error
-              const error = new Error("The license server had a problem and" +
-                                      ` responded with ${xhr.status} HTTP ` +
-                                      "error. We will now fallback to another" +
-                                      "quality.");
-              error.noRetry = true;
-              error.fallbackOnLastTry = true;
-              reject(error);
-            } else {
-              // else continue to retry
-              const error = new Error("getLicense's request finished with a " +
-                                      `${xhr.status} HTTP error`);
-              reject(error);
-            }
-          };
-          xhr.responseType = "arraybuffer";
-          xhr.send(challenge);
-        });
-      },
-      getLicenseConfig: {
-        retry: Infinity,
-        timeout: -1,
-      },
-    },
-    // ...
-  ]
-});
-
-

-

Contents with multiple keys

-

-

Why and how

-

One of the issues arising with DRM is that not all devices, Operating systems or -web browsers can provide a high level of guarantee that a content will be -protected against unauthorized usages (such as illegal copy). -In other words, some devices, OS or browsers might provide more guarantees than -other.

-

That’s the main reason why there’s sometime a compromise to have between -accessibility of a content (the number of the people able to view it) and this -guarantee.

-

To be able to provide the best of both worlds, a content right holder might ask -for a higher protection guarantee for higher video qualities.

-

For example, it might ask that a 4k video content of a given film should be much -harder to “pirate” than the 240p version of the same film. -In return, the 240p version can be watched by a lot more people on a lot of -different devices.

-

To achieve that, one of the solution on the content-side is to have different -decryption keys depending on the quality chosen. -There’s then two main strategies:

-
    -
  1. -

    Every keys are in the same license. A player will thus do only one -license request for the whole content and the keys inside will be -individually refused or accepted.

    -
  2. -
  3. -

    There is one or several keys per licenses, in several licenses. That way, -a player might ask a different license when switching the current -quality.

    -
  4. -
-

There’s pros and cons to both, but let’s not go too far into that!

-

Let’s start from the principle that our content is under one of those two cases -here and let’s find out what we have to do to handle it.

-

-

The strategy adopted by the RxPlayer

-

When playing a content, the RxPlayer by default stops and throws an error as -soon as either a key is refused or as the license fetching logic (the -getLicense function) fails (after enough retries).

-

When playing a content with multiple keys, you might instead not care that much -if a key is refused or if the license-fetching logic fails. -What you can just do is to remove the quality for which we could not obtain a -key and to instead fallback on another, decipherable, quality.

-

That’s exactly what the RxPlayer does, when the right options are set:

-
    -
  1. -

    when it detects a quality to be un-decipherable, it first emit a -decipherabilityUpdate event through its API, to signal to an application -which qualities have been blacklisted.

    -
  2. -
  3. -

    it automatically removes from the current media buffer the data linked to -the un-decipherable quality and put it in a black list: we will not load -this quality for the current content anymore.

    -
  4. -
  5. -

    it switches to another, hopefully decipherable, quality.

    -
  6. -
-

Let’s now talk about the API.

-

-

fallbackOnLastTry

-

This option was already explained in a previous chapter. Basically, it is a -boolean you can set to true when rejecting an error from the getLicense -callback. When set and if it was the last getLicense try or retry, the -RxPlayer will stop to play every quality sharing the same “protection -initialization data”. -What that last part really means is a little complex, but it generally means -that every qualities sharing the same license file will be considered as -un-decipherable.

-

For more information and an example on how to use it, you can go back on the -concerned previous part of this tutorial.

-

Please note that this option does not concern every errors linked to a refused -key. It only concerns issues when the license server refuse to deliver a -license. -On most cases you will also need the API documented in the next part, -fallbackOn.

-

-

fallbackOn

-

Where fallbackOnLastTry really is about the failure of a license request, the -fallbackOn is about the refused keys themselves.

-

As an example, the Content Decryption Module in the browser might decide that -your current device cannot provide a high enough guarantee that the content -cannot be copied. It might thus refuse to use one of the decryption key found in -a license, especially the one needed for the higher content qualities.

-

The fallbackOn object allows to fallback when this happens. -There is two possible sub-properties in it:

-
    -
  • keyInternalError: fallback when the corresponding key has the -status -"internal-error". We found that most widevine implementation use -this error when a key is refused.
  • -
  • keyOutputRestricted: fallback when the corresponding key has the -status -"output-restricted". This is the proper status for a key refused due -to output restrictions.
  • -
-

Both are booleans, and for the moment we recommend to set both to true in most -cases.

-

For people on embedded devices with specific key systems, you can look a little -more into what MediaKeyStatus -is set when a key is refused, and just set one of both.

-

Here is an example:

-
rxPlayer.loadVideo({
-  url: MANIFEST_URL,
-  transport: "dash",
-  keySystems: [
-    {
-      type: "widevine",
-      getLicense,
-      fallbackOn: {
-        keyInternalError: true,
-        keyOutputRestricted: true,
-      }
-    },
-  ]
-});
-
-

-

decipherabilityUpdate event

-

When the RxPlayer detects a quality to be un-decipherable (which can only -happens when one of the properties explained here is set), it sends a -decipherabilityUpdate event.

-

This event allows an application to know that some key or license could not be -used by the RxPlayer.

-

The application could then infer that other contents from the same right holders -will have the same issues. -In that case, an optimization is possible by using the representationFilter -API which is part of the transportOptions loadVideo option, documented -here. By using this API, -we can filter out un-decipherable quality to avoid downloading them in the -first place.

-

-

Server certificate

-

The “server Certificate” is a certificate allowing to encrypt messages coming -from the Content Decryption module to the license server. They can be required -by some key system as a supplementary security mechanism.

-

Thankfully, an application is not obligated to set one, even if one is needed. -If not set, the Content Decryption Module will download it itself by using the -same route than a license request (the getLicense callback will be called).

-

This means however, that we have to perform two round-trips to the license -server instead of one:

-
    -
  1. one to fetch the “server certificate”.
  2. -
  3. the other to fetch the license.
  4. -
-

To avoid the first round-trip, it is possible for an application to directly -indicate what the serverCertificate is when calling loadVideo.

-

This is done through the serverCertificate property, in keySystems:

-
rxPlayer.loadVideo({
-  url: MANIFEST_URL,
-  transport: "dash",
-  keySystems: [
-    {
-      type: "widevine",
-      getLicense,
-      serverCertificate,
-    },
-  ]
-});
-
-

The serverCertificate has to either be in an ArrayBuffer form or a -TypedArray (i.e. Uint8Array, Uint16Array etc.)

-

-

Persistent licenses

-

A persistent license allows to store a license for it to be available even when -a user quits the current page or restarts its computer. It can be used even if -the user is offline.

-

After loading a persistent license, it is automatically stored on the browser’s -side, but the RxPlayer still has to store an ID to be able to retrieve the right -session when reloading the same content later. -Because of that, persistent-license management comes in two part in the RxPlayer -API (as usual here, those should be set in keySystems):

-
    -
  1. -

    You’ll have to set the persistentLicense boolean to true

    -
  2. -
  3. -

    You’ll have to provide a license storage mechanism and set it as the -licenseStorage property.

    -
  4. -
-
rxPlayer.loadVideo({
-  url: MANIFEST_URL,
-  transport: "dash",
-  keySystems: [
-    {
-      type: "widevine",
-      getLicense,
-      persistentLicense: true,
-      licenseStorage,
-    },
-  ]
-});
-
-

-

licenseStorage property

-

The licenseStorage property is an object allowing the RxPlayer to load and -saved stored IDs.

-

It needs to contain two functions:

-
    -
  • save: Which sould store the argument given. The argument will be an array -of Objects.
  • -
  • load: Called without any argument, it has to return what was given to the -last save call. Any return value which is not an Array will be ignored -(example: when save has never been called).
  • -
-

This API can very simply be implemented with the -localStorage -browser API:

-
rxPlayer.loadVideo({
-  url: MANIFEST_URL,
-  transport: "dash",
-  keySystems: [
-    {
-      type: "widevine",
-      getLicense,
-      persistentLicense: true,
-      licenseStorage: {
-        save(data) {
-          localStorage.setItem("RxPlayer-licenseStorage", JSON.stringify(data));
-        },
-        load() {
-          const item = localStorage.getItem("RxPlayer-licenseStorage");
-          return item === null ? [] :
-                                 JSON.parse(item);
-        }
-      },
-    },
-  ]
-});
-
-

Do not be scared about security implications, the data saved is not secret and -does not help to identify a user.

-

You can also use every storage API at your disposition (some embedded devices -might have their own).

-

As a nice bonus, you can note that the data given is perfectly “serializable” -through the JSON.stringify browser API. This means that, as the example shown -above, you can call JSON.stringify on that data and retrieve it through a -JSON.parse call.

-

This is very useful for storage APIs which cannot store JavaScript objects.

-

-

Playback issues related to DRMs

-

The configuration example which finishes the last chapter should work in most -cases, but you might encounter very specific issues on some devices.

-

-

Issues with fallbacking with the Edge browser and PlayReady

-

We sometimes encountered a bug which makes the player loads indefinitely when -fallbacking from an undecipherable quality, if done through the -fallbackOnLastTry option. This was only constated on the Edge browser and -appears to be a browser or CDM bug.

-

Sadly, no work-around has been found for now for this issue. We’re currently -trying to create a reproducible scenario and document that issue so it can -hopefully be fixed in the future. In the meantime, you’re encouraged either to -use Widevine (only on Chromium-based Edge) or to not make use of the -fallBackOnLastTry option on that browser.

-

-

The Player do not download any segment when playing encrypted contents

-

This is probably due to an issue we encountered several time on embedded -devices.

-

Basically, this behavior is due to a deadlock, where the RxPlayer is waiting for -the CDM logic to be initialized to download segments but the CDM logic wait for -the opposite: it will only initialize itself once segments have been downloaded.

-

The RxPlayer is waiting for the CDM initialization for a very specific usage: -playing a mix of unencrypted and encrypted data. We detected that on some Chrome -versions we could not play encrypted data if we first played unencrypted data -without the CDM logic in place.

-

Fortunately, this usage is for very specific cases and you most likely won’t -need it (or even if you will, you most likely will not encounter that problem).

-

You can completely remove that deadlock with a property called -disableMediaKeysAttachmentLock. Like other properties introduced here, you -should put it in the keySystems object of loadVideo, like such:

-
rxPlayer.loadVideo({
-  url: MANIFEST_URL,
-  transport: "dash",
-  keySystems: [
-    {
-      type: "widevine",
-      getLicense,
-      disableMediaKeysAttachmentLock: true,
-    },
-    {
-      type: "playready",
-      getLicense,
-      disableMediaKeysAttachmentLock: true,
-    }
-  ]
-});
-
-

-

After two or several loadVideo calls the RxPlayer refuses to play

-

There’s a chance that you’re encountering another issue we found on embedded -devices.

-

By default, the RxPlayer maintains a cache containing the last loaded licenses. -This allows to quickly switch to already-played contents, an important -improvement when playing live contents for example. -Rest assured, our cache size is not infinite, and as such it should work on most -devices.

-

However, we found that on some devices, this logic can be problematic, and it -will just refuse to add a license at a given point.

-

You can add a property which will flush that cache anytime the content changes, -called closeSessionsOnStop.

-

Like other properties introduced here, you should put it in the keySystems -object of loadVideo, like such:

-
rxPlayer.loadVideo({
-  url: MANIFEST_URL,
-  transport: "dash",
-  keySystems: [
-    {
-      type: "widevine",
-      getLicense,
-      closeSessionsOnStop: true,
-    },
-    {
-      type: "playready",
-      getLicense,
-      closeSessionsOnStop: true,
-    }
-  ]
-});
-
-
\ No newline at end of file diff --git a/doc/generated/pages/tutorials/index.html b/doc/generated/pages/tutorials/index.html deleted file mode 100644 index d5b39bb45e..0000000000 --- a/doc/generated/pages/tutorials/index.html +++ /dev/null @@ -1,13 +0,0 @@ -Tutorials - RxPlayer Documentation

-

Tutorials

-

This directory regroups various tutorials to help a user familiarize with the -RxPlayer APIs.

-

Here is an exhaustive list of the available tutorials:

- -
\ No newline at end of file diff --git a/doc/generated/pages/tutorials/quick_start.html b/doc/generated/pages/tutorials/quick_start.html deleted file mode 100644 index f5714925d6..0000000000 --- a/doc/generated/pages/tutorials/quick_start.html +++ /dev/null @@ -1,146 +0,0 @@ -Tutorial: Quick Start - RxPlayer Documentation

-

Tutorial: Quick Start

-

Because the RxPlayer exports a lot of functionnalities, you might want to -quickly test basic use cases before you dive deep into the whole API -documentation.

-

We will here learn how to simply load a video and to react to basic events.

-

-

Instanciating a Player

-

The first step is to instanciate a new RxPlayer.

-

Each RxPlayer instance is attached to a single video (or audio) HTML element, -and is able to play a single content at once.

-

To instanciate it with a linked video element you can just do something along -the lines of:

-
import RxPlayer from "rx-player";
-
-const videoElement = document.querySelector("video");
-const player = new RxPlayer({ videoElement });
-
-

videoElement is an RxPlayer option and will be the HTMLElement the RxPlayer -will load your media on.

-

Despite its name, you can also give it an <audio> element. It will still be -able to play an audio content without issue.

-

When you are ready to make use of more advanced features, you can look at the -other possible options in the Player Options page.

-

-

Loading a content

-

The next logical step is to load a content (audio, video or both).

-

Loading a new content is done through the loadVideo method.

-

loadVideo takes an object as arguments. There is here also a lot of -possible options, but to simplify we will start -with just three:

-
    -
  • -

    transport: String describing the transport protocol (can be "dash", -"smooth" or "directfile" for now).

    -
  • -
  • -

    url: URL to the content (to the Manifest for Smooth contents, to the MPD -for DASH contents or to the whole file for DirectFile contents).

    -
  • -
  • -

    autoPlay: Boolean indicating if you want the content to automatically -begin to play once loaded. false by default (which means, the player -will not begin to play on its own).

    -
  • -
-

Here is a quick example which will load and play a DASH content:

-
player.loadVideo({
-  url: "http://vm2.dashif.org/livesim-dev/segtimeline_1/testpic_6s/Manifest.mpd",
-  transport: "dash",
-  autoPlay: true,
-});
-
-

-

Reacting to basic events

-

Now that we are loading a content, we might want to know:

-
    -
  • if it succeed
  • -
  • if it failed
  • -
  • when we are able to interact with the content
  • -
-

To do all three of those things, you will need to listen to player events. -This is done through the addEventListener -method.

-

This method works the same way than the native one you might already use on -HTML elements.

-

For example, to know if a fatal error happened (this is an error which -interrupted the playback of the current content), you will just have to do:

-
player.addEventListener("error", (err) => {
-  console.log("the content stopped with the following error", err);
-});
-
-

And to know if the player successfully loaded a content and if you can now -interact with it, you can just do:

-
player.addEventListener("playerStateChange", (state) => {
-  if (state === "LOADED") {
-    console.log("the content is loaded");
-    // interact with the content...
-  }
-});
-
-

There is multiple other events, all documented in the events documentation -.

-

As the state is a central focus of our API, we also heavily documented states in -the player states documentation.

-

-

Interacting with the player

-

We’re now ready to interact with the current content.

-

There is a huge list of APIs you can use. -Some are useful only when a content is currently loaded (like play, -pause, seekTo or setAudioTrack) and others can be used in any case -(like setVolume, getVideoElement or loadVideo).

-

Here is a complete example where I:

-
    -
  1. Instanciate an RxPlayer
  2. -
  3. load a content with it with autoPlay
  4. -
  5. toggle between play and pause once the content is loaded and the user click -on the video element.
  6. -
-
import RxPlayer from "rx-player";
-
-// take the first video element on the page
-const videoElement = document.querySelector("video");
-
-const player = new RxPlayer({ videoElement });
-
-player.addEventListener("error", (err) => {
-  console.log("the content stopped with the following error", err);
-});
-
-player.addEventListener("playerStateChange", (state) => {
-  if (state === "LOADED") {
-    console.log("the content is loaded");
-
-    // toggle between play and pause when the user clicks on the video
-    videoElement.onclick = function() {
-      if (player.getPlayerState() === "PLAYING") {
-        player.pause();
-      } else {
-        player.play();
-      }
-    };
-  }
-});
-
-player.loadVideo({
-  url: "http://vm2.dashif.org/livesim-dev/segtimeline_1/testpic_6s/Manifest.mpd",
-  transport: "dash",
-  autoPlay: true,
-});
-
-

-

And now?

-

Now that you know the basic RxPlayer APIs, you might want to dive deep into the -whole API documentation.

-

You can also read our next tutorial, on how to play contents with DRM, -here.

-
\ No newline at end of file diff --git a/doc/generated/pages/tutorials/stream_events.html b/doc/generated/pages/tutorials/stream_events.html deleted file mode 100644 index 4d9ee5c58e..0000000000 --- a/doc/generated/pages/tutorials/stream_events.html +++ /dev/null @@ -1,289 +0,0 @@ -Tutorial: Listening to stream events - RxPlayer Documentation

-

Tutorial: Listening to stream events

-

Some contents contain events a player will need to send at a particular point -in time. We call those in the RxPlayer “stream events”.

-

For example, stream events are often used jointly with ad-insertion, to allow a -player to notify when an user begin to see a particular ad.

-

Stream events are not only restrained to ad-related usages though. Any event -you want to synchronize with the played content can be inserted.

-

-

Event Formats understood by the RxPlayer

-

-

DASH EventStream elements

-

For now, the RxPlayer only make use of DASH’ EventStream elements.

-

Such elements are defined in a DASH MPD in the concerned Period. -Here is an example of such element in an MPD:

-
<?xml version="1.0" encoding="UTF-8"?>
-<MPD
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xmlns="urn:mpeg:dash:schema:mpd:2011"
-  xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"
-  type="dynamic"
-  minimumUpdatePeriod="PT2S"
-  timeShiftBufferDepth="PT30M"
-  availabilityStartTime="2011-12-25T12:30:00"
-  minBufferTime="PT4S"
-  profiles="urn:mpeg:dash:profile:isoff-live:2011">
-
-    <Period id="1">
-      <EventStream schemeIdUri="urn:uuid:XYZY" timescale="1000" value="call">
-        <Event presentationTime="0" duration="10000" id="0">
-          1 800 10101010
-        </Event>
-        <Event presentationTime="20000" duration="10000" id="1">
-          1 800 10101011
-        </Event>
-        <Event presentationTime="40000" duration="10000" id="2">
-          1 800 10101012
-        </Event>
-        <Event presentationTime="60000" duration="10000" id="3">
-          1 800 10101013
-        </Event>
-      </EventStream>
-      <!-- ... -->
-    </Period>
-
-</MPD>
-
-

Here the <EventStream /> elements and its <Event /> children elements will -be parsed by the RxPlayer.

-

Each <Event /> element can then be sent through a single RxPlayer events.

-

-

How to listen to stream events

-

The RxPlayer notify of such events through the usual RxPlayer events.

-

As a reminder (or if you didn’t know), the RxPlayer can send a multitude of -events that can be listened to by the usage of the -addEventListener method.

-

The events related to stream events are:

-
    -
  • -

    "streamEvent": an event has just been reached.

    -
  • -
  • -

    "streamEventSkip": an event has been skipped over. This usually means -that a player seek operation resulted in the corresponds event being -“missed”.

    -
  • -
-

In any case, the corresponding event will be attached as a payload.

-

Example:

-
// listen to "streamEvent" events
-rxPlayer.addEventListener("streamEvent", (evt) => {
-  console.log("An event has been reached:", evt);
-});
-
-// listen to "streamEventSkip" events
-rxPlayer.addEventListener("streamEventSkip", (evt) => {
-  console.log("We just 'skipped' an event:", evt);
-});
-
-

-

The event format

-

Whether you’re listening to the "streamEvent" or the "streamEventSkip" -event, you will receive an object containing the corresponding event -information.

-

Here is an example of such events:

-
{
-  start: 10, // start time of the event, in seconds.
-             //
-             // It is always defined, as a number.
-             //
-             // A start at `10` here means that the event began when the player
-             // reached the position at 10 seconds.
-
-  end: 25, // Optional end time of the event, in seconds.
-           //
-           // It can be undefined or unset for events without any duration.
-           // A end at `25` here indicates that this event only last from the
-           // position at 10 seconds (the `start`) to the position at 25
-           // seconds, or an event with a duration of 15 seconds.
-           //
-           // If `end` is defined, you can be notified when the end of this
-           // event is reached by adding an `onExit` callback to that event
-           // (continue reading this tutorial for more information).
-
-  data: { // The event's data itself.
-
-    type: EVENT_TYPE, // String describing the source of the event.
-
-    value: EVENT_VALUE, // This property's format and content depends on the
-                        // `type` property. For example, when the type property
-                        // is set to "dash-event-stream", this value will be the
-                        // <Event /> element corresponding to that DASH event.
-  }
-}
-
-

As written in this example, the underlying format of the event itself will -depend on the source of the event. For example, an event generated from a DASH’s -<EventStream /> won’t be in the same format that an event generated from a -MP4’s emsg box.

-

You can know which current format is used by checking the value of the -data.type property.

-

For now, we only have one format: DASH EventStream elements, which will have a -data.type property equal to "dash-event-stream".

-

-

DASH EventStream elements

-

A DASH EventStream’s event will be parsed under the following format:

-
{
-  start: 10, // As usual, the event start time in seconds
-
-  end: 15, // optional end position of the event, in seconds.
-           // Can be not set or set to `undefined` for events without a duration
-
-  data: {
-
-    type: "dash-event-stream", // Type corresponding to a DASH's EventStream's
-                               // Event element
-
-    value: {
-      schemeIdUri: SCHEME_ID_URI,
-      element: EVENT_ELEMENT,
-      timescale: EVENT_TIMESCALE,
-    }
-  }
-}
-
-

Where:

-
    -
  • -

    SCHEME_ID_URI will be the value of the corresponding EventStream’s -schemeIdUri attribute

    -
  • -
  • -

    EVENT_ELEMENT will be the corresponding <Event /> element in the MPD.

    -
  • -
  • -

    EVENT_TIMESCALE will be the value of the corresponding EventStream’s -timescale attribute. -This indicates a way to convert some time information on an -EVENT_ELEMENT into seconds (by dividing the value by timescale), -though it can usually safely be ignored.

    -
  • -
-

For example for the following EventStream:

-
<EventStream schemeIdUri="urn:uuid:XYZY" timescale="1000" value="call">
-  <Event presentationTime="0" duration="10000" id="0">1 800 10101010</Event>
-  <Event presentationTime="40000" duration="10000" id="1">1 800 10101012</Event>
-  <Event presentationTime="60000" duration="10000" id="2">1 800 10101013</Event>
-</EventStream>
-
-

The RxPlayer will define those three events (note: I used custom syntax here to -include a readable document format):

-
// The first event:
-{
-  start: 0,
-  end: 10,
-  data: {
-    type: "dash-event-stream",
-    value: {
-      schemeIdUri: "urn::uuid::XYZY",
-      element: <Event presentationTime="0" duration="10000" id="0">
-                 1 800 10101010
-               </Event>,
-      timescale: 1000,
-    }
-  }
-}
-
-// The second event:
-{
-  start: 40,
-  end: 50,
-  data: {
-    type: "dash-event-stream",
-    value: {
-      schemeIdUri: "urn::uuid::XYZY",
-      element: <Event presentationTime="40000" duration="10000" id="1">
-                 1 800 10101012
-               </Event>,
-      timescale: 1000,
-    }
-  }
-}
-
-// The third event:
-{
-  start: 60,
-  end: 70,
-  data: {
-    type: "dash-event-stream",
-    value: {
-      schemeIdUri: "urn::uuid::XYZY",
-      element: <Event presentationTime="60000" duration="10000" id="2">
-                 1 800 10101013
-               </Event>,
-      timescale: 1000,
-    }
-  }
-}
-
-

-

Listening when an event has ended

-

Some stream events have a end property, you could thus need to know when an -event that the RxPlayer reached is now ended.

-

Thankfully, we planned this need in the API of the RxPlayer.

-

Any event with a set end can be added an onExit callback. This callback will -be called once the event has ended.

-

So for example you can write:

-
rxPlayer.addEventListener("streamEvent", (evt) => {
-  console.log("An event has been reached:", evt);
-  if (evt.end !== undefined) {
-    evt.onExit = () => {
-      console.log("An event has been exited:", evt);
-    }  ;
-  }
-});
-
-

When defined, that onExit callback will be called once the RxPlayer either -reaches the end position of the event or seek outside of the scope of this -event.

-

Please note however that even if an event has an end property, it is possible -that the onExit callback will never be called. For example, the user could -stop the content while an event was “active” (we do not trigger onExit -callbacks in that case) or the corresponding <Event /> could “disappear” from -the MPD once it has been refreshed.

-

-

Example

-

To end this tutorial, lets define a complete example:

-
rxPlayer.addEventListener("streamEvent", (evt) => {
-  console.log("An event has been reached:", evt);
-
-  console.log("This is an event of type:", evt.data.type)
-  if (evt.data.type === "dash-event-stream") {
-    console.log("This is a DASH EventStream's Event element.");
-
-    console.log("schemeIdUri:", evt.data.schemeIdUri);
-    console.log("<Event /> element:", evt.data.element);
-  }
-
-  if (evt.end !== undefined) {
-    evt.onExit = () => {
-      console.log("An event has been exited:", evt);
-    };
-  }
-});
-
-rxPlayer.addEventListener("streamEventSkip", (evt) => {
-  console.log("We just 'skipped' an event:", evt);
-
-  console.log("This was an event of type:", evt.data.type)
-  // ...
-});
-
-
\ No newline at end of file diff --git a/doc/generated/pages/tutorials/track_selection.html b/doc/generated/pages/tutorials/track_selection.html deleted file mode 100644 index 7a29656eba..0000000000 --- a/doc/generated/pages/tutorials/track_selection.html +++ /dev/null @@ -1,583 +0,0 @@ -Tutorial: Selecting a track - RxPlayer Documentation

-

Tutorial: Selecting a track

-

-

The goal of this tutorial

-

The RxPlayer has an advanced API when it comes to track selection:

-
    -
  • -

    You can list the available audio, video and/or text tracks and chose one of -them

    -
  • -
  • -

    You can disable the current video and / or text track

    -
  • -
  • -

    You can also give to the RxPlayer a set of preferences so it can make the -best choice by itself without manually having to choose the right track -for every contents.

    -

    Those preferences can even be applied retro-actively (for example, to the -content currently being played), depending on your need.

    -
  • -
-

Because the RxPlayer declares multiple APIs to allow those different use cases, -the track selection API can seem intimidating and confusing at first.

-

This tutorial will help you understand what your options are, why you would use -an API instead of another one and how to use them.

-

-

What is a “track”?

-

We should first agree on what is a track, as a concept.

-

Let’s take for example an italian film presented to an english-speaking -audience.

-

For that film, let’s imagine those multiple “audio tracks”:

-
    -
  • one being the original audio track, in italian
  • -
  • one being a dub in the english language
  • -
  • another in english with accessibility features such as an audio description -of what visually happens in the film (for example, to give cues of what is -happening to the visually-impaired).
  • -
-

There also could be multiple “text tracks”:

-
    -
  • subtitles in english
  • -
  • closed-captions in english (for example, for the hearing impaired)
  • -
-

And we could even imagine multiple video tracks:

-
    -
  • one displaying the “regular” film
  • -
  • another displaying either the same film from a different camera angle (seems -far-fetched here but let’s just pretend we’re talking about some kind of -experimental film!)
  • -
-

All those will provide to the user a different way to offer the same film. They -even can technically be switched one independently of the other (though -restrictions on possible combinations can exist) to give a large number of -different experience for what is effectively the same content.

-

-

Listing the available tracks

-

-

Preamble

-

The RxPlayer does not “guess” the tracks available for a given content. -It usually finds every information about them in a specific file, called the -Manifest.

-

Thus, the list of available tracks will only be available once the RxPlayer has -loaded and parsed that Manifest. -Moreover, a Manifest can have several lists of available tracks depending on the -player’s position (for example, a live channel with multiple programs might have -different audio languages available for different programs).

-

This means both that the available tracks won’t generally be known just after a -loadVideo call and that it can then change at any time.

-

Thankfully, most of this complexity is abstracted by the RxPlayer API.

-

-

Using methods

-

Once the RxPlayer has loaded the content (meaning the RxPlayer is not in the -STOPPED, LOADING or RELOADING player state) you can -begin to ask it what is the current list of available tracks.

-

This can be done through three RxPlayer methods:

- -

Those methods will all return arrays of objects, each object containing -information about a single track.

-

It should be noted that the information for an audio track won’t be the same -than for a video or a text track. -For example, you might be interested by the height and width available in a -video track. Those notions make absolutely no sense for an audio track.

-

For more information about the structure of the data returned by those methods, -you can refer to their API documentation (a shortcut is available by clicking -on the method name).

-

Note that you can still ask for the current tracks when the RxPlayer does not -have loaded any content (is in the STOPPED, LOADING or RELOADING player -state), but you will most likely only get an empty array in those cases.

-

Examples

-

Those methods are straightforward, here are some examples of how they can be -used:

-
// Array of all available audio languages
-const availableLanguages = rxPlayer.getAvailableAudioTracks()
-  .map(track => track.language);
-
-// List of audio tracks containing an audio description of what is visually
-// happening
-const audioDescriptionTracks = rxPlayer.getAvailableAudioTracks()
-  .filter(track => track.audioDescription);
-
-// List of video tracks for which a profile with a 1080p resolution is available
-const highResVideoTracks = rxPlayer.getAvailableVideoTracks()
-  .filter(track => {
-    return track.representations
-      .some(representation => representation.height !== undefined &&
-                              representation.height >= 1080);
-  });
-
-// List of text tracks available in french
-const frenchTextTracks = rxPlayer.getAvailableTextTracks()
-  .filter(track => track.normalized === "fra");
-
-

-

Using events

-

If you want to have the list of available tracks as soon as possible, it might -be a good idea to rely on the related events.

-

Here are the three events you will need to know:

- -

All of those events will have the corresponding available tracks as a payload, -which will be the exact same data that what you would get when calling the -corresponding getAvailable...Tracks method at this point.

-

Note that no available...TracksChange event will be sent when the RxPlayer -stops the content or temporarly goes through the RELOADING player state, -despite the fact that in those cases there is no available tracks to choose -from.

-

Still, calling the getAvailable...Tracks methods in those cases will return -an empty array (as it should). This has to be considered.

-

Examples

-

Like any RxPlayer event, you will need to add an event listener for those:

-
let currentAudioTracks = [];
-let currentVideoTracks = [];
-let currentTextTracks = [];
-
-rxPlayer.addEventListener("availableAudioTracksChange", audioTracks => {
-  console.log("New audio tracks:", audioTracks);
-  currentAudioTracks = audioTracks;
-})
-
-rxPlayer.addEventListener("availableVideoTracksChange", videoTracks => {
-  console.log("New video tracks:", videoTracks);
-  currentVideoTracks = videoTracks;
-})
-
-rxPlayer.addEventListener("availableTextTracksChange", textTracks => {
-  console.log("New text tracks:", textTracks);
-  currentTextTracks = textTracks;
-})
-
-

-

Should you use the methods or events?

-

Both the exposed methods and events return the same data.

-

Whether you should rely on the former or on the latter will depend on what -corresponds the most to your codebase:

-
    -
  • -

    if you want to fetch that list at a given point in time - such as when the -user clicks on a button - it can be easier to just call the methods.

    -
  • -
  • -

    if you want to know that list as soon as available and perform an action -right after (such as selecting a track, displaying this list…), you might -prefer relying on the events.

    -

    Here you will also have to re-set that list yourself when the player has no -content loaded anymore (in the STOPPED, LOADING or RELOADING player -state).

    -
  • -
-

-

Knowing the current track

-

You might also want to know which track is the one currently selected. -There are several ways to do that.

-

-

Through methods

-

The RxPlayer has a set of methods that just return the currently active tracks:

-
    -
  • -

    getAudioTrack: return information -on the current audio track

    -
  • -
  • -

    getVideoTrack: return information -on the current video track

    -
  • -
  • -

    getTextTrack: return information -on the current text track

    -
  • -
-

Those methods will return an object describing the attributes of the current -tracks. -They can also return null if no track has been enabled (for example, the user -could have wanted to disable all text tracks) and undefined if the track is -either unknown (which is a very rare occurence) or if no content is currently -playing.

-

Like the getAvailable...Tracks methods, the format of the objects returned -will entirely depend on which method you call. You can refer to the API -documentation to get more information on this.

-

Also like the getAvailable...Tracks methods, the current text track will -usually only be known once the RxPlayer has loaded a content (which means we are -not in the STOPPED, LOADING or RELOADING player -state). If no content is loaded, those APIs will just return -undefined.

-

Examples

-

Here is an example on how you could use them:

-
const currentTextTrack = rxPlayer.getTextTrack();
-if (currentTextTrack === null) {
-  console.log("No text track is enabled");
-} else if (currentTextTrack === undefined) {
-  console.log("We don't know the current text track. " +
-              "Are you sure a content is loaded?");
-} else {
-  const language = currentTextTrack.language;
-  console.log("We have a current text track in the " + language + "language");
-}
-
-

-

Through events

-

Exactly like you would obtain the list of available tracks through the -available...TracksChange events, you can know when the current track change as -soon as possible through the following events:

- -

Those events just emit the current track information as soon as it changes, in -the same format that the get...Track methods.

-

Unlike for the get...Track methods however, its payload cannot be set to -undefined: you won’t receive any ...TracksChange event if the track is -unknown or if there is no content.

-

This also means that you won’t have any event when the RxPlayer stops or -re-load the current content, despite the fact that you don’t have any current -track in that case. -Calling the get...Track method in those cases will return undefined, as it -should. This has to be considered.

-

Example

-

Like for any events, you will have to register an event listener:

-
rxPlayer.addEventListener("textTrackChange", track => {
-  if (track === null) {
-    console.log("No text track is active");
-  } else {
-    console.log("new active text track in the following language: " + track.language);
-  }
-});
-
-

-

Through the list of available tracks

-

As written earlier the available...TracksChange events and the -getAvailable...Tracks methods both return arrays of objects, each object -defining a single track.

-

In each of those object, you will find an active boolean property, which will -be set to true if the track is the currently chosen one and false otherwise.

-

Note that it’s possible that none of the available tracks are active. This is -for example the case when the track has been disabled (for example when the user -wants no text tracks at all).

-
// get the active audio track through `getAvailableAudioTracks`
-const activeAudioTrack1 = rxPlayer.getAvailableAudioTracks()
-  .find(track => track.active);
-
-// get the active audio track through `availableAudioTracksChange`
-let activeAudioTrack2;
-rxPlayer.addEventListener("availableAudioTracksChange", (tracks) => {
-  activeAudioTrack2 = tracks.find(track => track.active);
-});
-
-

-

Which one to use?

-

As usual here, this is highly dependant on your application. All of those APIs -give the same information through different means.

-

Accessing with the get...Track method is simple to use, the events allow to -know at the earliest possible time and relying on the list of available tracks -can simplify your code if you want both of them.

-

-

Selecting a track

-

Now that we have the list of available tracks and the current one, we might want -to choose another one, or let the final user choose another one.

-

To do that, you will have to use one of those three RxPlayer methods:

- -

Each of those methods take a single string as argument. That string should be -the value of the id property of the chosen track.

-

For example, to choose the first audio track with an audio description, you can -do:

-
const firstAudioTrackWithAD = rxPlayer.getAvailableAudioTracks()
-  .find(track => track.audioDescription);
-
-if (firstAudioTrackWithAD !== undefined) {
-  rxPlayer.setAudioTrack(firstAudioTrackWithAD.id);
-}
-
-

It’s important to consider that those APIs only allow to change the current -track and will have no impact on the other contents you will encounter in the -future.

-

Depending on your application, you might also want to set a global preference at -some point, such as saying that the final user will prefer english audio -tracks for now on.

-

Although setAudioTrack can be used for this use case - by just setting an -english audio track every times the available audio tracks list change (we can -know that through the availableAudioTracksChange event) - it is much more -efficient and less cumbersome to use audio track preference APIs for that. -Those will be described later in this tutorial, so stay with me!

-

After manually setting a track through the set...Track methods, you will -receive the corresponding ...TrackChange event when the change is applied.

-

Note that on some contents, changing a track from a given type might -automatically also change the current track for another types. For example, -switching to another audio language might also automatically turn on the -subtitles. This is because some streaming protocols might “force” some -combination.

-

To detect those cases, you can either listen to every ...TrackChange events -or call the corresponding get...Track method everytime you want to use them.

-

-

Disabling a track

-

Now what if you want no track at all?

-

This is for example a frequent need for text tracks, where you might prefer to -have no subtitles or closed captions appearing on the screen.

-

You could also want to disable the video track, which is a trick often used to -reduce the network bandwidth used by a content.

-

You can disable respectively the current text track and the current video track -by calling those methods:

- -

However, like for selecting a track, this only concerns the current content -being played. When playing a new content or even when just switching to another -part of the content with a different track list, you might need to re-do the -same method call.

-

This is problematic most-of-all when disabling the video track, as going in and -out of that usually requires a short but visible “re-loading” step by the -RxPlayer. You want thus to limit the need to call disableVideoTrack every -times a new content is encountered.

-

Thankfully, the RxPlayer has another set of API to let you choose a track even -for future contents: the “track preferences APIs”.

-

-

Track preferences APIs

-

All methods and events discussed until now only have an effect for the current -content being played.

-

This has multiple disadvantages:

-
    -
  • -

    that code has to be run each time a new content is loaded (and each time the -track list changes, if there are multiple track lists for a single -contents).

    -
  • -
  • -

    it is inefficient: -In some cases the RxPlayer pre-load new content to allow a smooth transition -between the current content and that new one. -To do that, it chooses a track itself and begin to download it.

    -

    If when reaching the new content a totally other track is finally chosen, -we might have wasted network bandwidth for nothing as we would have to -re-download a completely different track.

    -

    Even more important, the transition won’t be smooth at all because we -will have to stop to build some buffer with the wanted track instead.

    -
  • -
-

Thankfully, there exists another set of APIs we call the “track preferences”.

-

With those, you can tell the RxPlayer that you might always prefer the audio -track to be in english - for example - or that you would prefer the video track -to be in a given codec.

-

Bear in mind that track preferences APIs are for a different use case than the -classic track selection APIs:

-
    -
  • -

    the “classic” track selection APIs are here to select a precize track -amongst available ones.

    -

    This is probably the APIs you will use when displaying a list of available -tracks to the final user and choosing one.

    -
  • -
  • -

    the track preferences APIs give hints of what the finally user generally -wants, so that the right track is automatically chosen by the RxPlayer. It -is also useful for optimizations such as when pre-loading the next content.

    -

    This is the APIs you will use in most other use cases, where you want to -give the general track settings the user wants to the RxPlayer.

    -
  • -
-

The track preferences can be set in two manners:

-
    -
  1. During instanciation of the RxPlayer
  2. -
  3. At any time, through specific methods
  4. -
-

-

Setting a track preference on instanciation

-

There are three options you can give to the RxPlayer on instanciation to set the -track preferences:

- -

You can click on the name of the option to be redirected to its corresponding -API documentation.

-

Each of those take an array of object which will define which track you want the -RxPlayer to choose by default.

-

As a simple example, to choose french audio tracks without audio description by -default you could do:

-
const rxPlayer = new RxPlayer({
-  preferredAudioTracks: [{ language: "fra", audioDescription: false }],
-});
-
-

Because not all contents could have a track matching that preferences, you can -add even more elements in that array. For example, if you want to fallback to -english if no french audio track is found you can do:

-
const rxPlayer = new RxPlayer({
-  preferredAudioTracks: [
-    { language: "fra", audioDescription: false },
-    { language: "eng", audioDescription: false },
-  ],
-});
-
-

Here, the RxPlayer will enable a french audio track if it finds one, but if it -does not, it will enable the english one instead.

-

If none of your preferences is found for a given content, the RxPlayer will -choose the content’s default (or first, if no default is announced in the -content) track itself.

-

Those options allow much more powerful configurations. You can refer to the API -documentation for that.

-

-

track preferences methods

-

You can also update at any time those track preferences - even when no content -is playing - by calling the following methods: -- setPreferredAudioTracks: -update the audio preferences -- setPreferredTextTracks -update the text preferences -- setPreferredVideoTracks -update the video preferences

-

Those methods mostly work the same way than the constructor options. You give -them an array of the wanted track configurations and the RxPlayer will try to -choose a track that match with the earliest possible configuration in that -array:

-
rxPlayer.setPreferredAudioTracks([
-  { language: "fra", audioDescription: false },
-  { language: "eng", audioDescription: false },
-]);
-
-

But there’s another element to consider here. -When calling the method (unlike when giving an option to the constructor), the -RxPlayer may already be playing a content. So here, there’s a dilemma:

-
    -
  • -

    should the RxPlayer apply the new preferences to the current content? It -could, but it might be unexpected if a track chosen explicitely by the user -for the current content changes because it does not match the preferences.

    -
  • -
  • -

    or should the RxPlayer only apply it to new contents? In that case, it could -also be an unexpected behavior. -Especially for contents with multiple track lists - here you could inversely -want your new preferences to be considered when seeking back to an -already-played content.

    -
  • -
-

There’s no good answer here, it all depends on the implementation you want to -do.

-

Because of that, those methods all can take a boolean as a second argument. -When this second argument is set to true, the RxPlayer will also apply that -preference to the already-loaded content:

-
// disable the text tracks from every contents - the current one included
-rxPlayer.setPreferredTextTracks([null], true);
-
-

If not set or set to false, it will only be applied for content that have not -been loaded yet.

-
// Only disable the text tracks from the next encountered contents.
-rxPlayer.setPreferredTextTracks([null]);
-
-

-

Obtaining the last set preferences

-

The RxPlayer also has three methods which will return the last set preferences:

- -

The format of the returned array will be the exact same than the array given to -the corresponding setPreferred...Tracks method (or the value of the -preferred...Tracks constructor option if the method was never called - or -just an empty array by default when neither was used).

-

-

What set of APIs should you use

-

The “classic” track selection APIs (getAvailable...Tracks, get...Track and -set...Track) are the APIs you should use when explicitely exposing the current -available tracks and selecting one precizely.

-

The track preferences APIs should be used for anything else.

-

This is because the track preferences APIs allow to completely move the task -of selecting a track out of your code and into the RxPlayer and will allow -some optimizations to take place.

-

The “classic” track selection APIs still allow to make a much more precize -choice and allow to know which tracks are currently available. -Due to that, they are a perfect fit when you want to propose a track choice menu -to the final user.

-

-

Notes about the “textTrackMode” option

-

This tutorial was focused on track selection but there’s still a last point I -want to approach, which is how subtitles will be displayed to the user.

-

By default, text tracks will be displayed through <tracks> elements which -will be contained in the media element where the content plays. -This allows to display subtitles but may not be sufficient when wanting to -display richer subtitles (such as closed-captions).

-

This is why the RxPlayer has a -textTrackMode concept.

-

By setting the textTrackMode to "html" in a -loadVideo call, you will be able to profit -from much richer subtitles than what you could have by default. -If you do that, you also need to set the -textTrackElement property -to an HTML element, that the RxPlayer will use to display subtitles into.

-

More information on those options can be found in the RxPlayer API.

-
\ No newline at end of file diff --git a/doc/generated/pages/v2_to_v3.html b/doc/generated/pages/v2_to_v3.html deleted file mode 100644 index 1befa6fde0..0000000000 --- a/doc/generated/pages/v2_to_v3.html +++ /dev/null @@ -1,1259 +0,0 @@ -Switching from version 2.x.x to 3.x.x - RxPlayer Documentation

-

Switching from version 2.x.x to 3.x.x

-

The 3.0.0 release brought multiple breaking changes that may impact your -codebase if you were based on a 2.x.x version (or inferior) previously.

-

Those breaking changes are mainly here to bring new features and simplify the -player maintenance. This file enumerates each one of those changes and propose -alternatives.

-

The simplest way of switching here would be to:

-
    -
  1. Check the General changes chapter
  2. -
  3. Check the constructor options you use (constructor options chapter)
  4. -
  5. Check the way you use the loadVideo method (loadVideo chapter)
  6. -
  7. Replace every method listed in the Removed methods chapter you use in -your codebase
  8. -
  9. Make sure that the methods listed in the Changed methods chapter are -correctly used now
  10. -
  11. Replace events listed in Removed events
  12. -
  13. Check events you use listed in Changed events
  14. -
-

If you were only using documented APIs and you follow this, you’ll be ready to -completely switch to a 3.x.x release !

-

If you don’t know if you were using documented APIs, you can still check if the -options, methods and events you use now are documented in the new -API. Now, most non-documented (private) APIs begin by the -string _priv_, to simplify this process.

-

-

-

General Changes

-

-

-

Features disabled by default

-

What Changed

-

Two features, previously activated by default, are now disabled by default.

-

Those features are:

-
    -
  1. The automatic limitation of the video track to filter those with a width -superior to the current video element’s width.
  2. -
  3. The automatic throttle on the audio and video bitrates set when the page is -hidden for more than one minute.
  4. -
-

If you want to activate the feature 1, you have to set the limitVideoWidth -boolean to true in the constructor’s option. For the feature 2, it is the -throttleWhenHidden constructor’s option you will have to set to true.

-

If you had set them to false to disable them before, you can now safely -remove those options from the constructor argument.

-

If you don’t know what to do with them, you might want to disable both features -(by not setting them on the constructor). They only are optimizations for -specific usecases.

-

Examples

-
// In the previous version
-player = new RxPlayer();
-
-// becomes
-player = new RxPlayer({
-  limitVideoWidth: true,
-  throttleWhenHidden: true
-});
-
-
// In the previous version
-player = new RxPlayer({
-  limitVideoWidth: false,
-  throttleWhenHidden: false
-});
-
-// becomes
-player = new RxPlayer();
-
-

-

-

Normalized language codes

-

What Changed

-

Previously, every language set in the manifest went through a translation step -to be translated into an ISO 639-2 language code.

-

This led the following APIs:

-
    -
  • getAvailableAudioTracks
  • -
  • getAvailableTextTracks
  • -
  • getAudioTrack
  • -
  • getTextTrack
  • -
  • getManifest
  • -
  • getCurrentAdaptations
  • -
-

To not reflect exactly the language as set in the manifest (just one of the ISO -639-2 translation of it). For example, "fra" was translated to "fre" -(even though both are valid ISO 639-2 language codes for the same language).

-

Because this behavior hide the true language value and ISO 639-2 language codes -have synonyms, we decided to:

-
    -
  1. switch to ISO 639-3 language codes instead. This standard has more -languages and does not have synonyms.
  2. -
  3. keep both the information of what is set in the manifest and the result of -our ISO 639-3 translation in two different properties
  4. -
-

Now, the tracks returned by:

-
    -
  • getAvailableAudioTracks
  • -
  • getAvailableTextTracks
  • -
  • getAudioTrack
  • -
  • getTextTrack
  • -
-

Will:

-
    -
  1. keep the language property, though this time it is the exact same one -than set in the manifest
  2. -
  3. will also have a normalized property, which is the ISO 639-3 -translation attempt. If the translation attempt fails (no corresponding ISO -639-3 language code is found), normalized will equal the value of -language.
  4. -
-

Likewise for the adaptations with a language set returned by:

-
    -
  • getManifest
  • -
  • getCurrentAdaptations
  • -
-

They will have both a language and a normalizedLanguage property, which -follow the same rule.

-

Difference between the previous and new language codes used

-

In most cases, if you were manually checking language codes in your codebase you -could just replace here the key language with its normalized counterpart -(either normalized or normalizedLanguage depending on the API you’re -using, see previous chapter).

-

However, while switching from ISO 639-2 to ISO 639-3, some language codes have -changed (all were synonyms in ISO 639-2):

-
    -
  • "alb" became "sqi" (for Albanian)
  • -
  • "arm" became "hye" (for Armenian)
  • -
  • "baq" became "eus" (for Basque)
  • -
  • "bur" became "mya" (for Burmese)
  • -
  • "chi" became "zho" (for Chinese)
  • -
  • "dut" became "nld" (for Dutch, Flemish)
  • -
  • "fre" became "fra" (for French)
  • -
  • "geo" became "kat" (for Georgian)
  • -
  • "ice" became "isl" (for Icelandic)
  • -
  • "mac" became "mkd" (for Macedonian)
  • -
  • "mao" became "mri" (for Maori)
  • -
  • "may" became "msa" (for Malay)
  • -
-

Example

-
console.log(player.getAvailableAudioTrack());
-
-// For a manifest with two audiotracks: "fr" and "en" without audio description
-
-// -- in the old version --:
-const oldVersionResult = [
-  {
-    language: "fre", // translated from "fr"
-    audioDescription: false,
-    id: "audio_1"
-  },
-  {
-    language: "eng", // translated from "en"
-    audioDescription: false,
-    id: "audio_2"
-  }
-];
-
-// -- became --:
-const result = [
-  {
-    language: "fr", // stays the same than in the manifest
-    normalized: "fra", // translated from "fr"
-                       // (notice that it's not "fre" like before)
-    audioDescription: false,
-    id: "audio_1"
-  },
-  {
-    language: "en", // stays the same than in the manifest
-    normalized: "eng", // translated from "en"
-    audioDescription: false,
-    id: "audio_2"
-  }
-];
-
-

-

-

Constructor options

-

-

-

defaultLanguage

-

What changed

-

This option has been removed from the constructor to simplify the API. Now you -have to set the wanted transport per-loadVideo calls via its -defaultAudioTrack option.

-

Examples

-

Without audio description:

-
// In the previous version
-player = new RxPlayer({
-  defaultLanguage: "en"
-});
-
-// becomes
-player = new RxPlayer();
-player.loadVideo({
-  defaultAudioTrack: {
-    language: "en"
-  },
-  // ...
-});
-
-

With audio description:

-
player = new RxPlayer();
-player.loadVideo({
-  defaultAudioTrack: {
-    language: "en",
-    audioDescription: true
-  },
-  // ...
-});
-
-

-

-

defaultSubtitle

-

What changed

-

This option has been removed from the constructor to simplify the API. Now you -have to set the wanted transport per-loadVideo calls via its -defaultTextTrack option.

-

Examples

-

Without closed caption:

-
// In the previous version
-player = new RxPlayer({
-  defaultSubtitle: "en"
-});
-
-// becomes
-player = new RxPlayer();
-player.loadVideo({
-  defaultTextTrack: {
-    language: "en"
-  },
-  // ...
-});
-
-

With closed caption:

-
player = new RxPlayer();
-player.loadVideo({
-  defaultTextTrack: {
-    language: "en",
-    closedCaption: true
-  },
-  // ...
-});
-
-

-

-

initVideoBitrate / initAudioBitrate

-

What changed

-

Those options just changed their name:

-
    -
  • initVideoBitrate becomes initialVideoBitrate
  • -
  • initAudioBitrate becomes initialAudioBitrate
  • -
-

This is to mainly to add clarity to the API.

-

Examples

-
// In the previous version
-player = new RxPlayer({
-  initVideoBitrate: 1e6,
-  initAudioBitrateBitrate: 2e4
-});
-
-// becomes
-player = new RxPlayer({
-  initialVideoBitrate: 1e6,
-  initialAudioBitrateBitrate: 2e4
-});
-
-

-

-

defaultAudioTrack

-

What changed

-

This option has been removed from the constructor to simplify the API. Now you -have to set the wanted transport per-loadVideo calls via its -defaultAudioTrack option, which has the exact same format.

-

-

-

defaultTextTrack

-

What changed

-

This option has been removed from the constructor to simplify the API. Now you -have to set the wanted transport per-loadVideo calls via its -defaultTextTrack option, which has the exact same format.

-

-

-

transport

-

What changed

-

This option has been removed from the constructor to simplify the API. Now you -have to set the wanted transport per-loadVideo calls via its transport -option, which has the exact same format.

-

-

-

transportOptions

-

What changed

-

This option has been removed from the constructor to simplify the API. Now you -have to set the wanted transport options per-loadVideo calls via its -transportOptions option, which has the exact same format.

-

-

-

loadVideo

-

loadVideo is the central method of the RxPlayer and changed enough to earn -its own chapter.

-

Both parameters and the return value changed.

-

-

-

Return value

-

What changed

-

loadVideo does not return anything anymore.

-

Replacement examples

-

If you want to know when the player is on error, you will have to listen to the -error events:

-
player.addEventListener("error", (error) => {
-  console.log("content on error");
-});
-
-

If you want to know when the content is loaded, you will have to listen to when -the playerStateChange events:

-
player.addEventListener("playerStateChange", (state) => {
-  switch (state) {
-    case "LOADING":
-      console.log("the content is loading");
-      break;
-    case "LOADED":
-      console.log("the content has loaded");
-      break;
-    case "PLAYING":
-      console.log("the content is now playing");
-      break;
-  }
-});
-
-

Bear in mind however that both are triggered when ANY content you choosed to -play are loaded/on error, not just the last one.

-

-

-

defaultLanguage parameter

-

What changed

-

defaultLanguage is replaced by the defaultAudioTrack option, which -supports audio description.

-

Replacement example

-

Without audio description:

-
// In the previous version
-player.loadVideo({
-  url: someURL,
-  defaultLanguage: "en"
-});
-
-// becomes
-player.loadVideo({
-  url: someURL,
-  defaultAudioTrack: {
-    language: "en"
-  }
-});
-
-

With audio description:

-
player.loadVideo({
-  url: someURL,
-  defaultAudioTrack: {
-    language: "en",
-    audioDescription: true
-  }
-});
-
-

-

-

defaultSubtitle parameter

-

What changed

-

defaultSubtitle is replaced by the defaultTextTrack option, which -supports closed caption.

-

Replacement example

-

Without closed caption:

-
// In the previous version
-player.loadVideo({
-  url: someURL,
-  defaultSubtitle: "en"
-});
-
-// becomes
-player.loadVideo({
-  url: someURL,
-  defaultTextTrack: {
-    language: "en"
-  }
-});
-
-

With closed caption:

-
player.loadVideo({
-  url: someURL,
-  defaultTextTrack: {
-    language: "en",
-    closedCaption: true
-  }
-});
-
-

-

-

images parameter

-

What changed

-

images is renamed as supplementaryImageTracks for clarity.

-

Replacement example

-
// In the previous version
-player.loadVideo({
-  url: someURL,
-  images: {
-    mimeType: "application/bif",
-    url: "",
-  },
-});
-
-// becomes
-player.loadVideo({
-  url: someURL,
-  supplementaryImageTracks: {
-    mimeType: "application/bif",
-    url: "",
-  },
-});
-
-

-

-

subtitles parameter

-

What changed

-

You have two possibilities. Either:

-
    -
  1. Use the exernal TextTrackRenderer tool, documented -here. This is the preferred way.
  2. -
  3. Replace subtitles by supplementaryTextTracks. Please note -however that supplementaryTextTracks is a deprecated feature.
  4. -
-

Replacement example

-

If you go under the supplementaryTextTracks route:

-
// In the previous version
-player.loadVideo({
-  url: someURL,
-  subtitles: {
-    mimeType: "application/x-sami",
-    url: "",
-  },
-});
-
-// becomes
-player.loadVideo({
-  url: someURL,
-  supplementaryTextTracks: {
-    mimeType: "application/x-sami",
-    url: "",
-  },
-});
-
-

If you prefer to use the TextTrackRenderer instead, I invite you to directly -read, its documentation, as the API is completely -different there.

-

-

-

timeFragment parameter

-

What changed

-

The timeFragment parameter has been completely removed.

-

If you want to start at a precize point in the content, you can use the -startAt parameter instead, documented -here.

-

If you want to end at a precize point in the content, this has not been -re-implemented as I do not know for now any usecase for that. Please open an -issue if you need that feature.

- - -### manifests parameter ######################################################## -

What changed

-

The manifests parameter has been completely removed. Its behavior can easily -be replaced by two existing options: url and keySystems:

-
    -
  • -

    The url of the first object in the manifests array should be put in the -url parameter

    -
  • -
  • -

    Each keySystem property defined in the manifests array should be put -in the keySystems array, in the same order

    -
  • -
-

Doing this should lead to the exact same behavior.

-

Replacement example

-
// In the previous version
-player.loadVideo({
-  manifests: [
-    {
-      url: someURL1
-      keySystem: keySystem1
-    },
-    {
-      url: someURL2
-    },
-    {
-      url: someURL3
-      keySystem: keySystem3
-    },
-    {
-      url: someURL4
-      keySystem: keySystem4
-    }
-  ],
-});
-
-// becomes
-player.loadVideo({
-  url: someURL1,
-  keySystems: [
-    keySystem1,
-    keySystem3,
-    keySystem4
-  ],
-});
-
-

-

-

Removed methods

-

-

-

getVideoMaxBitrate / getAudioMaxBitrate / setVideoMaxBitrate / setAudioMaxBitrate

-

What changed

-

Those methods just changed their name to have a more coherent API:

-
    -
  • setVideoMaxBitrate becomes setMaxVideoBitrate
  • -
  • setAudioMaxBitrate becomes setMaxAudioBitrate
  • -
  • getVideoMaxBitrate becomes getMaxVideoBitrate
  • -
  • getAudioMaxBitrate becomes getMaxAudioBitrate
  • -
-

This is mostly done to be aligned with the maxVideoBitrate and -maxAudioBitrate constructor options.

-

Replacement examples

-
setVideoMaxBitrate
-
// In the previous version
-player.setVideoMaxBitrate(1500);
-
-// becomes
-player.setMaxVideoBitrate(1500);
-
-
setAudioMaxBitrate
-
// In the previous version
-player.setAudioMaxBitrate(999);
-
-// becomes
-player.setMaxAudioBitrate(999);
-
-
getVideoMaxBitrate
-
// In the previous version
-maxBitrate = player.getVideoMaxBitrate();
-
-// becomes
-maxBitrate = player.getMaxVideoBitrate();
-
-
getAudioMaxBitrate
-
// In the previous version
-maxBitrate = player.getAudioMaxBitrate();
-
-// becomes
-maxBitrate = player.getMaxAudioBitrate();
-
-

-

-

setVideoBufferSize / setAudioBufferSize / getVideoBufferSize / getAudioBufferSize

-

What changed

-

Those four methods were removed to be replaced with simpler generic -getWantedBufferAhead/setWantedBufferAhead methods. They also take -seconds in argument.

-

The only difference is that you cannot discriminate by type of buffer -(audio/video) anymore. This is for done for multiple reasons:

-
    -
  • -

    There are more than two types of buffers (for now there are four: audio, -video, text and image). Adding one methods per type could be cumbersome for -the user (for example, when wanting to set the limit for three or four of -them)

    -
  • -
  • -

    More buffer-related APIs were added which are type-agnostic. Adding one -A per-type would be heavy both for the rx-player and for the application -using it

    -
  • -
  • -

    It’s easier to explain through the documentation, for people that do not -want to understand the nitty-gritty of a player

    -
  • -
  • -

    We did not encounter any usecase for separate methods yet

    -
  • -
-

Replacement examples

-
setVideoBufferSize
-
// In the previous version
-player.setVideoBufferSize(15);
-
-// becomes (also affect audio, text and image buffer)
-player.setWantedBufferAhead(15);
-
-
setAudioBufferSize
-
// In the previous version
-player.setAudioBufferSize(10);
-
-// becomes (also affect video, text and image buffer)
-player.setWantedBufferAhead(10);
-
-
getVideoBufferSize
-
// In the previous version
-bufferSize = player.getVideoBufferSize();
-
-// becomes
-bufferSize = player.getWantedBufferAhead();
-
-
getAudioBufferSize
-
// In the previous version
-bufferSize = player.getAudioBufferSize();
-
-// becomes
-bufferSize = player.setWantedBufferAhead();
-
-

-

-

asObservable

-

What Changed

-

asObservable has been completely removed for the following reasons:

-
    -
  • -

    it exposed too much of the player. Guaranteeing compatibility between -versions was too hard.

    -
  • -
  • -

    it exposed the internal RxJS library, which we now stop to do for various -reasons.

    -
  • -
-

-

-

getAvailableLanguages

-

What Changed

-

This method now has been completely replaced by getAvailableAudioTracks -which adds audio description support. See the API -documentation for more infos.

-

Replacement example

-
// In the previous version
-audioTracks = player.getAvailableLanguages();
-
-if (audioTracks && audioTracks.length) {
-  console.log("audio languages:", ...audioTracks);
-} else {
-  console.log("no audio language");
-}
-
-// -------------------------------
-
-// becomes
-audioTracks = player.getAvailableAudioTracks();
-
-if (audioTracks && audioTracks.length) {
-  console.log("audio languages:", ...audioTracks.map(track => track.language));
-} else {
-  console.log("no audio language");
-}
-
-

-

-

getAvailableSubtitles

-

What Changed

-

This method now has been completely replaced by getAvailableTextTracks which -adds closed caption support. See the API documentation for -more infos.

-

Replacement example

-
// In the previous version
-subtitleTracks = player.getAvailableSubtitles();
-
-if (subtitleTracks && subtitleTracks.length) {
-  console.log("subtitle languages:", ...subtitleTracks);
-} else {
-  console.log("no subtitle language");
-}
-
-// -------------------------------
-
-// becomes
-subtitleTracks = player.getAvailableTextTracks();
-
-if (subtitleTracks && subtitleTracks.length) {
-  console.log("subtitle languages:",
-    ...subtitleTracks.map(track => track.language));
-} else {
-  console.log("no subtitle language");
-}
-
-

-

-

getAverageBitrates

-

What Changed

-

getAverageBitrates is deleted. It can normally be completely replaced by the -bitrateEstimationChange -event which can be -listened thanks to the addEventListener -method.

-

-

-

getCurrentTime

-

What Changed

-

getCurrentTime was separated in two methods:

-
    -
  • -

    getWallClockTime: returns the wall-clock-time of the current position in -seconds. -That is:

    -
      -
    • for live content, get a timestamp in seconds of the current position.
    • -
    • for static content, returns the position from beginning, also in -seconds.
    • -
    -

    This is the closest implementation of getCurrentTime. The only difference -being that for live contents, a timestamp will be returned (in seconds), not -a Date object

    -
  • -
  • -

    getPosition: returns the video element’s current position, in seconds. The -difference with getWallClockTime is that for live contents the position is -not re-calculated to match a live timestamp.

    -
  • -
-

If you do not know if you want to use getWallClockTime or getPosition:

-
    -
  • If what you want is to display the current time to the user, you will most -probably want to use getWallClockTime.
  • -
  • If what you want is to interact with the player’s API or perform other -actions with the real player data, use getPosition.
  • -
-

Replacement example

-
// In the previous version
-currentTime = player.getCurrentTime();
-
-if (currentTime instanceof Date) {
-  currentTime = currentTime.getTime() / 1000;
-}
-
-// -------------------------------
-
-// becomes
-currentTime = player.getWallClockTime();
-
-

-

-

getDebug / showDebug / hideDebug / toggleDebug

-

What Changed

-

Those will be removed from the API and won’t be replaced.

-

Those methods were used internally, but were exposed like regular APIs. -They have not much usage either as other APIs should be sufficient.

-

-

-

getEndTime

-

What Changed

-

getEndTime was removed from the API. Its role can be replaced by the new -getMaximumPosition API which will return the maximum position the user can -seek to.

-

Replacement example

-
// In the previous version
-endTime = player.getEndTime();
-
-// becomes
-endTime = player.getMaximumPosition();
-
-

-

-

static getErrorCodes

-

What Changed

-

This static method was updated to a static property ErrorCodes.

-

Replacement example

-
// In the previous version
-errorCodes = player.getErrorCodes();
-
-// becomes
-errorCodes = player.ErrorCodes;
-
-

-

-

static getErrorTypes

-

What Changed

-

This static method was updated to a static property ErrorTypes.

-

Replacement example

-
// In the previous version
-errorTypes = player.getErrorTypes();
-
-// becomes
-errorTypes = player.ErrorTypes;
-
-

-

-

getImageTrack

-

What Changed

-

getImageTrack is now replaced by both:

-
    -
  • -

    the imageTrackUpdate event (the closest to getImageTrack previous -behavior) triggered each time new image data is received with the complete -image data as a payload (all the image data from the current image -adaptation) in a data property.

    -
  • -
  • -

    the getImageTrackData method, which returns an array for all the -currently referenced image data for the seekable content.

    -
  • -
-

Replacement example

-
// In the previous version
-player.getImageTrack().subscribe(images => {
-  displaySomeImages(images);
-});
-
-// becomes
-player.addEventListener("imageTrackUpdate", ({ data }) => {
-  displaySomeImages(data);
-});
-
-

-

-

getLanguage

-

What Changed

-

getLanguage has been replaced by getAudioTrack which adds audio -description support.

-

Replacement example

-
// In the previous version
-track = player.getLanguage();
-
-if (track) {
-  console.log("audio language:", track);
-} else {
-  console.log("no audio language");
-}
-
-// ------------------------
-
-// becomes
-track = player.getAudioTrack();
-
-if (track) {
-  console.log("audio language:", track.language);
-} else {
-  console.log("no audio language");
-}
-
-

-

-

getMetrics

-

What Changed

-

getMetrics is removed from the API and is not replaced. This is due to the fact -that the ABR (adaptive bitrate) strategy completely changed, and re-implementing -this method is not straightforward.

-

-

-

getStartTime

-

What Changed

-

getStartTime was removed from the API. Its role can be replaced by the new -getMinimumPosition API which will return the minimum position the user can -seek to.

-

Replacement example

-
// In the previous version
-startTime = player.getStartTime();
-
-// becomes
-startTime = player.getMinimumPosition();
-
-

-

-

getSubtitle

-

What Changed

-

getSubtitle has been replaced by getTextTrack which adds closed caption -support.

-

Replacement example

-
// In the previous version
-track = player.getSubtitle();
-
-if (track) {
-  console.log("text language:", track);
-} else {
-  console.log("no text language");
-}
-
-// ------------------------
-
-// becomes
-track = player.getTextTrack();
-
-if (track) {
-  console.log("text language:", track.language);
-} else {
-  console.log("no text language");
-}
-
-

-

-

goToStart

-

What Changed

-

goToStart is removed from the API and not replaced. You might want to use -both getMinimumPosition and seekTo to seek to the earliest part of the -content.

-

Replacement example

-
// In the previous version
-player.goToStart();
-
-// becomes
-player.seekTo(player.getMinimumPosition());
-
-

-

-

isLanguageAvailable / isSubtitleAvailable

-

What Changed

-

Those methods are removed and not replaced. Use getAvailableAudioTracks / -getAvailableTextTracks instead.

-

Replacement examples

-
isLanguageAvailable
-
// In the previous version
-console.log(player.isLanguageAvailable("fr"));
-
-// becomes
-const tracks = player.getAvailableAudioTracks();
-console.log(!!tracks && tracks.some(({ language }) => language === "fr"));
-
-
isSubtitleAvailable
-
// In the previous version
-console.log(player.isSubtitleAvailable("fr"));
-
-// becomes
-const tracks = player.getAvailableTextTracks();
-console.log(!!tracks && tracks.some(({ language }) => language === "fr"));
-
-

-

-

normalizeLanguageCode

-

What Changed

-

normalizeLanguageCode is removed and not replaced. Switching audio and text -tracks is now id-based, so the language code has much less use than before.

-

-

-

setLanguage

-

What Changed

-

setLanguage has been replaced by setAudioTrack which adds audio -description support.

-

Replacement example

-
// In the previous version
-try {
-  player.setLanguage("fr");
-} catch(e) {
-  console.warn("no track found with this language");
-}
-
-// -------------------------
-
-// becomes
-track = player.getAvailableAudioTracks();
-const indexOf = tracks && tracks.indexOf(({ language }) => language === "fr");
-
-if (tracks && indexOf !== -1) {
-  player.setAudioTrack(tracks[indexOf].id);
-} else {
-  console.warn("no track found with this language");
-}
-
-

-

-

setSubtitle

-

What Changed

-

setSubtitle has been replaced by setTextTrack which adds closed caption -support.

-

Replacement example

-
// In the previous version
-try {
-  player.setSubtitle("fr");
-} catch(e) {
-  console.warn("no track found with this language");
-}
-
-// -------------------------
-
-// becomes
-track = player.getAvailableTextTracks();
-const indexOf = tracks && tracks.indexOf(({ language }) => language === "fr");
-
-if (tracks && indexOf !== -1) {
-  player.setTextTrack(tracks[indexOf].id);
-} else {
-  console.warn("no track found with this language");
-}
-
-

-

-

Changed methods

-

-

-

seekTo

-

What Changed

-

In the previous version, you could give directly a Number or Date object to -seekTo. What it would do with that depended on if the content was a live -content or not:

-
    -
  • -

    for live content, a time in milliseconds or a Date object was expected -corresponding to the WallClock time (timestamp of the live content)

    -
  • -
  • -

    for non-live content, the time in seconds was expected, which was the time -the video tag seek to.

    -
  • -
-

Now, you can only give a number or an Object to this function. If you give a -number, it will allways be the new time in seconds the video tag will seek to. -This call is documented here.

-

Replacement example

-

To copy the old behavior for live contents, you can set the wallClockTime -property:

-
// seeking at 30 minute before now on what is broadcasted live
-
-// In the previous version:
-player.seekTo(Date.now() - 30*60 * 1000);
-
-// becomes
-player.seekTo({ wallClockTime: Date.now() / 1000 - 30*60});
-
-

To copy the old behavior for non-live contents, nothing has changed:

-
// seek to the tenth second for a non live content
-
-// In the previous version:
-player.seekTo(10);
-
-// becomes
-player.seekTo(10);
-
-

-

-

setVideoBitrate / setAudioBitrate

-

What Changed

-

Previously, calling this method in the following situation threw an error:

-
    -
  • no content is playing
  • -
  • the set bitrate does not exist
  • -
-

Now, this call never throws:

-
    -
  • -

    if you call it while no content is playing, the limit is still set for the -next content played.

    -
  • -
  • -

    if the set bitrate does not exist on the current content, the value will -just act as a ceil (the chosen bitrate will be the one immediately -inferior). If still no bitrate is inferior to it, the lowest bitrate will be -chosen instead.

    -
  • -
-

-

-

getUrl

-

What Changed

-

Previously, calling this method when no content is playing threw an error.

-

Now, doing so will just return undefined.

-

-

-

isLive

-

What Changed

-

Previously, calling this method when no content is playing threw an error.

-

Now, doing so will just return false.

-

-

-

Removed events

-

-

-

currentTimeChange

-

What Changed

-

The currentTimeChange is replaced by the positionUpdate event.

-

It is similar to currentTimeChange but with the following properties -removed:

-
    -
  • buffered
  • -
  • paused
  • -
  • range
  • -
  • readyState
  • -
  • stalled
  • -
  • ts (replaced by position)
  • -
  • playback (replaced by playbackRate)
  • -
  • gap (replaced by bufferGap)
  • -
-

And with the following property updated:

-
    -
  • wallClockTime: will go from a Date object to the same indication in -seconds.
  • -
-

-

-

progress

-

What Changed

-

progress events are removed and not replaced. This is because it exposed to -much of our internal logic.

-

-

-

languageChange

-

What Changed

-

languageChange is replaced by the audioTrackChange event, which supports -audio description.

-

Replacement example

-
// In the previous version
-player.addEventListener("languageChange", (lang) => {
-  console.log("language changed to", lang);
-});
-
-// becomes
-player.addEventListener("audioTrackChange", (track) => {
-  const { language, id, audioDescription } = track;
-  console.log("language changed to", language);
-});
-
-

-

-

subtitleChange

-

What Changed

-

subtitleChange is replaced by the textTrackChange event, which supports -closed caption.

-

Replacement example

-
// In the previous version
-player.addEventListener("subtitleChange", (lang) => {
-  console.log("subtitle changed to", lang);
-});
-
-// becomes
-player.addEventListener("textTrackChange", (track) => {
-  const { language, id, closedCaption } = track;
-  console.log("language changed to", language);
-});
-
-

-

-

nativeTextTrackChange

-

What Changed

-

nativeTextTrackChange is replace by the nativeTextTracksChange (notice -the supplementary “s”) event.

-

Three things have changed comparatively:

-
    -
  • -

    The payload of this event now is an array of TextTrack element. -Previously, it was a single TextTrackElement (which correspond to the -first in the array).

    -
  • -
  • -

    The event is also triggered when a TextTrackElement is removed from the -<video> tag. Previously, it was only when added.

    -
  • -
  • -

    The event is fired even if no content is playing

    -
  • -
-

This is to support edge cases where the <track> element could be modified by -the user of our library, in which case the RxPlayer could give false -information. Also, this allows to signal when a TextTrack has been removed -from the DOM to help you free up ressources on your side.

-

Replacement example

-
// In the previous version
-player.addEventListener("nativeTextTrackChange", (track) => {
-  console.log("the track changed:", track);
-});
-
-// becomes
-player.addEventListener("nativeTextTracksChange", (tracks) => {
-  if (tracks.length === 0) {
-    console.log("no active track!");
-  } else {
-    // in most usecases you can just check the first element.
-    // (this will have the exact same effect than the previous event)
-    console.log("the track changed:", tracks[0]);
-  }
-});
-
-

-

-

Changed events

-

-

-

positionUpdate

-

What Changed

-

The maximumBufferTime property has now been removed from positionUpdate -events. This is because this is now the exact same thing than:

-
    -
  • liveGap + position (from the same event) for live contents
  • -
  • duration (from the same event) for non-live contents
  • -
-
\ No newline at end of file diff --git a/doc/generated/pages/why_typescript.html b/doc/generated/pages/why_typescript.html deleted file mode 100644 index 3ea4fad9f1..0000000000 --- a/doc/generated/pages/why_typescript.html +++ /dev/null @@ -1,134 +0,0 @@ -On using TypeScript - RxPlayer Documentation

-

On using TypeScript

-

We recently (as from v3.0.1) have chosen to switch the rx-player codebase -from plain JavaScript to TypeScript.

-

This was in fact going for more than a month before the official v3.0.1 -release, a time during which we maintained both JavaScript and TypeScript -versions of the player:

-
    -
  • We ported fixes we found with our typescript branch on the regular releases
  • -
  • We ported improvements we were doing on regular releases to our typescript -branch.
  • -
-

This is one of the reasons why you saw a LOT of release candidates for the -v3.0.0, as we were seeing more typos and other minor errors in master we had -to fix.

-

-

Why refactoring?

-

It may appear shocking to most developpers, but we do not dislike JavaScript. -The language has its quirks (that we, as JS developers, learned to avoid the -hard way) but it has a flexibility that few other languages can compete with.

-

For example, our codebase adopts concepts of both Functional Programming and -Object Oriented Programming and it still looks idiomatic to the JS language -(even more since we’re using ES6+ and RxJS).

-

In recent years, we were spectators of a huge trend to write desktop -applications (thanks to Electron), mobile applications (e.g. with react-native) -and servers (thanks to Node.js) in what is basically JavaScript. Because it is -becoming a kind of developper -lingua-franca, the pool of -possible contributors is amazing. Moreover, as many developpers can read and -judge the quality of JavaScript codebases, open-sourcing becomes only more -exciting with a JavaScript project.

-

Despite this, we had issues with where our codebase was evolving toward:

-
    -
  • -

    it was becoming fairly large, and the old team in charge of the project -left. We lost a lot of the code’s knowledge in that process.

    -
  • -
  • -

    to renew the codebase and bring new features, some refactoring were -needed. But we did not have enough confidence on our code to do them.

    -
  • -
  • -

    As new features were added, bugs were also added. -A majority of these issues were either based on typos, or on a wrong -representation of the data structure we had at a certain point in the code.

    -
  • -
  • -

    There also were multiple coding styles in different parts of the player, -depending on the “era” in which the file was written in. -This harms the “welcomeness” of the codebase, which, as an open-source -library, is an important factor.

    -
  • -
-

We liked to present the rx-player as a really maintanable project, but by -keeping things like they were, we had a substantial risk of going toward the -exact opposite.

-

With that in mind, we observed that none of us were developping in “browser’s -JavaScript” anymore, as most projects we worked on made usage of Babel for -years now. -The code we write in looks very different than what is transpiled to run on -browsers (we’re treating the “real” JavaScript today as a - easily -readable - bytecode).

-

As such, we knew we needed to do something about the code, and we were not -hesitant to do substantial changes, while not wanting to depart too much from -JavaScript.

-

-

Why TypeScript?

-

When we were brainstorming on what we could do to improve our codebase, we edged -a lot around a better type system. As functional-programming fans, we were -seeing some wonderful type systems in other programming languages (Haskell, -Scala, Rust) that we thought could partially answer to a lot of our problems. -One of us worked with Scala in its previous professional experience, this also -amplified the need to “improve” our JavaScript.

-

In the browser’s world, there were two possibilities:

-
    -
  • using another language transpiled to JavaScript (elm, PureScript, Scala.js)
  • -
  • using a “superset” of JavaScript, which gives us typings without changing -the base language
  • -
-

The first solution was not wanted, as we would lost a lot of possible -contributors (both in-house or external), but also because it would need a lot -more work we could not afford.

-

The second solution was the only one we actually seriously thought about. -As such, a little more than a month ago, We began porting the rx-player in both -flow and TypeScript, to see which type system we could profit the more from.

-

We found both to be really similar for what we wanted to achieve. TypeScript -was finally chosen because:

-
    -
  1. -

    It has a lot more traction than flow today, with a lot more tools and a lot -more codebases written in/for TypeScript. This gives us more guarantees -about the language’s future.

    -
  2. -
  3. -

    RxJS, VisualStudioCode, BabylonJS and AngularJS are all well-regarded -codebases, all written in TypeScript. We consider this as a proof that the -language can helps us toward our goals, and that the language is mature -enough today.

    -
  4. -
  5. -

    The future of flow seemed too uncertain. This is even more the case now -that Facebook is working on the Reason -language.

    -
  6. -
-

-

What we have done

-

When we began to really consider switching the source to TypeScript, we set one -goal before the release: The whole RxPlayer should work under TypeScript’s -“strict” mode, and the code should look enough like idiomatic TypeScript to be -presented as a TypeScript project (and not as a ported JavaScript one).

-

As such, we worked on every files in the src directory, even doing important -refactorings, to ensure our code was elegant enough to be maintenable and -presentable. -Today, we have the confidence that the base we have can be approached naturally -in a TypeScript way.

-

We “switched” every rx-player source and unit tests files.

-

-

What we still need to do

-

Some parts of the code still need work to look like perfect idiomatic -TypeScript.

-

For example, the part gluing our networking logic to the streaming logic (what -we call the “pipeline”) relies too much on any types and casting. -This is the main part that needs work today. Specifically, the -manifest-refreshing logic shares too much logic with the segment-downloading -one, leading to types impossible to set.

-
\ No newline at end of file diff --git a/doc/generated/styles/code.css b/doc/generated/styles/code.css deleted file mode 100644 index 791932b87e..0000000000 --- a/doc/generated/styles/code.css +++ /dev/null @@ -1,99 +0,0 @@ -/* - -github.com style (c) Vasily Polovnyov - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #333; - background: #f8f8f8; -} - -.hljs-comment, -.hljs-quote { - color: #998; - font-style: italic; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-subst { - color: #333; - font-weight: bold; -} - -.hljs-number, -.hljs-literal, -.hljs-variable, -.hljs-template-variable, -.hljs-tag .hljs-attr { - color: #008080; -} - -.hljs-string, -.hljs-doctag { - color: #d14; -} - -.hljs-title, -.hljs-section, -.hljs-selector-id { - color: #900; - font-weight: bold; -} - -.hljs-subst { - font-weight: normal; -} - -.hljs-type, -.hljs-class .hljs-title { - color: #458; - font-weight: bold; -} - -.hljs-tag, -.hljs-name, -.hljs-attribute { - color: #000080; - font-weight: normal; -} - -.hljs-regexp, -.hljs-link { - color: #009926; -} - -.hljs-symbol, -.hljs-bullet { - color: #990073; -} - -.hljs-built_in, -.hljs-builtin-name { - color: #0086b3; -} - -.hljs-meta { - color: #999; - font-weight: bold; -} - -.hljs-deletion { - background: #fdd; -} - -.hljs-addition { - background: #dfd; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/doc/generated/styles/style.css b/doc/generated/styles/style.css deleted file mode 100644 index 0153d6358a..0000000000 --- a/doc/generated/styles/style.css +++ /dev/null @@ -1,267 +0,0 @@ -* { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -html { - scroll-behavior: smooth; -} -body { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 14px; - line-height: 1.5; - color: #333; - background-color: #fff; -} -.content-wrapper { - position: absolute; - top: 0px; - left: 0px; - padding-left: 325px; - padding-right: 10px; - width: 100%; - background-color: #fff; -} -body::-webkit-scrollbar { - background: #fff; -} -body::-webkit-scrollbar-thumb { - background: #ccc; -} -.content { - margin-top: 30px; - margin-bottom: 30px; - margin-left: auto; - margin-right: auto; - max-width: 750px; -} -.header { - display: none; -} -.content img { - width: 100%; -} -.footer { - position: fixed; - right: 0; - bottom: 0; - left: 0; - padding: 1rem; - background-color: #efefef; - text-align: center; -} -h1, h2, h3, h4, h5, h6 { - font-family: inherit; - font-weight: 500; - line-height: 1.1; - color: inherit; -} -h1, h2, h3 { - margin-top: 76px; - margin-bottom: 10px; -} -h1 { - font-size: 32px; -} -h2 { - display: block; - font-size: 24px; - font-weight: bold; - border-bottom: 1px dotted #aaa; - padding-bottom: 7px; -} -h3 { - font-size: 23px; -} -h4 { - margin-top: 10px; - margin-bottom: 10px; - font-size: 18px; -} -pre { - display: block; - padding: 9.5px; - margin: 0 0 10px; - font-size: 13px; - line-height: 1.42857143; - color: #333; - word-break: break-all; - word-wrap: break-word; - background-color: #f8f8f8; - border: 1px solid #ccc; - border-radius: 4px; -} -a:hover { - color: #0023ce; - text-decoration: underline; -} -a { - color: #001090; -} -code { - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - padding: 2px 4px; - font-size: 90%; - color: #484848; - background-color: #f9f2f4; - border-radius: 4px; -} -pre code { - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - background-color: transparent; - border-radius: 0; -} -.language-js { - padding: 9.5px; - display: block; - overflow-x: auto; - padding: 0.5em; - color: #333; - background: #f8f8f8; -} - -.emoji_warning { - color: #B71C1C; - padding-left: 4px; - padding-right: 3px; - font-size: 1.3em; -} -.sidebar { - height: 100%; - width: 300px; - position: fixed; - z-index: 1; - top: 0; - left: 0; - background-color: #fafafa; - overflow-x: hidden; - padding: 5px 20px; - line-height: 2em; -} -.sidebar::-webkit-scrollbar { - background: #fafafa; -} -.sidebar::-webkit-scrollbar-thumb { - background: #ccc; -} -.sidebar-nav { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - justify-content: space-between; - border-bottom: 1px dotted #364149; -} -.nav-icon { - margin-right: 6px; -} -.sidebar a { - color: #364149; - text-decoration: none; -} -.sidebar a:hover { - text-decoration: none; - color: #008cff; -} -.sidebar ul { - list-style-type: none; - padding-left: 20px; -} -.toc { - font-family: "Open Sans", sans-serif; - margin-top: 15px; -} -.toc p { - margin-top: 0px; - margin-bottom: 0px; -} -.toc ul { - margin-top: 0px; -} - -table { - padding: 0; - border-collapse: collapse; -} - -table tr { - border-top: 1px solid #cccccc; - background-color: white; - margin: 0; - padding: 0; -} - -table tr:nth-child(2n) { - background-color: #f8f8f8; -} - -table tr th { - font-weight: bold; - border: 1px solid #cccccc; - text-align: left; - margin: 0; - padding: 6px 13px; -} - -table tr td { - border: 1px solid #cccccc; - text-align: left; - margin: 0; - padding: 6px 13px; -} - -@media (max-width: 1120px) { - .sidebar { - display: none; - } - .content-wrapper { - position: absolute; - padding-left: 10px; - width: 100%; - min-width: 280px; - } - .content { - margin-top: 80px; - margin-left: auto; - margin-right: auto; - } - - .header { - display: block; - position: fixed; - height: 40px; - top: 0; - left: 0; - width: 100%; - font-size: 14px; - background-color: #ffffff; - border-bottom: 1px solid #e0e0e0; - } - .header-content { - display: flex; - flex-wrap: nowrap; - justify-content: space-between; - } - .header-content a { - margin: 10px; - color: #364149; - text-decoration: none; - } - .header-content a:hover { - text-decoration: none; - color: #008cff; - } -} - -@media screen and (prefers-reduced-motion: reduce) { - html { - scroll-behavior: auto; - } -} -@media (max-width: 350px) { - .header .nav-text { - display: none; - } -} From cc4aaf4e7e70f10ed902f959dad4e0dbb17ce393 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Thu, 25 Mar 2021 15:52:40 +0100 Subject: [PATCH 47/75] doc: rename `loadVideo method` quick link to `loadVideo options` --- doc/api/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/index.md b/doc/api/index.md index 06e666a62b..60bdc15ee0 100644 --- a/doc/api/index.md +++ b/doc/api/index.md @@ -5,7 +5,7 @@ - [Player Events](./player_events.md) - [Player errors and warning](./errors.md) - [Player Constructor options](./player_options.md) -- [loadVideo method](./loadVideo_options.md) +- [`loadVideo` options](./loadVideo_options.md) ## Table of Contents ########################################################### From fd2b8a632e7622c2028c29d9a0741cf2d6332c06 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Thu, 25 Mar 2021 17:18:32 +0100 Subject: [PATCH 48/75] tests: use new karma syntax for starting the test server --- tests/integration/run.js | 21 ++++++++++++++++----- tests/memory/run.js | 21 ++++++++++++++++----- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/tests/integration/run.js b/tests/integration/run.js index 1d3b1bc335..c656f507b5 100644 --- a/tests/integration/run.js +++ b/tests/integration/run.js @@ -1,7 +1,9 @@ /* eslint-env node */ const path = require("path"); -const Server = require("karma").Server; +const karma = require("karma"); +const parseConfig = karma.config.parseConfig; +const Server = karma.Server; const TestContentServer = require("../contents/server"); const webpackConfig = require("../../webpack-tests.config.js"); @@ -99,11 +101,20 @@ if (coverageIsWanted) { } const testContentServer = TestContentServer(3000); -const server = new Server(karmaConf, function(exitCode) { - testContentServer.close(); - process.exit(exitCode); +parseConfig( + null, + karmaConf, + { promiseConfig: true, throwErrors: true } +).then((parsedConfig) => { + const server = new Server(parsedConfig, function(exitCode) { + testContentServer.close(); + process.exit(exitCode); + }); + server.start(); +}, (rejectReason) => { + /* eslint-disable-next-line no-console */ + console.error("Karma config rejected:", rejectReason); }); -server.start(); function displayHelp() { /* eslint-disable no-console */ diff --git a/tests/memory/run.js b/tests/memory/run.js index f0d2edecbe..ad534a13d4 100644 --- a/tests/memory/run.js +++ b/tests/memory/run.js @@ -1,7 +1,9 @@ /* eslint-env node */ const path = require("path"); -const Server = require("karma").Server; +const karma = require("karma"); +const parseConfig = karma.config.parseConfig; +const Server = karma.Server; const TestContentServer = require("../contents/server"); const webpackConfig = require("../../webpack-tests.config.js"); @@ -72,11 +74,20 @@ const karmaConf = { }; const testContentServer = TestContentServer(3000); -const server = new Server(karmaConf, function(exitCode) { - testContentServer.close(); - process.exit(exitCode); +parseConfig( + null, + karmaConf, + { promiseConfig: true, throwErrors: true } +).then((parsedConfig) => { + const server = new Server(parsedConfig, function(exitCode) { + testContentServer.close(); + process.exit(exitCode); + }); + server.start(); +}, (rejectReason) => { + /* eslint-disable-next-line no-console */ + console.error("Karma config rejected:", rejectReason); }); -server.start(); /** * Display through `console.log` an helping message relative to how to run this From 29ac7c8057281e3a951900252f2ca8c31616bc21 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Wed, 24 Mar 2021 10:45:21 +0100 Subject: [PATCH 49/75] add v3.24.0 to CHANGELOG.md --- CHANGELOG.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 335cb7cc16..a804fcc244 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,45 @@ # Changelog +## v3.24.0 (2021/04/01) + +### Features + + - Add `inbandEvent` event for when an event is encountered in a media segment [#892] + - DRM: Add `singleLicensePer` `keySystems` option to be able to signal in advance that the current content has a single license, even if it has multiple encryption keys [#863, #904] + - DRM: Add `keySystems[].licenseStorage.disableRetroCompatibility` boolean to unlock optimizations when compatibility with EME sessions persisted in older RxPlayer versions is not important [#919] + +### Bug fixes + + - DASH: Fix rounding error that could cause infinite buffering issues when going from a DASH Period to the next [#897, #899] + - DRM: Always pass on server certificate before any challenge is generated. Contents with multiple licenses previously could lead to the latter being done before the former. [#895] + - DRM: Fix possible leaks of MediaKeySessions if closed at the wrong time [#920] + - Fix issue making sudden and acute fall in bandwidth not being considered soon enough [#906] + - On some devices when `maxBufferAhead` is set, avoid removing the initially loaded data if done before the initial seek could be performed [#907] + - Avoid cases of infinite rebuffering on Tizen 4 by avoiding pushing segments "on top of others" too close to the current position [#925] + - Avoid seeking issues on Tizen by not seeking over discontinuities that will be already handled by the browser [#922] + - Fix initial seek on Tizen (Samsung TVs) on live contents by setting a much lower duration (to work-around a Tizen overflow) [#914] + - DASH: Consider multiple defined `` tags for a single AdaptationSet [#903] + - Fix error that could be thrown on Safari when calling the `getStatusForHDCP` method from the experimental `MediaCapabilitiesProber` tool [#927] + +### Other improvements + + - Avoid to push on top of the current position if there's already a segment there as it can provoke minor decoding issues on some devices [#925] + - Update video element's duration if the content duration changes [#917] + - DASH: Improve loading time with encrypted contents by only using the encrypted initialization data found in the Manifest when found in it [#911, #919] + - Record redirections made on a `manifestUpdateUrl` to request directly the right URL on next update. [#929] + - Improve loading time when a `serverCertificate` is given by calling the `setServerCertificate` API earlier [#895] + - Improve loading time when switching contents by fetching the Manifest at the same time the previous content is cleaned-up [#894] + - Improve loading time on some CPU-constrained devices by not running unnecessary playback checks on the "progress" HTMLMediaElement event anymore [#893] + - DASH: Consider DASH audio AdaptationSet with a "urn:mpeg:dash:role:2011" schemeIdUri and a "description" role as `audioDescription` tracks [#903] + - Warn through the logger when the autoplay attribute is enabled on the media element but not on RxPlayer [#924] + - Avoid switching to a SEEKING state if the seek operation was performed inside the RxPlayer's code [#872, #887] + - DRM: Wait up to 100 milliseconds after a persistent MediaKeySession has been loaded to wait for possibly late `keyStatuses` updates [#928] + - DRM: Only store persistent MediaKeySession once at least one key is known [#926] + - DRM: Reconsider Representations that have been fallbacked from if they become decipherable [#905] + - Doc: Move architecture documentation closer to the code it documents [#764, #900] + - Doc: add "Quick links" to the top of the API documentation [#909] + + ## v3.23.1 (2021/02/01) ### Bug fixes From 0fd5d6515a12320f6965afe33ee54b774cbe60de Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Tue, 30 Mar 2021 17:02:54 +0200 Subject: [PATCH 50/75] update version to v3.24.0 --- VERSION | 2 +- dist/rx-player.js | 73607 ++++++++++++++++++----------------- dist/rx-player.min.js | 2 +- package-lock.json | 4 +- package.json | 2 +- sonar-project.properties | 2 +- src/core/api/public_api.ts | 4 +- 7 files changed, 37516 insertions(+), 36107 deletions(-) diff --git a/VERSION b/VERSION index 9b2f2a1688..954e228821 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.23.1 +3.24.0 diff --git a/dist/rx-player.js b/dist/rx-player.js index 51f1ea2cc4..b2769fa3ac 100644 --- a/dist/rx-player.js +++ b/dist/rx-player.js @@ -11,9 +11,13 @@ return /******/ (() => { // webpackBootstrap /******/ var __webpack_modules__ = ({ -/***/ 1506: -/***/ ((module) => { +/***/ 3349: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ _assertThisInitialized) +/* harmony export */ }); function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); @@ -22,84 +26,15 @@ function _assertThisInitialized(self) { return self; } -module.exports = _assertThisInitialized; - /***/ }), -/***/ 8926: -/***/ ((module) => { - -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); - }); - }; -} - -module.exports = _asyncToGenerator; - -/***/ }), - -/***/ 9100: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - -var setPrototypeOf = __webpack_require__(9489); - -var isNativeReflectConstruct = __webpack_require__(7067); - -function _construct(Parent, args, Class) { - if (isNativeReflectConstruct()) { - module.exports = _construct = Reflect.construct; - } else { - module.exports = _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) setPrototypeOf(instance, Class.prototype); - return instance; - }; - } - - return _construct.apply(null, arguments); -} - -module.exports = _construct; - -/***/ }), - -/***/ 3913: -/***/ ((module) => { +/***/ 5991: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ _createClass) +/* harmony export */ }); function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; @@ -116,100 +51,108 @@ function _createClass(Constructor, protoProps, staticProps) { return Constructor; } -module.exports = _createClass; - /***/ }), -/***/ 9754: -/***/ ((module) => { +/***/ 1788: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { -function _getPrototypeOf(o) { - module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { - return o.__proto__ || Object.getPrototypeOf(o); - }; - return _getPrototypeOf(o); -} - -module.exports = _getPrototypeOf; - -/***/ }), - -/***/ 5354: -/***/ ((module) => { +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ _inheritsLoose) +/* harmony export */ }); +/* harmony import */ var _setPrototypeOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4665); function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; - subClass.__proto__ = superClass; + (0,_setPrototypeOf_js__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(subClass, superClass); } -module.exports = _inheritsLoose; - /***/ }), -/***/ 430: -/***/ ((module) => { +/***/ 4665: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { -function _isNativeFunction(fn) { - return Function.toString.call(fn).indexOf("[native code]") !== -1; -} +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ _setPrototypeOf) +/* harmony export */ }); +function _setPrototypeOf(o, p) { + _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; -module.exports = _isNativeFunction; + return _setPrototypeOf(o, p); +} /***/ }), -/***/ 7067: -/***/ ((module) => { +/***/ 3786: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ _wrapNativeSuper) +}); + +;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js +function _getPrototypeOf(o) { + _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { + return o.__proto__ || Object.getPrototypeOf(o); + }; + return _getPrototypeOf(o); +} +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js +var setPrototypeOf = __webpack_require__(4665); +;// 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 { - Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); + Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } +;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/construct.js -module.exports = _isNativeReflectConstruct; - -/***/ }), - -/***/ 9489: -/***/ ((module) => { -function _setPrototypeOf(o, p) { - module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; +function _construct(Parent, args, Class) { + if (_isNativeReflectConstruct()) { + _construct = Reflect.construct; + } 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 _setPrototypeOf(o, p); + return _construct.apply(null, arguments); } +;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js -module.exports = _setPrototypeOf; - -/***/ }), - -/***/ 5957: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { -var getPrototypeOf = __webpack_require__(9754); -var setPrototypeOf = __webpack_require__(9489); - -var isNativeFunction = __webpack_require__(430); - -var construct = __webpack_require__(9100); function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; - module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) { - if (Class === null || !isNativeFunction(Class)) return Class; + _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"); @@ -222,7 +165,7 @@ function _wrapNativeSuper(Class) { } function Wrapper() { - return construct(Class, arguments, getPrototypeOf(this).constructor); + return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { @@ -233,14 +176,12 @@ function _wrapNativeSuper(Class) { configurable: true } }); - return setPrototypeOf(Wrapper, Class); + return (0,setPrototypeOf/* default */.Z)(Wrapper, Class); }; return _wrapNativeSuper(Class); } -module.exports = _wrapNativeSuper; - /***/ }), /***/ 7757: @@ -256,11 +197,11 @@ module.exports = __webpack_require__(5666); "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "DQ": () => /* binding */ HTMLElement_, -/* harmony export */ "JJ": () => /* binding */ MediaSource_, -/* harmony export */ "cX": () => /* binding */ READY_STATES, -/* harmony export */ "w": () => /* binding */ VTTCue_ +/* harmony export */ "DQ": () => (/* binding */ HTMLElement_), +/* harmony export */ "JJ": () => (/* binding */ MediaSource_), +/* harmony export */ "w": () => (/* binding */ VTTCue_) /* harmony export */ }); +/* unused harmony export READY_STATES */ /* harmony import */ var _utils_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1946); /* harmony import */ var _is_node__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2203); /** @@ -321,13 +262,14 @@ var READY_STATES = { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "kD": () => /* binding */ isEdgeChromium, -/* harmony export */ "fq": () => /* binding */ isIE11, -/* harmony export */ "YM": () => /* binding */ isIEOrEdge, -/* harmony export */ "vU": () => /* binding */ isFirefox, -/* harmony export */ "G6": () => /* binding */ isSafari, -/* harmony export */ "SB": () => /* binding */ isSafariMobile, -/* harmony export */ "op": () => /* binding */ isSamsungBrowser +/* harmony export */ "kD": () => (/* binding */ isEdgeChromium), +/* harmony export */ "fq": () => (/* binding */ isIE11), +/* harmony export */ "YM": () => (/* binding */ isIEOrEdge), +/* harmony export */ "vU": () => (/* binding */ isFirefox), +/* harmony export */ "G6": () => (/* binding */ isSafari), +/* harmony export */ "SB": () => (/* binding */ isSafariMobile), +/* harmony export */ "op": () => (/* binding */ isSamsungBrowser), +/* harmony export */ "yS": () => (/* binding */ isTizen) /* harmony export */ }); /* harmony import */ var _is_node__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2203); /** @@ -364,6 +306,7 @@ var isIEOrEdge = _is_node__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z ? false var isEdgeChromium = !_is_node__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z && navigator.userAgent.toLowerCase().indexOf("edg/") !== -1; var isFirefox = !_is_node__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z && navigator.userAgent.toLowerCase().indexOf("firefox") !== -1; var isSamsungBrowser = !_is_node__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z && /SamsungBrowser/.test(navigator.userAgent); +var isTizen = !_is_node__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z && /Tizen/.test(navigator.userAgent); /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-call */ @@ -383,7 +326,7 @@ var isSafariMobile = !_is_node__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z && "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ clearElementSrc +/* harmony export */ "Z": () => (/* binding */ clearElementSrc) /* harmony export */ }); /* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3887); /* harmony import */ var _browser_detection__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3666); @@ -452,8 +395,8 @@ function clearElementSrc(element) { // EXPORTS __webpack_require__.d(__webpack_exports__, { - "N": () => /* binding */ requestMediaKeySystemAccess, - "Y": () => /* binding */ setMediaKeys + "N": () => (/* binding */ requestMediaKeySystemAccess), + "Y": () => (/* binding */ setMediaKeys) }); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/throwError.js @@ -472,9 +415,8 @@ var browser_detection = __webpack_require__(3666); var is_node = __webpack_require__(2203); // EXTERNAL MODULE: ./src/compat/should_favour_custom_safari_EME.ts var should_favour_custom_safari_EME = __webpack_require__(5059); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/createClass.js -var createClass = __webpack_require__(3913); -var createClass_default = /*#__PURE__*/__webpack_require__.n(createClass); +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/createClass.js +var createClass = __webpack_require__(5991); // EXTERNAL MODULE: ./src/utils/promise.ts var promise = __webpack_require__(9589); ;// CONCATENATED MODULE: ./src/compat/eme/custom_key_system_access.ts @@ -544,7 +486,7 @@ var CustomMediaKeySystemAccess = /*#__PURE__*/function () { return this._configuration; }; - createClass_default()(CustomMediaKeySystemAccess, [{ + (0,createClass/* default */.Z)(CustomMediaKeySystemAccess, [{ key: "keySystem", get: function get() { return this._keyType; @@ -555,9 +497,8 @@ var CustomMediaKeySystemAccess = /*#__PURE__*/function () { }(); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/inheritsLoose.js -var inheritsLoose = __webpack_require__(5354); -var inheritsLoose_default = /*#__PURE__*/__webpack_require__.n(inheritsLoose); +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js +var inheritsLoose = __webpack_require__(1788); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subject.js var Subject = __webpack_require__(211); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/merge.js @@ -631,7 +572,7 @@ if (!is_node/* default */.Z) { var IE11MediaKeySession = /*#__PURE__*/function (_EventEmitter) { - inheritsLoose_default()(IE11MediaKeySession, _EventEmitter); + (0,inheritsLoose/* default */.Z)(IE11MediaKeySession, _EventEmitter); function IE11MediaKeySession(mk) { var _this; @@ -720,7 +661,7 @@ var IE11MediaKeySession = /*#__PURE__*/function (_EventEmitter) { return promise/* default.resolve */.Z.resolve(); }; - createClass_default()(IE11MediaKeySession, [{ + (0,createClass/* default */.Z)(IE11MediaKeySession, [{ key: "sessionId", get: function get() { var _a, _b; @@ -937,7 +878,7 @@ function isOldWebkitMediaElement(element) { } var OldWebkitMediaKeySession = /*#__PURE__*/function (_EventEmitter) { - inheritsLoose_default()(OldWebkitMediaKeySession, _EventEmitter); + (0,inheritsLoose/* default */.Z)(OldWebkitMediaKeySession, _EventEmitter); function OldWebkitMediaKeySession(mediaElement, keySystem) { var _this; @@ -1236,7 +1177,7 @@ function setWebKitMediaKeys(videoElement, mediaKeys) { var WebkitMediaKeySession = /*#__PURE__*/function (_EventEmitter) { - inheritsLoose_default()(WebkitMediaKeySession, _EventEmitter); + (0,inheritsLoose/* default */.Z)(WebkitMediaKeySession, _EventEmitter); /** * @param {HTMLMediaElement} mediaElement @@ -1373,7 +1314,7 @@ var WebkitMediaKeySession = /*#__PURE__*/function (_EventEmitter) { return promise/* default.resolve */.Z.resolve(); }; - createClass_default()(WebkitMediaKeySession, [{ + (0,createClass/* default */.Z)(WebkitMediaKeySession, [{ key: "sessionId", get: function get() { var _a, _b; @@ -1673,7 +1614,7 @@ function setMediaKeys(elt, mediaKeys) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "t": () => /* binding */ WebKitMediaKeysConstructor +/* harmony export */ "t": () => (/* binding */ WebKitMediaKeysConstructor) /* harmony export */ }); /* harmony import */ var _is_node__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2203); /** @@ -1721,28 +1662,27 @@ if (!_is_node__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z) { // EXPORTS __webpack_require__.d(__webpack_exports__, { - "zh": () => /* binding */ isActive, - "_K": () => /* binding */ isVideoVisible, - "Oh": () => /* binding */ onEncrypted$, - "C1": () => /* binding */ onEnded$, - "Q1": () => /* binding */ onFullscreenChange$, - "GV": () => /* binding */ onKeyAdded$, - "Xe": () => /* binding */ onKeyError$, - "GJ": () => /* binding */ onKeyMessage$, - "eX": () => /* binding */ onKeyStatusesChange$, - "K4": () => /* binding */ onLoadedMetadata$, - "yj": () => /* binding */ onPictureInPictureEvent$, - "Qt": () => /* binding */ onPlayPause$, - "gg": () => /* binding */ onRemoveSourceBuffers$, - "ik": () => /* binding */ onSeeked$, - "d5": () => /* binding */ onSeeking$, - "ym": () => /* binding */ onSourceOpen$, - "UA": () => /* binding */ onTextTrackChanges$, - "_E": () => /* binding */ onUpdate$, - "$x": () => /* binding */ videoWidth$ + "zh": () => (/* binding */ isActive), + "_K": () => (/* binding */ isVideoVisible), + "Oh": () => (/* binding */ onEncrypted$), + "C1": () => (/* binding */ onEnded$), + "Q1": () => (/* binding */ onFullscreenChange$), + "GV": () => (/* binding */ onKeyAdded$), + "Xe": () => (/* binding */ onKeyError$), + "GJ": () => (/* binding */ onKeyMessage$), + "eX": () => (/* binding */ onKeyStatusesChange$), + "yj": () => (/* binding */ onPictureInPictureEvent$), + "Qt": () => (/* binding */ onPlayPause$), + "gg": () => (/* binding */ onRemoveSourceBuffers$), + "ik": () => (/* binding */ onSeeked$), + "d5": () => (/* binding */ onSeeking$), + "ym": () => (/* binding */ onSourceOpen$), + "UA": () => (/* binding */ onTextTrackChanges$), + "_E": () => (/* binding */ onUpdate$), + "$x": () => (/* binding */ videoWidth$) }); -// UNUSED EXPORTS: onTimeUpdate$ +// UNUSED EXPORTS: onLoadedMetadata$, onTimeUpdate$ // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules var Observable = __webpack_require__(4379); @@ -2467,7 +2407,7 @@ var onKeyStatusesChange$ = compatibleListener(["keystatuseschange"]); "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /** * Copyright 2015 CANAL+ Group @@ -2494,7 +2434,7 @@ var isNode = typeof window === "undefined"; "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ isVTTCue +/* harmony export */ "Z": () => (/* binding */ isVTTCue) /* harmony export */ }); /** * Copyright 2015 CANAL+ Group @@ -2530,7 +2470,7 @@ function isVTTCue(cue) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ makeCue +/* harmony export */ "Z": () => (/* binding */ makeCue) /* harmony export */ }); /* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3887); /* harmony import */ var _browser_compatibility_types__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3774); @@ -2583,7 +2523,7 @@ function makeCue(startTime, endTime, payload) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ shouldFavourCustomSafariEME +/* harmony export */ "Z": () => (/* binding */ shouldFavourCustomSafariEME) /* harmony export */ }); /* harmony import */ var _browser_detection__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3666); /* harmony import */ var _eme_custom_media_keys_webkit_media_keys_constructor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(158); @@ -2623,7 +2563,7 @@ function shouldFavourCustomSafariEME() { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /** * Copyright 2015 CANAL+ Group @@ -2866,7 +2806,10 @@ function shouldFavourCustomSafariEME() { DEFAULT_INITIAL_BITRATES: { audio: 0, video: 0, - other: 0 + other: 0 // tracks which are not audio/video (text images). + // Though those are generally at a single bitrate, so no adaptive + // mechanism is triggered for them. + }, /* eslint-disable @typescript-eslint/consistent-type-assertions */ @@ -2884,7 +2827,10 @@ function shouldFavourCustomSafariEME() { DEFAULT_MIN_BITRATES: { audio: 0, video: 0, - other: 0 + other: 0 // tracks which are not audio/video + // Though those are generally at a single bitrate, so no + // adaptive mechanism is triggered for them. + }, /* eslint-enable @typescript-eslint/consistent-type-assertions */ @@ -2904,7 +2850,10 @@ function shouldFavourCustomSafariEME() { DEFAULT_MAX_BITRATES: { audio: Infinity, video: Infinity, - other: Infinity + other: Infinity // tracks which are not audio/video + // Though those are generally at a single bitrate, so no + // adaptive mechanism is triggered for them. + }, /* eslint-enable @typescript-eslint/consistent-type-assertions */ @@ -2963,6 +2912,23 @@ function shouldFavourCustomSafariEME() { */ BUFFER_DISCONTINUITY_THRESHOLD: 0.2, + /** + * When encountering small discontinuities, the RxPlayer may want, in specific + * conditions, ignore those and let the browser seek over them iself (this + * allows for example to avoid conflicts when both the browser and the + * RxPlayer want to seek at a different position, sometimes leading to a + * seeking loop). + * In this case, we however still want to seek it ourselves if the browser + * doesn't take the opportunity soon enough. + * + * This value specifies a delay after which a discontinuity ignored by the + * RxPlayer is finally considered. + * We want to maintain high enough to be sure the browser will not seek yet + * small enough so this (arguably rare) situation won't lead to too much + * waiting time. + */ + FORCE_DISCONTINUITY_SEEK_DELAY: 2000, + /** * Ratio used to know if an already loaded segment should be re-buffered. * We re-load the given segment if the current one times that ratio is @@ -3386,7 +3352,8 @@ function shouldFavourCustomSafariEME() { BUFFER_PADDING: { audio: 1, video: 3, - other: 1 + other: 1 // tracks which are not audio/video (text images). + }, /** @@ -3619,6 +3586,51 @@ function shouldFavourCustomSafariEME() { */ EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION: 1000, + /** + * Attempts to closing a MediaKeySession can fail, most likely because the + * MediaKeySession was not initialized yet. + * When we consider that we're in one of these case, we will retry to close it. + * + * To avoid going into an infinite loop of retry, this number indicates a + * maximum number of attemps we're going to make (`0` meaning no retry at all, + * `1` only one retry and so on). + */ + EME_SESSION_CLOSING_MAX_RETRY: 5, + + /** + * When closing a MediaKeySession failed due to the reasons explained for the + * `EME_SESSION_CLOSING_MAX_RETRY` config property, we may (among other + * triggers) choose to wait a delay raising exponentially at each retry before + * that new attempt. + * This value indicates the initial value for this delay, in milliseconds. + */ + EME_SESSION_CLOSING_INITIAL_DELAY: 100, + + /** + * When closing a MediaKeySession failed due to the reasons explained for the + * `EME_SESSION_CLOSING_MAX_RETRY` config property, we may (among other + * triggers) choose to wait a delay raising exponentially at each retry before + * that new attempt. + * This value indicates the maximum possible value for this delay, in + * milliseconds. + */ + EME_SESSION_CLOSING_MAX_DELAY: 1000, + + /** + * After loading a persistent MediaKeySession, the RxPlayer needs to ensure + * that its keys still allow to decrypt a content. + * + * However on some browsers, the `keyStatuses` property that we used to check + * the keys' satuses linked to that session can be empty for some time after + * the loading operation is done. + * + * This value allows to configure a delay in milliseconds that will be the + * maximum time we will wait after a persistent session is loaded. + * If after that time, the `keyStatuses` property is still empty, we will + * consider that session as not usable. + */ + EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES: 100, + /** * The player relies on browser events and properties to update its status to * "ENDED". @@ -3666,7 +3678,8 @@ function shouldFavourCustomSafariEME() { image: { before: 0, after: 0 - } + } // not managed natively, so no problem here + }, /** @@ -3683,12 +3696,14 @@ function shouldFavourCustomSafariEME() { SOURCE_BUFFER_FLUSHING_INTERVAL: 500, /** - * Padding under which we should not buffer from the current time, on - * Safari. To avoid some buffer appending issues on it, we decide not - * to load a segment if it may be pushed during playback time. + * Any already-pushed segment starting before or at the current position + + * CONTENT_REPLACEMENT_PADDING won't be replaced by new segments. + * + * This allows to avoid overwriting segments that are currently being decoded + * as we encountered many decoding issues when doing so. * @type {Number} - in seconds */ - CONTENT_REPLACEMENT_PADDING: 2, + CONTENT_REPLACEMENT_PADDING: 1.2, /** * For video and audio segments, determines two thresholds below which : @@ -3701,7 +3716,25 @@ function shouldFavourCustomSafariEME() { }, /** Interval we will use to poll for checking if an event shall be emitted */ - STREAM_EVENT_EMITTER_POLL_INTERVAL: 250 + STREAM_EVENT_EMITTER_POLL_INTERVAL: 250, + + /** + * In Javascript, numbers are encoded in a way that a floating number may be + * represented internally with a rounding error. When multiplying times in + * seconds by the timescale, we've encoutered cases were the rounding error + * was amplified by a factor which is about the timescale. + * Example : + * (192797480.641122).toFixed(20) = 192797480.64112201333045959473 + * (error is 0.0000000133...) + * 192797480.641122 * 10000000 = 1927974806411220.2 (error is 0.2) + * 192797480.641122 * 10000000 * 4 = 7711899225644881 (error is 1) + * The error is much more significant here, once the timescale has been + * applied. + * Thus, we consider that our max tolerable rounding error is 1ms. + * It is much more than max rounding errors when seen into practice, + * and not significant from the media loss perspective. + */ + DEFAULT_MAXIMUM_TIME_ROUNDING_ERROR: 1 / 1000 }); /***/ }), @@ -3711,12 +3744,11 @@ function shouldFavourCustomSafariEME() { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ MediaElementTrackChoiceManager +/* harmony export */ "Z": () => (/* binding */ MediaElementTrackChoiceManager) /* harmony export */ }); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5354); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1788); /* harmony import */ var _utils_event_emitter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1959); -/* harmony import */ var _utils_languages__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7829); +/* harmony import */ var _utils_languages__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7829); /** @@ -3780,7 +3812,7 @@ function createAudioTracks(audioTracks) { var track = { language: audioTrack.language, id: id, - normalized: (0,_utils_languages__WEBPACK_IMPORTED_MODULE_1__/* .default */ .ZP)(audioTrack.language), + normalized: (0,_utils_languages__WEBPACK_IMPORTED_MODULE_0__/* .default */ .ZP)(audioTrack.language), audioDescription: false, representations: [] }; @@ -3814,7 +3846,7 @@ function createTextTracks(textTracks) { var track = { language: textTrack.language, id: id, - normalized: (0,_utils_languages__WEBPACK_IMPORTED_MODULE_1__/* .default */ .ZP)(textTrack.language), + normalized: (0,_utils_languages__WEBPACK_IMPORTED_MODULE_0__/* .default */ .ZP)(textTrack.language), closedCaption: textTrack.kind === "captions" }; newTextTracks.push({ @@ -3862,7 +3894,7 @@ function createVideoTracks(videoTracks) { var MediaElementTrackChoiceManager = /*#__PURE__*/function (_EventEmitter) { - _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0___default()(MediaElementTrackChoiceManager, _EventEmitter); + (0,_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(MediaElementTrackChoiceManager, _EventEmitter); function MediaElementTrackChoiceManager(mediaElement) { var _this; @@ -4274,7 +4306,7 @@ var MediaElementTrackChoiceManager = /*#__PURE__*/function (_EventEmitter) { var track = preferredAudioTracks[i]; if (track !== null && track.language !== undefined) { - var normalized = (0,_utils_languages__WEBPACK_IMPORTED_MODULE_1__/* .default */ .ZP)(track.language); + var normalized = (0,_utils_languages__WEBPACK_IMPORTED_MODULE_0__/* .default */ .ZP)(track.language); for (var j = 0; j < this._audioTracks.length; j++) { var audioTrack = this._audioTracks[j]; @@ -4341,7 +4373,7 @@ var MediaElementTrackChoiceManager = /*#__PURE__*/function (_EventEmitter) { return; } - var normalized = (0,_utils_languages__WEBPACK_IMPORTED_MODULE_1__/* .default */ .ZP)(track.language); + var normalized = (0,_utils_languages__WEBPACK_IMPORTED_MODULE_0__/* .default */ .ZP)(track.language); for (var j = 0; j < this._textTracks.length; j++) { var textTrack = this._textTracks[j]; @@ -4707,28 +4739,32 @@ function disableVideoTracks(videoTracks) { /***/ }), -/***/ 8745: +/***/ 1603: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; // EXPORTS __webpack_require__.d(__webpack_exports__, { - "ZP": () => /* binding */ eme + "ZP": () => (/* binding */ eme) }); // UNUSED EXPORTS: clearEMESession, disposeEME, getCurrentKeySystem +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js +var of = __webpack_require__(8170); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/concat.js +var concat = __webpack_require__(9795); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/merge.js var merge = __webpack_require__(4370); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/throwError.js var throwError = __webpack_require__(4944); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js -var of = __webpack_require__(8170); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/ReplaySubject.js + 4 modules +var ReplaySubject = __webpack_require__(2135); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/empty.js var empty = __webpack_require__(5631); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/concat.js -var concat = __webpack_require__(9795); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMap.js +var mergeMap = __webpack_require__(7746); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/shareReplay.js var shareReplay = __webpack_require__(7006); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/filter.js @@ -4737,8 +4773,6 @@ var filter = __webpack_require__(6008); var take = __webpack_require__(1015); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/tap.js var tap = __webpack_require__(3068); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMap.js -var mergeMap = __webpack_require__(7746); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/map.js var map = __webpack_require__(5709); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/catchError.js @@ -4749,6 +4783,8 @@ var ignoreElements = __webpack_require__(6738); var event_listeners = __webpack_require__(1473); // EXTERNAL MODULE: ./src/log.ts + 1 modules var log = __webpack_require__(3887); +// EXTERNAL MODULE: ./src/parsers/containers/isobmff/take_pssh_out.ts + 1 modules +var take_pssh_out = __webpack_require__(6490); // EXTERNAL MODULE: ./src/utils/are_arrays_of_numbers_equal.ts var are_arrays_of_numbers_equal = __webpack_require__(4791); // EXTERNAL MODULE: ./src/utils/byte_parsing.ts @@ -4795,44 +4831,58 @@ var PSSH_TO_INTEGER = (0,byte_parsing/* be4toi */.pX)((0,string_parsing/* strToU + /** - * As we observed on some browsers (IE and Edge), the initialization data on - * some segments have sometimes duplicated PSSH when sent through an encrypted - * event (but not when pushed to the SourceBuffer). - * - * This function tries to guess if the initialization data contains only PSSHs - * concatenated (as it is usually the case). - * If that's the case, it will filter duplicated PSSHs from it. + * Take in input initialization data from an encrypted event and generate the + * corresponding array of initialization data values from it. * + * At the moment, this function only handles initialization data which have the + * "cenc" initialization data type. + * It will just return a single value with an `undefined` `systemId` for all + * other types of data. * @param {Uint8Array} initData - Raw initialization data - * @returns {Uint8Array} - Initialization data, "cleaned" + * @returns {Array.} */ -function cleanEncryptedEvent(initData) { - var resInitData = new Uint8Array(); - var encounteredPSSHs = []; +function getInitializationDataValues(initData) { + var result = []; var offset = 0; while (offset < initData.length) { if (initData.length < offset + 8 || (0,byte_parsing/* be4toi */.pX)(initData, offset + 4) !== PSSH_TO_INTEGER) { log/* default.warn */.Z.warn("Compat: Unrecognized initialization data. Use as is."); - return initData; + return [{ + systemId: undefined, + data: initData + }]; } var len = (0,byte_parsing/* be4toi */.pX)(new Uint8Array(initData), offset); if (offset + len > initData.length) { log/* default.warn */.Z.warn("Compat: Unrecognized initialization data. Use as is."); - return initData; + return [{ + systemId: undefined, + data: initData + }]; } var currentPSSH = initData.subarray(offset, offset + len); + var systemId = (0,take_pssh_out/* getPsshSystemID */.Y)(currentPSSH, 8); + var currentItem = { + systemId: systemId, + data: currentPSSH + }; - if (isPSSHAlreadyEncountered(encounteredPSSHs, currentPSSH)) { + if (isPSSHAlreadyEncountered(result, currentItem)) { + // As we observed on some browsers (IE and Edge), the initialization data on + // some segments have sometimes duplicated PSSH when sent through an encrypted + // event (but not when the corresponding segment has been pushed to the + // SourceBuffer). + // We prefer filtering them out, to avoid further issues. log/* default.warn */.Z.warn("Compat: Duplicated PSSH found in initialization data, removing it."); } else { - resInitData = (0,byte_parsing/* concat */.zo)(resInitData, currentPSSH); - encounteredPSSHs.push(initData); + result.push(currentItem); } offset += len; @@ -4840,10 +4890,13 @@ function cleanEncryptedEvent(initData) { if (offset !== initData.length) { log/* default.warn */.Z.warn("Compat: Unrecognized initialization data. Use as is."); - return initData; + return [{ + systemId: undefined, + data: initData + }]; } - return resInitData; + return result; } /** * Returns `true` if the given PSSH has already been stored in the @@ -4859,8 +4912,10 @@ function isPSSHAlreadyEncountered(encounteredPSSHs, pssh) { for (var i = 0; i < encounteredPSSHs.length; i++) { var item = encounteredPSSHs[i]; - if ((0,are_arrays_of_numbers_equal/* default */.Z)(pssh, item)) { - return true; + if (pssh.systemId === undefined || item.systemId === undefined || pssh.systemId === item.systemId) { + if ((0,are_arrays_of_numbers_equal/* default */.Z)(pssh.data, item.data)) { + return true; + } } } @@ -4885,16 +4940,14 @@ function getInitData(encryptedEvent) { if (initData == null) { log/* default.warn */.Z.warn("Compat: No init data found on media encrypted event."); - return { - initData: initData, - initDataType: initDataType - }; + return null; } var initDataBytes = new Uint8Array(initData); + var values = getInitializationDataValues(initDataBytes); return { - initData: cleanEncryptedEvent(initDataBytes), - initDataType: encryptedEvent.initDataType + type: initDataType, + values: values }; } // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/defer.js @@ -5019,20 +5072,18 @@ function patchInitData(initData) { * @returns {Observable} - Emit when done. Errors if fails. */ -function generateKeyRequest(session, initializationData) { +function generateKeyRequest(session, initializationDataType, initializationData) { return (0,defer/* defer */.P)(function () { - var _a; - log/* default.debug */.Z.debug("Compat: Calling generateRequest on the MediaKeySession"); var patchedInit; try { - patchedInit = patchInitData(initializationData.data); + patchedInit = patchInitData(initializationData); } catch (_e) { - patchedInit = initializationData.data; + patchedInit = initializationData; } - var initDataType = (_a = initializationData.type) !== null && _a !== void 0 ? _a : ""; + var initDataType = initializationDataType !== null && initializationDataType !== void 0 ? initializationDataType : ""; return (0,cast_to_observable/* default */.Z)(session.generateRequest(initDataType, patchedInit)).pipe((0,catchError/* catchError */.K)(function (error) { if (initDataType !== "" || !(error instanceof TypeError)) { throw error; @@ -5159,8 +5210,10 @@ function cleanOldLoadedSessions(loadedSessionsStore, limit) { return merge/* merge.apply */.T.apply(void 0, cleaningOldSessions$); } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules -var Observable = __webpack_require__(4379); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/race.js +var race = __webpack_require__(8821); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/timer.js +var timer = __webpack_require__(9604); // EXTERNAL MODULE: ./src/utils/rx-try_catch.ts var rx_try_catch = __webpack_require__(5561); ;// CONCATENATED MODULE: ./src/compat/eme/load_session.ts @@ -5184,6 +5237,8 @@ var rx_try_catch = __webpack_require__(5561); + +var EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES = 100; /** * Load a persistent session, based on its `sessionId`, on the given * MediaKeySession. @@ -5208,31 +5263,13 @@ function loadSession(session, sessionId) { }).pipe((0,mergeMap/* mergeMap */.zg)(function (isLoaded) { if (!isLoaded || session.keyStatuses.size > 0) { return (0,of.of)(isLoaded); - } // A browser race condition exists for example in some old Chromium/Chrome - // versions where the `keyStatuses` property from a loaded MediaKeySession - // would not be populated directly as the load answer but asynchronously - // after. - // - // Even a delay of `0` millisecond is sufficient, letting us think that it - // just happens just after and what is required is just to wait the next - // event loop turn. - // We found out that creating a micro-task (for example by calling - // `Promise.resolve.then`) was not sufficient, that's why we're using the - // somewhat less elegant `setTimeout` solution instead. - // This is also the reason why I didn't use RxJS's `timer` function, as I'm - // unsure of possible optimizations (or future optimizations), when the - // delay to wait is set to `0`. + } // A browser race condition can exist, seen for example in some + // Chromium/Chrome versions where the `keyStatuses` property from a loaded + // MediaKeySession would not be populated directly as the load answer but + // asynchronously after. - return new Observable/* Observable */.y(function (subscriber) { - var timer = setTimeout(function () { - subscriber.next(isLoaded); - subscriber.complete(); - }, 0); - return function () { - clearTimeout(timer); - }; - }); + return (0,race/* race */.S3)((0,timer/* timer */.H)(EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES), (0,event_listeners/* onKeyStatusesChange$ */.eX)(session)).pipe((0,take/* take */.q)(1), (0,mapTo/* mapTo */.h)(isLoaded)); })); } ;// CONCATENATED MODULE: ./src/core/eme/utils/is_session_usable.ts @@ -5533,8 +5570,6 @@ function getSession(initializationData, stores, wantedSessionType) { })); }); } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/ReplaySubject.js + 4 modules -var ReplaySubject = __webpack_require__(2135); // EXTERNAL MODULE: ./src/compat/eme/custom_media_keys/index.ts + 7 modules var custom_media_keys = __webpack_require__(6139); // EXTERNAL MODULE: ./src/core/eme/media_keys_infos_store.ts @@ -5608,6 +5643,49 @@ function attachMediaKeys(mediaElement, _ref) { })); }); } +// EXTERNAL MODULE: ./src/utils/starts_with.ts +var starts_with = __webpack_require__(9252); +;// CONCATENATED MODULE: ./src/core/eme/get_drm_system_id.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. + */ + +/** + * @param {string} keySystem + * @returns {string|undefined} + */ + +function getDrmSystemId(keySystem) { + if ((0,starts_with/* default */.Z)(keySystem, "com.microsoft.playready") || keySystem === "com.chromecast.playready" || keySystem === "com.youtube.playready") { + return "9a04f07998404286ab92e65be0885f95"; + } + + if (keySystem === "com.widevine.alpha") { + return "edef8ba979d64acea3c827dcd51d21ed"; + } + + if ((0,starts_with/* default */.Z)(keySystem, "com.apple.fps")) { + return "94ce86fb07ff4f43adb893d2fa968ca2"; + } + + if ((0,starts_with/* default */.Z)(keySystem, "com.nagra.")) { + return "adb41c242dbf4a6d958b4457c0d27b95"; + } + + return undefined; +} // EXTERNAL MODULE: ./src/compat/browser_detection.ts var browser_detection = __webpack_require__(3666); ;// CONCATENATED MODULE: ./src/compat/should_renew_media_keys.ts @@ -6066,10 +6144,6 @@ var serverCertificateHashesMap = new WeakMap(); return true; } }); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/race.js -var race = __webpack_require__(8821); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/timer.js -var timer = __webpack_require__(9604); ;// CONCATENATED MODULE: ./src/compat/eme/close_session.ts /** * Copyright 2015 CANAL+ Group @@ -6121,6 +6195,282 @@ function closeSession$(session) { })); }))); } +;// CONCATENATED MODULE: ./src/core/eme/utils/close_session.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 EME_SESSION_CLOSING_MAX_RETRY = config/* default.EME_SESSION_CLOSING_MAX_RETRY */.Z.EME_SESSION_CLOSING_MAX_RETRY, + EME_SESSION_CLOSING_INITIAL_DELAY = config/* default.EME_SESSION_CLOSING_INITIAL_DELAY */.Z.EME_SESSION_CLOSING_INITIAL_DELAY, + EME_SESSION_CLOSING_MAX_DELAY = config/* default.EME_SESSION_CLOSING_MAX_DELAY */.Z.EME_SESSION_CLOSING_MAX_DELAY; +/** + * Close a MediaKeySession with multiple attempts if needed and do not throw if + * this action throws an error. + * Emits then complete when done. + * @param {MediaKeySession} mediaKeySession + * @returns {Observable} + */ + +function safelyCloseMediaKeySession(mediaKeySession) { + return recursivelyTryToCloseMediaKeySession(0); + /** + * Perform a new attempt at closing the MediaKeySession. + * If this operation fails due to a not-"callable" (an EME term) + * MediaKeySession, retry based on either a timer or on MediaKeySession + * events, whichever comes first. + * Emits then complete when done. + * @param {number} retryNb - The attempt number starting at 0. + * @returns {Observable} + */ + + function recursivelyTryToCloseMediaKeySession(retryNb) { + log/* default.debug */.Z.debug("EME: Trying to close a MediaKeySession", mediaKeySession, retryNb); + return closeSession$(mediaKeySession).pipe((0,tap/* tap */.b)(function () { + log/* default.debug */.Z.debug("EME: Succeeded to close MediaKeySession"); + }), (0,catchError/* catchError */.K)(function (err) { + // Unitialized MediaKeySession may not close properly until their + // corresponding `generateRequest` or `load` call are handled by the + // browser. + // In that case the EME specification tells us that the browser is + // supposed to reject the `close` call with an InvalidStateError. + if (!(err instanceof Error) || err.name !== "InvalidStateError" || mediaKeySession.sessionId !== "") { + return failToCloseSession(err); + } // We will retry either: + // - when an event indicates that the MediaKeySession is + // initialized (`callable` is the proper EME term here) + // - after a delay, raising exponentially + + + var nextRetryNb = retryNb + 1; + + if (nextRetryNb > EME_SESSION_CLOSING_MAX_RETRY) { + return failToCloseSession(err); + } + + var delay = Math.min(Math.pow(2, retryNb) * EME_SESSION_CLOSING_INITIAL_DELAY, EME_SESSION_CLOSING_MAX_DELAY); + log/* default.warn */.Z.warn("EME: attempt to close a mediaKeySession failed, " + "scheduling retry...", delay); + return (0,race/* race */.S3)([(0,timer/* timer */.H)(delay), (0,event_listeners/* onKeyStatusesChange$ */.eX)(mediaKeySession), (0,event_listeners/* onKeyMessage$ */.GJ)(mediaKeySession)]).pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.zg)(function () { + return recursivelyTryToCloseMediaKeySession(nextRetryNb); + })); + })); + } + /** + * Log error anouncing that we could not close the MediaKeySession and emits + * then complete through Observable. + * TODO Emit warning? + * @returns {Observable} + */ + + + function failToCloseSession(err) { + log/* default.error */.Z.error("EME: Could not close MediaKeySession: " + (err instanceof Error ? err.toString() : "Unknown error")); + return (0,of.of)(null); + } +} +// EXTERNAL MODULE: ./src/utils/base64.ts +var utils_base64 = __webpack_require__(9689); +;// CONCATENATED MODULE: ./src/core/eme/utils/init_data_container.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. + */ + +/** Wrap initialization data and allow serialization of it into base64. */ + +var InitDataContainer = /*#__PURE__*/function () { + /** + * Create a new container, wrapping the initialization data given and allowing + * linearization into base64. + * @param {Uint8Array} + */ + function InitDataContainer(initData) { + this.initData = initData; + } + /** + * Convert it to base64. + * `toJSON` is specially interpreted by JavaScript engines to be able to rely + * on it when calling `JSON.stringify` on it or any of its parent objects: + * https://tc39.es/ecma262/#sec-serializejsonproperty + * @returns {string} + */ + + + var _proto = InitDataContainer.prototype; + + _proto.toJSON = function toJSON() { + return (0,utils_base64/* bytesToBase64 */.J)(this.initData); + } + /** + * Decode a base64 sequence representing an initialization data back to an + * Uint8Array. + * @param {string} + * @returns {Uint8Array} + */ + ; + + InitDataContainer.decode = function decode(base64) { + return (0,utils_base64/* base64ToBytes */.K)(base64); + }; + + return InitDataContainer; +}(); + + +;// CONCATENATED MODULE: ./src/core/eme/utils/are_init_values_compatible.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 both values are compatible initialization data, which + * means that one is completely contained in the other. + * + * Both values given should be sorted by systemId the same way. + * @param {Array.} stored + * @param {Array.} newElts + * @returns {boolean} + */ + +function areInitializationValuesCompatible(stored, newElts) { + var _a, _b; + + return (_b = (_a = _isAInB(stored, newElts)) !== null && _a !== void 0 ? _a : _isAInB(newElts, stored)) !== null && _b !== void 0 ? _b : false; +} +/** + * Take two arrays of initialization data values, `a` and `b`, sorted by + * their `systemId` property in the same order. + * + * Returns `true` if `a` is not empty and is completely contained in the `b` + * array. + * This is equivalent to: "`a` is contained in `b`". + * + * Returns `false` either if `a` is empty or if `b` has different initialization + * data than it for equivalent system ids. + * This is equivalent to: "`a` represents different data than `b`". + * + * Returns `null` if `a` is not fully contained in `b` but can still be + * compatible with it. + * This is equivalent to: "`a` is not contained in `b`, but `b` could be + * contained in `a`". + * @param {Array.} a + * @param {Array.} b + * @returns {boolean} + */ + +function _isAInB(a, b) { + if (a.length === 0) { + return false; + } + + if (b.length < a.length) { + return null; + } + + var firstAElt = a[0]; + var aIdx = 0; + var bIdx = 0; + + for (; bIdx < b.length; bIdx++) { + var bElt = b[bIdx]; + + if (bElt.systemId !== firstAElt.systemId) { + continue; + } + + if (bElt.hash !== firstAElt.hash) { + return false; + } + + var aData = firstAElt.data instanceof Uint8Array ? firstAElt.data : typeof firstAElt.data === "string" ? InitDataContainer.decode(firstAElt.data) : firstAElt.data.initData; + var bData = bElt.data instanceof Uint8Array ? bElt.data : typeof bElt.data === "string" ? InitDataContainer.decode(bElt.data) : bElt.data.initData; + + if (!(0,are_arrays_of_numbers_equal/* default */.Z)(aData, bData)) { + return false; + } + + if (b.length - bIdx < a.length) { + // not enough place to store `a`'s initialization data. + return null; + } // first `a` value was found. Check if all `a` values are found in `b` + + + for (aIdx = 1; aIdx < a.length; aIdx++) { + var aElt = a[aIdx]; + + for (bIdx += 1; bIdx < b.length; bIdx++) { + var bNewElt = b[bIdx]; + + if (aElt.systemId !== bNewElt.systemId) { + continue; + } + + if (aElt.hash !== bNewElt.hash) { + return false; + } + + var aNewData = aElt.data instanceof Uint8Array ? aElt.data : typeof aElt.data === "string" ? InitDataContainer.decode(aElt.data) : aElt.data.initData; + var bNewData = bNewElt.data instanceof Uint8Array ? bNewElt.data : typeof bNewElt.data === "string" ? InitDataContainer.decode(bNewElt.data) : bNewElt.data.initData; + + if (!(0,are_arrays_of_numbers_equal/* default */.Z)(aNewData, bNewData)) { + return false; + } + + break; + } + + if (aIdx === b.length) { + // we didn't find `aElt`'s systemId in b + return null; + } + } // If we're here, then we've found all `a`'s systemId in `b` and they match + + + return true; + } + + return null; // We didn't find the firstAElt`s systemId in `b`. +} ;// CONCATENATED MODULE: ./src/core/eme/utils/init_data_store.ts /** * Copyright 2015 CANAL+ Group @@ -6161,7 +6511,7 @@ var InitDataStore = /*#__PURE__*/function () { _proto.getAll = function getAll() { return this._storage.map(function (item) { - return item.value; + return item.payload; }); } /** @@ -6173,6 +6523,17 @@ var InitDataStore = /*#__PURE__*/function () { _proto.getLength = function getLength() { return this._storage.length; } + /** + * Returns `true` if no initialization data is stored yet in this + * InitDataStore. + * Returns `false` otherwise. + * @returns {boolean} + */ + ; + + _proto.isEmpty = function isEmpty() { + return this._storage.length === 0; + } /** * Returns the element associated with the given initData and initDataType. * Returns `undefined` if not found. @@ -6183,11 +6544,9 @@ var InitDataStore = /*#__PURE__*/function () { ; _proto.get = function get(initializationData) { - var initDataHash = (0,hash_buffer/* default */.Z)(initializationData.data); + var index = this._findIndex(initializationData); - var index = this._findIndex(initializationData, initDataHash); - - return index >= 0 ? this._storage[index].value : undefined; + return index >= 0 ? this._storage[index].payload : undefined; } /** * Like `get`, but also move the corresponding value at the end of the store @@ -6203,9 +6562,7 @@ var InitDataStore = /*#__PURE__*/function () { ; _proto.getAndReuse = function getAndReuse(initializationData) { - var initDataHash = (0,hash_buffer/* default */.Z)(initializationData.data); - - var index = this._findIndex(initializationData, initDataHash); + var index = this._findIndex(initializationData); if (index === -1) { return undefined; @@ -6215,22 +6572,19 @@ var InitDataStore = /*#__PURE__*/function () { this._storage.push(item); - return item.value; + return item.payload; } /** * Add to the store a value linked to the corresponding initData and * initDataType. * If a value was already stored linked to those, replace it. - * @param {Uint8Array} initData - * @param {string|undefined} initDataType - * @returns {boolean} + * @param {Object} initializationData + * @param {*} payload */ ; - _proto.store = function store(initializationData, value) { - var initDataHash = (0,hash_buffer/* default */.Z)(initializationData.data); - - var indexOf = this._findIndex(initializationData, initDataHash); + _proto.store = function store(initializationData, payload) { + var indexOf = this._findIndex(initializationData); if (indexOf >= 0) { // this._storage contains the stored value in the same order they have @@ -6239,11 +6593,12 @@ var InitDataStore = /*#__PURE__*/function () { this._storage.splice(indexOf, 1); } + var values = this._formatValuesForStore(initializationData.values); + this._storage.push({ - initData: initializationData.data, - initDataType: initializationData.type, - initDataHash: initDataHash, - value: value + type: initializationData.type, + values: values, + payload: payload }); } /** @@ -6257,26 +6612,25 @@ var InitDataStore = /*#__PURE__*/function () { * to see if a value is stored linked to that data - and then if not doing a * store. `storeIfNone` is more performant as it will only perform hashing * and a look-up a single time. - * @param {Uint8Array} initData - * @param {string|undefined} initDataType + * @param {Object} initializationData + * @param {*} payload * @returns {boolean} */ ; - _proto.storeIfNone = function storeIfNone(initializationData, value) { - var initDataHash = (0,hash_buffer/* default */.Z)(initializationData.data); - - var indexOf = this._findIndex(initializationData, initDataHash); + _proto.storeIfNone = function storeIfNone(initializationData, payload) { + var indexOf = this._findIndex(initializationData); if (indexOf >= 0) { return false; } + var values = this._formatValuesForStore(initializationData.values); + this._storage.push({ - initData: initializationData.data, - initDataType: initializationData.type, - initDataHash: initDataHash, - value: value + type: initializationData.type, + values: values, + payload: payload }); return true; @@ -6291,42 +6645,60 @@ var InitDataStore = /*#__PURE__*/function () { ; _proto.remove = function remove(initializationData) { - var initDataHash = (0,hash_buffer/* default */.Z)(initializationData.data); - - var indexOf = this._findIndex(initializationData, initDataHash); + var indexOf = this._findIndex(initializationData); if (indexOf === -1) { return undefined; } - return this._storage.splice(indexOf, 1)[0].value; + return this._storage.splice(indexOf, 1)[0].payload; } /** - * Find the index of the corresponding initData and initDataType in - * `this._storage`. Returns `-1` if not found. - * @param {Uint8Array} initData - * @param {string|undefined} initDataType - * @param {number} initDataHash + * Find the index of the corresponding initialization data in `this._storage`. + * Returns `-1` if not found. + * @param {Object} initializationData * @returns {boolean} */ ; - _proto._findIndex = function _findIndex(initializationData, initDataHash) { - var initDataType = initializationData.type, - initData = initializationData.data; // Begin by the last element as we usually re-encounter the last stored + _proto._findIndex = function _findIndex(initializationData) { + var formattedVals = this._formatValuesForStore(initializationData.values); // Begin by the last element as we usually re-encounter the last stored // initData sooner than the first one. + for (var i = this._storage.length - 1; i >= 0; i--) { var stored = this._storage[i]; - if (initDataHash === stored.initDataHash && initDataType === stored.initDataType) { - if ((0,are_arrays_of_numbers_equal/* default */.Z)(initData, stored.initData)) { + if (stored.type === initializationData.type) { + if (areInitializationValuesCompatible(stored.values, formattedVals)) { return i; } } } return -1; + } + /** + * Format given initializationData's values so they are ready to be stored: + * - sort them by systemId, so they are faster to compare + * - add hash for each initialization data encountered. + * @param {Array.} initialValues + * @returns {Array.} + */ + ; + + _proto._formatValuesForStore = function _formatValuesForStore(initialValues) { + return initialValues.slice().sort(function (a, b) { + return a.systemId === b.systemId ? 0 : a.systemId === undefined ? 1 : b.systemId === undefined ? -1 : a.systemId < b.systemId ? -1 : 1; + }).map(function (_ref) { + var systemId = _ref.systemId, + data = _ref.data; + return { + systemId: systemId, + data: data, + hash: (0,hash_buffer/* default */.Z)(data) + }; + }); }; return InitDataStore; @@ -6379,8 +6751,7 @@ var LoadedSessionsStore = /*#__PURE__*/function () { * Returns the stored MediaKeySession information related to the * given initDataType and initData if found. * Returns `null` if no such MediaKeySession is stored. - * @param {Uint8Array} initData - * @param {string|undefined} initDataType + * @param {Object} initializationData * @returns {Object|null} */ @@ -6400,11 +6771,10 @@ var LoadedSessionsStore = /*#__PURE__*/function () { * its internal storage, as returned by the `getAll` method. * * This can be used for example to tell when a previously-stored - * MediaKeySession is re-used to then be able to implement a caching + * initialization data is re-used to then be able to implement a caching * replacement algorithm based on the least-recently-used values by just * evicting the first values returned by `getAll`. - * @param {Uint8Array} initData - * @param {string|undefined} initDataType + * @param {Object} initializationData * @returns {Object|null} */ ; @@ -6417,11 +6787,29 @@ var LoadedSessionsStore = /*#__PURE__*/function () { sessionType: entry.sessionType }; } + /** + * Moves the corresponding MediaKeySession to the end of its internal storage, + * as returned by the `getAll` method. + * + * This can be used to signal that a previously-stored initialization data is + * re-used to then be able to implement a caching replacement algorithm based + * on the least-recently-used values by just evicting the first values + * returned by `getAll`. + * + * Returns `true` if the corresponding session was found in the store, `false` + * otherwise. + * @param {Object} initializationData + * @returns {boolean} + */ + ; + + _proto.reuse = function reuse(initializationData) { + return this._storage.getAndReuse(initializationData) !== undefined; + } /** * Create a new MediaKeySession and store it in this store. * @throws {EncryptedMediaError} - * @param {Uint8Array} initData - * @param {string|undefined} initDataType + * @param {Object} initializationData * @param {string} sessionType * @returns {MediaKeySession} */ @@ -6465,8 +6853,7 @@ var LoadedSessionsStore = /*#__PURE__*/function () { * Close a MediaKeySession corresponding to an initialization data and remove * its related stored information from the LoadedSessionsStore. * Emit when done. - * @param {Uint8Array} initData - * @param {string|undefined} initDataType + * @param {Object} initializationData * @returns {Observable} */ ; @@ -6530,26 +6917,10 @@ var LoadedSessionsStore = /*#__PURE__*/function () { return LoadedSessionsStore; }(); -/** - * Close a MediaKeySession and do not throw if this action throws an error. - * @param {MediaKeySession} mediaKeySession - * @returns {Observable} - */ - - -function safelyCloseMediaKeySession(mediaKeySession) { - log/* default.debug */.Z.debug("EME-LSS: Close MediaKeySession", mediaKeySession); - return closeSession$(mediaKeySession).pipe((0,catchError/* catchError */.K)(function (err) { - log/* default.error */.Z.error("EME-LSS: Could not close MediaKeySession: " + (err instanceof Error ? err.toString() : "Unknown error")); - return (0,of.of)(null); - })); -} // EXTERNAL MODULE: ./src/utils/assert.ts var assert = __webpack_require__(811); -// EXTERNAL MODULE: ./src/utils/base64.ts -var utils_base64 = __webpack_require__(9689); // EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts var is_non_empty_string = __webpack_require__(6923); ;// CONCATENATED MODULE: ./src/core/eme/utils/persistent_sessions_store.ts @@ -6575,6 +6946,8 @@ var is_non_empty_string = __webpack_require__(6923); + + /** * Throw if the given storage does not respect the right interface. * @param {Object} storage @@ -6586,10 +6959,10 @@ function checkStorage(storage) { load: "function" }, "licenseStorage"); } -/** Wrap initialization data and allow linearization of it into base64. */ +/** Wrap initialization data and allow serialization of it into base64. */ -var InitDataContainer = /*#__PURE__*/function () { +var persistent_sessions_store_InitDataContainer = /*#__PURE__*/function () { /** * Create a new container, wrapping the initialization data given and allowing * linearization into base64. @@ -6742,14 +7115,12 @@ var PersistentSessionsStore = /*#__PURE__*/function () { this["delete"](initData); } - var hash = (0,hash_buffer/* default */.Z)(initData.data); log/* default.info */.Z.info("EME-PSS: Add new session", sessionId, session); this._entries.push({ - version: 2, + version: 3, sessionId: sessionId, - initData: new InitDataContainer(initData.data), - initDataHash: hash, + values: this._formatValuesForStore(initData.values), initDataType: initData.type }); @@ -6815,40 +7186,62 @@ var PersistentSessionsStore = /*#__PURE__*/function () { ; _proto2._getIndex = function _getIndex(initData) { - var hash = (0,hash_buffer/* default */.Z)(initData.data); + var formatted = this._formatValuesForStore(initData.values); // Older versions of the format include a concatenation of all + // initialization data and its hash. + + + var concatInitData = byte_parsing/* concat.apply */.zo.apply(void 0, initData.values.map(function (i) { + return i.data; + })); + var concatInitDataHash = (0,hash_buffer/* default */.Z)(concatInitData); for (var i = 0; i < this._entries.length; i++) { var entry = this._entries[i]; if (entry.initDataType === initData.type) { - if (entry.version === 2) { - if (entry.initDataHash === hash) { - try { - var decodedInitData = typeof entry.initData === "string" ? InitDataContainer.decode(entry.initData) : entry.initData.initData; + switch (entry.version) { + case 3: + if (areInitializationValuesCompatible(formatted, entry.values)) { + return i; + } + + break; + + case 2: + if (entry.initDataHash === concatInitDataHash) { + try { + var decodedInitData = typeof entry.initData === "string" ? persistent_sessions_store_InitDataContainer.decode(entry.initData) : entry.initData.initData; + + if ((0,are_arrays_of_numbers_equal/* default */.Z)(decodedInitData, concatInitData)) { + return i; + } + } catch (e) { + log/* default.warn */.Z.warn("EME-PSS: Could not decode initialization data.", e); + } + } - if ((0,are_arrays_of_numbers_equal/* default */.Z)(decodedInitData, initData.data)) { + break; + + case 1: + if (entry.initDataHash === concatInitDataHash) { + if (typeof entry.initData.length === "undefined") { + // If length is undefined, it has been linearized. We could still + // convert it back to an Uint8Array but this would necessitate some + // ugly unreadable logic for a very very minor possibility. + // Just consider that it is a match based on the hash. + return i; + } else if ((0,are_arrays_of_numbers_equal/* default */.Z)(entry.initData, concatInitData)) { return i; } - } catch (e) { - log/* default.warn */.Z.warn("EME-PSS: Could not decode initialization data.", e); } - } - } else if (entry.version === 1) { - if (entry.initDataHash === hash) { - if (typeof entry.initData.length === "undefined") { - // If length is undefined, it has been linearized. We could still - // convert it back to an Uint8Array but this would necessitate some - // ugly unreadable logic for a very very minor possibility. - // Just consider that it is a match based on the hash. - return i; - } else if ((0,are_arrays_of_numbers_equal/* default */.Z)(entry.initData, initData.data)) { + + break; + + default: + if (entry.initData === concatInitDataHash) { return i; } - } - } else { - if (entry.initData === hash) { - return i; - } + } } } @@ -6866,6 +7259,28 @@ var PersistentSessionsStore = /*#__PURE__*/function () { } catch (e) { log/* default.warn */.Z.warn("EME-PSS: Could not save licenses in localStorage"); } + } + /** + * Format given initializationData's values so they are ready to be stored: + * - sort them by systemId, so they are faster to compare + * - add hash for each initialization data encountered. + * @param {Array.} initialValues + * @returns {Array.} + */ + ; + + _proto2._formatValuesForStore = function _formatValuesForStore(initialValues) { + return initialValues.slice().sort(function (a, b) { + return a.systemId === b.systemId ? 0 : a.systemId === undefined ? 1 : b.systemId === undefined ? -1 : a.systemId < b.systemId ? -1 : 1; + }).map(function (_ref) { + var systemId = _ref.systemId, + data = _ref.data; + return { + systemId: systemId, + data: new persistent_sessions_store_InitDataContainer(data), + hash: (0,hash_buffer/* default */.Z)(data) + }; + }); }; return PersistentSessionsStore; @@ -7006,6 +7421,8 @@ function createMediaKeys(mediaKeySystemAccess) { + + /** * Get media keys infos from key system configs then attach media keys to media element. * @param {HTMLMediaElement} mediaElement @@ -7019,12 +7436,33 @@ function initMediaKeys(mediaElement, keySystemsConfigs) { mediaKeySystemAccess = _ref.mediaKeySystemAccess, stores = _ref.stores, options = _ref.options; + + /** + * String identifying the key system, allowing the rest of the code to + * only advertise the required initialization data for license requests. + * + * Note that we only set this value if retro-compatibility to older + * persistent logic in the RxPlayer is not important, as the optimizations + * this property unlocks can break the loading of MediaKeySessions + * persisted in older RxPlayer's versions. + */ + var initializationDataSystemId; + + if ((0,is_null_or_undefined/* default */.Z)(options.licenseStorage) || options.licenseStorage.disableRetroCompatibility === true) { + initializationDataSystemId = getDrmSystemId(mediaKeySystemAccess.keySystem); + } + var attachMediaKeys$ = new ReplaySubject/* ReplaySubject */.t(1); var shouldDisableOldMediaKeys = mediaElement.mediaKeys !== null && mediaElement.mediaKeys !== undefined && mediaKeys !== mediaElement.mediaKeys; - var disableOldMediaKeys$ = shouldDisableOldMediaKeys ? disableMediaKeys(mediaElement) : (0,of.of)(null); - log/* default.debug */.Z.debug("EME: Disabling old MediaKeys"); + var disableOldMediaKeys$ = (0,of.of)(null); + + if (shouldDisableOldMediaKeys) { + log/* default.debug */.Z.debug("EME: Disabling old MediaKeys"); + disableOldMediaKeys$ = disableMediaKeys(mediaElement); + } + return disableOldMediaKeys$.pipe((0,mergeMap/* mergeMap */.zg)(function () { - log/* default.debug */.Z.debug("EME: Disabled old MediaKeys. Waiting to attach new MediaKeys"); + log/* default.debug */.Z.debug("EME: Attaching current MediaKeys"); return attachMediaKeys$.pipe((0,mergeMap/* mergeMap */.zg)(function () { var stateToAttatch = { loadedSessionsStore: stores.loadedSessionsStore, @@ -7045,6 +7483,7 @@ function initMediaKeys(mediaElement, keySystemsConfigs) { type: "created-media-keys", value: { mediaKeySystemAccess: mediaKeySystemAccess, + initializationDataSystemId: initializationDataSystemId, mediaKeys: mediaKeys, stores: stores, options: options, @@ -7054,15 +7493,12 @@ function initMediaKeys(mediaElement, keySystemsConfigs) { })); })); } -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/assertThisInitialized.js -var assertThisInitialized = __webpack_require__(1506); -var assertThisInitialized_default = /*#__PURE__*/__webpack_require__.n(assertThisInitialized); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/inheritsLoose.js -var inheritsLoose = __webpack_require__(5354); -var inheritsLoose_default = /*#__PURE__*/__webpack_require__.n(inheritsLoose); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/wrapNativeSuper.js -var wrapNativeSuper = __webpack_require__(5957); -var wrapNativeSuper_default = /*#__PURE__*/__webpack_require__.n(wrapNativeSuper); +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js +var assertThisInitialized = __webpack_require__(3349); +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js +var inheritsLoose = __webpack_require__(1788); +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js + 4 modules +var wrapNativeSuper = __webpack_require__(3786); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subject.js var Subject = __webpack_require__(211); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/identity.js @@ -7321,19 +7757,20 @@ var KEY_STATUSES = { }; /** * Look at the current key statuses in the sessions and construct the - * appropriate warnings and blacklisted key ids. + * appropriate warnings, whitelisted and blacklisted key ids. * * Throws if one of the keyID is on an error. * @param {MediaKeySession} session - The MediaKeySession from which the keys * will be checked. * @param {Object} options * @param {String} keySystem - The configuration keySystem used for deciphering - * @returns {Array} - Warnings to send and blacklisted key ids. + * @returns {Object} - Warnings to send, whitelisted and blacklisted key ids. */ function checkKeyStatuses(session, options, keySystem) { var warnings = []; var blacklistedKeyIDs = []; + var whitelistedKeyIds = []; var _options$fallbackOn = options.fallbackOn, fallbackOn = _options$fallbackOn === void 0 ? {} : _options$fallbackOn, throwOnLicenseExpiration = options.throwOnLicenseExpiration; @@ -7368,6 +7805,7 @@ function checkKeyStatuses(session, options, keySystem) { type: "warning", value: error }); + whitelistedKeyIds.push(keyId); break; } @@ -7402,287 +7840,306 @@ function checkKeyStatuses(session, options, keySystem) { blacklistedKeyIDs.push(keyId); break; } - } - }); - return [warnings, blacklistedKeyIDs]; -} -;// CONCATENATED MODULE: ./src/core/eme/session_events_listener.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 onKeyError$ = event_listeners/* onKeyError$ */.Xe, - onKeyMessage$ = event_listeners/* onKeyMessage$ */.GJ, - onKeyStatusesChange$ = event_listeners/* onKeyStatusesChange$ */.eX; -/** - * Error thrown when the MediaKeySession is blacklisted. - * Such MediaKeySession should not be re-used but other MediaKeySession for the - * same content can still be used. - * @class BlacklistedSessionError - * @extends Error - */ - -var BlacklistedSessionError = /*#__PURE__*/function (_Error) { - inheritsLoose_default()(BlacklistedSessionError, _Error); - - function BlacklistedSessionError(sessionError) { - var _this; - - _this = _Error.call(this) || this; // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class - - Object.setPrototypeOf(assertThisInitialized_default()(_this), BlacklistedSessionError.prototype); - _this.sessionError = sessionError; - return _this; - } - - return BlacklistedSessionError; -}( /*#__PURE__*/wrapNativeSuper_default()(Error)); -/** - * listen to various events from a MediaKeySession and react accordingly - * depending on the configuration given. - * @param {MediaKeySession} session - The MediaKeySession concerned. - * @param {Object} keySystemOptions - The key system options. - * @param {String} keySystem - The configuration keySystem used for deciphering - * @param {Object} initializationData - The initialization data linked to that - * session. - * @returns {Observable} - */ - -function SessionEventsListener(session, keySystemOptions, keySystem, initializationData) { - log/* default.info */.Z.info("EME: Binding session events", session); - var sessionWarningSubject$ = new Subject/* Subject */.xQ(); - var _keySystemOptions$get = keySystemOptions.getLicenseConfig, - getLicenseConfig = _keySystemOptions$get === void 0 ? {} : _keySystemOptions$get; - var keyErrors = onKeyError$(session).pipe((0,map/* map */.U)(function (error) { - throw new encrypted_media_error/* default */.Z("KEY_ERROR", error.type); - })); - var keyStatusesChange$ = onKeyStatusesChange$(session).pipe((0,mergeMap/* mergeMap */.zg)(function (keyStatusesEvent) { - return handleKeyStatusesChangeEvent(session, keySystemOptions, keySystem, keyStatusesEvent); - })); - var keyMessages$ = onKeyMessage$(session).pipe((0,mergeMap/* mergeMap */.zg)(function (messageEvent) { - var message = new Uint8Array(messageEvent.message); - var messageType = (0,is_non_empty_string/* default */.Z)(messageEvent.messageType) ? messageEvent.messageType : "license-request"; - log/* default.info */.Z.info("EME: Received message event, type " + messageType, session, messageEvent); - var getLicense$ = (0,defer/* defer */.P)(function () { - var getLicense = keySystemOptions.getLicense(message, messageType); - var getLicenseTimeout = (0,is_null_or_undefined/* default */.Z)(getLicenseConfig.timeout) ? 10 * 1000 : getLicenseConfig.timeout; - return (0,cast_to_observable/* default */.Z)(getLicense).pipe(getLicenseTimeout >= 0 ? timeout(getLicenseTimeout) : identity/* identity */.y - /* noop */ - ); - }); - var backoffOptions = getLicenseBackoffOptions(sessionWarningSubject$, getLicenseConfig.retry); - return retryObsWithBackoff(getLicense$, backoffOptions).pipe((0,map/* map */.U)(function (licenseObject) { - return { - type: "key-message-handled", - value: { - session: session, - license: licenseObject - } - }; - }), (0,catchError/* catchError */.K)(function (err) { - var formattedError = formatGetLicenseError(err); - - if (!(0,is_null_or_undefined/* default */.Z)(err)) { - var fallbackOnLastTry = err.fallbackOnLastTry; - - if (fallbackOnLastTry === true) { - log/* default.warn */.Z.warn("EME: Last `getLicense` attempt failed. " + "Blacklisting the current session."); - throw new BlacklistedSessionError(formattedError); - } - } - - throw formattedError; - }), (0,startWith/* startWith */.O)({ - type: "session-message", - value: { - messageType: messageType, - initializationData: initializationData - } - })); - })); - var sessionUpdates = (0,merge/* merge */.T)(keyMessages$, keyStatusesChange$).pipe(concatMap(function (evt) { - switch (evt.type) { - case "key-message-handled": - case "key-status-change-handled": - return updateSessionWithMessage(session, evt.value.license, initializationData); default: - return (0,of.of)(evt); + whitelistedKeyIds.push(keyId); + break; } - })); - var sessionEvents = (0,merge/* merge */.T)(getKeyStatusesEvents(session, keySystemOptions, keySystem), sessionUpdates, keyErrors, sessionWarningSubject$); - return !(0,is_null_or_undefined/* default */.Z)(session.closed) ? sessionEvents.pipe((0,takeUntil/* takeUntil */.R)((0,cast_to_observable/* default */.Z)(session.closed))) : sessionEvents; -} -/** - * Check current MediaKeyStatus for each key in the given MediaKeySession and - * return an Observable which either: - * - throw if at least one status is a non-recoverable error - * - emit warning events for recoverable errors - * - emit blacklist-keys events for key IDs that are not decipherable - * @param {MediaKeySession} session - The MediaKeySession concerned. - * @param {Object} options - Options related to key statuses checks. - * @param {String} keySystem - The name of the key system used for deciphering - * @returns {Observable} - */ - -function getKeyStatusesEvents(session, options, keySystem) { - return (0,defer/* defer */.P)(function () { - var _checkKeyStatuses = checkKeyStatuses(session, options, keySystem), - warnings = _checkKeyStatuses[0], - blacklistedKeyIDs = _checkKeyStatuses[1]; - - var warnings$ = warnings.length > 0 ? of.of.apply(void 0, warnings) : empty/* EMPTY */.E; - var blackListUpdate$ = blacklistedKeyIDs.length > 0 ? (0,of.of)({ - type: "blacklist-keys", - value: blacklistedKeyIDs - }) : empty/* EMPTY */.E; - return (0,concat/* concat */.z)(warnings$, blackListUpdate$); }); + return { + warnings: warnings, + blacklistedKeyIDs: blacklistedKeyIDs, + whitelistedKeyIds: whitelistedKeyIds + }; } -/** - * Format an error returned by a `getLicense` call to a proper form as defined - * by the RxPlayer's API. - * @param {*} error - * @returns {Error} - */ - - -function formatGetLicenseError(error) { - if (error instanceof TimeoutError) { - return new encrypted_media_error/* default */.Z("KEY_LOAD_TIMEOUT", "The license server took too much time to " + "respond."); - } - - var err = new encrypted_media_error/* default */.Z("KEY_LOAD_ERROR", "An error occured when calling `getLicense`."); - - if (!(0,is_null_or_undefined/* default */.Z)(error) && (0,is_non_empty_string/* default */.Z)(error.message)) { - err.message = error.message; - } - - return err; -} -/** - * Call MediaKeySession.update with the given `message`, if defined. - * Returns the right event depending on the action taken. - * @param {MediaKeySession} session - * @param {ArrayBuffer|TypedArray|null} message - * @param {Object} initializationData - * @returns {Observable} - */ - - -function updateSessionWithMessage(session, message, initializationData) { - if ((0,is_null_or_undefined/* default */.Z)(message)) { - log/* default.info */.Z.info("EME: No message given, skipping session.update"); - return (0,of.of)({ - type: "no-update", - value: { - initializationData: initializationData - } - }); - } - - log/* default.info */.Z.info("EME: Updating MediaKeySession with message"); - return (0,cast_to_observable/* default */.Z)(session.update(message)).pipe((0,catchError/* catchError */.K)(function (error) { - var reason = error instanceof Error ? error.toString() : "`session.update` failed"; - throw new encrypted_media_error/* default */.Z("KEY_UPDATE_ERROR", reason); - }), (0,tap/* tap */.b)(function () { - log/* default.info */.Z.info("EME: MediaKeySession update succeeded."); - }), (0,mapTo/* mapTo */.h)({ - type: "session-updated", - value: { - session: session, - license: message, - initializationData: initializationData - } - })); -} -/** - * @param {MediaKeySession} - * @param {Object} keySystem - * @param {Event} keyStatusesEvent - * @returns {Observable} - */ - - -function handleKeyStatusesChangeEvent(session, keySystemOptions, keySystem, keyStatusesEvent) { - log/* default.info */.Z.info("EME: keystatuseschange event received", session, keyStatusesEvent); - var callback$ = (0,defer/* defer */.P)(function () { - if (typeof keySystemOptions.onKeyStatusesChange !== "function") { - return empty/* EMPTY */.E; - } +;// CONCATENATED MODULE: ./src/core/eme/session_events_listener.ts - return (0,cast_to_observable/* default */.Z)(keySystemOptions.onKeyStatusesChange(keyStatusesEvent, session)); - }).pipe((0,map/* map */.U)(function (licenseObject) { - return { - type: "key-status-change-handled", - value: { - session: session, - license: licenseObject - } - }; - }), (0,catchError/* catchError */.K)(function (error) { - var err = new encrypted_media_error/* default */.Z("KEY_STATUS_CHANGE_ERROR", "Unknown `onKeyStatusesChange` error"); - if (!(0,is_null_or_undefined/* default */.Z)(error) && (0,is_non_empty_string/* default */.Z)(error.message)) { - err.message = error.message; - } - - throw err; - })); - return (0,concat/* concat */.z)(getKeyStatusesEvents(session, keySystemOptions, keySystem), callback$); -} -/** - * Construct backoff options for the getLicense call. - * @param {Subject} sessionWarningSubject$ - Subject through which retry - * warnings will be sent. - * @param {number|undefined} numberOfRetry - Maximum of amount retried. - * Equal to `2` if not defined. - * @returns {Object} - */ -function getLicenseBackoffOptions(sessionWarningSubject$, numberOfRetry) { - return { - totalRetry: numberOfRetry !== null && numberOfRetry !== void 0 ? numberOfRetry : 2, - baseDelay: 200, - maxDelay: 3000, - shouldRetry: function shouldRetry(error) { - return error instanceof TimeoutError || (0,is_null_or_undefined/* default */.Z)(error) || error.noRetry !== true; - }, - onRetry: function onRetry(error) { - return sessionWarningSubject$.next({ - type: "warning", - value: formatGetLicenseError(error) - }); - } - }; -} -;// CONCATENATED MODULE: ./src/core/eme/set_server_certificate.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 onKeyError$ = event_listeners/* onKeyError$ */.Xe, + onKeyMessage$ = event_listeners/* onKeyMessage$ */.GJ, + onKeyStatusesChange$ = event_listeners/* onKeyStatusesChange$ */.eX; +/** + * Error thrown when the MediaKeySession is blacklisted. + * Such MediaKeySession should not be re-used but other MediaKeySession for the + * same content can still be used. + * @class BlacklistedSessionError + * @extends Error + */ + +var BlacklistedSessionError = /*#__PURE__*/function (_Error) { + (0,inheritsLoose/* default */.Z)(BlacklistedSessionError, _Error); + + function BlacklistedSessionError(sessionError) { + var _this; + + _this = _Error.call(this) || this; // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class + + Object.setPrototypeOf((0,assertThisInitialized/* default */.Z)(_this), BlacklistedSessionError.prototype); + _this.sessionError = sessionError; + return _this; + } + + return BlacklistedSessionError; +}( /*#__PURE__*/(0,wrapNativeSuper/* default */.Z)(Error)); +/** + * listen to various events from a MediaKeySession and react accordingly + * depending on the configuration given. + * @param {MediaKeySession} session - The MediaKeySession concerned. + * @param {Object} keySystemOptions - The key system options. + * @param {String} keySystem - The configuration keySystem used for deciphering + * @param {Object} initializationData - The initialization data linked to that + * session. + * @returns {Observable} + */ + +function SessionEventsListener(session, keySystemOptions, keySystem, initializationData) { + log/* default.info */.Z.info("EME: Binding session events", session); + var sessionWarningSubject$ = new Subject/* Subject */.xQ(); + var _keySystemOptions$get = keySystemOptions.getLicenseConfig, + getLicenseConfig = _keySystemOptions$get === void 0 ? {} : _keySystemOptions$get; + var keyErrors = onKeyError$(session).pipe((0,map/* map */.U)(function (error) { + throw new encrypted_media_error/* default */.Z("KEY_ERROR", error.type); + })); + var keyStatusesChange$ = onKeyStatusesChange$(session).pipe((0,mergeMap/* mergeMap */.zg)(function (keyStatusesEvent) { + return handleKeyStatusesChangeEvent(session, keySystemOptions, keySystem, keyStatusesEvent); + })); + var keyMessages$ = onKeyMessage$(session).pipe((0,mergeMap/* mergeMap */.zg)(function (messageEvent) { + var message = new Uint8Array(messageEvent.message); + var messageType = (0,is_non_empty_string/* default */.Z)(messageEvent.messageType) ? messageEvent.messageType : "license-request"; + log/* default.info */.Z.info("EME: Received message event, type " + messageType, session, messageEvent); + var getLicense$ = (0,defer/* defer */.P)(function () { + var getLicense = keySystemOptions.getLicense(message, messageType); + var getLicenseTimeout = (0,is_null_or_undefined/* default */.Z)(getLicenseConfig.timeout) ? 10 * 1000 : getLicenseConfig.timeout; + return (0,cast_to_observable/* default */.Z)(getLicense).pipe(getLicenseTimeout >= 0 ? timeout(getLicenseTimeout) : identity/* identity */.y + /* noop */ + ); + }); + var backoffOptions = getLicenseBackoffOptions(sessionWarningSubject$, getLicenseConfig.retry); + return retryObsWithBackoff(getLicense$, backoffOptions).pipe((0,map/* map */.U)(function (licenseObject) { + return { + type: "key-message-handled", + value: { + session: session, + license: licenseObject + } + }; + }), (0,catchError/* catchError */.K)(function (err) { + var formattedError = formatGetLicenseError(err); + + if (!(0,is_null_or_undefined/* default */.Z)(err)) { + var fallbackOnLastTry = err.fallbackOnLastTry; + + if (fallbackOnLastTry === true) { + log/* default.warn */.Z.warn("EME: Last `getLicense` attempt failed. " + "Blacklisting the current session."); + throw new BlacklistedSessionError(formattedError); + } + } + + throw formattedError; + }), (0,startWith/* startWith */.O)({ + type: "session-message", + value: { + messageType: messageType, + initializationData: initializationData + } + })); + })); + var sessionUpdates = (0,merge/* merge */.T)(keyMessages$, keyStatusesChange$).pipe(concatMap(function (evt) { + switch (evt.type) { + case "key-message-handled": + case "key-status-change-handled": + return updateSessionWithMessage(session, evt.value.license, initializationData); + + default: + return (0,of.of)(evt); + } + })); + var sessionEvents = (0,merge/* merge */.T)(getKeyStatusesEvents(session, keySystemOptions, keySystem), sessionUpdates, keyErrors, sessionWarningSubject$); + return !(0,is_null_or_undefined/* default */.Z)(session.closed) ? sessionEvents.pipe((0,takeUntil/* takeUntil */.R)((0,cast_to_observable/* default */.Z)(session.closed))) : sessionEvents; +} +/** + * Check current MediaKeyStatus for each key in the given MediaKeySession and + * return an Observable which either: + * - throw if at least one status is a non-recoverable error + * - emit warning events for recoverable errors + * - emit blacklist-keys events for key IDs that are not decipherable + * @param {MediaKeySession} session - The MediaKeySession concerned. + * @param {Object} options - Options related to key statuses checks. + * @param {String} keySystem - The name of the key system used for deciphering + * @returns {Observable} + */ + +function getKeyStatusesEvents(session, options, keySystem) { + return (0,defer/* defer */.P)(function () { + if (session.keyStatuses.size === 0) { + return empty/* EMPTY */.E; + } + + var _checkKeyStatuses = checkKeyStatuses(session, options, keySystem), + warnings = _checkKeyStatuses.warnings, + blacklistedKeyIDs = _checkKeyStatuses.blacklistedKeyIDs, + whitelistedKeyIds = _checkKeyStatuses.whitelistedKeyIds; + + var warnings$ = warnings.length > 0 ? of.of.apply(void 0, warnings) : empty/* EMPTY */.E; + var keysUpdate$ = (0,of.of)({ + type: "keys-update", + value: { + whitelistedKeyIds: whitelistedKeyIds, + blacklistedKeyIDs: blacklistedKeyIDs + } + }); + return (0,concat/* concat */.z)(warnings$, keysUpdate$); + }); +} +/** + * Format an error returned by a `getLicense` call to a proper form as defined + * by the RxPlayer's API. + * @param {*} error + * @returns {Error} + */ + + +function formatGetLicenseError(error) { + if (error instanceof TimeoutError) { + return new encrypted_media_error/* default */.Z("KEY_LOAD_TIMEOUT", "The license server took too much time to " + "respond."); + } + + var err = new encrypted_media_error/* default */.Z("KEY_LOAD_ERROR", "An error occured when calling `getLicense`."); + + if (!(0,is_null_or_undefined/* default */.Z)(error) && (0,is_non_empty_string/* default */.Z)(error.message)) { + err.message = error.message; + } + + return err; +} +/** + * Call MediaKeySession.update with the given `message`, if defined. + * Returns the right event depending on the action taken. + * @param {MediaKeySession} session + * @param {ArrayBuffer|TypedArray|null} message + * @param {Object} initializationData + * @returns {Observable} + */ + + +function updateSessionWithMessage(session, message, initializationData) { + if ((0,is_null_or_undefined/* default */.Z)(message)) { + log/* default.info */.Z.info("EME: No message given, skipping session.update"); + return (0,of.of)({ + type: "no-update", + value: { + initializationData: initializationData + } + }); + } + + log/* default.info */.Z.info("EME: Updating MediaKeySession with message"); + return (0,cast_to_observable/* default */.Z)(session.update(message)).pipe((0,catchError/* catchError */.K)(function (error) { + var reason = error instanceof Error ? error.toString() : "`session.update` failed"; + throw new encrypted_media_error/* default */.Z("KEY_UPDATE_ERROR", reason); + }), (0,tap/* tap */.b)(function () { + log/* default.info */.Z.info("EME: MediaKeySession update succeeded."); + }), (0,mapTo/* mapTo */.h)({ + type: "session-updated", + value: { + session: session, + license: message, + initializationData: initializationData + } + })); +} +/** + * @param {MediaKeySession} + * @param {Object} keySystem + * @param {Event} keyStatusesEvent + * @returns {Observable} + */ + + +function handleKeyStatusesChangeEvent(session, keySystemOptions, keySystem, keyStatusesEvent) { + log/* default.info */.Z.info("EME: keystatuseschange event received", session, keyStatusesEvent); + var callback$ = (0,defer/* defer */.P)(function () { + return (0,rx_try_catch/* default */.Z)(function () { + if (typeof keySystemOptions.onKeyStatusesChange !== "function") { + return empty/* EMPTY */.E; + } + + return (0,cast_to_observable/* default */.Z)(keySystemOptions.onKeyStatusesChange(keyStatusesEvent, session)); + }, undefined); + }).pipe((0,map/* map */.U)(function (licenseObject) { + return { + type: "key-status-change-handled", + value: { + session: session, + license: licenseObject + } + }; + }), (0,catchError/* catchError */.K)(function (error) { + var err = new encrypted_media_error/* default */.Z("KEY_STATUS_CHANGE_ERROR", "Unknown `onKeyStatusesChange` error"); + + if (!(0,is_null_or_undefined/* default */.Z)(error) && (0,is_non_empty_string/* default */.Z)(error.message)) { + err.message = error.message; + } + + throw err; + })); + return (0,merge/* merge */.T)(getKeyStatusesEvents(session, keySystemOptions, keySystem), callback$); +} +/** + * Construct backoff options for the getLicense call. + * @param {Subject} sessionWarningSubject$ - Subject through which retry + * warnings will be sent. + * @param {number|undefined} numberOfRetry - Maximum of amount retried. + * Equal to `2` if not defined. + * @returns {Object} + */ + + +function getLicenseBackoffOptions(sessionWarningSubject$, numberOfRetry) { + return { + totalRetry: numberOfRetry !== null && numberOfRetry !== void 0 ? numberOfRetry : 2, + baseDelay: 200, + maxDelay: 3000, + shouldRetry: function shouldRetry(error) { + return error instanceof TimeoutError || (0,is_null_or_undefined/* default */.Z)(error) || error.noRetry !== true; + }, + onRetry: function onRetry(error) { + return sessionWarningSubject$.next({ + type: "warning", + value: formatGetLicenseError(error) + }); + } + }; +} +;// CONCATENATED MODULE: ./src/core/eme/set_server_certificate.ts /** * Copyright 2015 CANAL+ Group * @@ -7802,6 +8259,8 @@ function trySettingServerCertificate(mediaKeys, serverCertificate) { + + var EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION = config/* default.EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION */.Z.EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION; var onEncrypted$ = event_listeners/* onEncrypted$ */.Oh; /** @@ -7821,15 +8280,16 @@ var onEncrypted$ = event_listeners/* onEncrypted$ */.Oh; function EMEManager(mediaElement, keySystemsConfigs, contentProtections$) { log/* default.debug */.Z.debug("EME: Starting EMEManager logic."); /** - * Keep track of all initialization data handled for the current `EMEManager` - * instance. - * This allows to avoid handling multiple times the same encrypted events. + * Keep track of all decryption keys handled by this instance of the + * `EMEManager`. + * This allows to avoid creating multiple MediaKeySessions handling the same + * decryption keys. */ - var handledInitData = new InitDataStore(); + var contentSessions = new InitDataStore(); /** - * Keep track of which initialization data have been blacklisted (linked to - * non-decypherable content). + * Keep track of which initialization data have been blacklisted in the + * current instance of the `EMEManager`. * If the same initialization data is encountered again, we can directly emit * the same `BlacklistedSessionError`. */ @@ -7837,7 +8297,22 @@ function EMEManager(mediaElement, keySystemsConfigs, contentProtections$) { var blacklistedInitData = new InitDataStore(); /** Emit the MediaKeys instance and its related information when ready. */ - var mediaKeysInit$ = initMediaKeys(mediaElement, keySystemsConfigs).pipe((0,shareReplay/* shareReplay */.d)()); // Share side-effects and cache success + var mediaKeysInit$ = initMediaKeys(mediaElement, keySystemsConfigs).pipe((0,mergeMap/* mergeMap */.zg)(function (mediaKeysEvt) { + if (mediaKeysEvt.type !== "attached-media-keys") { + return (0,of.of)(mediaKeysEvt); + } + + var _mediaKeysEvt$value = mediaKeysEvt.value, + mediaKeys = _mediaKeysEvt$value.mediaKeys, + options = _mediaKeysEvt$value.options; + var serverCertificate = options.serverCertificate; + + if ((0,is_null_or_undefined/* default */.Z)(serverCertificate)) { + return (0,of.of)(mediaKeysEvt); + } + + return (0,concat/* concat */.z)(trySettingServerCertificate(mediaKeys, serverCertificate), (0,of.of)(mediaKeysEvt)); + }), (0,shareReplay/* shareReplay */.d)()); // Share side-effects and cache success /** Emit when the MediaKeys instance has been attached the HTMLMediaElement. */ @@ -7849,14 +8324,7 @@ function EMEManager(mediaElement, keySystemsConfigs, contentProtections$) { var mediaEncryptedEvents$ = onEncrypted$(mediaElement).pipe((0,tap/* tap */.b)(function (evt) { log/* default.debug */.Z.debug("EME: Encrypted event received from media element.", evt); }), (0,filter_map/* default */.Z)(function (evt) { - var _getInitData = getInitData(evt), - initData = _getInitData.initData, - initDataType = _getInitData.initDataType; - - return initData === null ? null : { - type: initDataType, - data: initData - }; + return getInitData(evt); }, null), (0,shareReplay/* shareReplay */.d)({ refCount: true })); // multiple Observables listen to that one @@ -7879,11 +8347,10 @@ function EMEManager(mediaElement, keySystemsConfigs, contentProtections$) { })); }), /* Attach server certificate and create/reuse MediaKeySession */ - (0,mergeMap/* mergeMap */.zg)(function (_ref, i) { + (0,mergeMap/* mergeMap */.zg)(function (_ref) { var initializationData = _ref[0], mediaKeysEvent = _ref[1]; var _mediaKeysEvent$value = mediaKeysEvent.value, - mediaKeys = _mediaKeysEvent$value.mediaKeys, mediaKeySystemAccess = _mediaKeysEvent$value.mediaKeySystemAccess, stores = _mediaKeysEvent$value.stores, options = _mediaKeysEvent$value.options; @@ -7904,7 +8371,57 @@ function EMEManager(mediaElement, keySystemsConfigs, contentProtections$) { }); } - if (!handledInitData.storeIfNone(initializationData, true)) { + var lastKeyUpdate$ = new ReplaySubject/* ReplaySubject */.t(1); // First, check that this initialization data is not already handled + + if (options.singleLicensePer === "content" && !contentSessions.isEmpty()) { + var keyIds = initializationData.keyIds; + + if (keyIds === undefined) { + log/* default.warn */.Z.warn("EME: Initialization data linked to unknown key id, we'll " + "not able to fallback from it."); + return (0,of.of)({ + type: "init-data-ignored", + value: { + initializationData: initializationData + } + }); + } + + var firstSession = contentSessions.getAll()[0]; + return firstSession.lastKeyUpdate$.pipe((0,mergeMap/* mergeMap */.zg)(function (evt) { + var hasAllNeededKeyIds = keyIds.every(function (keyId) { + for (var i = 0; i < evt.whitelistedKeyIds.length; i++) { + if ((0,are_arrays_of_numbers_equal/* default */.Z)(evt.whitelistedKeyIds[i], keyId)) { + return true; + } + } + }); + + if (!hasAllNeededKeyIds) { + // Not all keys are available in the current session, blacklist those + return (0,of.of)({ + type: "keys-update", + value: { + blacklistedKeyIDs: keyIds, + whitelistedKeyIds: [] + } + }); + } // Already handled by the current session. + // Move corresponding session on top of the cache if it exists + + + var loadedSessionsStore = mediaKeysEvent.value.stores.loadedSessionsStore; + loadedSessionsStore.reuse(firstSession.initializationData); + return (0,of.of)({ + type: "init-data-ignored", + value: { + initializationData: initializationData + } + }); + })); + } else if (!contentSessions.storeIfNone(initializationData, { + initializationData: initializationData, + lastKeyUpdate$: lastKeyUpdate$ + })) { log/* default.debug */.Z.debug("EME: Init data already received. Skipping it."); return (0,of.of)({ type: "init-data-ignored", @@ -7914,8 +8431,6 @@ function EMEManager(mediaElement, keySystemsConfigs, contentProtections$) { }); } - var serverCertificate = options.serverCertificate; - var serverCertificate$ = i === 0 && !(0,is_null_or_undefined/* default */.Z)(serverCertificate) ? trySettingServerCertificate(mediaKeys, serverCertificate) : empty/* EMPTY */.E; var wantedSessionType; if (options.persistentLicense !== true) { @@ -7927,13 +8442,10 @@ function EMEManager(mediaElement, keySystemsConfigs, contentProtections$) { wantedSessionType = "persistent-license"; } - return (0,concat/* concat */.z)(serverCertificate$, getSession(initializationData, stores, wantedSessionType)).pipe((0,mergeMap/* mergeMap */.zg)(function (sessionEvt) { + return getSession(initializationData, stores, wantedSessionType).pipe((0,mergeMap/* mergeMap */.zg)(function (sessionEvt) { switch (sessionEvt.type) { - case "warning": - return (0,of.of)(sessionEvt); - case "cleaning-old-session": - handledInitData.remove(sessionEvt.value.initializationData); + contentSessions.remove(sessionEvt.value.initializationData); return empty/* EMPTY */.E; case "cleaned-old-session": @@ -7953,17 +8465,37 @@ function EMEManager(mediaElement, keySystemsConfigs, contentProtections$) { var _sessionEvt$value = sessionEvt.value, mediaKeySession = _sessionEvt$value.mediaKeySession, sessionType = _sessionEvt$value.sessionType; - var generateRequest$ = sessionEvt.type !== "created-session" ? empty/* EMPTY */.E : generateKeyRequest(mediaKeySession, initializationData).pipe((0,tap/* tap */.b)(function () { - var persistentSessionsStore = stores.persistentSessionsStore; + /** + * We only store persistent sessions once its keys are known. + * This boolean allows to know if this session has already been + * persisted or not. + */ - if (sessionType === "persistent-license" && persistentSessionsStore !== null) { - cleanOldStoredPersistentInfo(persistentSessionsStore, EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION - 1); - persistentSessionsStore.add(initializationData, mediaKeySession); - } - }), (0,catchError/* catchError */.K)(function (error) { + var isSessionPersisted = false; // `generateKeyRequest` awaits a single Uint8Array containing all + // initialization data. + + var concatInitData = byte_parsing/* concat.apply */.zo.apply(void 0, initializationData.values.map(function (i) { + return i.data; + })); + var generateRequest$ = sessionEvt.type !== "created-session" ? empty/* EMPTY */.E : generateKeyRequest(mediaKeySession, initializationData.type, concatInitData).pipe((0,catchError/* catchError */.K)(function (error) { throw new encrypted_media_error/* default */.Z("KEY_GENERATE_REQUEST_ERROR", error instanceof Error ? error.toString() : "Unknown error"); }), (0,ignoreElements/* ignoreElements */.l)()); - return (0,merge/* merge */.T)(SessionEventsListener(mediaKeySession, options, mediaKeySystemAccess.keySystem, initializationData), generateRequest$).pipe((0,catchError/* catchError */.K)(function (err) { + return (0,merge/* merge */.T)(SessionEventsListener(mediaKeySession, options, mediaKeySystemAccess.keySystem, initializationData), generateRequest$).pipe((0,tap/* tap */.b)(function (evt) { + if (evt.type !== "keys-update") { + return; + } + + lastKeyUpdate$.next(evt.value); + + if (evt.value.whitelistedKeyIds.length === 0 && evt.value.blacklistedKeyIDs.length === 0 || sessionType === "temporary" || stores.persistentSessionsStore === null || isSessionPersisted) { + return; + } + + var persistentSessionsStore = stores.persistentSessionsStore; + cleanOldStoredPersistentInfo(persistentSessionsStore, EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION - 1); + persistentSessionsStore.add(initializationData, mediaKeySession); + isSessionPersisted = true; + }), (0,catchError/* catchError */.K)(function (err) { if (!(err instanceof BlacklistedSessionError)) { throw err; } @@ -8044,7 +8576,7 @@ function canCreatePersistentSession(mediaKeySystemAccess) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /** * Copyright 2015 CANAL+ Group @@ -8101,7 +8633,7 @@ var currentMediaState = new WeakMap(); // EXPORTS __webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ createEMEManager + "Z": () => (/* binding */ createEMEManager) }); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/merge.js @@ -8214,13 +8746,37 @@ function createEMEManager(mediaElement, keySystems, contentProtections$) { /***/ }), -/***/ 8343: +/***/ 7247: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ -/* harmony export */ }); + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ emitLoadedEventWhenReady) +}); + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js +var of = __webpack_require__(8170); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/concat.js +var concat = __webpack_require__(9795); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mapTo.js +var mapTo = __webpack_require__(5602); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/catchError.js +var catchError = __webpack_require__(486); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/filter.js +var filter = __webpack_require__(6008); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/take.js +var take = __webpack_require__(1015); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMap.js +var mergeMap = __webpack_require__(7746); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/defer.js +var defer = __webpack_require__(1410); +// EXTERNAL MODULE: ./src/utils/cast_to_observable.ts +var cast_to_observable = __webpack_require__(8117); +// EXTERNAL MODULE: ./src/utils/rx-try_catch.ts +var rx_try_catch = __webpack_require__(5561); +;// CONCATENATED MODULE: ./src/compat/play.ts /** * Copyright 2015 CANAL+ Group * @@ -8237,174 +8793,203 @@ function createEMEManager(mediaElement, keySystems, contentProtections$) { * limitations under the License. */ + + /** - * Construct a "loaded" event. - * @returns {Object} + * Call play on the media element on subscription and return the response as an + * observable. + * @param {HTMLMediaElement} mediaElement + * @returns {Observable} */ -function loaded(segmentBuffersStore) { - return { - type: "loaded", - value: { - segmentBuffersStore: segmentBuffersStore - } - }; + +function play$(mediaElement) { + return (0,defer/* defer */.P)(function () { + return (// mediaElement.play is not always a Promise. In the improbable case it + // throws, I prefer still to catch to return the error wrapped in an + // Observable + (0,rx_try_catch/* default */.Z)(function () { + return (0,cast_to_observable/* default */.Z)(mediaElement.play()); + }, undefined) + ); + }); } +// EXTERNAL MODULE: ./src/compat/browser_detection.ts +var browser_detection = __webpack_require__(3666); +;// CONCATENATED MODULE: ./src/compat/should_wait_for_data_before_loaded.ts /** - * Construct a "stalled" event. - * @param {Object|null} stalling - * @returns {Object} + * 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 stalled(stalling) { - return { - type: "stalled", - value: stalling - }; -} /** - * Construct a "stalled" event. - * @param {Object|null} stalling - * @returns {Object} + * On some browsers, the ready state might never go above `1` when autoplay is + * blocked. On these cases, for now, we just advertise the content as "loaded". + * We might go into BUFFERING just after that state, but that's a small price to + * pay. + * @param {Boolean} isDirectfile + * @returns {Boolean} */ +function shouldWaitForDataBeforeLoaded(isDirectfile, mustPlayInline) { + if (isDirectfile && browser_detection/* isSafariMobile */.SB) { + return mustPlayInline; + } -function unstalled() { - return { - type: "unstalled", - value: null - }; + return true; } +;// CONCATENATED MODULE: ./src/compat/should_validate_metadata.ts /** - * Construct a "decipherabilityUpdate" event. - * @param {Array.} arg - * @returns {Object} + * 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 metadata received after a "loadedmetadata" event has + * to be validated in the current browser (which means that we do not trust + * this event on these browsers). + * @returns {boolean} + */ -function decipherabilityUpdate(arg) { - return { - type: "decipherabilityUpdate", - value: arg - }; +function shouldValidateMetadata() { + return browser_detection/* isSamsungBrowser */.op; } +// EXTERNAL MODULE: ./src/log.ts + 1 modules +var log = __webpack_require__(3887); +;// CONCATENATED MODULE: ./src/core/init/emit_loaded_event.ts /** - * Construct a "manifestReady" event. - * @param {Object} manifest - * @returns {Object} + * 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 manifestReady(manifest) { - return { - type: "manifestReady", - value: { - manifest: manifest - } - }; -} + + /** - * Construct a "manifestUpdate" event. - * @returns {Object} + * Try to play content then handle autoplay errors. + * @param {HTMLMediaElement} - mediaElement + * @returns {Observable} */ - -function manifestUpdate() { - return { - type: "manifestUpdate", - value: null - }; +function tryToPlay$(mediaElement) { + return play$(mediaElement).pipe((0,mapTo/* mapTo */.h)("autoplay"), (0,catchError/* catchError */.K)(function (error) { + if (error instanceof Error && error.name === "NotAllowedError") { + // auto-play was probably prevented. + log/* default.warn */.Z.warn("Init: Media element can't play." + " It may be due to browser auto-play policies."); + return (0,of.of)("autoplay-blocked"); + } else { + throw error; + } + })); } /** - * Construct a "representationChange" event. - * @param {string} type - * @param {Object} period - * @returns {Object} + * Listen to the `initClock$` to know when the autoPlay action can be triggered. + * Emit either one of these values: + * - "autoplay": The content is loaded and autoplay has been performed + * - "loaded": The constent is loaded without autoplay, as asked + * - "autoplay-blocked": The content is loaded but autoplay could not be + * performed due to browser restrictions. + * - "not-loaded-metadata" + * @param {Observable} initClock$ + * @param {HTMLMediaElement} mediaElement + * @param {boolean} autoPlay + * @param {boolean} isDirectfile + * @returns {Observable} */ -function nullRepresentation(type, period) { - return { - type: "representationChange", - value: { - type: type, - representation: null, - period: period +function emitLoadedEventWhenReady(initClock$, mediaElement, autoPlay, isDirectfile) { + /** + * Observable which will try to apply the autoplay setting then announced the + * content as loaded (or as "autoplay-blocked"). + */ + var beginPlayback$ = initClock$.pipe((0,filter/* filter */.h)(function (tick) { + var seeking = tick.seeking, + stalled = tick.stalled, + readyState = tick.readyState, + currentRange = tick.currentRange; + + if (seeking || stalled !== null) { + return false; } - }; -} -/** - * construct a "warning" event. - * @param {error} value - * @returns {object} - */ + if (!shouldWaitForDataBeforeLoaded(isDirectfile, mediaElement.hasAttribute("playsinline"))) { + return readyState >= 1 && mediaElement.duration > 0; + } -function warning(value) { - return { - type: "warning", - value: value - }; -} -/** - * construct a "reloading-media-source" event. - * @returns {object} - */ + if (readyState >= 4 || readyState === 3 && currentRange !== null) { + return shouldValidateMetadata() ? mediaElement.duration > 0 : true; + } + return false; + }), (0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.zg)(function () { + if (!autoPlay) { + if (mediaElement.autoplay) { + log/* default.warn */.Z.warn("Init: autoplay is enabled on HTML media element. " + "Media will play as soon as possible."); + } -function reloadingMediaSource() { - return { - type: "reloading-media-source", - value: undefined - }; -} + return (0,of.of)("loaded"); + } -var INIT_EVENTS = { - loaded: loaded, - decipherabilityUpdate: decipherabilityUpdate, - manifestReady: manifestReady, - manifestUpdate: manifestUpdate, - nullRepresentation: nullRepresentation, - reloadingMediaSource: reloadingMediaSource, - stalled: stalled, - unstalled: unstalled, - warning: warning -}; -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (INIT_EVENTS); + return tryToPlay$(mediaElement); + })); + + if (!shouldValidateMetadata()) { + return beginPlayback$; + } + + return initClock$.pipe((0,filter/* filter */.h)(function (tick) { + return tick.readyState >= 1; + }), (0,mergeMap/* mergeMap */.zg)(function () { + if (mediaElement.duration === 0) { + return (0,concat/* concat */.z)((0,of.of)("not-loaded-metadata"), beginPlayback$); + } + + return beginPlayback$; + })); +} /***/ }), -/***/ 2795: +/***/ 8343: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ seekAndLoadOnMediaEvents -}); - -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/concat.js -var concat = __webpack_require__(9795); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js -var of = __webpack_require__(8170); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/filter.js -var filter = __webpack_require__(6008); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/take.js -var take = __webpack_require__(1015); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mapTo.js -var mapTo = __webpack_require__(5602); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/catchError.js -var catchError = __webpack_require__(486); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/tap.js -var tap = __webpack_require__(3068); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/shareReplay.js -var shareReplay = __webpack_require__(7006); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMap.js -var mergeMap = __webpack_require__(7746); -// EXTERNAL MODULE: ./src/compat/browser_detection.ts -var browser_detection = __webpack_require__(3666); -;// CONCATENATED MODULE: ./src/compat/should_wait_for_data_before_loaded.ts +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -8422,258 +9007,140 @@ var browser_detection = __webpack_require__(3666); */ /** - * On some browsers, the ready state might never go above `1` when autoplay is - * blocked. On these cases, for now, we just advertise the content as "loaded". - * We might go into BUFFERING just after that state, but that's a small price to - * pay. - * @param {Boolean} isDirectfile - * @returns {Boolean} + * Construct a "loaded" event. + * @returns {Object} */ - -function shouldWaitForDataBeforeLoaded(isDirectfile, mustPlayInline) { - if (isDirectfile && browser_detection/* isSafariMobile */.SB) { - return mustPlayInline; - } - - return true; +function loaded(segmentBuffersStore) { + return { + type: "loaded", + value: { + segmentBuffersStore: segmentBuffersStore + } + }; } -;// CONCATENATED MODULE: ./src/compat/should_validate_metadata.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. + * Construct a "stalled" event. + * @param {Object|null} stalling + * @returns {Object} */ -/** - * Returns true if the metadata received after a "loadedmetadata" event has - * to be validated in the current browser (which means that we do not trust - * this event on these browsers). - * @returns {boolean} - */ -function shouldValidateMetadata() { - return browser_detection/* isSamsungBrowser */.op; +function stalled(stalling) { + return { + type: "stalled", + value: stalling + }; } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/defer.js -var defer = __webpack_require__(1410); -// EXTERNAL MODULE: ./src/utils/cast_to_observable.ts -var cast_to_observable = __webpack_require__(8117); -// EXTERNAL MODULE: ./src/utils/rx-try_catch.ts -var rx_try_catch = __webpack_require__(5561); -;// CONCATENATED MODULE: ./src/compat/play.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. + * Construct a "stalled" event. + * @param {Object|null} stalling + * @returns {Object} */ - -/** - * Call play on the media element on subscription and return the response as an - * observable. - * @param {HTMLMediaElement} mediaElement - * @returns {Observable} - */ - -function play$(mediaElement) { - return (0,defer/* defer */.P)(function () { - return (// mediaElement.play is not always a Promise. In the improbable case it - // throws, I prefer still to catch to return the error wrapped in an - // Observable - (0,rx_try_catch/* default */.Z)(function () { - return (0,cast_to_observable/* default */.Z)(mediaElement.play()); - }, undefined) - ); - }); +function unstalled() { + return { + type: "unstalled", + value: null + }; } -// EXTERNAL MODULE: ./src/compat/browser_compatibility_types.ts -var browser_compatibility_types = __webpack_require__(3774); -// EXTERNAL MODULE: ./src/compat/event_listeners.ts + 4 modules -var event_listeners = __webpack_require__(1473); -;// CONCATENATED MODULE: ./src/compat/when_loaded_metadata.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. + * Construct a "decipherabilityUpdate" event. + * @param {Array.} arg + * @returns {Object} */ - - +function decipherabilityUpdate(arg) { + return { + type: "decipherabilityUpdate", + value: arg + }; +} /** - * Returns an observable emitting a single time, as soon as a seek is possible - * (the metadata are loaded). - * @param {HTMLMediaElement} mediaElement - * @returns {Observable} + * Construct a "manifestReady" event. + * @param {Object} manifest + * @returns {Object} */ -function whenLoadedMetadata$(mediaElement) { - if (mediaElement.readyState >= browser_compatibility_types/* READY_STATES.HAVE_METADATA */.cX.HAVE_METADATA) { - return (0,of.of)(null); - } else { - return (0,event_listeners/* onLoadedMetadata$ */.K4)(mediaElement).pipe((0,take/* take */.q)(1)); - } + +function manifestReady(manifest) { + return { + type: "manifestReady", + value: { + manifest: manifest + } + }; } -// EXTERNAL MODULE: ./src/log.ts + 1 modules -var log = __webpack_require__(3887); -;// CONCATENATED MODULE: ./src/core/init/initial_seek_and_play.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. + * Construct a "manifestUpdate" event. + * @returns {Object} */ - - +function manifestUpdate() { + return { + type: "manifestUpdate", + value: null + }; +} /** - * Emit once a "can-play" message as soon as the clock$ announce that the content - * can begin to be played. - * - * Warn you if the metadata is not yet loaded metadata by emitting a - * "not-loaded-metadata" message first. - * @param {Observable} clock$ - * @returns {Observable} + * Construct a "representationChange" event. + * @param {string} type + * @param {Object} period + * @returns {Object} */ -function canPlay(clock$, mediaElement, isDirectfile) { - var isLoaded$ = clock$.pipe((0,filter/* filter */.h)(function (tick) { - var seeking = tick.seeking, - stalled = tick.stalled, - readyState = tick.readyState, - currentRange = tick.currentRange; - if (seeking || stalled !== null) { - return false; - } - - if (!shouldWaitForDataBeforeLoaded(isDirectfile, mediaElement.hasAttribute("playsinline"))) { - return readyState >= 1 && mediaElement.duration > 0; - } - - if (readyState >= 4 || readyState === 3 && currentRange !== null) { - return shouldValidateMetadata() ? mediaElement.duration > 0 : true; +function nullRepresentation(type, period) { + return { + type: "representationChange", + value: { + type: type, + representation: null, + period: period } - - return false; - }), (0,take/* take */.q)(1), (0,mapTo/* mapTo */.h)("can-play")); - - if (shouldValidateMetadata() && mediaElement.duration === 0) { - return (0,concat/* concat */.z)((0,of.of)("not-loaded-metadata"), isLoaded$); - } - - return isLoaded$; + }; } /** - * Try to play content then handle autoplay errors. - * @param {HTMLMediaElement} - mediaElement - * @returns {Observable} + * construct a "warning" event. + * @param {error} value + * @returns {object} */ -function autoPlay$(mediaElement) { - return play$(mediaElement).pipe((0,mapTo/* mapTo */.h)("autoplay"), (0,catchError/* catchError */.K)(function (error) { - if (error instanceof Error && error.name === "NotAllowedError") { - // auto-play was probably prevented. - log/* default.warn */.Z.warn("Init: Media element can't play." + " It may be due to browser auto-play policies."); - return (0,of.of)("autoplay-blocked"); - } else { - throw error; - } - })); +function warning(value) { + return { + type: "warning", + value: value + }; } /** - * Returns two Observables: - * - * - seek$: when subscribed, will seek to the wanted started time as soon as - * it can. Emit and complete when done. - * - * - load$: when subscribed, will play if and only if the `mustAutoPlay` - * option is set as soon as it can. Emit and complete when done. - * When this observable emits, it also means that the content is `loaded` - * and can begin to play the current content. - * - * @param {Object} args - * @returns {Object} + * construct a "reloading-media-source" event. + * @returns {object} */ -function seekAndLoadOnMediaEvents(_ref) { - var clock$ = _ref.clock$, - mediaElement = _ref.mediaElement, - startTime = _ref.startTime, - mustAutoPlay = _ref.mustAutoPlay, - isDirectfile = _ref.isDirectfile; - var seek$ = whenLoadedMetadata$(mediaElement).pipe((0,take/* take */.q)(1), (0,tap/* tap */.b)(function () { - log/* default.info */.Z.info("Init: Set initial time", startTime); - mediaElement.currentTime = typeof startTime === "function" ? startTime() : startTime; - }), (0,shareReplay/* shareReplay */.d)({ - refCount: true - })); - var load$ = seek$.pipe((0,mergeMap/* mergeMap */.zg)(function () { - return canPlay(clock$, mediaElement, isDirectfile).pipe((0,tap/* tap */.b)(function () { - return log/* default.info */.Z.info("Init: Can begin to play content"); - }), (0,mergeMap/* mergeMap */.zg)(function (evt) { - if (evt === "can-play") { - if (!mustAutoPlay) { - return (0,of.of)("loaded"); - } - - return autoPlay$(mediaElement); - } - - return (0,of.of)(evt); - })); - }), (0,shareReplay/* shareReplay */.d)({ - refCount: true - })); +function reloadingMediaSource() { return { - seek$: seek$, - load$: load$ + type: "reloading-media-source", + value: undefined }; } +var INIT_EVENTS = { + loaded: loaded, + decipherabilityUpdate: decipherabilityUpdate, + manifestReady: manifestReady, + manifestUpdate: manifestUpdate, + nullRepresentation: nullRepresentation, + reloadingMediaSource: reloadingMediaSource, + stalled: stalled, + unstalled: unstalled, + warning: warning +}; +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (INIT_EVENTS); + /***/ }), /***/ 8969: @@ -8683,7 +9150,7 @@ function seekAndLoadOnMediaEvents(_ref) { // EXPORTS __webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ initializeDirectfileContent + "Z": () => (/* binding */ initializeDirectfileContent) }); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/empty.js @@ -8706,6 +9173,8 @@ var filter = __webpack_require__(6008); var take = __webpack_require__(1015); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMapTo.js var mergeMapTo = __webpack_require__(3756); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/tap.js +var tap = __webpack_require__(3068); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules var Observable = __webpack_require__(4379); // EXTERNAL MODULE: ./src/log.ts + 1 modules @@ -8757,10 +9226,10 @@ var media_error = __webpack_require__(3714); var defer_subscriptions = __webpack_require__(8025); // EXTERNAL MODULE: ./src/core/init/create_eme_manager.ts + 1 modules var create_eme_manager = __webpack_require__(4507); +// EXTERNAL MODULE: ./src/core/init/emit_loaded_event.ts + 3 modules +var emit_loaded_event = __webpack_require__(7247); // EXTERNAL MODULE: ./src/core/init/events_generators.ts var events_generators = __webpack_require__(8343); -// EXTERNAL MODULE: ./src/core/init/initial_seek_and_play.ts + 4 modules -var initial_seek_and_play = __webpack_require__(2795); // EXTERNAL MODULE: ./src/core/init/throw_on_media_error.ts var throw_on_media_error = __webpack_require__(2447); // EXTERNAL MODULE: ./src/core/init/update_playback_rate.ts @@ -8782,11 +9251,6 @@ var update_playback_rate = __webpack_require__(2983); * limitations under the License. */ -/** - * /!\ This file is feature-switchable. - * It always should be imported through the `features` object. - */ - @@ -8854,6 +9318,7 @@ function initializeDirectfileContent(_ref) { keySystems = _ref.keySystems, mediaElement = _ref.mediaElement, speed$ = _ref.speed$, + setCurrentTime = _ref.setCurrentTime, startAt = _ref.startAt, url = _ref.url; (0,clear_element_src/* default */.Z)(mediaElement); @@ -8870,20 +9335,9 @@ function initializeDirectfileContent(_ref) { return getDirectFileInitialTime(mediaElement, startAt); }; - log/* default.debug */.Z.debug("Init: Initial time calculated:", initialTime); - - var _seekAndLoadOnMediaEv = (0,initial_seek_and_play/* default */.Z)({ - clock$: clock$, - mediaElement: mediaElement, - startTime: initialTime, - mustAutoPlay: autoPlay, - isDirectfile: true - }), - seek$ = _seekAndLoadOnMediaEv.seek$, - load$ = _seekAndLoadOnMediaEv.load$; // Create EME Manager, an observable which will manage every EME-related + log/* default.debug */.Z.debug("Init: Initial time calculated:", initialTime); // Create EME Manager, an observable which will manage every EME-related // issue. - var emeManager$ = linkURL$.pipe((0,mergeMap/* mergeMap */.zg)(function () { return (0,create_eme_manager/* default */.Z)(mediaElement, keySystems, empty/* EMPTY */.E); }), (0,defer_subscriptions/* default */.Z)(), (0,share/* share */.B)()); // Translate errors coming from the media element into RxPlayer errors @@ -8908,7 +9362,7 @@ function initializeDirectfileContent(_ref) { } return evt.type === "eme-disabled" || evt.type === "attached-media-keys"; - }), (0,take/* take */.q)(1), (0,mergeMapTo/* mergeMapTo */.j)(load$), (0,mergeMap/* mergeMap */.zg)(function (evt) { + }), (0,take/* take */.q)(1), (0,mergeMapTo/* mergeMapTo */.j)((0,emit_loaded_event/* default */.Z)(clock$, mediaElement, autoPlay, true)), (0,mergeMap/* mergeMap */.zg)(function (evt) { if (evt === "autoplay-blocked") { var error = new media_error/* default */.Z("MEDIA_ERR_BLOCKED_AUTOPLAY", "Cannot trigger auto-play automatically: " + "your browser does not allow it."); return (0,of.of)(events_generators/* default.warning */.Z.warning(error), events_generators/* default.loaded */.Z.loaded(null)); @@ -8920,7 +9374,16 @@ function initializeDirectfileContent(_ref) { return (0,of.of)(events_generators/* default.loaded */.Z.loaded(null)); })); - var initialSeek$ = seek$.pipe((0,ignoreElements/* ignoreElements */.l)()); + var initialSeek$ = clock$.pipe((0,filter/* filter */.h)(function (tick) { + return tick.readyState > 0 || tick.event === "loadedmetadata"; + }), (0,take/* take */.q)(1), (0,tap/* tap */.b)(function () { + var startTime = initialTime(); + + if (mediaElement.currentTime !== startTime) { + log/* default.info */.Z.info("Init: Set initial time", startTime); + setCurrentTime(startTime); + } + }), (0,ignoreElements/* ignoreElements */.l)()); return (0,merge/* merge */.T)(loadedEvent$, initialSeek$, emeManager$, mediaError$, playbackRate$, stalled$); } @@ -8931,7 +9394,7 @@ function initializeDirectfileContent(_ref) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ throwOnMediaError +/* harmony export */ "Z": () => (/* binding */ throwOnMediaError) /* harmony export */ }); /* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7027); /* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7746); @@ -8991,7 +9454,7 @@ function throwOnMediaError(mediaElement) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ updatePlaybackRate +/* harmony export */ "Z": () => (/* binding */ updatePlaybackRate) /* harmony export */ }); /* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8170); /* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(1410); @@ -9026,7 +9489,7 @@ function throwOnMediaError(mediaElement) { * * @param {HTMLMediaElement} mediaElement * @param {Observable} speed$ - emit speed set by the user - * @param {Observable} clock$ - Current playback conditions + * @param {Observable} clock$ - Emit current stalled status. * @param {Object} options - Contains the following properties: * - pauseWhenStalled {Boolean|undefined} - true if the player * stalling should lead to a pause until it un-stalls. True by default. @@ -9071,12 +9534,11 @@ function updatePlaybackRate(mediaElement, speed$, clock$, _ref) { // EXPORTS __webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ implementations_image + "Z": () => (/* binding */ implementations_image) }); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/inheritsLoose.js -var inheritsLoose = __webpack_require__(5354); -var inheritsLoose_default = /*#__PURE__*/__webpack_require__.n(inheritsLoose); +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js +var inheritsLoose = __webpack_require__(1788); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/defer.js var defer = __webpack_require__(1410); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js @@ -9115,7 +9577,7 @@ var manual_time_ranges = __webpack_require__(4309); */ var ImageSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) { - inheritsLoose_default()(ImageSegmentBuffer, _SegmentBuffer); + (0,inheritsLoose/* default */.Z)(ImageSegmentBuffer, _SegmentBuffer); function ImageSegmentBuffer() { var _this; @@ -9254,12 +9716,11 @@ var ImageSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) { // EXPORTS __webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ html + "Z": () => (/* binding */ html) }); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/inheritsLoose.js -var inheritsLoose = __webpack_require__(5354); -var inheritsLoose_default = /*#__PURE__*/__webpack_require__.n(inheritsLoose); +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js +var inheritsLoose = __webpack_require__(1788); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/merge.js var merge = __webpack_require__(4370); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/interval.js @@ -10097,7 +10558,7 @@ function getElementResolution(element) { var HTMLTextSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) { - inheritsLoose_default()(HTMLTextSegmentBuffer, _SegmentBuffer); + (0,inheritsLoose/* default */.Z)(HTMLTextSegmentBuffer, _SegmentBuffer); /** * @param {HTMLMediaElement} videoElement @@ -10451,12 +10912,11 @@ var HTMLTextSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) { // EXPORTS __webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ text_native + "Z": () => (/* binding */ text_native) }); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/inheritsLoose.js -var inheritsLoose = __webpack_require__(5354); -var inheritsLoose_default = /*#__PURE__*/__webpack_require__.n(inheritsLoose); +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js +var inheritsLoose = __webpack_require__(1788); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/defer.js var defer = __webpack_require__(1410); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js @@ -10671,7 +11131,7 @@ function parseTextTrackToCues(type, data, timestampOffset, language) { */ var NativeTextSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) { - inheritsLoose_default()(NativeTextSegmentBuffer, _SegmentBuffer); + (0,inheritsLoose/* default */.Z)(NativeTextSegmentBuffer, _SegmentBuffer); /** * @param {HTMLMediaElement} videoElement @@ -10942,8 +11402,8 @@ var NativeTextSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) { // EXPORTS __webpack_require__.d(__webpack_exports__, { - "C": () => /* binding */ SegmentBuffer, - "f": () => /* binding */ SegmentBufferOperation + "C": () => (/* binding */ SegmentBuffer), + "f": () => (/* binding */ SegmentBufferOperation) }); // EXTERNAL MODULE: ./src/config.ts @@ -11900,7 +12360,7 @@ var SegmentBufferOperation; "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ ManualTimeRanges +/* harmony export */ "Z": () => (/* binding */ ManualTimeRanges) /* harmony export */ }); /* harmony import */ var _utils_ranges__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2829); /** @@ -11995,14 +12455,11 @@ var ManualTimeRanges = /*#__PURE__*/function () { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ AssertionError +/* harmony export */ "Z": () => (/* binding */ AssertionError) /* harmony export */ }); -/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1506); -/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5354); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5957); -/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3349); +/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1788); +/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3786); @@ -12030,7 +12487,7 @@ var ManualTimeRanges = /*#__PURE__*/function () { * @extends Error */ var AssertionError = /*#__PURE__*/function (_Error) { - _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1___default()(AssertionError, _Error); + (0,_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(AssertionError, _Error); /** * @param {string} message @@ -12040,14 +12497,14 @@ var AssertionError = /*#__PURE__*/function (_Error) { _this = _Error.call(this) || this; // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class - Object.setPrototypeOf(_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0___default()(_this), AssertionError.prototype); + Object.setPrototypeOf((0,_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(_this), AssertionError.prototype); _this.name = "AssertionError"; _this.message = message; return _this; } return AssertionError; -}( /*#__PURE__*/_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2___default()(Error)); +}( /*#__PURE__*/(0,_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__/* .default */ .Z)(Error)); @@ -12058,16 +12515,13 @@ var AssertionError = /*#__PURE__*/function (_Error) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ EncryptedMediaError +/* harmony export */ "Z": () => (/* binding */ EncryptedMediaError) /* harmony export */ }); -/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1506); -/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5354); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5957); -/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _error_codes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5992); -/* harmony import */ var _error_message__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7367); +/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3349); +/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1788); +/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3786); +/* harmony import */ var _error_codes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5992); +/* harmony import */ var _error_message__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7367); @@ -12097,7 +12551,7 @@ var AssertionError = /*#__PURE__*/function (_Error) { */ var EncryptedMediaError = /*#__PURE__*/function (_Error) { - _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1___default()(EncryptedMediaError, _Error); + (0,_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(EncryptedMediaError, _Error); /** * @param {string} code @@ -12109,17 +12563,17 @@ var EncryptedMediaError = /*#__PURE__*/function (_Error) { _this = _Error.call(this) || this; // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class - Object.setPrototypeOf(_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0___default()(_this), EncryptedMediaError.prototype); + Object.setPrototypeOf((0,_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(_this), EncryptedMediaError.prototype); _this.name = "EncryptedMediaError"; - _this.type = _error_codes__WEBPACK_IMPORTED_MODULE_3__/* .ErrorTypes.ENCRYPTED_MEDIA_ERROR */ .ZB.ENCRYPTED_MEDIA_ERROR; + _this.type = _error_codes__WEBPACK_IMPORTED_MODULE_2__/* .ErrorTypes.ENCRYPTED_MEDIA_ERROR */ .ZB.ENCRYPTED_MEDIA_ERROR; _this.code = code; - _this.message = (0,_error_message__WEBPACK_IMPORTED_MODULE_4__/* .default */ .Z)(_this.name, _this.code, reason); + _this.message = (0,_error_message__WEBPACK_IMPORTED_MODULE_3__/* .default */ .Z)(_this.name, _this.code, reason); _this.fatal = false; return _this; } return EncryptedMediaError; -}( /*#__PURE__*/_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2___default()(Error)); +}( /*#__PURE__*/(0,_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_4__/* .default */ .Z)(Error)); @@ -12130,9 +12584,9 @@ var EncryptedMediaError = /*#__PURE__*/function (_Error) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "ZB": () => /* binding */ ErrorTypes, -/* harmony export */ "br": () => /* binding */ NetworkErrorTypes, -/* harmony export */ "SM": () => /* binding */ ErrorCodes +/* harmony export */ "ZB": () => (/* binding */ ErrorTypes), +/* harmony export */ "br": () => (/* binding */ NetworkErrorTypes), +/* harmony export */ "SM": () => (/* binding */ ErrorCodes) /* harmony export */ }); /** * Copyright 2015 CANAL+ Group @@ -12212,7 +12666,7 @@ var ErrorCodes = { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ errorMessage +/* harmony export */ "Z": () => (/* binding */ errorMessage) /* harmony export */ }); /** * Copyright 2015 CANAL+ Group @@ -12248,7 +12702,7 @@ function errorMessage(name, code, reason) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ isKnownError +/* harmony export */ "Z": () => (/* binding */ isKnownError) /* harmony export */ }); /* harmony import */ var _encrypted_media_error__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5157); /* harmony import */ var _error_codes__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(5992); @@ -12292,16 +12746,13 @@ function isKnownError(error) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ MediaError +/* harmony export */ "Z": () => (/* binding */ MediaError) /* harmony export */ }); -/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1506); -/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5354); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5957); -/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _error_codes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5992); -/* harmony import */ var _error_message__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7367); +/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3349); +/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1788); +/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3786); +/* harmony import */ var _error_codes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5992); +/* harmony import */ var _error_message__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7367); @@ -12331,7 +12782,7 @@ function isKnownError(error) { */ var MediaError = /*#__PURE__*/function (_Error) { - _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1___default()(MediaError, _Error); + (0,_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(MediaError, _Error); /** * @param {string} code @@ -12343,17 +12794,17 @@ var MediaError = /*#__PURE__*/function (_Error) { _this = _Error.call(this) || this; // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class - Object.setPrototypeOf(_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0___default()(_this), MediaError.prototype); + Object.setPrototypeOf((0,_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(_this), MediaError.prototype); _this.name = "MediaError"; - _this.type = _error_codes__WEBPACK_IMPORTED_MODULE_3__/* .ErrorTypes.MEDIA_ERROR */ .ZB.MEDIA_ERROR; + _this.type = _error_codes__WEBPACK_IMPORTED_MODULE_2__/* .ErrorTypes.MEDIA_ERROR */ .ZB.MEDIA_ERROR; _this.code = code; - _this.message = (0,_error_message__WEBPACK_IMPORTED_MODULE_4__/* .default */ .Z)(_this.name, _this.code, reason); + _this.message = (0,_error_message__WEBPACK_IMPORTED_MODULE_3__/* .default */ .Z)(_this.name, _this.code, reason); _this.fatal = false; return _this; } return MediaError; -}( /*#__PURE__*/_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2___default()(Error)); +}( /*#__PURE__*/(0,_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_4__/* .default */ .Z)(Error)); @@ -12364,16 +12815,13 @@ var MediaError = /*#__PURE__*/function (_Error) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ NetworkError +/* harmony export */ "Z": () => (/* binding */ NetworkError) /* harmony export */ }); -/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1506); -/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5354); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5957); -/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _error_codes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5992); -/* harmony import */ var _error_message__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7367); +/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3349); +/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1788); +/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3786); +/* harmony import */ var _error_codes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5992); +/* harmony import */ var _error_message__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7367); @@ -12403,7 +12851,7 @@ var MediaError = /*#__PURE__*/function (_Error) { */ var NetworkError = /*#__PURE__*/function (_Error) { - _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1___default()(NetworkError, _Error); + (0,_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(NetworkError, _Error); /** * @param {string} code @@ -12415,15 +12863,15 @@ var NetworkError = /*#__PURE__*/function (_Error) { _this = _Error.call(this) || this; // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class - Object.setPrototypeOf(_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0___default()(_this), NetworkError.prototype); + Object.setPrototypeOf((0,_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(_this), NetworkError.prototype); _this.name = "NetworkError"; - _this.type = _error_codes__WEBPACK_IMPORTED_MODULE_3__/* .ErrorTypes.NETWORK_ERROR */ .ZB.NETWORK_ERROR; + _this.type = _error_codes__WEBPACK_IMPORTED_MODULE_2__/* .ErrorTypes.NETWORK_ERROR */ .ZB.NETWORK_ERROR; _this.xhr = options.xhr === undefined ? null : options.xhr; _this.url = options.url; _this.status = options.status; _this.errorType = options.type; _this.code = code; - _this.message = (0,_error_message__WEBPACK_IMPORTED_MODULE_4__/* .default */ .Z)(_this.name, _this.code, options.message); + _this.message = (0,_error_message__WEBPACK_IMPORTED_MODULE_3__/* .default */ .Z)(_this.name, _this.code, options.message); _this.fatal = false; return _this; } @@ -12437,11 +12885,11 @@ var NetworkError = /*#__PURE__*/function (_Error) { var _proto = NetworkError.prototype; _proto.isHttpError = function isHttpError(httpErrorCode) { - return this.errorType === _error_codes__WEBPACK_IMPORTED_MODULE_3__/* .NetworkErrorTypes.ERROR_HTTP_CODE */ .br.ERROR_HTTP_CODE && this.status === httpErrorCode; + return this.errorType === _error_codes__WEBPACK_IMPORTED_MODULE_2__/* .NetworkErrorTypes.ERROR_HTTP_CODE */ .br.ERROR_HTTP_CODE && this.status === httpErrorCode; }; return NetworkError; -}( /*#__PURE__*/_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2___default()(Error)); +}( /*#__PURE__*/(0,_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_4__/* .default */ .Z)(Error)); @@ -12452,16 +12900,13 @@ var NetworkError = /*#__PURE__*/function (_Error) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ OtherError +/* harmony export */ "Z": () => (/* binding */ OtherError) /* harmony export */ }); -/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1506); -/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5354); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5957); -/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _error_codes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5992); -/* harmony import */ var _error_message__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(7367); +/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3349); +/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1788); +/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3786); +/* harmony import */ var _error_codes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5992); +/* harmony import */ var _error_message__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7367); @@ -12489,7 +12934,7 @@ var NetworkError = /*#__PURE__*/function (_Error) { */ var OtherError = /*#__PURE__*/function (_Error) { - _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1___default()(OtherError, _Error); + (0,_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(OtherError, _Error); /** * @param {string} code @@ -12501,17 +12946,17 @@ var OtherError = /*#__PURE__*/function (_Error) { _this = _Error.call(this) || this; // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class - Object.setPrototypeOf(_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0___default()(_this), OtherError.prototype); + Object.setPrototypeOf((0,_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(_this), OtherError.prototype); _this.name = "OtherError"; - _this.type = _error_codes__WEBPACK_IMPORTED_MODULE_3__/* .ErrorTypes.OTHER_ERROR */ .ZB.OTHER_ERROR; + _this.type = _error_codes__WEBPACK_IMPORTED_MODULE_2__/* .ErrorTypes.OTHER_ERROR */ .ZB.OTHER_ERROR; _this.code = code; - _this.message = (0,_error_message__WEBPACK_IMPORTED_MODULE_4__/* .default */ .Z)(_this.name, _this.code, reason); + _this.message = (0,_error_message__WEBPACK_IMPORTED_MODULE_3__/* .default */ .Z)(_this.name, _this.code, reason); _this.fatal = false; return _this; } return OtherError; -}( /*#__PURE__*/_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2___default()(Error)); +}( /*#__PURE__*/(0,_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_4__/* .default */ .Z)(Error)); @@ -12522,14 +12967,11 @@ var OtherError = /*#__PURE__*/function (_Error) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ RequestError +/* harmony export */ "Z": () => (/* binding */ RequestError) /* harmony export */ }); -/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1506); -/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5354); -/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5957); -/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3349); +/* harmony import */ var _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1788); +/* harmony import */ var _babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3786); @@ -12557,7 +12999,7 @@ var OtherError = /*#__PURE__*/function (_Error) { * @extends Error */ var RequestError = /*#__PURE__*/function (_Error) { - _babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_1___default()(RequestError, _Error); + (0,_babel_runtime_helpers_inheritsLoose__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(RequestError, _Error); /** * @param {XMLHttpRequest} xhr @@ -12569,7 +13011,7 @@ var RequestError = /*#__PURE__*/function (_Error) { _this = _Error.call(this) || this; // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class - Object.setPrototypeOf(_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_0___default()(_this), RequestError.prototype); + Object.setPrototypeOf((0,_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(_this), RequestError.prototype); _this.name = "RequestError"; _this.url = url; _this.xhr = xhr; @@ -12580,7 +13022,7 @@ var RequestError = /*#__PURE__*/function (_Error) { } return RequestError; -}( /*#__PURE__*/_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2___default()(Error)); +}( /*#__PURE__*/(0,_babel_runtime_helpers_wrapNativeSuper__WEBPACK_IMPORTED_MODULE_2__/* .default */ .Z)(Error)); @@ -12591,7 +13033,7 @@ var RequestError = /*#__PURE__*/function (_Error) { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /** * Copyright 2015 CANAL+ Group @@ -12633,7 +13075,7 @@ var features = { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var _features_object__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7273); /** @@ -12673,170 +13115,19 @@ var features = { /***/ }), -/***/ 1452: +/***/ 3887: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; // EXPORTS __webpack_require__.d(__webpack_exports__, { - "default": () => /* binding */ src + "Z": () => (/* binding */ log) }); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/createClass.js -var createClass = __webpack_require__(3913); -var createClass_default = /*#__PURE__*/__webpack_require__.n(createClass); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/inheritsLoose.js -var inheritsLoose = __webpack_require__(5354); -var inheritsLoose_default = /*#__PURE__*/__webpack_require__.n(inheritsLoose); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subject.js -var Subject = __webpack_require__(211); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/ReplaySubject.js + 4 modules -var ReplaySubject = __webpack_require__(2135); -// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js -var tslib_es6 = __webpack_require__(655); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/ObjectUnsubscribedError.js -var ObjectUnsubscribedError = __webpack_require__(1016); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/BehaviorSubject.js -/** PURE_IMPORTS_START tslib,_Subject,_util_ObjectUnsubscribedError PURE_IMPORTS_END */ - - - -var BehaviorSubject = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(BehaviorSubject, _super); - function BehaviorSubject(_value) { - var _this = _super.call(this) || this; - _this._value = _value; - return _this; - } - Object.defineProperty(BehaviorSubject.prototype, "value", { - get: function () { - return this.getValue(); - }, - enumerable: true, - configurable: true - }); - BehaviorSubject.prototype._subscribe = function (subscriber) { - var subscription = _super.prototype._subscribe.call(this, subscriber); - if (subscription && !subscription.closed) { - subscriber.next(this._value); - } - return subscription; - }; - BehaviorSubject.prototype.getValue = function () { - if (this.hasError) { - throw this.thrownError; - } - else if (this.closed) { - throw new ObjectUnsubscribedError/* ObjectUnsubscribedError */.N(); - } - else { - return this._value; - } - }; - BehaviorSubject.prototype.next = function (value) { - _super.prototype.next.call(this, this._value = value); - }; - return BehaviorSubject; -}(Subject/* Subject */.xQ)); - -//# sourceMappingURL=BehaviorSubject.js.map - -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/merge.js -var merge = __webpack_require__(4370); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/empty.js -var empty = __webpack_require__(5631); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/combineLatest.js -var combineLatest = __webpack_require__(5142); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/concat.js -var concat = __webpack_require__(9795); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js -var of = __webpack_require__(8170); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/takeUntil.js -var takeUntil = __webpack_require__(1558); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/map.js -var map = __webpack_require__(5709); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/distinctUntilChanged.js -var distinctUntilChanged = __webpack_require__(1931); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/take.js -var take = __webpack_require__(1015); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/multicast.js + 1 modules -var multicast = __webpack_require__(1421); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/publish.js -/** PURE_IMPORTS_START _Subject,_multicast PURE_IMPORTS_END */ - - -function publish(selector) { - return selector ? - (0,multicast/* multicast */.O)(function () { return new Subject/* Subject */.xQ(); }, selector) : - (0,multicast/* multicast */.O)(new Subject/* Subject */.xQ()); -} -//# sourceMappingURL=publish.js.map - -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/filter.js -var filter = __webpack_require__(6008); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/share.js -var share = __webpack_require__(9095); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/startWith.js -var startWith = __webpack_require__(3485); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mapTo.js -var mapTo = __webpack_require__(5602); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscriber.js -var Subscriber = __webpack_require__(979); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/skipWhile.js -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ - - -function skipWhile(predicate) { - return function (source) { return source.lift(new SkipWhileOperator(predicate)); }; -} -var SkipWhileOperator = /*@__PURE__*/ (function () { - function SkipWhileOperator(predicate) { - this.predicate = predicate; - } - SkipWhileOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SkipWhileSubscriber(subscriber, this.predicate)); - }; - return SkipWhileOperator; -}()); -var SkipWhileSubscriber = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(SkipWhileSubscriber, _super); - function SkipWhileSubscriber(destination, predicate) { - var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.skipping = true; - _this.index = 0; - return _this; - } - SkipWhileSubscriber.prototype._next = function (value) { - var destination = this.destination; - if (this.skipping) { - this.tryCallPredicate(value); - } - if (!this.skipping) { - destination.next(value); - } - }; - SkipWhileSubscriber.prototype.tryCallPredicate = function (value) { - try { - var result = this.predicate(value, this.index++); - this.skipping = Boolean(result); - } - catch (err) { - this.destination.error(err); - } - }; - return SkipWhileSubscriber; -}(Subscriber/* Subscriber */.L)); -//# sourceMappingURL=skipWhile.js.map - -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/switchMapTo.js -var switchMapTo = __webpack_require__(1198); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMapTo.js -var mergeMapTo = __webpack_require__(3756); -// EXTERNAL MODULE: ./src/compat/event_listeners.ts + 4 modules -var event_listeners = __webpack_require__(1473); -;// CONCATENATED MODULE: ./src/compat/fullscreen.ts +// EXTERNAL MODULE: ./src/utils/noop.ts +var noop = __webpack_require__(8894); +;// CONCATENATED MODULE: ./src/utils/logger.ts /** * Copyright 2015 CANAL+ Group * @@ -12853,76 +13144,73 @@ var event_listeners = __webpack_require__(1473); * limitations under the License. */ +var DEFAULT_LOG_LEVEL = "NONE"; /** - * Request fullScreen action on a given element. - * @param {HTMLElement} elt + * Logger implementation. + * @class Logger */ -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") { - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - elt.webkitRequestFullscreen // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - (Element.ALLOW_KEYBOARD_INPUT); - } +var Logger = /*#__PURE__*/function () { + function Logger() { + this.error = noop/* default */.Z; + this.warn = noop/* default */.Z; + this.info = noop/* default */.Z; + this.debug = noop/* default */.Z; + this._levels = { + NONE: 0, + ERROR: 1, + WARNING: 2, + INFO: 3, + DEBUG: 4 + }; + this._currentLevel = DEFAULT_LOG_LEVEL; } -} -/** - * Exit fullscreen if an element is currently in fullscreen. - */ + /** + * @param {string} levelStr + */ -function fullscreen_exitFullscreen() { - if (fullscreen_isFullscreen()) { - var doc = document; - /* eslint-disable @typescript-eslint/unbound-method */ + var _proto = Logger.prototype; - if (typeof doc.exitFullscreen === "function") { - /* eslint-enable @typescript-eslint/unbound-method */ + _proto.setLevel = function setLevel(levelStr) { + var level; + var foundLevel = this._levels[levelStr]; - /* 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(); + if (typeof foundLevel === "number") { + level = foundLevel; + this._currentLevel = levelStr; + } else { + // not found + level = 0; + this._currentLevel = "NONE"; } + /* eslint-disable no-invalid-this */ + + /* eslint-disable no-console */ + + + this.error = level >= this._levels.ERROR ? console.error.bind(console) : noop/* default */.Z; + this.warn = level >= this._levels.WARNING ? console.warn.bind(console) : noop/* default */.Z; + this.info = level >= this._levels.INFO ? console.info.bind(console) : noop/* default */.Z; + this.debug = level >= this._levels.DEBUG ? console.log.bind(console) : noop/* default */.Z; + /* eslint-enable no-console */ + + /* eslint-enable no-invalid-this */ } -} -/** - * Returns true if an element in the document is being displayed in fullscreen - * mode; - * otherwise it's false. - * @returns {boolean} - */ + /** + * @returns {string} + */ + ; + _proto.getLevel = function getLevel() { + return this._currentLevel; + }; -function fullscreen_isFullscreen() { - var doc = document; - return doc.fullscreenElement != null || doc.mozFullScreenElement != null || doc.webkitFullscreenElement != null || doc.msFullscreenElement != null; -} + return Logger; +}(); -// 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 +;// CONCATENATED MODULE: ./src/log.ts /** * Copyright 2015 CANAL+ Group * @@ -12938,40 +13226,20 @@ var log = __webpack_require__(3887); * See the License for the specific language governing permissions and * limitations under the License. */ + // create a logger specifically for the RxPlayer. +var logger = new Logger(); +/* harmony default export */ const log = (logger); -/** - * 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; -} +/***/ }), +/***/ 5952: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -;// CONCATENATED MODULE: ./src/compat/can_rely_on_video_visibility_and_size.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ areSameContent) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -12988,117 +13256,53 @@ function getFirefoxVersion() { * 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. + * Check if two contents are the same + * @param {Object} content1 + * @param {Object} content2 * @returns {boolean} */ - -function canRelyOnVideoVisibilityAndSize() { - var _a, _b; - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - - - if (!browser_detection/* isFirefox */.vU) { - return true; - } - - var firefoxVersion = getFirefoxVersion(); - - if (firefoxVersion === null || firefoxVersion < 67) { - return true; - } - - return ((_b = (_a = HTMLVideoElement) === null || _a === void 0 ? void 0 : _a.prototype) === null || _b === void 0 ? void 0 : _b.requirePictureInPicture) !== undefined; - /* eslint-enable @typescript-eslint/no-unsafe-member-access */ +function areSameContent(content1, content2) { + return content1.segment.id === content2.segment.id && content1.representation.id === content2.representation.id && content1.adaptation.id === content2.adaptation.id && content1.period.id === content2.period.id; } -// EXTERNAL MODULE: ./src/config.ts -var config = __webpack_require__(944); -// EXTERNAL MODULE: ./src/errors/media_error.ts -var media_error = __webpack_require__(3714); -// EXTERNAL MODULE: ./src/errors/is_known_error.ts -var is_known_error = __webpack_require__(9822); -// EXTERNAL MODULE: ./src/errors/other_error.ts -var other_error = __webpack_require__(5389); -;// CONCATENATED MODULE: ./src/errors/format_error.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. - */ +/***/ }), -/* - * Format an unknown error into an API-defined error. - * @param {*} error - * @returns {Error} - */ +/***/ 1966: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -function formatError(error, _ref) { - var defaultCode = _ref.defaultCode, - defaultReason = _ref.defaultReason; +"use strict"; - if ((0,is_known_error/* default */.Z)(error)) { - return error; - } +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "ZP": () => (/* binding */ manifest) +}); - var reason = error instanceof Error ? error.toString() : defaultReason; - return new other_error/* default */.Z(defaultCode, reason); -} -// EXTERNAL MODULE: ./src/errors/error_codes.ts -var error_codes = __webpack_require__(5992); -// EXTERNAL MODULE: ./src/features/index.ts -var features = __webpack_require__(7874); +// UNUSED EXPORTS: Adaptation, Period, Representation, SUPPORTED_ADAPTATIONS_TYPE, StaticRepresentationIndex, areSameContent + +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js +var inheritsLoose = __webpack_require__(1788); // EXTERNAL MODULE: ./src/utils/are_arrays_of_numbers_equal.ts var are_arrays_of_numbers_equal = __webpack_require__(4791); +// EXTERNAL MODULE: ./src/utils/array_find.ts +var array_find = __webpack_require__(3274); // 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/noop.ts -var noop = __webpack_require__(8894); -// EXTERNAL MODULE: ./src/utils/object_assign.ts -var object_assign = __webpack_require__(8026); -// EXTERNAL MODULE: ./src/utils/promise.ts -var promise = __webpack_require__(9589); -// EXTERNAL MODULE: ./src/utils/ranges.ts -var ranges = __webpack_require__(2829); +// EXTERNAL MODULE: ./src/utils/id_generator.ts +var id_generator = __webpack_require__(908); // EXTERNAL MODULE: ./src/utils/warn_once.ts var warn_once = __webpack_require__(8806); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/defer.js -var defer = __webpack_require__(1410); -// EXTERNAL MODULE: ./src/compat/eme/custom_media_keys/index.ts + 7 modules -var custom_media_keys = __webpack_require__(6139); -// EXTERNAL MODULE: ./src/core/eme/media_keys_infos_store.ts -var media_keys_infos_store = __webpack_require__(6033); -;// CONCATENATED MODULE: ./src/core/eme/dispose_media_keys.ts +// EXTERNAL MODULE: ./src/errors/media_error.ts +var media_error = __webpack_require__(3714); +// EXTERNAL MODULE: ./src/log.ts + 1 modules +var log = __webpack_require__(3887); +// EXTERNAL MODULE: ./src/utils/array_includes.ts +var array_includes = __webpack_require__(7714); +// EXTERNAL MODULE: ./src/utils/is_null_or_undefined.ts +var is_null_or_undefined = __webpack_require__(1946); +// EXTERNAL MODULE: ./src/utils/languages/index.ts +var languages = __webpack_require__(7829); +;// CONCATENATED MODULE: ./src/utils/uniq.ts /** * Copyright 2015 CANAL+ Group * @@ -13115,30 +13319,40 @@ var media_keys_infos_store = __webpack_require__(6033); * limitations under the License. */ +/** + * Uniq implementation by combining a filter and an indexOf. + * @param {Array.<*>} arr + * @returns {Array.<*>} + */ +function uniqFromFilter(arr) { + return arr.filter(function (val, i, self) { + return self.indexOf(val) === i; + }); +} +/** + * Uniq implementation by using the Set browser API. + * @param {Array.<*>} arr + * @returns {Array.<*>} + */ - - +function uniqFromSet(arr) { + return Array.from(new Set(arr)); +} /** - * @param {Object} mediaKeysInfos - * @returns {Observable} + * Returns the input array without duplicates values. + * All values are unique. + * @param {Array.<*>} arr + * @returns {Array.<*>} */ -function disposeMediaKeys(mediaElement) { - return (0,defer/* defer */.P)(function () { - var currentState = media_keys_infos_store/* default.getState */.Z.getState(mediaElement); - if (currentState === null) { - return (0,of.of)(null); - } +/* harmony default export */ const uniq = (typeof window !== "undefined" && // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access +typeof window.Set === "function" && typeof Array.from === "function" ? uniqFromSet : uniqFromFilter); - log/* default.info */.Z.info("EME: Disposing of the current MediaKeys"); - var loadedSessionsStore = currentState.loadedSessionsStore; - media_keys_infos_store/* default.clearState */.Z.clearState(mediaElement); - return loadedSessionsStore.closeAllSessions().pipe((0,mergeMapTo/* mergeMapTo */.j)((0,custom_media_keys/* setMediaKeys */.Y)(mediaElement, null))); - }); -} -;// CONCATENATED MODULE: ./src/core/eme/dispose_eme.ts +// EXTERNAL MODULE: ./src/compat/browser_compatibility_types.ts +var browser_compatibility_types = __webpack_require__(3774); +;// CONCATENATED MODULE: ./src/compat/is_codec_supported.ts /** * Copyright 2015 CANAL+ Group * @@ -13155,15 +13369,31 @@ function disposeMediaKeys(mediaElement) { * limitations under the License. */ - /** - * Free up all ressources taken by the EME management. + * Returns true if the given codec is supported by the browser's MediaSource + * implementation. + * @param {string} mimeType - The MIME media type that you want to test support + * for in the current browser. + * This may include the codecs parameter to provide added details about the + * codecs used within the file. + * @returns {Boolean} */ -function disposeEME(mediaElement) { - disposeMediaKeys(mediaElement).subscribe(noop/* default */.Z); +function isCodecSupported(mimeType) { + if (browser_compatibility_types/* MediaSource_ */.JJ == null) { + return false; + } + /* eslint-disable @typescript-eslint/unbound-method */ + + + if (typeof browser_compatibility_types/* MediaSource_.isTypeSupported */.JJ.isTypeSupported === "function") { + /* eslint-enable @typescript-eslint/unbound-method */ + return browser_compatibility_types/* MediaSource_.isTypeSupported */.JJ.isTypeSupported(mimeType); + } + + return true; } -;// CONCATENATED MODULE: ./src/core/eme/get_current_key_system.ts +;// CONCATENATED MODULE: ./src/manifest/representation.ts /** * Copyright 2015 CANAL+ Group * @@ -13180,307 +13410,233 @@ function disposeEME(mediaElement) { * limitations under the License. */ + + /** - * Returns the name of the current key system used. - * @param {HTMLMediaElement} mediaElement - * @returns {string|null} + * Normalized Representation structure. + * @class Representation */ -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; -} -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/ignoreElements.js -var ignoreElements = __webpack_require__(6738); -;// 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. - */ +var Representation = /*#__PURE__*/function () { + /** + * @param {Object} args + */ + function Representation(args, opts) { + this.id = args.id; + this.bitrate = args.bitrate; + this.codec = args.codecs; -/** - * Returns true if the mediakeys associated to a media element should be - * unset once the content is stopped. - * Depends on the target. - * @returns {Boolean} - */ + if (args.height != null) { + this.height = args.height; + } -function shouldUnsetMediaKeys() { - return browser_detection/* isIE11 */.fq; -} -;// CONCATENATED MODULE: ./src/core/eme/clear_eme_session.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. - */ + if (args.width != null) { + this.width = args.width; + } + if (args.mimeType != null) { + this.mimeType = args.mimeType; + } + if (args.contentProtections !== undefined) { + this.contentProtections = args.contentProtections; + } + if (args.frameRate != null) { + this.frameRate = args.frameRate; + } + this.index = args.index; + this.isSupported = opts.type === "audio" || opts.type === "video" ? isCodecSupported(this.getMimeTypeString()) : true; // TODO for other types + } + /** + * Returns "mime-type string" which includes both the mime-type and the codec, + * which is often needed when interacting with the browser's APIs. + * @returns {string} + */ -/** - * Clear EME ressources that should be cleared when the current content stops - * its playback. - * @param {HTMLMediaElement} mediaElement - * @returns {Observable} - */ + var _proto = Representation.prototype; -function clearEMESession(mediaElement) { - return (0,defer/* defer */.P)(function () { - log/* default.info */.Z.info("EME: Clearing-up EME session."); + _proto.getMimeTypeString = function getMimeTypeString() { + var _a, _b; - if (shouldUnsetMediaKeys()) { - log/* default.info */.Z.info("EME: disposing current MediaKeys."); - return disposeMediaKeys(mediaElement).pipe((0,ignoreElements/* ignoreElements */.l)()); - } + return ((_a = this.mimeType) !== null && _a !== void 0 ? _a : "") + ";codecs=\"" + ((_b = this.codec) !== null && _b !== void 0 ? _b : "") + "\""; + } + /** + * Returns encryption initialization data linked to the given DRM's system ID. + * This data may be useful to decrypt encrypted media segments. + * + * Returns an empty array if there is no data found for that system ID at the + * moment. + * + * When you know that all encryption data has been added to this + * Representation, you can also call the `getAllEncryptionData` method. + * This second function will return all encryption initialization data + * regardless of the DRM system, and might thus be used in all cases. + * + * /!\ Note that encryption initialization data may be progressively added to + * this Representation after `_addProtectionData` calls or Manifest updates. + * Because of this, the return value of this function might change after those + * events. + * + * @param {string} drmSystemId - The hexa-encoded DRM system ID + * @returns {Array.} + */ + ; - var currentState = media_keys_infos_store/* default.getState */.Z.getState(mediaElement); + _proto.getEncryptionData = function getEncryptionData(drmSystemId) { + var _a; - if (currentState !== null && currentState.keySystemOptions.closeSessionsOnStop === true) { - log/* default.info */.Z.info("EME: closing all current sessions."); - return currentState.loadedSessionsStore.closeAllSessions().pipe((0,ignoreElements/* ignoreElements */.l)()); - } + var allInitData = this.getAllEncryptionData(); + var filtered = []; - log/* default.info */.Z.info("EME: Nothing to clear. Returning right away. No state =", currentState === null); - return empty/* EMPTY */.E; - }); -} -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMap.js -var mergeMap = __webpack_require__(7746); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/shareReplay.js -var shareReplay = __webpack_require__(7006); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/from.js + 6 modules -var from = __webpack_require__(4072); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/innerSubscribe.js -var innerSubscribe = __webpack_require__(7604); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/exhaustMap.js -/** PURE_IMPORTS_START tslib,_map,_observable_from,_innerSubscribe PURE_IMPORTS_END */ + for (var i = 0; i < allInitData.length; i++) { + var createdObjForType = false; + var initData = allInitData[i]; + for (var j = 0; j < initData.values.length; j++) { + if (initData.values[j].systemId.toLowerCase() === drmSystemId.toLowerCase()) { + if (!createdObjForType) { + var keyIds = (_a = this.contentProtections) === null || _a === void 0 ? void 0 : _a.keyIds.map(function (val) { + return val.keyId; + }); + filtered.push({ + type: initData.type, + keyIds: keyIds, + values: [initData.values[j]] + }); + createdObjForType = true; + } else { + filtered[filtered.length - 1].values.push(initData.values[j]); + } + } + } + } + return filtered; + } + /** + * Returns all currently-known encryption initialization data linked to this + * Representation. + * Encryption initialization data is generally required to be able to decrypt + * those Representation's media segments. + * + * Unlike `getEncryptionData`, this method will return all available + * encryption data. + * It might as such might be used when either the current drm's system id is + * not known or when no encryption data specific to it was found. In that + * case, providing every encryption data linked to this Representation might + * still allow decryption. + * + * Returns an empty array in two cases: + * - the content is not encrypted. + * - We don't have any decryption data yet. + * + * /!\ Note that new encryption initialization data can be added progressively + * through the `_addProtectionData` method or through Manifest updates. + * It is thus highly advised to only rely on this method once every protection + * data related to this Representation has been known to be added. + * + * The main situation where new encryption initialization data is added is + * after parsing this Representation's initialization segment, if one exists. + * @returns {Array.} + */ + ; + _proto.getAllEncryptionData = function getAllEncryptionData() { + var _a; -function exhaustMap(project, resultSelector) { - if (resultSelector) { - return function (source) { return source.pipe(exhaustMap(function (a, i) { return (0,from/* from */.D)(project(a, i)).pipe((0,map/* map */.U)(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; - } - return function (source) { - return source.lift(new ExhaustMapOperator(project)); - }; -} -var ExhaustMapOperator = /*@__PURE__*/ (function () { - function ExhaustMapOperator(project) { - this.project = project; - } - ExhaustMapOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ExhaustMapSubscriber(subscriber, this.project)); - }; - return ExhaustMapOperator; -}()); -var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(ExhaustMapSubscriber, _super); - function ExhaustMapSubscriber(destination, project) { - var _this = _super.call(this, destination) || this; - _this.project = project; - _this.hasSubscription = false; - _this.hasCompleted = false; - _this.index = 0; - return _this; + if (this.contentProtections === undefined || this.contentProtections.initData.length === 0) { + return []; } - ExhaustMapSubscriber.prototype._next = function (value) { - if (!this.hasSubscription) { - this.tryNext(value); - } - }; - ExhaustMapSubscriber.prototype.tryNext = function (value) { - var result; - var index = this.index++; - try { - result = this.project(value, index); - } - catch (err) { - this.destination.error(err); - return; - } - this.hasSubscription = true; - this._innerSub(result); - }; - ExhaustMapSubscriber.prototype._innerSub = function (result) { - var innerSubscriber = new innerSubscribe/* SimpleInnerSubscriber */.IY(this); - var destination = this.destination; - destination.add(innerSubscriber); - var innerSubscription = (0,innerSubscribe/* innerSubscribe */.ft)(result, innerSubscriber); - if (innerSubscription !== innerSubscriber) { - destination.add(innerSubscription); - } - }; - ExhaustMapSubscriber.prototype._complete = function () { - this.hasCompleted = true; - if (!this.hasSubscription) { - this.destination.complete(); - } - this.unsubscribe(); - }; - ExhaustMapSubscriber.prototype.notifyNext = function (innerValue) { - this.destination.next(innerValue); - }; - ExhaustMapSubscriber.prototype.notifyError = function (err) { - this.destination.error(err); - }; - ExhaustMapSubscriber.prototype.notifyComplete = function () { - this.hasSubscription = false; - if (this.hasCompleted) { - this.destination.complete(); - } - }; - return ExhaustMapSubscriber; -}(innerSubscribe/* SimpleOuterSubscriber */.Ds)); -//# sourceMappingURL=exhaustMap.js.map - -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/tap.js -var tap = __webpack_require__(3068); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscription.js + 1 modules -var Subscription = __webpack_require__(3884); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/finalize.js -/** PURE_IMPORTS_START tslib,_Subscriber,_Subscription PURE_IMPORTS_END */ + var keyIds = (_a = this.contentProtections) === null || _a === void 0 ? void 0 : _a.keyIds.map(function (val) { + return val.keyId; + }); + return this.contentProtections.initData.map(function (x) { + return { + type: x.type, + keyIds: keyIds, + values: x.values + }; + }); + } + /** + * Add new encryption initialization data to this Representation if it was not + * already included. + * + * Returns `true` if new encryption initialization data has been added. + * Returns `false` if none has been added (e.g. because it was already known). + * + * /!\ Mutates the current Representation + * @param {string} initDataArr + * @param {string} systemId + * @param {Uint8Array} data + * @returns {boolean} + */ + ; + _proto._addProtectionData = function _addProtectionData(initDataType, data) { + var hasUpdatedProtectionData = false; -function finalize(callback) { - return function (source) { return source.lift(new FinallyOperator(callback)); }; -} -var FinallyOperator = /*@__PURE__*/ (function () { - function FinallyOperator(callback) { - this.callback = callback; - } - FinallyOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new FinallySubscriber(subscriber, this.callback)); - }; - return FinallyOperator; -}()); -var FinallySubscriber = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(FinallySubscriber, _super); - function FinallySubscriber(destination, callback) { - var _this = _super.call(this, destination) || this; - _this.add(new Subscription/* Subscription */.w(callback)); - return _this; + if (this.contentProtections === undefined) { + this.contentProtections = { + keyIds: [], + initData: [{ + type: initDataType, + values: data + }] + }; + return true; } - return FinallySubscriber; -}(Subscriber/* Subscriber */.L)); -//# sourceMappingURL=finalize.js.map -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/switchMap.js -var switchMap = __webpack_require__(6381); -;// 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. - */ + var cInitData = this.contentProtections.initData; -/** - * 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} - */ -function shouldReloadMediaSourceOnDecipherabilityUpdate(currentKeySystem) { - return currentKeySystem === null || currentKeySystem.indexOf("widevine") < 0; -} -// EXTERNAL MODULE: ./src/manifest/index.ts + 10 modules -var manifest = __webpack_require__(1966); -// EXTERNAL MODULE: ./src/utils/defer_subscriptions.ts + 6 modules -var defer_subscriptions = __webpack_require__(8025); -// EXTERNAL MODULE: ./src/utils/filter_map.ts -var filter_map = __webpack_require__(2793); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules -var Observable = __webpack_require__(4379); -;// 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. - */ + for (var i = 0; i < cInitData.length; i++) { + if (cInitData[i].type === initDataType) { + var cValues = cInitData[i].values; // loop through data -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]; - } + for (var dataI = 0; dataI < data.length; dataI++) { + var dataToAdd = data[dataI]; + var cValuesIdx = void 0; - return new Observable/* Observable */.y(function (obs) { - if (isPending) { - obs.complete(); - return undefined; + for (cValuesIdx = 0; cValuesIdx < cValues.length; cValuesIdx++) { + if (dataToAdd.systemId === cValues[cValuesIdx].systemId) { + if ((0,are_arrays_of_numbers_equal/* default */.Z)(dataToAdd.data, cValues[cValuesIdx].data)) { + // go to next dataToAdd + break; + } else { + log/* default.warn */.Z.warn("Manifest: different init data for the same system ID"); + } + } + } + + if (cValuesIdx === cValues.length) { + // we didn't break the loop === we didn't already find that value + cValues.push(dataToAdd); + hasUpdatedProtectionData = true; + } + } + + return hasUpdatedProtectionData; } + } // If we are here, this means that we didn't find the corresponding + // init data type in this.contentProtections.initData. - isPending = true; - var funcSubscription = func.apply(void 0, args).subscribe(function (i) { - obs.next(i); - }, function (e) { - isPending = false; - obs.error(e); - }, function () { - isPending = false; - obs.complete(); - }); - return function () { - funcSubscription.unsubscribe(); - isPending = false; - }; + + this.contentProtections.initData.push({ + type: initDataType, + values: data }); + return true; }; -} -// EXTERNAL MODULE: ./src/utils/take_first_set.ts -var take_first_set = __webpack_require__(5278); -;// CONCATENATED MODULE: ./src/core/abr/ewma.ts + + return Representation; +}(); + +/* harmony default export */ const manifest_representation = (Representation); +;// CONCATENATED MODULE: ./src/manifest/adaptation.ts /** * Copyright 2015 CANAL+ Group * @@ -13497,308 +13653,180 @@ var take_first_set = __webpack_require__(5278); * limitations under the License. */ -/** - * Tweaked implementation of an exponential weighted Moving Average. - * Heavily "inspired" from the shaka-player one (Ewma). - * @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; -}(); +/** List in an array every possible value for the Adaptation's `type` property. */ -;// CONCATENATED MODULE: ./src/core/abr/bandwidth_estimator.ts +var SUPPORTED_ADAPTATIONS_TYPE = ["audio", "video", "text", "image"]; /** - * 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 given Adaptation's `type` is a valid `type` property. + * @param {string} adaptationType + * @returns {boolean} */ - -var ABR_MINIMUM_TOTAL_BYTES = config/* default.ABR_MINIMUM_TOTAL_BYTES */.Z.ABR_MINIMUM_TOTAL_BYTES, - ABR_MINIMUM_CHUNK_SIZE = config/* default.ABR_MINIMUM_CHUNK_SIZE */.Z.ABR_MINIMUM_CHUNK_SIZE, - ABR_FAST_EMA = config/* default.ABR_FAST_EMA */.Z.ABR_FAST_EMA, - ABR_SLOW_EMA = config/* default.ABR_SLOW_EMA */.Z.ABR_SLOW_EMA; +function isSupportedAdaptationType(adaptationType) { + return (0,array_includes/* default */.Z)(SUPPORTED_ADAPTATIONS_TYPE, adaptationType); +} /** - * Calculate a mean bandwidth based on the bytes downloaded and the amount - * of time needed to do so. - * - * Heavily "inspired" from the Shaka-Player's "ewma bandwidth estimator". - * @class BandwidthEstimator + * Normalized Adaptation structure. + * An Adaptation describes a single `Track`. For example a specific audio + * track (in a given language) or a specific video track. + * It istelf can be represented in different qualities, which we call here + * `Representation`. + * @class Adaptation */ -var BandwidthEstimator = /*#__PURE__*/function () { - function BandwidthEstimator() { - /** - * A fast-moving average. - * @private - */ - this._fastEWMA = new EWMA(ABR_FAST_EMA); - /** - * A slow-moving average. - * @private - */ - - this._slowEWMA = new EWMA(ABR_SLOW_EMA); - /** - * Number of bytes sampled. - * @private - */ - this._bytesSampled = 0; - } +var Adaptation = /*#__PURE__*/function () { /** - * Takes a bandwidth sample. - * @param {number} durationMs - The amount of time, in milliseconds, for a - * particular request. - * @param {number} numBytes - The total number of bytes transferred in that - * request. + * @constructor + * @param {Object} parsedAdaptation + * @param {Object|undefined} [options] */ + function Adaptation(parsedAdaptation, options) { + if (options === void 0) { + options = {}; + } + var _options = options, + representationFilter = _options.representationFilter, + isManuallyAdded = _options.isManuallyAdded; + this.parsingErrors = []; + this.id = parsedAdaptation.id; - var _proto = BandwidthEstimator.prototype; + if (!isSupportedAdaptationType(parsedAdaptation.type)) { + log/* default.info */.Z.info("Manifest: Not supported adaptation type", parsedAdaptation.type); + /* eslint-disable @typescript-eslint/restrict-template-expressions */ - _proto.addSample = function addSample(durationInMs, numberOfBytes) { - if (numberOfBytes < ABR_MINIMUM_CHUNK_SIZE) { - return; + throw new media_error/* default */.Z("MANIFEST_UNSUPPORTED_ADAPTATION_TYPE", "\"" + parsedAdaptation.type + "\" is not a valid " + "Adaptation type."); + /* eslint-enable @typescript-eslint/restrict-template-expressions */ } - var bandwidth = numberOfBytes * 8000 / durationInMs; - var weight = durationInMs / 1000; - this._bytesSampled += numberOfBytes; + this.type = parsedAdaptation.type; - this._fastEWMA.addSample(weight, bandwidth); + if (parsedAdaptation.language !== undefined) { + this.language = parsedAdaptation.language; + this.normalizedLanguage = (0,languages/* default */.ZP)(parsedAdaptation.language); + } - this._slowEWMA.addSample(weight, bandwidth); - } - /** - * Get estimate of the bandwidth, in bits per seconds. - * @returns {Number|undefined} - */ - ; + if (parsedAdaptation.closedCaption !== undefined) { + this.isClosedCaption = parsedAdaptation.closedCaption; + } - _proto.getEstimate = function getEstimate() { - 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. + if (parsedAdaptation.audioDescription !== undefined) { + this.isAudioDescription = parsedAdaptation.audioDescription; + } + if (parsedAdaptation.isDub !== undefined) { + this.isDub = parsedAdaptation.isDub; + } - return Math.min(this._fastEWMA.getEstimate(), this._slowEWMA.getEstimate()); - } - /** - * Reset the bandwidth estimation. - */ - ; + if (parsedAdaptation.isSignInterpreted !== undefined) { + this.isSignInterpreted = parsedAdaptation.isSignInterpreted; + } - _proto.reset = function reset() { - this._fastEWMA = new EWMA(ABR_FAST_EMA); - this._slowEWMA = new EWMA(ABR_SLOW_EMA); - this._bytesSampled = 0; - }; + var argsRepresentations = parsedAdaptation.representations; + var representations = []; + var isSupported = false; - return BandwidthEstimator; -}(); + for (var i = 0; i < argsRepresentations.length; i++) { + var representation = new manifest_representation(argsRepresentations[i], { + type: this.type + }); + var shouldAdd = (0,is_null_or_undefined/* default */.Z)(representationFilter) || representationFilter(representation, { + bufferType: this.type, + language: this.language, + normalizedLanguage: this.normalizedLanguage, + isClosedCaption: this.isClosedCaption, + isDub: this.isDub, + isAudioDescription: this.isAudioDescription, + isSignInterpreted: this.isSignInterpreted + }); + if (shouldAdd) { + representations.push(representation); -;// CONCATENATED MODULE: ./src/core/abr/create_filters.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. - */ + if (!isSupported && representation.isSupported) { + isSupported = true; + } + } + } + representations.sort(function (a, b) { + return a.bitrate - b.bitrate; + }); + this.representations = representations; + this.isSupported = isSupported; // for manuallyAdded adaptations (not in the manifest) + this.manuallyAdded = isManuallyAdded === true; -/** - * Create Observable that merge several throttling Observables into one. - * @param {Observable} limitWidth$ - Emit the width at which the chosen - * Representation should be limited. - * @param {Observable} throttleBitrate$ - Emit the maximum bitrate authorized. - * @param {Observable} throttle$ - Also emit the maximum bitrate authorized. - * Here for legacy reasons. - * @returns {Observable} - */ + if (this.representations.length > 0 && !isSupported) { + log/* default.warn */.Z.warn("Incompatible codecs for adaptation", parsedAdaptation); + var error = new media_error/* default */.Z("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs."); + this.parsingErrors.push(error); + } + } + /** + * Returns unique bitrate for every Representation in this Adaptation. + * @returns {Array.} + */ -function createFilters(limitWidth$, throttleBitrate$, throttle$) { - var deviceEventsArray = []; - if (limitWidth$ != null) { - deviceEventsArray.push(limitWidth$.pipe((0,map/* map */.U)(function (width) { - return { - width: width - }; - }))); - } + var _proto = Adaptation.prototype; - if (throttle$ != null) { - deviceEventsArray.push(throttle$.pipe((0,map/* map */.U)(function (bitrate) { - return { - bitrate: bitrate - }; - }))); - } + _proto.getAvailableBitrates = function getAvailableBitrates() { + var bitrates = []; - if (throttleBitrate$ != null) { - deviceEventsArray.push(throttleBitrate$.pipe((0,map/* map */.U)(function (bitrate) { - return { - bitrate: bitrate - }; - }))); - } // Emit restrictions on the pools of available representations to choose - // from. + for (var i = 0; i < this.representations.length; i++) { + var representation = this.representations[i]; + if (representation.decipherable !== false) { + bitrates.push(representation.bitrate); + } + } - return deviceEventsArray.length > 0 ? (0,combineLatest/* combineLatest */.aj)(deviceEventsArray).pipe((0,map/* map */.U)(function (args) { - return object_assign/* default.apply */.Z.apply(void 0, [{}].concat(args)); - })) : (0,of.of)({}); -} -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/OuterSubscriber.js -var OuterSubscriber = __webpack_require__(2039); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeToResult.js + 1 modules -var subscribeToResult = __webpack_require__(2080); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/withLatestFrom.js -/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ + return uniq(bitrates); + } + /** + * Returns all Representation in this Adaptation that can be played (that is: + * not undecipherable and with a supported codec). + * @returns {Array.} + */ + ; + _proto.getPlayableRepresentations = function getPlayableRepresentations() { + return this.representations.filter(function (rep) { + return rep.isSupported && rep.decipherable !== false; + }); + } + /** + * Returns the Representation linked to the given ID. + * @param {number|string} wantedId + * @returns {Object|undefined} + */ + ; + _proto.getRepresentation = function getRepresentation(wantedId) { + return (0,array_find/* default */.Z)(this.representations, function (_ref) { + var id = _ref.id; + return wantedId === id; + }); + }; -function withLatestFrom() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return function (source) { - var project; - if (typeof args[args.length - 1] === 'function') { - project = args.pop(); - } - var observables = args; - return source.lift(new WithLatestFromOperator(observables, project)); - }; -} -var WithLatestFromOperator = /*@__PURE__*/ (function () { - function WithLatestFromOperator(observables, project) { - this.observables = observables; - this.project = project; - } - WithLatestFromOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new WithLatestFromSubscriber(subscriber, this.observables, this.project)); - }; - return WithLatestFromOperator; -}()); -var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(WithLatestFromSubscriber, _super); - function WithLatestFromSubscriber(destination, observables, project) { - var _this = _super.call(this, destination) || this; - _this.observables = observables; - _this.project = project; - _this.toRespond = []; - var len = observables.length; - _this.values = new Array(len); - for (var i = 0; i < len; i++) { - _this.toRespond.push(i); - } - for (var i = 0; i < len; i++) { - var observable = observables[i]; - _this.add((0,subscribeToResult/* subscribeToResult */.D)(_this, observable, undefined, i)); - } - return _this; - } - WithLatestFromSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { - this.values[outerIndex] = innerValue; - var toRespond = this.toRespond; - if (toRespond.length > 0) { - var found = toRespond.indexOf(outerIndex); - if (found !== -1) { - toRespond.splice(found, 1); - } - } - }; - WithLatestFromSubscriber.prototype.notifyComplete = function () { - }; - WithLatestFromSubscriber.prototype._next = function (value) { - if (this.toRespond.length === 0) { - var args = [value].concat(this.values); - if (this.project) { - this._tryProject(args); - } - else { - this.destination.next(args); - } - } - }; - WithLatestFromSubscriber.prototype._tryProject = function (args) { - var result; - try { - result = this.project.apply(this, args); - } - catch (err) { - this.destination.error(err); - return; - } - this.destination.next(result); - }; - return WithLatestFromSubscriber; -}(OuterSubscriber/* OuterSubscriber */.L)); -//# sourceMappingURL=withLatestFrom.js.map + return Adaptation; +}(); -;// CONCATENATED MODULE: ./src/core/abr/get_buffer_levels.ts + +// EXTERNAL MODULE: ./src/errors/is_known_error.ts +var is_known_error = __webpack_require__(9822); +// EXTERNAL MODULE: ./src/utils/object_values.ts +var object_values = __webpack_require__(1679); +;// CONCATENATED MODULE: ./src/manifest/period.ts /** * Copyright 2015 CANAL+ Group * @@ -13815,180 +13843,150 @@ var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { * 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.} + * Class representing the tracks and qualities available from a given time + * period in the the Manifest. + * @class Period */ -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); - }); +var Period = /*#__PURE__*/function () { /** - * Get minimum buffer we should keep ahead to pick this bitrate. - * @param {number} index - * @returns {number} + * @constructor + * @param {Object} args + * @param {function|undefined} [representationFilter] */ + function Period(args, representationFilter) { + var _this = this; - function minBufferLevelForBitrate(index) { - if (index === 0) { - return 0; - } - - var boundedIndex = Math.min(Math.max(1, index), bitrates.length - 1); - return Vp * (gp + (bitrates[boundedIndex] * utilities[boundedIndex - 1] - bitrates[boundedIndex - 1] * utilities[boundedIndex]) / (bitrates[boundedIndex] - bitrates[boundedIndex - 1])) + 4; - } -} -// EXTERNAL MODULE: ./src/utils/array_find_index.ts -var array_find_index = __webpack_require__(5138); -;// CONCATENATED MODULE: ./src/core/abr/get_estimate_from_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. - */ + this.parsingErrors = []; + this.id = args.id; + this.adaptations = Object.keys(args.adaptations).reduce(function (acc, type) { + var adaptationsForType = args.adaptations[type]; + if (adaptationsForType == null) { + return acc; + } -/** - * From the buffer gap, choose a representation. - * @param {Object} clockTick - * @param {Array.} bitrates - * @param {Array.} bufferLevels - * @returns {Object|undefined} - */ + var filteredAdaptations = adaptationsForType.map(function (adaptation) { + var _this$parsingErrors; -function getEstimateFromBufferLevels(clockTick, bitrates, bufferLevels) { - var bufferGap = clockTick.bufferGap, - currentBitrate = clockTick.currentBitrate, - currentScore = clockTick.currentScore, - speed = clockTick.speed; + var newAdaptation = null; - if (currentBitrate == null) { - return bitrates[0]; - } + try { + newAdaptation = new Adaptation(adaptation, { + representationFilter: representationFilter + }); + } catch (err) { + if ((0,is_known_error/* default */.Z)(err) && err.code === "MANIFEST_UNSUPPORTED_ADAPTATION_TYPE") { + _this.parsingErrors.push(err); - var currentBitrateIndex = (0,array_find_index/* default */.Z)(bitrates, function (b) { - return b === currentBitrate; - }); + return null; + } - if (currentBitrateIndex < 0 || bitrates.length !== bufferLevels.length) { - log/* default.error */.Z.error("ABR: Current Bitrate not found in the calculated levels"); - return bitrates[0]; - } + throw err; + } - var scaledScore; + (_this$parsingErrors = _this.parsingErrors).push.apply(_this$parsingErrors, newAdaptation.parsingErrors); - if (currentScore != null) { - scaledScore = speed === 0 ? currentScore : currentScore / speed; - } + return newAdaptation; + }).filter(function (adaptation) { + return adaptation !== null && adaptation.representations.length > 0; + }); - if (scaledScore != null && scaledScore > 1) { - var currentBufferLevel = bufferLevels[currentBitrateIndex]; + if (filteredAdaptations.every(function (adaptation) { + return !adaptation.isSupported; + }) && adaptationsForType.length > 0 && (type === "video" || type === "audio")) { + throw new media_error/* default */.Z("MANIFEST_PARSE_ERROR", "No supported " + type + " adaptations"); + } - var nextIndex = function () { - for (var i = currentBitrateIndex + 1; i < bufferLevels.length; i++) { - if (bufferLevels[i] > currentBufferLevel) { - return i; - } + if (filteredAdaptations.length > 0) { + acc[type] = filteredAdaptations; } - }(); - if (nextIndex != null) { - var nextBufferLevel = bufferLevels[nextIndex]; + return acc; + }, {}); - if (bufferGap >= nextBufferLevel) { - return bitrates[nextIndex]; - } + if (!Array.isArray(this.adaptations.video) && !Array.isArray(this.adaptations.audio)) { + throw new media_error/* default */.Z("MANIFEST_PARSE_ERROR", "No supported audio and video tracks."); + } + + this.duration = args.duration; + this.start = args.start; + + if (this.duration != null && this.start != null) { + this.end = this.start + this.duration; } + + this.streamEvents = args.streamEvents === undefined ? [] : args.streamEvents; } + /** + * Returns every `Adaptations` (or `tracks`) linked to that Period, in an + * Array. + * @returns {Array.} + */ - 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]; - } - } + var _proto = Period.prototype; - return currentBitrate; - } + _proto.getAdaptations = function getAdaptations() { + var adaptationsByType = this.adaptations; + return (0,object_values/* default */.Z)(adaptationsByType).reduce( // Note: the second case cannot happen. TS is just being dumb here + function (acc, adaptations) { + return adaptations != null ? acc.concat(adaptations) : acc; + }, []); } + /** + * Returns every `Adaptations` (or `tracks`) linked to that Period for a + * given type. + * @param {string} adaptationType + * @returns {Array.} + */ + ; - return currentBitrate; -} -;// CONCATENATED MODULE: ./src/core/abr/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. - */ + _proto.getAdaptationsForType = function getAdaptationsForType(adaptationType) { + var adaptationsForType = this.adaptations[adaptationType]; + return adaptationsForType == null ? [] : adaptationsForType; + } + /** + * Returns the Adaptation linked to the given ID. + * @param {number|string} wantedId + * @returns {Object|undefined} + */ + ; + _proto.getAdaptation = function getAdaptation(wantedId) { + return (0,array_find/* default */.Z)(this.getAdaptations(), function (_ref) { + var id = _ref.id; + return wantedId === id; + }); + }; + _proto.getPlayableAdaptations = function getPlayableAdaptations(type) { + if (type === undefined) { + return this.getAdaptations().filter(function (ada) { + return ada.getPlayableRepresentations().length > 0; + }); + } + var adaptationsForType = this.adaptations[type]; -/** - * Choose a bitrate based on the currently available buffer. - * - * This algorithm is based on the 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. - * - * @param {Observable} update$ - * @param {Array.} bitrates - * @returns {Observable} - */ + if (adaptationsForType === undefined) { + return []; + } -function BufferBasedChooser(update$, bitrates) { - var levelsMap = getBufferLevels(bitrates); - log/* default.debug */.Z.debug("ABR: Steps for buffer based chooser.", levelsMap.map(function (l, i) { - return { - bufferLevel: l, - bitrate: bitrates[i] - }; - })); - return update$.pipe((0,map/* map */.U)(function (clockTick) { - return getEstimateFromBufferLevels(clockTick, bitrates, levelsMap); - })); -} -;// CONCATENATED MODULE: ./src/core/abr/cached_segment_detector.ts + return adaptationsForType.filter(function (ada) { + return ada.getPlayableRepresentations().length > 0; + }); + }; + + return Period; +}(); + + +;// CONCATENATED MODULE: ./src/manifest/representation_index/static.ts /** * Copyright 2015 CANAL+ Group * @@ -14005,60 +14003,138 @@ function BufferBasedChooser(update$, bitrates) { * limitations under the License. */ -var CACHE_LOAD_DURATION_THRESHOLDS = config/* default.CACHE_LOAD_DURATION_THRESHOLDS */.Z.CACHE_LOAD_DURATION_THRESHOLDS; -/** - * From segment download duration, tells if a segment - * may have been loaded from cache. - * @param {string} contentType - * @param {number} downloadDuration - */ - -function mayBeFromCache(contentType, downloadDuration) { - var cacheLoadDurationThreshold = CACHE_LOAD_DURATION_THRESHOLDS[contentType]; - return downloadDuration < cacheLoadDurationThreshold; -} /** - * Returns a function used to determine if a segment was loaded - * from cache or not. - * @returns {function} + * Simple RepresentationIndex implementation for static files. + * @class StaticRepresentationIndex */ - -function generateCachedSegmentDetector() { - var hasAlreadyLoadedNonCachedContent = false; +var StaticRepresentationIndex = /*#__PURE__*/function () { /** - * Determines with request duration if a loaded chunk may have been loaded - * from cache, and return true if should ignore the metrics for representation - * chooser. - * @param {Object} content - * @param {number} duration - * @returns {boolean} + * @param {Object} infos + */ + function StaticRepresentationIndex(infos) { + this._mediaURLs = infos.media; + } + /** + * Static contents do not have any initialization segments. + * Just return null. + * @returns {null} */ - return function shouldIgnoreMetrics(content, downloadDuration) { - var contentType = content.adaptation.type; - if (contentType === "text" || contentType === "image") { - return false; - } + var _proto = StaticRepresentationIndex.prototype; - var segmentMayBeFromCache = mayBeFromCache(contentType, downloadDuration); + _proto.getInitSegment = function getInitSegment() { + return null; + } + /** + * Returns the only Segment available here. + * @returns {Array.} + */ + ; - if (segmentMayBeFromCache && hasAlreadyLoadedNonCachedContent) { - // We already loaded not cached segments. - // Do not consider cached segments anymore. - return true; - } + _proto.getSegments = function getSegments() { + return [{ + id: "0", + isInit: false, + number: 0, + mediaURLs: [this._mediaURLs], + time: 0, + end: Number.MAX_VALUE, + duration: Number.MAX_VALUE, + timescale: 1 + }]; + } + /** + * Returns first position in index. + * @returns {undefined} + */ + ; - if (!segmentMayBeFromCache && !hasAlreadyLoadedNonCachedContent) { - // First segment not loaded from cache. - hasAlreadyLoadedNonCachedContent = true; - } + _proto.getFirstPosition = function getFirstPosition() { + return; + } + /** + * Returns last position in index. + * @returns {undefined} + */ + ; + + _proto.getLastPosition = function getLastPosition() { + return; + } + /** + * Returns false as a static file never need to be refreshed. + * @returns {Boolean} + */ + ; + + _proto.shouldRefresh = function shouldRefresh() { + return false; + } + /** + * @returns {null} + */ + ; + + _proto.checkDiscontinuity = function checkDiscontinuity() { + return null; + } + /** + * @returns {boolean} + */ + ; + + _proto.areSegmentsChronologicallyGenerated = function areSegmentsChronologicallyGenerated() { + return true; + } + /** + * Returns true as a static file should never need lose availability. + * @returns {Boolean} + */ + ; + + _proto.isSegmentStillAvailable = function isSegmentStillAvailable() { + return true; + } + /** + * @returns {Boolean} + */ + ; + _proto.canBeOutOfSyncError = function canBeOutOfSyncError() { return false; + } + /** + * @returns {Boolean} + */ + ; + + _proto.isFinished = function isFinished() { + return true; + } + /** + * @returns {Boolean} + */ + ; + + _proto.isInitialized = function isInitialized() { + return true; }; -} -;// CONCATENATED MODULE: ./src/core/abr/filter_by_bitrate.ts + + _proto._replace = function _replace() { + log/* default.warn */.Z.warn("Tried to replace a static RepresentationIndex"); + }; + + _proto._update = function _update() { + log/* default.warn */.Z.warn("Tried to update a static RepresentationIndex"); + }; + + return StaticRepresentationIndex; +}(); + + +;// CONCATENATED MODULE: ./src/manifest/types.ts /** * Copyright 2015 CANAL+ Group * @@ -14075,38 +14151,26 @@ function generateCachedSegmentDetector() { * 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 []; - } - - 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; - }); +/** Enumerate the different ways a Manifest update can be done. */ +var MANIFEST_UPDATE_TYPE; - if (firstSuperiorBitrateIndex === -1) { - return representations; // All representations have lower bitrates. - } +(function (MANIFEST_UPDATE_TYPE) { + /** + * Manifest is updated entirely thanks to a re-downloaded version of + * the original manifest document. + */ + MANIFEST_UPDATE_TYPE[MANIFEST_UPDATE_TYPE["Full"] = 0] = "Full"; + /** + * Manifest is updated partially thanks to a shortened version + * of the manifest document. The latter's URL might be different + * from the original one. + */ - return representations.slice(0, firstSuperiorBitrateIndex); -} -// EXTERNAL MODULE: ./src/utils/array_find.ts -var array_find = __webpack_require__(3274); -;// CONCATENATED MODULE: ./src/core/abr/filter_by_width.ts + MANIFEST_UPDATE_TYPE[MANIFEST_UPDATE_TYPE["Partial"] = 1] = "Partial"; +})(MANIFEST_UPDATE_TYPE || (MANIFEST_UPDATE_TYPE = {})); +// EXTERNAL MODULE: ./src/utils/array_find_index.ts +var array_find_index = __webpack_require__(5138); +;// CONCATENATED MODULE: ./src/manifest/update_period_in_place.ts /** * Copyright 2015 CANAL+ Group * @@ -14124,34 +14188,61 @@ var array_find = __webpack_require__(3274); */ + /** - * 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.} + * Update oldPeriod attributes with the one from newPeriod (e.g. when updating + * the Manifest). + * @param {Object} oldPeriod + * @param {Object} newPeriod */ -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; - }); +function updatePeriodInPlace(oldPeriod, newPeriod, updateType) { + oldPeriod.start = newPeriod.start; + oldPeriod.end = newPeriod.end; + oldPeriod.duration = newPeriod.duration; + var oldAdaptations = oldPeriod.getAdaptations(); + var newAdaptations = newPeriod.getAdaptations(); - if (repWithMaxWidth === undefined) { - return representations; - } + var _loop = function _loop(j) { + var oldAdaptation = oldAdaptations[j]; + var newAdaptation = (0,array_find/* default */.Z)(newAdaptations, function (a) { + return a.id === oldAdaptation.id; + }); - var maxWidth = typeof repWithMaxWidth.width === "number" ? repWithMaxWidth.width : 0; - return representations.filter(function (representation) { - return typeof representation.width === "number" ? representation.width <= maxWidth : true; - }); + if (newAdaptation === undefined) { + log/* default.warn */.Z.warn("Manifest: Adaptation \"" + oldAdaptations[j].id + "\" not found when merging."); + } else { + var oldRepresentations = oldAdaptations[j].representations; + var newRepresentations = newAdaptation.representations; + + var _loop2 = function _loop2(k) { + var oldRepresentation = oldRepresentations[k]; + var newRepresentation = (0,array_find/* default */.Z)(newRepresentations, function (representation) { + return representation.id === oldRepresentation.id; + }); + + if (newRepresentation === undefined) { + log/* default.warn */.Z.warn("Manifest: Representation \"" + oldRepresentations[k].id + "\" " + "not found when merging."); + } else { + if (updateType === MANIFEST_UPDATE_TYPE.Full) { + oldRepresentation.index._replace(newRepresentation.index); + } else { + oldRepresentation.index._update(newRepresentation.index); + } + } + }; + + for (var k = 0; k < oldRepresentations.length; k++) { + _loop2(k); + } + } + }; + + for (var j = 0; j < oldAdaptations.length; j++) { + _loop(j); + } } -;// CONCATENATED MODULE: ./src/core/abr/network_analyzer.ts +;// CONCATENATED MODULE: ./src/manifest/update_periods.ts /** * Copyright 2015 CANAL+ Group * @@ -14172,859 +14263,736 @@ function filterByWidth(representations, width) { -var ABR_REGULAR_FACTOR = config/* default.ABR_REGULAR_FACTOR */.Z.ABR_REGULAR_FACTOR, - ABR_STARVATION_DURATION_DELTA = config/* default.ABR_STARVATION_DURATION_DELTA */.Z.ABR_STARVATION_DURATION_DELTA, - ABR_STARVATION_FACTOR = config/* default.ABR_STARVATION_FACTOR */.Z.ABR_STARVATION_FACTOR, - ABR_STARVATION_GAP = config/* default.ABR_STARVATION_GAP */.Z.ABR_STARVATION_GAP, - OUT_OF_STARVATION_GAP = config/* default.OUT_OF_STARVATION_GAP */.Z.OUT_OF_STARVATION_GAP; /** - * Get pending segment request(s) starting with the asked segment position. - * @param {Object} requests - * @param {number} position - * @returns {Array.} + * Update old periods by adding new periods and removing + * not available ones. + * @param {Array.} oldPeriods + * @param {Array.} newPeriods */ -function getConcernedRequests(requests, neededPosition) { - /** Index of the request for the next needed segment, in `requests`. */ - var nextSegmentIndex = (0,array_find_index/* default */.Z)(requests, function (request) { - if (request.duration <= 0) { - return false; - } - - var segmentEnd = request.time + request.duration; - return segmentEnd > neededPosition && Math.abs(neededPosition - request.time) < -0.3; - }); +function replacePeriods(oldPeriods, newPeriods) { + var firstUnhandledPeriodIdx = 0; - if (nextSegmentIndex < 0) { - // Not found - return []; - } + for (var i = 0; i < newPeriods.length; i++) { + var newPeriod = newPeriods[i]; + var j = firstUnhandledPeriodIdx; + var oldPeriod = oldPeriods[j]; - var nextRequest = requests[nextSegmentIndex]; - var segmentTime = nextRequest.time; - var filteredRequests = [nextRequest]; // Get the possibly multiple requests for that segment's position + while (oldPeriod != null && oldPeriod.id !== newPeriod.id) { + j++; + oldPeriod = oldPeriods[j]; + } - for (var i = nextSegmentIndex + 1; i < requests.length; i++) { - if (requests[i].time === segmentTime) { - filteredRequests.push(requests[i]); - } else { - break; + if (oldPeriod != null) { + updatePeriodInPlace(oldPeriod, newPeriod, MANIFEST_UPDATE_TYPE.Full); + var periodsToInclude = newPeriods.slice(firstUnhandledPeriodIdx, i); + var nbrOfPeriodsToRemove = j - firstUnhandledPeriodIdx; + oldPeriods.splice.apply(oldPeriods, [firstUnhandledPeriodIdx, nbrOfPeriodsToRemove].concat(periodsToInclude)); + firstUnhandledPeriodIdx = i + 1; } } - return filteredRequests; -} -/** - * 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 + if (firstUnhandledPeriodIdx > oldPeriods.length) { + log/* default.error */.Z.error("Manifest: error when updating Periods"); + return; + } + if (firstUnhandledPeriodIdx < oldPeriods.length) { + oldPeriods.splice(firstUnhandledPeriodIdx, oldPeriods.length - firstUnhandledPeriodIdx); + } - var ewma1 = new EWMA(2); - var progress = request.progress; + var remainingNewPeriods = newPeriods.slice(firstUnhandledPeriodIdx, newPeriods.length); - 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); + if (remainingNewPeriods.length > 0) { + oldPeriods.push.apply(oldPeriods, remainingNewPeriods); } - - return ewma1.getEstimate(); } /** - * Estimate remaining time for a pending request from a progress event. - * @param {Object} lastProgressEvent - * @param {number} bandwidthEstimate - * @returns {number} + * Update old periods by adding new periods and removing + * not available ones. + * @param {Array.} oldPeriods + * @param {Array.} newPeriods */ +function updatePeriods(oldPeriods, newPeriods) { + if (oldPeriods.length === 0) { + oldPeriods.splice.apply(oldPeriods, [0, 0].concat(newPeriods)); + return; + } -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 - Current pending requests. - * @param {Object} playbackInfo - Information on the current playback. - * @param {Object|null} currentRepresentation - The Representation being - * presently being loaded. - * @param {Number} lastEstimatedBitrate - Last bitrate estimate emitted. - * @returns {Number|undefined} - */ + if (newPeriods.length === 0) { + return; + } + var oldLastPeriod = oldPeriods[oldPeriods.length - 1]; -function estimateStarvationModeBitrate(pendingRequests, playbackInfo, currentRepresentation, lastEstimatedBitrate) { - var nextNeededPosition = playbackInfo.position + playbackInfo.bufferGap; - var concernedRequests = getConcernedRequests(pendingRequests, nextNeededPosition); + if (oldLastPeriod.start < newPeriods[0].start) { + if (oldLastPeriod.end !== newPeriods[0].start) { + throw new media_error/* default */.Z("MANIFEST_UPDATE_ERROR", "Cannot perform partial update: not enough data"); + } - if (concernedRequests.length !== 1) { - // 0 == no request - // 2+ == too complicated to calculate - return undefined; + oldPeriods.push.apply(oldPeriods, newPeriods); + return; } - var concernedRequest = concernedRequests[0]; - var chunkDuration = concernedRequest.duration; - 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 indexOfNewFirstPeriod = (0,array_find_index/* default */.Z)(oldPeriods, function (_ref) { + var id = _ref.id; + return id === newPeriods[0].id; + }); - var bandwidthEstimate = estimateRequestBandwidth(concernedRequest); + if (indexOfNewFirstPeriod < 0) { + throw new media_error/* default */.Z("MANIFEST_UPDATE_ERROR", "Cannot perform partial update: incoherent data"); + } // The first updated Period can only be a partial part - 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 - playbackInfo.bufferGap / playbackInfo.speed; + updatePeriodInPlace(oldPeriods[indexOfNewFirstPeriod], newPeriods[0], MANIFEST_UPDATE_TYPE.Partial); + var prevIndexOfNewPeriod = indexOfNewFirstPeriod + 1; - if (expectedRebufferingTime > 2000) { - return bandwidthEstimate; + for (var i = 1; i < newPeriods.length; i++) { + var newPeriod = newPeriods[i]; + var indexOfNewPeriod = -1; + + for (var j = prevIndexOfNewPeriod; j < oldPeriods.length; j++) { + if (newPeriod.id === oldPeriods[j].id) { + indexOfNewPeriod = j; + break; // end the loop } } - } - var requestElapsedTime = (now - concernedRequest.requestTimestamp) / 1000; - var reasonableElapsedTime = requestElapsedTime <= (chunkDuration * 1.5 + 2) / playbackInfo.speed; + if (indexOfNewPeriod < 0) { + oldPeriods.splice.apply(oldPeriods, [prevIndexOfNewPeriod, oldPeriods.length - prevIndexOfNewPeriod].concat(newPeriods.slice(i, newPeriods.length))); + return; + } - if (currentRepresentation == null || reasonableElapsedTime) { - return undefined; - } // calculate a reduced bitrate from the current one + if (indexOfNewPeriod > prevIndexOfNewPeriod) { + oldPeriods.splice(prevIndexOfNewPeriod, indexOfNewPeriod - prevIndexOfNewPeriod); + indexOfNewPeriod = prevIndexOfNewPeriod; + } // Later Periods can be fully replaced - var factor = chunkDuration / requestElapsedTime; - var reducedBitrate = currentRepresentation.bitrate * Math.min(0.7, factor); + updatePeriodInPlace(oldPeriods[indexOfNewPeriod], newPeriod, MANIFEST_UPDATE_TYPE.Full); + prevIndexOfNewPeriod++; + } - if (lastEstimatedBitrate === undefined || reducedBitrate < lastEstimatedBitrate) { - return reducedBitrate; + if (prevIndexOfNewPeriod < oldPeriods.length) { + oldPeriods.splice(prevIndexOfNewPeriod, oldPeriods.length - prevIndexOfNewPeriod); } } +;// CONCATENATED MODULE: ./src/manifest/manifest.ts + + /** - * 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 - * @param {Object} requests - Every requests pending, in a chronological - * order in terms of segment time. - * @param {number} abrStarvationGap - "Buffer gap" from which we enter a - * "starvation mode". - * @returns {boolean} + * 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 shouldDirectlySwitchToLowBitrate(playbackInfo, requests) { - var nextNeededPosition = playbackInfo.position + playbackInfo.bufferGap; - var nextRequest = (0,array_find/* default */.Z)(requests, function (r) { - return r.duration > 0 && r.time + r.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 - playbackInfo.bufferGap / playbackInfo.speed; - return expectedRebufferingTime > -1.5; -} + +var generateSupplementaryTrackID = (0,id_generator/* default */.Z)(); +var generateNewManifestId = (0,id_generator/* default */.Z)(); /** - * Analyze the current network conditions and give a bandwidth estimate as well - * as a maximum bitrate a Representation should be. - * @class NetworkAnalyzer + * Normalized Manifest structure. + * + * Details the current content being played: + * - the duration of the content + * - the available tracks + * - the available qualities + * - the segments defined in those qualities + * - ... + * while staying agnostic of the transport protocol used (Smooth, DASH etc.). + * + * The Manifest and its contained information can evolve over time (like when + * updating a dynamic manifest or when right management forbid some tracks from + * being played). + * To perform actions on those changes, any module using this Manifest can + * listen to its sent events and react accordingly. + * + * @class Manifest */ +var Manifest = /*#__PURE__*/function (_EventEmitter) { + (0,inheritsLoose/* default */.Z)(Manifest, _EventEmitter); -var NetworkAnalyzer = /*#__PURE__*/function () { - function NetworkAnalyzer(initialBitrate, lowLatencyMode) { - this._initialBitrate = initialBitrate; - this._inStarvationMode = false; - - 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 - }; - } - } /** - * 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 - * @param {Object|null} currentRepresentation - * @param {Array.} currentRequests - * @param {number|undefined} lastEstimatedBitrate - * @returns {Object} + * Construct a Manifest instance from a parsed Manifest object (as returned by + * Manifest parsers) and options. + * + * Some minor errors can arise during that construction. `this.parsingErrors` + * will contain all such errors, in the order they have been encountered. + * @param {Object} parsedManifest + * @param {Object} options */ + function Manifest(parsedManifest, options) { + var _this; + var _a; - 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; // check if should get in/out of starvation mode + _this = _EventEmitter.call(this) || this; + var _options$supplementar = options.supplementaryTextTracks, + supplementaryTextTracks = _options$supplementar === void 0 ? [] : _options$supplementar, + _options$supplementar2 = options.supplementaryImageTracks, + supplementaryImageTracks = _options$supplementar2 === void 0 ? [] : _options$supplementar2, + representationFilter = options.representationFilter, + manifestUpdateUrl = options.manifestUpdateUrl; + _this.parsingErrors = []; + _this.id = generateNewManifestId(); + _this.expired = (_a = parsedManifest.expired) !== null && _a !== void 0 ? _a : null; + _this.transport = parsedManifest.transportType; + _this.clockOffset = parsedManifest.clockOffset; + _this.periods = parsedManifest.periods.map(function (parsedPeriod) { + var _this$parsingErrors; - if (isNaN(duration) || bufferGap + position < duration - ABR_STARVATION_DURATION_DELTA) { - if (!this._inStarvationMode && bufferGap <= localConf.starvationGap) { - log/* default.info */.Z.info("ABR: enter starvation mode."); - this._inStarvationMode = true; - } else if (this._inStarvationMode && bufferGap >= 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 + var period = new Period(parsedPeriod, representationFilter); + (_this$parsingErrors = _this.parsingErrors).push.apply(_this$parsingErrors, period.parsingErrors); - if (this._inStarvationMode) { - bandwidthEstimate = estimateStarvationModeBitrate(currentRequests, playbackInfo, currentRepresentation, lastEstimatedBitrate); + return period; + }).sort(function (a, b) { + return a.start - b.start; + }); + /** + * @deprecated It is here to ensure compatibility with the way the + * v3.x.x manages adaptations at the Manifest level + */ - 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 + /* eslint-disable import/no-deprecated */ + _this.adaptations = _this.periods[0] === undefined ? {} : _this.periods[0].adaptations; + /* eslint-enable import/no-deprecated */ - if (newBitrateCeil == null) { - bandwidthEstimate = bandwidthEstimator.getEstimate(); + _this._timeBounds = parsedManifest.timeBounds; + _this.isDynamic = parsedManifest.isDynamic; + _this.isLive = parsedManifest.isLive; + _this.uris = parsedManifest.uris === undefined ? [] : parsedManifest.uris; + _this.updateUrl = manifestUpdateUrl; + _this.lifetime = parsedManifest.lifetime; + _this.suggestedPresentationDelay = parsedManifest.suggestedPresentationDelay; + _this.availabilityStartTime = parsedManifest.availabilityStartTime; + _this.publishTime = parsedManifest.publishTime; - 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 (supplementaryImageTracks.length > 0) { + _this._addSupplementaryImageAdaptations(supplementaryImageTracks); } - if (playbackInfo.speed > 1) { - newBitrateCeil /= playbackInfo.speed; + if (supplementaryTextTracks.length > 0) { + _this._addSupplementaryTextAdaptations(supplementaryTextTracks); } - return { - bandwidthEstimate: bandwidthEstimate, - bitrateChosen: newBitrateCeil - }; + return _this; } /** - * For a given wanted bitrate, tells if should switch urgently. - * @param {number} bitrate - * @param {Object} playbackInfo - * @returns {boolean} + * Returns the Period corresponding to the given `id`. + * Returns `undefined` if there is none. + * @param {string} id + * @returns {Object|undefined} */ - ; - _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); - }; + var _proto = Manifest.prototype; - return NetworkAnalyzer; -}(); + _proto.getPeriod = function getPeriod(id) { + return (0,array_find/* default */.Z)(this.periods, function (period) { + return id === period.id; + }); + } + /** + * Returns the Period encountered at the given time. + * Returns `undefined` if there is no Period exactly at the given time. + * @param {number} time + * @returns {Object|undefined} + */ + ; + _proto.getPeriodForTime = function getPeriodForTime(time) { + return (0,array_find/* default */.Z)(this.periods, function (period) { + return time >= period.start && (period.end === undefined || period.end > time); + }); + } + /** + * Returns the first Period starting strictly after the given time. + * Returns `undefined` if there is no Period starting after that time. + * @param {number} time + * @returns {Object|undefined} + */ + ; -// EXTERNAL MODULE: ./src/utils/object_values.ts -var object_values = __webpack_require__(1679); -;// CONCATENATED MODULE: ./src/core/abr/pending_requests_store.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. - */ + _proto.getNextPeriod = function getNextPeriod(time) { + return (0,array_find/* default */.Z)(this.periods, function (period) { + return period.start > time; + }); + } + /** + * Returns the Period coming chronologically just after another given Period. + * Returns `undefined` if not found. + * @param {Object} period + * @returns {Object|null} + */ + ; + _proto.getPeriodAfter = function getPeriodAfter(period) { + var endOfPeriod = period.end; -/** - * Store information about pending requests, like information about: - * - for which segments they are - * - how the request's progress goes - * @class PendingRequestsStore - */ + if (endOfPeriod === undefined) { + return null; + } -var PendingRequestsStore = /*#__PURE__*/function () { - function PendingRequestsStore() { - this._currentRequests = {}; + var nextPeriod = (0,array_find/* default */.Z)(this.periods, function (_period) { + return _period.end === undefined || endOfPeriod < _period.end; + }); + return nextPeriod === undefined ? null : nextPeriod; } /** - * Add information about a new pending request. - * @param {string} id - * @param {Object} payload + * Returns the most important URL from which the Manifest can be refreshed. + * `undefined` if no URL is found. + * @returns {string|undefined} */ + ; + _proto.getUrl = function getUrl() { + return this.uris[0]; + } + /** + * Update the current Manifest properties by giving a new updated version. + * This instance will be updated with the new information coming from it. + * @param {Object} newManifest + */ + ; - var _proto = PendingRequestsStore.prototype; + _proto.replace = function replace(newManifest) { + this._performUpdate(newManifest, MANIFEST_UPDATE_TYPE.Full); + } + /** + * Update the current Manifest properties by giving a new but shorter version + * of it. + * This instance will add the new information coming from it and will + * automatically clean old Periods that shouldn't be available anymore. + * + * /!\ Throws if the given Manifest cannot be used or is not sufficient to + * update the Manifest. + * @param {Object} newManifest + */ + ; - _proto.add = function add(payload) { - var id = payload.id, - time = payload.time, - duration = payload.duration, - requestTimestamp = payload.requestTimestamp; - this._currentRequests[id] = { - time: time, - duration: duration, - requestTimestamp: requestTimestamp, - progress: [] - }; + _proto.update = function update(newManifest) { + this._performUpdate(newManifest, MANIFEST_UPDATE_TYPE.Partial); } /** - * Notify of the progress of a currently pending request. - * @param {Object} progress + * Get the minimum position currently defined by the Manifest, in seconds. + * @returns {number} */ ; - _proto.addProgress = function addProgress(progress) { - var request = this._currentRequests[progress.id]; + _proto.getMinimumPosition = function getMinimumPosition() { + var _a, _b; - if (request == null) { - if (false) {} + var windowData = this._timeBounds; - log/* default.warn */.Z.warn("ABR: progress for a request not added"); - return; + if (windowData.timeshiftDepth === null) { + return (_a = windowData.absoluteMinimumTime) !== null && _a !== void 0 ? _a : 0; } - request.progress.push(progress); + var maximumTimeData = windowData.maximumTimeData; + var maximumTime; + + if (!windowData.maximumTimeData.isLinear) { + maximumTime = maximumTimeData.value; + } else { + var timeDiff = performance.now() - maximumTimeData.time; + maximumTime = maximumTimeData.value + timeDiff / 1000; + } + + var theoricalMinimum = maximumTime - windowData.timeshiftDepth; + return Math.max((_b = windowData.absoluteMinimumTime) !== null && _b !== void 0 ? _b : 0, theoricalMinimum); } /** - * Remove a request previously set as pending. - * @param {string} id + * Get the maximum position currently defined by the Manifest, in seconds. + * @returns {number} */ ; - _proto.remove = function remove(id) { - if (this._currentRequests[id] == null) { - if (false) {} + _proto.getMaximumPosition = function getMaximumPosition() { + var maximumTimeData = this._timeBounds.maximumTimeData; - log/* default.warn */.Z.warn("ABR: can't remove unknown request"); + if (!maximumTimeData.isLinear) { + return maximumTimeData.value; } - delete this._currentRequests[id]; + var timeDiff = performance.now() - maximumTimeData.time; + return maximumTimeData.value + timeDiff / 1000; } /** - * Returns information about all pending requests, in segment's chronological - * order. - * @returns {Array.} + * Look in the Manifest for Representations linked to the given key ID, + * and mark them as being impossible to decrypt. + * Then trigger a "decipherabilityUpdate" event to notify everyone of the + * changes performed. + * @param {Object} keyUpdates */ ; - _proto.getRequests = function getRequests() { - return (0,object_values/* default */.Z)(this._currentRequests).filter(function (x) { - return x != null; - }).sort(function (reqA, reqB) { - return reqA.time - reqB.time; - }); - }; + _proto.updateDeciperabilitiesBasedOnKeyIds = function updateDeciperabilitiesBasedOnKeyIds(_ref) { + var whitelistedKeyIds = _ref.whitelistedKeyIds, + blacklistedKeyIDs = _ref.blacklistedKeyIDs; + var updates = updateDeciperability(this, function (representation) { + if (representation.decipherable === false || representation.contentProtections === undefined) { + return representation.decipherable; + } - return PendingRequestsStore; -}(); + var contentKIDs = representation.contentProtections.keyIds; + for (var i = 0; i < contentKIDs.length; i++) { + var elt = contentKIDs[i]; -;// CONCATENATED MODULE: ./src/core/abr/representation_score_calculator.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. - */ + for (var j = 0; j < blacklistedKeyIDs.length; j++) { + if ((0,are_arrays_of_numbers_equal/* default */.Z)(blacklistedKeyIDs[j], elt.keyId)) { + return false; + } + } + for (var _j = 0; _j < whitelistedKeyIds.length; _j++) { + if ((0,are_arrays_of_numbers_equal/* default */.Z)(whitelistedKeyIds[_j], elt.keyId)) { + return true; + } + } + } -/** - * 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 - * - * 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 - */ + return representation.decipherable; + }); -var RepresentationScoreCalculator = /*#__PURE__*/function () { - function RepresentationScoreCalculator() { - this._currentRepresentationData = null; - this._lastRepresentationWithGoodScore = null; + if (updates.length > 0) { + this.trigger("decipherabilityUpdate", updates); + } } /** - * 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. + * Look in the Manifest for Representations linked to the given content + * protection initialization data and mark them as being impossible to + * decrypt. + * Then trigger a "decipherabilityUpdate" event to notify everyone of the + * changes performed. + * @param {Object} initData */ + ; + _proto.addUndecipherableProtectionData = function addUndecipherableProtectionData(initData) { + var updates = updateDeciperability(this, function (representation) { + var _a, _b; - var _proto = RepresentationScoreCalculator.prototype; - - _proto.addSample = function addSample(representation, requestDuration, segmentDuration) { - var ratio = segmentDuration / requestDuration; + if (representation.decipherable === false) { + return false; + } - var oldEwma = this._getEWMA(representation); + var segmentProtections = (_b = (_a = representation.contentProtections) === null || _a === void 0 ? void 0 : _a.initData) !== null && _b !== void 0 ? _b : []; - var currentEWMA; + var _loop = function _loop(i) { + if (initData.type === undefined || segmentProtections[i].type === initData.type) { + var containedInitData = initData.values.every(function (undecipherableVal) { + return segmentProtections[i].values.some(function (currVal) { + return (undecipherableVal.systemId === undefined || currVal.systemId === undecipherableVal.systemId) && (0,are_arrays_of_numbers_equal/* default */.Z)(currVal.data, undecipherableVal.data); + }); + }); - if (oldEwma != null) { - currentEWMA = oldEwma; - oldEwma.addSample(requestDuration, ratio); - } else { - currentEWMA = new EWMA(5); - currentEWMA.addSample(requestDuration, ratio); - this._currentRepresentationData = { - representation: representation, - ewma: currentEWMA + if (containedInitData) { + return { + v: false + }; + } + } }; - } - if (currentEWMA.getEstimate() > 1 && this._lastRepresentationWithGoodScore !== representation) { - log/* default.debug */.Z.debug("ABR: New last stable representation", representation); - this._lastRepresentationWithGoodScore = representation; + for (var i = 0; i < segmentProtections.length; i++) { + var _ret = _loop(i); + + if (typeof _ret === "object") return _ret.v; + } + + return representation.decipherable; + }); + + if (updates.length > 0) { + this.trigger("decipherabilityUpdate", updates); } } /** - * Get score estimate for the given Representation. - * undefined if no estimate is available. - * @param {Representation} representation - * @returns {number|undefined} + * @deprecated only returns adaptations for the first period + * @returns {Array.} */ ; - _proto.getEstimate = function getEstimate(representation) { - var ewma = this._getEWMA(representation); + _proto.getAdaptations = function getAdaptations() { + (0,warn_once/* default */.Z)("manifest.getAdaptations() is deprecated." + " Please use manifest.period[].getAdaptations() instead"); + var firstPeriod = this.periods[0]; - if (ewma != null) { - return ewma.getEstimate(); + if (firstPeriod === undefined) { + return []; + } + + var adaptationsByType = firstPeriod.adaptations; + var adaptationsList = []; + + for (var adaptationType in adaptationsByType) { + if (adaptationsByType.hasOwnProperty(adaptationType)) { + var adaptations = adaptationsByType[adaptationType]; + adaptationsList.push.apply(adaptationsList, adaptations); + } } + + return adaptationsList; } /** - * 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} + * @deprecated only returns adaptations for the first period + * @returns {Array.} */ ; - _proto.getLastStableRepresentation = function getLastStableRepresentation() { - return this._lastRepresentationWithGoodScore; + _proto.getAdaptationsForType = function getAdaptationsForType(adaptationType) { + (0,warn_once/* default */.Z)("manifest.getAdaptationsForType(type) is deprecated." + " Please use manifest.period[].getAdaptationsForType(type) instead"); + var firstPeriod = this.periods[0]; + + if (firstPeriod === undefined) { + return []; + } + + var adaptationsForType = firstPeriod.adaptations[adaptationType]; + return adaptationsForType === undefined ? [] : adaptationsForType; } /** - * Returns EWMA for the given Representation. - * null if no EWMA is currently stored for it. - * @param {Representation} representation - * @returns {EWMA|null} + * @deprecated only returns adaptations for the first period + * @returns {Array.} */ ; - _proto._getEWMA = function _getEWMA(representation) { - if (this._currentRepresentationData != null && this._currentRepresentationData.representation.id === representation.id) { - return this._currentRepresentationData.ewma; - } - - return null; - }; - - return RepresentationScoreCalculator; -}(); - - -;// CONCATENATED MODULE: ./src/core/abr/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/abr/representation_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. - */ + _proto.getAdaptation = function getAdaptation(wantedId) { + (0,warn_once/* default */.Z)("manifest.getAdaptation(id) is deprecated." + " Please use manifest.period[].getAdaptation(id) instead"); + /* eslint-disable import/no-deprecated */ + return (0,array_find/* default */.Z)(this.getAdaptations(), function (_ref2) { + var id = _ref2.id; + return wantedId === id; + }); + /* eslint-enable import/no-deprecated */ + } + /** + * Add supplementary image Adaptation(s) to the manifest. + * @private + * @param {Object|Array.} imageTracks + */ + ; + _proto._addSupplementaryImageAdaptations = function _addSupplementaryImageAdaptations( + /* eslint-disable import/no-deprecated */ + imageTracks) { + var _this2 = this; + var _imageTracks = Array.isArray(imageTracks) ? imageTracks : [imageTracks]; + var newImageTracks = _imageTracks.map(function (_ref3) { + var _this2$parsingErrors; + var mimeType = _ref3.mimeType, + url = _ref3.url; + var adaptationID = "gen-image-ada-" + generateSupplementaryTrackID(); + var representationID = "gen-image-rep-" + generateSupplementaryTrackID(); + var newAdaptation = new Adaptation({ + id: adaptationID, + type: "image", + representations: [{ + bitrate: 0, + id: representationID, + mimeType: mimeType, + index: new StaticRepresentationIndex({ + media: url + }) + }] + }, { + isManuallyAdded: true + }); + (_this2$parsingErrors = _this2.parsingErrors).push.apply(_this2$parsingErrors, newAdaptation.parsingErrors); + return newAdaptation; + }); + if (newImageTracks.length > 0 && this.periods.length > 0) { + var adaptations = this.periods[0].adaptations; + adaptations.image = adaptations.image != null ? adaptations.image.concat(newImageTracks) : newImageTracks; + } + } + /** + * Add supplementary text Adaptation(s) to the manifest. + * @private + * @param {Object|Array.} textTracks + */ + ; + _proto._addSupplementaryTextAdaptations = function _addSupplementaryTextAdaptations( + /* eslint-disable import/no-deprecated */ + textTracks + /* eslint-enable import/no-deprecated */ + ) { + var _this3 = this; + var _textTracks = Array.isArray(textTracks) ? textTracks : [textTracks]; + var newTextAdaptations = _textTracks.reduce(function (allSubs, _ref4) { + var mimeType = _ref4.mimeType, + codecs = _ref4.codecs, + url = _ref4.url, + language = _ref4.language, + languages = _ref4.languages, + closedCaption = _ref4.closedCaption; + var langsToMapOn = language != null ? [language] : languages != null ? languages : []; + return allSubs.concat(langsToMapOn.map(function (_language) { + var _this3$parsingErrors; -/** - * Filter representations given through filters options. - * @param {Array.} representations - * @param {Object} filters - Filter Object. - * @returns {Array.} - */ + var adaptationID = "gen-text-ada-" + generateSupplementaryTrackID(); + var representationID = "gen-text-rep-" + generateSupplementaryTrackID(); + var newAdaptation = new Adaptation({ + id: adaptationID, + type: "text", + language: _language, + closedCaption: closedCaption, + representations: [{ + bitrate: 0, + id: representationID, + mimeType: mimeType, + codecs: codecs, + index: new StaticRepresentationIndex({ + media: url + }) + }] + }, { + isManuallyAdded: true + }); -function getFilteredRepresentations(representations, filters) { - var _representations = representations; + (_this3$parsingErrors = _this3.parsingErrors).push.apply(_this3$parsingErrors, newAdaptation.parsingErrors); - if (filters.bitrate != null) { - _representations = filterByBitrate(_representations, filters.bitrate); - } + return newAdaptation; + })); + }, []); - if (filters.width != null) { - _representations = filterByWidth(_representations, filters.width); + if (newTextAdaptations.length > 0 && this.periods.length > 0) { + var adaptations = this.periods[0].adaptations; + adaptations.text = adaptations.text != null ? adaptations.text.concat(newTextAdaptations) : newTextAdaptations; + } } - - return _representations; -} -/** - * Estimate regularly the current network bandwidth and the best Representation - * that can be played according to the current network and playback conditions. - * - * A `RepresentationEstimator` 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 - * create as many `RepresentationEstimator`. - * @param {Object} args - * @returns {Observable} - */ - - -function RepresentationEstimator(_ref) { - var bandwidthEstimator = _ref.bandwidthEstimator, - clock$ = _ref.clock$, - filters$ = _ref.filters$, - initialBitrate = _ref.initialBitrate, - lowLatencyMode = _ref.lowLatencyMode, - manualBitrate$ = _ref.manualBitrate$, - minAutoBitrate$ = _ref.minAutoBitrate$, - maxAutoBitrate$ = _ref.maxAutoBitrate$, - representations = _ref.representations, - streamEvents$ = _ref.streamEvents$; - var scoreCalculator = new RepresentationScoreCalculator(); - var networkAnalyzer = new NetworkAnalyzer(initialBitrate == null ? 0 : initialBitrate, lowLatencyMode); - var requestsStore = new PendingRequestsStore(); - var shouldIgnoreMetrics = generateCachedSegmentDetector(); /** - * Callback to call when new metrics are available - * @param {Object} value + * @param {Object} newManifest + * @param {number} type */ + ; - function onMetric(value) { - var duration = value.duration, - size = value.size, - content = value.content; - - if (shouldIgnoreMetrics(content, duration)) { - // We already loaded not cached segments. - // Do not consider cached segments anymore. - return; - } // calculate bandwidth - - - bandwidthEstimator.addSample(duration, size); // calculate "maintainability score" - - var segment = content.segment; - var requestDuration = duration / 1000; - var segmentDuration = segment.duration; - var representation = content.representation; - scoreCalculator.addSample(representation, requestDuration, segmentDuration); - } + _proto._performUpdate = function _performUpdate(newManifest, updateType) { + this.availabilityStartTime = newManifest.availabilityStartTime; + this.expired = newManifest.expired; + this.isDynamic = newManifest.isDynamic; + this.isLive = newManifest.isLive; + this.lifetime = newManifest.lifetime; + this.parsingErrors = newManifest.parsingErrors; + this.suggestedPresentationDelay = newManifest.suggestedPresentationDelay; + this.transport = newManifest.transport; + this.publishTime = newManifest.publishTime; - var metrics$ = streamEvents$.pipe((0,filter/* filter */.h)(function (e) { - return e.type === "metrics"; - }), (0,tap/* tap */.b)(function (_ref2) { - var value = _ref2.value; - return onMetric(value); - }), (0,ignoreElements/* ignoreElements */.l)()); - var requests$ = streamEvents$.pipe((0,tap/* tap */.b)(function (evt) { - switch (evt.type) { - case "requestBegin": - requestsStore.add(evt.value); - break; + if (updateType === MANIFEST_UPDATE_TYPE.Full) { + this._timeBounds = newManifest._timeBounds; + this.uris = newManifest.uris; + replacePeriods(this.periods, newManifest.periods); + } else { + this._timeBounds.maximumTimeData = newManifest._timeBounds.maximumTimeData; + this.updateUrl = newManifest.uris[0]; + updatePeriods(this.periods, newManifest.periods); // Partial updates do not remove old Periods. + // This can become a memory problem when playing a content long enough. + // Let's clean manually Periods behind the minimum possible position. - case "requestEnd": - requestsStore.remove(evt.value.id); - break; + var min = this.getMinimumPosition(); - case "progress": - requestsStore.addProgress(evt.value); - break; - } - }), (0,ignoreElements/* ignoreElements */.l)()); - var currentRepresentation$ = streamEvents$.pipe((0,filter/* filter */.h)(function (e) { - return e.type === "representationChange"; - }), (0,map/* map */.U)(function (e) { - return e.value.representation; - }), (0,startWith/* startWith */.O)(null)); - var estimate$ = (0,defer/* defer */.P)(function () { - if (representations.length === 0) { - throw new Error("ABRManager: no representation choice given"); - } + while (this.periods.length > 0) { + var period = this.periods[0]; - if (representations.length === 1) { - return (0,of.of)({ - bitrate: undefined, - representation: representations[0], - manual: false, - urgent: true, - knownStableBitrate: undefined - }); - } + if (period.end === undefined || period.end > min) { + break; + } - return manualBitrate$.pipe((0,switchMap/* switchMap */.w)(function (manualBitrate) { - if (manualBitrate >= 0) { - // -- MANUAL mode -- - var manualRepresentation = selectOptimalRepresentation(representations, manualBitrate, 0, Infinity); - return (0,of.of)({ - representation: manualRepresentation, - bitrate: undefined, - knownStableBitrate: undefined, - manual: true, - urgent: true - }); - } // -- AUTO mode -- + this.periods.shift(); + } + } // Re-set this.adaptations for retro-compatibility in v3.x.x + /* eslint-disable import/no-deprecated */ - var lastEstimatedBitrate; - var forceBandwidthMode = true; // Emit each time a buffer-based estimation should be actualized (each - // time a segment is added). - var bufferBasedClock$ = streamEvents$.pipe((0,filter/* filter */.h)(function (e) { - return e.type === "added-segment"; - }), withLatestFrom(clock$), (0,map/* map */.U)(function (_ref3) { - var evtValue = _ref3[0].value, - _ref3$ = _ref3[1], - speed = _ref3$.speed, - position = _ref3$.position; - var timeRanges = evtValue.buffered; - var bufferGap = (0,ranges/* getLeftSizeOfRange */.L7)(timeRanges, position); - var representation = evtValue.content.representation; - var currentScore = scoreCalculator.getEstimate(representation); - var currentBitrate = representation.bitrate; - return { - bufferGap: bufferGap, - currentBitrate: currentBitrate, - currentScore: currentScore, - speed: speed - }; - })); - var bitrates = representations.map(function (r) { - return r.bitrate; - }); - var bufferBasedEstimation$ = BufferBasedChooser(bufferBasedClock$, bitrates).pipe((0,startWith/* startWith */.O)(undefined)); - return (0,combineLatest/* combineLatest */.aj)([clock$, minAutoBitrate$, maxAutoBitrate$, filters$, bufferBasedEstimation$]).pipe(withLatestFrom(currentRepresentation$), (0,map/* map */.U)(function (_ref4) { - var _ref4$ = _ref4[0], - clock = _ref4$[0], - minAutoBitrate = _ref4$[1], - maxAutoBitrate = _ref4$[2], - filters = _ref4$[3], - bufferBasedBitrate = _ref4$[4], - currentRepresentation = _ref4[1]; + this.adaptations = this.periods[0] === undefined ? {} : this.periods[0].adaptations; + /* eslint-enable import/no-deprecated */ + // Let's trigger events at the end, as those can trigger side-effects. + // We do not want the current Manifest object to be incomplete when those + // happen. - var _representations = getFilteredRepresentations(representations, filters); + this.trigger("manifestUpdate", null); + }; - var requests = requestsStore.getRequests(); + return Manifest; +}(event_emitter/* default */.Z); +/** + * Update `decipherable` property of every `Representation` found in the + * Manifest based on the result of a `isDecipherable` callback: + * - When that callback returns `true`, update `decipherable` to `true` + * - When that callback returns `false`, update `decipherable` to `false` + * - When that callback returns `undefined`, update `decipherable` to + * `undefined` + * @param {Manifest} manifest + * @param {Function} isDecipherable + * @returns {Array.} + */ - var _networkAnalyzer$getB = networkAnalyzer.getBandwidthEstimate(clock, bandwidthEstimator, currentRepresentation, requests, lastEstimatedBitrate), - bandwidthEstimate = _networkAnalyzer$getB.bandwidthEstimate, - bitrateChosen = _networkAnalyzer$getB.bitrateChosen; - lastEstimatedBitrate = bandwidthEstimate; - var stableRepresentation = scoreCalculator.getLastStableRepresentation(); - var knownStableBitrate = stableRepresentation == null ? undefined : stableRepresentation.bitrate / (clock.speed > 0 ? clock.speed : 1); - var bufferGap = clock.bufferGap; - if (!forceBandwidthMode && bufferGap <= 5) { - forceBandwidthMode = true; - } else if (forceBandwidthMode && isFinite(bufferGap) && bufferGap > 10) { - forceBandwidthMode = false; - } - var chosenRepFromBandwidth = selectOptimalRepresentation(_representations, bitrateChosen, minAutoBitrate, maxAutoBitrate); +function updateDeciperability(manifest, isDecipherable) { + var updates = []; - if (forceBandwidthMode) { - log/* default.debug */.Z.debug("ABR: Choosing representation with bandwidth estimation.", chosenRepFromBandwidth); - return { - bitrate: bandwidthEstimate, - representation: chosenRepFromBandwidth, - urgent: networkAnalyzer.isUrgent(chosenRepFromBandwidth.bitrate, currentRepresentation, requests, clock), - manual: false, - knownStableBitrate: knownStableBitrate - }; - } + for (var i = 0; i < manifest.periods.length; i++) { + var period = manifest.periods[i]; + var adaptations = period.getAdaptations(); - if (bufferBasedBitrate == null || chosenRepFromBandwidth.bitrate >= bufferBasedBitrate) { - log/* default.debug */.Z.debug("ABR: Choosing representation with bandwidth estimation.", chosenRepFromBandwidth); - return { - bitrate: bandwidthEstimate, - representation: chosenRepFromBandwidth, - urgent: networkAnalyzer.isUrgent(chosenRepFromBandwidth.bitrate, currentRepresentation, requests, clock), - manual: false, - knownStableBitrate: knownStableBitrate - }; - } + for (var j = 0; j < adaptations.length; j++) { + var adaptation = adaptations[j]; + var representations = adaptation.representations; - var chosenRepresentation = selectOptimalRepresentation(_representations, bufferBasedBitrate, minAutoBitrate, maxAutoBitrate); + for (var k = 0; k < representations.length; k++) { + var representation = representations[k]; + var result = isDecipherable(representation); - if (bufferBasedBitrate <= maxAutoBitrate) { - log/* default.debug */.Z.debug("ABR: Choosing representation with buffer based bitrate ceiling.", chosenRepresentation); + if (result !== representation.decipherable) { + updates.push({ + manifest: manifest, + period: period, + adaptation: adaptation, + representation: representation + }); + representation.decipherable = result; } + } + } + } - return { - bitrate: bandwidthEstimate, - representation: chosenRepresentation, - urgent: networkAnalyzer.isUrgent(bufferBasedBitrate, currentRepresentation, requests, clock), - manual: false, - knownStableBitrate: knownStableBitrate - }; - })); - })); - }); - return (0,merge/* merge */.T)(metrics$, requests$, estimate$); + return updates; } -;// CONCATENATED MODULE: ./src/core/abr/abr_manager.ts +;// CONCATENATED MODULE: ./src/manifest/index.ts /** * Copyright 2015 CANAL+ Group * @@ -15046,86 +15014,18 @@ function RepresentationEstimator(_ref) { -/** - * Adaptive BitRate Manager. - * - * Select the right Representation from the network and buffer infos it - * receives. - * @class ABRManager - */ - -var ABRManager = /*#__PURE__*/function () { - /** - * @param {Object} options - */ - function ABRManager(options) { - this._manualBitrates = options.manualBitrates; - this._minAutoBitrates = options.minAutoBitrates; - this._maxAutoBitrates = options.maxAutoBitrates; - this._initialBitrates = options.initialBitrates; - this._throttlers = options.throttlers; - this._bandwidthEstimators = {}; - this._lowLatencyMode = options.lowLatencyMode; - } - /** - * Take type and an array of the available representations, spit out an - * observable emitting the best representation (given the network/buffer - * state). - * @param {string} type - * @param {Array.} representations - * @param {Observable} clock$ - * @param {Observable} streamEvents$ - * @returns {Observable} - */ - - - var _proto = ABRManager.prototype; - - _proto.get$ = function get$(type, representations, clock$, streamEvents$) { - var bandwidthEstimator = this._getBandwidthEstimator(type); - - var manualBitrate$ = (0,take_first_set/* default */.Z)(this._manualBitrates[type], (0,of.of)(-1)); - var minAutoBitrate$ = (0,take_first_set/* default */.Z)(this._minAutoBitrates[type], (0,of.of)(0)); - var maxAutoBitrate$ = (0,take_first_set/* default */.Z)(this._maxAutoBitrates[type], (0,of.of)(Infinity)); - var initialBitrate = (0,take_first_set/* default */.Z)(this._initialBitrates[type], 0); - var filters$ = createFilters(this._throttlers.limitWidth[type], this._throttlers.throttleBitrate[type], this._throttlers.throttle[type]); - return RepresentationEstimator({ - bandwidthEstimator: bandwidthEstimator, - streamEvents$: streamEvents$, - clock$: clock$, - filters$: filters$, - initialBitrate: initialBitrate, - manualBitrate$: manualBitrate$, - minAutoBitrate$: minAutoBitrate$, - maxAutoBitrate$: maxAutoBitrate$, - representations: representations, - lowLatencyMode: this._lowLatencyMode - }); - } - /** - * @param {string} bufferType - * @returns {Object} - */ - ; - - _proto._getBandwidthEstimator = function _getBandwidthEstimator(bufferType) { - var originalBandwidthEstimator = this._bandwidthEstimators[bufferType]; - - if (originalBandwidthEstimator == null) { - log/* default.debug */.Z.debug("ABR: Creating new BandwidthEstimator for ", bufferType); - var bandwidthEstimator = new BandwidthEstimator(); - this._bandwidthEstimators[bufferType] = bandwidthEstimator; - return bandwidthEstimator; - } +/* harmony default export */ const manifest = (Manifest); - return originalBandwidthEstimator; - }; - return ABRManager; -}(); +/***/ }), +/***/ 2689: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -;// CONCATENATED MODULE: ./src/core/abr/index.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "s": () => (/* binding */ MAX_32_BIT_INT) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -15142,16 +15042,30 @@ var ABRManager = /*#__PURE__*/function () { * limitations under the License. */ -/* harmony default export */ const abr = (ABRManager); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/catchError.js -var catchError = __webpack_require__(486); -// EXTERNAL MODULE: ./src/utils/rx-try_catch.ts -var rx_try_catch = __webpack_require__(5561); -// 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 +/** + * Maximum integer that can be stored on 32 bits. + * + * This can be used for example to know what is the maximum ISOBMFF box size + * that can be stored on the first four bytes of a box. Any value higher than + * that will need 8 bytes (64 bits) to be stored. + */ +var MAX_32_BIT_INT = Math.pow(2, 32) - 1; + +/***/ }), + +/***/ 2297: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "iz": () => (/* binding */ getBox), +/* harmony export */ "t_": () => (/* binding */ getBoxContent), +/* harmony export */ "Qy": () => (/* binding */ getBoxOffsets), +/* harmony export */ "Xj": () => (/* binding */ getNextBoxOffsets), +/* harmony export */ "nR": () => (/* binding */ getUuidContent) +/* harmony export */ }); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3887); +/* harmony import */ var _utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6968); /** * Copyright 2015 CANAL+ Group * @@ -15168,281 +15082,212 @@ var network_error = __webpack_require__(9362); * limitations under the License. */ + /** - * Generate a new error from the infos given. - * @param {string} code - * @param {Error} error - * @returns {Error} + * Returns the content of a box based on its name. + * `null` if not found. + * @param {Uint8Array} buf - the isobmff structure + * @param {Number} boxName - the 4-letter 'name' of the box as a 4 bit integer + * generated from encoding the corresponding ASCII in big endian. + * @returns {UInt8Array|null} */ -function errorSelector(error) { - if (error instanceof request_error/* default */.Z) { - return new network_error/* default */.Z("PIPELINE_LOAD_ERROR", error); - } - - return formatError(error, { - defaultCode: "PIPELINE_LOAD_ERROR", - defaultReason: "Unknown error when fetching the Manifest" - }); +function getBoxContent(buf, boxName) { + var offsets = getBoxOffsets(buf, boxName); + return offsets !== null ? buf.subarray(offsets[1], offsets[2]) : null; } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/timer.js -var timer = __webpack_require__(9604); -;// 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. + * Returns an ISOBMFF box - size and name included - based on its name. + * `null` if not found. + * @param {Uint8Array} buf - the isobmff structure + * @param {Number} boxName - the 4-letter 'name' of the box as a 4 bit integer + * generated from encoding the corresponding ASCII in big endian. + * @returns {UInt8Array|null} */ -/** - * 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 */ + +function getBox(buf, boxName) { + var offsets = getBoxOffsets(buf, boxName); + return offsets !== null ? buf.subarray(offsets[0], offsets[2]) : null; } -// EXTERNAL MODULE: ./src/utils/get_fuzzed_delay.ts -var get_fuzzed_delay = __webpack_require__(2572); -;// CONCATENATED MODULE: ./src/core/fetchers/utils/try_urls_with_backoff.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 + * Returns byte offsets for the start of the box, the start of its content and + * the end of the box (not inclusive). * - * http://www.apache.org/licenses/LICENSE-2.0 + * `null` if not found. * - * 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. + * If found, the tuple returned has three elements, all numbers: + * 1. The starting byte corresponding to the start of the box (from its size) + * 2. The beginning of the box content - meaning the first byte after the + * size and the name of the box. + * 3. The first byte after the end of the box, might be equal to `buf`'s + * length if we're considering the last box. + * @param {Uint8Array} buf - the isobmff structure + * @param {Number} boxName - the 4-letter 'name' of the box as a 4 bit integer + * generated from encoding the corresponding ASCII in big endian. + * @returns {Array.|null} */ +function getBoxOffsets(buf, boxName) { + var len = buf.length; + var boxBaseOffset = 0; + var name; + var lastBoxSize = 0; + var lastOffset; + while (boxBaseOffset + 8 <= len) { + lastOffset = boxBaseOffset; + lastBoxSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, lastOffset); + lastOffset += 4; + name = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, lastOffset); + lastOffset += 4; + if (lastBoxSize === 0) { + lastBoxSize = len - boxBaseOffset; + } else if (lastBoxSize === 1) { + if (lastOffset + 8 > len) { + return null; + } + lastBoxSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be8toi */ .pV)(buf, lastOffset); + lastOffset += 8; + } -/** - * Called on a loader error. - * Returns whether the loader request should be retried. - * @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; + if (lastBoxSize < 0) { + throw new Error("ISOBMFF: Size out of range"); } - return error.type === error_codes/* NetworkErrorTypes.TIMEOUT */.br.TIMEOUT || error.type === error_codes/* NetworkErrorTypes.ERROR_EVENT */.br.ERROR_EVENT; + if (name === boxName) { + if (boxName === 0x75756964 + /* === "uuid" */ + ) { + lastOffset += 16; // Skip uuid name + } + + return [boxBaseOffset, lastOffset, boxBaseOffset + lastBoxSize]; + } else { + boxBaseOffset += lastBoxSize; + } } - return (0,is_known_error/* default */.Z)(error) && error.code === "INTEGRITY_ERROR"; + return null; } /** - * Returns true if we're pretty sure that the current error is due to the - * user being offline. - * @param {Error} error - * @returns {Boolean} + * Gives the content of a specific UUID box. + * `undefined` if that box is not found. + * + * If found, the returned Uint8Array contains just the box's content: the box + * without its name and size. + * @param {Uint8Array} buf + * @param {Number} id1 + * @param {Number} id2 + * @param {Number} id3 + * @param {Number} id4 + * @returns {Uint8Array|undefined} */ -function isOfflineRequestError(error) { - return error.type === error_codes/* NetworkErrorTypes.ERROR_EVENT */.br.ERROR_EVENT && isOffline(); -} +function getUuidContent(buf, id1, id2, id3, id4) { + var len = buf.length; + var boxSize; -var REQUEST_ERROR_TYPES; + for (var boxBaseOffset = 0; boxBaseOffset < len; boxBaseOffset += boxSize) { + var currentOffset = boxBaseOffset; + boxSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, currentOffset); + currentOffset += 4; + var boxName = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, currentOffset); + currentOffset += 4; -(function (REQUEST_ERROR_TYPES) { - REQUEST_ERROR_TYPES[REQUEST_ERROR_TYPES["None"] = 0] = "None"; - REQUEST_ERROR_TYPES[REQUEST_ERROR_TYPES["Regular"] = 1] = "Regular"; - REQUEST_ERROR_TYPES[REQUEST_ERROR_TYPES["Offline"] = 2] = "Offline"; -})(REQUEST_ERROR_TYPES || (REQUEST_ERROR_TYPES = {})); -/** - * Guess the type of error obtained. - * @param {*} error - * @returns {number} - */ + if (boxSize === 0) { + boxSize = len - boxBaseOffset; + } else if (boxSize === 1) { + if (currentOffset + 8 > len) { + return undefined; + } + boxSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be8toi */ .pV)(buf, currentOffset); + currentOffset += 8; + } -function getRequestErrorType(error) { - return error instanceof request_error/* default */.Z && isOfflineRequestError(error) ? REQUEST_ERROR_TYPES.Offline : REQUEST_ERROR_TYPES.Regular; + if (boxName === 0x75756964 + /* === "uuid" */ + && currentOffset + 16 <= len && (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, currentOffset) === id1 && (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, currentOffset + 4) === id2 && (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, currentOffset + 8) === id3 && (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, currentOffset + 12) === id4) { + currentOffset += 16; + return buf.subarray(currentOffset, boxBaseOffset + boxSize); + } + } } /** - * Specific algorithm used to perform segment and manifest requests. - * - * Here how it works: - * - * 1. we give it one or multiple URLs available for the element we want to - * request, the request callback and some options - * - * 2. it tries to call the request callback with the first URL: - * - if it works as expected, it wrap the response in a `response` event. - * - if it fails, it emits a `retry` event and try with the next one. - * - * 3. When all URLs have been tested (and failed), it decides - according to - * the error counters, configuration and errors received - if it can retry - * at least one of them, in the same order: - * - If it can, it increments the corresponding error counter, wait a - * delay (based on an exponential backoff) and restart the same logic - * for all retry-able URL. - * - If it can't it just throws the error. + * For the next encountered box, return byte offsets corresponding to: + * 1. the starting byte offset for the next box (should always be equal to + * `0`). + * 2. The beginning of the box content - meaning the first byte after the + * size and the name of the box. + * 3. The first byte after the end of the box, might be equal to `buf`'s + * length if we're considering the last box. * - * Note that there are in fact two separate counters: - * - one for "offline" errors - * - one for other xhr errors - * Both counters are resetted if the error type changes from an error to the - * next. - * @param {Array.= urlsToTry.length - 1 ? 0 : index; - return tryURLsRecursively(urlsToTry[newIndex], newIndex).pipe((0,startWith/* startWith */.O)({ - type: "retry", - value: error - })); - } + if (boxSize === 0) { + boxSize = len; + } else if (boxSize === 1) { + if (lastOffset + 8 > len) { + _log__WEBPACK_IMPORTED_MODULE_1__/* .default.warn */ .Z.warn("ISOBMFF: box too short, cannot find offsets"); + return null; + } - var currentError = getRequestErrorType(error); - var maxRetry = currentError === REQUEST_ERROR_TYPES.Offline ? maxRetryOffline : maxRetryRegular; + boxSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be8toi */ .pV)(buf, lastOffset); + lastOffset += 8; + } - if (currentError !== lastError) { - retryCount = 0; - lastError = currentError; - } + if (boxSize < 0) { + throw new Error("ISOBMFF: Size out of range"); + } - if (index < urlsToTry.length - 1) { - // there is still URLs to test - var _newIndex = index + 1; + if (name === 0x75756964 + /* === "uuid" */ + ) { + lastOffset += 16; // Skip uuid name + } - return tryURLsRecursively(urlsToTry[_newIndex], _newIndex).pipe((0,startWith/* startWith */.O)({ - type: "retry", - value: error - })); - } // Here, we were using the last element of the `urlsToTry` array. - // Increment counter and restart with the first URL + return [0, lastOffset, boxSize]; +} - retryCount++; - if (retryCount > maxRetry) { - throw error; - } +/***/ }), - var delay = Math.min(baseDelay * Math.pow(2, retryCount - 1), maxDelay); - var fuzzedDelay = (0,get_fuzzed_delay/* default */.Z)(delay); - var nextURL = urlsToTry[0]; - return (0,timer/* timer */.H)(fuzzedDelay).pipe((0,mergeMap/* mergeMap */.zg)(function () { - return tryURLsRecursively(nextURL, 0); - }), (0,startWith/* startWith */.O)({ - type: "retry", - value: error - })); - })); - } -} -/** - * Lightweight version of the request algorithm, this time with only a simple - * Observable given. - * @param {Function} request$ - * @param {Object} options - * @returns {Observable} - */ +/***/ 6807: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -function tryRequestObservableWithBackoff(request$, options) { - // same than for a single unknown URL - return tryURLsWithBackoff([null], function () { - return request$; - }, options); -} -;// CONCATENATED MODULE: ./src/core/fetchers/utils/create_request_scheduler.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "XA": () => (/* binding */ getTRAF), +/* harmony export */ "Le": () => (/* binding */ getMDAT), +/* harmony export */ "fs": () => (/* binding */ getMDIA), +/* harmony export */ "E3": () => (/* binding */ getEMSG) +/* harmony export */ }); +/* harmony import */ var _get_box__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2297); /** * Copyright 2015 CANAL+ Group * @@ -15459,30 +15304,104 @@ function tryRequestObservableWithBackoff(request$, options) { * limitations under the License. */ +/** + * Returns TRAF Box from the whole ISOBMFF File. + * Returns null if not found. + * @param {Uint8Array} buffer + * @returns {Uint8Array|null} + */ + +function getTRAF(buffer) { + var moof = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(buffer, 0x6D6F6F66 + /* moof */ + ); + + if (moof === null) { + return null; + } + + return (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(moof, 0x74726166 + /* traf */ + ); +} +/** + * Returns MDAT Box from the whole ISOBMFF File. + * Returns null if not found. + * @param {Uint8Array} buffer + * @returns {Uint8Array|null} + */ + +function getMDAT(buf) { + return (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(buf, 0x6D646174 + /* "mdat" */ + ); +} +/** + * Returns MDIA Box from the whole ISOBMFF File. + * Returns null if not found. + * @param {Uint8Array} buffer + * @returns {Uint8Array|null} + */ +function getMDIA(buf) { + var moov = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(buf, 0x6D6F6F76 + /* moov */ + ); -function createRequestScheduler(backoffOptions, warning$) { - /** - * Allow the parser to schedule a new request. - * @param {Function} request - Function performing the request. - * @returns {Function} - */ - return function scheduleRequest(request) { - return tryRequestObservableWithBackoff((0,rx_try_catch/* default */.Z)(request, undefined), backoffOptions).pipe((0,filter_map/* default */.Z)(function (evt) { - if (evt.type === "retry") { - warning$.next(errorSelector(evt.value)); - return null; - } + if (moov === null) { + return null; + } - return evt.value; - }, null), (0,catchError/* catchError */.K)(function (error) { - throw errorSelector(error); - })); - }; + var trak = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(moov, 0x7472616B + /* "trak" */ + ); + + if (trak === null) { + return null; + } + + return (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(trak, 0x6D646961 + /* "mdia" */ + ); } -;// CONCATENATED MODULE: ./src/core/fetchers/manifest/get_manifest_backoff_options.ts +/** + * Returns EMSG Box from the while ISOBMFF File. + * Returns null if not found. + * @param {Uint8Array} buffer + * @returns {Uint8Array|null} + */ + + +function getEMSG(buffer, offset) { + if (offset === void 0) { + offset = 0; + } + + return (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(buffer.subarray(offset), 0x656D7367 + /* emsg */ + ); +} + + + +/***/ }), + +/***/ 6490: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ takePSSHOut), + "Y": () => (/* binding */ getPsshSystemID) +}); + +// EXTERNAL MODULE: ./src/log.ts + 1 modules +var log = __webpack_require__(3887); +;// CONCATENATED MODULE: ./src/utils/slice_uint8array.ts /** * Copyright 2015 CANAL+ Group * @@ -15499,30 +15418,39 @@ function createRequestScheduler(backoffOptions, warning$) { * limitations under the License. */ -var DEFAULT_MAX_MANIFEST_REQUEST_RETRY = config/* default.DEFAULT_MAX_MANIFEST_REQUEST_RETRY */.Z.DEFAULT_MAX_MANIFEST_REQUEST_RETRY, - DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE = config/* default.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE */.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE, - INITIAL_BACKOFF_DELAY_BASE = config/* default.INITIAL_BACKOFF_DELAY_BASE */.Z.INITIAL_BACKOFF_DELAY_BASE, - MAX_BACKOFF_DELAY_BASE = config/* default.MAX_BACKOFF_DELAY_BASE */.Z.MAX_BACKOFF_DELAY_BASE; /** - * Parse config to replace missing manifest backoff options. - * @param {Object} backoffOptions - * @returns {Object} + * @param {Uint8Array} arr - The Uint8Array you want to slice + * @param {number} start - The starting byte index from the beginning + * @param {number} end - Byte index before which to end slicing. + * If end is unspecified, the new ArrayBuffer contains all bytes from begin to + * the end of this ArrayBuffer. If negative, it will make the Byte index begin + * from the last Byte. + * @returns {Uint8Array} + */ +function arraySlice(arr, start, end) { + return new Uint8Array(Array.prototype.slice.call(arr, start, end)); +} +/** + * @param {Uint8Array} arr - The Uint8Array you want to slice + * @param {number} start - The starting byte index from the beginning + * @param {number} end - Byte index before which to end slicing. + * If end is unspecified, the new ArrayBuffer contains all bytes from begin to + * the end of this ArrayBuffer. If negative, it will make the Byte index begin + * from the last Byte. + * @returns {Uint8Array} */ -function getManifestBackoffOptions(_ref) { - var maxRetryRegular = _ref.maxRetryRegular, - maxRetryOffline = _ref.maxRetryOffline, - lowLatencyMode = _ref.lowLatencyMode; - 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; - return { - baseDelay: baseDelay, - maxDelay: maxDelay, - maxRetryRegular: maxRetryRegular !== undefined ? maxRetryRegular : DEFAULT_MAX_MANIFEST_REQUEST_RETRY, - maxRetryOffline: maxRetryOffline !== undefined ? maxRetryOffline : DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE - }; + +function uint8ArraySlice(arr, start, end) { + return arr.slice(start, end); } -;// CONCATENATED MODULE: ./src/core/fetchers/manifest/manifest_fetcher.ts + +/* harmony default export */ const slice_uint8array = (typeof Uint8Array.prototype.slice === "function" ? uint8ArraySlice : arraySlice); +// EXTERNAL MODULE: ./src/utils/string_parsing.ts +var string_parsing = __webpack_require__(3635); +// EXTERNAL MODULE: ./src/parsers/containers/isobmff/get_box.ts +var get_box = __webpack_require__(2297); +;// CONCATENATED MODULE: ./src/parsers/containers/isobmff/take_pssh_out.ts /** * Copyright 2015 CANAL+ Group * @@ -15542,167 +15470,110 @@ function getManifestBackoffOptions(_ref) { - - - - /** - * 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); - * }); - * ``` + * Replace every PSSH box from an ISOBMFF segment by FREE boxes and returns the + * removed PSSH in an array. + * Useful to manually manage encryption while avoiding the round-trip with the + * browser's encrypted event. + * @param {Uint8Array} data - the ISOBMFF segment + * @returns {Array.} - The extracted PSSH boxes. In the order they + * are encountered. */ -var ManifestFetcher = /*#__PURE__*/function () { - /** - * @param {string | undefined} url - * @param {Object} pipelines - * @param {Object} backoffOptions - */ - function ManifestFetcher(url, pipelines, backoffOptions) { - this._manifestUrl = url; - this._pipelines = pipelines.manifest; - this._backoffOptions = getManifestBackoffOptions(backoffOptions); +function takePSSHOut(data) { + var i = 0; + var moov = (0,get_box/* getBoxContent */.t_)(data, 0x6D6F6F76 + /* moov */ + ); + + if (moov === null) { + return []; } - /** - * (re-)Load the Manifest without yet parsing it. - * - * 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} [url] - * @returns {Observable} - */ + var psshBoxes = []; - var _proto = ManifestFetcher.prototype; + while (i < moov.length) { + var psshOffsets = void 0; - _proto.fetch = function fetch(url) { - var _this = this; + try { + psshOffsets = (0,get_box/* getBoxOffsets */.Qy)(moov, 0x70737368 + /* pssh */ + ); + } catch (e) { + log/* default.warn */.Z.warn("ISOBMFF:", e); + return psshBoxes; + } - var _a; + if (psshOffsets == null) { + return psshBoxes; + } - var requestUrl = url !== null && url !== void 0 ? url : this._manifestUrl; // TODO Remove the resolver completely in the next major version + var pssh = slice_uint8array(moov, psshOffsets[0], psshOffsets[2]); + var systemId = getPsshSystemID(pssh, psshOffsets[1] - psshOffsets[0]); - var resolver = (_a = this._pipelines.resolver) !== null && _a !== void 0 ? _a : of.of; - var loader = this._pipelines.loader; - return (0,rx_try_catch/* default */.Z)(resolver, { - url: requestUrl - }).pipe((0,catchError/* catchError */.K)(function (error) { - throw errorSelector(error); - }), (0,mergeMap/* mergeMap */.zg)(function (loaderArgument) { - var loader$ = (0,rx_try_catch/* default */.Z)(loader, loaderArgument); - return tryRequestObservableWithBackoff(loader$, _this._backoffOptions).pipe((0,catchError/* catchError */.K)(function (error) { - throw errorSelector(error); - }), (0,map/* map */.U)(function (evt) { - return evt.type === "retry" ? { - type: "warning", - value: errorSelector(evt.value) - } : { - type: "response", - parse: function parse(parserOptions) { - return _this._parseLoadedManifest(evt.value.value, parserOptions); - } - }; - })); - })); + if (systemId !== undefined) { + psshBoxes.push({ + systemId: systemId, + data: pssh + }); + } // replace by `free` box. + + + moov[psshOffsets[0] + 4] = 0x66; + moov[psshOffsets[0] + 5] = 0x72; + moov[psshOffsets[0] + 6] = 0x65; + moov[psshOffsets[0] + 7] = 0x65; + i = psshOffsets[2]; } - /** - * 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} - */ - ; - _proto.parse = function parse(manifest, parserOptions) { - return this._parseLoadedManifest({ - responseData: manifest, - size: undefined, - duration: undefined - }, parserOptions); + return psshBoxes; +} +/** + * Parse systemId from a "pssh" box into an hexadecimal string. + * `undefined` if we could not extract a systemId. + * @param {Uint8Array} buff - The pssh box + * @param {number} initialDataOffset - offset of the first byte after the size + * and name in this pssh box. + * @returns {string|undefined} + */ + +function getPsshSystemID(buff, initialDataOffset) { + if (buff[initialDataOffset] > 1) { + log/* default.warn */.Z.warn("ISOBMFF: un-handled PSSH version"); + return undefined; } - /** - * 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} - */ - ; - _proto._parseLoadedManifest = function _parseLoadedManifest(loaded, parserOptions) { - var sendingTime = loaded.sendingTime, - receivedTime = loaded.receivedTime; - var parsingTimeStart = performance.now(); - var schedulerWarnings$ = new Subject/* Subject */.xQ(); - var scheduleRequest = createRequestScheduler(this._backoffOptions, schedulerWarnings$); - return (0,merge/* merge */.T)(schedulerWarnings$.pipe((0,map/* map */.U)(function (err) { - return { - type: "warning", - value: err - }; - })), this._pipelines.parser({ - response: loaded, - url: this._manifestUrl, - externalClockOffset: parserOptions.externalClockOffset, - previousManifest: parserOptions.previousManifest, - scheduleRequest: scheduleRequest, - unsafeMode: parserOptions.unsafeMode - }).pipe((0,catchError/* catchError */.K)(function (error) { - throw formatError(error, { - defaultCode: "PIPELINE_PARSE_ERROR", - defaultReason: "Unknown error when parsing the Manifest" - }); - }), (0,map/* map */.U)(function (parsingEvt) { - if (parsingEvt.type === "warning") { - var formatted = formatError(parsingEvt.value, { - defaultCode: "PIPELINE_PARSE_ERROR", - defaultReason: "Unknown error when parsing the Manifest" - }); - return { - type: "warning", - value: formatted - }; - } // 2 - send response + var offset = initialDataOffset + 4; + /* version + flags */ + if (offset + 16 > buff.length) { + return undefined; + } - var parsingTime = performance.now() - parsingTimeStart; - return { - type: "parsed", - manifest: parsingEvt.value.manifest, - sendingTime: sendingTime, - receivedTime: receivedTime, - parsingTime: parsingTime - }; - }), finalize(function () { - schedulerWarnings$.complete(); - }))); - }; + var systemIDBytes = slice_uint8array(buff, offset, offset + 16); + return (0,string_parsing/* bytesToHex */.ci)(systemIDBytes); +} - return ManifestFetcher; -}(); +/***/ }), +/***/ 4644: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -;// CONCATENATED MODULE: ./src/core/fetchers/manifest/index.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "LD": () => (/* binding */ getMDHDTimescale), +/* harmony export */ "Qx": () => (/* binding */ getTrackFragmentDecodeTime), +/* harmony export */ "MM": () => (/* binding */ getDurationFromTrun), +/* harmony export */ "Wf": () => (/* binding */ getSegmentsFromSidx), +/* harmony export */ "J6": () => (/* binding */ updateBoxLength), +/* harmony export */ "s9": () => (/* binding */ parseEmsgBoxes) +/* harmony export */ }); +/* unused harmony export patchPssh */ +/* harmony import */ var _utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6968); +/* harmony import */ var _utils_string_parsing__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3635); +/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2689); +/* harmony import */ var _get_box__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2297); +/* harmony import */ var _read__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6807); /** * Copyright 2015 CANAL+ Group * @@ -15719,649 +15590,494 @@ var ManifestFetcher = /*#__PURE__*/function () { * limitations under the License. */ -/* harmony default export */ const fetchers_manifest = (ManifestFetcher); -;// CONCATENATED MODULE: ./src/core/fetchers/segment/get_segment_backoff_options.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 + * Parse the sidx part (segment index) of an ISOBMFF buffer and construct a + * corresponding Array of available segments. * - * 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 `null` if not found. + * @param {Uint8Array} buf + * @param {Number} sidxOffsetInWholeSegment + * @returns {Object|null} {Array.} - Information about each subsegment. */ -var DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR = config/* default.DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR */.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR, - get_segment_backoff_options_DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE = config/* default.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE */.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE, - get_segment_backoff_options_INITIAL_BACKOFF_DELAY_BASE = config/* default.INITIAL_BACKOFF_DELAY_BASE */.Z.INITIAL_BACKOFF_DELAY_BASE, - get_segment_backoff_options_MAX_BACKOFF_DELAY_BASE = config/* default.MAX_BACKOFF_DELAY_BASE */.Z.MAX_BACKOFF_DELAY_BASE; -/** - * @param {string} bufferType - * @param {Object} - * @returns {Object} - */ +function getSegmentsFromSidx(buf, sidxOffsetInWholeSegment) { + var sidxOffsets = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxOffsets */ .Qy)(buf, 0x73696478 + /* "sidx" */ + ); -function getSegmentBackoffOptions(bufferType, _ref) { - var maxRetryRegular = _ref.maxRetryRegular, - maxRetryOffline = _ref.maxRetryOffline, - lowLatencyMode = _ref.lowLatencyMode; - return { - maxRetryRegular: bufferType === "image" ? 0 : maxRetryRegular !== null && maxRetryRegular !== void 0 ? maxRetryRegular : DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR, - maxRetryOffline: maxRetryOffline !== null && maxRetryOffline !== void 0 ? maxRetryOffline : get_segment_backoff_options_DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE, - baseDelay: lowLatencyMode ? get_segment_backoff_options_INITIAL_BACKOFF_DELAY_BASE.LOW_LATENCY : get_segment_backoff_options_INITIAL_BACKOFF_DELAY_BASE.REGULAR, - maxDelay: lowLatencyMode ? get_segment_backoff_options_MAX_BACKOFF_DELAY_BASE.LOW_LATENCY : get_segment_backoff_options_MAX_BACKOFF_DELAY_BASE.REGULAR - }; + if (sidxOffsets === null) { + return null; + } + + var offset = sidxOffsetInWholeSegment; + var boxSize = sidxOffsets[2] - sidxOffsets[0]; + var cursor = sidxOffsets[1]; + /* version(8) */ + + /* flags(24) */ + + /* reference_ID(32); */ + + /* timescale(32); */ + + var version = buf[cursor]; + cursor += 4 + 4; + var timescale = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(buf, cursor); + cursor += 4; + /* earliest_presentation_time(32 / 64) */ + + /* first_offset(32 / 64) */ + + var time; + + if (version === 0) { + time = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(buf, cursor); + cursor += 4; + offset += (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(buf, cursor) + boxSize; + cursor += 4; + } else if (version === 1) { + time = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be8toi */ .pV)(buf, cursor); + cursor += 8; + offset += (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be8toi */ .pV)(buf, cursor) + boxSize; + cursor += 8; + } else { + return null; + } + + var segments = []; + /* reserved(16) */ + + /* reference_count(16) */ + + cursor += 2; + var count = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be2toi */ .zK)(buf, cursor); + cursor += 2; + + while (--count >= 0) { + /* reference_type(1) */ + + /* reference_size(31) */ + + /* segment_duration(32) */ + + /* sap..(32) */ + var refChunk = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(buf, cursor); + cursor += 4; + var refType = (refChunk & 0x80000000) >>> 31; + var refSize = refChunk & 0x7FFFFFFF; // when set to 1 indicates that the reference is to a sidx, else to media + + if (refType === 1) { + throw new Error("sidx with reference_type `1` not yet implemented"); + } + + var duration = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(buf, cursor); + cursor += 4; // let sapChunk = be4toi(buf, cursor + 8); + + cursor += 4; // TODO(pierre): handle sap + // let startsWithSap = (sapChunk & 0x80000000) >>> 31; + // let sapType = (sapChunk & 0x70000000) >>> 28; + // let sapDelta = sapChunk & 0x0FFFFFFF; + + segments.push({ + time: time, + duration: duration, + count: 0, + timescale: timescale, + range: [offset, offset + refSize - 1] + }); + time += duration; + offset += refSize; + } + + return segments; } -;// CONCATENATED MODULE: ./src/core/fetchers/segment/prioritized_segment_fetcher.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 + * Parse track Fragment Decode Time to get a precize initial time for this + * segment (in the media timescale). * - * 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. + * Stops at the first tfdt encountered from the beginning of the file. + * Returns this time. + * `undefined` if not found. + * @param {Uint8Array} buffer + * @returns {Number | undefined} */ +function getTrackFragmentDecodeTime(buffer) { + var traf = (0,_read__WEBPACK_IMPORTED_MODULE_2__/* .getTRAF */ .XA)(buffer); + + if (traf === null) { + return undefined; + } + + var tfdt = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(traf, 0x74666474 + /* tfdt */ + ); + + if (tfdt === null) { + return undefined; + } + + var version = tfdt[0]; + return version === 1 ? (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be8toi */ .pV)(tfdt, 4) : version === 0 ? (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(tfdt, 4) : undefined; +} /** - * This function basically put in relation: - * - a SegmentFetcher, which will be used to perform the segment request - * - a prioritizer, which will handle the priority of a segment request + * Returns the "default sample duration" which is the default value for duration + * of samples found in a "traf" ISOBMFF box. * - * and returns functions to fetch segments with a given priority. - * @param {Object} prioritizer - * @param {Object} fetcher - * @returns {Object} + * Returns `undefined` if no "default sample duration" has been found. + * @param {Uint8Array} traf + * @returns {number|undefined} */ -function applyPrioritizerToSegmentFetcher(prioritizer, fetcher) { - /** - * The Observables returned by `createRequest` are not exactly the same than - * the one created by the `ObservablePrioritizer`. Because we still have to - * keep a handle on that value. - */ - var taskHandlers = new WeakMap(); - return { - /** - * Create a Segment request with a given priority. - * @param {Object} content - content to request - * @param {Number} priority - priority at which the content should be requested. - * Lower number == higher priority. - * @returns {Observable} - */ - createRequest: function createRequest(content, priority) { - if (priority === void 0) { - priority = 0; - } - var task = prioritizer.create(fetcher(content), priority); - var flattenTask = task.pipe((0,map/* map */.U)(function (evt) { - return evt.type === "data" ? evt.value : evt; - })); - taskHandlers.set(flattenTask, task); - return flattenTask; - }, +function getDefaultDurationFromTFHDInTRAF(traf) { + var tfhd = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(traf, 0x74666864 + /* tfhd */ + ); - /** - * Update the priority of a pending request, created through - * `createRequest`. - * @param {Observable} observable - The Observable returned by `createRequest`. - * @param {Number} priority - The new priority value. - */ - updatePriority: function updatePriority(observable, priority) { - var correspondingTask = taskHandlers.get(observable); + if (tfhd === null) { + return undefined; + } - if (correspondingTask === undefined) { - log/* default.warn */.Z.warn("Fetchers: Cannot update the priority of a request: task not found."); - return; - } + var cursor = + /* version */ + 1; + var flags = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be3toi */ .QI)(tfhd, cursor); + cursor += 3; + var hasBaseDataOffset = (flags & 0x000001) > 0; + var hasSampleDescriptionIndex = (flags & 0x000002) > 0; + var hasDefaultSampleDuration = (flags & 0x000008) > 0; - prioritizer.updatePriority(correspondingTask, priority); - } - }; + if (!hasDefaultSampleDuration) { + return undefined; + } + + cursor += 4; + + if (hasBaseDataOffset) { + cursor += 8; + } + + if (hasSampleDescriptionIndex) { + cursor += 4; + } + + var defaultDuration = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(tfhd, cursor); + return defaultDuration; } -;// CONCATENATED MODULE: ./src/core/fetchers/segment/prioritizer.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 + * Calculate segment duration approximation by additioning the duration from + * every samples in a trun ISOBMFF box. * - * 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 `undefined` if we could not parse the duration. + * @param {Uint8Array} buffer + * @returns {number | undefined} */ +function getDurationFromTrun(buffer) { + var traf = (0,_read__WEBPACK_IMPORTED_MODULE_2__/* .getTRAF */ .XA)(buffer); -/** - * Create Observables which can be priorized between one another. - * - * With this class, you can link an Observables to a priority number. - * The lower this number is, the more priority the resulting Observable will - * have. - * - * Such returned Observables - called "tasks" - will then basically wait for - * pending task with more priority (i.e. a lower priority number) to finish - * before "starting". - * - * This only applies for non-pending tasks. For pending tasks, those are usually - * not interrupted except in the following case: - * - * When a task with a "high priority" (which is a configurable priority - * value) is created, pending tasks with a "low priority" (also configurable) - * will be interrupted. Those tasks will be restarted when all tasks with a - * higher priority are finished. - * - * You can also update the priority of an already-created task. - * - * ```js - * const observable1 = Observable.timer(100).pipe(mapTo(1)); - * const observable2 = Observable.timer(100).pipe(mapTo(2)); - * const observable3 = Observable.timer(100).pipe(mapTo(3)); - * const observable4 = Observable.timer(100).pipe(mapTo(4)); - * const observable5 = Observable.timer(100).pipe(mapTo(5)); - * - * // Instanciate ObservablePrioritizer. - * // Also provide a `high` priority step - the maximum priority number a "high - * // priority task" has and a `low` priority step - the minimum priority number - * // a "low priority task" has. - * const prioritizer = new ObservablePrioritizer({ - * prioritySteps: { high: 0, low: 20 } - * }); - * - * const pObservable1 = prioritizer.create(observable1, 4); - * const pObservable2 = prioritizer.create(observable2, 2); - * const pObservable3 = prioritizer.create(observable3, 1); - * const pObservable4 = prioritizer.create(observable4, 3); - * const pObservable5 = prioritizer.create(observable5, 2); - * - * // start every Observables at the same time - * observableMerge( - * pObservable1, - * pObservable2, - * pObservable3, - * pObservable4, - * pObservable5 - * ).subscribe((evt) => { - * if (evt.type === "data") { - * console.log(i); - * - * // To spice things up, update pObservable1 priority to go before - * // pObservable4 - * if (i === 5) { // if pObservable5 is currently emitting - * prioritizer.updatePriority(pObservable1, 1); - * } - * } - * }); - * - * // Result: - * // 3 - * // 2 - * // 5 - * // 1 - * // 4 - * - * // Note: here "1" goes before "4" only because the former's priority has been - * // updated before the latter was started. - * // It would be the other way around if not. - * ``` - * - * @class ObservablePrioritizer - */ + if (traf === null) { + return undefined; + } -var ObservablePrioritizer = /*#__PURE__*/function () { - /** - * @param {Options} prioritizerOptions - */ - function ObservablePrioritizer(_ref) { - var prioritySteps = _ref.prioritySteps; - this._minPendingPriority = null; - this._waitingQueue = []; - this._pendingTasks = []; - this._prioritySteps = prioritySteps; + var trun = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(traf, 0x7472756E + /* trun */ + ); - if (this._prioritySteps.high >= this._prioritySteps.low) { - throw new Error("FP Error: the max high level priority should be given a lower" + "priority number than the min low priority."); - } + if (trun === null) { + return undefined; } - /** - * Create a priorized Observable from a base Observable. - * - * When subscribed to, this Observable will have its priority compared to - * all the already-running Observables created from this class. - * - * Only if this number is inferior or equal to the priority of the - * currently-running Observables will it be immediately started. - * In the opposite case, we will wait for higher-priority Observables to - * finish before starting it. - * - * Note that while this Observable is waiting for its turn, it is possible - * to update its property through the updatePriority method, by providing - * the Observable returned by this function and its new priority number. - * - * @param {Observable} obs - * @param {number} priority - * @returns {Observable} - */ + var cursor = 0; + var version = trun[cursor]; + cursor += 1; - var _proto = ObservablePrioritizer.prototype; + if (version > 1) { + return undefined; + } - _proto.create = function create(obs, priority) { - var _this = this; + var flags = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be3toi */ .QI)(trun, cursor); + cursor += 3; + var hasSampleDuration = (flags & 0x000100) > 0; + var defaultDuration = 0; - var pObs$ = new Observable/* Observable */.y(function (subscriber) { - var isStillSubscribed = true; // eslint-disable-next-line prefer-const + if (!hasSampleDuration) { + defaultDuration = getDefaultDurationFromTFHDInTRAF(traf); - var newTask; - /** - * Function allowing to start / interrupt the underlying Observable. - * @param {Boolean} shouldRun - If `true`, the observable can run. If - * `false` it means that it just needs to be interrupted if already - * starte. - */ + if (defaultDuration === undefined) { + return undefined; + } + } - var trigger = function trigger(shouldRun) { - if (newTask.subscription !== null) { - newTask.subscription.unsubscribe(); - newTask.subscription = null; + var hasDataOffset = (flags & 0x000001) > 0; + var hasFirstSampleFlags = (flags & 0x000004) > 0; + var hasSampleSize = (flags & 0x000200) > 0; + var hasSampleFlags = (flags & 0x000400) > 0; + var hasSampleCompositionOffset = (flags & 0x000800) > 0; + var sampleCounts = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(trun, cursor); + cursor += 4; - if (isStillSubscribed) { - subscriber.next({ - type: "interrupted" - }); - } - } + if (hasDataOffset) { + cursor += 4; + } - if (!shouldRun) { - return; - } + if (hasFirstSampleFlags) { + cursor += 4; + } - _this._minPendingPriority = _this._minPendingPriority === null ? newTask.priority : Math.min(_this._minPendingPriority, newTask.priority); + var i = sampleCounts; + var duration = 0; - _this._pendingTasks.push(newTask); + while (i-- > 0) { + if (hasSampleDuration) { + duration += (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(trun, cursor); + cursor += 4; + } else { + duration += defaultDuration; + } - newTask.subscription = obs.subscribe(function (evt) { - return subscriber.next({ - type: "data", - value: evt - }); - }, function (error) { - subscriber.error(error); - newTask.subscription = null; - newTask.finished = true; + if (hasSampleSize) { + cursor += 4; + } - _this._onTaskEnd(newTask); - }, function () { - subscriber.next({ - type: "ended" - }); + if (hasSampleFlags) { + cursor += 4; + } - if (isStillSubscribed) { - subscriber.complete(); - } + if (hasSampleCompositionOffset) { + cursor += 4; + } + } - newTask.subscription = null; - newTask.finished = true; + return duration; +} +/** + * Get timescale information from a movie header box. Found in init segments. + * `undefined` if not found or not parsed. + * + * This timescale is the default timescale used for segments. + * @param {Uint8Array} buffer + * @returns {Number | undefined} + */ - _this._onTaskEnd(newTask); - }); - }; - newTask = { - observable: pObs$, - priority: priority, - trigger: trigger, - subscription: null, - finished: false - }; +function getMDHDTimescale(buffer) { + var mdia = (0,_read__WEBPACK_IMPORTED_MODULE_2__/* .getMDIA */ .fs)(buffer); - if (!_this._canBeStartedNow(newTask)) { - _this._waitingQueue.push(newTask); - } else { - newTask.trigger(true); + if (mdia === null) { + return undefined; + } - if (_this._isRunningHighPriorityTasks()) { - // Note: we want to begin interrupting low-priority tasks just - // after starting the current one because the interrupting - // logic can call external code. - // This would mean re-entrancy, itself meaning that some weird - // half-state could be reached unless we're very careful. - // To be sure no harm is done, we put that code at the last - // possible position (the previous Observable sould be - // performing all its initialization synchronously). - _this._interruptCancellableTasks(); - } - } - /** Callback called when this Observable is unsubscribed to. */ + var mdhd = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(mdia, 0x6D646864 + /* "mdhd" */ + ); + if (mdhd === null) { + return undefined; + } - return function () { - isStillSubscribed = false; + var cursor = 0; + var version = mdhd[cursor]; + cursor += 4; + return version === 1 ? (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(mdhd, cursor + 16) : version === 0 ? (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(mdhd, cursor + 8) : undefined; +} +/** + * Creates a PSSH box with the given systemId and data. + * @param {Array.} psshInfo + * @returns {Uint8Array} + */ - if (newTask.subscription !== null) { - newTask.subscription.unsubscribe(); - newTask.subscription = null; - } - if (newTask.finished) { - // Task already finished, we're good - return; - } // remove it from waiting queue if in it +function createPssh(_ref) { + var systemId = _ref.systemId, + privateData = _ref.privateData; + var _systemId = systemId.replace(/-/g, ""); - var waitingQueueIndex = (0,array_find_index/* default */.Z)(_this._waitingQueue, function (elt) { - return elt.observable === pObs$; - }); + assert(_systemId.length === 32); + return createBox("pssh", concat(4, // 4 initial zeroed bytes + hexToBytes(_systemId), itobe4(privateData.length), privateData)); +} +/** + * Update ISOBMFF given to add a "pssh" box in the "moov" box for every content + * protection in the psshList array given. + * @param {Uint8Array} buf - the ISOBMFF file + * @param {Array.} psshList + * @returns {Uint8Array} - The new ISOBMFF generated. + */ - if (waitingQueueIndex >= 0) { - // If it was still waiting for its turn - _this._waitingQueue.splice(waitingQueueIndex, 1); - } else { - // remove it from pending queue if in it - var pendingTasksIndex = (0,array_find_index/* default */.Z)(_this._pendingTasks, function (elt) { - return elt.observable === pObs$; - }); - if (pendingTasksIndex < 0) { - log/* default.warn */.Z.warn("FP: unsubscribing non-existent task"); - return; - } +function patchPssh(buf, psshList) { + if (psshList == null || psshList.length === 0) { + return buf; + } - var pendingTask = _this._pendingTasks.splice(pendingTasksIndex, 1)[0]; + var moovOffsets = getBoxOffsets(buf, 0x6D6F6F76 + /* = "moov" */ + ); - if (_this._pendingTasks.length === 0) { - _this._minPendingPriority = null; + if (moovOffsets === null) { + return buf; + } - _this._loopThroughWaitingQueue(); - } else if (_this._minPendingPriority === pendingTask.priority) { - _this._minPendingPriority = Math.min.apply(Math, _this._pendingTasks.map(function (t) { - return t.priority; - })); + var moov = buf.subarray(moovOffsets[0], moovOffsets[2]); + var moovArr = [moov]; - _this._loopThroughWaitingQueue(); - } - } - }; - }); - return pObs$; + for (var i = 0; i < psshList.length; i++) { + moovArr.push(createPssh(psshList[i])); } - /** - * Update the priority of an Observable created through the `create` method. - * @param {Observable} obs - * @param {number} priority - */ - ; - _proto.updatePriority = function updatePriority(obs, priority) { - var waitingQueueIndex = (0,array_find_index/* default */.Z)(this._waitingQueue, function (elt) { - return elt.observable === obs; - }); + var newmoov = updateBoxLength(concat.apply(void 0, moovArr)); + return concat(buf.subarray(0, moovOffsets[0]), newmoov, buf.subarray(moovOffsets[2])); +} +/** + * Returns a new version of the given box with the size updated + * so it reflects its actual size. + * + * You can use this function after modifying a ISOBMFF box so its size is + * updated. + * + * /!\ Please consider that this function might mutate the given Uint8Array + * in place or might create a new one, depending on the current conditions. + * @param {Uint8Array} buf - The ISOBMFF box + * @returns {Uint8Array} + */ - if (waitingQueueIndex >= 0) { - // If it was still waiting for its turn - var waitingQueueElt = this._waitingQueue[waitingQueueIndex]; - if (waitingQueueElt.priority === priority) { - return; - } +function updateBoxLength(buf) { + var newLen = buf.length; - waitingQueueElt.priority = priority; + if (newLen < 4) { + throw new Error("Cannot update box length: box too short"); + } - if (!this._canBeStartedNow(waitingQueueElt)) { - return; - } + var oldSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(buf, 0); - this._startWaitingQueueTask(waitingQueueIndex); + if (oldSize === 0) { + if (newLen > _constants__WEBPACK_IMPORTED_MODULE_3__/* .MAX_32_BIT_INT */ .s) { + var newBox = new Uint8Array(newLen + 8); + newBox.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe4 */ .kh)(1), 0); + newBox.set(buf.subarray(4, 8), 4); + newBox.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe8 */ .el)(newLen + 8), 8); + newBox.set(buf.subarray(8, newLen), 16); + return newBox; + } else { + buf.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe4 */ .kh)(newLen), 0); + return buf; + } + } else if (oldSize === 1) { + if (newLen < 16) { + throw new Error("Cannot update box length: box too short"); + } - if (this._isRunningHighPriorityTasks()) { - // Re-check to cancel every "cancellable" pending task - // - // Note: We start the task before interrupting cancellable tasks on - // purpose. - // Because both `_startWaitingQueueTask` and - // `_interruptCancellableTasks` can emit events and thus call external - // code, we could retrieve ourselves in a very weird state at this point - // (for example, the different Observable priorities could all be - // shuffled up, new Observables could have been started in the - // meantime, etc.). - // - // By starting the task first, we ensure that this is manageable: - // `_minPendingPriority` has already been updated to the right value at - // the time we reached external code, the priority of the current - // Observable has just been updated, and `_interruptCancellableTasks` - // will ensure that we're basing ourselves on the last `priority` value - // each time. - // Doing it in the reverse order is an order of magnitude more difficult - // to write and to reason about. - this._interruptCancellableTasks(); - } + buf.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe8 */ .el)(newLen), 8); + return buf; + } else if (newLen <= _constants__WEBPACK_IMPORTED_MODULE_3__/* .MAX_32_BIT_INT */ .s) { + buf.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe4 */ .kh)(newLen), 0); + return buf; + } else { + var _newBox = new Uint8Array(newLen + 8); - return; - } + _newBox.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe4 */ .kh)(1), 0); - var pendingTasksIndex = (0,array_find_index/* default */.Z)(this._pendingTasks, function (elt) { - return elt.observable === obs; - }); + _newBox.set(buf.subarray(4, 8), 4); - if (pendingTasksIndex < 0) { - log/* default.warn */.Z.warn("FP: request to update the priority of a non-existent task"); - return; - } + _newBox.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe8 */ .el)(newLen + 8), 8); - var task = this._pendingTasks[pendingTasksIndex]; + _newBox.set(buf.subarray(8, newLen), 16); - if (task.priority === priority) { - return; - } + return _newBox; + } +} +/** + * Parse EMSG boxes from ISOBMFF data. + * @param {Uint8Array} buf + * @returns {Array. | undefined} + */ - var prevPriority = task.priority; - task.priority = priority; - if (this._minPendingPriority === null || priority < this._minPendingPriority) { - this._minPendingPriority = priority; - } else if (this._minPendingPriority === prevPriority) { - // was highest priority - if (this._pendingTasks.length === 1) { - this._minPendingPriority = priority; - } else { - this._minPendingPriority = Math.min.apply(Math, this._pendingTasks.map(function (t) { - return t.priority; - })); - } +function parseEmsgBoxes(buffer) { + var emsgs = []; + var offset = 0; - this._loopThroughWaitingQueue(); - } else { - // We updated a task which already had a priority value higher than the - // minimum to a value still superior to the minimum. Nothing can happen. - return; - } + while (offset < buffer.length) { + var emsg = (0,_read__WEBPACK_IMPORTED_MODULE_2__/* .getEMSG */ .E3)(buffer, offset); - if (this._isRunningHighPriorityTasks()) { - // Always interrupt cancellable tasks after all other side-effects, to - // avoid re-entrancy issues - this._interruptCancellableTasks(); + if (emsg === null) { + break; } - } - /** - * Browse the current waiting queue and start all task in it that needs to be - * started: start the ones with the lowest priority value below - * `_minPendingPriority`. - * - * Private properties, such as `_minPendingPriority` are updated accordingly - * while this method is called. - */ - ; - _proto._loopThroughWaitingQueue = function _loopThroughWaitingQueue() { - var minWaitingPriority = this._waitingQueue.reduce(function (acc, elt) { - return acc === null || acc > elt.priority ? elt.priority : acc; - }, null); + var length = emsg.length; + offset += length; + var position = 4; // skip version + flags - if (minWaitingPriority === null || this._minPendingPriority !== null && this._minPendingPriority < minWaitingPriority) { - return; - } + var _readNullTerminatedSt = (0,_utils_string_parsing__WEBPACK_IMPORTED_MODULE_4__/* .readNullTerminatedString */ .DM)(emsg, position), + schemeIdEnd = _readNullTerminatedSt.end, + schemeIdUri = _readNullTerminatedSt.string; - for (var i = 0; i < this._waitingQueue.length; i++) { - var priorityToCheck = this._minPendingPriority === null ? minWaitingPriority : Math.min(this._minPendingPriority, minWaitingPriority); - var elt = this._waitingQueue[i]; + position = schemeIdEnd; // skip schemeIdUri - if (elt.priority <= priorityToCheck) { - this._startWaitingQueueTask(i); + var _readNullTerminatedSt2 = (0,_utils_string_parsing__WEBPACK_IMPORTED_MODULE_4__/* .readNullTerminatedString */ .DM)(emsg, position), + valueEnd = _readNullTerminatedSt2.end, + value = _readNullTerminatedSt2.string; - i--; // previous operation should have removed that element from the - // the waiting queue - } - } - } - /** - * Interrupt and move back to the waiting queue all pending tasks that are - * low priority (having a higher priority number than - * `this._prioritySteps.low`). - */ - ; + position = valueEnd; // skip value - _proto._interruptCancellableTasks = function _interruptCancellableTasks() { - for (var i = 0; i < this._pendingTasks.length; i++) { - var pendingObj = this._pendingTasks[i]; + var timescale = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(emsg, position); + position += 4; // skip timescale - if (pendingObj.priority >= this._prioritySteps.low) { - this._interruptPendingTask(pendingObj); // The previous call could have a lot of potential side-effects. - // It is safer to re-start the function to not miss any pending - // task that needs to be cancelled. + var presentationTimeDelta = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(emsg, position); + position += 4; // skip presentationTimeDelta + var eventDuration = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(emsg, position); + position += 4; // skip eventDuration - return this._interruptCancellableTasks(); - } - } - } - /** - * Start task which is at the given index in the waiting queue. - * The task will be removed from the waiting queue in the process. - * @param {number} index - */ - ; + var id = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(emsg, position); + position += 4; // skip id - _proto._startWaitingQueueTask = function _startWaitingQueueTask(index) { - var task = this._waitingQueue.splice(index, 1)[0]; + var messageData = emsg.subarray(position, length); + var emsgData = { + schemeIdUri: schemeIdUri, + value: value, + timescale: timescale, + presentationTimeDelta: presentationTimeDelta, + eventDuration: eventDuration, + id: id, + messageData: messageData + }; + emsgs.push(emsgData); + } - task.trigger(true); + if (emsgs.length === 0) { + return undefined; } - /** - * Move back pending task to the waiting queue and interrupt it. - * @param {object} task - */ - ; - _proto._interruptPendingTask = function _interruptPendingTask(task) { - var pendingTasksIndex = (0,array_find_index/* default */.Z)(this._pendingTasks, function (elt) { - return elt.observable === task.observable; - }); - - if (pendingTasksIndex < 0) { - log/* default.warn */.Z.warn("FP: Interrupting a non-existent pending task. Aborting..."); - return; - } // Stop task and put it back in the waiting queue - - - this._pendingTasks.splice(pendingTasksIndex, 1); - - this._waitingQueue.push(task); - - if (this._pendingTasks.length === 0) { - this._minPendingPriority = null; - } else if (this._minPendingPriority === task.priority) { - this._minPendingPriority = Math.min.apply(Math, this._pendingTasks.map(function (t) { - return t.priority; - })); - } - - task.trigger(false); // Interrupt at last step because it calls external code - } - /** - * Logic ran when a task has ended (either errored or completed). - * @param {Object} task - */ - ; - - _proto._onTaskEnd = function _onTaskEnd(task) { - var pendingTasksIndex = (0,array_find_index/* default */.Z)(this._pendingTasks, function (elt) { - return elt.observable === task.observable; - }); - - if (pendingTasksIndex < 0) { - return; // Happen for example when the task has been interrupted - } - - this._pendingTasks.splice(pendingTasksIndex, 1); - - if (this._pendingTasks.length > 0) { - if (this._minPendingPriority === task.priority) { - this._minPendingPriority = Math.min.apply(Math, this._pendingTasks.map(function (t) { - return t.priority; - })); - } - - return; // still waiting for Observables to finish - } - - this._minPendingPriority = null; - - this._loopThroughWaitingQueue(); - } - /** - * Return `true` if the given task can be started immediately based on its - * priority. - * @param {Object} task - * @returns {boolean} - */ - ; + return emsgs; +} - _proto._canBeStartedNow = function _canBeStartedNow(task) { - return this._minPendingPriority === null || task.priority <= this._minPendingPriority; - } - /** - * Returns `true` if any running task is considered "high priority". - * returns `false` otherwise. - * @param {Object} task - * @returns {boolean} - */ - ; - _proto._isRunningHighPriorityTasks = function _isRunningHighPriorityTasks() { - return this._minPendingPriority !== null && this._minPendingPriority <= this._prioritySteps.high; - }; - return ObservablePrioritizer; -}(); +/***/ }), +/***/ 3203: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -// EXTERNAL MODULE: ./src/utils/array_includes.ts -var array_includes = __webpack_require__(7714); -// EXTERNAL MODULE: ./src/utils/assert_unreachable.ts -var assert_unreachable = __webpack_require__(8418); -// EXTERNAL MODULE: ./src/utils/id_generator.ts -var id_generator = __webpack_require__(908); -;// CONCATENATED MODULE: ./src/utils/initialization_segment_cache.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6968); +/* harmony import */ var _utils_string_parsing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3635); /** * Copyright 2015 CANAL+ Group * @@ -16379,58 +16095,119 @@ var id_generator = __webpack_require__(908); */ /** - * Caching object used to cache initialization segments. - * This allow to have a faster representation switch and faster seeking. - * @class InitializationSegmentCache + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. */ -var InitializationSegmentCache = /*#__PURE__*/function () { - function InitializationSegmentCache() { - this._cache = new WeakMap(); + + +/** + * @param {UInt8Array} buf + * @returns {Object} + */ + +function parseBif(buf) { + var pos = 0; + var length = buf.length; + var fileFormat = (0,_utils_string_parsing__WEBPACK_IMPORTED_MODULE_0__/* .utf8ToStr */ .uR)(buf.subarray(pos + 1, pos + 8)); + pos += 8; + + if (buf[0] !== 0x89 || fileFormat !== "BIF\r\n\x1A\n") { + throw new Error("Invalid BIF file"); } - /** - * @param {Object} obj - * @param {*} response - */ + var minorVersion = buf[pos]; + pos += 1; + var majorVersion = buf[pos]; + pos += 1; + var patchVersion = buf[pos]; + pos += 1; + var increVersion = buf[pos]; + pos += 1; + var version = [minorVersion, majorVersion, patchVersion, increVersion].join("."); + + if (majorVersion > 0) { + throw new Error("Unhandled version: " + majorVersion); + } - var _proto = InitializationSegmentCache.prototype; + var imageCount = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .le4toi */ .dN)(buf, pos); + pos += 4; + var framewiseSeparation = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .le4toi */ .dN)(buf, pos); + pos += 4; + var format = (0,_utils_string_parsing__WEBPACK_IMPORTED_MODULE_0__/* .utf8ToStr */ .uR)(buf.subarray(pos, pos + 4)); + pos += 4; + var width = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .le2toi */ .qb)(buf, pos); + pos += 2; + var height = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .le2toi */ .qb)(buf, pos); + pos += 2; + var aspectRatio = [buf[pos], buf[pos + 1]].join(":"); + pos += 2; + var isVod = buf[pos] === 1; // bytes 0x1F to 0x40 is unused data for now - _proto.add = function add(_ref, response) { - var representation = _ref.representation, - segment = _ref.segment; + pos = 0x40; + var thumbs = []; - if (segment.isInit) { - this._cache.set(representation, response); - } + if (imageCount === 0) { + throw new Error("bif: no images to parse"); } - /** - * @param {Object} obj - * @returns {*} response - */ - ; - _proto.get = function get(_ref2) { - var representation = _ref2.representation, - segment = _ref2.segment; + var index = 0; + var previousImageInfo = null; - if (segment.isInit) { - var value = this._cache.get(representation); + while (pos < length) { + var currentImageTimestamp = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .le4toi */ .dN)(buf, pos); + pos += 4; + var currentImageOffset = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .le4toi */ .dN)(buf, pos); + pos += 4; - if (value !== undefined) { - return value; - } + if (previousImageInfo !== null) { + // calculate for index-1 + var ts = previousImageInfo.timestamp * framewiseSeparation; + var duration = framewiseSeparation; + var data = buf.slice(previousImageInfo.offset, currentImageOffset); + thumbs.push({ + index: index, + duration: duration, + ts: ts, + data: data + }); + index++; } - return null; + if (currentImageTimestamp === 0xFFFFFFFF) { + break; + } + + previousImageInfo = { + timestamp: currentImageTimestamp, + offset: currentImageOffset + }; + } + + return { + fileFormat: "BIF", + version: version, + imageCount: imageCount, + timescale: 1000, + format: format, + width: width, + height: height, + aspectRatio: aspectRatio, + isVod: isVod, + thumbs: thumbs }; +} - return InitializationSegmentCache; -}(); +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (parseBif); -/* harmony default export */ const initialization_segment_cache = (InitializationSegmentCache); -// EXTERNAL MODULE: ./src/utils/cast_to_observable.ts -var cast_to_observable = __webpack_require__(8117); -;// CONCATENATED MODULE: ./src/core/fetchers/segment/create_segment_loader.ts +/***/ }), + +/***/ 8232: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ clearTimelineFromPosition) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -16447,151 +16224,71 @@ var cast_to_observable = __webpack_require__(8117); * limitations under the License. */ - - - - - - - /** - * Returns a function allowing to load any wanted segment. - * - * The function returned takes in argument information about the wanted segment - * and returns an Observable which will emit various events related to the - * segment request (see ISegmentLoaderEvent). - * - * This observable will throw if, following the options given, the request and - * possible retry all failed. - * - * This observable will complete after emitting all the segment's data. - * - * Type parameters: - * - T: type of the data emitted - * - * @param {Function} loader - * @param {Object | undefined} cache - * @param {Object} options - * @returns {Function} + * Remove segments which starts before the given `firstAvailablePosition` from + * the timeline. `firstAvailablePosition` has to be time scaled. + * @param {Array.} + * @returns {number} */ +function clearTimelineFromPosition(timeline, firstAvailablePosition) { + while (timeline.length > 0) { + var firstElt = timeline[0]; -function createSegmentLoader(loader, cache, backoffOptions) { - /** - * Try to retrieve the segment from the cache and if not found call the - * pipeline's loader (with possible retries) to load it. - * @param {Object} loaderArgument - Context for the wanted segment. - * @returns {Observable} - */ - function loadData(wantedContent) { - /** - * Call the Pipeline's loader with an exponential Backoff. - * @returns {Observable} - */ - function startLoaderWithBackoff() { - var _a; + if (firstElt.start >= firstAvailablePosition) { + return; // all clear + } - var request$ = function request$(url) { - var loaderArgument = (0,object_assign/* default */.Z)({ - url: url - }, wantedContent); - return (0,concat/* concat */.z)((0,of.of)({ - type: "request", - value: loaderArgument - }), (0,rx_try_catch/* default */.Z)(loader, loaderArgument)); - }; + if (firstElt.repeatCount <= 0) { + timeline.shift(); + } else { + // we have a segment repetition + var nextElt = timeline[1]; - return tryURLsWithBackoff((_a = wantedContent.segment.mediaURLs) !== null && _a !== void 0 ? _a : [null], request$, backoffOptions).pipe((0,catchError/* catchError */.K)(function (error) { - throw errorSelector(error); - }), (0,map/* map */.U)(function (evt) { - if (evt.type === "retry") { - return { - type: "warning", - value: errorSelector(evt.value) - }; - } else if (evt.value.type === "request") { - return evt.value; + if (nextElt != null && nextElt.start <= firstAvailablePosition) { + timeline.shift(); + } else { + // no next segment or next segment is available + if (firstElt.duration <= 0) { + return; } - var response = evt.value; + var nextStart = firstElt.start + firstElt.duration; + var nextRepeat = 1; - if (response.type === "data-loaded" && cache != null) { - cache.add(wantedContent, response.value); + while (nextStart < firstAvailablePosition && nextRepeat <= firstElt.repeatCount) { + nextStart += firstElt.duration; + nextRepeat++; } - return evt.value; - })); - } - - var dataFromCache = cache != null ? cache.get(wantedContent) : null; - - if (dataFromCache != null) { - return (0,cast_to_observable/* default */.Z)(dataFromCache).pipe((0,map/* map */.U)(function (response) { - return { - type: "cache", - value: response - }; - }), (0,catchError/* catchError */.K)(startLoaderWithBackoff)); + if (nextRepeat > firstElt.repeatCount) { + // every start is before + timeline.shift(); + } else { + // some repetitions start after and some before + var newRepeat = firstElt.repeatCount - nextRepeat; + firstElt.start = nextStart; + firstElt.repeatCount = newRepeat; + return; + } + } } - - return startLoaderWithBackoff(); } - /** - * Load the corresponding segment. - * @param {Object} content - * @returns {Observable} - */ - - - return function loadSegment(content) { - return loadData(content).pipe((0,mergeMap/* mergeMap */.zg)(function (arg) { - var metrics$; - - if ((arg.type === "data-chunk-complete" || arg.type === "data-loaded") && arg.value.size !== undefined && arg.value.duration !== undefined) { - metrics$ = (0,of.of)({ - type: "metrics", - value: { - size: arg.value.size, - duration: arg.value.duration, - content: content - } - }); - } else { - metrics$ = empty/* EMPTY */.E; - } - - switch (arg.type) { - case "warning": - case "request": - case "progress": - return (0,of.of)(arg); - - case "cache": - case "data-created": - case "data-loaded": - return (0,concat/* concat */.z)((0,of.of)({ - type: "data", - value: arg.value - }), metrics$); +} - case "data-chunk": - return (0,of.of)({ - type: "chunk", - value: arg.value - }); +/***/ }), - case "data-chunk-complete": - return (0,concat/* concat */.z)((0,of.of)({ - type: "chunk-complete", - value: null - }), metrics$); +/***/ 3911: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - default: - (0,assert_unreachable/* default */.Z)(arg); - } - })); - }; -} -;// CONCATENATED MODULE: ./src/core/fetchers/segment/segment_fetcher.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "KF": () => (/* binding */ calculateRepeat), +/* harmony export */ "jH": () => (/* binding */ getIndexSegmentEnd), +/* harmony export */ "gT": () => (/* binding */ toIndexTime), +/* harmony export */ "zG": () => (/* binding */ fromIndexTime), +/* harmony export */ "PZ": () => (/* binding */ getTimescaledRange), +/* harmony export */ "_j": () => (/* binding */ checkDiscontinuity) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -16607,181 +16304,170 @@ function createSegmentLoader(loader, cache, backoffOptions) { * See the License for the specific language governing permissions and * limitations under the License. */ +// byte-range +/** + * Calculate the number of times a timeline element repeats based on the next + * element. + * @param {Object} element + * @param {Object} nextElement + * @param {number} maxPosition + * @returns {Number} + */ +function calculateRepeat(element, nextElement, maxPosition) { + var repeatCount = element.repeatCount; + if (repeatCount >= 0) { + return repeatCount; + } // A negative value of the @r attribute of the S element indicates + // that the duration indicated in @d attribute repeats until the + // start of the next S element, the end of the Period or until the + // next MPD update. + var segmentEnd; + if (nextElement != null) { + segmentEnd = nextElement.start; + } else if (maxPosition != null) { + segmentEnd = maxPosition; + } else { + segmentEnd = Number.MAX_VALUE; + } - - -var generateRequestID = (0,id_generator/* default */.Z)(); + return Math.ceil((segmentEnd - element.start) / element.duration) - 1; +} /** - * Create a function which will fetch and parse segments. - * @param {string} bufferType - * @param {Object} transport - * @param {Subject} requests$ - * @param {Object} options - * @returns {Function} + * Returns end of the segment given, in index time. + * @param {Object} segment + * @param {Object|null} [nextSegment] + * @param {number} maxPosition + * @returns {Number} */ -function segment_fetcher_createSegmentFetcher(bufferType, transport, requests$, options) { - var cache = (0,array_includes/* default */.Z)(["audio", "video"], bufferType) ? new initialization_segment_cache() : undefined; - var segmentLoader = createSegmentLoader(transport[bufferType].loader, cache, options); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment +function getIndexSegmentEnd(segment, nextSegment, maxPosition) { + var start = segment.start, + duration = segment.duration; - var segmentParser = transport[bufferType].parser; // deal with it + if (duration <= 0) { + return start; + } - /** - * Process the segmentLoader observable to adapt it to the the rest of the - * code: - * - use the requests subject for network requests and their progress - * - use the warning$ subject for retries' error messages - * - only emit the data - * @param {Object} content - * @returns {Observable} - */ + var repeat = calculateRepeat(segment, nextSegment, maxPosition); + return start + (repeat + 1) * duration; +} +/** + * Convert from `presentationTime`, the time of the segment at the moment it + * is decoded to `mediaTime`, the original time the segments point at. + * @param {number} time + * @param {Object} indexOptions + * @returns {number} + */ - return function fetchSegment(content) { - var id = generateRequestID(); - var requestBeginSent = false; - return segmentLoader(content).pipe((0,tap/* tap */.b)(function (arg) { - switch (arg.type) { - case "metrics": - { - requests$.next(arg); - break; - } +function toIndexTime(time, indexOptions) { + var _a; - case "request": - { - var value = arg.value; // format it for ABR Handling + return time * indexOptions.timescale + ((_a = indexOptions.indexTimeOffset) !== null && _a !== void 0 ? _a : 0); +} +/** + * Convert from `mediaTime`, the original time the segments point at to + * `presentationTime`, the time of the segment at the moment it is decoded. + * @param {number} time + * @param {Object} indexOptions + * @returns {number} + */ - var segment = value.segment; +function fromIndexTime(time, indexOptions) { + var _a; - if (segment === undefined) { - return; - } + return (time - ((_a = indexOptions.indexTimeOffset) !== null && _a !== void 0 ? _a : 0)) / indexOptions.timescale; +} +/** + * @param {Number} start + * @param {Number} duration + * @param {Number} timescale + * @returns {Object} - Object with two properties: + * - up {Number}: timescaled timestamp of the beginning time + * - to {Number}: timescaled timestamp of the end time (start time + duration) + */ - requestBeginSent = true; - requests$.next({ - type: "requestBegin", - value: { - duration: segment.duration, - time: segment.time, - requestTimestamp: performance.now(), - id: id - } - }); - break; - } - - case "progress": - { - var _value = arg.value; +function getTimescaledRange(start, duration, timescale) { + return [start * timescale, (start + duration) * timescale]; +} +/** + * Get index of the last segment in the timeline starting before/at the given + * timescaled time. + * Returns -1 if the given time is lower than the start of the first available + * segment. + * @param {Object} index + * @param {Number} timeTScaled + * @returns {Number} + */ - if (_value.totalSize != null && _value.size < _value.totalSize) { - requests$.next({ - type: "progress", - value: { - duration: _value.duration, - size: _value.size, - totalSize: _value.totalSize, - timestamp: performance.now(), - id: id - } - }); - } +function getIndexOfLastObjectBefore(timeline, timeTScaled) { + var low = 0; + var high = timeline.length; - break; - } - } - }), finalize(function () { - if (requestBeginSent) { - requests$.next({ - type: "requestEnd", - value: { - id: id - } - }); - } - }), (0,filter/* filter */.h)(function (e) { - switch (e.type) { - case "warning": - case "chunk": - case "chunk-complete": - case "data": - return true; + while (low < high) { + var mid = low + high >>> 1; // Divide by two + floor - case "progress": - case "metrics": - case "request": - return false; + if (timeline[mid].start <= timeTScaled) { + low = mid + 1; + } else { + high = mid; + } + } - default: - (0,assert_unreachable/* default */.Z)(e); - } - }), (0,mergeMap/* mergeMap */.zg)(function (evt) { - if (evt.type === "warning") { - return (0,of.of)(evt); - } + return low - 1; +} +/** + * @param {Object} index + * @param {number} timeSec + * @param {number} [maxPosition] + * @returns {number|null} + */ - if (evt.type === "chunk-complete") { - return (0,of.of)({ - type: "chunk-complete" - }); - } - var isChunked = evt.type === "chunk"; - var data = { - type: "chunk", +function checkDiscontinuity(index, timeSec, maxPosition) { + var timeline = index.timeline; + var scaledTime = toIndexTime(timeSec, index); - /** - * Parse the loaded data. - * @param {Object} [initTimescale] - * @returns {Observable} - */ - parse: function parse(initTimescale) { - var response = { - data: evt.value.responseData, - isChunked: isChunked - }; - /* eslint-disable @typescript-eslint/no-unsafe-call */ + if (scaledTime < 0) { + return null; + } - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ + var segmentIndex = getIndexOfLastObjectBefore(timeline, scaledTime); - /* eslint-disable @typescript-eslint/no-unsafe-return */ + if (segmentIndex < 0 || segmentIndex >= timeline.length - 1) { + return null; + } - return segmentParser({ - response: response, - initTimescale: initTimescale, - content: content - }) - /* eslint-enable @typescript-eslint/no-unsafe-call */ + var timelineItem = timeline[segmentIndex]; - /* eslint-enable @typescript-eslint/no-unsafe-member-access */ + if (timelineItem.duration <= 0) { + return null; + } - /* eslint-enable @typescript-eslint/no-unsafe-return */ - .pipe((0,catchError/* catchError */.K)(function (error) { - throw formatError(error, { - defaultCode: "PIPELINE_PARSE_ERROR", - defaultReason: "Unknown parsing error" - }); - })); - } - }; + var nextTimelineItem = timeline[segmentIndex + 1]; - if (isChunked) { - return (0,of.of)(data); - } + if (nextTimelineItem === undefined) { + return null; + } - return (0,concat/* concat */.z)((0,of.of)(data), (0,of.of)({ - type: "chunk-complete" - })); - }), (0,share/* share */.B)() // avoid multiple side effects if multiple subs - ); - }; + var nextStart = nextTimelineItem.start; + var segmentEnd = getIndexSegmentEnd(timelineItem, nextTimelineItem, maxPosition); + return scaledTime >= segmentEnd && scaledTime < nextStart ? fromIndexTime(nextStart, index) : null; } -;// CONCATENATED MODULE: ./src/core/fetchers/segment/segment_fetcher_creator.ts + +/***/ }), + +/***/ 1091: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ isSegmentStillAvailable) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -16798,79 +16484,59 @@ function segment_fetcher_createSegmentFetcher(bufferType, transport, requests$, * limitations under the License. */ - - - - -var MIN_CANCELABLE_PRIORITY = config/* default.MIN_CANCELABLE_PRIORITY */.Z.MIN_CANCELABLE_PRIORITY, - MAX_HIGH_PRIORITY_LEVEL = config/* default.MAX_HIGH_PRIORITY_LEVEL */.Z.MAX_HIGH_PRIORITY_LEVEL; /** - * Interact with the transport pipelines to download segments with the right - * priority. - * - * @class SegmentFetcherCreator - * - * @example - * ```js - * const creator = new SegmentFetcherCreator(transport); - * - * // 2 - create a new fetcher with its backoff options - * const fetcher = creator.createSegmentFetcher("audio", { - * maxRetryRegular: Infinity, - * maxRetryOffline: Infinity, - * }); - * - * // 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)); - * ``` + * Returns true if a Segment returned by the corresponding index is still + * considered available. + * Returns false if it is not available anymore. + * Returns undefined if we cannot know whether it is still available or not. + * /!\ We do not check the mediaURLs of the segment. + * @param {Object} segment + * @param {Array.} timescale + * @param {number} timeline + * @returns {Boolean|undefined} */ +function isSegmentStillAvailable(segment, timeline, timescale, indexTimeOffset) { + for (var i = 0; i < timeline.length; i++) { + var tSegment = timeline[i]; + var tSegmentTime = (tSegment.start - indexTimeOffset) / timescale; -var SegmentFetcherCreator = /*#__PURE__*/function () { - /** - * @param {Object} transport - */ - function SegmentFetcherCreator(transport, options) { - this._transport = transport; - this._prioritizer = new ObservablePrioritizer({ - prioritySteps: { - high: MAX_HIGH_PRIORITY_LEVEL, - low: MIN_CANCELABLE_PRIORITY + if (tSegmentTime > segment.time) { + return false; + } else if (tSegmentTime === segment.time) { + if (tSegment.duration / timescale !== segment.duration) { + return false; } - }); - this._backoffOptions = options; - } - /** - * Create a segment fetcher, allowing to easily perform segment requests. - * @param {string} bufferType - The type of buffer concerned (e.g. "audio", - * "video", etc.) - * @param {Subject} requests$ - Subject through which request-related events - * (such as those needed by the ABRManager) will be sent. - * @returns {Object} - */ + if (tSegment.range == null) { + return segment.range == null; + } - var _proto = SegmentFetcherCreator.prototype; - - _proto.createSegmentFetcher = function createSegmentFetcher(bufferType, requests$) { - var backoffOptions = getSegmentBackoffOptions(bufferType, this._backoffOptions); - - var segmentFetcher = segment_fetcher_createSegmentFetcher(bufferType, this._transport, requests$, backoffOptions); + return segment.range != null && tSegment.range[0] === segment.range[0] && tSegment.range[1] === segment.range[1]; + } else { + // tSegment.start < segment.time + if (tSegment.repeatCount >= 0 && tSegment.duration != null) { + var timeDiff = tSegmentTime - tSegment.start; + var repeat = timeDiff / tSegment.duration - 1; + return repeat % 1 === 0 && repeat <= tSegment.repeatCount; + } + } + } - return applyPrioritizerToSegmentFetcher(this._prioritizer, segmentFetcher); - }; + return false; +} - return SegmentFetcherCreator; -}(); +/***/ }), +/***/ 5505: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -;// CONCATENATED MODULE: ./src/core/fetchers/segment/index.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ updateSegmentTimeline) +/* harmony export */ }); +/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3714); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3887); +/* harmony import */ var _index_helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3911); /** * Copyright 2015 CANAL+ Group * @@ -16887,151 +16553,132 @@ var SegmentFetcherCreator = /*#__PURE__*/function () { * limitations under the License. */ -/* harmony default export */ const segment = (SegmentFetcherCreator); -// EXTERNAL MODULE: ./src/core/init/create_eme_manager.ts + 1 modules -var create_eme_manager = __webpack_require__(4507); -// 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. + * Update a complete array of segments in a given timeline with a [generally] + * smaller but [generally] newer set of segments. + * @param {Array.} oldTimeline + * @param {Array.} newTimeline */ +function updateSegmentTimeline(oldTimeline, newTimeline) { + var prevTimelineLength = oldTimeline.length; + if (oldTimeline.length === 0) { + oldTimeline.splice.apply(oldTimeline, [0, prevTimelineLength].concat(newTimeline)); + return; + } + if (newTimeline.length === 0) { + return; + } + var newIndexStart = newTimeline[0].start; + var oldLastElt = oldTimeline[prevTimelineLength - 1]; + var oldIndexEnd = (0,_index_helpers__WEBPACK_IMPORTED_MODULE_0__/* .getIndexSegmentEnd */ .jH)(oldLastElt, newTimeline[0]); + if (oldIndexEnd < newIndexStart) { + throw new _errors__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z("MANIFEST_UPDATE_ERROR", "Cannot perform partial update: not enough data"); + } -var onSourceOpen$ = event_listeners/* onSourceOpen$ */.ym; -/** - * Set the media duration in the mediaSource. - * @param {MediaSource} mediaSource - * @param {number} duration - */ + for (var i = prevTimelineLength - 1; i >= 0; i--) { + var currStart = oldTimeline[i].start; -function setDurationToMediaSource(mediaSource, duration) { - var newDuration = duration === Infinity ? Number.MAX_VALUE : duration; + if (currStart === newIndexStart) { + // replace that one and those after it + oldTimeline.splice.apply(oldTimeline, [i, prevTimelineLength - i].concat(newTimeline)); + return; + } else if (currStart < newIndexStart) { + // first to be before + var currElt = oldTimeline[i]; - if (mediaSource.duration !== newDuration) { - log/* default.info */.Z.info("Init: Setting duration", newDuration); - mediaSource.duration = newDuration; - } -} -/** - * 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 - */ + if (currElt.start + currElt.duration > newIndexStart) { + // the new Manifest overlaps a previous segment (weird). Remove the latter. + _log__WEBPACK_IMPORTED_MODULE_2__/* .default.warn */ .Z.warn("RepresentationIndex: Manifest update removed previous segments"); + oldTimeline.splice.apply(oldTimeline, [i, prevTimelineLength - i].concat(newTimeline)); + return; + } else if (currElt.repeatCount === undefined || currElt.repeatCount <= 0) { + if (currElt.repeatCount < 0) { + currElt.repeatCount = Math.floor((newIndexStart - currElt.start) / currElt.duration) - 1; + } -function resetMediaSource(mediaElement, mediaSource, mediaSourceURL) { - if (mediaSource !== null && mediaSource.readyState !== "closed") { - var readyState = mediaSource.readyState, - sourceBuffers = mediaSource.sourceBuffers; + oldTimeline.splice.apply(oldTimeline, [i + 1, prevTimelineLength - (i + 1)].concat(newTimeline)); + return; + } // else, there is a positive repeat we might want to update - 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); - sourceBuffer.abort(); - } + var eltLastTime = currElt.start + currElt.duration * (currElt.repeatCount + 1); - mediaSource.removeSourceBuffer(sourceBuffer); - } catch (e) { - log/* default.warn */.Z.warn("Init: Error while disposing SourceBuffer", e); + if (eltLastTime <= newIndexStart) { + // our new index comes directly after + // put it after this one + oldTimeline.splice.apply(oldTimeline, [i + 1, prevTimelineLength - (i + 1)].concat(newTimeline)); + return; } - } - if (sourceBuffers.length > 0) { - log/* default.warn */.Z.warn("Init: Not all SourceBuffers could have been removed."); + var newCurrRepeat = (newIndexStart - currElt.start) / currElt.duration - 1; + + if (newCurrRepeat % 1 === 0 && currElt.duration === newTimeline[0].duration) { + var newRepeatCount = newTimeline[0].repeatCount < 0 ? -1 : // === maximum possible repeat + newTimeline[0].repeatCount + newCurrRepeat + 1; // replace that one and those after it + + oldTimeline.splice.apply(oldTimeline, [i, prevTimelineLength - i].concat(newTimeline)); + oldTimeline[i].start = currElt.start; + oldTimeline[i].repeatCount = newRepeatCount; + return; + } + + _log__WEBPACK_IMPORTED_MODULE_2__/* .default.warn */ .Z.warn("RepresentationIndex: Manifest update removed previous segments"); + oldTimeline[i].repeatCount = Math.floor(newCurrRepeat); // put it after this one + + oldTimeline.splice.apply(oldTimeline, [i + 1, prevTimelineLength - (i + 1)].concat(newTimeline)); + return; } - } + } // if we got here, it means that every segments in the previous manifest are + // after the new one. This is unusual. + // Either the new one has more depth or it's an older one. - (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); + var prevLastElt = oldTimeline[oldTimeline.length - 1]; + var newLastElt = newTimeline[newTimeline.length - 1]; + + if (prevLastElt.repeatCount !== undefined && prevLastElt.repeatCount < 0) { + if (prevLastElt.start > newLastElt.start) { + _log__WEBPACK_IMPORTED_MODULE_2__/* .default.warn */ .Z.warn("RepresentationIndex: The new index is older than the previous one"); + return; // the old comes after + } else { + // the new has more depth + _log__WEBPACK_IMPORTED_MODULE_2__/* .default.warn */ .Z.warn("RepresentationIndex: The new index is \"bigger\" than the previous one"); + oldTimeline.splice.apply(oldTimeline, [0, prevTimelineLength].concat(newTimeline)); + return; } } -} -/** - * 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} - */ + var prevLastTime = prevLastElt.start + prevLastElt.duration * (prevLastElt.repeatCount + 1); + var newLastTime = newLastElt.start + newLastElt.duration * (newLastElt.repeatCount + 1); -function createMediaSource(mediaElement) { - return new Observable/* Observable */.y(function (observer) { - if (browser_compatibility_types/* MediaSource_ */.JJ == 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 + if (prevLastTime >= newLastTime) { + _log__WEBPACK_IMPORTED_MODULE_2__/* .default.warn */ .Z.warn("RepresentationIndex: The new index is older than the previous one"); + return; // the old comes after + } // the new one has more depth. full update - 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_ */.JJ(); - 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); - }; - }); + _log__WEBPACK_IMPORTED_MODULE_2__/* .default.warn */ .Z.warn("RepresentationIndex: The new index is \"bigger\" than the previous one"); + oldTimeline.splice.apply(oldTimeline, [0, prevTimelineLength].concat(newTimeline)); + return; } -/** - * 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 */.zg)(function (mediaSource) { - return onSourceOpen$(mediaSource).pipe((0,take/* take */.q)(1), (0,mapTo/* mapTo */.h)(mediaSource)); - })); -} -// EXTERNAL MODULE: ./src/core/init/events_generators.ts -var events_generators = __webpack_require__(8343); -;// CONCATENATED MODULE: ./src/core/init/get_initial_time.ts +/***/ 5734: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6923); /** * Copyright 2015 CANAL+ Group * @@ -17047,98 +16694,231 @@ var events_generators = __webpack_require__(8343); * See the License for the specific language governing permissions and * limitations under the License. */ +// __VERY__ simple SAMI parser, based on ugly-but-working REGEXP: +// - the text, start and end times are correctly parsed. +// - only text for the given language is parsed. +// - only the CSS style associated to the P element is set. +// - we should be safe for any XSS. +// The language indicated to the parser should be present in the CSS and the +// corresponding Class should be on the P elements. If we fail to find the +// language in a "lang" property of a CSS class, the parser will throw. +/** + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. + */ -var DEFAULT_LIVE_GAP = config/* default.DEFAULT_LIVE_GAP */.Z.DEFAULT_LIVE_GAP; +var HTML_ENTITIES = /&#([0-9]+);/g; +var BR = /
/gi; +var STYLE = /]*>([\s\S]*?)<\/style[^>]*>/i; +var PARAG = /\s*

]+))?>(.*)/i; +var START = /]+?start="?([0-9]*)"?[^0-9]/i; /** - * 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} + * Returns classnames for every languages. + * @param {string} str + * @returns {Object} */ -function getInitialTime(manifest, lowLatencyMode, startAt) { - log/* default.debug */.Z.debug("Init: calculating initial time"); +function getClassNameByLang(str) { + var ruleRe = /\.(\S+)\s*{([^}]*)}/gi; + var langs = {}; + var m = ruleRe.exec(str); - if (startAt != null) { - var min = manifest.getMinimumPosition(); - var max = manifest.getMaximumPosition(); + while (m !== null) { + var name = m[1]; + var lang = getCSSProperty(m[2], "lang"); - if (startAt.position != null) { - log/* default.debug */.Z.debug("Init: using startAt.minimumPosition"); - return Math.max(Math.min(startAt.position, max), min); - } else if (startAt.wallClockTime != null) { - log/* default.debug */.Z.debug("Init: using startAt.wallClockTime"); - var ast = manifest.availabilityStartTime == null ? 0 : manifest.availabilityStartTime; - var position = startAt.wallClockTime - ast; - return Math.max(Math.min(position, max), min); - } else if (startAt.fromFirstPosition != null) { - log/* default.debug */.Z.debug("Init: using startAt.fromFirstPosition"); - var fromFirstPosition = startAt.fromFirstPosition; - return fromFirstPosition <= 0 ? min : Math.min(max, min + fromFirstPosition); - } else if (startAt.fromLastPosition != null) { - log/* default.debug */.Z.debug("Init: using startAt.fromLastPosition"); - var fromLastPosition = startAt.fromLastPosition; - return fromLastPosition >= 0 ? max : Math.max(min, max + fromLastPosition); - } else if (startAt.percentage != null) { - log/* default.debug */.Z.debug("Init: using startAt.percentage"); - var percentage = startAt.percentage; + if (name != null && lang != null) { + langs[lang] = name; + } - if (percentage > 100) { - return max; - } else if (percentage < 0) { - return min; - } + m = ruleRe.exec(str); + } - var ratio = +percentage / 100; - var extent = max - min; - return min + extent * ratio; + return langs; +} +/** + * Returns the rules defined for the P element. + * Empty string if not found. + * @param {string} str - The entire styling part. + * @returns {string} + */ + + +function getPCSSRules(str) { + var pRuleRegex = /p\s*{([^}]*)}/gi; + var rule = pRuleRegex.exec(str); + + if (rule === null) { + return ""; + } + + return rule[1]; +} +/** + * @param {string} str - entire CSS rule + * @param {string} name - name of the property + * @returns {string|null} - value of the property. Null if not found. + */ + + +function getCSSProperty(str, name) { + var matches = new RegExp("\\s*" + name + ":\\s*(\\S+);", "i").exec(str); + return Array.isArray(matches) ? matches[1] : null; +} +/** + * @param {string} text + * @returns {string} + */ + + +function decodeEntities(text) { + return text.replace(HTML_ENTITIES, function (_, $1) { + return String.fromCharCode($1); + }); +} +/** + * Because sami is not really html... we have to use + * some kind of regular expressions to parse it... + * the cthulhu way :) + * The specification being quite clunky, this parser + * may not work for every sami input. + * + * @param {string} smi + * @param {Number} timeOffset + * @param {string} lang + */ + + +function parseSami(smi, timeOffset, lang) { + var syncOpen = /]/ig; + var syncClose = /]|<\/body>/ig; + var subs = []; + var styleMatches = STYLE.exec(smi); + var css = Array.isArray(styleMatches) ? styleMatches[1] : ""; + var up; + var to; // FIXME Is that wanted? + // previously written as let to = SyncClose.exec(smi); but never used + + syncClose.exec(smi); + var langs = getClassNameByLang(css); + var pCSS = getPCSSRules(css); + var klass; + + if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(lang)) { + klass = langs[lang]; + + if (klass === undefined) { + throw new Error("sami: could not find lang " + lang + " in CSS"); } } - var minimumPosition = manifest.getMinimumPosition(); + while (true) { + up = syncOpen.exec(smi); + to = syncClose.exec(smi); - if (manifest.isLive) { - var suggestedPresentationDelay = manifest.suggestedPresentationDelay, - clockOffset = manifest.clockOffset; - var maximumPosition = manifest.getMaximumPosition(); - var liveTime; + if (up === null && to === null) { + break; + } - if (clockOffset == null) { - 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"); + if (up === null || to === null || up.index >= to.index) { + throw new Error("parse error"); + } - var _ast = manifest.availabilityStartTime == null ? 0 : manifest.availabilityStartTime; + var str = smi.slice(up.index, to.index); + var tim = START.exec(str); - var clockRelativeLiveTime = (performance.now() + clockOffset) / 1000 - _ast; + if (!Array.isArray(tim)) { + throw new Error("parse error (sync time attribute)"); + } - liveTime = Math.min(maximumPosition, clockRelativeLiveTime); + var start = +tim[1]; + + if (isNaN(start)) { + throw new Error("parse error (sync time attribute NaN)"); } - 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); + appendToSubs(str.split("\n"), start / 1000); } - log/* default.info */.Z.info("Init: starting at the minimum available position:", minimumPosition); - return minimumPosition; + return subs; + + function appendToSubs(lines, start) { + var i = lines.length; + + while (--i >= 0) { + var paragraphInfos = PARAG.exec(lines[i]); + + if (!Array.isArray(paragraphInfos)) { + continue; + } + + var className = paragraphInfos[1], + txt = paragraphInfos[2]; + + if (klass !== className) { + continue; + } + + if (txt === " ") { + subs[subs.length - 1].end = start; + } else { + var wrapperEl = document.createElement("DIV"); + wrapperEl.className = "rxp-texttrack-region"; + var divEl = document.createElement("DIV"); + divEl.className = "rxp-texttrack-div"; + divEl.style.position = "absolute"; + divEl.style.bottom = "0"; + divEl.style.width = "100%"; + divEl.style.color = "#fff"; + divEl.style.textShadow = "-1px -1px 0 #000," + "1px -1px 0 #000," + "-1px 1px 0 #000," + "1px 1px 0 #000"; + var pEl = document.createElement("div"); + pEl.className = "rxp-texttrack-p"; + + if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(pCSS)) { + pEl.style.cssText = pCSS; + } + + var textEls = txt.split(BR); + + for (var j = 0; j < textEls.length; j++) { + if (j !== 0) { + pEl.appendChild(document.createElement("BR")); + } + + var spanEl = document.createElement("SPAN"); + spanEl.className = "rxp-texttrack-span"; + spanEl.textContent = decodeEntities(textEls[j]); + pEl.appendChild(spanEl); + } + + divEl.appendChild(pEl); + wrapperEl.appendChild(divEl); + subs.push({ + element: wrapperEl, + start: start + timeOffset, + end: -1 + /* Will be updated on a following iteration */ + + }); + } + } + } } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/throwError.js -var throwError = __webpack_require__(4944); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/interval.js -var observable_interval = __webpack_require__(6564); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/fromEvent.js -var fromEvent = __webpack_require__(7027); -;// CONCATENATED MODULE: ./src/compat/change_source_buffer_type.ts + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (parseSami); + +/***/ }), + +/***/ 1812: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _compat__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7253); +/* harmony import */ var _utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6923); /** * Copyright 2015 CANAL+ Group * @@ -17156,37 +16936,205 @@ var fromEvent = __webpack_require__(7027); */ /** - * If the changeType MSE API is implemented, update the current codec of the - * SourceBuffer and return true if it succeeded. - * In any other cases, return false. - * @param {Object} sourceBuffer - * @param {string} codec - * @returns {boolean} + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. */ -function tryToChangeSourceBufferType(sourceBuffer, codec) { - if (typeof sourceBuffer.changeType === "function") { - try { - sourceBuffer.changeType(codec); - } catch (e) { - log/* default.warn */.Z.warn("Could not call 'changeType' on the given SourceBuffer:", e); - return false; + +var HTML_ENTITIES = /&#([0-9]+);/g; +var BR = /
/gi; +var STYLE = /]*>([\s\S]*?)<\/style[^>]*>/i; +var PARAG = /\s*

]+))?>(.*)/i; +var START = /]+?start="?([0-9]*)"?[^0-9]/i; +/** + * Creates an array of VTTCue/TextTrackCue from a given array of cue objects. + * @param {Array.} cuesArray - Objects containing the start, end and + * text. + * @returns {Array.} + */ + +function createCuesFromArray(cuesArray) { + var nativeCues = []; + + for (var i = 0; i < cuesArray.length; i++) { + var _cuesArray$i = cuesArray[i], + start = _cuesArray$i.start, + end = _cuesArray$i.end, + text = _cuesArray$i.text; + + if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(text) && end != null) { + var cue = (0,_compat__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(start, end, text); + + if (cue != null) { + nativeCues.push(cue); + } } + } - return true; + return nativeCues; +} +/** + * Returns classnames for every languages. + * @param {string} str + * @returns {Object} + */ + + +function getClassNameByLang(str) { + var ruleRe = /\.(\S+)\s*{([^}]*)}/gi; + var langs = {}; + var m = ruleRe.exec(str); + + while (Array.isArray(m)) { + var name = m[1]; + var lang = getCSSProperty(m[2], "lang"); + + if (name != null && lang != null) { + langs[lang] = name; + } + + m = ruleRe.exec(str); } - return false; + return langs; } -// EXTERNAL MODULE: ./src/utils/byte_parsing.ts -var byte_parsing = __webpack_require__(6968); -// EXTERNAL MODULE: ./src/utils/hash_buffer.ts -var hash_buffer = __webpack_require__(2870); -// EXTERNAL MODULE: ./src/core/segment_buffers/implementations/types.ts + 1 modules -var types = __webpack_require__(4123); -;// CONCATENATED MODULE: ./src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +/** + * @param {string} str - entire CSS rule + * @param {string} name - name of the property + * @returns {string|null} - value of the property. Null if not found. + */ + + +function getCSSProperty(str, name) { + var matches = new RegExp("\\s*" + name + ":\\s*(\\S+);", "i").exec(str); + return Array.isArray(matches) ? matches[1] : null; +} +/** + * Decode HMTL formatting into a string. + * @param {string} text + * @returns {string} + */ + + +function decodeEntities(text) { + return text.replace(BR, "\n").replace(HTML_ENTITIES, function (_, $1) { + return String.fromCharCode($1); + }); +} +/** + * Because sami is not really html... we have to use + * some kind of regular expressions to parse it... + * the cthulhu way :) + * The specification being quite clunky, this parser + * may not work for every sami input. + * + * @param {string} smi + * @param {Number} timeOffset + * @param {string} lang + * @returns {Array.} + */ + + +function parseSami(smi, timeOffset, lang) { + var syncOpen = /]/ig; + var syncClose = /]|<\/body>/ig; + var subs = []; + var styleMatches = STYLE.exec(smi); + var css = styleMatches !== null ? styleMatches[1] : ""; + var up; + var to; // FIXME Is that wanted? + // previously written as let to = SyncClose.exec(smi); but never used + + syncClose.exec(smi); + var langs = getClassNameByLang(css); + var klass; + + if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(lang)) { + klass = langs[lang]; + + if (klass === undefined) { + throw new Error("sami: could not find lang " + lang + " in CSS"); + } + } + + while (true) { + up = syncOpen.exec(smi); + to = syncClose.exec(smi); + + if (up === null && to === null) { + break; + } + + if (up === null || to === null || up.index >= to.index) { + throw new Error("parse error"); + } + + var str = smi.slice(up.index, to.index); + var tim = START.exec(str); + + if (tim === null) { + throw new Error("parse error (sync time attribute)"); + } + + var start = +tim[1]; + + if (isNaN(start)) { + throw new Error("parse error (sync time attribute NaN)"); + } + + appendToSubs(str.split("\n"), start / 1000); + } + + return createCuesFromArray(subs); + + function appendToSubs(lines, start) { + var i = lines.length; + var m; + + while (--i >= 0) { + m = PARAG.exec(lines[i]); + + if (m === null) { + continue; + } + + var _m = m, + kl = _m[1], + txt = _m[2]; + + if (klass !== kl) { + continue; + } + + if (txt === " ") { + subs[subs.length - 1].end = start; + } else { + subs.push({ + text: decodeEntities(txt), + start: start + timeOffset + }); + } + } + } +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (parseSami); + +/***/ }), + +/***/ 2061: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ getCueBlocks) +}); +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +;// CONCATENATED MODULE: ./src/parsers/texttracks/srt/find_end_of_cue_block.ts /** * Copyright 2015 CANAL+ Group * @@ -17203,511 +17151,358 @@ var types = __webpack_require__(4123); * limitations under the License. */ +/** + * Returns the first line that is not apart of the given cue block. + * The index given can be anywhere in a known cue block. + * + * This function is extra-resilient due to observed real-life malformed + * subtitles. + * Basically, it allows some deviation from the specification as long as the + * intent is pretty clear. + * @param {Array} linified - Whole srt. Line by line. + * @param {number} startIndex - Index in `linified` of the first line within the + * block. + * @returns {number} + */ +function findEndOfCueBlock(linified, startIndex) { + var firstEmptyLineIndex = startIndex + 1; // continue incrementing i until either: + // - an empty line + // - the end + while ((0,is_non_empty_string/* default */.Z)(linified[firstEmptyLineIndex])) { + firstEmptyLineIndex++; + } - - - - - - - -var SOURCE_BUFFER_FLUSHING_INTERVAL = config/* default.SOURCE_BUFFER_FLUSHING_INTERVAL */.Z.SOURCE_BUFFER_FLUSHING_INTERVAL; + return firstEmptyLineIndex; +} +;// CONCATENATED MODULE: ./src/parsers/texttracks/srt/get_cue_blocks.ts /** - * 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 - * been pushed and what is being pushed. + * Copyright 2015 CANAL+ Group * - * To work correctly, only a single AudioVideoSegmentBuffer per SourceBuffer - * should be created. + * 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 * - * @class AudioVideoSegmentBuffer + * 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 AudioVideoSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) { - inheritsLoose_default()(AudioVideoSegmentBuffer, _SegmentBuffer); - /** - * @constructor - * @param {string} bufferType - * @param {string} codec - * @param {SourceBuffer} sourceBuffer - */ - function AudioVideoSegmentBuffer(bufferType, codec, mediaSource) { - var _this; +/** + * Get cue blocks from a srt file. + * @param {Array.} linified - Whole srt file. Each new element in this + * array is a new line. + * @returns {Array.>} + */ - _this = _SegmentBuffer.call(this) || this; - var sourceBuffer = mediaSource.addSourceBuffer(codec); - _this._destroy$ = new Subject/* Subject */.xQ(); - _this.bufferType = bufferType; - _this._mediaSource = mediaSource; - _this._sourceBuffer = sourceBuffer; - _this._queue = []; - _this._pendingTask = null; - _this._lastInitSegment = null; - _this.codec = codec; // Some browsers (happened with firefox 66) sometimes "forget" to send us - // `update` or `updateend` events. - // In that case, we're completely unable to continue the queue here and - // stay locked in a waiting state. - // This interval is here to check at regular intervals if the underlying - // SourceBuffer is currently updating. - - (0,observable_interval/* interval */.F)(SOURCE_BUFFER_FLUSHING_INTERVAL).pipe((0,tap/* tap */.b)(function () { - return _this._flush(); - }), (0,takeUntil/* takeUntil */.R)(_this._destroy$)).subscribe(); - (0,fromEvent/* fromEvent */.R)(_this._sourceBuffer, "error").pipe((0,tap/* tap */.b)(function (err) { - return _this._onPendingTaskError(err); - }), (0,takeUntil/* takeUntil */.R)(_this._destroy$)).subscribe(); - (0,fromEvent/* fromEvent */.R)(_this._sourceBuffer, "updateend").pipe((0,tap/* tap */.b)(function () { - return _this._flush(); - }), (0,takeUntil/* takeUntil */.R)(_this._destroy$)).subscribe(); - return _this; - } - /** - * Push a chunk of the media segment given to the attached SourceBuffer, in a - * FIFO queue. - * - * Once all chunks of a single Segment have been given to `pushChunk`, you - * should call `endOfSegment` to indicate that the whole Segment has been - * pushed. - * - * Depending on the type of data appended, the pushed chunk might rely on an - * initialization segment, given through the `data.initSegment` property. - * - * Such initialization segment will be first pushed to the SourceBuffer if the - * last pushed segment was associated to another initialization segment. - * This detection rely on the initialization segment's reference so you need - * to avoid mutating in-place a initialization segment given to that function - * (to avoid having two different values which have the same reference). - * - * If you don't need any initialization segment to push the wanted chunk, you - * can just set `data.initSegment` to `null`. - * - * You can also only push an initialization segment by setting the - * `data.chunk` argument to null. - * - * @param {Object} infos - * @returns {Observable} - */ - - - var _proto = AudioVideoSegmentBuffer.prototype; +function getCueBlocks(linified) { + var cueBlocks = []; - _proto.pushChunk = function pushChunk(infos) { - log/* default.debug */.Z.debug("AVSB: receiving order to push data to the SourceBuffer", this.bufferType, infos); - return this._addToQueue({ - type: types/* SegmentBufferOperation.Push */.f.Push, - value: infos - }); - } - /** - * Remove buffered data (added to the same FIFO queue than `pushChunk`). - * @param {number} start - start position, in seconds - * @param {number} end - end position, in seconds - * @returns {Observable} - */ - ; + for (var i = 0; i < linified.length; i++) { + if ((0,is_non_empty_string/* default */.Z)(linified[i])) { + var endOfCue = findEndOfCueBlock(linified, i); + var cueBlockCandidate = linified.slice(i, endOfCue); - _proto.removeBuffer = function removeBuffer(start, end) { - log/* default.debug */.Z.debug("AVSB: receiving order to remove data from the SourceBuffer", this.bufferType, start, end); - return this._addToQueue({ - type: types/* SegmentBufferOperation.Remove */.f.Remove, - value: { - start: start, - end: end + if (cueBlockCandidate.length > 0) { + if (cueBlockCandidate.length === 1) { + if (cueBlockCandidate[0].indexOf("-->") >= 0) { + cueBlocks.push(cueBlockCandidate); + } + } else { + if (cueBlockCandidate[1].indexOf("-->") >= 0 || cueBlockCandidate[0].indexOf("-->") >= 0) { + cueBlocks.push(cueBlockCandidate); + } + } } - }); - } - /** - * Indicate that every chunks from a Segment has been given to pushChunk so - * far. - * This will update our internal Segment inventory accordingly. - * The returned Observable will emit and complete successively once the whole - * segment has been pushed and this indication is acknowledged. - * @param {Object} infos - * @returns {Observable} - */ - ; - - _proto.endOfSegment = function endOfSegment(infos) { - log/* default.debug */.Z.debug("AVSB: receiving order for validating end of segment", this.bufferType, infos.segment); - return this._addToQueue({ - type: types/* SegmentBufferOperation.EndOfSegment */.f.EndOfSegment, - value: infos - }); - } - /** - * Returns the currently buffered data, in a TimeRanges object. - * @returns {TimeRanges} - */ - ; - _proto.getBufferedRanges = function getBufferedRanges() { - return this._sourceBuffer.buffered; + i = endOfCue; + } } - /** - * Returns the list of every operations that the `AudioVideoSegmentBuffer` is - * still processing. From the one with the highest priority (like the one - * being processed) - * @returns {Array.} - */ - ; - - _proto.getPendingOperations = function getPendingOperations() { - var parseQueuedOperation = function parseQueuedOperation(op) { - // Had to be written that way for TypeScrypt - switch (op.type) { - case types/* SegmentBufferOperation.Push */.f.Push: - return { - type: op.type, - value: op.value - }; - case types/* SegmentBufferOperation.Remove */.f.Remove: - return { - type: op.type, - value: op.value - }; + return cueBlocks; +} - case types/* SegmentBufferOperation.EndOfSegment */.f.EndOfSegment: - return { - type: op.type, - value: op.value - }; - } - }; +/***/ }), - var queued = this._queue.map(parseQueuedOperation); +/***/ 8675: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - return this._pendingTask === null ? queued : [parseQueuedOperation(this._pendingTask)].concat(queued); - } - /** - * Dispose of the resources used by this AudioVideoSegmentBuffer. - * - * /!\ You won't be able to use the AudioVideoSegmentBuffer after calling this - * function. - * @private - */ - ; +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ parseSRTStringToHTML) +/* harmony export */ }); +/* harmony import */ var _get_cue_blocks__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2061); +/* harmony import */ var _parse_cue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(788); +/** + * 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. + */ - _proto.dispose = function dispose() { - this._destroy$.next(); +/** + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. + */ +// Parse SRT subtitles into HTML. +// Done for fun. Understand , , and type +// of tags. - this._destroy$.complete(); - if (this._pendingTask !== null) { - this._pendingTask.subject.complete(); +/** + * @param {string} srtStr + * @param {Number} timeOffset + * @returns {Array.} + */ - this._pendingTask = null; - } +function parseSRTStringToHTML(srtStr, timeOffset) { + // Even if srt only authorize CRLF, we will also take LF or CR as line + // terminators for resilience + var lines = srtStr.split(/\r\n|\n|\r/); + var cueBlocks = (0,_get_cue_blocks__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(lines); + var cues = []; - while (this._queue.length > 0) { - var nextElement = this._queue.shift(); + for (var i = 0; i < cueBlocks.length; i++) { + var cueObject = (0,_parse_cue__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(cueBlocks[i], timeOffset); - if (nextElement !== undefined) { - nextElement.subject.complete(); - } - } + if (cueObject != null) { + var htmlCue = toHTML(cueObject); - if (this._mediaSource.readyState === "open") { - try { - this._sourceBuffer.abort(); - } catch (e) { - log/* default.warn */.Z.warn("AVSB: Failed to abort a " + this.bufferType + " SourceBuffer:", e); + if (htmlCue != null) { + cues.push(htmlCue); } } } - /** - * Called when an error arised that made the current task fail. - * @param {Event} error - */ - ; - _proto._onPendingTaskError = function _onPendingTaskError(err) { - this._lastInitSegment = null; // initialize init segment as a security + return cues; +} +/** + * @param {Array.} cueLines + * @param {Number} timeOffset + * @returns {Object|null} + */ - if (this._pendingTask !== null) { - var error = err instanceof Error ? err : new Error("An unknown error occured when doing operations " + "on the SourceBuffer"); +function toHTML(cueObj) { + var start = cueObj.start, + end = cueObj.end, + payload = cueObj.payload; + var pEl = document.createElement("div"); + pEl.className = "rxp-texttrack-p"; + pEl.style.fontSize = "28px"; + pEl.style.position = "absolute"; + pEl.style.bottom = "5%"; + pEl.style.width = "100%"; + pEl.style.textAlign = "center"; + pEl.style.color = "#fff"; + pEl.style.textShadow = "-1px -1px 2px #000," + "1px -1px 2px #000," + "-1px 1px 2px #000," + "1px 1px 2px #000"; - this._pendingTask.subject.error(error); + for (var i = 0; i < payload.length; i++) { + if (i !== 0) { + pEl.appendChild(document.createElement("br")); } + + var span = generateSpansFromSRTText(payload[i]); + pEl.appendChild(span); } - /** - * 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 - * @returns {Observable} - */ - ; - _proto._addToQueue = function _addToQueue(operation) { - var _this2 = this; + return { + start: start, + end: end, + element: pEl + }; +} +/** + * Take a single srt line and convert it into a span with the right style while + * avoiding XSS. + * What we do is set a whitelist of authorized tags, and recreate the + * corresponding tag from scratch. + * Supported tags: + * - : make content bold + * - : make content italic + * - : draw underline on content + * - : add color x to the content + * @param {string} text + * @returns {HTMLElement} + */ - return new Observable/* Observable */.y(function (obs) { - var shouldRestartQueue = _this2._queue.length === 0 && _this2._pendingTask === null; - var subject = new Subject/* Subject */.xQ(); - var queueItem = (0,object_assign/* default */.Z)({ - subject: subject - }, operation); - _this2._queue.push(queueItem); +function generateSpansFromSRTText(text) { + var secureDiv = document.createElement("div"); + secureDiv.innerHTML = text; - var subscription = subject.subscribe(obs); + var _loop = function _loop(node) { + var childNodes = node.childNodes; + var span = document.createElement("span"); + span.className = "rxp-texttrack-span"; - if (shouldRestartQueue) { - _this2._flush(); - } + for (var i = 0; i < childNodes.length; i++) { + var currentNode = childNodes[i]; - return function () { - subscription.unsubscribe(); // Remove the corresponding element from the AudioVideoSegmentBuffer's - // queue. - // If the operation was a pending task, it should still continue to not - // let the AudioVideoSegmentBuffer in a weird state. + if (currentNode.nodeName === "#text") { + var linifiedText = currentNode.wholeText.split("\n"); - var index = _this2._queue.indexOf(queueItem); + for (var line = 0; line < linifiedText.length; line++) { + if (line !== 0) { + span.appendChild(document.createElement("br")); + } - if (index >= 0) { - _this2._queue.splice(index, 1); + if (linifiedText[line].length > 0) { + var textNode = document.createTextNode(linifiedText[line]); + span.appendChild(textNode); + } } - }; - }); - } - /** - * Perform next task if one. - * @private - */ - ; - - _proto._flush = function _flush() { - if (this._sourceBuffer.updating) { - return; // still processing `this._pendingTask` - } - - if (this._pendingTask !== null) { - var task = this._pendingTask; - - if (task.type !== types/* SegmentBufferOperation.Push */.f.Push || task.data.length === 0) { - // If we're here, we've finished processing the task - switch (task.type) { - case types/* SegmentBufferOperation.Push */.f.Push: - if (task.inventoryData !== null) { - this._segmentInventory.insertChunk(task.inventoryData); - } - - break; - - case types/* SegmentBufferOperation.EndOfSegment */.f.EndOfSegment: - this._segmentInventory.completeSegment(task.value); + } else if (currentNode.nodeName === "B") { + var spanChild = _loop(currentNode); - break; + spanChild.style.fontWeight = "bold"; + span.appendChild(spanChild); + } else if (currentNode.nodeName === "I") { + var _spanChild = _loop(currentNode); - case types/* SegmentBufferOperation.Remove */.f.Remove: - this.synchronizeInventory(); - break; + _spanChild.style.fontStyle = "italic"; + span.appendChild(_spanChild); + } else if (currentNode.nodeName === "U") { + var _spanChild2 = _loop(currentNode); - default: - (0,assert_unreachable/* default */.Z)(task); - } + _spanChild2.style.textDecoration = "underline"; + span.appendChild(_spanChild2); + } else if (currentNode.nodeName === "FONT" && // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + currentNode.color != null) { + // TODO loop through attributes to find color? - var subject = task.subject; - this._pendingTask = null; - subject.next(); - subject.complete(); + /* eslint-disable @typescript-eslint/no-unsafe-assignment */ - this._flush(); // Go to next item in queue + /* eslint-disable @typescript-eslint/no-unsafe-member-access */ + var _spanChild3 = _loop(currentNode); + _spanChild3.style.color = currentNode.color; + /* eslint-enable @typescript-eslint/no-unsafe-assignment */ - return; - } - } else { - // if this._pendingTask is null, go to next item in queue - var nextItem = this._queue.shift(); + /* eslint-enable @typescript-eslint/no-unsafe-member-access */ - if (nextItem === undefined) { - return; // we have nothing left to do - } else if (nextItem.type !== types/* SegmentBufferOperation.Push */.f.Push) { - this._pendingTask = nextItem; + span.appendChild(_spanChild3); } else { - var itemValue = nextItem.value; - var dataToPush; - - try { - dataToPush = this._preparePushOperation(itemValue.data); - } catch (e) { - this._pendingTask = (0,object_assign/* default */.Z)({ - data: [], - inventoryData: itemValue.inventoryInfos - }, nextItem); - var error = e instanceof Error ? e : new Error("An unknown error occured when preparing a push operation"); - this._lastInitSegment = null; // initialize init segment as a security - - nextItem.subject.error(error); - return; - } + var _spanChild4 = _loop(currentNode); - this._pendingTask = (0,object_assign/* default */.Z)({ - data: dataToPush, - inventoryData: itemValue.inventoryInfos - }, nextItem); + span.appendChild(_spanChild4); } } - try { - switch (this._pendingTask.type) { - case types/* SegmentBufferOperation.EndOfSegment */.f.EndOfSegment: - // nothing to do, we will just acknowledge the segment. - log/* default.debug */.Z.debug("AVSB: Acknowledging complete segment", this._pendingTask.value); + return span; + }; - this._flush(); + return _loop(secureDiv); +} - return; +/***/ }), - case types/* SegmentBufferOperation.Push */.f.Push: - var segmentData = this._pendingTask.data.shift(); +/***/ 8057: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - if (segmentData === undefined) { - this._flush(); +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ parseSRTStringToVTTCues) +/* harmony export */ }); +/* harmony import */ var _compat_index__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7253); +/* harmony import */ var _get_cue_blocks__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2061); +/* harmony import */ var _parse_cue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(788); +/** + * 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; - } +/** + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. + */ +// srt to VTTCue parser, Done for fun. +// Heavily inspired from the WebVTT implementation - this._sourceBuffer.appendBuffer(segmentData); - break; - case types/* SegmentBufferOperation.Remove */.f.Remove: - var _this$_pendingTask$va = this._pendingTask.value, - start = _this$_pendingTask$va.start, - end = _this$_pendingTask$va.end; - log/* default.debug */.Z.debug("AVSB: removing data from SourceBuffer", this.bufferType, start, end); +/** + * Parse whole srt file into an array of cues, to be inserted in a video's + * TrackElement. + * @param {string} srtStr + * @param {Number} timeOffset + * @returns {Array.} + */ - this._sourceBuffer.remove(start, end); +function parseSRTStringToVTTCues(srtStr, timeOffset) { + // Even if srt only authorize CRLF, we will also take LF or CR as line + // terminators for resilience + var lines = srtStr.split(/\r\n|\n|\r/); + var cueBlocks = (0,_get_cue_blocks__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(lines); + var cues = []; - break; + for (var i = 0; i < cueBlocks.length; i++) { + var cueObject = (0,_parse_cue__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(cueBlocks[i], timeOffset); - default: - (0,assert_unreachable/* default */.Z)(this._pendingTask); + if (cueObject !== null) { + var nativeCue = toNativeCue(cueObject); + + if (nativeCue !== null) { + cues.push(nativeCue); } - } catch (e) { - this._onPendingTaskError(e); } } - /** - * A push Operation might necessitate to mutate some `SourceBuffer` and/or - * `AudioVideoSegmentBuffer` properties and also might need to be divided into - * multiple segments to push (exemple: when first pushing the initialization - * data before the segment data). - * - * This method allows to "prepare" that push operation so that all is left is - * to push the returned segment data one after the other (from first to last). - * @param {Object} item - * @returns {Object} - */ - ; - - _proto._preparePushOperation = function _preparePushOperation(data) { - // Push operation with both an init segment and a regular segment might - // need to be separated into two steps - var dataToPush = []; - var codec = data.codec, - timestampOffset = data.timestampOffset, - appendWindow = data.appendWindow; - var hasUpdatedSourceBufferType = false; - - if (codec !== this.codec) { - log/* default.debug */.Z.debug("AVSB: updating codec", codec); - hasUpdatedSourceBufferType = tryToChangeSourceBufferType(this._sourceBuffer, codec); - - if (hasUpdatedSourceBufferType) { - this.codec = codec; - } else { - log/* default.debug */.Z.debug("AVSB: could not update codec", codec, this.codec); - } - } - - if (this._sourceBuffer.timestampOffset !== timestampOffset) { - var newTimestampOffset = timestampOffset; - log/* default.debug */.Z.debug("AVSB: updating timestampOffset", this.bufferType, this._sourceBuffer.timestampOffset, newTimestampOffset); - this._sourceBuffer.timestampOffset = newTimestampOffset; - } - - if (appendWindow[0] === undefined) { - if (this._sourceBuffer.appendWindowStart > 0) { - this._sourceBuffer.appendWindowStart = 0; - } - } else if (appendWindow[0] !== this._sourceBuffer.appendWindowStart) { - if (appendWindow[0] >= this._sourceBuffer.appendWindowEnd) { - this._sourceBuffer.appendWindowEnd = appendWindow[0] + 1; - } - - this._sourceBuffer.appendWindowStart = appendWindow[0]; - } - - if (appendWindow[1] === undefined) { - if (this._sourceBuffer.appendWindowEnd !== Infinity) { - this._sourceBuffer.appendWindowEnd = Infinity; - } - } else if (appendWindow[1] !== this._sourceBuffer.appendWindowEnd) { - this._sourceBuffer.appendWindowEnd = appendWindow[1]; - } - - if (data.initSegment !== null && (hasUpdatedSourceBufferType || !this._isLastInitSegment(data.initSegment))) { - // Push initialization segment before the media segment - var segmentData = data.initSegment; - dataToPush.push(segmentData); - var initU8 = (0,byte_parsing/* toUint8Array */._f)(segmentData); - this._lastInitSegment = { - data: initU8, - hash: (0,hash_buffer/* default */.Z)(initU8) - }; - } - - if (data.chunk !== null) { - dataToPush.push(data.chunk); - } - - return dataToPush; - } - /** - * Return `true` if the given `segmentData` is the same segment than the last - * initialization segment pushed to the `AudioVideoSegmentBuffer`. - * @param {BufferSource} segmentData - * @returns {boolean} - */ - ; - _proto._isLastInitSegment = function _isLastInitSegment(segmentData) { - if (this._lastInitSegment === null) { - return false; - } - - if (this._lastInitSegment.data === segmentData) { - return true; - } - - var oldInit = this._lastInitSegment.data; + return cues; +} +/** + * @param {Object} cue Object + * @returns {TextTrackCue|VTTCue|null} + */ - if (oldInit.byteLength === segmentData.byteLength) { - var newInitU8 = (0,byte_parsing/* toUint8Array */._f)(segmentData); +function toNativeCue(cueObj) { + var start = cueObj.start, + end = cueObj.end, + payload = cueObj.payload; + var text = payload.join("\n"); + return (0,_compat_index__WEBPACK_IMPORTED_MODULE_2__/* .default */ .Z)(start, end, text); +} - if ((0,hash_buffer/* default */.Z)(newInitU8) === this._lastInitSegment.hash && (0,are_arrays_of_numbers_equal/* default */.Z)(oldInit, newInitU8)) { - return true; - } - } +/***/ }), - return false; - }; +/***/ 788: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - return AudioVideoSegmentBuffer; -}(types/* SegmentBuffer */.C); +"use strict"; +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ parseCueBlock) +}); -;// CONCATENATED MODULE: ./src/core/segment_buffers/implementations/audio_video/index.ts +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +;// CONCATENATED MODULE: ./src/parsers/texttracks/srt/parse_timestamp.ts /** * Copyright 2015 CANAL+ Group * @@ -17724,8 +17519,28 @@ var AudioVideoSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) { * limitations under the License. */ -/* harmony default export */ const audio_video = (AudioVideoSegmentBuffer); -;// CONCATENATED MODULE: ./src/core/segment_buffers/segment_buffers_store.ts +/** + * Parse a single srt timestamp into seconds + * @param {string} timestampString + * @returns {Number|undefined} + */ + +function parseTimestamp(timestampString) { + var splittedTS = timestampString.split(":"); + + if ((0,is_non_empty_string/* default */.Z)(splittedTS[2])) { + var hours = parseInt(splittedTS[0], 10); + var minutes = parseInt(splittedTS[1], 10); + var seconds = parseFloat(splittedTS[2].replace(",", ".")); + + if (isNaN(hours) || isNaN(minutes) || isNaN(seconds)) { + return undefined; + } + + return hours * 60 * 60 + minutes * 60 + seconds; + } +} +;// CONCATENATED MODULE: ./src/parsers/texttracks/srt/parse_cue.ts /** * Copyright 2015 CANAL+ Group * @@ -17743,351 +17558,316 @@ var AudioVideoSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) { */ - - - -var POSSIBLE_BUFFER_TYPES = ["audio", "video", "text", "image"]; /** - * Allows to easily create and dispose SegmentBuffers, which are interfaces to - * push and remove segments. - * - * Only one SegmentBuffer per type is allowed at the same time: - * - * - SegmentBuffers linked to a "native" media buffer (relying on a - * SourceBuffer: "audio" and "video" here) are reused if one is - * re-created. - * - * - SegmentBuffers for custom types (the other types of media) are aborted - * each time a new one of the same type is created. - * - * To be able to use a SegmentBuffer linked to a native media buffer, you - * will first need to create it, but also wait until the other one is either - * created or explicitely disabled through the `disableSegmentBuffer` method. - * The Observable returned by `waitForUsableBuffers` will emit when - * that is the case. - * - * @class SegmentBuffersStore + * Parse cue block into a cue object which contains: + * - start {number}: the start of the cue as a timestamp in seconds + * - end {number}: the end of the cue as a timestamp in seconds + * - payload {Array.}: the payload of the cue + * @param {Array.} cueLines + * @param {Number} timeOffset + * @returns {Object} */ -var SegmentBuffersStore = /*#__PURE__*/function () { - /** - * @param {HTMLMediaElement} mediaElement - * @param {MediaSource} mediaSource - * @constructor - */ - function SegmentBuffersStore(mediaElement, mediaSource) { - this._mediaElement = mediaElement; - this._mediaSource = mediaSource; - this._initializedSegmentBuffers = {}; - this._onNativeBufferAddedOrDisabled = []; +function parseCueBlock(cueLines, timeOffset) { + if (cueLines.length === 0) { + return null; } - /** - * Returns true if the type is linked to a "native" media buffer (i.e. relying - * on a SourceBuffer object, native to the browser). - * Native media buffers needed for the current content must all be created - * before the content begins to be played and cannot be disposed during - * playback. - * @param {string} bufferType - * @returns {Boolean} - */ + var startTimeString; + var endTimeString; + var payload = []; // normally in srt, the timing is at second position. + // We still authorize to put it in the first position for resilience - SegmentBuffersStore.isNative = function isNative(bufferType) { - return shouldHaveNativeBuffer(bufferType); + if ((0,is_non_empty_string/* default */.Z)(cueLines[1]) && cueLines[1].indexOf("-->") !== -1) { + var _cueLines$1$split$map = cueLines[1].split("-->").map(function (s) { + return s.trim(); + }); + + startTimeString = _cueLines$1$split$map[0]; + endTimeString = _cueLines$1$split$map[1]; + payload = cueLines.slice(2, cueLines.length); } - /** - * Get all currently available buffer types. - * /!\ This list can evolve at runtime depending on feature switching. - * @returns {Array.} - */ - ; - var _proto = SegmentBuffersStore.prototype; + if (!(0,is_non_empty_string/* default */.Z)(startTimeString) || !(0,is_non_empty_string/* default */.Z)(endTimeString)) { + // Try to see if we find them in the first position + var _cueLines$0$split$map = cueLines[0].split("-->").map(function (s) { + return s.trim(); + }); - _proto.getBufferTypes = function getBufferTypes() { - var bufferTypes = this.getNativeBufferTypes(); + startTimeString = _cueLines$0$split$map[0]; + endTimeString = _cueLines$0$split$map[1]; + payload = cueLines.slice(1, cueLines.length); + } - if (features/* default.nativeTextTracksBuffer */.Z.nativeTextTracksBuffer != null || features/* default.htmlTextTracksBuffer */.Z.htmlTextTracksBuffer != null) { - bufferTypes.push("text"); - } + if (!(0,is_non_empty_string/* default */.Z)(startTimeString) || !(0,is_non_empty_string/* default */.Z)(endTimeString)) { + // if the time is still not found, exit + return null; + } - if (features/* default.imageBuffer */.Z.imageBuffer != null) { - bufferTypes.push("image"); - } + var start = parseTimestamp(startTimeString); + var end = parseTimestamp(endTimeString); - return bufferTypes; + if (start === undefined || end === undefined) { + return null; } - /** - * Get all "native" buffer types that should be created before beginning to - * push contents. - * @returns {Array.} - */ - ; - _proto.getNativeBufferTypes = function getNativeBufferTypes() { - return this._mediaElement.nodeName === "AUDIO" ? ["audio"] : ["video", "audio"]; - } - /** - * Returns the current "status" of the SegmentBuffer linked to the buffer - * type given. - * - * This function will return an object containing a key named `type` which - * can be equal to either one of those three value: - * - * - "initialized": A SegmentBuffer has been created for that type. - * You will in this case also have a second key, `value`, which will - * contain the related SegmentBuffer instance. - * Please note that you will need to wait until - * `this.waitForUsableBuffers()` has emitted before pushing segment - * data to a SegmentBuffer relying on a SourceBuffer. - * - * - "disabled": The SegmentBuffer has been explicitely disabled for this - * type. - * - * - "uninitialized": No action has yet been yet for that SegmentBuffer. - * - * @param {string} bufferType - * @returns {Object|null} - */ - ; + return { + start: start + timeOffset, + end: end + timeOffset, + payload: payload + }; +} - _proto.getStatus = function getStatus(bufferType) { - var initializedBuffer = this._initializedSegmentBuffers[bufferType]; - return initializedBuffer === undefined ? { - type: "uninitialized" - } : initializedBuffer === null ? { - type: "disabled" - } : { - type: "initialized", - value: initializedBuffer - }; - } - /** - * Native media buffers (audio and video) needed for playing the current - * content need to all be created (by creating SegmentBuffers linked to them) - * before any one can be used. - * - * This function will return an Observable emitting when any and all native - * SourceBuffers can be used. - * - * From https://w3c.github.io/media-source/#methods - * For example, a user agent may throw a QuotaExceededError - * exception if the media element has reached the HAVE_METADATA - * readyState. This can occur if the user agent's media engine - * does not support adding more tracks during playback. - * @return {Observable} - */ - ; +/***/ }), - _proto.waitForUsableBuffers = function waitForUsableBuffers() { - var _this = this; +/***/ 2967: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - if (this._areNativeBuffersUsable()) { - return (0,of.of)(undefined); - } +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ getParentElementsByTagName) +/* harmony export */ }); +/** + * 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 new Observable/* Observable */.y(function (obs) { - _this._onNativeBufferAddedOrDisabled.push(function () { - if (_this._areNativeBuffersUsable()) { - obs.next(undefined); - obs.complete(); - } - }); - }); +/** + * Returns the parent elements which have the given tagName, by order of + * closeness relative to our element. + * @param {Element|Node} element + * @param {string} tagName + * @returns {Array.} + */ +function getParentElementsByTagName(element, tagName) { + if (!(element.parentNode instanceof Element)) { + return []; } - /** - * Explicitely disable the SegmentBuffer for a given buffer type. - * A call to this function is needed at least for unused native buffer types - * (usually "audio" and "video"), to be able to emit through - * `waitForUsableBuffers` when conditions are met. - * @param {string} - */ - ; - - _proto.disableSegmentBuffer = function disableSegmentBuffer(bufferType) { - var currentValue = this._initializedSegmentBuffers[bufferType]; - if (currentValue === null) { - log/* default.warn */.Z.warn("SBS: The " + bufferType + " SegmentBuffer was already disabled."); - return; - } + function constructArray(_element) { + var elements = []; - if (currentValue !== undefined) { - throw new Error("Cannot disable an active SegmentBuffer."); + if (_element.tagName.toLowerCase() === tagName.toLowerCase()) { + elements.push(_element); } - this._initializedSegmentBuffers[bufferType] = null; + var parentNode = _element.parentNode; - if (SegmentBuffersStore.isNative(bufferType)) { - this._onNativeBufferAddedOrDisabled.forEach(function (cb) { - return cb(); - }); + if (parentNode instanceof Element) { + elements.push.apply(elements, constructArray(parentNode)); } + + return elements; } - /** - * Creates a new SegmentBuffer associated to a type. - * Reuse an already created one if a SegmentBuffer for the given type - * already exists. - * - * Please note that you will need to wait until `this.waitForUsableBuffers()` - * has emitted before pushing segment data to a SegmentBuffer of a native - * type. - * @param {string} bufferType - * @param {string} codec - * @param {Object|undefined} options - * @returns {Object} - */ - ; - _proto.createSegmentBuffer = function createSegmentBuffer(bufferType, codec, options) { - if (options === void 0) { - options = {}; - } + return constructArray(element.parentNode); +} - var memorizedSegmentBuffer = this._initializedSegmentBuffers[bufferType]; +/***/ }), - if (shouldHaveNativeBuffer(bufferType)) { - if (memorizedSegmentBuffer != null) { - if (memorizedSegmentBuffer instanceof audio_video && memorizedSegmentBuffer.codec !== codec) { - log/* default.warn */.Z.warn("SB: Reusing native SegmentBuffer with codec", memorizedSegmentBuffer.codec, "for codec", codec); - } else { - log/* default.info */.Z.info("SB: Reusing native SegmentBuffer with codec", codec); - } +/***/ 3791: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - return memorizedSegmentBuffer; - } +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "U": () => (/* binding */ getStylingAttributes), +/* harmony export */ "b": () => (/* binding */ getStylingFromElement) +/* harmony export */ }); +/* harmony import */ var _utils_array_find__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3274); +/* harmony import */ var _utils_array_includes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7714); +/* harmony import */ var _utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6923); +/* harmony import */ var _utils_starts_with__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9252); +/** + * 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. + */ - log/* default.info */.Z.info("SB: Adding native SegmentBuffer with codec", codec); - var nativeSegmentBuffer = new audio_video(bufferType, codec, this._mediaSource); - this._initializedSegmentBuffers[bufferType] = nativeSegmentBuffer; - this._onNativeBufferAddedOrDisabled.forEach(function (cb) { - return cb(); - }); - return nativeSegmentBuffer; - } - if (memorizedSegmentBuffer != null) { - log/* default.info */.Z.info("SB: Reusing a previous custom SegmentBuffer for the type", bufferType); - return memorizedSegmentBuffer; - } +/** + * Retrieve the attributes given in arguments in the given nodes and their + * associated style(s)/region. + * The first notion of the attribute encountered will be taken (by looping + * through the given nodes in order). + * + * TODO manage IDREFS (plural) for styles and regions, that is, multiple one + * @param {Array.} attributes + * @param {Array.} nodes + * @param {Array.} styles + * @param {Array.} regions + * @returns {Object} + */ - var segmentBuffer; +function getStylingAttributes(attributes, nodes, styles, regions) { + var currentStyle = {}; + var leftAttributes = attributes.slice(); - if (bufferType === "text") { - log/* default.info */.Z.info("SB: Creating a new text SegmentBuffer"); + for (var i = 0; i <= nodes.length - 1; i++) { + var node = nodes[i]; - if (options.textTrackMode === "html") { - if (features/* default.htmlTextTracksBuffer */.Z.htmlTextTracksBuffer == null) { - throw new Error("HTML Text track feature not activated"); - } + if (node !== undefined) { + var _ret = function () { + var styleID = void 0; + var regionID = void 0; // 1. the style is directly set on a "tts:" attribute - segmentBuffer = new features/* default.htmlTextTracksBuffer */.Z.htmlTextTracksBuffer(this._mediaElement, options.textTrackElement); - } else { - if (features/* default.nativeTextTracksBuffer */.Z.nativeTextTracksBuffer == null) { - throw new Error("Native Text track feature not activated"); - } + if (node.nodeType === Node.ELEMENT_NODE) { + var element = node; - segmentBuffer = new features/* default.nativeTextTracksBuffer */.Z.nativeTextTracksBuffer(this._mediaElement, options.hideNativeSubtitle === true); - } + for (var j = 0; j <= element.attributes.length - 1; j++) { + var attribute = element.attributes[j]; + var name = attribute.name; - this._initializedSegmentBuffers.text = segmentBuffer; - return segmentBuffer; - } else if (bufferType === "image") { - if (features/* default.imageBuffer */.Z.imageBuffer == null) { - throw new Error("Image buffer feature not activated"); - } + if (name === "style") { + styleID = attribute.value; + } else if (name === "region") { + regionID = attribute.value; + } else { + var nameWithoutTTS = name.substring(4); - log/* default.info */.Z.info("SB: Creating a new image SegmentBuffer"); - segmentBuffer = new features/* default.imageBuffer */.Z.imageBuffer(); - this._initializedSegmentBuffers.image = segmentBuffer; - return segmentBuffer; - } + if ((0,_utils_array_includes__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(leftAttributes, nameWithoutTTS)) { + currentStyle[nameWithoutTTS] = attribute.value; + leftAttributes.splice(j, 1); - log/* default.error */.Z.error("SB: Unknown buffer type:", bufferType); - throw new media_error/* default */.Z("BUFFER_TYPE_UNKNOWN", "The player wants to create a SegmentBuffer " + "of an unknown type."); - } - /** - * Dispose of the active SegmentBuffer for the given type. - * @param {string} bufferType - */ - ; + if (leftAttributes.length === 0) { + return { + v: currentStyle + }; + } + } + } + } + } // 2. the style is referenced on a "style" attribute - _proto.disposeSegmentBuffer = function disposeSegmentBuffer(bufferType) { - var memorizedSegmentBuffer = this._initializedSegmentBuffers[bufferType]; - if (memorizedSegmentBuffer == null) { - log/* default.warn */.Z.warn("SB: Trying to dispose a SegmentBuffer that does not exist"); - return; - } + if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(styleID)) { + var style = (0,_utils_array_find__WEBPACK_IMPORTED_MODULE_2__/* .default */ .Z)(styles, function (x) { + return x.id === styleID; + }); - log/* default.info */.Z.info("SB: Aborting SegmentBuffer", bufferType); - memorizedSegmentBuffer.dispose(); - delete this._initializedSegmentBuffers[bufferType]; - } - /** - * Dispose of all SegmentBuffer created on this SegmentBuffersStore. - */ - ; + if (style !== undefined) { + for (var _j = 0; _j <= leftAttributes.length - 1; _j++) { + var _attribute = leftAttributes[_j]; - _proto.disposeAll = function disposeAll() { - var _this2 = this; + if (!(0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(currentStyle[_attribute])) { + if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(style.style[_attribute])) { + currentStyle[_attribute] = style.style[_attribute]; + leftAttributes.splice(_j, 1); - POSSIBLE_BUFFER_TYPES.forEach(function (bufferType) { - if (_this2.getStatus(bufferType).type === "initialized") { - _this2.disposeSegmentBuffer(bufferType); - } - }); - } - /** - * Returns `true` when we're ready to push and decode contents to - * SourceBuffers created by SegmentBuffers of a native buffer type. - */ - ; + if (leftAttributes.length === 0) { + return { + v: currentStyle + }; + } - _proto._areNativeBuffersUsable = function _areNativeBuffersUsable() { - var _this3 = this; + _j--; + } + } + } + } + } // 3. the node reference a region (which can have a value for the + // corresponding style) - var nativeBufferTypes = this.getNativeBufferTypes(); - var hasUnitializedBuffers = nativeBufferTypes.some(function (sbType) { - return _this3._initializedSegmentBuffers[sbType] === undefined; - }); - if (hasUnitializedBuffers) { - // one is not yet initialized/disabled - return false; - } + if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(regionID)) { + var region = (0,_utils_array_find__WEBPACK_IMPORTED_MODULE_2__/* .default */ .Z)(regions, function (x) { + return x.id === regionID; + }); - var areAllDisabled = nativeBufferTypes.every(function (sbType) { - return _this3._initializedSegmentBuffers[sbType] === null; - }); + if (region !== undefined) { + for (var _j2 = 0; _j2 <= leftAttributes.length - 1; _j2++) { + var _attribute2 = leftAttributes[_j2]; - if (areAllDisabled) { - // they all are disabled: we can't play the content - return false; - } + if (!(0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(currentStyle[_attribute2])) { + if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(region.style[_attribute2])) { + currentStyle[_attribute2] = region.style[_attribute2]; + leftAttributes.splice(_j2, 1); - return true; - }; + if (leftAttributes.length === 0) { + return { + v: currentStyle + }; + } - return SegmentBuffersStore; -}(); + _j2--; + } + } + } + } + } + }(); + + if (typeof _ret === "object") return _ret.v; + } + } + + return currentStyle; +} /** - * Returns true if the given buffeType has a linked SourceBuffer implementation, - * false otherwise. - * SourceBuffers are directly added to the MediaSource. - * @param {string} bufferType - * @returns {Boolean} + * Returns the styling directly linked to an element. + * @param {Node} node + * @returns {Object} */ +function getStylingFromElement(node) { + if (node.nodeType !== Node.ELEMENT_NODE) { + return {}; + } + var element = node; + var currentStyle = {}; + for (var i = 0; i <= element.attributes.length - 1; i++) { + var styleAttribute = element.attributes[i]; -function shouldHaveNativeBuffer(bufferType) { - return bufferType === "audio" || bufferType === "video"; + if ((0,_utils_starts_with__WEBPACK_IMPORTED_MODULE_3__/* .default */ .Z)(styleAttribute.name, "tts")) { + var nameWithoutTTS = styleAttribute.name.substring(4); + currentStyle[nameWithoutTTS] = styleAttribute.value; + } + } + + return currentStyle; } -;// CONCATENATED MODULE: ./src/core/segment_buffers/index.ts + +/***/ }), + +/***/ 6177: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ getTimeDelimiters) +}); + +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/regexps.ts +var regexps = __webpack_require__(5336); +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/time_parsing.ts /** * Copyright 2015 CANAL+ Group * @@ -18104,224 +17884,191 @@ function shouldHaveNativeBuffer(bufferType) { * limitations under the License. */ +/** + * Parses a TTML time into seconds. + * @param {string} text + * @param {Object} ttParams + * @returns {Number|undefined} + */ +function parseTime(text, ttParams) { + if (regexps/* REGXP_TIME_COLON_FRAMES.test */.gu.test(text)) { + return parseColonTimeWithFrames(ttParams, text); + } else if (regexps/* REGXP_TIME_COLON.test */.KO.test(text)) { + return parseTimeFromRegExp(regexps/* REGXP_TIME_COLON */.KO, text); + } else if (regexps/* REGXP_TIME_COLON_MS.test */.wf.test(text)) { + return parseTimeFromRegExp(regexps/* REGXP_TIME_COLON_MS */.wf, text); + } else if (regexps/* REGXP_TIME_FRAMES.test */.jb.test(text)) { + return parseFramesTime(ttParams, text); + } else if (regexps/* REGXP_TIME_TICK.test */.Du.test(text)) { + return parseTickTime(ttParams, text); + } else if (regexps/* REGXP_TIME_HMS.test */.te.test(text)) { + return parseTimeFromRegExp(regexps/* REGXP_TIME_HMS */.te, text); + } +} +/** + * Parses a TTML time in frame format + * @param {Object} ttParams + * @param {string} text + * @returns {Number} + */ -/* harmony default export */ const segment_buffers = (SegmentBuffersStore); -;// CONCATENATED MODULE: ./src/utils/sorted_list.ts +function parseFramesTime(ttParams, text) { + // 75f or 75.5f + // (We cast as we're sure the regexp is respected here) + var results = regexps/* REGXP_TIME_FRAMES.exec */.jb.exec(text); + var frames = Number(results[1]); + return frames / ttParams.frameRate; +} /** - * 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. + * Parses a TTML time in tick format + * @param {Object} ttParams + * @param {string} text + * @returns {Number} */ +function parseTickTime(ttParams, text) { + // 50t or 50.5t + // (We cast as we're sure the regexp is respected here) + var results = regexps/* REGXP_TIME_TICK.exec */.Du.exec(text); + var ticks = Number(results[1]); + return ticks / ttParams.tickRate; +} /** - * Creates an Array automatically sorted with the sorting function given to the - * constructor when the add method is called. - * - * @example - * ```js - * const sortedList = new SortedList((a, b) => a.start - b.start); - * const element1 = { start: 20 }; - * const element2 = { start: 10 }; - * const element3 = { start: 15 }; - * - * sortedList.add(element1, element2); - * console.log(sortedList.unwrap()); - * // -> [{ start: 10 }, { start : 20 }] - * - * sortedList.add(element3); - * console.log(sortedList.unwrap()); - * // -> [{ start: 10 }, { start : 15 }, { start: 20 }] - * - * sortedList.removeElement(element2); - * // -> [{ start: 10 }, { start: 15 }] - * ``` - * @class SortedList + * Parses a TTML colon formatted time containing frames + * @param {Object} ttParams + * @param {string} text + * @returns {Number} */ -var SortedList = /*#__PURE__*/function () { - /** - * @param {Function} sortingFunction - */ - function SortedList(sortingFunction) { - this._array = []; - this._sortingFn = sortingFunction; - } - /** - * Add a new element to the List at the right place for the List to stay - * sorted. - * - * /!\ The added Element will share the same reference than the given - * argument, any mutation on your part can lead to an un-sorted SortedList. - * You can still re-force the sorting to happen by calling forceSort. - * @param {...*} elements - */ +function parseColonTimeWithFrames(ttParams, text) { + // 01:02:43:07 ("07" is frames) or 01:02:43:07.1 (subframes) + // (We cast as we're sure the regexp is respected here) + var results = regexps/* REGXP_TIME_COLON_FRAMES.exec */.gu.exec(text); + var hours = Number(results[1]); + var minutes = Number(results[2]); + var seconds = Number(results[3]); + var frames = Number(results[4]); + var subframes = Number(results[5]); - var _proto = SortedList.prototype; + if (isNaN(subframes)) { + subframes = 0; + } - _proto.add = function add() { - for (var _len = arguments.length, elements = new Array(_len), _key = 0; _key < _len; _key++) { - elements[_key] = arguments[_key]; - } + frames += subframes / ttParams.subFrameRate; + seconds += frames / ttParams.frameRate; + return seconds + minutes * 60 + hours * 3600; +} +/** + * Parses a TTML time with a given regex. Expects regex to be some + * sort of a time-matcher to match hours, minutes, seconds and milliseconds + * + * @param {RegExp} regex + * @param {string} text + * @returns {number|null} + */ - elements.sort(this._sortingFn); - var j = 0; - for (var i = 0; i < elements.length; i++) { - var element = elements[i]; - var inserted = false; +function parseTimeFromRegExp(regex, text) { + var results = regex.exec(text); - while (!inserted && j < this._array.length) { - if (this._sortingFn(element, this._array[j]) < 0) { - this._array.splice(j, 0, element); + if (results === null || results[0] === "") { + return null; + } // This capture is optional, but will still be in the array as undefined, + // default to 0. - inserted = true; - } else { - j++; - } - } - if (!inserted) { - this._array.push(element); - } - } - } - /** - * Returns the current length of the list. - * @returns {number} - */ - ; + var hours = Number(results[1]); - _proto.length = function length() { - return this._array.length; + if (isNaN(hours)) { + hours = 0; } - /** - * Returns the nth element. Throws if the index does not exist. - * - * /!\ The returned Element shares the same reference with what is used - * internally, any mutation on your part can lead to an un-sorted SortedList. - * You can still re-force the sorting to happen by calling forceSort. - * @throws Error - Throws if the given index is negative or superior to the - * array's length. - * @param {number} index - * @returns {*} - */ - ; - _proto.get = function get(index) { - if (index < 0 || index >= this._array.length) { - throw new Error("Invalid index."); - } + var minutes = Number(results[2]); - return this._array[index]; + if (isNaN(minutes)) { + minutes = 0; } - /** - * Find the first element corresponding to the given predicate. - * - * /!\ The returned element shares the same reference with what is used - * internally, any mutation on your part can lead to an un-sorted SortedList. - * You can still re-force the sorting to happen by calling forceSort. - * @param {Function} fn - * @returns {*} - */ - ; - _proto.findFirst = function findFirst(fn) { - return (0,array_find/* default */.Z)(this._array, fn); + var seconds = Number(results[3]); + + if (isNaN(seconds)) { + seconds = 0; } - /** - * Returns true if the List contains the given element. - * @param {*} element - * @returns {Boolean} - */ - ; - _proto.has = function has(element) { - return (0,array_includes/* default */.Z)(this._array, element); + var milliseconds = Number(results[4]); + + if (isNaN(milliseconds)) { + milliseconds = 0; } - /** - * Remove the first occurence of the given element. - * Returns the index of the removed element. Undefined if not found. - * @returns {number|undefined} - */ - ; - _proto.removeElement = function removeElement(element) { - var indexOf = this._array.indexOf(element); + return milliseconds / 1000 + seconds + minutes * 60 + hours * 3600; +} - if (indexOf >= 0) { - this._array.splice(indexOf, 1); +/* harmony default export */ const time_parsing = (parseTime); +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/get_time_delimiters.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 indexOf; - } - return undefined; - } - /** - * Returns the first element. - * - * /!\ The returned Element shares the same reference with what is used - * internally, any mutation on your part can lead to an un-sorted SortedList. - * You can still re-force the sorting to happen by calling forceSort. - * @returns {*} - */ - ; +/** + * Get start and end time of an element. + * @param {Element} element + * @param {Object} ttParams + * @returns {Object} + */ - _proto.head = function head() { - return this._array[0]; - } - /** - * Returns the last element. - * - * /!\ The returned Element shares the same reference with what is used - * internally, any mutation on your part can lead to an un-sorted SortedList. - * You can still re-force the sorting to happen by calling forceSort. - * @returns {*} - */ - ; +function getTimeDelimiters(element, ttParams) { + var beginAttr = element.getAttribute("begin"); + var durationAttr = element.getAttribute("dur"); + var endAttr = element.getAttribute("end"); + var start = (0,is_non_empty_string/* default */.Z)(beginAttr) ? time_parsing(beginAttr, ttParams) : null; + var duration = (0,is_non_empty_string/* default */.Z)(durationAttr) ? time_parsing(durationAttr, ttParams) : null; + var parsedEnd = (0,is_non_empty_string/* default */.Z)(endAttr) ? time_parsing(endAttr, ttParams) : null; - _proto.last = function last() { - return this._array[this._array.length - 1]; - } - /** - * Remove the first element. - * Returns the element removed or undefined if no element were removed. - * @returns {*} - */ - ; + if (start == null || parsedEnd == null && duration == null) { + throw new Error("Invalid text cue"); + } // Huh? Is TypeScript that dumb here? - _proto.shift = function shift() { - return this._array.shift(); - } - /** - * Remove the last element. - * Returns the element removed or undefined if no element were removed. - * @returns {*} - */ - ; - _proto.pop = function pop() { - return this._array.pop(); + var end = parsedEnd == null ? start + duration : parsedEnd; + return { + start: start, + end: end }; +} - return SortedList; -}(); +/***/ }), +/***/ 7439: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -;// CONCATENATED MODULE: ./src/utils/weak_map_memory.ts +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ html) +}); + +// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/parse_ttml.ts + 3 modules +var parse_ttml = __webpack_require__(5403); +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/apply_default_ttml_paragraph_style.ts /** * Copyright 2015 CANAL+ Group * @@ -18339,89 +18086,214 @@ var SortedList = /*#__PURE__*/function () { */ /** - * Memoize Function results linked to an object, through a WeakMap. + * Return true if no style has been already declared and no conflict is + * detected with current cue style. * - * @example - * ```js - * // Initialize the WeakMapMemory with its logic: - * const memory = new WeakMapMemory(arg => { - * console.log("side-effect"); - * return [arg.a, arg.b]; - * }); + * No position, orientation and dimension style should have been set to + * avoid any conflict. + * @param {object} paragraphStyle + * @returns {boolean} + */ +function shouldApplyDefaultTTMLStyle(paragraphStyle) { + return paragraphStyle.extent === undefined && paragraphStyle.origin === undefined && paragraphStyle.displayAlign === undefined && paragraphStyle.display === undefined && paragraphStyle.textAlign === undefined && paragraphStyle.fontSize === undefined; +} +/** + * Apply a default style to TTML cue. * - * const obj = { a: 1, b: 2 }; + * The default style propose to set the cue at the bottom, centered + * and lightly spaced apart from the edges : * - * // first time obj is given: call the function, save the result and return it: - * const arr1 = memory.get(obj); - * // > "side-effect" - * // <- [1, 2] - * - * // nth time obj is given, returns the saved result without calling the - * // function: - * const arr2 = memory.get(obj); - * // <- [1, 2] + * ----------------------------------------------- + * | | + * | | + * | | + * | | + * | | + * | | + * | subtitle is displayed | + * | here | + * ----------------------------------------------- * - * // both of these use the same object, so the result is also the exact same - * // one - * console.log(arr1 === arr2); // => true + * @param {Object} cue + * TODO This code can be seen as risky because we might not predict every + * possible styles that can enter in conflict. + * A better solution should be found in the future + */ + +function applyDefaultTTMLStyle(paragraphStyle) { + paragraphStyle.extent = "70% 20%"; + paragraphStyle.fontSize = "1c"; + paragraphStyle.origin = "15% 80%"; + paragraphStyle.displayAlign = "before"; + paragraphStyle.textAlign = "center"; +} +// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/get_time_delimiters.ts + 1 modules +var get_time_delimiters = __webpack_require__(6177); +;// CONCATENATED MODULE: ./src/compat/add_class_name.ts +/** + * Copyright 2015 CANAL+ Group * - * // /!\ with a new object however: - * const obj2 = { a: 1, b: 2 }; + * 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 * - * const arr3 = memory.get(obj2); - * // > "side-effect" - * // <- [1, 2] + * http://www.apache.org/licenses/LICENSE-2.0 * - * console.log(arr1 === arr3); // => false - * ``` - * @class WeakMapMemory + * 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. */ -// eslint-disable-next-line @typescript-eslint/ban-types -var WeakMapMemory = /*#__PURE__*/function () { - /** - * @param {Function} - */ - function WeakMapMemory(fn) { - this._weakMap = new WeakMap(); - this._fn = fn; +var hasClassList; +/** + * Add className to an HTMLElement. Do nothing if the className was already + * added. + * @param {HTMLElement} elt + * @param {string} className + */ + +function addClassName(elt, className) { + if (hasClassList === undefined) { + hasClassList = elt.classList !== undefined && + /* eslint-disable @typescript-eslint/unbound-method */ + typeof elt.classList.add === "function"; + /* eslint-enable @typescript-eslint/unbound-method */ } - /** - * @param {Object} obj - * @returns {*} - */ + if (hasClassList) { + elt.classList.add(className); + } else { + var classNamesWithSpaces = " " + elt.className + " "; - var _proto = WeakMapMemory.prototype; + if (classNamesWithSpaces.indexOf(" " + className + " ") < 0) { + elt.className += " " + className; + } + } +} +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +// EXTERNAL MODULE: ./src/utils/object_assign.ts +var object_assign = __webpack_require__(8026); +// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/get_parent_elements_by_tag_name.ts +var get_parent_elements_by_tag_name = __webpack_require__(2967); +// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/get_styling.ts +var get_styling = __webpack_require__(3791); +// EXTERNAL MODULE: ./src/log.ts + 1 modules +var log = __webpack_require__(3887); +// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/regexps.ts +var regexps = __webpack_require__(5336); +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/apply_extent.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. + */ - _proto.get = function get(obj) { - var fromMemory = this._weakMap.get(obj); - if (fromMemory === undefined) { - var newElement = this._fn(obj); - this._weakMap.set(obj, newElement); +/** + * Apply `tts:extent` styling to an HTML element. + * @param {HTMLElement} element + * @param {string} extent + */ - return newElement; +function applyExtent(element, extent) { + var trimmedExtent = extent.trim(); + + if (trimmedExtent === "auto") { + return; + } + + var splittedExtent = trimmedExtent.split(" "); + + if (splittedExtent.length !== 2) { + return; + } + + var firstExtent = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedExtent[0]); + var secondExtent = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedExtent[1]); + + if (firstExtent !== null && secondExtent !== null) { + if (firstExtent[2] === "px" || firstExtent[2] === "%" || firstExtent[2] === "em") { + element.style.width = firstExtent[1] + firstExtent[2]; + } else if (firstExtent[2] === "c") { + addClassName(element, "proportional-style"); + element.setAttribute("data-proportional-width", firstExtent[1]); } else { - return fromMemory; + log/* default.warn */.Z.warn("TTML Parser: unhandled extent unit:", firstExtent[2]); + } + + if (secondExtent[2] === "px" || secondExtent[2] === "%" || secondExtent[2] === "em") { + element.style.height = secondExtent[1] + secondExtent[2]; + } else if (secondExtent[2] === "c") { + addClassName(element, "proportional-style"); + element.setAttribute("data-proportional-height", secondExtent[1]); + } else { + log/* default.warn */.Z.warn("TTML Parser: unhandled extent unit:", secondExtent[2]); } } - /** - * @param {Object} obj - */ - ; +} +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/apply_font_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. + */ - _proto.destroy = function destroy(obj) { - this._weakMap["delete"](obj); - }; - return WeakMapMemory; -}(); +/** + * Apply `tts:fontSize` styling to an HTML element. + * @param {HTMLElement} element + * @param {string} fontSize + */ + +function applyFontSize(element, fontSize) { + var trimmedFontSize = fontSize.trim(); + var splittedFontSize = trimmedFontSize.split(" "); + + if (splittedFontSize.length === 0) { + return; + } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/concatAll.js -var concatAll = __webpack_require__(2257); -;// CONCATENATED MODULE: ./src/core/segment_buffers/garbage_collector.ts + var firstFontSize = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedFontSize[0]); + + if (firstFontSize === null) { + return; + } + + if (firstFontSize[2] === "px" || firstFontSize[2] === "%" || firstFontSize[2] === "em") { + element.style.fontSize = firstFontSize[1] + firstFontSize[2]; + } else if (firstFontSize[2] === "c") { + element.style.position = "relative"; + addClassName(element, "proportional-style"); + element.setAttribute("data-proportional-font-size", firstFontSize[1]); + } else { + log/* default.warn */.Z.warn("TTML Parser: unhandled fontSize unit:", firstFontSize[2]); + } +} +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/apply_line_height.ts /** * Copyright 2015 CANAL+ Group * @@ -18440,123 +18312,233 @@ var concatAll = __webpack_require__(2257); +/** + * @param {HTMLElement} element + * @param {string} lineHeight + */ + +function applyLineHeight(element, lineHeight) { + var trimmedLineHeight = lineHeight.trim(); + + if (trimmedLineHeight === "auto") { + return; + } + + var firstLineHeight = regexps/* REGXP_LENGTH.exec */.eT.exec(trimmedLineHeight[0]); + + if (firstLineHeight === null) { + return; + } + if (firstLineHeight[2] === "px" || firstLineHeight[2] === "%" || firstLineHeight[2] === "em") { + element.style.lineHeight = firstLineHeight[1] + firstLineHeight[2]; + } else if (firstLineHeight[2] === "c") { + addClassName(element, "proportional-style"); + element.setAttribute("data-proportional-line-height", firstLineHeight[1]); + } else { + log/* default.warn */.Z.warn("TTML Parser: unhandled lineHeight unit:", firstLineHeight[2]); + } +} +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/apply_origin.ts /** - * Perform cleaning of the buffer according to the values set by the user - * at each clock tick and each times the maxBufferBehind/maxBufferAhead values - * change. + * Copyright 2015 CANAL+ Group * - * @param {Object} opt - * @returns {Observable} + * 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 BufferGarbageCollector(_ref) { - var segmentBuffer = _ref.segmentBuffer, - clock$ = _ref.clock$, - maxBufferBehind$ = _ref.maxBufferBehind$, - maxBufferAhead$ = _ref.maxBufferAhead$; - return (0,combineLatest/* combineLatest */.aj)([clock$, maxBufferBehind$, maxBufferAhead$]).pipe((0,mergeMap/* mergeMap */.zg)(function (_ref2) { - var currentTime = _ref2[0], - maxBufferBehind = _ref2[1], - maxBufferAhead = _ref2[2]; - return clearBuffer(segmentBuffer, currentTime, maxBufferBehind, maxBufferAhead); - })); + + +/** + * @param {HTMLElement} element + * @param {string} origin + */ + +function applyOrigin(element, origin) { + var trimmedOrigin = origin.trim(); + + if (trimmedOrigin === "auto") { + return; + } + + var splittedOrigin = trimmedOrigin.split(" "); + + if (splittedOrigin.length !== 2) { + return; + } + + var firstOrigin = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedOrigin[0]); + var secondOrigin = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedOrigin[1]); + + if (firstOrigin !== null && secondOrigin !== null) { + if (firstOrigin[2] === "px" || firstOrigin[2] === "%" || firstOrigin[2] === "em") { + element.style.left = firstOrigin[1] + firstOrigin[2]; + } else if (firstOrigin[2] === "c") { + addClassName(element, "proportional-style"); + element.setAttribute("data-proportional-left", firstOrigin[1]); + } else { + log/* default.warn */.Z.warn("TTML Parser: unhandled origin unit:", firstOrigin[2]); + } + + if (secondOrigin[2] === "px" || secondOrigin[2] === "%" || secondOrigin[2] === "em") { + element.style.top = secondOrigin[1] + secondOrigin[2]; + } else if (secondOrigin[2] === "c") { + addClassName(element, "proportional-style"); + element.setAttribute("data-proportional-top", secondOrigin[1]); + } else { + log/* default.warn */.Z.warn("TTML Parser: unhandled origin unit:", secondOrigin[2]); + } + } } +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/apply_padding.ts /** - * Remove buffer from the browser's memory based on the user's - * maxBufferAhead / maxBufferBehind settings. + * Copyright 2015 CANAL+ Group * - * Normally, the browser garbage-collect automatically old-added chunks of - * buffer data when memory is scarce. However, you might want to control - * the size of memory allocated. This function takes the current position - * and a "depth" behind and ahead wanted for the buffer, in seconds. + * 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 * - * Anything older than the depth will be removed from the buffer. - * @param {Object} segmentBuffer - * @param {Number} position - The current position - * @param {Number} maxBufferBehind - * @param {Number} maxBufferAhead - * @returns {Observable} + * 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 clearBuffer(segmentBuffer, position, maxBufferBehind, maxBufferAhead) { - if (!isFinite(maxBufferBehind) && !isFinite(maxBufferAhead)) { - return empty/* EMPTY */.E; - } - var cleanedupRanges = []; - var _getInnerAndOuterTime = (0,ranges/* getInnerAndOuterTimeRanges */.F_)(segmentBuffer.getBufferedRanges(), position), - innerRange = _getInnerAndOuterTime.innerRange, - outerRanges = _getInnerAndOuterTime.outerRanges; +/** + * @param {HTMLElement} element + * @param {string} padding + */ - var collectBufferBehind = function collectBufferBehind() { - if (!isFinite(maxBufferBehind)) { - return; - } // begin from the oldest +function applyPadding(element, padding) { + var trimmedPadding = padding.trim(); + var splittedPadding = trimmedPadding.split(" "); + if (splittedPadding.length < 1) { + return; + } - for (var i = 0; i < outerRanges.length; i++) { - var outerRange = outerRanges[i]; + var firstPadding = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedPadding[0]); - if (position - maxBufferBehind >= outerRange.end) { - cleanedupRanges.push(outerRange); - } else if (position >= outerRange.end && position - maxBufferBehind > outerRange.start && position - maxBufferBehind < outerRange.end) { - cleanedupRanges.push({ - start: outerRange.start, - end: position - maxBufferBehind - }); - } + if (firstPadding === null) { + return; + } + + if (firstPadding[2] === "px" || firstPadding[2] === "%" || firstPadding[2] === "em") { + var firstPaddingValue = firstPadding[1] + firstPadding[2]; + + if (splittedPadding.length === 1) { + element.style.padding = firstPaddingValue; + } else if (splittedPadding.length === 2) { + element.style.paddingTop = firstPaddingValue; + element.style.paddingBottom = firstPaddingValue; + } else { + element.style.paddingTop = firstPaddingValue; } + } else if (firstPadding[2] === "c") { + addClassName(element, "proportional-style"); - if (innerRange != null) { - if (position - maxBufferBehind > innerRange.start) { - cleanedupRanges.push({ - start: innerRange.start, - end: position - maxBufferBehind - }); - } + if (splittedPadding.length === 1) { + element.setAttribute("data-proportional-padding-top", firstPadding[1]); + element.setAttribute("data-proportional-padding-bottom", firstPadding[1]); + element.setAttribute("data-proportional-padding-left", firstPadding[1]); + element.setAttribute("data-proportional-padding-right", firstPadding[1]); + } else if (splittedPadding.length === 2) { + element.setAttribute("data-proportional-padding-top", firstPadding[1]); + element.setAttribute("data-proportional-padding-bottom", firstPadding[1]); + } else { + element.setAttribute("data-proportional-padding-top", firstPadding[1]); } - }; + } else { + log/* default.warn */.Z.warn("TTML Parser: unhandled padding unit:", firstPadding[2]); + } - var collectBufferAhead = function collectBufferAhead() { - if (!isFinite(maxBufferAhead)) { - return; - } // begin from the oldest + if (splittedPadding.length === 1) { + return; + } + var secondPadding = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedPadding[1]); - for (var i = 0; i < outerRanges.length; i++) { - var outerRange = outerRanges[i]; + if (secondPadding === null) { + return; + } - if (position + maxBufferAhead <= outerRange.start) { - cleanedupRanges.push(outerRange); - } else if (position <= outerRange.start && position + maxBufferAhead < outerRange.end && position + maxBufferAhead > outerRange.start) { - cleanedupRanges.push({ - start: position + maxBufferAhead, - end: outerRange.end - }); - } + if (secondPadding[2] === "px" || secondPadding[2] === "%" || secondPadding[2] === "em") { + var secondPaddingValue = secondPadding[1] + secondPadding[2]; + + if (splittedPadding.length < 4) { + element.style.paddingLeft = secondPaddingValue; + element.style.paddingRight = secondPaddingValue; + } else { + element.style.paddingRight = secondPaddingValue; } + } else if (secondPadding[2] === "c") { + addClassName(element, "proportional-style"); - if (innerRange != null) { - if (position + maxBufferAhead < innerRange.end) { - cleanedupRanges.push({ - start: position + maxBufferAhead, - end: innerRange.end - }); - } + if (splittedPadding.length < 4) { + element.setAttribute("data-proportional-padding-left", secondPadding[1]); + element.setAttribute("data-proportional-padding-right", secondPadding[1]); + } else { + element.setAttribute("data-proportional-padding-right", secondPadding[1]); } - }; + } else { + log/* default.warn */.Z.warn("TTML Parser: unhandled padding unit:", secondPadding[2]); + } - collectBufferBehind(); - collectBufferAhead(); - var clean$ = (0,from/* from */.D)(cleanedupRanges.map(function (range) { - log/* default.debug */.Z.debug("GC: cleaning range from SegmentBuffer", range); - return segmentBuffer.removeBuffer(range.start, range.end); - })).pipe((0,concatAll/* concatAll */.u)(), (0,ignoreElements/* ignoreElements */.l)()); - return clean$; + if (splittedPadding.length === 2) { + return; + } + + var thirdPadding = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedPadding[2]); + + if (thirdPadding === null) { + return; + } + + if (thirdPadding[2] === "px" || thirdPadding[2] === "%" || thirdPadding[2] === "em") { + var thirdPaddingValue = thirdPadding[1] + thirdPadding[2]; + element.style.paddingBottom = thirdPaddingValue; + } else if (thirdPadding[2] === "c") { + addClassName(element, "proportional-style"); + element.setAttribute("data-proportional-padding-bottom", thirdPadding[1]); + } else { + log/* default.warn */.Z.warn("TTML Parser: unhandled padding unit:", thirdPadding[2]); + } + + if (splittedPadding.length === 3) { + return; + } + + var fourthPadding = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedPadding[3]); + + if (fourthPadding === null) { + return; + } + + if (fourthPadding[2] === "px" || fourthPadding[2] === "%" || fourthPadding[2] === "em") { + var fourthPaddingValue = fourthPadding[1] + fourthPadding[2]; + element.style.paddingLeft = fourthPaddingValue; + } else if (fourthPadding[2] === "c") { + addClassName(element, "proportional-style"); + element.setAttribute("data-proportional-padding-left", fourthPadding[1]); + } else { + log/* default.warn */.Z.warn("TTML Parser: unhandled padding unit:", fourthPadding[2]); + } } -;// CONCATENATED MODULE: ./src/core/stream/events_generators.ts +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/generate_css_test_outline.ts /** * Copyright 2015 CANAL+ Group * @@ -18572,218 +18554,21 @@ function clearBuffer(segmentBuffer, position, maxBufferBehind, maxBufferAhead) { * See the License for the specific language governing permissions and * limitations under the License. */ -var EVENTS = { - activePeriodChanged: function activePeriodChanged(period) { - return { - type: "activePeriodChanged", - value: { - period: period - } - }; - }, - adaptationChange: function adaptationChange(bufferType, adaptation, period) { - return { - type: "adaptationChange", - value: { - type: bufferType, - adaptation: adaptation, - period: period - } - }; - }, - addedSegment: function addedSegment(content, segment, buffered, segmentData) { - return { - type: "added-segment", - value: { - content: content, - segment: segment, - segmentData: segmentData, - buffered: buffered - } - }; - }, - bitrateEstimationChange: function bitrateEstimationChange(type, bitrate) { - return { - type: "bitrateEstimationChange", - value: { - type: type, - bitrate: bitrate - } - }; - }, - streamComplete: function streamComplete(bufferType) { - return { - type: "complete-stream", - value: { - type: bufferType - } - }; - }, - endOfStream: function endOfStream() { - return { - type: "end-of-stream", - value: undefined - }; - }, - needsManifestRefresh: function needsManifestRefresh() { - return { - type: "needs-manifest-refresh", - value: undefined - }; - }, - manifestMightBeOufOfSync: function manifestMightBeOufOfSync() { - return { - type: "manifest-might-be-out-of-sync", - value: undefined - }; - }, - - /** - * @param {Object} period - The Period to which the stream logic asking for a - * media source reload is linked. - * @param {number} reloadAt - Position at which we should reload - * @param {boolean} reloadOnPause - If `false`, stay on pause after reloading. - * if `true`, automatically play once reloaded. - * @returns {Object} - */ - needsMediaSourceReload: function needsMediaSourceReload(period, reloadAt, reloadOnPause) { - return { - type: "needs-media-source-reload", - value: { - position: reloadAt, - autoPlay: reloadOnPause, - period: period - } - }; - }, - needsDecipherabilityFlush: function needsDecipherabilityFlush(position, autoPlay, duration) { - return { - type: "needs-decipherability-flush", - value: { - position: position, - autoPlay: autoPlay, - duration: duration - } - }; - }, - periodStreamReady: function periodStreamReady(type, period, adaptation$) { - return { - type: "periodStreamReady", - value: { - type: type, - period: period, - adaptation$: adaptation$ - } - }; - }, - periodStreamCleared: function periodStreamCleared(type, period) { - return { - type: "periodStreamCleared", - value: { - type: type, - period: period - } - }; - }, - protectedSegment: function protectedSegment(initDataInfo) { - return { - type: "protected-segment", - value: initDataInfo - }; - }, - representationChange: function representationChange(type, period, representation) { - return { - type: "representationChange", - value: { - type: type, - period: period, - representation: representation - } - }; - }, - streamTerminating: function streamTerminating() { - return { - type: "stream-terminating", - value: undefined - }; - }, - resumeStream: function resumeStream() { - return { - type: "resume-stream", - value: undefined - }; - }, - warning: function warning(value) { - return { - type: "warning", - value: value - }; - } -}; -/* harmony default export */ const stream_events_generators = (EVENTS); -// 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: ./node_modules/rxjs/_esm5/internal/operators/takeWhile.js -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ - -function takeWhile(predicate, inclusive) { - if (inclusive === void 0) { - inclusive = false; - } - return function (source) { - return source.lift(new TakeWhileOperator(predicate, inclusive)); - }; +/** + * Try to replicate the textOutline TTML style property into CSS. + * + * We mock it throught the text-shadow property, translating the TTML thickness + * into blur radius and the blur-radius into... nothing. + * + * @param {string} color + * @param {string|number} thickness + * @returns {string} + */ +function generateCSSTextOutline(color, thickness) { + return "-1px -1px " + thickness + " " + color + "," + ("1px -1px " + thickness + " " + color + ",") + ("-1px 1px " + thickness + " " + color + ",") + ("1px 1px " + thickness + " " + color); } -var TakeWhileOperator = /*@__PURE__*/ (function () { - function TakeWhileOperator(predicate, inclusive) { - this.predicate = predicate; - this.inclusive = inclusive; - } - TakeWhileOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TakeWhileSubscriber(subscriber, this.predicate, this.inclusive)); - }; - return TakeWhileOperator; -}()); -var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(TakeWhileSubscriber, _super); - function TakeWhileSubscriber(destination, predicate, inclusive) { - var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.inclusive = inclusive; - _this.index = 0; - return _this; - } - TakeWhileSubscriber.prototype._next = function (value) { - var destination = this.destination; - var result; - try { - result = this.predicate(value, this.index++); - } - catch (err) { - destination.error(err); - return; - } - this.nextOrComplete(value, result); - }; - TakeWhileSubscriber.prototype.nextOrComplete = function (value, predicateResult) { - var destination = this.destination; - if (Boolean(predicateResult)) { - destination.next(value); - } - else { - if (this.inclusive) { - destination.next(value); - } - destination.complete(); - } - }; - return TakeWhileSubscriber; -}(Subscriber/* Subscriber */.L)); -//# sourceMappingURL=takeWhile.js.map - -;// CONCATENATED MODULE: ./src/core/stream/representation/check_for_discontinuity.ts +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/ttml_color_to_css_color.ts /** * Copyright 2015 CANAL+ Group * @@ -18801,776 +18586,531 @@ var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { */ /** - * Check if there is a soon-to-be-encountered discontinuity in the buffer that - * won't be filled by any future segment. - * This function will only check discontinuities for the given `checkedRange`. - * - * @param {Object} content - The content we are currently loading. - * @param {Object} checkedRange - The time range that will be checked for - * discontinuities. - * Both `nextSegmentStart` and `bufferedSegments` arguments can only refer to - * that range. - * @param {number|null} nextSegmentStart - The start time in seconds of the next - * not-yet-pushed segment that can be pushed, in the limits of `checkedRange`. - * This includes segments which have not been loaded or pushed yet, but also - * segments which might be re-downloaded because currently incomplete in the - * buffer, the point being to know what is the earliest time in the buffer where - * a segment might be pushed in the future. - * `null` if no segment in `checkedRange` will be pushed under current buffer's - * conditions. - * @param {boolean} hasFinishedLoading - if `true`, all segments for the current - * Period have been loaded and none will be loaded in the future under the - * current buffer's state. - * @param {Array.} bufferedSegments - Information about every segments - * currently in the buffer, in chronological order. - * Only segments overlapping with the given `checkedRange` will be looked at, - * though the array given can be larger. + * Translate a color indicated in TTML-style to a CSS-style color. + * @param {string} color + * @returns {string} color */ -function checkForDiscontinuity(content, checkedRange, nextSegmentStart, hasFinishedLoading, bufferedSegments) { - var period = content.period, - adaptation = content.adaptation, - representation = content.representation; // `bufferedSegments` might also contains segments which are before - // `checkedRange`. - // Here we want the first one that goes over `checkedRange.start`, to see - // if there's a discontinuity at the beginning in the buffer - - var nextBufferedInRangeIdx = getIndexOfFirstChunkInRange(bufferedSegments, checkedRange); +function ttmlColorToCSSColor(color) { + // TODO check all possible color fomats + var regRes; + regRes = regexps/* REGXP_8_HEX_COLOR.exec */.Dq.exec(color); - if (nextBufferedInRangeIdx === null) { - // There's no segment currently buffered for the current range. - if (nextSegmentStart === null) { - // No segment to load in that range - // Check if we are in a discontinuity at the end of the current Period - if (hasFinishedLoading && period.end !== undefined && checkedRange.end >= period.end) { - return { - start: undefined, - end: null - }; // discontinuity to Period's end - } // Check that there is a discontinuity announced in the Manifest there + if (regRes != null) { + return "rgba(" + String(parseInt(regRes[1], 16)) + "," + String(parseInt(regRes[2], 16)) + "," + String(parseInt(regRes[3], 16)) + "," + String(parseInt(regRes[4], 16) / 255) + ")"; + } + regRes = regexps/* REGXP_4_HEX_COLOR.exec */.YU.exec(color); - var discontinuityEnd = representation.index.checkDiscontinuity(checkedRange.start); + if (regRes != null) { + return "rgba(" + String(parseInt(regRes[1] + regRes[1], 16)) + "," + String(parseInt(regRes[2] + regRes[2], 16)) + "," + String(parseInt(regRes[3] + regRes[3], 16)) + "," + String(parseInt(regRes[4] + regRes[4], 16) / 255) + ")"; + } - if (discontinuityEnd !== null) { - return { - start: undefined, - end: discontinuityEnd - }; - } - } + regRes = regexps/* REGXP_RGB_COLOR.exec */.GK.exec(color); - return null; + if (regRes != null) { + return "rgb(" + String(+regRes[1]) + "," + String(+regRes[2]) + "," + String(+regRes[3]) + ")"; } - var nextBufferedSegment = bufferedSegments[nextBufferedInRangeIdx]; // Check if there is a hole that won't be filled before `nextSegmentStart` - - if ( // Next buffered segment starts after the start of the current range - nextBufferedSegment.bufferedStart !== undefined && nextBufferedSegment.bufferedStart > checkedRange.start && ( // and no segment will fill in that hole - nextSegmentStart === null || nextBufferedSegment.infos.segment.end <= nextSegmentStart)) { - log/* default.debug */.Z.debug("RS: current discontinuity encountered", adaptation.type, nextBufferedSegment.bufferedStart); - return { - start: undefined, - end: nextBufferedSegment.bufferedStart - }; - } // Check if there's a discontinuity BETWEEN segments of the current range + regRes = regexps/* REGXP_RGBA_COLOR.exec */.ev.exec(color); + if (regRes != null) { + return "rgba(" + String(+regRes[1]) + "," + String(+regRes[2]) + "," + String(+regRes[3]) + "," + String(+regRes[4] / 255) + ")"; + } - var nextHoleIdx = getIndexOfFirstDiscontinuityBetweenChunks(bufferedSegments, checkedRange, nextBufferedInRangeIdx + 1); // If there was a hole between two consecutives segments, and if this hole - // comes before the next segment to load, there is a discontinuity (that hole!) + return color; +} +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/create_element.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. + */ - if (nextHoleIdx !== null && (nextSegmentStart === null || bufferedSegments[nextHoleIdx].infos.segment.end <= nextSegmentStart)) { - var start = bufferedSegments[nextHoleIdx - 1].bufferedEnd; - var end = bufferedSegments[nextHoleIdx].bufferedStart; - log/* default.debug */.Z.debug("RS: future discontinuity encountered", adaptation.type, start, end); - return { - start: start, - end: end - }; - } else if (nextSegmentStart === null) { - // If no hole between segments and no segment to load, check for a - // discontinuity at the end of the Period - if (hasFinishedLoading && period.end !== undefined) { - // Period is finished - if (checkedRange.end < period.end) { - // We've not reached the Period's end yet - return null; - } // Check if the last buffered segment ends before this Period's end - // In which case there is a discontinuity between those - var lastBufferedInPeriodIdx = getIndexOfLastChunkInPeriod(bufferedSegments, period.end); - if (lastBufferedInPeriodIdx !== null) { - var lastSegment = bufferedSegments[lastBufferedInPeriodIdx]; - if (lastSegment.bufferedEnd !== undefined && lastSegment.bufferedEnd < period.end) { - log/* default.debug */.Z.debug("RS: discontinuity encountered at the end of the current period", adaptation.type, lastSegment.bufferedEnd, period.end); - return { - start: lastSegment.bufferedEnd, - end: null - }; - } - } - } // At last, check if we don't have a discontinuity at the end of the current - // range, announced in the Manifest, that is too big to be detected through - // the previous checks. - if (period.end !== undefined && checkedRange.end >= period.end) { - return null; // The previous checks should have taken care of those - } - for (var bufIdx = bufferedSegments.length - 1; bufIdx >= 0; bufIdx--) { - var bufSeg = bufferedSegments[bufIdx]; - if (bufSeg.bufferedStart === undefined) { - break; - } - if (bufSeg.bufferedStart < checkedRange.end) { - if (bufSeg.bufferedEnd !== undefined && bufSeg.bufferedEnd < checkedRange.end) { - var _discontinuityEnd = representation.index.checkDiscontinuity(checkedRange.end); - if (_discontinuityEnd !== null) { - return { - start: bufSeg.bufferedEnd, - end: _discontinuityEnd - }; - } - } + // Styling which can be applied to from any level upper. +// Added here as an optimization - return null; - } - } - } +var SPAN_LEVEL_ATTRIBUTES = ["color", "direction", "display", "fontFamily", "fontSize", "fontStyle", "fontWeight", "textDecoration", "textOutline", "unicodeBidi", "visibility", "wrapOption"]; // TODO +// tts:showBackground (applies to region) +// tts:zIndex (applies to region) - return null; -} /** - * Returns the index of the first element in `bufferedChunks` that is part of - * `range` (starts before it ends and ends after it starts). - * - * Returns `null` if no element is found in that range or if we cannot know the - * index of the first element in it. - * @param {Array.} bufferedChunks - * @param {Object} range - * @returns {number|null} + * Apply style set for a singular text span of the current cue. + * @param {HTMLElement} element - The text span + * @param {Object} style - The style to apply */ -function getIndexOfFirstChunkInRange(bufferedChunks, range) { - for (var bufIdx = 0; bufIdx < bufferedChunks.length; bufIdx++) { - var bufSeg = bufferedChunks[bufIdx]; +function applyTextStyle(element, style, shouldTrimWhiteSpace) { + // applies to span + var color = style.color; - if (bufSeg.bufferedStart === undefined || bufSeg.bufferedEnd === undefined || bufSeg.bufferedStart >= range.end) { - return null; - } + if ((0,is_non_empty_string/* default */.Z)(color)) { + element.style.color = ttmlColorToCSSColor(color); + } // applies to body, div, p, region, span - if (bufSeg.bufferedEnd > range.start) { - return bufIdx; - } - } - return null; -} -/** - * Returns the index of the first element in `bufferedChunks` which is not - * immediately consecutive to the one before it. - * - * `startFromIndex` is the index of the first segment that will be checked with - * the element coming before it. As such, it has to be superior to 0. - * - * If the element at `startFromIndex` comes immediately after the one before it, - * the element at `startFromIndex + 1` will be checked instead and so on until a - * segment completely out of `checkedRange` (which starts after it) is detected. - * - * If no hole between elements is found, `null` is returned. - * @param {Array.} bufferedChunks - * @param {Object} range - * @param {number} startFromIndex - * @returns {number|null} - */ + var backgroundColor = style.backgroundColor; + if ((0,is_non_empty_string/* default */.Z)(backgroundColor)) { + element.style.backgroundColor = ttmlColorToCSSColor(backgroundColor); + } // applies to span -function getIndexOfFirstDiscontinuityBetweenChunks(bufferedChunks, range, startFromIndex) { - if (startFromIndex <= 0) { - log/* default.error */.Z.error("RS: Asked to check a discontinuity before the first chunk."); - return null; - } - for (var bufIdx = startFromIndex; bufIdx < bufferedChunks.length; bufIdx++) { - var currSegment = bufferedChunks[bufIdx]; - var prevSegment = bufferedChunks[bufIdx - 1]; // Exit as soon we miss information or when we go further than `checkedRange` + var textOutline = style.textOutline; - if (currSegment.bufferedStart === undefined || prevSegment.bufferedEnd === undefined || currSegment.bufferedStart >= range.end) { - return null; - } // If there is a hole between two consecutive buffered segment + if ((0,is_non_empty_string/* default */.Z)(textOutline)) { + var outlineData = textOutline.trim().replace(/\s+/g, " ").split(" "); + var len = outlineData.length; + if (len === 3) { + var outlineColor = ttmlColorToCSSColor(outlineData[0]); + var thickness = outlineData[1]; + element.style.textShadow = generateCSSTextOutline(outlineColor, thickness); + } else if ((0,is_non_empty_string/* default */.Z)(color) && len === 1) { + var _thickness = outlineData[0]; + element.style.textShadow = generateCSSTextOutline(color, _thickness); + } else if (len === 2) { + var isFirstArgAColor = /^[#A-Z]/i.test(outlineData[0]); + var isFirstArgANumber = /^[0-9]/.test(outlineData[0]); // XOR-ing to be sure we get what we have - if (currSegment.bufferedStart - prevSegment.bufferedEnd > 0) { - return bufIdx; + if (isFirstArgAColor !== isFirstArgANumber) { + if (isFirstArgAColor) { + var _outlineColor = ttmlColorToCSSColor(outlineData[0]); + + var _thickness2 = outlineData[1]; + element.style.textShadow = generateCSSTextOutline(_outlineColor, _thickness2); + } else if ((0,is_non_empty_string/* default */.Z)(color)) { + var _thickness3 = outlineData[0]; + element.style.textShadow = generateCSSTextOutline(color, _thickness3); + } + } } - } + } // applies to span - return null; -} -/** - * Returns the index of the last element in `bufferedChunks` that is part of - * `range` (starts before it ends and ends after it starts). - * - * Returns `null` if no element is found in that range or if we cannot know the - * index of the last element in it. - * @param {Array.} bufferedChunks - * @param {number} periodEnd - * @returns {number|null} - */ + var textDecoration = style.textDecoration; -function getIndexOfLastChunkInPeriod(bufferedChunks, periodEnd) { - for (var bufIdx = bufferedChunks.length - 1; bufIdx >= 0; bufIdx--) { - var bufSeg = bufferedChunks[bufIdx]; + if ((0,is_non_empty_string/* default */.Z)(textDecoration)) { + switch (textDecoration) { + case "noUnderline": + case "noLineThrough": + case "noOverline": + element.style.textDecoration = "none"; + break; - if (bufSeg.bufferedStart === undefined) { - return null; - } + case "lineThrough": + element.style.textDecoration = "line-through"; + break; - if (bufSeg.bufferedStart < periodEnd) { - return bufIdx; + default: + element.style.textDecoration = textDecoration; + break; } - } + } // applies to span - return null; -} -;// CONCATENATED MODULE: ./src/compat/should_append_buffer_after_padding.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. - */ -/** - * When the player decides to load another quality and replace - * currently buffered one, it may append buffer on current playback time. - * - * On Safari, with HSS contents, this provoques green macro-block screens - * during the transition. To avoid this situation, we decide not to load a - * segment if it may be pushed during playback time. We should not buffer - * under a certain padding from the current time. - */ + var fontFamily = style.fontFamily; -var shouldAppendBufferAfterPadding = browser_detection/* isSafari */.G6; -/* harmony default export */ const should_append_buffer_after_padding = (shouldAppendBufferAfterPadding); -// EXTERNAL MODULE: ./src/manifest/are_same_content.ts -var are_same_content = __webpack_require__(5952); -;// CONCATENATED MODULE: ./src/core/stream/representation/get_needed_segments.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. - */ -// eslint-disable-next-line max-len + if ((0,is_non_empty_string/* default */.Z)(fontFamily)) { + switch (fontFamily) { + case "proportionalSansSerif": + element.style.fontFamily = "Arial, Helvetica, Liberation Sans, sans-serif"; + break; + // TODO monospace or sans-serif or font with both? + case "monospaceSansSerif": + case "sansSerif": + element.style.fontFamily = "sans-serif"; + break; + case "monospaceSerif": + case "default": + element.style.fontFamily = "Courier New, Liberation Mono, monospace"; + break; + // TODO font with both? + case "proportionalSerif": + element.style.fontFamily = "serif"; + break; + default: + element.style.fontFamily = fontFamily; + } + } // applies to span -var CONTENT_REPLACEMENT_PADDING = config/* default.CONTENT_REPLACEMENT_PADDING */.Z.CONTENT_REPLACEMENT_PADDING, - BITRATE_REBUFFERING_RATIO = config/* default.BITRATE_REBUFFERING_RATIO */.Z.BITRATE_REBUFFERING_RATIO, - MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT = config/* default.MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT */.Z.MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT, - MINIMUM_SEGMENT_SIZE = config/* default.MINIMUM_SEGMENT_SIZE */.Z.MINIMUM_SEGMENT_SIZE; -/** - * Epsilon compensating for rounding errors when comparing the start and end - * time of multiple segments. - */ -var ROUNDING_ERROR = Math.min(1 / 60, MINIMUM_SEGMENT_SIZE); -/** - * Return the list of segments that can currently be downloaded to fill holes - * in the buffer in the given range, including already-pushed segments currently - * incomplete in the buffer. - * This list might also include already-loaded segments in a higher bitrate, - * according to the given configuration. - * Excludes segment that are already being pushed. - * @param {Object} args - * @returns {Array.} - */ + var fontStyle = style.fontStyle; -function getNeededSegments(_ref) { - var content = _ref.content, - currentPlaybackTime = _ref.currentPlaybackTime, - fastSwitchThreshold = _ref.fastSwitchThreshold, - neededRange = _ref.neededRange, - segmentsBeingPushed = _ref.segmentsBeingPushed, - bufferedSegments = _ref.bufferedSegments; - var representation = content.representation; - var availableSegmentsForRange = representation.index.getSegments(neededRange.start, neededRange.end - neededRange.start); // Remove from `bufferedSegments` any segments we would prefer to replace: - // - segments in the wrong track / bad quality - // - garbage-collected segments + if ((0,is_non_empty_string/* default */.Z)(fontStyle)) { + element.style.fontStyle = fontStyle; + } // applies to span - var segmentsToKeep = bufferedSegments.filter(function (bufferedSegment) { - return !shouldContentBeReplaced(bufferedSegment.infos, content, currentPlaybackTime, fastSwitchThreshold); - }).filter(function (currentSeg, i, consideredSegments) { - var prevSeg = i === 0 ? null : consideredSegments[i - 1]; - var nextSeg = i >= consideredSegments.length - 1 ? null : consideredSegments[i + 1]; - return !isStartGarbageCollected(currentSeg, prevSeg, neededRange.start) && !isEndGarbageCollected(currentSeg, nextSeg, neededRange.end); - }); - var segmentsToDownload = availableSegmentsForRange.filter(function (segment) { - var contentObject = (0,object_assign/* default */.Z)({ - segment: segment - }, content); // First, check that the segment is not already being pushed - if (segmentsBeingPushed.length > 0) { - var isAlreadyBeingPushed = segmentsBeingPushed.some(function (pendingSegment) { - return (0,are_same_content/* default */.Z)(contentObject, pendingSegment); - }); + var fontWeight = style.fontWeight; - if (isAlreadyBeingPushed) { - return false; - } - } + if ((0,is_non_empty_string/* default */.Z)(fontWeight)) { + element.style.fontWeight = fontWeight; + } // applies to span - var duration = segment.duration, - time = segment.time, - end = segment.end; - if (segment.isInit) { - return true; // never skip initialization segments - } + var fontSize = style.fontSize; - if (duration < MINIMUM_SEGMENT_SIZE) { - return false; // too small, don't download - } // Check if the same segment from another Representation is not already - // being pushed. + if ((0,is_non_empty_string/* default */.Z)(fontSize)) { + applyFontSize(element, fontSize); + } else { + addClassName(element, "proportional-style"); + element.setAttribute("data-proportional-font-size", "1"); + } // applies to p, span - if (segmentsBeingPushed.length > 0) { - var waitForPushedSegment = segmentsBeingPushed.some(function (pendingSegment) { - if (pendingSegment.period.id !== content.period.id || pendingSegment.adaptation.id !== content.adaptation.id) { - return false; - } + var direction = style.direction; - var oldSegment = pendingSegment.segment; + if ((0,is_non_empty_string/* default */.Z)(direction)) { + element.style.direction = direction; + } // applies to p, span - if (oldSegment.time - ROUNDING_ERROR > time) { - return false; - } - if (oldSegment.end + ROUNDING_ERROR < end) { - return false; - } + var unicodeBidi = style.unicodeBidi; - return !shouldContentBeReplaced(pendingSegment, contentObject, currentPlaybackTime, fastSwitchThreshold); - }); + if ((0,is_non_empty_string/* default */.Z)(unicodeBidi)) { + switch (unicodeBidi) { + case "bidiOverride": + element.style.unicodeBidi = "bidi-override"; + break; - if (waitForPushedSegment) { - return false; - } - } // check if the segment is already downloaded + case "embed": + element.style.unicodeBidi = "embed"; + break; + default: + element.style.unicodeBidi = "normal"; + } + } // applies to body, div, p, region, span - for (var i = 0; i < segmentsToKeep.length; i++) { - var completeSeg = segmentsToKeep[i]; - var areFromSamePeriod = completeSeg.infos.period.id === content.period.id; // Check if content are from same period, as there can't be overlapping - // periods, we should consider a segment as already downloaded if - // it is from same period (but can be from different adaptation or - // representation) - if (areFromSamePeriod) { - var completeSegInfos = completeSeg.infos.segment; + var visibility = style.visibility; - if (time - completeSegInfos.time > -ROUNDING_ERROR && completeSegInfos.end - end > -ROUNDING_ERROR) { - return false; // already downloaded - } - } - } // check if there is an hole in place of the segment currently + if ((0,is_non_empty_string/* default */.Z)(visibility)) { + element.style.visibility = visibility; + } // applies to body, div, p, region, span - for (var _i = 0; _i < segmentsToKeep.length; _i++) { - var _completeSeg = segmentsToKeep[_i]; + var display = style.display; - if (_completeSeg.end > time) { - // `true` if `completeSeg` starts too far after `time` - return _completeSeg.start > time + ROUNDING_ERROR || // `true` if `completeSeg` ends too soon before `end` - getLastContiguousSegment(segmentsToKeep, _i).end < end - ROUNDING_ERROR; - } - } + if (display === "none") { + element.style.display = "none"; + } // applies to body, div, p, region, span - return true; - }); - return segmentsToDownload; + + var wrapOption = style.wrapOption; + element.style.whiteSpace = wrapOption === "noWrap" ? shouldTrimWhiteSpace ? "nowrap" : "pre" : shouldTrimWhiteSpace ? "normal" : "pre-wrap"; } /** - * From the given array of buffered chunks (`bufferedSegments`) returns the last - * buffered chunk contiguous with the one at the `startIndex` index given. - * @param {Array.} - * @param {number} startIndex - * @returns {Object} + * Apply style for the general text track div. + * @param {HTMLElement} element - The
the style will be applied on. + * @param {Object} style - The general style object of the paragraph. */ -function getLastContiguousSegment(bufferedSegments, startIndex) { - var j = startIndex + 1; // go through all contiguous segments and take the last one - while (j < bufferedSegments.length - 1 && bufferedSegments[j - 1].end + ROUNDING_ERROR > bufferedSegments[j].start) { - j++; - } +function applyGeneralStyle(element, style) { + // Set default text color. It can be overrided by text element color. + element.style.color = "white"; + element.style.position = "absolute"; // applies to tt, region - j--; // index of last contiguous segment + var extent = style.extent; - return bufferedSegments[j]; -} -/** - * Returns `true` if segments linked to the given `oldContent` currently present - * in the buffer should be replaced by segments coming from `currentContent`. - * @param {Object} oldContent - * @param {Object} currentContent - * @param {number} currentPlaybackTime - * @param {number} [fastSwitchThreshold] - * @returns {boolean} - */ + if ((0,is_non_empty_string/* default */.Z)(extent)) { + applyExtent(element, extent); + } // applies to region -function shouldContentBeReplaced(oldContent, currentContent, currentPlaybackTime, fastSwitchThreshold) { - if (oldContent.period.id !== currentContent.period.id) { - return false; // keep segments from another Period by default. - } + var writingMode = style.writingMode; - var segment = oldContent.segment; + if ((0,is_non_empty_string/* default */.Z)(writingMode)) {// TODO + } // applies to region - if (should_append_buffer_after_padding && segment.time < currentPlaybackTime + CONTENT_REPLACEMENT_PADDING) { - return false; - } - if (oldContent.adaptation.id !== currentContent.adaptation.id) { - return true; // replace segments from another Adaptation - } + var overflow = style.overflow; + element.style.overflow = (0,is_non_empty_string/* default */.Z)(overflow) ? overflow : "hidden"; // applies to region - return canFastSwitch(oldContent.representation, currentContent.representation, fastSwitchThreshold); -} -/** - * Returns `true` if segments from the new Representation can replace - * previously-loaded segments from the old Representation given. - * - * This behavior is called "fast-switching". - * @param {Object} oldSegmentRepresentation - * @param {Object} newSegmentRepresentation - * @param {number|undefined} fastSwitchThreshold - * @returns {boolean} - */ + var padding = style.padding; + if ((0,is_non_empty_string/* default */.Z)(padding)) { + applyPadding(element, padding); + } // applies to region -function canFastSwitch(oldSegmentRepresentation, newSegmentRepresentation, fastSwitchThreshold) { - var oldContentBitrate = oldSegmentRepresentation.bitrate; - if (fastSwitchThreshold === undefined) { - // only re-load comparatively-poor bitrates for the same Adaptation. - var bitrateCeil = oldContentBitrate * BITRATE_REBUFFERING_RATIO; - return newSegmentRepresentation.bitrate > bitrateCeil; - } + var origin = style.origin; - return oldContentBitrate < fastSwitchThreshold && newSegmentRepresentation.bitrate > oldContentBitrate; -} -/** - * From buffered segment information, return `true` if the given `currentSeg` - * might have been garbage collected at the start. - * Return `false` if the segment is complete at least from `maximumStartTime`. - * @param {Object} currentSeg - The segment information for the segment in - * question. - * @param {Object|null} prevSeg - The segment information for the previous - * buffered segment, if one (`null` if none). - * @param {number} maximumStartTime - Only consider the data after that time. - * If `currentSeg` has only been garbage collected for some data which is before - * that time, we will return `false`. - */ + if ((0,is_non_empty_string/* default */.Z)(origin)) { + applyOrigin(element, origin); + } // applies to region -function isStartGarbageCollected(currentSeg, prevSeg, maximumStartTime) { - if (currentSeg.bufferedStart === undefined) { - log/* default.warn */.Z.warn("Stream: Start of a segment unknown. " + "Assuming it is garbage collected by default.", currentSeg); - return true; - } + var displayAlign = style.displayAlign; - if (prevSeg !== null && prevSeg.bufferedEnd !== undefined && currentSeg.bufferedStart - prevSeg.bufferedEnd < 0.1) { - return false; - } + if ((0,is_non_empty_string/* default */.Z)(displayAlign)) { + element.style.display = "flex"; + element.style.flexDirection = "column"; - if (maximumStartTime < currentSeg.bufferedStart && currentSeg.bufferedStart - currentSeg.start > MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT) { - log/* default.info */.Z.info("Stream: The start of the wanted segment has been garbage collected", currentSeg); - return true; - } + switch (displayAlign) { + case "before": + element.style.justifyContent = "flex-start"; + break; - return false; -} -/** - * From buffered segment information, return `true` if the given `currentSeg` - * might have been garbage collected at the end. - * Return `false` if the segment is complete at least until `minimumEndTime`. - * @param {Object} currentSeg - The segment information for the segment in - * question. - * @param {Object|null} nextSeg - The segment information for the next buffered - * segment, if one (`null` if none). - * @param {number} minimumEndTime - Only consider the data before that time. - * If `currentSeg` has only been garbage collected for some data which is after - * that time, we will return `false`. - */ + case "center": + element.style.justifyContent = "center"; + break; + case "after": + element.style.justifyContent = "flex-end"; + break; + } + } // applies to region -function isEndGarbageCollected(currentSeg, nextSeg, minimumEndTime) { - if (currentSeg.bufferedEnd === undefined) { - log/* default.warn */.Z.warn("Stream: End of a segment unknown. " + "Assuming it is garbage collected by default.", currentSeg); - return true; - } - if (nextSeg !== null && nextSeg.bufferedStart !== undefined && nextSeg.bufferedStart - currentSeg.bufferedEnd < 0.1) { - return false; - } + var opacity = style.opacity; - if (minimumEndTime > currentSeg.bufferedEnd && currentSeg.end - currentSeg.bufferedEnd > MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT) { - log/* default.info */.Z.info("Stream: The end of the wanted segment has been garbage collected", currentSeg); - return true; - } + if ((0,is_non_empty_string/* default */.Z)(opacity)) { + element.style.opacity = opacity; + } // applies to body, div, p, region, span - return false; + + var visibility = style.visibility; + + if ((0,is_non_empty_string/* default */.Z)(visibility)) { + element.style.visibility = visibility; + } // applies to body, div, p, region, span + + + var display = style.display; + + if (display === "none") { + element.style.display = "none"; + } } -;// CONCATENATED MODULE: ./src/core/stream/representation/get_segment_priority.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. + * Apply style set for a

element + * @param {HTMLElement} element - The

element + * @param {Object} style - The general style object of the paragraph. */ -var SEGMENT_PRIORITIES_STEPS = config/* default.SEGMENT_PRIORITIES_STEPS */.Z.SEGMENT_PRIORITIES_STEPS; -/** - * Calculate the priority number for a given time, in function of the distance - * with the current time. - * - * The lower is this number, the higher should be the priority of the request. - * - * Note that a `timeWanted` given behind the current time will always have the - * highest priority. - * @param {number} timeWanted - * @param {Object} clockTick - * @returns {number} - */ -function getSegmentPriority(timeWanted, clockTick) { - var currentTime = clockTick.position + clockTick.wantedTimeOffset; - var distance = timeWanted - currentTime; +function applyPStyle(element, style) { + element.style.margin = "0px"; // applies to body, div, p, region, span - for (var priority = 0; priority < SEGMENT_PRIORITIES_STEPS.length; priority++) { - if (distance < SEGMENT_PRIORITIES_STEPS[priority]) { - return priority; + var paragraphBackgroundColor = style.backgroundColor; + + if ((0,is_non_empty_string/* default */.Z)(paragraphBackgroundColor)) { + element.style.backgroundColor = ttmlColorToCSSColor(paragraphBackgroundColor); + } // applies to p + + + var lineHeight = style.lineHeight; + + if ((0,is_non_empty_string/* default */.Z)(lineHeight)) { + applyLineHeight(element, lineHeight); + } // applies to p + + + var textAlign = style.textAlign; + + if ((0,is_non_empty_string/* default */.Z)(textAlign)) { + switch (textAlign) { + case "center": + element.style.textAlign = "center"; + break; + + case "left": + case "start": + // TODO check what start means (difference with left, writing direction?) + element.style.textAlign = "left"; + break; + + case "right": + case "end": + // TODO check what end means (difference with right, writing direction?) + element.style.textAlign = "right"; + break; } } - - return SEGMENT_PRIORITIES_STEPS.length; } -;// CONCATENATED MODULE: ./src/core/stream/representation/get_buffer_status.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 + * Creates span of text for the given #text element, with the right style. * - * 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. + * TODO create text elements as string? Might help performances. + * @param {Element} el - the #text element, which text content should be + * displayed + * @param {Object} style - the style object for the given text + * @param {Boolean} shouldTrimWhiteSpace - True if the space should be + * trimmed. + * @returns {HTMLElement} */ +function createTextElement(el, style, shouldTrimWhiteSpace) { + var textElement = document.createElement("span"); + var textContent = el.textContent === null ? "" : el.textContent; + if (shouldTrimWhiteSpace) { + // 1. Trim leading and trailing whitespace. + // 2. Collapse multiple spaces into one. + var trimmed = textContent.trim(); + trimmed = trimmed.replace(/\s+/g, " "); + textContent = trimmed; + } - -var get_buffer_status_MINIMUM_SEGMENT_SIZE = config/* default.MINIMUM_SEGMENT_SIZE */.Z.MINIMUM_SEGMENT_SIZE; + textElement.innerHTML = textContent; + textElement.className = "rxp-texttrack-span"; + applyTextStyle(textElement, style, shouldTrimWhiteSpace); + return textElement; +} /** - * Checks on the current buffered data for the given type and Period - * and returns what should be done to fill the buffer according to the buffer - * goal, the Representation chosen, etc. - * Also emits discontinuities if found, which are parts of the buffer that won't - * be filled by any segment, even in the future. - * - * @param {Object} content - * @param {Object} tick - * @param {number|undefined} fastSwitchThreshold - * @param {number} bufferGoal - * @param {Object} segmentBuffer - * @returns {Object} + * Generate every text elements to display in a given paragraph. + * @param {Element} paragraph - The

tag. + * @param {Array.} regions + * @param {Array.} styles + * @param {Object} paragraphStyle - The general style object of the paragraph. + * @param {Boolean} shouldTrimWhiteSpace + * @returns {Array.} */ -function getBufferStatus(content, tick, fastSwitchThreshold, bufferGoal, segmentBuffer) { - var _a; - var period = content.period, - representation = content.representation; - segmentBuffer.synchronizeInventory(); - var wantedStartPosition = tick.position + tick.wantedTimeOffset; - var wantedEndPosition = wantedStartPosition + bufferGoal; - var neededRange = { - start: Math.max(wantedStartPosition, period.start), - end: Math.min(wantedEndPosition, (_a = period.end) !== null && _a !== void 0 ? _a : Infinity) - }; - var shouldRefreshManifest = representation.index.shouldRefresh(wantedStartPosition, wantedEndPosition); +function generateTextContent(paragraph, regions, styles, paragraphStyle, shouldTrimWhiteSpace) { /** - * Every segment awaiting an "EndOfSegment" operation, which indicates that a - * completely-loaded segment is still being pushed to the SegmentBuffer. - */ - - var segmentsBeingPushed = segmentBuffer.getPendingOperations().filter(function (operation) { - return operation.type === types/* SegmentBufferOperation.EndOfSegment */.f.EndOfSegment; - }).map(function (operation) { - return operation.value; - }); - /** Data on every segments buffered around `neededRange`. */ - - var bufferedSegments = getPlayableBufferedSegments({ - start: Math.max(neededRange.start - 0.5, 0), - end: neededRange.end + 0.5 - }, segmentBuffer.getInventory()); - /** List of segments we will need to download. */ - - var neededSegments = getNeededSegments({ - content: content, - currentPlaybackTime: tick.getCurrentTime(), - fastSwitchThreshold: fastSwitchThreshold, - neededRange: neededRange, - bufferedSegments: bufferedSegments, - segmentsBeingPushed: segmentsBeingPushed - }).map(function (segment) { - return { - priority: getSegmentPriority(segment.time, tick), - segment: segment - }; - }); - /** - * `true` if the current `RepresentationStream` has loaded all the - * needed segments for this Representation until the end of the Period. + * Recursive function, taking a node in argument and returning the + * corresponding array of HTMLElement in order. + * @param {Node} node - the node in question + * @param {Object} style - the current state of the style for the node. + * /!\ The style object can be mutated, provide a copy of it. + * @param {Array.} spans - The spans parent of this node. + * @param {Boolean} shouldTrimWhiteSpaceFromParent - True if the space should be + * trimmed by default. From the parent xml:space parameter. + * @returns {Array.} */ + function loop(node, style, spans, shouldTrimWhiteSpaceFromParent) { + var childNodes = node.childNodes; + var elements = []; - var hasFinishedLoading; - var lastPosition = representation.index.getLastPosition(); - - if (!representation.index.isInitialized() || period.end === undefined || neededSegments.length > 0) { - hasFinishedLoading = false; - } else { - if (lastPosition === undefined) { - // We do not know the end of this index. - // If we reached the end of the period, check that all segments are - // available. - hasFinishedLoading = neededRange.end >= period.end && representation.index.isFinished(); - } else if (lastPosition === null) { - // There is no available segment in the index currently. If the index - // tells us it has finished generating new segments, we're done. - hasFinishedLoading = representation.index.isFinished(); - } else { - // We have a declared end. Check that our range went until the last - // position available in the index. If that's the case and we're left - // with no segments after filtering them, it means we already have - // downloaded the last segments and have nothing left to do: full. - var endOfRange = period.end !== undefined ? Math.min(period.end, lastPosition) : lastPosition; - hasFinishedLoading = neededRange.end >= endOfRange && representation.index.isFinished(); - } - } + for (var i = 0; i < childNodes.length; i++) { + var currentNode = childNodes[i]; - var imminentDiscontinuity; + if (currentNode.nodeName === "#text") { + var _getStylingAttributes = (0,get_styling/* getStylingAttributes */.U)(["backgroundColor"], spans, styles, regions), + backgroundColor = _getStylingAttributes.backgroundColor; - if (!representation.index.isInitialized() || // TODO better handle contents not chronologically generated - !representation.index.areSegmentsChronologicallyGenerated() && !hasFinishedLoading) { - // We might be missing information about future segments - imminentDiscontinuity = null; - } else { - /** - * Start time in seconds of the next available not-yet pushed segment. - * `null` if no segment is wanted for the current wanted range. - */ - var nextSegmentStart = null; + if ((0,is_non_empty_string/* default */.Z)(backgroundColor)) { + style.backgroundColor = backgroundColor; + } else { + delete style.backgroundColor; + } - if (segmentsBeingPushed.length > 0) { - nextSegmentStart = Math.min.apply(Math, segmentsBeingPushed.map(function (info) { - return info.segment.time; - })); - } + var el = createTextElement(currentNode, style, shouldTrimWhiteSpaceFromParent); + elements.push(el); + } else if (currentNode.nodeName === "br") { + var br = document.createElement("BR"); + elements.push(br); + } else if (currentNode.nodeName === "span" && currentNode.nodeType === Node.ELEMENT_NODE && currentNode.childNodes.length > 0) { + var spaceAttribute = currentNode.getAttribute("xml:space"); + var shouldTrimWhiteSpaceOnSpan = (0,is_non_empty_string/* default */.Z)(spaceAttribute) ? spaceAttribute === "default" : shouldTrimWhiteSpaceFromParent; // compute the new applyable style - if (neededSegments.length > 0) { - nextSegmentStart = nextSegmentStart !== null ? Math.min(nextSegmentStart, neededSegments[0].segment.time) : neededSegments[0].segment.time; + var newStyle = (0,object_assign/* default */.Z)({}, style, (0,get_styling/* getStylingAttributes */.U)(SPAN_LEVEL_ATTRIBUTES, [currentNode], styles, regions)); + elements.push.apply(elements, loop(currentNode, newStyle, [currentNode].concat(spans), shouldTrimWhiteSpaceOnSpan)); + } } - imminentDiscontinuity = checkForDiscontinuity(content, neededRange, nextSegmentStart, hasFinishedLoading, bufferedSegments); + return elements; } - return { - imminentDiscontinuity: imminentDiscontinuity, - hasFinishedLoading: hasFinishedLoading, - neededSegments: neededSegments, - shouldRefreshManifest: shouldRefreshManifest - }; + return loop(paragraph, (0,object_assign/* default */.Z)({}, paragraphStyle), [], shouldTrimWhiteSpace); } /** - * From the given SegmentInventory, filters the "playable" (in a supported codec - * and not known to be undecipherable) buffered Segment Objects which overlap - * with the given range. - * @param {Object} neededRange - * @param {Array.} segmentInventory - * @returns {Array.} + * @param {Element} paragraph + * @param {Element} body + * @param {Array.} regions + * @param {Array.} styles + * @param {Object} paragraphStyle + * @param {Object} + * @returns {HTMLElement} */ -function getPlayableBufferedSegments(neededRange, segmentInventory) { - var segmentRoundingError = Math.max(1 / 60, get_buffer_status_MINIMUM_SEGMENT_SIZE); - var minEnd = neededRange.start + segmentRoundingError; - var maxStart = neededRange.end - segmentRoundingError; - var overlappingChunks = []; - for (var i = segmentInventory.length - 1; i >= 0; i--) { - var eltInventory = segmentInventory[i]; - var representation = eltInventory.infos.representation; +function createElement(paragraph, body, regions, styles, paragraphStyle, _ref) { + var cellResolution = _ref.cellResolution, + shouldTrimWhiteSpace = _ref.shouldTrimWhiteSpace; + var divs = (0,get_parent_elements_by_tag_name/* default */.Z)(paragraph, "div"); + var parentElement = document.createElement("DIV"); + parentElement.className = "rxp-texttrack-region"; + parentElement.setAttribute("data-resolution-columns", String(cellResolution.columns)); + parentElement.setAttribute("data-resolution-rows", String(cellResolution.rows)); + applyGeneralStyle(parentElement, paragraphStyle); - if (!eltInventory.partiallyPushed && representation.decipherable !== false && representation.isSupported) { - var inventorySegment = eltInventory.infos.segment; - var eltInventoryStart = inventorySegment.time / inventorySegment.timescale; - var eltInventoryEnd = inventorySegment.duration == null ? eltInventory.end : eltInventoryStart + inventorySegment.duration / inventorySegment.timescale; + if (body !== null) { + // applies to body, div, p, region, span + var _getStylingAttributes2 = (0,get_styling/* getStylingAttributes */.U)(["backgroundColor"], [].concat(divs, [body]), styles, regions), + bodyBackgroundColor = _getStylingAttributes2.bodyBackgroundColor; - if (eltInventoryEnd > minEnd && eltInventoryStart < maxStart || eltInventory.end > minEnd && eltInventory.start < maxStart) { - overlappingChunks.unshift(eltInventory); - } + if ((0,is_non_empty_string/* default */.Z)(bodyBackgroundColor)) { + parentElement.style.backgroundColor = ttmlColorToCSSColor(bodyBackgroundColor); } } - return overlappingChunks; + var pElement = document.createElement("p"); + pElement.className = "rxp-texttrack-p"; + applyPStyle(pElement, paragraphStyle); + var textContent = generateTextContent(paragraph, regions, styles, paragraphStyle, shouldTrimWhiteSpace); + + for (var i = 0; i < textContent.length; i++) { + pElement.appendChild(textContent[i]); + } // NOTE: + // The following code is for the inclusion of div elements. This has no + // advantage for now, and might only with future evolutions. + // (This is only an indication of what the base of the code could look like). + // if (divs.length) { + // let container = parentElement; + // for (let i = divs.length - 1; i >= 0; i--) { + // // TODO manage style at div level? + // // They are: visibility, display and backgroundColor + // // All these do not have any difference if applied to the

element + // // instead of the div. + // // The advantage might only be for multiple

elements dispatched + // // in multiple div Which we do not manage anyway for now. + // const divEl = document.createElement("DIV"); + // divEl.className = "rxp-texttrack-div"; + // container.appendChild(divEl); + // container = divEl; + // } + // container.appendChild(pElement); + // parentElement.appendChild(container); + // } else { + // parentElement.appendChild(pElement); + // } + + + parentElement.appendChild(pElement); + return parentElement; } -;// CONCATENATED MODULE: ./src/core/stream/representation/force_garbage_collection.ts +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/parse_cue.ts /** * Copyright 2015 CANAL+ Group * @@ -19588,96 +19128,45 @@ function getPlayableBufferedSegments(neededRange, segmentInventory) { */ - - - -var GC_GAP_CALM = config/* default.BUFFER_GC_GAPS.CALM */.Z.BUFFER_GC_GAPS.CALM; -var GC_GAP_BEEFY = config/* default.BUFFER_GC_GAPS.BEEFY */.Z.BUFFER_GC_GAPS.BEEFY; -/** - * Run the garbage collector. - * - * Try to clean up buffered ranges from a low gcGap at first. - * If it does not succeed to clean up space, use a higher gcCap. - * - * @param {Observable} timings$ - * @param {Object} bufferingQueue - * @returns {Observable} - */ - -function forceGarbageCollection(timings$, bufferingQueue) { - // wait for next timing event - return timings$.pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.zg)(function (timing) { - log/* default.warn */.Z.warn("Stream: Running garbage collector"); - var buffered = bufferingQueue.getBufferedRanges(); - var cleanedupRanges = selectGCedRanges(timing.position, buffered, GC_GAP_CALM); // more aggressive GC if we could not find any range to clean - - if (cleanedupRanges.length === 0) { - cleanedupRanges = selectGCedRanges(timing.position, buffered, GC_GAP_BEEFY); - } - - log/* default.debug */.Z.debug("Stream: GC cleaning", cleanedupRanges); - return (0,from/* from */.D)(cleanedupRanges.map(function (_ref) { - var start = _ref.start, - end = _ref.end; - return bufferingQueue.removeBuffer(start, end); - })).pipe((0,concatAll/* concatAll */.u)()); - })); -} /** - * Buffer garbage collector algorithm. - * - * Tries to free up some part of the ranges that are distant from the current - * playing time. - * See: https://w3c.github.io/media-source/#sourcebuffer-prepare-append - * - * @param {Number} position - * @param {TimeRanges} buffered - current buffered ranges - * @param {Number} gcGap - delta gap from current timestamp from which we - * should consider cleaning up. - * @returns {Array.} - Ranges selected for clean up + * @param {Object} parsedCue + * @returns {Object|null} */ -function selectGCedRanges(position, buffered, gcGap) { - var _getInnerAndOuterTime = (0,ranges/* getInnerAndOuterTimeRanges */.F_)(buffered, position), - innerRange = _getInnerAndOuterTime.innerRange, - outerRanges = _getInnerAndOuterTime.outerRanges; - - var cleanedupRanges = []; // start by trying to remove all ranges that do not contain the - // current time and respect the gcGap - // respect the gcGap? FIXME? - - for (var i = 0; i < outerRanges.length; i++) { - var outerRange = outerRanges[i]; - - if (position - gcGap < outerRange.end) { - cleanedupRanges.push(outerRange); - } else if (position + gcGap > outerRange.start) { - cleanedupRanges.push(outerRange); - } - } // try to clean up some space in the current range - +function parseCue(parsedCue) { + var paragraph = parsedCue.paragraph, + ttParams = parsedCue.ttParams, + body = parsedCue.body, + regionStyles = parsedCue.regionStyles, + idStyles = parsedCue.idStyles, + paragraphStyle = parsedCue.paragraphStyle, + timeOffset = parsedCue.timeOffset, + shouldTrimWhiteSpace = parsedCue.shouldTrimWhiteSpace; // Disregard empty elements: + // TTML allows for empty elements like
. + // If paragraph has neither time attributes, nor + // non-whitespace text, don't try to make a cue out of it. - if (innerRange != null) { - log/* default.debug */.Z.debug("Stream: GC removing part of inner range", cleanedupRanges); + if (!paragraph.hasAttribute("begin") && !paragraph.hasAttribute("end") && /^\s*$/.test(paragraph.textContent === null ? "" : paragraph.textContent)) { + return null; + } - if (position - gcGap > innerRange.start) { - cleanedupRanges.push({ - start: innerRange.start, - end: position - gcGap - }); - } + var cellResolution = ttParams.cellResolution; - if (position + gcGap < innerRange.end) { - cleanedupRanges.push({ - start: position + gcGap, - end: innerRange.end - }); - } - } + var _getTimeDelimiters = (0,get_time_delimiters/* default */.Z)(paragraph, ttParams), + start = _getTimeDelimiters.start, + end = _getTimeDelimiters.end; - return cleanedupRanges; + var element = createElement(paragraph, body, regionStyles, idStyles, paragraphStyle, { + cellResolution: cellResolution, + shouldTrimWhiteSpace: shouldTrimWhiteSpace + }); + return { + start: start + timeOffset, + end: end + timeOffset, + element: element + }; } -;// CONCATENATED MODULE: ./src/core/stream/representation/append_segment_to_buffer.ts +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/parse_ttml_to_div.ts /** * Copyright 2015 CANAL+ Group * @@ -19694,39 +19183,47 @@ function selectGCedRanges(position, buffered, gcGap) { * limitations under the License. */ + + /** - * This file allows any Stream to push data to a SegmentBuffer. + * Create array of objects which should represent the given TTML text track. + * These objects have the following structure + * - start {Number}: start time, in seconds, at which the cue should + * be displayed + * - end {Number}: end time, in seconds, at which the cue should + * be displayed + * - element {HTMLElement}:
element representing the cue, with the + * right style. This div should then be appended to an element having + * the exact size of the wanted region the text track provide cues for. + * + * TODO TTML parsing is still pretty heavy on the CPU. + * Optimizations have been done, principally to avoid using too much XML APIs, + * but we can still do better. + * @param {string} str + * @param {number} timeOffset */ +function parseTTMLToDiv(str, timeOffset) { + var parsedCues = (0,parse_ttml/* default */.Z)(str, timeOffset); + var cues = []; + for (var i = 0; i < parsedCues.length; i++) { + var paragraphStyle = parsedCues[i].paragraphStyle; + if (shouldApplyDefaultTTMLStyle(paragraphStyle)) { + applyDefaultTTMLStyle(paragraphStyle); + } -/** - * 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} clock$ - * @param {Object} segmentBuffer - * @param {Object} dataInfos - * @returns {Observable} - */ + var cue = parseCue(parsedCues[i]); -function appendSegmentToBuffer(clock$, segmentBuffer, dataInfos) { - var append$ = segmentBuffer.pushChunk(dataInfos); - return append$.pipe((0,catchError/* catchError */.K)(function (appendError) { - if (!(appendError instanceof Error) || appendError.name !== "QuotaExceededError") { - var reason = appendError instanceof Error ? appendError.toString() : "An unknown error happened when pushing content"; - throw new media_error/* default */.Z("BUFFER_APPEND_ERROR", reason); + if (cue !== null) { + cues.push(cue); } + } - return (0,concat/* concat */.z)(forceGarbageCollection(clock$, segmentBuffer).pipe((0,ignoreElements/* ignoreElements */.l)()), append$).pipe((0,catchError/* catchError */.K)(function (forcedGCError) { - var reason = forcedGCError instanceof Error ? forcedGCError.toString() : "Could not clean the buffer"; - throw new media_error/* default */.Z("BUFFER_FULL_ERROR", reason); - })); - })); + return cues; } -;// CONCATENATED MODULE: ./src/core/stream/representation/push_init_segment.ts +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/index.ts /** * Copyright 2015 CANAL+ Group * @@ -19743,47 +19240,38 @@ function appendSegmentToBuffer(clock$, segmentBuffer, dataInfos) { * limitations under the License. */ +/** + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. + */ +/* harmony default export */ const html = (parseTTMLToDiv); +/***/ }), -/** - * 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} - */ +/***/ 1570: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -function pushInitSegment(_ref) { - var clock$ = _ref.clock$, - 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; - } +"use strict"; - var codec = content.representation.getMimeTypeString(); - var data = { - initSegment: segmentData, - chunk: null, - timestampOffset: 0, - appendWindow: [undefined, undefined], - codec: codec - }; - return appendSegmentToBuffer(clock$, segmentBuffer, { - data: data, - inventoryInfos: null - }).pipe((0,map/* map */.U)(function () { - var buffered = segmentBuffer.getBufferedRanges(); - return stream_events_generators.addedSegment(content, segment, buffered, segmentData); - })); - }); -} -;// CONCATENATED MODULE: ./src/core/stream/representation/push_media_segment.ts +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ ttml_native) +}); + +// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/parse_ttml.ts + 3 modules +var parse_ttml = __webpack_require__(5403); +// EXTERNAL MODULE: ./src/compat/make_vtt_cue.ts +var make_vtt_cue = __webpack_require__(7253); +// EXTERNAL MODULE: ./src/compat/is_vtt_cue.ts +var is_vtt_cue = __webpack_require__(1988); +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/get_time_delimiters.ts + 1 modules +var get_time_delimiters = __webpack_require__(6177); +// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/regexps.ts +var regexps = __webpack_require__(5336); +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/native/parse_cue.ts /** * Copyright 2015 CANAL+ Group * @@ -19803,444 +19291,209 @@ function pushInitSegment(_ref) { +var TEXT_ALIGN_TO_LIGN_ALIGN = { + left: "start", + center: "center", + right: "end", + start: "start", + end: "end" +}; +/** + * @type {Object} + */ - -var APPEND_WINDOW_SECURITIES = config/* default.APPEND_WINDOW_SECURITIES */.Z.APPEND_WINDOW_SECURITIES; +var TEXT_ALIGN_TO_POSITION_ALIGN = { + left: "line-left", + center: "center", + right: "line-right" +}; /** - * 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} + * Parses an Element into a TextTrackCue or VTTCue. + * /!\ Mutates the given cueElement Element + * @param {Element} paragraph + * @param {Number} offset + * @param {Array.} styles + * @param {Array.} regions + * @param {Object} paragraphStyle + * @param {Object} ttParams + * @param {Boolean} shouldTrimWhiteSpace + * @returns {TextTrackCue|null} */ -function pushMediaSegment(_ref) { - var clock$ = _ref.clock$, - content = _ref.content, - initSegmentData = _ref.initSegmentData, - parsedSegment = _ref.parsedSegment, - segment = _ref.segment, - segmentBuffer = _ref.segmentBuffer; - return (0,defer/* defer */.P)(function () { - var _a, _b; +function parseCue(parsedCue) { + var paragraph = parsedCue.paragraph, + timeOffset = parsedCue.timeOffset, + paragraphStyle = parsedCue.paragraphStyle, + ttParams = parsedCue.ttParams, + shouldTrimWhiteSpace = parsedCue.shouldTrimWhiteSpace; // Disregard empty elements: + // TTML allows for empty elements like
. + // If paragraph has neither time attributes, nor + // non-whitespace text, don't try to make a cue out of it. - if (parsedSegment.chunkData === null) { - return empty/* EMPTY */.E; - } + if (!paragraph.hasAttribute("begin") && !paragraph.hasAttribute("end") && /^\s*$/.test(paragraph.textContent === null ? "" : paragraph.textContent)) { + return null; + } - var chunkData = parsedSegment.chunkData, - chunkInfos = parsedSegment.chunkInfos, - chunkOffset = parsedSegment.chunkOffset, - appendWindow = parsedSegment.appendWindow; - var codec = content.representation.getMimeTypeString(); // 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 _getTimeDelimiters = (0,get_time_delimiters/* default */.Z)(paragraph, ttParams), + start = _getTimeDelimiters.start, + end = _getTimeDelimiters.end; - 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; + var text = generateTextContent(paragraph, shouldTrimWhiteSpace); + var cue = (0,make_vtt_cue/* default */.Z)(start + timeOffset, end + timeOffset, text); - if (safeAppendWindow[0] !== undefined) { - estimatedStart = Math.max(estimatedStart, safeAppendWindow[0]); - } + if (cue === null) { + return null; + } - if (safeAppendWindow[1] !== undefined) { - estimatedEnd = Math.min(estimatedEnd, safeAppendWindow[1]); - } + if ((0,is_vtt_cue/* default */.Z)(cue)) { + addStyle(cue, paragraphStyle); + } - var inventoryInfos = (0,object_assign/* default */.Z)({ - segment: segment, - start: estimatedStart, - end: estimatedEnd - }, content); - return appendSegmentToBuffer(clock$, segmentBuffer, { - data: data, - inventoryInfos: inventoryInfos - }).pipe((0,map/* map */.U)(function () { - var buffered = segmentBuffer.getBufferedRanges(); - return stream_events_generators.addedSegment(content, segment, buffered, chunkData); - })); - }); + return cue; } -;// CONCATENATED MODULE: ./src/core/stream/representation/representation_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. - */ - -/** - * This file allows to create RepresentationStreams. - * - * A RepresentationStream downloads and push segment for a single - * Representation (e.g. a single video stream of a given quality). - * It chooses which segments should be downloaded according to the current - * position and what is currently buffered. - */ - - - - - - - - - - - /** - * Build up buffer for a single Representation. - * - * Download and push segments linked to the given Representation according - * to what is already in the SegmentBuffer and where the playback currently is. - * - * Multiple RepresentationStream observables can run on the same SegmentBuffer. - * This allows for example smooth transitions between multiple periods. - * - * @param {Object} args - * @returns {Observable} + * Generate text to display for a given paragraph. + * @param {Element} paragraph - The

tag. + * @param {Boolean} shouldTrimWhiteSpaceForParagraph + * @returns {string} */ -function RepresentationStream(_ref) { - var bufferGoal$ = _ref.bufferGoal$, - clock$ = _ref.clock$, - content = _ref.content, - fastSwitchThreshold$ = _ref.fastSwitchThreshold$, - segmentBuffer = _ref.segmentBuffer, - segmentFetcher = _ref.segmentFetcher, - terminate$ = _ref.terminate$; - var manifest = content.manifest, - period = content.period, - adaptation = content.adaptation, - representation = content.representation; - var bufferType = adaptation.type; - var initSegment = representation.index.getInitSegment(); +function generateTextContent(paragraph, shouldTrimWhiteSpaceForParagraph) { /** - * Saved initialization segment state for this representation. - * `null` if the initialization segment hasn't been loaded yet. + * Recursive function, taking a node in argument and returning the + * corresponding string. + * @param {Node} node - the node in question + * @returns {string} */ + function loop(node, shouldTrimWhiteSpaceFromParent) { + var childNodes = node.childNodes; + var text = ""; - var initSegmentObject = initSegment === null ? { - initializationData: null, - segmentProtections: [], - initTimescale: undefined - } : null; - /** Segments queued for download in this RepresentationStream. */ + for (var i = 0; i < childNodes.length; i++) { + var currentNode = childNodes[i]; - var downloadQueue = []; - /** Emit to start/restart a downloading Queue. */ + if (currentNode.nodeName === "#text") { + var textContent = currentNode.textContent; - var startDownloadingQueue$ = new ReplaySubject/* ReplaySubject */.t(1); - /** Emit when the RepresentationStream asks to re-check which segments are needed. */ + if (textContent === null) { + textContent = ""; + } - var reCheckNeededSegments$ = new Subject/* Subject */.xQ(); - /** - * Keep track of the information about the pending segment request. - * `null` if no segment request is pending in that RepresentationStream. - */ + if (shouldTrimWhiteSpaceFromParent) { + // 1. Trim leading and trailing whitespace. + // 2. Collapse multiple spaces into one. + var trimmed = textContent.trim(); + trimmed = trimmed.replace(/\s+/g, " "); + textContent = trimmed; + } // DOM Parser turns HTML escape caracters into caracters, + // that may be misinterpreted by VTTCue API (typically, less-than sign + // and greater-than sign can be interpreted as HTML tags signs). + // Original escaped caracters must be conserved. - var currentSegmentRequest = null; - var status$ = (0,combineLatest/* combineLatest */.aj)([clock$, bufferGoal$, terminate$.pipe((0,take/* take */.q)(1), (0,startWith/* startWith */.O)(null)), reCheckNeededSegments$.pipe((0,startWith/* startWith */.O)(undefined))]).pipe(withLatestFrom(fastSwitchThreshold$), (0,mergeMap/* mergeMap */.zg)(function (_ref2) { - var _ref2$ = _ref2[0], - tick = _ref2$[0], - bufferGoal = _ref2$[1], - terminate = _ref2$[2], - fastSwitchThreshold = _ref2[1]; - var status = getBufferStatus(content, tick, fastSwitchThreshold, bufferGoal, segmentBuffer); - var neededSegments = status.neededSegments; // Add initialization segment if required - if (!representation.index.isInitialized()) { - if (initSegment === null) { - log/* default.warn */.Z.warn("Stream: Uninitialized index without an initialization segment"); - } else if (initSegmentObject !== null) { - log/* default.warn */.Z.warn("Stream: Uninitialized index with an already loaded " + "initialization segment"); - } else { - neededSegments.unshift({ - segment: initSegment, - priority: getSegmentPriority(period.start, tick) - }); + var escapedTextContent = textContent.replace(/&|\u0026/g, "&").replace(/<|\u003C/g, "<").replace(/>|\u2265/g, ">").replace(/\u200E/g, "‎").replace(/\u200F/g, "‏").replace(/\u00A0/g, " "); + text += escapedTextContent; + } else if (currentNode.nodeName === "br") { + text += "\n"; + } else if (currentNode.nodeName === "span" && currentNode.nodeType === Node.ELEMENT_NODE && currentNode.childNodes.length > 0) { + var spaceAttribute = currentNode.getAttribute("xml:space"); + var shouldTrimWhiteSpaceForSpan = (0,is_non_empty_string/* default */.Z)(spaceAttribute) ? spaceAttribute === "default" : shouldTrimWhiteSpaceFromParent; + text += loop(currentNode, shouldTrimWhiteSpaceForSpan); } - } else if (neededSegments.length > 0 && initSegment !== null && initSegmentObject === null) { - // prepend initialization segment - var initSegmentPriority = neededSegments[0].priority; - neededSegments.unshift({ - segment: initSegment, - priority: initSegmentPriority - }); } - var mostNeededSegment = neededSegments[0]; - - if (terminate !== null) { - downloadQueue = []; - - if (terminate.urgent) { - log/* default.debug */.Z.debug("Stream: urgent termination request, terminate.", bufferType); - startDownloadingQueue$.complete(); // complete the downloading queue - - return (0,of.of)(stream_events_generators.streamTerminating()); - } else if (currentSegmentRequest === null) { - log/* default.debug */.Z.debug("Stream: no request, terminate.", bufferType); - startDownloadingQueue$.complete(); // complete the downloading queue - - return (0,of.of)(stream_events_generators.streamTerminating()); - } else if (mostNeededSegment === undefined || currentSegmentRequest.segment.id !== mostNeededSegment.segment.id) { - log/* default.debug */.Z.debug("Stream: cancel request and terminate.", bufferType); - startDownloadingQueue$.next(); // interrupt the current request + return text; + } - startDownloadingQueue$.complete(); // complete the downloading queue + return loop(paragraph, shouldTrimWhiteSpaceForParagraph); +} +/** + * Adds applicable style properties to a cue. + * /!\ Mutates cue argument. + * @param {VTTCue} cue + * @param {Object} style + */ - return (0,of.of)(stream_events_generators.streamTerminating()); - } else if (currentSegmentRequest.priority !== mostNeededSegment.priority) { - var _currentSegmentReques = currentSegmentRequest, - request$ = _currentSegmentReques.request$; - currentSegmentRequest.priority = mostNeededSegment.priority; - segmentFetcher.updatePriority(request$, mostNeededSegment.priority); - } - log/* default.debug */.Z.debug("Stream: terminate after request.", bufferType); - } else if (mostNeededSegment === undefined) { - if (currentSegmentRequest !== null) { - log/* default.debug */.Z.debug("Stream: interrupt segment request.", bufferType); - } +function addStyle(cue, style) { + var extent = style.extent; - downloadQueue = []; - startDownloadingQueue$.next(); // (re-)start with an empty queue - } else if (currentSegmentRequest === null) { - log/* default.debug */.Z.debug("Stream: start downloading queue.", bufferType); - downloadQueue = neededSegments; - startDownloadingQueue$.next(); // restart the queue - } else if (currentSegmentRequest.segment.id !== mostNeededSegment.segment.id) { - log/* default.debug */.Z.debug("Stream: restart download queue.", bufferType); - downloadQueue = neededSegments; - startDownloadingQueue$.next(); // restart the queue - } else if (currentSegmentRequest.priority !== mostNeededSegment.priority) { - log/* default.debug */.Z.debug("Stream: update request priority.", bufferType); - var _currentSegmentReques2 = currentSegmentRequest, - _request$ = _currentSegmentReques2.request$; - currentSegmentRequest.priority = mostNeededSegment.priority; - segmentFetcher.updatePriority(_request$, mostNeededSegment.priority); - } else { - log/* default.debug */.Z.debug("Stream: update downloading queue", bufferType); // Update the previous queue to be all needed segments but the first one, - // for which a request is already pending + if ((0,is_non_empty_string/* default */.Z)(extent)) { + var results = regexps/* REGXP_PERCENT_VALUES.exec */._0.exec(extent); - downloadQueue = neededSegments.slice().splice(1, neededSegments.length); + if (results != null) { + // Use width value of the extent attribute for size. + // Height value is ignored. + cue.size = Number(results[1]); } + } - var bufferStatusEvt = (0,of.of)({ - type: "stream-status", - value: { - period: period, - position: tick.position, - bufferType: bufferType, - imminentDiscontinuity: status.imminentDiscontinuity, - hasFinishedLoading: status.hasFinishedLoading, - neededSegments: status.neededSegments - } - }); - return status.shouldRefreshManifest ? (0,concat/* concat */.z)((0,of.of)(stream_events_generators.needsManifestRefresh()), bufferStatusEvt) : bufferStatusEvt; - }), takeWhile(function (e) { - return e.type !== "stream-terminating"; - }, true)); - /** - * Stream Queue: - * - download every segments queued sequentially - * - when a segment is loaded, append it to the SegmentBuffer - */ - - var streamQueue$ = startDownloadingQueue$.pipe((0,switchMap/* switchMap */.w)(function () { - return downloadQueue.length > 0 ? loadSegmentsFromQueue() : empty/* EMPTY */.E; - }), (0,mergeMap/* mergeMap */.zg)(onLoaderEvent)); - return (0,merge/* merge */.T)(status$, streamQueue$).pipe((0,share/* share */.B)()); - /** - * Request every Segment in the ``downloadQueue`` on subscription. - * Emit the data of a segment when a request succeeded. - * - * Important side-effects: - * - Mutates `currentSegmentRequest` when doing and finishing a request. - * - Will emit from reCheckNeededSegments$ Subject when it's done. - * - * Might emit warnings when a request is retried. - * - * Throws when the request will not be retried (configuration or un-retryable - * error). - * @returns {Observable} - */ - - function loadSegmentsFromQueue() { - var requestNextSegment$ = (0,defer/* defer */.P)(function () { - var currentNeededSegment = downloadQueue.shift(); - - if (currentNeededSegment === undefined) { - next_tick_default()(function () { - reCheckNeededSegments$.next(); - }); - return empty/* EMPTY */.E; - } - - var segment = currentNeededSegment.segment, - priority = currentNeededSegment.priority; - var context = { - manifest: manifest, - period: period, - adaptation: adaptation, - representation: representation, - segment: segment - }; - var request$ = segmentFetcher.createRequest(context, priority); - currentSegmentRequest = { - segment: segment, - priority: priority, - request$: request$ - }; - return request$.pipe((0,mergeMap/* mergeMap */.zg)(function (evt) { - switch (evt.type) { - case "warning": - return (0,of.of)({ - type: "retry", - value: { - segment: segment, - error: evt.value - } - }); - - case "chunk-complete": - currentSegmentRequest = null; - return (0,of.of)({ - type: "end-of-segment", - value: { - segment: segment - } - }); - - case "interrupted": - log/* default.info */.Z.info("Stream: segment request interrupted temporarly.", segment); - return empty/* EMPTY */.E; + var writingMode = style.writingMode; // let isVerticalText = true; - case "chunk": - var initTimescale = initSegmentObject === null || initSegmentObject === void 0 ? void 0 : initSegmentObject.initTimescale; - return evt.parse(initTimescale).pipe((0,map/* map */.U)(function (parserResponse) { - return (0,object_assign/* default */.Z)({ - segment: segment - }, parserResponse); - })); + switch (writingMode) { + case "tb": + case "tblr": + cue.vertical = "lr"; + break; - case "ended": - return requestNextSegment$; + case "tbrl": + cue.vertical = "rl"; + break; - default: - (0,assert_unreachable/* default */.Z)(evt); - } - })); - }); - return requestNextSegment$.pipe(finalize(function () { - currentSegmentRequest = null; - })); + default: + // isVerticalText = false; + break; } - /** - * React to event from `loadSegmentsFromQueue`. - * @param {Object} evt - * @returns {Observable} - */ - - - function onLoaderEvent(evt) { - var _a; - 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; + var origin = style.origin; - if (index.isSegmentStillAvailable(retriedSegment) === false) { - reCheckNeededSegments$.next(); - } else if (index.canBeOutOfSyncError(evt.value.error, retriedSegment)) { - return (0,of.of)(stream_events_generators.manifestMightBeOufOfSync()); - } + if ((0,is_non_empty_string/* default */.Z)(origin)) { + var _results = regexps/* REGXP_PERCENT_VALUES.exec */._0.exec(origin); - return empty/* EMPTY */.E; // else, ignore. - })); + if (_results != null) {// for vertical text use first coordinate of tts:origin + // to represent line of the cue and second - for position. + // Otherwise (horizontal), use them the other way around. + // if (isVerticalText) { + // TODO check and uncomment + // cue.position = Number(results[2]); + // cue.line = Number(results[1]); + // } else { + // TODO check and uncomment + // cue.position = Number(results[1]); + // cue.line = Number(results[2]); + // } + // A boolean indicating whether the line is an integer + // number of lines (using the line dimensions of the first + // line of the cue), or whether it is a percentage of the + // dimension of the video. The flag is set to true when lines + // are counted, and false otherwise. + // TODO check and uncomment + // cue.snapToLines = false; + } + } - case "parsed-init-segment": - initSegmentObject = evt.value; - var protectedEvents$ = of.of.apply(void 0, evt.value.segmentProtections.map(function (segmentProt) { - return stream_events_generators.protectedSegment(segmentProt); - })); - var pushEvent$ = pushInitSegment({ - clock$: clock$, - content: content, - segment: evt.segment, - segmentData: evt.value.initializationData, - segmentBuffer: segmentBuffer - }); - return (0,merge/* merge */.T)(protectedEvents$, pushEvent$); + var align = style.align; - case "parsed-segment": - var initSegmentData = (_a = initSegmentObject === null || initSegmentObject === void 0 ? void 0 : initSegmentObject.initializationData) !== null && _a !== void 0 ? _a : null; - return pushMediaSegment({ - clock$: clock$, - content: content, - initSegmentData: initSegmentData, - parsedSegment: evt.value, - segment: evt.segment, - segmentBuffer: segmentBuffer - }); + if ((0,is_non_empty_string/* default */.Z)(align)) { + cue.align = align; - case "end-of-segment": - { - var segment = evt.value.segment; - return segmentBuffer.endOfSegment((0,object_assign/* default */.Z)({ - segment: segment - }, content)).pipe((0,ignoreElements/* ignoreElements */.l)()); - } + if (align === "center") { + if (cue.align !== "center") { + // Workaround for a Chrome bug http://crbug.com/663797 + // Chrome does not support align = "center" + cue.align = "middle"; + } - default: - (0,assert_unreachable/* default */.Z)(evt); + cue.position = "auto"; } + + var positionAlign = TEXT_ALIGN_TO_POSITION_ALIGN[align]; + cue.positionAlign = positionAlign === undefined ? "" : positionAlign; + var lineAlign = TEXT_ALIGN_TO_LIGN_ALIGN[align]; + cue.lineAlign = lineAlign === undefined ? "" : lineAlign; } } -;// CONCATENATED MODULE: ./src/core/stream/representation/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 */ const stream_representation = (RepresentationStream); -;// CONCATENATED MODULE: ./src/core/stream/utils.ts +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/native/parse_ttml_to_vtt.ts /** * Copyright 2015 CANAL+ Group * @@ -20258,64 +19511,27 @@ function RepresentationStream(_ref) { */ - /** - * Switching to another `Adaptation` and or `Representation` can necessitate a - * complete reload of the MediaSource. - * - * This is done through the `INeedsMediaSourceReload` event which among other - * things indicate the position the player should seek to after "reloading". - * That position depends on the playback conditions at the time of the switch. - * - * When you already know you have to reload, you can call this function to take - * care of that complex behavior: - * - * - If `period` is not being played when that function is called, this - * function will emit regularly the `INeedsMediaSourceReload` event after - * applying the given `deltaPos` value to the reloading position. - * - * - If `period` is not being when that function is called, it emits regularly - * the `INeedsMediaSourceReload` without applying the given `deltaPos` value - * to the reloading position. - * This is because that value is only applied when the previous Adaptation - * or Representation for the current Period was being played and should not - * be for cases like entering the current Period, or seeking _into_ th - * current Period. - * The main point of that configuration variable being to give back some - * context, there is no context to give back on those cases (as the Period - * was not already playing). - * - * @param {Object} period - The Period linked to the Adaptation or - * Representation that you want to switch to. - * @param {Observable} clock$ - Observable emitting 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} + * @param str + * @param timeOffset */ -function reloadAfterSwitch(period, clock$, deltaPos) { - return clock$.pipe((0,take/* take */.q)(1), // only the first (current) event interests us here - (0,mergeMap/* mergeMap */.zg)(function (initialTick) { - var _a; +function parseTtmlToNative(str, timeOffset) { + var parsedCues = (0,parse_ttml/* default */.Z)(str, timeOffset); + var cues = []; - if (period.start <= initialTick.position && (period.end === undefined || period.end > initialTick.position)) { - // if the Period was playing at the time of the switch - var pos = initialTick.getCurrentTime() + deltaPos; - var reloadAt = Math.min(Math.max(period.start, pos), (_a = period.end) !== null && _a !== void 0 ? _a : Infinity); - return (0,of.of)(stream_events_generators.needsMediaSourceReload(period, reloadAt, !initialTick.isPaused)); - } // If the Period was not playing, just ask to reload to the exact same position + for (var i = 0; i < parsedCues.length; i++) { + var parsedCue = parsedCues[i]; + var cue = parseCue(parsedCue); + if (cue !== null) { + cues.push(cue); + } + } - return clock$.pipe((0,map/* map */.U)(function (tick) { - return stream_events_generators.needsMediaSourceReload(period, tick.getCurrentTime(), !tick.isPaused); - })); - })); + return cues; } -;// CONCATENATED MODULE: ./src/core/stream/adaptation/create_representation_estimator.ts +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/native/index.ts /** * Copyright 2015 CANAL+ Group * @@ -20332,52 +19548,34 @@ function reloadAfterSwitch(period, clock$, deltaPos) { * limitations under the License. */ - /** - * Create an "estimator$" Observable which will emit which Representation (from - * the given `Adaptation`) is the best fit (see `IABREstimate` type definition) - * corresponding to the current network and playback conditions. - * - * This function also returns two subjects that should be used to add feedback - * helping the estimator to make its choices: - * - * - `requestFeedback$`: Subject through which information about new requests - * and network metrics should be emitted. - * - * - `streamFeedback$`: Subject through which stream-related events should be - * emitted. - * - * You can look at the types defined for both of those Subjects to have more - * information on what data is expected. The idea is to provide as much data as - * possible so the estimation is as adapted as possible. - * - * @param {Object} adaptation - * @param {Object} abrManager - * @param {Observable} clock$ - * @returns {Object} + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. */ -function createRepresentationEstimator(adaptation, abrManager, clock$) { - var streamFeedback$ = new Subject/* Subject */.xQ(); - var requestFeedback$ = new Subject/* Subject */.xQ(); - var abrEvents$ = (0,merge/* merge */.T)(streamFeedback$, requestFeedback$); - /** Representations for which a `RepresentationStream` can be created. */ +/* harmony default export */ const ttml_native = (parseTtmlToNative); - var playableRepresentations = adaptation.getPlayableRepresentations(); +/***/ }), - if (playableRepresentations.length <= 0) { - var noRepErr = new media_error/* default */.Z("NO_PLAYABLE_REPRESENTATION", "No Representation in the chosen " + "Adaptation can be played"); - throw noRepErr; - } +/***/ 5403: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - var estimator$ = abrManager.get$(adaptation.type, playableRepresentations, clock$, abrEvents$); - return { - estimator$: estimator$, - streamFeedback$: streamFeedback$, - requestFeedback$: requestFeedback$ - }; -} -;// CONCATENATED MODULE: ./src/core/stream/adaptation/adaptation_stream.ts +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ parseTTMLString) +}); + +// EXTERNAL MODULE: ./src/utils/array_find.ts +var array_find = __webpack_require__(3274); +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +// EXTERNAL MODULE: ./src/utils/object_assign.ts +var object_assign = __webpack_require__(8026); +// EXTERNAL MODULE: ./src/log.ts + 1 modules +var log = __webpack_require__(3887); +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/get_parameters.ts /** * Copyright 2015 CANAL+ Group * @@ -20394,240 +19592,98 @@ function createRepresentationEstimator(adaptation, abrManager, clock$) { * 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 - * ABRManager, and orchestrates a RepresentationStream, which will download and - * push segments corresponding to a chosen Representation. - */ - - - - - - - - - -var DELTA_POSITION_AFTER_RELOAD = config/* default.DELTA_POSITION_AFTER_RELOAD */.Z.DELTA_POSITION_AFTER_RELOAD; +var CELL_RESOLUTION_REGEXP = /(\d+) (\d+)/; /** - * Create new AdaptationStream Observable, which task will be to download the - * media data for a given Adaptation (i.e. "track"). - * - * It will rely on the ABRManager 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} + * Returns global parameters from a TTML Document + * @param {Element} tt - node + * @throws Error - Throws if the spacing style is invalid. + * @returns {Object} */ -function AdaptationStream(_ref) { - var abrManager = _ref.abrManager, - clock$ = _ref.clock$, - content = _ref.content, - options = _ref.options, - segmentBuffer = _ref.segmentBuffer, - segmentFetcherCreator = _ref.segmentFetcherCreator, - wantedBufferAhead$ = _ref.wantedBufferAhead$; - var directManualBitrateSwitching = options.manualBitrateSwitchingMode === "direct"; - var manifest = content.manifest, - period = content.period, - adaptation = content.adaptation; - /** - * The buffer goal ratio base itself on the value given by `wantedBufferAhead` - * to determine a more dynamic buffer goal for a given Representation. - * - * It can help in cases such as : the current browser has issues with - * buffering and tells us that we should try to bufferize less data : - * https://developers.google.com/web/updates/2017/10/quotaexceedederror - */ - - var bufferGoalRatioMap = {}; - - var _createRepresentation = createRepresentationEstimator(adaptation, abrManager, clock$), - estimator$ = _createRepresentation.estimator$, - requestFeedback$ = _createRepresentation.requestFeedback$, - streamFeedback$ = _createRepresentation.streamFeedback$; - /** Allows the `RepresentationStream` to easily fetch media segments. */ - - - var segmentFetcher = segmentFetcherCreator.createSegmentFetcher(adaptation.type, requestFeedback$); - /** - * Emits each time an estimate is made through the `abrEstimate$` Observable, - * starting with the last one. - * This allows to easily rely on that value in inner Observables which might also - * need the last already-considered value. - */ - - var lastEstimate$ = new BehaviorSubject(null); - /** Emits abr estimates on Subscription. */ - - var abrEstimate$ = estimator$.pipe((0,tap/* tap */.b)(function (estimate) { - lastEstimate$.next(estimate); - }), (0,defer_subscriptions/* default */.Z)(), (0,share/* share */.B)()); - /** Emit at each bitrate estimate done by the ABRManager. */ - - var bitrateEstimate$ = abrEstimate$.pipe((0,filter/* filter */.h)(function (_ref2) { - var bitrate = _ref2.bitrate; - return bitrate != null; - }), (0,distinctUntilChanged/* distinctUntilChanged */.x)(function (old, current) { - return old.bitrate === current.bitrate; - }), (0,map/* map */.U)(function (_ref3) { - var bitrate = _ref3.bitrate; - log/* default.debug */.Z.debug("Stream: new " + adaptation.type + " bitrate estimate", bitrate); - return stream_events_generators.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)(representationStreams$, bitrateEstimate$); - /** - * Create `RepresentationStream`s starting with the Representation indicated in - * `fromEstimate` argument. - * 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`. - * 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; // A manual bitrate switch might need an immediate feedback. - // To do that properly, we need to reload the MediaSource - - if (directManualBitrateSwitching && fromEstimate.manual && !isFirstEstimate) { - return reloadAfterSwitch(period, clock$, DELTA_POSITION_AFTER_RELOAD.bitrateSwitch); - } - /** - * Emit when the current RepresentationStream should be terminated to make - * place for a new one (e.g. when switching quality). - */ +function getParameters(tt) { + var parsedFrameRate = tt.getAttribute("ttp:frameRate"); + var parsedSubFrameRate = tt.getAttribute("ttp:subFramRate"); + var parsedTickRate = tt.getAttribute("ttp:tickRate"); + var parsedFrameRateMultiplier = tt.getAttribute("ttp:frameRateMultiplier"); + var parsedSpaceStyle = tt.getAttribute("xml:space"); + var parsedCellResolution = tt.getAttribute("ttp:cellResolution"); + var cellResolution = { + columns: 32, + rows: 15 + }; + if (parsedCellResolution !== null) { + var extractedData = CELL_RESOLUTION_REGEXP.exec(parsedCellResolution); - var terminateCurrentStream$ = lastEstimate$.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 - }; - } + if (extractedData === null || extractedData.length < 3) { + log/* default.warn */.Z.warn("TTML Parser: Invalid cellResolution"); + } else { + var columns = parseInt(extractedData[1], 10); + var rows = parseInt(extractedData[2], 10); - if (newEstimate.urgent) { - log/* default.info */.Z.info("Stream: urgent Representation switch", adaptation.type); - return { - urgent: true - }; + if (isNaN(columns) || isNaN(rows)) { + log/* default.warn */.Z.warn("TTML Parser: Invalid cellResolution"); } else { - log/* default.info */.Z.info("Stream: slow Representation switch", adaptation.type); - return { - urgent: false + cellResolution = { + columns: columns, + rows: rows }; } - })); - /** - * "Fast-switching" is a behavior allowing to replace low-quality segments - * (i.e. with a low bitrate) with higher-quality segments (higher bitrate) in - * the buffer. - * This threshold defines a bitrate from which "fast-switching" is disabled. - * For example with a fastSwitchThreshold set to `100`, segments with a - * bitrate of `90` can be replaced. But segments with a bitrate of `100` - * onward won't be replaced by higher quality segments. - * 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$.pipe((0,map/* map */.U)(function (estimate) { - return estimate === null ? undefined : estimate.knownStableBitrate; - }), (0,distinctUntilChanged/* distinctUntilChanged */.x)()); - var representationChange$ = (0,of.of)(stream_events_generators.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 === "representationChange" || evt.type === "added-segment") { - return streamFeedback$.next(evt); - } - }), (0,mergeMap/* mergeMap */.zg)(function (evt) { - if (evt.type === "stream-terminating") { - var lastEstimate = lastEstimate$.getValue(); + } + } - if (lastEstimate === null) { - return empty/* EMPTY */.E; - } + if ((0,is_non_empty_string/* default */.Z)(parsedSpaceStyle) && parsedSpaceStyle !== "default" && parsedSpaceStyle !== "preserve") { + throw new Error("Invalid spacing style"); + } - return recursivelyCreateRepresentationStreams(lastEstimate, false); - } + var nbFrameRate = Number(parsedFrameRate); - return (0,of.of)(evt); - })); + if (isNaN(nbFrameRate) || nbFrameRate <= 0) { + nbFrameRate = 30; } - /** - * Create and returns a new RepresentationStream Observable, linked to the - * given Representation. - * @param {Representation} representation - * @returns {Observable} - */ + var nbSubFrameRate = Number(parsedSubFrameRate); - 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$.pipe((0,map/* map */.U)(function (wba) { - return wba * bufferGoalRatio; - })); - log/* default.info */.Z.info("Stream: changing representation", adaptation.type, representation); - return stream_representation({ - clock$: clock$, - content: { - representation: representation, - adaptation: adaptation, - period: period, - manifest: manifest - }, - segmentBuffer: segmentBuffer, - segmentFetcher: segmentFetcher, - terminate$: terminateCurrentStream$, - bufferGoal$: bufferGoal$, - fastSwitchThreshold$: fastSwitchThreshold$ - }).pipe((0,catchError/* catchError */.K)(function (err) { - var formattedError = formatError(err, { - defaultCode: "NONE", - defaultReason: "Unknown `RepresentationStream` error" - }); + if (isNaN(nbSubFrameRate) || nbSubFrameRate <= 0) { + nbSubFrameRate = 1; + } - if (formattedError.code === "BUFFER_FULL_ERROR") { - var wantedBufferAhead = wantedBufferAhead$.getValue(); - var lastBufferGoalRatio = bufferGoalRatio; + var nbTickRate = Number(parsedTickRate); - if (lastBufferGoalRatio <= 0.25 || wantedBufferAhead * lastBufferGoalRatio <= 2) { - throw formattedError; - } + if (isNaN(nbTickRate) || nbTickRate <= 0) { + nbTickRate = undefined; + } - bufferGoalRatioMap[representation.id] = lastBufferGoalRatio - 0.25; - return createRepresentationStream(representation, terminateCurrentStream$, fastSwitchThreshold$); - } + var frameRate = nbFrameRate; + var subFrameRate = nbSubFrameRate != null ? nbSubFrameRate : 1; + var spaceStyle = parsedSpaceStyle !== null ? parsedSpaceStyle : "default"; + var tickRate = nbTickRate !== undefined ? nbTickRate : nbFrameRate * nbSubFrameRate; - throw formattedError; - })); - }); + if (parsedFrameRateMultiplier !== null) { + var multiplierResults = /^(\d+) (\d+)$/g.exec(parsedFrameRateMultiplier); + + if (multiplierResults !== null) { + var numerator = Number(multiplierResults[1]); + var denominator = Number(multiplierResults[2]); + var multiplierNum = numerator / denominator; + frameRate = nbFrameRate * multiplierNum; + } } + + return { + cellResolution: cellResolution, + tickRate: tickRate, + frameRate: frameRate, + subFrameRate: subFrameRate, + spaceStyle: spaceStyle + }; } -;// CONCATENATED MODULE: ./src/core/stream/adaptation/index.ts +// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/get_parent_elements_by_tag_name.ts +var get_parent_elements_by_tag_name = __webpack_require__(2967); +// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/get_styling.ts +var get_styling = __webpack_require__(3791); +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/nodes.ts /** * Copyright 2015 CANAL+ Group * @@ -20644,68 +19700,47 @@ function AdaptationStream(_ref) { * limitations under the License. */ -/* harmony default export */ const 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. + * @param {Element} tt + * @returns {Element} + */ +function getBodyNode(tt) { + return tt.getElementsByTagName("body")[0]; +} +/** + * @param {Element} tt - node + * @returns {Array.} */ - +function getStyleNodes(tt) { + return tt.getElementsByTagName("style"); +} /** - * 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} streamClock$ - * @param {Observable} wantedBufferAhead$ - * @param {string} bufferType - * @param {Object} content - * @returns {Observable} + * @param {Element} tt - node + * @returns {Array.} */ -function createEmptyAdaptationStream(streamClock$, wantedBufferAhead$, bufferType, content) { - var period = content.period; - var hasFinishedLoading = false; - return (0,combineLatest/* combineLatest */.aj)([streamClock$, wantedBufferAhead$]).pipe((0,mergeMap/* mergeMap */.zg)(function (_ref) { - var clockTick = _ref[0], - wantedBufferAhead = _ref[1]; - var position = clockTick.position; - if (period.end !== undefined && position + wantedBufferAhead >= period.end) { - log/* default.debug */.Z.debug("Stream: full \"empty\" AdaptationStream", bufferType); - hasFinishedLoading = true; - } +function getRegionNodes(tt) { + return tt.getElementsByTagName("region"); +} +/** + * @param {Element} tt - node + * @returns {Array.} + */ - return (0,of.of)({ - type: "stream-status", - value: { - period: period, - bufferType: bufferType, - position: clockTick.position, - imminentDiscontinuity: null, - hasFinishedLoading: hasFinishedLoading, - neededSegments: [], - shouldRefreshManifest: false - } - }); - })); + +function getTextNodes(tt) { + return tt.getElementsByTagName("p"); } -// EXTERNAL MODULE: ./src/utils/starts_with.ts -var starts_with = __webpack_require__(9252); -;// CONCATENATED MODULE: ./src/utils/are_codecs_compatible.ts + + +// EXTERNAL MODULE: ./src/utils/array_find_index.ts +var array_find_index = __webpack_require__(5138); +// EXTERNAL MODULE: ./src/utils/array_includes.ts +var array_includes = __webpack_require__(7714); +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/resolve_styles_inheritance.ts /** * Copyright 2015 CANAL+ Group * @@ -20723,51 +19758,82 @@ var starts_with = __webpack_require__(9252); */ + + /** - * This function is a shortcut that helps differentiate two codecs - * of the form "audio/mp4;codecs=\"av1.40.2\"". + * Transform all styles inheriting from other styles to the same styles but with + * the inheritance removed (by resolving those inheritance here). * - * @param codecA - * @param codecB - * @returns A boolean that tell whether or not those two codecs provided are even. + * Note that the original style object is directly mutated with every + * inheritance they had resolved and removed. + * + * To make a pseudo-code analogy this would be equivalent to transform those + * two classes: + * ``` + * class A { + * methodA() {} + * } + * + * class B extends A { + * method B() {} + * } + * ``` + * into the same two classes without inheritance: + * ``` + * class A { + * methodA() {} + * } + * class B { + * methodA() {} // inherited from class A + * methodB() {} + * } + * ``` + * + * Doing this here allows to simplify further treatment of those styles. + * @param {Array.} styles */ -function areCodecsCompatible(a, b) { - var _a$split = a.split(";"), - mimeTypeA = _a$split[0], - propsA = _a$split.slice(1); +function resolveStylesInheritance(styles) { + // keep track of all the indexes parsed to avoid infinite loops + var recursivelyBrowsedIndexes = []; - var _b$split = b.split(";"), - mimeTypeB = _b$split[0], - propsB = _b$split.slice(1); + function resolveStyleInheritance(styleElt, index) { + recursivelyBrowsedIndexes.push(index); - if (mimeTypeA !== mimeTypeB) { - return false; - } + var _loop = function _loop(j) { + var extendedStyleID = styleElt.extendsStyles[j]; + var extendedStyleIndex = (0,array_find_index/* default */.Z)(styles, function (x) { + return x.id === extendedStyleID; + }); - var codecsA = (0,array_find/* default */.Z)(propsA, function (prop) { - return (0,starts_with/* default */.Z)(prop, "codecs="); - }); - var codecsB = (0,array_find/* default */.Z)(propsB, function (prop) { - return (0,starts_with/* default */.Z)(prop, "codecs="); - }); + if (extendedStyleIndex < 0) { + log/* default.warn */.Z.warn("TTML Parser: unknown style inheritance: " + extendedStyleID); + } else { + var extendedStyle = styles[extendedStyleIndex]; - if (codecsA === undefined || codecsB === undefined) { - return false; - } + if ((0,array_includes/* default */.Z)(recursivelyBrowsedIndexes, extendedStyleIndex)) { + log/* default.warn */.Z.warn("TTML Parser: infinite style inheritance loop avoided"); + } else { + resolveStyleInheritance(extendedStyle, extendedStyleIndex); + } - var codecA = codecsA.substring(7); - var codecB = codecsB.substring(7); + styleElt.style = (0,object_assign/* default */.Z)({}, extendedStyle.style, styleElt.style); + } + }; - if (codecA.split(".")[0] !== codecB.split(".")[0]) { - return false; + for (var j = 0; j < styleElt.extendsStyles.length; j++) { + _loop(j); + } + + styleElt.extendsStyles.length = 0; } - return true; + for (var i = 0; i < styles.length; i++) { + resolveStyleInheritance(styles[i], i); + recursivelyBrowsedIndexes.length = 0; // reset + } } - -/* harmony default export */ const are_codecs_compatible = (areCodecsCompatible); -;// CONCATENATED MODULE: ./src/core/stream/period/get_adaptation_switch_strategy.ts +;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/parse_ttml.ts /** * Copyright 2015 CANAL+ Group * @@ -20786,258 +19852,351 @@ function areCodecsCompatible(a, b) { -var ADAPTATION_SWITCH_BUFFER_PADDINGS = config/* default.ADAPTATION_SWITCH_BUFFER_PADDINGS */.Z.ADAPTATION_SWITCH_BUFFER_PADDINGS; -/** - * Find out what to do when switching Adaptation, based on the current - * situation. - * @param {Object} segmentBuffer - * @param {Object} period - * @param {Object} adaptation - * @param {Object} playbackInfo - * @returns {Object} - */ -function getAdaptationSwitchStrategy(segmentBuffer, period, adaptation, playbackInfo, options) { - if (segmentBuffer.codec !== undefined && options.onCodecSwitch === "reload" && !hasCompatibleCodec(adaptation, segmentBuffer.codec)) { - return { - type: "needs-reload", - value: undefined - }; - } - var buffered = segmentBuffer.getBufferedRanges(); - if (buffered.length === 0) { - return { - type: "continue", - value: undefined - }; - } - var bufferedRanges = (0,ranges/* convertToRanges */.JN)(buffered); - var start = period.start; - var end = period.end == null ? Infinity : period.end; - var intersection = (0,ranges/* keepRangeIntersection */.tn)(bufferedRanges, [{ - start: start, - end: end - }]); - if (intersection.length === 0) { - return { - type: "continue", - value: undefined - }; - } +var STYLE_ATTRIBUTES = ["align", "backgroundColor", "color", "direction", "display", "displayAlign", "extent", "fontFamily", "fontSize", "fontStyle", "fontWeight", "lineHeight", "opacity", "origin", "overflow", "padding", "textAlign", "textDecoration", "textOutline", "unicodeBidi", "visibility", "wrapOption", "writingMode" // Not managed anywhere for now +// "showBackground", +// "zIndex", +]; +/** + * Create array of objects which should represent the given TTML text track. + * TODO TTML parsing is still pretty heavy on the CPU. + * Optimizations have been done, principally to avoid using too much XML APIs, + * but we can still do better. + * @param {string} str + * @param {Number} timeOffset + * @returns {Array.} + */ - segmentBuffer.synchronizeInventory(); - var inventory = segmentBuffer.getInventory(); // Continue if we have no other Adaptation buffered in the current Period +function parseTTMLString(str, timeOffset) { + var cues = []; + var xml = new DOMParser().parseFromString(str, "text/xml"); - if (!inventory.some(function (buf) { - return buf.infos.period.id === period.id && buf.infos.adaptation.id !== adaptation.id; - })) { - return { - type: "continue", - value: undefined - }; - } - /** Data already in the right Adaptation */ + if (xml !== null && xml !== undefined) { + var tts = xml.getElementsByTagName("tt"); + var tt = tts[0]; + if (tt === undefined) { + throw new Error("invalid XML"); + } - var adaptationInBuffer = getBufferedRangesFromAdaptation(inventory, period, adaptation); - /** - * Data different from the wanted Adaptation in the Period's range. - * /!\ Could contain some data at the end of the previous Period or at the - * beginning of the next one. - */ + var body = getBodyNode(tt); + var styleNodes = getStyleNodes(tt); + var regionNodes = getRegionNodes(tt); + var paragraphNodes = getTextNodes(tt); + var ttParams = getParameters(tt); // construct idStyles array based on the xml as an optimization - var unwantedRange = (0,ranges/* excludeFromRanges */.uH)(intersection, adaptationInBuffer); + var idStyles = []; - if (unwantedRange.length === 0) { - return { - type: "continue", - value: undefined - }; - } + for (var i = 0; i <= styleNodes.length - 1; i++) { + var styleNode = styleNodes[i]; - var currentTime = playbackInfo.currentTime; + if (styleNode instanceof Element) { + var styleID = styleNode.getAttribute("xml:id"); - if (adaptation.type === "video" && // We're playing the current Period - (0,ranges/* isTimeInRange */.Ti)({ - start: start, - end: end - }, currentTime) && ( // There is data for the current position or the codecs are differents - playbackInfo.readyState > 1 || !adaptation.getPlayableRepresentations().some(function (rep) { - var _a; + if (styleID !== null) { + var subStyles = styleNode.getAttribute("style"); + var extendsStyles = subStyles === null ? [] : subStyles.split(" "); + idStyles.push({ + id: styleID, + style: (0,get_styling/* getStylingFromElement */.b)(styleNode), + extendsStyles: extendsStyles + }); + } + } + } - return are_codecs_compatible(rep.getMimeTypeString(), (_a = segmentBuffer.codec) !== null && _a !== void 0 ? _a : ""); - })) && // We're not playing the current wanted video Adaptation - !(0,ranges/* isTimeInRanges */.A1)(adaptationInBuffer, currentTime)) { - return { - type: "needs-reload", - value: undefined - }; - } + resolveStylesInheritance(idStyles); // construct regionStyles array based on the xml as an optimization - if (adaptation.type === "audio" && segmentBuffer.codec !== undefined && // We have been explicitly asked to reload - options.audioTrackSwitchingMode === "direct" && // We're playing the current Period - (0,ranges/* isTimeInRange */.Ti)({ - start: start, - end: end - }, currentTime) && ( // There is data for the current position or the codecs are differents - playbackInfo.readyState > 1 || !hasCompatibleCodec(adaptation, segmentBuffer.codec)) && // We're not playing the current wanted audio Adaptation yet - !(0,ranges/* isTimeInRanges */.A1)(adaptationInBuffer, currentTime)) { - return { - type: "needs-reload", - value: undefined - }; - } // From here, clean-up data from the previous Adaptation, if one + var regionStyles = []; + for (var _i = 0; _i <= regionNodes.length - 1; _i++) { + var regionNode = regionNodes[_i]; - var rangesToExclude = []; // First, we don't want to accidentally remove some segments from the previous - // Period (which overlap a little with this one) + if (regionNode instanceof Element) { + var regionID = regionNode.getAttribute("xml:id"); - /** Last segment before one for the current period. */ + if (regionID !== null) { + (function () { + var regionStyle = (0,get_styling/* getStylingFromElement */.b)(regionNode); + var associatedStyleID = regionNode.getAttribute("style"); - var lastSegmentBefore = getLastSegmentBeforePeriod(inventory, period); + if ((0,is_non_empty_string/* default */.Z)(associatedStyleID)) { + var style = (0,array_find/* default */.Z)(idStyles, function (x) { + return x.id === associatedStyleID; + }); - if (lastSegmentBefore !== null && (lastSegmentBefore.bufferedEnd === undefined || period.start - lastSegmentBefore.bufferedEnd < 1)) // Close to Period's start - { - // Exclude data close to the period's start to avoid cleaning - // to much - rangesToExclude.push({ - start: 0, - end: period.start + 1 - }); - } // Next, exclude data around current position to avoid decoding issues + if (style !== undefined) { + regionStyle = (0,object_assign/* default */.Z)({}, style.style, regionStyle); + } + } + regionStyles.push({ + id: regionID, + style: regionStyle, + // already handled + extendsStyles: [] + }); + })(); + } + } + } // Computing the style takes a lot of ressources. + // To avoid too much re-computation, let's compute the body style right + // now and do the rest progressively. + // TODO Compute corresponding CSS style here (as soon as we now the TTML + // style) to speed up the process even more. - var bufferType = adaptation.type; - /** Ranges that won't be cleaned from the current buffer. */ - var paddingBefore = ADAPTATION_SWITCH_BUFFER_PADDINGS[bufferType].before; + var bodyStyle = (0,get_styling/* getStylingAttributes */.U)(STYLE_ATTRIBUTES, body !== null ? [body] : [], idStyles, regionStyles); + var bodySpaceAttribute = body !== null ? body.getAttribute("xml:space") : undefined; + var shouldTrimWhiteSpaceOnBody = bodySpaceAttribute === "default" || ttParams.spaceStyle === "default"; - if (paddingBefore == null) { - paddingBefore = 0; - } + for (var _i2 = 0; _i2 < paragraphNodes.length; _i2++) { + var paragraph = paragraphNodes[_i2]; - var paddingAfter = ADAPTATION_SWITCH_BUFFER_PADDINGS[bufferType].after; + if (paragraph instanceof Element) { + var divs = (0,get_parent_elements_by_tag_name/* default */.Z)(paragraph, "div"); + var paragraphStyle = (0,object_assign/* default */.Z)({}, bodyStyle, (0,get_styling/* getStylingAttributes */.U)(STYLE_ATTRIBUTES, [paragraph].concat(divs), idStyles, regionStyles)); + var paragraphSpaceAttribute = paragraph.getAttribute("xml:space"); + var shouldTrimWhiteSpace = (0,is_non_empty_string/* default */.Z)(paragraphSpaceAttribute) ? paragraphSpaceAttribute === "default" : shouldTrimWhiteSpaceOnBody; + var cue = { + paragraph: paragraph, + timeOffset: timeOffset, + idStyles: idStyles, + regionStyles: regionStyles, + body: body, + paragraphStyle: paragraphStyle, + ttParams: ttParams, + shouldTrimWhiteSpace: shouldTrimWhiteSpace + }; - if (paddingAfter == null) { - paddingAfter = 0; + if (cue !== null) { + cues.push(cue); + } + } + } } - rangesToExclude.push({ - start: currentTime - paddingBefore, - end: currentTime + paddingAfter - }); // Now remove possible small range from the end if there is a segment from the - // next Period + return cues; +} - if (period.end !== undefined) { - /** first segment after for the current period. */ - var firstSegmentAfter = getFirstSegmentAfterPeriod(inventory, period); +/***/ }), - if (firstSegmentAfter !== null && (firstSegmentAfter.bufferedStart === undefined || firstSegmentAfter.bufferedStart - period.end < 1)) // Close to Period's end - { - rangesToExclude.push({ - start: period.end - 1, - end: Number.MAX_VALUE - }); - } - } +/***/ 5336: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - var toRemove = (0,ranges/* excludeFromRanges */.uH)(unwantedRange, rangesToExclude); - return toRemove.length > 0 ? { - type: "clean-buffer", - value: toRemove - } : { - type: "continue", - value: undefined - }; -} +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "YU": () => (/* binding */ REGXP_4_HEX_COLOR), +/* harmony export */ "Dq": () => (/* binding */ REGXP_8_HEX_COLOR), +/* harmony export */ "GK": () => (/* binding */ REGXP_RGB_COLOR), +/* harmony export */ "ev": () => (/* binding */ REGXP_RGBA_COLOR), +/* harmony export */ "eT": () => (/* binding */ REGXP_LENGTH), +/* harmony export */ "_0": () => (/* binding */ REGXP_PERCENT_VALUES), +/* harmony export */ "KO": () => (/* binding */ REGXP_TIME_COLON), +/* harmony export */ "gu": () => (/* binding */ REGXP_TIME_COLON_FRAMES), +/* harmony export */ "wf": () => (/* binding */ REGXP_TIME_COLON_MS), +/* harmony export */ "jb": () => (/* binding */ REGXP_TIME_FRAMES), +/* harmony export */ "te": () => (/* binding */ REGXP_TIME_HMS), +/* harmony export */ "Du": () => (/* binding */ REGXP_TIME_TICK) +/* harmony export */ }); /** - * Returns `true` if at least one codec of the Representations in the given - * Adaptation has a codec compatible with the given SegmentBuffer's codec. - * @param {Object} adaptation - * @param {string} segmentBufferCodec - * @returns {boolean} + * 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. */ +// examples: 00:00:40:07 (7 frames) or 00:00:40:07.1 (7 frames, 1 subframe) +var REGXP_TIME_COLON_FRAMES = /^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/; // examples: 00:00:40:07 (7 frames) or 00:00:40:07.1 (7 frames, 1 subframe) -function hasCompatibleCodec(adaptation, segmentBufferCodec) { - return adaptation.getPlayableRepresentations().some(function (rep) { - return are_codecs_compatible(rep.getMimeTypeString(), segmentBufferCodec); - }); -} -/** - * Returns buffered ranges of what we know correspond to the given `adaptation` - * in the SegmentBuffer. - * @param {Object} segmentBuffer - * @param {Object} period - * @param {Object} adaptation - * @returns {Array.} - */ +var REGXP_TIME_COLON = /^(?:(\d{2,}):)?(\d{2}):(\d{2})$/; // examples: 01:02:43.0345555 or 02:43.03 +var REGXP_TIME_COLON_MS = /^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{2,})$/; // examples: 75f or 75.5f -function getBufferedRangesFromAdaptation(inventory, period, adaptation) { - return inventory.reduce(function (acc, chunk) { - if (chunk.infos.period.id !== period.id || chunk.infos.adaptation.id !== adaptation.id) { - return acc; - } +var REGXP_TIME_FRAMES = /^(\d*\.?\d*)f$/; // examples: 50t or 50.5t - var bufferedStart = chunk.bufferedStart, - bufferedEnd = chunk.bufferedEnd; +var REGXP_TIME_TICK = /^(\d*\.?\d*)t$/; // examples: 3.45h, 3m or 4.20s - if (bufferedStart === undefined || bufferedEnd === undefined) { - return acc; - } +var REGXP_TIME_HMS = /^(?:(\d*\.?\d*)h)?(?:(\d*\.?\d*)m)?(?:(\d*\.?\d*)s)?(?:(\d*\.?\d*)ms)?$/; // examples: 50% 10% - acc.push({ - start: bufferedStart, - end: bufferedEnd - }); - return acc; - }, []); -} +var REGXP_PERCENT_VALUES = /^(\d{1,2}|100)% (\d{1,2}|100)%$/; +var REGXP_LENGTH = /^((?:\+|\-)?\d*(?:\.\d+)?)(px|em|c|%|rh|rw)$/; +var REGXP_8_HEX_COLOR = /^#([0-9A-f]{2})([0-9A-f]{2})([0-9A-f]{2})([0-9A-f]{2})$/; +var REGXP_4_HEX_COLOR = /^#([0-9A-f])([0-9A-f])([0-9A-f])([0-9A-f])$/; +var REGXP_RGB_COLOR = /^rgb\( *(\d+) *, *(\d+) *, *(\d+) *\)/; +var REGXP_RGBA_COLOR = /^rgba\( *(\d+) *, *(\d+) *, *(\d+) *, *(\d+) *\)/; + + +/***/ }), + +/***/ 1138: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ getCueBlocks) +/* harmony export */ }); +/* harmony import */ var _utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6923); +/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(360); /** - * Returns the last segment in the `inventory` which is linked to a Period - * before `period`. - * @param {Array.} inventory - * @param {Object} period - * @returns {Object|null} + * 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 getLastSegmentBeforePeriod(inventory, period) { - for (var i = 0; i < inventory.length; i++) { - if (inventory[i].infos.period.start >= period.start) { - if (i > 0) { - return inventory[i - 1]; - } +/** + * Get cue blocks from a WebVTT file. + * @param {Array.} linified - Whole WebVTT file. Each new element in + * this array is a new line. + * @param {number} headerOffset - index of the first line after the header. + * Used to avoid taking the header into consideration. + * @returns {Array.>} + */ - return null; +function getCueBlocks(linified, headerOffset) { + var cueBlocks = []; + + for (var i = headerOffset; i < linified.length; i++) { + if ((0,_utils__WEBPACK_IMPORTED_MODULE_0__/* .isStartOfCueBlock */ .tq)(linified, i)) { + var endOfCue = (0,_utils__WEBPACK_IMPORTED_MODULE_0__/* .findEndOfCueBlock */ .$4)(linified, i); + cueBlocks.push(linified.slice(i, endOfCue)); + i = endOfCue; + } else if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(linified[i])) { + // continue incrementing i until either: + // - empty line + // - end + while ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(linified[i])) { + i++; + } } } - return inventory.length > 0 ? inventory[inventory.length - 1] : null; + return cueBlocks; } + +/***/ }), + +/***/ 4099: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ html) +}); + +// EXTERNAL MODULE: ./src/parsers/texttracks/webvtt/get_cue_blocks.ts +var get_cue_blocks = __webpack_require__(1138); +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +// EXTERNAL MODULE: ./src/parsers/texttracks/webvtt/utils.ts +var utils = __webpack_require__(360); +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/get_style_blocks.ts /** - * Returns the first segment in the `inventory` which is linked to a Period - * after `period`. - * @param {Array.} inventory - * @param {Object} period - * @returns {Object|null} + * 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 getFirstSegmentAfterPeriod(inventory, period) { - for (var i = 0; i < inventory.length; i++) { - if (inventory[i].infos.period.start > period.start) { - return inventory[i]; +/** + * Get cue blocks from a WebVTT file. + * @param {Array.} linified - Whole WebVTT file. Each new element in + * this array is a new line. + * @param {number} headerOffset - index of the first line after the header. + * Used to avoid taking the header into consideration. + * @returns {Array.>} + */ + +function getStyleBlocks(linified, headerOffset) { + var styleBlocks = []; + + for (var i = headerOffset; i < linified.length; i++) { + // + if ((0,utils/* isStartOfStyleBlock */.JF)(linified, i)) { + var startOfStyleBlock = i; + i++; // continue incrementing i until either: + // - empty line + // - end of file + + while ((0,is_non_empty_string/* default */.Z)(linified[i])) { + i++; + } + + var styleBlock = linified.slice(startOfStyleBlock, i); + styleBlocks.push(styleBlock); + } else if ((0,is_non_empty_string/* default */.Z)(linified[i])) { + // continue incrementing i until either: + // - empty line + // - end + while ((0,is_non_empty_string/* default */.Z)(linified[i])) { + i++; + } } } - return null; + return styleBlocks; } -;// CONCATENATED MODULE: ./src/core/stream/period/period_stream.ts +// EXTERNAL MODULE: ./src/parsers/texttracks/webvtt/parse_cue_block.ts + 1 modules +var parse_cue_block = __webpack_require__(9525); +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/create_default_style_elements.ts +/** + * Creates default classes defined in the W3 specification + * + * https://www.w3.org/TR/webvtt1/#default-classes + */ +var colorMap = { + white: "#ffffff", + lime: "#00ff00", + cyan: "#00ffff", + red: "#ff0000", + yellow: "#ffff00", + magenta: "#ff00ff", + blue: "#0000ff", + black: "#000000" +}; +function createDefaultStyleElements() { + return Object.keys(colorMap).reduce(function (result, key) { + result[key] = "color: " + colorMap[key] + ";"; + result["bg_" + key] = "background-color: " + colorMap[key] + ";"; + return result; + }, {}); +} +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/parse_style_block.ts /** * Copyright 2015 CANAL+ Group * @@ -21055,215 +20214,67 @@ function getFirstSegmentAfterPeriod(inventory, period) { */ +/** + * Parse style element from WebVTT. + * @param {Array.>} styleBlocks + * @return {Object} + */ +function parseStyleBlocks(styleBlocks) { + var classes = createDefaultStyleElements(); + var global = ""; + styleBlocks.forEach(function (styleBlock) { + if (styleBlock.length >= 2) { + for (var index = 1; index < styleBlock.length; index++) { + var line = styleBlock[index]; + if (Array.isArray(/::cue {/.exec(line))) { + line = styleBlock[++index]; + while ((0,is_non_empty_string/* default */.Z)(line) && !(Array.isArray(/}/.exec(line)) || line.length === 0)) { + global += line; + line = styleBlock[++index]; + } + } else { + (function () { + var classNames = []; + var cueClassLine = /::cue\(\.?(.*?)\)(?:,| {)/.exec(line); + while ((0,is_non_empty_string/* default */.Z)(line) && Array.isArray(cueClassLine)) { + classNames.push(cueClassLine[1]); + line = styleBlock[++index]; + cueClassLine = /::cue\(\.?(.*?)\)(?:,| {)/.exec(line); + } + var styleContent = ""; + while ((0,is_non_empty_string/* default */.Z)(line) && !(Array.isArray(/}/.exec(line)) || line.length === 0)) { + styleContent += line; + line = styleBlock[++index]; + } + classNames.forEach(function (className) { + var styleElement = classes[className]; - - - -var period_stream_DELTA_POSITION_AFTER_RELOAD = config/* default.DELTA_POSITION_AFTER_RELOAD */.Z.DELTA_POSITION_AFTER_RELOAD; -/** - * Create single PeriodStream Observable: - * - 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) { - var abrManager = _ref.abrManager, - bufferType = _ref.bufferType, - clock$ = _ref.clock$, - content = _ref.content, - garbageCollectors = _ref.garbageCollectors, - segmentFetcherCreator = _ref.segmentFetcherCreator, - segmentBuffersStore = _ref.segmentBuffersStore, - options = _ref.options, - wantedBufferAhead$ = _ref.wantedBufferAhead$; - 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 relativePosAfterSwitch = switchNb === 0 ? 0 : bufferType === "audio" ? period_stream_DELTA_POSITION_AFTER_RELOAD.trackSwitch.audio : bufferType === "video" ? period_stream_DELTA_POSITION_AFTER_RELOAD.trackSwitch.video : period_stream_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", period); - 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, clock$, relativePosAfterSwitch); - } - - cleanBuffer$ = segmentBufferStatus.value.removeBuffer(period.start, period.end == null ? Infinity : period.end); - } else { - if (segmentBufferStatus.type === "uninitialized") { - segmentBuffersStore.disableSegmentBuffer(bufferType); + if (styleElement === undefined) { + classes[className] = styleContent; + } else { + classes[className] += styleContent; + } + }); + })(); } - - cleanBuffer$ = (0,of.of)(null); } - - return (0,concat/* concat */.z)(cleanBuffer$.pipe((0,mapTo/* mapTo */.h)(stream_events_generators.adaptationChange(bufferType, null, period))), createEmptyAdaptationStream(clock$, wantedBufferAhead$, bufferType, { - period: period - })); } - - if (segment_buffers.isNative(bufferType) && segmentBuffersStore.getStatus(bufferType).type === "disabled") { - return reloadAfterSwitch(period, clock$, relativePosAfterSwitch); - } - - log/* default.info */.Z.info("Stream: Updating " + bufferType + " adaptation", adaptation, period); - var newStream$ = clock$.pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.zg)(function (tick) { - var segmentBuffer = createOrReuseSegmentBuffer(segmentBuffersStore, bufferType, adaptation, options); - var playbackInfos = { - currentTime: tick.getCurrentTime(), - readyState: tick.readyState - }; - var strategy = getAdaptationSwitchStrategy(segmentBuffer, period, adaptation, playbackInfos, options); - - if (strategy.type === "needs-reload") { - return reloadAfterSwitch(period, clock$, relativePosAfterSwitch); - } - - var cleanBuffer$ = strategy.type === "clean-buffer" ? concat/* concat.apply */.z.apply(void 0, strategy.value.map(function (_ref2) { - var start = _ref2.start, - end = _ref2.end; - return segmentBuffer.removeBuffer(start, end); - })).pipe((0,ignoreElements/* ignoreElements */.l)()) : empty/* EMPTY */.E; - var bufferGarbageCollector$ = garbageCollectors.get(segmentBuffer); - var adaptationStream$ = createAdaptationStream(adaptation, segmentBuffer); - return segmentBuffersStore.waitForUsableBuffers().pipe((0,mergeMap/* mergeMap */.zg)(function () { - return (0,concat/* concat */.z)(cleanBuffer$, (0,merge/* merge */.T)(adaptationStream$, bufferGarbageCollector$)); - })); - })); - return (0,concat/* concat */.z)((0,of.of)(stream_events_generators.adaptationChange(bufferType, adaptation, period)), newStream$); - }), (0,startWith/* startWith */.O)(stream_events_generators.periodStreamReady(bufferType, period, adaptation$))); - /** - * @param {Object} adaptation - * @param {Object} segmentBuffer - * @returns {Observable} - */ - - function createAdaptationStream(adaptation, segmentBuffer) { - var manifest = content.manifest; - var adaptationStreamClock$ = clock$.pipe((0,map/* map */.U)(function (tick) { - var buffered = segmentBuffer.getBufferedRanges(); - return (0,object_assign/* default */.Z)({}, tick, { - bufferGap: (0,ranges/* getLeftSizeOfRange */.L7)(buffered, tick.position) - }); - })); - return stream_adaptation({ - abrManager: abrManager, - clock$: adaptationStreamClock$, - content: { - manifest: manifest, - period: period, - adaptation: adaptation - }, - options: options, - segmentBuffer: segmentBuffer, - segmentFetcherCreator: segmentFetcherCreator, - wantedBufferAhead$: wantedBufferAhead$ - }).pipe((0,catchError/* catchError */.K)(function (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 - if (!segment_buffers.isNative(bufferType)) { - log/* default.error */.Z.error("Stream: " + bufferType + " Stream crashed. Aborting it.", error); - segmentBuffersStore.disposeSegmentBuffer(bufferType); - var formattedError = formatError(error, { - defaultCode: "NONE", - defaultReason: "Unknown `AdaptationStream` error" - }); - return (0,concat/* concat */.z)((0,of.of)(stream_events_generators.warning(formattedError)), createEmptyAdaptationStream(clock$, wantedBufferAhead$, bufferType, { - period: period - })); - } - - log/* default.error */.Z.error("Stream: " + bufferType + " Stream crashed. Stopping playback.", error); - throw error; - })); - } -} -/** - * @param {string} bufferType - * @param {Object} adaptation - * @returns {Object} - */ - -function createOrReuseSegmentBuffer(segmentBuffersStore, bufferType, adaptation, options) { - var segmentBufferStatus = segmentBuffersStore.getStatus(bufferType); - - if (segmentBufferStatus.type === "initialized") { - log/* default.info */.Z.info("Stream: Reusing a previous SegmentBuffer for the type", bufferType); // eslint-disable-next-line @typescript-eslint/no-unsafe-return - - return segmentBufferStatus.value; - } - - var codec = getFirstDeclaredMimeType(adaptation); - var sbOptions = bufferType === "text" ? options.textTrackOptions : undefined; // eslint-disable-next-line @typescript-eslint/no-unsafe-return - - return segmentBuffersStore.createSegmentBuffer(bufferType, codec, sbOptions); -} -/** - * Get mime-type string of the first representation declared in the given - * adaptation. - * @param {Adaptation} adaptation - * @returns {string} - */ - - -function getFirstDeclaredMimeType(adaptation) { - var representations = adaptation.representations; - - if (representations[0] == null) { - return ""; - } - - return representations[0].getMimeTypeString(); + }); + return { + classes: classes, + global: global + }; } -;// 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 */ const period = (PeriodStream); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/scan.js -var scan = __webpack_require__(2807); -;// CONCATENATED MODULE: ./src/core/stream/orchestrator/active_period_emitter.ts +// EXTERNAL MODULE: ./src/utils/array_includes.ts +var array_includes = __webpack_require__(7714); +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/create_styled_element.ts /** * Copyright 2015 CANAL+ Group * @@ -21282,131 +20293,77 @@ var scan = __webpack_require__(2807); /** - * 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.} bufferTypes - Every buffer types in the content. - * @param {Observable} addPeriodStream$ - Emit PeriodStream information when - * one is added. - * @param {Observable} removePeriodStream$ - Emit PeriodStream information when - * one is removed. - * @returns {Observable} + * Construct an HTMLElement/TextNode representing the given node and apply + * the right styling on it. + * @param {Node} baseNode + * @param {Array.} styleElements + * @param {Array.} styleClasses + * @returns {Node} */ -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]; +function createStyledElement(baseNode, styleElements) { + var HTMLTags = ["u", "i", "b"]; + var authorizedNodeNames = ["u", "i", "b", "c", "#text"]; + var mainNodeName = baseNode.nodeName.toLowerCase().split(".")[0]; + var nodeWithStyle; - if (currentInfos !== undefined && currentInfos.buffers.has(type)) { - currentInfos.buffers["delete"](type); + if ((0,array_includes/* default */.Z)(authorizedNodeNames, mainNodeName)) { + if (mainNodeName === "#text") { + var linifiedText = baseNode.wholeText.split("\n"); + nodeWithStyle = document.createElement("span"); - if (currentInfos.buffers.size === 0) { - delete acc[period.id]; - } - } + for (var i = 0; i < linifiedText.length; i++) { + if (i > 0) { + nodeWithStyle.appendChild(document.createElement("br")); } - 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; - } + if (linifiedText[i].length > 0) { + var textNode = document.createTextNode(linifiedText[i]); + nodeWithStyle.appendChild(textNode); } - // /!\ 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 && !_currentInfos.buffers.has(_type)) { - _currentInfos.buffers.add(_type); - } else { - var bufferSet = new Set(); - bufferSet.add(_type); - acc[_period.id] = { - period: _period, - buffers: bufferSet - }; - } + } + } else { + var nodeClasses = baseNode.nodeName.toLowerCase().split("."); + var styleContents = []; + nodeClasses.forEach(function (nodeClass) { + if ((0,is_non_empty_string/* default */.Z)(styleElements[nodeClass])) { + styleContents.push(styleElements[nodeClass]); } - 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 (styleContents.length !== 0) { + // If style must be applied + var attr = document.createAttribute("style"); + styleContents.forEach(function (styleContent) { + attr.value += styleContent; + }); + var nameClass = (0,array_includes/* default */.Z)(HTMLTags, mainNodeName) ? mainNodeName : "span"; + nodeWithStyle = document.createElement(nameClass); + nodeWithStyle.setAttributeNode(attr); + } else { + // If style mustn't be applied. Rebuild element with tag name + var elementTag = !(0,array_includes/* default */.Z)(HTMLTags, mainNodeName) ? "span" : mainNodeName; + nodeWithStyle = document.createElement(elementTag); + } - if (periodInfos !== undefined && periodInfos.buffers.size === numberOfStreams) { - completePeriods.push(periodInfos.period); + for (var j = 0; j < baseNode.childNodes.length; j++) { + var child = createStyledElement(baseNode.childNodes[j], styleElements); + nodeWithStyle.appendChild(child); } } + } else { + nodeWithStyle = document.createElement("span"); - return completePeriods.reduce(function (acc, period) { - if (acc === null) { - return period; - } + for (var _j = 0; _j < baseNode.childNodes.length; _j++) { + var _child = createStyledElement(baseNode.childNodes[_j], styleElements); - return period.start < acc.start ? period : acc; - }, null); - }), (0,distinctUntilChanged/* distinctUntilChanged */.x)(function (a, b) { - return a === null && b === null || a !== null && b !== null && a.id === b.id; - })); + nodeWithStyle.appendChild(_child); + } + } + + return nodeWithStyle; } -;// CONCATENATED MODULE: ./src/core/stream/orchestrator/are_streams_complete.ts +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/convert_payload_to_html.ts /** * Copyright 2015 CANAL+ Group * @@ -21423,50 +20380,29 @@ 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} + * @param {string} text + * @param {Array.} styleElements + * @returns {Array.} */ -function areStreamsComplete() { - for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) { - streams[_key] = arguments[_key]; +function convertPayloadToHTML(text, styleElements) { + var filteredText = text // Remove timestamp tags + .replace(/<[0-9]{2}:[0-9]{2}.[0-9]{3}>/, "") // Remove tag content or attributes (e.g. => ) + .replace(/<([u,i,b,c])(\..*?)?(?: .*?)?>(.*?)<\/\1>/g, "<$1$2>$3"); + var parsedWebVTT = new DOMParser().parseFromString(filteredText, "text/html"); + var nodes = parsedWebVTT.body.childNodes; + var styledElements = []; + + for (var i = 0; i < nodes.length; i++) { + styledElements.push(createStyledElement(nodes[i], styleElements)); } - /** - * 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), (0,distinctUntilChanged/* distinctUntilChanged */.x)()); - }); - return (0,combineLatest/* combineLatest */.aj)(isCompleteArray).pipe((0,map/* map */.U)(function (areComplete) { - return areComplete.every(function (isComplete) { - return isComplete; - }); - }), (0,distinctUntilChanged/* distinctUntilChanged */.x)()); + return styledElements; } -;// CONCATENATED MODULE: ./src/core/stream/orchestrator/get_blacklisted_ranges.ts +// EXTERNAL MODULE: ./src/utils/object_values.ts +var object_values = __webpack_require__(1679); +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/create_style_attribute.ts /** * Copyright 2015 CANAL+ Group * @@ -21484,429 +20420,175 @@ function areStreamsComplete() { */ /** - * Returns the buffered ranges which hold the given content. - * Returns the whole buffered ranges if some of it is unknown. - * @param {Object} segmentBuffer - * @param {Array.} contents - * @returns {Array.} + * Construct a DOM attribute reflecting given cue settings + * @param {Partial>} settings + * @returns {Attr} */ -function getBlacklistedRanges(segmentBuffer, contents) { - segmentBuffer.synchronizeInventory(); - var accumulator = []; - var inventory = segmentBuffer.getInventory(); - - var _loop = function _loop(i) { - var chunk = inventory[i]; - var hasContent = contents.some(function (content) { - return chunk.infos.period.id === content.period.id && chunk.infos.adaptation.id === content.adaptation.id && chunk.infos.representation.id === content.representation.id; - }); - - if (hasContent) { - var bufferedStart = chunk.bufferedStart, - bufferedEnd = chunk.bufferedEnd; - - if (bufferedStart === undefined || bufferedEnd === undefined) { - log/* default.warn */.Z.warn("SO: No buffered start or end found from a segment."); - var buffered = segmentBuffer.getBufferedRanges(); - var len = buffered.length; - - if (len === 0) { - return { - v: [] - }; - } - - return { - v: [{ - start: buffered.start(0), - end: buffered.end(len - 1) - }] - }; - } - - var previousLastElement = accumulator[accumulator.length - 1]; - - if (previousLastElement !== undefined && previousLastElement.end === bufferedStart) { - previousLastElement.end = bufferedEnd; - } else { - accumulator.push({ - start: bufferedStart, - end: bufferedEnd - }); - } - } - }; - - for (var i = 0; i < inventory.length; i++) { - var _ret = _loop(i); - - if (typeof _ret === "object") return _ret.v; - } - - return accumulator; -} -;// CONCATENATED MODULE: ./src/core/stream/orchestrator/stream_orchestrator.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 createStyleAttribute(settings) { + var pAttr = document.createAttribute("style"); + pAttr.value = getAttrValue(settings); + return pAttr; +} +var getAttrValue = function getAttrValue(settings) { + var hasSettings = settings !== undefined && (0,object_values/* default */.Z)(settings).length !== 0; + if (!hasSettings) { + return "text-align:center"; + } + var xPositioning = getPositioningX(settings); + var yPositioning = getPositioningY(settings); + return "position: absolute;" + "margin: 0;" + ("transform: translate(" + xPositioning.offset + "%," + yPositioning.offset + "%);") + ("width: " + getSizePercentage(settings.size) + "%;") + ("left: " + xPositioning.position + "%;") + ("top: " + (yPositioning.position !== null ? yPositioning.position + "%" : "auto") + ";") + ("text-align: " + getAlignValue(settings.align) + ";"); +}; +var PositionAlignment; +(function (PositionAlignment) { + PositionAlignment["LINE_LEFT"] = "line-left"; + PositionAlignment["CENTER"] = "center"; + PositionAlignment["LINE_RIGHT"] = "line-right"; +})(PositionAlignment || (PositionAlignment = {})); +var Align; +(function (Align) { + Align["LEFT"] = "left"; + Align["CENTER"] = "center"; + Align["RIGHT"] = "right"; +})(Align || (Align = {})); +var LineAlignment; +(function (LineAlignment) { + LineAlignment["START"] = "start"; + LineAlignment["CENTER"] = "center"; + LineAlignment["END"] = "end"; +})(LineAlignment || (LineAlignment = {})); +var getPositioningX = function getPositioningX(settings) { + return { + position: getXPositionPercentage(settings), + offset: getXOffsetPercentage(settings) + }; +}; +var getXPositionPercentage = function getXPositionPercentage(settings) { + var _alignMap; -var MAXIMUM_MAX_BUFFER_AHEAD = config/* default.MAXIMUM_MAX_BUFFER_AHEAD */.Z.MAXIMUM_MAX_BUFFER_AHEAD, - MAXIMUM_MAX_BUFFER_BEHIND = config/* default.MAXIMUM_MAX_BUFFER_BEHIND */.Z.MAXIMUM_MAX_BUFFER_BEHIND; -/** - * Create and manage the various Stream Observables needed for the content to - * play: - * - * - Create or dispose SegmentBuffers depending on the chosen Adaptations. - * - * - Push the right segments to those SegmentBuffers depending on the user's - * preferences, the current position, the bandwidth, the decryption - * conditions... - * - * - 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 - * - * @param {Object} content - * @param {Observable} clock$ - Emit position information - * @param {Object} abrManager - 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} - */ + var positionPercentage = getPercentageValue(settings.position); -function StreamOrchestrator(content, clock$, abrManager, segmentBuffersStore, segmentFetcherCreator, options) { - var manifest = content.manifest, - initialPeriod = content.initialPeriod; - var maxBufferAhead$ = options.maxBufferAhead$, - maxBufferBehind$ = options.maxBufferBehind$, - wantedBufferAhead$ = options.wantedBufferAhead$; // Keep track of a unique BufferGarbageCollector created per - // SegmentBuffer. + if (positionPercentage !== null) { + return positionPercentage; + } - var garbageCollectors = new WeakMapMemory(function (segmentBuffer) { - 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 BufferGarbageCollector({ - segmentBuffer: segmentBuffer, - clock$: clock$.pipe((0,map/* map */.U)(function (tick) { - return tick.position; - })), - maxBufferBehind$: maxBufferBehind$.pipe((0,map/* map */.U)(function (val) { - return Math.min(val, defaultMaxBehind); - })), - maxBufferAhead$: maxBufferAhead$.pipe((0,map/* map */.U)(function (val) { - return Math.min(val, defaultMaxAhead); - })) - }); - }); // trigger warnings when the wanted time is before or after the manifest's - // segments + var align = getAlignValue(settings.align); + var alignMap = (_alignMap = {}, _alignMap[Align.LEFT] = 0, _alignMap[Align.CENTER] = 50, _alignMap[Align.RIGHT] = 100, _alignMap); + return alignMap[align]; +}; - var outOfManifest$ = clock$.pipe((0,filter_map/* default */.Z)(function (_ref) { - var position = _ref.position, - wantedTimeOffset = _ref.wantedTimeOffset; - var offsetedPosition = wantedTimeOffset + position; +var getXOffsetPercentage = function getXOffsetPercentage(settings) { + var _positionAlignmentMap, _alignMap2; - if (offsetedPosition < manifest.getMinimumPosition()) { - var warning = new media_error/* default */.Z("MEDIA_TIME_BEFORE_MANIFEST", "The current position is behind the " + "earliest time announced in the Manifest."); - return stream_events_generators.warning(warning); - } else if (offsetedPosition > manifest.getMaximumPosition()) { - var _warning = new media_error/* default */.Z("MEDIA_TIME_AFTER_MANIFEST", "The current position is after the latest " + "time announced in the Manifest."); + var getPositionAlignment = function getPositionAlignment(positionSetting) { + var positionRegex = /,(line-left|line-right|center)/; + var matches = positionRegex.exec(positionSetting); - return stream_events_generators.warning(_warning); + if (!Array.isArray(matches) || matches.length < 2) { + return null; } - return null; - }, null)); - var bufferTypes = segmentBuffersStore.getBufferTypes(); // Every PeriodStreams for every possible types - - var streamsArray = bufferTypes.map(function (bufferType) { - return manageEveryStreams(bufferType, initialPeriod).pipe((0,defer_subscriptions/* default */.Z)(), (0,share/* share */.B)()); - }); // 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); - return stream_events_generators.activePeriodChanged(period); - })); // Emits an "end-of-stream" event once every PeriodStream are complete. - // Emits a 'resume-stream" when it's not - - var endOfStream$ = areStreamsComplete.apply(void 0, streamsArray).pipe((0,map/* map */.U)(function (areComplete) { - return areComplete ? stream_events_generators.endOfStream() : stream_events_generators.resumeStream(); - })); - return merge/* merge.apply */.T.apply(void 0, streamsArray.concat([activePeriodChanged$, endOfStream$, outOfManifest$])); - /** - * Manage creation and removal of Streams for every Periods for a given type. - * - * Works by creating consecutive Streams through the - * `manageConsecutivePeriodStreams` function, and restarting it when the clock - * goes out of the bounds of these Streams. - * @param {string} bufferType - e.g. "audio" or "video" - * @param {Period} basePeriod - Initial Period downloaded. - * @returns {Observable} - */ + return matches[1]; + }; - function manageEveryStreams(bufferType, basePeriod) { - // 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 */.xQ(); // 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 positionAlignmentMap = (_positionAlignmentMap = {}, _positionAlignmentMap[PositionAlignment.LINE_LEFT] = 0, _positionAlignmentMap[PositionAlignment.CENTER] = -50, _positionAlignmentMap[PositionAlignment.LINE_RIGHT] = -100, _positionAlignmentMap); + var positionAlignment = settings.position !== undefined ? getPositionAlignment(settings.position) : null; - var enableOutOfBoundsCheck = false; - /** - * @param {Object} period - * @returns {Observable} - */ + if (positionAlignment !== null) { + return positionAlignmentMap[positionAlignment]; + } - function launchConsecutiveStreamsForPeriod(period) { - return manageConsecutivePeriodStreams(bufferType, period, destroyStreams$).pipe((0,filter_map/* default */.Z)(function (message) { - switch (message.type) { - case "needs-media-source-reload": - // Only reload the MediaSource when the more immediately required - // Period is the one asking for it - var firstPeriod = periodList.head(); + var alignMap = (_alignMap2 = {}, _alignMap2[Align.LEFT] = 0, _alignMap2[Align.CENTER] = -50, _alignMap2[Align.RIGHT] = -100, _alignMap2); + var align = settings.align !== undefined ? getAlignValue(settings.align) : Align.CENTER; + return alignMap[align]; +}; - if (firstPeriod === undefined || firstPeriod.id !== message.value.period.id) { - return null; - } +var getPositioningY = function getPositioningY(settings) { + return { + position: getYPositionPercentage(settings.line), + offset: getYOffsetPercentage(settings.line) + }; +}; - break; +var getYPositionPercentage = function getYPositionPercentage(lineSetting) { + return getPercentageValue(lineSetting); +}; - case "periodStreamReady": - enableOutOfBoundsCheck = true; - periodList.add(message.value.period); - break; +var getYOffsetPercentage = function getYOffsetPercentage(lineSetting) { + var _lineAlignmentMap; - case "periodStreamCleared": - periodList.removeElement(message.value.period); - break; - } + var getLineAlignment = function getLineAlignment(line) { + var positionRegex = /,(start|center|end)/; + var matches = positionRegex.exec(line); - return message; - }, null), (0,share/* share */.B)()); + if (!Array.isArray(matches) || matches.length < 2) { + return null; } - /** - * Returns true if the given time is either: - * - less than the start of the chronologically first Period - * - more than the end of the chronologically last Period - * @param {number} time - * @returns {boolean} - */ - - - function isOutOfPeriodList(time) { - var head = periodList.head(); - var last = periodList.last(); - - if (head == null || last == null) { - // if no period - return true; - } - - 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 restartStreamsWhenOutOfBounds$ = clock$.pipe((0,filter_map/* default */.Z)(function (_ref2) { - var position = _ref2.position, - wantedTimeOffset = _ref2.wantedTimeOffset; - - var _a; - - var time = wantedTimeOffset + position; - - if (!enableOutOfBoundsCheck || !isOutOfPeriodList(time)) { - return null; - } - - var nextPeriod = (_a = manifest.getPeriodForTime(time)) !== null && _a !== void 0 ? _a : 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, position + wantedTimeOffset); - enableOutOfBoundsCheck = false; - destroyStreams$.next(); - return nextPeriod; - }, null), (0,mergeMap/* mergeMap */.zg)(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 */.zg)(function (updates) { - var segmentBufferStatus = segmentBuffersStore.getStatus(bufferType); - var hasType = updates.some(function (update) { - return update.adaptation.type === bufferType; - }); - - if (!hasType || segmentBufferStatus.type !== "initialized") { - return empty/* EMPTY */.E; // no need to stop the current Streams. - } - var segmentBuffer = segmentBufferStatus.value; - var rangesToClean = getBlacklistedRanges(segmentBuffer, updates); - enableOutOfBoundsCheck = false; - destroyStreams$.next(); - return concat/* concat.apply */.z.apply(void 0, rangesToClean.map(function (_ref3) { - var start = _ref3.start, - end = _ref3.end; - return segmentBuffer.removeBuffer(start, end).pipe((0,ignoreElements/* ignoreElements */.l)()); - }).concat([clock$.pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.zg)(function (lastTick) { - return (0,concat/* concat */.z)((0,of.of)(stream_events_generators.needsDecipherabilityFlush(lastTick.position, !lastTick.isPaused, lastTick.duration)), (0,defer/* defer */.P)(function () { - var lastPosition = lastTick.position + lastTick.wantedTimeOffset; - var newInitialPeriod = manifest.getPeriodForTime(lastPosition); + return matches[1]; + }; - if (newInitialPeriod == null) { - throw new media_error/* default */.Z("MEDIA_TIME_NOT_FOUND", "The wanted position is not found in the Manifest."); - } + var lineAlignmentMap = (_lineAlignmentMap = {}, _lineAlignmentMap[LineAlignment.START] = 0, _lineAlignmentMap[LineAlignment.CENTER] = -50, _lineAlignmentMap[LineAlignment.END] = -100, _lineAlignmentMap); - return launchConsecutiveStreamsForPeriod(newInitialPeriod); - })); - }))])); - })); - return (0,merge/* merge */.T)(restartStreamsWhenOutOfBounds$, handleDecipherabilityUpdate$, launchConsecutiveStreamsForPeriod(basePeriod)); + if (lineSetting === undefined) { + return lineAlignmentMap[LineAlignment.START]; } - /** - * Create lazily consecutive PeriodStreams: - * - * 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 - * full. - * - * 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 clock announces a time 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. - * - * A "periodStreamCleared" event is sent each times a PeriodStream is - * destroyed. - * @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); // Emits the Period of the next Period Stream when it can be created. - - var createNextPeriodStream$ = new Subject/* Subject */.xQ(); // Emits when the Streams for the next Periods should be destroyed, if - // created. - - var destroyNextStreams$ = new Subject/* Subject */.xQ(); // Emits when the current position goes over the end of the current Stream. - - var endOfCurrentStream$ = clock$.pipe((0,filter/* filter */.h)(function (_ref4) { - var position = _ref4.position, - wantedTimeOffset = _ref4.wantedTimeOffset; - return basePeriod.end != null && position + wantedTimeOffset >= 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 lineAlignment = getLineAlignment(lineSetting); + return lineAlignment !== null ? lineAlignmentMap[lineAlignment] : lineAlignmentMap[LineAlignment.START]; +}; - 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 +var getAlignValue = function getAlignValue(alignSetting) { + switch (alignSetting) { + case "left": + case "start": + return "left"; - 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. + case "right": + case "end": + return "right"; - var killCurrentStream$ = (0,merge/* merge */.T)(endOfCurrentStream$, destroyAll$); - var periodStream$ = period({ - abrManager: abrManager, - bufferType: bufferType, - clock$: clock$, - content: { - manifest: manifest, - period: basePeriod - }, - garbageCollectors: garbageCollectors, - segmentFetcherCreator: segmentFetcherCreator, - segmentBuffersStore: segmentBuffersStore, - options: options, - wantedBufferAhead$: wantedBufferAhead$ - }).pipe((0,mergeMap/* mergeMap */.zg)(function (evt) { - if (evt.type === "stream-status") { - if (evt.value.hasFinishedLoading) { - var nextPeriod = manifest.getPeriodAfter(basePeriod); + default: + return "center"; + } +}; - if (nextPeriod === null) { - return (0,concat/* concat */.z)((0,of.of)(evt), (0,of.of)(stream_events_generators.streamComplete(bufferType))); - } // current Stream is full, create the next one if not +var getSizePercentage = function getSizePercentage(sizeSetting) { + var defaultSize = 100; + return getPercentageValueOrDefault(sizeSetting, defaultSize); +}; +var getPercentageValueOrDefault = function getPercentageValueOrDefault(percentageString, defaultValue) { + var value = getPercentageValue(percentageString); + return value !== null ? value : defaultValue; +}; - createNextPeriodStream$.next(nextPeriod); - } else { - // current Stream is active, destroy next Stream if created - destroyNextStreams$.next(); - } - } +var getPercentageValue = function getPercentageValue(percentageString) { + if (percentageString === undefined) { + return null; + } - return (0,of.of)(evt); - }), (0,share/* share */.B)()); // Stream for the current Period. + var percentageValueRegex = /^([\d.]+)%/; + var matches = percentageValueRegex.exec(percentageString); - var currentStream$ = (0,concat/* concat */.z)(periodStream$.pipe((0,takeUntil/* takeUntil */.R)(killCurrentStream$)), (0,of.of)(stream_events_generators.periodStreamCleared(bufferType, basePeriod)).pipe((0,tap/* tap */.b)(function () { - log/* default.info */.Z.info("SO: Destroying Stream for", bufferType, basePeriod); - }))); - return (0,merge/* merge */.T)(currentStream$, nextPeriodStream$, destroyAll$.pipe((0,ignoreElements/* ignoreElements */.l)())); + if (!Array.isArray(matches) || matches.length < 2) { + return null; } -} -;// CONCATENATED MODULE: ./src/core/stream/orchestrator/index.ts + + return parseInt(matches[1], 10); +}; +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/to_html.ts /** * Copyright 2015 CANAL+ Group * @@ -21923,27 +20605,61 @@ function StreamOrchestrator(content, clock$, abrManager, segmentBuffersStore, se * limitations under the License. */ -/* harmony default export */ const orchestrator = (StreamOrchestrator); -;// CONCATENATED MODULE: ./src/core/stream/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 + * Parse cue block into an object with the following properties: + * - start {number}: start time at which the cue should be displayed + * - end {number}: end time at which the cue should be displayed + * - element {HTMLElement}: the cue text, translated into an HTMLElement * - * 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 undefined if the cue block could not be parsed. + * @param {Array.} cueBlock + * @param {Number} timeOffset + * @param {Array.} classes + * @returns {Object|undefined} */ +function toHTML(cueObj, styling) { + var start = cueObj.start, + end = cueObj.end, + settings = cueObj.settings, + header = cueObj.header, + payload = cueObj.payload; + var region = document.createElement("div"); + var regionAttr = document.createAttribute("style"); + regionAttr.value = "width:100%;" + "height:100%;" + "display:flex;" + "flex-direction:column;" + "justify-content:flex-end;" + "align-items:center;"; + region.setAttributeNode(regionAttr); // Get content, format and apply style. -/* harmony default export */ const stream = (orchestrator); -;// CONCATENATED MODULE: ./src/core/init/create_stream_clock.ts + var pElement = document.createElement("p"); + var pAttr = createStyleAttribute(settings); + pElement.setAttributeNode(pAttr); + var spanElement = document.createElement("span"); + var attr = document.createAttribute("style"); // set color and background-color default values, as indicated in: + // https://www.w3.org/TR/webvtt1/#applying-css-properties + + attr.value = "background-color:rgba(0,0,0,0.8);" + "color:white;"; + spanElement.setAttributeNode(attr); + var global = styling.global, + classes = styling.classes; + var localStyle = (0,is_non_empty_string/* default */.Z)(header) ? classes[header] : undefined; + var styles = [global, localStyle].filter(function (s) { + return s !== undefined; + }).join(""); + attr.value += styles; + spanElement.setAttributeNode(attr); + convertPayloadToHTML(payload.join("\n"), classes).forEach(function (element) { + spanElement.appendChild(element); + }); + region.appendChild(pElement); + pElement.appendChild(spanElement); + return { + start: start, + end: end, + element: region + }; +} +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/parse_webvtt_to_div.ts /** * Copyright 2015 CANAL+ Group * @@ -21961,123 +20677,52 @@ function StreamOrchestrator(content, clock$, abrManager, segmentBuffersStore, se */ -/** - * Create clock Observable for the `Stream` part of the code. - * @param {Observable} initClock$ - * @param {Object} streamClockArgument - * @returns {Observable} - */ - -function createStreamClock(initClock$, _ref) { - var autoPlay = _ref.autoPlay, - initialPlay$ = _ref.initialPlay$, - initialSeek$ = _ref.initialSeek$, - manifest = _ref.manifest, - speed$ = _ref.speed$, - startTime = _ref.startTime; - var initialPlayPerformed = false; - var initialSeekPerformed = false; - var updateIsPaused$ = initialPlay$.pipe((0,tap/* tap */.b)(function () { - initialPlayPerformed = true; - }), (0,ignoreElements/* ignoreElements */.l)()); - var updateTimeOffset$ = initialSeek$.pipe((0,tap/* tap */.b)(function () { - initialSeekPerformed = true; - }), (0,ignoreElements/* ignoreElements */.l)()); - var clock$ = (0,combineLatest/* combineLatest */.aj)([initClock$, speed$]).pipe((0,map/* map */.U)(function (_ref2) { - var tick = _ref2[0], - speed = _ref2[1]; - var isLive = manifest.isLive; - return { - position: tick.position, - getCurrentTime: tick.getCurrentTime, - duration: tick.duration, - isPaused: initialPlayPerformed ? tick.paused : !autoPlay, - liveGap: isLive ? manifest.getMaximumPosition() - tick.position : Infinity, - readyState: tick.readyState, - speed: speed, - stalled: tick.stalled, - // wantedTimeOffset is an offset to add to the timing's current time to have - // the "real" wanted position. - // For now, this is seen when the media element has not yet seeked to its - // initial position, the currentTime will most probably be 0 where the - // effective starting position will be _startTime_. - // Thus we initially set a wantedTimeOffset equal to startTime. - wantedTimeOffset: initialSeekPerformed ? 0 : startTime - tick.position - }; - })); - return (0,merge/* merge */.T)(updateIsPaused$, updateTimeOffset$, clock$); -} -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/race.js -var race = __webpack_require__(8821); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/ArgumentOutOfRangeError.js -var ArgumentOutOfRangeError = __webpack_require__(6565); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/takeLast.js -/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ -function takeLast(count) { - return function takeLastOperatorFunction(source) { - if (count === 0) { - return (0,empty/* empty */.c)(); - } - else { - return source.lift(new TakeLastOperator(count)); - } - }; -} -var TakeLastOperator = /*@__PURE__*/ (function () { - function TakeLastOperator(total) { - this.total = total; - if (this.total < 0) { - throw new ArgumentOutOfRangeError/* ArgumentOutOfRangeError */.W; - } - } - TakeLastOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TakeLastSubscriber(subscriber, this.total)); - }; - return TakeLastOperator; -}()); -var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(TakeLastSubscriber, _super); - function TakeLastSubscriber(destination, total) { - var _this = _super.call(this, destination) || this; - _this.total = total; - _this.ring = new Array(); - _this.count = 0; - return _this; +/** + * Parse WebVTT from text. Returns an array with: + * - start : start of current cue, in seconds + * - end : end of current cue, in seconds + * - content : HTML formatted cue. + * + * Global style is parsed and applied to div element. + * Specific style is parsed and applied to class element. + * + * @throws Error - Throws if the given WebVTT string is invalid. + * @param {string} text - The whole webvtt subtitles to parse + * @param {Number} timeOffset - Offset to add to start and end times, in seconds + * @return {Array.} + */ + +function parseWebVTT(text, timeOffset) { + var newLineChar = /\r\n|\n|\r/g; // CRLF|LF|CR + + var linified = text.split(newLineChar); + var cuesArray = []; + + if (/^WEBVTT( |\t|\n|\r|$)/.exec(linified[0]) === null) { + throw new Error("Can't parse WebVTT: Invalid File."); + } + + var firstLineAfterHeader = (0,utils/* getFirstLineAfterHeader */.yE)(linified); + var styleBlocks = getStyleBlocks(linified, firstLineAfterHeader); + var cueBlocks = (0,get_cue_blocks/* default */.Z)(linified, firstLineAfterHeader); + var styles = parseStyleBlocks(styleBlocks); + + for (var i = 0; i < cueBlocks.length; i++) { + var cueObject = (0,parse_cue_block/* default */.Z)(cueBlocks[i], timeOffset); + + if (cueObject != null) { + var htmlCue = toHTML(cueObject, styles); + cuesArray.push(htmlCue); } - TakeLastSubscriber.prototype._next = function (value) { - var ring = this.ring; - var total = this.total; - var count = this.count++; - if (ring.length < total) { - ring.push(value); - } - else { - var index = count % total; - ring[index] = value; - } - }; - TakeLastSubscriber.prototype._complete = function () { - var destination = this.destination; - var count = this.count; - if (count > 0) { - var total = this.count >= this.total ? this.total : this.count; - var ring = this.ring; - for (var i = 0; i < total; i++) { - var idx = (count++) % total; - destination.next(ring[idx]); - } - } - destination.complete(); - }; - return TakeLastSubscriber; -}(Subscriber/* Subscriber */.L)); -//# sourceMappingURL=takeLast.js.map + } -;// CONCATENATED MODULE: ./src/core/init/end_of_stream.ts + return cuesArray; +} +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/index.ts /** * Copyright 2015 CANAL+ Group * @@ -22094,84 +20739,130 @@ var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { * limitations under the License. */ +/** + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. + */ + +/* harmony default export */ const html = (parseWebVTT); + +/***/ }), +/***/ 9405: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +"use strict"; -var onRemoveSourceBuffers$ = event_listeners/* onRemoveSourceBuffers$ */.gg, - end_of_stream_onSourceOpen$ = event_listeners/* onSourceOpen$ */.ym, - onUpdate$ = event_listeners/* onUpdate$ */._E; +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ webvtt_native) +}); + +// EXTERNAL MODULE: ./src/compat/is_vtt_cue.ts +var is_vtt_cue = __webpack_require__(1988); +// EXTERNAL MODULE: ./src/parsers/texttracks/webvtt/get_cue_blocks.ts +var get_cue_blocks = __webpack_require__(1138); +// EXTERNAL MODULE: ./src/parsers/texttracks/webvtt/parse_cue_block.ts + 1 modules +var parse_cue_block = __webpack_require__(9525); +// EXTERNAL MODULE: ./src/parsers/texttracks/webvtt/utils.ts +var utils = __webpack_require__(360); +// EXTERNAL MODULE: ./src/utils/array_includes.ts +var array_includes = __webpack_require__(7714); +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/native/set_settings_on_cue.ts /** - * Get "updating" SourceBuffers from a SourceBufferList. - * @param {SourceBufferList} sourceBuffers - * @returns {Array.} + * 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 getUpdatingSourceBuffers(sourceBuffers) { - var updatingSourceBuffers = []; - for (var i = 0; i < sourceBuffers.length; i++) { - var SourceBuffer = sourceBuffers[i]; +/** + * Add the corresponding settings on the given cue. + * /!\ Mutates the cue given. + * @param {Object} settings - settings for the cue, as a key-value object. + * @param {ICompatVTTCue|TextTrackCue} cue + */ - if (SourceBuffer.updating) { - updatingSourceBuffers.push(SourceBuffer); - } +function setSettingsOnCue(settings, cue) { + if ((0,is_non_empty_string/* default */.Z)(settings.vertical) && (settings.vertical === "rl" || settings.vertical === "lr")) { + cue.vertical = settings.vertical; } - return updatingSourceBuffers; -} -/** - * Trigger the `endOfStream` method of a MediaSource. - * - * If the MediaSource is ended/closed, do not call this method. - * If SourceBuffers are updating, wait for them to be updated before closing - * it. - * @param {MediaSource} mediaSource - * @returns {Observable} - */ + if ((0,is_non_empty_string/* default */.Z)(settings.line)) { + // Capture groups: + // 1 -> percentage position + // 2 -> optional decimals from percentage position + // 3 -> optional follow-up of the string indicating alignment value + // 4 -> alignment value + var percentagePosition = /^(\d+(\.\d+)?)%(,([a-z]+))?/; + var percentageMatches = percentagePosition.exec(settings.line); + if (Array.isArray(percentageMatches)) { + cue.line = Number(percentageMatches[1]); + cue.snapToLines = false; -function triggerEndOfStream(mediaSource) { - return (0,defer/* defer */.P)(function () { - log/* default.debug */.Z.debug("Init: Trying to call endOfStream"); + if ((0,array_includes/* default */.Z)(["start", "center", "end"], percentageMatches[4])) { + cue.lineAlign = percentageMatches[4]; + } + } else { + // Capture groups: + // 1 -> line number + // 2 -> optional follow-up of the string indicating alignment value + // 3 -> alignment value + var linePosition = /^(-?\d+)(,([a-z]+))?/; + var lineMatches = linePosition.exec(settings.line); - if (mediaSource.readyState !== "open") { - log/* default.debug */.Z.debug("Init: MediaSource not open, cancel endOfStream"); - return (0,of.of)(null); + if (Array.isArray(lineMatches)) { + cue.line = Number(lineMatches[1]); + cue.snapToLines = true; + + if ((0,array_includes/* default */.Z)(["start", "center", "end"], lineMatches[3])) { + cue.lineAlign = lineMatches[3]; + } + } } + } - var sourceBuffers = mediaSource.sourceBuffers; - var updatingSourceBuffers = getUpdatingSourceBuffers(sourceBuffers); + if ((0,is_non_empty_string/* default */.Z)(settings.position)) { + var positionRegex = /^([\d\.]+)%(?:,(line-left|line-right|center))?$/; + var positionArr = positionRegex.exec(settings.position); - if (updatingSourceBuffers.length === 0) { - log/* default.info */.Z.info("Init: Triggering end of stream"); - mediaSource.endOfStream(); - return (0,of.of)(null); + if (Array.isArray(positionArr) && positionArr.length >= 2) { + var position = parseInt(positionArr[1], 10); + + if (!isNaN(position)) { + cue.position = position; + + if (positionArr[2] !== undefined) { + cue.positionAlign = positionArr[2]; + } + } } + } - 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 (0,race/* race */.S3)(merge/* merge.apply */.T.apply(void 0, updatedSourceBuffers$).pipe(takeLast(1)), onRemoveSourceBuffers$(sourceBuffers).pipe((0,take/* take */.q)(1))).pipe((0,mergeMap/* mergeMap */.zg)(function () { - return triggerEndOfStream(mediaSource); - })); - }); -} -/** - * Trigger the `endOfStream` method of a MediaSource each times it opens. - * @see triggerEndOfStream - * @param {MediaSource} mediaSource - * @returns {Observable} - */ + if ((0,is_non_empty_string/* default */.Z)(settings.size)) { + cue.size = settings.size; + } -function maintainEndOfStream(mediaSource) { - return end_of_stream_onSourceOpen$(mediaSource).pipe((0,startWith/* startWith */.O)(null), (0,switchMap/* switchMap */.w)(function () { - return triggerEndOfStream(mediaSource); - })); + if (typeof settings.align === "string" && (0,array_includes/* default */.Z)(["start", "center", "end", "left"], settings.align)) { + cue.align = settings.align; + } } -// EXTERNAL MODULE: ./src/core/init/initial_seek_and_play.ts + 4 modules -var initial_seek_and_play = __webpack_require__(2795); -;// CONCATENATED MODULE: ./src/compat/is_playback_stuck.ts +// EXTERNAL MODULE: ./src/compat/make_vtt_cue.ts +var make_vtt_cue = __webpack_require__(7253); +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/native/to_native_cue.ts /** * Copyright 2015 CANAL+ Group * @@ -22189,21 +20880,18 @@ var initial_seek_and_play = __webpack_require__(2795); */ /** - * firefox fix: sometimes playback can be stalled, even if we are in a buffer. - * TODO This seems to be about an old Firefox version. Delete it? - * @param {number} time - * @param {Object|null} currentRange - * @param {string} state - * @param {Boolean} isStalled - * @returns {Boolean} + * @param {Object} cue Object + * @returns {TextTrackCue|ICompatVTTCue|null} */ -function isPlaybackStuck(time, currentRange, state, isStalled) { - var FREEZE_THRESHOLD = 10; // freeze threshold in seconds - - return browser_detection/* isFirefox */.vU && isStalled && state === "timeupdate" && currentRange != null && currentRange.end - time > FREEZE_THRESHOLD; +function toNativeCue(cueObj) { + var start = cueObj.start, + end = cueObj.end, + payload = cueObj.payload; + var text = payload.join("\n"); + return (0,make_vtt_cue/* default */.Z)(start, end, text); } -;// CONCATENATED MODULE: ./src/core/init/stall_avoider.ts +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/native/parse_vtt_to_cues.ts /** * Copyright 2015 CANAL+ Group * @@ -22220,338 +20908,270 @@ function isPlaybackStuck(time, currentRange, state, isStalled) { * limitations under the License. */ +/** + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. + */ + // Simple VTT to ICompatVTTCue parser: +// Just parse cues and associated settings. +// Does not take into consideration STYLE and REGION blocks. -var BUFFER_DISCONTINUITY_THRESHOLD = config/* default.BUFFER_DISCONTINUITY_THRESHOLD */.Z.BUFFER_DISCONTINUITY_THRESHOLD; /** - * Work-around rounding errors with floating points by setting an acceptable, - * very short, deviation when checking equalities. + * Parse whole WEBVTT file into an array of cues, to be inserted in a video's + * TrackElement. + * @param {string} vttStr + * @param {Number} timeOffset + * @returns {Array.} */ -var EPSILON = 1 / 60; -/** - * Monitor situations where playback is stalled and try to get out of those. - * Emit "stalled" then "unstalled" respectably when an unavoidable stall is - * encountered and exited. - * @param {Observable} clock$ - Observable emitting the current playback - * conditions. - * @param {HTMLMediaElement} mediaElement - The HTMLMediaElement on which the - * media is played. - * @param {Object} manifest - The Manifest of the currently-played content. - * @param {Observable} discontinuityUpdate$ - Observable emitting encountered - * discontinuities for loaded Period and buffer types. - * @returns {Observable} - */ +function parseVTTStringToVTTCues(vttStr, timeOffset) { + // WEBVTT authorize CRLF, LF or CR as line terminators + var lines = vttStr.split(/\r\n|\n|\r/); -function StallAvoider(clock$, mediaElement, manifest, discontinuityUpdate$) { - var initialDiscontinuitiesStore = []; - /** - * Emit every known audio and video buffer discontinuities in chronological - * order (first ordered by Period's start, then by bufferType in any order. - */ + if (!/^WEBVTT($| |\t)/.test(lines[0])) { + throw new Error("Can't parse WebVTT: Invalid file."); + } - var discontinuitiesStore$ = discontinuityUpdate$.pipe(withLatestFrom(clock$), // listen to clock to clean-up old discontinuities - (0,scan/* scan */.R)(function (discontinuitiesStore, _ref) { - var evt = _ref[0], - tick = _ref[1]; - return updateDiscontinuitiesStore(discontinuitiesStore, evt, tick); - }, initialDiscontinuitiesStore)); - return clock$.pipe(withLatestFrom(discontinuitiesStore$), (0,map/* map */.U)(function (_ref2) { - var tick = _ref2[0], - discontinuitiesStore = _ref2[1]; - var buffered = tick.buffered, - currentRange = tick.currentRange, - position = tick.position, - state = tick.state, - stalled = tick.stalled; + var firstLineAfterHeader = (0,utils/* getFirstLineAfterHeader */.yE)(lines); + var cueBlocks = (0,get_cue_blocks/* default */.Z)(lines, firstLineAfterHeader); + var cues = []; - if (stalled === null) { - return { - type: "unstalled", - value: null - }; - } - /** Position at which data is awaited. */ + for (var i = 0; i < cueBlocks.length; i++) { + var cueObject = (0,parse_cue_block/* default */.Z)(cueBlocks[i], timeOffset); + if (cueObject != null) { + var nativeCue = toNativeCue(cueObject); - var stalledPosition = stalled.position; + if (nativeCue != null) { + if ((0,is_vtt_cue/* default */.Z)(nativeCue)) { + setSettingsOnCue(cueObject.settings, nativeCue); + } - if (stalledPosition !== null) { - var skippableDiscontinuity = findSeekableDiscontinuity(discontinuitiesStore, manifest, stalledPosition); + cues.push(nativeCue); + } + } + } - if (skippableDiscontinuity !== null) { - var realSeekTime = skippableDiscontinuity + 0.001; + return cues; +} +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/native/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. + */ - if (realSeekTime <= mediaElement.currentTime) { - log/* default.info */.Z.info("Init: position to seek already reached, no seeking", mediaElement.currentTime, realSeekTime); - } else { - log/* default.warn */.Z.warn("SA: skippable discontinuity found in the stream", position, realSeekTime); - mediaElement.currentTime = realSeekTime; - return stream_events_generators.warning(generateDiscontinuityError(stalledPosition, realSeekTime)); - } - } - } // Is it a browser bug? -> force seek at the same current time +/** + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. + */ +/* harmony default export */ const webvtt_native = (parseVTTStringToVTTCues); - if (isPlaybackStuck(position, currentRange, state, stalled !== null)) { - log/* default.warn */.Z.warn("Init: After freeze seek", position, currentRange); - mediaElement.currentTime = position; - return stream_events_generators.warning(generateDiscontinuityError(position, position)); - } +/***/ }), - var freezePosition = stalledPosition !== null && stalledPosition !== void 0 ? stalledPosition : position; // Is it a very short discontinuity in buffer ? -> Seek at the beginning of the - // next range - // - // Discontinuity check in case we are close a buffered range but still - // calculate a stalled state. This is useful for some - // implementation that might drop an injected segment, or in - // case of small discontinuity in the content. +/***/ 9525: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - var nextBufferRangeGap = (0,ranges/* getNextRangeGap */.XS)(buffered, freezePosition); +"use strict"; - if (nextBufferRangeGap < BUFFER_DISCONTINUITY_THRESHOLD) { - var seekTo = freezePosition + nextBufferRangeGap + EPSILON; +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ parseCueBlock) +}); - if (mediaElement.currentTime < seekTo) { - log/* default.warn */.Z.warn("Init: discontinuity encountered inferior to the threshold", freezePosition, seekTo, BUFFER_DISCONTINUITY_THRESHOLD); - mediaElement.currentTime = seekTo; - return stream_events_generators.warning(generateDiscontinuityError(freezePosition, seekTo)); - } - } // Are we in a discontinuity between periods ? -> Seek at the beginning of the - // next period +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/parse_timestamp.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. + */ +/** + * Parse a single webvtt timestamp into seconds + * @param {string} timestampString + * @returns {Number|undefined} + */ - for (var i = manifest.periods.length - 2; i >= 0; i--) { - var period = manifest.periods[i]; +function parseTimestamp(timestampString) { + var splittedTS = timestampString.split(":").reverse(); - if (period.end !== undefined && period.end <= freezePosition) { - if (manifest.periods[i + 1].start > freezePosition && manifest.periods[i + 1].start > mediaElement.currentTime) { - var nextPeriod = manifest.periods[i + 1]; - mediaElement.currentTime = nextPeriod.start; - return stream_events_generators.warning(generateDiscontinuityError(freezePosition, nextPeriod.start)); - } + if ((0,is_non_empty_string/* default */.Z)(splittedTS[2]) || (0,is_non_empty_string/* default */.Z)(splittedTS[1])) { + var hours = (0,is_non_empty_string/* default */.Z)(splittedTS[2]) ? parseInt(splittedTS[2], 10) : 0; + var minutes = parseInt(splittedTS[1], 10); + var seconds = parseFloat(splittedTS[0].replace(",", ".")); - break; - } + if (isNaN(hours) || isNaN(minutes) || isNaN(seconds)) { + return undefined; } - return { - type: "stalled", - value: stalled - }; - })); + return hours * 60 * 60 + minutes * 60 + seconds; + } } +;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/parse_cue_block.ts /** - * @param {Array.} discontinuitiesStore - * @param {Object} manifest - * @param {number} stalledPosition - * @returns {number|null} + * 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 findSeekableDiscontinuity(discontinuitiesStore, manifest, stalledPosition) { - if (discontinuitiesStore.length === 0) { - return null; - } - - var maxDiscontinuityEnd = null; +/** + * Parse the settings part of a cue, into key-value object. + * @param {string} settingsString + * @returns {Object} + */ - for (var i = 0; i < discontinuitiesStore.length; i++) { - var period = discontinuitiesStore[i].period; +function parseSettings(settingsString) { + var splittedSettings = settingsString.split(/ |\t/); + return splittedSettings.reduce(function (acc, setting) { + var splittedSetting = setting.split(":"); - if (period.start > stalledPosition) { - return maxDiscontinuityEnd; + if (splittedSetting.length === 2) { + acc[splittedSetting[0]] = splittedSetting[1]; } - var discontinuityEnd = void 0; - - if (period.end === undefined || period.end > stalledPosition) { - var _discontinuitiesStore = discontinuitiesStore[i], - discontinuity = _discontinuitiesStore.discontinuity, - position = _discontinuitiesStore.position; - var start = discontinuity.start, - end = discontinuity.end; - var discontinuityLowerLimit = start !== null && start !== void 0 ? start : position; - - if (stalledPosition >= discontinuityLowerLimit - EPSILON) { - if (end === null) { - var nextPeriod = manifest.getPeriodAfter(period); - - if (nextPeriod !== null) { - discontinuityEnd = nextPeriod.start + EPSILON; - } else { - log/* default.warn */.Z.warn("Init: discontinuity at Period's end but no next Period"); - } - } else if (stalledPosition < end + EPSILON) { - discontinuityEnd = end + EPSILON; - } - } - - if (discontinuityEnd !== undefined) { - log/* default.info */.Z.info("Init: discontinuity found", stalledPosition, discontinuityEnd); - maxDiscontinuityEnd = maxDiscontinuityEnd !== null && maxDiscontinuityEnd > discontinuityEnd ? maxDiscontinuityEnd : discontinuityEnd; - } - } - } - - return maxDiscontinuityEnd; + return acc; + }, {}); } /** - * Return `true` if the given event indicates that a discontinuity is present. - * @param {Object} evt - * @returns {Array.} + * Parse the line containing the timestamp and settings in a cue. + * The returned object has the following properties: + * - start {Number}: start of the cue, in seconds + * - end {Number}: end of the cue, in seconds + * - settings {Object}: settings for the cue as a key-value object. + * @param {string} timeString + * @returns {Object|null} */ -function eventContainsDiscontinuity(evt) { - return evt.discontinuity !== null; -} -/** - * Update the `discontinuitiesStore` Object with the given event information: - * - * - If that event indicates than no discontinuity is found for a Period - * and buffer type, remove a possible existing discontinuity for that - * combination. - * - * - If that event indicates that a discontinuity can be found for a Period - * and buffer type, replace previous occurences for that combination and - * store it in Period's chronological order in the Array. - * @param {Array.} discontinuitiesStore - * @param {Object} evt - * @param {Object} tick - * @returns {Array.} - */ - +function parseTimeAndSettings(timeString) { + // RegExp for the timestamps + settings line. + // Capture groups: + // 1 -> start timestamp + // 2 -> end timestamp + // 3 - settings + var lineRegex = /^([\d:.]+)[ |\t]+-->[ |\t]+([\d:.]+)[ |\t]*(.*)$/; + var matches = lineRegex.exec(timeString); -function updateDiscontinuitiesStore(discontinuitiesStore, evt, tick) { - // First, perform clean-up of old discontinuities - while (discontinuitiesStore.length > 0 && discontinuitiesStore[0].period.end !== undefined && discontinuitiesStore[0].period.end + 10 < tick.position) { - discontinuitiesStore.shift(); + if (matches === null) { + return null; } - var period = evt.period, - bufferType = evt.bufferType; + var start = parseTimestamp(matches[1]); + var end = parseTimestamp(matches[2]); - if (bufferType !== "audio" && bufferType !== "video") { - return discontinuitiesStore; + if (start == null || end == null) { + return null; } - for (var i = 0; i < discontinuitiesStore.length; i++) { - if (discontinuitiesStore[i].period.id === period.id) { - if (discontinuitiesStore[i].bufferType === bufferType) { - if (!eventContainsDiscontinuity(evt)) { - discontinuitiesStore.splice(i, 1); - } else { - discontinuitiesStore[i] = evt; - } + var settings = parseSettings(matches[3]); + return { + start: start, + end: end, + settings: settings + }; +} +/** + * Parse cue block into a cue object which contains: + * - start {number}: the start of the cue as a timestamp in seconds + * - end {number}: the end of the cue as a timestamp in seconds + * - header {string|undefined}: The optional cue identifier + * - payload {Array.}: the payload of the cue + * @param {Array.} cueLines + * @param {Number} timeOffset + * @returns {Object} + */ - return discontinuitiesStore; - } - } else if (discontinuitiesStore[i].period.start > period.start) { - if (eventContainsDiscontinuity(evt)) { - discontinuitiesStore.splice(i, 0, evt); - } - return discontinuitiesStore; +function parseCueBlock(cueLines, timeOffset) { + var timingRegexp = /-->/; + var timeString; + var payload; + var header; + + if (!timingRegexp.test(cueLines[0])) { + if (!timingRegexp.test(cueLines[1])) { + // not a cue + return null; } - } - if (eventContainsDiscontinuity(evt)) { - discontinuitiesStore.push(evt); + header = cueLines[0]; + timeString = cueLines[1]; + payload = cueLines.slice(2, cueLines.length); + } else { + timeString = cueLines[0]; + payload = cueLines.slice(1, cueLines.length); } - return discontinuitiesStore; -} -/** - * Generate error emitted when a discontinuity has been encountered. - * @param {number} stalledPosition - * @param {number} seekTo - * @returns {Error} - */ - - -function generateDiscontinuityError(stalledPosition, seekTo) { - return new media_error/* default */.Z("DISCONTINUITY_ENCOUNTERED", "A discontinuity has been encountered at position " + String(stalledPosition) + ", seeked at position " + String(seekTo)); -} -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/pairwise.js -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + var timeAndSettings = parseTimeAndSettings(timeString); + if (timeAndSettings === null) { + return null; + } -function pairwise() { - return function (source) { return source.lift(new PairwiseOperator()); }; + var start = timeAndSettings.start, + end = timeAndSettings.end, + settings = timeAndSettings.settings; + return { + start: start + timeOffset, + end: end + timeOffset, + settings: settings, + payload: payload, + header: header + }; } -var PairwiseOperator = /*@__PURE__*/ (function () { - function PairwiseOperator() { - } - PairwiseOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new PairwiseSubscriber(subscriber)); - }; - return PairwiseOperator; -}()); -var PairwiseSubscriber = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(PairwiseSubscriber, _super); - function PairwiseSubscriber(destination) { - var _this = _super.call(this, destination) || this; - _this.hasPrev = false; - return _this; - } - PairwiseSubscriber.prototype._next = function (value) { - var pair; - if (this.hasPrev) { - pair = [this.prev, value]; - } - else { - this.hasPrev = true; - } - this.prev = value; - if (pair) { - this.destination.next(pair); - } - }; - return PairwiseSubscriber; -}(Subscriber/* Subscriber */.L)); -//# sourceMappingURL=pairwise.js.map -;// CONCATENATED MODULE: ./src/core/init/stream_events_emitter/are_same_stream_events.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. - */ +/***/ }), -/** - * Compare 2 events. - * As the payload of two events may be the same, but the JS objects may not - * have the same references, it may be difficult to compare them. - * If two events start and end at the same moment, and possess the same id, - * we consider the two to be the same. - * /!\ However, the DASH-if spec does not say that the event payload - * may be the same if these conditions are met. Thus, there are high chances - * that it may be the case. - * TODO See if we can compare payloads - * @param {Object} evt1 - * @param {Object} evt2 - * @returns {Boolean} - */ -function areSameStreamEvents(evt1, evt2) { - return evt1.id === evt2.id && evt1.start === evt2.start && evt1.end === evt2.end; -} +/***/ 360: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -/* harmony default export */ const are_same_stream_events = (areSameStreamEvents); -;// CONCATENATED MODULE: ./src/core/init/stream_events_emitter/refresh_scheduled_events_list.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "yE": () => (/* binding */ getFirstLineAfterHeader), +/* harmony export */ "tq": () => (/* binding */ isStartOfCueBlock), +/* harmony export */ "JF": () => (/* binding */ isStartOfStyleBlock), +/* harmony export */ "$4": () => (/* binding */ findEndOfCueBlock) +/* harmony export */ }); +/* unused harmony exports isStartOfNoteBlock, isStartOfRegionBlock */ +/* harmony import */ var _utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6923); /** * Copyright 2015 CANAL+ Group * @@ -22569,229 +21189,135 @@ function areSameStreamEvents(evt1, evt2) { */ /** - * Refresh local scheduled events list - * @param {Array.} oldScheduledEvents - * @param {Object} manifest - * @returns {Array.} + * Returns first line after the WEBVTT header. + * That is, the line after the first blank line after the first line! + * @param {Array.} linified + * @returns {Number} */ -function refreshScheduledEventsList(oldScheduledEvents, manifest) { - var scheduledEvents = []; - var periods = manifest.periods; - - for (var i = 0; i < periods.length; i++) { - var period = periods[i]; - var streamEvents = period.streamEvents; - streamEvents.forEach(function (_ref) { - var start = _ref.start, - end = _ref.end, - id = _ref.id, - data = _ref.data; - - for (var j = 0; j < oldScheduledEvents.length; j++) { - var currentScheduledEvent = oldScheduledEvents[j]; +function getFirstLineAfterHeader(linified) { + var i = 0; - if (are_same_stream_events(currentScheduledEvent, { - id: id, - start: start, - end: end - })) { - scheduledEvents.push(currentScheduledEvent); - return; - } - } + while (i < linified.length) { + if (linified[i] === "") { + return i + 1; + } - if (end === undefined) { - var newScheduledEvent = { - start: start, - id: id, - data: data, - publicEvent: { - start: start, - data: data - } - }; - scheduledEvents.push(newScheduledEvent); - } else { - var _newScheduledEvent = { - start: start, - end: end, - id: id, - data: data, - publicEvent: { - start: start, - end: end, - data: data - } - }; - scheduledEvents.push(_newScheduledEvent); - } - }); + i++; } - return scheduledEvents; + return i; } - -/* harmony default export */ const refresh_scheduled_events_list = (refreshScheduledEventsList); -;// CONCATENATED MODULE: ./src/core/init/stream_events_emitter/stream_events_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. + * Returns true if the given line looks like the beginning of a Style block. + * @param {string} text + * @returns {Boolean} */ +function isStartOfStyleBlock(lines, index) { + return typeof lines[index] === "string" && /^STYLE( .*)?$/g.test(lines[index]) && ( // A cue identifer can also contain "STYLE". Check that we have no timings + // on the second line + lines[index + 1] === undefined || lines[index + 1].indexOf("-->") < 0); +} +/** + * Returns true if the given line looks like the beginning of a comment block. + * @param {string} text + * @returns {Boolean} + */ - -var STREAM_EVENT_EMITTER_POLL_INTERVAL = config/* default.STREAM_EVENT_EMITTER_POLL_INTERVAL */.Z.STREAM_EVENT_EMITTER_POLL_INTERVAL; +function isStartOfNoteBlock(lines, index) { + return typeof lines[index] === "string" && /^NOTE( .*)?$/g.test(lines[index]) && ( // A cue identifer can also contain "NOTE". Check that we have no timings + // on the second line + lines[index + 1] === undefined || lines[index + 1].indexOf("-->") < 0); +} /** - * Tells if a stream event has a duration - * @param {Object} evt + * Returns true if the given line looks like the beginning of a region block. + * @param {string} text * @returns {Boolean} */ -function isFiniteStreamEvent(evt) { - return evt.end !== undefined; + +function isStartOfRegionBlock(lines, index) { + return typeof lines[index] === "string" && /^REGION( .*)?$/g.test(lines[index]) && ( // A cue identifer can also contain "REGION". Check that we have no timings + // on the second line + lines[index + 1] === undefined || lines[index + 1].indexOf("-->") < 0); } /** - * Get events from manifest and emit each time an event has to be emitted - * @param {Object} manifest - * @param {HTMLMediaElement} mediaElement - * @returns {Observable} + * Returns true if the line given looks like the beginning of a cue. + * You should provide to this function only lines following "empty" lines. + * @param {Array.} lines + * @param {number} index + * @returns {Boolean} */ -function streamEventsEmitter(manifest, mediaElement, clock$) { - 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); - }, [])); - /** - * Examine playback situation from clock ticks to emit stream events and - * prepare set onExit callbacks if needed. - * @param {Array.} scheduledEvents - * @param {Object} oldTick - * @param {Object} newTick - * @returns {Observable} - */ +function isStartOfCueBlock(lines, index) { + // checked cases: + // - empty lines + // - start of a comment + // - start of a region + // - start of a style + // Anything else whose first or second line is a timestamp line is a cue. + var firstLine = lines[index]; - function emitStreamEvents$(scheduledEvents, oldClockTick, newClockTick) { - var previousTime = oldClockTick.currentTime; - var isSeeking = newClockTick.isSeeking, - currentTime = newClockTick.currentTime; - var eventsToSend = []; - var eventsToExit = []; + if (firstLine === undefined || firstLine === "" || isStartOfStyleBlock(lines, index) || isStartOfRegionBlock(lines, index) || isStartOfNoteBlock(lines, index)) { + return false; + } - for (var i = 0; i < scheduledEvents.length; i++) { - var event = scheduledEvents[i]; - var start = event.start; - var end = isFiniteStreamEvent(event) ? event.end : undefined; - var isBeingPlayed = eventsBeingPlayed.has(event); + if (firstLine.indexOf("-->") >= 0) { + return true; + } - if (isBeingPlayed) { - if (start > currentTime || end !== undefined && currentTime >= end) { - if (isFiniteStreamEvent(event)) { - eventsToExit.push(event.publicEvent); - } + var secondLine = lines[index + 1]; + return secondLine !== undefined && secondLine.indexOf("-->") >= 0; +} +/** + * Find end of current WebVTT cue block. + * @param {Array} linified + * @param {number} startOfCueBlock + * @returns {number} + */ - eventsBeingPlayed["delete"](event); - } - } else if (start <= currentTime && end !== undefined && currentTime < end) { - eventsToSend.push({ - type: "stream-event", - value: event.publicEvent - }); - eventsBeingPlayed.set(event, true); - } else if (previousTime < start && currentTime >= (end !== null && end !== void 0 ? end : start)) { - if (isSeeking) { - eventsToSend.push({ - type: "stream-event-skip", - value: event.publicEvent - }); - } else { - eventsToSend.push({ - type: "stream-event", - value: event.publicEvent - }); - if (isFiniteStreamEvent(event)) { - eventsToExit.push(event.publicEvent); - } - } - } - } +function findEndOfCueBlock(linified, startOfCueBlock) { + var firstEmptyLineIndex = startOfCueBlock + 1; // continue incrementing i until either: + // - empty line + // - end - 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(); - } - }), (0,ignoreElements/* ignoreElements */.l)()) : empty/* EMPTY */.E); + while ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(linified[firstEmptyLineIndex])) { + firstEmptyLineIndex++; } - /** - * This pipe allows to control wether the polling should occur, if there - * are scheduledEvents, or not. - */ + return firstEmptyLineIndex; +} - return scheduledEvents$.pipe((0,tap/* tap */.b)(function (scheduledEvents) { - return lastScheduledEvents = scheduledEvents; - }), (0,map/* map */.U)(function (evt) { - return evt.length > 0; - }), (0,distinctUntilChanged/* distinctUntilChanged */.x)(), (0,switchMap/* switchMap */.w)(function (hasEvents) { - if (!hasEvents) { - return empty/* EMPTY */.E; - } - return (0,combineLatest/* combineLatest */.aj)([(0,observable_interval/* interval */.F)(STREAM_EVENT_EMITTER_POLL_INTERVAL).pipe((0,startWith/* startWith */.O)(null)), clock$]).pipe((0,map/* map */.U)(function (_ref) { - var _ = _ref[0], - clockTick = _ref[1]; - var seeking = clockTick.seeking; - return { - isSeeking: seeking, - currentTime: mediaElement.currentTime - }; - }), pairwise(), (0,mergeMap/* mergeMap */.zg)(function (_ref2) { - var oldTick = _ref2[0], - newTick = _ref2[1]; - return emitStreamEvents$(lastScheduledEvents, oldTick, newTick); - })); - })); -} -/* harmony default export */ const 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 */ const init_stream_events_emitter = (stream_events_emitter); -// EXTERNAL MODULE: ./src/core/init/update_playback_rate.ts -var update_playback_rate = __webpack_require__(2983); -;// CONCATENATED MODULE: ./src/core/init/load_on_media_source.ts +/***/ 1923: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ transports_dash) +}); + +// EXTERNAL MODULE: ./src/transports/utils/text_manifest_loader.ts + 1 modules +var text_manifest_loader = __webpack_require__(7278); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js +var of = __webpack_require__(8170); +// EXTERNAL MODULE: ./src/features/index.ts +var features = __webpack_require__(7874); +// EXTERNAL MODULE: ./src/utils/request/index.ts + 1 modules +var request = __webpack_require__(4597); +// EXTERNAL MODULE: ./src/utils/take_first_set.ts +var take_first_set = __webpack_require__(5278); +;// CONCATENATED MODULE: ./src/transports/dash/image_pipelines.ts /** * Copyright 2015 CANAL+ Group * @@ -22811,154 +21337,119 @@ var update_playback_rate = __webpack_require__(2983); - - - - - - - - - - /** - * Returns a function allowing to load or reload the content in arguments into - * a single or multiple MediaSources. * @param {Object} args - * @returns {Function} + * @returns {Observable} */ -function createMediaSourceLoader(_ref) { - var mediaElement = _ref.mediaElement, - manifest = _ref.manifest, - clock$ = _ref.clock$, - speed$ = _ref.speed$, - bufferOptions = _ref.bufferOptions, - abrManager = _ref.abrManager, - 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; // TODO Update the duration if it evolves? - - - var duration = manifest.isLive ? Infinity : manifest.getMaximumPosition(); - setDurationToMediaSource(mediaSource, duration); - 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 */._)(error); - } - /** Interface to create media buffers for loaded segments. */ - - - var segmentBuffersStore = new segment_buffers(mediaElement, mediaSource); - - var _seekAndLoadOnMediaEv = (0,initial_seek_and_play/* default */.Z)({ - clock$: clock$, - mediaElement: mediaElement, - startTime: initialTime, - mustAutoPlay: autoPlay, - isDirectfile: false - }), - seek$ = _seekAndLoadOnMediaEv.seek$, - load$ = _seekAndLoadOnMediaEv.load$; +function imageLoader(_ref) { + var segment = _ref.segment, + url = _ref.url; - var initialPlay$ = load$.pipe((0,filter/* filter */.h)(function (evt) { - return evt !== "not-loaded-metadata"; - })); - var streamEvents$ = initialPlay$.pipe((0,mergeMap/* mergeMap */.zg)(function () { - return init_stream_events_emitter(manifest, mediaElement, clock$); - })); - var streamClock$ = createStreamClock(clock$, { - autoPlay: autoPlay, - initialPlay$: initialPlay$, - initialSeek$: seek$, - manifest: manifest, - speed$: speed$, - startTime: initialTime + if (segment.isInit || url === null) { + return (0,of.of)({ + type: "data-created", + value: { + responseData: null + } }); - /** Cancel endOfStream calls when streams become active again. */ - - var cancelEndOfStream$ = new Subject/* Subject */.xQ(); - /** Emits discontinuities detected by the StreamOrchestrator. */ - - var discontinuityUpdate$ = new Subject/* Subject */.xQ(); // Creates Observable which will manage every Stream for the given Content. - - var streams$ = stream({ - manifest: manifest, - initialPeriod: initialPeriod - }, streamClock$, abrManager, segmentBuffersStore, segmentFetcherCreator, bufferOptions).pipe((0,mergeMap/* mergeMap */.zg)(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; + return (0,request/* default */.ZP)({ + url: url, + responseType: "arraybuffer", + sendProgressEvents: true + }); +} +/** + * @param {Object} args + * @returns {Observable} + */ - 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 - }); - return empty/* EMPTY */.E; +function imageParser(_ref2) { + var response = _ref2.response, + content = _ref2.content; + var segment = content.segment, + period = content.period; + var data = response.data, + isChunked = response.isChunked; - default: - return (0,of.of)(evt); + if (content.segment.isInit) { + // image init segment has no use + return (0,of.of)({ + type: "parsed-init-segment", + value: { + initializationData: null, + protectionDataUpdate: false, + initTimescale: undefined } - })); - /** - * On subscription, keep the playback speed synchronized to the speed set by - * the user on the media element and force a speed of `0` when the buffer is - * empty, so it can build back buffer. - */ - - var playbackRate$ = (0,update_playback_rate/* default */.Z)(mediaElement, speed$, clock$, { - pauseWhenStalled: true - }).pipe((0,ignoreElements/* ignoreElements */.l)()); - /** - * 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 stallAvoider$ = StallAvoider(clock$, mediaElement, manifest, discontinuityUpdate$); - var loadedEvent$ = load$.pipe((0,mergeMap/* mergeMap */.zg)(function (evt) { - if (evt === "autoplay-blocked") { - var _error = new media_error/* default */.Z("MEDIA_ERR_BLOCKED_AUTOPLAY", "Cannot trigger auto-play automatically: " + "your browser does not allow it."); + if (isChunked) { + throw new Error("Image data should not be downloaded in chunks"); + } - return (0,of.of)(events_generators/* default.warning */.Z.warning(_error), events_generators/* default.loaded */.Z.loaded(segmentBuffersStore)); - } else if (evt === "not-loaded-metadata") { - var _error2 = new media_error/* default */.Z("MEDIA_ERR_NOT_LOADED_METADATA", "Cannot load automatically: your browser " + "falsely announced having loaded the content."); + var chunkOffset = (0,take_first_set/* default */.Z)(segment.timestampOffset, 0); // TODO image Parsing should be more on the buffer side, no? - return (0,of.of)(events_generators/* default.warning */.Z.warning(_error2)); + if (data === null || features/* default.imageParser */.Z.imageParser === null) { + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: null, + chunkInfos: { + duration: segment.duration, + time: segment.time + }, + chunkOffset: chunkOffset, + appendWindow: [period.start, period.end] } + }); + } - log/* default.debug */.Z.debug("Init: The current content is loaded."); - return (0,of.of)(events_generators/* default.loaded */.Z.loaded(segmentBuffersStore)); - })); - return (0,merge/* merge */.T)(loadedEvent$, playbackRate$, stallAvoider$, streams$, streamEvents$).pipe(finalize(function () { - // clean-up every created SegmentBuffers - segmentBuffersStore.disposeAll(); - })); - }; + var bifObject = features/* default.imageParser */.Z.imageParser(new Uint8Array(data)); + var thumbsData = bifObject.thumbs; + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: { + data: thumbsData, + start: 0, + end: Number.MAX_VALUE, + timescale: 1, + type: "bif" + }, + chunkInfos: { + time: 0, + duration: Number.MAX_VALUE, + timescale: bifObject.timescale + }, + chunkOffset: chunkOffset, + appendWindow: [period.start, period.end] + } + }); } -;// CONCATENATED MODULE: ./src/core/init/manifest_update_scheduler.ts +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/concat.js +var concat = __webpack_require__(9795); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/combineLatest.js +var combineLatest = __webpack_require__(5142); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/filter.js +var filter = __webpack_require__(6008); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/map.js +var map = __webpack_require__(5709); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMap.js +var mergeMap = __webpack_require__(7746); +// EXTERNAL MODULE: ./src/manifest/index.ts + 10 modules +var src_manifest = __webpack_require__(1966); +// EXTERNAL MODULE: ./src/config.ts +var config = __webpack_require__(944); +// EXTERNAL MODULE: ./src/log.ts + 1 modules +var log = __webpack_require__(3887); +// EXTERNAL MODULE: ./src/utils/array_find.ts +var array_find = __webpack_require__(3274); +// EXTERNAL MODULE: ./src/utils/resolve_url.ts +var resolve_url = __webpack_require__(9829); +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/extract_minimum_availability_time_offset.ts /** * Copyright 2015 CANAL+ Group * @@ -22975,203 +21466,96 @@ function createMediaSourceLoader(_ref) { * limitations under the License. */ - - - -var FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY = config/* default.FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY */.Z.FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY, - MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE = config/* default.MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE */.Z.MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE, - MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE = config/* default.MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE */.Z.MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE; /** - * Refresh the Manifest at the right time. - * @param {Object} manifestUpdateSchedulerArguments - * @returns {Observable} + * From 0 to N baseURL elements takes the minimum availabilityTimeOffset + * possible. + * + * `0` if no baseURL was given (which means `no delay added`: coherent with how + * this value is used). + * + * Taking the minimum time allow to simplify its processing: + * Instead of having multiple URL each with a different pool of available + * segment at a given instant, let's always consider every URLs by aligning with + * the one with the most segment. + * + * @param {Array.} baseURLs */ +function extractMinimumAvailabilityTimeOffset(baseURLs) { + return baseURLs.length === 0 ? 0 : baseURLs.reduce(function (acc, baseURL) { + var _a; -function manifestUpdateScheduler(_ref) { - var fetchManifest = _ref.fetchManifest, - initialManifest = _ref.initialManifest, - manifestUpdateUrl = _ref.manifestUpdateUrl, - minimumManifestUpdateInterval = _ref.minimumManifestUpdateInterval, - scheduleRefresh$ = _ref.scheduleRefresh$; - // The Manifest always keeps the same Manifest - var manifest = initialManifest.manifest; - /** Number of consecutive times the parsing has been done in `unsafeMode`. */ - - var consecutiveUnsafeMode = 0; - - function handleManifestRefresh$(manifestInfos) { - var sendingTime = manifestInfos.sendingTime, - parsingTime = manifestInfos.parsingTime, - updatingTime = manifestInfos.updatingTime; - /** - * Total time taken to fully update the last Manifest. - * Note: this time also includes possible requests done by the parsers. - */ - - var totalUpdateTime = parsingTime !== undefined ? parsingTime + (updatingTime !== null && updatingTime !== void 0 ? updatingTime : 0) : undefined; // 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; - var internalRefresh$ = scheduleRefresh$.pipe((0,mergeMap/* mergeMap */.zg)(function (_ref2) { - var completeRefresh = _ref2.completeRefresh, - delay = _ref2.delay, - canUseUnsafeMode = _ref2.canUseUnsafeMode; - var unsafeMode = canUseUnsafeMode && unsafeModeEnabled; - return startManualRefreshTimer(delay !== null && delay !== void 0 ? delay : 0, minimumManifestUpdateInterval, sendingTime).pipe((0,mapTo/* mapTo */.h)({ - completeRefresh: completeRefresh, - unsafeMode: unsafeMode - })); - })); - var timeSinceRequest = sendingTime === undefined ? 0 : performance.now() - sendingTime; - var minInterval = Math.max(minimumManifestUpdateInterval - timeSinceRequest, 0); - var autoRefresh$; - - if (manifest.lifetime === undefined || manifest.lifetime < 0) { - autoRefresh$ = empty/* EMPTY */.E; - } else { - var autoRefreshInterval = manifest.lifetime * 1000 - timeSinceRequest; - - if (totalUpdateTime !== undefined) { - if (manifest.lifetime < 3 && totalUpdateTime >= 100) { - var defaultDelay = (3 - manifest.lifetime) * 1000 + autoRefreshInterval; - var newInterval = Math.max(defaultDelay, Math.max(autoRefreshInterval, 0) + totalUpdateTime); - log/* default.info */.Z.info("MUS: Manifest update rythm is too frequent. Postponing next request.", autoRefreshInterval, newInterval); - autoRefreshInterval = newInterval; - } else if (totalUpdateTime >= manifest.lifetime * 1000 / 10) { - var _newInterval = Math.max(autoRefreshInterval, 0) + totalUpdateTime; - - log/* default.info */.Z.info("MUS: Manifest took too long to parse. Postponing next request", autoRefreshInterval, _newInterval); - autoRefreshInterval = _newInterval; - } - } - - autoRefresh$ = (0,timer/* timer */.H)(Math.max(autoRefreshInterval, minInterval)).pipe((0,mapTo/* mapTo */.h)({ - completeRefresh: false, - unsafeMode: unsafeModeEnabled - })); - } + return Math.min((_a = baseURL.attributes.availabilityTimeOffset) !== null && _a !== void 0 ? _a : 0, acc); + }, Infinity); +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/get_clock_offset.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 expired$ = manifest.expired === null ? empty/* EMPTY */.E : (0,timer/* timer */.H)(minInterval).pipe((0,mergeMapTo/* mergeMapTo */.j)((0,from/* from */.D)(manifest.expired)), (0,mapTo/* mapTo */.h)({ - completeRefresh: true, - unsafeMode: unsafeModeEnabled - })); // Emit when the manifest should be refreshed. Either when: - // - A Stream asks for it to be refreshed - // - its lifetime expired. +/** + * Get difference between the server's clock, in milliseconds and the return of + * the JS function `performance.now`. + * This property allows to calculate the server time at any moment. + * + * `undefined` if we could not define such offset (in which case, you could have + * to rely on the user's clock instead). + * + * For example, a response of 1000 would mean that performance.now() is 1 second + * behind the server's time. + * @param {string} serverClock + * @returns {number|undefined} + */ - return (0,merge/* merge */.T)(autoRefresh$, internalRefresh$, expired$).pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.zg)(function (_ref3) { - var completeRefresh = _ref3.completeRefresh, - unsafeMode = _ref3.unsafeMode; - return refreshManifest({ - completeRefresh: completeRefresh, - unsafeMode: unsafeMode - }); - }), (0,mergeMap/* mergeMap */.zg)(function (evt) { - if (evt.type === "warning") { - return (0,of.of)(evt); - } +function getClockOffset(serverClock) { + var httpOffset = Date.parse(serverClock) - performance.now(); - return handleManifestRefresh$(evt); - })); + if (isNaN(httpOffset)) { + log/* default.warn */.Z.warn("DASH Parser: Invalid clock received: ", serverClock); + return undefined; } - return (0,defer/* defer */.P)(function () { - return handleManifestRefresh$(initialManifest); - }); - /** - * Refresh the Manifest. - * Perform a full update if a partial update failed. - * @param {boolean} completeRefresh - * @returns {Observable} - */ - - function refreshManifest(_ref4) { - var completeRefresh = _ref4.completeRefresh, - unsafeMode = _ref4.unsafeMode; - 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 */.zg)(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"); - return startManualRefreshTimer(FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY, minimumManifestUpdateInterval, newSendingTime).pipe((0,mergeMap/* mergeMap */.zg)(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 - }); - })); - } + return httpOffset; } +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/get_http_utc-timing_url.ts /** - * 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} + * 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 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)); +/** + * @param {Object} mpdIR + * @returns {string|undefined} + */ +function getHTTPUTCTimingURL(mpdIR) { + var UTCTimingHTTP = mpdIR.children.utcTimings.filter(function (utcTiming) { + return utcTiming.schemeIdUri === "urn:mpeg:dash:utc:http-iso:2014" && utcTiming.value !== undefined; }); + return UTCTimingHTTP.length > 0 ? UTCTimingHTTP[0].value : undefined; } -// 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 +;// CONCATENATED MODULE: ./src/parsers/manifest/utils/get_last_time_from_adaptation.ts /** * Copyright 2015 CANAL+ Group * @@ -23188,314 +21572,240 @@ var throw_on_media_error = __webpack_require__(2447); * limitations under the License. */ +/** + * Returns "last time of reference" from the adaptation given, considering a + * dynamic content. + * Undefined if a time could not be found. + * Null if the Adaptation has no segments (it could be that it didn't started or + * that it already finished for example). + * + * We consider the earliest last time from every representations in the given + * adaptation. + * @param {Object} adaptation + * @returns {Number|undefined|null} + */ +function getLastPositionFromAdaptation(adaptation) { + var representations = adaptation.representations; + var min = null; + for (var i = 0; i < representations.length; i++) { + var lastPosition = representations[i].index.getLastPosition(); + if (lastPosition === undefined) { + // we cannot tell + return undefined; + } + if (lastPosition !== null) { + min = min == null ? lastPosition : Math.min(min, lastPosition); + } + } + if (min === null) { + // It means that all positions were null === no segments (yet?) + return null; + } + return min; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/utils/get_maximum_position.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. + */ +/** + * @param {Object} manifest + * @returns {number | undefined} + */ + +function getMaximumPosition(periods) { + for (var i = periods.length - 1; i >= 0; i--) { + var periodAdaptations = periods[i].adaptations; + var firstAudioAdaptationFromPeriod = periodAdaptations.audio === undefined ? undefined : periodAdaptations.audio[0]; + var firstVideoAdaptationFromPeriod = periodAdaptations.video === undefined ? undefined : periodAdaptations.video[0]; + if (firstAudioAdaptationFromPeriod !== undefined || firstVideoAdaptationFromPeriod !== undefined) { + // null == no segment + var maximumAudioPosition = null; + var maximumVideoPosition = null; + if (firstAudioAdaptationFromPeriod !== undefined) { + var lastPosition = getLastPositionFromAdaptation(firstAudioAdaptationFromPeriod); + if (lastPosition === undefined) { + return undefined; + } + maximumAudioPosition = lastPosition; + } + if (firstVideoAdaptationFromPeriod !== undefined) { + var _lastPosition = getLastPositionFromAdaptation(firstVideoAdaptationFromPeriod); + if (_lastPosition === undefined) { + return undefined; + } + maximumVideoPosition = _lastPosition; + } + if (firstAudioAdaptationFromPeriod !== undefined && maximumAudioPosition === null || firstVideoAdaptationFromPeriod !== undefined && maximumVideoPosition === null) { + log/* default.info */.Z.info("Parser utils: found Period with no segment. ", "Going to previous one to calculate last position"); + return undefined; + } + if (maximumVideoPosition !== null) { + if (maximumAudioPosition !== null) { + return Math.min(maximumAudioPosition, maximumVideoPosition); + } + return maximumVideoPosition; + } - - -var OUT_OF_SYNC_MANIFEST_REFRESH_DELAY = config/* default.OUT_OF_SYNC_MANIFEST_REFRESH_DELAY */.Z.OUT_OF_SYNC_MANIFEST_REFRESH_DELAY; + if (maximumAudioPosition !== null) { + return maximumAudioPosition; + } + } + } +} +;// CONCATENATED MODULE: ./src/parsers/manifest/utils/get_first_time_from_adaptation.ts /** - * 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 EME management if needed - * - * - ask for the choice of the wanted Adaptation through events (e.g. to - * choose a language) - * - * - requests and push the right segments (according to the Adaptation choice, - * the current position, the network conditions etc.) + * Copyright 2015 CANAL+ Group * - * 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. + * 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 * - * This Observable will never complete, it will always run until it is - * unsubscribed from. - * Unsubscription will stop playback and reset the corresponding state. + * http://www.apache.org/licenses/LICENSE-2.0 * - * @param {Object} args - * @returns {Observable} + * 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 InitializeOnMediaSource(_ref) { - var adaptiveOptions = _ref.adaptiveOptions, - autoPlay = _ref.autoPlay, - bufferOptions = _ref.bufferOptions, - clock$ = _ref.clock$, - content = _ref.content, - keySystems = _ref.keySystems, - lowLatencyMode = _ref.lowLatencyMode, - mediaElement = _ref.mediaElement, - minimumManifestUpdateInterval = _ref.minimumManifestUpdateInterval, - networkConfig = _ref.networkConfig, - speed$ = _ref.speed$, - startAt = _ref.startAt, - textTrackOptions = _ref.textTrackOptions, - transportPipelines = _ref.transportPipelines; - var url = content.url, - initialManifest = content.initialManifest, - manifestUpdateUrl = content.manifestUpdateUrl; - var offlineRetry = networkConfig.offlineRetry, - segmentRetry = networkConfig.segmentRetry, - manifestRetry = networkConfig.manifestRetry; - var manifestFetcher = new fetchers_manifest(url, transportPipelines, { - lowLatencyMode: lowLatencyMode, - maxRetryRegular: manifestRetry, - maxRetryOffline: offlineRetry - }); - /** - * 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 */.zg)(function (response) { - return response.type === "warning" ? (0,of.of)(response) : // bubble-up warnings - response.parse(options); - }), (0,share/* share */.B)()); - }); - /** Interface used to download segments. */ - - var segmentFetcherCreator = new segment(transportPipelines, { - lowLatencyMode: lowLatencyMode, - maxRetryOffline: offlineRetry, - maxRetryRegular: segmentRetry - }); - /** Choose the right "Representation" for a given "Adaptation". */ - - var abrManager = new abr(adaptiveOptions); - /** - * 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 data to the `EMEManager`. */ - - var protectedSegments$ = new Subject/* Subject */.xQ(); - /** Create `EMEManager`, an observable which will handle content DRM. */ - - var emeManager$ = (0,create_eme_manager/* default */.Z)(mediaElement, keySystems, protectedSegments$).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 `emeManager$` 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 - // `emeManager$` 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 initialManifestRequest$; - - if (initialManifest instanceof manifest/* default */.ZP) { - initialManifestRequest$ = (0,of.of)({ - type: "parsed", - manifest: initialManifest - }); - } else if (initialManifest !== undefined) { - initialManifestRequest$ = manifestFetcher.parse(initialManifest, { - previousManifest: null, - unsafeMode: false - }); - } else { - initialManifestRequest$ = fetchManifest(url, { - previousManifest: null, - unsafeMode: false - }); - } - /** - * Wait for the MediaKeys to have been created before - * opening MediaSource, and ask EME to attach MediaKeys. - */ - - - var prepareMediaSource$ = emeManager$.pipe((0,mergeMap/* mergeMap */.zg)(function (evt) { - switch (evt.type) { - case "eme-disabled": - case "attached-media-keys": - return (0,of.of)(undefined); - - case "created-media-keys": - return openMediaSource$.pipe((0,mergeMap/* mergeMap */.zg)(function () { - evt.value.attachMediaKeys$.next(); - var shouldDisableLock = evt.value.options.disableMediaKeysAttachmentLock === true; - - if (shouldDisableLock) { - return (0,of.of)(undefined); - } // wait for "attached-media-keys" - +/** + * Returns "first time of reference" from the adaptation given, considering a + * dynamic content. + * Undefined if a time could not be found. + * + * We consider the latest first time from every representations in the given + * adaptation. + * @param {Object} adaptation + * @returns {Number|undefined} + */ +function getFirstPositionFromAdaptation(adaptation) { + var representations = adaptation.representations; + var max = null; - return empty/* EMPTY */.E; - })); + for (var i = 0; i < representations.length; i++) { + var firstPosition = representations[i].index.getFirstPosition(); - default: - return empty/* EMPTY */.E; + if (firstPosition === undefined) { + // we cannot tell + return undefined; } - }), (0,take/* take */.q)(1), exhaustMap(function () { - return openMediaSource$; - })); - /** Load and play the content asked. */ - - var loadContent$ = (0,combineLatest/* combineLatest */.aj)([initialManifestRequest$, prepareMediaSource$]).pipe((0,mergeMap/* mergeMap */.zg)(function (_ref2) { - var manifestEvt = _ref2[0], - initialMediaSource = _ref2[1]; - if (manifestEvt.type === "warning") { - return (0,of.of)(manifestEvt); + if (firstPosition !== null) { + max = max == null ? firstPosition : Math.max(max, firstPosition); } + } - 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 mediaSourceLoader = createMediaSourceLoader({ - abrManager: abrManager, - bufferOptions: (0,object_assign/* default */.Z)({ - textTrackOptions: textTrackOptions - }, bufferOptions), - clock$: clock$, - manifest: manifest, - mediaElement: mediaElement, - segmentFetcherCreator: segmentFetcherCreator, - speed$: speed$ - }); // handle initial load and reloads + if (max === null) { + // It means that all positions were null === no segments (yet?) + return null; + } - var recursiveLoad$ = recursivelyLoadOnMediaSource(initialMediaSource, initialTime, autoPlay); // Emit when we want to manually update the manifest. + return max; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/utils/get_minimum_position.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 scheduleRefresh$ = new Subject/* Subject */.xQ(); - var manifestUpdate$ = manifestUpdateScheduler({ - fetchManifest: fetchManifest, - initialManifest: manifestEvt, - manifestUpdateUrl: manifestUpdateUrl, - minimumManifestUpdateInterval: minimumManifestUpdateInterval, - scheduleRefresh$: scheduleRefresh$ - }); - var manifestEvents$ = (0,merge/* merge */.T)((0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,mapTo/* mapTo */.h)(events_generators/* default.manifestUpdate */.Z.manifestUpdate())), (0,event_emitter/* fromEvent */.R)(manifest, "decipherabilityUpdate").pipe((0,map/* map */.U)(events_generators/* default.decipherabilityUpdate */.Z.decipherabilityUpdate))); - var setUndecipherableRepresentations$ = emeManager$.pipe((0,tap/* tap */.b)(function (evt) { - if (evt.type === "blacklist-keys") { - log/* default.info */.Z.info("Init: blacklisting Representations based on keyIDs"); - manifest.addUndecipherableKIDs(evt.value); - } else if (evt.type === "blacklist-protection-data") { - log/* default.info */.Z.info("Init: blacklisting Representations based on protection data."); - if (evt.value.type !== undefined) { - manifest.addUndecipherableProtectionData(evt.value.type, evt.value.data); - } - } - }), (0,ignoreElements/* ignoreElements */.l)()); - return (0,merge/* merge */.T)(manifestEvents$, manifestUpdate$, setUndecipherableRepresentations$, recursiveLoad$).pipe((0,startWith/* startWith */.O)(events_generators/* default.manifestReady */.Z.manifestReady(manifest)), finalize(function () { - scheduleRefresh$.complete(); - })); - /** - * 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} - */ +/** + * @param {Object} manifest + * @returns {number | undefined} + */ - function recursivelyLoadOnMediaSource(mediaSource, startingPos, shouldPlay) { - var reloadMediaSource$ = new Subject/* Subject */.xQ(); - 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; +function getMinimumPosition(periods) { + for (var i = 0; i <= periods.length - 1; i++) { + var periodAdaptations = periods[i].adaptations; + var firstAudioAdaptationFromPeriod = periodAdaptations.audio === undefined ? undefined : periodAdaptations.audio[0]; + var firstVideoAdaptationFromPeriod = periodAdaptations.video === undefined ? undefined : periodAdaptations.video[0]; - case "manifest-might-be-out-of-sync": - scheduleRefresh$.next({ - completeRefresh: true, - canUseUnsafeMode: false, - delay: OUT_OF_SYNC_MANIFEST_REFRESH_DELAY - }); - return null; + if (firstAudioAdaptationFromPeriod !== undefined || firstVideoAdaptationFromPeriod !== undefined) { + // null == no segment + var minimumAudioPosition = null; + var minimumVideoPosition = null; - case "needs-media-source-reload": - reloadMediaSource$.next(evt.value); - return null; + if (firstAudioAdaptationFromPeriod !== undefined) { + var firstPosition = getFirstPositionFromAdaptation(firstAudioAdaptationFromPeriod); - case "needs-decipherability-flush": - var keySystem = get_current_key_system_getCurrentKeySystem(mediaElement); + if (firstPosition === undefined) { + return undefined; + } - if (shouldReloadMediaSourceOnDecipherabilityUpdate(keySystem)) { - reloadMediaSource$.next(evt.value); - return null; - } // simple seek close to the current position - // to flush the buffers + minimumAudioPosition = firstPosition; + } + if (firstVideoAdaptationFromPeriod !== undefined) { + var _firstPosition = getFirstPositionFromAdaptation(firstVideoAdaptationFromPeriod); - var position = evt.value.position; + if (_firstPosition === undefined) { + return undefined; + } - if (position + 0.001 < evt.value.duration) { - mediaElement.currentTime += 0.001; - } else { - mediaElement.currentTime = position; - } + minimumVideoPosition = _firstPosition; + } - return null; + if (firstAudioAdaptationFromPeriod !== undefined && minimumAudioPosition === null || firstVideoAdaptationFromPeriod !== undefined && minimumVideoPosition === null) { + log/* default.info */.Z.info("Parser utils: found Period with no segment. ", "Going to next one to calculate first position"); + return undefined; + } - case "protected-segment": - protectedSegments$.next(evt.value); - return null; + if (minimumVideoPosition !== null) { + if (minimumAudioPosition !== null) { + return Math.max(minimumAudioPosition, minimumVideoPosition); } - 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 */.zg)(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 minimumVideoPosition; + } + + if (minimumAudioPosition !== null) { + return minimumAudioPosition; + } } - })); - return (0,merge/* merge */.T)(loadContent$, mediaError$, emeManager$); + } } -;// CONCATENATED MODULE: ./src/core/init/index.ts +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/get_minimum_and_maximum_positions.ts /** * Copyright 2015 CANAL+ Group * @@ -23513,10 +21823,33 @@ function InitializeOnMediaSource(_ref) { */ -/* harmony default export */ const init = (InitializeOnMediaSource); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/refCount.js -var refCount = __webpack_require__(3018); -;// CONCATENATED MODULE: ./src/core/api/clock.ts +/** + * @param {Object} periods + * @returns {Array.} + */ + +function getMinimumAndMaximumPosition(periods) { + if (periods.length === 0) { + throw new Error("DASH Parser: no period available for a dynamic content"); + } + + return [getMinimumPosition(periods), getMaximumPosition(periods)]; +} +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js +var assertThisInitialized = __webpack_require__(3349); +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js +var inheritsLoose = __webpack_require__(1788); +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/wrapNativeSuper.js + 4 modules +var wrapNativeSuper = __webpack_require__(3786); +// EXTERNAL MODULE: ./src/utils/base64.ts +var base64 = __webpack_require__(9689); +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/utils.ts + + + + /** * Copyright 2015 CANAL+ Group * @@ -23532,338 +21865,328 @@ var refCount = __webpack_require__(3018); * See the License for the specific language governing permissions and * limitations under the License. */ +// XML-Schema -/** - * This file defines a global clock for the RxPlayer. - * - * Each clock tick also pass information about the current state of the - * media element to sub-parts of the player. - */ - - +/* eslint-disable max-len */ +// +/* eslint-enable max-len */ -var SAMPLING_INTERVAL_MEDIASOURCE = config/* default.SAMPLING_INTERVAL_MEDIASOURCE */.Z.SAMPLING_INTERVAL_MEDIASOURCE, - SAMPLING_INTERVAL_LOW_LATENCY = config/* default.SAMPLING_INTERVAL_LOW_LATENCY */.Z.SAMPLING_INTERVAL_LOW_LATENCY, - SAMPLING_INTERVAL_NO_MEDIASOURCE = config/* default.SAMPLING_INTERVAL_NO_MEDIASOURCE */.Z.SAMPLING_INTERVAL_NO_MEDIASOURCE, - RESUME_GAP_AFTER_SEEKING = config/* default.RESUME_GAP_AFTER_SEEKING */.Z.RESUME_GAP_AFTER_SEEKING, - RESUME_GAP_AFTER_NOT_ENOUGH_DATA = config/* default.RESUME_GAP_AFTER_NOT_ENOUGH_DATA */.Z.RESUME_GAP_AFTER_NOT_ENOUGH_DATA, - RESUME_GAP_AFTER_BUFFERING = config/* default.RESUME_GAP_AFTER_BUFFERING */.Z.RESUME_GAP_AFTER_BUFFERING, - STALL_GAP = config/* default.STALL_GAP */.Z.STALL_GAP; +var iso8601Duration = /^P(([\d.]*)Y)?(([\d.]*)M)?(([\d.]*)D)?T?(([\d.]*)H)?(([\d.]*)M)?(([\d.]*)S)?/; +var rangeRe = /([0-9]+)-([0-9]+)/; /** - * HTMLMediaElement Events for which timings are calculated and emitted. - * @type {Array.} + * Parse MPD boolean attributes. + * + * The returned value is a tuple of two elements where: + * 1. the first value is the parsed boolean - or `null` if we could not parse + * it + * 2. the second value is a possible error encountered while parsing this + * value - set to `null` if no error was encountered. + * @param {string} val - The value to parse + * @param {string} displayName - The name of the property. Used for error + * formatting. + * @returns {Array.} */ -var SCANNED_MEDIA_ELEMENTS_EVENTS = ["canplay", "play", "progress", "seeking", "seeked", "loadedmetadata", "ratechange"]; -/** - * Returns the amount of time in seconds the buffer should have ahead of the - * current position before resuming playback. Based on the infos of the stall. - * Waiting time differs between a "seeking" stall and a buffering stall. - * @param {Object|null} stalled - * @param {Boolean} lowLatencyMode - * @returns {Number} - */ +function parseBoolean(val, displayName) { + if (val === "true") { + return [true, null]; + } -function getResumeGap(stalled, lowLatencyMode) { - if (stalled === null) { - return 0; + if (val === "false") { + return [false, null]; } - var suffix = lowLatencyMode ? "LOW_LATENCY" : "DEFAULT"; + var error = new MPDError("`" + displayName + "` property is not a boolean value but \"" + val + "\""); + return [false, error]; +} +/** + * Parse MPD integer attributes. + * + * The returned value is a tuple of two elements where: + * 1. the first value is the parsed boolean - or `null` if we could not parse + * it + * 2. the second value is a possible error encountered while parsing this + * value - set to `null` if no error was encountered. + * @param {string} val - The value to parse + * @param {string} displayName - The name of the property. Used for error + * formatting. + * @returns {Array.} + */ - switch (stalled.reason) { - case "seeking": - return RESUME_GAP_AFTER_SEEKING[suffix]; - case "not-ready": - return RESUME_GAP_AFTER_NOT_ENOUGH_DATA[suffix]; +function parseMPDInteger(val, displayName) { + var toInt = parseInt(val, 10); - case "buffering": - return RESUME_GAP_AFTER_BUFFERING[suffix]; + if (isNaN(toInt)) { + var error = new MPDError("`" + displayName + "` property is not an integer value but \"" + val + "\""); + return [null, error]; } + + return [toInt, null]; } /** - * @param {Object} currentRange - * @param {Number} duration - * @param {Boolean} lowLatencyMode - * @returns {Boolean} + * Parse MPD float attributes. + * + * The returned value is a tuple of two elements where: + * 1. the first value is the parsed boolean - or `null` if we could not parse + * it + * 2. the second value is a possible error encountered while parsing this + * value - set to `null` if no error was encountered. + * @param {string} val - The value to parse + * @param {string} displayName - The name of the property. Used for error + * formatting. + * @returns {Array.} */ -function hasLoadedUntilTheEnd(currentRange, duration, lowLatencyMode) { - var suffix = lowLatencyMode ? "LOW_LATENCY" : "DEFAULT"; - return currentRange !== null && duration - currentRange.end <= STALL_GAP[suffix]; +function parseMPDFloat(val, displayName) { + var toInt = parseFloat(val); + + if (isNaN(toInt)) { + var error = new MPDError("`" + displayName + "` property is not an integer value but \"" + val + "\""); + return [null, error]; + } + + return [toInt, null]; } /** - * Generate a basic timings object from the media element and the eventName - * which triggered the request. - * @param {HTMLMediaElement} mediaElement - * @param {string} currentState - * @returns {Object} + * Parse MPD attributes which are either integer or boolean values. + * + * The returned value is a tuple of two elements where: + * 1. the first value is the parsed value - or `null` if we could not parse + * it + * 2. the second value is a possible error encountered while parsing this + * value - set to `null` if no error was encountered. + * @param {string} val - The value to parse + * @param {string} displayName - The name of the property. Used for error + * formatting. + * @returns {Array.} */ -function getMediaInfos(mediaElement, currentState) { - var buffered = mediaElement.buffered, - currentTime = mediaElement.currentTime, - duration = mediaElement.duration, - ended = mediaElement.ended, - paused = mediaElement.paused, - playbackRate = mediaElement.playbackRate, - readyState = mediaElement.readyState, - seeking = mediaElement.seeking; - var currentRange = (0,ranges/* getRange */.rx)(buffered, currentTime); - return { - bufferGap: currentRange !== null ? currentRange.end - currentTime : // TODO null/0 would probably be - // more appropriate - Infinity, - buffered: buffered, - currentRange: currentRange, - position: currentTime, - duration: duration, - ended: ended, - paused: paused, - playbackRate: playbackRate, - readyState: readyState, - seeking: seeking, - state: currentState - }; +function parseIntOrBoolean(val, displayName) { + if (val === "true") { + return [true, null]; + } + + if (val === "false") { + return [false, null]; + } + + var toInt = parseInt(val, 10); + + if (isNaN(toInt)) { + var error = new MPDError("`" + displayName + "` property is not a boolean nor an integer but \"" + val + "\""); + return [null, error]; + } + + return [toInt, null]; } /** - * Infer stalled status of the media based on: - * - the return of the function getMediaInfos - * - the previous timings object. + * Parse MPD date attributes. * - * @param {Object} prevTimings - Previous timings object. See function to know - * the different properties needed. - * @param {Object} currentTimings - Current timings object. This does not need - * to have every single infos, see function to know which properties are needed. - * @param {Object} options - * @returns {Object|null} + * The returned value is a tuple of two elements where: + * 1. the first value is the parsed value - or `null` if we could not parse + * it + * 2. the second value is a possible error encountered while parsing this + * value - set to `null` if no error was encountered. + * @param {string} val - The value to parse + * @param {string} displayName - The name of the property. Used for error + * formatting. + * @returns {Array.} */ -function getStalledStatus(prevTimings, currentTimings, _ref) { - var withMediaSource = _ref.withMediaSource, - lowLatencyMode = _ref.lowLatencyMode; - var currentState = currentTimings.state, - currentTime = currentTimings.position, - bufferGap = currentTimings.bufferGap, - currentRange = currentTimings.currentRange, - duration = currentTimings.duration, - paused = currentTimings.paused, - readyState = currentTimings.readyState, - ended = currentTimings.ended; - var prevStalled = prevTimings.stalled, - prevState = prevTimings.state, - prevTime = prevTimings.position; - var fullyLoaded = hasLoadedUntilTheEnd(currentRange, duration, lowLatencyMode); - var canStall = readyState >= 1 && currentState !== "loadedmetadata" && prevStalled === null && !(fullyLoaded || ended); - var stalledPosition = null; - var shouldStall; - var shouldUnstall; - var stallGap = lowLatencyMode ? STALL_GAP.LOW_LATENCY : STALL_GAP.DEFAULT; +function parseDateTime(val, displayName) { + var parsed = Date.parse(val); - if (withMediaSource) { - if (canStall) { - if (bufferGap <= stallGap) { - shouldStall = true; - stalledPosition = currentTime + bufferGap; - } else if (bufferGap === Infinity) { - shouldStall = true; - stalledPosition = currentTime; - } else if (readyState === 1) { - shouldStall = true; - } - } else if (prevStalled !== null) { - var resumeGap = getResumeGap(prevStalled, lowLatencyMode); + if (isNaN(parsed)) { + var error = new MPDError("`" + displayName + "` is in an invalid date format: \"" + val + "\""); + return [null, error]; + } - if (shouldStall !== true && prevStalled !== null && readyState > 1 && (fullyLoaded || ended || bufferGap < Infinity && bufferGap > resumeGap)) { - shouldUnstall = true; - } else if (bufferGap === Infinity || bufferGap <= resumeGap) { - stalledPosition = bufferGap === Infinity ? currentTime : currentTime + bufferGap; - } - } - } // when using a direct file, the media will stall and unstall on its - // own, so we only try to detect when the media timestamp has not changed - // between two consecutive timeupdates - else { - if (canStall && (!paused && currentState === "timeupdate" && prevState === "timeupdate" && currentTime === prevTime || currentState === "seeking" && bufferGap === Infinity)) { - shouldStall = true; - } else if (prevStalled !== null && (currentState !== "seeking" && currentTime !== prevTime || currentState === "canplay" || bufferGap < Infinity && (bufferGap > getResumeGap(prevStalled, lowLatencyMode) || fullyLoaded || ended))) { - shouldUnstall = true; - } - } + return [new Date(Date.parse(val)).getTime() / 1000, null]; +} +/** + * Parse MPD ISO8601 duration attributes into seconds. + * + * The returned value is a tuple of two elements where: + * 1. the first value is the parsed value - or `null` if we could not parse + * it + * 2. the second value is a possible error encountered while parsing this + * value - set to `null` if no error was encountered. + * @param {string} val - The value to parse + * @param {string} displayName - The name of the property. Used for error + * formatting. + * @returns {Array.} + */ - if (shouldUnstall === true) { - return null; - } else if (shouldStall === true || prevStalled !== null) { - var reason; - if (currentState === "seeking" || currentTimings.seeking || prevStalled !== null && prevStalled.reason === "seeking") { - reason = "seeking"; - } else if (readyState === 1) { - reason = "not-ready"; - } else { - reason = "buffering"; - } +function parseDuration(val, displayName) { + if (!(0,is_non_empty_string/* default */.Z)(val)) { + var error = new MPDError("`" + displayName + "` property is empty"); + return [0, error]; + } - if (prevStalled !== null && prevStalled.reason === reason) { - return { - reason: prevStalled.reason, - timestamp: prevStalled.timestamp, - position: stalledPosition - }; - } + var match = iso8601Duration.exec(val); - return { - reason: reason, - timestamp: performance.now(), - position: stalledPosition - }; + if (match === null) { + var _error = new MPDError("`" + displayName + "` property has an unrecognized format \"" + val + "\""); + + return [null, _error]; } - return null; + var duration = parseFloat((0,is_non_empty_string/* default */.Z)(match[2]) ? match[2] : "0") * 365 * 24 * 60 * 60 + parseFloat((0,is_non_empty_string/* default */.Z)(match[4]) ? match[4] : "0") * 30 * 24 * 60 * 60 + parseFloat((0,is_non_empty_string/* default */.Z)(match[6]) ? match[6] : "0") * 24 * 60 * 60 + parseFloat((0,is_non_empty_string/* default */.Z)(match[8]) ? match[8] : "0") * 60 * 60 + parseFloat((0,is_non_empty_string/* default */.Z)(match[10]) ? match[10] : "0") * 60 + parseFloat((0,is_non_empty_string/* default */.Z)(match[12]) ? match[12] : "0"); + return [duration, null]; } /** - * Timings observable. - * - * This Observable samples snapshots of player's current state: - * * time position - * * playback rate - * * current buffered range - * * gap with current buffered range ending - * * media duration - * - * In addition to sampling, this Observable also reacts to "seeking" and "play" - * events. + * Parse MPD byterange attributes into arrays of two elements: the start and + * the end. * - * Observable is shared for performance reason: reduces the number of event - * listeners and intervals/timeouts but also limit access to the media element - * properties and gap calculations. + * The returned value is a tuple of two elements where: + * 1. the first value is the parsed value - or `null` if we could not parse + * it + * 2. the second value is a possible error encountered while parsing this + * value - set to `null` if no error was encountered. + * @param {string} val + * @param {string} displayName + * @returns {Array. | Error | null>} + */ + + +function parseByteRange(val, displayName) { + var match = rangeRe.exec(val); + + if (match === null) { + var error = new MPDError("`" + displayName + "` property has an unrecognized format \"" + val + "\""); + return [null, error]; + } else { + return [[+match[1], +match[2]], null]; + } +} +/** + * Parse MPD base64 attribute into an Uint8Array. + * the end. * - * The sampling is manual instead of based on "timeupdate" to reduce the - * number of events. - * @param {HTMLMediaElement} mediaElement - * @param {Object} options - * @returns {Observable} + * The returned value is a tuple of two elements where: + * 1. the first value is the parsed value - or `null` if we could not parse + * it + * 2. the second value is a possible error encountered while parsing this + * value - set to `null` if no error was encountered. + * @param {string} val + * @param {string} displayName + * @returns {Uint8Array | Error | null>} */ -function createClock(mediaElement, options) { - return (0,defer/* defer */.P)(function () { - var lastTimings = (0,object_assign/* default */.Z)(getMediaInfos(mediaElement, "init"), { - stalled: null, - getCurrentTime: function getCurrentTime() { - return mediaElement.currentTime; - } - }); +function parseBase64(val, displayName) { + try { + return [(0,base64/* base64ToBytes */.K)(val), null]; + } catch (_) { + var error = new MPDError("`" + displayName + "` is not a valid base64 string: \"" + val + "\""); + return [null, error]; + } +} +/** + * @param {Element} root + * @returns {Object} + */ - function getCurrentClockTick(state) { - var mediaTimings = getMediaInfos(mediaElement, state); - var stalledState = getStalledStatus(lastTimings, mediaTimings, options); - var timings = (0,object_assign/* default */.Z)({}, { - stalled: stalledState, - getCurrentTime: function getCurrentTime() { - return mediaElement.currentTime; - } - }, mediaTimings); - log/* default.debug */.Z.debug("API: current media element state", timings); - return timings; - } - var eventObs = SCANNED_MEDIA_ELEMENTS_EVENTS.map(function (eventName) { - return (0,fromEvent/* fromEvent */.R)(mediaElement, eventName).pipe((0,mapTo/* mapTo */.h)(eventName)); - }); - var interval = options.lowLatencyMode ? SAMPLING_INTERVAL_LOW_LATENCY : options.withMediaSource ? SAMPLING_INTERVAL_MEDIASOURCE : SAMPLING_INTERVAL_NO_MEDIASOURCE; - var interval$ = (0,observable_interval/* interval */.F)(interval).pipe((0,mapTo/* mapTo */.h)("timeupdate")); - return merge/* merge.apply */.T.apply(void 0, [interval$].concat(eventObs)).pipe((0,map/* map */.U)(function (state) { - lastTimings = getCurrentClockTick(state); +function parseScheme(root) { + var schemeIdUri; + var value; - if (log/* default.getLevel */.Z.getLevel() === "DEBUG") { - log/* default.debug */.Z.debug("API: current playback timeline:\n" + prettyPrintBuffered(lastTimings.buffered, lastTimings.position), "\n" + state); - } + for (var i = 0; i < root.attributes.length; i++) { + var attribute = root.attributes[i]; - return lastTimings; - }), (0,startWith/* startWith */.O)(lastTimings)); - }).pipe((0,multicast/* multicast */.O)(function () { - return new ReplaySubject/* ReplaySubject */.t(1); - }), // Always emit the last - (0,refCount/* refCount */.x)()); + switch (attribute.name) { + case "schemeIdUri": + schemeIdUri = attribute.value; + break; + + case "value": + value = attribute.value; + break; + } + } + + return { + schemeIdUri: schemeIdUri, + value: value + }; } /** - * Pretty print a TimeRanges Object, to see the current content of it in a - * one-liner string. - * - * @example - * This function is called by giving it directly the TimeRanges, such as: - * ```js - * prettyPrintBuffered(document.getElementsByTagName("video")[0].buffered); - * ``` - * - * Let's consider this possible return: - * - * ``` - * 0.00|==29.95==|29.95 ~30.05~ 60.00|==29.86==|89.86 - * ^14 - * ``` - * This means that our video element has 29.95 seconds of buffer between 0 and - * 29.95 seconds. - * Then 30.05 seconds where no buffer is found. - * Then 29.86 seconds of buffer between 60.00 and 89.86 seconds. - * - * A caret on the second line indicates the current time we're at. - * The number coming after it is the current time. - * @param {TimeRanges} buffered - * @param {number} currentTime - * @returns {string} + * Create a function to factorize the MPD parsing logic. + * @param {Object} dest - The destination object which will contain the parsed + * values. + * @param {Array.} warnings - An array which will contain every parsing + * error encountered. + * @return {Function} */ -function prettyPrintBuffered(buffered, currentTime) { - var str = ""; - var currentTimeStr = ""; +function ValueParser(dest, warnings) { + /** + * Parse a single value and add it to the `dest` objects. + * If an error arised while parsing, add it at the end of the `warnings` array. + * @param {string} objKey - The key which will be added to the `dest` object. + * @param {string} val - The value found in the MPD which we should parse. + * @param {Function} parsingFn - The parsing function adapted for this value. + * @param {string} displayName - The name of the key as it appears in the MPD. + * This is used only in error formatting, + */ + return function (val, _ref) { + var asKey = _ref.asKey, + parser = _ref.parser, + dashName = _ref.dashName; - for (var i = 0; i < buffered.length; i++) { - var start = buffered.start(i); - var end = buffered.end(i); - var fixedStart = start.toFixed(2); - var fixedEnd = end.toFixed(2); - var fixedDuration = (end - start).toFixed(2); - var newIntervalStr = fixedStart + "|==" + fixedDuration + "==|" + fixedEnd; - str += newIntervalStr; + var _parser = parser(val, dashName), + parsingResult = _parser[0], + parsingError = _parser[1]; - if (currentTimeStr.length === 0 && end > currentTime) { - var padBefore = str.length - Math.floor(newIntervalStr.length / 2); - currentTimeStr = " ".repeat(padBefore) + ("^" + currentTime); + if (parsingError !== null) { + log/* default.warn */.Z.warn(parsingError.message); + warnings.push(parsingError); } - if (i < buffered.length - 1) { - var nextStart = buffered.start(i + 1); - var fixedDiff = (nextStart - end).toFixed(2); - var holeStr = " ~" + fixedDiff + "~ "; - str += holeStr; + if (parsingResult !== null) { + dest[asKey] = parsingResult; + } + }; +} +/** + * Error arising when parsing the MPD. + * @class MPDError + * @extends Error + */ - if (currentTimeStr.length === 0 && currentTime < nextStart) { - var _padBefore = str.length - Math.floor(holeStr.length / 2); - currentTimeStr = " ".repeat(_padBefore) + ("^" + currentTime); - } - } - } +var MPDError = /*#__PURE__*/function (_Error) { + (0,inheritsLoose/* default */.Z)(MPDError, _Error); - if (currentTimeStr.length === 0) { - currentTimeStr = " ".repeat(str.length) + ("^" + currentTime); + /** + * @param {string} message + */ + function MPDError(message) { + var _this; + + _this = _Error.call(this) || this; // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class + + Object.setPrototypeOf((0,assertThisInitialized/* default */.Z)(_this), MPDError.prototype); + _this.name = "MPDError"; + _this.message = message; + return _this; } - return str + "\n" + currentTimeStr; -} + return MPDError; +}( /*#__PURE__*/(0,wrapNativeSuper/* default */.Z)(Error)); -/* harmony default export */ const clock = (createClock); -;// CONCATENATED MODULE: ./src/core/api/emit_seek_events.ts + +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/BaseURL.ts /** * Copyright 2015 CANAL+ Group * @@ -23880,32 +22203,48 @@ function prettyPrintBuffered(buffered, currentTime) { * limitations under the License. */ - /** - * 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 clock$ - * Observable. - * @param {HTMLMediaElement} mediaElement - * @param {Observable} clock$ - * @returns {Observable} + * Parse an BaseURL element into an BaseURL intermediate + * representation. + * @param {Element} adaptationSetElement - The BaseURL root element. + * @returns {Array.} */ -function emitSeekEvents(mediaElement, clock$) { - return (0,defer/* defer */.P)(function () { - if (mediaElement === null) { - return empty/* EMPTY */.E; +function parseBaseURL(root) { + var attributes = {}; + var value = root.textContent; + var warnings = []; + var parseValue = ValueParser(attributes, warnings); + + if (value === null || value.length === 0) { + return [undefined, warnings]; + } + + for (var i = 0; i < root.attributes.length; i++) { + var attribute = root.attributes[i]; + + switch (attribute.name) { + case "availabilityTimeOffset": + if (attribute.value === "INF") { + attributes.availabilityTimeOffset = Infinity; + } else { + parseValue(attribute.value, { + asKey: "availabilityTimeOffset", + parser: parseMPDInteger, + dashName: "availabilityTimeOffset" + }); + } + + break; } + } - var isSeeking$ = (0,fromEvent/* fromEvent */.R)(mediaElement, "seeking").pipe((0,mapTo/* mapTo */.h)("seeking")); - var hasSeeked$ = (0,fromEvent/* fromEvent */.R)(mediaElement, "seeked").pipe((0,switchMapTo/* switchMapTo */.c)(clock$.pipe((0,mergeMap/* mergeMap */.zg)(function (tick) { - return tick.stalled === null || tick.stalled.reason !== "seeking" ? (0,of.of)("seeked") : empty/* EMPTY */.E; - }), (0,take/* take */.q)(1)))); - var seekingEvents$ = (0,merge/* merge */.T)(isSeeking$, hasSeeked$); - return mediaElement.seeking ? seekingEvents$.pipe((0,startWith/* startWith */.O)("seeking")) : seekingEvents$; - }); + return [{ + value: value, + attributes: attributes + }, warnings]; } -;// CONCATENATED MODULE: ./src/core/api/get_player_state.ts +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/ContentComponent.ts /** * Copyright 2015 CANAL+ Group * @@ -23922,60 +22261,41 @@ function emitSeekEvents(mediaElement, clock$) { * limitations under the License. */ -var FORCED_ENDED_THRESHOLD = config/* default.FORCED_ENDED_THRESHOLD */.Z.FORCED_ENDED_THRESHOLD; -/** Player state dictionnary. */ - -var PLAYER_STATES = { - STOPPED: "STOPPED", - LOADED: "LOADED", - LOADING: "LOADING", - PLAYING: "PLAYING", - PAUSED: "PAUSED", - ENDED: "ENDED", - BUFFERING: "BUFFERING", - SEEKING: "SEEKING", - RELOADING: "RELOADING" -}; /** - * Get state string for a _loaded_ content. - * @param {HTMLMediaElement} mediaElement - * @param {boolean} isPlaying - false when the player is paused. true otherwise. - * @param {Object} stalledStatus - Current stalled state: - * - null when not stalled - * - an object with a description of the situation if stalled. - * @returns {string} + * Parse a "ContentComponent" Element in a DASH MPD. + * @param {Element} root + * @returns {Object} */ +function parseContentComponent(root) { + var ret = {}; -function getLoadedContentState(mediaElement, isPlaying, stalledStatus) { - if (mediaElement.ended) { - return PLAYER_STATES.ENDED; - } + for (var i = 0; i < root.attributes.length; i++) { + var attribute = root.attributes[i]; - if (stalledStatus !== null) { - // On some old browsers (e.g. Chrome 54), the browser does not - // emit an 'ended' event in some conditions. Detect if we - // reached the end by comparing the current position and the - // duration instead. - var gapBetweenDurationAndCurrentTime = Math.abs(mediaElement.duration - mediaElement.currentTime); + switch (attribute.name) { + case "id": + ret.id = attribute.value; + break; - if (FORCED_ENDED_THRESHOLD != null && gapBetweenDurationAndCurrentTime < FORCED_ENDED_THRESHOLD) { - return PLAYER_STATES.ENDED; - } + case "lang": + ret.language = attribute.value; + break; - return stalledStatus.reason === "seeking" ? PLAYER_STATES.SEEKING : PLAYER_STATES.BUFFERING; + case "contentType": + ret.contentType = attribute.value; + break; + + case "par": + ret.par = attribute.value; + break; + } } - return isPlaying ? PLAYER_STATES.PLAYING : PLAYER_STATES.PAUSED; + return ret; } -// EXTERNAL MODULE: ./src/utils/languages/normalize.ts + 2 modules -var normalize = __webpack_require__(5553); -;// CONCATENATED MODULE: ./src/core/api/option_utils.ts -function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { 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."); } it = o[Symbol.iterator](); return it.next.bind(it); } - -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; } - +// EXTERNAL MODULE: ./src/utils/string_parsing.ts +var string_parsing = __webpack_require__(3635); +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/ContentProtection.ts /** * Copyright 2015 CANAL+ Group * @@ -23992,479 +22312,520 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len * limitations under the License. */ + + /** - * This file exports various helpers to parse options given to various APIs, - * throw if something is wrong, and return a normalized option object. + * @param {NodeList} contentProtectionChildren + * @Returns {Object} */ +function parseContentProtectionChildren(contentProtectionChildren) { + var warnings = []; + var cencPssh = []; + for (var i = 0; i < contentProtectionChildren.length; i++) { + if (contentProtectionChildren[i].nodeType === Node.ELEMENT_NODE) { + var currentElement = contentProtectionChildren[i]; + if (currentElement.nodeName === "cenc:pssh") { + var content = currentElement.textContent; + if (content !== null && content.length > 0) { + var _parseBase = parseBase64(content, "cenc:pssh"), + toUint8Array = _parseBase[0], + error = _parseBase[1]; + if (error !== null) { + log/* default.warn */.Z.warn(error.message); + warnings.push(error); + } + if (toUint8Array !== null) { + cencPssh.push(toUint8Array); + } + } + } + } + } -var DEFAULT_AUDIO_TRACK_SWITCHING_MODE = config/* default.DEFAULT_AUDIO_TRACK_SWITCHING_MODE */.Z.DEFAULT_AUDIO_TRACK_SWITCHING_MODE, - DEFAULT_AUTO_PLAY = config/* default.DEFAULT_AUTO_PLAY */.Z.DEFAULT_AUTO_PLAY, - DEFAULT_CODEC_SWITCHING_BEHAVIOR = config/* default.DEFAULT_CODEC_SWITCHING_BEHAVIOR */.Z.DEFAULT_CODEC_SWITCHING_BEHAVIOR, - DEFAULT_ENABLE_FAST_SWITCHING = config/* default.DEFAULT_ENABLE_FAST_SWITCHING */.Z.DEFAULT_ENABLE_FAST_SWITCHING, - DEFAULT_INITIAL_BITRATES = config/* default.DEFAULT_INITIAL_BITRATES */.Z.DEFAULT_INITIAL_BITRATES, - DEFAULT_LIMIT_VIDEO_WIDTH = config/* default.DEFAULT_LIMIT_VIDEO_WIDTH */.Z.DEFAULT_LIMIT_VIDEO_WIDTH, - DEFAULT_MANUAL_BITRATE_SWITCHING_MODE = config/* default.DEFAULT_MANUAL_BITRATE_SWITCHING_MODE */.Z.DEFAULT_MANUAL_BITRATE_SWITCHING_MODE, - DEFAULT_MIN_BITRATES = config/* default.DEFAULT_MIN_BITRATES */.Z.DEFAULT_MIN_BITRATES, - DEFAULT_MAX_BITRATES = config/* default.DEFAULT_MAX_BITRATES */.Z.DEFAULT_MAX_BITRATES, - DEFAULT_MAX_BUFFER_AHEAD = config/* default.DEFAULT_MAX_BUFFER_AHEAD */.Z.DEFAULT_MAX_BUFFER_AHEAD, - DEFAULT_MAX_BUFFER_BEHIND = config/* default.DEFAULT_MAX_BUFFER_BEHIND */.Z.DEFAULT_MAX_BUFFER_BEHIND, - DEFAULT_SHOW_NATIVE_SUBTITLE = config/* default.DEFAULT_SHOW_NATIVE_SUBTITLE */.Z.DEFAULT_SHOW_NATIVE_SUBTITLE, - DEFAULT_STOP_AT_END = config/* default.DEFAULT_STOP_AT_END */.Z.DEFAULT_STOP_AT_END, - DEFAULT_TEXT_TRACK_MODE = config/* default.DEFAULT_TEXT_TRACK_MODE */.Z.DEFAULT_TEXT_TRACK_MODE, - DEFAULT_THROTTLE_WHEN_HIDDEN = config/* default.DEFAULT_THROTTLE_WHEN_HIDDEN */.Z.DEFAULT_THROTTLE_WHEN_HIDDEN, - DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN = config/* default.DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN */.Z.DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN, - DEFAULT_WANTED_BUFFER_AHEAD = config/* default.DEFAULT_WANTED_BUFFER_AHEAD */.Z.DEFAULT_WANTED_BUFFER_AHEAD; + return [{ + cencPssh: cencPssh + }, warnings]; +} /** - * Parse options given to the API constructor and set default options as found - * in the config. - * - * Do not mutate anything, only cross the given options and sane default options - * (most coming from the config). - * @param {Object|undefined} options + * @param {Element} root * @returns {Object} */ -function parseConstructorOptions(options) { - var maxBufferAhead; - var maxBufferBehind; - var wantedBufferAhead; - var throttleWhenHidden; - var throttleVideoBitrateWhenHidden; - var preferredAudioTracks; - var preferredTextTracks; - var preferredVideoTracks; - var videoElement; - var initialVideoBitrate; - var initialAudioBitrate; - var minAudioBitrate; - var minVideoBitrate; - var maxAudioBitrate; - var maxVideoBitrate; - if ((0,is_null_or_undefined/* default */.Z)(options.maxBufferAhead)) { - maxBufferAhead = DEFAULT_MAX_BUFFER_AHEAD; - } else { - maxBufferAhead = Number(options.maxBufferAhead); +function parseContentProtectionAttributes(root) { + var ret = {}; - if (isNaN(maxBufferAhead)) { - throw new Error("Invalid maxBufferAhead parameter. Should be a number."); - } - } + for (var i = 0; i < root.attributes.length; i++) { + var attribute = root.attributes[i]; - if ((0,is_null_or_undefined/* default */.Z)(options.maxBufferBehind)) { - maxBufferBehind = DEFAULT_MAX_BUFFER_BEHIND; - } else { - maxBufferBehind = Number(options.maxBufferBehind); + switch (attribute.name) { + case "schemeIdUri": + ret.schemeIdUri = attribute.value; + break; - if (isNaN(maxBufferBehind)) { - throw new Error("Invalid maxBufferBehind parameter. Should be a number."); + case "value": + ret.value = attribute.value; + break; + + case "cenc:default_KID": + ret.keyId = (0,string_parsing/* hexToBytes */.nr)(attribute.value.replace(/-/g, "")); } } - if ((0,is_null_or_undefined/* default */.Z)(options.wantedBufferAhead)) { - wantedBufferAhead = DEFAULT_WANTED_BUFFER_AHEAD; - } else { - wantedBufferAhead = Number(options.wantedBufferAhead); + return ret; +} +/** + * @param {Element} contentProtectionElement + * @returns {Object} + */ - if (isNaN(wantedBufferAhead)) { - /* eslint-disable max-len */ - throw new Error("Invalid wantedBufferAhead parameter. Should be a number."); - /* eslint-enable max-len */ - } - } - var limitVideoWidth = (0,is_null_or_undefined/* default */.Z)(options.limitVideoWidth) ? DEFAULT_LIMIT_VIDEO_WIDTH : !!options.limitVideoWidth; +function parseContentProtection(contentProtectionElement) { + var _parseContentProtecti = parseContentProtectionChildren(contentProtectionElement.childNodes), + children = _parseContentProtecti[0], + childrenWarnings = _parseContentProtecti[1]; - if (!(0,is_null_or_undefined/* default */.Z)(options.throttleWhenHidden)) { - (0,warn_once/* default */.Z)("`throttleWhenHidden` API is deprecated. Consider using " + "`throttleVideoBitrateWhenHidden` instead."); - throttleWhenHidden = !!options.throttleWhenHidden; - } else { - throttleWhenHidden = DEFAULT_THROTTLE_WHEN_HIDDEN; - } // `throttleWhenHidden` and `throttleVideoBitrateWhenHidden` can be in conflict - // Do not activate the latter if the former is + var attributes = parseContentProtectionAttributes(contentProtectionElement); + return [{ + children: children, + attributes: attributes + }, childrenWarnings]; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/Initialization.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. + */ +/** + * @param {Element} root + * @returns {Array.} + */ - if (throttleWhenHidden) { - throttleVideoBitrateWhenHidden = false; - } else { - throttleVideoBitrateWhenHidden = (0,is_null_or_undefined/* default */.Z)(options.throttleVideoBitrateWhenHidden) ? DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN : !!options.throttleVideoBitrateWhenHidden; - } +function parseInitialization(root) { + var parsedInitialization = {}; + var warnings = []; + var parseValue = ValueParser(parsedInitialization, warnings); - if (options.preferredTextTracks !== undefined) { - if (!Array.isArray(options.preferredTextTracks)) { - (0,warn_once/* default */.Z)("Invalid `preferredTextTracks` option, it should be an Array"); - preferredTextTracks = []; - } else { - preferredTextTracks = options.preferredTextTracks; - } - } else { - preferredTextTracks = []; - } + for (var i = 0; i < root.attributes.length; i++) { + var attribute = root.attributes[i]; - if (options.preferredAudioTracks !== undefined) { - if (!Array.isArray(options.preferredAudioTracks)) { - (0,warn_once/* default */.Z)("Invalid `preferredAudioTracks` option, it should be an Array"); - preferredAudioTracks = []; - } else { - preferredAudioTracks = options.preferredAudioTracks; - } - } else { - preferredAudioTracks = []; - } + switch (attribute.name) { + case "range": + parseValue(attribute.value, { + asKey: "range", + parser: parseByteRange, + dashName: "range" + }); + break; - if (options.preferredVideoTracks !== undefined) { - if (!Array.isArray(options.preferredVideoTracks)) { - (0,warn_once/* default */.Z)("Invalid `preferredVideoTracks` option, it should be an Array"); - preferredVideoTracks = []; - } else { - preferredVideoTracks = options.preferredVideoTracks; + case "sourceURL": + parsedInitialization.media = attribute.value; + break; } - } else { - preferredVideoTracks = []; } - if ((0,is_null_or_undefined/* default */.Z)(options.videoElement)) { - videoElement = document.createElement("video"); - } else if (options.videoElement instanceof HTMLMediaElement) { - videoElement = options.videoElement; - } else { - /* eslint-disable max-len */ - throw new Error("Invalid videoElement parameter. Should be a HTMLMediaElement."); - /* eslint-enable max-len */ - } + return [parsedInitialization, warnings]; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/SegmentBase.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. + */ - if ((0,is_null_or_undefined/* default */.Z)(options.initialVideoBitrate)) { - initialVideoBitrate = DEFAULT_INITIAL_BITRATES.video; - } else { - initialVideoBitrate = Number(options.initialVideoBitrate); - if (isNaN(initialVideoBitrate)) { - /* eslint-disable max-len */ - throw new Error("Invalid initialVideoBitrate parameter. Should be a number."); - /* eslint-enable max-len */ - } - } +/** + * Parse a SegmentBase element into a SegmentBase intermediate representation. + * @param {Element} root - The SegmentBase root element. + * @returns {Array} + */ - if ((0,is_null_or_undefined/* default */.Z)(options.initialAudioBitrate)) { - initialAudioBitrate = DEFAULT_INITIAL_BITRATES.audio; - } else { - initialAudioBitrate = Number(options.initialAudioBitrate); +function parseSegmentBase(root) { + var attributes = {}; + var warnings = []; + var parseValue = ValueParser(attributes, warnings); + var segmentBaseChildren = root.childNodes; - if (isNaN(initialAudioBitrate)) { - /* eslint-disable max-len */ - throw new Error("Invalid initialAudioBitrate parameter. Should be a number."); - /* eslint-enable max-len */ - } - } + for (var i = 0; i < segmentBaseChildren.length; i++) { + if (segmentBaseChildren[i].nodeType === Node.ELEMENT_NODE) { + var currentNode = segmentBaseChildren[i]; - if ((0,is_null_or_undefined/* default */.Z)(options.minVideoBitrate)) { - minVideoBitrate = DEFAULT_MIN_BITRATES.video; - } else { - minVideoBitrate = Number(options.minVideoBitrate); + if (currentNode.nodeName === "Initialization") { + var _parseInitialization = parseInitialization(currentNode), + initialization = _parseInitialization[0], + initializationWarnings = _parseInitialization[1]; - if (isNaN(minVideoBitrate)) { - throw new Error("Invalid maxVideoBitrate parameter. Should be a number."); + attributes.initialization = initialization; + warnings = warnings.concat(initializationWarnings); + } } } - if ((0,is_null_or_undefined/* default */.Z)(options.minAudioBitrate)) { - minAudioBitrate = DEFAULT_MIN_BITRATES.audio; - } else { - minAudioBitrate = Number(options.minAudioBitrate); + for (var _i = 0; _i < root.attributes.length; _i++) { + var attr = root.attributes[_i]; - if (isNaN(minAudioBitrate)) { - throw new Error("Invalid minAudioBitrate parameter. Should be a number."); - } - } + switch (attr.name) { + case "timescale": + parseValue(attr.value, { + asKey: "timescale", + parser: parseMPDInteger, + dashName: "timescale" + }); + break; - if ((0,is_null_or_undefined/* default */.Z)(options.maxVideoBitrate)) { - maxVideoBitrate = DEFAULT_MAX_BITRATES.video; - } else { - maxVideoBitrate = Number(options.maxVideoBitrate); + case "presentationTimeOffset": + parseValue(attr.value, { + asKey: "presentationTimeOffset", + parser: parseMPDFloat, + dashName: "presentationTimeOffset" + }); + break; - if (isNaN(maxVideoBitrate)) { - throw new Error("Invalid maxVideoBitrate parameter. Should be a number."); - } else if (minVideoBitrate > maxVideoBitrate) { - throw new Error("Invalid maxVideoBitrate parameter. Its value, \"" + (maxVideoBitrate + "\", is inferior to the set minVideoBitrate, \"") + (minVideoBitrate + "\"")); - } - } + case "indexRange": + parseValue(attr.value, { + asKey: "indexRange", + parser: parseByteRange, + dashName: "indexRange" + }); + break; - if ((0,is_null_or_undefined/* default */.Z)(options.maxAudioBitrate)) { - maxAudioBitrate = DEFAULT_MAX_BITRATES.audio; - } else { - maxAudioBitrate = Number(options.maxAudioBitrate); + case "indexRangeExact": + parseValue(attr.value, { + asKey: "indexRangeExact", + parser: parseBoolean, + dashName: "indexRangeExact" + }); + break; - if (isNaN(maxAudioBitrate)) { - throw new Error("Invalid maxAudioBitrate parameter. Should be a number."); - } else if (minAudioBitrate > maxAudioBitrate) { - throw new Error("Invalid maxAudioBitrate parameter. Its value, \"" + (maxAudioBitrate + "\", is inferior to the set minAudioBitrate, \"") + (minAudioBitrate + "\"")); + case "availabilityTimeOffset": + parseValue(attr.value, { + asKey: "availabilityTimeOffset", + parser: parseMPDFloat, + dashName: "availabilityTimeOffset" + }); + break; + + case "availabilityTimeComplete": + parseValue(attr.value, { + asKey: "availabilityTimeComplete", + parser: parseBoolean, + dashName: "availabilityTimeComplete" + }); + break; + + case "duration": + parseValue(attr.value, { + asKey: "duration", + parser: parseMPDInteger, + dashName: "duration" + }); + break; + + case "startNumber": + parseValue(attr.value, { + asKey: "startNumber", + parser: parseMPDInteger, + dashName: "startNumber" + }); + break; } } - var stopAtEnd = (0,is_null_or_undefined/* default */.Z)(options.stopAtEnd) ? DEFAULT_STOP_AT_END : !!options.stopAtEnd; - return { - maxBufferAhead: maxBufferAhead, - maxBufferBehind: maxBufferBehind, - limitVideoWidth: limitVideoWidth, - videoElement: videoElement, - wantedBufferAhead: wantedBufferAhead, - throttleWhenHidden: throttleWhenHidden, - throttleVideoBitrateWhenHidden: throttleVideoBitrateWhenHidden, - preferredAudioTracks: preferredAudioTracks, - preferredTextTracks: preferredTextTracks, - preferredVideoTracks: preferredVideoTracks, - initialAudioBitrate: initialAudioBitrate, - initialVideoBitrate: initialVideoBitrate, - minAudioBitrate: minAudioBitrate, - minVideoBitrate: minVideoBitrate, - maxAudioBitrate: maxAudioBitrate, - maxVideoBitrate: maxVideoBitrate, - stopAtEnd: stopAtEnd - }; + return [attributes, warnings]; } +// EXTERNAL MODULE: ./src/utils/object_assign.ts +var object_assign = __webpack_require__(8026); +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/SegmentURL.ts /** - * Check the format of given reload options. - * Throw if format in invalid. - * @param {object | undefined} options + * 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. */ +/** + * Parse a SegmentURL element into a SegmentURL intermediate + * representation. + * @param {Element} root - The SegmentURL root element. + * @returns {Array} + */ -function checkReloadOptions(options) { - var _a, _b, _c, _d; +function parseSegmentURL(root) { + var parsedSegmentURL = {}; + var warnings = []; + var parseValue = ValueParser(parsedSegmentURL, warnings); - if (options === null || typeof options !== "object" && options !== undefined) { - throw new Error("API: reload - Invalid options format."); - } + for (var i = 0; i < root.attributes.length; i++) { + var attribute = root.attributes[i]; - if ((options === null || options === void 0 ? void 0 : options.reloadAt) === null || typeof (options === null || options === void 0 ? void 0 : options.reloadAt) !== "object" && (options === null || options === void 0 ? void 0 : options.reloadAt) !== undefined) { - throw new Error("API: reload - Invalid 'reloadAt' option format."); - } + switch (attribute.name) { + case "media": + parsedSegmentURL.media = attribute.value; + break; - if (typeof ((_a = options === null || options === void 0 ? void 0 : options.reloadAt) === null || _a === void 0 ? void 0 : _a.position) !== "number" && ((_b = options === null || options === void 0 ? void 0 : options.reloadAt) === null || _b === void 0 ? void 0 : _b.position) !== undefined) { - throw new Error("API: reload - Invalid 'reloadAt.position' option format."); - } + case "indexRange": + parseValue(attribute.value, { + asKey: "indexRange", + parser: parseByteRange, + dashName: "indexRange" + }); + break; - if (typeof ((_c = options === null || options === void 0 ? void 0 : options.reloadAt) === null || _c === void 0 ? void 0 : _c.relative) !== "number" && ((_d = options === null || options === void 0 ? void 0 : options.reloadAt) === null || _d === void 0 ? void 0 : _d.relative) !== undefined) { - throw new Error("API: reload - Invalid 'reloadAt.relative' option format."); + case "index": + parsedSegmentURL.index = attribute.value; + break; + + case "mediaRange": + parseValue(attribute.value, { + asKey: "mediaRange", + parser: parseByteRange, + dashName: "mediaRange" + }); + break; + } } + + return [parsedSegmentURL, warnings]; } +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/SegmentList.ts /** - * Parse options given to loadVideo and set default options as found - * in the config. + * Copyright 2015 CANAL+ Group * - * Do not mutate anything, only cross the given options and sane default options - * (most coming from the config). + * 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 * - * Throws if any mandatory option is not set. - * @param {Object|undefined} options - * @param {Object} ctx - The player context, needed for some default values. - * @returns {Object} + * 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 parseLoadVideoOptions(options) { - var _a, _b, _c, _d, _e, _f, _g; - - var url; - var transport; - var keySystems; - var textTrackMode; - var textTrackElement; - var startAt; - - if ((0,is_null_or_undefined/* default */.Z)(options)) { - throw new Error("No option set on loadVideo"); - } - if (!(0,is_null_or_undefined/* default */.Z)(options.url)) { - url = String(options.url); - } else if ((0,is_null_or_undefined/* default */.Z)((_a = options.transportOptions) === null || _a === void 0 ? void 0 : _a.initialManifest) && (0,is_null_or_undefined/* default */.Z)((_b = options.transportOptions) === null || _b === void 0 ? void 0 : _b.manifestLoader)) { - throw new Error("Unable to load a content: no url set on loadVideo.\n" + "Please provide at least either an `url` argument, a " + "`transportOptions.initialManifest` option or a " + "`transportOptions.manifestLoader` option so the RxPlayer " + "can load the content."); - } +/** + * @param {Element} root + * @returns {Array} + */ - if ((0,is_null_or_undefined/* default */.Z)(options.transport)) { - throw new Error("No transport set on loadVideo"); - } else { - transport = String(options.transport); - } +function parseSegmentList(root) { + var _parseSegmentBase = parseSegmentBase(root), + base = _parseSegmentBase[0], + baseWarnings = _parseSegmentBase[1]; - var autoPlay = (0,is_null_or_undefined/* default */.Z)(options.autoPlay) ? DEFAULT_AUTO_PLAY : !!options.autoPlay; + var warnings = baseWarnings; + var list = []; + var segmentListChildren = root.childNodes; - if ((0,is_null_or_undefined/* default */.Z)(options.keySystems)) { - keySystems = []; - } else { - keySystems = Array.isArray(options.keySystems) ? options.keySystems : [options.keySystems]; + for (var i = 0; i < segmentListChildren.length; i++) { + if (segmentListChildren[i].nodeType === Node.ELEMENT_NODE) { + var currentNode = segmentListChildren[i]; - for (var _iterator = _createForOfIteratorHelperLoose(keySystems), _step; !(_step = _iterator()).done;) { - var keySystem = _step.value; + if (currentNode.nodeName === "SegmentURL") { + var _parseSegmentURL = parseSegmentURL(currentNode), + segmentURL = _parseSegmentURL[0], + segmentURLWarnings = _parseSegmentURL[1]; - if (typeof keySystem.type !== "string" || typeof keySystem.getLicense !== "function") { - throw new Error("Invalid key system given: Missing type string or " + "getLicense callback"); + list.push(segmentURL); + warnings = warnings.concat(segmentURLWarnings); } } } - 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 manifestUpdateUrl = (_d = options.transportOptions) === null || _d === void 0 ? void 0 : _d.manifestUpdateUrl; - 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; + var baseDuration = base.duration; - if (!(0,array_includes/* default */.Z)(["seamless", "direct"], audioTrackSwitchingMode)) { - log/* default.warn */.Z.warn("The `audioTrackSwitchingMode` loadVideo option must match one of " + "the following strategy name:\n" + "- `seamless`\n" + "- `direct`\n" + "If badly set, " + DEFAULT_AUDIO_TRACK_SWITCHING_MODE + " strategy will be used as default"); - audioTrackSwitchingMode = DEFAULT_AUDIO_TRACK_SWITCHING_MODE; + if (baseDuration == null) { + throw new Error("Invalid SegmentList: no duration"); } - var onCodecSwitch = (0,is_null_or_undefined/* default */.Z)(options.onCodecSwitch) ? DEFAULT_CODEC_SWITCHING_BEHAVIOR : options.onCodecSwitch; + var ret = (0,object_assign/* default */.Z)(base, { + list: list, + // Ugly but TS is too dumb there + duration: baseDuration + }); + return [ret, warnings]; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/SegmentTimeline.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. + */ - if (!(0,array_includes/* default */.Z)(["continue", "reload"], onCodecSwitch)) { - log/* default.warn */.Z.warn("The `onCodecSwitch` loadVideo option must match one of " + "the following string:\n" + "- `continue`\n" + "- `reload`\n" + "If badly set, " + DEFAULT_CODEC_SWITCHING_BEHAVIOR + " will be used as default"); - onCodecSwitch = DEFAULT_CODEC_SWITCHING_BEHAVIOR; - } +/** + * @param {Element} root + * @returns {Function} + */ +function createSegmentTimelineParser(root) { + var result = null; + return function () { + if (result === null) { + var elements = root.getElementsByTagName("S"); + result = elements; + return elements; + } - var transportOptions = (0,object_assign/* default */.Z)({}, transportOptsArg, { - /* eslint-disable import/no-deprecated */ - supplementaryImageTracks: [], - supplementaryTextTracks: [], + return result; + }; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/SegmentTemplate.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. + */ - /* eslint-enable import/no-deprecated */ - lowLatencyMode: lowLatencyMode - }); // remove already parsed data to simplify the `transportOptions` object - delete transportOptions.initialManifest; - delete transportOptions.manifestUpdateUrl; - delete transportOptions.minimumManifestUpdateInterval; - if (options.supplementaryTextTracks !== undefined) { - (0,warn_once/* default */.Z)("The `supplementaryTextTracks` loadVideo option is deprecated.\n" + "Please use the `TextTrackRenderer` tool instead."); - var supplementaryTextTracks = Array.isArray(options.supplementaryTextTracks) ? options.supplementaryTextTracks : [options.supplementaryTextTracks]; - for (var _iterator2 = _createForOfIteratorHelperLoose(supplementaryTextTracks), _step2; !(_step2 = _iterator2()).done;) { - var supplementaryTextTrack = _step2.value; +/** + * Parse initialization attribute found in SegmentTemplateTemplate to + * correspond to the initialization found in a regular segmentBase. + * @param {string} attrValue + * @returns {Object} + */ - if (typeof supplementaryTextTrack.language !== "string" || typeof supplementaryTextTrack.mimeType !== "string" || typeof supplementaryTextTrack.url !== "string") { - throw new Error("Invalid supplementary text track given. " + "Missing either language, mimetype or url"); - } - } +function parseInitializationAttribute(attrValue) { + return { + media: attrValue + }; +} +/** + * Parse a SegmentTemplate element into a SegmentTemplate intermediate + * representation. + * @param {Element} root - The SegmentTemplate root element. + * @returns {Array} + */ - transportOptions.supplementaryTextTracks = supplementaryTextTracks; - } - if (options.supplementaryImageTracks !== undefined) { - (0,warn_once/* default */.Z)("The `supplementaryImageTracks` loadVideo option is deprecated.\n" + "Please use the `parseBifThumbnails` tool instead."); - var supplementaryImageTracks = Array.isArray(options.supplementaryImageTracks) ? options.supplementaryImageTracks : [options.supplementaryImageTracks]; +function parseSegmentTemplate(root) { + var _parseSegmentBase = parseSegmentBase(root), + base = _parseSegmentBase[0], + segmentBaseWarnings = _parseSegmentBase[1]; - for (var _iterator3 = _createForOfIteratorHelperLoose(supplementaryImageTracks), _step3; !(_step3 = _iterator3()).done;) { - var supplementaryImageTrack = _step3.value; + var warnings = segmentBaseWarnings; + var timelineParser; // First look for a possible SegmentTimeline - if (typeof supplementaryImageTrack.mimeType !== "string" || typeof supplementaryImageTrack.url !== "string") { - throw new Error("Invalid supplementary image track given. " + "Missing either mimetype or url"); + for (var i = 0; i < root.childNodes.length; i++) { + if (root.childNodes[i].nodeType === Node.ELEMENT_NODE) { + var currentNode = root.childNodes[i]; + + if (currentNode.nodeName === "SegmentTimeline") { + timelineParser = createSegmentTimelineParser(currentNode); } } - - transportOptions.supplementaryImageTracks = supplementaryImageTracks; } - if ((0,is_null_or_undefined/* default */.Z)(options.textTrackMode)) { - textTrackMode = DEFAULT_TEXT_TRACK_MODE; - } else { - if (options.textTrackMode !== "native" && options.textTrackMode !== "html") { - throw new Error("Invalid textTrackMode."); - } - - textTrackMode = options.textTrackMode; - } + var ret = (0,object_assign/* default */.Z)({}, base, { + duration: base.duration, + timelineParser: timelineParser + }); + var parseValue = ValueParser(ret, warnings); - if (!(0,is_null_or_undefined/* default */.Z)(options.defaultAudioTrack)) { - (0,warn_once/* default */.Z)("The `defaultAudioTrack` loadVideo option is deprecated.\n" + "Please use the `preferredAudioTracks` constructor option or the" + "`setPreferredAudioTracks` method instead"); - } + for (var _i = 0; _i < root.attributes.length; _i++) { + var attribute = root.attributes[_i]; - var defaultAudioTrack = (0,normalize/* normalizeAudioTrack */.iH)(options.defaultAudioTrack); + switch (attribute.nodeName) { + case "initialization": + if (ret.initialization == null) { + ret.initialization = parseInitializationAttribute(attribute.value); + } - if (!(0,is_null_or_undefined/* default */.Z)(options.defaultTextTrack)) { - (0,warn_once/* default */.Z)("The `defaultTextTrack` loadVideo option is deprecated.\n" + "Please use the `preferredTextTracks` constructor option or the" + "`setPreferredTextTracks` method instead"); - } + break; - var defaultTextTrack = (0,normalize/* normalizeTextTrack */.Y1)(options.defaultTextTrack); - var hideNativeSubtitle = !DEFAULT_SHOW_NATIVE_SUBTITLE; + case "index": + ret.index = attribute.value; + break; - if (!(0,is_null_or_undefined/* default */.Z)(options.hideNativeSubtitle)) { - (0,warn_once/* default */.Z)("The `hideNativeSubtitle` loadVideo option is deprecated"); - hideNativeSubtitle = !!options.hideNativeSubtitle; - } + case "availabilityTimeOffset": + if (attribute.value === "INF") { + ret.availabilityTimeOffset = Infinity; + } - 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; + parseValue(attribute.value, { + asKey: "availabilityTimeOffset", + parser: parseMPDInteger, + dashName: "availabilityTimeOffset" + }); + break; - if (textTrackMode === "html") { - // TODO Better way to express that in TypeScript? - if ((0,is_null_or_undefined/* default */.Z)(options.textTrackElement)) { - throw new Error("You have to provide a textTrackElement " + "in \"html\" textTrackMode."); - } else if (!(options.textTrackElement instanceof HTMLElement)) { - throw new Error("textTrackElement should be an HTMLElement."); - } else { - textTrackElement = options.textTrackElement; - } - } else if (!(0,is_null_or_undefined/* default */.Z)(options.textTrackElement)) { - log/* default.warn */.Z.warn("API: You have set a textTrackElement without being in " + "an \"html\" textTrackMode. It will be ignored."); - } + case "media": + ret.media = attribute.value; + break; - if (!(0,is_null_or_undefined/* default */.Z)(options.startAt)) { - // TODO Better way to express that in TypeScript? - if (options.startAt.wallClockTime instanceof Date) { - var wallClockTime = options.startAt.wallClockTime.getTime() / 1000; - startAt = (0,object_assign/* default */.Z)({}, options.startAt, { - wallClockTime: wallClockTime - }); - } else { - startAt = options.startAt; + case "bitstreamSwitching": + parseValue(attribute.value, { + asKey: "bitstreamSwitching", + parser: parseBoolean, + dashName: "bitstreamSwitching" + }); + break; } } - var networkConfig = (0,is_null_or_undefined/* default */.Z)(options.networkConfig) ? {} : { - manifestRetry: options.networkConfig.manifestRetry, - offlineRetry: options.networkConfig.offlineRetry, - segmentRetry: options.networkConfig.segmentRetry - }; // TODO without cast - - /* eslint-disable @typescript-eslint/consistent-type-assertions */ - - return { - autoPlay: autoPlay, - defaultAudioTrack: defaultAudioTrack, - defaultTextTrack: defaultTextTrack, - enableFastSwitching: enableFastSwitching, - hideNativeSubtitle: hideNativeSubtitle, - keySystems: keySystems, - initialManifest: initialManifest, - lowLatencyMode: lowLatencyMode, - manualBitrateSwitchingMode: manualBitrateSwitchingMode, - audioTrackSwitchingMode: audioTrackSwitchingMode, - manifestUpdateUrl: manifestUpdateUrl, - minimumManifestUpdateInterval: minimumManifestUpdateInterval, - networkConfig: networkConfig, - onCodecSwitch: onCodecSwitch, - startAt: startAt, - textTrackElement: textTrackElement, - textTrackMode: textTrackMode, - transport: transport, - transportOptions: transportOptions, - url: url - }; - /* eslint-enable @typescript-eslint/consistent-type-assertions */ + return [ret, warnings]; } - - -// EXTERNAL MODULE: ./src/utils/languages/index.ts -var languages = __webpack_require__(7829); -;// CONCATENATED MODULE: ./src/core/api/track_choice_manager.ts +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/Representation.ts /** * Copyright 2015 CANAL+ Group * @@ -24485,1171 +22846,1111 @@ var languages = __webpack_require__(7829); - /** - * Transform an array of IAudioTrackPreference into an array of - * INormalizedPreferredAudioTrack to be exploited by the TrackChoiceManager. - * @param {Array.} - * @returns {Array.} + * @param {NodeList} representationChildren + * @returns {Object} */ -function normalizeAudioTracks(tracks) { - return tracks.map(function (t) { - return t == null ? t : { - normalized: t.language === undefined ? undefined : (0,languages/* default */.ZP)(t.language), - audioDescription: t.audioDescription, - codec: t.codec - }; - }); -} -/** - * Transform an array of ITextTrackPreference into an array of - * INormalizedPreferredTextTrack to be exploited by the TrackChoiceManager. - * @param {Array.} tracks - * @returns {Array.} - */ +function parseRepresentationChildren(representationChildren) { + var children = { + baseURLs: [] + }; + var warnings = []; + for (var i = 0; i < representationChildren.length; i++) { + if (representationChildren[i].nodeType === Node.ELEMENT_NODE) { + var currentElement = representationChildren[i]; -function normalizeTextTracks(tracks) { - return tracks.map(function (t) { - return t == null ? t : { - normalized: (0,languages/* default */.ZP)(t.language), - closedCaption: t.closedCaption - }; - }); -} -/** - * Manage audio and text tracks for all active periods. - * Choose the audio and text tracks for each period and record this choice. - * @class TrackChoiceManager - */ + switch (currentElement.nodeName) { + case "BaseURL": + var _parseBaseURL = parseBaseURL(currentElement), + baseURLObj = _parseBaseURL[0], + baseURLWarnings = _parseBaseURL[1]; + if (baseURLObj !== undefined) { + children.baseURLs.push(baseURLObj); + } -var TrackChoiceManager = /*#__PURE__*/function () { - function TrackChoiceManager() { - this._periods = new SortedList(function (a, b) { - return a.period.start - b.period.start; - }); - this._audioChoiceMemory = new WeakMap(); - this._textChoiceMemory = new WeakMap(); - this._videoChoiceMemory = new WeakMap(); - this._preferredAudioTracks = []; - this._preferredTextTracks = []; - this._preferredVideoTracks = []; - } - /** - * Set the list of preferred audio tracks, in preference order. - * @param {Array.} preferredAudioTracks - * @param {boolean} shouldApply - `true` if those preferences should be - * applied on the currently loaded Period. `false` if it should only - * be applied to new content. - */ + warnings = warnings.concat(baseURLWarnings); + break; + case "InbandEventStream": + if (children.inbandEventStreams === undefined) { + children.inbandEventStreams = []; + } - var _proto = TrackChoiceManager.prototype; + children.inbandEventStreams.push(parseScheme(currentElement)); + break; - _proto.setPreferredAudioTracks = function setPreferredAudioTracks(preferredAudioTracks, shouldApply) { - this._preferredAudioTracks = preferredAudioTracks; + case "SegmentBase": + var _parseSegmentBase = parseSegmentBase(currentElement), + segmentBase = _parseSegmentBase[0], + segmentBaseWarnings = _parseSegmentBase[1]; - if (shouldApply) { - this._applyAudioPreferences(); - } - } - /** - * Set the list of preferred text tracks, in preference order. - * @param {Array.} preferredTextTracks - * @param {boolean} shouldApply - `true` if those preferences should be - * applied on the currently loaded Periods. `false` if it should only - * be applied to new content. - */ - ; + children.segmentBase = segmentBase; - _proto.setPreferredTextTracks = function setPreferredTextTracks(preferredTextTracks, shouldApply) { - this._preferredTextTracks = preferredTextTracks; + if (segmentBaseWarnings.length > 0) { + warnings = warnings.concat(segmentBaseWarnings); + } - if (shouldApply) { - this._applyTextPreferences(); - } - } - /** - * Set the list of preferred text tracks, in preference order. - * @param {Array.} tracks - * @param {boolean} shouldApply - `true` if those preferences should be - * applied on the currently loaded Period. `false` if it should only - * be applied to new content. - */ - ; + break; - _proto.setPreferredVideoTracks = function setPreferredVideoTracks(preferredVideoTracks, shouldApply) { - this._preferredVideoTracks = preferredVideoTracks; + case "SegmentList": + var _parseSegmentList = parseSegmentList(currentElement), + segmentList = _parseSegmentList[0], + segmentListWarnings = _parseSegmentList[1]; - if (shouldApply) { - this._applyVideoPreferences(); - } - } - /** - * Add Subject 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 - */ - ; + warnings = warnings.concat(segmentListWarnings); + children.segmentList = segmentList; + break; - _proto.addPeriod = function addPeriod(bufferType, period, adaptation$) { - var periodItem = getPeriodItem(this._periods, period); - var adaptations = period.getPlayableAdaptations(bufferType); + case "SegmentTemplate": + var _parseSegmentTemplate = parseSegmentTemplate(currentElement), + segmentTemplate = _parseSegmentTemplate[0], + segmentTemplateWarnings = _parseSegmentTemplate[1]; - if (periodItem != null) { - if (periodItem[bufferType] != null) { - log/* default.warn */.Z.warn("TrackChoiceManager: " + bufferType + " already added for period", period); - return; - } else { - periodItem[bufferType] = { - adaptations: adaptations, - adaptation$: adaptation$ - }; + warnings = warnings.concat(segmentTemplateWarnings); + children.segmentTemplate = segmentTemplate; + break; } - } else { - var _this$_periods$add; - - this._periods.add((_this$_periods$add = { - period: period - }, _this$_periods$add[bufferType] = { - adaptations: adaptations, - adaptation$: adaptation$ - }, _this$_periods$add)); } } - /** - * Remove Subject to choose an "audio", "video" or "text" Adaptation for a - * Period. - * @param {string} bufferType - The concerned buffer type - * @param {Period} period - The concerned Period. - */ - ; - _proto.removePeriod = function removePeriod(bufferType, period) { - var periodIndex = findPeriodIndex(this._periods, period); + return [children, warnings]; +} +/** + * @param {Element} representationElement + * @returns {Array} + */ - if (periodIndex == null) { - log/* default.warn */.Z.warn("TrackChoiceManager: " + bufferType + " not found for period", period); - return; - } - var periodItem = this._periods.get(periodIndex); +function parseRepresentationAttributes(representationElement) { + var attributes = {}; + var warnings = []; + var parseValue = ValueParser(attributes, warnings); - if (periodItem[bufferType] == null) { - log/* default.warn */.Z.warn("TrackChoiceManager: " + bufferType + " already removed for period", period); - return; - } + for (var i = 0; i < representationElement.attributes.length; i++) { + var attr = representationElement.attributes[i]; - delete periodItem[bufferType]; + switch (attr.name) { + case "audioSamplingRate": + attributes.audioSamplingRate = attr.value; + break; - if (periodItem.audio == null && periodItem.text == null && periodItem.video == null) { - this._periods.removeElement(periodItem); - } - }; + case "bandwidth": + parseValue(attr.value, { + asKey: "bitrate", + parser: parseMPDInteger, + dashName: "bandwidth" + }); + break; - _proto.resetPeriods = function resetPeriods() { - while (this._periods.length() > 0) { - this._periods.pop(); - } - } - /** - * Update the choice of all added Periods based on: - * 1. What was the last chosen adaptation - * 2. If not found, the preferences - */ - ; + case "codecs": + attributes.codecs = attr.value; + break; - _proto.update = function update() { - this._resetChosenAudioTracks(); + case "codingDependency": + parseValue(attr.value, { + asKey: "codingDependency", + parser: parseBoolean, + dashName: "codingDependency" + }); + break; - this._resetChosenTextTracks(); + case "frameRate": + attributes.frameRate = attr.value; + break; - this._resetChosenVideoTracks(); - } - /** - * Emit initial audio Adaptation through the given Subject based on: - * - the preferred audio tracks - * - the last choice for this period, if one - * @param {Period} period - The concerned Period. - */ - ; + case "height": + parseValue(attr.value, { + asKey: "height", + parser: parseMPDInteger, + dashName: "height" + }); + break; - _proto.setInitialAudioTrack = function setInitialAudioTrack(period) { - var periodItem = getPeriodItem(this._periods, period); - var audioInfos = periodItem != null ? periodItem.audio : null; + case "id": + attributes.id = attr.value; + break; - if (audioInfos == null || periodItem == null) { - throw new Error("TrackChoiceManager: Given Period not found."); - } + case "maxPlayoutRate": + parseValue(attr.value, { + asKey: "maxPlayoutRate", + parser: parseMPDFloat, + dashName: "maxPlayoutRate" + }); + break; - var audioAdaptations = period.getPlayableAdaptations("audio"); + case "maximumSAPPeriod": + parseValue(attr.value, { + asKey: "maximumSAPPeriod", + parser: parseMPDFloat, + dashName: "maximumSAPPeriod" + }); + break; - var chosenAudioAdaptation = this._audioChoiceMemory.get(period); + case "mimeType": + attributes.mimeType = attr.value; + break; - if (chosenAudioAdaptation === null) { - // If the Period was previously without audio, keep it that way - audioInfos.adaptation$.next(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); + case "profiles": + attributes.profiles = attr.value; + break; - this._audioChoiceMemory.set(period, optimalAdaptation); + case "qualityRanking": + parseValue(attr.value, { + asKey: "qualityRanking", + parser: parseMPDInteger, + dashName: "qualityRanking" + }); + break; - audioInfos.adaptation$.next(optimalAdaptation); - } else { - audioInfos.adaptation$.next(chosenAudioAdaptation); // set last one + case "segmentProfiles": + attributes.segmentProfiles = attr.value; + break; + + case "width": + parseValue(attr.value, { + asKey: "width", + parser: parseMPDInteger, + dashName: "width" + }); + break; } } - /** - * Emit initial text Adaptation through the given Subject based on: - * - the preferred text tracks - * - the last choice for this period, if one - * @param {Period} period - The concerned Period. - */ - ; - - _proto.setInitialTextTrack = function setInitialTextTrack(period) { - var periodItem = getPeriodItem(this._periods, period); - var textInfos = periodItem != null ? periodItem.text : null; - if (textInfos == null || periodItem == null) { - throw new Error("TrackChoiceManager: Given Period not found."); - } + if (attributes.bitrate === undefined) { + warnings.push(new MPDError("No bitrate found on a Representation")); + } - var textAdaptations = period.getPlayableAdaptations("text"); + return [attributes, warnings]; +} +/** + * @param {Element} representationElement + * @returns {Array} + */ - var chosenTextAdaptation = this._textChoiceMemory.get(period); - if (chosenTextAdaptation === null) { - // If the Period was previously without text, keep it that way - textInfos.adaptation$.next(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); +function createRepresentationIntermediateRepresentation(representationElement) { + var _parseRepresentationC = parseRepresentationChildren(representationElement.childNodes), + children = _parseRepresentationC[0], + childrenWarnings = _parseRepresentationC[1]; - this._textChoiceMemory.set(period, optimalAdaptation); + var _parseRepresentationA = parseRepresentationAttributes(representationElement), + attributes = _parseRepresentationA[0], + attrsWarnings = _parseRepresentationA[1]; - textInfos.adaptation$.next(optimalAdaptation); - } else { - textInfos.adaptation$.next(chosenTextAdaptation); // set last one - } - } - /** - * Emit initial video Adaptation through the given Subject based on: - * - the preferred video tracks - * - the last choice for this period, if one - * @param {Period} period - The concerned Period. - */ - ; + var warnings = childrenWarnings.concat(attrsWarnings); + return [{ + children: children, + attributes: attributes + }, warnings]; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/AdaptationSet.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. + */ - _proto.setInitialVideoTrack = function setInitialVideoTrack(period) { - var periodItem = getPeriodItem(this._periods, period); - var videoInfos = periodItem != null ? periodItem.video : null; - if (videoInfos == null || periodItem == null) { - throw new Error("TrackChoiceManager: Given Period not found."); - } - var videoAdaptations = period.getPlayableAdaptations("video"); - var chosenVideoAdaptation = this._videoChoiceMemory.get(period); - if (chosenVideoAdaptation === null) { - // If the Period was previously without video, keep it that way - videoInfos.adaptation$.next(null); - } else if (chosenVideoAdaptation === undefined || !(0,array_includes/* default */.Z)(videoAdaptations, chosenVideoAdaptation)) { - var preferredVideoTracks = this._preferredVideoTracks; - var optimalAdaptation = findFirstOptimalVideoAdaptation(videoAdaptations, preferredVideoTracks); - this._videoChoiceMemory.set(period, optimalAdaptation); - videoInfos.adaptation$.next(optimalAdaptation); - } else { - videoInfos.adaptation$.next(chosenVideoAdaptation); // set last one - } - } - /** - * Set audio track based on the ID of its adaptation for a given added Period. - * @param {Period} period - The concerned Period. - * @param {string} wantedId - adaptation id of the wanted track - */ - ; - _proto.setAudioTrackByID = function setAudioTrackByID(period, wantedId) { - var periodItem = getPeriodItem(this._periods, period); - var audioInfos = periodItem != null ? periodItem.audio : null; +/** + * Parse child nodes from an AdaptationSet. + * @param {NodeList} adaptationSetChildren - The AdaptationSet child nodes. + * @returns {Array.} + */ - if (audioInfos == null) { - throw new Error("TrackChoiceManager: Given Period not found."); - } +function parseAdaptationSetChildren(adaptationSetChildren) { + var children = { + baseURLs: [], + representations: [] + }; + var contentProtections = []; + var warnings = []; - var wantedAdaptation = (0,array_find/* default */.Z)(audioInfos.adaptations, function (_ref) { - var id = _ref.id; - return id === wantedId; - }); + for (var i = 0; i < adaptationSetChildren.length; i++) { + if (adaptationSetChildren[i].nodeType === Node.ELEMENT_NODE) { + var currentElement = adaptationSetChildren[i]; - if (wantedAdaptation === undefined) { - throw new Error("Audio Track not found."); - } + switch (currentElement.nodeName) { + case "Accessibility": + if (children.accessibilities === undefined) { + children.accessibilities = [parseScheme(currentElement)]; + } else { + children.accessibilities.push(parseScheme(currentElement)); + } - var chosenAudioAdaptation = this._audioChoiceMemory.get(period); + break; - if (chosenAudioAdaptation === wantedAdaptation) { - return; - } + case "BaseURL": + var _parseBaseURL = parseBaseURL(currentElement), + baseURLObj = _parseBaseURL[0], + baseURLWarnings = _parseBaseURL[1]; - this._audioChoiceMemory.set(period, wantedAdaptation); + if (baseURLObj !== undefined) { + children.baseURLs.push(baseURLObj); + } - audioInfos.adaptation$.next(wantedAdaptation); - } - /** - * Set text track based on the ID of its adaptation for a given added Period. - * @param {Period} period - The concerned Period. - * @param {string} wantedId - adaptation id of the wanted track - */ - ; + if (baseURLWarnings.length > 0) { + warnings = warnings.concat(baseURLWarnings); + } - _proto.setTextTrackByID = function setTextTrackByID(period, wantedId) { - var periodItem = getPeriodItem(this._periods, period); - var textInfos = periodItem != null ? periodItem.text : null; + break; - if (textInfos == null) { - throw new Error("TrackChoiceManager: Given Period not found."); - } + case "ContentComponent": + children.contentComponent = parseContentComponent(currentElement); + break; - var wantedAdaptation = (0,array_find/* default */.Z)(textInfos.adaptations, function (_ref2) { - var id = _ref2.id; - return id === wantedId; - }); + case "EssentialProperty": + if (children.essentialProperties == null) { + children.essentialProperties = [parseScheme(currentElement)]; + } else { + children.essentialProperties.push(parseScheme(currentElement)); + } - if (wantedAdaptation === undefined) { - throw new Error("Text Track not found."); - } + break; - var chosenTextAdaptation = this._textChoiceMemory.get(period); + case "InbandEventStream": + if (children.inbandEventStreams === undefined) { + children.inbandEventStreams = []; + } - if (chosenTextAdaptation === wantedAdaptation) { - return; - } + children.inbandEventStreams.push(parseScheme(currentElement)); + break; - this._textChoiceMemory.set(period, wantedAdaptation); + case "Representation": + var _createRepresentation = createRepresentationIntermediateRepresentation(currentElement), + representation = _createRepresentation[0], + representationWarnings = _createRepresentation[1]; - textInfos.adaptation$.next(wantedAdaptation); - } - /** - * Set video track based on the ID of its adaptation for a given added Period. - * @param {Period} period - The concerned Period. - * @param {string} wantedId - adaptation id of the wanted track - * - * @throws Error - Throws if the period given has not been added - * @throws Error - Throws if the given id is not found in any video adaptation - * of the given Period. - */ - ; + children.representations.push(representation); - _proto.setVideoTrackByID = function setVideoTrackByID(period, wantedId) { - var periodItem = getPeriodItem(this._periods, period); - var videoInfos = periodItem != null ? periodItem.video : null; + if (representationWarnings.length > 0) { + warnings = warnings.concat(representationWarnings); + } - if (videoInfos == null) { - throw new Error("LanguageManager: Given Period not found."); - } + break; - var wantedAdaptation = (0,array_find/* default */.Z)(videoInfos.adaptations, function (_ref3) { - var id = _ref3.id; - return id === wantedId; - }); + case "Role": + if (children.roles == null) { + children.roles = [parseScheme(currentElement)]; + } else { + children.roles.push(parseScheme(currentElement)); + } - if (wantedAdaptation === undefined) { - throw new Error("Video Track not found."); - } + break; - var chosenVideoAdaptation = this._videoChoiceMemory.get(period); + case "SupplementalProperty": + if (children.supplementalProperties == null) { + children.supplementalProperties = [parseScheme(currentElement)]; + } else { + children.supplementalProperties.push(parseScheme(currentElement)); + } - if (chosenVideoAdaptation === wantedAdaptation) { - return; - } + break; - this._videoChoiceMemory.set(period, wantedAdaptation); + case "SegmentBase": + var _parseSegmentBase = parseSegmentBase(currentElement), + segmentBase = _parseSegmentBase[0], + segmentBaseWarnings = _parseSegmentBase[1]; - videoInfos.adaptation$.next(wantedAdaptation); - } - /** - * Disable the current text track for a given period. - * - * @param {Period} period - The concerned Period. - * - * @throws Error - Throws if the period given has not been added - */ - ; + children.segmentBase = segmentBase; - _proto.disableTextTrack = function disableTextTrack(period) { - var periodItem = getPeriodItem(this._periods, period); - var textInfos = periodItem != null ? periodItem.text : null; + if (segmentBaseWarnings.length > 0) { + warnings = warnings.concat(segmentBaseWarnings); + } - if (textInfos == null) { - throw new Error("TrackChoiceManager: Given Period not found."); - } + break; - var chosenTextAdaptation = this._textChoiceMemory.get(period); + case "SegmentList": + var _parseSegmentList = parseSegmentList(currentElement), + segmentList = _parseSegmentList[0], + segmentListWarnings = _parseSegmentList[1]; - if (chosenTextAdaptation === null) { - return; - } + children.segmentList = segmentList; - this._textChoiceMemory.set(period, null); + if (segmentListWarnings.length > 0) { + warnings = warnings.concat(segmentListWarnings); + } - textInfos.adaptation$.next(null); - } - /** - * Disable the current video track for a given period. - * @param {Object} period - * @throws Error - Throws if the period given has not been added - */ - ; + break; - _proto.disableVideoTrack = function disableVideoTrack(period) { - var periodItem = getPeriodItem(this._periods, period); - var videoInfos = periodItem === null || periodItem === void 0 ? void 0 : periodItem.video; + case "SegmentTemplate": + var _parseSegmentTemplate = parseSegmentTemplate(currentElement), + segmentTemplate = _parseSegmentTemplate[0], + segmentTemplateWarnings = _parseSegmentTemplate[1]; - if (videoInfos === undefined) { - throw new Error("TrackManager: Given Period not found."); - } + children.segmentTemplate = segmentTemplate; - var chosenVideoAdaptation = this._videoChoiceMemory.get(period); + if (segmentTemplateWarnings.length > 0) { + warnings = warnings.concat(segmentTemplateWarnings); + } - if (chosenVideoAdaptation === null) { - return; - } + break; - this._videoChoiceMemory.set(period, null); + case "ContentProtection": + var _parseContentProtecti = parseContentProtection(currentElement), + contentProtection = _parseContentProtecti[0], + contentProtectionWarnings = _parseContentProtecti[1]; - videoInfos.adaptation$.next(null); - } - /** - * Returns an object describing the chosen audio track for the given audio - * Period. - * - * Returns null is the the current audio track is disabled or not - * set yet. - * - * @param {Period} period - The concerned Period. - * @returns {Object|null} - The audio track chosen for this Period - */ - ; + if (contentProtectionWarnings.length > 0) { + warnings = warnings.concat(contentProtectionWarnings); + } - _proto.getChosenAudioTrack = function getChosenAudioTrack(period) { - var periodItem = getPeriodItem(this._periods, period); - var audioInfos = periodItem != null ? periodItem.audio : null; + if (contentProtection !== undefined) { + contentProtections.push(contentProtection); + } - if (audioInfos == null) { - return null; + break; + // case "Rating": + // children.rating = currentElement; + // break; + // case "Viewpoint": + // children.viewpoint = currentElement; + // break; + } } + } - var chosenTrack = this._audioChoiceMemory.get(period); + if (contentProtections.length > 0) { + children.contentProtections = contentProtections; + } - if (chosenTrack == null) { - return null; - } + return [children, warnings]; +} +/** + * Parse every attributes from an AdaptationSet root element into a simple JS + * object. + * @param {Element} root - The AdaptationSet root element. + * @returns {Array.} + */ - var audioTrack = { - language: (0,take_first_set/* default */.Z)(chosenTrack.language, ""), - normalized: (0,take_first_set/* default */.Z)(chosenTrack.normalizedLanguage, ""), - audioDescription: chosenTrack.isAudioDescription === true, - id: chosenTrack.id, - representations: chosenTrack.representations.map(parseAudioRepresentation) - }; - if (chosenTrack.isDub === true) { - audioTrack.dub = true; - } +function parseAdaptationSetAttributes(root) { + var parsedAdaptation = {}; + var warnings = []; + var parseValue = ValueParser(parsedAdaptation, warnings); - return audioTrack; - } - /** - * Returns an object describing the chosen text track for the given text - * Period. - * - * Returns null is the the current text track is disabled or not - * set yet. - * - * @param {Period} period - The concerned Period. - * @returns {Object|null} - The text track chosen for this Period - */ - ; + for (var i = 0; i < root.attributes.length; i++) { + var attribute = root.attributes[i]; - _proto.getChosenTextTrack = function getChosenTextTrack(period) { - var periodItem = getPeriodItem(this._periods, period); - var textInfos = periodItem != null ? periodItem.text : null; + switch (attribute.name) { + case "id": + parsedAdaptation.id = attribute.value; + break; - if (textInfos == null) { - return null; - } + case "group": + parseValue(attribute.value, { + asKey: "group", + parser: parseMPDInteger, + dashName: "group" + }); + break; - var chosenTextAdaptation = this._textChoiceMemory.get(period); + case "lang": + parsedAdaptation.language = attribute.value; + break; - if (chosenTextAdaptation == null) { - return null; - } + case "contentType": + parsedAdaptation.contentType = attribute.value; + break; - return { - 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 - }; - } - /** - * Returns an object describing the chosen video track for the given video - * Period. - * - * Returns null is the the current video track is disabled or not - * set yet. - * - * @param {Period} period - The concerned Period. - * @returns {Object|null} - The video track chosen for this Period - */ - ; + case "par": + parsedAdaptation.par = attribute.value; + break; - _proto.getChosenVideoTrack = function getChosenVideoTrack(period) { - var periodItem = getPeriodItem(this._periods, period); - var videoInfos = periodItem != null ? periodItem.video : null; + case "minBandwidth": + parseValue(attribute.value, { + asKey: "minBitrate", + parser: parseMPDInteger, + dashName: "minBandwidth" + }); + break; - if (videoInfos == null) { - return null; - } + case "maxBandwidth": + parseValue(attribute.value, { + asKey: "maxBitrate", + parser: parseMPDInteger, + dashName: "maxBandwidth" + }); + break; - var chosenVideoAdaptation = this._videoChoiceMemory.get(period); + case "minWidth": + parseValue(attribute.value, { + asKey: "minWidth", + parser: parseMPDInteger, + dashName: "minWidth" + }); + break; - if (chosenVideoAdaptation == null) { - return null; - } + case "maxWidth": + parseValue(attribute.value, { + asKey: "maxWidth", + parser: parseMPDInteger, + dashName: "maxWidth" + }); + break; - var videoTrack = { - id: chosenVideoAdaptation.id, - representations: chosenVideoAdaptation.representations.map(parseVideoRepresentation) - }; - - if (chosenVideoAdaptation.isSignInterpreted === true) { - videoTrack.signInterpreted = true; - } - - return videoTrack; - } - /** - * Returns all available audio tracks for a given Period, as an array of - * objects. - * - * @returns {Array.} - */ - ; + case "minHeight": + parseValue(attribute.value, { + asKey: "minHeight", + parser: parseMPDInteger, + dashName: "minHeight" + }); + break; - _proto.getAvailableAudioTracks = function getAvailableAudioTracks(period) { - var periodItem = getPeriodItem(this._periods, period); - var audioInfos = periodItem != null ? periodItem.audio : null; + case "maxHeight": + parseValue(attribute.value, { + asKey: "maxHeight", + parser: parseMPDInteger, + dashName: "maxHeight" + }); + break; - if (audioInfos == null) { - return []; - } + case "minFrameRate": + { + parsedAdaptation.minFrameRate = attribute.value; + } + break; - var chosenAudioAdaptation = this._audioChoiceMemory.get(period); + case "maxFrameRate": + parsedAdaptation.maxFrameRate = attribute.value; + break; - var currentId = chosenAudioAdaptation != null ? chosenAudioAdaptation.id : null; - return audioInfos.adaptations.map(function (adaptation) { - var formatted = { - language: (0,take_first_set/* default */.Z)(adaptation.language, ""), - normalized: (0,take_first_set/* default */.Z)(adaptation.normalizedLanguage, ""), - audioDescription: adaptation.isAudioDescription === true, - id: adaptation.id, - active: currentId == null ? false : currentId === adaptation.id, - representations: adaptation.representations.map(parseAudioRepresentation) - }; + case "selectionPriority": + parseValue(attribute.value, { + asKey: "selectionPriority", + parser: parseMPDInteger, + dashName: "selectionPriority" + }); + break; - if (adaptation.isDub === true) { - formatted.dub = true; - } + case "segmentAlignment": + parseValue(attribute.value, { + asKey: "segmentAlignment", + parser: parseIntOrBoolean, + dashName: "segmentAlignment" + }); + break; - return formatted; - }); - } - /** - * Returns all available text tracks for a given Period, as an array of - * objects. - * - * @param {Period} period - * @returns {Array.} - */ - ; + case "subsegmentAlignment": + parseValue(attribute.value, { + asKey: "subsegmentAlignment", + parser: parseIntOrBoolean, + dashName: "subsegmentAlignment" + }); + break; - _proto.getAvailableTextTracks = function getAvailableTextTracks(period) { - var periodItem = getPeriodItem(this._periods, period); - var textInfos = periodItem != null ? periodItem.text : null; + case "bitstreamSwitching": + parseValue(attribute.value, { + asKey: "bitstreamSwitching", + parser: parseBoolean, + dashName: "bitstreamSwitching" + }); + break; - if (textInfos == null) { - return []; - } + case "audioSamplingRate": + parsedAdaptation.audioSamplingRate = attribute.value; + break; - var chosenTextAdaptation = this._textChoiceMemory.get(period); + case "codecs": + parsedAdaptation.codecs = attribute.value; + break; - var currentId = chosenTextAdaptation != null ? chosenTextAdaptation.id : null; - return textInfos.adaptations.map(function (adaptation) { - return { - language: (0,take_first_set/* default */.Z)(adaptation.language, ""), - normalized: (0,take_first_set/* default */.Z)(adaptation.normalizedLanguage, ""), - closedCaption: adaptation.isClosedCaption === true, - id: adaptation.id, - active: currentId == null ? false : currentId === adaptation.id - }; - }); - } - /** - * Returns all available video tracks for a given Period, as an array of - * objects. - * - * @returns {Array.} - */ - ; + case "codingDependency": + parseValue(attribute.value, { + asKey: "codingDependency", + parser: parseBoolean, + dashName: "codingDependency" + }); + break; - _proto.getAvailableVideoTracks = function getAvailableVideoTracks(period) { - var periodItem = getPeriodItem(this._periods, period); - var videoInfos = periodItem != null ? periodItem.video : null; + case "frameRate": + parsedAdaptation.frameRate = attribute.value; + break; - if (videoInfos == null) { - return []; - } + case "height": + parseValue(attribute.value, { + asKey: "height", + parser: parseMPDInteger, + dashName: "height" + }); + break; - var chosenVideoAdaptation = this._videoChoiceMemory.get(period); + case "maxPlayoutRate": + parseValue(attribute.value, { + asKey: "maxPlayoutRate", + parser: parseMPDFloat, + dashName: "maxPlayoutRate" + }); + break; - var currentId = chosenVideoAdaptation != null ? chosenVideoAdaptation.id : null; - return videoInfos.adaptations.map(function (adaptation) { - var formatted = { - id: adaptation.id, - active: currentId === null ? false : currentId === adaptation.id, - representations: adaptation.representations.map(parseVideoRepresentation) - }; + case "maximumSAPPeriod": + parseValue(attribute.value, { + asKey: "maximumSAPPeriod", + parser: parseMPDFloat, + dashName: "maximumSAPPeriod" + }); + break; - if (adaptation.isSignInterpreted === true) { - formatted.signInterpreted = true; - } + case "mimeType": + parsedAdaptation.mimeType = attribute.value; + break; - return formatted; - }); - } - /** - * Reset all audio tracks choices to corresponds to the current preferences. - */ - ; + case "profiles": + parsedAdaptation.profiles = attribute.value; + break; - _proto._applyAudioPreferences = function _applyAudioPreferences() { - // Remove all memorized choices and start over - this._audioChoiceMemory = new WeakMap(); + case "segmentProfiles": + parsedAdaptation.segmentProfiles = attribute.value; + break; - this._resetChosenAudioTracks(); + case "width": + parseValue(attribute.value, { + asKey: "width", + parser: parseMPDInteger, + dashName: "width" + }); + break; + } } - /** - * Reset all text tracks choices to corresponds to the current preferences. - */ - ; - - _proto._applyTextPreferences = function _applyTextPreferences() { - // Remove all memorized choices and start over - this._textChoiceMemory = new WeakMap(); - this._resetChosenTextTracks(); - } - /** - * Reset all video tracks choices to corresponds to the current preferences. - */ - ; + return [parsedAdaptation, warnings]; +} +/** + * Parse an AdaptationSet element into an AdaptationSet intermediate + * representation. + * @param {Element} adaptationSetElement - The AdaptationSet root element. + * @returns {Array.} + */ - _proto._applyVideoPreferences = function _applyVideoPreferences() { - // Remove all memorized choices and start over - this._videoChoiceMemory = new WeakMap(); - this._resetChosenVideoTracks(); - } - /** - * Choose again the best audio tracks for all current Periods. - * This is based on two things: - * 1. what was the track previously chosen for that Period (by checking - * `this._audioChoiceMemory`). - * 2. If no track were previously chosen or if it is not available anymore - * we check the audio preferences. - */ - ; +function createAdaptationSetIntermediateRepresentation(adaptationSetElement) { + var childNodes = adaptationSetElement.childNodes; - _proto._resetChosenAudioTracks = function _resetChosenAudioTracks() { - var _this = this; + var _parseAdaptationSetCh = parseAdaptationSetChildren(childNodes), + children = _parseAdaptationSetCh[0], + childrenWarnings = _parseAdaptationSetCh[1]; - var preferredAudioTracks = this._preferredAudioTracks; - var normalizedPref = normalizeAudioTracks(preferredAudioTracks); + var _parseAdaptationSetAt = parseAdaptationSetAttributes(adaptationSetElement), + attributes = _parseAdaptationSetAt[0], + attrsWarnings = _parseAdaptationSetAt[1]; - var recursiveUpdateAudioTrack = function recursiveUpdateAudioTrack(index) { - if (index >= _this._periods.length()) { - // we did all audio Periods, exit - return; - } + var warnings = childrenWarnings.concat(attrsWarnings); + return [{ + children: children, + attributes: attributes + }, warnings]; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/EventStream.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 periodItem = _this._periods.get(index); +/** + * Parse the EventStream node to extract Event nodes and their + * content. + * @param {Element} element + */ - if (periodItem.audio == null) { - // No audio choice for this period, check next one - recursiveUpdateAudioTrack(index + 1); - return; - } +function parseEventStream(element) { + var _a; - var period = periodItem.period, - audioItem = periodItem.audio; - var audioAdaptations = period.getPlayableAdaptations("audio"); + var streamEvents = []; + var attributes = { + timescale: 1 + }; + var warnings = []; + var parseValue = ValueParser(attributes, warnings); - var chosenAudioAdaptation = _this._audioChoiceMemory.get(period); + for (var i = 0; i < element.attributes.length; i++) { + var attribute = element.attributes[i]; - if (chosenAudioAdaptation === null || chosenAudioAdaptation !== undefined && (0,array_includes/* default */.Z)(audioAdaptations, chosenAudioAdaptation)) { - // Already best audio for this Period, check next one - recursiveUpdateAudioTrack(index + 1); - return; - } + switch (attribute.name) { + case "schemeIdUri": + attributes.schemeId = attribute.value; + break; - var optimalAdaptation = findFirstOptimalAudioAdaptation(audioAdaptations, normalizedPref); + case "timescale": + parseValue(attribute.value, { + asKey: "timescale", + parser: parseMPDInteger, + dashName: "timescale" + }); + break; - _this._audioChoiceMemory.set(period, optimalAdaptation); + case "value": + attributes.value = attribute.value; + break; - audioItem.adaptation$.next(optimalAdaptation); // previous "next" call could have changed everything, start over + default: + break; + } + } - recursiveUpdateAudioTrack(0); + for (var k = 0; k < element.childNodes.length; k++) { + var node = element.childNodes[k]; + var streamEvent = { + id: undefined, + eventPresentationTime: 0, + duration: undefined, + timescale: attributes.timescale, + data: { + type: "dash-event-stream", + value: { + schemeIdUri: (_a = attributes.schemeId) !== null && _a !== void 0 ? _a : "", + timescale: attributes.timescale, + element: node + } + } }; + var parseEventValue = ValueParser(streamEvent, warnings); - recursiveUpdateAudioTrack(0); - } - /** - * Choose again the best text tracks for all current Periods. - * This is based on two things: - * 1. what was the track previously chosen for that Period (by checking - * `this._textChoiceMemory`). - * 2. If no track were previously chosen or if it is not available anymore - * we check the text preferences. - */ - ; + if (node.nodeName === "Event" && node.nodeType === Node.ELEMENT_NODE) { + var eventAttributes = node.attributes; - _proto._resetChosenTextTracks = function _resetChosenTextTracks() { - var _this2 = this; + for (var j = 0; j < eventAttributes.length; j++) { + var _attribute = eventAttributes[j]; - var preferredTextTracks = this._preferredTextTracks; - var normalizedPref = normalizeTextTracks(preferredTextTracks); + switch (_attribute.name) { + case "presentationTime": + parseEventValue(_attribute.value, { + asKey: "eventPresentationTime", + parser: parseMPDInteger, + dashName: "presentationTime" + }); + break; - var recursiveUpdateTextTrack = function recursiveUpdateTextTrack(index) { - if (index >= _this2._periods.length()) { - // we did all text Periods, exit - return; - } + case "duration": + parseEventValue(_attribute.value, { + asKey: "duration", + parser: parseMPDInteger, + dashName: "duration" + }); + break; - var periodItem = _this2._periods.get(index); + case "id": + streamEvent.id = _attribute.value; + break; - if (periodItem.text == null) { - // No text choice for this period, check next one - recursiveUpdateTextTrack(index + 1); - return; + default: + break; + } } - var period = periodItem.period, - textItem = periodItem.text; - var textAdaptations = period.getPlayableAdaptations("text"); + streamEvents.push(streamEvent); + } + } - var chosenTextAdaptation = _this2._textChoiceMemory.get(period); + return [streamEvents, warnings]; +} - if (chosenTextAdaptation === null || chosenTextAdaptation !== undefined && (0,array_includes/* default */.Z)(textAdaptations, chosenTextAdaptation)) { - // Already best text for this Period, check next one - recursiveUpdateTextTrack(index + 1); - return; - } +/* harmony default export */ const EventStream = (parseEventStream); +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/Period.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 optimalAdaptation = findFirstOptimalTextAdaptation(textAdaptations, normalizedPref); - _this2._textChoiceMemory.set(period, optimalAdaptation); - textItem.adaptation$.next(optimalAdaptation); // previous "next" call could have changed everything, start over - recursiveUpdateTextTrack(0); - }; - recursiveUpdateTextTrack(0); - } - /** - * Choose again the best video tracks for all current Periods. - * This is based on two things: - * 1. what was the track previously chosen for that Period (by checking - * `this._videoChoiceMemory`). - * 2. If no track were previously chosen or if it is not available anymore - * we check the video preferences. - */ - ; +/** + * @param {NodeList} periodChildren + * @returns {Array} + */ - _proto._resetChosenVideoTracks = function _resetChosenVideoTracks() { - var _this3 = this; +function parsePeriodChildren(periodChildren) { + var baseURLs = []; + var adaptations = []; + var segmentTemplate; + var warnings = []; + var streamEvents = []; - var preferredVideoTracks = this._preferredVideoTracks; + for (var i = 0; i < periodChildren.length; i++) { + if (periodChildren[i].nodeType === Node.ELEMENT_NODE) { + var currentElement = periodChildren[i]; - var recursiveUpdateVideoTrack = function recursiveUpdateVideoTrack(index) { - if (index >= _this3._periods.length()) { - // we did all video Periods, exit - return; - } + switch (currentElement.nodeName) { + case "BaseURL": + var _parseBaseURL = parseBaseURL(currentElement), + baseURLObj = _parseBaseURL[0], + baseURLWarnings = _parseBaseURL[1]; - var periodItem = _this3._periods.get(index); + if (baseURLObj !== undefined) { + baseURLs.push(baseURLObj); + } - if (periodItem.video == null) { - // No video choice for this period, check next one - recursiveUpdateVideoTrack(index + 1); - return; - } + warnings = warnings.concat(baseURLWarnings); + break; - var period = periodItem.period, - videoItem = periodItem.video; - var videoAdaptations = period.getPlayableAdaptations("video"); + case "AdaptationSet": + var _createAdaptationSetI = createAdaptationSetIntermediateRepresentation(currentElement), + adaptation = _createAdaptationSetI[0], + adaptationWarnings = _createAdaptationSetI[1]; - var chosenVideoAdaptation = _this3._videoChoiceMemory.get(period); + adaptations.push(adaptation); + warnings = warnings.concat(adaptationWarnings); + break; - if (chosenVideoAdaptation === null || chosenVideoAdaptation !== undefined && (0,array_includes/* default */.Z)(videoAdaptations, chosenVideoAdaptation)) { - // Already best video for this Period, check next one - recursiveUpdateVideoTrack(index + 1); - return; - } + case "EventStream": + var _parseEventStream = EventStream(currentElement), + newStreamEvents = _parseEventStream[0], + eventStreamWarnings = _parseEventStream[1]; - var optimalAdaptation = findFirstOptimalVideoAdaptation(videoAdaptations, preferredVideoTracks); + streamEvents.push.apply(streamEvents, newStreamEvents); + warnings = warnings.concat(eventStreamWarnings); + break; - _this3._videoChoiceMemory.set(period, optimalAdaptation); + case "SegmentTemplate": + var _parseSegmentTemplate = parseSegmentTemplate(currentElement), + parsedSegmentTemplate = _parseSegmentTemplate[0], + segmentTemplateWarnings = _parseSegmentTemplate[1]; - videoItem.adaptation$.next(optimalAdaptation); // previous "next" call could have changed everything, start over + segmentTemplate = parsedSegmentTemplate; - recursiveUpdateVideoTrack(0); - }; + if (segmentTemplateWarnings.length > 0) { + warnings = warnings.concat(segmentTemplateWarnings); + } - recursiveUpdateVideoTrack(0); - }; + break; + } + } + } - return TrackChoiceManager; -}(); + return [{ + baseURLs: baseURLs, + adaptations: adaptations, + streamEvents: streamEvents, + segmentTemplate: segmentTemplate + }, warnings]; +} /** - * Create a function allowing to compare audio Adaptations with a given - * `preferredAudioTrack` preference to see if they match. - * - * This function is curried to be easily and optimally used in a loop context. - * - * @param {Object} preferredAudioTrack - The audio track preference you want to - * compare audio Adaptations to. - * @returns {Function} - Function taking in argument an audio Adaptation and - * returning `true` if it matches the `preferredAudioTrack` preference (and - * `false` otherwise. + * @param {Element} periodElement + * @returns {Array} */ +function parsePeriodAttributes(periodElement) { + var res = {}; + var warnings = []; + var parseValue = ValueParser(res, warnings); + for (var i = 0; i < periodElement.attributes.length; i++) { + var attr = periodElement.attributes[i]; -function createAudioPreferenceMatcher(preferredAudioTrack) { - /** - * Compares an audio Adaptation to the given `preferredAudioTrack` preference. - * Returns `true` if it matches, false otherwise. - * @param {Object} audioAdaptation - * @returns {boolean} - */ - return function matchAudioPreference(audioAdaptation) { - var _a; - - if (preferredAudioTrack.normalized !== undefined) { - var language = (_a = audioAdaptation.normalizedLanguage) !== null && _a !== void 0 ? _a : ""; - - if (language !== preferredAudioTrack.normalized) { - return false; - } - } + switch (attr.name) { + case "id": + res.id = attr.value; + break; - if (preferredAudioTrack.audioDescription !== undefined) { - if (preferredAudioTrack.audioDescription) { - if (audioAdaptation.isAudioDescription !== true) { - return false; - } - } else if (audioAdaptation.isAudioDescription === true) { - return false; - } - } + case "start": + parseValue(attr.value, { + asKey: "start", + parser: parseDuration, + dashName: "start" + }); + break; - if (preferredAudioTrack.codec === undefined) { - return true; - } + case "duration": + parseValue(attr.value, { + asKey: "duration", + parser: parseDuration, + dashName: "duration" + }); + break; - var regxp = preferredAudioTrack.codec.test; + case "bitstreamSwitching": + parseValue(attr.value, { + asKey: "bitstreamSwitching", + parser: parseBoolean, + dashName: "bitstreamSwitching" + }); + break; - var codecTestingFn = function codecTestingFn(rep) { - return rep.codec !== undefined && regxp.test(rep.codec); - }; + case "xlink:href": + res.xlinkHref = attr.value; + break; - if (preferredAudioTrack.codec.all) { - return audioAdaptation.representations.every(codecTestingFn); + case "xlink:actuate": + res.xlinkActuate = attr.value; + break; } + } - return audioAdaptation.representations.some(codecTestingFn); - }; + return [res, warnings]; } /** - * Find an optimal audio adaptation given their list and the array of preferred - * audio tracks sorted from the most preferred to the least preferred. - * - * `null` if the most optimal audio adaptation is no audio adaptation. - * @param {Array.} audioAdaptations - * @param {Array.} preferredAudioTracks - * @returns {Adaptation|null} + * @param {Element} periodElement + * @returns {Array} */ -function findFirstOptimalAudioAdaptation(audioAdaptations, preferredAudioTracks) { - if (audioAdaptations.length === 0) { - return null; - } - - for (var i = 0; i < preferredAudioTracks.length; i++) { - var preferredAudioTrack = preferredAudioTracks[i]; - - if (preferredAudioTrack === null) { - return null; - } - - var matchPreferredAudio = createAudioPreferenceMatcher(preferredAudioTrack); - var foundAdaptation = (0,array_find/* default */.Z)(audioAdaptations, matchPreferredAudio); - - if (foundAdaptation !== undefined) { - return foundAdaptation; - } - } // no optimal adaptation, just return the first one +function createPeriodIntermediateRepresentation(periodElement) { + var _parsePeriodChildren = parsePeriodChildren(periodElement.childNodes), + children = _parsePeriodChildren[0], + childrenWarnings = _parsePeriodChildren[1]; + var _parsePeriodAttribute = parsePeriodAttributes(periodElement), + attributes = _parsePeriodAttribute[0], + attrsWarnings = _parsePeriodAttribute[1]; - return audioAdaptations[0]; + var warnings = childrenWarnings.concat(attrsWarnings); + return [{ + children: children, + attributes: attributes + }, warnings]; } +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/MPD.ts /** - * Create a function allowing to compare text Adaptations with a given - * `preferredTextTrack` preference to see if they match. + * Copyright 2015 CANAL+ Group * - * This function is curried to be easily and optimally used in a loop context. + * 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 * - * @param {Object} preferredTextTrack - The text track preference you want to - * compare text Adaptations to. - * @returns {Function} - Function taking in argument a text Adaptation and - * returning `true` if it matches the `preferredTextTrack` preference (and - * `false` otherwise. - */ - - -function createTextPreferenceMatcher(preferredTextTrack) { - /** - * Compares a text Adaptation to the given `preferredTextTrack` preference. - * Returns `true` if it matches, false otherwise. - * @param {Object} textAdaptation - * @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); - }; -} -/** - * Find an optimal text adaptation given their list and the array of preferred - * text tracks sorted from the most preferred to the least preferred. + * http://www.apache.org/licenses/LICENSE-2.0 * - * `null` if the most optimal text adaptation is no text adaptation. - * @param {Array.} textAdaptations - * @param {Array.} preferredTextTracks - * @returns {Adaptation|null} + * 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 findFirstOptimalTextAdaptation(textAdaptations, preferredTextTracks) { - if (textAdaptations.length === 0) { - return null; - } - - for (var i = 0; i < preferredTextTracks.length; i++) { - var preferredTextTrack = preferredTextTracks[i]; - - if (preferredTextTrack === null) { - return null; - } - var matchPreferredText = createTextPreferenceMatcher(preferredTextTrack); - var foundAdaptation = (0,array_find/* default */.Z)(textAdaptations, matchPreferredText); +/** + * Parse children of the MPD's root into a simple object. + * @param {NodeList} mpdChildren + * @returns {Array.} + */ - if (foundAdaptation !== undefined) { - return foundAdaptation; - } - } // no optimal adaptation +function parseMPDChildren(mpdChildren) { + var baseURLs = []; + var locations = []; + var periods = []; + var utcTimings = []; + var warnings = []; + for (var i = 0; i < mpdChildren.length; i++) { + if (mpdChildren[i].nodeType === Node.ELEMENT_NODE) { + var currentNode = mpdChildren[i]; - return null; -} -/** - * Create a function allowing to compare video Adaptations with a given - * `preferredVideoTrack` preference to see if they match. - * - * This function is curried to be easily and optimally used in a loop context. - * - * @param {Object} preferredVideoTrack - The video track preference you want to - * compare video Adaptations to. - * @returns {Function} - Function taking in argument a video Adaptation and - * returning `true` if it matches the `preferredVideoTrack` preference (and - * `false` otherwise. - */ + switch (currentNode.nodeName) { + case "BaseURL": + var _parseBaseURL = parseBaseURL(currentNode), + baseURLObj = _parseBaseURL[0], + baseURLWarnings = _parseBaseURL[1]; + if (baseURLObj !== undefined) { + baseURLs.push(baseURLObj); + } -function createVideoPreferenceMatcher(preferredVideoTrack) { - /** - * Compares a video Adaptation to the given `preferredVideoTrack` preference. - * Returns `true` if it matches, false otherwise. - * @param {Object} videoAdaptation - * @returns {boolean} - */ - return function matchVideoPreference(videoAdaptation) { - if (preferredVideoTrack.signInterpreted !== undefined && preferredVideoTrack.signInterpreted !== videoAdaptation.isSignInterpreted) { - return false; - } + warnings = warnings.concat(baseURLWarnings); + break; - if (preferredVideoTrack.codec === undefined) { - return true; - } + case "Location": + locations.push(currentNode.textContent === null ? "" : currentNode.textContent); + break; - var regxp = preferredVideoTrack.codec.test; + case "Period": + var _createPeriodIntermed = createPeriodIntermediateRepresentation(currentNode), + period = _createPeriodIntermed[0], + periodWarnings = _createPeriodIntermed[1]; - var codecTestingFn = function codecTestingFn(rep) { - return rep.codec !== undefined && regxp.test(rep.codec); - }; + periods.push(period); + warnings = warnings.concat(periodWarnings); + break; - if (preferredVideoTrack.codec.all) { - return videoAdaptation.representations.every(codecTestingFn); + case "UTCTiming": + var utcTiming = parseScheme(currentNode); + utcTimings.push(utcTiming); + break; + } } + } - return videoAdaptation.representations.some(codecTestingFn); - }; + return [{ + baseURLs: baseURLs, + locations: locations, + periods: periods, + utcTimings: utcTimings + }, warnings]; } /** - * Find an optimal video adaptation given their list and the array of preferred - * video tracks sorted from the most preferred to the least preferred. - * - * `null` if the most optimal video adaptation is no video adaptation. - * @param {Array.} videoAdaptations - * @param {Array.} preferredvideoTracks - * @returns {Adaptation|null} + * @param {Element} root + * @returns {Array.} */ -function findFirstOptimalVideoAdaptation(videoAdaptations, preferredVideoTracks) { - if (videoAdaptations.length === 0) { - return null; - } +function parseMPDAttributes(root) { + var res = {}; + var warnings = []; + var parseValue = ValueParser(res, warnings); - for (var i = 0; i < preferredVideoTracks.length; i++) { - var preferredVideoTrack = preferredVideoTracks[i]; + for (var i = 0; i < root.attributes.length; i++) { + var attribute = root.attributes[i]; - if (preferredVideoTrack === null) { - return null; - } + switch (attribute.name) { + case "id": + res.id = attribute.value; + break; - var matchPreferredVideo = createVideoPreferenceMatcher(preferredVideoTrack); - var foundAdaptation = (0,array_find/* default */.Z)(videoAdaptations, matchPreferredVideo); + case "profiles": + res.profiles = attribute.value; + break; - if (foundAdaptation !== undefined) { - return foundAdaptation; - } - } // no optimal adaptation, just return the first one + case "type": + res.type = attribute.value; + break; + case "availabilityStartTime": + parseValue(attribute.value, { + asKey: "availabilityStartTime", + parser: parseDateTime, + dashName: "availabilityStartTime" + }); + break; - return videoAdaptations[0]; -} -/** - * Returns the index of the given `period` in the given `periods` - * SortedList. - * Returns `undefined` if that `period` is not found. - * @param {Object} periods - * @param {Object} period - * @returns {number|undefined} - */ + case "availabilityEndTime": + parseValue(attribute.value, { + asKey: "availabilityEndTime", + parser: parseDateTime, + dashName: "availabilityEndTime" + }); + break; + case "publishTime": + parseValue(attribute.value, { + asKey: "publishTime", + parser: parseDateTime, + dashName: "publishTime" + }); + break; -function findPeriodIndex(periods, period) { - for (var i = 0; i < periods.length(); i++) { - var periodI = periods.get(i); + case "mediaPresentationDuration": + parseValue(attribute.value, { + asKey: "duration", + parser: parseDuration, + dashName: "mediaPresentationDuration" + }); + break; - if (periodI.period.id === period.id) { - return i; - } - } -} -/** - * Returns element in the given `periods` SortedList that corresponds to the - * `period` given. - * Returns `undefined` if that `period` is not found. - * @param {Object} periods - * @param {Object} period - * @returns {Object|undefined} - */ + case "minimumUpdatePeriod": + parseValue(attribute.value, { + asKey: "minimumUpdatePeriod", + parser: parseDuration, + dashName: "minimumUpdatePeriod" + }); + break; + case "minBufferTime": + parseValue(attribute.value, { + asKey: "minBufferTime", + parser: parseDuration, + dashName: "minBufferTime" + }); + break; -function getPeriodItem(periods, period) { - for (var i = 0; i < periods.length(); i++) { - var periodI = periods.get(i); + case "timeShiftBufferDepth": + parseValue(attribute.value, { + asKey: "timeShiftBufferDepth", + parser: parseDuration, + dashName: "timeShiftBufferDepth" + }); + break; - if (periodI.period.id === period.id) { - return periodI; + case "suggestedPresentationDelay": + parseValue(attribute.value, { + asKey: "suggestedPresentationDelay", + parser: parseDuration, + dashName: "suggestedPresentationDelay" + }); + break; + + case "maxSegmentDuration": + parseValue(attribute.value, { + asKey: "maxSegmentDuration", + parser: parseDuration, + dashName: "maxSegmentDuration" + }); + break; + + case "maxSubsegmentDuration": + parseValue(attribute.value, { + asKey: "maxSubsegmentDuration", + parser: parseDuration, + dashName: "maxSubsegmentDuration" + }); + break; } } -} -/** - * Parse video Representation into a ITMVideoRepresentation. - * @param {Object} representation - * @returns {Object} - */ - -function parseVideoRepresentation(_ref4) { - var id = _ref4.id, - bitrate = _ref4.bitrate, - frameRate = _ref4.frameRate, - width = _ref4.width, - height = _ref4.height, - codec = _ref4.codec; - return { - id: id, - bitrate: bitrate, - frameRate: frameRate, - width: width, - height: height, - codec: codec - }; + return [res, warnings]; } /** - * Parse audio Representation into a ITMAudioRepresentation. - * @param {Object} representation - * @returns {Object} + * @param {Element} root + * @returns {Array.} */ -function parseAudioRepresentation(_ref5) { - var id = _ref5.id, - bitrate = _ref5.bitrate, - codec = _ref5.codec; - return { - id: id, - bitrate: bitrate, - codec: codec - }; -} -;// CONCATENATED MODULE: ./src/core/api/public_api.ts - +function createMPDIntermediateRepresentation(root) { + var _parseMPDChildren = parseMPDChildren(root.childNodes), + children = _parseMPDChildren[0], + childrenWarnings = _parseMPDChildren[1]; + var _parseMPDAttributes = parseMPDAttributes(root), + attributes = _parseMPDAttributes[0], + attrsWarnings = _parseMPDAttributes[1]; + var warnings = childrenWarnings.concat(attrsWarnings); + return [{ + children: children, + attributes: attributes + }, warnings]; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_availability_start_time.ts /** * Copyright 2015 CANAL+ Group * @@ -25667,2687 +23968,3254 @@ function parseAudioRepresentation(_ref5) { */ /** - * This file defines the public API for the RxPlayer. - * It also starts the different sub-parts of the player on various API calls. + * Returns the base time of the Manifest. + * @param {Object} rootAttributes + * @param {number|undefined} */ +function parseAvailabilityStartTime(rootAttributes, referenceDateTime) { + if (rootAttributes.type !== "dynamic") { + return 0; + } + if (rootAttributes.availabilityStartTime == null) { + return referenceDateTime == null ? 0 : referenceDateTime; + } + return rootAttributes.availabilityStartTime; +} +// EXTERNAL MODULE: ./src/utils/flat_map.ts +var flat_map = __webpack_require__(9592); +// EXTERNAL MODULE: ./src/utils/id_generator.ts +var id_generator = __webpack_require__(908); +// EXTERNAL MODULE: ./src/utils/object_values.ts +var object_values = __webpack_require__(1679); +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/flatten_overlapping_periods.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. + */ -/* eslint-disable-next-line max-len */ - - - - - - - - - - - - - - - +/** + * Avoid periods to overlap. + * + * According to DASH guidelines, if a period has media duration longer than + * the distance between the start of this period and the start of the next period, + * use of start times implies that the client will start the playout of the next + * period at the time stated, rather than finishing the playout of the last period. + * + * Even if that case if defined when period last(s) segment(s) is/are a bit longer, + * it can be meaningful when two periods are overlapping. We will always shorten + * the first period, and even erase it if its duration is equal to zero. + * + * Example (Periods are numbered under their manifest order) : + * + * [ Period 1 ][ Period 2 ] ------> [ Period 1 ][ Period 3 ] + * [ Period 3 ] + * + * [ Period 1 ][ Period 2 ] ------> [ Period 1 ][ 2 ][ Period 3 ] + * [ Period 3 ] + * + * [ Period 1 ][ Period 2 ] ------> [ 1 ][ Period 3 ] + * [ Period 3 ] + * + * @param {Array.} parsedPeriods + * @return {Array.} + */ +function flattenOverlappingPeriods(parsedPeriods) { + if (parsedPeriods.length === 0) { + return []; + } + var flattenedPeriods = [parsedPeriods[0]]; + for (var i = 1; i < parsedPeriods.length; i++) { + var parsedPeriod = parsedPeriods[i]; + var lastFlattenedPeriod = flattenedPeriods[flattenedPeriods.length - 1]; + while (lastFlattenedPeriod.duration == null || lastFlattenedPeriod.start + lastFlattenedPeriod.duration > parsedPeriod.start) { + log/* default.warn */.Z.warn("DASH: Updating overlapping Periods.", lastFlattenedPeriod, parsedPeriod); + lastFlattenedPeriod.duration = parsedPeriod.start - lastFlattenedPeriod.start; + lastFlattenedPeriod.end = parsedPeriod.start; + if (lastFlattenedPeriod.duration <= 0) { + flattenedPeriods.pop(); + lastFlattenedPeriod = flattenedPeriods[flattenedPeriods.length - 1]; + } + } -/* eslint-disable @typescript-eslint/naming-convention */ + flattenedPeriods.push(parsedPeriod); + } -var DEFAULT_UNMUTED_VOLUME = config/* default.DEFAULT_UNMUTED_VOLUME */.Z.DEFAULT_UNMUTED_VOLUME; -var isActive = event_listeners/* isActive */.zh, - isVideoVisible = event_listeners/* isVideoVisible */._K, - onEnded$ = event_listeners/* onEnded$ */.C1, - onFullscreenChange$ = event_listeners/* onFullscreenChange$ */.Q1, - onPlayPause$ = event_listeners/* onPlayPause$ */.Qt, - onPictureInPictureEvent$ = event_listeners/* onPictureInPictureEvent$ */.yj, - onSeeking$ = event_listeners/* onSeeking$ */.d5, - onTextTrackChanges$ = event_listeners/* onTextTrackChanges$ */.UA, - videoWidth$ = event_listeners/* videoWidth$ */.$x; + return flattenedPeriods; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/get_periods_time_infos.ts /** - * @class Player - * @extends EventEmitter + * 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 Player = /*#__PURE__*/function (_EventEmitter) { - inheritsLoose_default()(Player, _EventEmitter); +/** + * Get periods time information from current, next and previous + * periods. + * @param {Array.} periodsIR + * @param {Object} manifestInfos + * @return {Array.} + */ +function getPeriodsTimeInformation(periodsIR, manifestInfos) { + var periodsTimeInformation = []; + periodsIR.forEach(function (currentPeriod, i) { + var periodStart; - /** - * @constructor - * @param {Object} options - */ - function Player(options) { - var _this; + if (currentPeriod.attributes.start != null) { + periodStart = currentPeriod.attributes.start; + } else { + if (i === 0) { + periodStart = !manifestInfos.isDynamic || manifestInfos.availabilityStartTime == null ? 0 : manifestInfos.availabilityStartTime; + } else { + // take time information from previous period + var prevPeriodInfos = periodsTimeInformation[periodsTimeInformation.length - 1]; - if (options === void 0) { - options = {}; + if (prevPeriodInfos != null && prevPeriodInfos.periodEnd != null) { + periodStart = prevPeriodInfos.periodEnd; + } else { + throw new Error("Missing start time when parsing periods."); + } + } } - _this = _EventEmitter.call(this) || this; - - var _parseConstructorOpti = parseConstructorOptions(options), - initialAudioBitrate = _parseConstructorOpti.initialAudioBitrate, - initialVideoBitrate = _parseConstructorOpti.initialVideoBitrate, - limitVideoWidth = _parseConstructorOpti.limitVideoWidth, - minAudioBitrate = _parseConstructorOpti.minAudioBitrate, - minVideoBitrate = _parseConstructorOpti.minVideoBitrate, - maxAudioBitrate = _parseConstructorOpti.maxAudioBitrate, - maxBufferAhead = _parseConstructorOpti.maxBufferAhead, - maxBufferBehind = _parseConstructorOpti.maxBufferBehind, - maxVideoBitrate = _parseConstructorOpti.maxVideoBitrate, - preferredAudioTracks = _parseConstructorOpti.preferredAudioTracks, - preferredTextTracks = _parseConstructorOpti.preferredTextTracks, - preferredVideoTracks = _parseConstructorOpti.preferredVideoTracks, - throttleWhenHidden = _parseConstructorOpti.throttleWhenHidden, - throttleVideoBitrateWhenHidden = _parseConstructorOpti.throttleVideoBitrateWhenHidden, - videoElement = _parseConstructorOpti.videoElement, - wantedBufferAhead = _parseConstructorOpti.wantedBufferAhead, - stopAtEnd = _parseConstructorOpti.stopAtEnd; // Workaround to support Firefox autoplay on FF 42. - // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624 - + var periodDuration; + var nextPeriod = periodsIR[i + 1]; - videoElement.preload = "auto"; - _this.version = - /* PLAYER_VERSION */ - "3.23.1"; - _this.log = log/* default */.Z; - _this.state = "STOPPED"; - _this.videoElement = videoElement; - _this._priv_destroy$ = new Subject/* Subject */.xQ(); - _this._priv_pictureInPictureEvent$ = new ReplaySubject/* ReplaySubject */.t(1); - onPictureInPictureEvent$(videoElement).pipe((0,takeUntil/* takeUntil */.R)(_this._priv_destroy$)).subscribe(_this._priv_pictureInPictureEvent$); - /** @deprecated */ + if (currentPeriod.attributes.duration != null) { + periodDuration = currentPeriod.attributes.duration; + } else if (i === periodsIR.length - 1) { + periodDuration = manifestInfos.duration; + } else if (nextPeriod.attributes.start != null) { + periodDuration = nextPeriod.attributes.start - periodStart; + } - onFullscreenChange$(videoElement).pipe((0,takeUntil/* takeUntil */.R)(_this._priv_destroy$)) - /* eslint-disable import/no-deprecated */ - .subscribe(function () { - return _this.trigger("fullscreenChange", _this.isFullscreen()); + var periodEnd = periodDuration != null ? periodStart + periodDuration : undefined; + periodsTimeInformation.push({ + periodStart: periodStart, + periodDuration: periodDuration, + periodEnd: periodEnd }); - /* eslint-enable import/no-deprecated */ - - /** @deprecated */ - - onTextTrackChanges$(videoElement.textTracks).pipe((0,takeUntil/* takeUntil */.R)(_this._priv_destroy$), (0,map/* map */.U)(function (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. - (0,distinctUntilChanged/* distinctUntilChanged */.x)(function (textTracksA, textTracksB) { - if (textTracksA.length !== textTracksB.length) { - return false; - } + }); + return periodsTimeInformation; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/manifest_bounds_calculator.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. + */ - for (var i = 0; i < textTracksA.length; i++) { - if (textTracksA[i] !== textTracksB[i]) { - return false; - } - } +/** + * This class allows to easily calculate the first and last available positions + * in a content at any time. + * + * That task can be an hard for dynamic DASH contents: it depends on a + * `timeShiftBufferDepth` defined in the MPD and on the maximum possible + * position. + * + * The latter can come from either a clock synchronization mechanism or the + * indexing schemes (e.g. SegmentTemplate, SegmentTimeline etc.) of the last + * Periods. + * As such, it might only be known once a large chunk of the MPD has already + * been parsed. + * + * By centralizing the manifest bounds calculation in this class and by giving + * an instance of it to each parsed elements which might depend on it, we + * ensure that we can provide it once it is known to every one of those + * elements without needing to parse a second time the MPD. + * @class ManifestBoundsCalculator + */ +var ManifestBoundsCalculator = /*#__PURE__*/function () { + /** + * @param {Object} args + */ + function ManifestBoundsCalculator(args) { + this._isDynamic = args.isDynamic; + this._timeShiftBufferDepth = !args.isDynamic || args.timeShiftBufferDepth === undefined ? null : args.timeShiftBufferDepth; + } + /** + * Set the last position and the position time (the value of `performance.now()` + * at the time that position was true converted into seconds). + * + * @example + * Example if you trust `Date.now()` to give you a reliable offset: + * ```js + * const lastPosition = Date.now(); + * const positionTime = performance.now() / 1000; + * manifestBoundsCalculator.setLastPosition(lastPosition, positionTime); + * ``` + * + * @param {number} lastPosition + * @param {number|undefined} positionTime + */ - return true; - })).subscribe(function (x) { - return _this._priv_onNativeTextTracksNext(x); - }); - _this._priv_playing$ = new ReplaySubject/* ReplaySubject */.t(1); - _this._priv_speed$ = new BehaviorSubject(videoElement.playbackRate); - _this._priv_stopCurrentContent$ = new Subject/* Subject */.xQ(); - _this._priv_contentLock$ = new BehaviorSubject(false); - _this._priv_bufferOptions = { - wantedBufferAhead$: new BehaviorSubject(wantedBufferAhead), - maxBufferAhead$: new BehaviorSubject(maxBufferAhead), - maxBufferBehind$: new BehaviorSubject(maxBufferBehind) - }; - _this._priv_bitrateInfos = { - lastBitrates: { - audio: initialAudioBitrate, - video: initialVideoBitrate - }, - minAutoBitrates: { - audio: new BehaviorSubject(minAudioBitrate), - video: new BehaviorSubject(minVideoBitrate) - }, - maxAutoBitrates: { - audio: new BehaviorSubject(maxAudioBitrate), - video: new BehaviorSubject(maxVideoBitrate) - }, - manualBitrates: { - audio: new BehaviorSubject(-1), - video: new BehaviorSubject(-1) - } - }; - _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 = {}; - _this._priv_stopAtEnd = stopAtEnd; - _this._priv_setPlayerState(PLAYER_STATES.STOPPED); + var _proto = ManifestBoundsCalculator.prototype; - _this._priv_preferredAudioTracks = preferredAudioTracks; - _this._priv_preferredTextTracks = preferredTextTracks; - _this._priv_preferredVideoTracks = preferredVideoTracks; - _this._priv_lastContentPlaybackInfos = {}; - return _this; + _proto.setLastPosition = function setLastPosition(lastPosition, positionTime) { + this._lastPosition = lastPosition; + this._positionTime = positionTime; } - /** All possible Error types emitted by the RxPlayer. */ - + /** + * Returns `true` if the last position and the position time + * (for dynamic content only) have been comunicated. + * `false` otherwise. + * @returns {boolean} + */ + ; - var _proto = Player.prototype; + _proto.lastPositionIsKnown = function lastPositionIsKnown() { + if (this._isDynamic) { + return this._positionTime != null && this._lastPosition != null; + } + return this._lastPosition != null; + } /** - * Stop the playback for the current content. + * Estimate a minimum bound for the content from the last set segment time + * and buffer depth. + * Consider that it is only an estimation, not the real value. + * @return {number|undefined} */ - _proto.stop = function stop() { - if (this.state !== PLAYER_STATES.STOPPED) { - this._priv_stopCurrentContent$.next(); + ; - this._priv_cleanUpCurrentContentState(); + _proto.estimateMinimumBound = function estimateMinimumBound() { + if (!this._isDynamic || this._timeShiftBufferDepth === null) { + return 0; + } - this._priv_setPlayerState(PLAYER_STATES.STOPPED); + var maximumBound = this.estimateMaximumBound(); + + if (maximumBound === undefined) { + return undefined; } + + var minimumBound = maximumBound - this._timeShiftBufferDepth; + return minimumBound; } /** - * Free the resources used by the player. - * /!\ The player cannot be "used" anymore after this method has been called. + * Estimate a maximum bound for the content from the last set segment time. + * Consider that it is only an estimation, not the real value. + * @return {number|undefined} */ ; - _proto.dispose = function dispose() { - // free resources linked to the loaded content - this.stop(); - - if (this.videoElement !== null) { - // free resources used for EME management - disposeEME(this.videoElement); - } // free Observables linked to the Player instance + _proto.estimateMaximumBound = function estimateMaximumBound() { + if (this._isDynamic && this._positionTime != null && this._lastPosition != null) { + return Math.max(this._lastPosition - this._positionTime + performance.now() / 1000, 0); + } + return this._lastPosition; + }; - this._priv_destroy$.next(); + return ManifestBoundsCalculator; +}(); - this._priv_destroy$.complete(); // Complete all subjects +// EXTERNAL MODULE: ./src/utils/array_includes.ts +var array_includes = __webpack_require__(7714); +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/infer_adaptation_type.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._priv_stopCurrentContent$.complete(); - this._priv_playing$.complete(); +/** Array grouping every possible type a parsed Adaptation can be. */ - this._priv_speed$.complete(); +var KNOWN_ADAPTATION_TYPES = ["audio", "video", "text", "image"]; +/** Different `role`s a text Adaptation can be. */ - this._priv_contentLock$.complete(); +var SUPPORTED_TEXT_TYPES = ["subtitle", "caption"]; +/** + * Infers the type of adaptation from codec and mimetypes found in it. + * + * This follows the guidelines defined by the DASH-IF IOP: + * - one adaptation set contains a single media type + * - The order of verifications are: + * 1. mimeType + * 2. Role + * 3. codec + * + * Note: This is based on DASH-IF-IOP-v4.0 with some more freedom. + * @param {Array.} representations + * @param {string|null} adaptationMimeType + * @param {string|null} adaptationCodecs + * @param {Array.|null} adaptationRoles + * @returns {string} - "audio"|"video"|"text"|"image"|"metadata"|"unknown" + */ - this._priv_bufferOptions.wantedBufferAhead$.complete(); +function inferAdaptationType(representations, adaptationMimeType, adaptationCodecs, adaptationRoles) { + function fromMimeType(mimeType, roles) { + var topLevel = mimeType.split("/")[0]; - this._priv_bufferOptions.maxBufferAhead$.complete(); + if ((0,array_includes/* default */.Z)(KNOWN_ADAPTATION_TYPES, topLevel)) { + return topLevel; + } - this._priv_bufferOptions.maxBufferBehind$.complete(); + if (mimeType === "application/bif") { + return "image"; + } - this._priv_pictureInPictureEvent$.complete(); + if (mimeType === "application/ttml+xml") { + return "text"; + } // manage DASH-IF mp4-embedded subtitles and metadata - this._priv_bitrateInfos.manualBitrates.video.complete(); - this._priv_bitrateInfos.manualBitrates.audio.complete(); + if (mimeType === "application/mp4") { + if (roles != null) { + if ((0,array_find/* default */.Z)(roles, function (role) { + return role.schemeIdUri === "urn:mpeg:dash:role:2011" && (0,array_includes/* default */.Z)(SUPPORTED_TEXT_TYPES, role.value); + }) != null) { + return "text"; + } + } - this._priv_bitrateInfos.minAutoBitrates.video.complete(); + return undefined; + } + } - this._priv_bitrateInfos.minAutoBitrates.audio.complete(); + function fromCodecs(codecs) { + switch (codecs.substring(0, 3)) { + case "avc": + case "hev": + case "hvc": + case "vp8": + case "vp9": + case "av1": + return "video"; - this._priv_bitrateInfos.maxAutoBitrates.video.complete(); + case "vtt": + return "text"; - this._priv_bitrateInfos.maxAutoBitrates.audio.complete(); + case "bif": + return "image"; + } - this._priv_lastContentPlaybackInfos = {}; // un-attach video element + switch (codecs.substring(0, 4)) { + case "mp4a": + return "audio"; - this.videoElement = null; + case "wvtt": + case "stpp": + return "text"; + } } - /** - * Load a new video. - * @param {Object} opts - */ - ; - _proto.loadVideo = function loadVideo(opts) { - var options = parseLoadVideoOptions(opts); - log/* default.info */.Z.info("API: Calling loadvideo", options); - this._priv_lastContentPlaybackInfos = { - options: options - }; + if (adaptationMimeType !== null) { + var typeFromMimeType = fromMimeType(adaptationMimeType, adaptationRoles); - this._priv_initializeContentPlayback(options); + if (typeFromMimeType !== undefined) { + return typeFromMimeType; + } } - /** - * Reload last content. Init media playback without fetching again - * the manifest. - * @param {Object} reloadOpts - */ - ; - _proto.reload = function reload(reloadOpts) { - var _this$_priv_lastConte = this._priv_lastContentPlaybackInfos, - options = _this$_priv_lastConte.options, - manifest = _this$_priv_lastConte.manifest, - lastPlaybackPosition = _this$_priv_lastConte.lastPlaybackPosition; + if (adaptationCodecs !== null) { + var typeFromCodecs = fromCodecs(adaptationCodecs); - if (options === undefined || manifest === undefined || lastPlaybackPosition === undefined) { - throw new Error("API: Can't reload without having previously loaded a content."); + if (typeFromCodecs !== undefined) { + return typeFromCodecs; } + } - checkReloadOptions(reloadOpts); - var startAtPositon; - - if (reloadOpts !== undefined && reloadOpts.reloadAt !== undefined && reloadOpts.reloadAt.position !== undefined) { - startAtPositon = reloadOpts.reloadAt.position; - } else { - var playbackPosition; - - if (this.state === "STOPPED" || this.state === "ENDED") { - playbackPosition = lastPlaybackPosition; - } else { - if (this.videoElement === null) { - throw new Error("Can't reload when video element does not exist."); - } + for (var i = 0; i < representations.length; i++) { + var representation = representations[i]; + var _representation$attri = representation.attributes, + mimeType = _representation$attri.mimeType, + codecs = _representation$attri.codecs; - playbackPosition = this.videoElement.currentTime; - } + if (mimeType !== undefined) { + var _typeFromMimeType = fromMimeType(mimeType, adaptationRoles); - if (reloadOpts !== undefined && reloadOpts.reloadAt !== undefined && reloadOpts.reloadAt.relative !== undefined) { - startAtPositon = reloadOpts.reloadAt.relative + playbackPosition; - } else { - startAtPositon = playbackPosition; + if (_typeFromMimeType !== undefined) { + return _typeFromMimeType; } } - var newOptions = Object.assign(Object.assign({}, options), { - initialManifest: manifest - }); - newOptions.startAt = { - position: startAtPositon - }; + if (codecs !== undefined) { + var _typeFromCodecs = fromCodecs(codecs); - this._priv_initializeContentPlayback(newOptions); + if (_typeFromCodecs !== undefined) { + return _typeFromCodecs; + } + } } - /** - * From given options, initialize content playback. - * @param {Object} options - */ - ; - _proto._priv_initializeContentPlayback = function _priv_initializeContentPlayback(options) { - var _this2 = this; + return undefined; +} +// EXTERNAL MODULE: ./src/parsers/manifest/utils/index_helpers.ts +var index_helpers = __webpack_require__(3911); +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/get_init_segment.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 _a, _b, _c; +/** + * Construct init segment for the given index. + * @param {Object} index + * @param {function} isEMSGWhitelisted + * @returns {Object} + */ +function get_init_segment_getInitSegment(index, isEMSGWhitelisted) { + var _a; - var autoPlay = options.autoPlay, - audioTrackSwitchingMode = options.audioTrackSwitchingMode, - defaultAudioTrack = options.defaultAudioTrack, - defaultTextTrack = options.defaultTextTrack, - enableFastSwitching = options.enableFastSwitching, - initialManifest = options.initialManifest, - keySystems = options.keySystems, - lowLatencyMode = options.lowLatencyMode, - manualBitrateSwitchingMode = options.manualBitrateSwitchingMode, - manifestUpdateUrl = options.manifestUpdateUrl, - minimumManifestUpdateInterval = options.minimumManifestUpdateInterval, - networkConfig = options.networkConfig, - onCodecSwitch = options.onCodecSwitch, - startAt = options.startAt, - transport = options.transport, - transportOptions = options.transportOptions, - url = options.url; // Perform multiple checks on the given options + var initialization = index.initialization; + var privateInfos; - if (this.videoElement === null) { - throw new Error("the attached video element is disposed"); - } // now that every checks have passed, stop previous content + if (isEMSGWhitelisted !== undefined) { + privateInfos = { + isEMSGWhitelisted: isEMSGWhitelisted + }; + } + + return { + id: "init", + isInit: true, + time: 0, + end: 0, + duration: 0, + timescale: 1, + range: initialization != null ? initialization.range : undefined, + indexRange: index.indexRange, + mediaURLs: (_a = initialization === null || initialization === void 0 ? void 0 : initialization.mediaURLs) !== null && _a !== void 0 ? _a : null, + privateInfos: privateInfos, + timestampOffset: -(index.indexTimeOffset / index.timescale) + }; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/tokens.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.stop(); - var isDirectFile = transport === "directfile"; - this._priv_currentError = null; - this._priv_contentInfos = { - url: url, - isDirectFile: isDirectFile, - segmentBuffersStore: null, - thumbnails: null, - manifest: null, - currentPeriod: null, - activeAdaptations: null, - activeRepresentations: null, - initialAudioTrack: defaultAudioTrack, - initialTextTrack: defaultTextTrack - }; // inilialize `_priv_playing$` to false (meaning the content is not playing yet) +/** + * Pad with 0 in the left of the given n argument to reach l length + * @param {Number|string} n + * @param {Number} l + * @returns {string} + */ - this._priv_playing$.next(false); +function padLeftWithZeros(n, l) { + var nToString = n.toString(); - var videoElement = this.videoElement; - /** Global "clock" used for content playback */ + if (nToString.length >= l) { + return nToString; + } - var clock$ = clock(videoElement, { - withMediaSource: !isDirectFile, - lowLatencyMode: lowLatencyMode - }); - /** Emit when the current content has been stopped. */ + var arr = new Array(l + 1).join("0") + nToString; + return arr.slice(-l); +} +/** + * @param {string|number} replacer + * @returns {Function} + */ - var contentIsStopped$ = (0,merge/* merge */.T)(this._priv_stopCurrentContent$, this._priv_stopAtEnd ? onEnded$(videoElement) : empty/* EMPTY */.E).pipe((0,take/* take */.q)(1)); - /** Emit playback events. */ - var playback$; +function processFormatedToken(replacer) { + return function (_match, _format, widthStr) { + var width = (0,is_non_empty_string/* default */.Z)(widthStr) ? parseInt(widthStr, 10) : 1; + return padLeftWithZeros(String(replacer), width); + }; +} +/** + * @param {string} representationURL + * @param {string|undefined} media + * @param {string|undefined} id + * @param {number|undefined} bitrate + * @returns {string} + */ - if (!isDirectFile) { - var transportFn = features/* default.transports */.Z.transports[transport]; - if (typeof transportFn !== "function") { - throw new Error("transport \"" + transport + "\" not supported"); - } +function createIndexURLs(baseURLs, media, id, bitrate) { + if (baseURLs.length === 0) { + return media !== undefined ? [replaceRepresentationDASHTokens(media, id, bitrate)] : null; + } - var transportPipelines = transportFn(transportOptions); - var relyOnVideoVisibilityAndSize = canRelyOnVideoVisibilityAndSize(); - var throttlers = { - throttle: {}, - throttleBitrate: {}, - limitWidth: {} - }; + return baseURLs.map(function (baseURL) { + return replaceRepresentationDASHTokens((0,resolve_url/* default */.Z)(baseURL, media), id, bitrate); + }); +} +/** + * Replace "tokens" written in a given path (e.g. $RepresentationID$) by the corresponding + * infos, taken from the given segment. + * @param {string} path + * @param {string|undefined} id + * @param {number|undefined} bitrate + * @returns {string} + */ - if (this._priv_throttleWhenHidden) { - if (!relyOnVideoVisibilityAndSize) { - log/* default.warn */.Z.warn("API: Can't apply throttleWhenHidden because " + "browser can't be trusted for visibility."); - } else { - throttlers.throttle = { - video: isActive().pipe((0,map/* map */.U)(function (active) { - return active ? Infinity : 0; - }), (0,takeUntil/* takeUntil */.R)(this._priv_stopCurrentContent$)) - }; - } - } +function replaceRepresentationDASHTokens(path, id, bitrate) { + if (path.indexOf("$") === -1) { + return path; + } else { + return path.replace(/\$\$/g, "$").replace(/\$RepresentationID\$/g, String(id)).replace(/\$Bandwidth(|\%0(\d+)d)\$/g, processFormatedToken(bitrate === undefined ? 0 : bitrate)); + } +} +/** + * Create function allowing to replace "tokens" in a given DASH segment URL + * (e.g. $Time$, which has to be replaced by the segment's start time) by the + * right information. + * @param {number|undefined} time + * @param {number|undefined} nb + * @returns {Function} + */ - if (this._priv_throttleVideoBitrateWhenHidden) { - if (!relyOnVideoVisibilityAndSize) { - log/* default.warn */.Z.warn("API: Can't apply throttleVideoBitrateWhenHidden because " + "browser can't be trusted for visibility."); - } else { - throttlers.throttleBitrate = { - video: isVideoVisible(this._priv_pictureInPictureEvent$).pipe((0,map/* map */.U)(function (active) { - return active ? Infinity : 0; - }), (0,takeUntil/* takeUntil */.R)(this._priv_stopCurrentContent$)) - }; +function createDashUrlDetokenizer(time, nb) { + /** + * Replace the tokens in the given `url` by the segment information defined + * by the outer function. + * @param {string} url + * @returns {string} + * + * @throws Error - Throws if we do not have enough data to construct the URL + */ + return function replaceTokensInUrl(url) { + if (url.indexOf("$") === -1) { + return url; + } else { + return url.replace(/\$\$/g, "$").replace(/\$Number(|\%0(\d+)d)\$/g, function (_x, _y, widthStr) { + if (nb === undefined) { + throw new Error("Segment number not defined in a $Number$ scheme"); } - } - if (this._priv_limitVideoWidth) { - if (!relyOnVideoVisibilityAndSize) { - log/* default.warn */.Z.warn("API: Can't apply limitVideoWidth because browser can't be " + "trusted for video size."); - } else { - throttlers.limitWidth = { - video: videoWidth$(videoElement, this._priv_pictureInPictureEvent$).pipe((0,takeUntil/* takeUntil */.R)(this._priv_stopCurrentContent$)) - }; + return processFormatedToken(nb)(_x, _y, widthStr); + }).replace(/\$Time(|\%0(\d+)d)\$/g, function (_x, _y, widthStr) { + if (time === undefined) { + throw new Error("Segment time not defined in a $Time$ scheme"); } - } - /** Options used by the ABR Manager. */ + return processFormatedToken(time)(_x, _y, widthStr); + }); + } + }; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/get_segments_from_timeline.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 adaptiveOptions = { - initialBitrates: this._priv_bitrateInfos.lastBitrates, - lowLatencyMode: lowLatencyMode, - manualBitrates: this._priv_bitrateInfos.manualBitrates, - minAutoBitrates: this._priv_bitrateInfos.minAutoBitrates, - maxAutoBitrates: this._priv_bitrateInfos.maxAutoBitrates, - throttlers: throttlers - }; - /** Options used by the TextTrack SegmentBuffer. */ - var textTrackOptions = options.textTrackMode === "native" ? { - textTrackMode: "native", - hideNativeSubtitle: options.hideNativeSubtitle - } : { - textTrackMode: "html", - textTrackElement: options.textTrackElement - }; - var bufferOptions = (0,object_assign/* default */.Z)({ - audioTrackSwitchingMode: audioTrackSwitchingMode, - enableFastSwitching: enableFastSwitching, - manualBitrateSwitchingMode: manualBitrateSwitchingMode, - onCodecSwitch: onCodecSwitch - }, this._priv_bufferOptions); // We've every options set up. Start everything now +/** + * For the given start time and duration of a timeline element, calculate how + * much this element should be repeated to contain the time given. + * 0 being the same element, 1 being the next one etc. + * @param {Number} segmentStartTime + * @param {Number} segmentDuration + * @param {Number} wantedTime + * @returns {Number} + */ - var init$ = init({ - adaptiveOptions: adaptiveOptions, - autoPlay: autoPlay, - bufferOptions: bufferOptions, - clock$: clock$, - content: { - initialManifest: initialManifest, - manifestUpdateUrl: manifestUpdateUrl, - url: url - }, - keySystems: keySystems, - lowLatencyMode: lowLatencyMode, - mediaElement: videoElement, - minimumManifestUpdateInterval: minimumManifestUpdateInterval, - networkConfig: networkConfig, - transportPipelines: transportPipelines, - speed$: this._priv_speed$, - startAt: startAt, - textTrackOptions: textTrackOptions - }).pipe((0,takeUntil/* takeUntil */.R)(contentIsStopped$)); - playback$ = publish()(init$); - } else { - if (features/* default.directfile */.Z.directfile === null) { - throw new Error("DirectFile feature not activated in your build."); - } +function getWantedRepeatIndex(segmentStartTime, segmentDuration, wantedTime) { + var diff = wantedTime - segmentStartTime; + return diff > 0 ? Math.floor(diff / segmentDuration) : 0; +} +/** + * Get a list of Segments for the time range wanted. + * @param {Object} index - index object, constructed by parsing the manifest. + * @param {number} from - starting timestamp wanted, in seconds + * @param {number} durationWanted - duration wanted, in seconds + * @param {function} isEMSGWhitelisted + * @param {number|undefined} maximumTime + * @returns {Array.} + */ - 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); +function getSegmentsFromTimeline(index, from, durationWanted, isEMSGWhitelisted, maximumTime) { + var scaledUp = (0,index_helpers/* toIndexTime */.gT)(from, index); + var scaledTo = (0,index_helpers/* toIndexTime */.gT)(from + durationWanted, index); + var timeline = index.timeline, + timescale = index.timescale, + mediaURLs = index.mediaURLs, + startNumber = index.startNumber; + var currentNumber = startNumber != null ? startNumber : undefined; + var segments = []; + var timelineLength = timeline.length; // TODO(pierre): use @maxSegmentDuration if possible - var preferredTextTracks = defaultTextTrack === undefined ? this._priv_preferredTextTracks : [defaultTextTrack]; + var maxEncounteredDuration = timeline.length > 0 && timeline[0].duration != null ? timeline[0].duration : 0; - this._priv_mediaElementTrackChoiceManager.setPreferredTextTracks(preferredTextTracks, true); + for (var i = 0; i < timelineLength; i++) { + var timelineItem = timeline[i]; + var duration = timelineItem.duration, + start = timelineItem.start, + range = timelineItem.range; + maxEncounteredDuration = Math.max(maxEncounteredDuration, duration); + var repeat = (0,index_helpers/* calculateRepeat */.KF)(timelineItem, timeline[i + 1], maximumTime); + var segmentNumberInCurrentRange = getWantedRepeatIndex(start, duration, scaledUp); + var segmentTime = start + segmentNumberInCurrentRange * duration; - this._priv_mediaElementTrackChoiceManager.setPreferredVideoTracks(this._priv_preferredVideoTracks, true); + while (segmentTime < scaledTo && segmentNumberInCurrentRange <= repeat) { + var segmentNumber = currentNumber != null ? currentNumber + segmentNumberInCurrentRange : undefined; + var detokenizedURLs = mediaURLs === null ? null : mediaURLs.map(createDashUrlDetokenizer(segmentTime, segmentNumber)); + var time = segmentTime - index.indexTimeOffset; + var segment = { + id: String(segmentTime), + time: time / timescale, + end: (time + duration) / timescale, + duration: duration / timescale, + isInit: false, + range: range, + timescale: 1, + mediaURLs: detokenizedURLs, + number: segmentNumber, + timestampOffset: -(index.indexTimeOffset / timescale), + privateInfos: { + isEMSGWhitelisted: isEMSGWhitelisted + } + }; + segments.push(segment); // update segment number and segment time for the next segment - 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); + segmentNumberInCurrentRange++; + segmentTime = start + segmentNumberInCurrentRange * duration; + } - this._priv_mediaElementTrackChoiceManager.addEventListener("availableVideoTracksChange", function (val) { - return _this2.trigger("availableVideoTracksChange", val); - }); + if (segmentTime >= scaledTo) { + // we reached ``scaledTo``, we're done + return segments; + } - this._priv_mediaElementTrackChoiceManager.addEventListener("availableAudioTracksChange", function (val) { - return _this2.trigger("availableAudioTracksChange", val); - }); + if (currentNumber != null) { + currentNumber += repeat + 1; + } + } - this._priv_mediaElementTrackChoiceManager.addEventListener("availableTextTracksChange", function (val) { - return _this2.trigger("availableTextTracksChange", val); - }); + return segments; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/base.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._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({ - autoPlay: autoPlay, - clock$: clock$, - keySystems: keySystems, - mediaElement: videoElement, - speed$: this._priv_speed$, - startAt: startAt, - url: url - }).pipe((0,takeUntil/* takeUntil */.R)(contentIsStopped$)); - playback$ = publish()(directfileInit$); - } - /** Emit an object when the player "stalls" and null when it un-stalls */ +/** + * Add a new segment to the index. + * + * /!\ Mutate the given index + * @param {Object} index + * @param {Object} segmentInfos + * @returns {Boolean} - true if the segment has been added + */ - 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; - }), (0,distinctUntilChanged/* distinctUntilChanged */.x)(function (wasStalled, isStalled) { - return wasStalled === null && isStalled === null || wasStalled !== null && isStalled !== null && wasStalled.reason === isStalled.reason; - })); - /** Emit when the content is considered "loaded". */ +function _addSegmentInfos(index, segmentInfos) { + if (segmentInfos.timescale !== index.timescale) { + var timescale = index.timescale; + index.timeline.push({ + start: segmentInfos.time / segmentInfos.timescale * timescale, + duration: segmentInfos.duration / segmentInfos.timescale * timescale, + repeatCount: segmentInfos.count === undefined ? 0 : segmentInfos.count, + range: segmentInfos.range + }); + } else { + index.timeline.push({ + start: segmentInfos.time, + duration: segmentInfos.duration, + repeatCount: segmentInfos.count === undefined ? 0 : segmentInfos.count, + range: segmentInfos.range + }); + } - 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. */ + return true; +} - 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 an "ended" event. */ +var BaseRepresentationIndex = /*#__PURE__*/function () { + /** + * @param {Object} index + * @param {Object} context + */ + function BaseRepresentationIndex(index, context) { + var _a, _b; - var endedEvent$ = onEnded$(videoElement); - /** Emit when the media element emits a "seeking" event. */ - - var seekingEvent$ = onSeeking$(videoElement); - /** Emit state updates once the content is considered "loaded". */ - - var loadedStateUpdates$ = (0,combineLatest/* combineLatest */.aj)([this._priv_playing$, stalled$.pipe((0,startWith/* startWith */.O)(null)), endedEvent$.pipe((0,startWith/* startWith */.O)(null)), seekingEvent$.pipe((0,startWith/* startWith */.O)(null))]).pipe((0,takeUntil/* takeUntil */.R)(this._priv_stopCurrentContent$), (0,map/* map */.U)(function (_ref) { - var isPlaying = _ref[0], - stalledStatus = _ref[1]; - return getLoadedContentState(videoElement, isPlaying, stalledStatus); - })); - /** Emit all player "state" updates. */ - - var playerState$ = (0,concat/* concat */.z)((0,of.of)(PLAYER_STATES.LOADING), // Begin with LOADING - // LOADED as soon as the first "loaded" event is sent - loaded$.pipe((0,take/* take */.q)(1), (0,mapTo/* mapTo */.h)(PLAYER_STATES.LOADED)), (0,merge/* merge */.T)(loadedStateUpdates$.pipe( // From the first reload onward, we enter another dynamic (below) - (0,takeUntil/* takeUntil */.R)(reloading$), skipWhile(function (state) { - return state === PLAYER_STATES.PAUSED; - })), // when reloading - reloading$.pipe((0,switchMapTo/* switchMapTo */.c)(loaded$.pipe((0,take/* take */.q)(1), // wait for the next loaded event - (0,mergeMapTo/* mergeMapTo */.j)(loadedStateUpdates$), // to update the state as usual - (0,startWith/* startWith */.O)(PLAYER_STATES.RELOADING) // Starts with "RELOADING" state - ))))).pipe((0,distinctUntilChanged/* distinctUntilChanged */.x)()); - var playbackSubscription; - - this._priv_stopCurrentContent$.pipe((0,take/* take */.q)(1)).subscribe(function () { - if (playbackSubscription !== undefined) { - playbackSubscription.unsubscribe(); - } - }); // Link `_priv_onPlayPauseNext` Observable to "play"/"pause" events - - - onPlayPause$(videoElement).pipe((0,takeUntil/* takeUntil */.R)(this._priv_stopCurrentContent$)).subscribe(function (e) { - return _this2._priv_onPlayPauseNext(e.type === "play"); - }, noop/* default */.Z); // Link "positionUpdate" events to the clock - - clock$.pipe((0,takeUntil/* takeUntil */.R)(this._priv_stopCurrentContent$)).subscribe(function (x) { - return _this2._priv_triggerPositionUpdate(x); - }, noop/* default */.Z); // Link "seeking" and "seeked" events (once the content is loaded) + var periodStart = context.periodStart, + periodEnd = context.periodEnd, + representationBaseURLs = context.representationBaseURLs, + representationId = context.representationId, + representationBitrate = context.representationBitrate, + isEMSGWhitelisted = context.isEMSGWhitelisted; + var timescale = (_a = index.timescale) !== null && _a !== void 0 ? _a : 1; + var presentationTimeOffset = index.presentationTimeOffset != null ? index.presentationTimeOffset : 0; + var indexTimeOffset = presentationTimeOffset - periodStart * timescale; + var mediaURLs = createIndexURLs(representationBaseURLs, index.initialization !== undefined ? index.initialization.media : undefined, representationId, representationBitrate); // TODO If indexRange is either undefined or behind the initialization segment + // the following logic will not work. + // However taking the nth first bytes like `dash.js` does (where n = 1500) is + // not straightforward as we would need to clean-up the segment after that. + // The following logic corresponds to 100% of tested cases, so good enough for + // now. - loaded$.pipe((0,switchMapTo/* switchMapTo */.c)(emitSeekEvents(this.videoElement, clock$)), (0,takeUntil/* takeUntil */.R)(this._priv_stopCurrentContent$)).subscribe(function (evt) { - log/* default.info */.Z.info("API: Triggering \"" + evt + "\" event"); + var range = index.initialization !== undefined ? index.initialization.range : index.indexRange !== undefined ? [0, index.indexRange[0] - 1] : undefined; + this._index = { + indexRange: index.indexRange, + indexTimeOffset: indexTimeOffset, + initialization: { + mediaURLs: mediaURLs, + range: range + }, + mediaURLs: createIndexURLs(representationBaseURLs, index.media, representationId, representationBitrate), + startNumber: index.startNumber, + timeline: (_b = index.timeline) !== null && _b !== void 0 ? _b : [], + timescale: timescale + }; + this._scaledPeriodEnd = periodEnd == null ? undefined : (0,index_helpers/* toIndexTime */.gT)(periodEnd, this._index); + this._isInitialized = this._index.timeline.length > 0; + this._isEMSGWhitelisted = isEMSGWhitelisted; + } + /** + * Construct init Segment. + * @returns {Object} + */ - _this2.trigger(evt, null); - }); // Handle state updates - playerState$.pipe((0,takeUntil/* takeUntil */.R)(this._priv_stopCurrentContent$)).subscribe(function (x) { - return _this2._priv_setPlayerState(x); - }, noop/* default */.Z); // Link playback events to the corresponding callbacks + var _proto = BaseRepresentationIndex.prototype; - playback$.subscribe(function (x) { - return _this2._priv_onPlaybackEvent(x); - }, function (err) { - return _this2._priv_onPlaybackError(err); - }, function () { - return _this2._priv_onPlaybackFinished(); - }); // initialize the content only when the lock is inactive + _proto.getInitSegment = function getInitSegment() { + return get_init_segment_getInitSegment(this._index, this._isEMSGWhitelisted); + } + /** + * @param {Number} _up + * @param {Number} _to + * @returns {Array.} + */ + ; - this._priv_contentLock$.pipe((0,filter/* filter */.h)(function (isLocked) { - return !isLocked; - }), (0,take/* take */.q)(1), (0,takeUntil/* takeUntil */.R)(this._priv_stopCurrentContent$)).subscribe(function () { - // start playback! - playbackSubscription = playback$.connect(); - }); + _proto.getSegments = function getSegments(_up, _to) { + return getSegmentsFromTimeline(this._index, _up, _to, this._isEMSGWhitelisted, this._scaledPeriodEnd); } /** - * Returns fatal error if one for the current content. - * null otherwise. - * @returns {Object|null} - The current Error (`null` when no error). + * Returns false as no Segment-Base based index should need to be refreshed. + * @returns {Boolean} */ ; - _proto.getError = function getError() { - return this._priv_currentError; + _proto.shouldRefresh = function shouldRefresh() { + return false; } /** - * Returns manifest/playlist object. - * null if the player is STOPPED. - * @deprecated - * @returns {Manifest|null} - The current Manifest (`null` when not known). + * Returns first position in index. + * @returns {Number|null} */ ; - _proto.getManifest = function getManifest() { - (0,warn_once/* default */.Z)("getManifest is deprecated." + " Please open an issue if you used this API."); + _proto.getFirstPosition = function getFirstPosition() { + var index = this._index; - if (this._priv_contentInfos === null) { + if (index.timeline.length === 0) { return null; } - return this._priv_contentInfos.manifest; + return (0,index_helpers/* fromIndexTime */.zG)(index.timeline[0].start, index); } /** - * Returns Adaptations (tracks) for every currently playing type - * (audio/video/text...). - * @deprecated - * @returns {Object|null} - The current Adaptation objects, per type (`null` - * when none is known for now. + * Returns last position in index. + * @returns {Number|null} */ ; - _proto.getCurrentAdaptations = function getCurrentAdaptations() { - (0,warn_once/* default */.Z)("getCurrentAdaptations is deprecated." + " Please open an issue if you used this API."); - - if (this._priv_contentInfos === null) { - return null; - } - - var _this$_priv_contentIn = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn.currentPeriod, - activeAdaptations = _this$_priv_contentIn.activeAdaptations; + _proto.getLastPosition = function getLastPosition() { + var timeline = this._index.timeline; - if (currentPeriod === null || activeAdaptations === null || (0,is_null_or_undefined/* default */.Z)(activeAdaptations[currentPeriod.id])) { + if (timeline.length === 0) { return null; } - return activeAdaptations[currentPeriod.id]; + var lastTimelineElement = timeline[timeline.length - 1]; + var lastTime = (0,index_helpers/* getIndexSegmentEnd */.jH)(lastTimelineElement, null, this._scaledPeriodEnd); + return (0,index_helpers/* fromIndexTime */.zG)(lastTime, this._index); } /** - * Returns representations (qualities) for every currently playing type - * (audio/video/text...). - * @deprecated - * @returns {Object|null} - The current Representation objects, per type - * (`null` when none is known for now. + * Segments in a segmentBase scheme should stay available. + * @returns {Boolean|undefined} */ ; - _proto.getCurrentRepresentations = function getCurrentRepresentations() { - (0,warn_once/* default */.Z)("getCurrentRepresentations is deprecated." + " Please open an issue if you used this API."); - return this._priv_getCurrentRepresentations(); + _proto.isSegmentStillAvailable = function isSegmentStillAvailable() { + return true; } /** - * Returns the media DOM element used by the player. - * You should not its HTML5 API directly and use the player's method instead, - * to ensure a well-behaved player. - * @returns {HTMLMediaElement|null} - The HTMLMediaElement used (`null` when - * disposed) + * We do not check for discontinuity in SegmentBase-based indexes. + * @returns {null} */ ; - _proto.getVideoElement = function getVideoElement() { - return this.videoElement; + _proto.checkDiscontinuity = function checkDiscontinuity() { + return null; } /** - * If one returns the first native text-track element attached to the media element. - * @deprecated - * @returns {TextTrack} - The native TextTrack attached (`null` when none) + * @returns {boolean} */ ; - _proto.getNativeTextTrack = function getNativeTextTrack() { - (0,warn_once/* default */.Z)("getNativeTextTrack is deprecated." + " Please open an issue if you used this API."); + _proto.areSegmentsChronologicallyGenerated = function areSegmentsChronologicallyGenerated() { + return true; + } + /** + * @param {Array.} nextSegments + * @returns {Array.} + */ + ; - if (this.videoElement === null) { - throw new Error("Disposed player"); + _proto._addSegments = function _addSegments(nextSegments) { + for (var i = 0; i < nextSegments.length; i++) { + _addSegmentInfos(this._index, nextSegments[i]); } - var videoElement = this.videoElement; - var textTracks = videoElement.textTracks; - - if (textTracks.length > 0) { - return videoElement.textTracks[0]; - } else { - return null; + if (!this._isInitialized && this._index.timeline.length > 0) { + this._isInitialized = true; } } /** - * Returns the player's current state. - * @returns {string} - The current Player's state + * Returns true as SegmentBase does not get updated. + * @returns {Boolean} */ ; - _proto.getPlayerState = function getPlayerState() { - return this.state; + _proto.canBeOutOfSyncError = function canBeOutOfSyncError() { + return false; } /** - * Returns true if both: - * - a content is loaded - * - the content loaded is a live content - * @returns {Boolean} - `true` if we're playing a live content, `false` otherwise. + * Returns true as SegmentBase does not get updated. + * @returns {Boolean} */ ; - _proto.isLive = function isLive() { - if (this._priv_contentInfos === null) { - return false; - } - - var _this$_priv_contentIn2 = this._priv_contentInfos, - isDirectFile = _this$_priv_contentIn2.isDirectFile, - manifest = _this$_priv_contentIn2.manifest; - - if (isDirectFile || manifest === null) { - return false; - } + _proto.isFinished = function isFinished() { + return true; + } + /** + * @returns {Boolean} + */ + ; - return manifest.isLive; + _proto.isInitialized = function isInitialized() { + return this._isInitialized; } /** - * Returns the url of the content's manifest - * @returns {string|undefined} - Current URL. `undefined` if not known or no - * URL yet. + * @param {Object} newIndex */ ; - _proto.getUrl = function getUrl() { - if (this._priv_contentInfos === null) { - return undefined; - } + _proto._replace = function _replace(newIndex) { + this._index = newIndex._index; + }; - var _this$_priv_contentIn3 = this._priv_contentInfos, - isDirectFile = _this$_priv_contentIn3.isDirectFile, - manifest = _this$_priv_contentIn3.manifest, - url = _this$_priv_contentIn3.url; + _proto._update = function _update() { + log/* default.error */.Z.error("Base RepresentationIndex: Cannot update a SegmentList"); + }; - if (isDirectFile) { - return url; - } + return BaseRepresentationIndex; +}(); - if (manifest !== null) { - return manifest.getUrl(); - } - return undefined; +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/list.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 ListRepresentationIndex = /*#__PURE__*/function () { + /** + * @param {Object} index + * @param {Object} context + */ + function ListRepresentationIndex(index, context) { + var _a; + + var periodStart = context.periodStart, + representationBaseURLs = context.representationBaseURLs, + representationId = context.representationId, + representationBitrate = context.representationBitrate, + isEMSGWhitelisted = context.isEMSGWhitelisted; + this._isEMSGWhitelisted = isEMSGWhitelisted; + this._periodStart = periodStart; + var presentationTimeOffset = index.presentationTimeOffset != null ? index.presentationTimeOffset : 0; + var timescale = (_a = index.timescale) !== null && _a !== void 0 ? _a : 1; + var indexTimeOffset = presentationTimeOffset - periodStart * timescale; + var list = index.list.map(function (lItem) { + return { + mediaURLs: createIndexURLs(representationBaseURLs, lItem.media, representationId, representationBitrate), + mediaRange: lItem.mediaRange + }; + }); + this._index = { + list: list, + timescale: timescale, + duration: index.duration, + indexTimeOffset: indexTimeOffset, + indexRange: index.indexRange, + initialization: index.initialization == null ? undefined : { + mediaURLs: createIndexURLs(representationBaseURLs, index.initialization.media, representationId, representationBitrate), + range: index.initialization.range + } + }; } /** - * Returns the video duration, in seconds. - * NaN if no video is playing. - * @returns {Number} + * Construct init Segment. + * @returns {Object} */ - ; - _proto.getVideoDuration = function getVideoDuration() { - if (this.videoElement === null) { - throw new Error("Disposed player"); + + var _proto = ListRepresentationIndex.prototype; + + _proto.getInitSegment = function getInitSegment() { + var initSegment = get_init_segment_getInitSegment(this._index); + + if (initSegment.privateInfos === undefined) { + initSegment.privateInfos = {}; } - return this.videoElement.duration; + initSegment.privateInfos.isEMSGWhitelisted = this._isEMSGWhitelisted; + return initSegment; } /** - * Returns in seconds the difference between: - * - the end of the current contiguous loaded range. - * - the current time - * @returns {Number} + * @param {Number} fromTime + * @param {Number} duration + * @returns {Array.} */ ; - _proto.getVideoBufferGap = function getVideoBufferGap() { - if (this.videoElement === null) { - throw new Error("Disposed player"); + _proto.getSegments = function getSegments(fromTime, dur) { + var index = this._index; + var duration = index.duration, + list = index.list, + timescale = index.timescale; + var durationInSeconds = duration / timescale; + var fromTimeInPeriod = fromTime - this._periodStart; + + var _getTimescaledRange = (0,index_helpers/* getTimescaledRange */.PZ)(fromTimeInPeriod, dur, timescale), + up = _getTimescaledRange[0], + to = _getTimescaledRange[1]; + + var length = Math.min(list.length - 1, Math.floor(to / duration)); + var segments = []; + var i = Math.floor(up / duration); + + while (i <= length) { + var range = list[i].mediaRange; + var mediaURLs = list[i].mediaURLs; + var time = i * durationInSeconds + this._periodStart; + var segment = { + id: String(i), + time: time, + isInit: false, + range: range, + duration: durationInSeconds, + timescale: 1, + end: time + durationInSeconds, + mediaURLs: mediaURLs, + timestampOffset: -(index.indexTimeOffset / timescale), + privateInfos: { + isEMSGWhitelisted: this._isEMSGWhitelisted + } + }; + segments.push(segment); + i++; } - var videoElement = this.videoElement; - return (0,ranges/* getLeftSizeOfRange */.L7)(videoElement.buffered, videoElement.currentTime); + return segments; } /** - * Returns in seconds the difference between: - * - the end of the current contiguous loaded range. - * - the start of the current contiguous loaded range. - * @returns {Number} + * Returns true if, based on the arguments, the index should be refreshed. + * (If we should re-fetch the manifest) + * @param {Number} _fromTime + * @param {Number} toTime + * @returns {Boolean} */ ; - _proto.getVideoLoadedTime = function getVideoLoadedTime() { - if (this.videoElement === null) { - throw new Error("Disposed player"); - } - - var videoElement = this.videoElement; - return (0,ranges/* getSizeOfRange */.at)(videoElement.buffered, videoElement.currentTime); + _proto.shouldRefresh = function shouldRefresh(_fromTime, toTime) { + var _this$_index = this._index, + timescale = _this$_index.timescale, + duration = _this$_index.duration, + list = _this$_index.list; + var scaledTo = toTime * timescale; + var i = Math.floor(scaledTo / duration); + return i < 0 || i >= list.length; } /** - * Returns in seconds the difference between: - * - the current time. - * - the start of the current contiguous loaded range. + * Returns first position in this index, in seconds. * @returns {Number} */ ; - _proto.getVideoPlayedTime = function getVideoPlayedTime() { - if (this.videoElement === null) { - throw new Error("Disposed player"); - } - - var videoElement = this.videoElement; - return (0,ranges/* getPlayedSizeOfRange */.DD)(videoElement.buffered, videoElement.currentTime); + _proto.getFirstPosition = function getFirstPosition() { + return this._periodStart; } /** - * Get the current position, in s, in wall-clock time. - * That is: - * - for live content, get a timestamp, in s, of the current played content. - * - for static content, returns the position from beginning in s. - * - * If you do not know if you want to use this method or getPosition: - * - If what you want is to display the current time to the user, use this - * one. - * - If what you want is to interact with the player's API or perform other - * actions (like statistics) with the real player data, use getPosition. - * + * Returns last position in this index, in seconds. * @returns {Number} */ ; - _proto.getWallClockTime = function getWallClockTime() { - if (this.videoElement === null) { - throw new Error("Disposed player"); - } - - if (this._priv_contentInfos === null) { - return this.videoElement.currentTime; - } - - var _this$_priv_contentIn4 = this._priv_contentInfos, - isDirectFile = _this$_priv_contentIn4.isDirectFile, - manifest = _this$_priv_contentIn4.manifest; - - if (isDirectFile) { - return this.videoElement.currentTime; - } - - if (manifest !== null) { - var currentTime = this.videoElement.currentTime; - var ast = manifest.availabilityStartTime !== undefined ? manifest.availabilityStartTime : 0; - return currentTime + ast; - } - - return 0; + _proto.getLastPosition = function getLastPosition() { + var index = this._index; + var duration = index.duration, + list = index.list; + return list.length * duration / index.timescale + this._periodStart; } /** - * Get the current position, in seconds, of the video element. - * - * If you do not know if you want to use this method or getWallClockTime: - * - If what you want is to display the current time to the user, use - * getWallClockTime. - * - If what you want is to interact with the player's API or perform other - * actions (like statistics) with the real player data, use this one. - * - * @returns {Number} + * Returns true if a Segment returned by this index is still considered + * available. + * @param {Object} segment + * @returns {Boolean} */ ; - _proto.getPosition = function getPosition() { - if (this.videoElement === null) { - throw new Error("Disposed player"); - } - - return this.videoElement.currentTime; + _proto.isSegmentStillAvailable = function isSegmentStillAvailable() { + return true; } /** - * Returns the current speed at which the video plays. - * @returns {Number} + * We do not check for discontinuity in SegmentList-based indexes. + * @returns {null} */ ; - _proto.getPlaybackRate = function getPlaybackRate() { - return this._priv_speed$.getValue(); + _proto.checkDiscontinuity = function checkDiscontinuity() { + return null; } /** - * Update the playback rate of the video. - * @param {Number} rate + * @returns {boolean} */ ; - _proto.setPlaybackRate = function setPlaybackRate(rate) { - this._priv_speed$.next(rate); + _proto.areSegmentsChronologicallyGenerated = function areSegmentsChronologicallyGenerated() { + return true; } /** - * Returns all available bitrates for the current video Adaptation. - * @returns {Array.} + * SegmentList should not be updated. + * @returns {Boolean} */ ; - _proto.getAvailableVideoBitrates = function getAvailableVideoBitrates() { - if (this._priv_contentInfos === null) { - return []; - } - - var _this$_priv_contentIn5 = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn5.currentPeriod, - activeAdaptations = _this$_priv_contentIn5.activeAdaptations; - - if (currentPeriod === null || activeAdaptations === null) { - return []; - } - - var adaptations = activeAdaptations[currentPeriod.id]; - - if (adaptations === undefined || (0,is_null_or_undefined/* default */.Z)(adaptations.video)) { - return []; - } - - return adaptations.video.getAvailableBitrates(); + _proto.canBeOutOfSyncError = function canBeOutOfSyncError() { + return false; } /** - * Returns all available bitrates for the current audio Adaptation. - * @returns {Array.} + * @returns {Boolean} */ ; - _proto.getAvailableAudioBitrates = function getAvailableAudioBitrates() { - if (this._priv_contentInfos === null) { - return []; - } - - var _this$_priv_contentIn6 = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn6.currentPeriod, - activeAdaptations = _this$_priv_contentIn6.activeAdaptations; - - if (currentPeriod === null || activeAdaptations === null) { - return []; - } - - var adaptations = activeAdaptations[currentPeriod.id]; - - if (adaptations === undefined || (0,is_null_or_undefined/* default */.Z)(adaptations.audio)) { - return []; - } - - return adaptations.audio.getAvailableBitrates(); + _proto.isFinished = function isFinished() { + return true; } /** - * Returns the manual audio bitrate set. -1 if in AUTO mode. - * @returns {Number} + * @returns {Boolean} */ ; - _proto.getManualAudioBitrate = function getManualAudioBitrate() { - return this._priv_bitrateInfos.manualBitrates.audio.getValue(); + _proto.isInitialized = function isInitialized() { + return true; } /** - * Returns the manual video bitrate set. -1 if in AUTO mode. - * @returns {Number} + * @param {Object} newIndex */ ; - _proto.getManualVideoBitrate = function getManualVideoBitrate() { - return this._priv_bitrateInfos.manualBitrates.video.getValue(); + _proto._replace = function _replace(newIndex) { + this._index = newIndex._index; } /** - * Returns currently considered bitrate for video segments. - * @returns {Number|undefined} + * @param {Object} newIndex */ ; - _proto.getVideoBitrate = function getVideoBitrate() { - var representations = this._priv_getCurrentRepresentations(); + _proto._update = function _update() { + log/* default.error */.Z.error("List RepresentationIndex: Cannot update a SegmentList"); + }; - if (representations === null || (0,is_null_or_undefined/* default */.Z)(representations.video)) { - return undefined; - } + return ListRepresentationIndex; +}(); - return representations.video.bitrate; - } - /** - * Returns currently considered bitrate for audio segments. - * @returns {Number|undefined} - */ - ; - _proto.getAudioBitrate = function getAudioBitrate() { - var representations = this._priv_getCurrentRepresentations(); +// EXTERNAL MODULE: ./src/errors/network_error.ts +var network_error = __webpack_require__(9362); +// EXTERNAL MODULE: ./src/parsers/manifest/utils/clear_timeline_from_position.ts +var clear_timeline_from_position = __webpack_require__(8232); +// EXTERNAL MODULE: ./src/parsers/manifest/utils/is_segment_still_available.ts +var is_segment_still_available = __webpack_require__(1091); +// EXTERNAL MODULE: ./src/parsers/manifest/utils/update_segment_timeline.ts +var update_segment_timeline = __webpack_require__(5505); +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/is_period_fulfilled.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. + */ - if (representations === null || (0,is_null_or_undefined/* default */.Z)(representations.audio)) { - return undefined; - } +var DEFAULT_MAXIMUM_TIME_ROUNDING_ERROR = config/* default.DEFAULT_MAXIMUM_TIME_ROUNDING_ERROR */.Z.DEFAULT_MAXIMUM_TIME_ROUNDING_ERROR; +/** + * In Javascript, numbers are encoded in a way that a floating number may be + * represented internally with a rounding error. + * + * As the period end is the result of a multiplication between a floating or integer + * number (period end * timescale), this function takes into account the potential + * rounding error to tell if the period is fulfilled with content. + * @param {number} timescale + * @param {number} lastSegmentEnd + * @param {number} periodEnd + * @returns {boolean} + */ - return representations.audio.bitrate; - } - /** - * Returns minimum wanted video bitrate currently set. - * @returns {Number} - */ - ; +function isPeriodFulfilled(timescale, lastSegmentEnd, periodEnd) { + var scaledRoundingError = DEFAULT_MAXIMUM_TIME_ROUNDING_ERROR * timescale; + return lastSegmentEnd + scaledRoundingError >= periodEnd; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/convert_element_to_index_segment.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. + */ - _proto.getMinVideoBitrate = function getMinVideoBitrate() { - return this._priv_bitrateInfos.minAutoBitrates.video.getValue(); - } - /** - * Returns minimum wanted audio bitrate currently set. - * @returns {Number} - */ - ; +/** + * Translate parsed `S` node into Segment compatible with this index: + * Find out the start, repeatCount and duration of each of these. + * + * @param {Object} item - parsed `S` node + * @param {Object|null} previousItem - the previously parsed Segment (related + * to the `S` node coming just before). If `null`, we're talking about the first + * segment. + * @param {Object|null} nextItem - the `S` node coming next. If `null`, we're + * talking about the last segment. + * @param {number} timelineStart - Absolute start for the timeline. In the same + * timescale than the given `S` nodes. + * @returns {Object|null} + */ - _proto.getMinAudioBitrate = function getMinAudioBitrate() { - return this._priv_bitrateInfos.minAutoBitrates.audio.getValue(); +function convertElementsToIndexSegment(item, previousItem, nextItem, timelineStart) { + var start = item.start; + var duration = item.duration; + var repeatCount = item.repeatCount; + + if (start == null) { + if (previousItem == null) { + start = timelineStart; + } else if (previousItem.duration != null) { + start = previousItem.start + previousItem.duration * (previousItem.repeatCount + 1); + } } - /** - * Returns maximum wanted video bitrate currently set. - * @returns {Number} - */ - ; - _proto.getMaxVideoBitrate = function getMaxVideoBitrate() { - return this._priv_bitrateInfos.maxAutoBitrates.video.getValue(); + if ((duration == null || isNaN(duration)) && nextItem != null && nextItem.start != null && !isNaN(nextItem.start) && start != null && !isNaN(start)) { + duration = nextItem.start - start; } - /** - * Returns maximum wanted audio bitrate currently set. - * @returns {Number} - */ - ; - _proto.getMaxAudioBitrate = function getMaxAudioBitrate() { - return this._priv_bitrateInfos.maxAutoBitrates.audio.getValue(); + if (start != null && !isNaN(start) && duration != null && !isNaN(duration) && (repeatCount == null || !isNaN(repeatCount))) { + return { + start: start, + duration: duration, + repeatCount: repeatCount === undefined ? 0 : repeatCount + }; } - /** - * Play/Resume the current video. - * @returns {Promise} - */ - ; - _proto.play = function play() { - var _this3 = this; + log/* default.warn */.Z.warn("DASH: A \"S\" Element could not have been parsed."); + return null; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/parse_s_element.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. + */ - if (this.videoElement === null) { - throw new Error("Disposed player"); - } +/** + * Parse a given element in the MPD into a JS Object. + * @param {Element} root + * @returns {Object} + */ - var playPromise = this.videoElement.play(); - /* eslint-disable @typescript-eslint/unbound-method */ +function parseSElement(root) { + var parsedS = {}; - if ((0,is_null_or_undefined/* default */.Z)(playPromise) || typeof playPromise["catch"] !== "function") { - /* eslint-enable @typescript-eslint/unbound-method */ - return promise/* default.resolve */.Z.resolve(); - } + for (var j = 0; j < root.attributes.length; j++) { + var attribute = root.attributes[j]; - return playPromise["catch"](function (error) { - if (error.name === "NotAllowedError") { - var warning = new media_error/* default */.Z("MEDIA_ERR_PLAY_NOT_ALLOWED", error.toString()); + switch (attribute.name) { + case "t": + var start = parseInt(attribute.value, 10); - _this3.trigger("warning", warning); - } + if (isNaN(start)) { + log/* default.warn */.Z.warn("DASH: invalid t (\"" + attribute.value + "\")"); + } else { + parsedS.start = start; + } - throw error; - }); - } - /** - * Pause the current video. - */ - ; + break; - _proto.pause = function pause() { - if (this.videoElement === null) { - throw new Error("Disposed player"); - } + case "d": + var duration = parseInt(attribute.value, 10); - this.videoElement.pause(); - } - /** - * Seek to a given absolute position. - * @param {Number|Object} time - * @returns {Number} - The time the player has seek to - */ - ; + if (isNaN(duration)) { + log/* default.warn */.Z.warn("DASH: invalid d (\"" + attribute.value + "\")"); + } else { + parsedS.duration = duration; + } - _proto.seekTo = function seekTo(time) { - if (this.videoElement === null) { - throw new Error("Disposed player"); - } + break; - if (this._priv_contentInfos === null) { - throw new Error("player: no content loaded"); - } + case "r": + var repeatCount = parseInt(attribute.value, 10); - var _this$_priv_contentIn7 = this._priv_contentInfos, - isDirectFile = _this$_priv_contentIn7.isDirectFile, - manifest = _this$_priv_contentIn7.manifest; + if (isNaN(repeatCount)) { + log/* default.warn */.Z.warn("DASH: invalid r (\"" + attribute.value + "\")"); + } else { + parsedS.repeatCount = repeatCount; + } - if (!isDirectFile && manifest === null) { - throw new Error("player: the content did not load yet"); + break; } + } - var positionWanted; - - if (typeof time === "number") { - positionWanted = time; - } else if (typeof time === "object") { - var timeObj = time; - var currentTs = this.videoElement.currentTime; + return parsedS; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/construct_timeline_from_elements.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. + */ - if (!(0,is_null_or_undefined/* default */.Z)(timeObj.relative)) { - positionWanted = currentTs + timeObj.relative; - } else if (!(0,is_null_or_undefined/* default */.Z)(timeObj.position)) { - positionWanted = timeObj.position; - } else if (!(0,is_null_or_undefined/* default */.Z)(timeObj.wallClockTime)) { - positionWanted = isDirectFile || manifest === null ? timeObj.wallClockTime : timeObj.wallClockTime - (manifest.availabilityStartTime !== undefined ? manifest.availabilityStartTime : 0); - } else { - throw new Error("invalid time object. You must set one of the " + "following properties: \"relative\", \"position\" or " + "\"wallClockTime\""); - } - } - if (positionWanted === undefined) { - throw new Error("invalid time given"); - } +/** + * Allows to generate the "timeline" for the "Timeline" RepresentationIndex. + * Call this function when the timeline is unknown. + * This function was added to only perform that task lazily, i.e. only when + * first needed. + * @param {HTMLCollection} elements - All S nodes constituting the corresponding + * SegmentTimeline node. + * @param {number} scaledPeriodStart - Absolute start of the concerned Period, + * in the same scale than the segments found in `elements`. + * @returns {Array.} + */ - this.videoElement.currentTime = positionWanted; - return positionWanted; - } - /** - * Returns true if the media element is full screen. - * @deprecated - * @returns {Boolean} - */ - ; +function constructTimelineFromElements(elements, scaledPeriodStart) { + var initialTimeline = []; - _proto.isFullscreen = function isFullscreen() { - (0,warn_once/* default */.Z)("isFullscreen is deprecated." + " Fullscreen management should now be managed by the application"); - return fullscreen_isFullscreen(); + for (var i = 0; i < elements.length; i++) { + initialTimeline.push(parseSElement(elements[i])); } - /** - * Set/exit fullScreen. - * @deprecated - * @param {Boolean} [goFull=true] - if false, exit full screen. - */ - ; - - _proto.setFullscreen = function setFullscreen(goFull) { - if (goFull === void 0) { - goFull = true; - } - (0,warn_once/* default */.Z)("setFullscreen is deprecated." + " Fullscreen management should now be managed by the application"); + var timeline = []; - if (this.videoElement === null) { - throw new Error("Disposed player"); - } + for (var _i = 0; _i < initialTimeline.length; _i++) { + var item = initialTimeline[_i]; + var previousItem = timeline[timeline.length - 1] === undefined ? null : timeline[timeline.length - 1]; + var nextItem = initialTimeline[_i + 1] === undefined ? null : initialTimeline[_i + 1]; + var timelineElement = convertElementsToIndexSegment(item, previousItem, nextItem, scaledPeriodStart); - if (goFull) { - requestFullscreen(this.videoElement); - } else { - fullscreen_exitFullscreen(); + if (timelineElement != null) { + timeline.push(timelineElement); } } - /** - * Exit from full screen mode. - * @deprecated - */ - ; - _proto.exitFullscreen = function exitFullscreen() { - (0,warn_once/* default */.Z)("exitFullscreen is deprecated." + " Fullscreen management should now be managed by the application"); + return timeline; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/find_first_common_start_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. + */ - fullscreen_exitFullscreen(); +/** + * By comparing two timelines for the same content at different points in time, + * retrieve the index in both timelines of the first segment having the same + * starting time. + * Returns `null` if not found. + * @param {Array.} prevTimeline + * @param {HTMLCollection} newElements + * @returns {Object|null} + */ +function findFirstCommonStartTime(prevTimeline, newElements) { + if (prevTimeline.length === 0 || newElements.length === 0) { + return null; } - /** - * Returns the current player's audio volume on the media element. - * From 0 (no audio) to 1 (maximum volume). - * @returns {Number} - */ - ; - _proto.getVolume = function getVolume() { - if (this.videoElement === null) { - throw new Error("Disposed player"); - } + var prevInitialStart = prevTimeline[0].start; + var newFirstTAttr = newElements[0].getAttribute("t"); + var newInitialStart = newFirstTAttr === null ? null : parseInt(newFirstTAttr, 10); - return this.videoElement.volume; + if (newInitialStart === null || Number.isNaN(newInitialStart)) { + return null; } - /** - * Set the player's audio volume. From 0 (no volume) to 1 (maximum volume). - * @param {Number} volume - */ - ; - _proto.setVolume = function setVolume(volume) { - if (this.videoElement === null) { - throw new Error("Disposed player"); - } + if (prevInitialStart === newInitialStart) { + return { + prevSegmentsIdx: 0, + newElementsIdx: 0, + repeatNumberInPrevSegments: 0, + repeatNumberInNewElements: 0 + }; + } else if (prevInitialStart < newInitialStart) { + var prevElt = prevTimeline[0]; + var prevElementIndex = 0; - var videoElement = this.videoElement; + while (true) { + if (prevElt.repeatCount > 0) { + var diff = newInitialStart - prevElt.start; - if (volume !== videoElement.volume) { - videoElement.volume = volume; - this.trigger("volumeChange", volume); - } - } - /** - * Returns true if the volume is set to 0. false otherwise. - * @returns {Boolean} - */ - ; + if (diff % prevElt.duration === 0 && diff / prevElt.duration <= prevElt.repeatCount) { + var repeatNumberInPrevSegments = diff / prevElt.duration; + return { + repeatNumberInPrevSegments: repeatNumberInPrevSegments, + prevSegmentsIdx: prevElementIndex, + newElementsIdx: 0, + repeatNumberInNewElements: 0 + }; + } + } - _proto.isMute = function isMute() { - return this.getVolume() === 0; - } - /** - * Set the volume to 0 and save current one for when unmuted. - */ - ; + prevElementIndex++; - _proto.mute = function mute() { - this._priv_mutedMemory = this.getVolume(); - this.setVolume(0); - } - /** - * Set the volume back to when it was when mute was last called. - * If the volume was set to 0, set a default volume instead (see config). - */ - ; + if (prevElementIndex >= prevTimeline.length) { + return null; + } - _proto.unMute = function unMute() { - var vol = this.getVolume(); + prevElt = prevTimeline[prevElementIndex]; - if (vol === 0) { - this.setVolume(this._priv_mutedMemory === 0 ? DEFAULT_UNMUTED_VOLUME : this._priv_mutedMemory); + if (prevElt.start === newInitialStart) { + return { + prevSegmentsIdx: prevElementIndex, + newElementsIdx: 0, + repeatNumberInPrevSegments: 0, + repeatNumberInNewElements: 0 + }; + } else if (prevElt.start > newInitialStart) { + return null; + } } - } - /** - * Force the video bitrate to a given value. Act as a ceil. - * -1 to set it on AUTO Mode - * @param {Number} btr - */ - ; + } else { + var newElementsIdx = 0; + var newElt = newElements[0]; + var currentTimeOffset = newInitialStart; - _proto.setVideoBitrate = function setVideoBitrate(btr) { - this._priv_bitrateInfos.manualBitrates.video.next(btr); + while (true) { + var dAttr = newElt.getAttribute("d"); + var duration = dAttr === null ? null : parseInt(dAttr, 10); + + if (duration === null || Number.isNaN(duration)) { + return null; + } + + var rAttr = newElt.getAttribute("r"); + var repeatCount = rAttr === null ? null : parseInt(rAttr, 10); + + if (repeatCount !== null) { + if (Number.isNaN(repeatCount) || repeatCount < 0) { + return null; + } + + if (repeatCount > 0) { + var _diff = prevInitialStart - currentTimeOffset; + + if (_diff % duration === 0 && _diff / duration <= repeatCount) { + var repeatNumberInNewElements = _diff / duration; + return { + repeatNumberInPrevSegments: 0, + repeatNumberInNewElements: repeatNumberInNewElements, + prevSegmentsIdx: 0, + newElementsIdx: newElementsIdx + }; + } + } + + currentTimeOffset += duration * (repeatCount + 1); + } else { + currentTimeOffset += duration; + } + + newElementsIdx++; + + if (newElementsIdx >= newElements.length) { + return null; + } + + newElt = newElements[newElementsIdx]; + var tAttr = newElt.getAttribute("t"); + var time = tAttr === null ? null : parseInt(tAttr, 10); + + if (time !== null) { + if (Number.isNaN(time)) { + return null; + } + + currentTimeOffset = time; + } + + if (currentTimeOffset === prevInitialStart) { + return { + newElementsIdx: newElementsIdx, + prevSegmentsIdx: 0, + repeatNumberInPrevSegments: 0, + repeatNumberInNewElements: 0 + }; + } else if (currentTimeOffset > newInitialStart) { + return null; + } + } } - /** - * Force the audio bitrate to a given value. Act as a ceil. - * -1 to set it on AUTO Mode - * @param {Number} btr - */ - ; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/construct_timeline_from_previous_timeline.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. + */ - _proto.setAudioBitrate = function setAudioBitrate(btr) { - this._priv_bitrateInfos.manualBitrates.audio.next(btr); + + + + +function constructTimelineFromPreviousTimeline(newElements, prevTimeline, scaledPeriodStart) { + var _a; // Find first index in both timeline where a common segment is found. + + + var commonStartInfo = findFirstCommonStartTime(prevTimeline, newElements); + + if (commonStartInfo === null) { + log/* default.warn */.Z.warn("DASH: Cannot perform \"based\" update. Common segment not found."); + return constructTimelineFromElements(newElements, scaledPeriodStart); } - /** - * Update the minimum video bitrate the user can switch to. - * @param {Number} btr - */ - ; - _proto.setMinVideoBitrate = function setMinVideoBitrate(btr) { - var maxVideoBitrate = this._priv_bitrateInfos.maxAutoBitrates.video.getValue(); + var prevSegmentsIdx = commonStartInfo.prevSegmentsIdx, + newElementsIdx = commonStartInfo.newElementsIdx, + repeatNumberInPrevSegments = commonStartInfo.repeatNumberInPrevSegments, + repeatNumberInNewElements = commonStartInfo.repeatNumberInNewElements; + /** Guess of the number of elements in common. */ - if (btr > maxVideoBitrate) { - throw new Error("Invalid minimum video bitrate given. " + ("Its value, \"" + btr + "\" is superior the current maximum ") + ("video birate, \"" + maxVideoBitrate + "\".")); - } + var numberCommonEltGuess = prevTimeline.length - prevSegmentsIdx; + var lastCommonEltNewEltsIdx = numberCommonEltGuess + newElementsIdx - 1; - this._priv_bitrateInfos.minAutoBitrates.video.next(btr); + if (lastCommonEltNewEltsIdx >= newElements.length) { + log/* default.info */.Z.info("DASH: Cannot perform \"based\" update. New timeline too short"); + return constructTimelineFromElements(newElements, scaledPeriodStart); + } // Remove elements which are not available anymore + + + var newTimeline = prevTimeline.slice(prevSegmentsIdx); + + if (repeatNumberInPrevSegments > 0) { + var commonEltInOldTimeline = newTimeline[0]; + commonEltInOldTimeline.start += commonEltInOldTimeline.duration * repeatNumberInPrevSegments; + newTimeline[0].repeatCount -= repeatNumberInPrevSegments; } - /** - * Update the minimum audio bitrate the user can switch to. - * @param {Number} btr - */ - ; - _proto.setMinAudioBitrate = function setMinAudioBitrate(btr) { - var maxAudioBitrate = this._priv_bitrateInfos.maxAutoBitrates.audio.getValue(); + if (repeatNumberInNewElements > 0 && newElementsIdx !== 0) { + log/* default.info */.Z.info("DASH: Cannot perform \"based\" update. " + "The new timeline has a different form."); + return constructTimelineFromElements(newElements, scaledPeriodStart); + } - if (btr > maxAudioBitrate) { - throw new Error("Invalid minimum audio bitrate given. " + ("Its value, \"" + btr + "\" is superior the current maximum ") + ("audio birate, \"" + maxAudioBitrate + "\".")); - } + var prevLastElement = newTimeline[newTimeline.length - 1]; + var newCommonElt = parseSElement(newElements[lastCommonEltNewEltsIdx]); + var newRepeatCountOffseted = ((_a = newCommonElt.repeatCount) !== null && _a !== void 0 ? _a : 0) - repeatNumberInNewElements; - this._priv_bitrateInfos.minAutoBitrates.audio.next(btr); + if (newCommonElt.duration !== prevLastElement.duration || prevLastElement.repeatCount > newRepeatCountOffseted) { + log/* default.info */.Z.info("DASH: Cannot perform \"based\" update. " + "The new timeline has a different form at the beginning."); + return constructTimelineFromElements(newElements, scaledPeriodStart); + } + + if (newCommonElt.repeatCount !== undefined && newCommonElt.repeatCount > prevLastElement.repeatCount) { + prevLastElement.repeatCount = newCommonElt.repeatCount; + } + + var newEltsToPush = []; + var items = []; + + for (var i = lastCommonEltNewEltsIdx + 1; i < newElements.length; i++) { + items.push(parseSElement(newElements[i])); + } + + for (var _i = 0; _i < items.length; _i++) { + var item = items[_i]; + var previousItem = newEltsToPush[newEltsToPush.length - 1] === undefined ? prevLastElement : newEltsToPush[newEltsToPush.length - 1]; + var nextItem = items[_i + 1] === undefined ? null : items[_i + 1]; + var timelineElement = convertElementsToIndexSegment(item, previousItem, nextItem, scaledPeriodStart); + + if (timelineElement !== null) { + newEltsToPush.push(timelineElement); + } } + + return newTimeline.concat(newEltsToPush); +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/timeline_representation_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. + */ + + + + + + + + + + + + // eslint-disable-next-line max-len + + +var MIN_DASH_S_ELEMENTS_TO_PARSE_UNSAFELY = config/* default.MIN_DASH_S_ELEMENTS_TO_PARSE_UNSAFELY */.Z.MIN_DASH_S_ELEMENTS_TO_PARSE_UNSAFELY; + +var TimelineRepresentationIndex = /*#__PURE__*/function () { /** - * Update the maximum video bitrate the user can switch to. - * @param {Number} btr + * @param {Object} index + * @param {Object} context */ - ; + function TimelineRepresentationIndex(index, timelineParser, context) { + var _a; - _proto.setMaxVideoBitrate = function setMaxVideoBitrate(btr) { - var minVideoBitrate = this._priv_bitrateInfos.minAutoBitrates.video.getValue(); + var manifestBoundsCalculator = context.manifestBoundsCalculator, + isDynamic = context.isDynamic, + representationBaseURLs = context.representationBaseURLs, + representationId = context.representationId, + representationBitrate = context.representationBitrate, + periodStart = context.periodStart, + periodEnd = context.periodEnd, + isEMSGWhitelisted = context.isEMSGWhitelisted; + var timescale = (_a = index.timescale) !== null && _a !== void 0 ? _a : 1; + var presentationTimeOffset = index.presentationTimeOffset != null ? index.presentationTimeOffset : 0; + var scaledStart = periodStart * timescale; + var indexTimeOffset = presentationTimeOffset - scaledStart; + this._manifestBoundsCalculator = manifestBoundsCalculator; + this._isEMSGWhitelisted = isEMSGWhitelisted; + this._lastUpdate = context.receivedTime == null ? performance.now() : context.receivedTime; + this._unsafelyBaseOnPreviousIndex = null; - if (btr < minVideoBitrate) { - throw new Error("Invalid maximum video bitrate given. " + ("Its value, \"" + btr + "\" is inferior the current minimum ") + ("video birate, \"" + minVideoBitrate + "\".")); + if (context.unsafelyBaseOnPreviousRepresentation !== null && context.unsafelyBaseOnPreviousRepresentation.index instanceof TimelineRepresentationIndex) { + // avoid too much nested references, to keep memory down + context.unsafelyBaseOnPreviousRepresentation.index._unsafelyBaseOnPreviousIndex = null; + this._unsafelyBaseOnPreviousIndex = context.unsafelyBaseOnPreviousRepresentation.index; } - this._priv_bitrateInfos.maxAutoBitrates.video.next(btr); + this._isDynamic = isDynamic; + this._parseTimeline = timelineParser; + this._index = { + indexRange: index.indexRange, + indexTimeOffset: indexTimeOffset, + initialization: index.initialization == null ? undefined : { + mediaURLs: createIndexURLs(representationBaseURLs, index.initialization.media, representationId, representationBitrate), + range: index.initialization.range + }, + mediaURLs: createIndexURLs(representationBaseURLs, index.media, representationId, representationBitrate), + startNumber: index.startNumber, + timeline: null, + timescale: timescale + }; + this._scaledPeriodStart = (0,index_helpers/* toIndexTime */.gT)(periodStart, this._index); + this._scaledPeriodEnd = periodEnd == null ? undefined : (0,index_helpers/* toIndexTime */.gT)(periodEnd, this._index); } /** - * Update the maximum audio bitrate the user can switch to. - * @param {Number} btr + * Construct init Segment. + * @returns {Object} */ - ; - _proto.setMaxAudioBitrate = function setMaxAudioBitrate(btr) { - var minAudioBitrate = this._priv_bitrateInfos.minAutoBitrates.audio.getValue(); - if (btr < minAudioBitrate) { - throw new Error("Invalid maximum audio bitrate given. " + ("Its value, \"" + btr + "\" is inferior the current minimum ") + ("audio birate, \"" + minAudioBitrate + "\".")); - } + var _proto = TimelineRepresentationIndex.prototype; - this._priv_bitrateInfos.maxAutoBitrates.audio.next(btr); + _proto.getInitSegment = function getInitSegment() { + return get_init_segment_getInitSegment(this._index, this._isEMSGWhitelisted); } /** - * Set the max buffer size for the buffer behind the current position. - * Every buffer data before will be removed. - * @param {Number} depthInSeconds + * Asks for segments to download for a given time range. + * @param {Number} from - Beginning of the time wanted, in seconds + * @param {Number} duration - duration wanted, in seconds + * @returns {Array.} */ ; - _proto.setMaxBufferBehind = function setMaxBufferBehind(depthInSeconds) { - this._priv_bufferOptions.maxBufferBehind$.next(depthInSeconds); + _proto.getSegments = function getSegments(from, duration) { + this._refreshTimeline(); // clear timeline if needed + + + if (this._index.timeline === null) { + this._index.timeline = this._getTimeline(); + } // destructuring to please TypeScript + + + var _this$_index = this._index, + mediaURLs = _this$_index.mediaURLs, + startNumber = _this$_index.startNumber, + timeline = _this$_index.timeline, + timescale = _this$_index.timescale, + indexTimeOffset = _this$_index.indexTimeOffset; + return getSegmentsFromTimeline({ + mediaURLs: mediaURLs, + startNumber: startNumber, + timeline: timeline, + timescale: timescale, + indexTimeOffset: indexTimeOffset + }, from, duration, this._isEMSGWhitelisted, this._scaledPeriodEnd); } /** - * Set the max buffer size for the buffer behind the current position. - * Every buffer data before will be removed. - * @param {Number} depthInSeconds + * Returns true if the index should be refreshed. + * @param {Number} _up + * @param {Number} to + * @returns {Boolean} */ ; - _proto.setMaxBufferAhead = function setMaxBufferAhead(depthInSeconds) { - this._priv_bufferOptions.maxBufferAhead$.next(depthInSeconds); + _proto.shouldRefresh = function shouldRefresh() { + // DASH Manifest based on a SegmentTimeline should have minimumUpdatePeriod + // attribute which should be sufficient to know when to refresh it. + return false; } /** - * Set the max buffer size for the buffer ahead of the current position. - * The player will stop downloading chunks when this size is reached. - * @param {Number} sizeInSeconds + * Returns the starting time, in seconds, of the earliest segment currently + * available. + * Returns null if nothing is in the index + * @returns {Number|null} */ ; - _proto.setWantedBufferAhead = function setWantedBufferAhead(sizeInSeconds) { - this._priv_bufferOptions.wantedBufferAhead$.next(sizeInSeconds); + _proto.getFirstPosition = function getFirstPosition() { + this._refreshTimeline(); + + if (this._index.timeline === null) { + this._index.timeline = this._getTimeline(); + } + + var timeline = this._index.timeline; + return timeline.length === 0 ? null : (0,index_helpers/* fromIndexTime */.zG)(timeline[0].start, this._index); } /** - * Returns the max buffer size for the buffer behind the current position. - * @returns {Number} + * Returns the ending time, in seconds, of the last segment currently + * available. + * Returns null if nothing is in the index + * @returns {Number|null} */ ; - _proto.getMaxBufferBehind = function getMaxBufferBehind() { - return this._priv_bufferOptions.maxBufferBehind$.getValue(); + _proto.getLastPosition = function getLastPosition() { + this._refreshTimeline(); + + if (this._index.timeline === null) { + this._index.timeline = this._getTimeline(); + } + + var lastTime = TimelineRepresentationIndex.getIndexEnd(this._index.timeline, this._scaledPeriodStart); + return lastTime === null ? null : (0,index_helpers/* fromIndexTime */.zG)(lastTime, this._index); } /** - * Returns the max buffer size for the buffer behind the current position. - * @returns {Number} + * Returns true if a Segment returned by this index is still considered + * available. + * Returns false if it is not available anymore. + * Returns undefined if we cannot know whether it is still available or not. + * @param {Object} segment + * @returns {Boolean|undefined} */ ; - _proto.getMaxBufferAhead = function getMaxBufferAhead() { - return this._priv_bufferOptions.maxBufferAhead$.getValue(); + _proto.isSegmentStillAvailable = function isSegmentStillAvailable(segment) { + if (segment.isInit) { + return true; + } + + this._refreshTimeline(); + + if (this._index.timeline === null) { + this._index.timeline = this._getTimeline(); + } + + var _this$_index2 = this._index, + timeline = _this$_index2.timeline, + timescale = _this$_index2.timescale, + indexTimeOffset = _this$_index2.indexTimeOffset; + return (0,is_segment_still_available/* default */.Z)(segment, timeline, timescale, indexTimeOffset); } /** - * Returns the max buffer size for the buffer ahead of the current position. - * @returns {Number} + * Checks if the time given is in a discontinuity. That is: + * - We're on the upper bound of the current range (end of the range - time + * is inferior to the timescale) + * - The next range starts after the end of the current range. + * @param {Number} time + * @returns {Number|null} */ ; - _proto.getWantedBufferAhead = function getWantedBufferAhead() { - return this._priv_bufferOptions.wantedBufferAhead$.getValue(); + _proto.checkDiscontinuity = function checkDiscontinuity(time) { + this._refreshTimeline(); + + var timeline = this._index.timeline; + + if (timeline === null) { + timeline = this._getTimeline(); + this._index.timeline = timeline; + } + + return (0,index_helpers/* checkDiscontinuity */._j)({ + timeline: timeline, + timescale: this._index.timescale, + indexTimeOffset: this._index.indexTimeOffset + }, time, this._scaledPeriodEnd); } /** - * Returns type of current keysystem (e.g. playready, widevine) if the content - * is encrypted. null otherwise. - * @returns {string|null} + * @param {Error} error + * @returns {Boolean} */ ; - _proto.getCurrentKeySystem = function getCurrentKeySystem() { - if (this.videoElement === null) { - throw new Error("Disposed player"); + _proto.canBeOutOfSyncError = function canBeOutOfSyncError(error) { + if (!this._isDynamic) { + return false; } - return get_current_key_system_getCurrentKeySystem(this.videoElement); + return error instanceof network_error/* default */.Z && error.isHttpError(404); + }; + + _proto.areSegmentsChronologicallyGenerated = function areSegmentsChronologicallyGenerated() { + return true; } /** - * Returns every available audio tracks for the current Period. - * @returns {Array.|null} + * Replace this RepresentationIndex with one from a new version of the + * Manifest. + * @param {Object} newIndex */ ; - _proto.getAvailableAudioTracks = function getAvailableAudioTracks() { - var _a, _b; - - if (this._priv_contentInfos === null) { - return []; - } - - var _this$_priv_contentIn8 = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn8.currentPeriod, - isDirectFile = _this$_priv_contentIn8.isDirectFile; + _proto._replace = function _replace(newIndex) { + this._parseTimeline = newIndex._parseTimeline; + this._index = newIndex._index; + this._isDynamic = newIndex._isDynamic; + this._scaledPeriodStart = newIndex._scaledPeriodStart; + this._scaledPeriodEnd = newIndex._scaledPeriodEnd; + this._lastUpdate = newIndex._lastUpdate; + this._manifestBoundsCalculator = newIndex._manifestBoundsCalculator; + } + /** + * Update this RepresentationIndex with a shorter version of it coming from a + * new version of the MPD. + * @param {Object} newIndex + */ + ; - if (isDirectFile) { - return (_b = (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.getAvailableAudioTracks()) !== null && _b !== void 0 ? _b : []; + _proto._update = function _update(newIndex) { + if (this._index.timeline === null) { + this._index.timeline = this._getTimeline(); } - if (this._priv_trackChoiceManager === null || currentPeriod === null) { - return []; + if (newIndex._index.timeline === null) { + newIndex._index.timeline = newIndex._getTimeline(); } - return this._priv_trackChoiceManager.getAvailableAudioTracks(currentPeriod); + (0,update_segment_timeline/* default */.Z)(this._index.timeline, newIndex._index.timeline); + this._isDynamic = newIndex._isDynamic; + this._scaledPeriodStart = newIndex._scaledPeriodStart; + this._scaledPeriodEnd = newIndex._scaledPeriodEnd; + this._lastUpdate = newIndex._lastUpdate; } /** - * Returns every available text tracks for the current Period. - * @returns {Array.|null} + * Returns `true` if this RepresentationIndex currently contains its last + * segment. + * Returns `false` if it's still pending. + * @returns {Boolean} */ ; - _proto.getAvailableTextTracks = function getAvailableTextTracks() { - var _a, _b; - - if (this._priv_contentInfos === null) { - return []; + _proto.isFinished = function isFinished() { + if (!this._isDynamic) { + return true; } - var _this$_priv_contentIn9 = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn9.currentPeriod, - isDirectFile = _this$_priv_contentIn9.isDirectFile; - - if (isDirectFile) { - return (_b = (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.getAvailableTextTracks()) !== null && _b !== void 0 ? _b : []; + if (this._index.timeline === null) { + this._index.timeline = this._getTimeline(); } - if (this._priv_trackChoiceManager === null || currentPeriod === null) { - return []; + var timeline = this._index.timeline; + + if (this._scaledPeriodEnd === undefined || timeline.length === 0) { + return false; } - return this._priv_trackChoiceManager.getAvailableTextTracks(currentPeriod); + var lastTimelineElement = timeline[timeline.length - 1]; + var lastTime = (0,index_helpers/* getIndexSegmentEnd */.jH)(lastTimelineElement, null, this._scaledPeriodEnd); + return isPeriodFulfilled(this._index.timescale, lastTime, this._scaledPeriodEnd); } /** - * Returns every available video tracks for the current Period. - * @returns {Array.|null} + * @returns {Boolean} */ ; - _proto.getAvailableVideoTracks = function getAvailableVideoTracks() { - var _a, _b; + _proto.isInitialized = function isInitialized() { + return true; + } + /** + * Clean-up timeline to remove segment information which should not be + * available due to timeshifting. + */ + ; - if (this._priv_contentInfos === null) { - return []; + _proto._refreshTimeline = function _refreshTimeline() { + if (this._index.timeline === null) { + this._index.timeline = this._getTimeline(); } - var _this$_priv_contentIn10 = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn10.currentPeriod, - isDirectFile = _this$_priv_contentIn10.isDirectFile; + var firstPosition = this._manifestBoundsCalculator.estimateMinimumBound(); - if (isDirectFile) { - return (_b = (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.getAvailableVideoTracks()) !== null && _b !== void 0 ? _b : []; + if (firstPosition == null) { + return; // we don't know yet } - if (this._priv_trackChoiceManager === null || currentPeriod === null) { - return []; + var scaledFirstPosition = (0,index_helpers/* toIndexTime */.gT)(firstPosition, this._index); + (0,clear_timeline_from_position/* default */.Z)(this._index.timeline, scaledFirstPosition); + }; + + TimelineRepresentationIndex.getIndexEnd = function getIndexEnd(timeline, scaledPeriodEnd) { + if (timeline.length <= 0) { + return null; } - return this._priv_trackChoiceManager.getAvailableVideoTracks(currentPeriod); + return (0,index_helpers/* getIndexSegmentEnd */.jH)(timeline[timeline.length - 1], null, scaledPeriodEnd); } /** - * Returns currently chosen audio language for the current Period. - * @returns {string} + * Allows to generate the "timeline" for this RepresentationIndex. + * Call this function when the timeline is unknown. + * This function was added to only perform that task lazily, i.e. only when + * first needed. + * After calling it, every now unneeded variable will be freed from memory. + * This means that calling _getTimeline more than once will just return an + * empty array. + * + * /!\ Please note that this structure should follow the exact same structure + * than a SegmentTimeline element in the corresponding MPD. + * This means: + * - It should have the same amount of elements in its array than there was + * `` elements in the SegmentTimeline. + * - Each of those same elements should have the same start time, the same + * duration and the same repeat counter than what could be deduced from + * the SegmentTimeline. + * This is needed to be able to run parsing optimization when refreshing the + * MPD. Not doing so could lead to the RxPlayer not being able to play the + * stream anymore. + * @returns {Array.} */ ; - _proto.getAudioTrack = function getAudioTrack() { - if (this._priv_contentInfos === null) { - return undefined; + _proto._getTimeline = function _getTimeline() { + if (this._parseTimeline === null) { + if (this._index.timeline !== null) { + return this._index.timeline; + } + + log/* default.error */.Z.error("DASH: Timeline already lazily parsed."); + return []; } - var _this$_priv_contentIn11 = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn11.currentPeriod, - isDirectFile = _this$_priv_contentIn11.isDirectFile; + var newElements = this._parseTimeline(); - if (isDirectFile) { - if (this._priv_mediaElementTrackChoiceManager === null) { - return undefined; - } + this._parseTimeline = null; // Free memory - return this._priv_mediaElementTrackChoiceManager.getChosenAudioTrack(); - } + if (this._unsafelyBaseOnPreviousIndex === null || newElements.length < MIN_DASH_S_ELEMENTS_TO_PARSE_UNSAFELY) { + // Just completely parse the current timeline + return constructTimelineFromElements(newElements, this._scaledPeriodStart); + } // Construct previously parsed timeline if not already done - if (this._priv_trackChoiceManager === null || currentPeriod === null) { - return undefined; - } - return this._priv_trackChoiceManager.getChosenAudioTrack(currentPeriod); - } - /** - * Returns currently chosen subtitle for the current Period. - * @returns {string} - */ - ; + var prevTimeline; - _proto.getTextTrack = function getTextTrack() { - if (this._priv_contentInfos === null) { - return undefined; + if (this._unsafelyBaseOnPreviousIndex._index.timeline === null) { + prevTimeline = this._unsafelyBaseOnPreviousIndex._getTimeline(); + this._unsafelyBaseOnPreviousIndex._index.timeline = prevTimeline; + } else { + prevTimeline = this._unsafelyBaseOnPreviousIndex._index.timeline; } - var _this$_priv_contentIn12 = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn12.currentPeriod, - isDirectFile = _this$_priv_contentIn12.isDirectFile; + this._unsafelyBaseOnPreviousIndex = null; // Free memory - if (isDirectFile) { - if (this._priv_mediaElementTrackChoiceManager === null) { - return undefined; - } + return constructTimelineFromPreviousTimeline(newElements, prevTimeline, this._scaledPeriodStart); + }; - return this._priv_mediaElementTrackChoiceManager.getChosenTextTrack(); - } + return TimelineRepresentationIndex; +}(); - if (this._priv_trackChoiceManager === null || currentPeriod === null) { - return undefined; - } - return this._priv_trackChoiceManager.getChosenTextTrack(currentPeriod); - } - /** - * Returns currently chosen video track for the current Period. - * @returns {string} - */ - ; +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/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. + */ - _proto.getVideoTrack = function getVideoTrack() { - if (this._priv_contentInfos === null) { - return undefined; - } +/* harmony default export */ const timeline = (TimelineRepresentationIndex); +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/template.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 _this$_priv_contentIn13 = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn13.currentPeriod, - isDirectFile = _this$_priv_contentIn13.isDirectFile; - if (isDirectFile) { - if (this._priv_mediaElementTrackChoiceManager === null) { - return undefined; - } - return this._priv_mediaElementTrackChoiceManager.getChosenVideoTrack(); - } - if (this._priv_trackChoiceManager === null || currentPeriod === null) { - return undefined; - } +var MINIMUM_SEGMENT_SIZE = config/* default.MINIMUM_SEGMENT_SIZE */.Z.MINIMUM_SEGMENT_SIZE; +/** + * IRepresentationIndex implementation for DASH' SegmentTemplate without a + * SegmentTimeline. + * @class TemplateRepresentationIndex + */ - return this._priv_trackChoiceManager.getChosenVideoTrack(currentPeriod); - } +var TemplateRepresentationIndex = /*#__PURE__*/function () { /** - * Update the audio language for the current Period. - * @param {string} audioId - * @throws Error - the current content has no TrackChoiceManager. - * @throws Error - the given id is linked to no audio track. + * @param {Object} index + * @param {Object} context */ - ; - - _proto.setAudioTrack = function setAudioTrack(audioId) { + function TemplateRepresentationIndex(index, context) { var _a; - if (this._priv_contentInfos === null) { - throw new Error("No content loaded"); + var aggressiveMode = context.aggressiveMode, + availabilityTimeOffset = context.availabilityTimeOffset, + manifestBoundsCalculator = context.manifestBoundsCalculator, + isDynamic = context.isDynamic, + periodEnd = context.periodEnd, + periodStart = context.periodStart, + representationBaseURLs = context.representationBaseURLs, + representationId = context.representationId, + representationBitrate = context.representationBitrate, + isEMSGWhitelisted = context.isEMSGWhitelisted; + var timescale = (_a = index.timescale) !== null && _a !== void 0 ? _a : 1; + this._availabilityTimeOffset = availabilityTimeOffset; + this._manifestBoundsCalculator = manifestBoundsCalculator; + this._aggressiveMode = aggressiveMode; + var presentationTimeOffset = index.presentationTimeOffset != null ? index.presentationTimeOffset : 0; + var scaledStart = periodStart * timescale; + var indexTimeOffset = presentationTimeOffset - scaledStart; + + if (index.duration === undefined) { + throw new Error("Invalid SegmentTemplate: no duration"); } - var _this$_priv_contentIn14 = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn14.currentPeriod, - isDirectFile = _this$_priv_contentIn14.isDirectFile; + this._index = { + duration: index.duration, + timescale: timescale, + indexRange: index.indexRange, + indexTimeOffset: indexTimeOffset, + initialization: index.initialization == null ? undefined : { + mediaURLs: createIndexURLs(representationBaseURLs, index.initialization.media, representationId, representationBitrate), + range: index.initialization.range + }, + mediaURLs: createIndexURLs(representationBaseURLs, index.media, representationId, representationBitrate), + presentationTimeOffset: presentationTimeOffset, + startNumber: index.startNumber + }; + this._isDynamic = isDynamic; + this._periodStart = periodStart; + this._scaledPeriodEnd = periodEnd == null ? undefined : (periodEnd - periodStart) * timescale; + this._isEMSGWhitelisted = isEMSGWhitelisted; + } + /** + * Construct init Segment. + * @returns {Object} + */ - if (isDirectFile) { - try { - (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.setAudioTrackById(audioId); - return; - } catch (e) { - throw new Error("player: unknown audio track"); - } - } - if (this._priv_trackChoiceManager === null || currentPeriod === null) { - throw new Error("No compatible content launched."); - } + var _proto = TemplateRepresentationIndex.prototype; - try { - this._priv_trackChoiceManager.setAudioTrackByID(currentPeriod, audioId); - } catch (e) { - throw new Error("player: unknown audio track"); - } + _proto.getInitSegment = function getInitSegment() { + return get_init_segment_getInitSegment(this._index, this._isEMSGWhitelisted); } /** - * Update the text language for the current Period. - * @param {string} sub - * @throws Error - the current content has no TrackChoiceManager. - * @throws Error - the given id is linked to no text track. + * @param {Number} fromTime + * @param {Number} dur + * @returns {Array.} */ ; - _proto.setTextTrack = function setTextTrack(textId) { - var _a; - - if (this._priv_contentInfos === null) { - throw new Error("No content loaded"); - } + _proto.getSegments = function getSegments(fromTime, dur) { + var index = this._index; + var duration = index.duration, + startNumber = index.startNumber, + timescale = index.timescale, + mediaURLs = index.mediaURLs; + var scaledStart = this._periodStart * timescale; + var scaledEnd = this._scaledPeriodEnd; // Convert the asked position to the right timescales, and consider them + // relatively to the Period's start. - var _this$_priv_contentIn15 = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn15.currentPeriod, - isDirectFile = _this$_priv_contentIn15.isDirectFile; + var upFromPeriodStart = fromTime * timescale - scaledStart; + var toFromPeriodStart = (fromTime + dur) * timescale - scaledStart; - if (isDirectFile) { - try { - (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.setTextTrackById(textId); - return; - } catch (e) { - throw new Error("player: unknown text track"); - } - } + var firstSegmentStart = this._getFirstSegmentStart(); - if (this._priv_trackChoiceManager === null || currentPeriod === null) { - throw new Error("No compatible content launched."); - } + var lastSegmentStart = this._getLastSegmentStart(); - try { - this._priv_trackChoiceManager.setTextTrackByID(currentPeriod, textId); - } catch (e) { - throw new Error("player: unknown text track"); + if (firstSegmentStart == null || lastSegmentStart == null) { + return []; } - } - /** - * Disable subtitles for the current content. - */ - ; - _proto.disableTextTrack = function disableTextTrack() { - var _a; + var startPosition = Math.max(firstSegmentStart, upFromPeriodStart); + var lastWantedStartPosition = Math.min(lastSegmentStart, toFromPeriodStart); - if (this._priv_contentInfos === null) { - return; + if (lastWantedStartPosition + duration <= startPosition) { + return []; } - var _this$_priv_contentIn16 = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn16.currentPeriod, - isDirectFile = _this$_priv_contentIn16.isDirectFile; + var segments = []; // number corresponding to the Period's start - if (isDirectFile) { - (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.disableTextTrack(); - return; - } + var numberOffset = startNumber == null ? 1 : startNumber; // calcul initial time from Period start, where the first segment would have + // the `0` number - if (this._priv_trackChoiceManager === null || currentPeriod === null) { - return; + var numberIndexedToZero = Math.floor(startPosition / duration); + + for (var timeFromPeriodStart = numberIndexedToZero * duration; timeFromPeriodStart <= lastWantedStartPosition; timeFromPeriodStart += duration) { + // To obtain the real number, adds the real number from the Period's start + var realNumber = numberIndexedToZero + numberOffset; + var realDuration = scaledEnd != null && timeFromPeriodStart + duration > scaledEnd ? scaledEnd - timeFromPeriodStart : duration; + var realTime = timeFromPeriodStart + scaledStart; + var manifestTime = timeFromPeriodStart + this._index.presentationTimeOffset; + var detokenizedURLs = mediaURLs === null ? null : mediaURLs.map(createDashUrlDetokenizer(manifestTime, realNumber)); + var args = { + id: String(realNumber), + number: realNumber, + time: realTime / timescale, + end: (realTime + realDuration) / timescale, + duration: realDuration / timescale, + timescale: 1, + isInit: false, + scaledDuration: realDuration / timescale, + mediaURLs: detokenizedURLs, + timestampOffset: -(index.indexTimeOffset / timescale), + privateInfos: { + isEMSGWhitelisted: this._isEMSGWhitelisted + } + }; + segments.push(args); + numberIndexedToZero++; } - return this._priv_trackChoiceManager.disableTextTrack(currentPeriod); + return segments; } /** - * Update the video track for the current Period. - * @param {string} videoId - * @throws Error - the current content has no TrackChoiceManager. - * @throws Error - the given id is linked to no video track. + * Returns first possible position in the index, in seconds. + * @returns {number|null|undefined} */ ; - _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; - - if (isDirectFile) { - try { - (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.setVideoTrackById(videoId); - return; - } catch (e) { - throw new Error("player: unknown video track"); - } - } + _proto.getFirstPosition = function getFirstPosition() { + var firstSegmentStart = this._getFirstSegmentStart(); - if (this._priv_trackChoiceManager === null || currentPeriod === null) { - throw new Error("No compatible content launched."); + if (firstSegmentStart == null) { + return firstSegmentStart; // return undefined or null } - try { - this._priv_trackChoiceManager.setVideoTrackByID(currentPeriod, videoId); - } catch (e) { - throw new Error("player: unknown video track"); - } + return firstSegmentStart / this._index.timescale + this._periodStart; } /** - * Disable video track for the current content. + * Returns last possible position in the index, in seconds. + * @returns {number|null} */ ; - _proto.disableVideoTrack = function disableVideoTrack() { - if (this._priv_contentInfos === null) { - return; - } - - 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(); - } + _proto.getLastPosition = function getLastPosition() { + var lastSegmentStart = this._getLastSegmentStart(); - if (this._priv_trackChoiceManager === null || currentPeriod === null) { - return; + if (lastSegmentStart == null) { + // In that case (null or undefined), getLastPosition should reflect + // the result of getLastSegmentStart, as the meaning is the same for + // the two functions. So, we return the result of the latter. + return lastSegmentStart; } - return this._priv_trackChoiceManager.disableVideoTrack(currentPeriod); + var lastSegmentEnd = lastSegmentStart + this._index.duration; + return lastSegmentEnd / this._index.timescale + this._periodStart; } /** - * Returns the current list of preferred audio tracks, in preference order. - * @returns {Array.} + * Returns true if, based on the arguments, the index should be refreshed. + * We never have to refresh a SegmentTemplate-based manifest. + * @returns {Boolean} */ ; - _proto.getPreferredAudioTracks = function getPreferredAudioTracks() { - return this._priv_preferredAudioTracks; + _proto.shouldRefresh = function shouldRefresh() { + return false; } /** - * Returns the current list of preferred text tracks, in preference order. - * @returns {Array.} + * We cannot check for discontinuity in SegmentTemplate-based indexes. + * @returns {null} */ ; - _proto.getPreferredTextTracks = function getPreferredTextTracks() { - return this._priv_preferredTextTracks; + _proto.checkDiscontinuity = function checkDiscontinuity() { + return null; } /** - * Returns the current list of preferred text tracks, in preference order. - * @returns {Array.} + * @returns {Boolean} */ ; - _proto.getPreferredVideoTracks = function getPreferredVideoTracks() { - return this._priv_preferredVideoTracks; + _proto.areSegmentsChronologicallyGenerated = function areSegmentsChronologicallyGenerated() { + return true; } /** - * Set the list of preferred audio tracks, in preference order. - * @param {Array.} tracks - * @param {boolean} shouldApply - `true` if those preferences should be - * applied on the currently loaded Period. `false` if it should only - * be applied to new content. + * Returns `true` if the given segment should still be available as of now + * (not removed since and still request-able). + * Returns `false` if that's not the case. + * Returns `undefined` if we do not know whether that's the case or not. + * @param {Object} segment + * @returns {boolean|undefined} */ ; - _proto.setPreferredAudioTracks = function setPreferredAudioTracks(tracks, shouldApply) { - if (shouldApply === void 0) { - shouldApply = false; - } - - if (!Array.isArray(tracks)) { - throw new Error("Invalid `setPreferredAudioTracks` argument. " + "Should have been an Array."); + _proto.isSegmentStillAvailable = function isSegmentStillAvailable(segment) { + if (segment.isInit) { + return true; } - this._priv_preferredAudioTracks = tracks; + var segmentsForTime = this.getSegments(segment.time, 0.1); - if (this._priv_trackChoiceManager !== null) { - this._priv_trackChoiceManager.setPreferredAudioTracks(tracks, shouldApply); - } else if (this._priv_mediaElementTrackChoiceManager !== null) { - this._priv_mediaElementTrackChoiceManager.setPreferredAudioTracks(tracks, shouldApply); + if (segmentsForTime.length === 0) { + return false; } + + return segmentsForTime[0].time === segment.time && segmentsForTime[0].end === segment.end && segmentsForTime[0].number === segment.number; } /** - * Set the list of preferred text tracks, in preference order. - * @param {Array.} tracks - * @param {boolean} shouldApply - `true` if those preferences should be - * applied on the currently loaded Periods. `false` if it should only - * be applied to new content. + * SegmentTemplate without a SegmentTimeline should not be updated. + * @returns {Boolean} */ ; - _proto.setPreferredTextTracks = function setPreferredTextTracks(tracks, shouldApply) { - if (shouldApply === void 0) { - shouldApply = false; - } - - if (!Array.isArray(tracks)) { - 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); - } + _proto.canBeOutOfSyncError = function canBeOutOfSyncError() { + return false; } /** - * Set the list of preferred text tracks, in preference order. - * @param {Array.} tracks - * @param {boolean} shouldApply - `true` if those preferences should be - * applied on the currently loaded Period. `false` if it should only - * be applied to new content. + * @returns {Boolean} */ ; - _proto.setPreferredVideoTracks = function setPreferredVideoTracks(tracks, shouldApply) { - if (shouldApply === void 0) { - shouldApply = false; + _proto.isFinished = function isFinished() { + if (!this._isDynamic) { + return true; } - if (!Array.isArray(tracks)) { - throw new Error("Invalid `setPreferredVideoTracks` argument. " + "Should have been an Array."); + if (this._scaledPeriodEnd === undefined) { + return false; } - this._priv_preferredVideoTracks = tracks; + var timescale = this._index.timescale; - if (this._priv_trackChoiceManager !== null) { - this._priv_trackChoiceManager.setPreferredVideoTracks(tracks, shouldApply); - } else if (this._priv_mediaElementTrackChoiceManager !== null) { - this._priv_mediaElementTrackChoiceManager.setPreferredVideoTracks(tracks, shouldApply); + var lastSegmentStart = this._getLastSegmentStart(); // As last segment start is null if live time is before + // current period, consider the index not to be finished. + + + if (lastSegmentStart == null) { + return false; } + + var lastSegmentEnd = lastSegmentStart + this._index.duration; + return isPeriodFulfilled(timescale, lastSegmentEnd, this._scaledPeriodEnd); } /** - * @returns {Array.|null} - * @deprecated + * @returns {Boolean} */ ; - _proto.getImageTrackData = function getImageTrackData() { - (0,warn_once/* default */.Z)("`getImageTrackData` is deprecated." + "Please use the `parseBifThumbnails` tool instead."); - - if (this._priv_contentInfos === null) { - return null; - } - /* eslint-disable import/no-deprecated */ - - - return this._priv_contentInfos.thumbnails; - /* eslint-enable import/no-deprecated */ + _proto.isInitialized = function isInitialized() { + return true; } /** - * Get minimum seek-able position. - * @returns {number} + * @param {Object} newIndex */ ; - _proto.getMinimumPosition = function getMinimumPosition() { - if (this._priv_contentInfos === null) { - return null; - } - - if (this._priv_contentInfos.isDirectFile) { - return 0; - } - - var manifest = this._priv_contentInfos.manifest; - - if (manifest !== null) { - return manifest.getMinimumPosition(); - } + _proto._replace = function _replace(newIndex) { + this._index = newIndex._index; + this._aggressiveMode = newIndex._aggressiveMode; + this._isDynamic = newIndex._isDynamic; + this._periodStart = newIndex._periodStart; + this._scaledPeriodEnd = newIndex._scaledPeriodEnd; + this._manifestBoundsCalculator = newIndex._manifestBoundsCalculator; + } + /** + * @param {Object} newIndex + */ + ; - return null; + _proto._update = function _update(newIndex) { + // As segments are not declared individually, as long as this Representation + // is present, we have every information we need + this._replace(newIndex); } /** - * Get maximum seek-able position. - * @returns {number} + * Returns the timescaled start of the first segment that should be available, + * relatively to the start of the Period. + * @returns {number | null | undefined} */ ; - _proto.getMaximumPosition = function getMaximumPosition() { - if (this._priv_contentInfos === null) { - return null; - } + _proto._getFirstSegmentStart = function _getFirstSegmentStart() { + if (!this._isDynamic) { + return 0; // it is the start of the Period + } // 1 - check that this index is already available - var _this$_priv_contentIn19 = this._priv_contentInfos, - isDirectFile = _this$_priv_contentIn19.isDirectFile, - manifest = _this$_priv_contentIn19.manifest; - if (isDirectFile) { - if (this.videoElement === null) { - throw new Error("Disposed player"); - } + if (this._scaledPeriodEnd === 0 || this._scaledPeriodEnd === undefined) { + // /!\ The scaled max position augments continuously and might not + // reflect exactly the real server-side value. As segments are + // generated discretely. + var maximumBound = this._manifestBoundsCalculator.estimateMaximumBound(); - return this.videoElement.duration; + if (maximumBound !== undefined && maximumBound < this._periodStart) { + // Maximum position is before this period. + // No segment is yet available here + return null; + } } - if (manifest !== null) { - return manifest.getMaximumPosition(); - } + var _this$_index = this._index, + duration = _this$_index.duration, + timescale = _this$_index.timescale; - return null; - } - /** - * /!\ For demo use only! Do not touch! - * - * Returns every chunk buffered for a given buffer type. - * Returns `null` if no SegmentBuffer was created for this type of buffer. - * @param {string} bufferType - * @returns {Array.|null} - */ - ; + var firstPosition = this._manifestBoundsCalculator.estimateMinimumBound(); - _proto.__priv_getSegmentBufferContent = function __priv_getSegmentBufferContent(bufferType) { - if (this._priv_contentInfos === null || this._priv_contentInfos.segmentBuffersStore === null) { - return null; + if (firstPosition === undefined) { + return undefined; } - var segmentBufferStatus = this._priv_contentInfos.segmentBuffersStore.getStatus(bufferType); - - return segmentBufferStatus.type === "initialized" ? segmentBufferStatus.value.getInventory() : null; + var segmentTime = firstPosition > this._periodStart ? (firstPosition - this._periodStart) * timescale : 0; + var numberIndexedToZero = Math.floor(segmentTime / duration); + return numberIndexedToZero * duration; } /** - * Reset all state properties relative to a playing content. + * Returns the timescaled start of the last segment that should be available, + * relatively to the start of the Period. + * Returns null if live time is before current period. + * @returns {number|null|undefined} */ ; - _proto._priv_cleanUpCurrentContentState = function _priv_cleanUpCurrentContentState() { - var _this4 = this; - + _proto._getLastSegmentStart = function _getLastSegmentStart() { var _a; - 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$.next(true); - - 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 = {}; // EME cleaning - - var freeUpContentLock = function freeUpContentLock() { - log/* default.debug */.Z.debug("Unlocking `contentLock`. Next content can begin."); - - _this4._priv_contentLock$.next(false); - }; + var _this$_index2 = this._index, + duration = _this$_index2.duration, + timescale = _this$_index2.timescale; - if (!(0,is_null_or_undefined/* default */.Z)(this.videoElement)) { - clearEMESession(this.videoElement).subscribe(noop/* default */.Z, function (err) { - log/* default.error */.Z.error("API: An error arised when trying to clean-up the EME session:" + (err instanceof Error ? err.toString() : "Unknown Error")); - freeUpContentLock(); - }, function () { - log/* default.debug */.Z.debug("API: EME session cleaned-up with success!"); - freeUpContentLock(); - }); - } else { - freeUpContentLock(); - } - } - /** - * Triggered each time the playback Observable emits. - * - * React to various events. - * - * @param {Object} event - payload emitted - */ - ; + if (this._isDynamic) { + var lastPos = this._manifestBoundsCalculator.estimateMaximumBound(); - _proto._priv_onPlaybackEvent = function _priv_onPlaybackEvent(event) { - switch (event.type) { - case "stream-event": - this.trigger("streamEvent", event.value); - break; + if (lastPos === undefined) { + return undefined; + } - case "stream-event-skip": - this.trigger("streamEventSkip", event.value); - break; + var agressiveModeOffset = this._aggressiveMode ? duration / timescale : 0; - case "activePeriodChanged": - this._priv_onActivePeriodChanged(event.value); + if (this._scaledPeriodEnd != null && this._scaledPeriodEnd < (lastPos + agressiveModeOffset - this._periodStart) * this._index.timescale) { + if (this._scaledPeriodEnd < duration) { + return null; + } - break; + return (Math.floor(this._scaledPeriodEnd / duration) - 1) * duration; + } // /!\ The scaled last position augments continuously and might not + // reflect exactly the real server-side value. As segments are + // generated discretely. - case "periodStreamReady": - this._priv_onPeriodStreamReady(event.value); - break; + var scaledLastPosition = (lastPos - this._periodStart) * timescale; // Maximum position is before this period. + // No segment is yet available here - case "periodStreamCleared": - this._priv_onPeriodStreamCleared(event.value); + if (scaledLastPosition < 0) { + return null; + } - break; + var availabilityTimeOffset = ((this._availabilityTimeOffset !== undefined ? this._availabilityTimeOffset : 0) + agressiveModeOffset) * timescale; + var numberOfSegmentsAvailable = Math.floor((scaledLastPosition + availabilityTimeOffset) / duration); + return numberOfSegmentsAvailable <= 0 ? null : (numberOfSegmentsAvailable - 1) * duration; + } else { + var maximumTime = (_a = this._scaledPeriodEnd) !== null && _a !== void 0 ? _a : 0; + var numberIndexedToZero = Math.ceil(maximumTime / duration) - 1; + var regularLastSegmentStart = numberIndexedToZero * duration; // In some SegmentTemplate, we could think that there is one more + // segment that there actually is due to a very little difference between + // the period's duration and a multiple of a segment's duration. + // Check that we're within a good margin - case "reloading-media-source": - this._priv_onReloadingMediaSource(); + var minimumDuration = MINIMUM_SEGMENT_SIZE * timescale; - break; + if (maximumTime - regularLastSegmentStart > minimumDuration || numberIndexedToZero === 0) { + return regularLastSegmentStart; + } - case "representationChange": - this._priv_onRepresentationChange(event.value); + return (numberIndexedToZero - 1) * duration; + } + }; - break; + return TemplateRepresentationIndex; +}(); - case "adaptationChange": - this._priv_onAdaptationChange(event.value); - break; +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/resolve_base_urls.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. + */ - case "bitrateEstimationChange": - this._priv_onBitrateEstimationChange(event.value); - break; +/** + * @param {Array.} currentBaseURLs + * @param {Array.} newBaseURLs + * @returns {Array.} + */ - case "manifestReady": - this._priv_onManifestReady(event.value); +function resolveBaseURLs(currentBaseURLs, newBaseURLs) { + var result = []; - break; + if (newBaseURLs.length === 0) { + return currentBaseURLs; + } else if (currentBaseURLs.length === 0) { + for (var i = 0; i < newBaseURLs.length; i++) { + if (!(0,array_includes/* default */.Z)(result, newBaseURLs[i].value)) { + result.push(newBaseURLs[i].value); + } + } - case "warning": - this._priv_onPlaybackWarning(event.value); + return result; + } else { + for (var _i = 0; _i < currentBaseURLs.length; _i++) { + var rootURL = currentBaseURLs[_i]; - break; + for (var j = 0; j < newBaseURLs.length; j++) { + var newURL = (0,resolve_url/* default */.Z)(rootURL, newBaseURLs[j].value); - case "loaded": - if (this._priv_contentInfos === null) { - log/* default.error */.Z.error("API: Loaded event while no content is loaded"); - return; + if (!(0,array_includes/* default */.Z)(result, newURL)) { + result.push(newURL); } + } + } + } - this._priv_contentInfos.segmentBuffersStore = event.value.segmentBuffersStore; - break; + return result; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_representation_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. + */ + // eslint-disable-next-line max-len - 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; +/** + * Parse the specific segment indexing information found in a representation + * into a IRepresentationIndex implementation. + * @param {Array.} representation + * @param {Object} representationInfos + * @returns {Array.} + */ - 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 */ +function parseRepresentationIndex(representation, representationInfos) { + var _a, _b; - this._priv_contentInfos.thumbnails = imageData; - this.trigger("imageTrackUpdate", { - data: this._priv_contentInfos.thumbnails - }); - /* eslint-enable import/no-deprecated */ - } - } + var representationBaseURLs = resolveBaseURLs(representationInfos.baseURLs, representation.children.baseURLs); + var aggressiveMode = representationInfos.aggressiveMode, + availabilityTimeOffset = representationInfos.availabilityTimeOffset, + manifestBoundsCalculator = representationInfos.manifestBoundsCalculator, + isDynamic = representationInfos.isDynamic, + periodEnd = representationInfos.end, + periodStart = representationInfos.start, + receivedTime = representationInfos.receivedTime, + timeShiftBufferDepth = representationInfos.timeShiftBufferDepth, + unsafelyBaseOnPreviousRepresentation = representationInfos.unsafelyBaseOnPreviousRepresentation, + inbandEventStreams = representationInfos.inbandEventStreams; + var isEMSGWhitelisted = function isEMSGWhitelisted(inbandEvent) { + if (inbandEventStreams === undefined) { + return false; } - } - /** - * 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 = formatError(error, { - defaultCode: "NONE", - defaultReason: "An unknown error stopped content playback." + return inbandEventStreams.some(function (_ref) { + var schemeIdUri = _ref.schemeIdUri; + return schemeIdUri === inbandEvent.schemeIdUri; }); - formattedError.fatal = true; - - this._priv_stopCurrentContent$.next(); + }; - this._priv_cleanUpCurrentContentState(); + var context = { + aggressiveMode: aggressiveMode, + availabilityTimeOffset: availabilityTimeOffset, + unsafelyBaseOnPreviousRepresentation: unsafelyBaseOnPreviousRepresentation, + isEMSGWhitelisted: isEMSGWhitelisted, + manifestBoundsCalculator: manifestBoundsCalculator, + isDynamic: isDynamic, + periodEnd: periodEnd, + periodStart: periodStart, + receivedTime: receivedTime, + representationBaseURLs: representationBaseURLs, + representationBitrate: representation.attributes.bitrate, + representationId: representation.attributes.id, + timeShiftBufferDepth: timeShiftBufferDepth + }; + var representationIndex; - this._priv_currentError = formattedError; - log/* default.error */.Z.error("API: The player stopped because of an error:", error); + if (representation.children.segmentBase !== undefined) { + var segmentBase = representation.children.segmentBase; + context.availabilityTimeOffset = representationInfos.availabilityTimeOffset + extractMinimumAvailabilityTimeOffset(representation.children.baseURLs) + ((_a = segmentBase.availabilityTimeOffset) !== null && _a !== void 0 ? _a : 0); + representationIndex = new BaseRepresentationIndex(segmentBase, context); + } else if (representation.children.segmentList !== undefined) { + var segmentList = representation.children.segmentList; + representationIndex = new ListRepresentationIndex(segmentList, context); + } else if (representation.children.segmentTemplate !== undefined || representationInfos.parentSegmentTemplates.length > 0) { + var segmentTemplates = representationInfos.parentSegmentTemplates.slice(); + var childSegmentTemplate = representation.children.segmentTemplate; - this._priv_setPlayerState(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 (childSegmentTemplate !== undefined) { + segmentTemplates.push(childSegmentTemplate); + } + var segmentTemplate = object_assign/* default.apply */.Z.apply(void 0, [{}].concat(segmentTemplates)); + context.availabilityTimeOffset = representationInfos.availabilityTimeOffset + extractMinimumAvailabilityTimeOffset(representation.children.baseURLs) + ((_b = segmentTemplate.availabilityTimeOffset) !== null && _b !== void 0 ? _b : 0); + var timelineParser = segmentTemplate.timelineParser; + representationIndex = timelineParser !== undefined ? new timeline(segmentTemplate, timelineParser, context) : new TemplateRepresentationIndex(segmentTemplate, context); + } else { + var adaptationChildren = representationInfos.adaptation.children; - if (this._priv_currentError === formattedError) { - this.trigger("error", formattedError); + if (adaptationChildren.segmentBase !== undefined) { + var _segmentBase = adaptationChildren.segmentBase; + representationIndex = new BaseRepresentationIndex(_segmentBase, context); + } else if (adaptationChildren.segmentList !== undefined) { + var _segmentList = adaptationChildren.segmentList; + representationIndex = new ListRepresentationIndex(_segmentList, context); + } else { + representationIndex = new TemplateRepresentationIndex({ + duration: Number.MAX_VALUE, + timescale: 1, + startNumber: 0, + initialization: { + media: "" + }, + media: "" + }, context); } } - /** - * Triggered when the playback Observable completes. - * Clean-up ressources and signal that the content has ended. - */ - ; - _proto._priv_onPlaybackFinished = function _priv_onPlaybackFinished() { - log/* default.info */.Z.info("API: Previous playback finished. Stopping and cleaning-up..."); + return representationIndex; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_representations.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._priv_stopCurrentContent$.next(); - this._priv_cleanUpCurrentContentState(); - this._priv_setPlayerState(PLAYER_STATES.ENDED); + +/** + * Combine inband event streams from representation and + * adaptation data. + * @param {Object} representation + * @param {Object} adaptation + * @returns {undefined | Array.} + */ + +function combineInbandEventStreams(representation, adaptation) { + var newSchemeId = []; + + if (representation.children.inbandEventStreams !== undefined) { + newSchemeId.push.apply(newSchemeId, representation.children.inbandEventStreams); } - /** - * 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 = formatError(error, { - defaultCode: "NONE", - defaultReason: "An unknown error happened." - }); - log/* default.warn */.Z.warn("API: Sending warning:", formattedError); - this.trigger("warning", formattedError); + if (adaptation.children.inbandEventStreams !== undefined) { + newSchemeId.push.apply(newSchemeId, adaptation.children.inbandEventStreams); } - /** - * Triggered when the Manifest has been loaded for the current content. - * Initialize various private properties and emit initial event. - * @param {Object} value - */ - ; - _proto._priv_onManifestReady = function _priv_onManifestReady(_ref2) { - var _this5 = this; + if (newSchemeId.length === 0) { + return undefined; + } - var manifest = _ref2.manifest; + return newSchemeId; +} +/** + * Process intermediate representations to create final parsed representations. + * @param {Array.} representationsIR + * @param {Object} adaptationInfos + * @returns {Array.} + */ - if (this._priv_contentInfos === null) { - log/* default.error */.Z.error("API: The manifest is loaded but no content is."); - return; - } - this._priv_contentInfos.manifest = manifest; - this._priv_lastContentPlaybackInfos.manifest = manifest; - var _this$_priv_contentIn20 = this._priv_contentInfos, - initialAudioTrack = _this$_priv_contentIn20.initialAudioTrack, - initialTextTrack = _this$_priv_contentIn20.initialTextTrack; - this._priv_trackChoiceManager = new TrackChoiceManager(); - var preferredAudioTracks = initialAudioTrack === undefined ? this._priv_preferredAudioTracks : [initialAudioTrack]; +function parseRepresentations(representationsIR, adaptation, adaptationInfos) { + var _a, _b; - this._priv_trackChoiceManager.setPreferredAudioTracks(preferredAudioTracks, true); + var parsedRepresentations = []; - var preferredTextTracks = initialTextTrack === undefined ? this._priv_preferredTextTracks : [initialTextTrack]; + var _loop = function _loop(reprIdx) { + var representation = representationsIR[reprIdx]; // Compute Representation ID - this._priv_trackChoiceManager.setPreferredTextTracks(preferredTextTracks, true); + var representationID = representation.attributes.id != null ? representation.attributes.id : String(representation.attributes.bitrate) + (representation.attributes.height != null ? "-" + representation.attributes.height : "") + (representation.attributes.width != null ? "-" + representation.attributes.width : "") + (representation.attributes.mimeType != null ? "-" + representation.attributes.mimeType : "") + (representation.attributes.codecs != null ? "-" + representation.attributes.codecs : ""); // Avoid duplicate IDs - this._priv_trackChoiceManager.setPreferredVideoTracks(this._priv_preferredVideoTracks, true); + while (parsedRepresentations.some(function (r) { + return r.id === representationID; + })) { + representationID += "-dup"; + } // Retrieve previous version of the Representation, if one. - (0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,takeUntil/* takeUntil */.R)(this._priv_stopCurrentContent$)).subscribe(function () { - // Update the tracks chosen if it changed - if (_this5._priv_trackChoiceManager !== null) { - _this5._priv_trackChoiceManager.update(); - } + + var unsafelyBaseOnPreviousRepresentation = (_b = (_a = adaptationInfos.unsafelyBaseOnPreviousAdaptation) === null || _a === void 0 ? void 0 : _a.getRepresentation(representationID)) !== null && _b !== void 0 ? _b : null; + var inbandEventStreams = combineInbandEventStreams(representation, adaptation); + var representationInfos = (0,object_assign/* default */.Z)({}, adaptationInfos, { + unsafelyBaseOnPreviousRepresentation: unsafelyBaseOnPreviousRepresentation, + adaptation: adaptation, + inbandEventStreams: inbandEventStreams }); - } - /** - * Triggered each times the current Period Changed. - * Store and emit initial state for the Period. - * - * @param {Object} value - */ - ; + var representationIndex = parseRepresentationIndex(representation, representationInfos); // Find bitrate - _proto._priv_onActivePeriodChanged = function _priv_onActivePeriodChanged(_ref3) { - var period = _ref3.period; + var representationBitrate = void 0; - var _a, _b, _c, _d, _e, _f; + if (representation.attributes.bitrate == null) { + log/* default.warn */.Z.warn("DASH: No usable bitrate found in the Representation."); + representationBitrate = 0; + } else { + representationBitrate = representation.attributes.bitrate; + } // Construct Representation Base - if (this._priv_contentInfos === null) { - log/* default.error */.Z.error("API: The active period changed but no content is loaded"); - return; - } - this._priv_contentInfos.currentPeriod = period; + var parsedRepresentation = { + bitrate: representationBitrate, + index: representationIndex, + id: representationID + }; // Add optional attributes - if (this._priv_contentEventsMemory.periodChange !== period) { - this._priv_contentEventsMemory.periodChange = period; - this.trigger("periodChange", period); + var codecs = void 0; + + if (representation.attributes.codecs != null) { + codecs = representation.attributes.codecs; + } else if (adaptation.attributes.codecs != null) { + codecs = adaptation.attributes.codecs; } - this.trigger("availableAudioTracksChange", this.getAvailableAudioTracks()); - this.trigger("availableTextTracksChange", this.getAvailableTextTracks()); - this.trigger("availableVideoTracksChange", this.getAvailableVideoTracks()); // Emit intial events for the Period + if (codecs != null) { + codecs = codecs === "mp4a.40.02" ? "mp4a.40.2" : codecs; + parsedRepresentation.codecs = codecs; + } - if (this._priv_trackChoiceManager !== null) { - var audioTrack = this._priv_trackChoiceManager.getChosenAudioTrack(period); + if (representation.attributes.frameRate != null) { + parsedRepresentation.frameRate = representation.attributes.frameRate; + } else if (adaptation.attributes.frameRate != null) { + parsedRepresentation.frameRate = adaptation.attributes.frameRate; + } - var textTrack = this._priv_trackChoiceManager.getChosenTextTrack(period); + if (representation.attributes.height != null) { + parsedRepresentation.height = representation.attributes.height; + } else if (adaptation.attributes.height != null) { + parsedRepresentation.height = adaptation.attributes.height; + } - var videoTrack = this._priv_trackChoiceManager.getChosenVideoTrack(period); + if (representation.attributes.mimeType != null) { + parsedRepresentation.mimeType = representation.attributes.mimeType; + } else if (adaptation.attributes.mimeType != null) { + parsedRepresentation.mimeType = adaptation.attributes.mimeType; + } - this.trigger("audioTrackChange", audioTrack); - this.trigger("textTrackChange", textTrack); - this.trigger("videoTrackChange", videoTrack); - } else { - this.trigger("audioTrackChange", null); - this.trigger("textTrackChange", null); - this.trigger("videoTrackChange", null); + if (representation.attributes.width != null) { + parsedRepresentation.width = representation.attributes.width; + } else if (adaptation.attributes.width != null) { + parsedRepresentation.width = adaptation.attributes.width; } - this._priv_triggerAvailableBitratesChangeEvent("availableAudioBitratesChange", this.getAvailableAudioBitrates()); + if (adaptation.children.contentProtections != null) { + var contentProtections = adaptation.children.contentProtections.reduce(function (acc, cp) { + var systemId; - this._priv_triggerAvailableBitratesChangeEvent("availableVideoBitratesChange", this.getAvailableVideoBitrates()); + if (cp.attributes.schemeIdUri !== undefined && cp.attributes.schemeIdUri.substring(0, 9) === "urn:uuid:") { + systemId = cp.attributes.schemeIdUri.substring(9).replace(/-/g, "").toLowerCase(); + } - 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; + if (cp.attributes.keyId !== undefined && cp.attributes.keyId.length > 0) { + acc.keyIds.push({ + keyId: cp.attributes.keyId, + systemId: systemId + }); + } - this._priv_triggerCurrentBitrateChangeEvent("audioBitrateChange", audioBitrate); + if (systemId !== undefined) { + var cencPssh = cp.children.cencPssh; + var values = []; - 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; + for (var i = 0; i < cencPssh.length; i++) { + var data = cencPssh[i]; + values.push({ + systemId: systemId, + data: data + }); + } - this._priv_triggerCurrentBitrateChangeEvent("videoBitrateChange", videoBitrate); + if (values.length > 0) { + var cencInitData = (0,array_find/* default */.Z)(acc.initData, function (i) { + return i.type === "cenc"; + }); + + if (cencInitData === undefined) { + acc.initData.push({ + type: "cenc", + values: values + }); + } else { + var _cencInitData$values; + + (_cencInitData$values = cencInitData.values).push.apply(_cencInitData$values, values); + } + } + } + + return acc; + }, { + keyIds: [], + initData: [] + }); + + if (Object.keys(contentProtections.initData).length > 0 || contentProtections.keyIds.length > 0) { + parsedRepresentation.contentProtections = contentProtections; + } + } + + parsedRepresentations.push(parsedRepresentation); + }; + + for (var reprIdx = 0; reprIdx < representationsIR.length; reprIdx++) { + _loop(reprIdx); } - /** - * Triggered each times a new "PeriodStream" is ready. - * Choose the right Adaptation for the Period and emit it. - * @param {Object} value - */ - ; - _proto._priv_onPeriodStreamReady = function _priv_onPeriodStreamReady(value) { - var type = value.type, - period = value.period, - adaptation$ = value.adaptation$; + return parsedRepresentations; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_adaptation_sets.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. + */ - switch (type) { - case "video": - if (this._priv_trackChoiceManager === null) { - log/* default.error */.Z.error("API: TrackChoiceManager not instanciated for a new video period"); - adaptation$.next(null); - } else { - this._priv_trackChoiceManager.addPeriod(type, period, adaptation$); - this._priv_trackChoiceManager.setInitialVideoTrack(period); - } - break; + // eslint-disable-next-line max-len - case "audio": - if (this._priv_trackChoiceManager === null) { - log/* default.error */.Z.error("API: TrackChoiceManager not instanciated for a new " + type + " period"); - adaptation$.next(null); - } else { - this._priv_trackChoiceManager.addPeriod(type, period, adaptation$); - this._priv_trackChoiceManager.setInitialAudioTrack(period); - } - break; - case "text": - if (this._priv_trackChoiceManager === null) { - log/* default.error */.Z.error("API: TrackChoiceManager not instanciated for a new " + type + " period"); - adaptation$.next(null); - } else { - this._priv_trackChoiceManager.addPeriod(type, period, adaptation$); - this._priv_trackChoiceManager.setInitialTextTrack(period); - } +/** + * Detect if the accessibility given defines an adaptation for the visually + * impaired. + * Based on DVB Document A168 (DVB-DASH) and DASH-IF 4.3. + * @param {Object} accessibility + * @returns {Boolean} + */ - break; +function isVisuallyImpaired(accessibility) { + if (accessibility == null) { + return false; + } - default: - var adaptations = period.adaptations[type]; + var isVisuallyImpairedAudioDvbDash = accessibility.schemeIdUri === "urn:tva:metadata:cs:AudioPurposeCS:2007" && accessibility.value === "1"; + var isVisuallyImpairedDashIf = accessibility.schemeIdUri === "urn:mpeg:dash:role:2011" && accessibility.value === "description"; + return isVisuallyImpairedAudioDvbDash || isVisuallyImpairedDashIf; +} +/** + * Detect if the accessibility given defines an adaptation for the hard of + * hearing. + * Based on DVB Document A168 (DVB-DASH). + * @param {Object} accessibility + * @returns {Boolean} + */ - if (!(0,is_null_or_undefined/* default */.Z)(adaptations) && adaptations.length > 0) { - adaptation$.next(adaptations[0]); - } else { - adaptation$.next(null); - } - break; - } +function isHardOfHearing(accessibility) { + if (accessibility == null) { + return false; } - /** - * Triggered each times we "remove" a PeriodStream. - * @param {Object} value - */ - ; - _proto._priv_onPeriodStreamCleared = function _priv_onPeriodStreamCleared(value) { - var type = value.type, - period = value.period; // Clean-up track choice from TrackChoiceManager + return accessibility.schemeIdUri === "urn:tva:metadata:cs:AudioPurposeCS:2007" && accessibility.value === "2"; +} +/** + * Detect if the accessibility given defines an AdaptationSet containing a sign + * language interpretation. + * Based on DASH-IF 4.3. + * @param {Object} accessibility + * @returns {Boolean} + */ - switch (type) { - case "audio": - case "text": - case "video": - if (this._priv_trackChoiceManager !== null) { - this._priv_trackChoiceManager.removePeriod(type, period); - } - break; - } // Clean-up stored Representation and Adaptation information +function hasSignLanguageInterpretation(accessibility) { + if (accessibility == null) { + return false; + } + return accessibility.schemeIdUri === "urn:mpeg:dash:role:2011" && accessibility.value === "sign"; +} +/** + * Contruct Adaptation ID from the information we have. + * @param {Object} adaptation + * @param {Array.} representations + * @param {Object} infos + * @returns {string} + */ - if (this._priv_contentInfos === null) { - return; - } - var _this$_priv_contentIn21 = this._priv_contentInfos, - activeAdaptations = _this$_priv_contentIn21.activeAdaptations, - activeRepresentations = _this$_priv_contentIn21.activeRepresentations; +function getAdaptationID(adaptation, infos) { + if ((0,is_non_empty_string/* default */.Z)(adaptation.attributes.id)) { + return adaptation.attributes.id; + } - 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]; + var idString = infos.type; - if (Object.keys(activePeriodAdaptations).length === 0) { - delete activeAdaptations[period.id]; - } - } + if ((0,is_non_empty_string/* default */.Z)(adaptation.attributes.language)) { + idString += "-" + adaptation.attributes.language; + } - if (!(0,is_null_or_undefined/* default */.Z)(activeRepresentations) && !(0,is_null_or_undefined/* default */.Z)(activeRepresentations[period.id])) { - var activePeriodRepresentations = activeRepresentations[period.id]; - delete activePeriodRepresentations[type]; + if (infos.isClosedCaption === true) { + idString += "-cc"; + } - if (Object.keys(activePeriodRepresentations).length === 0) { - delete activeRepresentations[period.id]; - } - } + if (infos.isAudioDescription === true) { + idString += "-ad"; } - /** - * 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 (infos.isSignInterpreted === true) { + idString += "-si"; + } - if (this._priv_trackChoiceManager !== null) { - this._priv_trackChoiceManager.resetPeriods(); - } + if ((0,is_non_empty_string/* default */.Z)(adaptation.attributes.contentType)) { + idString += "-" + adaptation.attributes.contentType; } - /** - * 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} value - */ - ; - _proto._priv_onAdaptationChange = function _priv_onAdaptationChange(_ref4) { - var type = _ref4.type, - adaptation = _ref4.adaptation, - period = _ref4.period; + if ((0,is_non_empty_string/* default */.Z)(adaptation.attributes.codecs)) { + idString += "-" + adaptation.attributes.codecs; + } - if (this._priv_contentInfos === null) { - log/* default.error */.Z.error("API: The adaptations changed but no content is loaded"); - return; - } // lazily create this._priv_contentInfos.activeAdaptations + if ((0,is_non_empty_string/* default */.Z)(adaptation.attributes.mimeType)) { + idString += "-" + adaptation.attributes.mimeType; + } + if ((0,is_non_empty_string/* default */.Z)(adaptation.attributes.frameRate)) { + idString += "-" + adaptation.attributes.frameRate; + } - if (this._priv_contentInfos.activeAdaptations === null) { - this._priv_contentInfos.activeAdaptations = {}; - } + return idString; +} +/** + * Returns a list of ID this adaptation can be seamlessly switched to + * @param {Object} adaptation + * @returns {Array.} + */ - var _this$_priv_contentIn22 = this._priv_contentInfos, - activeAdaptations = _this$_priv_contentIn22.activeAdaptations, - currentPeriod = _this$_priv_contentIn22.currentPeriod; - var activePeriodAdaptations = activeAdaptations[period.id]; - if ((0,is_null_or_undefined/* default */.Z)(activePeriodAdaptations)) { - var _activeAdaptations$pe; +function getAdaptationSetSwitchingIDs(adaptation) { + if (adaptation.children.supplementalProperties != null) { + var supplementalProperties = adaptation.children.supplementalProperties; - activeAdaptations[period.id] = (_activeAdaptations$pe = {}, _activeAdaptations$pe[type] = adaptation, _activeAdaptations$pe); - } else { - activePeriodAdaptations[type] = adaptation; + for (var j = 0; j < supplementalProperties.length; j++) { + var supplementalProperty = supplementalProperties[j]; + + if (supplementalProperty.schemeIdUri === "urn:mpeg:dash:adaptation-set-switching:2016" && supplementalProperty.value != null) { + return supplementalProperty.value.split(",").map(function (id) { + return id.trim(); + }).filter(function (id) { + return id; + }); + } } + } - if (this._priv_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); + return []; +} +/** + * Process AdaptationSets intermediate representations to return under its final + * form. + * Note that the AdaptationSets returned are sorted by priority (from the most + * priority to the least one). + * @param {Array.} adaptationsIR + * @param {Object} periodInfos + * @returns {Array.} + */ - this.trigger("audioTrackChange", audioTrack); - var availableAudioBitrates = this.getAvailableAudioBitrates(); - this._priv_triggerAvailableBitratesChangeEvent("availableAudioBitratesChange", availableAudioBitrates); +function parseAdaptationSets(adaptationsIR, periodInfos) { + var _a, _b, _c, _d; - break; + var parsedAdaptations = {}; + var adaptationSwitchingInfos = {}; + var parsedAdaptationsIDs = []; + /** + * Index of the last parsed AdaptationSet with a Role set as "main" in + * `parsedAdaptations` for a given type. + * Not defined for a type with no main Adaptation inside. + * This is used to put main AdaptationSet first in the resulting array of + * Adaptation while still preserving the MPD order among them. + */ - case "text": - var textTrack = this._priv_trackChoiceManager.getChosenTextTrack(currentPeriod); + var lastMainAdaptationIndex = {}; // first sort AdaptationSets by absolute priority. - this.trigger("textTrackChange", textTrack); - break; + adaptationsIR.sort(function (a, b) { + var _a, _b; + /* As of DASH-IF 4.3, `1` is the default value. */ - case "video": - var videoTrack = this._priv_trackChoiceManager.getChosenVideoTrack(currentPeriod); - this.trigger("videoTrackChange", videoTrack); - var availableVideoBitrates = this.getAvailableVideoBitrates(); + var priority1 = (_a = a.attributes.selectionPriority) !== null && _a !== void 0 ? _a : 1; + var priority2 = (_b = b.attributes.selectionPriority) !== null && _b !== void 0 ? _b : 1; + return priority2 - priority1; + }); - this._priv_triggerAvailableBitratesChangeEvent("availableVideoBitratesChange", availableVideoBitrates); + for (var i = 0; i < adaptationsIR.length; i++) { + var adaptation = adaptationsIR[i]; + var adaptationChildren = adaptation.children; + var essentialProperties = adaptationChildren.essentialProperties, + roles = adaptationChildren.roles; + var isExclusivelyTrickModeTrack = Array.isArray(essentialProperties) && essentialProperties.some(function (ep) { + return ep.schemeIdUri === "http://dashif.org/guidelines/trickmode"; + }); - break; - } + if (isExclusivelyTrickModeTrack) { + // We do not for the moment parse trickmode tracks + continue; } - } - /** - * Triggered each times a new Representation is considered during playback. - * - * Store given Representation and emit it if from the current Period. - * - * @param {Object} obj - */ - ; - _proto._priv_onRepresentationChange = function _priv_onRepresentationChange(_ref5) { - var type = _ref5.type, - period = _ref5.period, - representation = _ref5.representation; + var isMainAdaptation = Array.isArray(roles) && roles.some(function (role) { + return role.value === "main"; + }) && roles.some(function (role) { + return role.schemeIdUri === "urn:mpeg:dash:role:2011"; + }); + var representationsIR = adaptation.children.representations; + var availabilityTimeOffset = extractMinimumAvailabilityTimeOffset(adaptation.children.baseURLs) + periodInfos.availabilityTimeOffset; + var adaptationMimeType = adaptation.attributes.mimeType; + var adaptationCodecs = adaptation.attributes.codecs; + var type = inferAdaptationType(representationsIR, (0,is_non_empty_string/* default */.Z)(adaptationMimeType) ? adaptationMimeType : null, (0,is_non_empty_string/* default */.Z)(adaptationCodecs) ? adaptationCodecs : null, adaptationChildren.roles != null ? adaptationChildren.roles : null); - var _a; + if (type === undefined) { + continue; + } - if (this._priv_contentInfos === null) { - log/* default.error */.Z.error("API: The representations changed but no content is loaded"); - return; - } // lazily create this._priv_contentInfos.activeRepresentations + var originalID = adaptation.attributes.id; + var newID = void 0; + var adaptationSetSwitchingIDs = getAdaptationSetSwitchingIDs(adaptation); + var parentSegmentTemplates = []; + if (periodInfos.segmentTemplate !== undefined) { + parentSegmentTemplates.push(periodInfos.segmentTemplate); + } - if (this._priv_contentInfos.activeRepresentations === null) { - this._priv_contentInfos.activeRepresentations = {}; + if (adaptation.children.segmentTemplate !== undefined) { + parentSegmentTemplates.push(adaptation.children.segmentTemplate); } - var _this$_priv_contentIn23 = this._priv_contentInfos, - activeRepresentations = _this$_priv_contentIn23.activeRepresentations, - currentPeriod = _this$_priv_contentIn23.currentPeriod; - var activePeriodRepresentations = activeRepresentations[period.id]; + var adaptationInfos = { + aggressiveMode: periodInfos.aggressiveMode, + availabilityTimeOffset: availabilityTimeOffset, + baseURLs: resolveBaseURLs(periodInfos.baseURLs, adaptationChildren.baseURLs), + manifestBoundsCalculator: periodInfos.manifestBoundsCalculator, + end: periodInfos.end, + isDynamic: periodInfos.isDynamic, + parentSegmentTemplates: parentSegmentTemplates, + receivedTime: periodInfos.receivedTime, + start: periodInfos.start, + timeShiftBufferDepth: periodInfos.timeShiftBufferDepth, + unsafelyBaseOnPreviousAdaptation: null + }; - if ((0,is_null_or_undefined/* default */.Z)(activePeriodRepresentations)) { - var _activeRepresentation; + if (type === "video" && isMainAdaptation && parsedAdaptations.video !== undefined && parsedAdaptations.video.length > 0 && lastMainAdaptationIndex.video !== undefined) { + var _videoMainAdaptation$; - activeRepresentations[period.id] = (_activeRepresentation = {}, _activeRepresentation[type] = representation, _activeRepresentation); + // Add to the already existing main video adaptation + // TODO remove that ugly custom logic? + var videoMainAdaptation = parsedAdaptations.video[lastMainAdaptationIndex.video]; + adaptationInfos.unsafelyBaseOnPreviousAdaptation = (_b = (_a = periodInfos.unsafelyBaseOnPreviousPeriod) === null || _a === void 0 ? void 0 : _a.getAdaptation(videoMainAdaptation.id)) !== null && _b !== void 0 ? _b : null; + var representations = parseRepresentations(representationsIR, adaptation, adaptationInfos); + + (_videoMainAdaptation$ = videoMainAdaptation.representations).push.apply(_videoMainAdaptation$, representations); + + newID = videoMainAdaptation.id; } else { - activePeriodRepresentations[type] = representation; - } + var accessibilities = adaptationChildren.accessibilities; + var isDub = void 0; - var bitrate = (_a = representation === null || representation === void 0 ? void 0 : representation.bitrate) !== null && _a !== void 0 ? _a : -1; + if (roles !== undefined && roles.some(function (role) { + return role.value === "dub"; + })) { + isDub = true; + } - if (!(0,is_null_or_undefined/* default */.Z)(period) && currentPeriod !== null && currentPeriod.id === period.id) { - if (type === "video") { - this._priv_triggerCurrentBitrateChangeEvent("videoBitrateChange", bitrate); - } else if (type === "audio") { - this._priv_triggerCurrentBitrateChangeEvent("audioBitrateChange", bitrate); + var isClosedCaption = void 0; + + if (type !== "text") { + isClosedCaption = false; + } else if (accessibilities !== undefined) { + isClosedCaption = accessibilities.some(isHardOfHearing); } - } - } - /** - * Triggered each time a bitrate estimate is calculated. - * - * Emit it. - * - * @param {Object} value - */ - ; - _proto._priv_onBitrateEstimationChange = function _priv_onBitrateEstimationChange(_ref6) { - var type = _ref6.type, - bitrate = _ref6.bitrate; + var isAudioDescription = void 0; - if (bitrate !== undefined) { - this._priv_bitrateInfos.lastBitrates[type] = bitrate; - } + if (type !== "audio") { + isAudioDescription = false; + } else if (accessibilities !== undefined) { + isAudioDescription = accessibilities.some(isVisuallyImpaired); + } - this.trigger("bitrateEstimationChange", { - type: type, - bitrate: bitrate - }); - } - /** - * Triggered each time the videoElement alternates between play and pause. - * - * Emit the info through the right Subject. - * - * @param {Boolean} isPlaying - */ - ; + var isSignInterpreted = void 0; - _proto._priv_onPlayPauseNext = function _priv_onPlayPauseNext(isPlaying) { - if (this.videoElement === null) { - throw new Error("Disposed player"); - } + if (type !== "video") { + isSignInterpreted = false; + } else if (accessibilities !== undefined) { + isSignInterpreted = accessibilities.some(hasSignLanguageInterpretation); + } - this._priv_playing$.next(isPlaying); - } - /** - * Triggered each time a textTrack is added to the video DOM Element. - * - * Trigger the right Player Event. - * - * @param {Array.} tracks - */ - ; + var adaptationID = getAdaptationID(adaptation, { + isAudioDescription: isAudioDescription, + isClosedCaption: isClosedCaption, + isSignInterpreted: isSignInterpreted, + type: type + }); // Avoid duplicate IDs - _proto._priv_onNativeTextTracksNext = function _priv_onNativeTextTracksNext(tracks) { - this.trigger("nativeTextTracksChange", tracks); - } - /** - * Triggered each time the player state updates. - * - * Trigger the right Player Event. - * - * @param {string} newState - */ - ; + while ((0,array_includes/* default */.Z)(parsedAdaptationsIDs, adaptationID)) { + adaptationID += "-dup"; + } - _proto._priv_setPlayerState = function _priv_setPlayerState(newState) { - if (this.state !== newState) { - this.state = newState; - log/* default.info */.Z.info("API: playerStateChange event", newState); - this.trigger("playerStateChange", newState); - } - } - /** - * Triggered each time a new clock tick object is emitted. - * - * Trigger the right Player Event - * - * @param {Object} clockTick - */ - ; + newID = adaptationID; + parsedAdaptationsIDs.push(adaptationID); + adaptationInfos.unsafelyBaseOnPreviousAdaptation = (_d = (_c = periodInfos.unsafelyBaseOnPreviousPeriod) === null || _c === void 0 ? void 0 : _c.getAdaptation(adaptationID)) !== null && _d !== void 0 ? _d : null; - _proto._priv_triggerPositionUpdate = function _priv_triggerPositionUpdate(clockTick) { - var _a; + var _representations = parseRepresentations(representationsIR, adaptation, adaptationInfos); - if (this._priv_contentInfos === null) { - log/* default.warn */.Z.warn("API: Cannot perform time update: no content loaded."); - return; - } + var parsedAdaptationSet = { + id: adaptationID, + representations: _representations, + type: type + }; - if (this.state === PLAYER_STATES.RELOADING) { - return; - } + if (adaptation.attributes.language != null) { + parsedAdaptationSet.language = adaptation.attributes.language; + } - var _this$_priv_contentIn24 = this._priv_contentInfos, - isDirectFile = _this$_priv_contentIn24.isDirectFile, - manifest = _this$_priv_contentIn24.manifest; + if (isClosedCaption != null) { + parsedAdaptationSet.closedCaption = isClosedCaption; + } - if (!isDirectFile && manifest === null || (0,is_null_or_undefined/* default */.Z)(clockTick)) { - return; - } + if (isAudioDescription != null) { + parsedAdaptationSet.audioDescription = isAudioDescription; + } - this._priv_lastContentPlaybackInfos.lastPlaybackPosition = clockTick.position; - var maximumPosition = manifest !== null ? manifest.getMaximumPosition() : undefined; - var positionData = { - position: clockTick.position, - duration: clockTick.duration, - playbackRate: clockTick.playbackRate, - maximumBufferTime: maximumPosition, - // TODO fix higher up? - bufferGap: isFinite(clockTick.bufferGap) ? clockTick.bufferGap : 0 - }; + if (isDub === true) { + parsedAdaptationSet.isDub = true; + } - if (manifest !== null && maximumPosition !== undefined && manifest.isLive && clockTick.position > 0) { - var ast = (_a = manifest.availabilityStartTime) !== null && _a !== void 0 ? _a : 0; - positionData.wallClockTime = clockTick.position + ast; - positionData.liveGap = maximumPosition - clockTick.position; - } + if (isSignInterpreted === true) { + parsedAdaptationSet.isSignInterpreted = true; + } - this.trigger("positionUpdate", positionData); - } - /** - * Trigger one of the "availableBitratesChange" event only if it changed from - * the previously stored value. - * @param {string} event - * @param {Array.} newVal - */ - ; + var adaptationsOfTheSameType = parsedAdaptations[type]; - _proto._priv_triggerAvailableBitratesChangeEvent = function _priv_triggerAvailableBitratesChangeEvent(event, newVal) { - var prevVal = this._priv_contentEventsMemory[event]; + if (adaptationsOfTheSameType === undefined) { + parsedAdaptations[type] = [parsedAdaptationSet]; - if (prevVal === undefined || (0,are_arrays_of_numbers_equal/* default */.Z)(newVal, prevVal)) { - this._priv_contentEventsMemory[event] = newVal; - this.trigger(event, newVal); - } - } - /** - * Trigger one of the "bitrateChange" event only if it changed from the - * previously stored value. - * @param {string} event - * @param {number} newVal - */ - ; + if (isMainAdaptation) { + lastMainAdaptationIndex[type] = 0; + } + } else { + var mergedInto = null; // look if we have to merge this into another Adaptation - _proto._priv_triggerCurrentBitrateChangeEvent = function _priv_triggerCurrentBitrateChangeEvent(event, newVal) { - if (newVal !== this._priv_contentEventsMemory[event]) { - this._priv_contentEventsMemory[event] = newVal; - this.trigger(event, newVal); - } - }; + var _loop = function _loop(k) { + var id = adaptationSetSwitchingIDs[k]; + var switchingInfos = adaptationSwitchingInfos[id]; - _proto._priv_getCurrentRepresentations = function _priv_getCurrentRepresentations() { - if (this._priv_contentInfos === null) { - return null; - } + if (switchingInfos != null && switchingInfos.newID !== newID && (0,array_includes/* default */.Z)(switchingInfos.adaptationSetSwitchingIDs, originalID)) { + var adaptationToMergeInto = (0,array_find/* default */.Z)(adaptationsOfTheSameType, function (a) { + return a.id === id; + }); - var _this$_priv_contentIn25 = this._priv_contentInfos, - currentPeriod = _this$_priv_contentIn25.currentPeriod, - activeRepresentations = _this$_priv_contentIn25.activeRepresentations; + if (adaptationToMergeInto != null && adaptationToMergeInto.audioDescription === parsedAdaptationSet.audioDescription && adaptationToMergeInto.closedCaption === parsedAdaptationSet.closedCaption && adaptationToMergeInto.language === parsedAdaptationSet.language) { + var _adaptationToMergeInt; - if (currentPeriod === null || activeRepresentations === null || (0,is_null_or_undefined/* default */.Z)(activeRepresentations[currentPeriod.id])) { - return null; - } + log/* default.info */.Z.info("DASH Parser: merging \"switchable\" AdaptationSets", originalID, id); - return activeRepresentations[currentPeriod.id]; - }; + (_adaptationToMergeInt = adaptationToMergeInto.representations).push.apply(_adaptationToMergeInt, parsedAdaptationSet.representations); - createClass_default()(Player, null, [{ - key: "ErrorTypes", - get: function get() { - return error_codes/* ErrorTypes */.ZB; - } - /** All possible Error codes emitted by the RxPlayer. */ + mergedInto = adaptationToMergeInto; + } + } + }; - }, { - key: "ErrorCodes", - get: function get() { - return error_codes/* ErrorCodes */.SM; - } - /** - * Current log level. - * Update current log level. - * Should be either (by verbosity ascending): - * - "NONE" - * - "ERROR" - * - "WARNING" - * - "INFO" - * - "DEBUG" - * Any other value will be translated to "NONE". - */ + for (var k = 0; k < adaptationSetSwitchingIDs.length; k++) { + _loop(k); + } - }, { - key: "LogLevel", - get: function get() { - return log/* default.getLevel */.Z.getLevel(); - }, - set: function set(logLevel) { - log/* default.setLevel */.Z.setLevel(logLevel); + if (isMainAdaptation) { + var oldLastMainIdx = lastMainAdaptationIndex[type]; + var newLastMainIdx = oldLastMainIdx === undefined ? 0 : oldLastMainIdx + 1; + + if (mergedInto === null) { + // put "main" Adaptation after all other Main Adaptations + adaptationsOfTheSameType.splice(newLastMainIdx, 0, parsedAdaptationSet); + lastMainAdaptationIndex[type] = newLastMainIdx; + } else { + var indexOf = adaptationsOfTheSameType.indexOf(mergedInto); + + if (indexOf < 0) { + // Weird, not found + adaptationsOfTheSameType.splice(newLastMainIdx, 0, parsedAdaptationSet); + lastMainAdaptationIndex[type] = newLastMainIdx; + } else if (oldLastMainIdx === undefined || indexOf > oldLastMainIdx) { + // Found but was not main + adaptationsOfTheSameType.splice(indexOf, 1); + adaptationsOfTheSameType.splice(newLastMainIdx, 0, mergedInto); + lastMainAdaptationIndex[type] = newLastMainIdx; + } + } + } else if (mergedInto === null) { + adaptationsOfTheSameType.push(parsedAdaptationSet); + } + } } - }]); - return Player; -}(event_emitter/* default */.Z); + if (originalID != null && adaptationSwitchingInfos[originalID] == null) { + adaptationSwitchingInfos[originalID] = { + newID: newID, + adaptationSetSwitchingIDs: adaptationSetSwitchingIDs + }; + } + } -Player.version = -/* PLAYER_VERSION */ -"3.23.1"; -/* harmony default export */ const public_api = (Player); -;// CONCATENATED MODULE: ./src/core/api/index.ts + return parsedAdaptations; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_periods.ts /** * Copyright 2015 CANAL+ Group * @@ -28364,165 +27232,253 @@ Player.version = * limitations under the License. */ -/* harmony default export */ const api = (public_api); -// EXTERNAL MODULE: ./src/features/features_object.ts -var features_object = __webpack_require__(7273); -;// CONCATENATED MODULE: ./src/features/initialize_features.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. - */ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ + // eslint-disable-next-line max-len -/* eslint-disable @typescript-eslint/no-var-requires */ -/** - * Selects the features to include based on environment variables. - * - * @param {Object} features - */ -function initializeFeaturesObject() { - if (true) { - features_object/* default.emeManager */.Z.emeManager = __webpack_require__(8745)/* .default */ .ZP; - } - if (true) { - features_object/* default.imageBuffer */.Z.imageBuffer = __webpack_require__(7127)/* .default */ .Z; - features_object/* default.imageParser */.Z.imageParser = __webpack_require__(3203)/* .default */ .Z; - } // Feature switching the Native TextTrack implementation - var HAS_NATIVE_MODE = true || 0; - if (true) { - features_object/* default.transports.smooth */.Z.transports.smooth = __webpack_require__(2339)/* .default */ .Z; - } +var generatePeriodID = (0,id_generator/* default */.Z)(); +/** + * Process intermediate periods to create final parsed periods. + * @param {Array.} periodsIR + * @param {Object} contextInfos + * @returns {Array.} + */ - if (true) { - features_object/* default.transports.dash */.Z.transports.dash = __webpack_require__(1459)/* .default */ .Z; +function parsePeriods(periodsIR, contextInfos) { + var _a, _b, _c; + + var parsedPeriods = []; + var periodsTimeInformation = getPeriodsTimeInformation(periodsIR, contextInfos); + + if (periodsTimeInformation.length !== periodsIR.length) { + throw new Error("MPD parsing error: the time information are incoherent."); } - if (false) {} + var isDynamic = contextInfos.isDynamic, + timeShiftBufferDepth = contextInfos.timeShiftBufferDepth; + var manifestBoundsCalculator = new ManifestBoundsCalculator({ + isDynamic: isDynamic, + timeShiftBufferDepth: timeShiftBufferDepth + }); - if (false) {} + if (!isDynamic && contextInfos.duration != null) { + manifestBoundsCalculator.setLastPosition(contextInfos.duration); + } // We parse it in reverse because we might need to deduce the buffer depth from + // the last Periods' indexes - 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; - } + var _loop = function _loop(i) { + var periodIR = periodsIR[i]; + var xlinkInfos = contextInfos.xlinkInfos.get(periodIR); + var periodBaseURLs = resolveBaseURLs(contextInfos.baseURLs, periodIR.children.baseURLs); + var _periodsTimeInformati = periodsTimeInformation[i], + periodStart = _periodsTimeInformati.periodStart, + periodDuration = _periodsTimeInformati.periodDuration, + periodEnd = _periodsTimeInformati.periodEnd; + var periodID = void 0; - if (true) { - features_object/* default.nativeTextTracksParsers.ttml */.Z.nativeTextTracksParsers.ttml = __webpack_require__(1570)/* .default */ .Z; - } + if (periodIR.attributes.id == null) { + log/* default.warn */.Z.warn("DASH: No usable id found in the Period. Generating one."); + periodID = "gen-dash-period-" + generatePeriodID(); + } else { + periodID = periodIR.attributes.id; + } // Avoid duplicate IDs - if (true) { - features_object/* default.nativeTextTracksParsers.sami */.Z.nativeTextTracksParsers.sami = __webpack_require__(1812)/* .default */ .Z; - } - if (true) { - features_object/* default.nativeTextTracksParsers.srt */.Z.nativeTextTracksParsers.srt = __webpack_require__(8057)/* .default */ .Z; + while (parsedPeriods.some(function (p) { + return p.id === periodID; + })) { + periodID += "-dup"; } - } // Feature switching the HTML TextTrack implementation + var receivedTime = xlinkInfos !== undefined ? xlinkInfos.receivedTime : contextInfos.receivedTime; + var availabilityTimeOffset = extractMinimumAvailabilityTimeOffset(periodIR.children.baseURLs) + contextInfos.availabilityTimeOffset; + var unsafelyBaseOnPreviousPeriod = (_b = (_a = contextInfos.unsafelyBaseOnPreviousManifest) === null || _a === void 0 ? void 0 : _a.getPeriod(periodID)) !== null && _b !== void 0 ? _b : null; + var periodInfos = { + aggressiveMode: contextInfos.aggressiveMode, + availabilityTimeOffset: availabilityTimeOffset, + baseURLs: periodBaseURLs, + manifestBoundsCalculator: manifestBoundsCalculator, + end: periodEnd, + isDynamic: isDynamic, + receivedTime: receivedTime, + segmentTemplate: periodIR.children.segmentTemplate, + start: periodStart, + timeShiftBufferDepth: timeShiftBufferDepth, + unsafelyBaseOnPreviousPeriod: unsafelyBaseOnPreviousPeriod + }; + var adaptations = parseAdaptationSets(periodIR.children.adaptations, periodInfos); + var streamEvents = (_c = periodIR.children.streamEvents) === null || _c === void 0 ? void 0 : _c.map(function (event) { + var _a; - var HAS_HTML_MODE = true || 0; + var start = ((_a = event.eventPresentationTime) !== null && _a !== void 0 ? _a : 0) / event.timescale + periodStart; + var end = event.duration !== undefined ? start + event.duration / event.timescale : undefined; + return { + start: start, + end: end, + data: event.data, + id: event.id + }; + }); + var parsedPeriod = { + id: periodID, + start: periodStart, + end: periodEnd, + duration: periodDuration, + adaptations: adaptations, + streamEvents: streamEvents + }; + parsedPeriods.unshift(parsedPeriod); - if (HAS_HTML_MODE) { - features_object/* default.htmlTextTracksBuffer */.Z.htmlTextTracksBuffer = __webpack_require__(5192)/* .default */ .Z; + if (!manifestBoundsCalculator.lastPositionIsKnown()) { + var _lastPosition = getMaximumLastPosition(adaptations); - if (true) { - features_object/* default.htmlTextTracksParsers.sami */.Z.htmlTextTracksParsers.sami = __webpack_require__(5734)/* .default */ .Z; - } + if (!isDynamic) { + if (typeof _lastPosition === "number") { + manifestBoundsCalculator.setLastPosition(_lastPosition); + } + } else { + if (typeof _lastPosition === "number") { + var _positionTime = performance.now() / 1000; - if (true) { - features_object/* default.htmlTextTracksParsers.ttml */.Z.htmlTextTracksParsers.ttml = __webpack_require__(7439)/* .default */ .Z; - } + manifestBoundsCalculator.setLastPosition(_lastPosition, _positionTime); + } else { + var _guessedLastPositionFromClock = guessLastPositionFromClock(contextInfos, periodStart); - if (true) { - features_object/* default.htmlTextTracksParsers.srt */.Z.htmlTextTracksParsers.srt = __webpack_require__(8675)/* .default */ .Z; + if (_guessedLastPositionFromClock !== undefined) { + var guessedLastPosition = _guessedLastPositionFromClock[0], + guessedPositionTime = _guessedLastPositionFromClock[1]; + manifestBoundsCalculator.setLastPosition(guessedLastPosition, guessedPositionTime); + } + } + } } + }; - if (true) { - features_object/* default.htmlTextTracksParsers.vtt */.Z.htmlTextTracksParsers.vtt = __webpack_require__(4099)/* .default */ .Z; - } + for (var i = periodsIR.length - 1; i >= 0; i--) { + _loop(i); } - if (true) { - var initDirectFile = __webpack_require__(8969)/* .default */ .Z; - - var mediaElementTrackChoiceManager = __webpack_require__(7794)/* .default */ .Z; + if (contextInfos.isDynamic && !manifestBoundsCalculator.lastPositionIsKnown()) { + // Guess a last time the last position + var guessedLastPositionFromClock = guessLastPositionFromClock(contextInfos, 0); - features_object/* default.directfile */.Z.directfile = { - initDirectFile: initDirectFile, - mediaElementTrackChoiceManager: mediaElementTrackChoiceManager - }; + if (guessedLastPositionFromClock !== undefined) { + var lastPosition = guessedLastPositionFromClock[0], + positionTime = guessedLastPositionFromClock[1]; + manifestBoundsCalculator.setLastPosition(lastPosition, positionTime); + } } + + return flattenOverlappingPeriods(parsedPeriods); } -;// CONCATENATED MODULE: ./src/index.ts /** - * Copyright 2015 CANAL+ Group + * Try to guess the "last position", which is the last position + * available in the manifest in seconds, and the "position time", the time + * (`performance.now()`) in which the last position was collected. * - * 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 + * These values allows to retrieve at any time in the future the new last + * position, by substracting the position time to the last position, and + * adding to it the new value returned by `performance.now`. * - * http://www.apache.org/licenses/LICENSE-2.0 + * The last position and position time are returned by this function if and only if + * it would indicate a last position superior to the `minimumTime` given. * - * 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 file exports a Player class with a default feature set (depends on the - * environment variables set at build). + * This last part allows for example to detect which Period is likely to be the + * "current" one in multi-periods contents. By giving the Period's start as a + * `minimumTime`, you ensure that you will get a value only if the current time + * is in that period. * - * This is the class used from a regular build. + * This is useful as guessing the live time from the clock can be seen as a last + * resort. By detecting that the current time is before the currently considered + * Period, we can just parse and look at the previous Period. If we can guess + * the live time more directly from that previous one, we might be better off + * than just using the clock. + * + * @param {Object} contextInfos + * @param {number} minimumTime + * @returns {Array.} */ +function guessLastPositionFromClock(contextInfos, minimumTime) { + if (contextInfos.clockOffset != null) { + var lastPosition = contextInfos.clockOffset / 1000 - contextInfos.availabilityStartTime; + var positionTime = performance.now() / 1000; + var timeInSec = positionTime + lastPosition; - // set initial features according to environment variables + if (timeInSec >= minimumTime) { + return [timeInSec, positionTime]; + } + } else { + var now = Date.now() / 1000; -initializeFeaturesObject(); + if (now >= minimumTime) { + log/* default.warn */.Z.warn("DASH Parser: no clock synchronization mechanism found." + " Using the system clock instead."); -if (false) {} + var _lastPosition2 = now - contextInfos.availabilityStartTime; -/* harmony default export */ const src = (api); + var _positionTime2 = performance.now() / 1000; -/***/ }), + return [_lastPosition2, _positionTime2]; + } + } -/***/ 3887: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + return undefined; +} +/** + * Try to extract the last position declared for any segments in a Period: + * - If at least a single index' last position is defined, take the maximum + * among them. + * - If segments are available but we cannot define the last position + * return undefined. + * - If no segment are available in that period, return null + * @param {Object} adaptationsPerType + * @returns {number|null|undefined} + */ -"use strict"; -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ log -}); +function getMaximumLastPosition(adaptationsPerType) { + var maxEncounteredPosition = null; + var allIndexAreEmpty = true; + var adaptationsVal = (0,object_values/* default */.Z)(adaptationsPerType).filter(function (ada) { + return ada != null; + }); + var allAdaptations = (0,flat_map/* default */.Z)(adaptationsVal, function (adaptationsForType) { + return adaptationsForType; + }); -// EXTERNAL MODULE: ./src/utils/noop.ts -var noop = __webpack_require__(8894); -;// CONCATENATED MODULE: ./src/utils/logger.ts + for (var adapIndex = 0; adapIndex < allAdaptations.length; adapIndex++) { + var representations = allAdaptations[adapIndex].representations; + + for (var repIndex = 0; repIndex < representations.length; repIndex++) { + var representation = representations[repIndex]; + var position = representation.index.getLastPosition(); + + if (position !== null) { + allIndexAreEmpty = false; + + if (typeof position === "number") { + maxEncounteredPosition = maxEncounteredPosition == null ? position : Math.max(maxEncounteredPosition, position); + } + } + } + } + + if (maxEncounteredPosition != null) { + return maxEncounteredPosition; + } else if (allIndexAreEmpty) { + return null; + } + + return undefined; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_mpd.ts /** * Copyright 2015 CANAL+ Group * @@ -28539,166 +27495,290 @@ var noop = __webpack_require__(8894); * limitations under the License. */ -var DEFAULT_LOG_LEVEL = "NONE"; + + + // eslint-disable-next-line max-len + + + + + + + + + + +var DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0 = config/* default.DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0 */.Z.DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0; /** - * Logger implementation. - * @class Logger + * @param {Element} root - The MPD root. + * @param {Object} args + * @returns {Object} */ -var Logger = /*#__PURE__*/function () { - function Logger() { - this.error = noop/* default */.Z; - this.warn = noop/* default */.Z; - this.info = noop/* default */.Z; - this.debug = noop/* default */.Z; - this._levels = { - NONE: 0, - ERROR: 1, - WARNING: 2, - INFO: 3, - DEBUG: 4 - }; - this._currentLevel = DEFAULT_LOG_LEVEL; - } - /** - * @param {string} levelStr - */ +function parseMPD(root, args) { + // Transform whole MPD into a parsed JS object representation + var _createMPDIntermediat = createMPDIntermediateRepresentation(root), + mpdIR = _createMPDIntermediat[0], + warnings = _createMPDIntermediat[1]; + return loadExternalRessourcesAndParse(mpdIR, args, warnings); +} +/** + * Checks if xlinks needs to be loaded before actually parsing the manifest. + * @param {Object} mpdIR + * @param {Object} args + * @param {Array.} warnings + * @returns {Object} + */ - var _proto = Logger.prototype; +function loadExternalRessourcesAndParse(mpdIR, args, warnings, hasLoadedClock) { + var rootChildren = mpdIR.children, + rootAttributes = mpdIR.attributes; + var xlinkInfos = new WeakMap(); - _proto.setLevel = function setLevel(levelStr) { - var level; - var foundLevel = this._levels[levelStr]; + if (args.externalClockOffset == null) { + var isDynamic = rootAttributes.type === "dynamic"; + var directTiming = (0,array_find/* default */.Z)(rootChildren.utcTimings, function (utcTiming) { + return utcTiming.schemeIdUri === "urn:mpeg:dash:utc:direct:2014" && utcTiming.value != null; + }); + var clockOffsetFromDirectUTCTiming = directTiming != null && directTiming.value != null ? getClockOffset(directTiming.value) : undefined; + var clockOffset = clockOffsetFromDirectUTCTiming != null && !isNaN(clockOffsetFromDirectUTCTiming) ? clockOffsetFromDirectUTCTiming : undefined; - if (typeof foundLevel === "number") { - level = foundLevel; - this._currentLevel = levelStr; - } else { - // not found - level = 0; - this._currentLevel = "NONE"; + if (clockOffset != null) { + args.externalClockOffset = clockOffset; + } else if (isDynamic && hasLoadedClock !== true) { + var UTCTimingHTTPURL = getHTTPUTCTimingURL(mpdIR); + + if (UTCTimingHTTPURL != null && UTCTimingHTTPURL.length > 0) { + // TODO fetch UTCTiming and XLinks at the same time + return { + type: "needs-ressources", + value: { + ressources: [UTCTimingHTTPURL], + "continue": function continueParsingMPD(loadedRessources) { + if (loadedRessources.length !== 1) { + throw new Error("DASH parser: wrong number of loaded ressources."); + } + + clockOffset = getClockOffset(loadedRessources[0].responseData); + args.externalClockOffset = clockOffset; + return loadExternalRessourcesAndParse(mpdIR, args, warnings, true); + } + } + }; + } } - /* eslint-disable no-invalid-this */ + } - /* eslint-disable no-console */ + var xlinksToLoad = []; + for (var i = 0; i < rootChildren.periods.length; i++) { + var _rootChildren$periods = rootChildren.periods[i].attributes, + xlinkHref = _rootChildren$periods.xlinkHref, + xlinkActuate = _rootChildren$periods.xlinkActuate; - this.error = level >= this._levels.ERROR ? console.error.bind(console) : noop/* default */.Z; - this.warn = level >= this._levels.WARNING ? console.warn.bind(console) : noop/* default */.Z; - this.info = level >= this._levels.INFO ? console.info.bind(console) : noop/* default */.Z; - this.debug = level >= this._levels.DEBUG ? console.log.bind(console) : noop/* default */.Z; - /* eslint-enable no-console */ + if (xlinkHref != null && xlinkActuate === "onLoad") { + xlinksToLoad.push({ + index: i, + ressource: xlinkHref + }); + } + } - /* eslint-enable no-invalid-this */ + if (xlinksToLoad.length === 0) { + return parseCompleteIntermediateRepresentation(mpdIR, args, warnings, xlinkInfos); } - /** - * @returns {string} - */ - ; - _proto.getLevel = function getLevel() { - return this._currentLevel; - }; + return { + type: "needs-ressources", + value: { + ressources: xlinksToLoad.map(function (_ref) { + var ressource = _ref.ressource; + return ressource; + }), + "continue": function continueParsingMPD(loadedRessources) { + if (loadedRessources.length !== xlinksToLoad.length) { + throw new Error("DASH parser: wrong number of loaded ressources."); + } // Note: It is important to go from the last index to the first index in + // the resulting array, as we will potentially add elements to the array - return Logger; -}(); + for (var _i = loadedRessources.length - 1; _i >= 0; _i--) { + var _rootChildren$periods2; -;// CONCATENATED MODULE: ./src/log.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 a logger specifically for the RxPlayer. + var index = xlinksToLoad[_i].index; + var _loadedRessources$_i = loadedRessources[_i], + xlinkData = _loadedRessources$_i.responseData, + receivedTime = _loadedRessources$_i.receivedTime, + sendingTime = _loadedRessources$_i.sendingTime, + url = _loadedRessources$_i.url; + var wrappedData = "" + xlinkData + ""; + var dataAsXML = new DOMParser().parseFromString(wrappedData, "text/xml"); -var logger = new Logger(); -/* harmony default export */ const log = (logger); + if (dataAsXML == null || dataAsXML.children.length === 0) { + throw new Error("DASH parser: Invalid external ressources"); + } -/***/ }), + var periods = dataAsXML.children[0].children; + var periodsIR = []; -/***/ 5952: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + for (var j = 0; j < periods.length; j++) { + if (periods[j].nodeType === Node.ELEMENT_NODE) { + var _createPeriodIntermed = createPeriodIntermediateRepresentation(periods[j]), + periodIR = _createPeriodIntermed[0], + periodWarnings = _createPeriodIntermed[1]; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ areSameContent -/* harmony export */ }); -/** - * 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. - */ + xlinkInfos.set(periodIR, { + receivedTime: receivedTime, + sendingTime: sendingTime, + url: url + }); + periodsIR.push(periodIR); + + if (periodWarnings.length > 0) { + warnings.push.apply(warnings, periodWarnings); + } + } + } // replace original "xlinked" periods by the real deal + + + (_rootChildren$periods2 = rootChildren.periods).splice.apply(_rootChildren$periods2, [index, 1].concat(periodsIR)); + } + return loadExternalRessourcesAndParse(mpdIR, args, warnings); + } + } + }; +} /** - * Check if two contents are the same - * @param {Object} content1 - * @param {Object} content2 - * @returns {boolean} + * Parse the MPD intermediate representation into a regular Manifest. + * @param {Object} mpdIR + * @param {Object} args + * @param {Array.} warnings + * @param {Object} xlinkInfos + * @returns {Object} */ -function areSameContent(content1, content2) { - return content1.segment.id === content2.segment.id && content1.representation.id === content2.representation.id && content1.adaptation.id === content2.adaptation.id && content1.period.id === content2.period.id; -} -/***/ }), -/***/ 1966: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +function parseCompleteIntermediateRepresentation(mpdIR, args, warnings, xlinkInfos) { + var _a, _b; -"use strict"; + var rootChildren = mpdIR.children, + rootAttributes = mpdIR.attributes; + var isDynamic = rootAttributes.type === "dynamic"; + var baseURLs = resolveBaseURLs(args.url === undefined ? [] : [(0,resolve_url/* normalizeBaseURL */.f)(args.url)], rootChildren.baseURLs); + var availabilityStartTime = parseAvailabilityStartTime(rootAttributes, args.referenceDateTime); + var timeShiftBufferDepth = rootAttributes.timeShiftBufferDepth; + var clockOffset = args.externalClockOffset, + unsafelyBaseOnPreviousManifest = args.unsafelyBaseOnPreviousManifest; + var availabilityTimeOffset = extractMinimumAvailabilityTimeOffset(rootChildren.baseURLs); + var manifestInfos = { + aggressiveMode: args.aggressiveMode, + availabilityStartTime: availabilityStartTime, + availabilityTimeOffset: availabilityTimeOffset, + baseURLs: baseURLs, + clockOffset: clockOffset, + duration: rootAttributes.duration, + isDynamic: isDynamic, + receivedTime: args.manifestReceivedTime, + timeShiftBufferDepth: timeShiftBufferDepth, + unsafelyBaseOnPreviousManifest: unsafelyBaseOnPreviousManifest, + xlinkInfos: xlinkInfos + }; + var parsedPeriods = parsePeriods(rootChildren.periods, manifestInfos); + var mediaPresentationDuration = rootAttributes.duration; + var lifetime; + var minimumTime; + var timeshiftDepth = null; + var maximumTimeData; -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "ZP": () => /* binding */ manifest -}); + if (rootAttributes.minimumUpdatePeriod !== undefined && rootAttributes.minimumUpdatePeriod >= 0) { + lifetime = rootAttributes.minimumUpdatePeriod === 0 ? DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0 : rootAttributes.minimumUpdatePeriod; + } -// UNUSED EXPORTS: Adaptation, Period, Representation, SUPPORTED_ADAPTATIONS_TYPE, StaticRepresentationIndex, areSameContent + var _getMinimumAndMaximum = getMinimumAndMaximumPosition(parsedPeriods), + contentStart = _getMinimumAndMaximum[0], + contentEnd = _getMinimumAndMaximum[1]; -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/inheritsLoose.js -var inheritsLoose = __webpack_require__(5354); -var inheritsLoose_default = /*#__PURE__*/__webpack_require__.n(inheritsLoose); -// EXTERNAL MODULE: ./src/utils/are_arrays_of_numbers_equal.ts -var are_arrays_of_numbers_equal = __webpack_require__(4791); -// EXTERNAL MODULE: ./src/utils/array_find.ts -var array_find = __webpack_require__(3274); -// 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/warn_once.ts -var warn_once = __webpack_require__(8806); -// EXTERNAL MODULE: ./src/errors/media_error.ts -var media_error = __webpack_require__(3714); -// EXTERNAL MODULE: ./src/log.ts + 1 modules -var log = __webpack_require__(3887); -// EXTERNAL MODULE: ./src/utils/array_includes.ts -var array_includes = __webpack_require__(7714); -// EXTERNAL MODULE: ./src/utils/is_null_or_undefined.ts -var is_null_or_undefined = __webpack_require__(1946); -// EXTERNAL MODULE: ./src/utils/languages/index.ts -var languages = __webpack_require__(7829); -;// CONCATENATED MODULE: ./src/utils/uniq.ts + var now = performance.now(); + + if (!isDynamic) { + minimumTime = contentStart !== undefined ? contentStart : ((_a = parsedPeriods[0]) === null || _a === void 0 ? void 0 : _a.start) !== undefined ? parsedPeriods[0].start : 0; + var maximumTime; + + if (contentEnd !== undefined) { + maximumTime = contentEnd; + } else if (mediaPresentationDuration !== undefined) { + maximumTime = mediaPresentationDuration; + } else if (parsedPeriods[parsedPeriods.length - 1] !== undefined) { + var lastPeriod = parsedPeriods[parsedPeriods.length - 1]; + maximumTime = (_b = lastPeriod.end) !== null && _b !== void 0 ? _b : lastPeriod.duration !== undefined ? lastPeriod.start + lastPeriod.duration : undefined; + } + + maximumTimeData = { + isLinear: false, + value: maximumTime !== null && maximumTime !== void 0 ? maximumTime : Infinity, + time: now + }; + } else { + minimumTime = contentStart; + timeshiftDepth = timeShiftBufferDepth !== null && timeShiftBufferDepth !== void 0 ? timeShiftBufferDepth : null; + + var _maximumTime; + + if (contentEnd !== undefined) { + _maximumTime = contentEnd; + } else { + var ast = availabilityStartTime !== null && availabilityStartTime !== void 0 ? availabilityStartTime : 0; + var externalClockOffset = args.externalClockOffset; + + if (externalClockOffset === undefined) { + log/* default.warn */.Z.warn("DASH Parser: use system clock to define maximum position"); + _maximumTime = Date.now() / 1000 - ast; + } else { + var serverTime = performance.now() + externalClockOffset; + _maximumTime = serverTime / 1000 - ast; + } + } + + maximumTimeData = { + isLinear: true, + value: _maximumTime, + time: now + }; // if the minimum calculated time is even below the buffer depth, perhaps we + // can go even lower in terms of depth + + if (timeshiftDepth !== null && minimumTime !== undefined && _maximumTime - minimumTime > timeshiftDepth) { + timeshiftDepth = _maximumTime - minimumTime; + } + } + + var parsedMPD = { + availabilityStartTime: availabilityStartTime, + clockOffset: args.externalClockOffset, + isDynamic: isDynamic, + isLive: isDynamic, + periods: parsedPeriods, + publishTime: rootAttributes.publishTime, + suggestedPresentationDelay: rootAttributes.suggestedPresentationDelay, + transportType: "dash", + timeBounds: { + absoluteMinimumTime: minimumTime, + timeshiftDepth: timeshiftDepth, + maximumTimeData: maximumTimeData + }, + lifetime: lifetime, + uris: args.url == null ? rootChildren.locations : [args.url].concat(rootChildren.locations) + }; + return { + type: "done", + value: { + parsed: parsedMPD, + warnings: warnings + } + }; +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_from_document.ts /** * Copyright 2015 CANAL+ Group * @@ -28716,39 +27796,21 @@ var languages = __webpack_require__(7829); */ /** - * Uniq implementation by combining a filter and an indexOf. - * @param {Array.<*>} arr - * @returns {Array.<*>} - */ -function uniqFromFilter(arr) { - return arr.filter(function (val, i, self) { - return self.indexOf(val) === i; - }); -} -/** - * Uniq implementation by using the Set browser API. - * @param {Array.<*>} arr - * @returns {Array.<*>} - */ - - -function uniqFromSet(arr) { - return Array.from(new Set(arr)); -} -/** - * Returns the input array without duplicates values. - * All values are unique. - * @param {Array.<*>} arr - * @returns {Array.<*>} + * @param {Document} manifest - Original manifest as returned by the server + * @param {Object} args + * @returns {Object} - parsed manifest */ +function parseFromDocument(document, args) { + var root = document.documentElement; -/* harmony default export */ const uniq = (typeof window !== "undefined" && // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -typeof window.Set === "function" && typeof Array.from === "function" ? uniqFromSet : uniqFromFilter); + if (root == null || root.nodeName !== "MPD") { + throw new Error("DASH Parser: document root should be MPD"); + } -// EXTERNAL MODULE: ./src/compat/browser_compatibility_types.ts -var browser_compatibility_types = __webpack_require__(3774); -;// CONCATENATED MODULE: ./src/compat/is_codec_supported.ts + return parseMPD(root, args); +} +;// CONCATENATED MODULE: ./src/parsers/manifest/dash/index.ts /** * Copyright 2015 CANAL+ Group * @@ -28765,33 +27827,12 @@ var browser_compatibility_types = __webpack_require__(3774); * limitations under the License. */ -/** - * Returns true if the given codec is supported by the browser's MediaSource - * implementation. - * @param {string} mimeType - The MIME media type that you want to test support - * for in the current browser. - * This may include the codecs parameter to provide added details about the - * codecs used within the file. - * @returns {Boolean} - */ - -function isCodecSupported(mimeType) { - if (browser_compatibility_types/* MediaSource_ */.JJ == null) { - return false; - } - /* eslint-disable @typescript-eslint/unbound-method */ - - if (typeof browser_compatibility_types/* MediaSource_.isTypeSupported */.JJ.isTypeSupported === "function") { - /* eslint-enable @typescript-eslint/unbound-method */ - return browser_compatibility_types/* MediaSource_.isTypeSupported */.JJ.isTypeSupported(mimeType); - } +/* harmony default export */ const dash = (parseFromDocument); - return true; -} -// EXTERNAL MODULE: ./src/utils/byte_parsing.ts -var byte_parsing = __webpack_require__(6968); -;// CONCATENATED MODULE: ./src/manifest/representation.ts +// EXTERNAL MODULE: ./src/transports/utils/return_parsed_manifest.ts +var return_parsed_manifest = __webpack_require__(7445); +;// CONCATENATED MODULE: ./src/transports/dash/manifest_parser.ts /** * Copyright 2015 CANAL+ Group * @@ -28811,143 +27852,152 @@ var byte_parsing = __webpack_require__(6968); -/** - * Normalized Representation structure. - * @class Representation - */ -var Representation = /*#__PURE__*/function () { - /** - * @param {Object} args - */ - function Representation(args, opts) { - this.id = args.id; - this.bitrate = args.bitrate; - this.codec = args.codecs; - if (args.height != null) { - this.height = args.height; - } - if (args.width != null) { - this.width = args.width; - } +/** + * Request external "xlink" ressource from a MPD. + * @param {string} xlinkURL + * @returns {Observable} + */ - if (args.mimeType != null) { - this.mimeType = args.mimeType; - } - - if (args.contentProtections !== undefined) { - this.contentProtections = args.contentProtections; - } - - if (args.frameRate != null) { - this.frameRate = args.frameRate; - } +function requestStringResource(url) { + return (0,request/* default */.ZP)({ + url: url, + responseType: "text" + }).pipe((0,filter/* filter */.h)(function (e) { + return e.type === "data-loaded"; + }), (0,map/* map */.U)(function (e) { + return e.value; + })); +} +/** + * @param {Object} options + * @returns {Function} + */ - this.index = args.index; - this.isSupported = opts.type === "audio" || opts.type === "video" ? isCodecSupported(this.getMimeTypeString()) : true; // TODO for other types - } - /** - * Returns "mime-type string" which includes both the mime-type and the codec, - * which is often needed when interacting with the browser's APIs. - * @returns {string} - */ +function generateManifestParser(options) { + var aggressiveMode = options.aggressiveMode, + referenceDateTime = options.referenceDateTime; + var serverTimeOffset = options.serverSyncInfos !== undefined ? options.serverSyncInfos.serverTimestamp - options.serverSyncInfos.clientTime : undefined; + return function manifestParser(args) { + var _a; - var _proto = Representation.prototype; + var response = args.response, + scheduleRequest = args.scheduleRequest; + var argClockOffset = args.externalClockOffset; + var loaderURL = args.url; + var url = (_a = response.url) !== null && _a !== void 0 ? _a : loaderURL; + var data = typeof response.responseData === "string" ? new DOMParser().parseFromString(response.responseData, "text/xml") : // TODO find a way to check if Document? + response.responseData; + var externalClockOffset = serverTimeOffset !== null && serverTimeOffset !== void 0 ? serverTimeOffset : argClockOffset; + var unsafelyBaseOnPreviousManifest = args.unsafeMode ? args.previousManifest : null; + var parsedManifest = dash(data, { + aggressiveMode: aggressiveMode === true, + unsafelyBaseOnPreviousManifest: unsafelyBaseOnPreviousManifest, + url: url, + referenceDateTime: referenceDateTime, + externalClockOffset: externalClockOffset + }); + return loadExternalResources(parsedManifest); - _proto.getMimeTypeString = function getMimeTypeString() { - var _a, _b; + function loadExternalResources(parserResponse) { + if (parserResponse.type === "done") { + var _parserResponse$value = parserResponse.value, + warnings = _parserResponse$value.warnings, + parsed = _parserResponse$value.parsed; + var warningEvents = warnings.map(function (warning) { + return { + type: "warning", + value: warning + }; + }); + var manifest = new src_manifest/* default */.ZP(parsed, options); + return (0,concat/* concat */.z)(of.of.apply(void 0, warningEvents), (0,return_parsed_manifest/* default */.Z)(manifest, url)); + } - return ((_a = this.mimeType) !== null && _a !== void 0 ? _a : "") + ";codecs=\"" + ((_b = this.codec) !== null && _b !== void 0 ? _b : "") + "\""; - } - /** - * Returns every protection initialization data concatenated. - * This data can then be used through the usual EME APIs. - * `null` if this Representation has no detected protection initialization - * data. - * @returns {Array.|null} - */ - ; + var _parserResponse$value2 = parserResponse.value, + ressources = _parserResponse$value2.ressources, + continueParsing = _parserResponse$value2["continue"]; + var externalResources$ = ressources.map(function (resource) { + return scheduleRequest(function () { + return requestStringResource(resource); + }); + }); + return (0,combineLatest/* combineLatest */.aj)(externalResources$).pipe((0,mergeMap/* mergeMap */.zg)(function (loadedResources) { + var resources = []; - _proto.getProtectionsInitializationData = function getProtectionsInitializationData() { - var contentProtections = this.contentProtections; + for (var i = 0; i < loadedResources.length; i++) { + var resource = loadedResources[i]; - if (contentProtections === undefined) { - return []; - } + if (typeof resource.responseData !== "string") { + throw new Error("External DASH resources should only be strings"); + } // Normally not needed but TypeScript is just dumb here - return Object.keys(contentProtections.initData).reduce(function (acc, initDataType) { - var initDataArr = contentProtections.initData[initDataType]; - if (initDataArr === undefined || initDataArr.length === 0) { - return acc; - } + resources.push((0,object_assign/* default */.Z)(resource, { + responseData: resource.responseData + })); + } - var initData = byte_parsing/* concat.apply */.zo.apply(void 0, initDataArr.map(function (_ref) { - var data = _ref.data; - return data; + return loadExternalResources(continueParsing(resources)); })); - acc.push({ - type: initDataType, - data: initData - }); - return acc; - }, []); - } - /** - * Add protection data to the Representation to be able to properly blacklist - * it if that data is. - * /!\ Mutates the current Representation - * @param {string} initDataArr - * @param {string} systemId - * @param {Uint8Array} data - */ - ; - - _proto._addProtectionData = function _addProtectionData(initDataType, systemId, data) { - var newElement = { - systemId: systemId, - data: data - }; - - if (this.contentProtections === undefined) { - var _initData; - - this.contentProtections = { - keyIds: [], - initData: (_initData = {}, _initData[initDataType] = [newElement], _initData) - }; - return; } + }; +} +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules +var Observable = __webpack_require__(4379); +;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } - var initDataArr = this.contentProtections.initData[initDataType]; + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } +} - if (initDataArr === undefined) { - this.contentProtections.initData[initDataType] = [newElement]; - return; - } +function _asyncToGenerator(fn) { + return function () { + var self = this, + args = arguments; + return new Promise(function (resolve, reject) { + var gen = fn.apply(self, args); - for (var i = initDataArr.length - 1; i >= 0; i--) { - if (initDataArr[i].systemId === systemId) { - if ((0,are_arrays_of_numbers_equal/* default */.Z)(initDataArr[i].data, data)) { - return; - } + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); + } - log/* default.warn */.Z.warn("Manifest: Two PSSH for the same system ID"); + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } - } - initDataArr.push(newElement); + _next(undefined); + }); }; +} +// EXTERNAL MODULE: ./node_modules/@babel/runtime/regenerator/index.js +var regenerator = __webpack_require__(7757); +var regenerator_default = /*#__PURE__*/__webpack_require__.n(regenerator); +// EXTERNAL MODULE: ./src/errors/request_error.ts +var request_error = __webpack_require__(9105); +// EXTERNAL MODULE: ./src/errors/error_codes.ts +var error_codes = __webpack_require__(5992); +// EXTERNAL MODULE: ./src/utils/is_null_or_undefined.ts +var is_null_or_undefined = __webpack_require__(1946); +;// CONCATENATED MODULE: ./src/utils/request/fetch.ts - return Representation; -}(); -/* harmony default export */ const manifest_representation = (Representation); -;// CONCATENATED MODULE: ./src/manifest/adaptation.ts -/** + +/* * Copyright 2015 CANAL+ Group * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28967,182 +28017,188 @@ var Representation = /*#__PURE__*/function () { +var DEFAULT_REQUEST_TIMEOUT = config/* default.DEFAULT_REQUEST_TIMEOUT */.Z.DEFAULT_REQUEST_TIMEOUT; +var _Headers = typeof Headers === "function" ? Headers : null; +var _AbortController = typeof AbortController === "function" ? AbortController : null; -/** List in an array every possible value for the Adaptation's `type` property. */ - -var SUPPORTED_ADAPTATIONS_TYPE = ["audio", "video", "text", "image"]; -/** - * Returns true if the given Adaptation's `type` is a valid `type` property. - * @param {string} adaptationType - * @returns {boolean} - */ - -function isSupportedAdaptationType(adaptationType) { - return (0,array_includes/* default */.Z)(SUPPORTED_ADAPTATIONS_TYPE, adaptationType); -} -/** - * Normalized Adaptation structure. - * An Adaptation describes a single `Track`. For example a specific audio - * track (in a given language) or a specific video track. - * It istelf can be represented in different qualities, which we call here - * `Representation`. - * @class Adaptation - */ - - -var Adaptation = /*#__PURE__*/function () { - /** - * @constructor - * @param {Object} parsedAdaptation - * @param {Object|undefined} [options] - */ - function Adaptation(parsedAdaptation, options) { - if (options === void 0) { - options = {}; - } - - var _options = options, - representationFilter = _options.representationFilter, - isManuallyAdded = _options.isManuallyAdded; - this.parsingErrors = []; - this.id = parsedAdaptation.id; - - if (!isSupportedAdaptationType(parsedAdaptation.type)) { - log/* default.info */.Z.info("Manifest: Not supported adaptation type", parsedAdaptation.type); - /* eslint-disable @typescript-eslint/restrict-template-expressions */ - - throw new media_error/* default */.Z("MANIFEST_UNSUPPORTED_ADAPTATION_TYPE", "\"" + parsedAdaptation.type + "\" is not a valid " + "Adaptation type."); - /* eslint-enable @typescript-eslint/restrict-template-expressions */ - } - - this.type = parsedAdaptation.type; +function fetchRequest(options) { + var headers; - if (parsedAdaptation.language !== undefined) { - this.language = parsedAdaptation.language; - this.normalizedLanguage = (0,languages/* default */.ZP)(parsedAdaptation.language); - } + if (!(0,is_null_or_undefined/* default */.Z)(options.headers)) { + if ((0,is_null_or_undefined/* default */.Z)(_Headers)) { + headers = options.headers; + } else { + headers = new _Headers(); + var headerNames = Object.keys(options.headers); - if (parsedAdaptation.closedCaption !== undefined) { - this.isClosedCaption = parsedAdaptation.closedCaption; + for (var i = 0; i < headerNames.length; i++) { + var headerName = headerNames[i]; + headers.append(headerName, options.headers[headerName]); + } } + } - if (parsedAdaptation.audioDescription !== undefined) { - this.isAudioDescription = parsedAdaptation.audioDescription; - } + return new Observable/* Observable */.y(function (obs) { + log/* default.debug */.Z.debug("Fetch: Called with URL", options.url); + var hasAborted = false; + var timeouted = false; + var isDone = false; + var sendingTime = performance.now(); + var abortController = !(0,is_null_or_undefined/* default */.Z)(_AbortController) ? new _AbortController() : null; + /** + * Abort current fetchRequest by triggering AbortController signal. + * @returns {void} + */ - if (parsedAdaptation.isDub !== undefined) { - this.isDub = parsedAdaptation.isDub; - } + function abortRequest() { + if (!isDone) { + if (!(0,is_null_or_undefined/* default */.Z)(abortController)) { + abortController.abort(); + return; + } - if (parsedAdaptation.isSignInterpreted !== undefined) { - this.isSignInterpreted = parsedAdaptation.isSignInterpreted; + log/* default.warn */.Z.warn("Fetch: AbortController API not available."); + } } - var argsRepresentations = parsedAdaptation.representations; - var representations = []; - var decipherable = false; - var isSupported = false; - - for (var i = 0; i < argsRepresentations.length; i++) { - var representation = new manifest_representation(argsRepresentations[i], { - type: this.type - }); - var shouldAdd = (0,is_null_or_undefined/* default */.Z)(representationFilter) || representationFilter(representation, { - bufferType: this.type, - language: this.language, - normalizedLanguage: this.normalizedLanguage, - isClosedCaption: this.isClosedCaption, - isDub: this.isDub, - isAudioDescription: this.isAudioDescription, - isSignInterpreted: this.isSignInterpreted - }); - - if (shouldAdd) { - representations.push(representation); + var requestTimeout = (0,is_null_or_undefined/* default */.Z)(options.timeout) ? DEFAULT_REQUEST_TIMEOUT : options.timeout; + var timeout = window.setTimeout(function () { + timeouted = true; + abortRequest(); + }, requestTimeout); + fetch(options.url, { + headers: headers, + method: "GET", + signal: !(0,is_null_or_undefined/* default */.Z)(abortController) ? abortController.signal : undefined + }).then(function (response) { + if (!(0,is_null_or_undefined/* default */.Z)(timeout)) { + clearTimeout(timeout); + } - if (decipherable === false && representation.decipherable !== false) { - decipherable = representation.decipherable; - } + if (response.status >= 300) { + log/* default.warn */.Z.warn("Fetch: Request HTTP Error", response); + obs.error(new request_error/* default */.Z(response.url, response.status, error_codes/* NetworkErrorTypes.ERROR_HTTP_CODE */.br.ERROR_HTTP_CODE)); + return undefined; + } - if (!isSupported && representation.isSupported) { - isSupported = true; - } + if ((0,is_null_or_undefined/* default */.Z)(response.body)) { + obs.error(new request_error/* default */.Z(response.url, response.status, error_codes/* NetworkErrorTypes.PARSE_ERROR */.br.PARSE_ERROR)); + return undefined; } - } - representations.sort(function (a, b) { - return a.bitrate - b.bitrate; - }); - this.representations = representations; - this.decipherable = decipherable; - this.isSupported = isSupported; // for manuallyAdded adaptations (not in the manifest) + var contentLengthHeader = response.headers.get("Content-Length"); + var contentLength = !(0,is_null_or_undefined/* default */.Z)(contentLengthHeader) && !isNaN(+contentLengthHeader) ? +contentLengthHeader : undefined; + var reader = response.body.getReader(); + var size = 0; + return readBufferAndSendEvents(); - this.manuallyAdded = isManuallyAdded === true; + function readBufferAndSendEvents() { + return _readBufferAndSendEvents.apply(this, arguments); + } - if (this.representations.length > 0 && !isSupported) { - log/* default.warn */.Z.warn("Incompatible codecs for adaptation", parsedAdaptation); - var error = new media_error/* default */.Z("MANIFEST_INCOMPATIBLE_CODECS_ERROR", "An Adaptation contains only incompatible codecs."); - this.parsingErrors.push(error); - } - } - /** - * Returns unique bitrate for every Representation in this Adaptation. - * @returns {Array.} - */ + function _readBufferAndSendEvents() { + _readBufferAndSendEvents = _asyncToGenerator( /*#__PURE__*/regenerator_default().mark(function _callee() { + var data, currentTime, dataChunk, receivedTime, duration; + return regenerator_default().wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return reader.read(); + case 2: + data = _context.sent; - var _proto = Adaptation.prototype; + if (!(!data.done && !(0,is_null_or_undefined/* default */.Z)(data.value))) { + _context.next = 11; + break; + } - _proto.getAvailableBitrates = function getAvailableBitrates() { - var bitrates = []; + size += data.value.byteLength; + currentTime = performance.now(); + dataChunk = { + type: "data-chunk", + value: { + url: response.url, + currentTime: currentTime, + duration: currentTime - sendingTime, + sendingTime: sendingTime, + chunkSize: data.value.byteLength, + chunk: data.value.buffer, + size: size, + totalSize: contentLength + } + }; + obs.next(dataChunk); + return _context.abrupt("return", readBufferAndSendEvents()); - for (var i = 0; i < this.representations.length; i++) { - var representation = this.representations[i]; + case 11: + if (data.done) { + receivedTime = performance.now(); + duration = receivedTime - sendingTime; + isDone = true; + obs.next({ + type: "data-complete", + value: { + duration: duration, + receivedTime: receivedTime, + sendingTime: sendingTime, + size: size, + status: response.status, + url: response.url + } + }); + obs.complete(); + } - if (representation.decipherable !== false) { - bitrates.push(representation.bitrate); + case 12: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + return _readBufferAndSendEvents.apply(this, arguments); + } + })["catch"](function (err) { + if (hasAborted) { + log/* default.debug */.Z.debug("Fetch: Request aborted."); + return; } - } - - return uniq(bitrates); - } - /** - * Returns all Representation in this Adaptation that can be played (that is: - * not undecipherable and with a supported codec). - * @returns {Array.} - */ - ; - _proto.getPlayableRepresentations = function getPlayableRepresentations() { - return this.representations.filter(function (rep) { - return rep.isSupported && rep.decipherable !== false; - }); - } - /** - * Returns the Representation linked to the given ID. - * @param {number|string} wantedId - * @returns {Object|undefined} - */ - ; + if (timeouted) { + log/* default.warn */.Z.warn("Fetch: Request timeouted."); + obs.error(new request_error/* default */.Z(options.url, 0, error_codes/* NetworkErrorTypes.TIMEOUT */.br.TIMEOUT)); + return; + } - _proto.getRepresentation = function getRepresentation(wantedId) { - return (0,array_find/* default */.Z)(this.representations, function (_ref) { - var id = _ref.id; - return wantedId === id; + log/* default.warn */.Z.warn("Fetch: Request Error", err instanceof Error ? err.toString() : ""); + obs.error(new request_error/* default */.Z(options.url, 0, error_codes/* NetworkErrorTypes.ERROR_EVENT */.br.ERROR_EVENT)); + return; }); - }; - - return Adaptation; -}(); + return function () { + hasAborted = true; + abortRequest(); + }; + }); +} +/** + * Returns true if fetch should be supported in the current browser. + * @return {boolean} + */ -// EXTERNAL MODULE: ./src/errors/is_known_error.ts -var is_known_error = __webpack_require__(9822); -// EXTERNAL MODULE: ./src/utils/object_values.ts -var object_values = __webpack_require__(1679); -;// CONCATENATED MODULE: ./src/manifest/period.ts +function fetchIsSupported() { + return typeof window.fetch === "function" && !(0,is_null_or_undefined/* default */.Z)(_AbortController) && !(0,is_null_or_undefined/* default */.Z)(_Headers); +} +/* harmony default export */ const request_fetch = (fetchRequest); +// EXTERNAL MODULE: ./src/utils/warn_once.ts +var warn_once = __webpack_require__(8806); +// EXTERNAL MODULE: ./src/transports/utils/byte_range.ts +var byte_range = __webpack_require__(281); +;// CONCATENATED MODULE: ./src/transports/utils/is_webm_embedded_track.ts /** * Copyright 2015 CANAL+ Group * @@ -29159,150 +28215,48 @@ var object_values = __webpack_require__(1679); * limitations under the License. */ - - - /** - * Class representing the tracks and qualities available from a given time - * period in the the Manifest. - * @class Period + * @param {Object} representation + * @returns {boolean} + */ +function isWEBMEmbeddedTrack(representation) { + return representation.mimeType === "video/webm" || representation.mimeType === "audio/webm"; +} +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/tap.js +var tap = __webpack_require__(3068); +// EXTERNAL MODULE: ./src/transports/utils/check_isobmff_integrity.ts +var check_isobmff_integrity = __webpack_require__(4460); +;// CONCATENATED MODULE: ./src/transports/dash/add_segment_integrity_checks_to_loader.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 Period = /*#__PURE__*/function () { - /** - * @constructor - * @param {Object} args - * @param {function|undefined} [representationFilter] - */ - function Period(args, representationFilter) { - var _this = this; - - this.parsingErrors = []; - this.id = args.id; - this.adaptations = Object.keys(args.adaptations).reduce(function (acc, type) { - var adaptationsForType = args.adaptations[type]; - - if (adaptationsForType == null) { - return acc; - } - - var filteredAdaptations = adaptationsForType.map(function (adaptation) { - var _this$parsingErrors; - - var newAdaptation = null; - - try { - newAdaptation = new Adaptation(adaptation, { - representationFilter: representationFilter - }); - } catch (err) { - if ((0,is_known_error/* default */.Z)(err) && err.code === "MANIFEST_UNSUPPORTED_ADAPTATION_TYPE") { - _this.parsingErrors.push(err); - - return null; - } - - throw err; - } - - (_this$parsingErrors = _this.parsingErrors).push.apply(_this$parsingErrors, newAdaptation.parsingErrors); - - return newAdaptation; - }).filter(function (adaptation) { - return adaptation !== null && adaptation.representations.length > 0; - }); - if (filteredAdaptations.every(function (adaptation) { - return !adaptation.isSupported; - }) && adaptationsForType.length > 0 && (type === "video" || type === "audio")) { - throw new media_error/* default */.Z("MANIFEST_PARSE_ERROR", "No supported " + type + " adaptations"); - } - if (filteredAdaptations.length > 0) { - acc[type] = filteredAdaptations; +function addSegmentIntegrityChecks(segmentLoader) { + return function (content) { + return segmentLoader(content).pipe((0,tap/* tap */.b)(function (res) { + if ((res.type === "data-loaded" || res.type === "data-chunk") && res.value.responseData !== null && typeof res.value.responseData !== "string" && !isWEBMEmbeddedTrack(content.representation)) { + (0,check_isobmff_integrity/* default */.Z)(new Uint8Array(res.value.responseData), content.segment.isInit); } - - return acc; - }, {}); - - if (!Array.isArray(this.adaptations.video) && !Array.isArray(this.adaptations.audio)) { - throw new media_error/* default */.Z("MANIFEST_PARSE_ERROR", "No supported audio and video tracks."); - } - - this.duration = args.duration; - this.start = args.start; - - if (this.duration != null && this.start != null) { - this.end = this.start + this.duration; - } - - this.streamEvents = args.streamEvents === undefined ? [] : args.streamEvents; - } - /** - * Returns every `Adaptations` (or `tracks`) linked to that Period, in an - * Array. - * @returns {Array.} - */ - - - var _proto = Period.prototype; - - _proto.getAdaptations = function getAdaptations() { - var adaptationsByType = this.adaptations; - return (0,object_values/* default */.Z)(adaptationsByType).reduce( // Note: the second case cannot happen. TS is just being dumb here - function (acc, adaptations) { - return adaptations != null ? acc.concat(adaptations) : acc; - }, []); - } - /** - * Returns every `Adaptations` (or `tracks`) linked to that Period for a - * given type. - * @param {string} adaptationType - * @returns {Array.} - */ - ; - - _proto.getAdaptationsForType = function getAdaptationsForType(adaptationType) { - var adaptationsForType = this.adaptations[adaptationType]; - return adaptationsForType == null ? [] : adaptationsForType; - } - /** - * Returns the Adaptation linked to the given ID. - * @param {number|string} wantedId - * @returns {Object|undefined} - */ - ; - - _proto.getAdaptation = function getAdaptation(wantedId) { - return (0,array_find/* default */.Z)(this.getAdaptations(), function (_ref) { - var id = _ref.id; - return wantedId === id; - }); - }; - - _proto.getPlayableAdaptations = function getPlayableAdaptations(type) { - if (type === undefined) { - return this.getAdaptations().filter(function (ada) { - return ada.isSupported && ada.decipherable !== false; - }); - } - - var adaptationsForType = this.adaptations[type]; - - if (adaptationsForType === undefined) { - return []; - } - - return adaptationsForType.filter(function (ada) { - return ada.isSupported && ada.decipherable !== false; - }); + })); }; - - return Period; -}(); - - -;// CONCATENATED MODULE: ./src/manifest/representation_index/static.ts +} +// EXTERNAL MODULE: ./src/utils/byte_parsing.ts +var byte_parsing = __webpack_require__(6968); +;// CONCATENATED MODULE: ./src/transports/dash/init_segment_loader.ts /** * Copyright 2015 CANAL+ Group * @@ -29319,138 +28273,90 @@ var Period = /*#__PURE__*/function () { * limitations under the License. */ -/** - * Simple RepresentationIndex implementation for static files. - * @class StaticRepresentationIndex - */ - -var StaticRepresentationIndex = /*#__PURE__*/function () { - /** - * @param {Object} infos - */ - function StaticRepresentationIndex(infos) { - this._mediaURLs = infos.media; - } - /** - * Static contents do not have any initialization segments. - * Just return null. - * @returns {null} - */ - - - var _proto = StaticRepresentationIndex.prototype; - - _proto.getInitSegment = function getInitSegment() { - return null; - } - /** - * Returns the only Segment available here. - * @returns {Array.} - */ - ; - _proto.getSegments = function getSegments() { - return [{ - id: "0", - isInit: false, - number: 0, - mediaURLs: [this._mediaURLs], - time: 0, - end: Number.MAX_VALUE, - duration: Number.MAX_VALUE, - timescale: 1 - }]; - } - /** - * Returns first position in index. - * @returns {undefined} - */ - ; - _proto.getFirstPosition = function getFirstPosition() { - return; - } - /** - * Returns last position in index. - * @returns {undefined} - */ - ; - _proto.getLastPosition = function getLastPosition() { - return; - } - /** - * Returns false as a static file never need to be refreshed. - * @returns {Boolean} - */ - ; - _proto.shouldRefresh = function shouldRefresh() { - return false; - } - /** - * @returns {null} - */ - ; +/** + * Perform a request for an initialization segment, agnostic to the container. + * @param {string} url + * @param {Object} content + */ - _proto.checkDiscontinuity = function checkDiscontinuity() { - return null; - } - /** - * @returns {boolean} - */ - ; +function initSegmentLoader(url, _ref) { + var segment = _ref.segment; - _proto.areSegmentsChronologicallyGenerated = function areSegmentsChronologicallyGenerated() { - return true; + if (segment.range === undefined) { + return (0,request/* default */.ZP)({ + url: url, + responseType: "arraybuffer", + sendProgressEvents: true + }); } - /** - * Returns true as a static file should never need lose availability. - * @returns {Boolean} - */ - ; - _proto.isSegmentStillAvailable = function isSegmentStillAvailable() { - return true; - } - /** - * @returns {Boolean} - */ - ; + if (segment.indexRange === undefined) { + return (0,request/* default */.ZP)({ + url: url, + headers: { + Range: (0,byte_range/* default */.Z)(segment.range) + }, + responseType: "arraybuffer", + sendProgressEvents: true + }); + } // range and indexRange are contiguous (99% of the cases) - _proto.canBeOutOfSyncError = function canBeOutOfSyncError() { - return false; - } - /** - * @returns {Boolean} - */ - ; - _proto.isFinished = function isFinished() { - return true; + if (segment.range[1] + 1 === segment.indexRange[0]) { + return (0,request/* default */.ZP)({ + url: url, + headers: { + Range: (0,byte_range/* default */.Z)([segment.range[0], segment.indexRange[1]]) + }, + responseType: "arraybuffer", + sendProgressEvents: true + }); } - /** - * @returns {Boolean} - */ - ; - - _proto.isInitialized = function isInitialized() { - return true; - }; - - _proto._replace = function _replace() { - log/* default.warn */.Z.warn("Tried to replace a static RepresentationIndex"); - }; - - _proto._update = function _update() { - log/* default.warn */.Z.warn("Tried to update a static RepresentationIndex"); - }; - - return StaticRepresentationIndex; -}(); - -;// CONCATENATED MODULE: ./src/manifest/types.ts + var rangeRequest$ = (0,request/* default */.ZP)({ + url: url, + headers: { + Range: (0,byte_range/* default */.Z)(segment.range) + }, + responseType: "arraybuffer", + sendProgressEvents: false + }); + var indexRequest$ = (0,request/* default */.ZP)({ + url: url, + headers: { + Range: (0,byte_range/* default */.Z)(segment.indexRange) + }, + responseType: "arraybuffer", + sendProgressEvents: false + }); + return (0,combineLatest/* combineLatest */.aj)([rangeRequest$, indexRequest$]).pipe((0,map/* map */.U)(function (_ref2) { + var initData = _ref2[0], + indexData = _ref2[1]; + var data = (0,byte_parsing/* concat */.zo)(new Uint8Array(initData.value.responseData), new Uint8Array(indexData.value.responseData)); + var sendingTime = Math.min(initData.value.sendingTime, indexData.value.sendingTime); + var receivedTime = Math.max(initData.value.receivedTime, indexData.value.receivedTime); + return { + type: "data-loaded", + value: { + url: url, + responseData: data, + size: initData.value.size + indexData.value.size, + duration: receivedTime - sendingTime, + sendingTime: sendingTime, + receivedTime: receivedTime + } + }; + })); +} +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/scan.js +var scan = __webpack_require__(2807); +// EXTERNAL MODULE: ./src/transports/utils/find_complete_box.ts +var find_complete_box = __webpack_require__(8766); +;// CONCATENATED MODULE: ./src/transports/dash/extract_complete_chunks.ts /** * Copyright 2015 CANAL+ Group * @@ -29467,19 +28373,65 @@ var StaticRepresentationIndex = /*#__PURE__*/function () { * limitations under the License. */ -/** Enumerate the different ways a Manifest update can be done. */ -var MANIFEST_UPDATE_TYPE; -(function (MANIFEST_UPDATE_TYPE) { - /** The full version of the Manifest has been re-downloaded. */ - MANIFEST_UPDATE_TYPE[MANIFEST_UPDATE_TYPE["Full"] = 0] = "Full"; - /** Only a shortened version of the Manifest has been downloaded. */ +/** + * Take a chunk of ISOBMFF data and extract complete `moof`+`mdat` subsegments + * which are ready to be decoded. + * Returns a tuple of two containing first an array of those subsegments + * followed by tha last un-decodable part. + * @param {Uint8Array} buffer + * @returns {Array} + */ - MANIFEST_UPDATE_TYPE[MANIFEST_UPDATE_TYPE["Partial"] = 1] = "Partial"; -})(MANIFEST_UPDATE_TYPE || (MANIFEST_UPDATE_TYPE = {})); -// EXTERNAL MODULE: ./src/utils/array_find_index.ts -var array_find_index = __webpack_require__(5138); -;// CONCATENATED MODULE: ./src/manifest/update_period_in_place.ts +function extractCompleteChunks(buffer) { + var _position = 0; + var chunks = []; + + while (_position < buffer.length) { + var currentBuffer = buffer.subarray(_position, Infinity); + var moofIndex = (0,find_complete_box/* default */.Z)(currentBuffer, 0x6D6F6F66 + /* moof */ + ); + + if (moofIndex < 0) { + // no moof, not a segment. + return [chunks, currentBuffer]; + } + + var moofLen = (0,byte_parsing/* be4toi */.pX)(buffer, moofIndex + _position); + var moofEnd = _position + moofIndex + moofLen; + + if (moofEnd > buffer.length) { + // not a complete moof segment + return [chunks, currentBuffer]; + } + + var mdatIndex = (0,find_complete_box/* default */.Z)(currentBuffer, 0x6D646174 + /* mdat */ + ); + + if (mdatIndex < 0) { + // no mdat, not a segment. + return [chunks, currentBuffer]; + } + + var mdatLen = (0,byte_parsing/* be4toi */.pX)(buffer, mdatIndex + _position); + var mdatEnd = _position + mdatIndex + mdatLen; + + if (mdatEnd > buffer.length) { + // not a complete mdat segment + return [chunks, currentBuffer]; + } + + var maxEnd = Math.max(moofEnd, mdatEnd); + var chunk = buffer.subarray(_position, maxEnd); + chunks.push(chunk); + _position = maxEnd; + } + + return [chunks, null]; +} +;// CONCATENATED MODULE: ./src/transports/dash/low_latency_segment_loader.ts /** * Copyright 2015 CANAL+ Group * @@ -29498,60 +28450,89 @@ var array_find_index = __webpack_require__(5138); -/** - * Update oldPeriod attributes with the one from newPeriod (e.g. when updating - * the Manifest). - * @param {Object} oldPeriod - * @param {Object} newPeriod - */ -function updatePeriodInPlace(oldPeriod, newPeriod, updateType) { - oldPeriod.start = newPeriod.start; - oldPeriod.end = newPeriod.end; - oldPeriod.duration = newPeriod.duration; - var oldAdaptations = oldPeriod.getAdaptations(); - var newAdaptations = newPeriod.getAdaptations(); - var _loop = function _loop(j) { - var oldAdaptation = oldAdaptations[j]; - var newAdaptation = (0,array_find/* default */.Z)(newAdaptations, function (a) { - return a.id === oldAdaptation.id; - }); - if (newAdaptation === undefined) { - log/* default.warn */.Z.warn("Manifest: Adaptation \"" + oldAdaptations[j].id + "\" not found when merging."); - } else { - var oldRepresentations = oldAdaptations[j].representations; - var newRepresentations = newAdaptation.representations; - var _loop2 = function _loop2(k) { - var oldRepresentation = oldRepresentations[k]; - var newRepresentation = (0,array_find/* default */.Z)(newRepresentations, function (representation) { - return representation.id === oldRepresentation.id; - }); +function lowLatencySegmentLoader(url, args) { + var segment = args.segment; + var headers = segment.range !== undefined ? { + Range: (0,byte_range/* default */.Z)(segment.range) + } : undefined; + return request_fetch({ + url: url, + headers: headers + }).pipe((0,scan/* scan */.R)(function (acc, evt) { + if (evt.type === "data-complete") { + if (acc.partialChunk !== null) { + log/* default.warn */.Z.warn("DASH Pipelines: remaining chunk does not belong to any segment"); + } - if (newRepresentation === undefined) { - log/* default.warn */.Z.warn("Manifest: Representation \"" + oldRepresentations[k].id + "\" " + "not found when merging."); - } else { - if (updateType === MANIFEST_UPDATE_TYPE.Full) { - oldRepresentation.index._replace(newRepresentation.index); - } else { - oldRepresentation.index._update(newRepresentation.index); - } - } + return { + event: evt, + completeChunks: [], + partialChunk: null }; + } - for (var k = 0; k < oldRepresentations.length; k++) { - _loop2(k); - } + var data = new Uint8Array(evt.value.chunk); + var concatenated = acc.partialChunk !== null ? (0,byte_parsing/* concat */.zo)(acc.partialChunk, data) : data; + + var _extractCompleteChunk = extractCompleteChunks(concatenated), + completeChunks = _extractCompleteChunk[0], + partialChunk = _extractCompleteChunk[1]; + + return { + event: evt, + completeChunks: completeChunks, + partialChunk: partialChunk + }; + }, { + event: null, + completeChunks: [], + partialChunk: null + }), (0,mergeMap/* mergeMap */.zg)(function (evt) { + var emitted = []; + + for (var i = 0; i < evt.completeChunks.length; i++) { + emitted.push({ + type: "data-chunk", + value: { + responseData: evt.completeChunks[i] + } + }); } - }; - for (var j = 0; j < oldAdaptations.length; j++) { - _loop(j); - } + var event = evt.event; + + if (event !== null && event.type === "data-chunk") { + var value = event.value; + emitted.push({ + type: "progress", + value: { + duration: value.duration, + size: value.size, + totalSize: value.totalSize + } + }); + } else if (event !== null && event.type === "data-complete") { + var _value = event.value; + emitted.push({ + type: "data-chunk-complete", + value: { + duration: _value.duration, + receivedTime: _value.receivedTime, + sendingTime: _value.sendingTime, + size: _value.size, + url: _value.url + } + }); + } + + return of.of.apply(void 0, emitted); + })); } -;// CONCATENATED MODULE: ./src/manifest/update_periods.ts +;// CONCATENATED MODULE: ./src/transports/dash/segment_loader.ts /** * Copyright 2015 CANAL+ Group * @@ -29572,124 +28553,173 @@ function updatePeriodInPlace(oldPeriod, newPeriod, updateType) { + + + /** - * Update old periods by adding new periods and removing - * not available ones. - * @param {Array.} oldPeriods - * @param {Array.} newPeriods + * Segment loader triggered if there was no custom-defined one in the API. + * @param {Object} opt + * @returns {Observable} */ -function replacePeriods(oldPeriods, newPeriods) { - var firstUnhandledPeriodIdx = 0; - - for (var i = 0; i < newPeriods.length; i++) { - var newPeriod = newPeriods[i]; - var j = firstUnhandledPeriodIdx; - var oldPeriod = oldPeriods[j]; - - while (oldPeriod != null && oldPeriod.id !== newPeriod.id) { - j++; - oldPeriod = oldPeriods[j]; - } - - if (oldPeriod != null) { - updatePeriodInPlace(oldPeriod, newPeriod, MANIFEST_UPDATE_TYPE.Full); - var periodsToInclude = newPeriods.slice(firstUnhandledPeriodIdx, i); - var nbrOfPeriodsToRemove = j - firstUnhandledPeriodIdx; - oldPeriods.splice.apply(oldPeriods, [firstUnhandledPeriodIdx, nbrOfPeriodsToRemove].concat(periodsToInclude)); - firstUnhandledPeriodIdx = i + 1; - } +function regularSegmentLoader(url, args, lowLatencyMode) { + if (args.segment.isInit) { + return initSegmentLoader(url, args); } - if (firstUnhandledPeriodIdx > oldPeriods.length) { - log/* default.error */.Z.error("Manifest: error when updating Periods"); - return; - } + var isWEBM = isWEBMEmbeddedTrack(args.representation); - if (firstUnhandledPeriodIdx < oldPeriods.length) { - oldPeriods.splice(firstUnhandledPeriodIdx, oldPeriods.length - firstUnhandledPeriodIdx); + if (lowLatencyMode && !isWEBM) { + if (fetchIsSupported()) { + return lowLatencySegmentLoader(url, args); + } else { + (0,warn_once/* default */.Z)("DASH: Your browser does not have the fetch API. You will have " + "a higher chance of rebuffering when playing close to the live edge"); + } } - var remainingNewPeriods = newPeriods.slice(firstUnhandledPeriodIdx, newPeriods.length); - - if (remainingNewPeriods.length > 0) { - oldPeriods.push.apply(oldPeriods, remainingNewPeriods); - } + var segment = args.segment; + return (0,request/* default */.ZP)({ + url: url, + responseType: "arraybuffer", + sendProgressEvents: true, + headers: segment.range !== undefined ? { + Range: (0,byte_range/* default */.Z)(segment.range) + } : undefined + }); } /** - * Update old periods by adding new periods and removing - * not available ones. - * @param {Array.} oldPeriods - * @param {Array.} newPeriods + * @param {Object} config + * @returns {Function} */ -function updatePeriods(oldPeriods, newPeriods) { - if (oldPeriods.length === 0) { - oldPeriods.splice.apply(oldPeriods, [0, 0].concat(newPeriods)); - return; - } - if (newPeriods.length === 0) { - return; - } +function generateSegmentLoader(_ref) { + var lowLatencyMode = _ref.lowLatencyMode, + customSegmentLoader = _ref.segmentLoader, + checkMediaSegmentIntegrity = _ref.checkMediaSegmentIntegrity; + return checkMediaSegmentIntegrity !== true ? segmentLoader : addSegmentIntegrityChecks(segmentLoader); + /** + * @param {Object} content + * @returns {Observable} + */ - var oldLastPeriod = oldPeriods[oldPeriods.length - 1]; + function segmentLoader(content) { + var url = content.url; - if (oldLastPeriod.start < newPeriods[0].start) { - if (oldLastPeriod.end !== newPeriods[0].start) { - throw new media_error/* default */.Z("MANIFEST_UPDATE_ERROR", "Cannot perform partial update: not enough data"); + if (url == null) { + return (0,of.of)({ + type: "data-created", + value: { + responseData: null + } + }); } - oldPeriods.push.apply(oldPeriods, newPeriods); - return; - } + if (lowLatencyMode || customSegmentLoader === undefined) { + return regularSegmentLoader(url, content, lowLatencyMode); + } - var indexOfNewFirstPeriod = (0,array_find_index/* default */.Z)(oldPeriods, function (_ref) { - var id = _ref.id; - return id === newPeriods[0].id; - }); + var args = { + adaptation: content.adaptation, + manifest: content.manifest, + period: content.period, + representation: content.representation, + segment: content.segment, + transport: "dash", + url: url + }; + return new Observable/* Observable */.y(function (obs) { + var hasFinished = false; + var hasFallbacked = false; + /** + * Callback triggered when the custom segment loader has a response. + * @param {Object} args + */ - if (indexOfNewFirstPeriod < 0) { - throw new media_error/* default */.Z("MANIFEST_UPDATE_ERROR", "Cannot perform partial update: incoherent data"); - } // The first updated Period can only be a partial part + var resolve = function resolve(_args) { + if (!hasFallbacked) { + hasFinished = true; + obs.next({ + type: "data-loaded", + value: { + responseData: _args.data, + size: _args.size, + duration: _args.duration + } + }); + obs.complete(); + } + }; + /** + * Callback triggered when the custom segment loader fails + * @param {*} err - The corresponding error encountered + */ - updatePeriodInPlace(oldPeriods[indexOfNewFirstPeriod], newPeriods[0], MANIFEST_UPDATE_TYPE.Partial); - var prevIndexOfNewPeriod = indexOfNewFirstPeriod + 1; + var reject = function reject(err) { + if (err === void 0) { + err = {}; + } - for (var i = 1; i < newPeriods.length; i++) { - var newPeriod = newPeriods[i]; - var indexOfNewPeriod = -1; + if (!hasFallbacked) { + hasFinished = true; + obs.error(err); + } + }; - for (var j = prevIndexOfNewPeriod; j < oldPeriods.length; j++) { - if (newPeriod.id === oldPeriods[j].id) { - indexOfNewPeriod = j; - break; // end the loop - } - } + var progress = function progress(_args) { + if (!hasFallbacked) { + obs.next({ + type: "progress", + value: { + duration: _args.duration, + size: _args.size, + totalSize: _args.totalSize + } + }); + } + }; + /** + * Callback triggered when the custom segment loader wants to fallback to + * the "regular" implementation + */ - if (indexOfNewPeriod < 0) { - oldPeriods.splice.apply(oldPeriods, [prevIndexOfNewPeriod, oldPeriods.length - prevIndexOfNewPeriod].concat(newPeriods.slice(i, newPeriods.length))); - return; - } - if (indexOfNewPeriod > prevIndexOfNewPeriod) { - oldPeriods.splice(prevIndexOfNewPeriod, indexOfNewPeriod - prevIndexOfNewPeriod); - indexOfNewPeriod = prevIndexOfNewPeriod; - } // Later Periods can be fully replaced + var fallback = function fallback() { + hasFallbacked = true; + var regular$ = regularSegmentLoader(url, content, lowLatencyMode); // HACK What is TypeScript/RxJS doing here?????? + /* eslint-disable import/no-deprecated */ - updatePeriodInPlace(oldPeriods[indexOfNewPeriod], newPeriod, MANIFEST_UPDATE_TYPE.Full); - prevIndexOfNewPeriod++; - } + /* eslint-disable @typescript-eslint/ban-ts-comment */ + // @ts-ignore - if (prevIndexOfNewPeriod < oldPeriods.length) { - oldPeriods.splice(prevIndexOfNewPeriod, oldPeriods.length - prevIndexOfNewPeriod); - } -} -;// CONCATENATED MODULE: ./src/manifest/manifest.ts + regular$.subscribe(obs); + /* eslint-enable import/no-deprecated */ + /* eslint-enable @typescript-eslint/ban-ts-comment */ + }; + var callbacks = { + reject: reject, + resolve: resolve, + progress: progress, + fallback: fallback + }; + var abort = customSegmentLoader(args, callbacks); + return function () { + if (!hasFinished && !hasFallbacked && typeof abort === "function") { + abort(); + } + }; + }); + } +} +// EXTERNAL MODULE: ./src/parsers/containers/isobmff/utils.ts +var utils = __webpack_require__(4644); +// EXTERNAL MODULE: ./src/parsers/containers/isobmff/take_pssh_out.ts + 1 modules +var take_pssh_out = __webpack_require__(6490); +;// CONCATENATED MODULE: ./src/parsers/containers/matroska/utils.ts /** * Copyright 2015 CANAL+ Group * @@ -29706,570 +28736,296 @@ function updatePeriods(oldPeriods, newPeriods) { * limitations under the License. */ +var SEGMENT_ID = 0x18538067; +var INFO_ID = 0x1549A966; +var TIMECODESCALE_ID = 0x2AD7B1; +var DURATION_ID = 0x4489; +var CUES_ID = 0x1C53BB6B; +var CUE_POINT_ID = 0xBB; +var CUE_TIME_ID = 0xB3; +var CUE_TRACK_POSITIONS_ID = 0xB7; +var CUE_CLUSTER_POSITIONS_ID = 0xF1; +/** + * Find the offsets of the value linked to the given element ID. + * @param {number} elementID - ID for the searched element. + * @param {Array.} parents - eventual IDs of the parent elements. From + * top level to lower level (from the furthest to the closest). + * @param {Uint8Array} buffer - buffer where the ID will be searched + * @param {Array.} range - start and end offsets in the buffer where the + * ID will be searched. + * @returns {Array.|null} + */ +function findNextElement(elementID, parents, buffer, _ref) { + var initialOffset = _ref[0], + maxOffset = _ref[1]; + var currentOffset = initialOffset; + while (currentOffset < maxOffset) { + var parsedID = getEBMLID(buffer, currentOffset); + if (parsedID == null) { + return null; + } + var ebmlTagID = parsedID.value, + ebmlTagLength = parsedID.length; + var sizeOffset = currentOffset + ebmlTagLength; + var parsedValue = getEBMLValue(buffer, sizeOffset); + if (parsedValue == null) { + return null; + } + var valueLengthLength = parsedValue.length, + valueLength = parsedValue.value; + var valueOffset = sizeOffset + valueLengthLength; + var valueEndOffset = valueOffset + valueLength; + if (ebmlTagID === elementID) { + return [valueOffset, valueEndOffset]; + } else if (parents.length > 0) { + for (var i = 0; i < parents.length; i++) { + if (ebmlTagID === parents[i]) { + var newParents = parents.slice(i + 1, parents.length); + return findNextElement(elementID, newParents, buffer, [valueOffset, valueEndOffset]); + } + } + } + currentOffset = valueEndOffset; + } -var generateSupplementaryTrackID = (0,id_generator/* default */.Z)(); -var generateNewManifestId = (0,id_generator/* default */.Z)(); + return null; +} /** - * Normalized Manifest structure. - * - * Details the current content being played: - * - the duration of the content - * - the available tracks - * - the available qualities - * - the segments defined in those qualities - * - ... - * while staying agnostic of the transport protocol used (Smooth, DASH etc.). - * - * The Manifest and its contained information can evolve over time (like when - * updating a dynamic manifest or when right management forbid some tracks from - * being played). - * To perform actions on those changes, any module using this Manifest can - * listen to its sent events and react accordingly. - * - * @class Manifest + * Return the timecode scale (basically timescale) of the whole file. + * @param {Uint8Array} buffer + * @param {number} initialOffset + * @returns {number|null} */ -var Manifest = /*#__PURE__*/function (_EventEmitter) { - inheritsLoose_default()(Manifest, _EventEmitter); - - /** - * Construct a Manifest instance from a parsed Manifest object (as returned by - * Manifest parsers) and options. - * - * Some minor errors can arise during that construction. `this.parsingErrors` - * will contain all such errors, in the order they have been encountered. - * @param {Object} parsedManifest - * @param {Object} options - */ - function Manifest(parsedManifest, options) { - var _this; - var _a; +function getTimeCodeScale(buffer, initialOffset) { + var timeCodeScaleOffsets = findNextElement(TIMECODESCALE_ID, [SEGMENT_ID, INFO_ID], buffer, [initialOffset, buffer.length]); - _this = _EventEmitter.call(this) || this; - var _options$supplementar = options.supplementaryTextTracks, - supplementaryTextTracks = _options$supplementar === void 0 ? [] : _options$supplementar, - _options$supplementar2 = options.supplementaryImageTracks, - supplementaryImageTracks = _options$supplementar2 === void 0 ? [] : _options$supplementar2, - representationFilter = options.representationFilter; - _this.parsingErrors = []; - _this.id = generateNewManifestId(); - _this.expired = (_a = parsedManifest.expired) !== null && _a !== void 0 ? _a : null; - _this.transport = parsedManifest.transportType; - _this.clockOffset = parsedManifest.clockOffset; - _this.periods = parsedManifest.periods.map(function (parsedPeriod) { - var _this$parsingErrors; + if (timeCodeScaleOffsets == null) { + return null; + } - var period = new Period(parsedPeriod, representationFilter); + var length = timeCodeScaleOffsets[1] - timeCodeScaleOffsets[0]; + return 1e9 / bytesToNumber(buffer, timeCodeScaleOffsets[0], length); +} +/** + * Return the duration of the concerned media. + * @param {Uint8Array} buffer + * @param {number} initialOffset + * @returns {number|null} + */ - (_this$parsingErrors = _this.parsingErrors).push.apply(_this$parsingErrors, period.parsingErrors); +function getDuration(buffer, initialOffset) { + var timeCodeScaleOffsets = findNextElement(DURATION_ID, [SEGMENT_ID, INFO_ID], buffer, [initialOffset, buffer.length]); - return period; - }).sort(function (a, b) { - return a.start - b.start; - }); - /** - * @deprecated It is here to ensure compatibility with the way the - * v3.x.x manages adaptations at the Manifest level - */ + if (timeCodeScaleOffsets == null) { + return null; + } - /* eslint-disable import/no-deprecated */ + var length = timeCodeScaleOffsets[1] - timeCodeScaleOffsets[0]; - _this.adaptations = _this.periods[0] === undefined ? {} : _this.periods[0].adaptations; - /* eslint-enable import/no-deprecated */ + if (length === 4) { + return get_IEEE754_32Bits(buffer, timeCodeScaleOffsets[0]); + } else if (length === 8) { + return get_IEEE754_64Bits(buffer, timeCodeScaleOffsets[0]); + } - _this._timeBounds = parsedManifest.timeBounds; - _this.isDynamic = parsedManifest.isDynamic; - _this.isLive = parsedManifest.isLive; - _this.uris = parsedManifest.uris === undefined ? [] : parsedManifest.uris; - _this.lifetime = parsedManifest.lifetime; - _this.suggestedPresentationDelay = parsedManifest.suggestedPresentationDelay; - _this.availabilityStartTime = parsedManifest.availabilityStartTime; + return null; +} +/** + * @param {Uint8Array} buffer + * @param {number} initialOffset + * @returns {Array.|null} + */ - if (supplementaryImageTracks.length > 0) { - _this._addSupplementaryImageAdaptations(supplementaryImageTracks); - } - if (supplementaryTextTracks.length > 0) { - _this._addSupplementaryTextAdaptations(supplementaryTextTracks); - } +function getSegmentsFromCues(buffer, initialOffset) { + var segmentRange = findNextElement(SEGMENT_ID, [], buffer, [initialOffset, buffer.length]); - return _this; + if (segmentRange == null) { + return null; } - /** - * Returns the Period corresponding to the given `id`. - * Returns `undefined` if there is none. - * @param {string} id - * @returns {Object|undefined} - */ - - var _proto = Manifest.prototype; + var segmentRangeStart = segmentRange[0], + segmentRangeEnd = segmentRange[1]; + var timescale = getTimeCodeScale(buffer, segmentRangeStart); - _proto.getPeriod = function getPeriod(id) { - return (0,array_find/* default */.Z)(this.periods, function (period) { - return id === period.id; - }); + if (timescale == null) { + return null; } - /** - * Returns the Period encountered at the given time. - * Returns `undefined` if there is no Period exactly at the given time. - * @param {number} time - * @returns {Object|undefined} - */ - ; - _proto.getPeriodForTime = function getPeriodForTime(time) { - return (0,array_find/* default */.Z)(this.periods, function (period) { - return time >= period.start && (period.end === undefined || period.end > time); - }); - } - /** - * Returns the first Period starting strictly after the given time. - * Returns `undefined` if there is no Period starting after that time. - * @param {number} time - * @returns {Object|undefined} - */ - ; + var duration = getDuration(buffer, segmentRangeStart); - _proto.getNextPeriod = function getNextPeriod(time) { - return (0,array_find/* default */.Z)(this.periods, function (period) { - return period.start > time; - }); + if (duration == null) { + return null; } - /** - * Returns the Period coming chronologically just after another given Period. - * Returns `undefined` if not found. - * @param {Object} period - * @returns {Object|null} - */ - ; - - _proto.getPeriodAfter = function getPeriodAfter(period) { - var endOfPeriod = period.end; - - if (endOfPeriod === undefined) { - return null; - } - var nextPeriod = (0,array_find/* default */.Z)(this.periods, function (_period) { - return _period.end === undefined || endOfPeriod < _period.end; - }); - return nextPeriod === undefined ? null : nextPeriod; - } - /** - * Returns the most important URL from which the Manifest can be refreshed. - * `undefined` if no URL is found. - * @returns {string|undefined} - */ - ; + var cuesRange = findNextElement(CUES_ID, [], buffer, [segmentRangeStart, segmentRangeEnd]); - _proto.getUrl = function getUrl() { - return this.uris[0]; + if (cuesRange == null) { + return null; } - /** - * Update the current Manifest properties by giving a new updated version. - * This instance will be updated with the new information coming from it. - * @param {Object} newManifest - */ - ; - _proto.replace = function replace(newManifest) { - this._performUpdate(newManifest, MANIFEST_UPDATE_TYPE.Full); - } - /** - * Update the current Manifest properties by giving a new but shorter version - * of it. - * This instance will add the new information coming from it and will - * automatically clean old Periods that shouldn't be available anymore. - * - * /!\ Throws if the given Manifest cannot be used or is not sufficient to - * update the Manifest. - * @param {Object} newManifest - */ - ; + var rawInfos = []; + var currentOffset = cuesRange[0]; - _proto.update = function update(newManifest) { - this._performUpdate(newManifest, MANIFEST_UPDATE_TYPE.Partial); - } - /** - * Get the minimum position currently defined by the Manifest, in seconds. - * @returns {number} - */ - ; + while (currentOffset < cuesRange[1]) { + var cuePointRange = findNextElement(CUE_POINT_ID, [], buffer, [currentOffset, cuesRange[1]]); - _proto.getMinimumPosition = function getMinimumPosition() { - var _a, _b; + if (cuePointRange == null) { + break; + } - var windowData = this._timeBounds; + var cueTimeRange = findNextElement(CUE_TIME_ID, [], buffer, [cuePointRange[0], cuePointRange[1]]); - if (windowData.timeshiftDepth === null) { - return (_a = windowData.absoluteMinimumTime) !== null && _a !== void 0 ? _a : 0; + if (cueTimeRange == null) { + return null; } - var maximumTimeData = windowData.maximumTimeData; - var maximumTime; + var time = bytesToNumber(buffer, cueTimeRange[0], cueTimeRange[1] - cueTimeRange[0]); + var cueOffsetRange = findNextElement(CUE_CLUSTER_POSITIONS_ID, [CUE_TRACK_POSITIONS_ID], buffer, [cuePointRange[0], cuePointRange[1]]); - if (!windowData.maximumTimeData.isLinear) { - maximumTime = maximumTimeData.value; - } else { - var timeDiff = performance.now() - maximumTimeData.time; - maximumTime = maximumTimeData.value + timeDiff / 1000; + if (cueOffsetRange == null) { + return null; } - var theoricalMinimum = maximumTime - windowData.timeshiftDepth; - return Math.max((_b = windowData.absoluteMinimumTime) !== null && _b !== void 0 ? _b : 0, theoricalMinimum); - } - /** - * Get the maximum position currently defined by the Manifest, in seconds. - * @returns {number} - */ - ; - - _proto.getMaximumPosition = function getMaximumPosition() { - var maximumTimeData = this._timeBounds.maximumTimeData; - - if (!maximumTimeData.isLinear) { - return maximumTimeData.value; - } - - var timeDiff = performance.now() - maximumTimeData.time; - return maximumTimeData.value + timeDiff / 1000; - } - /** - * Look in the Manifest for Representations linked to the given key ID, - * and mark them as being impossible to decrypt. - * Then trigger a "blacklist-update" event to notify everyone of the changes - * performed. - * @param {Array.} keyIDs - */ - ; - - _proto.addUndecipherableKIDs = function addUndecipherableKIDs(keyIDs) { - var updates = updateDeciperability(this, function (representation) { - if (representation.decipherable === false || representation.contentProtections === undefined) { - return true; - } - - var contentKIDs = representation.contentProtections.keyIds; - - for (var i = 0; i < contentKIDs.length; i++) { - var elt = contentKIDs[i]; - - for (var j = 0; j < keyIDs.length; j++) { - if ((0,are_arrays_of_numbers_equal/* default */.Z)(keyIDs[j], elt.keyId)) { - return false; - } - } - } - - return true; + var rangeStart = bytesToNumber(buffer, cueOffsetRange[0], cueOffsetRange[1] - cueOffsetRange[0]) + segmentRangeStart; + rawInfos.push({ + time: time, + rangeStart: rangeStart }); - - if (updates.length > 0) { - this.trigger("decipherabilityUpdate", updates); - } + currentOffset = cuePointRange[1]; } - /** - * Look in the Manifest for Representations linked to the given content - * protection initialization data and mark them as being impossible to - * decrypt. - * Then trigger a "blacklist-update" event to notify everyone of the changes - * performed. - * @param {Array.} keyIDs - */ - ; - _proto.addUndecipherableProtectionData = function addUndecipherableProtectionData(initDataType, initData) { - var updates = updateDeciperability(this, function (representation) { - if (representation.decipherable === false) { - return true; - } - - var segmentProtections = representation.getProtectionsInitializationData(); - - for (var i = 0; i < segmentProtections.length; i++) { - if (segmentProtections[i].type === initDataType) { - if ((0,are_arrays_of_numbers_equal/* default */.Z)(initData, segmentProtections[i].data)) { - return false; - } - } - } + var segments = []; - return true; - }); + for (var i = 0; i < rawInfos.length; i++) { + var currentSegment = rawInfos[i]; - if (updates.length > 0) { - this.trigger("decipherabilityUpdate", updates); + if (i === rawInfos.length - 1) { + segments.push({ + time: currentSegment.time, + count: 0, + timescale: timescale, + duration: i === 0 ? duration : duration - currentSegment.time, + range: [currentSegment.rangeStart, Infinity] + }); + } else { + segments.push({ + time: currentSegment.time, + count: 0, + timescale: timescale, + duration: rawInfos[i + 1].time - currentSegment.time, + range: [currentSegment.rangeStart, rawInfos[i + 1].rangeStart - 1] + }); } } - /** - * @deprecated only returns adaptations for the first period - * @returns {Array.} - */ - ; - - _proto.getAdaptations = function getAdaptations() { - (0,warn_once/* default */.Z)("manifest.getAdaptations() is deprecated." + " Please use manifest.period[].getAdaptations() instead"); - var firstPeriod = this.periods[0]; - - if (firstPeriod === undefined) { - return []; - } - var adaptationsByType = firstPeriod.adaptations; - var adaptationsList = []; + return segments; +} - for (var adaptationType in adaptationsByType) { - if (adaptationsByType.hasOwnProperty(adaptationType)) { - var adaptations = adaptationsByType[adaptationType]; - adaptationsList.push.apply(adaptationsList, adaptations); - } +function getLength(buffer, offset) { + for (var length = 1; length <= 8; length++) { + if (buffer[offset] >= Math.pow(2, 8 - length)) { + return length; } - - return adaptationsList; } - /** - * @deprecated only returns adaptations for the first period - * @returns {Array.} - */ - ; - _proto.getAdaptationsForType = function getAdaptationsForType(adaptationType) { - (0,warn_once/* default */.Z)("manifest.getAdaptationsForType(type) is deprecated." + " Please use manifest.period[].getAdaptationsForType(type) instead"); - var firstPeriod = this.periods[0]; + return undefined; +} - if (firstPeriod === undefined) { - return []; - } +function getEBMLID(buffer, offset) { + var length = getLength(buffer, offset); - var adaptationsForType = firstPeriod.adaptations[adaptationType]; - return adaptationsForType === undefined ? [] : adaptationsForType; + if (length == null) { + log/* default.warn */.Z.warn("webm: unrepresentable length"); + return null; } - /** - * @deprecated only returns adaptations for the first period - * @returns {Array.} - */ - ; - - _proto.getAdaptation = function getAdaptation(wantedId) { - (0,warn_once/* default */.Z)("manifest.getAdaptation(id) is deprecated." + " Please use manifest.period[].getAdaptation(id) instead"); - /* eslint-disable import/no-deprecated */ - return (0,array_find/* default */.Z)(this.getAdaptations(), function (_ref) { - var id = _ref.id; - return wantedId === id; - }); - /* eslint-enable import/no-deprecated */ + if (offset + length > buffer.length) { + log/* default.warn */.Z.warn("webm: impossible length"); + return null; } - /** - * Add supplementary image Adaptation(s) to the manifest. - * @private - * @param {Object|Array.} imageTracks - */ - ; - - _proto._addSupplementaryImageAdaptations = function _addSupplementaryImageAdaptations( - /* eslint-disable import/no-deprecated */ - imageTracks) { - var _this2 = this; - - var _imageTracks = Array.isArray(imageTracks) ? imageTracks : [imageTracks]; - - var newImageTracks = _imageTracks.map(function (_ref2) { - var _this2$parsingErrors; - - var mimeType = _ref2.mimeType, - url = _ref2.url; - var adaptationID = "gen-image-ada-" + generateSupplementaryTrackID(); - var representationID = "gen-image-rep-" + generateSupplementaryTrackID(); - var newAdaptation = new Adaptation({ - id: adaptationID, - type: "image", - representations: [{ - bitrate: 0, - id: representationID, - mimeType: mimeType, - index: new StaticRepresentationIndex({ - media: url - }) - }] - }, { - isManuallyAdded: true - }); - - (_this2$parsingErrors = _this2.parsingErrors).push.apply(_this2$parsingErrors, newAdaptation.parsingErrors); - return newAdaptation; - }); + var value = 0; - if (newImageTracks.length > 0 && this.periods.length > 0) { - var adaptations = this.periods[0].adaptations; - adaptations.image = adaptations.image != null ? adaptations.image.concat(newImageTracks) : newImageTracks; - } + for (var i = 0; i < length; i++) { + value = buffer[offset + i] * Math.pow(2, (length - i - 1) * 8) + value; } - /** - * Add supplementary text Adaptation(s) to the manifest. - * @private - * @param {Object|Array.} textTracks - */ - ; - - _proto._addSupplementaryTextAdaptations = function _addSupplementaryTextAdaptations( - /* eslint-disable import/no-deprecated */ - textTracks - /* eslint-enable import/no-deprecated */ - ) { - var _this3 = this; - - var _textTracks = Array.isArray(textTracks) ? textTracks : [textTracks]; - - var newTextAdaptations = _textTracks.reduce(function (allSubs, _ref3) { - var mimeType = _ref3.mimeType, - codecs = _ref3.codecs, - url = _ref3.url, - language = _ref3.language, - languages = _ref3.languages, - closedCaption = _ref3.closedCaption; - var langsToMapOn = language != null ? [language] : languages != null ? languages : []; - return allSubs.concat(langsToMapOn.map(function (_language) { - var _this3$parsingErrors; - - var adaptationID = "gen-text-ada-" + generateSupplementaryTrackID(); - var representationID = "gen-text-rep-" + generateSupplementaryTrackID(); - var newAdaptation = new Adaptation({ - id: adaptationID, - type: "text", - language: _language, - closedCaption: closedCaption, - representations: [{ - bitrate: 0, - id: representationID, - mimeType: mimeType, - codecs: codecs, - index: new StaticRepresentationIndex({ - media: url - }) - }] - }, { - isManuallyAdded: true - }); - (_this3$parsingErrors = _this3.parsingErrors).push.apply(_this3$parsingErrors, newAdaptation.parsingErrors); + return { + length: length, + value: value + }; +} - return newAdaptation; - })); - }, []); +function getEBMLValue(buffer, offset) { + var length = getLength(buffer, offset); - if (newTextAdaptations.length > 0 && this.periods.length > 0) { - var adaptations = this.periods[0].adaptations; - adaptations.text = adaptations.text != null ? adaptations.text.concat(newTextAdaptations) : newTextAdaptations; - } + if (length == null) { + log/* default.warn */.Z.warn("webm: unrepresentable length"); + return null; } - /** - * @param {Object} newManifest - * @param {number} type - */ - ; - - _proto._performUpdate = function _performUpdate(newManifest, updateType) { - this.availabilityStartTime = newManifest.availabilityStartTime; - this.expired = newManifest.expired; - this.isDynamic = newManifest.isDynamic; - this.isLive = newManifest.isLive; - this.lifetime = newManifest.lifetime; - this.parsingErrors = newManifest.parsingErrors; - this.suggestedPresentationDelay = newManifest.suggestedPresentationDelay; - this.transport = newManifest.transport; - - if (updateType === MANIFEST_UPDATE_TYPE.Full) { - this._timeBounds = newManifest._timeBounds; - this.uris = newManifest.uris; - replacePeriods(this.periods, newManifest.periods); - } else { - this._timeBounds.maximumTimeData = newManifest._timeBounds.maximumTimeData; - updatePeriods(this.periods, newManifest.periods); // Partial updates do not remove old Periods. - // This can become a memory problem when playing a content long enough. - // Let's clean manually Periods behind the minimum possible position. - - var min = this.getMinimumPosition(); - - while (this.periods.length > 0) { - var period = this.periods[0]; - - if (period.end === undefined || period.end > min) { - break; - } - - this.periods.shift(); - } - } // Re-set this.adaptations for retro-compatibility in v3.x.x - /* eslint-disable import/no-deprecated */ + if (offset + length > buffer.length) { + log/* default.warn */.Z.warn("webm: impossible length"); + return null; + } + var value = (buffer[offset] & (1 << 8 - length) - 1) * Math.pow(2, (length - 1) * 8); - this.adaptations = this.periods[0] === undefined ? {} : this.periods[0].adaptations; - /* eslint-enable import/no-deprecated */ - // Let's trigger events at the end, as those can trigger side-effects. - // We do not want the current Manifest object to be incomplete when those - // happen. + for (var i = 1; i < length; i++) { + value = buffer[offset + i] * Math.pow(2, (length - i - 1) * 8) + value; + } - this.trigger("manifestUpdate", null); + return { + length: length, + value: value }; - - return Manifest; -}(event_emitter/* default */.Z); +} /** - * Update decipherability based on a predicate given. - * Do nothing for a Representation when the predicate returns false, mark as - * undecipherable when the predicate returns false. Returns every updates in - * an array. - * @param {Manifest} manifest - * @param {Function} predicate - * @returns {Array.} + * Convert a IEEE754 32 bits floating number as an Uint8Array into its + * corresponding Number. + * @param {Uint8Array} buffer + * @param {number} offset + * @returns {number} */ +function get_IEEE754_32Bits(buffer, offset) { + return new DataView(buffer.buffer).getFloat32(offset); +} +/** + * Convert a IEEE754 64 bits floating number as an Uint8Array into its + * corresponding Number. + * @param {Uint8Array} buffer + * @param {number} offset + * @returns {number} + */ -function updateDeciperability(manifest, predicate) { - var updates = []; - - for (var i = 0; i < manifest.periods.length; i++) { - var period = manifest.periods[i]; - var adaptations = period.getAdaptations(); - - for (var j = 0; j < adaptations.length; j++) { - var adaptation = adaptations[j]; - var representations = adaptation.representations; +function get_IEEE754_64Bits(buffer, offset) { + return new DataView(buffer.buffer).getFloat64(offset); +} - for (var k = 0; k < representations.length; k++) { - var representation = representations[k]; +function bytesToNumber(buffer, offset, length) { + var value = 0; - if (!predicate(representation)) { - updates.push({ - manifest: manifest, - period: period, - adaptation: adaptation, - representation: representation - }); - representation.decipherable = false; - } - } - } + for (var i = 0; i < length; i++) { + value = buffer[offset + i] * Math.pow(2, (length - i - 1) * 8) + value; } - return updates; + return value; } -;// CONCATENATED MODULE: ./src/manifest/index.ts +;// CONCATENATED MODULE: ./src/transports/utils/get_isobmff_timing_infos.ts /** * Copyright 2015 CANAL+ Group * @@ -30286,23 +29042,56 @@ function updateDeciperability(manifest, predicate) { * limitations under the License. */ +/** + * Get precize start and duration of a chunk. + * @param {UInt8Array} buffer - An ISOBMFF container (at least a `moof` + a + * `mdat` box. + * @param {Boolean} isChunked - If true, the whole segment was chunked into + * multiple parts and buffer is one of them. If false, buffer is the whole + * segment. + * @param {Object} segment + * @param {Array.|undefined} sidxSegments - Segments from sidx. Here + * pre-parsed for performance reasons as it is usually available when + * this function is called. + * @param {number|undefined} initTimescale + * @returns {Object} + */ +function getISOBMFFTimingInfos(buffer, isChunked, segment, initTimescale) { + var baseDecodeTime = (0,utils/* getTrackFragmentDecodeTime */.Qx)(buffer); + if (baseDecodeTime === undefined || initTimescale === undefined) { + return null; + } + var startTime = segment.timestampOffset !== undefined ? baseDecodeTime + segment.timestampOffset * initTimescale : baseDecodeTime; + var trunDuration = (0,utils/* getDurationFromTrun */.MM)(buffer); + if (isChunked) { + // when chunked, no mean to know the duration for now + return { + time: startTime / initTimescale, + duration: trunDuration !== undefined ? trunDuration / initTimescale : undefined + }; + } -/* harmony default export */ const manifest = (Manifest); - + var duration; + var segmentDuration = segment.duration * initTimescale; // we could always make a mistake when reading a container. + // If the estimate is too far from what the segment seems to imply, take + // the segment infos instead. -/***/ }), + var maxDecodeTimeDelta = Math.min(initTimescale * 0.9, segmentDuration / 4); -/***/ 2689: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (trunDuration !== undefined && Math.abs(trunDuration - segmentDuration) <= maxDecodeTimeDelta) { + duration = trunDuration; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "s": () => /* binding */ MAX_32_BIT_INT -/* harmony export */ }); + return { + time: startTime / initTimescale, + duration: duration !== undefined ? duration / initTimescale : duration + }; +} +;// CONCATENATED MODULE: ./src/transports/dash/get_events_out_of_emsgs.ts /** * Copyright 2015 CANAL+ Group * @@ -30320,29 +29109,97 @@ function updateDeciperability(manifest, predicate) { */ /** - * Maximum integer that can be stored on 32 bits. - * - * This can be used for example to know what is the maximum ISOBMFF box size - * that can be stored on the first four bytes of a box. Any value higher than - * that will need 8 bytes (64 bits) to be stored. + * From an array of EMSGs with manifest validity scheme id, + * tells if the manifest needs to be refreshed. + * @param {Array.} emsgs + * @param {Object} segment + * @param {number} manifestPublishTime + * @returns {boolean} */ -var MAX_32_BIT_INT = Math.pow(2, 32) - 1; -/***/ }), +function manifestNeedsToBeRefreshed(emsgs, manifestPublishTime) { + if (emsgs.length <= 0) { + return false; + } -/***/ 2297: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var len = emsgs.length; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "iz": () => /* binding */ getBox, -/* harmony export */ "t_": () => /* binding */ getBoxContent, -/* harmony export */ "Qy": () => /* binding */ getBoxOffsets, -/* harmony export */ "Xj": () => /* binding */ getNextBoxOffsets, -/* harmony export */ "nR": () => /* binding */ getUuidContent -/* harmony export */ }); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3887); -/* harmony import */ var _utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6968); + for (var i = 0; i < len; i++) { + var manifestRefreshEventFromEMSGs = emsgs[i]; + var currentManifestPublishTime = manifestPublishTime; + var messageData = manifestRefreshEventFromEMSGs.messageData; + var strPublishTime = (0,string_parsing/* utf8ToStr */.uR)(messageData); + var eventManifestPublishTime = Date.parse(strPublishTime); + + if (currentManifestPublishTime === undefined || eventManifestPublishTime === undefined || isNaN(eventManifestPublishTime) || // DASH-if 4.3 tells (4.5.2.1) : + // "The media presentation time beyond the event time (indicated + // time by presentation_time_delta) is correctly described only + // by MPDs with publish time greater than indicated value in the + // message_data field." + // + // Here, if the current manifest has its publish time inferior or + // identical to the event manifest publish time, then the manifest needs + // to be updated + eventManifestPublishTime >= currentManifestPublishTime) { + return true; + } + } + + return false; +} +/** + * Get wrapped inband events and manifest refresh event from + * parsed ISOBMFF EMSG boxes. + * @param {Array.} parsedEMSGs + * @param {Object} segment + * @param {undefined | number} manifestPublishTime + * @returns {Object} + */ + + +function getEventsOutOfEMSGs(parsedEMSGs, manifestPublishTime) { + if (parsedEMSGs.length === 0) { + return undefined; + } + + var _parsedEMSGs$reduce = parsedEMSGs.reduce(function (acc, val) { + // Scheme that signals manifest update + if (val.schemeIdUri === "urn:mpeg:dash:event:2012" && // TODO support value 2 and 3 + val.value === "1") { + if (acc.manifestRefreshEventsFromEMSGs === undefined) { + acc.manifestRefreshEventsFromEMSGs = []; + } + + acc.manifestRefreshEventsFromEMSGs.push(val); + } else { + if (acc.EMSGs === undefined) { + acc.EMSGs = []; + } + + acc.EMSGs.push(val); + } + + return acc; + }, { + manifestRefreshEventsFromEMSGs: undefined, + EMSGs: undefined + }), + manifestRefreshEventsFromEMSGs = _parsedEMSGs$reduce.manifestRefreshEventsFromEMSGs, + EMSGs = _parsedEMSGs$reduce.EMSGs; + + var inbandEvents = EMSGs === null || EMSGs === void 0 ? void 0 : EMSGs.map(function (evt) { + return { + type: "emsg", + value: evt + }; + }); + var needsManifestRefresh = manifestPublishTime === undefined || manifestRefreshEventsFromEMSGs === undefined ? false : manifestNeedsToBeRefreshed(manifestRefreshEventsFromEMSGs, manifestPublishTime); + return { + inbandEvents: inbandEvents, + needsManifestRefresh: needsManifestRefresh + }; +} +;// CONCATENATED MODULE: ./src/transports/dash/segment_parser.ts /** * Copyright 2015 CANAL+ Group * @@ -30360,210 +29217,157 @@ var MAX_32_BIT_INT = Math.pow(2, 32) - 1; */ -/** - * Returns the content of a box based on its name. - * `null` if not found. - * @param {Uint8Array} buf - the isobmff structure - * @param {Number} boxName - the 4-letter 'name' of the box as a 4 bit integer - * generated from encoding the corresponding ASCII in big endian. - * @returns {UInt8Array|null} - */ -function getBoxContent(buf, boxName) { - var offsets = getBoxOffsets(buf, boxName); - return offsets !== null ? buf.subarray(offsets[1], offsets[2]) : null; -} -/** - * Returns an ISOBMFF box - size and name included - based on its name. - * `null` if not found. - * @param {Uint8Array} buf - the isobmff structure - * @param {Number} boxName - the 4-letter 'name' of the box as a 4 bit integer - * generated from encoding the corresponding ASCII in big endian. - * @returns {UInt8Array|null} - */ -function getBox(buf, boxName) { - var offsets = getBoxOffsets(buf, boxName); - return offsets !== null ? buf.subarray(offsets[0], offsets[2]) : null; -} -/** - * Returns byte offsets for the start of the box, the start of its content and - * the end of the box (not inclusive). - * - * `null` if not found. - * - * If found, the tuple returned has three elements, all numbers: - * 1. The starting byte corresponding to the start of the box (from its size) - * 2. The beginning of the box content - meaning the first byte after the - * size and the name of the box. - * 3. The first byte after the end of the box, might be equal to `buf`'s - * length if we're considering the last box. - * @param {Uint8Array} buf - the isobmff structure - * @param {Number} boxName - the 4-letter 'name' of the box as a 4 bit integer - * generated from encoding the corresponding ASCII in big endian. - * @returns {Array.|null} - */ -function getBoxOffsets(buf, boxName) { - var len = buf.length; - var boxBaseOffset = 0; - var name; - var lastBoxSize = 0; - var lastOffset; - while (boxBaseOffset + 8 <= len) { - lastOffset = boxBaseOffset; - lastBoxSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, lastOffset); - lastOffset += 4; - name = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, lastOffset); - lastOffset += 4; - if (lastBoxSize === 0) { - lastBoxSize = len - boxBaseOffset; - } else if (lastBoxSize === 1) { - if (lastOffset + 8 > len) { - return null; - } - lastBoxSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be8toi */ .pV)(buf, lastOffset); - lastOffset += 8; - } +/** + * @param {Object} config + * @returns {Function} + */ - if (lastBoxSize < 0) { - throw new Error("ISOBMFF: Size out of range"); - } +function generateAudioVideoSegmentParser(_ref) { + var __priv_patchLastSegmentInSidx = _ref.__priv_patchLastSegmentInSidx; + return function audioVideoSegmentParser(_ref2) { + var content = _ref2.content, + response = _ref2.response, + initTimescale = _ref2.initTimescale; + var period = content.period, + representation = content.representation, + segment = content.segment, + manifest = content.manifest; + var data = response.data, + isChunked = response.isChunked; + var appendWindow = [period.start, period.end]; - if (name === boxName) { - if (boxName === 0x75756964 - /* === "uuid" */ - ) { - lastOffset += 16; // Skip uuid name - } + if (data === null) { + if (segment.isInit) { + return (0,of.of)({ + type: "parsed-init-segment", + value: { + initializationData: null, + protectionDataUpdate: false, + initTimescale: undefined + } + }); + } - return [boxBaseOffset, lastOffset, boxBaseOffset + lastBoxSize]; - } else { - boxBaseOffset += lastBoxSize; + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: null, + chunkInfos: null, + chunkOffset: 0, + appendWindow: appendWindow + } + }); } - } - return null; -} -/** - * Gives the content of a specific UUID box. - * `undefined` if that box is not found. - * - * If found, the returned Uint8Array contains just the box's content: the box - * without its name and size. - * @param {Uint8Array} buf - * @param {Number} id1 - * @param {Number} id2 - * @param {Number} id3 - * @param {Number} id4 - * @returns {Uint8Array|undefined} - */ + var chunkData = data instanceof Uint8Array ? data : new Uint8Array(data); + var isWEBM = isWEBMEmbeddedTrack(representation); + if (!segment.isInit) { + var chunkInfos = isWEBM ? null : // TODO extract time info from webm + getISOBMFFTimingInfos(chunkData, isChunked, segment, initTimescale); + var chunkOffset = (0,take_first_set/* default */.Z)(segment.timestampOffset, 0); -function getUuidContent(buf, id1, id2, id3, id4) { - var len = buf.length; - var boxSize; + if (!isWEBM) { + var parsedEMSGs = (0,utils/* parseEmsgBoxes */.s9)(chunkData); - for (var boxBaseOffset = 0; boxBaseOffset < len; boxBaseOffset += boxSize) { - var currentOffset = boxBaseOffset; - boxSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, currentOffset); - currentOffset += 4; - var boxName = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, currentOffset); - currentOffset += 4; + if (parsedEMSGs !== undefined) { + var whitelistedEMSGs = parsedEMSGs.filter(function (evt) { + if (segment.privateInfos === undefined || segment.privateInfos.isEMSGWhitelisted === undefined) { + return false; + } - if (boxSize === 0) { - boxSize = len - boxBaseOffset; - } else if (boxSize === 1) { - if (currentOffset + 8 > len) { - return undefined; + return segment.privateInfos.isEMSGWhitelisted(evt); + }); + var events = getEventsOutOfEMSGs(whitelistedEMSGs, manifest.publishTime); + + if (events !== undefined) { + var needsManifestRefresh = events.needsManifestRefresh, + inbandEvents = events.inbandEvents; + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: chunkData, + chunkInfos: chunkInfos, + chunkOffset: chunkOffset, + appendWindow: appendWindow, + inbandEvents: inbandEvents, + needsManifestRefresh: needsManifestRefresh + } + }); + } + } } - boxSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be8toi */ .pV)(buf, currentOffset); - currentOffset += 8; - } + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: chunkData, + chunkInfos: chunkInfos, + chunkOffset: chunkOffset, + appendWindow: appendWindow + } + }); + } // we're handling an initialization segment - if (boxName === 0x75756964 - /* === "uuid" */ - && currentOffset + 16 <= len && (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, currentOffset) === id1 && (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, currentOffset + 4) === id2 && (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, currentOffset + 8) === id3 && (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, currentOffset + 12) === id4) { - currentOffset += 16; - return buf.subarray(currentOffset, boxBaseOffset + boxSize); - } - } -} -/** - * For the next encountered box, return byte offsets corresponding to: - * 1. the starting byte offset for the next box (should always be equal to - * `0`). - * 2. The beginning of the box content - meaning the first byte after the - * size and the name of the box. - * 3. The first byte after the end of the box, might be equal to `buf`'s - * length if we're considering the last box. - * - * `null` if no box is found. - * @param {Uint8Array} buf - the isobmff structure - * @param {Number} boxName - the 4-letter 'name' of the box as a 4 bit integer - * generated from encoding the corresponding ASCII in big endian. - */ + var indexRange = segment.indexRange; + var nextSegments; -function getNextBoxOffsets(buf) { - var len = buf.length; + if (isWEBM) { + nextSegments = getSegmentsFromCues(chunkData, 0); + } else { + nextSegments = (0,utils/* getSegmentsFromSidx */.Wf)(chunkData, Array.isArray(indexRange) ? indexRange[0] : 0); // This is a very specific handling for streams we know have a very + // specific problem at Canal+: The last reference gives a truncated + // segment. + // Sadly, people on the packaging side could not fix all legacy contents. + // This is an easy-but-ugly fix for those. + // TODO Cleaner way? I tried to always check the obtained segment after + // a byte-range request but it leads to a lot of code. - if (len < 8) { - _log__WEBPACK_IMPORTED_MODULE_1__/* .default.warn */ .Z.warn("ISOBMFF: box inferior to 8 bytes, cannot find offsets"); - return null; - } + if (__priv_patchLastSegmentInSidx === true && nextSegments !== null && nextSegments.length > 0) { + var lastSegment = nextSegments[nextSegments.length - 1]; - var lastOffset = 0; - var boxSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, lastOffset); - lastOffset += 4; - var name = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, lastOffset); - lastOffset += 4; + if (Array.isArray(lastSegment.range)) { + lastSegment.range[1] = Infinity; + } + } + } - if (boxSize === 0) { - boxSize = len; - } else if (boxSize === 1) { - if (lastOffset + 8 > len) { - _log__WEBPACK_IMPORTED_MODULE_1__/* .default.warn */ .Z.warn("ISOBMFF: box too short, cannot find offsets"); - return null; + if (representation.index instanceof BaseRepresentationIndex && nextSegments !== null && nextSegments.length > 0) { + representation.index._addSegments(nextSegments); } - boxSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be8toi */ .pV)(buf, lastOffset); - lastOffset += 8; - } + var timescale = isWEBM ? getTimeCodeScale(chunkData, 0) : (0,utils/* getMDHDTimescale */.LD)(chunkData); + var parsedTimescale = (0,is_null_or_undefined/* default */.Z)(timescale) ? undefined : timescale; + var protectionDataUpdate = false; - if (boxSize < 0) { - throw new Error("ISOBMFF: Size out of range"); - } + if (!isWEBM) { + var psshInfo = (0,take_pssh_out/* default */.Z)(chunkData); - if (name === 0x75756964 - /* === "uuid" */ - ) { - lastOffset += 16; // Skip uuid name + if (psshInfo.length > 0) { + protectionDataUpdate = representation._addProtectionData("cenc", psshInfo); + } } - return [0, lastOffset, boxSize]; + return (0,of.of)({ + type: "parsed-init-segment", + value: { + initializationData: chunkData, + protectionDataUpdate: protectionDataUpdate, + initTimescale: parsedTimescale + } + }); + }; } - - - -/***/ }), - -/***/ 6807: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "XA": () => /* binding */ getTRAF, -/* harmony export */ "Le": () => /* binding */ getMDAT, -/* harmony export */ "fs": () => /* binding */ getMDIA -/* harmony export */ }); -/* harmony import */ var _get_box__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2297); +;// CONCATENATED MODULE: ./src/transports/utils/is_mp4_embedded_text_track.ts /** * Copyright 2015 CANAL+ Group * @@ -30581,85 +29385,15 @@ function getNextBoxOffsets(buf) { */ /** - * Returns TRAF Box from the whole ISOBMFF File. - * Returns null if not found. - * @param {Uint8Array} buffer - * @returns {Uint8Array|null} - */ - -function getTRAF(buffer) { - var moof = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(buffer, 0x6D6F6F66 - /* moof */ - ); - - if (moof === null) { - return null; - } - - return (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(moof, 0x74726166 - /* traf */ - ); -} -/** - * Returns MDAT Box from the whole ISOBMFF File. - * Returns null if not found. - * @param {Uint8Array} buffer - * @returns {Uint8Array|null} - */ - - -function getMDAT(buf) { - return (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(buf, 0x6D646174 - /* "mdat" */ - ); -} -/** - * Returns MDIA Box from the whole ISOBMFF File. - * Returns null if not found. - * @param {Uint8Array} buffer - * @returns {Uint8Array|null} + * Returns true if the given texttrack segment represents a textrack embedded + * in a mp4 file. + * @param {Representation} representation + * @returns {Boolean} */ - - -function getMDIA(buf) { - var moov = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(buf, 0x6D6F6F76 - /* moov */ - ); - - if (moov === null) { - return null; - } - - var trak = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(moov, 0x7472616B - /* "trak" */ - ); - - if (trak === null) { - return null; - } - - return (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(trak, 0x6D646961 - /* "mdia" */ - ); +function isMP4EmbeddedTextTrack(representation) { + return representation.mimeType === "application/mp4"; } - - - -/***/ }), - -/***/ 6490: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ takePSSHOut -}); - -// EXTERNAL MODULE: ./src/log.ts + 1 modules -var log = __webpack_require__(3887); -;// CONCATENATED MODULE: ./src/utils/slice_uint8array.ts +;// CONCATENATED MODULE: ./src/transports/dash/text_loader.ts /** * Copyright 2015 CANAL+ Group * @@ -30676,159 +29410,70 @@ var log = __webpack_require__(3887); * limitations under the License. */ -/** - * @param {Uint8Array} arr - The Uint8Array you want to slice - * @param {number} start - The starting byte index from the beginning - * @param {number} end - Byte index before which to end slicing. - * If end is unspecified, the new ArrayBuffer contains all bytes from begin to - * the end of this ArrayBuffer. If negative, it will make the Byte index begin - * from the last Byte. - * @returns {Uint8Array} - */ -function arraySlice(arr, start, end) { - return new Uint8Array(Array.prototype.slice.call(arr, start, end)); -} -/** - * @param {Uint8Array} arr - The Uint8Array you want to slice - * @param {number} start - The starting byte index from the beginning - * @param {number} end - Byte index before which to end slicing. - * If end is unspecified, the new ArrayBuffer contains all bytes from begin to - * the end of this ArrayBuffer. If negative, it will make the Byte index begin - * from the last Byte. - * @returns {Uint8Array} - */ -function uint8ArraySlice(arr, start, end) { - return arr.slice(start, end); -} -/* harmony default export */ const slice_uint8array = (typeof Uint8Array.prototype.slice === "function" ? uint8ArraySlice : arraySlice); -// EXTERNAL MODULE: ./src/utils/string_parsing.ts -var string_parsing = __webpack_require__(3635); -// EXTERNAL MODULE: ./src/parsers/containers/isobmff/get_box.ts -var get_box = __webpack_require__(2297); -;// CONCATENATED MODULE: ./src/parsers/containers/isobmff/take_pssh_out.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. - */ /** - * Replace every PSSH box from an ISOBMFF segment by FREE boxes and returns the - * removed PSSH in an array. - * Useful to manually manage encryption while avoiding the round-trip with the - * browser's encrypted event. - * @param {Uint8Array} data - the ISOBMFF segment - * @returns {Array.} - The extracted PSSH boxes. In the order they - * are encountered. + * Perform requests for "text" segments + * @param {boolean} lowLatencyMode + * @returns {Function} */ -function takePSSHOut(data) { - var i = 0; - var moov = (0,get_box/* getBoxContent */.t_)(data, 0x6D6F6F76 - /* moov */ - ); - - if (moov === null) { - return []; - } - - var psshBoxes = []; +function generateTextTrackLoader(_ref) { + var lowLatencyMode = _ref.lowLatencyMode, + checkMediaSegmentIntegrity = _ref.checkMediaSegmentIntegrity; + return checkMediaSegmentIntegrity !== true ? textTrackLoader : addSegmentIntegrityChecks(textTrackLoader); + /** + * @param {Object} args + * @returns {Observable} + */ - while (i < moov.length) { - var psshOffsets = void 0; + function textTrackLoader(args) { + var range = args.segment.range; + var url = args.url; - try { - psshOffsets = (0,get_box/* getBoxOffsets */.Qy)(moov, 0x70737368 - /* pssh */ - ); - } catch (e) { - log/* default.warn */.Z.warn("ISOBMFF:", e); - return psshBoxes; + if (url === null) { + return (0,of.of)({ + type: "data-created", + value: { + responseData: null + } + }); } - if (psshOffsets == null) { - return psshBoxes; + if (args.segment.isInit) { + return initSegmentLoader(url, args); } - var pssh = slice_uint8array(moov, psshOffsets[0], psshOffsets[2]); - var systemID = getSystemID(pssh, psshOffsets[1] - psshOffsets[0]); - - if (systemID !== null) { - psshBoxes.push({ - systemID: systemID, - data: pssh - }); - } // replace by `free` box. - - - moov[psshOffsets[0] + 4] = 0x66; - moov[psshOffsets[0] + 5] = 0x72; - moov[psshOffsets[0] + 6] = 0x65; - moov[psshOffsets[0] + 7] = 0x65; - i = psshOffsets[2]; - } - - return psshBoxes; -} -/** - * Parse systemID from a "pssh" box into an hexadecimal string. - * @param {Uint8Array} buff - The pssh box - * @param {number} initialDataOffset - offset of the first byte after the size - * and name in this pssh box. - * @returns {string|null} - */ + var isMP4Embedded = isMP4EmbeddedTextTrack(args.representation); -function getSystemID(buff, initialDataOffset) { - if (buff[initialDataOffset] > 1) { - log/* default.warn */.Z.warn("ISOBMFF: un-handled PSSH version"); - return null; - } + if (lowLatencyMode && isMP4Embedded) { + if (fetchIsSupported()) { + return lowLatencySegmentLoader(url, args); + } else { + (0,warn_once/* default */.Z)("DASH: Your browser does not have the fetch API. You will have " + "a higher chance of rebuffering when playing close to the live edge"); + } + } // ArrayBuffer when in mp4 to parse isobmff manually, text otherwise - var offset = initialDataOffset + 4; - /* version + flags */ - if (offset + 16 > buff.length) { - return null; + var responseType = isMP4Embedded ? "arraybuffer" : "text"; + return (0,request/* default */.ZP)({ + url: url, + responseType: responseType, + headers: Array.isArray(range) ? { + Range: (0,byte_range/* default */.Z)(range) + } : null, + sendProgressEvents: true + }); } - - var systemIDBytes = slice_uint8array(buff, offset + 16); - return (0,string_parsing/* bytesToHex */.ci)(systemIDBytes); } - -/***/ }), - -/***/ 4644: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "LD": () => /* binding */ getMDHDTimescale, -/* harmony export */ "Qx": () => /* binding */ getTrackFragmentDecodeTime, -/* harmony export */ "MM": () => /* binding */ getDurationFromTrun, -/* harmony export */ "Wf": () => /* binding */ getSegmentsFromSidx, -/* harmony export */ "J6": () => /* binding */ updateBoxLength -/* harmony export */ }); -/* unused harmony export patchPssh */ -/* harmony import */ var _utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6968); -/* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2689); -/* harmony import */ var _get_box__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2297); -/* harmony import */ var _read__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6807); +// EXTERNAL MODULE: ./src/parsers/containers/isobmff/read.ts +var read = __webpack_require__(6807); +;// CONCATENATED MODULE: ./src/transports/utils/parse_text_track.ts /** * Copyright 2015 CANAL+ Group * @@ -30847,427 +29492,422 @@ function getSystemID(buff, initialDataOffset) { +/** + * Return plain text text track from the given ISOBMFF. + * @param {Uint8Array} chunkBytes + * @returns {string} + */ - - - - +function extractTextTrackFromISOBMFF(chunkBytes) { + var mdat = (0,read/* getMDAT */.Le)(chunkBytes); + return mdat === null ? "" : (0,string_parsing/* utf8ToStr */.uR)(mdat); +} /** - * Parse the sidx part (segment index) of an ISOBMFF buffer and construct a - * corresponding Array of available segments. - * - * Returns `null` if not found. - * @param {Uint8Array} buf - * @param {Number} sidxOffsetInWholeSegment - * @returns {Object|null} {Array.} - Information about each subsegment. + * Returns the a string expliciting the format of a text track when that text + * track is embedded into a ISOBMFF file. + * @param {Object} representation + * @returns {string} */ -function getSegmentsFromSidx(buf, sidxOffsetInWholeSegment) { - var sidxOffsets = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxOffsets */ .Qy)(buf, 0x73696478 - /* "sidx" */ - ); +function getISOBMFFTextTrackFormat(representation) { + var codec = representation.codec; - if (sidxOffsets === null) { - return null; + if (codec === undefined) { + throw new Error("Cannot parse subtitles: unknown format"); } - var offset = sidxOffsetInWholeSegment; - var boxSize = sidxOffsets[2] - sidxOffsets[0]; - var cursor = sidxOffsets[1]; - /* version(8) */ - - /* flags(24) */ + switch (codec.toLowerCase()) { + case "stpp": // stpp === TTML in MP4 - /* reference_ID(32); */ + case "stpp.ttml.im1t": + return "ttml"; - /* timescale(32); */ - - var version = buf[cursor]; - cursor += 4 + 4; - var timescale = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(buf, cursor); - cursor += 4; - /* earliest_presentation_time(32 / 64) */ - - /* first_offset(32 / 64) */ - - var time; - - if (version === 0) { - time = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(buf, cursor); - cursor += 4; - offset += (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(buf, cursor) + boxSize; - cursor += 4; - } else if (version === 1) { - time = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be8toi */ .pV)(buf, cursor); - cursor += 8; - offset += (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be8toi */ .pV)(buf, cursor) + boxSize; - cursor += 8; - } else { - return null; + case "wvtt": + // wvtt === WebVTT in MP4 + return "vtt"; } - var segments = []; - /* reserved(16) */ - - /* reference_count(16) */ - - cursor += 2; - var count = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be2toi */ .zK)(buf, cursor); - cursor += 2; - - while (--count >= 0) { - /* reference_type(1) */ - - /* reference_size(31) */ + throw new Error("The codec used for the subtitles " + ("\"" + codec + "\" is not managed yet.")); +} +/** + * Returns the a string expliciting the format of a text track in plain text. + * @param {Object} representation + * @returns {string} + */ - /* segment_duration(32) */ +function getPlainTextTrackFormat(representation) { + var _representation$mimeT = representation.mimeType, + mimeType = _representation$mimeT === void 0 ? "" : _representation$mimeT; - /* sap..(32) */ - var refChunk = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(buf, cursor); - cursor += 4; - var refType = (refChunk & 0x80000000) >>> 31; - var refSize = refChunk & 0x7FFFFFFF; // when set to 1 indicates that the reference is to a sidx, else to media + switch (representation.mimeType) { + case "application/ttml+xml": + return "ttml"; - if (refType === 1) { - throw new Error("sidx with reference_type `1` not yet implemented"); - } + case "application/x-sami": + case "application/smil": + return "sami"; - var duration = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(buf, cursor); - cursor += 4; // let sapChunk = be4toi(buf, cursor + 8); + case "text/vtt": + return "vtt"; + } - cursor += 4; // TODO(pierre): handle sap - // let startsWithSap = (sapChunk & 0x80000000) >>> 31; - // let sapType = (sapChunk & 0x70000000) >>> 28; - // let sapDelta = sapChunk & 0x0FFFFFFF; + var _representation$codec = representation.codec, + codec = _representation$codec === void 0 ? "" : _representation$codec; + var codeLC = codec.toLowerCase(); - segments.push({ - time: time, - duration: duration, - count: 0, - timescale: timescale, - range: [offset, offset + refSize - 1] - }); - time += duration; - offset += refSize; + if (codeLC === "srt") { + return "srt"; } - return segments; + throw new Error("could not find a text-track parser for the type " + mimeType); } /** - * Parse track Fragment Decode Time to get a precize initial time for this - * segment (in the media timescale). - * - * Stops at the first tfdt encountered from the beginning of the file. - * Returns this time. - * `undefined` if not found. - * @param {Uint8Array} buffer - * @returns {Number | undefined} + * @param {Object} content + * @param {ArrayBuffer|UInt8Array|null} chunkData + * @param {Object|null} chunkInfos + * @param {boolean} isChunked + * @returns {Object|null} */ +function getISOBMFFEmbeddedTextTrackData(_ref, chunkBytes, chunkInfos, isChunked) { + var segment = _ref.segment, + adaptation = _ref.adaptation, + representation = _ref.representation; -function getTrackFragmentDecodeTime(buffer) { - var traf = (0,_read__WEBPACK_IMPORTED_MODULE_2__/* .getTRAF */ .XA)(buffer); - - if (traf === null) { - return undefined; + if (segment.isInit) { + return null; } - var tfdt = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(traf, 0x74666474 - /* tfdt */ - ); + var startTime; + var endTime; - if (tfdt === null) { - return undefined; + if (chunkInfos === null) { + if (!isChunked) { + log/* default.warn */.Z.warn("Transport: Unavailable time data for current text track."); + } else { + startTime = segment.time; + endTime = segment.end; + } + } else { + startTime = chunkInfos.time; + + if (chunkInfos.duration !== undefined) { + endTime = startTime + chunkInfos.duration; + } else if (!isChunked) { + endTime = startTime + segment.duration; + } } - var version = tfdt[0]; - return version === 1 ? (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be8toi */ .pV)(tfdt, 4) : version === 0 ? (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(tfdt, 4) : undefined; + var type = getISOBMFFTextTrackFormat(representation); + var textData = extractTextTrackFromISOBMFF(chunkBytes); + return { + data: textData, + type: type, + language: adaptation.language, + start: startTime, + end: endTime + }; } /** - * Returns the "default sample duration" which is the default value for duration - * of samples found in a "traf" ISOBMFF box. - * - * Returns `undefined` if no "default sample duration" has been found. - * @param {Uint8Array} traf - * @returns {number|undefined} + * @param {Object} content + * @param {ArrayBuffer|UInt8Array|null} chunkData + * @param {Object|null} chunkInfos + * @param {boolean} isChunked + * @returns {Object|null} */ +function getPlainTextTrackData(_ref2, textTrackData, isChunked) { + var segment = _ref2.segment, + adaptation = _ref2.adaptation, + representation = _ref2.representation; -function getDefaultDurationFromTFHDInTRAF(traf) { - var tfhd = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(traf, 0x74666864 - /* tfhd */ - ); - - if (tfhd === null) { - return undefined; - } - - var cursor = - /* version */ - 1; - var flags = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be3toi */ .QI)(tfhd, cursor); - cursor += 3; - var hasBaseDataOffset = (flags & 0x000001) > 0; - var hasSampleDescriptionIndex = (flags & 0x000002) > 0; - var hasDefaultSampleDuration = (flags & 0x000008) > 0; - - if (!hasDefaultSampleDuration) { - return undefined; - } - - cursor += 4; - - if (hasBaseDataOffset) { - cursor += 8; + if (segment.isInit) { + return null; } - if (hasSampleDescriptionIndex) { - cursor += 4; + if (isChunked) { + log/* default.warn */.Z.warn("Transport: Unavailable time data for current text track."); } - var defaultDuration = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(tfhd, cursor); - return defaultDuration; + var type = getPlainTextTrackFormat(representation); + return { + data: textTrackData, + type: type, + language: adaptation.language + }; } +;// CONCATENATED MODULE: ./src/transports/dash/text_parser.ts /** - * Calculate segment duration approximation by additioning the duration from - * every samples in a trun ISOBMFF box. + * Copyright 2015 CANAL+ Group * - * Returns `undefined` if we could not parse the duration. - * @param {Uint8Array} buffer - * @returns {number | undefined} + * 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 getDurationFromTrun(buffer) { - var traf = (0,_read__WEBPACK_IMPORTED_MODULE_2__/* .getTRAF */ .XA)(buffer); - - if (traf === null) { - return undefined; - } - - var trun = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(traf, 0x7472756E - /* trun */ - ); - - if (trun === null) { - return undefined; - } - var cursor = 0; - var version = trun[cursor]; - cursor += 1; - if (version > 1) { - return undefined; - } - var flags = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be3toi */ .QI)(trun, cursor); - cursor += 3; - var hasSampleDuration = (flags & 0x000100) > 0; - var defaultDuration = 0; - if (!hasSampleDuration) { - defaultDuration = getDefaultDurationFromTFHDInTRAF(traf); - if (defaultDuration === undefined) { - return undefined; - } - } - var hasDataOffset = (flags & 0x000001) > 0; - var hasFirstSampleFlags = (flags & 0x000004) > 0; - var hasSampleSize = (flags & 0x000200) > 0; - var hasSampleFlags = (flags & 0x000400) > 0; - var hasSampleCompositionOffset = (flags & 0x000800) > 0; - var sampleCounts = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(trun, cursor); - cursor += 4; +/** + * Parse TextTrack data when it is embedded in an ISOBMFF file. + * @param {Object} infos + * @returns {Observable.} + */ - if (hasDataOffset) { - cursor += 4; - } +function parseISOBMFFEmbeddedTextTrack(_ref, __priv_patchLastSegmentInSidx) { + var response = _ref.response, + content = _ref.content, + initTimescale = _ref.initTimescale; + var period = content.period, + representation = content.representation, + segment = content.segment; + var isInit = segment.isInit, + indexRange = segment.indexRange; + var data = response.data, + isChunked = response.isChunked; + var chunkBytes = typeof data === "string" ? (0,string_parsing/* strToUtf8 */.tG)(data) : data instanceof Uint8Array ? data : new Uint8Array(data); - if (hasFirstSampleFlags) { - cursor += 4; - } + if (isInit) { + var sidxSegments = (0,utils/* getSegmentsFromSidx */.Wf)(chunkBytes, Array.isArray(indexRange) ? indexRange[0] : 0); // This is a very specific handling for streams we know have a very + // specific problem at Canal+: The last reference gives a truncated + // segment. + // Sadly, people on the packaging side could not fix all legacy contents. + // This is an easy-but-ugly fix for those. + // TODO Cleaner way? I tried to always check the obtained segment after + // a byte-range request but it leads to a lot of code. - var i = sampleCounts; - var duration = 0; + if (__priv_patchLastSegmentInSidx === true && sidxSegments !== null && sidxSegments.length > 0) { + var lastSegment = sidxSegments[sidxSegments.length - 1]; - while (i-- > 0) { - if (hasSampleDuration) { - duration += (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(trun, cursor); - cursor += 4; - } else { - duration += defaultDuration; + if (Array.isArray(lastSegment.range)) { + lastSegment.range[1] = Infinity; + } } - if (hasSampleSize) { - cursor += 4; - } + var mdhdTimescale = (0,utils/* getMDHDTimescale */.LD)(chunkBytes); - if (hasSampleFlags) { - cursor += 4; + if (representation.index instanceof BaseRepresentationIndex && sidxSegments !== null && sidxSegments.length > 0) { + representation.index._addSegments(sidxSegments); } - if (hasSampleCompositionOffset) { - cursor += 4; - } + return (0,of.of)({ + type: "parsed-init-segment", + value: { + initializationData: null, + protectionDataUpdate: false, + initTimescale: mdhdTimescale + } + }); } - return duration; + var chunkInfos = getISOBMFFTimingInfos(chunkBytes, isChunked, segment, initTimescale); + var chunkData = getISOBMFFEmbeddedTextTrackData(content, chunkBytes, chunkInfos, isChunked); + var chunkOffset = (0,take_first_set/* default */.Z)(segment.timestampOffset, 0); + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: chunkData, + chunkInfos: chunkInfos, + chunkOffset: chunkOffset, + appendWindow: [period.start, period.end] + } + }); } /** - * Get timescale information from a movie header box. Found in init segments. - * `undefined` if not found or not parsed. - * - * This timescale is the default timescale used for segments. - * @param {Uint8Array} buffer - * @returns {Number | undefined} + * Parse TextTrack data in plain text form. + * @param {Object} infos + * @returns {Observable.} */ -function getMDHDTimescale(buffer) { - var mdia = (0,_read__WEBPACK_IMPORTED_MODULE_2__/* .getMDIA */ .fs)(buffer); +function parsePlainTextTrack(_ref2) { + var response = _ref2.response, + content = _ref2.content; + var period = content.period, + segment = content.segment; + var _segment$timestampOff = segment.timestampOffset, + timestampOffset = _segment$timestampOff === void 0 ? 0 : _segment$timestampOff; - if (mdia === null) { - return undefined; + if (segment.isInit) { + return (0,of.of)({ + type: "parsed-init-segment", + value: { + initializationData: null, + protectionDataUpdate: false, + initTimescale: undefined + } + }); } - var mdhd = (0,_get_box__WEBPACK_IMPORTED_MODULE_0__/* .getBoxContent */ .t_)(mdia, 0x6D646864 - /* "mdhd" */ - ); + var data = response.data, + isChunked = response.isChunked; + var textTrackData; - if (mdhd === null) { - return undefined; + if (typeof data !== "string") { + var bytesData = data instanceof Uint8Array ? data : new Uint8Array(data); + textTrackData = (0,string_parsing/* utf8ToStr */.uR)(bytesData); + } else { + textTrackData = data; } - var cursor = 0; - var version = mdhd[cursor]; - cursor += 4; - return version === 1 ? (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(mdhd, cursor + 16) : version === 0 ? (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(mdhd, cursor + 8) : undefined; -} -/** - * Creates a PSSH box with the given systemId and data. - * @param {Array.} psshInfo - * @returns {Uint8Array} - */ - - -function createPssh(_ref) { - var systemId = _ref.systemId, - privateData = _ref.privateData; - - var _systemId = systemId.replace(/-/g, ""); - - assert(_systemId.length === 32); - return createBox("pssh", concat(4, // 4 initial zeroed bytes - hexToBytes(_systemId), itobe4(privateData.length), privateData)); + var chunkData = getPlainTextTrackData(content, textTrackData, isChunked); + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: chunkData, + chunkInfos: null, + chunkOffset: timestampOffset, + appendWindow: [period.start, period.end] + } + }); } /** - * Update ISOBMFF given to add a "pssh" box in the "moov" box for every content - * protection in the psshList array given. - * @param {Uint8Array} buf - the ISOBMFF file - * @param {Array.} psshList - * @returns {Uint8Array} - The new ISOBMFF generated. + * @param {Object} config + * @returns {Function} */ -function patchPssh(buf, psshList) { - if (psshList == null || psshList.length === 0) { - return buf; - } +function generateTextTrackParser(_ref3) { + var __priv_patchLastSegmentInSidx = _ref3.__priv_patchLastSegmentInSidx; - var moovOffsets = getBoxOffsets(buf, 0x6D6F6F76 - /* = "moov" */ - ); + /** + * Parse TextTrack data. + * @param {Object} infos + * @returns {Observable.} + */ + return function textTrackParser(_ref4) { + var response = _ref4.response, + content = _ref4.content, + initTimescale = _ref4.initTimescale; + var period = content.period, + representation = content.representation, + segment = content.segment; + var _segment$timestampOff2 = segment.timestampOffset, + timestampOffset = _segment$timestampOff2 === void 0 ? 0 : _segment$timestampOff2; + var data = response.data, + isChunked = response.isChunked; - if (moovOffsets === null) { - return buf; - } + if (data === null) { + // No data, just return empty infos + if (segment.isInit) { + return (0,of.of)({ + type: "parsed-init-segment", + value: { + initializationData: null, + protectionDataUpdate: false, + initTimescale: undefined + } + }); + } - var moov = buf.subarray(moovOffsets[0], moovOffsets[2]); - var moovArr = [moov]; + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: null, + chunkInfos: null, + chunkOffset: timestampOffset, + appendWindow: [period.start, period.end] + } + }); + } - for (var i = 0; i < psshList.length; i++) { - moovArr.push(createPssh(psshList[i])); - } + var isMP4 = isMP4EmbeddedTextTrack(representation); - var newmoov = updateBoxLength(concat.apply(void 0, moovArr)); - return concat(buf.subarray(0, moovOffsets[0]), newmoov, buf.subarray(moovOffsets[2])); + if (isMP4) { + return parseISOBMFFEmbeddedTextTrack({ + response: { + data: data, + isChunked: isChunked + }, + content: content, + initTimescale: initTimescale + }, __priv_patchLastSegmentInSidx); + } else { + return parsePlainTextTrack({ + response: { + data: data, + isChunked: isChunked + }, + content: content + }); + } + }; } +;// CONCATENATED MODULE: ./src/transports/dash/pipelines.ts /** - * Returns a new version of the given box with the size updated - * so it reflects its actual size. + * Copyright 2015 CANAL+ Group * - * You can use this function after modifying a ISOBMFF box so its size is - * updated. + * 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 * - * /!\ Please consider that this function might mutate the given Uint8Array - * in place or might create a new one, depending on the current conditions. - * @param {Uint8Array} buf - The ISOBMFF box - * @returns {Uint8Array} + * 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 updateBoxLength(buf) { - var newLen = buf.length; - if (newLen < 4) { - throw new Error("Cannot update box length: box too short"); - } - var oldSize = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .be4toi */ .pX)(buf, 0); - if (oldSize === 0) { - if (newLen > _constants__WEBPACK_IMPORTED_MODULE_3__/* .MAX_32_BIT_INT */ .s) { - var newBox = new Uint8Array(newLen + 8); - newBox.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe4 */ .kh)(1), 0); - newBox.set(buf.subarray(4, 8), 4); - newBox.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe8 */ .el)(newLen + 8), 8); - newBox.set(buf.subarray(8, newLen), 16); - return newBox; - } else { - buf.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe4 */ .kh)(newLen), 0); - return buf; - } - } else if (oldSize === 1) { - if (newLen < 16) { - throw new Error("Cannot update box length: box too short"); - } - buf.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe8 */ .el)(newLen), 8); - return buf; - } else if (newLen <= _constants__WEBPACK_IMPORTED_MODULE_3__/* .MAX_32_BIT_INT */ .s) { - buf.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe4 */ .kh)(newLen), 0); - return buf; - } else { - var _newBox = new Uint8Array(newLen + 8); - - _newBox.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe4 */ .kh)(1), 0); - - _newBox.set(buf.subarray(4, 8), 4); - - _newBox.set((0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .itobe8 */ .el)(newLen + 8), 8); - _newBox.set(buf.subarray(8, newLen), 16); +/** + * Returns pipelines used for DASH streaming. + * @param {Object} options + * implementation. Used for each generated http request. + * @returns {Object} + */ - return _newBox; - } +/* harmony default export */ function pipelines(options) { + var manifestLoader = (0,text_manifest_loader/* default */.Z)({ + customManifestLoader: options.manifestLoader + }); + var manifestParser = generateManifestParser(options); + var segmentLoader = generateSegmentLoader(options); + var audioVideoSegmentParser = generateAudioVideoSegmentParser(options); + var textTrackLoader = generateTextTrackLoader(options); + var textTrackParser = generateTextTrackParser(options); + return { + manifest: { + loader: manifestLoader, + parser: manifestParser + }, + audio: { + loader: segmentLoader, + parser: audioVideoSegmentParser + }, + video: { + loader: segmentLoader, + parser: audioVideoSegmentParser + }, + text: { + loader: textTrackLoader, + parser: textTrackParser + }, + image: { + loader: imageLoader, + parser: imageParser + } + }; } - - - -/***/ }), - -/***/ 3203: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ -/* harmony export */ }); -/* harmony import */ var _utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6968); -/* harmony import */ var _utils_string_parsing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3635); +;// CONCATENATED MODULE: ./src/transports/dash/index.ts /** * Copyright 2015 CANAL+ Group * @@ -31289,115 +29929,125 @@ function updateBoxLength(buf) { * It always should be imported through the `features` object. */ +/* harmony default export */ const transports_dash = (pipelines); -/** - * @param {UInt8Array} buf - * @returns {Object} - */ - -function parseBif(buf) { - var pos = 0; - var length = buf.length; - var fileFormat = (0,_utils_string_parsing__WEBPACK_IMPORTED_MODULE_0__/* .utf8ToStr */ .uR)(buf.subarray(pos + 1, pos + 8)); - pos += 8; +/***/ }), - if (buf[0] !== 0x89 || fileFormat !== "BIF\r\n\x1A\n") { - throw new Error("Invalid BIF file"); - } +/***/ 2339: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - var minorVersion = buf[pos]; - pos += 1; - var majorVersion = buf[pos]; - pos += 1; - var patchVersion = buf[pos]; - pos += 1; - var increVersion = buf[pos]; - pos += 1; - var version = [minorVersion, majorVersion, patchVersion, increVersion].join("."); +"use strict"; - if (majorVersion > 0) { - throw new Error("Unhandled version: " + majorVersion); - } +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ transports_smooth) +}); - var imageCount = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .le4toi */ .dN)(buf, pos); - pos += 4; - var framewiseSeparation = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .le4toi */ .dN)(buf, pos); - pos += 4; - var format = (0,_utils_string_parsing__WEBPACK_IMPORTED_MODULE_0__/* .utf8ToStr */ .uR)(buf.subarray(pos, pos + 4)); - pos += 4; - var width = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .le2toi */ .qb)(buf, pos); - pos += 2; - var height = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .le2toi */ .qb)(buf, pos); - pos += 2; - var aspectRatio = [buf[pos], buf[pos + 1]].join(":"); - pos += 2; - var isVod = buf[pos] === 1; // bytes 0x1F to 0x40 is unused data for now +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js +var of = __webpack_require__(8170); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/map.js +var map = __webpack_require__(5709); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/tap.js +var tap = __webpack_require__(3068); +// EXTERNAL MODULE: ./src/features/index.ts +var features = __webpack_require__(7874); +// EXTERNAL MODULE: ./src/log.ts + 1 modules +var log = __webpack_require__(3887); +// EXTERNAL MODULE: ./src/manifest/index.ts + 10 modules +var src_manifest = __webpack_require__(1966); +// EXTERNAL MODULE: ./src/parsers/containers/isobmff/read.ts +var read = __webpack_require__(6807); +// EXTERNAL MODULE: ./src/utils/array_includes.ts +var array_includes = __webpack_require__(7714); +// EXTERNAL MODULE: ./src/utils/assert.ts +var assert = __webpack_require__(811); +// EXTERNAL MODULE: ./src/utils/byte_parsing.ts +var byte_parsing = __webpack_require__(6968); +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +// EXTERNAL MODULE: ./src/utils/object_assign.ts +var object_assign = __webpack_require__(8026); +// EXTERNAL MODULE: ./src/utils/resolve_url.ts +var resolve_url = __webpack_require__(9829); +// EXTERNAL MODULE: ./src/utils/string_parsing.ts +var string_parsing = __webpack_require__(3635); +// EXTERNAL MODULE: ./src/utils/take_first_set.ts +var take_first_set = __webpack_require__(5278); +// EXTERNAL MODULE: ./src/parsers/containers/isobmff/constants.ts +var constants = __webpack_require__(2689); +;// CONCATENATED MODULE: ./src/parsers/containers/isobmff/create_box.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. + */ - pos = 0x40; - var thumbs = []; - if (imageCount === 0) { - throw new Error("bif: no images to parse"); - } - var index = 0; - var previousImageInfo = null; +/** + * Speed up string to bytes conversion by memorizing the result + * + * The keys here are ISOBMFF box names. The values are the corresponding + * bytes conversion for putting as an ISOBMFF boxes. + * + * Used by the boxName method. + * @type {Object} + */ - while (pos < length) { - var currentImageTimestamp = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .le4toi */ .dN)(buf, pos); - pos += 4; - var currentImageOffset = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_1__/* .le4toi */ .dN)(buf, pos); - pos += 4; +var boxNamesMem = {}; +/** + * Convert the string name of an ISOBMFF box into the corresponding bytes. + * Has a memorization mechanism to speed-up if you want to translate the + * same string multiple times. + * @param {string} str + * @returns {Uint8Array} + */ - if (previousImageInfo !== null) { - // calculate for index-1 - var ts = previousImageInfo.timestamp * framewiseSeparation; - var duration = framewiseSeparation; - var data = buf.slice(previousImageInfo.offset, currentImageOffset); - thumbs.push({ - index: index, - duration: duration, - ts: ts, - data: data - }); - index++; - } +function boxName(str) { + if (boxNamesMem[str] != null) { + return boxNamesMem[str]; + } - if (currentImageTimestamp === 0xFFFFFFFF) { - break; - } + var nameInBytes = (0,string_parsing/* strToUtf8 */.tG)(str); + boxNamesMem[str] = nameInBytes; + return nameInBytes; +} +/** + * Create a new ISOBMFF "box" with the given name. + * @param {string} name - name of the box you want to create, must always + * be 4 characters (uuid boxes not supported) + * @param {Uint8Array} buff - content of the box + * @returns {Uint8Array} - The entire ISOBMFF box (length+name+content) + */ - previousImageInfo = { - timestamp: currentImageTimestamp, - offset: currentImageOffset - }; - } - return { - fileFormat: "BIF", - version: version, - imageCount: imageCount, - timescale: 1000, - format: format, - width: width, - height: height, - aspectRatio: aspectRatio, - isVod: isVod, - thumbs: thumbs - }; +function createBox(name, buff) { + var len = buff.length + 8; + return len <= constants/* MAX_32_BIT_INT */.s ? (0,byte_parsing/* concat */.zo)((0,byte_parsing/* itobe4 */.kh)(len), boxName(name), buff) : (0,byte_parsing/* concat */.zo)((0,byte_parsing/* itobe4 */.kh)(1), boxName(name), (0,byte_parsing/* itobe8 */.el)(len + 8), buff); } +/** + * @param {string} name + * @param {Array.} children + * @returns {Uint8Array} + */ -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (parseBif); -/***/ }), +function createBoxWithChildren(name, children) { + return createBox(name, byte_parsing/* concat.apply */.zo.apply(void 0, children)); +} -/***/ 8232: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ clearTimelineFromPosition -/* harmony export */ }); +;// CONCATENATED MODULE: ./src/parsers/manifest/utils/check_manifest_ids.ts /** * Copyright 2015 CANAL+ Group * @@ -31414,71 +30064,76 @@ function parseBif(buf) { * limitations under the License. */ + /** - * Remove segments which starts before the given `firstAvailablePosition` from - * the timeline. `firstAvailablePosition` has to be time scaled. - * @param {Array.} - * @returns {number} + * Ensure that no two periods, adaptations from the same period and + * representations from the same adaptation, have the same ID. + * + * Log and mutate their ID if not until this is verified. + * + * @param {Object} manifest */ -function clearTimelineFromPosition(timeline, firstAvailablePosition) { - while (timeline.length > 0) { - var firstElt = timeline[0]; - if (firstElt.start >= firstAvailablePosition) { - return; // all clear - } +function checkManifestIDs(manifest) { + var periodIDS = []; + manifest.periods.forEach(function (period) { + var periodID = period.id; - if (firstElt.repeatCount <= 0) { - timeline.shift(); + if ((0,array_includes/* default */.Z)(periodIDS, periodID)) { + log/* default.warn */.Z.warn("Two periods with the same ID found. Updating."); + var newID = periodID + "-dup"; + period.id = newID; + checkManifestIDs(manifest); + periodIDS.push(newID); } else { - // we have a segment repetition - var nextElt = timeline[1]; + periodIDS.push(periodID); + } - if (nextElt != null && nextElt.start <= firstAvailablePosition) { - timeline.shift(); - } else { - // no next segment or next segment is available - if (firstElt.duration <= 0) { - return; - } + var adaptations = period.adaptations; + var adaptationIDs = []; + Object.keys(adaptations).forEach(function (type) { + var adaptationsForType = adaptations[type]; - var nextStart = firstElt.start + firstElt.duration; - var nextRepeat = 1; + if (adaptationsForType === undefined) { + return; + } - while (nextStart < firstAvailablePosition && nextRepeat <= firstElt.repeatCount) { - nextStart += firstElt.duration; - nextRepeat++; - } + adaptationsForType.forEach(function (adaptation) { + var adaptationID = adaptation.id; - if (nextRepeat > firstElt.repeatCount) { - // every start is before - timeline.shift(); + if ((0,array_includes/* default */.Z)(adaptationIDs, adaptationID)) { + log/* default.warn */.Z.warn("Two adaptations with the same ID found. Updating.", adaptationID); + + var _newID = adaptationID + "-dup"; + + adaptation.id = _newID; + checkManifestIDs(manifest); + adaptationIDs.push(_newID); } else { - // some repetitions start after and some before - var newRepeat = firstElt.repeatCount - nextRepeat; - firstElt.start = nextStart; - firstElt.repeatCount = newRepeat; - return; + adaptationIDs.push(adaptationID); } - } - } - } -} -/***/ }), + var representationIDs = []; + adaptation.representations.forEach(function (representation) { + var representationID = representation.id; -/***/ 3911: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if ((0,array_includes/* default */.Z)(representationIDs, representationID)) { + log/* default.warn */.Z.warn("Two representations with the same ID found. Updating.", representationID); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "KF": () => /* binding */ calculateRepeat, -/* harmony export */ "jH": () => /* binding */ getIndexSegmentEnd, -/* harmony export */ "gT": () => /* binding */ toIndexTime, -/* harmony export */ "zG": () => /* binding */ fromIndexTime, -/* harmony export */ "PZ": () => /* binding */ getTimescaledRange, -/* harmony export */ "_j": () => /* binding */ checkDiscontinuity -/* harmony export */ }); + var _newID2 = representationID + "-dup"; + + representation.id = _newID2; + checkManifestIDs(manifest); + representationIDs.push(_newID2); + } else { + representationIDs.push(representationID); + } + }); + }); + }); + }); +} +;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/get_codecs.ts /** * Copyright 2015 CANAL+ Group * @@ -31494,170 +30149,120 @@ function clearTimelineFromPosition(timeline, firstAvailablePosition) { * See the License for the specific language governing permissions and * limitations under the License. */ -// byte-range /** - * Calculate the number of times a timeline element repeats based on the next - * element. - * @param {Object} element - * @param {Object} nextElement - * @param {number} maxPosition - * @returns {Number} + * @param {string} codecPrivateData + * @param {string|undefined} fourCC + * @returns {string} */ -function calculateRepeat(element, nextElement, maxPosition) { - var repeatCount = element.repeatCount; - - if (repeatCount >= 0) { - return repeatCount; - } // A negative value of the @r attribute of the S element indicates - // that the duration indicated in @d attribute repeats until the - // start of the next S element, the end of the Period or until the - // next MPD update. - - var segmentEnd; +function getAudioCodecs(codecPrivateData, fourCC) { + var mpProfile; - if (nextElement != null) { - segmentEnd = nextElement.start; - } else if (maxPosition != null) { - segmentEnd = maxPosition; + if (fourCC === "AACH") { + mpProfile = 5; // High Efficiency AAC Profile } else { - segmentEnd = Number.MAX_VALUE; + mpProfile = (0,is_non_empty_string/* default */.Z)(codecPrivateData) ? (parseInt(codecPrivateData.substring(0, 2), 16) & 0xF8) >> 3 : 2; } - return Math.ceil((segmentEnd - element.start) / element.duration) - 1; + if (mpProfile === 0) { + // Return default audio codec + return "mp4a.40.2"; + } + + return "mp4a.40." + mpProfile; } /** - * Returns end of the segment given, in index time. - * @param {Object} segment - * @param {Object|null} [nextSegment] - * @param {number} maxPosition - * @returns {Number} + * @param {string} codecPrivateData + * @returns {string} */ -function getIndexSegmentEnd(segment, nextSegment, maxPosition) { - var start = segment.start, - duration = segment.duration; +function getVideoCodecs(codecPrivateData) { + // we can extract codes only if fourCC is on of "H264", "X264", "DAVC", "AVC1" + var arr = /00000001\d7([0-9a-fA-F]{6})/.exec(codecPrivateData); - if (duration <= 0) { - return start; + if (arr === null || !(0,is_non_empty_string/* default */.Z)(arr[1])) { + // Return default video codec + return "avc1.4D401E"; } - var repeat = calculateRepeat(segment, nextSegment, maxPosition); - return start + (repeat + 1) * duration; + return "avc1." + arr[1]; } +;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/parse_C_nodes.ts /** - * Convert from `presentationTime`, the time of the segment at the moment it - * is decoded to `mediaTime`, the original time the segments point at. - * @param {number} time - * @param {Object} indexOptions - * @returns {number} + * 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 toIndexTime(time, indexOptions) { - var _a; - - return time * indexOptions.timescale + ((_a = indexOptions.indexTimeOffset) !== null && _a !== void 0 ? _a : 0); -} /** - * Convert from `mediaTime`, the original time the segments point at to - * `presentationTime`, the time of the segment at the moment it is decoded. - * @param {number} time - * @param {Object} indexOptions - * @returns {number} + * Parse C nodes to build index timeline. + * @param {Element} nodes */ -function fromIndexTime(time, indexOptions) { - var _a; +function parseCNodes(nodes) { + return nodes.reduce(function (timeline, node, i) { + var dAttr = node.getAttribute("d"); + var tAttr = node.getAttribute("t"); + var rAttr = node.getAttribute("r"); + var repeatCount = rAttr !== null ? +rAttr - 1 : 0; + var start = tAttr !== null ? +tAttr : undefined; + var duration = dAttr !== null ? +dAttr : undefined; - return (time - ((_a = indexOptions.indexTimeOffset) !== null && _a !== void 0 ? _a : 0)) / indexOptions.timescale; -} -/** - * @param {Number} start - * @param {Number} duration - * @param {Number} timescale - * @returns {Object} - Object with two properties: - * - up {Number}: timescaled timestamp of the beginning time - * - to {Number}: timescaled timestamp of the end time (start time + duration) - */ + if (i === 0) { + // first node + start = start === undefined || isNaN(start) ? 0 : start; + } else { + // from second node to the end + var prev = timeline[i - 1]; -function getTimescaledRange(start, duration, timescale) { - return [start * timescale, (start + duration) * timescale]; -} -/** - * Get index of the last segment in the timeline starting before/at the given - * timescaled time. - * Returns -1 if the given time is lower than the start of the first available - * segment. - * @param {Object} index - * @param {Number} timeTScaled - * @returns {Number} - */ + if (start == null || isNaN(start)) { + if (prev.duration == null || isNaN(prev.duration)) { + throw new Error("Smooth: Invalid CNodes. Missing timestamp."); + } -function getIndexOfLastObjectBefore(timeline, timeTScaled) { - var low = 0; - var high = timeline.length; + start = prev.start + prev.duration * (prev.repeatCount + 1); + } + } - while (low < high) { - var mid = low + high >>> 1; // Divide by two + floor - - if (timeline[mid].start <= timeTScaled) { - low = mid + 1; - } else { - high = mid; - } - } - - return low - 1; -} -/** - * @param {Object} index - * @param {number} timeSec - * @param {number} [maxPosition] - * @returns {number|null} - */ - - -function checkDiscontinuity(index, timeSec, maxPosition) { - var timeline = index.timeline; - var scaledTime = toIndexTime(timeSec, index); - - if (scaledTime < 0) { - return null; - } - - var segmentIndex = getIndexOfLastObjectBefore(timeline, scaledTime); - - if (segmentIndex < 0 || segmentIndex >= timeline.length - 1) { - return null; - } - - var timelineItem = timeline[segmentIndex]; + if (duration == null || isNaN(duration)) { + var nextNode = nodes[i + 1]; - if (timelineItem.duration <= 0) { - return null; - } + if (nextNode !== undefined) { + var nextTAttr = nextNode.getAttribute("t"); + var nextStart = (0,is_non_empty_string/* default */.Z)(nextTAttr) ? +nextTAttr : null; - var nextTimelineItem = timeline[segmentIndex + 1]; + if (nextStart === null) { + throw new Error("Can't build index timeline from Smooth Manifest."); + } - if (nextTimelineItem === undefined) { - return null; - } + duration = nextStart - start; + } else { + return timeline; + } + } - var nextStart = nextTimelineItem.start; - var segmentEnd = getIndexSegmentEnd(timelineItem, nextTimelineItem, maxPosition); - return scaledTime >= segmentEnd && scaledTime < nextStart ? fromIndexTime(nextStart, index) : null; + timeline.push({ + duration: duration, + start: start, + repeatCount: repeatCount + }); + return timeline; + }, []); } - -/***/ }), - -/***/ 1091: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ isSegmentStillAvailable -/* harmony export */ }); +// EXTERNAL MODULE: ./src/utils/base64.ts +var base64 = __webpack_require__(9689); +;// CONCATENATED MODULE: ./src/parsers/containers/isobmff/drm/playready.ts /** * Copyright 2015 CANAL+ Group * @@ -31674,59 +30279,29 @@ function checkDiscontinuity(index, timeSec, maxPosition) { * limitations under the License. */ + + /** - * Returns true if a Segment returned by the corresponding index is still - * considered available. - * Returns false if it is not available anymore. - * Returns undefined if we cannot know whether it is still available or not. - * /!\ We do not check the mediaURLs of the segment. - * @param {Object} segment - * @param {Array.} timescale - * @param {number} timeline - * @returns {Boolean|undefined} + * Parse PlayReady privateData to get its Hexa-coded KeyID. + * @param {Uint8Array} privateData + * @returns {string} */ -function isSegmentStillAvailable(segment, timeline, timescale, indexTimeOffset) { - for (var i = 0; i < timeline.length; i++) { - var tSegment = timeline[i]; - var tSegmentTime = (tSegment.start - indexTimeOffset) / timescale; - - if (tSegmentTime > segment.time) { - return false; - } else if (tSegmentTime === segment.time) { - if (tSegment.duration / timescale !== segment.duration) { - return false; - } - if (tSegment.range == null) { - return segment.range == null; - } +function getPlayReadyKIDFromPrivateData(data) { + var xmlLength = (0,byte_parsing/* le2toi */.qb)(data, 8); + var xml = (0,string_parsing/* utf16LEToStr */.wV)(data.subarray(10, xmlLength + 10)); + var doc = new DOMParser().parseFromString(xml, "application/xml"); + var kidElement = doc.querySelector("KID"); - return segment.range != null && tSegment.range[0] === segment.range[0] && tSegment.range[1] === segment.range[1]; - } else { - // tSegment.start < segment.time - if (tSegment.repeatCount >= 0 && tSegment.duration != null) { - var timeDiff = tSegmentTime - tSegment.start; - var repeat = timeDiff / tSegment.duration - 1; - return repeat % 1 === 0 && repeat <= tSegment.repeatCount; - } - } + if (kidElement === null) { + throw new Error("Cannot parse PlayReady private data: invalid XML"); } - return false; + var b64guidKid = kidElement.textContent === null ? "" : kidElement.textContent; + var uuidKid = (0,string_parsing/* guidToUuid */.wO)((0,base64/* base64ToBytes */.K)(b64guidKid)); + return (0,string_parsing/* bytesToHex */.ci)(uuidKid).toLowerCase(); } - -/***/ }), - -/***/ 5505: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ updateSegmentTimeline -/* harmony export */ }); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3714); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3887); -/* harmony import */ var _index_helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3911); +;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/parse_protection_node.ts /** * Copyright 2015 CANAL+ Group * @@ -31745,130 +30320,130 @@ function isSegmentStillAvailable(segment, timeline, timescale, indexTimeOffset) + /** - * Update a complete array of segments in a given timeline with a [generally] - * smaller but [generally] newer set of segments. - * @param {Array.} oldTimeline - * @param {Array.} newTimeline + * @param {Uint8Array} keyIdBytes + * @returns {Array.} */ -function updateSegmentTimeline(oldTimeline, newTimeline) { - var prevTimelineLength = oldTimeline.length; +function createWidevineKeySystem(keyIdBytes) { + return [{ + systemId: "edef8ba9-79d6-4ace-a3c8-27dcd51d21ed", + privateData: (0,byte_parsing/* concat */.zo)([0x08, 0x01, 0x12, 0x10], keyIdBytes) + }]; +} +/** + * Parse "Protection" Node, which contains DRM information + * @param {Element} protectionNode + * @returns {Object} + */ - if (oldTimeline.length === 0) { - oldTimeline.splice.apply(oldTimeline, [0, prevTimelineLength].concat(newTimeline)); - return; - } - if (newTimeline.length === 0) { - return; +function parseProtectionNode(protectionNode, keySystemCreator) { + if (keySystemCreator === void 0) { + keySystemCreator = createWidevineKeySystem; } - var newIndexStart = newTimeline[0].start; - var oldLastElt = oldTimeline[prevTimelineLength - 1]; - var oldIndexEnd = (0,_index_helpers__WEBPACK_IMPORTED_MODULE_0__/* .getIndexSegmentEnd */ .jH)(oldLastElt, newTimeline[0]); - - if (oldIndexEnd < newIndexStart) { - throw new _errors__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z("MANIFEST_UPDATE_ERROR", "Cannot perform partial update: not enough data"); + if (protectionNode.firstElementChild === null || protectionNode.firstElementChild.nodeName !== "ProtectionHeader") { + throw new Error("Protection should have ProtectionHeader child"); } - for (var i = prevTimelineLength - 1; i >= 0; i--) { - var currStart = oldTimeline[i].start; - - if (currStart === newIndexStart) { - // replace that one and those after it - oldTimeline.splice.apply(oldTimeline, [i, prevTimelineLength - i].concat(newTimeline)); - return; - } else if (currStart < newIndexStart) { - // first to be before - var currElt = oldTimeline[i]; - - if (currElt.start + currElt.duration > newIndexStart) { - // the new Manifest overlaps a previous segment (weird). Remove the latter. - _log__WEBPACK_IMPORTED_MODULE_2__/* .default.warn */ .Z.warn("RepresentationIndex: Manifest update removed previous segments"); - oldTimeline.splice.apply(oldTimeline, [i, prevTimelineLength - i].concat(newTimeline)); - return; - } else if (currElt.repeatCount === undefined || currElt.repeatCount <= 0) { - if (currElt.repeatCount < 0) { - currElt.repeatCount = Math.floor((newIndexStart - currElt.start) / currElt.duration) - 1; - } - - oldTimeline.splice.apply(oldTimeline, [i + 1, prevTimelineLength - (i + 1)].concat(newTimeline)); - return; - } // else, there is a positive repeat we might want to update - - - var eltLastTime = currElt.start + currElt.duration * (currElt.repeatCount + 1); - - if (eltLastTime <= newIndexStart) { - // our new index comes directly after - // put it after this one - oldTimeline.splice.apply(oldTimeline, [i + 1, prevTimelineLength - (i + 1)].concat(newTimeline)); - return; - } - - var newCurrRepeat = (newIndexStart - currElt.start) / currElt.duration - 1; - - if (newCurrRepeat % 1 === 0 && currElt.duration === newTimeline[0].duration) { - var newRepeatCount = newTimeline[0].repeatCount < 0 ? -1 : // === maximum possible repeat - newTimeline[0].repeatCount + newCurrRepeat + 1; // replace that one and those after it + var header = protectionNode.firstElementChild; + var privateData = (0,base64/* base64ToBytes */.K)(header.textContent === null ? "" : header.textContent); + var keyIdHex = getPlayReadyKIDFromPrivateData(privateData); + var keyIdBytes = (0,string_parsing/* hexToBytes */.nr)(keyIdHex); // remove possible braces - oldTimeline.splice.apply(oldTimeline, [i, prevTimelineLength - i].concat(newTimeline)); - oldTimeline[i].start = currElt.start; - oldTimeline[i].repeatCount = newRepeatCount; - return; - } + var systemIdAttr = header.getAttribute("SystemID"); + var systemId = (systemIdAttr !== null ? systemIdAttr : "").toLowerCase().replace(/\{|\}/g, ""); + return { + keyId: keyIdBytes, + keySystems: [{ + systemId: systemId, + privateData: privateData + /* keyIds: [keyIdBytes], */ - _log__WEBPACK_IMPORTED_MODULE_2__/* .default.warn */ .Z.warn("RepresentationIndex: Manifest update removed previous segments"); - oldTimeline[i].repeatCount = Math.floor(newCurrRepeat); // put it after this one + }].concat(keySystemCreator(keyIdBytes)) + }; +} +// EXTERNAL MODULE: ./src/errors/network_error.ts +var network_error = __webpack_require__(9362); +// EXTERNAL MODULE: ./src/parsers/manifest/utils/clear_timeline_from_position.ts +var clear_timeline_from_position = __webpack_require__(8232); +// EXTERNAL MODULE: ./src/parsers/manifest/utils/index_helpers.ts +var index_helpers = __webpack_require__(3911); +// EXTERNAL MODULE: ./src/parsers/manifest/utils/is_segment_still_available.ts +var is_segment_still_available = __webpack_require__(1091); +// EXTERNAL MODULE: ./src/parsers/manifest/utils/update_segment_timeline.ts +var update_segment_timeline = __webpack_require__(5505); +;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/utils/add_segment_infos.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. + */ - oldTimeline.splice.apply(oldTimeline, [i + 1, prevTimelineLength - (i + 1)].concat(newTimeline)); - return; - } - } // if we got here, it means that every segments in the previous manifest are - // after the new one. This is unusual. - // Either the new one has more depth or it's an older one. +/** + * Add a new segment to the index. + * + * /!\ Mutate the given index + * @param {Object} index + * @param {Object} newSegment + * @param {Object} currentSegment + * @returns {Boolean} - true if the segment has been added + */ +function _addSegmentInfos(index, newSegment, currentSegment) { + var timeline = index.timeline, + timescale = index.timescale; + var timelineLength = timeline.length; + var last = timeline[timelineLength - 1]; + var scaledNewSegment = newSegment.timescale === timescale ? { + time: newSegment.time, + duration: newSegment.duration + } : { + time: newSegment.time / newSegment.timescale * timescale, + duration: newSegment.duration / newSegment.timescale * timescale + }; // in some circumstances, the new segment information are only duration + // information that we could use to deduct the start of the next segment. + // This is the case where the new segment are associated to a current + // segment and have the same start. + // However, we prefer to be sure of the duration of the new segments + // before adding such segments. - var prevLastElt = oldTimeline[oldTimeline.length - 1]; - var newLastElt = newTimeline[newTimeline.length - 1]; + var shouldDeductNextSegment = currentSegment.time === scaledNewSegment.time; - if (prevLastElt.repeatCount !== undefined && prevLastElt.repeatCount < 0) { - if (prevLastElt.start > newLastElt.start) { - _log__WEBPACK_IMPORTED_MODULE_2__/* .default.warn */ .Z.warn("RepresentationIndex: The new index is older than the previous one"); - return; // the old comes after + if (shouldDeductNextSegment) { + return false; + } else if (scaledNewSegment.time >= (0,index_helpers/* getIndexSegmentEnd */.jH)(last, null)) { + // if the given timing has a timestamp after the timeline end we + // just need to push a new element in the timeline, or increase + // the @r attribute of the last element. + if (last.duration === scaledNewSegment.duration) { + last.repeatCount++; } else { - // the new has more depth - _log__WEBPACK_IMPORTED_MODULE_2__/* .default.warn */ .Z.warn("RepresentationIndex: The new index is \"bigger\" than the previous one"); - oldTimeline.splice.apply(oldTimeline, [0, prevTimelineLength].concat(newTimeline)); - return; + index.timeline.push({ + duration: scaledNewSegment.duration, + start: scaledNewSegment.time, + repeatCount: 0 + }); } - } - - var prevLastTime = prevLastElt.start + prevLastElt.duration * (prevLastElt.repeatCount + 1); - var newLastTime = newLastElt.start + newLastElt.duration * (newLastElt.repeatCount + 1); - - if (prevLastTime >= newLastTime) { - _log__WEBPACK_IMPORTED_MODULE_2__/* .default.warn */ .Z.warn("RepresentationIndex: The new index is older than the previous one"); - return; // the old comes after - } // the new one has more depth. full update + return true; + } - _log__WEBPACK_IMPORTED_MODULE_2__/* .default.warn */ .Z.warn("RepresentationIndex: The new index is \"bigger\" than the previous one"); - oldTimeline.splice.apply(oldTimeline, [0, prevTimelineLength].concat(newTimeline)); - return; + return false; } - -/***/ }), - -/***/ 5734: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ -/* harmony export */ }); -/* harmony import */ var _utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6923); +;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/utils/tokens.ts /** * Copyright 2015 CANAL+ Group * @@ -31884,454 +30459,515 @@ function updateSegmentTimeline(oldTimeline, newTimeline) { * See the License for the specific language governing permissions and * limitations under the License. */ -// __VERY__ simple SAMI parser, based on ugly-but-working REGEXP: -// - the text, start and end times are correctly parsed. -// - only text for the given language is parsed. -// - only the CSS style associated to the P element is set. -// - we should be safe for any XSS. -// The language indicated to the parser should be present in the CSS and the -// corresponding Class should be on the P elements. If we fail to find the -// language in a "lang" property of a CSS class, the parser will throw. /** - * /!\ This file is feature-switchable. - * It always should be imported through the `features` object. + * @param {string} url + * @param {string|number} bitrate + * @returns {string} */ - -var HTML_ENTITIES = /&#([0-9]+);/g; -var BR = /
/gi; -var STYLE = /]*>([\s\S]*?)<\/style[^>]*>/i; -var PARAG = /\s*

]+))?>(.*)/i; -var START = /]+?start="?([0-9]*)"?[^0-9]/i; +function replaceRepresentationSmoothTokens(url, bitrate, customAttributes) { + return url.replace(/\{bitrate\}/g, String(bitrate)).replace(/{CustomAttributes}/g, customAttributes.length > 0 ? customAttributes[0] : ""); +} /** - * Returns classnames for every languages. - * @param {string} str - * @returns {Object} + * @param {string} url + * @param {number} time + * @returns {string} */ -function getClassNameByLang(str) { - var ruleRe = /\.(\S+)\s*{([^}]*)}/gi; - var langs = {}; - var m = ruleRe.exec(str); - - while (m !== null) { - var name = m[1]; - var lang = getCSSProperty(m[2], "lang"); - if (name != null && lang != null) { - langs[lang] = name; - } +function replaceSegmentSmoothTokens(url, time) { + return url.replace(/\{start time\}/g, String(time)); +} - m = ruleRe.exec(str); - } - return langs; -} +;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/representation_index.ts /** - * Returns the rules defined for the P element. - * Empty string if not found. - * @param {string} str - The entire styling part. - * @returns {string} + * 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 getPCSSRules(str) { - var pRuleRegex = /p\s*{([^}]*)}/gi; - var rule = pRuleRegex.exec(str); - if (rule === null) { - return ""; - } - return rule[1]; -} + + + + /** - * @param {string} str - entire CSS rule - * @param {string} name - name of the property - * @returns {string|null} - value of the property. Null if not found. + * @param {Number} start + * @param {Number} up + * @param {Number} duration + * @returns {Number} */ - -function getCSSProperty(str, name) { - var matches = new RegExp("\\s*" + name + ":\\s*(\\S+);", "i").exec(str); - return Array.isArray(matches) ? matches[1] : null; +function getSegmentNumber(start, up, duration) { + var diff = up - start; + return diff > 0 ? Math.floor(diff / duration) : 0; } /** - * @param {string} text - * @returns {string} + * Convert second-based start time and duration to the timescale of the + * manifest's index. + * @param {Object} index + * @param {Number} start + * @param {Number} duration + * @returns {Object} - Object with two properties: + * - up {Number}: timescaled timestamp of the beginning time + * - to {Number}: timescaled timestamp of the end time (start time + duration) */ -function decodeEntities(text) { - return text.replace(HTML_ENTITIES, function (_, $1) { - return String.fromCharCode($1); - }); +function normalizeRange(index, start, duration) { + var timescale = index.timescale === undefined || index.timescale === 0 ? 1 : index.timescale; + return { + up: start * timescale, + to: (start + duration) * timescale + }; } /** - * Because sami is not really html... we have to use - * some kind of regular expressions to parse it... - * the cthulhu way :) - * The specification being quite clunky, this parser - * may not work for every sami input. - * - * @param {string} smi - * @param {Number} timeOffset - * @param {string} lang + * Calculate the number of times a segment repeat based on the next segment. + * @param {Object} segment + * @param {Object} nextSegment + * @returns {Number} */ -function parseSami(smi, timeOffset, lang) { - var syncOpen = /]/ig; - var syncClose = /]|<\/body>/ig; - var subs = []; - var styleMatches = STYLE.exec(smi); - var css = Array.isArray(styleMatches) ? styleMatches[1] : ""; - var up; - var to; // FIXME Is that wanted? - // previously written as let to = SyncClose.exec(smi); but never used - - syncClose.exec(smi); - var langs = getClassNameByLang(css); - var pCSS = getPCSSRules(css); - var klass; - - if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(lang)) { - klass = langs[lang]; +function calculateRepeat(segment, nextSegment) { + var repeatCount = segment.repeatCount; // A negative value of the @r attribute of the S element indicates + // that the duration indicated in @d attribute repeats until the + // start of the next S element, the end of the Period or until the + // next MPD update. + // TODO Also for SMOOTH???? - if (klass === undefined) { - throw new Error("sami: could not find lang " + lang + " in CSS"); - } + if (segment.duration != null && repeatCount < 0) { + var repeatEnd = nextSegment !== undefined ? nextSegment.start : Infinity; + repeatCount = Math.ceil((repeatEnd - segment.start) / segment.duration) - 1; } - while (true) { - up = syncOpen.exec(smi); - to = syncClose.exec(smi); + return repeatCount; +} +/** + * RepresentationIndex implementation for Smooth Manifests. + * + * Allows to interact with the index to create new Segments. + * + * @class SmoothRepresentationIndex + */ - if (up === null && to === null) { - break; - } - if (up === null || to === null || up.index >= to.index) { - throw new Error("parse error"); - } - - var str = smi.slice(up.index, to.index); - var tim = START.exec(str); - - if (!Array.isArray(tim)) { - throw new Error("parse error (sync time attribute)"); - } +var SmoothRepresentationIndex = /*#__PURE__*/function () { + function SmoothRepresentationIndex(index, options) { + var aggressiveMode = options.aggressiveMode, + isLive = options.isLive, + segmentPrivateInfos = options.segmentPrivateInfos; + var estimatedReceivedTime = index.manifestReceivedTime == null ? performance.now() : index.manifestReceivedTime; + this._index = index; + this._indexValidityTime = estimatedReceivedTime; + this._initSegmentInfos = { + bitsPerSample: segmentPrivateInfos.bitsPerSample, + channels: segmentPrivateInfos.channels, + codecPrivateData: segmentPrivateInfos.codecPrivateData, + packetSize: segmentPrivateInfos.packetSize, + samplingRate: segmentPrivateInfos.samplingRate, + timescale: index.timescale, + protection: segmentPrivateInfos.protection + }; + this._isAggressiveMode = aggressiveMode; + this._isLive = isLive; - var start = +tim[1]; + if (index.timeline.length !== 0) { + var lastItem = index.timeline[index.timeline.length - 1]; + var scaledEnd = (0,index_helpers/* getIndexSegmentEnd */.jH)(lastItem, null); + this._initialScaledLastPosition = scaledEnd; - if (isNaN(start)) { - throw new Error("parse error (sync time attribute NaN)"); + if (index.isLive) { + var scaledReceivedTime = estimatedReceivedTime / 1000 * index.timescale; + this._scaledLiveGap = scaledReceivedTime - scaledEnd; + } } - - appendToSubs(str.split("\n"), start / 1000); } + /** + * Construct init Segment compatible with a Smooth Manifest. + * @returns {Object} + */ - return subs; - - function appendToSubs(lines, start) { - var i = lines.length; - - while (--i >= 0) { - var paragraphInfos = PARAG.exec(lines[i]); - if (!Array.isArray(paragraphInfos)) { - continue; - } + var _proto = SmoothRepresentationIndex.prototype; - var className = paragraphInfos[1], - txt = paragraphInfos[2]; + _proto.getInitSegment = function getInitSegment() { + return { + id: "init", + isInit: true, + privateInfos: { + smoothInitSegment: this._initSegmentInfos + }, + mediaURLs: null, + time: 0, + end: 0, + duration: 0, + timescale: 1 + }; + } + /** + * Generate a list of Segments for a particular period of time. + * + * @param {Number} _up + * @param {Number} _to + * @returns {Array.} + */ + ; - if (klass !== className) { - continue; - } + _proto.getSegments = function getSegments(_up, _to) { + this._refreshTimeline(); - if (txt === " ") { - subs[subs.length - 1].end = start; - } else { - var wrapperEl = document.createElement("DIV"); - wrapperEl.className = "rxp-texttrack-region"; - var divEl = document.createElement("DIV"); - divEl.className = "rxp-texttrack-div"; - divEl.style.position = "absolute"; - divEl.style.bottom = "0"; - divEl.style.width = "100%"; - divEl.style.color = "#fff"; - divEl.style.textShadow = "-1px -1px 0 #000," + "1px -1px 0 #000," + "-1px 1px 0 #000," + "1px 1px 0 #000"; - var pEl = document.createElement("div"); - pEl.className = "rxp-texttrack-p"; + var _normalizeRange = normalizeRange(this._index, _up, _to), + up = _normalizeRange.up, + to = _normalizeRange.to; - if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(pCSS)) { - pEl.style.cssText = pCSS; - } + var _this$_index = this._index, + timeline = _this$_index.timeline, + timescale = _this$_index.timescale, + media = _this$_index.media; + var isAggressive = this._isAggressiveMode; + var currentNumber; + var segments = []; + var timelineLength = timeline.length; + var maxPosition = this._scaledLiveGap == null ? undefined : performance.now() / 1000 * timescale - this._scaledLiveGap; - var textEls = txt.split(BR); + for (var i = 0; i < timelineLength; i++) { + var segmentRange = timeline[i]; + var duration = segmentRange.duration, + start = segmentRange.start; + var repeat = calculateRepeat(segmentRange, timeline[i + 1]); + var segmentNumberInCurrentRange = getSegmentNumber(start, up, duration); + var segmentTime = start + segmentNumberInCurrentRange * duration; + var timeToAddToCheckMaxPosition = isAggressive ? 0 : duration; - for (var j = 0; j < textEls.length; j++) { - if (j !== 0) { - pEl.appendChild(document.createElement("BR")); + while (segmentTime < to && segmentNumberInCurrentRange <= repeat && (maxPosition == null || segmentTime + timeToAddToCheckMaxPosition <= maxPosition)) { + var time = segmentTime; + var number = currentNumber != null ? currentNumber + segmentNumberInCurrentRange : undefined; + var segment = { + id: String(segmentTime), + isInit: false, + time: time / timescale, + end: (time + duration) / timescale, + duration: duration / timescale, + timescale: 1, + number: number, + mediaURLs: [replaceSegmentSmoothTokens(media, time)], + privateInfos: { + smoothMediaSegment: { + time: time, + duration: duration + } } + }; + segments.push(segment); // update segment number and segment time for the next segment - var spanEl = document.createElement("SPAN"); - spanEl.className = "rxp-texttrack-span"; - spanEl.textContent = decodeEntities(textEls[j]); - pEl.appendChild(spanEl); - } + segmentNumberInCurrentRange++; + segmentTime = start + segmentNumberInCurrentRange * duration; + } - divEl.appendChild(pEl); - wrapperEl.appendChild(divEl); - subs.push({ - element: wrapperEl, - start: start + timeOffset, - end: -1 - /* Will be updated on a following iteration */ + if (segmentTime >= to) { + // we reached ``to``, we're done + return segments; + } - }); + if (currentNumber != null) { + currentNumber += repeat + 1; } } - } -} - -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (parseSami); -/***/ }), + return segments; + } + /** + * Returns true if, based on the arguments, the index should be refreshed. + * (If we should re-fetch the manifest) + * @param {Number} up + * @param {Number} to + * @returns {Boolean} + */ + ; -/***/ 1812: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.shouldRefresh = function shouldRefresh(up, to) { + this._refreshTimeline(); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ -/* harmony export */ }); -/* harmony import */ var _compat__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7253); -/* harmony import */ var _utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6923); -/** - * 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. - */ + if (!this._index.isLive) { + return false; + } -/** - * /!\ This file is feature-switchable. - * It always should be imported through the `features` object. - */ + var _this$_index2 = this._index, + timeline = _this$_index2.timeline, + timescale = _this$_index2.timescale; + var lastSegmentInCurrentTimeline = timeline[timeline.length - 1]; + if (lastSegmentInCurrentTimeline === undefined) { + return false; + } -var HTML_ENTITIES = /&#([0-9]+);/g; -var BR = /
/gi; -var STYLE = /]*>([\s\S]*?)<\/style[^>]*>/i; -var PARAG = /\s*

]+))?>(.*)/i; -var START = /]+?start="?([0-9]*)"?[^0-9]/i; -/** - * Creates an array of VTTCue/TextTrackCue from a given array of cue objects. - * @param {Array.} cuesArray - Objects containing the start, end and - * text. - * @returns {Array.} - */ + var repeat = lastSegmentInCurrentTimeline.repeatCount; + var endOfLastSegmentInCurrentTimeline = lastSegmentInCurrentTimeline.start + (repeat + 1) * lastSegmentInCurrentTimeline.duration; -function createCuesFromArray(cuesArray) { - var nativeCues = []; + if (to * timescale < endOfLastSegmentInCurrentTimeline) { + return false; + } - for (var i = 0; i < cuesArray.length; i++) { - var _cuesArray$i = cuesArray[i], - start = _cuesArray$i.start, - end = _cuesArray$i.end, - text = _cuesArray$i.text; + if (up * timescale >= endOfLastSegmentInCurrentTimeline) { + return true; + } // ---- - if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(text) && end != null) { - var cue = (0,_compat__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(start, end, text); - if (cue != null) { - nativeCues.push(cue); - } - } + var startOfLastSegmentInCurrentTimeline = lastSegmentInCurrentTimeline.start + repeat * lastSegmentInCurrentTimeline.duration; + return up * timescale > startOfLastSegmentInCurrentTimeline; } + /** + * Returns first position available in the index. + * + * @param {Object} index + * @returns {Number|null} + */ + ; - return nativeCues; -} -/** - * Returns classnames for every languages. - * @param {string} str - * @returns {Object} - */ - - -function getClassNameByLang(str) { - var ruleRe = /\.(\S+)\s*{([^}]*)}/gi; - var langs = {}; - var m = ruleRe.exec(str); + _proto.getFirstPosition = function getFirstPosition() { + this._refreshTimeline(); - while (Array.isArray(m)) { - var name = m[1]; - var lang = getCSSProperty(m[2], "lang"); + var index = this._index; - if (name != null && lang != null) { - langs[lang] = name; + if (index.timeline.length === 0) { + return null; } - m = ruleRe.exec(str); + return index.timeline[0].start / index.timescale; } + /** + * Returns last position available in the index. + * @param {Object} index + * @returns {Number} + */ + ; - return langs; -} -/** - * @param {string} str - entire CSS rule - * @param {string} name - name of the property - * @returns {string|null} - value of the property. Null if not found. - */ - + _proto.getLastPosition = function getLastPosition() { + this._refreshTimeline(); -function getCSSProperty(str, name) { - var matches = new RegExp("\\s*" + name + ":\\s*(\\S+);", "i").exec(str); - return Array.isArray(matches) ? matches[1] : null; -} -/** - * Decode HMTL formatting into a string. - * @param {string} text - * @returns {string} - */ + var index = this._index; + if (this._scaledLiveGap == null) { + var lastTimelineElement = index.timeline[index.timeline.length - 1]; + return (0,index_helpers/* getIndexSegmentEnd */.jH)(lastTimelineElement, null) / index.timescale; + } -function decodeEntities(text) { - return text.replace(BR, "\n").replace(HTML_ENTITIES, function (_, $1) { - return String.fromCharCode($1); - }); -} -/** - * Because sami is not really html... we have to use - * some kind of regular expressions to parse it... - * the cthulhu way :) - * The specification being quite clunky, this parser - * may not work for every sami input. - * - * @param {string} smi - * @param {Number} timeOffset - * @param {string} lang - * @returns {Array.} - */ + for (var i = index.timeline.length - 1; i >= 0; i--) { + var timelineElt = index.timeline[i]; + var timescaledNow = performance.now() / 1000 * index.timescale; + var start = timelineElt.start, + duration = timelineElt.duration, + repeatCount = timelineElt.repeatCount; + for (var j = repeatCount; j >= 0; j--) { + var end = start + duration * (j + 1); + var positionToReach = this._isAggressiveMode ? end - duration : end; -function parseSami(smi, timeOffset, lang) { - var syncOpen = /]/ig; - var syncClose = /]|<\/body>/ig; - var subs = []; - var styleMatches = STYLE.exec(smi); - var css = styleMatches !== null ? styleMatches[1] : ""; - var up; - var to; // FIXME Is that wanted? - // previously written as let to = SyncClose.exec(smi); but never used + if (positionToReach <= timescaledNow - this._scaledLiveGap) { + return end / index.timescale; + } + } + } - syncClose.exec(smi); - var langs = getClassNameByLang(css); - var klass; + return undefined; + } + /** + * @param {number} timeSec + * @returns {number|null} + */ + ; - if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(lang)) { - klass = langs[lang]; + _proto.checkDiscontinuity = function checkDiscontinuity(timeSec) { + this._refreshTimeline(); - if (klass === undefined) { - throw new Error("sami: could not find lang " + lang + " in CSS"); - } + return (0,index_helpers/* checkDiscontinuity */._j)(this._index, timeSec, undefined); } + /** + * @returns {boolean} + */ + ; - while (true) { - up = syncOpen.exec(smi); - to = syncClose.exec(smi); - - if (up === null && to === null) { - break; - } + _proto.areSegmentsChronologicallyGenerated = function areSegmentsChronologicallyGenerated() { + return true; + }; - if (up === null || to === null || up.index >= to.index) { - throw new Error("parse error"); + _proto.isSegmentStillAvailable = function isSegmentStillAvailable(segment) { + if (segment.isInit) { + return true; } - var str = smi.slice(up.index, to.index); - var tim = START.exec(str); - - if (tim === null) { - throw new Error("parse error (sync time attribute)"); - } + this._refreshTimeline(); - var start = +tim[1]; + var _this$_index3 = this._index, + timeline = _this$_index3.timeline, + timescale = _this$_index3.timescale; + return (0,is_segment_still_available/* default */.Z)(segment, timeline, timescale, 0); + } + /** + * @param {Error} error + * @returns {Boolean} + */ + ; - if (isNaN(start)) { - throw new Error("parse error (sync time attribute NaN)"); + _proto.canBeOutOfSyncError = function canBeOutOfSyncError(error) { + if (!this._isLive) { + return false; } - appendToSubs(str.split("\n"), start / 1000); + return error instanceof network_error/* default */.Z && (error.isHttpError(404) || error.isHttpError(412)); } + /** + * Replace this RepresentationIndex by a newly downloaded one. + * Check if the old index had more information about new segments and re-add + * them if that's the case. + * @param {Object} newIndex + */ + ; - return createCuesFromArray(subs); + _proto._replace = function _replace(newIndex) { + var oldTimeline = this._index.timeline; + var newTimeline = newIndex._index.timeline; + var oldTimescale = this._index.timescale; + var newTimescale = newIndex._index.timescale; + this._index = newIndex._index; + this._initialScaledLastPosition = newIndex._initialScaledLastPosition; + this._indexValidityTime = newIndex._indexValidityTime; + this._scaledLiveGap = newIndex._scaledLiveGap; - function appendToSubs(lines, start) { - var i = lines.length; - var m; + if (oldTimeline.length === 0 || newTimeline.length === 0 || oldTimescale !== newTimescale) { + return; // don't take risk, if something is off, take the new one + } - while (--i >= 0) { - m = PARAG.exec(lines[i]); + var lastOldTimelineElement = oldTimeline[oldTimeline.length - 1]; + var lastNewTimelineElement = newTimeline[newTimeline.length - 1]; + var newEnd = (0,index_helpers/* getIndexSegmentEnd */.jH)(lastNewTimelineElement, null); - if (m === null) { - continue; - } + if ((0,index_helpers/* getIndexSegmentEnd */.jH)(lastOldTimelineElement, null) <= newEnd) { + return; + } - var _m = m, - kl = _m[1], - txt = _m[2]; + for (var i = 0; i < oldTimeline.length; i++) { + var oldTimelineRange = oldTimeline[i]; + var oldEnd = (0,index_helpers/* getIndexSegmentEnd */.jH)(oldTimelineRange, null); - if (klass !== kl) { - continue; + if (oldEnd === newEnd) { + // just add the supplementary segments + this._index.timeline = this._index.timeline.concat(oldTimeline.slice(i + 1)); + return; } - if (txt === " ") { - subs[subs.length - 1].end = start; - } else { - subs.push({ - text: decodeEntities(txt), - start: start + timeOffset - }); - } - } - } -} + if (oldEnd > newEnd) { + // adjust repeatCount + add supplementary segments + if (oldTimelineRange.duration !== lastNewTimelineElement.duration) { + return; + } -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (parseSami); + var rangeDuration = newEnd - oldTimelineRange.start; -/***/ }), + if (rangeDuration === 0) { + log/* default.warn */.Z.warn("Smooth Parser: a discontinuity detected in the previous manifest" + " has been resolved."); + this._index.timeline = this._index.timeline.concat(oldTimeline.slice(i)); + return; + } -/***/ 2061: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (rangeDuration < 0 || rangeDuration % oldTimelineRange.duration !== 0) { + return; + } -"use strict"; + var repeatWithOld = rangeDuration / oldTimelineRange.duration - 1; + var relativeRepeat = oldTimelineRange.repeatCount - repeatWithOld; -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ getCueBlocks -}); + if (relativeRepeat < 0) { + return; + } -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -;// CONCATENATED MODULE: ./src/parsers/texttracks/srt/find_end_of_cue_block.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 - * + lastNewTimelineElement.repeatCount += relativeRepeat; + var supplementarySegments = oldTimeline.slice(i + 1); + this._index.timeline = this._index.timeline.concat(supplementarySegments); + return; + } + } + }; + + _proto._update = function _update(newIndex) { + (0,update_segment_timeline/* default */.Z)(this._index.timeline, newIndex._index.timeline); + this._initialScaledLastPosition = newIndex._initialScaledLastPosition; + this._indexValidityTime = newIndex._indexValidityTime; + this._scaledLiveGap = newIndex._scaledLiveGap; + } + /** + * @returns {Boolean} + */ + ; + + _proto.isFinished = function isFinished() { + return !this._isLive; + } + /** + * @returns {Boolean} + */ + ; + + _proto.isInitialized = function isInitialized() { + return true; + }; + + _proto._addSegments = function _addSegments(nextSegments, currentSegment) { + this._refreshTimeline(); + + for (var i = 0; i < nextSegments.length; i++) { + _addSegmentInfos(this._index, nextSegments[i], currentSegment); + } + } + /** + * Clean-up timeline to remove segment information which should not be + * available due to the timeshift window + */ + ; + + _proto._refreshTimeline = function _refreshTimeline() { + // clean segments before time shift buffer depth + if (this._initialScaledLastPosition == null) { + return; + } + + var index = this._index; + var timeShiftBufferDepth = index.timeShiftBufferDepth; + var timeSinceLastRealUpdate = (performance.now() - this._indexValidityTime) / 1000; + var lastPositionEstimate = timeSinceLastRealUpdate + this._initialScaledLastPosition / index.timescale; + + if (timeShiftBufferDepth != null) { + var minimumPosition = (lastPositionEstimate - timeShiftBufferDepth) * index.timescale; + (0,clear_timeline_from_position/* default */.Z)(index.timeline, minimumPosition); + } + }; + + return SmoothRepresentationIndex; +}(); + + +;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/utils/parseBoolean.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 @@ -32342,31 +30978,19 @@ var is_non_empty_string = __webpack_require__(6923); */ /** - * Returns the first line that is not apart of the given cue block. - * The index given can be anywhere in a known cue block. - * - * This function is extra-resilient due to observed real-life malformed - * subtitles. - * Basically, it allows some deviation from the specification as long as the - * intent is pretty clear. - * @param {Array} linified - Whole srt. Line by line. - * @param {number} startIndex - Index in `linified` of the first line within the - * block. - * @returns {number} + * @param {*} parseBoolean + * @returns {Boolean} */ - -function findEndOfCueBlock(linified, startIndex) { - var firstEmptyLineIndex = startIndex + 1; // continue incrementing i until either: - // - an empty line - // - the end - - while ((0,is_non_empty_string/* default */.Z)(linified[firstEmptyLineIndex])) { - firstEmptyLineIndex++; +function parseBoolean(val) { + if (typeof val === "boolean") { + return val; + } else if (typeof val === "string") { + return val.toUpperCase() === "TRUE"; + } else { + return false; } - - return firstEmptyLineIndex; } -;// CONCATENATED MODULE: ./src/parsers/texttracks/srt/get_cue_blocks.ts +;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/utils/reduceChildren.ts /** * Copyright 2015 CANAL+ Group * @@ -32383,52 +31007,25 @@ function findEndOfCueBlock(linified, startIndex) { * limitations under the License. */ - /** - * Get cue blocks from a srt file. - * @param {Array.} linified - Whole srt file. Each new element in this - * array is a new line. - * @returns {Array.>} + * Reduce implementation for the children of the given element. + * @param {Element} root + * @param {Function} fn + * @param {*} init + * @returns {*} */ +function reduceChildren(root, fn, init) { + var node = root.firstElementChild; + var accumulator = init; -function getCueBlocks(linified) { - var cueBlocks = []; - - for (var i = 0; i < linified.length; i++) { - if ((0,is_non_empty_string/* default */.Z)(linified[i])) { - var endOfCue = findEndOfCueBlock(linified, i); - var cueBlockCandidate = linified.slice(i, endOfCue); - - if (cueBlockCandidate.length > 0) { - if (cueBlockCandidate.length === 1) { - if (cueBlockCandidate[0].indexOf("-->") >= 0) { - cueBlocks.push(cueBlockCandidate); - } - } else { - if (cueBlockCandidate[1].indexOf("-->") >= 0 || cueBlockCandidate[0].indexOf("-->") >= 0) { - cueBlocks.push(cueBlockCandidate); - } - } - } - - i = endOfCue; - } + while (node !== null) { + accumulator = fn(accumulator, node.nodeName, node); + node = node.nextElementSibling; } - return cueBlocks; + return accumulator; } - -/***/ }), - -/***/ 8675: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ parseSRTStringToHTML -/* harmony export */ }); -/* harmony import */ var _get_cue_blocks__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2061); -/* harmony import */ var _parse_cue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(788); +;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/create_parser.ts /** * Copyright 2015 CANAL+ Group * @@ -32445,256 +31042,572 @@ function getCueBlocks(linified) { * limitations under the License. */ -/** - * /!\ This file is feature-switchable. - * It always should be imported through the `features` object. - */ -// Parse SRT subtitles into HTML. -// Done for fun. Understand , , and type -// of tags. -/** - * @param {string} srtStr - * @param {Number} timeOffset - * @returns {Array.} - */ -function parseSRTStringToHTML(srtStr, timeOffset) { - // Even if srt only authorize CRLF, we will also take LF or CR as line - // terminators for resilience - var lines = srtStr.split(/\r\n|\n|\r/); - var cueBlocks = (0,_get_cue_blocks__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(lines); - var cues = []; - for (var i = 0; i < cueBlocks.length; i++) { - var cueObject = (0,_parse_cue__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(cueBlocks[i], timeOffset); - if (cueObject != null) { - var htmlCue = toHTML(cueObject); - if (htmlCue != null) { - cues.push(htmlCue); - } - } - } - return cues; -} -/** - * @param {Array.} cueLines - * @param {Number} timeOffset - * @returns {Object|null} - */ -function toHTML(cueObj) { - var start = cueObj.start, - end = cueObj.end, - payload = cueObj.payload; - var pEl = document.createElement("div"); - pEl.className = "rxp-texttrack-p"; - pEl.style.fontSize = "28px"; - pEl.style.position = "absolute"; - pEl.style.bottom = "5%"; - pEl.style.width = "100%"; - pEl.style.textAlign = "center"; - pEl.style.color = "#fff"; - pEl.style.textShadow = "-1px -1px 2px #000," + "1px -1px 2px #000," + "-1px 1px 2px #000," + "1px 1px 2px #000"; - for (var i = 0; i < payload.length; i++) { - if (i !== 0) { - pEl.appendChild(document.createElement("br")); - } - var span = generateSpansFromSRTText(payload[i]); - pEl.appendChild(span); - } - return { - start: start, - end: end, - element: pEl - }; -} -/** - * Take a single srt line and convert it into a span with the right style while - * avoiding XSS. - * What we do is set a whitelist of authorized tags, and recreate the - * corresponding tag from scratch. - * Supported tags: - * - : make content bold - * - : make content italic - * - : draw underline on content - * - : add color x to the content - * @param {string} text - * @returns {HTMLElement} - */ -function generateSpansFromSRTText(text) { - var secureDiv = document.createElement("div"); - secureDiv.innerHTML = text; - var _loop = function _loop(node) { - var childNodes = node.childNodes; - var span = document.createElement("span"); - span.className = "rxp-texttrack-span"; - for (var i = 0; i < childNodes.length; i++) { - var currentNode = childNodes[i]; - if (currentNode.nodeName === "#text") { - var linifiedText = currentNode.wholeText.split("\n"); - for (var line = 0; line < linifiedText.length; line++) { - if (line !== 0) { - span.appendChild(document.createElement("br")); - } +/** + * Default value for the aggressive `mode`. + * In this mode, segments will be returned even if we're not sure those had time + * to be generated. + */ - if (linifiedText[line].length > 0) { - var textNode = document.createTextNode(linifiedText[line]); - span.appendChild(textNode); - } - } - } else if (currentNode.nodeName === "B") { - var spanChild = _loop(currentNode); +var DEFAULT_AGGRESSIVE_MODE = false; +var KNOWN_ADAPTATION_TYPES = ["audio", "video", "text", "image"]; +var DEFAULT_MIME_TYPES = { + audio: "audio/mp4", + video: "video/mp4", + text: "application/ttml+xml" +}; +var MIME_TYPES = { + AACL: "audio/mp4", + AVC1: "video/mp4", + H264: "video/mp4", + TTML: "application/ttml+xml+mp4" +}; +/** + * @param {Object|undefined} parserOptions + * @returns {Function} + */ - spanChild.style.fontWeight = "bold"; - span.appendChild(spanChild); - } else if (currentNode.nodeName === "I") { - var _spanChild = _loop(currentNode); +function createSmoothStreamingParser(parserOptions) { + if (parserOptions === void 0) { + parserOptions = {}; + } - _spanChild.style.fontStyle = "italic"; - span.appendChild(_spanChild); - } else if (currentNode.nodeName === "U") { - var _spanChild2 = _loop(currentNode); + var referenceDateTime = parserOptions.referenceDateTime === undefined ? Date.UTC(1970, 0, 1, 0, 0, 0, 0) / 1000 : parserOptions.referenceDateTime; + var minRepresentationBitrate = parserOptions.minRepresentationBitrate === undefined ? 0 : parserOptions.minRepresentationBitrate; + var _parserOptions = parserOptions, + serverSyncInfos = _parserOptions.serverSyncInfos; + var serverTimeOffset = serverSyncInfos !== undefined ? serverSyncInfos.serverTimestamp - serverSyncInfos.clientTime : undefined; + /** + * @param {Element} q + * @param {string} streamType + * @return {Object} + */ - _spanChild2.style.textDecoration = "underline"; - span.appendChild(_spanChild2); - } else if (currentNode.nodeName === "FONT" && // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - currentNode.color != null) { - // TODO loop through attributes to find color? + function parseQualityLevel(q, streamType) { + var customAttributes = reduceChildren(q, function (acc, qName, qNode) { + if (qName === "CustomAttributes") { + acc.push.apply(acc, reduceChildren(qNode, function (cAttrs, cName, cNode) { + if (cName === "Attribute") { + var name = cNode.getAttribute("Name"); + var value = cNode.getAttribute("Value"); - /* eslint-disable @typescript-eslint/no-unsafe-assignment */ + if (name !== null && value !== null) { + cAttrs.push(name + "=" + value); + } + } - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - var _spanChild3 = _loop(currentNode); + return cAttrs; + }, [])); + } - _spanChild3.style.color = currentNode.color; - /* eslint-enable @typescript-eslint/no-unsafe-assignment */ + return acc; + }, []); + /** + * @param {string} name + * @returns {string|undefined} + */ - /* eslint-enable @typescript-eslint/no-unsafe-member-access */ + function getAttribute(name) { + var attr = q.getAttribute(name); + return attr == null ? undefined : attr; + } - span.appendChild(_spanChild3); - } else { - var _spanChild4 = _loop(currentNode); + switch (streamType) { + case "audio": + { + var audiotag = getAttribute("AudioTag"); + var bitsPerSample = getAttribute("BitsPerSample"); + var channels = getAttribute("Channels"); + var codecPrivateData = getAttribute("CodecPrivateData"); + var fourCC = getAttribute("FourCC"); + var packetSize = getAttribute("PacketSize"); + var samplingRate = getAttribute("SamplingRate"); + var bitrateAttr = getAttribute("Bitrate"); + var bitrate = bitrateAttr === undefined ? 0 : isNaN(parseInt(bitrateAttr, 10)) ? 0 : parseInt(bitrateAttr, 10); - span.appendChild(_spanChild4); - } - } + if (fourCC !== undefined && MIME_TYPES[fourCC] === undefined || codecPrivateData === undefined) { + log/* default.warn */.Z.warn("Smooth parser: Unsupported audio codec. Ignoring quality level."); + return null; + } - return span; - }; + var codecs = getAudioCodecs(codecPrivateData, fourCC); + return { + audiotag: audiotag !== undefined ? parseInt(audiotag, 10) : audiotag, + bitrate: bitrate, + bitsPerSample: bitsPerSample !== undefined ? parseInt(bitsPerSample, 10) : bitsPerSample, + channels: channels !== undefined ? parseInt(channels, 10) : channels, + codecPrivateData: codecPrivateData, + codecs: codecs, + customAttributes: customAttributes, + mimeType: fourCC !== undefined ? MIME_TYPES[fourCC] : fourCC, + packetSize: packetSize !== undefined ? parseInt(packetSize, 10) : packetSize, + samplingRate: samplingRate !== undefined ? parseInt(samplingRate, 10) : samplingRate + }; + } - return _loop(secureDiv); -} + case "video": + { + var _codecPrivateData = getAttribute("CodecPrivateData"); -/***/ }), + var _fourCC = getAttribute("FourCC"); -/***/ 8057: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var width = getAttribute("MaxWidth"); + var height = getAttribute("MaxHeight"); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ parseSRTStringToVTTCues -/* harmony export */ }); -/* harmony import */ var _compat_index__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7253); -/* harmony import */ var _get_cue_blocks__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2061); -/* harmony import */ var _parse_cue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(788); -/** - * 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 _bitrateAttr = getAttribute("Bitrate"); -/** - * /!\ This file is feature-switchable. - * It always should be imported through the `features` object. - */ -// srt to VTTCue parser, Done for fun. -// Heavily inspired from the WebVTT implementation + var _bitrate = _bitrateAttr === undefined ? 0 : isNaN(parseInt(_bitrateAttr, 10)) ? 0 : parseInt(_bitrateAttr, 10); + if (_fourCC !== undefined && MIME_TYPES[_fourCC] === undefined || _codecPrivateData === undefined) { + log/* default.warn */.Z.warn("Smooth parser: Unsupported video codec. Ignoring quality level."); + return null; + } + var _codecs = getVideoCodecs(_codecPrivateData); -/** - * Parse whole srt file into an array of cues, to be inserted in a video's - * TrackElement. - * @param {string} srtStr - * @param {Number} timeOffset - * @returns {Array.} - */ + return { + bitrate: _bitrate, + customAttributes: customAttributes, + mimeType: _fourCC !== undefined ? MIME_TYPES[_fourCC] : _fourCC, + codecPrivateData: _codecPrivateData, + codecs: _codecs, + width: width !== undefined ? parseInt(width, 10) : undefined, + height: height !== undefined ? parseInt(height, 10) : undefined + }; + } -function parseSRTStringToVTTCues(srtStr, timeOffset) { - // Even if srt only authorize CRLF, we will also take LF or CR as line - // terminators for resilience - var lines = srtStr.split(/\r\n|\n|\r/); - var cueBlocks = (0,_get_cue_blocks__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(lines); - var cues = []; + case "text": + { + var _codecPrivateData2 = getAttribute("CodecPrivateData"); - for (var i = 0; i < cueBlocks.length; i++) { - var cueObject = (0,_parse_cue__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(cueBlocks[i], timeOffset); + var _fourCC2 = getAttribute("FourCC"); - if (cueObject !== null) { - var nativeCue = toNativeCue(cueObject); + var _bitrateAttr2 = getAttribute("Bitrate"); - if (nativeCue !== null) { - cues.push(nativeCue); - } + var _bitrate2 = _bitrateAttr2 === undefined ? 0 : isNaN(parseInt(_bitrateAttr2, 10)) ? 0 : parseInt(_bitrateAttr2, 10); + + return { + bitrate: _bitrate2, + customAttributes: customAttributes, + mimeType: _fourCC2 !== undefined ? MIME_TYPES[_fourCC2] : _fourCC2, + codecPrivateData: (0,take_first_set/* default */.Z)(_codecPrivateData2, "") + }; + } + + default: + log/* default.error */.Z.error("Smooth Parser: Unrecognized StreamIndex type: " + streamType); + return null; } } + /** + * Parse the adaptations () tree containing + * representations () and timestamp indexes (). + * Indexes can be quite huge, and this function needs to + * to be optimized. + * @param {Object} args + * @returns {Object} + */ - return cues; -} -/** - * @param {Object} cue Object - * @returns {TextTrackCue|VTTCue|null} - */ -function toNativeCue(cueObj) { - var start = cueObj.start, - end = cueObj.end, - payload = cueObj.payload; - var text = payload.join("\n"); - return (0,_compat_index__WEBPACK_IMPORTED_MODULE_2__/* .default */ .Z)(start, end, text); -} + function parseAdaptation(args) { + var root = args.root, + timescale = args.timescale, + rootURL = args.rootURL, + protections = args.protections, + timeShiftBufferDepth = args.timeShiftBufferDepth, + manifestReceivedTime = args.manifestReceivedTime, + isLive = args.isLive; + var timescaleAttr = root.getAttribute("Timescale"); -/***/ }), + var _timescale = timescaleAttr === null ? timescale : isNaN(+timescaleAttr) ? timescale : +timescaleAttr; -/***/ 788: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var typeAttribute = root.getAttribute("Type"); -"use strict"; + if (typeAttribute === null) { + throw new Error("StreamIndex without type."); + } -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ parseCueBlock -}); + if (!(0,array_includes/* default */.Z)(KNOWN_ADAPTATION_TYPES, typeAttribute)) { + log/* default.warn */.Z.warn("Smooth Parser: Unrecognized adaptation type:", typeAttribute); + } -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -;// CONCATENATED MODULE: ./src/parsers/texttracks/srt/parse_timestamp.ts -/** - * Copyright 2015 CANAL+ Group + var adaptationType = typeAttribute; + var subType = root.getAttribute("Subtype"); + var language = root.getAttribute("Language"); + var baseURLAttr = root.getAttribute("Url"); + var baseURL = baseURLAttr === null ? "" : baseURLAttr; + + if (false) {} + + var _reduceChildren = reduceChildren(root, function (res, _name, node) { + switch (_name) { + case "QualityLevel": + var qualityLevel = parseQualityLevel(node, adaptationType); + + if (qualityLevel === null) { + return res; + } // filter out video qualityLevels with small bitrates + + + if (adaptationType !== "video" || qualityLevel.bitrate > minRepresentationBitrate) { + res.qualityLevels.push(qualityLevel); + } + + break; + + case "c": + res.cNodes.push(node); + break; + } + + return res; + }, { + qualityLevels: [], + cNodes: [] + }), + qualityLevels = _reduceChildren.qualityLevels, + cNodes = _reduceChildren.cNodes; + + var index = { + timeline: parseCNodes(cNodes), + timescale: _timescale + }; // we assume that all qualityLevels have the same + // codec and mimeType + + (0,assert/* default */.Z)(qualityLevels.length !== 0, "Adaptation should have at least one playable representation."); + var adaptationID = adaptationType + ((0,is_non_empty_string/* default */.Z)(language) ? "_" + language : ""); + var representations = qualityLevels.map(function (qualityLevel) { + var path = (0,resolve_url/* default */.Z)(rootURL, baseURL); + var repIndex = { + timeline: index.timeline, + timescale: index.timescale, + media: replaceRepresentationSmoothTokens(path, qualityLevel.bitrate, qualityLevel.customAttributes), + isLive: isLive, + timeShiftBufferDepth: timeShiftBufferDepth, + manifestReceivedTime: manifestReceivedTime + }; + var mimeType = (0,is_non_empty_string/* default */.Z)(qualityLevel.mimeType) ? qualityLevel.mimeType : DEFAULT_MIME_TYPES[adaptationType]; + var codecs = qualityLevel.codecs; + var id = adaptationID + "_" + (adaptationType != null ? adaptationType + "-" : "") + (mimeType != null ? mimeType + "-" : "") + (codecs != null ? codecs + "-" : "") + String(qualityLevel.bitrate); + var keyIDs = []; + var firstProtection; + + if (protections.length > 0) { + firstProtection = protections[0]; + protections.forEach(function (protection) { + var keyId = protection.keyId; + protection.keySystems.forEach(function (keySystem) { + keyIDs.push({ + keyId: keyId, + systemId: keySystem.systemId + }); + }); + }); + } + + var segmentPrivateInfos = { + bitsPerSample: qualityLevel.bitsPerSample, + channels: qualityLevel.channels, + codecPrivateData: qualityLevel.codecPrivateData, + packetSize: qualityLevel.packetSize, + samplingRate: qualityLevel.samplingRate, + // TODO set multiple protections here + // instead of the first one + protection: firstProtection != null ? { + keyId: firstProtection.keyId + } : undefined + }; + var aggressiveMode = parserOptions.aggressiveMode == null ? DEFAULT_AGGRESSIVE_MODE : parserOptions.aggressiveMode; + var reprIndex = new SmoothRepresentationIndex(repIndex, { + aggressiveMode: aggressiveMode, + isLive: isLive, + segmentPrivateInfos: segmentPrivateInfos + }); + var representation = (0,object_assign/* default */.Z)({}, qualityLevel, { + index: reprIndex, + mimeType: mimeType, + codecs: codecs, + id: id + }); + + if (keyIDs.length > 0 || firstProtection !== undefined) { + var initDataValues = firstProtection === undefined ? [] : firstProtection.keySystems.map(function (keySystemData) { + var systemId = keySystemData.systemId, + privateData = keySystemData.privateData; + var cleanedSystemId = systemId.replace(/-/g, ""); + var pssh = createPSSHBox(cleanedSystemId, privateData); + return { + systemId: cleanedSystemId, + data: pssh + }; + }); + + if (initDataValues.length > 0) { + var initData = [{ + type: "cenc", + values: initDataValues + }]; + representation.contentProtections = { + keyIds: keyIDs, + initData: initData + }; + } else { + representation.contentProtections = { + keyIds: keyIDs, + initData: [] + }; + } + } + + return representation; + }); // TODO(pierre): real ad-insert support + + if (subType === "ADVT") { + return null; + } + + var parsedAdaptation = { + id: adaptationID, + type: adaptationType, + representations: representations, + language: language == null ? undefined : language + }; + + if (adaptationType === "text" && subType === "DESC") { + parsedAdaptation.closedCaption = true; + } + + return parsedAdaptation; + } + + function parseFromDocument(doc, url, manifestReceivedTime) { + var rootURL = (0,resolve_url/* normalizeBaseURL */.f)(url == null ? "" : url); + var root = doc.documentElement; + + if (root == null || root.nodeName !== "SmoothStreamingMedia") { + throw new Error("document root should be SmoothStreamingMedia"); + } + + var majorVersionAttr = root.getAttribute("MajorVersion"); + var minorVersionAttr = root.getAttribute("MinorVersion"); + + if (majorVersionAttr === null || minorVersionAttr === null || !/^[2]-[0-2]$/.test(majorVersionAttr + "-" + minorVersionAttr)) { + throw new Error("Version should be 2.0, 2.1 or 2.2"); + } + + var timescaleAttr = root.getAttribute("Timescale"); + var timescale = !(0,is_non_empty_string/* default */.Z)(timescaleAttr) ? 10000000 : isNaN(+timescaleAttr) ? 10000000 : +timescaleAttr; + + var _reduceChildren2 = reduceChildren(root, function (res, name, node) { + switch (name) { + case "Protection": + { + res.protections.push(parseProtectionNode(node, parserOptions.keySystems)); + break; + } + + case "StreamIndex": + res.adaptationNodes.push(node); + break; + } + + return res; + }, { + adaptationNodes: [], + protections: [] + }), + protections = _reduceChildren2.protections, + adaptationNodes = _reduceChildren2.adaptationNodes; + + var initialAdaptations = {}; + var isLive = parseBoolean(root.getAttribute("IsLive")); + var timeShiftBufferDepth; + + if (isLive) { + var dvrWindowLength = root.getAttribute("DVRWindowLength"); + + if (dvrWindowLength != null && !isNaN(+dvrWindowLength) && +dvrWindowLength !== 0) { + timeShiftBufferDepth = +dvrWindowLength / timescale; + } + } + + var adaptations = adaptationNodes.reduce(function (acc, node) { + var adaptation = parseAdaptation({ + root: node, + rootURL: rootURL, + timescale: timescale, + protections: protections, + isLive: isLive, + timeShiftBufferDepth: timeShiftBufferDepth, + manifestReceivedTime: manifestReceivedTime + }); + + if (adaptation === null) { + return acc; + } + + var type = adaptation.type; + var adaps = acc[type]; + + if (adaps === undefined) { + acc[type] = [adaptation]; + } else { + adaps.push(adaptation); + } + + return acc; + }, initialAdaptations); + var suggestedPresentationDelay; + var availabilityStartTime; + var minimumTime; + var timeshiftDepth = null; + var maximumTimeData; + var firstVideoAdaptation = adaptations.video !== undefined ? adaptations.video[0] : undefined; + var firstAudioAdaptation = adaptations.audio !== undefined ? adaptations.audio[0] : undefined; + var firstTimeReference; + var lastTimeReference; + + if (firstVideoAdaptation !== undefined || firstAudioAdaptation !== undefined) { + var firstTimeReferences = []; + var lastTimeReferences = []; + + if (firstVideoAdaptation !== undefined) { + var firstVideoRepresentation = firstVideoAdaptation.representations[0]; + + if (firstVideoRepresentation !== undefined) { + var firstVideoTimeReference = firstVideoRepresentation.index.getFirstPosition(); + var lastVideoTimeReference = firstVideoRepresentation.index.getLastPosition(); + + if (firstVideoTimeReference != null) { + firstTimeReferences.push(firstVideoTimeReference); + } + + if (lastVideoTimeReference != null) { + lastTimeReferences.push(lastVideoTimeReference); + } + } + } + + if (firstAudioAdaptation !== undefined) { + var firstAudioRepresentation = firstAudioAdaptation.representations[0]; + + if (firstAudioRepresentation !== undefined) { + var firstAudioTimeReference = firstAudioRepresentation.index.getFirstPosition(); + var lastAudioTimeReference = firstAudioRepresentation.index.getLastPosition(); + + if (firstAudioTimeReference != null) { + firstTimeReferences.push(firstAudioTimeReference); + } + + if (lastAudioTimeReference != null) { + lastTimeReferences.push(lastAudioTimeReference); + } + } + } + + if (firstTimeReferences.length > 0) { + firstTimeReference = Math.max.apply(Math, firstTimeReferences); + } + + if (lastTimeReferences.length > 0) { + lastTimeReference = Math.min.apply(Math, lastTimeReferences); + } + } + + var manifestDuration = root.getAttribute("Duration"); + var duration = manifestDuration != null && +manifestDuration !== 0 ? +manifestDuration / timescale : undefined; + + if (isLive) { + suggestedPresentationDelay = parserOptions.suggestedPresentationDelay; + availabilityStartTime = referenceDateTime; + minimumTime = firstTimeReference !== null && firstTimeReference !== void 0 ? firstTimeReference : availabilityStartTime; + var maximumTime = lastTimeReference != null ? lastTimeReference : Date.now() / 1000 - availabilityStartTime; + maximumTimeData = { + isLinear: true, + value: maximumTime, + time: performance.now() + }; + timeshiftDepth = timeShiftBufferDepth !== null && timeShiftBufferDepth !== void 0 ? timeShiftBufferDepth : null; + } else { + minimumTime = firstTimeReference !== null && firstTimeReference !== void 0 ? firstTimeReference : 0; + + var _maximumTime = lastTimeReference !== undefined ? lastTimeReference : duration !== undefined ? minimumTime + duration : Infinity; + + maximumTimeData = { + isLinear: false, + value: _maximumTime, + time: performance.now() + }; + } + + var periodStart = isLive ? 0 : minimumTime; + var periodEnd = isLive ? undefined : maximumTimeData.value; + var manifest = { + availabilityStartTime: availabilityStartTime === undefined ? 0 : availabilityStartTime, + clockOffset: serverTimeOffset, + isLive: isLive, + isDynamic: isLive, + timeBounds: { + absoluteMinimumTime: minimumTime, + timeshiftDepth: timeshiftDepth, + maximumTimeData: maximumTimeData + }, + periods: [{ + adaptations: adaptations, + duration: periodEnd !== undefined ? periodEnd - periodStart : duration, + end: periodEnd, + id: "gen-smooth-period-0", + start: periodStart + }], + suggestedPresentationDelay: suggestedPresentationDelay, + transportType: "smooth", + uris: url == null ? [] : [url] + }; + checkManifestIDs(manifest); + return manifest; + } + + return parseFromDocument; +} +/** + * @param {string} systemId - Hex string representing the CDM, 16 bytes. + * @param {Uint8Array|undefined} privateData - Data associated to protection + * specific system. + * @returns {Uint8Array} + */ + + +function createPSSHBox(systemId, privateData) { + if (systemId.length !== 32) { + throw new Error("HSS: wrong system id length"); + } + + var version = 0; + return createBox("pssh", (0,byte_parsing/* concat */.zo)([version, 0, 0, 0], (0,string_parsing/* hexToBytes */.nr)(systemId), + /** To put there KIDs if it exists (necessitate PSSH v1) */ + (0,byte_parsing/* itobe4 */.kh)(privateData.length), privateData)); +} + +/* harmony default export */ const create_parser = (createSmoothStreamingParser); +;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/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. @@ -32709,28 +31622,24 @@ var is_non_empty_string = __webpack_require__(6923); * limitations under the License. */ -/** - * Parse a single srt timestamp into seconds - * @param {string} timestampString - * @returns {Number|undefined} - */ - -function parseTimestamp(timestampString) { - var splittedTS = timestampString.split(":"); - - if ((0,is_non_empty_string/* default */.Z)(splittedTS[2])) { - var hours = parseInt(splittedTS[0], 10); - var minutes = parseInt(splittedTS[1], 10); - var seconds = parseFloat(splittedTS[2].replace(",", ".")); - if (isNaN(hours) || isNaN(minutes) || isNaN(seconds)) { - return undefined; - } +/* harmony default export */ const smooth = (create_parser); - return hours * 60 * 60 + minutes * 60 + seconds; - } -} -;// CONCATENATED MODULE: ./src/parsers/texttracks/srt/parse_cue.ts +// EXTERNAL MODULE: ./src/utils/request/index.ts + 1 modules +var request = __webpack_require__(4597); +// EXTERNAL MODULE: ./src/utils/warn_once.ts +var warn_once = __webpack_require__(8806); +// EXTERNAL MODULE: ./src/transports/utils/check_isobmff_integrity.ts +var check_isobmff_integrity = __webpack_require__(4460); +// EXTERNAL MODULE: ./src/transports/utils/return_parsed_manifest.ts +var return_parsed_manifest = __webpack_require__(7445); +// EXTERNAL MODULE: ./src/transports/utils/text_manifest_loader.ts + 1 modules +var text_manifest_loader = __webpack_require__(7278); +// EXTERNAL MODULE: ./src/parsers/containers/isobmff/utils.ts +var utils = __webpack_require__(4644); +// EXTERNAL MODULE: ./src/parsers/containers/isobmff/get_box.ts +var get_box = __webpack_require__(2297); +;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/parse_tfrf.ts /** * Copyright 2015 CANAL+ Group * @@ -32749,74 +31658,42 @@ function parseTimestamp(timestampString) { /** - * Parse cue block into a cue object which contains: - * - start {number}: the start of the cue as a timestamp in seconds - * - end {number}: the end of the cue as a timestamp in seconds - * - payload {Array.}: the payload of the cue - * @param {Array.} cueLines - * @param {Number} timeOffset - * @returns {Object} + * @param {Uint8Array} traf + * @returns {Array.} */ -function parseCueBlock(cueLines, timeOffset) { - if (cueLines.length === 0) { - return null; - } - - var startTimeString; - var endTimeString; - var payload = []; // normally in srt, the timing is at second position. - // We still authorize to put it in the first position for resilience - - if ((0,is_non_empty_string/* default */.Z)(cueLines[1]) && cueLines[1].indexOf("-->") !== -1) { - var _cueLines$1$split$map = cueLines[1].split("-->").map(function (s) { - return s.trim(); - }); +function parseTfrf(traf) { + var tfrf = (0,get_box/* getUuidContent */.nR)(traf, 0xD4807EF2, 0xCA394695, 0x8E5426CB, 0x9E46A79F); - startTimeString = _cueLines$1$split$map[0]; - endTimeString = _cueLines$1$split$map[1]; - payload = cueLines.slice(2, cueLines.length); + if (tfrf === undefined) { + return []; } - if (!(0,is_non_empty_string/* default */.Z)(startTimeString) || !(0,is_non_empty_string/* default */.Z)(endTimeString)) { - // Try to see if we find them in the first position - var _cueLines$0$split$map = cueLines[0].split("-->").map(function (s) { - return s.trim(); - }); - - startTimeString = _cueLines$0$split$map[0]; - endTimeString = _cueLines$0$split$map[1]; - payload = cueLines.slice(1, cueLines.length); - } + var frags = []; + var version = tfrf[0]; + var fragCount = tfrf[4]; - if (!(0,is_non_empty_string/* default */.Z)(startTimeString) || !(0,is_non_empty_string/* default */.Z)(endTimeString)) { - // if the time is still not found, exit - return null; - } + for (var i = 0; i < fragCount; i++) { + var duration = void 0; + var time = void 0; - var start = parseTimestamp(startTimeString); - var end = parseTimestamp(endTimeString); + if (version === 1) { + time = (0,byte_parsing/* be8toi */.pV)(tfrf, i * 16 + 5); + duration = (0,byte_parsing/* be8toi */.pV)(tfrf, i * 16 + 5 + 8); + } else { + time = (0,byte_parsing/* be4toi */.pX)(tfrf, i * 8 + 5); + duration = (0,byte_parsing/* be4toi */.pX)(tfrf, i * 8 + 5 + 4); + } - if (start === undefined || end === undefined) { - return null; + frags.push({ + time: time, + duration: duration + }); } - return { - start: start + timeOffset, - end: end + timeOffset, - payload: payload - }; + return frags; } - -/***/ }), - -/***/ 2967: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ getParentElementsByTagName -/* harmony export */ }); +;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/parse_tfxd.ts /** * Copyright 2015 CANAL+ Group * @@ -32833,51 +31710,25 @@ function parseCueBlock(cueLines, timeOffset) { * limitations under the License. */ + /** - * Returns the parent elements which have the given tagName, by order of - * closeness relative to our element. - * @param {Element|Node} element - * @param {string} tagName - * @returns {Array.} + * @param {Uint8Array} traf + * @returns {Object|undefined} */ -function getParentElementsByTagName(element, tagName) { - if (!(element.parentNode instanceof Element)) { - return []; - } - function constructArray(_element) { - var elements = []; - - if (_element.tagName.toLowerCase() === tagName.toLowerCase()) { - elements.push(_element); - } - - var parentNode = _element.parentNode; - - if (parentNode instanceof Element) { - elements.push.apply(elements, constructArray(parentNode)); - } +function parseTfxd(traf) { + var tfxd = (0,get_box/* getUuidContent */.nR)(traf, 0x6D1D9B05, 0x42D544E6, 0x80E2141D, 0xAFF757B2); - return elements; + if (tfxd === undefined) { + return undefined; } - return constructArray(element.parentNode); + return { + duration: (0,byte_parsing/* be8toi */.pV)(tfxd, 12), + time: (0,byte_parsing/* be8toi */.pV)(tfxd, 4) + }; } - -/***/ }), - -/***/ 3791: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "U": () => /* binding */ getStylingAttributes, -/* harmony export */ "b": () => /* binding */ getStylingFromElement -/* harmony export */ }); -/* harmony import */ var _utils_array_find__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3274); -/* harmony import */ var _utils_array_includes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7714); -/* harmony import */ var _utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6923); -/* harmony import */ var _utils_starts_with__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9252); +;// CONCATENATED MODULE: ./src/transports/smooth/extract_timings_infos.ts /** * Copyright 2015 CANAL+ Group * @@ -32896,168 +31747,123 @@ function getParentElementsByTagName(element, tagName) { - /** - * Retrieve the attributes given in arguments in the given nodes and their - * associated style(s)/region. - * The first notion of the attribute encountered will be taken (by looping - * through the given nodes in order). - * - * TODO manage IDREFS (plural) for styles and regions, that is, multiple one - * @param {Array.} attributes - * @param {Array.} nodes - * @param {Array.} styles - * @param {Array.} regions - * @returns {Object} + * Try to obtain time information from the given data. + * @param {Uint8Array} data + * @param {boolean} isChunked + * @param {Object} segment + * @param {boolean} isLive + * @returns {Object} */ -function getStylingAttributes(attributes, nodes, styles, regions) { - var currentStyle = {}; - var leftAttributes = attributes.slice(); - - for (var i = 0; i <= nodes.length - 1; i++) { - var node = nodes[i]; - - if (node !== undefined) { - var _ret = function () { - var styleID = void 0; - var regionID = void 0; // 1. the style is directly set on a "tts:" attribute - - if (node.nodeType === Node.ELEMENT_NODE) { - var element = node; - - for (var j = 0; j <= element.attributes.length - 1; j++) { - var attribute = element.attributes[j]; - var name = attribute.name; - - if (name === "style") { - styleID = attribute.value; - } else if (name === "region") { - regionID = attribute.value; - } else { - var nameWithoutTTS = name.substring(4); - - if ((0,_utils_array_includes__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(leftAttributes, nameWithoutTTS)) { - currentStyle[nameWithoutTTS] = attribute.value; - leftAttributes.splice(j, 1); - - if (leftAttributes.length === 0) { - return { - v: currentStyle - }; - } - } - } - } - } // 2. the style is referenced on a "style" attribute - - - if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(styleID)) { - var style = (0,_utils_array_find__WEBPACK_IMPORTED_MODULE_2__/* .default */ .Z)(styles, function (x) { - return x.id === styleID; - }); - - if (style !== undefined) { - for (var _j = 0; _j <= leftAttributes.length - 1; _j++) { - var _attribute = leftAttributes[_j]; - - if (!(0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(currentStyle[_attribute])) { - if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(style.style[_attribute])) { - currentStyle[_attribute] = style.style[_attribute]; - leftAttributes.splice(_j, 1); - - if (leftAttributes.length === 0) { - return { - v: currentStyle - }; - } - - _j--; - } - } - } - } - } // 3. the node reference a region (which can have a value for the - // corresponding style) - - - if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(regionID)) { - var region = (0,_utils_array_find__WEBPACK_IMPORTED_MODULE_2__/* .default */ .Z)(regions, function (x) { - return x.id === regionID; - }); - - if (region !== undefined) { - for (var _j2 = 0; _j2 <= leftAttributes.length - 1; _j2++) { - var _attribute2 = leftAttributes[_j2]; +function extractTimingsInfos(data, isChunked, initTimescale, segment, isLive) { + var _a; - if (!(0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(currentStyle[_attribute2])) { - if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(region.style[_attribute2])) { - currentStyle[_attribute2] = region.style[_attribute2]; - leftAttributes.splice(_j2, 1); + var nextSegments = []; + var chunkInfos; + var tfxdSegment; + var tfrfSegments; - if (leftAttributes.length === 0) { - return { - v: currentStyle - }; - } + if (isLive) { + var traf = (0,read/* getTRAF */.XA)(data); - _j2--; - } - } - } - } - } - }(); + if (traf !== null) { + tfrfSegments = parseTfrf(traf); + tfxdSegment = parseTfxd(traf); + } else { + log/* default.warn */.Z.warn("smooth: could not find traf atom"); + } + } - if (typeof _ret === "object") return _ret.v; + if (tfrfSegments !== undefined) { + for (var i = 0; i < tfrfSegments.length; i++) { + nextSegments.push({ + time: tfrfSegments[i].time, + duration: tfrfSegments[i].duration, + timescale: initTimescale + }); } } - return currentStyle; -} -/** - * Returns the styling directly linked to an element. - * @param {Node} node - * @returns {Object} - */ + if (tfxdSegment !== undefined) { + chunkInfos = { + time: tfxdSegment.time / initTimescale, + duration: tfxdSegment.duration / initTimescale + }; + return { + nextSegments: nextSegments, + chunkInfos: chunkInfos, + scaledSegmentTime: tfxdSegment.time + }; + } -function getStylingFromElement(node) { - if (node.nodeType !== Node.ELEMENT_NODE) { - return {}; + if (isChunked) { + return { + nextSegments: nextSegments, + chunkInfos: null, + scaledSegmentTime: undefined + }; } - var element = node; - var currentStyle = {}; + var segmentDuration = segment.duration * initTimescale; // we could always make a mistake when reading a container. + // If the estimate is too far from what the segment seems to imply, take + // the segment infos instead. - for (var i = 0; i <= element.attributes.length - 1; i++) { - var styleAttribute = element.attributes[i]; + var maxDecodeTimeDelta = Math.min(initTimescale * 0.9, segmentDuration / 4); + var trunDuration = (0,utils/* getDurationFromTrun */.MM)(data); + var scaledSegmentTime = ((_a = segment.privateInfos) === null || _a === void 0 ? void 0 : _a.smoothMediaSegment) !== undefined ? segment.privateInfos.smoothMediaSegment.time : Math.round(segment.time * initTimescale); - if ((0,_utils_starts_with__WEBPACK_IMPORTED_MODULE_3__/* .default */ .Z)(styleAttribute.name, "tts")) { - var nameWithoutTTS = styleAttribute.name.substring(4); - currentStyle[nameWithoutTTS] = styleAttribute.value; - } + if (trunDuration !== undefined && Math.abs(trunDuration - segmentDuration) <= maxDecodeTimeDelta) { + chunkInfos = { + time: segment.time, + duration: trunDuration / initTimescale + }; + } else { + chunkInfos = { + time: segment.time, + duration: segment.duration + }; } - return currentStyle; + return { + nextSegments: nextSegments, + chunkInfos: chunkInfos, + scaledSegmentTime: scaledSegmentTime + }; } +// EXTERNAL MODULE: ./src/compat/browser_detection.ts +var browser_detection = __webpack_require__(3666); +;// CONCATENATED MODULE: ./src/compat/can_patch_isobmff.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. + */ -/***/ }), - -/***/ 6177: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ getTimeDelimiters -}); +/** + * TODO(pierre): fix patchSegmentInPlace to work with IE11. Maybe + * try to put free atom inside traf children + * + * Returns true if the current target is tolerant enough for us to + * simply be able to "patch" an ISOBMFF segment or if we have to create a + * new one from scratch instead. + * @returns {Boolean} + */ -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/regexps.ts -var regexps = __webpack_require__(5336); -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/time_parsing.ts +function canPatchISOBMFFSegment() { + return !browser_detection/* isIEOrEdge */.YM; +} +;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/create_boxes.ts /** * Copyright 2015 CANAL+ Group * @@ -33074,252 +31880,362 @@ var regexps = __webpack_require__(5336); * limitations under the License. */ + + /** - * Parses a TTML time into seconds. - * @param {string} text - * @param {Object} ttParams - * @returns {Number|undefined} + * @param {Number} width + * @param {Number} height + * @param {Number} hRes - horizontal resolution, eg 72 + * @param {Number} vRes - vertical resolution, eg 72 + * @param {string} encDepth + * @param {Number} colorDepth - eg 24 + * @param {Uint8Array} avcc - Uint8Array representing the avcC atom + * @returns {Uint8Array} */ -function parseTime(text, ttParams) { - if (regexps/* REGXP_TIME_COLON_FRAMES.test */.gu.test(text)) { - return parseColonTimeWithFrames(ttParams, text); - } else if (regexps/* REGXP_TIME_COLON.test */.KO.test(text)) { - return parseTimeFromRegExp(regexps/* REGXP_TIME_COLON */.KO, text); - } else if (regexps/* REGXP_TIME_COLON_MS.test */.wf.test(text)) { - return parseTimeFromRegExp(regexps/* REGXP_TIME_COLON_MS */.wf, text); - } else if (regexps/* REGXP_TIME_FRAMES.test */.jb.test(text)) { - return parseFramesTime(ttParams, text); - } else if (regexps/* REGXP_TIME_TICK.test */.Du.test(text)) { - return parseTickTime(ttParams, text); - } else if (regexps/* REGXP_TIME_HMS.test */.te.test(text)) { - return parseTimeFromRegExp(regexps/* REGXP_TIME_HMS */.te, text); - } +function createAVC1Box(width, height, hRes, vRes, encName, colorDepth, avcc) { + return createBox("avc1", (0,byte_parsing/* concat */.zo)(6, // 6 bytes reserved + (0,byte_parsing/* itobe2 */.XT)(1), 16, // drefIdx + QuickTime reserved, zeroes + (0,byte_parsing/* itobe2 */.XT)(width), // size 2 w + (0,byte_parsing/* itobe2 */.XT)(height), // size 2 h + (0,byte_parsing/* itobe2 */.XT)(hRes), 2, // reso 4 h + (0,byte_parsing/* itobe2 */.XT)(vRes), 2 + 4, // reso 4 v + QuickTime reserved, zeroes + [0, 1, encName.length], // frame count (default 1) + (0,string_parsing/* strToUtf8 */.tG)(encName), // 1byte len + encoder name str + 31 - encName.length, // + padding + (0,byte_parsing/* itobe2 */.XT)(colorDepth), // color depth + [0xFF, 0xFF], // reserved ones + avcc // avcc atom, + )); } /** - * Parses a TTML time in frame format - * @param {Object} ttParams - * @param {string} text - * @returns {Number} + * @param {Number} width + * @param {Number} height + * @param {Number} hRes - horizontal resolution, eg 72 + * @param {Number} vRes - vertical resolution, eg 72 + * @param {string} encDepth + * @param {Number} colorDepth - eg 24 + * @param {Uint8Array} avcc - Uint8Array representing the avcC atom + * @param {Uint8Array} sinf - Uint8Array representing the sinf atom + * @returns {Uint8Array} */ -function parseFramesTime(ttParams, text) { - // 75f or 75.5f - // (We cast as we're sure the regexp is respected here) - var results = regexps/* REGXP_TIME_FRAMES.exec */.jb.exec(text); - var frames = Number(results[1]); - return frames / ttParams.frameRate; +function createENCVBox(width, height, hRes, vRes, encName, colorDepth, avcc, sinf) { + return createBox("encv", (0,byte_parsing/* concat */.zo)(6, // 6 bytes reserved + (0,byte_parsing/* itobe2 */.XT)(1), 16, // drefIdx + QuickTime reserved, zeroes + (0,byte_parsing/* itobe2 */.XT)(width), // size 2 w + (0,byte_parsing/* itobe2 */.XT)(height), // size 2 h + (0,byte_parsing/* itobe2 */.XT)(hRes), 2, // reso 4 h + (0,byte_parsing/* itobe2 */.XT)(vRes), 2 + 4, // reso 4 v + QuickTime reserved, zeroes + [0, 1, encName.length], // frame count (default 1) + (0,string_parsing/* strToUtf8 */.tG)(encName), // 1byte len + encoder name str + 31 - encName.length, // + padding + (0,byte_parsing/* itobe2 */.XT)(colorDepth), // color depth + [0xFF, 0xFF], // reserved ones + avcc, // avcc atom, + sinf)); } /** - * Parses a TTML time in tick format - * @param {Object} ttParams - * @param {string} text - * @returns {Number} + * @param {Number} drefIdx + * @param {Number} channelsCount + * @param {Number} sampleSize + * @param {Number} packetSize + * @param {Number} sampleRate + * @param {Uint8Array} esds - Uint8Array representing the esds atom + * @param {Uint8Array} [sinf] - Uint8Array representing the sinf atom, + * only if name == "enca" + * @returns {Uint8Array} */ -function parseTickTime(ttParams, text) { - // 50t or 50.5t - // (We cast as we're sure the regexp is respected here) - var results = regexps/* REGXP_TIME_TICK.exec */.Du.exec(text); - var ticks = Number(results[1]); - return ticks / ttParams.tickRate; +function createMP4ABox(drefIdx, channelsCount, sampleSize, packetSize, sampleRate, esds) { + return createBox("mp4a", (0,byte_parsing/* concat */.zo)(6, (0,byte_parsing/* itobe2 */.XT)(drefIdx), 8, (0,byte_parsing/* itobe2 */.XT)(channelsCount), (0,byte_parsing/* itobe2 */.XT)(sampleSize), 2, (0,byte_parsing/* itobe2 */.XT)(packetSize), (0,byte_parsing/* itobe2 */.XT)(sampleRate), 2, esds)); } /** - * Parses a TTML colon formatted time containing frames - * @param {Object} ttParams - * @param {string} text - * @returns {Number} + * @param {Number} drefIdx + * @param {Number} channelsCount + * @param {Number} sampleSize + * @param {Number} packetSize + * @param {Number} sampleRate + * @param {Uint8Array} esds - Uint8Array representing the esds atom + * @param {Uint8Array} [sinf] - Uint8Array representing the sinf atom, + * only if name == "enca" + * @returns {Uint8Array} */ -function parseColonTimeWithFrames(ttParams, text) { - // 01:02:43:07 ("07" is frames) or 01:02:43:07.1 (subframes) - // (We cast as we're sure the regexp is respected here) - var results = regexps/* REGXP_TIME_COLON_FRAMES.exec */.gu.exec(text); - var hours = Number(results[1]); - var minutes = Number(results[2]); - var seconds = Number(results[3]); - var frames = Number(results[4]); - var subframes = Number(results[5]); +function createENCABox(drefIdx, channelsCount, sampleSize, packetSize, sampleRate, esds, sinf) { + return createBox("enca", (0,byte_parsing/* concat */.zo)(6, (0,byte_parsing/* itobe2 */.XT)(drefIdx), 8, (0,byte_parsing/* itobe2 */.XT)(channelsCount), (0,byte_parsing/* itobe2 */.XT)(sampleSize), 2, (0,byte_parsing/* itobe2 */.XT)(packetSize), (0,byte_parsing/* itobe2 */.XT)(sampleRate), 2, esds, sinf)); +} +/** + * @param {url} Uint8Array + * @returns {Uint8Array} + */ - if (isNaN(subframes)) { - subframes = 0; - } - frames += subframes / ttParams.subFrameRate; - seconds += frames / ttParams.frameRate; - return seconds + minutes * 60 + hours * 3600; +function createDREFBox(url) { + // only one description here... FIXME + return createBox("dref", (0,byte_parsing/* concat */.zo)(7, [1], url)); } /** - * Parses a TTML time with a given regex. Expects regex to be some - * sort of a time-matcher to match hours, minutes, seconds and milliseconds - * - * @param {RegExp} regex - * @param {string} text - * @returns {number|null} + * @param {string} majorBrand + * @param {Array.} brands + * @returns {Uint8Array} */ -function parseTimeFromRegExp(regex, text) { - var results = regex.exec(text); +function createFTYPBox(majorBrand, brands) { + var content = byte_parsing/* concat.apply */.zo.apply(void 0, [(0,string_parsing/* strToUtf8 */.tG)(majorBrand), [0, 0, 0, 1]].concat(brands.map(string_parsing/* strToUtf8 */.tG))); + return createBox("ftyp", content); +} +/** + * @param {string} schemeType - four letters (eg "cenc" for Common Encryption) + * @param {Number} schemeVersion - eg 65536 + * @returns {Uint8Array} + */ - if (results === null || results[0] === "") { - return null; - } // This capture is optional, but will still be in the array as undefined, - // default to 0. +function createSCHMBox(schemeType, schemeVersion) { + return createBox("schm", (0,byte_parsing/* concat */.zo)(4, (0,string_parsing/* strToUtf8 */.tG)(schemeType), (0,byte_parsing/* itobe4 */.kh)(schemeVersion))); +} +/** + * Create tfdt box from a decoding time. + * @param {number} decodeTime + * @returns {Uint8Array} + */ - var hours = Number(results[1]); - if (isNaN(hours)) { - hours = 0; - } +function createTfdtBox(decodeTime) { + return createBox("tfdt", (0,byte_parsing/* concat */.zo)([1, 0, 0, 0], (0,byte_parsing/* itobe8 */.el)(decodeTime))); +} +/** + * @returns {Uint8Array} + */ - var minutes = Number(results[2]); - if (isNaN(minutes)) { - minutes = 0; - } +function createVMHDBox() { + var arr = new Uint8Array(12); + arr[3] = 1; // QuickTime... - var seconds = Number(results[3]); + return createBox("vmhd", arr); +} +/** + * @param {Number} trackId + * @returns {Uint8Array} + */ - if (isNaN(seconds)) { - seconds = 0; - } - var milliseconds = Number(results[4]); +function createTREXBox(trackId) { + // default sample desc idx = 1 + return createBox("trex", (0,byte_parsing/* concat */.zo)(4, (0,byte_parsing/* itobe4 */.kh)(trackId), [0, 0, 0, 1], 12)); +} +/** + * @param {Number} length + * @returns {Uint8Array} + */ - if (isNaN(milliseconds)) { - milliseconds = 0; - } - return milliseconds / 1000 + seconds + minutes * 60 + hours * 3600; +function createFreeBox(length) { + return createBox("free", new Uint8Array(length - 8)); } - -/* harmony default export */ const time_parsing = (parseTime); -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/get_time_delimiters.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. + * @param {Number} stream + * @param {string} codecPrivateData - hex string + * @returns {Uint8Array} */ +function createESDSBox(stream, codecPrivateData) { + return createBox("esds", (0,byte_parsing/* concat */.zo)(4, [0x03, 0x19], (0,byte_parsing/* itobe2 */.XT)(stream), [0x00, 0x04, 0x11, 0x40, 0x15], 11, [0x05, 0x02], (0,string_parsing/* hexToBytes */.nr)(codecPrivateData), [0x06, 0x01, 0x02])); +} /** - * Get start and end time of an element. - * @param {Element} element - * @param {Object} ttParams - * @returns {Object} + * @param {string} dataFormat - four letters (eg "avc1") + * @returns {Uint8Array} */ -function getTimeDelimiters(element, ttParams) { - var beginAttr = element.getAttribute("begin"); - var durationAttr = element.getAttribute("dur"); - var endAttr = element.getAttribute("end"); - var start = (0,is_non_empty_string/* default */.Z)(beginAttr) ? time_parsing(beginAttr, ttParams) : null; - var duration = (0,is_non_empty_string/* default */.Z)(durationAttr) ? time_parsing(durationAttr, ttParams) : null; - var parsedEnd = (0,is_non_empty_string/* default */.Z)(endAttr) ? time_parsing(endAttr, ttParams) : null; - if (start == null || parsedEnd == null && duration == null) { - throw new Error("Invalid text cue"); - } // Huh? Is TypeScript that dumb here? +function createFRMABox(dataFormat) { + return createBox("frma", (0,string_parsing/* strToUtf8 */.tG)(dataFormat)); +} +/** + * @param {Uint8Array} sps + * @param {Uint8Array} pps + * @param {Number} nalLen - NAL Unit length: 1, 2 or 4 bytes + * eg: avcc(0x4d, 0x40, 0x0d, 4, 0xe1, "674d400d96560c0efcb80a70505050a0", + * 1, "68ef3880") + * @returns {Uint8Array} + */ - var end = parsedEnd == null ? start + duration : parsedEnd; - return { - start: start, - end: end - }; +function createAVCCBox(sps, pps, nalLen) { + var nal = nalLen === 2 ? 0x1 : nalLen === 4 ? 0x3 : 0x0; // Deduce AVC Profile from SPS + + var h264Profile = sps[1]; + var h264CompatibleProfile = sps[2]; + var h264Level = sps[3]; + return createBox("avcC", (0,byte_parsing/* concat */.zo)([1, h264Profile, h264CompatibleProfile, h264Level, 0x3F << 2 | nal, 0xE0 | 1], (0,byte_parsing/* itobe2 */.XT)(sps.length), sps, [1], (0,byte_parsing/* itobe2 */.XT)(pps.length), pps)); } +/** + * @param {string} type - "video"/"audio"/"hint" + * @returns {Uint8Array} + */ -/***/ }), -/***/ 7439: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +function createHDLRBox(type) { + var name; + var handlerName; -"use strict"; + switch (type) { + case "video": + name = "vide"; + handlerName = "VideoHandler"; + break; -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ html -}); + case "audio": + name = "soun"; + handlerName = "SoundHandler"; + break; -// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/parse_ttml.ts + 3 modules -var parse_ttml = __webpack_require__(5403); -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/apply_default_ttml_paragraph_style.ts + default: + name = "hint"; + handlerName = ""; + break; + } + + return createBox("hdlr", (0,byte_parsing/* concat */.zo)(8, (0,string_parsing/* strToUtf8 */.tG)(name), 12, (0,string_parsing/* strToUtf8 */.tG)(handlerName), 1 // handler name is C-style string (0 terminated) + )); +} /** - * 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 {number} timescale + * @returns {Uint8Array} */ + +function createMDHDBox(timescale) { + return createBox("mdhd", (0,byte_parsing/* concat */.zo)(12, (0,byte_parsing/* itobe4 */.kh)(timescale), 8)); +} /** - * Return true if no style has been already declared and no conflict is - * detected with current cue style. - * - * No position, orientation and dimension style should have been set to - * avoid any conflict. - * @param {object} paragraphStyle - * @returns {boolean} + * @param {Number} timescale + * @param {Number} trackId + * @returns {Uint8Array} */ -function shouldApplyDefaultTTMLStyle(paragraphStyle) { - return paragraphStyle.extent === undefined && paragraphStyle.origin === undefined && paragraphStyle.displayAlign === undefined && paragraphStyle.display === undefined && paragraphStyle.textAlign === undefined && paragraphStyle.fontSize === undefined; + + +function createMVHDBox(timescale, trackId) { + return createBox("mvhd", (0,byte_parsing/* concat */.zo)(12, (0,byte_parsing/* itobe4 */.kh)(timescale), 4, [0, 1], 2, // we assume rate = 1; + [1, 0], 10, // we assume volume = 100%; + [0, 1], 14, // default matrix + [0, 1], 14, // default matrix + [64, 0, 0, 0], 26, (0,byte_parsing/* itobe2 */.XT)(trackId + 1) // next trackId (=trackId + 1); + )); } /** - * Apply a default style to TTML cue. - * - * The default style propose to set the cue at the bottom, centered - * and lightly spaced apart from the edges : - * - * ----------------------------------------------- - * | | - * | | - * | | - * | | - * | | - * | | - * | subtitle is displayed | - * | here | - * ----------------------------------------------- - * - * @param {Object} cue - * TODO This code can be seen as risky because we might not predict every - * possible styles that can enter in conflict. - * A better solution should be found in the future + * @param {Uint8Array} mfhd + * @param {Uint8Array} tfhd + * @param {Uint8Array} tfdt + * @param {Uint8Array} trun + * @returns {Uint8Array} */ -function applyDefaultTTMLStyle(paragraphStyle) { - paragraphStyle.extent = "70% 20%"; - paragraphStyle.fontSize = "1c"; - paragraphStyle.origin = "15% 80%"; - paragraphStyle.displayAlign = "before"; - paragraphStyle.textAlign = "center"; + +function createSAIOBox(mfhd, tfhd, tfdt, trun) { + return createBox("saio", (0,byte_parsing/* concat */.zo)(4, [0, 0, 0, 1], // ?? + (0,byte_parsing/* itobe4 */.kh)(mfhd.length + tfhd.length + tfdt.length + trun.length + 8 + 8 + 8 + 8))); } -// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/get_time_delimiters.ts + 1 modules -var get_time_delimiters = __webpack_require__(6177); -;// CONCATENATED MODULE: ./src/compat/add_class_name.ts +/** + * @param {Uint8Array} sencContent - including 8 bytes flags and entries count + * @returns {Uint8Array} + */ + + +function createSAIZBox(sencContent) { + if (sencContent.length === 0) { + return createBox("saiz", new Uint8Array(0)); + } + + var flags = (0,byte_parsing/* be4toi */.pX)(sencContent, 0); + var entries = (0,byte_parsing/* be4toi */.pX)(sencContent, 4); + var arr = new Uint8Array(entries + 9); + arr.set((0,byte_parsing/* itobe4 */.kh)(entries), 5); + var i = 9; + var j = 8; + var pairsCnt; + var pairsLen; + + while (j < sencContent.length) { + j += 8; // assuming IV is 8 bytes TODO handle 16 bytes IV + // if we have extradata for each entry + + if ((flags & 0x2) === 0x2) { + pairsLen = 2; + pairsCnt = (0,byte_parsing/* be2toi */.zK)(sencContent, j); + j += pairsCnt * 6 + 2; + } else { + pairsCnt = 0; + pairsLen = 0; + } + + arr[i] = pairsCnt * 6 + 8 + pairsLen; + i++; + } + + return createBox("saiz", arr); +} +/** + * @returns {Uint8Array} + */ + + +function createSMHDBox() { + return createBox("smhd", new Uint8Array(8)); +} +/** + * @param {Array.} representations - arrays of Uint8Array, + * typically [avc1] or [encv, avc1] + * @returns {Uint8Array} + */ + + +function createSTSDBox(reps) { + // only one description here... FIXME + var arrBase = [7, [reps.length]]; + return createBox("stsd", byte_parsing/* concat.apply */.zo.apply(void 0, arrBase.concat(reps))); +} +/** + * @param {Number} width + * @param {Number} height + * @param {Number} trackId + * @returns {Uint8Array} + */ + + +function createTKHDBox(width, height, trackId) { + return createBox("tkhd", (0,byte_parsing/* concat */.zo)((0,byte_parsing/* itobe4 */.kh)(1 + 2 + 4), 8, // we assume track is enabled, + // in media and in preview. + (0,byte_parsing/* itobe4 */.kh)(trackId), 20, // we assume trackId = 1; + [1, 0, 0, 0], // we assume volume = 100%; + [0, 1, 0, 0], 12, // default matrix + [0, 1, 0, 0], 12, // default matrix + [64, 0, 0, 0], // ?? + (0,byte_parsing/* itobe2 */.XT)(width), 2, // width (TODO handle fixed) + (0,byte_parsing/* itobe2 */.XT)(height), 2 // height (TODO handle fixed) + )); +} +/** + * @param {Number} algId - eg 1 + * @param {Number} ivSize - eg 8 + * @param {string} keyId - Hex KID 93789920e8d6520098577df8f2dd5546 + * @returns {Uint8Array} + */ + + +function createTENCBox(algId, ivSize, keyId) { + return createBox("tenc", (0,byte_parsing/* concat */.zo)(6, [algId, ivSize], keyId)); +} + + +;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/create_traf_box.ts /** * Copyright 2015 CANAL+ Group * @@ -33335,45 +32251,18 @@ var get_time_delimiters = __webpack_require__(6177); * See the License for the specific language governing permissions and * limitations under the License. */ -var hasClassList; -/** - * Add className to an HTMLElement. Do nothing if the className was already - * added. - * @param {HTMLElement} elt - * @param {string} className - */ -function addClassName(elt, className) { - if (hasClassList === undefined) { - hasClassList = elt.classList !== undefined && - /* eslint-disable @typescript-eslint/unbound-method */ - typeof elt.classList.add === "function"; - /* eslint-enable @typescript-eslint/unbound-method */ - } - if (hasClassList) { - elt.classList.add(className); - } else { - var classNamesWithSpaces = " " + elt.className + " "; +function createTrafBox(tfhd, tfdt, trun, mfhd, senc) { + var trafs = [tfhd, tfdt, trun]; - if (classNamesWithSpaces.indexOf(" " + className + " ") < 0) { - elt.className += " " + className; - } + if (senc !== undefined) { + trafs.push(createBox("senc", senc), createSAIZBox(senc), createSAIOBox(mfhd, tfhd, tfdt, trun)); } + + return createBoxWithChildren("traf", trafs); } -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -// EXTERNAL MODULE: ./src/utils/object_assign.ts -var object_assign = __webpack_require__(8026); -// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/get_parent_elements_by_tag_name.ts -var get_parent_elements_by_tag_name = __webpack_require__(2967); -// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/get_styling.ts -var get_styling = __webpack_require__(3791); -// EXTERNAL MODULE: ./src/log.ts + 1 modules -var log = __webpack_require__(3887); -// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/regexps.ts -var regexps = __webpack_require__(5336); -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/apply_extent.ts +;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/patch_segment.ts /** * Copyright 2015 CANAL+ Group * @@ -33392,49 +32281,157 @@ var regexps = __webpack_require__(5336); + + /** - * Apply `tts:extent` styling to an HTML element. - * @param {HTMLElement} element - * @param {string} extent + * Update ISOBMFF Segment downloaded in Smooth Streaming so it is playable on + * the browser. + * @param {Uint8Array} segment + * @param {Number} decodeTime + * @return {Uint8Array} */ -function applyExtent(element, extent) { - var trimmedExtent = extent.trim(); +function patchSegment(segment, decodeTime) { + var oldMoofOffsets = (0,get_box/* getBoxOffsets */.Qy)(segment, 0x6D6F6F66 + /* moof */ + ); - if (trimmedExtent === "auto") { - return; + if (oldMoofOffsets === null) { + throw new Error("Smooth: Invalid ISOBMFF given"); } - var splittedExtent = trimmedExtent.split(" "); + var oldMoofContent = segment.subarray(oldMoofOffsets[1], oldMoofOffsets[2]); + var mfhdBox = (0,get_box/* getBox */.iz)(oldMoofContent, 0x6D666864 + /* mfhd */ + ); + var trafContent = (0,get_box/* getBoxContent */.t_)(oldMoofContent, 0x74726166 + /* traf */ + ); - if (splittedExtent.length !== 2) { - return; + if (trafContent === null || mfhdBox === null) { + throw new Error("Smooth: Invalid ISOBMFF given"); } - var firstExtent = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedExtent[0]); - var secondExtent = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedExtent[1]); + var tfhdOffsets = (0,get_box/* getBoxOffsets */.Qy)(trafContent, 0x74666864 + /* tfhd */ + ); + var oldTrunOffsets = (0,get_box/* getBoxOffsets */.Qy)(trafContent, 0x7472756E + /* trun */ + ); - if (firstExtent !== null && secondExtent !== null) { - if (firstExtent[2] === "px" || firstExtent[2] === "%" || firstExtent[2] === "em") { - element.style.width = firstExtent[1] + firstExtent[2]; - } else if (firstExtent[2] === "c") { - addClassName(element, "proportional-style"); - element.setAttribute("data-proportional-width", firstExtent[1]); - } else { - log/* default.warn */.Z.warn("TTML Parser: unhandled extent unit:", firstExtent[2]); - } + if (tfhdOffsets === null || oldTrunOffsets === null) { + throw new Error("Smooth: Invalid ISOBMFF given"); + } - if (secondExtent[2] === "px" || secondExtent[2] === "%" || secondExtent[2] === "em") { - element.style.height = secondExtent[1] + secondExtent[2]; - } else if (secondExtent[2] === "c") { - addClassName(element, "proportional-style"); - element.setAttribute("data-proportional-height", secondExtent[1]); - } else { - log/* default.warn */.Z.warn("TTML Parser: unhandled extent unit:", secondExtent[2]); + var tfhdBox = trafContent.subarray(tfhdOffsets[0], tfhdOffsets[2]); + var oldTrunBox = trafContent.subarray(oldTrunOffsets[0], oldTrunOffsets[2]); // force trackId=1 since trackIds are not always reliable... + + tfhdBox.set([0, 0, 0, 1], tfhdOffsets[1] - tfhdOffsets[0] + 4 + /* version + flags */ + ); + var tfdtBox = createTfdtBox(decodeTime); + var newTrunBox = updateTrunDataOffset(oldTrunBox, oldTrunOffsets[1] - oldTrunOffsets[0]); + var sencContent = (0,get_box/* getUuidContent */.nR)(trafContent, 0xA2394F52, 0x5A9B4F14, 0xA2446C42, 0x7C648DF4); + var newTrafBox = createTrafBox(tfhdBox, tfdtBox, newTrunBox, mfhdBox, sencContent); + var newMoof = createBoxWithChildren("moof", [mfhdBox, newTrafBox]); + var newMoofOffsets = (0,get_box/* getBoxOffsets */.Qy)(newMoof, 0x6D6F6F66 + /* moof */ + ); + var newTrafOffsets = (0,get_box/* getBoxOffsets */.Qy)(newTrafBox, 0x74726166 + /* traf */ + ); + var newTrunOffsets = (0,get_box/* getBoxOffsets */.Qy)(newTrunBox, 0x7472756E + /* trun */ + ); + + if (newMoofOffsets === null || newTrafOffsets === null || newTrunOffsets === null) { + throw new Error("Smooth: Invalid moof, trun or traf generation"); + } + /** index of the `data_offset` property from the trun box in the whole "moof". */ + + + var indexOfTrunDataOffsetInMoof = newMoofOffsets[1] - newMoofOffsets[0] + mfhdBox.length + ( + /* new traf size + name */ + newTrafOffsets[1] - newTrafOffsets[0]) + tfhdBox.length + tfdtBox.length + ( + /* new trun size + name */ + newTrunOffsets[1] - newTrunOffsets[0]) + 8 + /* trun version + flags + `sample_count` */ + ; + var oldMoofLength = oldMoofOffsets[2] - oldMoofOffsets[0]; + var newMoofSizeDiff = newMoof.length - oldMoofLength; + var oldMdatOffset = (0,get_box/* getBoxOffsets */.Qy)(segment, 0x6D646174 + /* "mdat" */ + ); + + if (oldMdatOffset === null) { + throw new Error("Smooth: Invalid ISOBMFF given"); + } + + if (canPatchISOBMFFSegment() && (newMoofSizeDiff === 0 || newMoofSizeDiff <= -8)) { + // patch trun data_offset + var mdatContentOffset = oldMdatOffset[1]; + newMoof.set((0,byte_parsing/* itobe4 */.kh)(mdatContentOffset), indexOfTrunDataOffsetInMoof); + segment.set(newMoof, oldMoofOffsets[0]); // add "free" box for the remaining space + + if (newMoofSizeDiff <= -8) { + segment.set(createFreeBox(-newMoofSizeDiff), newMoof.length); } + + return segment; + } else { + // patch trun data_offset + var _mdatContentOffset = oldMdatOffset[1] + newMoofSizeDiff; + + newMoof.set((0,byte_parsing/* itobe4 */.kh)(_mdatContentOffset), indexOfTrunDataOffsetInMoof); + var newSegment = new Uint8Array(segment.length + newMoofSizeDiff); + var beforeMoof = segment.subarray(0, oldMoofOffsets[0]); + var afterMoof = segment.subarray(oldMoofOffsets[2], segment.length); + newSegment.set(beforeMoof, 0); + newSegment.set(newMoof, beforeMoof.length); + newSegment.set(afterMoof, beforeMoof.length + newMoof.length); + return newSegment; } } -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/apply_font_size.ts +/** + * Update `trun` box given or create a new one from it to add a data offset + * flag and the corresponding space to set a data offset. + * Do not do anything if the flag is already set. + * + * Note that the `oldTrunBox` given should not be mutated by this function but + * the returned value CAN point to the exact same `Uint8Array`. + * + * @param {Uint8Array} oldTrunBox - The whole original trun box + * @param {number} initialDataOffset - Offset at which the first value of the + * "trun" box (the "version") is set. + * @returns {Uint8Array} + */ + +function updateTrunDataOffset(oldTrunBox, initialDataOffset) { + var trunHasDataOffset = (oldTrunBox[initialDataOffset + 3 + /* last flag */ + ] & 0x01) > 0; + + if (trunHasDataOffset) { + return oldTrunBox; + } // If no data_offset is present, we create another "trun" with one + + + var newTrunBox = new Uint8Array(oldTrunBox.length + 4); // copy size + name + version=1 + flags=3 + sample_count=4 + + newTrunBox.set(oldTrunBox.subarray(0, initialDataOffset + 8), 0); // add data_offset flag + + newTrunBox[initialDataOffset + 3] = newTrunBox[initialDataOffset + 3] | 0x01; + newTrunBox.set([0, 0, 0, 0], initialDataOffset + 8); // add data offset + // add the rest + + newTrunBox.set(oldTrunBox.subarray(initialDataOffset + 8, oldTrunBox.length), initialDataOffset + 12); + return (0,utils/* updateBoxLength */.J6)(newTrunBox); // update the trun box's length +} +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules +var Observable = __webpack_require__(4379); +// EXTERNAL MODULE: ./src/transports/utils/byte_range.ts +var byte_range = __webpack_require__(281); +;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/create_init_segment.ts /** * Copyright 2015 CANAL+ Group * @@ -33454,36 +32451,52 @@ function applyExtent(element, extent) { /** - * Apply `tts:fontSize` styling to an HTML element. - * @param {HTMLElement} element - * @param {string} fontSize + * @param {Uint8Array} mvhd + * @param {Uint8Array} mvex + * @param {Uint8Array} trak + * @returns {Array.} */ -function applyFontSize(element, fontSize) { - var trimmedFontSize = fontSize.trim(); - var splittedFontSize = trimmedFontSize.split(" "); +function createMOOVBox(mvhd, mvex, trak) { + var children = [mvhd, mvex, trak]; + return createBoxWithChildren("moov", children); +} +/** + * Create an initialization segment with the information given. + * @param {Number} timescale + * @param {string} type + * @param {Uint8Array} stsd + * @param {Uint8Array} mhd + * @param {Number} width + * @param {Number} height + * @param {Array.} pssList - List of dict, example: + * {systemId: "DEADBEEF", codecPrivateData: "DEAFBEEF} + * @returns {Uint8Array} + */ - if (splittedFontSize.length === 0) { - return; - } - var firstFontSize = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedFontSize[0]); +function createInitSegment(timescale, type, stsd, mhd, width, height) { + var stbl = createBoxWithChildren("stbl", [stsd, createBox("stts", new Uint8Array(0x08)), createBox("stsc", new Uint8Array(0x08)), createBox("stsz", new Uint8Array(0x0C)), createBox("stco", new Uint8Array(0x08))]); + var url = createBox("url ", new Uint8Array([0, 0, 0, 1])); + var dref = createDREFBox(url); + var dinf = createBoxWithChildren("dinf", [dref]); + var minf = createBoxWithChildren("minf", [mhd, dinf, stbl]); + var hdlr = createHDLRBox(type); + var mdhd = createMDHDBox(timescale); // this one is really important - if (firstFontSize === null) { - return; - } + var mdia = createBoxWithChildren("mdia", [mdhd, hdlr, minf]); + var tkhd = createTKHDBox(width, height, 1); + var trak = createBoxWithChildren("trak", [tkhd, mdia]); + var trex = createTREXBox(1); + var mvex = createBoxWithChildren("mvex", [trex]); + var mvhd = createMVHDBox(timescale, 1); // in fact, we don't give a sh** about + // this value :O - if (firstFontSize[2] === "px" || firstFontSize[2] === "%" || firstFontSize[2] === "em") { - element.style.fontSize = firstFontSize[1] + firstFontSize[2]; - } else if (firstFontSize[2] === "c") { - element.style.position = "relative"; - addClassName(element, "proportional-style"); - element.setAttribute("data-proportional-font-size", firstFontSize[1]); - } else { - log/* default.warn */.Z.warn("TTML Parser: unhandled fontSize unit:", firstFontSize[2]); - } + var moov = createMOOVBox(mvhd, mvex, trak); + var ftyp = createFTYPBox("isom", ["isom", "iso2", "iso6", "avc1", "dash"]); + return (0,byte_parsing/* concat */.zo)(ftyp, moov); } -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/apply_line_height.ts +;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/create_video_init_segment.ts /** * Copyright 2015 CANAL+ Group * @@ -33502,34 +32515,55 @@ function applyFontSize(element, fontSize) { + /** - * @param {HTMLElement} element - * @param {string} lineHeight + * Return full video Init segment as Uint8Array + * @param {Number} timescale - lowest number, this one will be set into mdhd + * *10000 in mvhd, e.g. 1000 + * @param {Number} width + * @param {Number} height + * @param {Number} hRes + * @param {Number} vRes + * @param {Number} nalLength (1, 2 or 4) + * @param {string} codecPrivateData + * @param {Uint8Array} keyId - hex string representing the key Id, + * 32 chars. eg. a800dbed49c12c4cb8e0b25643844b9b + * @param {Array.} [pssList] - List of dict, example: + * {systemId: "DEADBEEF", codecPrivateData: "DEAFBEEF} + * @returns {Uint8Array} */ -function applyLineHeight(element, lineHeight) { - var trimmedLineHeight = lineHeight.trim(); +function createVideoInitSegment(timescale, width, height, hRes, vRes, nalLength, codecPrivateData, keyId) { + var _codecPrivateData$spl = codecPrivateData.split("00000001"), + spsHex = _codecPrivateData$spl[1], + ppsHex = _codecPrivateData$spl[2]; - if (trimmedLineHeight === "auto") { - return; + if (spsHex === undefined || ppsHex === undefined) { + throw new Error("Smooth: unsupported codec private data."); } - var firstLineHeight = regexps/* REGXP_LENGTH.exec */.eT.exec(trimmedLineHeight[0]); + var sps = (0,string_parsing/* hexToBytes */.nr)(spsHex); + var pps = (0,string_parsing/* hexToBytes */.nr)(ppsHex); // TODO NAL length is forced to 4 - if (firstLineHeight === null) { - return; - } + var avcc = createAVCCBox(sps, pps, nalLength); + var stsd; - if (firstLineHeight[2] === "px" || firstLineHeight[2] === "%" || firstLineHeight[2] === "em") { - element.style.lineHeight = firstLineHeight[1] + firstLineHeight[2]; - } else if (firstLineHeight[2] === "c") { - addClassName(element, "proportional-style"); - element.setAttribute("data-proportional-line-height", firstLineHeight[1]); + if (keyId === undefined) { + var avc1 = createAVC1Box(width, height, hRes, vRes, "AVC Coding", 24, avcc); + stsd = createSTSDBox([avc1]); } else { - log/* default.warn */.Z.warn("TTML Parser: unhandled lineHeight unit:", firstLineHeight[2]); + var tenc = createTENCBox(1, 8, keyId); + var schi = createBoxWithChildren("schi", [tenc]); + var schm = createSCHMBox("cenc", 65536); + var frma = createFRMABox("avc1"); + var sinf = createBoxWithChildren("sinf", [frma, schm, schi]); + var encv = createENCVBox(width, height, hRes, vRes, "AVC Coding", 24, avcc, sinf); + stsd = createSTSDBox([encv]); } + + return createInitSegment(timescale, "video", stsd, createVMHDBox(), width, height); } -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/apply_origin.ts +;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/get_aaces_header.ts /** * Copyright 2015 CANAL+ Group * @@ -33547,49 +32581,90 @@ function applyLineHeight(element, lineHeight) { */ - /** - * @param {HTMLElement} element - * @param {string} origin + * Sampling frequencies defined in MPEG-4 Audio. + * @type {Array.} */ -function applyOrigin(element, origin) { - var trimmedOrigin = origin.trim(); +var SAMPLING_FREQUENCIES = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350]; +/** + * Return AAC ES Header (hexstr form) + * + * @param {Number} type + * 1 = AAC Main + * 2 = AAC LC + * cf http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio + * @param {Number} frequency + * @param {Number} chans (1 or 2) + * @returns {string} + */ - if (trimmedOrigin === "auto") { - return; - } +function getAacesHeader(type, frequency, chans) { + var freq = SAMPLING_FREQUENCIES.indexOf(frequency); // TODO : handle Idx = 15... - var splittedOrigin = trimmedOrigin.split(" "); + var val; + val = (type & 0x3F) << 0x4; + val = (val | freq & 0x1F) << 0x4; + val = (val | chans & 0x1F) << 0x3; + return (0,string_parsing/* bytesToHex */.ci)((0,byte_parsing/* itobe2 */.XT)(val)); +} +;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/create_audio_init_segment.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. + */ - if (splittedOrigin.length !== 2) { - return; - } - var firstOrigin = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedOrigin[0]); - var secondOrigin = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedOrigin[1]); - if (firstOrigin !== null && secondOrigin !== null) { - if (firstOrigin[2] === "px" || firstOrigin[2] === "%" || firstOrigin[2] === "em") { - element.style.left = firstOrigin[1] + firstOrigin[2]; - } else if (firstOrigin[2] === "c") { - addClassName(element, "proportional-style"); - element.setAttribute("data-proportional-left", firstOrigin[1]); - } else { - log/* default.warn */.Z.warn("TTML Parser: unhandled origin unit:", firstOrigin[2]); - } - if (secondOrigin[2] === "px" || secondOrigin[2] === "%" || secondOrigin[2] === "em") { - element.style.top = secondOrigin[1] + secondOrigin[2]; - } else if (secondOrigin[2] === "c") { - addClassName(element, "proportional-style"); - element.setAttribute("data-proportional-top", secondOrigin[1]); - } else { - log/* default.warn */.Z.warn("TTML Parser: unhandled origin unit:", secondOrigin[2]); +/** + * Return full audio initialization segment as Uint8Array. + * @param {Number} timescale + * @param {Number} channelsCount + * @param {Number} sampleSize + * @param {Number} packetSize + * @param {Number} sampleRate + * @param {string} codecPrivateData + * @param {Uint8Array} keyId - hex string representing the key Id, 32 chars. + * eg. a800dbed49c12c4cb8e0b25643844b9b + * @param {Array.} [pssList] + * @returns {Uint8Array} + */ + +function createAudioInitSegment(timescale, channelsCount, sampleSize, packetSize, sampleRate, codecPrivateData, keyId) { + var _codecPrivateData = codecPrivateData.length === 0 ? getAacesHeader(2, sampleRate, channelsCount) : codecPrivateData; + + var esds = createESDSBox(1, _codecPrivateData); + + var stsd = function () { + if (keyId === undefined) { + var mp4a = createMP4ABox(1, channelsCount, sampleSize, packetSize, sampleRate, esds); + return createSTSDBox([mp4a]); } - } + + var tenc = createTENCBox(1, 8, keyId); + var schi = createBoxWithChildren("schi", [tenc]); + var schm = createSCHMBox("cenc", 65536); + var frma = createFRMABox("mp4a"); + var sinf = createBoxWithChildren("sinf", [frma, schm, schi]); + var enca = createENCABox(1, channelsCount, sampleSize, packetSize, sampleRate, esds, sinf); + return createSTSDBox([enca]); + }(); + + return createInitSegment(timescale, "audio", stsd, createSMHDBox(), 0, 0); } -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/apply_padding.ts +;// CONCATENATED MODULE: ./src/transports/smooth/segment_loader.ts /** * Copyright 2015 CANAL+ Group * @@ -33608,127 +32683,212 @@ function applyOrigin(element, origin) { + + /** - * @param {HTMLElement} element - * @param {string} padding + * Segment loader triggered if there was no custom-defined one in the API. + * @param {Object} opt + * @returns {Observable} */ -function applyPadding(element, padding) { - var trimmedPadding = padding.trim(); - var splittedPadding = trimmedPadding.split(" "); +function regularSegmentLoader(_ref) { + var url = _ref.url, + segment = _ref.segment; + var headers; + var range = segment.range; - if (splittedPadding.length < 1) { - return; + if (Array.isArray(range)) { + headers = { + Range: (0,byte_range/* default */.Z)(range) + }; } - var firstPadding = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedPadding[0]); + return (0,request/* default */.ZP)({ + url: url, + responseType: "arraybuffer", + headers: headers, + sendProgressEvents: true + }); +} +/** + * Defines the url for the request, load the right loader (custom/default + * one). + */ - if (firstPadding === null) { - return; - } - if (firstPadding[2] === "px" || firstPadding[2] === "%" || firstPadding[2] === "em") { - var firstPaddingValue = firstPadding[1] + firstPadding[2]; +var generateSegmentLoader = function generateSegmentLoader(customSegmentLoader) { + return function (_ref2) { + var segment = _ref2.segment, + representation = _ref2.representation, + adaptation = _ref2.adaptation, + period = _ref2.period, + manifest = _ref2.manifest, + url = _ref2.url; - if (splittedPadding.length === 1) { - element.style.padding = firstPaddingValue; - } else if (splittedPadding.length === 2) { - element.style.paddingTop = firstPaddingValue; - element.style.paddingBottom = firstPaddingValue; - } else { - element.style.paddingTop = firstPaddingValue; - } - } else if (firstPadding[2] === "c") { - addClassName(element, "proportional-style"); + if (segment.isInit) { + if (segment.privateInfos === undefined || segment.privateInfos.smoothInitSegment === undefined) { + throw new Error("Smooth: Invalid segment format"); + } - if (splittedPadding.length === 1) { - element.setAttribute("data-proportional-padding-top", firstPadding[1]); - element.setAttribute("data-proportional-padding-bottom", firstPadding[1]); - element.setAttribute("data-proportional-padding-left", firstPadding[1]); - element.setAttribute("data-proportional-padding-right", firstPadding[1]); - } else if (splittedPadding.length === 2) { - element.setAttribute("data-proportional-padding-top", firstPadding[1]); - element.setAttribute("data-proportional-padding-bottom", firstPadding[1]); - } else { - element.setAttribute("data-proportional-padding-top", firstPadding[1]); - } - } else { - log/* default.warn */.Z.warn("TTML Parser: unhandled padding unit:", firstPadding[2]); - } + var smoothInitPrivateInfos = segment.privateInfos.smoothInitSegment; + var responseData; + var codecPrivateData = smoothInitPrivateInfos.codecPrivateData, + timescale = smoothInitPrivateInfos.timescale, + _smoothInitPrivateInf = smoothInitPrivateInfos.protection, + protection = _smoothInitPrivateInf === void 0 ? { + keyId: undefined, + keySystems: undefined + } : _smoothInitPrivateInf; - if (splittedPadding.length === 1) { - return; - } + if (codecPrivateData === undefined) { + throw new Error("Smooth: no codec private data."); + } - var secondPadding = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedPadding[1]); + switch (adaptation.type) { + case "video": + { + var _representation$width = representation.width, + width = _representation$width === void 0 ? 0 : _representation$width, + _representation$heigh = representation.height, + height = _representation$heigh === void 0 ? 0 : _representation$heigh; + responseData = createVideoInitSegment(timescale, width, height, 72, 72, 4, // vRes, hRes, nal + codecPrivateData, protection.keyId); + break; + } - if (secondPadding === null) { - return; - } + case "audio": + { + var _smoothInitPrivateInf2 = smoothInitPrivateInfos.channels, + channels = _smoothInitPrivateInf2 === void 0 ? 0 : _smoothInitPrivateInf2, + _smoothInitPrivateInf3 = smoothInitPrivateInfos.bitsPerSample, + bitsPerSample = _smoothInitPrivateInf3 === void 0 ? 0 : _smoothInitPrivateInf3, + _smoothInitPrivateInf4 = smoothInitPrivateInfos.packetSize, + packetSize = _smoothInitPrivateInf4 === void 0 ? 0 : _smoothInitPrivateInf4, + _smoothInitPrivateInf5 = smoothInitPrivateInfos.samplingRate, + samplingRate = _smoothInitPrivateInf5 === void 0 ? 0 : _smoothInitPrivateInf5; + responseData = createAudioInitSegment(timescale, channels, bitsPerSample, packetSize, samplingRate, codecPrivateData, protection.keyId); + break; + } - if (secondPadding[2] === "px" || secondPadding[2] === "%" || secondPadding[2] === "em") { - var secondPaddingValue = secondPadding[1] + secondPadding[2]; + default: + if (false) {} - if (splittedPadding.length < 4) { - element.style.paddingLeft = secondPaddingValue; - element.style.paddingRight = secondPaddingValue; - } else { - element.style.paddingRight = secondPaddingValue; - } - } else if (secondPadding[2] === "c") { - addClassName(element, "proportional-style"); + responseData = new Uint8Array(0); + } - if (splittedPadding.length < 4) { - element.setAttribute("data-proportional-padding-left", secondPadding[1]); - element.setAttribute("data-proportional-padding-right", secondPadding[1]); + return (0,of.of)({ + type: "data-created", + value: { + responseData: responseData + } + }); + } else if (url === null) { + return (0,of.of)({ + type: "data-created", + value: { + responseData: null + } + }); } else { - element.setAttribute("data-proportional-padding-right", secondPadding[1]); - } - } else { - log/* default.warn */.Z.warn("TTML Parser: unhandled padding unit:", secondPadding[2]); - } + var args = { + adaptation: adaptation, + manifest: manifest, + period: period, + representation: representation, + segment: segment, + transport: "smooth", + url: url + }; - if (splittedPadding.length === 2) { - return; - } + if (typeof customSegmentLoader !== "function") { + return regularSegmentLoader(args); + } - var thirdPadding = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedPadding[2]); + return new Observable/* Observable */.y(function (obs) { + var hasFinished = false; + var hasFallbacked = false; + /** + * Callback triggered when the custom segment loader has a response. + * @param {Object} args + */ - if (thirdPadding === null) { - return; - } + var resolve = function resolve(_args) { + if (!hasFallbacked) { + hasFinished = true; + obs.next({ + type: "data-loaded", + value: { + responseData: _args.data, + size: _args.size, + duration: _args.duration + } + }); + obs.complete(); + } + }; + /** + * Callback triggered when the custom segment loader fails + * @param {*} err - The corresponding error encountered + */ - if (thirdPadding[2] === "px" || thirdPadding[2] === "%" || thirdPadding[2] === "em") { - var thirdPaddingValue = thirdPadding[1] + thirdPadding[2]; - element.style.paddingBottom = thirdPaddingValue; - } else if (thirdPadding[2] === "c") { - addClassName(element, "proportional-style"); - element.setAttribute("data-proportional-padding-bottom", thirdPadding[1]); - } else { - log/* default.warn */.Z.warn("TTML Parser: unhandled padding unit:", thirdPadding[2]); - } - if (splittedPadding.length === 3) { - return; - } + var reject = function reject(err) { + if (err === void 0) { + err = {}; + } - var fourthPadding = regexps/* REGXP_LENGTH.exec */.eT.exec(splittedPadding[3]); + if (!hasFallbacked) { + hasFinished = true; + obs.error(err); + } + }; - if (fourthPadding === null) { - return; - } + var progress = function progress(_args) { + if (!hasFallbacked) { + obs.next({ + type: "progress", + value: { + duration: _args.duration, + size: _args.size, + totalSize: _args.totalSize + } + }); + } + }; - if (fourthPadding[2] === "px" || fourthPadding[2] === "%" || fourthPadding[2] === "em") { - var fourthPaddingValue = fourthPadding[1] + fourthPadding[2]; - element.style.paddingLeft = fourthPaddingValue; - } else if (fourthPadding[2] === "c") { - addClassName(element, "proportional-style"); - element.setAttribute("data-proportional-padding-left", fourthPadding[1]); - } else { - log/* default.warn */.Z.warn("TTML Parser: unhandled padding unit:", fourthPadding[2]); - } -} -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/generate_css_test_outline.ts + var fallback = function fallback() { + hasFallbacked = true; // HACK What is TypeScript/RxJS doing here?????? + + /* eslint-disable import/no-deprecated */ + + /* eslint-disable @typescript-eslint/ban-ts-comment */ + // @ts-ignore + + regularSegmentLoader(args).subscribe(obs); + /* eslint-enable import/no-deprecated */ + + /* eslint-enable @typescript-eslint/ban-ts-comment */ + }; + + var callbacks = { + reject: reject, + resolve: resolve, + fallback: fallback, + progress: progress + }; + var abort = customSegmentLoader(args, callbacks); + return function () { + if (!hasFinished && !hasFallbacked && typeof abort === "function") { + abort(); + } + }; + }); + } + }; +}; + +/* harmony default export */ const segment_loader = (generateSegmentLoader); +;// CONCATENATED MODULE: ./src/transports/smooth/utils.ts /** * Copyright 2015 CANAL+ Group * @@ -33745,72 +32905,71 @@ function applyPadding(element, padding) { * limitations under the License. */ + +var ISM_REG = /(\.isml?)(\?token=\S+)?$/; +var TOKEN_REG = /\?token=(\S+)/; /** - * Try to replicate the textOutline TTML style property into CSS. - * - * We mock it throught the text-shadow property, translating the TTML thickness - * into blur radius and the blur-radius into... nothing. - * - * @param {string} color - * @param {string|number} thickness - * @returns {string} - */ -function generateCSSTextOutline(color, thickness) { - return "-1px -1px " + thickness + " " + color + "," + ("1px -1px " + thickness + " " + color + ",") + ("-1px 1px " + thickness + " " + color + ",") + ("1px 1px " + thickness + " " + color); -} -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/ttml_color_to_css_color.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. + * TODO Remove this logic completely from the player + * @param {Document} doc + * @returns {string|null} */ +function extractISML(doc) { + return doc.getElementsByTagName("media")[0].getAttribute("src"); +} /** - * Translate a color indicated in TTML-style to a CSS-style color. - * @param {string} color - * @returns {string} color + * Returns string corresponding to the token contained in the url's querystring. + * Empty string if no token is found. + * @param {string} url + * @returns {string} */ -function ttmlColorToCSSColor(color) { - // TODO check all possible color fomats - var regRes; - regRes = regexps/* REGXP_8_HEX_COLOR.exec */.Dq.exec(color); - if (regRes != null) { - return "rgba(" + String(parseInt(regRes[1], 16)) + "," + String(parseInt(regRes[2], 16)) + "," + String(parseInt(regRes[3], 16)) + "," + String(parseInt(regRes[4], 16) / 255) + ")"; - } +function extractToken(url) { + var tokenMatch = TOKEN_REG.exec(url); - regRes = regexps/* REGXP_4_HEX_COLOR.exec */.YU.exec(color); + if (tokenMatch !== null) { + var match = tokenMatch[1]; - if (regRes != null) { - return "rgba(" + String(parseInt(regRes[1] + regRes[1], 16)) + "," + String(parseInt(regRes[2] + regRes[2], 16)) + "," + String(parseInt(regRes[3] + regRes[3], 16)) + "," + String(parseInt(regRes[4] + regRes[4], 16) / 255) + ")"; + if (match !== undefined) { + return match; + } } - regRes = regexps/* REGXP_RGB_COLOR.exec */.GK.exec(color); + return ""; +} +/** + * Replace/Remove token from the url's querystring + * @param {string} url + * @param {string} [token] + * @returns {string} + */ - if (regRes != null) { - return "rgb(" + String(+regRes[1]) + "," + String(+regRes[2]) + "," + String(+regRes[3]) + ")"; + +function replaceToken(url, token) { + if ((0,is_non_empty_string/* default */.Z)(token)) { + return url.replace(TOKEN_REG, "?token=" + token); + } else { + return url.replace(TOKEN_REG, ""); } +} +/** + * @param {string} url + * @returns {string} + */ - regRes = regexps/* REGXP_RGBA_COLOR.exec */.ev.exec(color); - if (regRes != null) { - return "rgba(" + String(+regRes[1]) + "," + String(+regRes[2]) + "," + String(+regRes[3]) + "," + String(+regRes[4] / 255) + ")"; +function resolveManifest(url) { + if (ISM_REG.test(url)) { + (0,warn_once/* default */.Z)("Giving a isml URL to loadVideo is deprecated." + " Please give the Manifest URL directly"); + return url.replace(ISM_REG, "$1/manifest$2"); } - return color; + return url; } -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/create_element.ts + + +;// CONCATENATED MODULE: ./src/transports/smooth/pipelines.ts /** * Copyright 2015 CANAL+ Group * @@ -33837,470 +32996,547 @@ function ttmlColorToCSSColor(color) { - // Styling which can be applied to from any level upper. -// Added here as an optimization -var SPAN_LEVEL_ATTRIBUTES = ["color", "direction", "display", "fontFamily", "fontSize", "fontStyle", "fontWeight", "textDecoration", "textOutline", "unicodeBidi", "visibility", "wrapOption"]; // TODO -// tts:showBackground (applies to region) -// tts:zIndex (applies to region) -/** - * Apply style set for a singular text span of the current cue. - * @param {HTMLElement} element - The text span - * @param {Object} style - The style to apply - */ -function applyTextStyle(element, style, shouldTrimWhiteSpace) { - // applies to span - var color = style.color; - if ((0,is_non_empty_string/* default */.Z)(color)) { - element.style.color = ttmlColorToCSSColor(color); - } // applies to body, div, p, region, span - var backgroundColor = style.backgroundColor; +var WSX_REG = /\.wsx?(\?token=\S+)?/; +/** + * @param {Object} adaptation + * @param {Object} dlSegment + * @param {Object} nextSegments + */ - if ((0,is_non_empty_string/* default */.Z)(backgroundColor)) { - element.style.backgroundColor = ttmlColorToCSSColor(backgroundColor); - } // applies to span +function addNextSegments(adaptation, nextSegments, dlSegment) { + var _a; + log/* default.debug */.Z.debug("Smooth Parser: update segments information."); + var representations = adaptation.representations; - var textOutline = style.textOutline; + for (var i = 0; i < representations.length; i++) { + var representation = representations[i]; - if ((0,is_non_empty_string/* default */.Z)(textOutline)) { - var outlineData = textOutline.trim().replace(/\s+/g, " ").split(" "); - var len = outlineData.length; + if (representation.index instanceof SmoothRepresentationIndex && ((_a = dlSegment === null || dlSegment === void 0 ? void 0 : dlSegment.privateInfos) === null || _a === void 0 ? void 0 : _a.smoothMediaSegment) !== undefined) { + representation.index._addSegments(nextSegments, dlSegment.privateInfos.smoothMediaSegment); + } else { + log/* default.warn */.Z.warn("Smooth Parser: should only encounter SmoothRepresentationIndex"); + } + } +} - if (len === 3) { - var outlineColor = ttmlColorToCSSColor(outlineData[0]); - var thickness = outlineData[1]; - element.style.textShadow = generateCSSTextOutline(outlineColor, thickness); - } else if ((0,is_non_empty_string/* default */.Z)(color) && len === 1) { - var _thickness = outlineData[0]; - element.style.textShadow = generateCSSTextOutline(color, _thickness); - } else if (len === 2) { - var isFirstArgAColor = /^[#A-Z]/i.test(outlineData[0]); - var isFirstArgANumber = /^[0-9]/.test(outlineData[0]); // XOR-ing to be sure we get what we have - - if (isFirstArgAColor !== isFirstArgANumber) { - if (isFirstArgAColor) { - var _outlineColor = ttmlColorToCSSColor(outlineData[0]); - - var _thickness2 = outlineData[1]; - element.style.textShadow = generateCSSTextOutline(_outlineColor, _thickness2); - } else if ((0,is_non_empty_string/* default */.Z)(color)) { - var _thickness3 = outlineData[0]; - element.style.textShadow = generateCSSTextOutline(color, _thickness3); - } - } - } - } // applies to span - - - var textDecoration = style.textDecoration; - - if ((0,is_non_empty_string/* default */.Z)(textDecoration)) { - switch (textDecoration) { - case "noUnderline": - case "noLineThrough": - case "noOverline": - element.style.textDecoration = "none"; - break; - - case "lineThrough": - element.style.textDecoration = "line-through"; - break; +/* harmony default export */ function pipelines(options) { + var smoothManifestParser = smooth(options); + var segmentLoader = segment_loader(options.segmentLoader); + var manifestLoaderOptions = { + customManifestLoader: options.manifestLoader + }; + var manifestLoader = (0,text_manifest_loader/* default */.Z)(manifestLoaderOptions); + var manifestPipeline = { + resolver: function resolver(_ref) { + var url = _ref.url; - default: - element.style.textDecoration = textDecoration; - break; - } - } // applies to span + if (url === undefined) { + return (0,of.of)({ + url: undefined + }); + } // TODO Remove WSX logic - var fontFamily = style.fontFamily; + var resolving; - if ((0,is_non_empty_string/* default */.Z)(fontFamily)) { - switch (fontFamily) { - case "proportionalSansSerif": - element.style.fontFamily = "Arial, Helvetica, Liberation Sans, sans-serif"; - break; - // TODO monospace or sans-serif or font with both? + if (WSX_REG.test(url)) { + (0,warn_once/* default */.Z)("Giving WSX URL to loadVideo is deprecated." + " You should only give Manifest URLs."); + resolving = (0,request/* default */.ZP)({ + url: replaceToken(url, ""), + responseType: "document" + }).pipe((0,map/* map */.U)(function (_ref2) { + var value = _ref2.value; + var extractedURL = extractISML(value.responseData); - case "monospaceSansSerif": - case "sansSerif": - element.style.fontFamily = "sans-serif"; - break; + if (extractedURL === null || extractedURL.length === 0) { + throw new Error("Invalid ISML"); + } - case "monospaceSerif": - case "default": - element.style.fontFamily = "Courier New, Liberation Mono, monospace"; - break; - // TODO font with both? + return extractedURL; + })); + } else { + resolving = (0,of.of)(url); + } - case "proportionalSerif": - element.style.fontFamily = "serif"; - break; + var token = extractToken(url); + return resolving.pipe((0,map/* map */.U)(function (_url) { + return { + url: replaceToken(resolveManifest(_url), token) + }; + })); + }, + loader: manifestLoader, + parser: function parser(_ref3) { + var response = _ref3.response, + reqURL = _ref3.url; + var url = response.url === undefined ? reqURL : response.url; + var data = typeof response.responseData === "string" ? new DOMParser().parseFromString(response.responseData, "text/xml") : response.responseData; // TODO find a way to check if Document? - default: - element.style.fontFamily = fontFamily; + var manifestReceivedTime = response.receivedTime; + var parserResult = smoothManifestParser(data, url, manifestReceivedTime); + var manifest = new src_manifest/* default */.ZP(parserResult, { + representationFilter: options.representationFilter, + supplementaryImageTracks: options.supplementaryImageTracks, + supplementaryTextTracks: options.supplementaryTextTracks + }); + return (0,return_parsed_manifest/* default */.Z)(manifest, url); } - } // applies to span - - - var fontStyle = style.fontStyle; - - if ((0,is_non_empty_string/* default */.Z)(fontStyle)) { - element.style.fontStyle = fontStyle; - } // applies to span - - - var fontWeight = style.fontWeight; + }; + var segmentPipeline = { + loader: function loader(content) { + if (content.segment.isInit || options.checkMediaSegmentIntegrity !== true) { + return segmentLoader(content); + } - if ((0,is_non_empty_string/* default */.Z)(fontWeight)) { - element.style.fontWeight = fontWeight; - } // applies to span + return segmentLoader(content).pipe((0,tap/* tap */.b)(function (res) { + if ((res.type === "data-loaded" || res.type === "data-chunk") && res.value.responseData !== null) { + (0,check_isobmff_integrity/* default */.Z)(new Uint8Array(res.value.responseData), content.segment.isInit); + } + })); + }, + parser: function parser(_ref4) { + var content = _ref4.content, + response = _ref4.response, + initTimescale = _ref4.initTimescale; + var _a, _b; - var fontSize = style.fontSize; + var segment = content.segment, + adaptation = content.adaptation, + manifest = content.manifest; + var data = response.data, + isChunked = response.isChunked; - if ((0,is_non_empty_string/* default */.Z)(fontSize)) { - applyFontSize(element, fontSize); - } else { - addClassName(element, "proportional-style"); - element.setAttribute("data-proportional-font-size", "1"); - } // applies to p, span + if (data === null) { + if (segment.isInit) { + return (0,of.of)({ + type: "parsed-init-segment", + value: { + initializationData: null, + protectionDataUpdate: false, + initTimescale: undefined + } + }); + } + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: null, + chunkInfos: null, + chunkOffset: 0, + appendWindow: [undefined, undefined] + } + }); + } - var direction = style.direction; + var responseBuffer = data instanceof Uint8Array ? data : new Uint8Array(data); - if ((0,is_non_empty_string/* default */.Z)(direction)) { - element.style.direction = direction; - } // applies to p, span + if (segment.isInit) { + var timescale = (_b = (_a = segment.privateInfos) === null || _a === void 0 ? void 0 : _a.smoothInitSegment) === null || _b === void 0 ? void 0 : _b.timescale; + return (0,of.of)({ + type: "parsed-init-segment", + value: { + initializationData: data, + // smooth init segments are crafted by hand. + // Their timescale is the one from the manifest. + initTimescale: timescale, + protectionDataUpdate: false + } + }); + } + var timingInfos = initTimescale !== undefined ? extractTimingsInfos(responseBuffer, isChunked, initTimescale, segment, manifest.isLive) : null; - var unicodeBidi = style.unicodeBidi; + if (timingInfos === null || timingInfos.chunkInfos === null || timingInfos.scaledSegmentTime === undefined) { + throw new Error("Smooth Segment without time information"); + } - if ((0,is_non_empty_string/* default */.Z)(unicodeBidi)) { - switch (unicodeBidi) { - case "bidiOverride": - element.style.unicodeBidi = "bidi-override"; - break; + var nextSegments = timingInfos.nextSegments, + chunkInfos = timingInfos.chunkInfos, + scaledSegmentTime = timingInfos.scaledSegmentTime; + var chunkData = patchSegment(responseBuffer, scaledSegmentTime); - case "embed": - element.style.unicodeBidi = "embed"; - break; + if (nextSegments.length > 0) { + addNextSegments(adaptation, nextSegments, segment); + } - default: - element.style.unicodeBidi = "normal"; + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: chunkData, + chunkInfos: chunkInfos, + chunkOffset: 0, + appendWindow: [undefined, undefined] + } + }); } - } // applies to body, div, p, region, span - + }; + var textTrackPipeline = { + loader: function loader(_ref5) { + var segment = _ref5.segment, + representation = _ref5.representation, + url = _ref5.url; - var visibility = style.visibility; + if (segment.isInit || url === null) { + return (0,of.of)({ + type: "data-created", + value: { + responseData: null + } + }); + } - if ((0,is_non_empty_string/* default */.Z)(visibility)) { - element.style.visibility = visibility; - } // applies to body, div, p, region, span + var isMP4 = isMP4EmbeddedTrack(representation); + if (!isMP4 || options.checkMediaSegmentIntegrity !== true) { + return (0,request/* default */.ZP)({ + url: url, + responseType: isMP4 ? "arraybuffer" : "text", + sendProgressEvents: true + }); + } - var display = style.display; + return (0,request/* default */.ZP)({ + url: url, + responseType: "arraybuffer", + sendProgressEvents: true + }).pipe((0,tap/* tap */.b)(function (res) { + if (res.type === "data-loaded") { + (0,check_isobmff_integrity/* default */.Z)(new Uint8Array(res.value.responseData), segment.isInit); + } + })); + }, + parser: function parser(_ref6) { + var content = _ref6.content, + response = _ref6.response, + initTimescale = _ref6.initTimescale; - if (display === "none") { - element.style.display = "none"; - } // applies to body, div, p, region, span + var _a; + var manifest = content.manifest, + adaptation = content.adaptation, + representation = content.representation, + segment = content.segment; + var language = adaptation.language; + var isMP4 = isMP4EmbeddedTrack(representation); + var _representation$mimeT = representation.mimeType, + mimeType = _representation$mimeT === void 0 ? "" : _representation$mimeT, + _representation$codec = representation.codec, + codec = _representation$codec === void 0 ? "" : _representation$codec; + var data = response.data, + isChunked = response.isChunked; - var wrapOption = style.wrapOption; - element.style.whiteSpace = wrapOption === "noWrap" ? shouldTrimWhiteSpace ? "nowrap" : "pre" : shouldTrimWhiteSpace ? "normal" : "pre-wrap"; -} -/** - * Apply style for the general text track div. - * @param {HTMLElement} element - The
the style will be applied on. - * @param {Object} style - The general style object of the paragraph. - */ + if (segment.isInit) { + // text init segment has no use in HSS + return (0,of.of)({ + type: "parsed-init-segment", + value: { + initializationData: null, + protectionDataUpdate: false, + initTimescale: undefined + } + }); + } + if (data === null) { + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: null, + chunkInfos: null, + chunkOffset: 0, + appendWindow: [undefined, undefined] + } + }); + } -function applyGeneralStyle(element, style) { - // Set default text color. It can be overrided by text element color. - element.style.color = "white"; - element.style.position = "absolute"; // applies to tt, region + var nextSegments; + var chunkInfos = null; + var segmentStart; + var segmentEnd; - var extent = style.extent; + var _sdData; - if ((0,is_non_empty_string/* default */.Z)(extent)) { - applyExtent(element, extent); - } // applies to region + var _sdType; + if (isMP4) { + var chunkBytes; - var writingMode = style.writingMode; + if (typeof data === "string") { + chunkBytes = (0,string_parsing/* strToUtf8 */.tG)(data); + } else { + chunkBytes = data instanceof Uint8Array ? data : new Uint8Array(data); + } - if ((0,is_non_empty_string/* default */.Z)(writingMode)) {// TODO - } // applies to region + var timingInfos = initTimescale !== undefined ? extractTimingsInfos(chunkBytes, isChunked, initTimescale, segment, manifest.isLive) : null; + nextSegments = timingInfos === null || timingInfos === void 0 ? void 0 : timingInfos.nextSegments; + chunkInfos = (_a = timingInfos === null || timingInfos === void 0 ? void 0 : timingInfos.chunkInfos) !== null && _a !== void 0 ? _a : null; + if (chunkInfos === null) { + if (isChunked) { + log/* default.warn */.Z.warn("Smooth: Unavailable time data for current text track."); + } else { + segmentStart = segment.time; + segmentEnd = segment.end; + } + } else { + segmentStart = chunkInfos.time; + segmentEnd = chunkInfos.duration !== undefined ? chunkInfos.time + chunkInfos.duration : segment.end; + } - var overflow = style.overflow; - element.style.overflow = (0,is_non_empty_string/* default */.Z)(overflow) ? overflow : "hidden"; // applies to region + var lcCodec = codec.toLowerCase(); - var padding = style.padding; + if (mimeType === "application/ttml+xml+mp4" || lcCodec === "stpp" || lcCodec === "stpp.ttml.im1t") { + _sdType = "ttml"; + } else if (lcCodec === "wvtt") { + _sdType = "vtt"; + } else { + throw new Error("could not find a text-track parser for the type " + mimeType); + } - if ((0,is_non_empty_string/* default */.Z)(padding)) { - applyPadding(element, padding); - } // applies to region + var mdat = (0,read/* getMDAT */.Le)(chunkBytes); + _sdData = mdat === null ? "" : (0,string_parsing/* utf8ToStr */.uR)(mdat); + } else { + // not MP4 + segmentStart = segment.time; + segmentEnd = segment.end; + var chunkString; + if (typeof data !== "string") { + var bytesData = data instanceof Uint8Array ? data : new Uint8Array(data); + chunkString = (0,string_parsing/* utf8ToStr */.uR)(bytesData); + } else { + chunkString = data; + } - var origin = style.origin; + switch (mimeType) { + case "application/x-sami": + case "application/smil": + // TODO SMIL should be its own format, no? + _sdType = "sami"; + break; - if ((0,is_non_empty_string/* default */.Z)(origin)) { - applyOrigin(element, origin); - } // applies to region + case "application/ttml+xml": + _sdType = "ttml"; + break; + case "text/vtt": + _sdType = "vtt"; + break; + } - var displayAlign = style.displayAlign; + if (_sdType === undefined) { + var _lcCodec = codec.toLowerCase(); - if ((0,is_non_empty_string/* default */.Z)(displayAlign)) { - element.style.display = "flex"; - element.style.flexDirection = "column"; + if (_lcCodec === "srt") { + _sdType = "srt"; + } else { + throw new Error("could not find a text-track parser for the type " + mimeType); + } + } - switch (displayAlign) { - case "before": - element.style.justifyContent = "flex-start"; - break; + _sdData = chunkString; + } - case "center": - element.style.justifyContent = "center"; - break; + if (chunkInfos !== null && Array.isArray(nextSegments) && nextSegments.length > 0) { + addNextSegments(adaptation, nextSegments, segment); + } - case "after": - element.style.justifyContent = "flex-end"; - break; + var chunkOffset = segmentStart !== null && segmentStart !== void 0 ? segmentStart : 0; + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: { + type: _sdType, + data: _sdData, + start: segmentStart, + end: segmentEnd, + language: language + }, + chunkInfos: chunkInfos, + chunkOffset: chunkOffset, + appendWindow: [undefined, undefined] + } + }); } - } // applies to region - - - var opacity = style.opacity; - - if ((0,is_non_empty_string/* default */.Z)(opacity)) { - element.style.opacity = opacity; - } // applies to body, div, p, region, span - + }; + var imageTrackPipeline = { + loader: function loader(_ref7) { + var segment = _ref7.segment, + url = _ref7.url; - var visibility = style.visibility; + if (segment.isInit || url === null) { + // image do not need an init segment. Passthrough directly to the parser + return (0,of.of)({ + type: "data-created", + value: { + responseData: null + } + }); + } - if ((0,is_non_empty_string/* default */.Z)(visibility)) { - element.style.visibility = visibility; - } // applies to body, div, p, region, span + return (0,request/* default */.ZP)({ + url: url, + responseType: "arraybuffer", + sendProgressEvents: true + }); + }, + parser: function parser(_ref8) { + var response = _ref8.response, + content = _ref8.content; + var data = response.data, + isChunked = response.isChunked; + if (content.segment.isInit) { + // image init segment has no use + return (0,of.of)({ + type: "parsed-init-segment", + value: { + initializationData: null, + protectionDataUpdate: false, + initTimescale: undefined + } + }); + } - var display = style.display; + if (isChunked) { + throw new Error("Image data should not be downloaded in chunks"); + } // TODO image Parsing should be more on the buffer side, no? - if (display === "none") { - element.style.display = "none"; - } -} -/** - * Apply style set for a

element - * @param {HTMLElement} element - The

element - * @param {Object} style - The general style object of the paragraph. - */ + if (data === null || features/* default.imageParser */.Z.imageParser === null) { + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: null, + chunkInfos: null, + chunkOffset: 0, + appendWindow: [undefined, undefined] + } + }); + } -function applyPStyle(element, style) { - element.style.margin = "0px"; // applies to body, div, p, region, span - - var paragraphBackgroundColor = style.backgroundColor; - - if ((0,is_non_empty_string/* default */.Z)(paragraphBackgroundColor)) { - element.style.backgroundColor = ttmlColorToCSSColor(paragraphBackgroundColor); - } // applies to p - - - var lineHeight = style.lineHeight; - - if ((0,is_non_empty_string/* default */.Z)(lineHeight)) { - applyLineHeight(element, lineHeight); - } // applies to p - - - var textAlign = style.textAlign; - - if ((0,is_non_empty_string/* default */.Z)(textAlign)) { - switch (textAlign) { - case "center": - element.style.textAlign = "center"; - break; - - case "left": - case "start": - // TODO check what start means (difference with left, writing direction?) - element.style.textAlign = "left"; - break; - - case "right": - case "end": - // TODO check what end means (difference with right, writing direction?) - element.style.textAlign = "right"; - break; + var bifObject = features/* default.imageParser */.Z.imageParser(new Uint8Array(data)); + var thumbsData = bifObject.thumbs; + return (0,of.of)({ + type: "parsed-segment", + value: { + chunkData: { + data: thumbsData, + start: 0, + end: Number.MAX_VALUE, + timescale: 1, + type: "bif" + }, + chunkInfos: { + time: 0, + duration: Number.MAX_VALUE, + timescale: bifObject.timescale + }, + chunkOffset: 0, + protectionDataUpdate: false, + appendWindow: [undefined, undefined] + } + }); } - } + }; + return { + manifest: manifestPipeline, + audio: segmentPipeline, + video: segmentPipeline, + text: textTrackPipeline, + image: imageTrackPipeline + }; } /** - * Creates span of text for the given #text element, with the right style. - * - * TODO create text elements as string? Might help performances. - * @param {Element} el - the #text element, which text content should be - * displayed - * @param {Object} style - the style object for the given text - * @param {Boolean} shouldTrimWhiteSpace - True if the space should be - * trimmed. - * @returns {HTMLElement} + * Returns true if the given texttrack segment represents a textrack embedded + * in a mp4 file. + * @param {Representation} representation + * @returns {Boolean} */ - -function createTextElement(el, style, shouldTrimWhiteSpace) { - var textElement = document.createElement("span"); - var textContent = el.textContent === null ? "" : el.textContent; - - if (shouldTrimWhiteSpace) { - // 1. Trim leading and trailing whitespace. - // 2. Collapse multiple spaces into one. - var trimmed = textContent.trim(); - trimmed = trimmed.replace(/\s+/g, " "); - textContent = trimmed; - } - - textElement.innerHTML = textContent; - textElement.className = "rxp-texttrack-span"; - applyTextStyle(textElement, style, shouldTrimWhiteSpace); - return textElement; +function isMP4EmbeddedTrack(representation) { + return typeof representation.mimeType === "string" && representation.mimeType.indexOf("mp4") >= 0; } +;// CONCATENATED MODULE: ./src/transports/smooth/index.ts /** - * Generate every text elements to display in a given paragraph. - * @param {Element} paragraph - The

tag. - * @param {Array.} regions - * @param {Array.} styles - * @param {Object} paragraphStyle - The general style object of the paragraph. - * @param {Boolean} shouldTrimWhiteSpace - * @returns {Array.} + * 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 generateTextContent(paragraph, regions, styles, paragraphStyle, shouldTrimWhiteSpace) { - /** - * Recursive function, taking a node in argument and returning the - * corresponding array of HTMLElement in order. - * @param {Node} node - the node in question - * @param {Object} style - the current state of the style for the node. - * /!\ The style object can be mutated, provide a copy of it. - * @param {Array.} spans - The spans parent of this node. - * @param {Boolean} shouldTrimWhiteSpaceFromParent - True if the space should be - * trimmed by default. From the parent xml:space parameter. - * @returns {Array.} - */ - function loop(node, style, spans, shouldTrimWhiteSpaceFromParent) { - var childNodes = node.childNodes; - var elements = []; - - for (var i = 0; i < childNodes.length; i++) { - var currentNode = childNodes[i]; - - if (currentNode.nodeName === "#text") { - var _getStylingAttributes = (0,get_styling/* getStylingAttributes */.U)(["backgroundColor"], spans, styles, regions), - backgroundColor = _getStylingAttributes.backgroundColor; - - if ((0,is_non_empty_string/* default */.Z)(backgroundColor)) { - style.backgroundColor = backgroundColor; - } else { - delete style.backgroundColor; - } - - var el = createTextElement(currentNode, style, shouldTrimWhiteSpaceFromParent); - elements.push(el); - } else if (currentNode.nodeName === "br") { - var br = document.createElement("BR"); - elements.push(br); - } else if (currentNode.nodeName === "span" && currentNode.nodeType === Node.ELEMENT_NODE && currentNode.childNodes.length > 0) { - var spaceAttribute = currentNode.getAttribute("xml:space"); - var shouldTrimWhiteSpaceOnSpan = (0,is_non_empty_string/* default */.Z)(spaceAttribute) ? spaceAttribute === "default" : shouldTrimWhiteSpaceFromParent; // compute the new applyable style - - var newStyle = (0,object_assign/* default */.Z)({}, style, (0,get_styling/* getStylingAttributes */.U)(SPAN_LEVEL_ATTRIBUTES, [currentNode], styles, regions)); - elements.push.apply(elements, loop(currentNode, newStyle, [currentNode].concat(spans), shouldTrimWhiteSpaceOnSpan)); - } - } - - return elements; - } - - return loop(paragraph, (0,object_assign/* default */.Z)({}, paragraphStyle), [], shouldTrimWhiteSpace); -} /** - * @param {Element} paragraph - * @param {Element} body - * @param {Array.} regions - * @param {Array.} styles - * @param {Object} paragraphStyle - * @param {Object} - * @returns {HTMLElement} + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. */ +/* harmony default export */ const transports_smooth = (pipelines); -function createElement(paragraph, body, regions, styles, paragraphStyle, _ref) { - var cellResolution = _ref.cellResolution, - shouldTrimWhiteSpace = _ref.shouldTrimWhiteSpace; - var divs = (0,get_parent_elements_by_tag_name/* default */.Z)(paragraph, "div"); - var parentElement = document.createElement("DIV"); - parentElement.className = "rxp-texttrack-region"; - parentElement.setAttribute("data-resolution-columns", String(cellResolution.columns)); - parentElement.setAttribute("data-resolution-rows", String(cellResolution.rows)); - applyGeneralStyle(parentElement, paragraphStyle); +/***/ }), - if (body !== null) { - // applies to body, div, p, region, span - var _getStylingAttributes2 = (0,get_styling/* getStylingAttributes */.U)(["backgroundColor"], [].concat(divs, [body]), styles, regions), - bodyBackgroundColor = _getStylingAttributes2.bodyBackgroundColor; +/***/ 281: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - if ((0,is_non_empty_string/* default */.Z)(bodyBackgroundColor)) { - parentElement.style.backgroundColor = ttmlColorToCSSColor(bodyBackgroundColor); - } - } +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ byteRange) +/* harmony export */ }); +/** + * 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 pElement = document.createElement("p"); - pElement.className = "rxp-texttrack-p"; - applyPStyle(pElement, paragraphStyle); - var textContent = generateTextContent(paragraph, regions, styles, paragraphStyle, shouldTrimWhiteSpace); +/** + * Returns text-formatted byteRange (`bytes=$start-$end?)` + * @param {Array.} arr + * @returns {string} + */ +function byteRange(_ref) { + var start = _ref[0], + end = _ref[1]; + return end === Infinity ? "bytes=" + start + "-" : "bytes=" + start + "-" + end; +} - for (var i = 0; i < textContent.length; i++) { - pElement.appendChild(textContent[i]); - } // NOTE: - // The following code is for the inclusion of div elements. This has no - // advantage for now, and might only with future evolutions. - // (This is only an indication of what the base of the code could look like). - // if (divs.length) { - // let container = parentElement; - // for (let i = divs.length - 1; i >= 0; i--) { - // // TODO manage style at div level? - // // They are: visibility, display and backgroundColor - // // All these do not have any difference if applied to the

element - // // instead of the div. - // // The advantage might only be for multiple

elements dispatched - // // in multiple div Which we do not manage anyway for now. - // const divEl = document.createElement("DIV"); - // divEl.className = "rxp-texttrack-div"; - // container.appendChild(divEl); - // container = divEl; - // } - // container.appendChild(pElement); - // parentElement.appendChild(container); - // } else { - // parentElement.appendChild(pElement); - // } +/***/ }), +/***/ 4460: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - parentElement.appendChild(pElement); - return parentElement; -} -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/parse_cue.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ checkISOBMFFIntegrity) +/* harmony export */ }); +/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5389); +/* harmony import */ var _find_complete_box__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8766); /** * Copyright 2015 CANAL+ Group * @@ -34319,44 +33555,59 @@ function createElement(paragraph, body, regions, styles, paragraphStyle, _ref) { /** - * @param {Object} parsedCue - * @returns {Object|null} + * Check if an ISOBMFF segment has all the right box needed to be decoded. + * Throw if that's not the case. + * @param {Uint8Array} buffer - The whole ISOBMFF segment + * @param {boolean} isInitSegment - `true` if this is an initialization segment, + * `false` otherwise. */ -function parseCue(parsedCue) { - var paragraph = parsedCue.paragraph, - ttParams = parsedCue.ttParams, - body = parsedCue.body, - regionStyles = parsedCue.regionStyles, - idStyles = parsedCue.idStyles, - paragraphStyle = parsedCue.paragraphStyle, - timeOffset = parsedCue.timeOffset, - shouldTrimWhiteSpace = parsedCue.shouldTrimWhiteSpace; // Disregard empty elements: - // TTML allows for empty elements like

. - // If paragraph has neither time attributes, nor - // non-whitespace text, don't try to make a cue out of it. +function checkISOBMFFIntegrity(buffer, isInitSegment) { + if (isInitSegment) { + var ftypIndex = (0,_find_complete_box__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(buffer, 0x66747970 + /* ftyp */ + ); - if (!paragraph.hasAttribute("begin") && !paragraph.hasAttribute("end") && /^\s*$/.test(paragraph.textContent === null ? "" : paragraph.textContent)) { - return null; - } + if (ftypIndex < 0) { + throw new _errors__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z("INTEGRITY_ERROR", "Incomplete `ftyp` box"); + } - var cellResolution = ttParams.cellResolution; + var moovIndex = (0,_find_complete_box__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(buffer, 0x6D6F6F76 + /* moov */ + ); - var _getTimeDelimiters = (0,get_time_delimiters/* default */.Z)(paragraph, ttParams), - start = _getTimeDelimiters.start, - end = _getTimeDelimiters.end; + if (moovIndex < 0) { + throw new _errors__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z("INTEGRITY_ERROR", "Incomplete `moov` box"); + } + } else { + var moofIndex = (0,_find_complete_box__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(buffer, 0x6D6F6F66 + /* moof */ + ); - var element = createElement(paragraph, body, regionStyles, idStyles, paragraphStyle, { - cellResolution: cellResolution, - shouldTrimWhiteSpace: shouldTrimWhiteSpace - }); - return { - start: start + timeOffset, - end: end + timeOffset, - element: element - }; + if (moofIndex < 0) { + throw new _errors__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z("INTEGRITY_ERROR", "Incomplete `moof` box"); + } + + var mdatIndex = (0,_find_complete_box__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(buffer, 0x6D646174 + /* mdat */ + ); + + if (mdatIndex < 0) { + throw new _errors__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z("INTEGRITY_ERROR", "Incomplete `mdat` box"); + } + } } -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/parse_ttml_to_div.ts + +/***/ }), + +/***/ 8766: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ findCompleteBox) +/* harmony export */ }); +/* harmony import */ var _utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6968); /** * Copyright 2015 CANAL+ Group * @@ -34373,47 +33624,65 @@ function parseCue(parsedCue) { * limitations under the License. */ - - /** - * Create array of objects which should represent the given TTML text track. - * These objects have the following structure - * - start {Number}: start time, in seconds, at which the cue should - * be displayed - * - end {Number}: end time, in seconds, at which the cue should - * be displayed - * - element {HTMLElement}:
element representing the cue, with the - * right style. This div should then be appended to an element having - * the exact size of the wanted region the text track provide cues for. + * Find the offset for the first declaration of the given box in an isobmff. + * Returns -1 if not found or if incomplete. * - * TODO TTML parsing is still pretty heavy on the CPU. - * Optimizations have been done, principally to avoid using too much XML APIs, - * but we can still do better. - * @param {string} str - * @param {number} timeOffset + * This function does not throw or log in case of partial segments. + * @param {Uint8Array} buf - the isobmff + * @param {Number} wantedName + * @returns {Number} - Offset where the box begins. -1 if not found. */ -function parseTTMLToDiv(str, timeOffset) { - var parsedCues = (0,parse_ttml/* default */.Z)(str, timeOffset); - var cues = []; +function findCompleteBox(buf, wantedName) { + var len = buf.length; + var i = 0; - for (var i = 0; i < parsedCues.length; i++) { - var paragraphStyle = parsedCues[i].paragraphStyle; + while (i + 8 <= len) { + var size = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, i); - if (shouldApplyDefaultTTMLStyle(paragraphStyle)) { - applyDefaultTTMLStyle(paragraphStyle); + if (size === 0) { + size = len - i; + } else if (size === 1) { + if (i + 16 > len) { + return -1; + } + + size = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be8toi */ .pV)(buf, i + 8); } - var cue = parseCue(parsedCues[i]); + if (isNaN(size) || size <= 0) { + // should not happen + return -1; + } - if (cue !== null) { - cues.push(cue); + var name = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, i + 4); + + if (name === wantedName) { + if (i + size <= len) { + return i; + } + + return -1; } + + i += size; } - return cues; + return -1; } -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/html/index.ts + +/***/ }), + +/***/ 7445: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ returnParsedManifest) +/* harmony export */ }); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8170); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9795); /** * Copyright 2015 CANAL+ Group * @@ -34431,37 +33700,49 @@ function parseTTMLToDiv(str, timeOffset) { */ /** - * /!\ This file is feature-switchable. - * It always should be imported through the `features` object. + * As a Manifest instance is obtained, emit the right `warning` events + * (according to the Manifest's `parsingErrors` property`) followed by the right + * `parsed` event, as expected from a Manifest parser. + * @param {Manifest} manifest + * @param {string|undefined} url + * @returns {Observable} */ -/* harmony default export */ const html = (parseTTMLToDiv); +function returnParsedManifest(manifest, url) { + var warningEvts$ = rxjs__WEBPACK_IMPORTED_MODULE_0__.of.apply(void 0, manifest.parsingErrors.map(function (error) { + return { + type: "warning", + value: error + }; + })); + return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__/* .concat */ .z)(warningEvts$, (0,rxjs__WEBPACK_IMPORTED_MODULE_0__.of)({ + type: "parsed", + value: { + manifest: manifest, + url: url + } + })); +} /***/ }), -/***/ 1570: +/***/ 7278: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; // EXPORTS __webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ ttml_native + "Z": () => (/* binding */ generateManifestLoader) }); -// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/parse_ttml.ts + 3 modules -var parse_ttml = __webpack_require__(5403); -// EXTERNAL MODULE: ./src/compat/make_vtt_cue.ts -var make_vtt_cue = __webpack_require__(7253); -// EXTERNAL MODULE: ./src/compat/is_vtt_cue.ts -var is_vtt_cue = __webpack_require__(1988); -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/get_time_delimiters.ts + 1 modules -var get_time_delimiters = __webpack_require__(6177); -// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/regexps.ts -var regexps = __webpack_require__(5336); -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/native/parse_cue.ts +// EXTERNAL MODULE: ./src/utils/is_null_or_undefined.ts +var is_null_or_undefined = __webpack_require__(1946); +// EXTERNAL MODULE: ./src/utils/request/index.ts + 1 modules +var request = __webpack_require__(4597); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules +var Observable = __webpack_require__(4379); +;// CONCATENATED MODULE: ./src/transports/utils/call_custom_manifest_loader.ts /** * Copyright 2015 CANAL+ Group * @@ -34478,212 +33759,182 @@ var regexps = __webpack_require__(5336); * limitations under the License. */ +function callCustomManifestLoader(customManifestLoader, fallbackManifestLoader) { + return function (args) { + return new Observable/* Observable */.y(function (obs) { + var url = args.url; + var timeAPIsDelta = Date.now() - performance.now(); + var hasFinished = false; + var hasFallbacked = false; + /** + * Callback triggered when the custom manifest loader has a response. + * @param {Object} args + */ + var resolve = function resolve(_args) { + if (!hasFallbacked) { + hasFinished = true; + var receivedTime = _args.receivingTime !== undefined ? _args.receivingTime - timeAPIsDelta : undefined; + var sendingTime = _args.sendingTime !== undefined ? _args.sendingTime - timeAPIsDelta : undefined; + obs.next({ + type: "data-loaded", + value: { + responseData: _args.data, + size: _args.size, + duration: _args.duration, + url: _args.url, + receivedTime: receivedTime, + sendingTime: sendingTime + } + }); + obs.complete(); + } + }; + /** + * Callback triggered when the custom manifest loader fails + * @param {*} err - The corresponding error encountered + */ -var TEXT_ALIGN_TO_LIGN_ALIGN = { - left: "start", - center: "center", - right: "end", - start: "start", - end: "end" -}; -/** - * @type {Object} - */ - -var TEXT_ALIGN_TO_POSITION_ALIGN = { - left: "line-left", - center: "center", - right: "line-right" -}; -/** - * Parses an Element into a TextTrackCue or VTTCue. - * /!\ Mutates the given cueElement Element - * @param {Element} paragraph - * @param {Number} offset - * @param {Array.} styles - * @param {Array.} regions - * @param {Object} paragraphStyle - * @param {Object} ttParams - * @param {Boolean} shouldTrimWhiteSpace - * @returns {TextTrackCue|null} - */ - -function parseCue(parsedCue) { - var paragraph = parsedCue.paragraph, - timeOffset = parsedCue.timeOffset, - paragraphStyle = parsedCue.paragraphStyle, - ttParams = parsedCue.ttParams, - shouldTrimWhiteSpace = parsedCue.shouldTrimWhiteSpace; // Disregard empty elements: - // TTML allows for empty elements like
. - // If paragraph has neither time attributes, nor - // non-whitespace text, don't try to make a cue out of it. - - if (!paragraph.hasAttribute("begin") && !paragraph.hasAttribute("end") && /^\s*$/.test(paragraph.textContent === null ? "" : paragraph.textContent)) { - return null; - } - - var _getTimeDelimiters = (0,get_time_delimiters/* default */.Z)(paragraph, ttParams), - start = _getTimeDelimiters.start, - end = _getTimeDelimiters.end; - - var text = generateTextContent(paragraph, shouldTrimWhiteSpace); - var cue = (0,make_vtt_cue/* default */.Z)(start + timeOffset, end + timeOffset, text); + var reject = function reject(err) { + if (!hasFallbacked) { + hasFinished = true; + obs.error(err); + } + }; + /** + * Callback triggered when the custom manifest loader wants to fallback to + * the "regular" implementation + */ - if (cue === null) { - return null; - } - if ((0,is_vtt_cue/* default */.Z)(cue)) { - addStyle(cue, paragraphStyle); - } + var fallback = function fallback() { + hasFallbacked = true; + fallbackManifestLoader(args).subscribe(obs); + }; - return cue; + var callbacks = { + reject: reject, + resolve: resolve, + fallback: fallback + }; + var abort = customManifestLoader(url, callbacks); + return function () { + if (!hasFinished && !hasFallbacked && typeof abort === "function") { + abort(); + } + }; + }); + }; } +;// CONCATENATED MODULE: ./src/transports/utils/text_manifest_loader.ts /** - * Generate text to display for a given paragraph. - * @param {Element} paragraph - The

tag. - * @param {Boolean} shouldTrimWhiteSpaceForParagraph - * @returns {string} + * 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 generateTextContent(paragraph, shouldTrimWhiteSpaceForParagraph) { - /** - * Recursive function, taking a node in argument and returning the - * corresponding string. - * @param {Node} node - the node in question - * @returns {string} - */ - function loop(node, shouldTrimWhiteSpaceFromParent) { - var childNodes = node.childNodes; - var text = ""; - - for (var i = 0; i < childNodes.length; i++) { - var currentNode = childNodes[i]; - - if (currentNode.nodeName === "#text") { - var textContent = currentNode.textContent; - - if (textContent === null) { - textContent = ""; - } - if (shouldTrimWhiteSpaceFromParent) { - // 1. Trim leading and trailing whitespace. - // 2. Collapse multiple spaces into one. - var trimmed = textContent.trim(); - trimmed = trimmed.replace(/\s+/g, " "); - textContent = trimmed; - } // DOM Parser turns HTML escape caracters into caracters, - // that may be misinterpreted by VTTCue API (typically, less-than sign - // and greater-than sign can be interpreted as HTML tags signs). - // Original escaped caracters must be conserved. +/** + * Manifest loader triggered if there was no custom-defined one in the API. + * @param {string} url + * @returns {Observable} + */ - var escapedTextContent = textContent.replace(/&|\u0026/g, "&").replace(/<|\u003C/g, "<").replace(/>|\u2265/g, ">").replace(/\u200E/g, "‎").replace(/\u200F/g, "‏").replace(/\u00A0/g, " "); - text += escapedTextContent; - } else if (currentNode.nodeName === "br") { - text += "\n"; - } else if (currentNode.nodeName === "span" && currentNode.nodeType === Node.ELEMENT_NODE && currentNode.childNodes.length > 0) { - var spaceAttribute = currentNode.getAttribute("xml:space"); - var shouldTrimWhiteSpaceForSpan = (0,is_non_empty_string/* default */.Z)(spaceAttribute) ? spaceAttribute === "default" : shouldTrimWhiteSpaceFromParent; - text += loop(currentNode, shouldTrimWhiteSpaceForSpan); - } - } +function regularManifestLoader(_ref) { + var url = _ref.url; - return text; + if (url === undefined) { + throw new Error("Cannot perform HTTP(s) request. URL not known"); } - return loop(paragraph, shouldTrimWhiteSpaceForParagraph); + return (0,request/* default */.ZP)({ + url: url, + responseType: "text" + }); } /** - * Adds applicable style properties to a cue. - * /!\ Mutates cue argument. - * @param {VTTCue} cue - * @param {Object} style + * Generate a manifest loader for the application + * @param {Function} [customManifestLoader] + * @returns {Function} */ -function addStyle(cue, style) { - var extent = style.extent; - - if ((0,is_non_empty_string/* default */.Z)(extent)) { - var results = regexps/* REGXP_PERCENT_VALUES.exec */._0.exec(extent); +function generateManifestLoader(_ref2) { + var customManifestLoader = _ref2.customManifestLoader; - if (results != null) { - // Use width value of the extent attribute for size. - // Height value is ignored. - cue.size = Number(results[1]); - } + if ((0,is_null_or_undefined/* default */.Z)(customManifestLoader)) { + return regularManifestLoader; } - var writingMode = style.writingMode; // let isVerticalText = true; - - switch (writingMode) { - case "tb": - case "tblr": - cue.vertical = "lr"; - break; + return callCustomManifestLoader(customManifestLoader, regularManifestLoader); +} - case "tbrl": - cue.vertical = "rl"; - break; +/***/ }), - default: - // isVerticalText = false; - break; - } +/***/ 4791: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - var origin = style.origin; +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ areArraysOfNumbersEqual) +/* harmony export */ }); +/** + * 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. + */ - if ((0,is_non_empty_string/* default */.Z)(origin)) { - var _results = regexps/* REGXP_PERCENT_VALUES.exec */._0.exec(origin); +/** + * Check if two two arrays containing only numbers are equal. + * @param {Array.|TypedArray} arr1 + * @param {Array.|TypedArray} arr2 + * @returns {Boolean} + */ +function areArraysOfNumbersEqual(arr1, arr2) { + if (arr1.length !== arr2.length) { + return false; + } - if (_results != null) {// for vertical text use first coordinate of tts:origin - // to represent line of the cue and second - for position. - // Otherwise (horizontal), use them the other way around. - // if (isVerticalText) { - // TODO check and uncomment - // cue.position = Number(results[2]); - // cue.line = Number(results[1]); - // } else { - // TODO check and uncomment - // cue.position = Number(results[1]); - // cue.line = Number(results[2]); - // } - // A boolean indicating whether the line is an integer - // number of lines (using the line dimensions of the first - // line of the cue), or whether it is a percentage of the - // dimension of the video. The flag is set to true when lines - // are counted, and false otherwise. - // TODO check and uncomment - // cue.snapToLines = false; + for (var i = arr1.length - 1; i >= 0; i--) { + if (arr1[i] !== arr2[i]) { + return false; } } - var align = style.align; - - if ((0,is_non_empty_string/* default */.Z)(align)) { - cue.align = align; + return true; +} - if (align === "center") { - if (cue.align !== "center") { - // Workaround for a Chrome bug http://crbug.com/663797 - // Chrome does not support align = "center" - cue.align = "middle"; - } +/***/ }), - cue.position = "auto"; - } +/***/ 3274: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - var positionAlign = TEXT_ALIGN_TO_POSITION_ALIGN[align]; - cue.positionAlign = positionAlign === undefined ? "" : positionAlign; - var lineAlign = TEXT_ALIGN_TO_LIGN_ALIGN[align]; - cue.lineAlign = lineAlign === undefined ? "" : lineAlign; - } -} -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/native/parse_ttml_to_vtt.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ arrayFind) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -34700,28 +33951,50 @@ function addStyle(cue, style) { * limitations under the License. */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ + +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ + +/* eslint-disable @typescript-eslint/no-unsafe-call */ + +/* eslint-disable @typescript-eslint/no-unsafe-return */ + +/* eslint-disable no-restricted-properties */ /** - * @param str - * @param timeOffset + * Array.prototype.find ponyfill. + * @param {Array} arr + * @param {Function} predicate + * @param {*} context + * @returns {boolean} */ +function arrayFind(arr, predicate, thisArg) { + if (typeof Array.prototype.find === "function") { + return arr.find(predicate, thisArg); + } -function parseTtmlToNative(str, timeOffset) { - var parsedCues = (0,parse_ttml/* default */.Z)(str, timeOffset); - var cues = []; + var len = arr.length >>> 0; - for (var i = 0; i < parsedCues.length; i++) { - var parsedCue = parsedCues[i]; - var cue = parseCue(parsedCue); + for (var i = 0; i < len; i++) { + var val = arr[i]; - if (cue !== null) { - cues.push(cue); + if (predicate.call(thisArg, val, i, arr)) { + return val; } } - return cues; + return undefined; } -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/native/index.ts + +/***/ }), + +/***/ 5138: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ arrayFindIndex) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -34738,34 +34011,48 @@ function parseTtmlToNative(str, timeOffset) { * limitations under the License. */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ + +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ + +/* eslint-disable @typescript-eslint/no-unsafe-call */ + +/* eslint-disable @typescript-eslint/no-unsafe-return */ + +/* eslint-disable no-restricted-properties */ + /** - * /!\ This file is feature-switchable. - * It always should be imported through the `features` object. + * Array.prototype.find ponyfill. + * @param {Array} arr + * @param {Function} predicate + * @param {*} context + * @returns {boolean} */ +function arrayFindIndex(arr, predicate, thisArg) { + if (typeof Array.prototype.findIndex === "function") { + return arr.findIndex(predicate, thisArg); + } -/* harmony default export */ const ttml_native = (parseTtmlToNative); + var len = arr.length >>> 0; + + for (var i = 0; i < len; i++) { + if (predicate.call(thisArg, arr[i], i, arr)) { + return i; + } + } + + return -1; +} /***/ }), -/***/ 5403: +/***/ 7714: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ parseTTMLString -}); - -// EXTERNAL MODULE: ./src/utils/array_find.ts -var array_find = __webpack_require__(3274); -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -// EXTERNAL MODULE: ./src/utils/object_assign.ts -var object_assign = __webpack_require__(8026); -// EXTERNAL MODULE: ./src/log.ts + 1 modules -var log = __webpack_require__(3887); -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/get_parameters.ts +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ arrayIncludes) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -34782,98 +34069,89 @@ var log = __webpack_require__(3887); * limitations under the License. */ - -var CELL_RESOLUTION_REGEXP = /(\d+) (\d+)/; /** - * Returns global parameters from a TTML Document - * @param {Element} tt - node - * @throws Error - Throws if the spacing style is invalid. - * @returns {Object} + * Array.prototype.includes ponyfill. + * Returns ``true`` if the given array ``arr`` contains the element + * ``searchElement``. false ``otherwise``. + * + * Inspired from MDN polyfill, but ponyfilled instead + * + * @example + * ```js + * arrayIncludes([1, 2, 3], 3); + * // => true + * + * arrayIncludes([1, 2, 3], 7); + * // => false + * + * const obj = { a: 4 }; + * arrayIncludes([obj, { b: 7 }, { a: 3 }], obj); + * // => true + * + * // does not perform deep equality + * arrayIncludes([{ a: 4 }, { b: 7 }, { a: 3 }], { a: 4 }); + * // => false + * + * // the third argument state the starting index. 0 if not set. + * + * arrayIncludes([1, 2, 3], 2, 1); + * // => true + * + * arrayIncludes([1, 2, 3], 2, 2); + * // => false + * ``` + * + * @param {Array} arr + * @param {*} searchElement + * @param {number} [fromIndex] + * @returns {boolean} */ - -function getParameters(tt) { - var parsedFrameRate = tt.getAttribute("ttp:frameRate"); - var parsedSubFrameRate = tt.getAttribute("ttp:subFramRate"); - var parsedTickRate = tt.getAttribute("ttp:tickRate"); - var parsedFrameRateMultiplier = tt.getAttribute("ttp:frameRateMultiplier"); - var parsedSpaceStyle = tt.getAttribute("xml:space"); - var parsedCellResolution = tt.getAttribute("ttp:cellResolution"); - var cellResolution = { - columns: 32, - rows: 15 - }; - - if (parsedCellResolution !== null) { - var extractedData = CELL_RESOLUTION_REGEXP.exec(parsedCellResolution); - - if (extractedData === null || extractedData.length < 3) { - log/* default.warn */.Z.warn("TTML Parser: Invalid cellResolution"); - } else { - var columns = parseInt(extractedData[1], 10); - var rows = parseInt(extractedData[2], 10); - - if (isNaN(columns) || isNaN(rows)) { - log/* default.warn */.Z.warn("TTML Parser: Invalid cellResolution"); - } else { - cellResolution = { - columns: columns, - rows: rows - }; - } - } - } - - if ((0,is_non_empty_string/* default */.Z)(parsedSpaceStyle) && parsedSpaceStyle !== "default" && parsedSpaceStyle !== "preserve") { - throw new Error("Invalid spacing style"); +function arrayIncludes(arr, searchElement, fromIndex) { + /* eslint-disable @typescript-eslint/unbound-method */ + // eslint-disable-next-line no-restricted-properties + if (typeof Array.prototype.includes === "function") { + /* eslint-enable @typescript-eslint/unbound-method */ + // eslint-disable-next-line no-restricted-properties + return arr.includes(searchElement, fromIndex); } - var nbFrameRate = Number(parsedFrameRate); + var len = arr.length >>> 0; - if (isNaN(nbFrameRate) || nbFrameRate <= 0) { - nbFrameRate = 30; + if (len === 0) { + return false; } - var nbSubFrameRate = Number(parsedSubFrameRate); + var n = fromIndex | 0; + var k = n >= 0 ? Math.min(n, len - 1) : Math.max(len + n, 0); - if (isNaN(nbSubFrameRate) || nbSubFrameRate <= 0) { - nbSubFrameRate = 1; - } + var areTheSame = function areTheSame(x, y) { + return x === y || // Viva las JavaScriptas! + typeof x === "number" && typeof y === "number" && isNaN(x) && isNaN(y); + }; - var nbTickRate = Number(parsedTickRate); + while (k < len) { + if (areTheSame(arr[k], searchElement)) { + return true; + } - if (isNaN(nbTickRate) || nbTickRate <= 0) { - nbTickRate = undefined; + k++; } - var frameRate = nbFrameRate; - var subFrameRate = nbSubFrameRate != null ? nbSubFrameRate : 1; - var spaceStyle = parsedSpaceStyle !== null ? parsedSpaceStyle : "default"; - var tickRate = nbTickRate !== undefined ? nbTickRate : nbFrameRate * nbSubFrameRate; + return false; +} - if (parsedFrameRateMultiplier !== null) { - var multiplierResults = /^(\d+) (\d+)$/g.exec(parsedFrameRateMultiplier); +/***/ }), - if (multiplierResults !== null) { - var numerator = Number(multiplierResults[1]); - var denominator = Number(multiplierResults[2]); - var multiplierNum = numerator / denominator; - frameRate = nbFrameRate * multiplierNum; - } - } +/***/ 811: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - return { - cellResolution: cellResolution, - tickRate: tickRate, - frameRate: frameRate, - subFrameRate: subFrameRate, - spaceStyle: spaceStyle - }; -} -// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/get_parent_elements_by_tag_name.ts -var get_parent_elements_by_tag_name = __webpack_require__(2967); -// EXTERNAL MODULE: ./src/parsers/texttracks/ttml/get_styling.ts -var get_styling = __webpack_require__(3791); -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/nodes.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ assert), +/* harmony export */ "u": () => (/* binding */ assertInterface) +/* harmony export */ }); +/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3801); +/* harmony import */ var _is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1946); /** * Copyright 2015 CANAL+ Group * @@ -34890,47 +34168,59 @@ var get_styling = __webpack_require__(3791); * limitations under the License. */ + /** - * @param {Element} tt - * @returns {Element} + * Throw an AssertionError if the given assertion is false. + * @param {boolean} assertion + * @param {string} [message] - Optional message property for the AssertionError. + * @throws AssertionError - Throws if the assertion given is false */ -function getBodyNode(tt) { - return tt.getElementsByTagName("body")[0]; + +function assert(assertion, message) { + if (!assertion) { + throw new _errors__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z(message === undefined ? "invalid assertion" : message); + } } /** - * @param {Element} tt - node - * @returns {Array.} + * Throws if the given Object does not respect the interface. + * @param {Object} o + * @param {Object} iface - Contains the checked keynames of o and link them + * to their types (obtained through the typeof operator). + * @param {string} [name="object"] - name of the _interface_ + * @throws AssertionError - The argument o given is not an object + * @throws AssertionError - The _interface_ is not respected. */ +function assertInterface(o, iface, name) { + if (name === void 0) { + name = "object"; + } -function getStyleNodes(tt) { - return tt.getElementsByTagName("style"); -} -/** - * @param {Element} tt - node - * @returns {Array.} - */ - + assert(!(0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(o), name + " should be an object"); -function getRegionNodes(tt) { - return tt.getElementsByTagName("region"); -} -/** - * @param {Element} tt - node - * @returns {Array.} - */ + for (var k in iface) { + if (iface.hasOwnProperty(k)) { + /* eslint-disable max-len */ + /* eslint-disable @typescript-eslint/restrict-template-expressions */ + assert(typeof o[k] === iface[k], name + " should have property " + k + " as a " + iface[k]); + /* eslint-enable max-len */ -function getTextNodes(tt) { - return tt.getElementsByTagName("p"); + /* eslint-enable @typescript-eslint/restrict-template-expressions */ + } + } } +/***/ }), -// EXTERNAL MODULE: ./src/utils/array_find_index.ts -var array_find_index = __webpack_require__(5138); -// EXTERNAL MODULE: ./src/utils/array_includes.ts -var array_includes = __webpack_require__(7714); -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/resolve_styles_inheritance.ts +/***/ 8418: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ assertUnreachable) +/* harmony export */ }); +/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3801); /** * Copyright 2015 CANAL+ Group * @@ -34947,249 +34237,216 @@ var array_includes = __webpack_require__(7714); * limitations under the License. */ - - - /** - * Transform all styles inheriting from other styles to the same styles but with - * the inheritance removed (by resolving those inheritance here). - * - * Note that the original style object is directly mutated with every - * inheritance they had resolved and removed. + * TypeScript hack to make sure a code path is never taken. * - * To make a pseudo-code analogy this would be equivalent to transform those - * two classes: - * ``` - * class A { - * methodA() {} - * } + * This can for example be used to ensure that a switch statement handle all + * possible cases by adding a default clause calling assertUnreachable with + * an argument (it doesn't matter which one). * - * class B extends A { - * method B() {} - * } - * ``` - * into the same two classes without inheritance: - * ``` - * class A { - * methodA() {} - * } - * class B { - * methodA() {} // inherited from class A - * methodB() {} + * @example + * function parseBinary(str : "0" | "1") : number { + * switch (str) { + * case "0: + * return 0; + * case "1": + * return 1; + * default: + * // branch never taken. If it can be, TypeScript will yell at us because + * // its argument (here, `str`) is not of the right type. + * assertUnreachable(str); + * } * } - * ``` - * - * Doing this here allows to simplify further treatment of those styles. - * @param {Array.} styles + * @param {*} _ + * @throws AssertionError - Throw an AssertionError when called. If we're + * sufficiently strict with how we use TypeScript, this should never happen. */ -function resolveStylesInheritance(styles) { - // keep track of all the indexes parsed to avoid infinite loops - var recursivelyBrowsedIndexes = []; - - function resolveStyleInheritance(styleElt, index) { - recursivelyBrowsedIndexes.push(index); - - var _loop = function _loop(j) { - var extendedStyleID = styleElt.extendsStyles[j]; - var extendedStyleIndex = (0,array_find_index/* default */.Z)(styles, function (x) { - return x.id === extendedStyleID; - }); - - if (extendedStyleIndex < 0) { - log/* default.warn */.Z.warn("TTML Parser: unknown style inheritance: " + extendedStyleID); - } else { - var extendedStyle = styles[extendedStyleIndex]; +function assertUnreachable(_) { + throw new _errors__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z("Unreachable path taken"); +} - if ((0,array_includes/* default */.Z)(recursivelyBrowsedIndexes, extendedStyleIndex)) { - log/* default.warn */.Z.warn("TTML Parser: infinite style inheritance loop avoided"); - } else { - resolveStyleInheritance(extendedStyle, extendedStyleIndex); - } +/***/ }), - styleElt.style = (0,object_assign/* default */.Z)({}, extendedStyle.style, styleElt.style); - } - }; +/***/ 9689: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - for (var j = 0; j < styleElt.extendsStyles.length; j++) { - _loop(j); - } +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "J": () => (/* binding */ bytesToBase64), +/* harmony export */ "K": () => (/* binding */ base64ToBytes) +/* harmony export */ }); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3887); +/* eslint-disable */ - styleElt.extendsStyles.length = 0; - } +/* +MIT License +Copyright (c) 2020 Egor Nepomnyaschih +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ - for (var i = 0; i < styles.length; i++) { - resolveStyleInheritance(styles[i], i); - recursivelyBrowsedIndexes.length = 0; // reset - } +/* +// This constant can also be computed with the following algorithm: +const base64abc = [], + A = "A".charCodeAt(0), + a = "a".charCodeAt(0), + n = "0".charCodeAt(0); +for (let i = 0; i < 26; ++i) { + base64abc.push(String.fromCharCode(A + i)); } -;// CONCATENATED MODULE: ./src/parsers/texttracks/ttml/parse_ttml.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. +for (let i = 0; i < 26; ++i) { + base64abc.push(String.fromCharCode(a + i)); +} +for (let i = 0; i < 10; ++i) { + base64abc.push(String.fromCharCode(n + i)); +} +base64abc.push("+"); +base64abc.push("/"); */ +var base64abc = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"]; +/* +// This constant can also be computed with the following algorithm: +const l = 256, base64codes = new Uint8Array(l); +for (let i = 0; i < l; ++i) { + base64codes[i] = 255; // invalid character +} +base64abc.forEach((char, index) => { + base64codes[char.charCodeAt(0)] = index; +}); +base64codes["=".charCodeAt(0)] = 0; // ignored anyway, so we just need to prevent an error + */ - - - - - - -var STYLE_ATTRIBUTES = ["align", "backgroundColor", "color", "direction", "display", "displayAlign", "extent", "fontFamily", "fontSize", "fontStyle", "fontWeight", "lineHeight", "opacity", "origin", "overflow", "padding", "textAlign", "textDecoration", "textOutline", "unicodeBidi", "visibility", "wrapOption", "writingMode"]; +var base64codes = [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 0, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51]; /** - * Create array of objects which should represent the given TTML text track. - * TODO TTML parsing is still pretty heavy on the CPU. - * Optimizations have been done, principally to avoid using too much XML APIs, - * but we can still do better. - * @param {string} str - * @param {Number} timeOffset - * @returns {Array.} + * Obtain the value corresponding to a base64 char code. + * /!\ Can throw if the char code given is invalid. + * @param {number} charCode + * @returns {number} */ -function parseTTMLString(str, timeOffset) { - var cues = []; - var xml = new DOMParser().parseFromString(str, "text/xml"); - - if (xml !== null && xml !== undefined) { - var tts = xml.getElementsByTagName("tt"); - var tt = tts[0]; - - if (tt === undefined) { - throw new Error("invalid XML"); - } - - var body = getBodyNode(tt); - var styleNodes = getStyleNodes(tt); - var regionNodes = getRegionNodes(tt); - var paragraphNodes = getTextNodes(tt); - var ttParams = getParameters(tt); // construct idStyles array based on the xml as an optimization - - var idStyles = []; - - for (var i = 0; i <= styleNodes.length - 1; i++) { - var styleNode = styleNodes[i]; +function getBase64Code(charCode) { + if (charCode >= base64codes.length) { + throw new Error("Unable to parse base64 string."); + } - if (styleNode instanceof Element) { - var styleID = styleNode.getAttribute("xml:id"); + var code = base64codes[charCode]; - if (styleID !== null) { - var subStyles = styleNode.getAttribute("style"); - var extendsStyles = subStyles === null ? [] : subStyles.split(" "); - idStyles.push({ - id: styleID, - style: (0,get_styling/* getStylingFromElement */.b)(styleNode), - extendsStyles: extendsStyles - }); - } - } - } + if (code === 255) { + throw new Error("Unable to parse base64 string."); + } - resolveStylesInheritance(idStyles); // construct regionStyles array based on the xml as an optimization + return code; +} +/** + * Convert an array of bytes into a base64 string. + * @param {Array.|Uint8Array} bytes + * @returns {string} + */ - var regionStyles = []; - for (var _i = 0; _i <= regionNodes.length - 1; _i++) { - var regionNode = regionNodes[_i]; +function bytesToBase64(bytes) { + var result = ""; + var i; + var length = bytes.length; - if (regionNode instanceof Element) { - var regionID = regionNode.getAttribute("xml:id"); + for (i = 2; i < length; i += 3) { + result += base64abc[bytes[i - 2] >> 2]; + result += base64abc[(bytes[i - 2] & 0x03) << 4 | bytes[i - 1] >> 4]; + result += base64abc[(bytes[i - 1] & 0x0F) << 2 | bytes[i] >> 6]; + result += base64abc[bytes[i] & 0x3F]; + } - if (regionID !== null) { - (function () { - var regionStyle = (0,get_styling/* getStylingFromElement */.b)(regionNode); - var associatedStyleID = regionNode.getAttribute("style"); + if (i === length + 1) { + // 1 octet yet to write + result += base64abc[bytes[i - 2] >> 2]; + result += base64abc[(bytes[i - 2] & 0x03) << 4]; + result += "=="; + } - if ((0,is_non_empty_string/* default */.Z)(associatedStyleID)) { - var style = (0,array_find/* default */.Z)(idStyles, function (x) { - return x.id === associatedStyleID; - }); + if (i === length) { + // 2 octets yet to write + result += base64abc[bytes[i - 2] >> 2]; + result += base64abc[(bytes[i - 2] & 0x03) << 4 | bytes[i - 1] >> 4]; + result += base64abc[(bytes[i - 1] & 0x0F) << 2]; + result += "="; + } - if (style !== undefined) { - regionStyle = (0,object_assign/* default */.Z)({}, style.style, regionStyle); - } - } + return result; +} +/** + * Convert a base64 string into the corresponding Uint8Array containing its + * corresponding binary data. + * /!\ Can throw if an invalid base64 string was given. + * @param {Array.|Uint8Array} bytes + * @returns {string} + */ - regionStyles.push({ - id: regionID, - style: regionStyle, - // already handled - extendsStyles: [] - }); - })(); - } - } - } // Computing the style takes a lot of ressources. - // To avoid too much re-computation, let's compute the body style right - // now and do the rest progressively. - // TODO Compute corresponding CSS style here (as soon as we now the TTML - // style) to speed up the process even more. +function base64ToBytes(str) { + var paddingNeeded = str.length % 4; + var paddedStr = str; + if (paddingNeeded !== 0) { + _log__WEBPACK_IMPORTED_MODULE_0__/* .default.warn */ .Z.warn("base64ToBytes: base64 given miss padding"); + paddedStr += paddingNeeded === 3 ? "=" : paddingNeeded === 2 ? "==" : "==="; // invalid, but we will catch it + } - var bodyStyle = (0,get_styling/* getStylingAttributes */.U)(STYLE_ATTRIBUTES, body !== null ? [body] : [], idStyles, regionStyles); - var bodySpaceAttribute = body !== null ? body.getAttribute("xml:space") : undefined; - var shouldTrimWhiteSpaceOnBody = bodySpaceAttribute === "default" || ttParams.spaceStyle === "default"; + var index = paddedStr.indexOf("="); - for (var _i2 = 0; _i2 < paragraphNodes.length; _i2++) { - var paragraph = paragraphNodes[_i2]; + if (index !== -1 && index < paddedStr.length - 2) { + throw new Error("Unable to parse base64 string."); + } - if (paragraph instanceof Element) { - var divs = (0,get_parent_elements_by_tag_name/* default */.Z)(paragraph, "div"); - var paragraphStyle = (0,object_assign/* default */.Z)({}, bodyStyle, (0,get_styling/* getStylingAttributes */.U)(STYLE_ATTRIBUTES, [paragraph].concat(divs), idStyles, regionStyles)); - var paragraphSpaceAttribute = paragraph.getAttribute("xml:space"); - var shouldTrimWhiteSpace = (0,is_non_empty_string/* default */.Z)(paragraphSpaceAttribute) ? paragraphSpaceAttribute === "default" : shouldTrimWhiteSpaceOnBody; - var cue = { - paragraph: paragraph, - timeOffset: timeOffset, - idStyles: idStyles, - regionStyles: regionStyles, - body: body, - paragraphStyle: paragraphStyle, - ttParams: ttParams, - shouldTrimWhiteSpace: shouldTrimWhiteSpace - }; + var missingOctets = paddedStr.endsWith("==") ? 2 : paddedStr.endsWith("=") ? 1 : 0; + var n = paddedStr.length; + var result = new Uint8Array(n / 4 * 3); + var buffer; - if (cue !== null) { - cues.push(cue); - } - } - } + for (var i = 0, j = 0; i < n; i += 4, j += 3) { + buffer = getBase64Code(paddedStr.charCodeAt(i)) << 18 | getBase64Code(paddedStr.charCodeAt(i + 1)) << 12 | getBase64Code(paddedStr.charCodeAt(i + 2)) << 6 | getBase64Code(paddedStr.charCodeAt(i + 3)); + result[j] = buffer >> 16; + result[j + 1] = buffer >> 8 & 0xFF; + result[j + 2] = buffer & 0xFF; } - return cues; + return result.subarray(0, result.length - missingOctets); } /***/ }), -/***/ 5336: +/***/ 6968: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "YU": () => /* binding */ REGXP_4_HEX_COLOR, -/* harmony export */ "Dq": () => /* binding */ REGXP_8_HEX_COLOR, -/* harmony export */ "GK": () => /* binding */ REGXP_RGB_COLOR, -/* harmony export */ "ev": () => /* binding */ REGXP_RGBA_COLOR, -/* harmony export */ "eT": () => /* binding */ REGXP_LENGTH, -/* harmony export */ "_0": () => /* binding */ REGXP_PERCENT_VALUES, -/* harmony export */ "KO": () => /* binding */ REGXP_TIME_COLON, -/* harmony export */ "gu": () => /* binding */ REGXP_TIME_COLON_FRAMES, -/* harmony export */ "wf": () => /* binding */ REGXP_TIME_COLON_MS, -/* harmony export */ "jb": () => /* binding */ REGXP_TIME_FRAMES, -/* harmony export */ "te": () => /* binding */ REGXP_TIME_HMS, -/* harmony export */ "Du": () => /* binding */ REGXP_TIME_TICK +/* harmony export */ "zo": () => (/* binding */ concat), +/* harmony export */ "zK": () => (/* binding */ be2toi), +/* harmony export */ "QI": () => (/* binding */ be3toi), +/* harmony export */ "pX": () => (/* binding */ be4toi), +/* harmony export */ "pV": () => (/* binding */ be8toi), +/* harmony export */ "qb": () => (/* binding */ le2toi), +/* harmony export */ "dN": () => (/* binding */ le4toi), +/* harmony export */ "XT": () => (/* binding */ itobe2), +/* harmony export */ "kh": () => (/* binding */ itobe4), +/* harmony export */ "el": () => (/* binding */ itobe8), +/* harmony export */ "O_": () => (/* binding */ itole4), +/* harmony export */ "_f": () => (/* binding */ toUint8Array) /* harmony export */ }); +/* unused harmony exports le8toi, itole2, isABEqualBytes */ /** * Copyright 2015 CANAL+ Group * @@ -35205,391 +34462,228 @@ function parseTTMLString(str, timeOffset) { * See the License for the specific language governing permissions and * limitations under the License. */ -// examples: 00:00:40:07 (7 frames) or 00:00:40:07.1 (7 frames, 1 subframe) -var REGXP_TIME_COLON_FRAMES = /^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/; // examples: 00:00:40:07 (7 frames) or 00:00:40:07.1 (7 frames, 1 subframe) - -var REGXP_TIME_COLON = /^(?:(\d{2,}):)?(\d{2}):(\d{2})$/; // examples: 01:02:43.0345555 or 02:43.03 - -var REGXP_TIME_COLON_MS = /^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{2,})$/; // examples: 75f or 75.5f -var REGXP_TIME_FRAMES = /^(\d*\.?\d*)f$/; // examples: 50t or 50.5t +/** + * Returns a Uint8Array from the arguments given, in order: + * - if the next argument given is a number N set the N next bytes to 0. + * - else set the next bytes to the argument given. + * @param {...(Number|Uint8Array)} args + * @returns {Uint8Array} + */ +function concat() { + var l = arguments.length; + var i = -1; + var len = 0; + var arg; -var REGXP_TIME_TICK = /^(\d*\.?\d*)t$/; // examples: 3.45h, 3m or 4.20s + while (++i < l) { + arg = i < 0 || arguments.length <= i ? undefined : arguments[i]; + len += typeof arg === "number" ? arg : arg.length; + } -var REGXP_TIME_HMS = /^(?:(\d*\.?\d*)h)?(?:(\d*\.?\d*)m)?(?:(\d*\.?\d*)s)?(?:(\d*\.?\d*)ms)?$/; // examples: 50% 10% + var arr = new Uint8Array(len); + var offset = 0; + i = -1; -var REGXP_PERCENT_VALUES = /^(\d{1,2}|100)% (\d{1,2}|100)%$/; -var REGXP_LENGTH = /^((?:\+|\-)?\d*(?:\.\d+)?)(px|em|c|%|rh|rw)$/; -var REGXP_8_HEX_COLOR = /^#([0-9A-f]{2})([0-9A-f]{2})([0-9A-f]{2})([0-9A-f]{2})$/; -var REGXP_4_HEX_COLOR = /^#([0-9A-f])([0-9A-f])([0-9A-f])([0-9A-f])$/; -var REGXP_RGB_COLOR = /^rgb\( *(\d+) *, *(\d+) *, *(\d+) *\)/; -var REGXP_RGBA_COLOR = /^rgba\( *(\d+) *, *(\d+) *, *(\d+) *, *(\d+) *\)/; + while (++i < l) { + arg = i < 0 || arguments.length <= i ? undefined : arguments[i]; + if (typeof arg === "number") { + offset += arg; + } else if (arg.length > 0) { + arr.set(arg, offset); + offset += arg.length; + } + } -/***/ }), + return arr; +} +/** + * Translate groups of 2 big-endian bytes to Integer (from 0 up to 65535). + * @param {Uint8Array} bytes + * @param {Number} offset - The offset (from the start of the given array) + * @returns {Number} + */ -/***/ 1138: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ getCueBlocks -/* harmony export */ }); -/* harmony import */ var _utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6923); -/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(360); +function be2toi(bytes, offset) { + return (bytes[offset + 0] << 8) + (bytes[offset + 1] << 0); +} /** - * 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. + * Translate groups of 3 big-endian bytes to Integer. + * @param {Uint8Array} bytes + * @param {Number} offset - The offset (from the start of the given array) + * @returns {Number} */ +function be3toi(bytes, offset) { + return bytes[offset + 0] * 0x0010000 + bytes[offset + 1] * 0x0000100 + bytes[offset + 2]; +} /** - * Get cue blocks from a WebVTT file. - * @param {Array.} linified - Whole WebVTT file. Each new element in - * this array is a new line. - * @param {number} headerOffset - index of the first line after the header. - * Used to avoid taking the header into consideration. - * @returns {Array.>} + * Translate groups of 4 big-endian bytes to Integer. + * @param {Uint8Array} bytes + * @param {Number} offset - The offset (from the start of the given array) + * @returns {Number} */ -function getCueBlocks(linified, headerOffset) { - var cueBlocks = []; - - for (var i = headerOffset; i < linified.length; i++) { - if ((0,_utils__WEBPACK_IMPORTED_MODULE_0__/* .isStartOfCueBlock */ .tq)(linified, i)) { - var endOfCue = (0,_utils__WEBPACK_IMPORTED_MODULE_0__/* .findEndOfCueBlock */ .$4)(linified, i); - cueBlocks.push(linified.slice(i, endOfCue)); - i = endOfCue; - } else if ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(linified[i])) { - // continue incrementing i until either: - // - empty line - // - end - while ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(linified[i])) { - i++; - } - } - } - return cueBlocks; +function be4toi(bytes, offset) { + return bytes[offset + 0] * 0x1000000 + bytes[offset + 1] * 0x0010000 + bytes[offset + 2] * 0x0000100 + bytes[offset + 3]; } +/** + * Translate groups of 8 big-endian bytes to Integer. + * @param {Uint8Array} bytes + * @param {Number} offset - The offset (from the start of the given array) + * @returns {Number} + */ -/***/ }), -/***/ 4099: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ html -}); - -// EXTERNAL MODULE: ./src/parsers/texttracks/webvtt/get_cue_blocks.ts -var get_cue_blocks = __webpack_require__(1138); -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -// EXTERNAL MODULE: ./src/parsers/texttracks/webvtt/utils.ts -var utils = __webpack_require__(360); -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/get_style_blocks.ts +function be8toi(bytes, offset) { + return (bytes[offset + 0] * 0x1000000 + bytes[offset + 1] * 0x0010000 + bytes[offset + 2] * 0x0000100 + bytes[offset + 3]) * 0x100000000 + bytes[offset + 4] * 0x1000000 + bytes[offset + 5] * 0x0010000 + bytes[offset + 6] * 0x0000100 + bytes[offset + 7]; +} /** - * 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. + * Translate Integer (from 0 up to 65535) to a Uint8Array of length 2 of + * the corresponding big-endian bytes. + * @param {Number} num + * @returns {Uint8Array} */ +function itobe2(num) { + return new Uint8Array([num >>> 8 & 0xFF, num & 0xFF]); +} /** - * Get cue blocks from a WebVTT file. - * @param {Array.} linified - Whole WebVTT file. Each new element in - * this array is a new line. - * @param {number} headerOffset - index of the first line after the header. - * Used to avoid taking the header into consideration. - * @returns {Array.>} + * Translate Integer to a Uint8Array of length 4 of the corresponding big-endian + * bytes. + * @param {Number} num + * @returns {Uint8Array} */ -function getStyleBlocks(linified, headerOffset) { - var styleBlocks = []; - - for (var i = headerOffset; i < linified.length; i++) { - // - if ((0,utils/* isStartOfStyleBlock */.JF)(linified, i)) { - var startOfStyleBlock = i; - i++; // continue incrementing i until either: - // - empty line - // - end of file - - while ((0,is_non_empty_string/* default */.Z)(linified[i])) { - i++; - } - - var styleBlock = linified.slice(startOfStyleBlock, i); - styleBlocks.push(styleBlock); - } else if ((0,is_non_empty_string/* default */.Z)(linified[i])) { - // continue incrementing i until either: - // - empty line - // - end - while ((0,is_non_empty_string/* default */.Z)(linified[i])) { - i++; - } - } - } - return styleBlocks; +function itobe4(num) { + return new Uint8Array([num >>> 24 & 0xFF, num >>> 16 & 0xFF, num >>> 8 & 0xFF, num & 0xFF]); } -// EXTERNAL MODULE: ./src/parsers/texttracks/webvtt/parse_cue_block.ts + 1 modules -var parse_cue_block = __webpack_require__(9525); -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/create_default_style_elements.ts /** - * Creates default classes defined in the W3 specification - * - * https://www.w3.org/TR/webvtt1/#default-classes + * Translate Integer to a Uint8Array of length 8 of the corresponding big-endian + * bytes. + * /!\ If the top-most bytes are set, this might go over MAX_SAFE_INTEGER, thus + * leading to a "bad" value. + * @param {Number} num + * @returns {Uint8Array} */ -var colorMap = { - white: "#ffffff", - lime: "#00ff00", - cyan: "#00ffff", - red: "#ff0000", - yellow: "#ffff00", - magenta: "#ff00ff", - blue: "#0000ff", - black: "#000000" -}; -function createDefaultStyleElements() { - return Object.keys(colorMap).reduce(function (result, key) { - result[key] = "color: " + colorMap[key] + ";"; - result["bg_" + key] = "background-color: " + colorMap[key] + ";"; - return result; - }, {}); + + +function itobe8(num) { + var l = num % 0x100000000; + var h = (num - l) / 0x100000000; + return new Uint8Array([h >>> 24 & 0xFF, h >>> 16 & 0xFF, h >>> 8 & 0xFF, h & 0xFF, l >>> 24 & 0xFF, l >>> 16 & 0xFF, l >>> 8 & 0xFF, l & 0xFF]); } -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/parse_style_block.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. + * Translate groups of 2 little-endian bytes to Integer (from 0 up to 65535). + * @param {Uint8Array} bytes + * @param {Number} offset - The offset (from the start of the given array) + * @returns {Number} */ +function le2toi(bytes, offset) { + return (bytes[offset + 0] << 0) + (bytes[offset + 1] << 8); +} /** - * Parse style element from WebVTT. - * @param {Array.>} styleBlocks - * @return {Object} + * Translate groups of 4 little-endian bytes to Integer. + * @param {Uint8Array} bytes + * @param {Number} offset - The offset (from the start of the given array) + * @returns {Number} */ -function parseStyleBlocks(styleBlocks) { - var classes = createDefaultStyleElements(); - var global = ""; - styleBlocks.forEach(function (styleBlock) { - if (styleBlock.length >= 2) { - for (var index = 1; index < styleBlock.length; index++) { - var line = styleBlock[index]; - - if (Array.isArray(/::cue {/.exec(line))) { - line = styleBlock[++index]; - - while ((0,is_non_empty_string/* default */.Z)(line) && !(Array.isArray(/}/.exec(line)) || line.length === 0)) { - global += line; - line = styleBlock[++index]; - } - } else { - (function () { - var classNames = []; - var cueClassLine = /::cue\(\.?(.*?)\)(?:,| {)/.exec(line); - - while ((0,is_non_empty_string/* default */.Z)(line) && Array.isArray(cueClassLine)) { - classNames.push(cueClassLine[1]); - line = styleBlock[++index]; - cueClassLine = /::cue\(\.?(.*?)\)(?:,| {)/.exec(line); - } - - var styleContent = ""; - - while ((0,is_non_empty_string/* default */.Z)(line) && !(Array.isArray(/}/.exec(line)) || line.length === 0)) { - styleContent += line; - line = styleBlock[++index]; - } - - classNames.forEach(function (className) { - var styleElement = classes[className]; - if (styleElement === undefined) { - classes[className] = styleContent; - } else { - classes[className] += styleContent; - } - }); - })(); - } - } - } - }); - return { - classes: classes, - global: global - }; +function le4toi(bytes, offset) { + return bytes[offset + 0] + bytes[offset + 1] * 0x0000100 + bytes[offset + 2] * 0x0010000 + bytes[offset + 3] * 0x1000000; } -// EXTERNAL MODULE: ./src/utils/array_includes.ts -var array_includes = __webpack_require__(7714); -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/create_styled_element.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. + * Translate groups of 8 little-endian bytes to Integer. + * @param {Uint8Array} bytes + * @param {Number} offset - The offset (from the start of the given array) + * @returns {Number} */ +function le8toi(bytes, offset) { + return bytes[offset + 0] + bytes[offset + 1] * 0x0000100 + bytes[offset + 2] * 0x0010000 + bytes[offset + 3] * 0x1000000 + (bytes[offset + 4] + bytes[offset + 5] * 0x0000100 + bytes[offset + 6] * 0x0010000 + bytes[offset + 7] * 0x1000000) * 0x100000000; +} /** - * Construct an HTMLElement/TextNode representing the given node and apply - * the right styling on it. - * @param {Node} baseNode - * @param {Array.} styleElements - * @param {Array.} styleClasses - * @returns {Node} + * Translate Integer (from 0 up to 65535) to a Uint8Array of length 2 of + * the corresponding little-endian bytes. + * @param {Number} num + * @returns {Uint8Array} */ -function createStyledElement(baseNode, styleElements) { - var HTMLTags = ["u", "i", "b"]; - var authorizedNodeNames = ["u", "i", "b", "c", "#text"]; - var mainNodeName = baseNode.nodeName.toLowerCase().split(".")[0]; - var nodeWithStyle; - if ((0,array_includes/* default */.Z)(authorizedNodeNames, mainNodeName)) { - if (mainNodeName === "#text") { - var linifiedText = baseNode.wholeText.split("\n"); - nodeWithStyle = document.createElement("span"); +function itole2(num) { + return new Uint8Array([num & 0xFF, num >>> 8 & 0xFF]); +} +/** + * Translate Integer to a Uint8Array of length 4 of the corresponding + * little-endian bytes. + * @param {Number} num + * @returns {Uint8Array} + */ - for (var i = 0; i < linifiedText.length; i++) { - if (i > 0) { - nodeWithStyle.appendChild(document.createElement("br")); - } - if (linifiedText[i].length > 0) { - var textNode = document.createTextNode(linifiedText[i]); - nodeWithStyle.appendChild(textNode); - } - } - } else { - var nodeClasses = baseNode.nodeName.toLowerCase().split("."); - var styleContents = []; - nodeClasses.forEach(function (nodeClass) { - if ((0,is_non_empty_string/* default */.Z)(styleElements[nodeClass])) { - styleContents.push(styleElements[nodeClass]); - } - }); +function itole4(num) { + return new Uint8Array([num & 0xFF, num >>> 8 & 0xFF, num >>> 16 & 0xFF, num >>> 24 & 0xFF]); +} +/** + * Check if an ArrayBuffer is equal to the bytes given. + * @param {ArrayBuffer} buffer + * @param {Uint8Array} bytes + * @returns {Boolean} + */ - if (styleContents.length !== 0) { - // If style must be applied - var attr = document.createAttribute("style"); - styleContents.forEach(function (styleContent) { - attr.value += styleContent; - }); - var nameClass = (0,array_includes/* default */.Z)(HTMLTags, mainNodeName) ? mainNodeName : "span"; - nodeWithStyle = document.createElement(nameClass); - nodeWithStyle.setAttributeNode(attr); - } else { - // If style mustn't be applied. Rebuild element with tag name - var elementTag = !(0,array_includes/* default */.Z)(HTMLTags, mainNodeName) ? "span" : mainNodeName; - nodeWithStyle = document.createElement(elementTag); - } - for (var j = 0; j < baseNode.childNodes.length; j++) { - var child = createStyledElement(baseNode.childNodes[j], styleElements); - nodeWithStyle.appendChild(child); - } - } - } else { - nodeWithStyle = document.createElement("span"); +function isABEqualBytes(buffer, bytes) { + var view = new DataView(buffer); + var len = view.byteLength; - for (var _j = 0; _j < baseNode.childNodes.length; _j++) { - var _child = createStyledElement(baseNode.childNodes[_j], styleElements); + if (len !== bytes.length) { + return false; + } - nodeWithStyle.appendChild(_child); + for (var i = 0; i < len; i++) { + if (view.getUint8(i) !== bytes[i]) { + return false; } } - return nodeWithStyle; + return true; } -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/convert_payload_to_html.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. + * Convert any BufferSource-typed structure into the corresponding Uint8Array. + * @param {BufferSource} input + * @returns {Uint8Array} */ -/** - * @param {string} text - * @param {Array.} styleElements - * @returns {Array.} - */ -function convertPayloadToHTML(text, styleElements) { - var filteredText = text // Remove timestamp tags - .replace(/<[0-9]{2}:[0-9]{2}.[0-9]{3}>/, "") // Remove tag content or attributes (e.g. => ) - .replace(/<([u,i,b,c])(\..*?)?(?: .*?)?>(.*?)<\/\1>/g, "<$1$2>$3"); - var parsedWebVTT = new DOMParser().parseFromString(filteredText, "text/html"); - var nodes = parsedWebVTT.body.childNodes; - var styledElements = []; +function toUint8Array(input) { + return input instanceof Uint8Array ? input : input instanceof ArrayBuffer ? new Uint8Array(input) : new Uint8Array(input.buffer); +} - for (var i = 0; i < nodes.length; i++) { - styledElements.push(createStyledElement(nodes[i], styleElements)); - } - return styledElements; -} -// EXTERNAL MODULE: ./src/utils/object_values.ts -var object_values = __webpack_require__(1679); -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/create_style_attribute.ts + +/***/ }), + +/***/ 8117: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4379); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4072); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8170); +/* harmony import */ var _is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1946); /** * Copyright 2015 CANAL+ Group * @@ -35606,176 +34700,260 @@ var object_values = __webpack_require__(1679); * limitations under the License. */ -/** - * Construct a DOM attribute reflecting given cue settings - * @param {Partial>} settings - * @returns {Attr} - */ - -function createStyleAttribute(settings) { - var pAttr = document.createAttribute("style"); - pAttr.value = getAttrValue(settings); - return pAttr; -} - -var getAttrValue = function getAttrValue(settings) { - var hasSettings = settings !== undefined && (0,object_values/* default */.Z)(settings).length !== 0; + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - if (!hasSettings) { - return "text-align:center"; +function castToObservable(value) { + if (value instanceof rxjs__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return value; } + /* eslint-disable-next-line @typescript-eslint/no-unsafe-member-access */ - var xPositioning = getPositioningX(settings); - var yPositioning = getPositioningY(settings); - return "position: absolute;" + "margin: 0;" + ("transform: translate(" + xPositioning.offset + "%," + yPositioning.offset + "%);") + ("width: " + getSizePercentage(settings.size) + "%;") + ("left: " + xPositioning.position + "%;") + ("top: " + (yPositioning.position !== null ? yPositioning.position + "%" : "auto") + ";") + ("text-align: " + getAlignValue(settings.align) + ";"); -}; -var PositionAlignment; + if (!(0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(value) && typeof value.subscribe === "function") { + var valObsLike = value; + return new rxjs__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (obs) { + var sub = valObsLike.subscribe(function (val) { + obs.next(val); + }, function (err) { + obs.error(err); + }, function () { + obs.complete(); + }); + return function () { + if (!(0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(sub) && typeof sub.dispose === "function") { + sub.dispose(); + } else if (!(0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(sub) && typeof sub.unsubscribe === "function") { + sub.unsubscribe(); + } + }; + }); + } // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -(function (PositionAlignment) { - PositionAlignment["LINE_LEFT"] = "line-left"; - PositionAlignment["CENTER"] = "center"; - PositionAlignment["LINE_RIGHT"] = "line-right"; -})(PositionAlignment || (PositionAlignment = {})); -var Align; + if (!(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); + } // eslint-disable-next-line @typescript-eslint/no-unsafe-return -(function (Align) { - Align["LEFT"] = "left"; - Align["CENTER"] = "center"; - Align["RIGHT"] = "right"; -})(Align || (Align = {})); -var LineAlignment; + return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.of)(value); +} -(function (LineAlignment) { - LineAlignment["START"] = "start"; - LineAlignment["CENTER"] = "center"; - LineAlignment["END"] = "end"; -})(LineAlignment || (LineAlignment = {})); +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castToObservable); -var getPositioningX = function getPositioningX(settings) { - return { - position: getXPositionPercentage(settings), - offset: getXOffsetPercentage(settings) - }; -}; +/***/ }), -var getXPositionPercentage = function getXPositionPercentage(settings) { - var _alignMap; +/***/ 8025: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - var positionPercentage = getPercentageValue(settings.position); +"use strict"; - if (positionPercentage !== null) { - return positionPercentage; - } +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ deferSubscriptions) +}); - var align = getAlignValue(settings.align); - var alignMap = (_alignMap = {}, _alignMap[Align.LEFT] = 0, _alignMap[Align.CENTER] = 50, _alignMap[Align.RIGHT] = 100, _alignMap); - return alignMap[align]; +// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js +var tslib_es6 = __webpack_require__(655); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/Immediate.js +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var nextHandle = 1; +var RESOLVED = /*@__PURE__*/ (function () { return /*@__PURE__*/ Promise.resolve(); })(); +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; + RESOLVED.then(function () { return findAndClearHandle(handle) && cb(); }); + return handle; + }, + clearImmediate: function (handle) { + findAndClearHandle(handle); + }, }; - -var getXOffsetPercentage = function getXOffsetPercentage(settings) { - var _positionAlignmentMap, _alignMap2; - - var getPositionAlignment = function getPositionAlignment(positionSetting) { - var positionRegex = /,(line-left|line-right|center)/; - var matches = positionRegex.exec(positionSetting); - - if (!Array.isArray(matches) || matches.length < 2) { - return null; +var TestTools = { + pending: function () { + return Object.keys(activeHandles).length; } - - return matches[1]; - }; - - var positionAlignmentMap = (_positionAlignmentMap = {}, _positionAlignmentMap[PositionAlignment.LINE_LEFT] = 0, _positionAlignmentMap[PositionAlignment.CENTER] = -50, _positionAlignmentMap[PositionAlignment.LINE_RIGHT] = -100, _positionAlignmentMap); - var positionAlignment = settings.position !== undefined ? getPositionAlignment(settings.position) : null; - - if (positionAlignment !== null) { - return positionAlignmentMap[positionAlignment]; - } - - var alignMap = (_alignMap2 = {}, _alignMap2[Align.LEFT] = 0, _alignMap2[Align.CENTER] = -50, _alignMap2[Align.RIGHT] = -100, _alignMap2); - var align = settings.align !== undefined ? getAlignValue(settings.align) : Align.CENTER; - return alignMap[align]; }; +//# sourceMappingURL=Immediate.js.map -var getPositioningY = function getPositioningY(settings) { - return { - position: getYPositionPercentage(settings.line), - offset: getYOffsetPercentage(settings.line) - }; -}; +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsyncAction.js + 1 modules +var AsyncAction = __webpack_require__(6114); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsapAction.js +/** PURE_IMPORTS_START tslib,_util_Immediate,_AsyncAction PURE_IMPORTS_END */ -var getYPositionPercentage = function getYPositionPercentage(lineSetting) { - return getPercentageValue(lineSetting); -}; -var getYOffsetPercentage = function getYOffsetPercentage(lineSetting) { - var _lineAlignmentMap; - var getLineAlignment = function getLineAlignment(line) { - var positionRegex = /,(start|center|end)/; - var matches = positionRegex.exec(line); +var AsapAction = /*@__PURE__*/ (function (_super) { + 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; + } + 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 = Immediate.setImmediate(scheduler.flush.bind(scheduler, null))); + }; + AsapAction.prototype.recycleAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + if ((delay !== null && delay > 0) || (delay === null && this.delay > 0)) { + return _super.prototype.recycleAsyncId.call(this, scheduler, id, delay); + } + if (scheduler.actions.length === 0) { + Immediate.clearImmediate(id); + scheduler.scheduled = undefined; + } + return undefined; + }; + return AsapAction; +}(AsyncAction/* AsyncAction */.o)); - if (!Array.isArray(matches) || matches.length < 2) { - return null; +//# sourceMappingURL=AsapAction.js.map + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsyncScheduler.js + 1 modules +var AsyncScheduler = __webpack_require__(2980); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsapScheduler.js +/** PURE_IMPORTS_START tslib,_AsyncScheduler PURE_IMPORTS_END */ + + +var AsapScheduler = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(AsapScheduler, _super); + function AsapScheduler() { + return _super !== null && _super.apply(this, arguments) || this; } + AsapScheduler.prototype.flush = function (action) { + this.active = true; + this.scheduled = undefined; + var actions = this.actions; + var error; + var index = -1; + var count = actions.length; + action = action || actions.shift(); + do { + if (error = action.execute(action.state, action.delay)) { + break; + } + } while (++index < count && (action = actions.shift())); + this.active = false; + if (error) { + while (++index < count && (action = actions.shift())) { + action.unsubscribe(); + } + throw error; + } + }; + return AsapScheduler; +}(AsyncScheduler/* AsyncScheduler */.v)); - return matches[1]; - }; +//# sourceMappingURL=AsapScheduler.js.map - var lineAlignmentMap = (_lineAlignmentMap = {}, _lineAlignmentMap[LineAlignment.START] = 0, _lineAlignmentMap[LineAlignment.CENTER] = -50, _lineAlignmentMap[LineAlignment.END] = -100, _lineAlignmentMap); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/asap.js +/** PURE_IMPORTS_START _AsapAction,_AsapScheduler PURE_IMPORTS_END */ - if (lineSetting === undefined) { - return lineAlignmentMap[LineAlignment.START]; - } - var lineAlignment = getLineAlignment(lineSetting); - return lineAlignment !== null ? lineAlignmentMap[lineAlignment] : lineAlignmentMap[LineAlignment.START]; -}; +var asapScheduler = /*@__PURE__*/ new AsapScheduler(AsapAction); +var asap = asapScheduler; +//# sourceMappingURL=asap.js.map -var getAlignValue = function getAlignValue(alignSetting) { - switch (alignSetting) { - case "left": - case "start": - return "left"; +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules +var Observable = __webpack_require__(4379); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isNumeric.js +var isNumeric = __webpack_require__(5812); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/observable/SubscribeOnObservable.js +/** PURE_IMPORTS_START tslib,_Observable,_scheduler_asap,_util_isNumeric PURE_IMPORTS_END */ - case "right": - case "end": - return "right"; - default: - return "center"; - } -}; -var getSizePercentage = function getSizePercentage(sizeSetting) { - var defaultSize = 100; - return getPercentageValueOrDefault(sizeSetting, defaultSize); -}; -var getPercentageValueOrDefault = function getPercentageValueOrDefault(percentageString, defaultValue) { - var value = getPercentageValue(percentageString); - return value !== null ? value : defaultValue; -}; +var SubscribeOnObservable = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(SubscribeOnObservable, _super); + function SubscribeOnObservable(source, delayTime, scheduler) { + if (delayTime === void 0) { + delayTime = 0; + } + if (scheduler === void 0) { + scheduler = asap; + } + var _this = _super.call(this) || this; + _this.source = source; + _this.delayTime = delayTime; + _this.scheduler = scheduler; + if (!(0,isNumeric/* isNumeric */.k)(delayTime) || delayTime < 0) { + _this.delayTime = 0; + } + if (!scheduler || typeof scheduler.schedule !== 'function') { + _this.scheduler = asap; + } + return _this; + } + SubscribeOnObservable.create = function (source, delay, scheduler) { + if (delay === void 0) { + delay = 0; + } + if (scheduler === void 0) { + scheduler = asap; + } + return new SubscribeOnObservable(source, delay, scheduler); + }; + SubscribeOnObservable.dispatch = function (arg) { + var source = arg.source, subscriber = arg.subscriber; + return this.add(source.subscribe(subscriber)); + }; + SubscribeOnObservable.prototype._subscribe = function (subscriber) { + var delay = this.delayTime; + var source = this.source; + var scheduler = this.scheduler; + return scheduler.schedule(SubscribeOnObservable.dispatch, delay, { + source: source, subscriber: subscriber + }); + }; + return SubscribeOnObservable; +}(Observable/* Observable */.y)); -var getPercentageValue = function getPercentageValue(percentageString) { - if (percentageString === undefined) { - return null; - } +//# sourceMappingURL=SubscribeOnObservable.js.map - var percentageValueRegex = /^([\d.]+)%/; - var matches = percentageValueRegex.exec(percentageString); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/subscribeOn.js +/** PURE_IMPORTS_START _observable_SubscribeOnObservable PURE_IMPORTS_END */ - if (!Array.isArray(matches) || matches.length < 2) { - return null; - } +function subscribeOn(scheduler, delay) { + if (delay === void 0) { + delay = 0; + } + return function subscribeOnOperatorFunction(source) { + return source.lift(new SubscribeOnOperator(scheduler, delay)); + }; +} +var SubscribeOnOperator = /*@__PURE__*/ (function () { + function SubscribeOnOperator(scheduler, delay) { + this.scheduler = scheduler; + this.delay = delay; + } + SubscribeOnOperator.prototype.call = function (subscriber, source) { + return new SubscribeOnObservable(source, this.delay, this.scheduler).subscribe(subscriber); + }; + return SubscribeOnOperator; +}()); +//# sourceMappingURL=subscribeOn.js.map - return parseInt(matches[1], 10); -}; -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/to_html.ts +;// CONCATENATED MODULE: ./src/utils/defer_subscriptions.ts /** * Copyright 2015 CANAL+ Group * @@ -35793,60 +34971,94 @@ var getPercentageValue = function getPercentageValue(percentageString) { */ - /** - * Parse cue block into an object with the following properties: - * - start {number}: start time at which the cue should be displayed - * - end {number}: end time at which the cue should be displayed - * - element {HTMLElement}: the cue text, translated into an HTMLElement + * At subscription, instead of "running" the Observable right away, wait until + * the current task has finished executing before actually running this + * Observable. * - * Returns undefined if the cue block could not be parsed. - * @param {Array.} cueBlock - * @param {Number} timeOffset - * @param {Array.} classes - * @returns {Object|undefined} + * 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 toHTML(cueObj, styling) { - var start = cueObj.start, - end = cueObj.end, - settings = cueObj.settings, - header = cueObj.header, - payload = cueObj.payload; - var region = document.createElement("div"); - var regionAttr = document.createAttribute("style"); - regionAttr.value = "width:100%;" + "height:100%;" + "display:flex;" + "flex-direction:column;" + "justify-content:flex-end;" + "align-items:center;"; - region.setAttributeNode(regionAttr); // Get content, format and apply style. - - var pElement = document.createElement("p"); - var pAttr = createStyleAttribute(settings); - pElement.setAttributeNode(pAttr); - var spanElement = document.createElement("span"); - var attr = document.createAttribute("style"); // set color and background-color default values, as indicated in: - // https://www.w3.org/TR/webvtt1/#applying-css-properties - - attr.value = "background-color:rgba(0,0,0,0.8);" + "color:white;"; - spanElement.setAttributeNode(attr); - var global = styling.global, - classes = styling.classes; - var localStyle = (0,is_non_empty_string/* default */.Z)(header) ? classes[header] : undefined; - var styles = [global, localStyle].filter(function (s) { - return s !== undefined; - }).join(""); - attr.value += styles; - spanElement.setAttributeNode(attr); - convertPayloadToHTML(payload.join("\n"), classes).forEach(function (element) { - spanElement.appendChild(element); - }); - region.appendChild(pElement); - pElement.appendChild(spanElement); - return { - start: start, - end: end, - element: region +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(subscribeOn(asapScheduler)); }; } -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/parse_webvtt_to_div.ts + +/***/ }), + +/***/ 1959: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ EventEmitter), +/* harmony export */ "R": () => (/* binding */ fromEvent) +/* harmony export */ }); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4379); +/* 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); /** * Copyright 2015 CANAL+ Group * @@ -35865,99 +35077,135 @@ function toHTML(cueObj, styling) { - - - /** - * Parse WebVTT from text. Returns an array with: - * - start : start of current cue, in seconds - * - end : end of current cue, in seconds - * - content : HTML formatted cue. - * - * Global style is parsed and applied to div element. - * Specific style is parsed and applied to class element. - * - * @throws Error - Throws if the given WebVTT string is invalid. - * @param {string} text - The whole webvtt subtitles to parse - * @param {Number} timeOffset - Offset to add to start and end times, in seconds - * @return {Array.} + * Simple but fully type-safe EventEmitter implementation. + * @class EventEmitter */ -function parseWebVTT(text, timeOffset) { - var newLineChar = /\r\n|\n|\r/g; // CRLF|LF|CR +var EventEmitter = /*#__PURE__*/function () { + function EventEmitter() { + this._listeners = {}; + } + /** + * Register a new callback for an event. + * + * @param {string} evt - The event to register a callback to + * @param {Function} fn - The callback to call as that event is triggered. + * The callback will take as argument the eventual payload of the event + * (single argument). + */ - var linified = text.split(newLineChar); - var cuesArray = []; - if (/^WEBVTT( |\t|\n|\r|$)/.exec(linified[0]) === null) { - throw new Error("Can't parse WebVTT: Invalid File."); + var _proto = EventEmitter.prototype; + + _proto.addEventListener = function addEventListener(evt, fn) { + var listeners = this._listeners[evt]; + + if (!Array.isArray(listeners)) { + this._listeners[evt] = [fn]; + } else { + listeners.push(fn); + } } + /** + * Unregister callbacks linked to events. + * @param {string} [evt] - The event for which the callback[s] should be + * unregistered. Set it to null or undefined to remove all callbacks + * currently registered (for any event). + * @param {Function} [fn] - The callback to unregister. If set to null + * or undefined while the evt argument is set, all callbacks linked to that + * event will be unregistered. + */ + ; - var firstLineAfterHeader = (0,utils/* getFirstLineAfterHeader */.yE)(linified); - var styleBlocks = getStyleBlocks(linified, firstLineAfterHeader); - var cueBlocks = (0,get_cue_blocks/* default */.Z)(linified, firstLineAfterHeader); - var styles = parseStyleBlocks(styleBlocks); + _proto.removeEventListener = function removeEventListener(evt, fn) { + if ((0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(evt)) { + this._listeners = {}; + return; + } - for (var i = 0; i < cueBlocks.length; i++) { - var cueObject = (0,parse_cue_block/* default */.Z)(cueBlocks[i], timeOffset); + var listeners = this._listeners[evt]; - if (cueObject != null) { - var htmlCue = toHTML(cueObject, styles); - cuesArray.push(htmlCue); + if (!Array.isArray(listeners)) { + return; + } + + if ((0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(fn)) { + delete this._listeners[evt]; + return; + } + + var index = listeners.indexOf(fn); + + if (index !== -1) { + listeners.splice(index, 1); + } + + if (listeners.length === 0) { + delete this._listeners[evt]; } } + /** + * Trigger every registered callbacks for a given event + * @param {string} evt - The event to trigger + * @param {*} arg - The eventual payload for that event. All triggered + * callbacks will recieve this payload as argument. + */ + ; - return cuesArray; -} -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/html/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. - */ + _proto.trigger = function trigger(evt, arg) { + var listeners = this._listeners[evt]; + + if (!Array.isArray(listeners)) { + return; + } + + listeners.slice().forEach(function (listener) { + try { + listener(arg); + } catch (e) { + _log__WEBPACK_IMPORTED_MODULE_1__/* .default.error */ .Z.error(e, e instanceof Error ? e.stack : null); + } + }); + }; + return EventEmitter; +}(); /** - * /!\ This file is feature-switchable. - * It always should be imported through the `features` object. + * 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} */ -/* harmony default export */ const html = (parseWebVTT); + + +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); + }; + }); +} /***/ }), -/***/ 9405: +/***/ 2793: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ webvtt_native -}); - -// EXTERNAL MODULE: ./src/compat/is_vtt_cue.ts -var is_vtt_cue = __webpack_require__(1988); -// EXTERNAL MODULE: ./src/parsers/texttracks/webvtt/get_cue_blocks.ts -var get_cue_blocks = __webpack_require__(1138); -// EXTERNAL MODULE: ./src/parsers/texttracks/webvtt/parse_cue_block.ts + 1 modules -var parse_cue_block = __webpack_require__(9525); -// EXTERNAL MODULE: ./src/parsers/texttracks/webvtt/utils.ts -var utils = __webpack_require__(360); -// EXTERNAL MODULE: ./src/utils/array_includes.ts -var array_includes = __webpack_require__(7714); -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/native/set_settings_on_cue.ts +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ filterMap) +/* harmony export */ }); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1410); +/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5709); +/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6008); /** * Copyright 2015 CANAL+ Group * @@ -35976,109 +35224,36 @@ var is_non_empty_string = __webpack_require__(6923); /** - * Add the corresponding settings on the given cue. - * /!\ Mutates the cue given. - * @param {Object} settings - settings for the cue, as a key-value object. - * @param {ICompatVTTCue|TextTrackCue} cue + * 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 setSettingsOnCue(settings, cue) { - if ((0,is_non_empty_string/* default */.Z)(settings.vertical) && (settings.vertical === "rl" || settings.vertical === "lr")) { - cue.vertical = settings.vertical; - } - - if ((0,is_non_empty_string/* default */.Z)(settings.line)) { - // Capture groups: - // 1 -> percentage position - // 2 -> optional decimals from percentage position - // 3 -> optional follow-up of the string indicating alignment value - // 4 -> alignment value - var percentagePosition = /^(\d+(\.\d+)?)%(,([a-z]+))?/; - var percentageMatches = percentagePosition.exec(settings.line); - - if (Array.isArray(percentageMatches)) { - cue.line = Number(percentageMatches[1]); - cue.snapToLines = false; - - if ((0,array_includes/* default */.Z)(["start", "center", "end"], percentageMatches[4])) { - cue.lineAlign = percentageMatches[4]; - } - } else { - // Capture groups: - // 1 -> line number - // 2 -> optional follow-up of the string indicating alignment value - // 3 -> alignment value - var linePosition = /^(-?\d+)(,([a-z]+))?/; - var lineMatches = linePosition.exec(settings.line); - - if (Array.isArray(lineMatches)) { - cue.line = Number(lineMatches[1]); - cue.snapToLines = true; - - if ((0,array_includes/* default */.Z)(["start", "center", "end"], lineMatches[3])) { - cue.lineAlign = lineMatches[3]; - } - } - } - } - - if ((0,is_non_empty_string/* default */.Z)(settings.position)) { - var positionRegex = /^([\d\.]+)%(?:,(line-left|line-right|center))?$/; - var positionArr = positionRegex.exec(settings.position); - - if (Array.isArray(positionArr) && positionArr.length >= 2) { - var position = parseInt(positionArr[1], 10); - - if (!isNaN(position)) { - cue.position = position; - - if (positionArr[2] !== undefined) { - cue.positionAlign = positionArr[2]; - } - } - } - } - - if ((0,is_non_empty_string/* default */.Z)(settings.size)) { - cue.size = settings.size; - } - - if (typeof settings.align === "string" && (0,array_includes/* default */.Z)(["start", "center", "end", "left"], settings.align)) { - cue.align = settings.align; - } +function filterMap(callback, filteringToken) { + return function (source) { + return (0,rxjs__WEBPACK_IMPORTED_MODULE_0__/* .defer */ .P)(function () { + return source.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_1__/* .map */ .U)(callback), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__/* .filter */ .h)(function (x) { + return x !== filteringToken; + })); + }); + }; } -// EXTERNAL MODULE: ./src/compat/make_vtt_cue.ts -var make_vtt_cue = __webpack_require__(7253); -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/native/to_native_cue.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. - */ -/** - * @param {Object} cue Object - * @returns {TextTrackCue|ICompatVTTCue|null} - */ +/***/ }), -function toNativeCue(cueObj) { - var start = cueObj.start, - end = cueObj.end, - payload = cueObj.payload; - var text = payload.join("\n"); - return (0,make_vtt_cue/* default */.Z)(start, end, text); -} -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/native/parse_vtt_to_cues.ts +/***/ 9592: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ flatMap) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -36096,57 +35271,53 @@ function toNativeCue(cueObj) { */ /** - * /!\ This file is feature-switchable. - * It always should be imported through the `features` object. + * Map each element using a mapping function, then flat the result into + * a new array. + * @param {Array.<*>} originalArray + * @param {Function} fn */ +function flatMap(originalArray, fn) { + /* eslint-disable @typescript-eslint/unbound-method */ + /* eslint-disable @typescript-eslint/no-unsafe-member-access */ + /* eslint-disable @typescript-eslint/no-unsafe-return */ + /* eslint-disable @typescript-eslint/no-unsafe-call */ + if (typeof Array.prototype.flatMap === "function") { + return originalArray.flatMap(fn); + } + /* eslint-enable @typescript-eslint/unbound-method */ + /* eslint-enable @typescript-eslint/no-unsafe-member-access */ - // Simple VTT to ICompatVTTCue parser: -// Just parse cues and associated settings. -// Does not take into consideration STYLE and REGION blocks. - -/** - * Parse whole WEBVTT file into an array of cues, to be inserted in a video's - * TrackElement. - * @param {string} vttStr - * @param {Number} timeOffset - * @returns {Array.} - */ + /* eslint-enable @typescript-eslint/no-unsafe-return */ -function parseVTTStringToVTTCues(vttStr, timeOffset) { - // WEBVTT authorize CRLF, LF or CR as line terminators - var lines = vttStr.split(/\r\n|\n|\r/); + /* eslint-enable @typescript-eslint/no-unsafe-call */ - if (!/^WEBVTT($| |\t)/.test(lines[0])) { - throw new Error("Can't parse WebVTT: Invalid file."); - } - var firstLineAfterHeader = (0,utils/* getFirstLineAfterHeader */.yE)(lines); - var cueBlocks = (0,get_cue_blocks/* default */.Z)(lines, firstLineAfterHeader); - var cues = []; + return originalArray.reduce(function (acc, arg) { + var r = fn(arg); - for (var i = 0; i < cueBlocks.length; i++) { - var cueObject = (0,parse_cue_block/* default */.Z)(cueBlocks[i], timeOffset); + if (Array.isArray(r)) { + acc.push.apply(acc, r); + return acc; + } - if (cueObject != null) { - var nativeCue = toNativeCue(cueObject); + acc.push(r); + return acc; + }, []); +} - if (nativeCue != null) { - if ((0,is_vtt_cue/* default */.Z)(nativeCue)) { - setSettingsOnCue(cueObject.settings, nativeCue); - } +/***/ }), - cues.push(nativeCue); - } - } - } +/***/ 2572: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - return cues; -} -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/native/index.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ getFuzzedDelay) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -36162,29 +35333,27 @@ function parseVTTStringToVTTCues(vttStr, timeOffset) { * See the License for the specific language governing permissions and * limitations under the License. */ - +var FUZZ_FACTOR = 0.3; /** - * /!\ This file is feature-switchable. - * It always should be imported through the `features` object. + * Perform "fuzzing" on the delay given. + * @param {Number} retryDelay + * @returns {Number} */ -/* harmony default export */ const webvtt_native = (parseVTTStringToVTTCues); +function getFuzzedDelay(retryDelay) { + var fuzzingFactor = (Math.random() * 2 - 1) * FUZZ_FACTOR; + return retryDelay * (fuzzingFactor + 1); // Max 1.3 Min 0.7 +} /***/ }), -/***/ 9525: +/***/ 2870: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ parseCueBlock -}); - -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/parse_timestamp.ts +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ hashBuffer) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -36202,27 +35371,44 @@ var is_non_empty_string = __webpack_require__(6923); */ /** - * Parse a single webvtt timestamp into seconds - * @param {string} timestampString - * @returns {Number|undefined} + * Convert given buffer to a 32bit integer hash + * + * This algorithm is the same one that Java `String.hashCode()` one which + * is a fast hashing function adapted to short ASCII strings. + * This consequently might not be the most adapted to buffers of various length + * containing a various amount of data but still has the advantage of being + * fast. + * + * As this function is used in persistent MediaKeySession storage, we probably + * should keep this function somewhere as long as we want to support + * MediaKeySessions persisted in old versions of the RxPlayer. + * + * @param {Array.|TypedArray} buffer + * @returns {number} */ +function hashBuffer(buffer) { + var hash = 0; -function parseTimestamp(timestampString) { - var splittedTS = timestampString.split(":").reverse(); - - if ((0,is_non_empty_string/* default */.Z)(splittedTS[2]) || (0,is_non_empty_string/* default */.Z)(splittedTS[1])) { - var hours = (0,is_non_empty_string/* default */.Z)(splittedTS[2]) ? parseInt(splittedTS[2], 10) : 0; - var minutes = parseInt(splittedTS[1], 10); - var seconds = parseFloat(splittedTS[0].replace(",", ".")); - - if (isNaN(hours) || isNaN(minutes) || isNaN(seconds)) { - return undefined; - } + var _char; - return hours * 60 * 60 + minutes * 60 + seconds; + for (var i = 0; i < buffer.length; i++) { + _char = buffer[i]; + hash = (hash << 5) - hash + _char; + hash = hash & hash; // Convert to 32bit integer } + + return hash; } -;// CONCATENATED MODULE: ./src/parsers/texttracks/webvtt/parse_cue_block.ts + +/***/ }), + +/***/ 908: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ idGenerator) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -36239,126 +35425,36 @@ function parseTimestamp(timestampString) { * limitations under the License. */ -/** - * Parse the settings part of a cue, into key-value object. - * @param {string} settingsString - * @returns {Object} - */ - -function parseSettings(settingsString) { - var splittedSettings = settingsString.split(/ |\t/); - return splittedSettings.reduce(function (acc, setting) { - var splittedSetting = setting.split(":"); - - if (splittedSetting.length === 2) { - acc[splittedSetting[0]] = splittedSetting[1]; - } - - return acc; - }, {}); -} -/** - * Parse the line containing the timestamp and settings in a cue. - * The returned object has the following properties: - * - start {Number}: start of the cue, in seconds - * - end {Number}: end of the cue, in seconds - * - settings {Object}: settings for the cue as a key-value object. - * @param {string} timeString - * @returns {Object|null} - */ - - -function parseTimeAndSettings(timeString) { - // RegExp for the timestamps + settings line. - // Capture groups: - // 1 -> start timestamp - // 2 -> end timestamp - // 3 - settings - var lineRegex = /^([\d:.]+)[ |\t]+-->[ |\t]+([\d:.]+)[ |\t]*(.*)$/; - var matches = lineRegex.exec(timeString); - - if (matches === null) { - return null; - } - - var start = parseTimestamp(matches[1]); - var end = parseTimestamp(matches[2]); - - if (start == null || end == null) { - return null; - } +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ - var settings = parseSettings(matches[3]); - return { - start: start, - end: end, - settings: settings - }; -} /** - * Parse cue block into a cue object which contains: - * - start {number}: the start of the cue as a timestamp in seconds - * - end {number}: the end of the cue as a timestamp in seconds - * - header {string|undefined}: The optional cue identifier - * - payload {Array.}: the payload of the cue - * @param {Array.} cueLines - * @param {Number} timeOffset - * @returns {Object} + * Creates an ID generator which generates an ID each time you call it. + * @returns {Function} */ +function idGenerator() { + var prefix = ""; + var currId = -1; + return function generateNewId() { + currId++; - -function parseCueBlock(cueLines, timeOffset) { - var timingRegexp = /-->/; - var timeString; - var payload; - var header; - - if (!timingRegexp.test(cueLines[0])) { - if (!timingRegexp.test(cueLines[1])) { - // not a cue - return null; + if (currId >= Number.MAX_SAFE_INTEGER) { + prefix += "0"; + currId = 0; } - header = cueLines[0]; - timeString = cueLines[1]; - payload = cueLines.slice(2, cueLines.length); - } else { - timeString = cueLines[0]; - payload = cueLines.slice(1, cueLines.length); - } - - var timeAndSettings = parseTimeAndSettings(timeString); - - if (timeAndSettings === null) { - return null; - } - - var start = timeAndSettings.start, - end = timeAndSettings.end, - settings = timeAndSettings.settings; - return { - start: start + timeOffset, - end: end + timeOffset, - settings: settings, - payload: payload, - header: header + return prefix + String(currId); }; } /***/ }), -/***/ 360: +/***/ 6923: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; /* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "yE": () => /* binding */ getFirstLineAfterHeader, -/* harmony export */ "tq": () => /* binding */ isStartOfCueBlock, -/* harmony export */ "JF": () => /* binding */ isStartOfStyleBlock, -/* harmony export */ "$4": () => /* binding */ findEndOfCueBlock +/* harmony export */ "Z": () => (/* binding */ isNonEmptyString) /* harmony export */ }); -/* unused harmony exports isStartOfNoteBlock, isStartOfRegionBlock */ -/* harmony import */ var _utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6923); /** * Copyright 2015 CANAL+ Group * @@ -36376,135 +35472,60 @@ function parseCueBlock(cueLines, timeOffset) { */ /** - * Returns first line after the WEBVTT header. - * That is, the line after the first blank line after the first line! - * @param {Array.} linified - * @returns {Number} - */ - -function getFirstLineAfterHeader(linified) { - var i = 0; - - while (i < linified.length) { - if (linified[i] === "") { - return i + 1; - } - - i++; - } - - return i; -} -/** - * Returns true if the given line looks like the beginning of a Style block. - * @param {string} text - * @returns {Boolean} + * @param {*} x + * @returns {string} */ - - -function isStartOfStyleBlock(lines, index) { - return typeof lines[index] === "string" && /^STYLE( .*)?$/g.test(lines[index]) && ( // A cue identifer can also contain "STYLE". Check that we have no timings - // on the second line - lines[index + 1] === undefined || lines[index + 1].indexOf("-->") < 0); +function isNonEmptyString(x) { + return typeof x === "string" && x.length > 0; } -/** - * Returns true if the given line looks like the beginning of a comment block. - * @param {string} text - * @returns {Boolean} - */ +/***/ }), -function isStartOfNoteBlock(lines, index) { - return typeof lines[index] === "string" && /^NOTE( .*)?$/g.test(lines[index]) && ( // A cue identifer can also contain "NOTE". Check that we have no timings - // on the second line - lines[index + 1] === undefined || lines[index + 1].indexOf("-->") < 0); -} -/** - * Returns true if the given line looks like the beginning of a region block. - * @param {string} text - * @returns {Boolean} - */ - +/***/ 1946: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -function isStartOfRegionBlock(lines, index) { - return typeof lines[index] === "string" && /^REGION( .*)?$/g.test(lines[index]) && ( // A cue identifer can also contain "REGION". Check that we have no timings - // on the second line - lines[index + 1] === undefined || lines[index + 1].indexOf("-->") < 0); -} +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ isNullOrUndefined) +/* harmony export */ }); /** - * Returns true if the line given looks like the beginning of a cue. - * You should provide to this function only lines following "empty" lines. - * @param {Array.} lines - * @param {number} index - * @returns {Boolean} + * 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 isStartOfCueBlock(lines, index) { - // checked cases: - // - empty lines - // - start of a comment - // - start of a region - // - start of a style - // Anything else whose first or second line is a timestamp line is a cue. - var firstLine = lines[index]; - - if (firstLine === undefined || firstLine === "" || isStartOfStyleBlock(lines, index) || isStartOfRegionBlock(lines, index) || isStartOfNoteBlock(lines, index)) { - return false; - } - - if (firstLine.indexOf("-->") >= 0) { - return true; - } - - var secondLine = lines[index + 1]; - return secondLine !== undefined && secondLine.indexOf("-->") >= 0; -} /** - * Find end of current WebVTT cue block. - * @param {Array} linified - * @param {number} startOfCueBlock - * @returns {number} + * Returns true if the argument given is either null or undefined. + * This function was added to have a clearer alternative to `== null` which is + * not always understood by newcomers to the code, and which can be overused when + * only one of the possibility can arise. + * @param {*} x + * @returns {*} */ - - -function findEndOfCueBlock(linified, startOfCueBlock) { - var firstEmptyLineIndex = startOfCueBlock + 1; // continue incrementing i until either: - // - empty line - // - end - - while ((0,_utils_is_non_empty_string__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(linified[firstEmptyLineIndex])) { - firstEmptyLineIndex++; - } - - return firstEmptyLineIndex; +function isNullOrUndefined(x) { + return x === null || x === undefined; } - - /***/ }), -/***/ 1459: +/***/ 7829: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ transports_dash -}); - -// EXTERNAL MODULE: ./src/transports/utils/text_manifest_loader.ts + 1 modules -var text_manifest_loader = __webpack_require__(7278); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js -var of = __webpack_require__(8170); -// EXTERNAL MODULE: ./src/features/index.ts -var features = __webpack_require__(7874); -// EXTERNAL MODULE: ./src/utils/request/index.ts + 1 modules -var request = __webpack_require__(4597); -// EXTERNAL MODULE: ./src/utils/take_first_set.ts -var take_first_set = __webpack_require__(5278); -;// CONCATENATED MODULE: ./src/transports/dash/image_pipelines.ts +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ZP": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _normalize__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5553); /** * Copyright 2015 CANAL+ Group * @@ -36521,122 +35542,28 @@ var take_first_set = __webpack_require__(5278); * limitations under the License. */ +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_normalize__WEBPACK_IMPORTED_MODULE_0__/* .default */ .ZP); +/***/ }), -/** - * @param {Object} args - * @returns {Observable} - */ - -function imageLoader(_ref) { - var segment = _ref.segment, - url = _ref.url; - - if (segment.isInit || url === null) { - return (0,of.of)({ - type: "data-created", - value: { - responseData: null - } - }); - } - - return (0,request/* default */.ZP)({ - url: url, - responseType: "arraybuffer", - sendProgressEvents: true - }); -} -/** - * @param {Object} args - * @returns {Observable} - */ - -function imageParser(_ref2) { - var response = _ref2.response, - content = _ref2.content; - var segment = content.segment, - period = content.period; - var data = response.data, - isChunked = response.isChunked; - - if (content.segment.isInit) { - // image init segment has no use - return (0,of.of)({ - type: "parsed-init-segment", - value: { - initializationData: null, - segmentProtections: [], - initTimescale: undefined - } - }); - } - - if (isChunked) { - throw new Error("Image data should not be downloaded in chunks"); - } +/***/ 5553: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - var chunkOffset = (0,take_first_set/* default */.Z)(segment.timestampOffset, 0); // TODO image Parsing should be more on the buffer side, no? +"use strict"; - if (data === null || features/* default.imageParser */.Z.imageParser === null) { - return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: null, - chunkInfos: { - duration: segment.duration, - time: segment.time - }, - chunkOffset: chunkOffset, - appendWindow: [period.start, period.end] - } - }); - } +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "ZP": () => (/* binding */ normalize), + "iH": () => (/* binding */ normalizeAudioTrack), + "Y1": () => (/* binding */ normalizeTextTrack) +}); - var bifObject = features/* default.imageParser */.Z.imageParser(new Uint8Array(data)); - var thumbsData = bifObject.thumbs; - return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: { - data: thumbsData, - start: 0, - end: Number.MAX_VALUE, - timescale: 1, - type: "bif" - }, - chunkInfos: { - time: 0, - duration: Number.MAX_VALUE, - timescale: bifObject.timescale - }, - chunkOffset: chunkOffset, - appendWindow: [period.start, period.end] - } - }); -} -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/concat.js -var concat = __webpack_require__(9795); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/combineLatest.js -var combineLatest = __webpack_require__(5142); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/filter.js -var filter = __webpack_require__(6008); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/map.js -var map = __webpack_require__(5709); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMap.js -var mergeMap = __webpack_require__(7746); -// EXTERNAL MODULE: ./src/manifest/index.ts + 10 modules -var src_manifest = __webpack_require__(1966); -// EXTERNAL MODULE: ./src/config.ts -var config = __webpack_require__(944); -// EXTERNAL MODULE: ./src/log.ts + 1 modules -var log = __webpack_require__(3887); -// EXTERNAL MODULE: ./src/utils/array_find.ts -var array_find = __webpack_require__(3274); -// EXTERNAL MODULE: ./src/utils/resolve_url.ts -var resolve_url = __webpack_require__(9829); -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/extract_minimum_availability_time_offset.ts +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +// EXTERNAL MODULE: ./src/utils/is_null_or_undefined.ts +var is_null_or_undefined = __webpack_require__(1946); +;// CONCATENATED MODULE: ./src/utils/languages/ISO_639-1_to_ISO_639-3.ts /** * Copyright 2015 CANAL+ Group * @@ -36654,27 +35581,197 @@ var resolve_url = __webpack_require__(9829); */ /** - * From 0 to N baseURL elements takes the minimum availabilityTimeOffset - * possible. - * - * `0` if no baseURL was given (which means `no delay added`: coherent with how - * this value is used). - * - * Taking the minimum time allow to simplify its processing: - * Instead of having multiple URL each with a different pool of available - * segment at a given instant, let's always consider every URLs by aligning with - * the one with the most segment. - * - * @param {Array.} baseURLs + * Translate ISO 639-1 language codes into ISO 639-3 ones. */ -function extractMinimumAvailabilityTimeOffset(baseURLs) { - return baseURLs.length === 0 ? 0 : baseURLs.reduce(function (acc, baseURL) { - var _a; +var ISO_MAP_1_TO_3 = { + aa: "aar", + ab: "abk", + ae: "ave", + af: "afr", + ak: "aka", + am: "amh", + an: "arg", + ar: "ara", + as: "asm", + av: "ava", + ay: "aym", + az: "aze", + ba: "bak", + be: "bel", + bg: "bul", + bi: "bis", + bm: "bam", + bn: "ben", + bo: "bod", + br: "bre", + bs: "bos", + ca: "cat", + ce: "che", + ch: "cha", + co: "cos", + cr: "cre", + cs: "ces", + cu: "chu", + // Old Slavonic, Old Bulgarian + cv: "chv", + cy: "cym", + da: "dan", + de: "deu", + dv: "div", + dz: "dzo", + ee: "ewe", + el: "ell", + en: "eng", + eo: "epo", + es: "spa", + et: "est", + eu: "eus", + fa: "fas", + ff: "ful", + fi: "fin", + fj: "fij", + fo: "fao", + fr: "fra", + fy: "fry", + ga: "gle", + gd: "gla", + gl: "glg", + gn: "grn", + gu: "guj", + gv: "glv", + ha: "hau", + he: "heb", + hi: "hin", + ho: "hmo", + hr: "hrv", + ht: "hat", + hu: "hun", + hy: "hye", + hz: "her", + ia: "ina", + id: "ind", + ie: "ile", + ig: "ibo", + ii: "iii", + ik: "ipk", + io: "ido", + is: "isl", + it: "ita", + iu: "iku", + ja: "jpn", + jv: "jav", + ka: "kat", + kg: "kon", + ki: "kik", + kj: "kua", + kk: "kaz", + kl: "kal", + km: "khm", + kn: "kan", + ko: "kor", + kr: "kau", + ks: "kas", + ku: "kur", + kv: "kom", + kw: "cor", + ky: "kir", + la: "lat", + lb: "ltz", + lg: "lug", + li: "lim", + ln: "lin", + lo: "lao", + lt: "lit", + lu: "lub", + lv: "lav", + mg: "mlg", + mh: "mah", + mi: "mri", + mk: "mkd", + ml: "mal", + mn: "mon", + mr: "mar", + ms: "msa", + mt: "mlt", + my: "mya", + na: "nau", + nb: "nob", + nd: "nde", + ne: "nep", + ng: "ndo", + nl: "nld", + nn: "nno", + no: "nor", + nr: "nbl", + nv: "nav", + ny: "nya", + oc: "oci", + oj: "oji", + om: "orm", + or: "ori", + os: "oss", + pa: "pan", + pi: "pli", + pl: "pol", + ps: "pus", + pt: "por", + qu: "que", + rm: "roh", + rn: "run", + ro: "ron", + ru: "rus", + rw: "kin", + sa: "san", + sc: "srd", + sd: "snd", + se: "sme", + sg: "sag", + si: "sin", + sk: "slk", + sl: "slv", + sm: "smo", + sn: "sna", + so: "som", + sq: "sqi", + sr: "srp", + ss: "ssw", + st: "sot", + su: "sun", + sv: "swe", + sw: "swa", + ta: "tam", + te: "tel", + tg: "tgk", + th: "tha", + ti: "tir", + tk: "tuk", + tl: "tgl", + tn: "tsn", + to: "ton", + tr: "tur", + ts: "tso", + tt: "tat", + tw: "twi", + ty: "tah", + ug: "uig", + uk: "ukr", + ur: "urd", + uz: "uzb", + ve: "ven", + vi: "vie", + vo: "vol", + wa: "wln", + wo: "wol", + xh: "xho", + yi: "yid", + yo: "yor", + za: "zha", + zh: "zho", + zu: "zul" // Zulu - return Math.min((_a = baseURL.attributes.availabilityTimeOffset) !== null && _a !== void 0 ? _a : 0, acc); - }, Infinity); -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/get_clock_offset.ts +}; +/* harmony default export */ const ISO_639_1_to_ISO_639_3 = (ISO_MAP_1_TO_3); +;// CONCATENATED MODULE: ./src/utils/languages/ISO_639-2_to_ISO_639-3.ts /** * Copyright 2015 CANAL+ Group * @@ -36692,30 +35789,33 @@ function extractMinimumAvailabilityTimeOffset(baseURLs) { */ /** - * Get difference between the server's clock, in milliseconds and the return of - * the JS function `performance.now`. - * This property allows to calculate the server time at any moment. - * - * `undefined` if we could not define such offset (in which case, you could have - * to rely on the user's clock instead). - * - * For example, a response of 1000 would mean that performance.now() is 1 second - * behind the server's time. - * @param {string} serverClock - * @returns {number|undefined} + * Translate ISO 639-2 synonyms to their ISO 639-3 counterparts. */ +var ISO_MAP_2_TO_3 = { + alb: "sqi", + arm: "hye", + baq: "eus", + bur: "mya", + chi: "zho", + cze: "ces", + dut: "nld", + fre: "fra", + geo: "kat", + ger: "deu", + gre: "ell", + ice: "isl", + mac: "mkd", + mao: "mri", + may: "msa", + per: "fas", + slo: "slk", + rum: "ron", + tib: "bod", + wel: "cym" // Welsh -function getClockOffset(serverClock) { - var httpOffset = Date.parse(serverClock) - performance.now(); - - if (isNaN(httpOffset)) { - log/* default.warn */.Z.warn("DASH Parser: Invalid clock received: ", serverClock); - return undefined; - } - - return httpOffset; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/get_http_utc-timing_url.ts +}; +/* harmony default export */ const ISO_639_2_to_ISO_639_3 = (ISO_MAP_2_TO_3); +;// CONCATENATED MODULE: ./src/utils/languages/normalize.ts /** * Copyright 2015 CANAL+ Group * @@ -36732,143 +35832,145 @@ function getClockOffset(serverClock) { * limitations under the License. */ -/** - * @param {Object} mpdIR - * @returns {string|undefined} - */ -function getHTTPUTCTimingURL(mpdIR) { - var UTCTimingHTTP = mpdIR.children.utcTimings.filter(function (utcTiming) { - return utcTiming.schemeIdUri === "urn:mpeg:dash:utc:http-iso:2014" && utcTiming.value !== undefined; - }); - return UTCTimingHTTP.length > 0 ? UTCTimingHTTP[0].value : undefined; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/utils/get_last_time_from_adaptation.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 "last time of reference" from the adaptation given, considering a - * dynamic content. - * Undefined if a time could not be found. - * Null if the Adaptation has no segments (it could be that it didn't started or - * that it already finished for example). - * - * We consider the earliest last time from every representations in the given - * adaptation. - * @param {Object} adaptation - * @returns {Number|undefined|null} + * Normalize language given. + * Basically: + * - converts it to lowercase. + * - normalize "base" (what is before the possible first "-") to an ISO639-3 + * compatible string. + * @param {string} _language + * @returns {string} */ -function getLastPositionFromAdaptation(adaptation) { - var representations = adaptation.representations; - var min = null; - for (var i = 0; i < representations.length; i++) { - var lastPosition = representations[i].index.getLastPosition(); +function normalizeLanguage(_language) { + if ((0,is_null_or_undefined/* default */.Z)(_language) || _language === "") { + return ""; + } - if (lastPosition === undefined) { - // we cannot tell - return undefined; - } + var fields = ("" + _language).toLowerCase().split("-"); - if (lastPosition !== null) { - min = min == null ? lastPosition : Math.min(min, lastPosition); - } - } + var base = fields[0]; + var normalizedBase = normalizeBase(base); - if (min === null) { - // It means that all positions were null === no segments (yet?) - return null; + if ((0,is_non_empty_string/* default */.Z)(normalizedBase)) { + return normalizedBase; } - return min; + return _language; } -;// CONCATENATED MODULE: ./src/parsers/manifest/utils/get_maximum_position.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. + * Normalize language into an ISO639-3 format. + * Returns undefined if it failed to do so + * @param {string} base + * @returns {string} */ +function normalizeBase(base) { + var result; + + switch (base.length) { + case 2: + result = ISO_639_1_to_ISO_639_3[base]; + break; + + case 3: + result = ISO_639_2_to_ISO_639_3[base]; + break; + } + + return result; +} /** - * @param {Object} manifest - * @returns {number | undefined} + * Normalize text track from a user given input into an object + * with three properties: + * - language {string}: The language the user gave us + * - normalized {string}: An attempt to normalize the language into an + * ISO 639-3 code + * - closedCaption {Boolean}: Whether the track is a closed caption track + * @param {Object|string|null|undefined} _language + * @returns {Object|null|undefined} */ -function getMaximumPosition(periods) { - for (var i = periods.length - 1; i >= 0; i--) { - var periodAdaptations = periods[i].adaptations; - var firstAudioAdaptationFromPeriod = periodAdaptations.audio === undefined ? undefined : periodAdaptations.audio[0]; - var firstVideoAdaptationFromPeriod = periodAdaptations.video === undefined ? undefined : periodAdaptations.video[0]; - - if (firstAudioAdaptationFromPeriod !== undefined || firstVideoAdaptationFromPeriod !== undefined) { - // null == no segment - var maximumAudioPosition = null; - var maximumVideoPosition = null; - if (firstAudioAdaptationFromPeriod !== undefined) { - var lastPosition = getLastPositionFromAdaptation(firstAudioAdaptationFromPeriod); +function normalizeTextTrack(_language) { + if (!(0,is_null_or_undefined/* default */.Z)(_language)) { + var language; + var closedCaption = false; - if (lastPosition === undefined) { - return undefined; - } + if (typeof _language === "string") { + language = _language; + } else { + language = _language.language; - maximumAudioPosition = lastPosition; + if (_language.closedCaption === true) { + closedCaption = true; } + } - if (firstVideoAdaptationFromPeriod !== undefined) { - var _lastPosition = getLastPositionFromAdaptation(firstVideoAdaptationFromPeriod); + return { + language: language, + closedCaption: closedCaption, + normalized: normalizeLanguage(language) + }; + } - if (_lastPosition === undefined) { - return undefined; - } + return _language; +} +/** + * Normalize audio track from a user given input into an object + * with the following properties: + * - language {string}: The language the user gave us + * - normalized {string}: An attempt to normalize the language into an + * ISO 639-3 code + * - audioDescription {Boolean}: Whether the track is a closed caption track + * - isDub {Boolean|undefined}: if true, this is a dub. + * @param {Object|string|null|undefined} _language + * @returns {Object|null|undefined} + */ - maximumVideoPosition = _lastPosition; - } - if (firstAudioAdaptationFromPeriod !== undefined && maximumAudioPosition === null || firstVideoAdaptationFromPeriod !== undefined && maximumVideoPosition === null) { - log/* default.info */.Z.info("Parser utils: found Period with no segment. ", "Going to previous one to calculate last position"); - return undefined; - } +function normalizeAudioTrack(_language) { + if ((0,is_null_or_undefined/* default */.Z)(_language)) { + return _language; + } - if (maximumVideoPosition !== null) { - if (maximumAudioPosition !== null) { - return Math.min(maximumAudioPosition, maximumVideoPosition); - } + if (typeof _language === "string") { + return { + language: _language, + audioDescription: false, + normalized: normalizeLanguage(_language) + }; + } - return maximumVideoPosition; - } + var normalized = { + language: _language.language, + audioDescription: _language.audioDescription === true, + normalized: normalizeLanguage(normalizeLanguage(_language.language)) + }; - if (maximumAudioPosition !== null) { - return maximumAudioPosition; - } - } + if (_language.isDub === true) { + normalized.isDub = true; } + + return normalized; } -;// CONCATENATED MODULE: ./src/parsers/manifest/utils/get_first_time_from_adaptation.ts + +/* harmony default export */ const normalize = (normalizeLanguage); + + +/***/ }), + +/***/ 8894: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -36886,40 +35988,26 @@ function getMaximumPosition(periods) { */ /** - * Returns "first time of reference" from the adaptation given, considering a - * dynamic content. - * Undefined if a time could not be found. + * Do nothing (but do it well). * - * We consider the latest first time from every representations in the given - * adaptation. - * @param {Object} adaptation - * @returns {Number|undefined} + * Having this definition here allow to use the same reference each time a noop + * is needed. + * Also, it allows to avoid telling eslint to ignore empty blocks everywhere. */ -function getFirstPositionFromAdaptation(adaptation) { - var representations = adaptation.representations; - var max = null; - - for (var i = 0; i < representations.length; i++) { - var firstPosition = representations[i].index.getFirstPosition(); - if (firstPosition === undefined) { - // we cannot tell - return undefined; - } +/* eslint-disable no-empty,@typescript-eslint/no-empty-function */ +/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__() {} +/* eslint-enable no-empty, @typescript-eslint/no-empty-function */ - if (firstPosition !== null) { - max = max == null ? firstPosition : Math.max(max, firstPosition); - } - } +/***/ }), - if (max === null) { - // It means that all positions were null === no segments (yet?) - return null; - } +/***/ 8026: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - return max; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/utils/get_minimum_position.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -36935,64 +36023,45 @@ function getFirstPositionFromAdaptation(adaptation) { * See the License for the specific language governing permissions and * limitations under the License. */ +function objectAssign(target) { + if (target === null || target === undefined) { + throw new TypeError("Cannot convert undefined or null to object"); + } // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -/** - * @param {Object} manifest - * @returns {number | undefined} - */ - -function getMinimumPosition(periods) { - for (var i = 0; i <= periods.length - 1; i++) { - var periodAdaptations = periods[i].adaptations; - var firstAudioAdaptationFromPeriod = periodAdaptations.audio === undefined ? undefined : periodAdaptations.audio[0]; - var firstVideoAdaptationFromPeriod = periodAdaptations.video === undefined ? undefined : periodAdaptations.video[0]; - - if (firstAudioAdaptationFromPeriod !== undefined || firstVideoAdaptationFromPeriod !== undefined) { - // null == no segment - var minimumAudioPosition = null; - var minimumVideoPosition = null; - - if (firstAudioAdaptationFromPeriod !== undefined) { - var firstPosition = getFirstPositionFromAdaptation(firstAudioAdaptationFromPeriod); + var to = Object(target); - if (firstPosition === undefined) { - return undefined; - } + for (var i = 0; i < (arguments.length <= 1 ? 0 : arguments.length - 1); i++) { + var source = i + 1 < 1 || arguments.length <= i + 1 ? undefined : arguments[i + 1]; - minimumAudioPosition = firstPosition; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + /* eslint-disable @typescript-eslint/no-unsafe-member-access */ + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + to[key] = source[key]; + /* eslint-enable @typescript-eslint/no-unsafe-member-access */ } + } + } - if (firstVideoAdaptationFromPeriod !== undefined) { - var _firstPosition = getFirstPositionFromAdaptation(firstVideoAdaptationFromPeriod); - - if (_firstPosition === undefined) { - return undefined; - } + return to; +} // eslint-disable-next-line @typescript-eslint/unbound-method, no-restricted-properties - minimumVideoPosition = _firstPosition; - } - if (firstAudioAdaptationFromPeriod !== undefined && minimumAudioPosition === null || firstVideoAdaptationFromPeriod !== undefined && minimumVideoPosition === null) { - log/* default.info */.Z.info("Parser utils: found Period with no segment. ", "Going to next one to calculate first position"); - return undefined; - } +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (typeof Object.assign === "function" ? // eslint-disable-next-line no-restricted-properties +Object.assign : // eslint-disable-next-line @typescript-eslint/unbound-method +objectAssign); - if (minimumVideoPosition !== null) { - if (minimumAudioPosition !== null) { - return Math.max(minimumAudioPosition, minimumVideoPosition); - } +/***/ }), - return minimumVideoPosition; - } +/***/ 1679: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - if (minimumAudioPosition !== null) { - return minimumAudioPosition; - } - } - } -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/get_minimum_and_maximum_positions.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* unused harmony export objectValues */ /** * Copyright 2015 CANAL+ Group * @@ -37009,37 +36078,31 @@ function getMinimumPosition(periods) { * limitations under the License. */ - /** - * @param {Object} periods - * @returns {Array.} + * @param {Object|Array} o + * @returns {Array.<*>} */ +function objectValues(o) { + return Object.keys(o).map(function (k) { + return o[k]; + }); +} // eslint-disable-next-line @typescript-eslint/unbound-method, no-restricted-properties -function getMinimumAndMaximumPosition(periods) { - if (periods.length === 0) { - throw new Error("DASH Parser: no period available for a dynamic content"); - } - return [getMinimumPosition(periods), getMaximumPosition(periods)]; -} -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/assertThisInitialized.js -var assertThisInitialized = __webpack_require__(1506); -var assertThisInitialized_default = /*#__PURE__*/__webpack_require__.n(assertThisInitialized); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/inheritsLoose.js -var inheritsLoose = __webpack_require__(5354); -var inheritsLoose_default = /*#__PURE__*/__webpack_require__.n(inheritsLoose); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/wrapNativeSuper.js -var wrapNativeSuper = __webpack_require__(5957); -var wrapNativeSuper_default = /*#__PURE__*/__webpack_require__.n(wrapNativeSuper); -// EXTERNAL MODULE: ./src/utils/base64.ts -var base64 = __webpack_require__(9689); -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/utils.ts +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (typeof Object.values === "function" ? Object.values : objectValues); +/***/ }), +/***/ 9589: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var pinkie__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8555); +/* harmony import */ var pinkie__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(pinkie__WEBPACK_IMPORTED_MODULE_0__); /** * Copyright 2015 CANAL+ Group * @@ -37055,539 +36118,574 @@ var is_non_empty_string = __webpack_require__(6923); * See the License for the specific language governing permissions and * limitations under the License. */ -// XML-Schema -/* eslint-disable max-len */ -// +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (typeof Promise === "function" ? Promise : (pinkie__WEBPACK_IMPORTED_MODULE_0___default())); -/* eslint-enable max-len */ +/***/ }), +/***/ 2829: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "JN": () => (/* binding */ convertToRanges), +/* harmony export */ "uH": () => (/* binding */ excludeFromRanges), +/* harmony export */ "F_": () => (/* binding */ getInnerAndOuterTimeRanges), +/* harmony export */ "L7": () => (/* binding */ getLeftSizeOfRange), +/* harmony export */ "XS": () => (/* binding */ getNextRangeGap), +/* harmony export */ "DD": () => (/* binding */ getPlayedSizeOfRange), +/* harmony export */ "rx": () => (/* binding */ getRange), +/* harmony export */ "at": () => (/* binding */ getSizeOfRange), +/* harmony export */ "kR": () => (/* binding */ insertInto), +/* harmony export */ "Ti": () => (/* binding */ isTimeInRange), +/* harmony export */ "A1": () => (/* binding */ isTimeInRanges), +/* harmony export */ "tn": () => (/* binding */ keepRangeIntersection) +/* harmony export */ }); +/* unused harmony exports isAfter, isBefore, isTimeInTimeRanges, mergeContiguousRanges, removeEmptyRanges */ +/** + * 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 iso8601Duration = /^P(([\d.]*)Y)?(([\d.]*)M)?(([\d.]*)D)?T?(([\d.]*)H)?(([\d.]*)M)?(([\d.]*)S)?/; -var rangeRe = /([0-9]+)-([0-9]+)/; /** - * Parse MPD boolean attributes. + * This file contains functions helping with TimeRanges management. * - * The returned value is a tuple of two elements where: - * 1. the first value is the parsed boolean - or `null` if we could not parse - * it - * 2. the second value is a possible error encountered while parsing this - * value - set to `null` if no error was encountered. - * @param {string} val - The value to parse - * @param {string} displayName - The name of the property. Used for error - * formatting. - * @returns {Array.} + * For simplicity/performance reasons, many of those work with a simplified + * "Range" object, which is an object with two keys: + * - start {Number} + * - end {Number} + * + * Those two corresponds to what is returned by the start and end methods of a + * TimeRanges Object. + * + * You can convert from TimeRanges to Range object(s) with the getRange/ + * convertToRanges methods. + */ +// Factor for rounding errors +var EPSILON = 1 / 60; +/** + * Check equality with a tolerance of EPSILON. + * Used for various functions with this sort of tolerance regarding the + * start/end of contiguous ranges. + * @param {Number} a + * @param {Number} b + * @returns {Boolean} */ -function parseBoolean(val, displayName) { - if (val === "true") { - return [true, null]; - } +function nearlyEqual(a, b) { + return Math.abs(a - b) < EPSILON; +} +/** + * Construct a new range which will have, as start/end, the min/max + * of both the range given, and the given bitrate. + * @param {Object} range1 + * @param {Object} range2 + * @returns {Object} + */ - if (val === "false") { - return [false, null]; - } - var error = new MPDError("`" + displayName + "` property is not a boolean value but \"" + val + "\""); - return [false, error]; +function createRangeUnion(range1, range2) { + var start = Math.min(range1.start, range2.start); + var end = Math.max(range1.end, range2.end); + return { + start: start, + end: end + }; } /** - * Parse MPD integer attributes. - * - * The returned value is a tuple of two elements where: - * 1. the first value is the parsed boolean - or `null` if we could not parse - * it - * 2. the second value is a possible error encountered while parsing this - * value - set to `null` if no error was encountered. - * @param {string} val - The value to parse - * @param {string} displayName - The name of the property. Used for error - * formatting. - * @returns {Array.} + * Clean array ranges from "empty" ranges. + * That is, range objects which have their start equal to their end. + * /!\ Mutate the array of ranges. + * @param {Array} ranges + * @returns {Array} */ -function parseMPDInteger(val, displayName) { - var toInt = parseInt(val, 10); +function removeEmptyRanges(ranges) { + for (var index = 0; index < ranges.length; index++) { + var range = ranges[index]; - if (isNaN(toInt)) { - var error = new MPDError("`" + displayName + "` property is not an integer value but \"" + val + "\""); - return [null, error]; + if (range.start === range.end) { + ranges.splice(index--, 1); + } } - return [toInt, null]; + return ranges; } /** - * Parse MPD float attributes. - * - * The returned value is a tuple of two elements where: - * 1. the first value is the parsed boolean - or `null` if we could not parse - * it - * 2. the second value is a possible error encountered while parsing this - * value - set to `null` if no error was encountered. - * @param {string} val - The value to parse - * @param {string} displayName - The name of the property. Used for error - * formatting. - * @returns {Array.} + * /!\ Mutate the array of ranges. + * @param {Array} ranges + * @returns {Array} */ -function parseMPDFloat(val, displayName) { - var toInt = parseFloat(val); +function mergeContiguousRanges(ranges) { + for (var index = 1; index < ranges.length; index++) { + var prevRange = ranges[index - 1]; + var currRange = ranges[index]; - if (isNaN(toInt)) { - var error = new MPDError("`" + displayName + "` property is not an integer value but \"" + val + "\""); - return [null, error]; + if (areRangesNearlyContiguous(prevRange, currRange)) { + var unionRange = createRangeUnion(prevRange, currRange); + ranges.splice(--index, 2, unionRange); + } } - return [toInt, null]; + return ranges; } /** - * Parse MPD attributes which are either integer or boolean values. - * - * The returned value is a tuple of two elements where: - * 1. the first value is the parsed value - or `null` if we could not parse - * it - * 2. the second value is a possible error encountered while parsing this - * value - set to `null` if no error was encountered. - * @param {string} val - The value to parse - * @param {string} displayName - The name of the property. Used for error - * formatting. - * @returns {Array.} + * True if range1 is considered _after_ range2. + * @param {Object} range1 + * @param {Object} range2 + * @returns {Boolean} */ -function parseIntOrBoolean(val, displayName) { - if (val === "true") { - return [true, null]; - } +function isAfter(range1, range2) { + return range1.start >= range2.end; +} +/** + * True if range1 is considered _before_ range2. + * @param {Object} range1 + * @param {Object} range2 + * @returns {Boolean} + */ - if (val === "false") { - return [false, null]; - } - var toInt = parseInt(val, 10); +function isBefore(range1, range2) { + return range1.end <= range2.start; +} +/** + * Returns true if the time given can be considered as part of any of the given + * ranges. + * @param {Array.} ranges + * @param {number} time + * @returns {boolean} + */ - if (isNaN(toInt)) { - var error = new MPDError("`" + displayName + "` property is not a boolean nor an integer but \"" + val + "\""); - return [null, error]; + +function isTimeInRanges(ranges, time) { + for (var i = 0; i < ranges.length; i++) { + if (isTimeInRange(ranges[i], time)) { + return true; + } } - return [toInt, null]; + return false; } /** - * Parse MPD date attributes. - * - * The returned value is a tuple of two elements where: - * 1. the first value is the parsed value - or `null` if we could not parse - * it - * 2. the second value is a possible error encountered while parsing this - * value - set to `null` if no error was encountered. - * @param {string} val - The value to parse - * @param {string} displayName - The name of the property. Used for error - * formatting. - * @returns {Array.} + * Returns true if the time given can be considered as part of the given range. + * @param {Object} range1 + * @param {Number} Time + * @returns {Boolean} */ -function parseDateTime(val, displayName) { - var parsed = Date.parse(val); +function isTimeInRange(_ref, time) { + var start = _ref.start, + end = _ref.end; + return start <= time && time < end; +} +/** + * Returns true if the two ranges given are overlapping. + * @param {Object} range1 + * @param {Object} range2 + * @returns {Boolean} + */ - if (isNaN(parsed)) { - var error = new MPDError("`" + displayName + "` is in an invalid date format: \"" + val + "\""); - return [null, error]; - } - return [new Date(Date.parse(val)).getTime() / 1000, null]; +function areRangesOverlapping(range1, range2) { + return isTimeInRange(range1, range2.start) || range1.start < range2.end && range2.end < range1.end || isTimeInRange(range2, range1.start); } /** - * Parse MPD ISO8601 duration attributes into seconds. - * - * The returned value is a tuple of two elements where: - * 1. the first value is the parsed value - or `null` if we could not parse - * it - * 2. the second value is a possible error encountered while parsing this - * value - set to `null` if no error was encountered. - * @param {string} val - The value to parse - * @param {string} displayName - The name of the property. Used for error - * formatting. - * @returns {Array.} + * Returns true if the two ranges given can be considered contiguous. + * @param {Object} range1 + * @param {Object} range2 + * @returns {Boolean} */ -function parseDuration(val, displayName) { - if (!(0,is_non_empty_string/* default */.Z)(val)) { - var error = new MPDError("`" + displayName + "` property is empty"); - return [0, error]; - } +function areRangesNearlyContiguous(range1, range2) { + return nearlyEqual(range2.start, range1.end) || nearlyEqual(range2.end, range1.start); +} +/** + * Convert from a TimeRanges object to an array of Ranges. + * @param {TimeRanges} timeRanges + * @returns {Array.} + */ - var match = iso8601Duration.exec(val); - if (match === null) { - var _error = new MPDError("`" + displayName + "` property has an unrecognized format \"" + val + "\""); +function convertToRanges(timeRanges) { + var ranges = []; - return [null, _error]; + for (var i = 0; i < timeRanges.length; i++) { + ranges.push({ + start: timeRanges.start(i), + end: timeRanges.end(i) + }); } - var duration = parseFloat((0,is_non_empty_string/* default */.Z)(match[2]) ? match[2] : "0") * 365 * 24 * 60 * 60 + parseFloat((0,is_non_empty_string/* default */.Z)(match[4]) ? match[4] : "0") * 30 * 24 * 60 * 60 + parseFloat((0,is_non_empty_string/* default */.Z)(match[6]) ? match[6] : "0") * 24 * 60 * 60 + parseFloat((0,is_non_empty_string/* default */.Z)(match[8]) ? match[8] : "0") * 60 * 60 + parseFloat((0,is_non_empty_string/* default */.Z)(match[10]) ? match[10] : "0") * 60 + parseFloat((0,is_non_empty_string/* default */.Z)(match[12]) ? match[12] : "0"); - return [duration, null]; + return ranges; } /** - * Parse MPD byterange attributes into arrays of two elements: the start and - * the end. - * - * The returned value is a tuple of two elements where: - * 1. the first value is the parsed value - or `null` if we could not parse - * it - * 2. the second value is a possible error encountered while parsing this - * value - set to `null` if no error was encountered. - * @param {string} val - * @param {string} displayName - * @returns {Array. | Error | null>} + * Get range object of a specific time in a TimeRanges object. + * @param {TimeRanges} timeRanges + * @returns {Object} */ -function parseByteRange(val, displayName) { - var match = rangeRe.exec(val); +function getRange(timeRanges, time) { + for (var i = timeRanges.length - 1; i >= 0; i--) { + var start = timeRanges.start(i); - if (match === null) { - var error = new MPDError("`" + displayName + "` property has an unrecognized format \"" + val + "\""); - return [null, error]; - } else { - return [[+match[1], +match[2]], null]; + if (time >= start) { + var end = timeRanges.end(i); + + if (time < end) { + return { + start: start, + end: end + }; + } + } } + + return null; } /** - * Parse MPD base64 attribute into an Uint8Array. - * the end. - * - * The returned value is a tuple of two elements where: - * 1. the first value is the parsed value - or `null` if we could not parse - * it - * 2. the second value is a possible error encountered while parsing this - * value - set to `null` if no error was encountered. - * @param {string} val - * @param {string} displayName - * @returns {Uint8Array | Error | null>} + * Get gap from a specific time until the start of the next Range. + * @param {TimeRanges} timeRanges + * @param {Number} time + * @returns {Number} */ -function parseBase64(val, displayName) { - try { - return [(0,base64/* base64ToBytes */.K)(val), null]; - } catch (_) { - var error = new MPDError("`" + displayName + "` is not a valid base64 string: \"" + val + "\""); - return [null, error]; +function getNextRangeGap(timeRanges, time) { + var len = timeRanges.length; + + for (var i = 0; i < len; i++) { + var start = timeRanges.start(i); + + if (time < start) { + return start - time; + } } + + return Infinity; } /** - * @param {Element} root - * @returns {Object} + * @param {TimeRanges} timeRanges + * @param {Number} time + * @returns {Object} - Object with two properties: + * - outerRanges {Array.}: every ranges which does not contain the + * given time. + * - innerRange {Object|null}: the range which contain the given time. */ -function parseScheme(root) { - var schemeIdUri; - var value; - - for (var i = 0; i < root.attributes.length; i++) { - var attribute = root.attributes[i]; +function getInnerAndOuterTimeRanges(timeRanges, time) { + var innerRange = null; + var outerRanges = []; - switch (attribute.name) { - case "schemeIdUri": - schemeIdUri = attribute.value; - break; + for (var i = 0; i < timeRanges.length; i++) { + var start = timeRanges.start(i); + var end = timeRanges.end(i); - case "value": - value = attribute.value; - break; + if (time < start || time >= end) { + outerRanges.push({ + start: start, + end: end + }); + } else { + innerRange = { + start: start, + end: end + }; } } return { - schemeIdUri: schemeIdUri, - value: value + outerRanges: outerRanges, + innerRange: innerRange }; } /** - * Create a function to factorize the MPD parsing logic. - * @param {Object} dest - The destination object which will contain the parsed - * values. - * @param {Array.} warnings - An array which will contain every parsing - * error encountered. - * @return {Function} + * Get "size" (difference between end and start) of the range containing the + * given time. 0 if the range is not found. + * @param {TimeRanges} timeRanges + * @param {Number} currentTime + * @returns {Number} */ -function ValueParser(dest, warnings) { - /** - * Parse a single value and add it to the `dest` objects. - * If an error arised while parsing, add it at the end of the `warnings` array. - * @param {string} objKey - The key which will be added to the `dest` object. - * @param {string} val - The value found in the MPD which we should parse. - * @param {Function} parsingFn - The parsing function adapted for this value. - * @param {string} displayName - The name of the key as it appears in the MPD. - * This is used only in error formatting, - */ - return function (val, _ref) { - var asKey = _ref.asKey, - parser = _ref.parser, - dashName = _ref.dashName; - - var _parser = parser(val, dashName), - parsingResult = _parser[0], - parsingError = _parser[1]; +function getSizeOfRange(timeRanges, currentTime) { + var range = getRange(timeRanges, currentTime); + return range !== null ? range.end - range.start : 0; +} +/** + * Get "currently played" (difference between time given and start) of the + * range containing the given time. 0 if the range is not found. + * @param {TimeRanges} timeRanges + * @param {Number} currentTime + * @returns {Number} + */ - if (parsingError !== null) { - log/* default.warn */.Z.warn(parsingError.message); - warnings.push(parsingError); - } - if (parsingResult !== null) { - dest[asKey] = parsingResult; - } - }; +function getPlayedSizeOfRange(timeRanges, currentTime) { + var range = getRange(timeRanges, currentTime); + return range !== null ? currentTime - range.start : 0; } /** - * Error arising when parsing the MPD. - * @class MPDError - * @extends Error + * Get "left to play" (difference between end and time given) of the range + * containing the given time. Infinity if the range is not found. + * @param {TimeRanges} timeRanges + * @param {Number} currentTime + * @returns {Number} */ -var MPDError = /*#__PURE__*/function (_Error) { - inheritsLoose_default()(MPDError, _Error); - - /** - * @param {string} message - */ - function MPDError(message) { - var _this; +function getLeftSizeOfRange(timeRanges, currentTime) { + var range = getRange(timeRanges, currentTime); + return range !== null ? range.end - currentTime : Infinity; +} +/** + * Insert a range object into an array of ranges objects, at the right place. + * /!\ Mutate the array of ranges. + * @param {Array.} ranges + * @param {Object} rangeToAddArg + * @returns {Array.} + */ - _this = _Error.call(this) || this; // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class - Object.setPrototypeOf(assertThisInitialized_default()(_this), MPDError.prototype); - _this.name = "MPDError"; - _this.message = message; - return _this; +function insertInto(ranges, rangeToAddArg) { + if (rangeToAddArg.start === rangeToAddArg.end) { + return ranges; } - return MPDError; -}( /*#__PURE__*/wrapNativeSuper_default()(Error)); + var rangeToAdd = rangeToAddArg; // For each present range check if we need to: + // - In case we are overlapping or contiguous: + // - if added range has the same bitrate as the overlapped or + // contiguous one, we can merge themcurrentRange + // - if added range has a different bitrate we need to insert it + // in place + // - Need to insert in place, we we are completely, not overlapping + // and not contiguous in between two ranges. + var index = 0; -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/BaseURL.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. - */ + for (; index < ranges.length; index++) { + var range = ranges[index]; + var overlapping = areRangesOverlapping(rangeToAdd, range); + var contiguous = areRangesNearlyContiguous(rangeToAdd, range); // We assume ranges are ordered and two ranges can not be + // completely overlapping. -/** - * Parse an BaseURL element into an BaseURL intermediate - * representation. - * @param {Element} adaptationSetElement - The BaseURL root element. - * @returns {Array.} - */ + if (overlapping || contiguous) { + rangeToAdd = createRangeUnion(rangeToAdd, range); + ranges.splice(index--, 1); + } else { + // Check the case for which there is no more to do + if (index === 0) { + if (isBefore(rangeToAdd, ranges[0])) { + // First index, and we are completely before that range (and + // not contiguous, nor overlapping). We just need to be + // inserted here. + break; + } + } else { + if (isBefore(ranges[index - 1], rangeToAdd) && isBefore(rangeToAdd, range)) { + // We are exactly after the current previous range, and + // before the current range, while not overlapping with none + // of them. Insert here. + break; + } + } + } + } // Now that we are sure we don't overlap with any range, just add it. -function parseBaseURL(root) { - var attributes = {}; - var value = root.textContent; - var warnings = []; - var parseValue = ValueParser(attributes, warnings); - if (value === null || value.length === 0) { - return [undefined, warnings]; - } + ranges.splice(index, 0, rangeToAdd); + return mergeContiguousRanges(removeEmptyRanges(ranges)); +} +/** + * Returns range, from a range objects array overlapping with a range given + * in argument. null if none is found. + * @param {Object} range + * @param {Array.} ranges + * @returns {Array.} + */ - for (var i = 0; i < root.attributes.length; i++) { - var attribute = root.attributes[i]; - switch (attribute.name) { - case "availabilityTimeOffset": - if (attribute.value === "INF") { - attributes.availabilityTimeOffset = Infinity; - } else { - parseValue(attribute.value, { - asKey: "availabilityTimeOffset", - parser: parseMPDInteger, - dashName: "availabilityTimeOffset" - }); - } +function findOverlappingRanges(range, ranges) { + var resultingRanges = []; - break; + for (var i = 0; i < ranges.length; i++) { + if (areRangesOverlapping(range, ranges[i])) { + resultingRanges.push(ranges[i]); } } - return [{ - value: value, - attributes: attributes - }, warnings]; + return resultingRanges; } -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/ContentComponent.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. - */ - /** - * Parse a "ContentComponent" Element in a DASH MPD. - * @param {Element} root - * @returns {Object} + * Returns only the intersection between the two ranges, from the first + * ranges argument given. + * @param {Array.} ranges1 + * @param {Array.} ranges2 + * @returns {Array.} */ -function parseContentComponent(root) { - var ret = {}; - - for (var i = 0; i < root.attributes.length; i++) { - var attribute = root.attributes[i]; - switch (attribute.name) { - case "id": - ret.id = attribute.value; - break; - case "lang": - ret.language = attribute.value; - break; +function keepRangeIntersection(ranges1, ranges2) { + var result = []; - case "contentType": - ret.contentType = attribute.value; - break; + for (var i = 0; i < ranges1.length; i++) { + var range = ranges1[i]; + var overlappingRanges = findOverlappingRanges(range, ranges2); - case "par": - ret.par = attribute.value; - break; + if (overlappingRanges.length > 0) { + for (var j = 0; j < overlappingRanges.length; j++) { + var overlappingRange = overlappingRanges[j]; + result.push({ + start: Math.max(range.start, overlappingRange.start), + end: Math.min(range.end, overlappingRange.end) + }); + } } } - return ret; + return result; } -// EXTERNAL MODULE: ./src/utils/string_parsing.ts -var string_parsing = __webpack_require__(3635); -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/ContentProtection.ts /** - * Copyright 2015 CANAL+ Group + * Exclude from the `baseRanges` everything that is in `rangesToExclude`. + * Example: * - * 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 + * Let's say we have the following base ranges: + * |==========| |===============| |======| |==========| * - * http://www.apache.org/licenses/LICENSE-2.0 + * From which we want to "exclude" the following ranges: + * |=========| |==| |===| |=====| * - * 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. + * We will obtain the first ranges from which we remove the second ranges: + * ----------------------------------------------------------------------- + * |==========| |===============| |======| |==========| + * |=========| |==| |===| |=====| + * _______________________________________________________________________ + * | + * | + * V + * ----------------------------------------------------------------------- + * |==| |======| |==| |====| |==========| + * ----------------------------------------------------------------------- + * + * @param {Array.} */ +function excludeFromRanges(baseRanges, rangesToExclude) { + var result = []; // For every range in `baseRanges`, find overlapping ranges with + // `rangesToExclude` and remove them. -/** - * @param {NodeList} contentProtectionChildren - * @Returns {Object} - */ - -function parseContentProtectionChildren(contentProtectionChildren) { - var warnings = []; - var cencPssh = []; + for (var i = 0; i < baseRanges.length; i++) { + var range = baseRanges[i]; + var intersections = []; + var overlappingRanges = findOverlappingRanges(range, rangesToExclude); - for (var i = 0; i < contentProtectionChildren.length; i++) { - if (contentProtectionChildren[i].nodeType === Node.ELEMENT_NODE) { - var currentElement = contentProtectionChildren[i]; + if (overlappingRanges.length > 0) { + for (var j = 0; j < overlappingRanges.length; j++) { + var overlappingRange = overlappingRanges[j]; + intersections.push({ + start: Math.max(range.start, overlappingRange.start), + end: Math.min(range.end, overlappingRange.end) + }); + } + } - if (currentElement.nodeName === "cenc:pssh") { - var content = currentElement.textContent; + if (intersections.length === 0) { + result.push(range); + } else { + var lastStart = range.start; - if (content !== null && content.length > 0) { - var _parseBase = parseBase64(content, "cenc:pssh"), - toUint8Array = _parseBase[0], - error = _parseBase[1]; + for (var _j = 0; _j < intersections.length; _j++) { + if (intersections[_j].start > lastStart) { + result.push({ + start: lastStart, + end: intersections[_j].start + }); + } - if (error !== null) { - log/* default.warn */.Z.warn(error.message); - warnings.push(error); - } + lastStart = intersections[_j].end; + } - if (toUint8Array !== null) { - cencPssh.push(toUint8Array); - } - } + if (lastStart < range.end) { + result.push({ + start: lastStart, + end: range.end + }); } } } - return [{ - cencPssh: cencPssh - }, warnings]; + return result; } /** - * @param {Element} root - * @returns {Object} + * Returns `true` if the given `time` is available in the TimeRanges object + * given. + * Returns `false` otherwise. + * @param {TimeRanges} ranges + * @param {Number} time + * @returns {boolean} */ -function parseContentProtectionAttributes(root) { - var ret = {}; +function isTimeInTimeRanges(ranges, time) { + for (var i = 0; i < ranges.length; i++) { + if (ranges.start(i) <= time && time < ranges.end(i)) { + return true; + } + } - for (var i = 0; i < root.attributes.length; i++) { - var attribute = root.attributes[i]; + return false; +} - switch (attribute.name) { - case "schemeIdUri": - ret.schemeIdUri = attribute.value; - break; - case "value": - ret.value = attribute.value; - break; - case "cenc:default_KID": - ret.keyId = (0,string_parsing/* hexToBytes */.nr)(attribute.value.replace(/-/g, "")); - } - } +/***/ }), - return ret; -} -/** - * @param {Element} contentProtectionElement - * @returns {Object} - */ +/***/ 4597: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +"use strict"; -function parseContentProtection(contentProtectionElement) { - var _parseContentProtecti = parseContentProtectionChildren(contentProtectionElement.childNodes), - children = _parseContentProtecti[0], - childrenWarnings = _parseContentProtecti[1]; +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "ZP": () => (/* binding */ utils_request) +}); - var attributes = parseContentProtectionAttributes(contentProtectionElement); - return [{ - children: children, - attributes: attributes - }, childrenWarnings]; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/Initialization.ts +// UNUSED EXPORTS: fetchIsSupported, fetchRequest, xhr + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules +var Observable = __webpack_require__(4379); +// EXTERNAL MODULE: ./src/config.ts +var config = __webpack_require__(944); +// EXTERNAL MODULE: ./src/errors/request_error.ts +var request_error = __webpack_require__(9105); +// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts +var is_non_empty_string = __webpack_require__(6923); +// EXTERNAL MODULE: ./src/utils/is_null_or_undefined.ts +var is_null_or_undefined = __webpack_require__(1946); +;// CONCATENATED MODULE: ./src/utils/request/xhr.ts /** * Copyright 2015 CANAL+ Group * @@ -37604,156 +36702,144 @@ function parseContentProtection(contentProtectionElement) { * limitations under the License. */ -/** - * @param {Element} root - * @returns {Array.} - */ -function parseInitialization(root) { - var parsedInitialization = {}; - var warnings = []; - var parseValue = ValueParser(parsedInitialization, warnings); - for (var i = 0; i < root.attributes.length; i++) { - var attribute = root.attributes[i]; - switch (attribute.name) { - case "range": - parseValue(attribute.value, { - asKey: "range", - parser: parseByteRange, - dashName: "range" - }); - break; - - case "sourceURL": - parsedInitialization.media = attribute.value; - break; - } - } - return [parsedInitialization, warnings]; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/SegmentBase.ts +var DEFAULT_REQUEST_TIMEOUT = config/* default.DEFAULT_REQUEST_TIMEOUT */.Z.DEFAULT_REQUEST_TIMEOUT; +var DEFAULT_RESPONSE_TYPE = "json"; /** - * 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 {string} data + * @returns {Object|null} */ +function toJSONForIE(data) { + try { + return JSON.parse(data); + } catch (e) { + return null; + } +} -/** - * Parse a SegmentBase element into a SegmentBase intermediate representation. - * @param {Element} root - The SegmentBase root element. - * @returns {Array} - */ +function request(options) { + var requestOptions = { + url: options.url, + headers: options.headers, + responseType: (0,is_null_or_undefined/* default */.Z)(options.responseType) ? DEFAULT_RESPONSE_TYPE : options.responseType, + timeout: (0,is_null_or_undefined/* default */.Z)(options.timeout) ? DEFAULT_REQUEST_TIMEOUT : options.timeout + }; + return new Observable/* Observable */.y(function (obs) { + var url = requestOptions.url, + headers = requestOptions.headers, + responseType = requestOptions.responseType, + timeout = requestOptions.timeout; + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, true); -function parseSegmentBase(root) { - var attributes = {}; - var warnings = []; - var parseValue = ValueParser(attributes, warnings); - var segmentBaseChildren = root.childNodes; + if (timeout >= 0) { + xhr.timeout = timeout; + } - for (var i = 0; i < segmentBaseChildren.length; i++) { - if (segmentBaseChildren[i].nodeType === Node.ELEMENT_NODE) { - var currentNode = segmentBaseChildren[i]; + xhr.responseType = responseType; - if (currentNode.nodeName === "Initialization") { - var _parseInitialization = parseInitialization(currentNode), - initialization = _parseInitialization[0], - initializationWarnings = _parseInitialization[1]; + if (xhr.responseType === "document") { + xhr.overrideMimeType("text/xml"); + } - attributes.initialization = initialization; - warnings = warnings.concat(initializationWarnings); + if (!(0,is_null_or_undefined/* default */.Z)(headers)) { + var _headers = headers; + + for (var key in _headers) { + if (_headers.hasOwnProperty(key)) { + xhr.setRequestHeader(key, _headers[key]); + } } } - } - for (var _i = 0; _i < root.attributes.length; _i++) { - var attr = root.attributes[_i]; + var sendingTime = performance.now(); - switch (attr.name) { - case "timescale": - parseValue(attr.value, { - asKey: "timescale", - parser: parseMPDInteger, - dashName: "timescale" - }); - break; + xhr.onerror = function onXHRError() { + obs.error(new request_error/* default */.Z(url, xhr.status, "ERROR_EVENT", xhr)); + }; - case "presentationTimeOffset": - parseValue(attr.value, { - asKey: "presentationTimeOffset", - parser: parseMPDFloat, - dashName: "presentationTimeOffset" - }); - break; + xhr.ontimeout = function onXHRTimeout() { + obs.error(new request_error/* default */.Z(url, xhr.status, "TIMEOUT", xhr)); + }; - case "indexRange": - parseValue(attr.value, { - asKey: "indexRange", - parser: parseByteRange, - dashName: "indexRange" + if (options.sendProgressEvents === true) { + xhr.onprogress = function onXHRProgress(event) { + var currentTime = performance.now(); + obs.next({ + type: "progress", + value: { + url: url, + duration: currentTime - sendingTime, + sendingTime: sendingTime, + currentTime: currentTime, + size: event.loaded, + totalSize: event.total + } }); - break; + }; + } - case "indexRangeExact": - parseValue(attr.value, { - asKey: "indexRangeExact", - parser: parseBoolean, - dashName: "indexRangeExact" - }); - break; + xhr.onload = function onXHRLoad(event) { + if (xhr.readyState === 4) { + if (xhr.status >= 200 && xhr.status < 300) { + var receivedTime = performance.now(); + var totalSize = xhr.response instanceof ArrayBuffer ? xhr.response.byteLength : event.total; + var status = xhr.status; + var loadedResponseType = xhr.responseType; - case "availabilityTimeOffset": - parseValue(attr.value, { - asKey: "availabilityTimeOffset", - parser: parseMPDFloat, - dashName: "availabilityTimeOffset" - }); - break; + var _url = (0,is_non_empty_string/* default */.Z)(xhr.responseURL) ? xhr.responseURL : url; - case "availabilityTimeComplete": - parseValue(attr.value, { - asKey: "availabilityTimeComplete", - parser: parseBoolean, - dashName: "availabilityTimeComplete" - }); - break; + var responseData; - case "duration": - parseValue(attr.value, { - asKey: "duration", - parser: parseMPDInteger, - dashName: "duration" - }); - break; + if (loadedResponseType === "json") { + // IE bug where response is string with responseType json + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + responseData = typeof xhr.response === "object" ? xhr.response : toJSONForIE(xhr.responseText); + } else { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + responseData = xhr.response; + } - case "startNumber": - parseValue(attr.value, { - asKey: "startNumber", - parser: parseMPDInteger, - dashName: "startNumber" - }); - break; - } - } + if ((0,is_null_or_undefined/* default */.Z)(responseData)) { + obs.error(new request_error/* default */.Z(url, xhr.status, "PARSE_ERROR", xhr)); + return; + } - return [attributes, warnings]; + obs.next({ + type: "data-loaded", + value: { + status: status, + url: _url, + responseType: loadedResponseType, + sendingTime: sendingTime, + receivedTime: receivedTime, + duration: receivedTime - sendingTime, + size: totalSize, + responseData: responseData + } + }); + obs.complete(); + } else { + obs.error(new request_error/* default */.Z(url, xhr.status, "ERROR_HTTP_CODE", xhr)); + } + } + }; + + xhr.send(); + return function () { + if (!(0,is_null_or_undefined/* default */.Z)(xhr) && xhr.readyState !== 4) { + xhr.abort(); + } + }; + }); } -// EXTERNAL MODULE: ./src/utils/object_assign.ts -var object_assign = __webpack_require__(8026); -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/SegmentURL.ts + +/* harmony default export */ const xhr = (request); +;// CONCATENATED MODULE: ./src/utils/request/index.ts /** * Copyright 2015 CANAL+ Group * @@ -37770,51 +36856,20 @@ var object_assign = __webpack_require__(8026); * limitations under the License. */ -/** - * Parse a SegmentURL element into a SegmentURL intermediate - * representation. - * @param {Element} root - The SegmentURL root element. - * @returns {Array} - */ - -function parseSegmentURL(root) { - var parsedSegmentURL = {}; - var warnings = []; - var parseValue = ValueParser(parsedSegmentURL, warnings); - - for (var i = 0; i < root.attributes.length; i++) { - var attribute = root.attributes[i]; - switch (attribute.name) { - case "media": - parsedSegmentURL.media = attribute.value; - break; +/* harmony default export */ const utils_request = (xhr); - case "indexRange": - parseValue(attribute.value, { - asKey: "indexRange", - parser: parseByteRange, - dashName: "indexRange" - }); - break; - case "index": - parsedSegmentURL.index = attribute.value; - break; +/***/ }), - case "mediaRange": - parseValue(attribute.value, { - asKey: "mediaRange", - parser: parseByteRange, - dashName: "mediaRange" - }); - break; - } - } +/***/ 9829: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - return [parsedSegmentURL, warnings]; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/SegmentList.ts +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ resolveURL), +/* harmony export */ "f": () => (/* binding */ normalizeBaseURL) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -37830,52 +36885,131 @@ function parseSegmentURL(root) { * See the License for the specific language governing permissions and * limitations under the License. */ +// Scheme part of an url (e.g. "http://"). +var schemeRe = /^(?:[a-z]+:)?\/\//i; // Captures "/../" or "/./". + +var selfDirRe = /\/\.{1,2}\//; +/** + * Resolve self directory and previous directory references to obtain a + * "normalized" url. + * @example "https://foo.bar/baz/booz/../biz" => "https://foo.bar/baz/biz" + * @param {string} url + * @returns {string} + */ + +function _normalizeUrl(url) { + // fast path if no ./ or ../ are present in the url + if (!selfDirRe.test(url)) { + return url; + } + var newUrl = []; + var oldUrl = url.split("/"); + for (var i = 0, l = oldUrl.length; i < l; i++) { + if (oldUrl[i] === "..") { + newUrl.pop(); + } else if (oldUrl[i] === ".") { + continue; + } else { + newUrl.push(oldUrl[i]); + } + } + return newUrl.join("/"); +} /** - * @param {Element} root - * @returns {Array} + * Construct an url from the arguments given. + * Basically: + * - The last arguments that contains a scheme (e.g. "http://") is the base + * of the url. + * - every subsequent string arguments are concatened to it. + * @param {...string|undefined} args + * @returns {string} */ -function parseSegmentList(root) { - var _parseSegmentBase = parseSegmentBase(root), - base = _parseSegmentBase[0], - baseWarnings = _parseSegmentBase[1]; - var warnings = baseWarnings; - var list = []; - var segmentListChildren = root.childNodes; +function resolveURL() { + var len = arguments.length; - for (var i = 0; i < segmentListChildren.length; i++) { - if (segmentListChildren[i].nodeType === Node.ELEMENT_NODE) { - var currentNode = segmentListChildren[i]; + if (len === 0) { + return ""; + } - if (currentNode.nodeName === "SegmentURL") { - var _parseSegmentURL = parseSegmentURL(currentNode), - segmentURL = _parseSegmentURL[0], - segmentURLWarnings = _parseSegmentURL[1]; + var base = ""; - list.push(segmentURL); - warnings = warnings.concat(segmentURLWarnings); + for (var i = 0; i < len; i++) { + var part = i < 0 || arguments.length <= i ? undefined : arguments[i]; + + if (typeof part !== "string" || part === "") { + continue; + } + + if (schemeRe.test(part)) { + base = part; + } else { + // trim if begins with "/" + if (part[0] === "/") { + part = part.substring(1); + } // trim if ends with "/" + + + if (base[base.length - 1] === "/") { + base = base.substring(0, base.length - 1); } + + base = base + "/" + part; } } - var baseDuration = base.duration; + return _normalizeUrl(base); +} +/** + * Remove string after the last '/'. + * @param {string} url + * @returns {string} + */ - if (baseDuration == null) { - throw new Error("Invalid SegmentList: no duration"); +function normalizeBaseURL(url) { + var indexOfLastSlash = url.lastIndexOf("/"); + + if (indexOfLastSlash < 0) { + return url; } - var ret = (0,object_assign/* default */.Z)(base, { - list: list, - // Ugly but TS is too dumb there - duration: baseDuration - }); - return [ret, warnings]; + if (schemeRe.test(url)) { + var firstSlashIndex = url.indexOf("/"); + + if (firstSlashIndex >= 0 && indexOfLastSlash === firstSlashIndex + 1) { + // The "/" detected is actually the one from the protocol part of the URL + // ("https://") + return url; + } + } + + var indexOfQuestionMark = url.indexOf("?"); + + if (indexOfQuestionMark >= 0 && indexOfQuestionMark < indexOfLastSlash) { + // There are query parameters. Let's ignore them and re-run the logic + // without + return normalizeBaseURL(url.substring(0, indexOfQuestionMark)); + } + + return url.substring(0, indexOfLastSlash + 1); } -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/SegmentTimeline.ts + + + +/***/ }), + +/***/ 5561: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ tryCatch) +/* harmony export */ }); +/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4944); /** * Copyright 2015 CANAL+ Group * @@ -37893,22 +37027,29 @@ function parseSegmentList(root) { */ /** - * @param {Element} root - * @returns {Function} + * @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 createSegmentTimelineParser(root) { - var result = null; - return function () { - if (result === null) { - var elements = root.getElementsByTagName("S"); - result = elements; - return elements; - } - return result; - }; +function tryCatch(func, argsForFunc) { + try { + return func(argsForFunc); + } catch (e) { + return (0,rxjs__WEBPACK_IMPORTED_MODULE_0__/* .throwError */ ._)(e); + } } -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/SegmentTemplate.ts + +/***/ }), + +/***/ 9252: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ startsWith) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -37925,310 +37066,466 @@ function createSegmentTimelineParser(root) { * limitations under the License. */ +/** + * String.prototype.startsWith ponyfill. + * Indicates Whether a string starts with another substring. + * + * Inspired from MDN polyfill, but ponyfilled instead. + * @param {string} completeString + * @param {string} searchString + * @param {number} [position] + * @returns {boolean} + */ +function startsWith(completeString, searchString, position) { + // eslint-disable-next-line @typescript-eslint/unbound-method + // eslint-disable-next-line no-restricted-properties + if (typeof String.prototype.startsWith === "function") { + // eslint-disable-next-line no-restricted-properties + return completeString.startsWith(searchString, position); + } + + var initialPosition = typeof position === "number" ? Math.max(position, 0) : 0; + return completeString.substring(initialPosition, initialPosition + searchString.length) === searchString; +} +/***/ }), +/***/ 3635: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ci": () => (/* binding */ bytesToHex), +/* harmony export */ "nr": () => (/* binding */ hexToBytes), +/* harmony export */ "tG": () => (/* binding */ strToUtf8), +/* harmony export */ "uR": () => (/* binding */ utf8ToStr), +/* harmony export */ "TZ": () => (/* binding */ strToUtf16LE), +/* harmony export */ "wV": () => (/* binding */ utf16LEToStr), +/* harmony export */ "wO": () => (/* binding */ guidToUuid), +/* harmony export */ "DM": () => (/* binding */ readNullTerminatedString) +/* harmony export */ }); +/* unused harmony exports strToBeUtf16, beUtf16ToStr */ +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3887); +/* harmony import */ var _assert__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(811); /** - * Parse initialization attribute found in SegmentTemplateTemplate to - * correspond to the initialization found in a regular segmentBase. - * @param {string} attrValue - * @returns {Object} + * 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 parseInitializationAttribute(attrValue) { - return { - media: attrValue - }; -} + +var hasTextDecoder = typeof window === "object" && typeof window.TextDecoder === "function"; +var hasTextEncoder = typeof window === "object" && typeof window.TextEncoder === "function"; /** - * Parse a SegmentTemplate element into a SegmentTemplate intermediate - * representation. - * @param {Element} root - The SegmentTemplate root element. - * @returns {Array} + * Convert a string to an Uint8Array containing the corresponding UTF-16 code + * units in little-endian. + * @param {string} str + * @returns {Uint8Array} */ +function strToUtf16LE(str) { + var buffer = new ArrayBuffer(str.length * 2); + var res = new Uint8Array(buffer); -function parseSegmentTemplate(root) { - var _parseSegmentBase = parseSegmentBase(root), - base = _parseSegmentBase[0], - segmentBaseWarnings = _parseSegmentBase[1]; - - var warnings = segmentBaseWarnings; - var timelineParser; // First look for a possible SegmentTimeline + for (var i = 0; i < res.length; i += 2) { + var value = str.charCodeAt(i / 2); + res[i] = value & 0xFF; + res[i + 1] = value >> 8 & 0xFF; + } - for (var i = 0; i < root.childNodes.length; i++) { - if (root.childNodes[i].nodeType === Node.ELEMENT_NODE) { - var currentNode = root.childNodes[i]; + return res; +} +/** + * Convert a string to an Uint8Array containing the corresponding UTF-16 code + * units in little-endian. + * @param {string} str + * @returns {Uint8Array} + */ - if (currentNode.nodeName === "SegmentTimeline") { - timelineParser = createSegmentTimelineParser(currentNode); - } - } - } - var ret = (0,object_assign/* default */.Z)({}, base, { - duration: base.duration, - timelineParser: timelineParser - }); - var parseValue = ValueParser(ret, warnings); +function strToBeUtf16(str) { + var buffer = new ArrayBuffer(str.length * 2); + var res = new Uint8Array(buffer); - for (var _i = 0; _i < root.attributes.length; _i++) { - var attribute = root.attributes[_i]; + for (var i = 0; i < res.length; i += 2) { + var value = str.charCodeAt(i / 2); + res[i + 1] = value & 0xFF; + res[i] = value >> 8 & 0xFF; + } - switch (attribute.nodeName) { - case "initialization": - if (ret.initialization == null) { - ret.initialization = parseInitializationAttribute(attribute.value); - } + return res; +} +/** + * Construct string from the little-endian UTF-16 code units given. + * @param {Uint8Array} bytes + * @returns {string} + */ - break; - case "index": - ret.index = attribute.value; - break; +function utf16LEToStr(bytes) { + if (hasTextDecoder) { + try { + // instanciation throws if the encoding is unsupported + var decoder = new TextDecoder("utf-16le"); + return decoder.decode(bytes); + } catch (e) { + _log__WEBPACK_IMPORTED_MODULE_0__/* .default.warn */ .Z.warn("Utils: could not use TextDecoder to parse UTF-16LE, " + "fallbacking to another implementation", e); + } + } - case "availabilityTimeOffset": - if (attribute.value === "INF") { - ret.availabilityTimeOffset = Infinity; - } + var str = ""; - parseValue(attribute.value, { - asKey: "availabilityTimeOffset", - parser: parseMPDInteger, - dashName: "availabilityTimeOffset" - }); - break; + for (var i = 0; i < bytes.length; i += 2) { + str += String.fromCharCode((bytes[i + 1] << 8) + bytes[i]); + } - case "media": - ret.media = attribute.value; - break; + return str; +} +/** + * Construct string from the little-endian UTF-16 code units given. + * @param {Uint8Array} bytes + * @returns {string} + */ - case "bitstreamSwitching": - parseValue(attribute.value, { - asKey: "bitstreamSwitching", - parser: parseBoolean, - dashName: "bitstreamSwitching" - }); - break; + +function beUtf16ToStr(bytes) { + if (hasTextDecoder) { + try { + // instanciation throws if the encoding is unsupported + var decoder = new TextDecoder("utf-16be"); + return decoder.decode(bytes); + } catch (e) { + log.warn("Utils: could not use TextDecoder to parse UTF-16BE, " + "fallbacking to another implementation", e); } } - return [ret, warnings]; + var str = ""; + + for (var i = 0; i < bytes.length; i += 2) { + str += String.fromCharCode((bytes[i] << 8) + bytes[i + 1]); + } + + return str; } -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/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. + * Convert a string to an Uint8Array containing the corresponding UTF-8 code + * units. + * @param {string} str + * @returns {Uint8Array} */ +function strToUtf8(str) { + if (hasTextEncoder) { + try { + var encoder = new TextEncoder(); + return encoder.encode(str); + } catch (e) { + _log__WEBPACK_IMPORTED_MODULE_0__/* .default.warn */ .Z.warn("Utils: could not use TextEncoder to encode string into UTF-8, " + "fallbacking to another implementation", e); + } + } // http://stackoverflow.com/a/13691499 provides an ugly but functional solution. + // (Note you have to dig deeper to understand it but I have more faith in + // stackoverflow not going down in the future so I leave that link.) + // Briefly said, `utf8Str` will contain a version of `str` where every + // non-ASCII characters will be replaced by an escape sequence of the + // corresponding representation of those characters in UTF-8. + // It does sound weird and unnecessarily complicated, but it works! + // + // Here is actually what happens with more words. We will rely on two browser + // APIs: + // + // - `encodeURIComponent` will take a string and convert the non-ASCII + // characters in it into the percent-encoded version of the corresponding + // UTF-8 bytes + // Example: encodeURIComponent("é") => 0xC3 0xA9 => `"%C3%A9"` + // + // - `unescape` unescapes (so far so good) a percent-encoded string. But it + // does it in a really simple way: percent-encoded byte by percent-encoded + // byte into the corresponding extended ASCII representation on 8 bits. + // As a result, we end-up with a string which actually contains instead of + // each of its original characters, the UTF-8 code units (8 bits) of + // those characters. + // Let's take our previous `"é" => "%C3%A9"` example. Here we would get: + // unecape("%C3%A9") => "\u00c3\u00a9" === "é" (in extended ASCII) + // + // By iterating on the resulting string, we will then be able to generate a + // Uint8Array containing the UTF-8 representation of that original string, by + // just calling the charCodeAt API on it. + + + var utf8Str; + var pcStr = encodeURIComponent(str); // As "unescape" is a deprecated function we want to declare a fallback in the + // case a browser decide to not implement it. + + if (typeof unescape === "function") { + utf8Str = unescape(pcStr); + } else { + // Let's implement a simple unescape function (got to admit it was for the challenge) + // http://ecma-international.org/ecma-262/9.0/#sec-unescape-string + var isHexChar = /[0-9a-fA-F]/; + var pcStrLen = pcStr.length; + utf8Str = ""; + + for (var i = 0; i < pcStr.length; i++) { + var wasPercentEncoded = false; + + if (pcStr[i] === "%") { + if (i <= pcStrLen - 6 && pcStr[i + 1] === "u" && isHexChar.test(pcStr[i + 2]) && isHexChar.test(pcStr[i + 3]) && isHexChar.test(pcStr[i + 4]) && isHexChar.test(pcStr[i + 5])) { + var charCode = parseInt(pcStr.substring(i + 1, i + 6), 16); + utf8Str += String.fromCharCode(charCode); + wasPercentEncoded = true; + i += 5; // Skip the next 5 chars + } else if (i <= pcStrLen - 3 && isHexChar.test(pcStr[i + 1]) && isHexChar.test(pcStr[i + 2])) { + var _charCode = parseInt(pcStr.substring(i + 1, i + 3), 16); + + utf8Str += String.fromCharCode(_charCode); + wasPercentEncoded = true; + i += 2; // Skip the next 2 chars + } + } + + if (!wasPercentEncoded) { + utf8Str += pcStr[i]; + } + } + } // Now let's just build our array from every other bytes of that string's + // UTF-16 representation + + var res = new Uint8Array(utf8Str.length); + for (var _i = 0; _i < utf8Str.length; _i++) { + res[_i] = utf8Str.charCodeAt(_i) & 0xFF; // first byte should be 0x00 anyway + } + return res; +} /** - * @param {NodeList} representationChildren - * @returns {Object} + * Creates a new string from the given array of char codes. + * @param {Uint8Array} args + * @returns {string} */ -function parseRepresentationChildren(representationChildren) { - var children = { - baseURLs: [] - }; - var warnings = []; - for (var i = 0; i < representationChildren.length; i++) { - if (representationChildren[i].nodeType === Node.ELEMENT_NODE) { - var currentElement = representationChildren[i]; +function stringFromCharCodes(args) { + var max = 16000; + var ret = ""; - switch (currentElement.nodeName) { - case "BaseURL": - var _parseBaseURL = parseBaseURL(currentElement), - baseURLObj = _parseBaseURL[0], - baseURLWarnings = _parseBaseURL[1]; + for (var i = 0; i < args.length; i += max) { + var subArray = args.subarray(i, i + max); // NOTE: ugly I know, but TS is problematic here (you can try) - if (baseURLObj !== undefined) { - children.baseURLs.push(baseURLObj); - } + ret += String.fromCharCode.apply(null, subArray); + } - warnings = warnings.concat(baseURLWarnings); - break; + return ret; +} +/** + * Transform an integer into an hexadecimal string of the given length, padded + * to the left with `0` if needed. + * @example + * ``` + * intToHex(5, 4); // => "0005" + * intToHex(5, 2); // => "05" + * intToHex(10, 1); // => "a" + * intToHex(268, 3); // => "10c" + * intToHex(4584, 6) // => "0011e8" + * intToHex(123456, 4); // => "1e240" (we do nothing when going over 4 chars) + * ``` + * @param {number} num + * @param {number} size + * @returns {string} + */ - case "SegmentBase": - var _parseSegmentBase = parseSegmentBase(currentElement), - segmentBase = _parseSegmentBase[0], - segmentBaseWarnings = _parseSegmentBase[1]; - children.segmentBase = segmentBase; +function intToHex(num, size) { + var toStr = num.toString(16); + return toStr.length >= size ? toStr : new Array(size - toStr.length + 1).join("0") + toStr; +} +/** + * Creates a string from the given Uint8Array containing utf-8 code units. + * @param {Uint8Array} bytes + * @returns {string} + */ - if (segmentBaseWarnings.length > 0) { - warnings = warnings.concat(segmentBaseWarnings); - } - break; +function utf8ToStr(data) { + if (hasTextDecoder) { + try { + // TextDecoder use UTF-8 by default + var decoder = new TextDecoder(); + return decoder.decode(data); + } catch (e) { + _log__WEBPACK_IMPORTED_MODULE_0__/* .default.warn */ .Z.warn("Utils: could not use TextDecoder to parse UTF-8, " + "fallbacking to another implementation", e); + } + } - case "SegmentList": - var _parseSegmentList = parseSegmentList(currentElement), - segmentList = _parseSegmentList[0], - segmentListWarnings = _parseSegmentList[1]; + var uint8 = data; // If present, strip off the UTF-8 BOM. - warnings = warnings.concat(segmentListWarnings); - children.segmentList = segmentList; - break; + if (uint8[0] === 0xEF && uint8[1] === 0xBB && uint8[2] === 0xBF) { + uint8 = uint8.subarray(3); + } // We're basically doing strToUtf8 in reverse. + // You can look at that other function for the whole story. + // Generate string containing escaped UTF-8 code units - case "SegmentTemplate": - var _parseSegmentTemplate = parseSegmentTemplate(currentElement), - segmentTemplate = _parseSegmentTemplate[0], - segmentTemplateWarnings = _parseSegmentTemplate[1]; - warnings = warnings.concat(segmentTemplateWarnings); - children.segmentTemplate = segmentTemplate; - break; + var utf8Str = stringFromCharCodes(uint8); + var escaped; + + if (typeof escape === "function") { + // Transform UTF-8 escape sequence into percent-encoded escape sequences. + escaped = escape(utf8Str); + } else { + // Let's implement a simple escape function + // http://ecma-international.org/ecma-262/9.0/#sec-escape-string + var nonEscapedChar = /[A-Za-z0-9*_\+-\.\/]/; + escaped = ""; + + for (var i = 0; i < utf8Str.length; i++) { + if (nonEscapedChar.test(utf8Str[i])) { + escaped += utf8Str[i]; + } else { + var charCode = utf8Str.charCodeAt(i); + escaped += charCode >= 256 ? "%u" + intToHex(charCode, 4) : "%" + intToHex(charCode, 2); } } - } + } // Decode the percent-encoded UTF-8 string into the proper JS string. + // Example: "g#%E3%82%AC" -> "g#€" - return [children, warnings]; + + return decodeURIComponent(escaped); } /** - * @param {Element} representationElement - * @returns {Array} + * Convert hex codes in a string form into the corresponding bytes. + * @param {string} str + * @returns {Uint8Array} + * @throws TypeError - str.length is odd */ -function parseRepresentationAttributes(representationElement) { - var attributes = {}; - var warnings = []; - var parseValue = ValueParser(attributes, warnings); +function hexToBytes(str) { + var len = str.length; + var arr = new Uint8Array(len / 2); - for (var i = 0; i < representationElement.attributes.length; i++) { - var attr = representationElement.attributes[i]; + for (var i = 0, j = 0; i < len; i += 2, j++) { + arr[j] = parseInt(str.substring(i, i + 2), 16) & 0xFF; + } - switch (attr.name) { - case "audioSamplingRate": - attributes.audioSamplingRate = attr.value; - break; + return arr; +} +/** + * Convert bytes into the corresponding hex string, with the possibility + * to add a separator. + * @param {Uint8Array} bytes + * @param {string} [sep=""] - separator. Separate each two hex character. + * @returns {string} + */ - case "bandwidth": - parseValue(attr.value, { - asKey: "bitrate", - parser: parseMPDInteger, - dashName: "bandwidth" - }); - break; - case "codecs": - attributes.codecs = attr.value; - break; +function bytesToHex(bytes, sep) { + if (sep === void 0) { + sep = ""; + } - case "codingDependency": - parseValue(attr.value, { - asKey: "codingDependency", - parser: parseBoolean, - dashName: "codingDependency" - }); - break; + var hex = ""; - case "frameRate": - attributes.frameRate = attr.value; - break; + for (var i = 0; i < bytes.byteLength; i++) { + hex += (bytes[i] >>> 4).toString(16); + hex += (bytes[i] & 0xF).toString(16); - case "height": - parseValue(attr.value, { - asKey: "height", - parser: parseMPDInteger, - dashName: "height" - }); - break; + if (sep.length > 0 && i < bytes.byteLength - 1) { + hex += sep; + } + } - case "id": - attributes.id = attr.value; - break; + return hex; +} +/** + * Convert little-endian GUID into big-endian UUID. + * @param {Uint8Array} guid + * @returns {Uint8Array} - uuid + * @throws AssertionError - The guid length is not 16 + */ - case "maxPlayoutRate": - parseValue(attr.value, { - asKey: "maxPlayoutRate", - parser: parseMPDFloat, - dashName: "maxPlayoutRate" - }); - break; - case "maximumSAPPeriod": - parseValue(attr.value, { - asKey: "maximumSAPPeriod", - parser: parseMPDFloat, - dashName: "maximumSAPPeriod" - }); - break; +function guidToUuid(guid) { + (0,_assert__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(guid.length === 16, "GUID length should be 16"); + var p1A = guid[0]; + var p1B = guid[1]; + var p1C = guid[2]; + var p1D = guid[3]; + var p2A = guid[4]; + var p2B = guid[5]; + var p3A = guid[6]; + var p3B = guid[7]; + var uuid = new Uint8Array(16); // swapping byte endian on 4 bytes + // [1, 2, 3, 4] => [4, 3, 2, 1] - case "mimeType": - attributes.mimeType = attr.value; - break; + uuid[0] = p1D; + uuid[1] = p1C; + uuid[2] = p1B; + uuid[3] = p1A; // swapping byte endian on 2 bytes + // [5, 6] => [6, 5] - case "profiles": - attributes.profiles = attr.value; - break; + uuid[4] = p2B; + uuid[5] = p2A; // swapping byte endian on 2 bytes + // [7, 8] => [8, 7] - case "qualityRanking": - parseValue(attr.value, { - asKey: "qualityRanking", - parser: parseMPDInteger, - dashName: "qualityRanking" - }); - break; + uuid[6] = p3B; + uuid[7] = p3A; + uuid.set(guid.subarray(8, 16), 8); + return uuid; +} +/** + * Decode string from bytes (UTF-8). + * Keeps reading until it reaches a byte that equals to zero. + * @param {Uint8Array} buffer + * @param {number} offset + * @returns {Object} + */ - case "segmentProfiles": - attributes.segmentProfiles = attr.value; - break; - case "width": - parseValue(attr.value, { - asKey: "width", - parser: parseMPDInteger, - dashName: "width" - }); - break; +function readNullTerminatedString(buffer, offset) { + var position = offset; + + while (position < buffer.length) { + var value = buffer[position]; + + if (value === 0) { + break; } - } - if (attributes.bitrate === undefined) { - warnings.push(new MPDError("No bitrate found on a Representation")); + position += 1; } - return [attributes, warnings]; + var bytes = buffer.subarray(offset, position); + return { + end: position + 1, + string: utf8ToStr(bytes) + }; } -/** - * @param {Element} representationElement - * @returns {Array} - */ -function createRepresentationIntermediateRepresentation(representationElement) { - var _parseRepresentationC = parseRepresentationChildren(representationElement.childNodes), - children = _parseRepresentationC[0], - childrenWarnings = _parseRepresentationC[1]; - var _parseRepresentationA = parseRepresentationAttributes(representationElement), - attributes = _parseRepresentationA[0], - attrsWarnings = _parseRepresentationA[1]; +/***/ }), - var warnings = childrenWarnings.concat(attrsWarnings); - return [{ - children: children, - attributes: attributes - }, warnings]; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/AdaptationSet.ts +/***/ 5278: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ takeFirstSet) +/* harmony export */ }); +/* harmony import */ var _is_null_or_undefined__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1946); /** * Copyright 2015 CANAL+ Group * @@ -38245,2383 +37542,6017 @@ function createRepresentationIntermediateRepresentation(representationElement) { * limitations under the License. */ +function takeFirstSet() { + var i = 0; + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + var len = args.length; + while (i < len) { + var arg = args[i]; + if (!(0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(arg)) { + return arg; + } + i++; + } + return undefined; +} -/** - * Parse child nodes from an AdaptationSet. - * @param {NodeList} adaptationSetChildren - The AdaptationSet child nodes. - * @returns {Array.} - */ - -function parseAdaptationSetChildren(adaptationSetChildren) { - var children = { - baseURLs: [], - representations: [] - }; - var contentProtections = []; - var warnings = []; - - for (var i = 0; i < adaptationSetChildren.length; i++) { - if (adaptationSetChildren[i].nodeType === Node.ELEMENT_NODE) { - var currentElement = adaptationSetChildren[i]; +/***/ }), - switch (currentElement.nodeName) { - case "Accessibility": - children.accessibility = parseScheme(currentElement); - break; +/***/ 8806: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - case "BaseURL": - var _parseBaseURL = parseBaseURL(currentElement), - baseURLObj = _parseBaseURL[0], - baseURLWarnings = _parseBaseURL[1]; +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ warnOnce) +/* harmony export */ }); +/* harmony import */ var _array_includes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7714); +/** + * 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. + */ - if (baseURLObj !== undefined) { - children.baseURLs.push(baseURLObj); - } +var WARNED_MESSAGES = []; +/** + * Perform a console.warn only once in the application lifetime. + * + * Useful for deprecated messages, for example. + * + * @param {string} message + */ - if (baseURLWarnings.length > 0) { - warnings = warnings.concat(baseURLWarnings); - } +function warnOnce(message) { + if (!(0,_array_includes__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(WARNED_MESSAGES, message)) { + // eslint-disable-next-line no-console + console.warn(message); + WARNED_MESSAGES.push(message); + } +} - break; +/***/ }), - case "ContentComponent": - children.contentComponent = parseContentComponent(currentElement); - break; +/***/ 7473: +/***/ ((module) => { - case "EssentialProperty": - if (children.essentialProperties == null) { - children.essentialProperties = [parseScheme(currentElement)]; - } else { - children.essentialProperties.push(parseScheme(currentElement)); - } +"use strict"; - break; - case "Representation": - var _createRepresentation = createRepresentationIntermediateRepresentation(currentElement), - representation = _createRepresentation[0], - representationWarnings = _createRepresentation[1]; +var ensureCallable = function (fn) { + if (typeof fn !== 'function') throw new TypeError(fn + " is not a function"); + return fn; +}; - children.representations.push(representation); +var byObserver = function (Observer) { + var node = document.createTextNode(''), queue, currentQueue, i = 0; + new Observer(function () { + var callback; + if (!queue) { + if (!currentQueue) return; + queue = currentQueue; + } else if (currentQueue) { + queue = currentQueue.concat(queue); + } + currentQueue = queue; + queue = null; + if (typeof currentQueue === 'function') { + callback = currentQueue; + currentQueue = null; + callback(); + return; + } + node.data = (i = ++i % 2); // Invoke other batch, to handle leftover callbacks in case of crash + while (currentQueue) { + callback = currentQueue.shift(); + if (!currentQueue.length) currentQueue = null; + callback(); + } + }).observe(node, { characterData: true }); + return function (fn) { + ensureCallable(fn); + if (queue) { + if (typeof queue === 'function') queue = [queue, fn]; + else queue.push(fn); + return; + } + queue = fn; + node.data = (i = ++i % 2); + }; +}; - if (representationWarnings.length > 0) { - warnings = warnings.concat(representationWarnings); - } +module.exports = (function () { + // Node.js + if ((typeof process === 'object') && process && (typeof process.nextTick === 'function')) { + return process.nextTick; + } - break; + // queueMicrotask + if (typeof queueMicrotask === "function") { + return function (cb) { queueMicrotask(ensureCallable(cb)); }; + } - case "Role": - if (children.roles == null) { - children.roles = [parseScheme(currentElement)]; - } else { - children.roles.push(parseScheme(currentElement)); - } + // MutationObserver + if ((typeof document === 'object') && document) { + if (typeof MutationObserver === 'function') return byObserver(MutationObserver); + if (typeof WebKitMutationObserver === 'function') return byObserver(WebKitMutationObserver); + } - break; + // W3C Draft + // http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html + if (typeof setImmediate === 'function') { + return function (cb) { setImmediate(ensureCallable(cb)); }; + } - case "SupplementalProperty": - if (children.supplementalProperties == null) { - children.supplementalProperties = [parseScheme(currentElement)]; - } else { - children.supplementalProperties.push(parseScheme(currentElement)); - } + // Wide available standard + if ((typeof setTimeout === 'function') || (typeof setTimeout === 'object')) { + return function (cb) { setTimeout(ensureCallable(cb), 0); }; + } - break; + return null; +}()); - case "SegmentBase": - var _parseSegmentBase = parseSegmentBase(currentElement), - segmentBase = _parseSegmentBase[0], - segmentBaseWarnings = _parseSegmentBase[1]; - children.segmentBase = segmentBase; +/***/ }), - if (segmentBaseWarnings.length > 0) { - warnings = warnings.concat(segmentBaseWarnings); - } +/***/ 8555: +/***/ ((module, __unused_webpack_exports, __webpack_require__) => { - break; +"use strict"; - case "SegmentList": - var _parseSegmentList = parseSegmentList(currentElement), - segmentList = _parseSegmentList[0], - segmentListWarnings = _parseSegmentList[1]; - children.segmentList = segmentList; +var PENDING = 'pending'; +var SETTLED = 'settled'; +var FULFILLED = 'fulfilled'; +var REJECTED = 'rejected'; +var NOOP = function () {}; +var isNode = typeof __webpack_require__.g !== 'undefined' && typeof __webpack_require__.g.process !== 'undefined' && typeof __webpack_require__.g.process.emit === 'function'; - if (segmentListWarnings.length > 0) { - warnings = warnings.concat(segmentListWarnings); - } +var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate; +var asyncQueue = []; +var asyncTimer; - break; +function asyncFlush() { + // run promise callbacks + for (var i = 0; i < asyncQueue.length; i++) { + asyncQueue[i][0](asyncQueue[i][1]); + } - case "SegmentTemplate": - var _parseSegmentTemplate = parseSegmentTemplate(currentElement), - segmentTemplate = _parseSegmentTemplate[0], - segmentTemplateWarnings = _parseSegmentTemplate[1]; + // reset async asyncQueue + asyncQueue = []; + asyncTimer = false; +} - children.segmentTemplate = segmentTemplate; +function asyncCall(callback, arg) { + asyncQueue.push([callback, arg]); - if (segmentTemplateWarnings.length > 0) { - warnings = warnings.concat(segmentTemplateWarnings); - } + if (!asyncTimer) { + asyncTimer = true; + asyncSetTimer(asyncFlush, 0); + } +} - break; +function invokeResolver(resolver, promise) { + function resolvePromise(value) { + resolve(promise, value); + } - case "ContentProtection": - var _parseContentProtecti = parseContentProtection(currentElement), - contentProtection = _parseContentProtecti[0], - contentProtectionWarnings = _parseContentProtecti[1]; + function rejectPromise(reason) { + reject(promise, reason); + } - if (contentProtectionWarnings.length > 0) { - warnings = warnings.concat(contentProtectionWarnings); - } + try { + resolver(resolvePromise, rejectPromise); + } catch (e) { + rejectPromise(e); + } +} - if (contentProtection !== undefined) { - contentProtections.push(contentProtection); - } +function invokeCallback(subscriber) { + var owner = subscriber.owner; + var settled = owner._state; + var value = owner._data; + var callback = subscriber[settled]; + var promise = subscriber.then; - break; - // case "Rating": - // children.rating = currentElement; - // break; - // case "Viewpoint": - // children.viewpoint = currentElement; - // break; - } - } - } + if (typeof callback === 'function') { + settled = FULFILLED; + try { + value = callback(value); + } catch (e) { + reject(promise, e); + } + } - if (contentProtections.length > 0) { - children.contentProtections = contentProtections; - } + if (!handleThenable(promise, value)) { + if (settled === FULFILLED) { + resolve(promise, value); + } - return [children, warnings]; + if (settled === REJECTED) { + reject(promise, value); + } + } } -/** - * Parse every attributes from an AdaptationSet root element into a simple JS - * object. - * @param {Element} root - The AdaptationSet root element. - * @returns {Array.} - */ +function handleThenable(promise, value) { + var resolved; -function parseAdaptationSetAttributes(root) { - var parsedAdaptation = {}; - var warnings = []; - var parseValue = ValueParser(parsedAdaptation, warnings); - - for (var i = 0; i < root.attributes.length; i++) { - var attribute = root.attributes[i]; + try { + if (promise === value) { + throw new TypeError('A promises callback cannot return that same promise.'); + } - switch (attribute.name) { - case "id": - parsedAdaptation.id = attribute.value; - break; + if (value && (typeof value === 'function' || typeof value === 'object')) { + // then should be retrieved only once + var then = value.then; - case "group": - parseValue(attribute.value, { - asKey: "group", - parser: parseMPDInteger, - dashName: "group" - }); - break; + if (typeof then === 'function') { + then.call(value, function (val) { + if (!resolved) { + resolved = true; - case "lang": - parsedAdaptation.language = attribute.value; - break; + if (value === val) { + fulfill(promise, val); + } else { + resolve(promise, val); + } + } + }, function (reason) { + if (!resolved) { + resolved = true; - case "contentType": - parsedAdaptation.contentType = attribute.value; - break; + reject(promise, reason); + } + }); - case "par": - parsedAdaptation.par = attribute.value; - break; + return true; + } + } + } catch (e) { + if (!resolved) { + reject(promise, e); + } - case "minBandwidth": - parseValue(attribute.value, { - asKey: "minBitrate", - parser: parseMPDInteger, - dashName: "minBandwidth" - }); - break; + return true; + } - case "maxBandwidth": - parseValue(attribute.value, { - asKey: "maxBitrate", - parser: parseMPDInteger, - dashName: "maxBandwidth" - }); - break; + return false; +} - case "minWidth": - parseValue(attribute.value, { - asKey: "minWidth", - parser: parseMPDInteger, - dashName: "minWidth" - }); - break; +function resolve(promise, value) { + if (promise === value || !handleThenable(promise, value)) { + fulfill(promise, value); + } +} - case "maxWidth": - parseValue(attribute.value, { - asKey: "maxWidth", - parser: parseMPDInteger, - dashName: "maxWidth" - }); - break; +function fulfill(promise, value) { + if (promise._state === PENDING) { + promise._state = SETTLED; + promise._data = value; - case "minHeight": - parseValue(attribute.value, { - asKey: "minHeight", - parser: parseMPDInteger, - dashName: "minHeight" - }); - break; + asyncCall(publishFulfillment, promise); + } +} - case "maxHeight": - parseValue(attribute.value, { - asKey: "maxHeight", - parser: parseMPDInteger, - dashName: "maxHeight" - }); - break; +function reject(promise, reason) { + if (promise._state === PENDING) { + promise._state = SETTLED; + promise._data = reason; - case "minFrameRate": - { - parsedAdaptation.minFrameRate = attribute.value; - } - break; + asyncCall(publishRejection, promise); + } +} - case "maxFrameRate": - parsedAdaptation.maxFrameRate = attribute.value; - break; +function publish(promise) { + promise._then = promise._then.forEach(invokeCallback); +} - case "selectionPriority": - parseValue(attribute.value, { - asKey: "selectionPriority", - parser: parseMPDInteger, - dashName: "selectionPriority" - }); - break; +function publishFulfillment(promise) { + promise._state = FULFILLED; + publish(promise); +} - case "segmentAlignment": - parseValue(attribute.value, { - asKey: "segmentAlignment", - parser: parseIntOrBoolean, - dashName: "segmentAlignment" - }); - break; +function publishRejection(promise) { + promise._state = REJECTED; + publish(promise); + if (!promise._handled && isNode) { + __webpack_require__.g.process.emit('unhandledRejection', promise._data, promise); + } +} - case "subsegmentAlignment": - parseValue(attribute.value, { - asKey: "subsegmentAlignment", - parser: parseIntOrBoolean, - dashName: "subsegmentAlignment" - }); - break; +function notifyRejectionHandled(promise) { + __webpack_require__.g.process.emit('rejectionHandled', promise); +} - case "bitstreamSwitching": - parseValue(attribute.value, { - asKey: "bitstreamSwitching", - parser: parseBoolean, - dashName: "bitstreamSwitching" - }); - break; +/** + * @class + */ +function Promise(resolver) { + if (typeof resolver !== 'function') { + throw new TypeError('Promise resolver ' + resolver + ' is not a function'); + } - case "audioSamplingRate": - parsedAdaptation.audioSamplingRate = attribute.value; - break; + if (this instanceof Promise === false) { + throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); + } - case "codecs": - parsedAdaptation.codecs = attribute.value; - break; + this._then = []; - case "codingDependency": - parseValue(attribute.value, { - asKey: "codingDependency", - parser: parseBoolean, - dashName: "codingDependency" - }); - break; + invokeResolver(resolver, this); +} - case "frameRate": - parsedAdaptation.frameRate = attribute.value; - break; - - case "height": - parseValue(attribute.value, { - asKey: "height", - parser: parseMPDInteger, - dashName: "height" - }); - break; - - case "maxPlayoutRate": - parseValue(attribute.value, { - asKey: "maxPlayoutRate", - parser: parseMPDFloat, - dashName: "maxPlayoutRate" - }); - break; - - case "maximumSAPPeriod": - parseValue(attribute.value, { - asKey: "maximumSAPPeriod", - parser: parseMPDFloat, - dashName: "maximumSAPPeriod" - }); - break; - - case "mimeType": - parsedAdaptation.mimeType = attribute.value; - break; - - case "profiles": - parsedAdaptation.profiles = attribute.value; - break; - - case "segmentProfiles": - parsedAdaptation.segmentProfiles = attribute.value; - break; - - case "width": - parseValue(attribute.value, { - asKey: "width", - parser: parseMPDInteger, - dashName: "width" - }); - break; - } - } - - return [parsedAdaptation, warnings]; -} -/** - * Parse an AdaptationSet element into an AdaptationSet intermediate - * representation. - * @param {Element} adaptationSetElement - The AdaptationSet root element. - * @returns {Array.} - */ +Promise.prototype = { + constructor: Promise, + _state: PENDING, + _then: null, + _data: undefined, + _handled: false, -function createAdaptationSetIntermediateRepresentation(adaptationSetElement) { - var childNodes = adaptationSetElement.childNodes; + then: function (onFulfillment, onRejection) { + var subscriber = { + owner: this, + then: new this.constructor(NOOP), + fulfilled: onFulfillment, + rejected: onRejection + }; - var _parseAdaptationSetCh = parseAdaptationSetChildren(childNodes), - children = _parseAdaptationSetCh[0], - childrenWarnings = _parseAdaptationSetCh[1]; + if ((onRejection || onFulfillment) && !this._handled) { + this._handled = true; + if (this._state === REJECTED && isNode) { + asyncCall(notifyRejectionHandled, this); + } + } - var _parseAdaptationSetAt = parseAdaptationSetAttributes(adaptationSetElement), - attributes = _parseAdaptationSetAt[0], - attrsWarnings = _parseAdaptationSetAt[1]; + if (this._state === FULFILLED || this._state === REJECTED) { + // already resolved, call callback async + asyncCall(invokeCallback, subscriber); + } else { + // subscribe + this._then.push(subscriber); + } - var warnings = childrenWarnings.concat(attrsWarnings); - return [{ - children: children, - attributes: attributes - }, warnings]; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/EventStream.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 subscriber.then; + }, -/** - * Parse the EventStream node to extract Event nodes and their - * content. - * @param {Element} element - */ + catch: function (onRejection) { + return this.then(null, onRejection); + } +}; -function parseEventStream(element) { - var _a; +Promise.all = function (promises) { + if (!Array.isArray(promises)) { + throw new TypeError('You must pass an array to Promise.all().'); + } - var streamEvents = []; - var attributes = { - timescale: 1 - }; - var warnings = []; - var parseValue = ValueParser(attributes, warnings); + return new Promise(function (resolve, reject) { + var results = []; + var remaining = 0; - for (var i = 0; i < element.attributes.length; i++) { - var attribute = element.attributes[i]; + function resolver(index) { + remaining++; + return function (value) { + results[index] = value; + if (!--remaining) { + resolve(results); + } + }; + } - switch (attribute.name) { - case "schemeIdUri": - attributes.schemeId = attribute.value; - break; + for (var i = 0, promise; i < promises.length; i++) { + promise = promises[i]; - case "timescale": - parseValue(attribute.value, { - asKey: "timescale", - parser: parseMPDInteger, - dashName: "timescale" - }); - break; + if (promise && typeof promise.then === 'function') { + promise.then(resolver(i), reject); + } else { + results[i] = promise; + } + } - case "value": - attributes.value = attribute.value; - break; + if (!remaining) { + resolve(results); + } + }); +}; - default: - break; - } - } +Promise.race = function (promises) { + if (!Array.isArray(promises)) { + throw new TypeError('You must pass an array to Promise.race().'); + } - for (var k = 0; k < element.childNodes.length; k++) { - var node = element.childNodes[k]; - var streamEvent = { - id: undefined, - eventPresentationTime: 0, - duration: undefined, - timescale: attributes.timescale, - data: { - type: "dash-event-stream", - value: { - schemeIdUri: (_a = attributes.schemeId) !== null && _a !== void 0 ? _a : "", - timescale: attributes.timescale, - element: node - } - } - }; - var parseEventValue = ValueParser(streamEvent, warnings); + return new Promise(function (resolve, reject) { + for (var i = 0, promise; i < promises.length; i++) { + promise = promises[i]; - if (node.nodeName === "Event" && node.nodeType === Node.ELEMENT_NODE) { - var eventAttributes = node.attributes; + if (promise && typeof promise.then === 'function') { + promise.then(resolve, reject); + } else { + resolve(promise); + } + } + }); +}; - for (var j = 0; j < eventAttributes.length; j++) { - var _attribute = eventAttributes[j]; +Promise.resolve = function (value) { + if (value && typeof value === 'object' && value.constructor === Promise) { + return value; + } - switch (_attribute.name) { - case "presentationTime": - parseEventValue(_attribute.value, { - asKey: "eventPresentationTime", - parser: parseMPDInteger, - dashName: "presentationTime" - }); - break; + return new Promise(function (resolve) { + resolve(value); + }); +}; - case "duration": - parseEventValue(_attribute.value, { - asKey: "duration", - parser: parseMPDInteger, - dashName: "duration" - }); - break; +Promise.reject = function (reason) { + return new Promise(function (resolve, reject) { + reject(reason); + }); +}; - case "id": - streamEvent.id = _attribute.value; - break; +module.exports = Promise; - default: - break; - } - } - streamEvents.push(streamEvent); - } - } +/***/ }), - return [streamEvents, warnings]; -} +/***/ 5666: +/***/ ((module) => { -/* harmony default export */ const EventStream = (parseEventStream); -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/Period.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 + * Copyright (c) 2014-present, Facebook, Inc. * - * 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 source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ +var runtime = (function (exports) { + "use strict"; + var Op = Object.prototype; + var hasOwn = Op.hasOwnProperty; + var undefined; // More compressible than void 0. + var $Symbol = typeof Symbol === "function" ? Symbol : {}; + var iteratorSymbol = $Symbol.iterator || "@@iterator"; + var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; + var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; + function define(obj, key, value) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + return obj[key]; + } + try { + // IE 8 has a broken Object.defineProperty that only works on DOM objects. + define({}, ""); + } catch (err) { + define = function(obj, key, value) { + return obj[key] = value; + }; + } + function wrap(innerFn, outerFn, self, tryLocsList) { + // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. + var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; + var generator = Object.create(protoGenerator.prototype); + var context = new Context(tryLocsList || []); -/** - * @param {NodeList} periodChildren - * @returns {Array} - */ - -function parsePeriodChildren(periodChildren) { - var baseURLs = []; - var adaptations = []; - var segmentTemplate; - var warnings = []; - var streamEvents = []; - - for (var i = 0; i < periodChildren.length; i++) { - if (periodChildren[i].nodeType === Node.ELEMENT_NODE) { - var currentElement = periodChildren[i]; + // The ._invoke method unifies the implementations of the .next, + // .throw, and .return methods. + generator._invoke = makeInvokeMethod(innerFn, self, context); - switch (currentElement.nodeName) { - case "BaseURL": - var _parseBaseURL = parseBaseURL(currentElement), - baseURLObj = _parseBaseURL[0], - baseURLWarnings = _parseBaseURL[1]; + return generator; + } + exports.wrap = wrap; - if (baseURLObj !== undefined) { - baseURLs.push(baseURLObj); - } + // Try/catch helper to minimize deoptimizations. Returns a completion + // record like context.tryEntries[i].completion. This interface could + // have been (and was previously) designed to take a closure to be + // invoked without arguments, but in all the cases we care about we + // already have an existing method we want to call, so there's no need + // to create a new function object. We can even get away with assuming + // the method takes exactly one argument, since that happens to be true + // in every case, so we don't have to touch the arguments object. The + // only additional allocation required is the completion record, which + // has a stable shape and so hopefully should be cheap to allocate. + function tryCatch(fn, obj, arg) { + try { + return { type: "normal", arg: fn.call(obj, arg) }; + } catch (err) { + return { type: "throw", arg: err }; + } + } - warnings = warnings.concat(baseURLWarnings); - break; + var GenStateSuspendedStart = "suspendedStart"; + var GenStateSuspendedYield = "suspendedYield"; + var GenStateExecuting = "executing"; + var GenStateCompleted = "completed"; - case "AdaptationSet": - var _createAdaptationSetI = createAdaptationSetIntermediateRepresentation(currentElement), - adaptation = _createAdaptationSetI[0], - adaptationWarnings = _createAdaptationSetI[1]; + // Returning this object from the innerFn has the same effect as + // breaking out of the dispatch switch statement. + var ContinueSentinel = {}; - adaptations.push(adaptation); - warnings = warnings.concat(adaptationWarnings); - break; + // Dummy constructor functions that we use as the .constructor and + // .constructor.prototype properties for functions that return Generator + // objects. For full spec compliance, you may wish to configure your + // minifier not to mangle the names of these two functions. + function Generator() {} + function GeneratorFunction() {} + function GeneratorFunctionPrototype() {} - case "EventStream": - var _parseEventStream = EventStream(currentElement), - newStreamEvents = _parseEventStream[0], - eventStreamWarnings = _parseEventStream[1]; + // This is a polyfill for %IteratorPrototype% for environments that + // don't natively support it. + var IteratorPrototype = {}; + IteratorPrototype[iteratorSymbol] = function () { + return this; + }; - streamEvents.push.apply(streamEvents, newStreamEvents); - warnings = warnings.concat(eventStreamWarnings); - break; + var getProto = Object.getPrototypeOf; + var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); + if (NativeIteratorPrototype && + NativeIteratorPrototype !== Op && + hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { + // This environment has a native %IteratorPrototype%; use it instead + // of the polyfill. + IteratorPrototype = NativeIteratorPrototype; + } - case "SegmentTemplate": - var _parseSegmentTemplate = parseSegmentTemplate(currentElement), - parsedSegmentTemplate = _parseSegmentTemplate[0], - segmentTemplateWarnings = _parseSegmentTemplate[1]; + var Gp = GeneratorFunctionPrototype.prototype = + Generator.prototype = Object.create(IteratorPrototype); + GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; + GeneratorFunctionPrototype.constructor = GeneratorFunction; + GeneratorFunction.displayName = define( + GeneratorFunctionPrototype, + toStringTagSymbol, + "GeneratorFunction" + ); - segmentTemplate = parsedSegmentTemplate; + // Helper for defining the .next, .throw, and .return methods of the + // Iterator interface in terms of a single ._invoke method. + function defineIteratorMethods(prototype) { + ["next", "throw", "return"].forEach(function(method) { + define(prototype, method, function(arg) { + return this._invoke(method, arg); + }); + }); + } - if (segmentTemplateWarnings.length > 0) { - warnings = warnings.concat(segmentTemplateWarnings); - } + exports.isGeneratorFunction = function(genFun) { + var ctor = typeof genFun === "function" && genFun.constructor; + return ctor + ? ctor === GeneratorFunction || + // For the native GeneratorFunction constructor, the best we can + // do is to check its .name property. + (ctor.displayName || ctor.name) === "GeneratorFunction" + : false; + }; - break; - } + exports.mark = function(genFun) { + if (Object.setPrototypeOf) { + Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); + } else { + genFun.__proto__ = GeneratorFunctionPrototype; + define(genFun, toStringTagSymbol, "GeneratorFunction"); } - } - - return [{ - baseURLs: baseURLs, - adaptations: adaptations, - streamEvents: streamEvents, - segmentTemplate: segmentTemplate - }, warnings]; -} -/** - * @param {Element} periodElement - * @returns {Array} - */ + genFun.prototype = Object.create(Gp); + return genFun; + }; + // Within the body of any async function, `await x` is transformed to + // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test + // `hasOwn.call(value, "__await")` to determine if the yielded value is + // meant to be awaited. + exports.awrap = function(arg) { + return { __await: arg }; + }; -function parsePeriodAttributes(periodElement) { - var res = {}; - var warnings = []; - var parseValue = ValueParser(res, warnings); + function AsyncIterator(generator, PromiseImpl) { + function invoke(method, arg, resolve, reject) { + var record = tryCatch(generator[method], generator, arg); + if (record.type === "throw") { + reject(record.arg); + } else { + var result = record.arg; + var value = result.value; + if (value && + typeof value === "object" && + hasOwn.call(value, "__await")) { + return PromiseImpl.resolve(value.__await).then(function(value) { + invoke("next", value, resolve, reject); + }, function(err) { + invoke("throw", err, resolve, reject); + }); + } - for (var i = 0; i < periodElement.attributes.length; i++) { - var attr = periodElement.attributes[i]; + return PromiseImpl.resolve(value).then(function(unwrapped) { + // When a yielded Promise is resolved, its final value becomes + // the .value of the Promise<{value,done}> result for the + // current iteration. + result.value = unwrapped; + resolve(result); + }, function(error) { + // If a rejected Promise was yielded, throw the rejection back + // into the async generator function so it can be handled there. + return invoke("throw", error, resolve, reject); + }); + } + } - switch (attr.name) { - case "id": - res.id = attr.value; - break; + var previousPromise; - case "start": - parseValue(attr.value, { - asKey: "start", - parser: parseDuration, - dashName: "start" + function enqueue(method, arg) { + function callInvokeWithMethodAndArg() { + return new PromiseImpl(function(resolve, reject) { + invoke(method, arg, resolve, reject); }); - break; + } - case "duration": - parseValue(attr.value, { - asKey: "duration", - parser: parseDuration, - dashName: "duration" - }); - break; - - case "bitstreamSwitching": - parseValue(attr.value, { - asKey: "bitstreamSwitching", - parser: parseBoolean, - dashName: "bitstreamSwitching" - }); - break; - - case "xlink:href": - res.xlinkHref = attr.value; - break; - - case "xlink:actuate": - res.xlinkActuate = attr.value; - break; + return previousPromise = + // If enqueue has been called before, then we want to wait until + // all previous Promises have been resolved before calling invoke, + // so that results are always delivered in the correct order. If + // enqueue has not been called before, then it is important to + // call invoke immediately, without waiting on a callback to fire, + // so that the async generator function has the opportunity to do + // any necessary setup in a predictable way. This predictability + // is why the Promise constructor synchronously invokes its + // executor callback, and why async functions synchronously + // execute code before the first await. Since we implement simple + // async functions in terms of async generators, it is especially + // important to get this right, even though it requires care. + previousPromise ? previousPromise.then( + callInvokeWithMethodAndArg, + // Avoid propagating failures to Promises returned by later + // invocations of the iterator. + callInvokeWithMethodAndArg + ) : callInvokeWithMethodAndArg(); } + + // Define the unified helper method that is used to implement .next, + // .throw, and .return (see defineIteratorMethods). + this._invoke = enqueue; } - return [res, warnings]; -} -/** - * @param {Element} periodElement - * @returns {Array} - */ + defineIteratorMethods(AsyncIterator.prototype); + AsyncIterator.prototype[asyncIteratorSymbol] = function () { + return this; + }; + exports.AsyncIterator = AsyncIterator; + // Note that simple async functions are implemented on top of + // AsyncIterator objects; they just return a Promise for the value of + // the final result produced by the iterator. + exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) { + if (PromiseImpl === void 0) PromiseImpl = Promise; -function createPeriodIntermediateRepresentation(periodElement) { - var _parsePeriodChildren = parsePeriodChildren(periodElement.childNodes), - children = _parsePeriodChildren[0], - childrenWarnings = _parsePeriodChildren[1]; + var iter = new AsyncIterator( + wrap(innerFn, outerFn, self, tryLocsList), + PromiseImpl + ); - var _parsePeriodAttribute = parsePeriodAttributes(periodElement), - attributes = _parsePeriodAttribute[0], - attrsWarnings = _parsePeriodAttribute[1]; + return exports.isGeneratorFunction(outerFn) + ? iter // If outerFn is a generator, return the full iterator. + : iter.next().then(function(result) { + return result.done ? result.value : iter.next(); + }); + }; - var warnings = childrenWarnings.concat(attrsWarnings); - return [{ - children: children, - attributes: attributes - }, warnings]; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/node_parsers/MPD.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 makeInvokeMethod(innerFn, self, context) { + var state = GenStateSuspendedStart; + return function invoke(method, arg) { + if (state === GenStateExecuting) { + throw new Error("Generator is already running"); + } + if (state === GenStateCompleted) { + if (method === "throw") { + throw arg; + } -/** - * Parse children of the MPD's root into a simple object. - * @param {NodeList} mpdChildren - * @returns {Array.} - */ + // Be forgiving, per 25.3.3.3.3 of the spec: + // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume + return doneResult(); + } -function parseMPDChildren(mpdChildren) { - var baseURLs = []; - var locations = []; - var periods = []; - var utcTimings = []; - var warnings = []; + context.method = method; + context.arg = arg; - for (var i = 0; i < mpdChildren.length; i++) { - if (mpdChildren[i].nodeType === Node.ELEMENT_NODE) { - var currentNode = mpdChildren[i]; + while (true) { + var delegate = context.delegate; + if (delegate) { + var delegateResult = maybeInvokeDelegate(delegate, context); + if (delegateResult) { + if (delegateResult === ContinueSentinel) continue; + return delegateResult; + } + } - switch (currentNode.nodeName) { - case "BaseURL": - var _parseBaseURL = parseBaseURL(currentNode), - baseURLObj = _parseBaseURL[0], - baseURLWarnings = _parseBaseURL[1]; + if (context.method === "next") { + // Setting context._sent for legacy support of Babel's + // function.sent implementation. + context.sent = context._sent = context.arg; - if (baseURLObj !== undefined) { - baseURLs.push(baseURLObj); + } else if (context.method === "throw") { + if (state === GenStateSuspendedStart) { + state = GenStateCompleted; + throw context.arg; } - warnings = warnings.concat(baseURLWarnings); - break; + context.dispatchException(context.arg); - case "Location": - locations.push(currentNode.textContent === null ? "" : currentNode.textContent); - break; + } else if (context.method === "return") { + context.abrupt("return", context.arg); + } - case "Period": - var _createPeriodIntermed = createPeriodIntermediateRepresentation(currentNode), - period = _createPeriodIntermed[0], - periodWarnings = _createPeriodIntermed[1]; + state = GenStateExecuting; - periods.push(period); - warnings = warnings.concat(periodWarnings); - break; + var record = tryCatch(innerFn, self, context); + if (record.type === "normal") { + // If an exception is thrown from innerFn, we leave state === + // GenStateExecuting and loop back for another invocation. + state = context.done + ? GenStateCompleted + : GenStateSuspendedYield; - case "UTCTiming": - var utcTiming = parseScheme(currentNode); - utcTimings.push(utcTiming); - break; + if (record.arg === ContinueSentinel) { + continue; + } + + return { + value: record.arg, + done: context.done + }; + + } else if (record.type === "throw") { + state = GenStateCompleted; + // Dispatch the exception by looping back around to the + // context.dispatchException(context.arg) call above. + context.method = "throw"; + context.arg = record.arg; + } } - } + }; } - return [{ - baseURLs: baseURLs, - locations: locations, - periods: periods, - utcTimings: utcTimings - }, warnings]; -} -/** - * @param {Element} root - * @returns {Array.} - */ - + // Call delegate.iterator[context.method](context.arg) and handle the + // result, either by returning a { value, done } result from the + // delegate iterator, or by modifying context.method and context.arg, + // setting context.delegate to null, and returning the ContinueSentinel. + function maybeInvokeDelegate(delegate, context) { + var method = delegate.iterator[context.method]; + if (method === undefined) { + // A .throw or .return when the delegate iterator has no .throw + // method always terminates the yield* loop. + context.delegate = null; -function parseMPDAttributes(root) { - var res = {}; - var warnings = []; - var parseValue = ValueParser(res, warnings); + if (context.method === "throw") { + // Note: ["return"] must be used for ES3 parsing compatibility. + if (delegate.iterator["return"]) { + // If the delegate iterator has a return method, give it a + // chance to clean up. + context.method = "return"; + context.arg = undefined; + maybeInvokeDelegate(delegate, context); - for (var i = 0; i < root.attributes.length; i++) { - var attribute = root.attributes[i]; + if (context.method === "throw") { + // If maybeInvokeDelegate(context) changed context.method from + // "return" to "throw", let that override the TypeError below. + return ContinueSentinel; + } + } - switch (attribute.name) { - case "id": - res.id = attribute.value; - break; + context.method = "throw"; + context.arg = new TypeError( + "The iterator does not provide a 'throw' method"); + } - case "profiles": - res.profiles = attribute.value; - break; + return ContinueSentinel; + } - case "type": - res.type = attribute.value; - break; + var record = tryCatch(method, delegate.iterator, context.arg); - case "availabilityStartTime": - parseValue(attribute.value, { - asKey: "availabilityStartTime", - parser: parseDateTime, - dashName: "availabilityStartTime" - }); - break; + if (record.type === "throw") { + context.method = "throw"; + context.arg = record.arg; + context.delegate = null; + return ContinueSentinel; + } - case "availabilityEndTime": - parseValue(attribute.value, { - asKey: "availabilityEndTime", - parser: parseDateTime, - dashName: "availabilityEndTime" - }); - break; + var info = record.arg; - case "publishTime": - parseValue(attribute.value, { - asKey: "publishTime", - parser: parseDateTime, - dashName: "publishTime" - }); - break; + if (! info) { + context.method = "throw"; + context.arg = new TypeError("iterator result is not an object"); + context.delegate = null; + return ContinueSentinel; + } - case "mediaPresentationDuration": - parseValue(attribute.value, { - asKey: "duration", - parser: parseDuration, - dashName: "mediaPresentationDuration" - }); - break; + if (info.done) { + // Assign the result of the finished delegate to the temporary + // variable specified by delegate.resultName (see delegateYield). + context[delegate.resultName] = info.value; - case "minimumUpdatePeriod": - parseValue(attribute.value, { - asKey: "minimumUpdatePeriod", - parser: parseDuration, - dashName: "minimumUpdatePeriod" - }); - break; + // Resume execution at the desired location (see delegateYield). + context.next = delegate.nextLoc; - case "minBufferTime": - parseValue(attribute.value, { - asKey: "minBufferTime", - parser: parseDuration, - dashName: "minBufferTime" - }); - break; + // If context.method was "throw" but the delegate handled the + // exception, let the outer generator proceed normally. If + // context.method was "next", forget context.arg since it has been + // "consumed" by the delegate iterator. If context.method was + // "return", allow the original .return call to continue in the + // outer generator. + if (context.method !== "return") { + context.method = "next"; + context.arg = undefined; + } - case "timeShiftBufferDepth": - parseValue(attribute.value, { - asKey: "timeShiftBufferDepth", - parser: parseDuration, - dashName: "timeShiftBufferDepth" - }); - break; + } else { + // Re-yield the result returned by the delegate method. + return info; + } - case "suggestedPresentationDelay": - parseValue(attribute.value, { - asKey: "suggestedPresentationDelay", - parser: parseDuration, - dashName: "suggestedPresentationDelay" - }); - break; + // The delegate iterator is finished, so forget it and continue with + // the outer generator. + context.delegate = null; + return ContinueSentinel; + } - case "maxSegmentDuration": - parseValue(attribute.value, { - asKey: "maxSegmentDuration", - parser: parseDuration, - dashName: "maxSegmentDuration" - }); - break; + // Define Generator.prototype.{next,throw,return} in terms of the + // unified ._invoke helper method. + defineIteratorMethods(Gp); - case "maxSubsegmentDuration": - parseValue(attribute.value, { - asKey: "maxSubsegmentDuration", - parser: parseDuration, - dashName: "maxSubsegmentDuration" - }); - break; - } - } + define(Gp, toStringTagSymbol, "Generator"); - return [res, warnings]; -} -/** - * @param {Element} root - * @returns {Array.} - */ + // A Generator should always return itself as the iterator object when the + // @@iterator function is called on it. Some browsers' implementations of the + // iterator prototype chain incorrectly implement this, causing the Generator + // object to not be returned from this call. This ensures that doesn't happen. + // See https://github.com/facebook/regenerator/issues/274 for more details. + Gp[iteratorSymbol] = function() { + return this; + }; + Gp.toString = function() { + return "[object Generator]"; + }; -function createMPDIntermediateRepresentation(root) { - var _parseMPDChildren = parseMPDChildren(root.childNodes), - children = _parseMPDChildren[0], - childrenWarnings = _parseMPDChildren[1]; + function pushTryEntry(locs) { + var entry = { tryLoc: locs[0] }; - var _parseMPDAttributes = parseMPDAttributes(root), - attributes = _parseMPDAttributes[0], - attrsWarnings = _parseMPDAttributes[1]; + if (1 in locs) { + entry.catchLoc = locs[1]; + } - var warnings = childrenWarnings.concat(attrsWarnings); - return [{ - children: children, - attributes: attributes - }, warnings]; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_availability_start_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. - */ + if (2 in locs) { + entry.finallyLoc = locs[2]; + entry.afterLoc = locs[3]; + } -/** - * Returns the base time of the Manifest. - * @param {Object} rootAttributes - * @param {number|undefined} - */ -function parseAvailabilityStartTime(rootAttributes, referenceDateTime) { - if (rootAttributes.type !== "dynamic") { - return 0; + this.tryEntries.push(entry); } - if (rootAttributes.availabilityStartTime == null) { - return referenceDateTime == null ? 0 : referenceDateTime; + function resetTryEntry(entry) { + var record = entry.completion || {}; + record.type = "normal"; + delete record.arg; + entry.completion = record; } - return rootAttributes.availabilityStartTime; -} -// EXTERNAL MODULE: ./src/utils/flat_map.ts -var flat_map = __webpack_require__(9592); -// EXTERNAL MODULE: ./src/utils/id_generator.ts -var id_generator = __webpack_require__(908); -// EXTERNAL MODULE: ./src/utils/object_values.ts -var object_values = __webpack_require__(1679); -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/flatten_overlapping_periods.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. - */ - -/** - * Avoid periods to overlap. - * - * According to DASH guidelines, if a period has media duration longer than - * the distance between the start of this period and the start of the next period, - * use of start times implies that the client will start the playout of the next - * period at the time stated, rather than finishing the playout of the last period. - * - * Even if that case if defined when period last(s) segment(s) is/are a bit longer, - * it can be meaningful when two periods are overlapping. We will always shorten - * the first period, and even erase it if its duration is equal to zero. - * - * Example (Periods are numbered under their manifest order) : - * - * [ Period 1 ][ Period 2 ] ------> [ Period 1 ][ Period 3 ] - * [ Period 3 ] - * - * [ Period 1 ][ Period 2 ] ------> [ Period 1 ][ 2 ][ Period 3 ] - * [ Period 3 ] - * - * [ Period 1 ][ Period 2 ] ------> [ 1 ][ Period 3 ] - * [ Period 3 ] - * - * @param {Array.} parsedPeriods - * @return {Array.} - */ - -function flattenOverlappingPeriods(parsedPeriods) { - if (parsedPeriods.length === 0) { - return []; + function Context(tryLocsList) { + // The root entry object (effectively a try statement without a catch + // or a finally block) gives us a place to store values thrown from + // locations where there is no enclosing try statement. + this.tryEntries = [{ tryLoc: "root" }]; + tryLocsList.forEach(pushTryEntry, this); + this.reset(true); } - var flattenedPeriods = [parsedPeriods[0]]; - - for (var i = 1; i < parsedPeriods.length; i++) { - var parsedPeriod = parsedPeriods[i]; - var lastFlattenedPeriod = flattenedPeriods[flattenedPeriods.length - 1]; - - while (lastFlattenedPeriod.duration == null || lastFlattenedPeriod.start + lastFlattenedPeriod.duration > parsedPeriod.start) { - log/* default.warn */.Z.warn("DASH: Updating overlapping Periods.", lastFlattenedPeriod, parsedPeriod); - lastFlattenedPeriod.duration = parsedPeriod.start - lastFlattenedPeriod.start; - lastFlattenedPeriod.end = parsedPeriod.start; - - if (lastFlattenedPeriod.duration <= 0) { - flattenedPeriods.pop(); - lastFlattenedPeriod = flattenedPeriods[flattenedPeriods.length - 1]; - } + exports.keys = function(object) { + var keys = []; + for (var key in object) { + keys.push(key); } + keys.reverse(); - flattenedPeriods.push(parsedPeriod); - } - - return flattenedPeriods; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/get_periods_time_infos.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 periods time information from current, next and previous - * periods. - * @param {Array.} periodsIR - * @param {Object} manifestInfos - * @return {Array.} - */ -function getPeriodsTimeInformation(periodsIR, manifestInfos) { - var periodsTimeInformation = []; - periodsIR.forEach(function (currentPeriod, i) { - var periodStart; - - if (currentPeriod.attributes.start != null) { - periodStart = currentPeriod.attributes.start; - } else { - if (i === 0) { - periodStart = !manifestInfos.isDynamic || manifestInfos.availabilityStartTime == null ? 0 : manifestInfos.availabilityStartTime; - } else { - // take time information from previous period - var prevPeriodInfos = periodsTimeInformation[periodsTimeInformation.length - 1]; - - if (prevPeriodInfos != null && prevPeriodInfos.periodEnd != null) { - periodStart = prevPeriodInfos.periodEnd; - } else { - throw new Error("Missing start time when parsing periods."); + // Rather than returning an object with a next method, we keep + // things simple and return the next function itself. + return function next() { + while (keys.length) { + var key = keys.pop(); + if (key in object) { + next.value = key; + next.done = false; + return next; } } - } - var periodDuration; - var nextPeriod = periodsIR[i + 1]; - - if (currentPeriod.attributes.duration != null) { - periodDuration = currentPeriod.attributes.duration; - } else if (i === periodsIR.length - 1) { - periodDuration = manifestInfos.duration; - } else if (nextPeriod.attributes.start != null) { - periodDuration = nextPeriod.attributes.start - periodStart; - } + // To avoid creating an additional object, we just hang the .value + // and .done properties off the next function object itself. This + // also ensures that the minifier will not anonymize the function. + next.done = true; + return next; + }; + }; - var periodEnd = periodDuration != null ? periodStart + periodDuration : undefined; - periodsTimeInformation.push({ - periodStart: periodStart, - periodDuration: periodDuration, - periodEnd: periodEnd - }); - }); - return periodsTimeInformation; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/manifest_bounds_calculator.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 values(iterable) { + if (iterable) { + var iteratorMethod = iterable[iteratorSymbol]; + if (iteratorMethod) { + return iteratorMethod.call(iterable); + } -/** - * This class allows to easily calculate the first and last available positions - * in a content at any time. - * - * That task can be an hard for dynamic DASH contents: it depends on a - * `timeShiftBufferDepth` defined in the MPD and on the maximum possible - * position. - * - * The latter can come from either a clock synchronization mechanism or the - * indexing schemes (e.g. SegmentTemplate, SegmentTimeline etc.) of the last - * Periods. - * As such, it might only be known once a large chunk of the MPD has already - * been parsed. - * - * By centralizing the manifest bounds calculation in this class and by giving - * an instance of it to each parsed elements which might depend on it, we - * ensure that we can provide it once it is known to every one of those - * elements without needing to parse a second time the MPD. - * @class ManifestBoundsCalculator - */ -var ManifestBoundsCalculator = /*#__PURE__*/function () { - /** - * @param {Object} args - */ - function ManifestBoundsCalculator(args) { - this._isDynamic = args.isDynamic; - this._timeShiftBufferDepth = !args.isDynamic || args.timeShiftBufferDepth === undefined ? null : args.timeShiftBufferDepth; - } - /** - * Set the last position and the position time (the value of `performance.now()` - * at the time that position was true converted into seconds). - * - * @example - * Example if you trust `Date.now()` to give you a reliable offset: - * ```js - * const lastPosition = Date.now(); - * const positionTime = performance.now() / 1000; - * manifestBoundsCalculator.setLastPosition(lastPosition, positionTime); - * ``` - * - * @param {number} lastPosition - * @param {number|undefined} positionTime - */ + if (typeof iterable.next === "function") { + return iterable; + } + if (!isNaN(iterable.length)) { + var i = -1, next = function next() { + while (++i < iterable.length) { + if (hasOwn.call(iterable, i)) { + next.value = iterable[i]; + next.done = false; + return next; + } + } - var _proto = ManifestBoundsCalculator.prototype; + next.value = undefined; + next.done = true; - _proto.setLastPosition = function setLastPosition(lastPosition, positionTime) { - this._lastPosition = lastPosition; - this._positionTime = positionTime; - } - /** - * Returns `true` if the last position and the position time - * (for dynamic content only) have been comunicated. - * `false` otherwise. - * @returns {boolean} - */ - ; + return next; + }; - _proto.lastPositionIsKnown = function lastPositionIsKnown() { - if (this._isDynamic) { - return this._positionTime != null && this._lastPosition != null; + return next.next = next; + } } - return this._lastPosition != null; + // Return an iterator with no values. + return { next: doneResult }; } - /** - * Estimate a minimum bound for the content from the last set segment time - * and buffer depth. - * Consider that it is only an estimation, not the real value. - * @return {number|undefined} - */ - ; + exports.values = values; - _proto.estimateMinimumBound = function estimateMinimumBound() { - if (!this._isDynamic || this._timeShiftBufferDepth === null) { - return 0; - } + function doneResult() { + return { value: undefined, done: true }; + } - var maximumBound = this.estimateMaximumBound(); + Context.prototype = { + constructor: Context, - if (maximumBound === undefined) { - return undefined; - } + reset: function(skipTempReset) { + this.prev = 0; + this.next = 0; + // Resetting context._sent for legacy support of Babel's + // function.sent implementation. + this.sent = this._sent = undefined; + this.done = false; + this.delegate = null; - var minimumBound = maximumBound - this._timeShiftBufferDepth; - return minimumBound; - } - /** - * Estimate a maximum bound for the content from the last set segment time. - * Consider that it is only an estimation, not the real value. - * @return {number|undefined} - */ - ; + this.method = "next"; + this.arg = undefined; - _proto.estimateMaximumBound = function estimateMaximumBound() { - if (this._isDynamic && this._positionTime != null && this._lastPosition != null) { - return Math.max(this._lastPosition - this._positionTime + performance.now() / 1000, 0); - } + this.tryEntries.forEach(resetTryEntry); - return this._lastPosition; - }; + if (!skipTempReset) { + for (var name in this) { + // Not sure about the optimal order of these conditions: + if (name.charAt(0) === "t" && + hasOwn.call(this, name) && + !isNaN(+name.slice(1))) { + this[name] = undefined; + } + } + } + }, - return ManifestBoundsCalculator; -}(); + stop: function() { + this.done = true; + var rootEntry = this.tryEntries[0]; + var rootRecord = rootEntry.completion; + if (rootRecord.type === "throw") { + throw rootRecord.arg; + } -// EXTERNAL MODULE: ./src/utils/array_includes.ts -var array_includes = __webpack_require__(7714); -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/infer_adaptation_type.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 this.rval; + }, + dispatchException: function(exception) { + if (this.done) { + throw exception; + } -/** Array grouping every possible type a parsed Adaptation can be. */ + var context = this; + function handle(loc, caught) { + record.type = "throw"; + record.arg = exception; + context.next = loc; -var KNOWN_ADAPTATION_TYPES = ["audio", "video", "text", "image"]; -/** Different `role`s a text Adaptation can be. */ + if (caught) { + // If the dispatched exception was caught by a catch block, + // then let that catch block handle the exception normally. + context.method = "next"; + context.arg = undefined; + } -var SUPPORTED_TEXT_TYPES = ["subtitle", "caption"]; -/** - * Infers the type of adaptation from codec and mimetypes found in it. - * - * This follows the guidelines defined by the DASH-IF IOP: - * - one adaptation set contains a single media type - * - The order of verifications are: - * 1. mimeType - * 2. Role - * 3. codec - * - * Note: This is based on DASH-IF-IOP-v4.0 with some more freedom. - * @param {Array.} representations - * @param {string|null} adaptationMimeType - * @param {string|null} adaptationCodecs - * @param {Array.|null} adaptationRoles - * @returns {string} - "audio"|"video"|"text"|"image"|"metadata"|"unknown" - */ + return !! caught; + } -function inferAdaptationType(representations, adaptationMimeType, adaptationCodecs, adaptationRoles) { - function fromMimeType(mimeType, roles) { - var topLevel = mimeType.split("/")[0]; + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + var record = entry.completion; - if ((0,array_includes/* default */.Z)(KNOWN_ADAPTATION_TYPES, topLevel)) { - return topLevel; - } + if (entry.tryLoc === "root") { + // Exception thrown outside of any try block that could handle + // it, so set the completion value of the entire function to + // throw the exception. + return handle("end"); + } - if (mimeType === "application/bif") { - return "image"; - } + if (entry.tryLoc <= this.prev) { + var hasCatch = hasOwn.call(entry, "catchLoc"); + var hasFinally = hasOwn.call(entry, "finallyLoc"); - if (mimeType === "application/ttml+xml") { - return "text"; - } // manage DASH-IF mp4-embedded subtitles and metadata + if (hasCatch && hasFinally) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } else if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + } else if (hasCatch) { + if (this.prev < entry.catchLoc) { + return handle(entry.catchLoc, true); + } - if (mimeType === "application/mp4") { - if (roles != null) { - if ((0,array_find/* default */.Z)(roles, function (role) { - return role.schemeIdUri === "urn:mpeg:dash:role:2011" && (0,array_includes/* default */.Z)(SUPPORTED_TEXT_TYPES, role.value); - }) != null) { - return "text"; + } else if (hasFinally) { + if (this.prev < entry.finallyLoc) { + return handle(entry.finallyLoc); + } + + } else { + throw new Error("try statement without catch or finally"); + } } } + }, - return undefined; - } - } + abrupt: function(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; + } + } - function fromCodecs(codecs) { - switch (codecs.substring(0, 3)) { - case "avc": - case "hev": - case "hvc": - case "vp8": - case "vp9": - case "av1": - return "video"; + if (finallyEntry && + (type === "break" || + type === "continue") && + finallyEntry.tryLoc <= arg && + arg <= finallyEntry.finallyLoc) { + // Ignore the finally entry if control is not jumping to a + // location outside the try/catch block. + finallyEntry = null; + } - case "vtt": - return "text"; + var record = finallyEntry ? finallyEntry.completion : {}; + record.type = type; + record.arg = arg; - case "bif": - return "image"; - } + if (finallyEntry) { + this.method = "next"; + this.next = finallyEntry.finallyLoc; + return ContinueSentinel; + } - switch (codecs.substring(0, 4)) { - case "mp4a": - return "audio"; + return this.complete(record); + }, - case "wvtt": - case "stpp": - return "text"; - } - } + complete: function(record, afterLoc) { + if (record.type === "throw") { + throw record.arg; + } - if (adaptationMimeType !== null) { - var typeFromMimeType = fromMimeType(adaptationMimeType, adaptationRoles); + if (record.type === "break" || + record.type === "continue") { + this.next = record.arg; + } else if (record.type === "return") { + this.rval = this.arg = record.arg; + this.method = "return"; + this.next = "end"; + } else if (record.type === "normal" && afterLoc) { + this.next = afterLoc; + } - if (typeFromMimeType !== undefined) { - return typeFromMimeType; - } - } + return ContinueSentinel; + }, - if (adaptationCodecs !== null) { - var typeFromCodecs = fromCodecs(adaptationCodecs); + finish: function(finallyLoc) { + for (var i = this.tryEntries.length - 1; i >= 0; --i) { + var entry = this.tryEntries[i]; + if (entry.finallyLoc === finallyLoc) { + this.complete(entry.completion, entry.afterLoc); + resetTryEntry(entry); + return ContinueSentinel; + } + } + }, - if (typeFromCodecs !== undefined) { - return typeFromCodecs; - } - } + "catch": function(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 (record.type === "throw") { + var thrown = record.arg; + resetTryEntry(entry); + } + return thrown; + } + } - for (var i = 0; i < representations.length; i++) { - var representation = representations[i]; - var _representation$attri = representation.attributes, - mimeType = _representation$attri.mimeType, - codecs = _representation$attri.codecs; + // The context.catch method must only be called with a location + // argument that corresponds to a known catch block. + throw new Error("illegal catch attempt"); + }, - if (mimeType !== undefined) { - var _typeFromMimeType = fromMimeType(mimeType, adaptationRoles); + delegateYield: function(iterable, resultName, nextLoc) { + this.delegate = { + iterator: values(iterable), + resultName: resultName, + nextLoc: nextLoc + }; - if (_typeFromMimeType !== undefined) { - return _typeFromMimeType; + if (this.method === "next") { + // Deliberately forget the last sent value so that we don't + // accidentally pass it on to the delegate. + this.arg = undefined; } - } - - if (codecs !== undefined) { - var _typeFromCodecs = fromCodecs(codecs); - if (_typeFromCodecs !== undefined) { - return _typeFromCodecs; - } + return ContinueSentinel; } - } + }; - return undefined; -} -// EXTERNAL MODULE: ./src/parsers/manifest/utils/index_helpers.ts -var index_helpers = __webpack_require__(3911); -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/get_init_segment.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. - */ + // Regardless of whether this script is executing as a CommonJS module + // or not, return the runtime object so that we can declare the variable + // regeneratorRuntime in the outer scope, which allows this module to be + // injected easily by `bin/regenerator --include-runtime script.js`. + return exports; -/** - * Construct init segment for the given index. - * @param {Object} index - * @returns {Object} - */ -function get_init_segment_getInitSegment(index) { - var _a; +}( + // If this script is executing as a CommonJS module, use module.exports + // as the regeneratorRuntime namespace. Otherwise create a new empty + // object. Either way, the resulting object will be used to initialize + // the regeneratorRuntime variable at the top of this file. + true ? module.exports : 0 +)); - var initialization = index.initialization; - return { - id: "init", - isInit: true, - time: 0, - end: 0, - duration: 0, - timescale: 1, - range: initialization != null ? initialization.range : undefined, - indexRange: index.indexRange, - mediaURLs: (_a = initialization === null || initialization === void 0 ? void 0 : initialization.mediaURLs) !== null && _a !== void 0 ? _a : null, - timestampOffset: -(index.indexTimeOffset / index.timescale) - }; +try { + regeneratorRuntime = runtime; +} catch (accidentalStrictMode) { + // This module should not be running in strict mode, so the above + // assignment should always work unless something is misconfigured. Just + // in case runtime.js accidentally runs in strict mode, we can escape + // strict mode using a global Function call. This could conceivably fail + // if a Content Security Policy forbids using Function, but in that case + // the proper solution is to fix the accidental strict mode problem. If + // you've misconfigured your bundler to force strict mode and applied a + // CSP to forbid Function, and you're not willing to fix either of those + // problems, please detail your unique predicament in a GitHub issue. + Function("r", "regeneratorRuntime = r")(runtime); } -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/tokens.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. - */ - - -/** - * Pad with 0 in the left of the given n argument to reach l length - * @param {Number|string} n - * @param {Number} l - * @returns {string} - */ -function padLeftWithZeros(n, l) { - var nToString = n.toString(); - if (nToString.length >= l) { - return nToString; - } +/***/ }), - var arr = new Array(l + 1).join("0") + nToString; - return arr.slice(-l); -} -/** - * @param {string|number} replacer - * @returns {Function} - */ +/***/ 2632: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "P": () => (/* binding */ Notification) +/* harmony export */ }); +/* unused harmony export NotificationKind */ +/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5631); +/* harmony import */ var _observable_of__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8170); +/* harmony import */ var _observable_throwError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4944); +/** PURE_IMPORTS_START _observable_empty,_observable_of,_observable_throwError PURE_IMPORTS_END */ -function processFormatedToken(replacer) { - return function (_match, _format, widthStr) { - var width = (0,is_non_empty_string/* default */.Z)(widthStr) ? parseInt(widthStr, 10) : 1; - return padLeftWithZeros(String(replacer), width); - }; -} -/** - * @param {string} representationURL - * @param {string|undefined} media - * @param {string|undefined} id - * @param {number|undefined} bitrate - * @returns {string} - */ -function createIndexURLs(baseURLs, media, id, bitrate) { - if (baseURLs.length === 0) { - return media !== undefined ? [replaceRepresentationDASHTokens(media, id, bitrate)] : null; - } +var NotificationKind; +/*@__PURE__*/ (function (NotificationKind) { + NotificationKind["NEXT"] = "N"; + NotificationKind["ERROR"] = "E"; + NotificationKind["COMPLETE"] = "C"; +})(NotificationKind || (NotificationKind = {})); +var Notification = /*@__PURE__*/ (function () { + function Notification(kind, value, error) { + this.kind = kind; + this.value = value; + this.error = error; + this.hasValue = kind === 'N'; + } + Notification.prototype.observe = function (observer) { + switch (this.kind) { + case 'N': + return observer.next && observer.next(this.value); + case 'E': + return observer.error && observer.error(this.error); + case 'C': + return observer.complete && observer.complete(); + } + }; + Notification.prototype.do = function (next, error, complete) { + var kind = this.kind; + switch (kind) { + case 'N': + return next && next(this.value); + case 'E': + return error && error(this.error); + case 'C': + return complete && complete(); + } + }; + Notification.prototype.accept = function (nextOrObserver, error, complete) { + if (nextOrObserver && typeof nextOrObserver.next === 'function') { + return this.observe(nextOrObserver); + } + else { + return this.do(nextOrObserver, error, complete); + } + }; + Notification.prototype.toObservable = function () { + var kind = this.kind; + switch (kind) { + case 'N': + return (0,_observable_of__WEBPACK_IMPORTED_MODULE_0__.of)(this.value); + case 'E': + return (0,_observable_throwError__WEBPACK_IMPORTED_MODULE_1__/* .throwError */ ._)(this.error); + case 'C': + return (0,_observable_empty__WEBPACK_IMPORTED_MODULE_2__/* .empty */ .c)(); + } + throw new Error('unexpected notification kind value'); + }; + Notification.createNext = function (value) { + if (typeof value !== 'undefined') { + return new Notification('N', value); + } + return Notification.undefinedValueNotification; + }; + Notification.createError = function (err) { + return new Notification('E', undefined, err); + }; + Notification.createComplete = function () { + return Notification.completeNotification; + }; + Notification.completeNotification = new Notification('C'); + Notification.undefinedValueNotification = new Notification('N', undefined); + return Notification; +}()); - return baseURLs.map(function (baseURL) { - return replaceRepresentationDASHTokens((0,resolve_url/* default */.Z)(baseURL, media), id, bitrate); - }); -} -/** - * Replace "tokens" written in a given path (e.g. $RepresentationID$) by the corresponding - * infos, taken from the given segment. - * @param {string} path - * @param {string|undefined} id - * @param {number|undefined} bitrate - * @returns {string} - */ +//# sourceMappingURL=Notification.js.map -function replaceRepresentationDASHTokens(path, id, bitrate) { - if (path.indexOf("$") === -1) { - return path; - } else { - return path.replace(/\$\$/g, "$").replace(/\$RepresentationID\$/g, String(id)).replace(/\$Bandwidth(|\%0(\d+)d)\$/g, processFormatedToken(bitrate === undefined ? 0 : bitrate)); - } -} -/** - * Create function allowing to replace "tokens" in a given DASH segment URL - * (e.g. $Time$, which has to be replaced by the segment's start time) by the - * right information. - * @param {number|undefined} time - * @param {number|undefined} nb - * @returns {Function} - */ -function createDashUrlDetokenizer(time, nb) { - /** - * Replace the tokens in the given `url` by the segment information defined - * by the outer function. - * @param {string} url - * @returns {string} - * - * @throws Error - Throws if we do not have enough data to construct the URL - */ - return function replaceTokensInUrl(url) { - if (url.indexOf("$") === -1) { - return url; - } else { - return url.replace(/\$\$/g, "$").replace(/\$Number(|\%0(\d+)d)\$/g, function (_x, _y, widthStr) { - if (nb === undefined) { - throw new Error("Segment number not defined in a $Number$ scheme"); - } +/***/ }), - return processFormatedToken(nb)(_x, _y, widthStr); - }).replace(/\$Time(|\%0(\d+)d)\$/g, function (_x, _y, widthStr) { - if (time === undefined) { - throw new Error("Segment time not defined in a $Time$ scheme"); - } +/***/ 4379: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - return processFormatedToken(time)(_x, _y, widthStr); - }); - } - }; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/get_segments_from_timeline.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"; +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "y": () => (/* binding */ Observable) +}); -/** - * For the given start time and duration of a timeline element, calculate how - * much this element should be repeated to contain the time given. - * 0 being the same element, 1 being the next one etc. - * @param {Number} segmentStartTime - * @param {Number} segmentDuration - * @param {Number} wantedTime - * @returns {Number} - */ +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscriber.js +var Subscriber = __webpack_require__(979); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/canReportError.js +/** PURE_IMPORTS_START _Subscriber PURE_IMPORTS_END */ -function getWantedRepeatIndex(segmentStartTime, segmentDuration, wantedTime) { - var diff = wantedTime - segmentStartTime; - return diff > 0 ? Math.floor(diff / segmentDuration) : 0; +function canReportError(observer) { + while (observer) { + var _a = observer, closed_1 = _a.closed, destination = _a.destination, isStopped = _a.isStopped; + if (closed_1 || isStopped) { + return false; + } + else if (destination && destination instanceof Subscriber/* Subscriber */.L) { + observer = destination; + } + else { + observer = null; + } + } + return true; } -/** - * Get a list of Segments for the time range wanted. - * @param {Object} index - index object, constructed by parsing the manifest. - * @param {number} from - starting timestamp wanted, in seconds - * @param {number} durationWanted - duration wanted, in seconds - * @param {number|undefined} maximumTime - * @returns {Array.} - */ +//# sourceMappingURL=canReportError.js.map +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/symbol/rxSubscriber.js +var rxSubscriber = __webpack_require__(3142); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observer.js +var Observer = __webpack_require__(2174); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/toSubscriber.js +/** PURE_IMPORTS_START _Subscriber,_symbol_rxSubscriber,_Observer PURE_IMPORTS_END */ -function getSegmentsFromTimeline(index, from, durationWanted, maximumTime) { - var scaledUp = (0,index_helpers/* toIndexTime */.gT)(from, index); - var scaledTo = (0,index_helpers/* toIndexTime */.gT)(from + durationWanted, index); - var timeline = index.timeline, - timescale = index.timescale, - mediaURLs = index.mediaURLs, - startNumber = index.startNumber; - var currentNumber = startNumber != null ? startNumber : undefined; - var segments = []; - var timelineLength = timeline.length; // TODO(pierre): use @maxSegmentDuration if possible - var maxEncounteredDuration = timeline.length > 0 && timeline[0].duration != null ? timeline[0].duration : 0; - for (var i = 0; i < timelineLength; i++) { - var timelineItem = timeline[i]; - var duration = timelineItem.duration, - start = timelineItem.start, - range = timelineItem.range; - maxEncounteredDuration = Math.max(maxEncounteredDuration, duration); - var repeat = (0,index_helpers/* calculateRepeat */.KF)(timelineItem, timeline[i + 1], maximumTime); - var segmentNumberInCurrentRange = getWantedRepeatIndex(start, duration, scaledUp); - var segmentTime = start + segmentNumberInCurrentRange * duration; +function toSubscriber(nextOrObserver, error, complete) { + if (nextOrObserver) { + if (nextOrObserver instanceof Subscriber/* Subscriber */.L) { + return nextOrObserver; + } + if (nextOrObserver[rxSubscriber/* rxSubscriber */.b]) { + return nextOrObserver[rxSubscriber/* rxSubscriber */.b](); + } + } + if (!nextOrObserver && !error && !complete) { + return new Subscriber/* Subscriber */.L(Observer/* empty */.c); + } + return new Subscriber/* Subscriber */.L(nextOrObserver, error, complete); +} +//# sourceMappingURL=toSubscriber.js.map - while (segmentTime < scaledTo && segmentNumberInCurrentRange <= repeat) { - var segmentNumber = currentNumber != null ? currentNumber + segmentNumberInCurrentRange : undefined; - var detokenizedURLs = mediaURLs === null ? null : mediaURLs.map(createDashUrlDetokenizer(segmentTime, segmentNumber)); - var time = segmentTime - index.indexTimeOffset; - var segment = { - id: String(segmentTime), - time: time / timescale, - end: (time + duration) / timescale, - duration: duration / timescale, - isInit: false, - range: range, - timescale: 1, - mediaURLs: detokenizedURLs, - number: segmentNumber, - timestampOffset: -(index.indexTimeOffset / timescale) - }; - segments.push(segment); // update segment number and segment time for the next segment +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/symbol/observable.js +var observable = __webpack_require__(5050); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/identity.js +var identity = __webpack_require__(3608); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/pipe.js +/** PURE_IMPORTS_START _identity PURE_IMPORTS_END */ - segmentNumberInCurrentRange++; - segmentTime = start + segmentNumberInCurrentRange * duration; +function pipe() { + var fns = []; + for (var _i = 0; _i < arguments.length; _i++) { + fns[_i] = arguments[_i]; } - - if (segmentTime >= scaledTo) { - // we reached ``scaledTo``, we're done - return segments; + return pipeFromArray(fns); +} +function pipeFromArray(fns) { + if (fns.length === 0) { + return identity/* identity */.y; } - - if (currentNumber != null) { - currentNumber += repeat + 1; + if (fns.length === 1) { + return fns[0]; } - } - - return segments; + return function piped(input) { + return fns.reduce(function (prev, fn) { return fn(prev); }, input); + }; } -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/base.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. - */ - - - - +//# sourceMappingURL=pipe.js.map -/** - * Add a new segment to the index. - * - * /!\ Mutate the given index - * @param {Object} index - * @param {Object} segmentInfos - * @returns {Boolean} - true if the segment has been added - */ +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/config.js +var config = __webpack_require__(150); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js +/** PURE_IMPORTS_START _util_canReportError,_util_toSubscriber,_symbol_observable,_util_pipe,_config PURE_IMPORTS_END */ -function _addSegmentInfos(index, segmentInfos) { - if (segmentInfos.timescale !== index.timescale) { - var timescale = index.timescale; - index.timeline.push({ - start: segmentInfos.time / segmentInfos.timescale * timescale, - duration: segmentInfos.duration / segmentInfos.timescale * timescale, - repeatCount: segmentInfos.count === undefined ? 0 : segmentInfos.count, - range: segmentInfos.range - }); - } else { - index.timeline.push({ - start: segmentInfos.time, - duration: segmentInfos.duration, - repeatCount: segmentInfos.count === undefined ? 0 : segmentInfos.count, - range: segmentInfos.range - }); - } - return true; -} -var BaseRepresentationIndex = /*#__PURE__*/function () { - /** - * @param {Object} index - * @param {Object} context - */ - function BaseRepresentationIndex(index, context) { - var _a, _b; - var periodStart = context.periodStart, - periodEnd = context.periodEnd, - representationBaseURLs = context.representationBaseURLs, - representationId = context.representationId, - representationBitrate = context.representationBitrate; - var timescale = (_a = index.timescale) !== null && _a !== void 0 ? _a : 1; - var presentationTimeOffset = index.presentationTimeOffset != null ? index.presentationTimeOffset : 0; - var indexTimeOffset = presentationTimeOffset - periodStart * timescale; - var mediaURLs = createIndexURLs(representationBaseURLs, index.initialization !== undefined ? index.initialization.media : undefined, representationId, representationBitrate); // TODO If indexRange is either undefined or behind the initialization segment - // the following logic will not work. - // However taking the nth first bytes like `dash.js` does (where n = 1500) is - // not straightforward as we would need to clean-up the segment after that. - // The following logic corresponds to 100% of tested cases, so good enough for - // now. - var range = index.initialization !== undefined ? index.initialization.range : index.indexRange !== undefined ? [0, index.indexRange[0] - 1] : undefined; - this._index = { - indexRange: index.indexRange, - indexTimeOffset: indexTimeOffset, - initialization: { - mediaURLs: mediaURLs, - range: range - }, - mediaURLs: createIndexURLs(representationBaseURLs, index.media, representationId, representationBitrate), - startNumber: index.startNumber, - timeline: (_b = index.timeline) !== null && _b !== void 0 ? _b : [], - timescale: timescale +var Observable = /*@__PURE__*/ (function () { + function Observable(subscribe) { + this._isScalar = false; + if (subscribe) { + this._subscribe = subscribe; + } + } + Observable.prototype.lift = function (operator) { + var observable = new Observable(); + observable.source = this; + observable.operator = operator; + return observable; }; - this._scaledPeriodEnd = periodEnd == null ? undefined : (0,index_helpers/* toIndexTime */.gT)(periodEnd, this._index); - this._isInitialized = this._index.timeline.length > 0; - } - /** - * Construct init Segment. - * @returns {Object} - */ - - - var _proto = BaseRepresentationIndex.prototype; - - _proto.getInitSegment = function getInitSegment() { - return get_init_segment_getInitSegment(this._index); - } - /** - * @param {Number} _up - * @param {Number} _to - * @returns {Array.} - */ - ; + Observable.prototype.subscribe = function (observerOrNext, error, complete) { + var operator = this.operator; + var sink = toSubscriber(observerOrNext, error, complete); + if (operator) { + sink.add(operator.call(sink, this.source)); + } + else { + sink.add(this.source || (config/* config.useDeprecatedSynchronousErrorHandling */.v.useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ? + this._subscribe(sink) : + this._trySubscribe(sink)); + } + if (config/* config.useDeprecatedSynchronousErrorHandling */.v.useDeprecatedSynchronousErrorHandling) { + if (sink.syncErrorThrowable) { + sink.syncErrorThrowable = false; + if (sink.syncErrorThrown) { + throw sink.syncErrorValue; + } + } + } + return sink; + }; + Observable.prototype._trySubscribe = function (sink) { + try { + return this._subscribe(sink); + } + catch (err) { + if (config/* config.useDeprecatedSynchronousErrorHandling */.v.useDeprecatedSynchronousErrorHandling) { + sink.syncErrorThrown = true; + sink.syncErrorValue = err; + } + if (canReportError(sink)) { + sink.error(err); + } + else { + console.warn(err); + } + } + }; + Observable.prototype.forEach = function (next, promiseCtor) { + var _this = this; + promiseCtor = getPromiseCtor(promiseCtor); + return new promiseCtor(function (resolve, reject) { + var subscription; + subscription = _this.subscribe(function (value) { + try { + next(value); + } + catch (err) { + reject(err); + if (subscription) { + subscription.unsubscribe(); + } + } + }, reject, resolve); + }); + }; + Observable.prototype._subscribe = function (subscriber) { + var source = this.source; + return source && source.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]; + } + if (operations.length === 0) { + return this; + } + 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); }); + }); + }; + Observable.create = function (subscribe) { + return new Observable(subscribe); + }; + return Observable; +}()); - _proto.getSegments = function getSegments(_up, _to) { - return getSegmentsFromTimeline(this._index, _up, _to, this._scaledPeriodEnd); - } - /** - * Returns false as no Segment-Base based index should need to be refreshed. - * @returns {Boolean} - */ - ; +function getPromiseCtor(promiseCtor) { + if (!promiseCtor) { + promiseCtor = config/* config.Promise */.v.Promise || Promise; + } + if (!promiseCtor) { + throw new Error('no Promise impl found'); + } + return promiseCtor; +} +//# sourceMappingURL=Observable.js.map - _proto.shouldRefresh = function shouldRefresh() { - return false; - } - /** - * Returns first position in index. - * @returns {Number|null} - */ - ; - _proto.getFirstPosition = function getFirstPosition() { - var index = this._index; +/***/ }), - if (index.timeline.length === 0) { - return null; - } +/***/ 2174: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - return (0,index_helpers/* fromIndexTime */.zG)(index.timeline[0].start, index); - } - /** - * Returns last position in index. - * @returns {Number|null} - */ - ; +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "c": () => (/* binding */ empty) +/* harmony export */ }); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(150); +/* harmony import */ var _util_hostReportError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1644); +/** PURE_IMPORTS_START _config,_util_hostReportError PURE_IMPORTS_END */ - _proto.getLastPosition = function getLastPosition() { - var timeline = this._index.timeline; - if (timeline.length === 0) { - return null; - } +var empty = { + closed: true, + next: function (value) { }, + error: function (err) { + if (_config__WEBPACK_IMPORTED_MODULE_0__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling) { + throw err; + } + else { + (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_1__/* .hostReportError */ .z)(err); + } + }, + complete: function () { } +}; +//# sourceMappingURL=Observer.js.map - var lastTimelineElement = timeline[timeline.length - 1]; - var lastTime = (0,index_helpers/* getIndexSegmentEnd */.jH)(lastTimelineElement, null, this._scaledPeriodEnd); - return (0,index_helpers/* fromIndexTime */.zG)(lastTime, this._index); - } - /** - * Segments in a segmentBase scheme should stay available. - * @returns {Boolean|undefined} - */ - ; - _proto.isSegmentStillAvailable = function isSegmentStillAvailable() { - return true; - } - /** - * We do not check for discontinuity in SegmentBase-based indexes. - * @returns {null} - */ - ; +/***/ }), - _proto.checkDiscontinuity = function checkDiscontinuity() { - return null; - } - /** - * @returns {boolean} - */ - ; +/***/ 2039: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - _proto.areSegmentsChronologicallyGenerated = function areSegmentsChronologicallyGenerated() { - return true; - } - /** - * @param {Array.} nextSegments - * @returns {Array.} - */ - ; +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "L": () => (/* binding */ OuterSubscriber) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ - _proto._addSegments = function _addSegments(nextSegments) { - for (var i = 0; i < nextSegments.length; i++) { - _addSegmentInfos(this._index, nextSegments[i]); - } - if (!this._isInitialized && this._index.timeline.length > 0) { - this._isInitialized = true; +var OuterSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(OuterSubscriber, _super); + function OuterSubscriber() { + return _super !== null && _super.apply(this, arguments) || this; } - } - /** - * Returns true as SegmentBase does not get updated. - * @returns {Boolean} - */ - ; + OuterSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + this.destination.next(innerValue); + }; + OuterSubscriber.prototype.notifyError = function (error, innerSub) { + this.destination.error(error); + }; + OuterSubscriber.prototype.notifyComplete = function (innerSub) { + this.destination.complete(); + }; + return OuterSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); - _proto.canBeOutOfSyncError = function canBeOutOfSyncError() { - return false; - } - /** - * Returns true as SegmentBase does not get updated. - * @returns {Boolean} - */ - ; +//# sourceMappingURL=OuterSubscriber.js.map - _proto.isFinished = function isFinished() { - return true; - } - /** - * @returns {Boolean} - */ - ; - _proto.isInitialized = function isInitialized() { - return this._isInitialized; - } - /** - * @param {Object} newIndex - */ - ; +/***/ }), - _proto._replace = function _replace(newIndex) { - this._index = newIndex._index; - }; +/***/ 2135: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - _proto._update = function _update() { - log/* default.error */.Z.error("Base RepresentationIndex: Cannot update a SegmentList"); - }; +"use strict"; - return BaseRepresentationIndex; -}(); +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "t": () => (/* binding */ ReplaySubject) +}); +// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js +var tslib_es6 = __webpack_require__(655); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subject.js +var Subject = __webpack_require__(211); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsyncAction.js + 1 modules +var AsyncAction = __webpack_require__(6114); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/QueueAction.js +/** PURE_IMPORTS_START tslib,_AsyncAction PURE_IMPORTS_END */ -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/list.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 QueueAction = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(QueueAction, _super); + function QueueAction(scheduler, work) { + var _this = _super.call(this, scheduler, work) || this; + _this.scheduler = scheduler; + _this.work = work; + return _this; + } + QueueAction.prototype.schedule = function (state, delay) { + if (delay === void 0) { + delay = 0; + } + if (delay > 0) { + return _super.prototype.schedule.call(this, state, delay); + } + this.delay = delay; + this.state = state; + this.scheduler.flush(this); + return this; + }; + QueueAction.prototype.execute = function (state, delay) { + return (delay > 0 || this.closed) ? + _super.prototype.execute.call(this, state, delay) : + this._execute(state, delay); + }; + QueueAction.prototype.requestAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + if ((delay !== null && delay > 0) || (delay === null && this.delay > 0)) { + return _super.prototype.requestAsyncId.call(this, scheduler, id, delay); + } + return scheduler.flush(this); + }; + return QueueAction; +}(AsyncAction/* AsyncAction */.o)); +//# sourceMappingURL=QueueAction.js.map +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsyncScheduler.js + 1 modules +var AsyncScheduler = __webpack_require__(2980); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/QueueScheduler.js +/** PURE_IMPORTS_START tslib,_AsyncScheduler PURE_IMPORTS_END */ -var ListRepresentationIndex = /*#__PURE__*/function () { - /** - * @param {Object} index - * @param {Object} context - */ - function ListRepresentationIndex(index, context) { - var _a; +var QueueScheduler = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(QueueScheduler, _super); + function QueueScheduler() { + return _super !== null && _super.apply(this, arguments) || this; + } + return QueueScheduler; +}(AsyncScheduler/* AsyncScheduler */.v)); - var periodStart = context.periodStart, - representationBaseURLs = context.representationBaseURLs, - representationId = context.representationId, - representationBitrate = context.representationBitrate; - this._periodStart = periodStart; - var presentationTimeOffset = index.presentationTimeOffset != null ? index.presentationTimeOffset : 0; - var timescale = (_a = index.timescale) !== null && _a !== void 0 ? _a : 1; - var indexTimeOffset = presentationTimeOffset - periodStart * timescale; - var list = index.list.map(function (lItem) { - return { - mediaURLs: createIndexURLs(representationBaseURLs, lItem.media, representationId, representationBitrate), - mediaRange: lItem.mediaRange - }; - }); - this._index = { - list: list, - timescale: timescale, - duration: index.duration, - indexTimeOffset: indexTimeOffset, - indexRange: index.indexRange, - initialization: index.initialization == null ? undefined : { - mediaURLs: createIndexURLs(representationBaseURLs, index.initialization.media, representationId, representationBitrate), - range: index.initialization.range - } - }; - } - /** - * Construct init Segment. - * @returns {Object} - */ +//# sourceMappingURL=QueueScheduler.js.map +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/queue.js +/** PURE_IMPORTS_START _QueueAction,_QueueScheduler PURE_IMPORTS_END */ - var _proto = ListRepresentationIndex.prototype; - _proto.getInitSegment = function getInitSegment() { - return get_init_segment_getInitSegment(this._index); - } - /** - * @param {Number} fromTime - * @param {Number} duration - * @returns {Array.} - */ - ; +var queueScheduler = /*@__PURE__*/ new QueueScheduler(QueueAction); +var queue = queueScheduler; +//# sourceMappingURL=queue.js.map - _proto.getSegments = function getSegments(fromTime, dur) { - var index = this._index; - var duration = index.duration, - list = index.list, - timescale = index.timescale; - var durationInSeconds = duration / timescale; - var fromTimeInPeriod = fromTime - this._periodStart; +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscription.js + 1 modules +var Subscription = __webpack_require__(3884); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscriber.js +var Subscriber = __webpack_require__(979); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Notification.js +var Notification = __webpack_require__(2632); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/observeOn.js +/** PURE_IMPORTS_START tslib,_Subscriber,_Notification PURE_IMPORTS_END */ - var _getTimescaledRange = (0,index_helpers/* getTimescaledRange */.PZ)(fromTimeInPeriod, dur, timescale), - up = _getTimescaledRange[0], - to = _getTimescaledRange[1]; - var length = Math.min(list.length - 1, Math.floor(to / duration)); - var segments = []; - var i = Math.floor(up / duration); - while (i <= length) { - var range = list[i].mediaRange; - var mediaURLs = list[i].mediaURLs; - var time = i * durationInSeconds + this._periodStart; - var args = { - id: String(i), - time: time, - isInit: false, - range: range, - duration: durationInSeconds, - timescale: 1, - end: time + durationInSeconds, - mediaURLs: mediaURLs, - timestampOffset: -(index.indexTimeOffset / timescale) - }; - segments.push(args); - i++; +function observeOn(scheduler, delay) { + if (delay === void 0) { + delay = 0; + } + return function observeOnOperatorFunction(source) { + return source.lift(new ObserveOnOperator(scheduler, delay)); + }; +} +var ObserveOnOperator = /*@__PURE__*/ ((/* unused pure expression or super */ null && (function () { + function ObserveOnOperator(scheduler, delay) { + if (delay === void 0) { + delay = 0; + } + this.scheduler = scheduler; + this.delay = delay; } + ObserveOnOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ObserveOnSubscriber(subscriber, this.scheduler, this.delay)); + }; + return ObserveOnOperator; +}()))); - return segments; - } - /** - * Returns true if, based on the arguments, the index should be refreshed. - * (If we should re-fetch the manifest) - * @param {Number} _fromTime - * @param {Number} toTime - * @returns {Boolean} - */ - ; +var ObserveOnSubscriber = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(ObserveOnSubscriber, _super); + function ObserveOnSubscriber(destination, scheduler, delay) { + if (delay === void 0) { + delay = 0; + } + var _this = _super.call(this, destination) || this; + _this.scheduler = scheduler; + _this.delay = delay; + return _this; + } + ObserveOnSubscriber.dispatch = function (arg) { + var notification = arg.notification, destination = arg.destination; + notification.observe(destination); + this.unsubscribe(); + }; + ObserveOnSubscriber.prototype.scheduleMessage = function (notification) { + var destination = this.destination; + destination.add(this.scheduler.schedule(ObserveOnSubscriber.dispatch, this.delay, new ObserveOnMessage(notification, this.destination))); + }; + ObserveOnSubscriber.prototype._next = function (value) { + this.scheduleMessage(Notification/* Notification.createNext */.P.createNext(value)); + }; + ObserveOnSubscriber.prototype._error = function (err) { + this.scheduleMessage(Notification/* Notification.createError */.P.createError(err)); + this.unsubscribe(); + }; + ObserveOnSubscriber.prototype._complete = function () { + this.scheduleMessage(Notification/* Notification.createComplete */.P.createComplete()); + this.unsubscribe(); + }; + return ObserveOnSubscriber; +}(Subscriber/* Subscriber */.L)); - _proto.shouldRefresh = function shouldRefresh(_fromTime, toTime) { - var _this$_index = this._index, - timescale = _this$_index.timescale, - duration = _this$_index.duration, - list = _this$_index.list; - var scaledTo = toTime * timescale; - var i = Math.floor(scaledTo / duration); - return i < 0 || i >= list.length; - } - /** - * Returns first position in this index, in seconds. - * @returns {Number} - */ - ; +var ObserveOnMessage = /*@__PURE__*/ (function () { + function ObserveOnMessage(notification, destination) { + this.notification = notification; + this.destination = destination; + } + return ObserveOnMessage; +}()); - _proto.getFirstPosition = function getFirstPosition() { - return this._periodStart; - } - /** - * Returns last position in this index, in seconds. - * @returns {Number} - */ - ; - - _proto.getLastPosition = function getLastPosition() { - var index = this._index; - var duration = index.duration, - list = index.list; - return list.length * duration / index.timescale + this._periodStart; - } - /** - * Returns true if a Segment returned by this index is still considered - * available. - * @param {Object} segment - * @returns {Boolean} - */ - ; - - _proto.isSegmentStillAvailable = function isSegmentStillAvailable() { - return true; - } - /** - * We do not check for discontinuity in SegmentList-based indexes. - * @returns {null} - */ - ; +//# sourceMappingURL=observeOn.js.map - _proto.checkDiscontinuity = function checkDiscontinuity() { - return null; - } - /** - * @returns {boolean} - */ - ; +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/ObjectUnsubscribedError.js +var ObjectUnsubscribedError = __webpack_require__(1016); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/SubjectSubscription.js +var SubjectSubscription = __webpack_require__(8253); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/ReplaySubject.js +/** PURE_IMPORTS_START tslib,_Subject,_scheduler_queue,_Subscription,_operators_observeOn,_util_ObjectUnsubscribedError,_SubjectSubscription PURE_IMPORTS_END */ - _proto.areSegmentsChronologicallyGenerated = function areSegmentsChronologicallyGenerated() { - return true; - } - /** - * SegmentList should not be updated. - * @returns {Boolean} - */ - ; - _proto.canBeOutOfSyncError = function canBeOutOfSyncError() { - return false; - } - /** - * @returns {Boolean} - */ - ; - _proto.isFinished = function isFinished() { - return true; - } - /** - * @returns {Boolean} - */ - ; - _proto.isInitialized = function isInitialized() { - return true; - } - /** - * @param {Object} newIndex - */ - ; - _proto._replace = function _replace(newIndex) { - this._index = newIndex._index; - } - /** - * @param {Object} newIndex - */ - ; - _proto._update = function _update() { - log/* default.error */.Z.error("List RepresentationIndex: Cannot update a SegmentList"); - }; - return ListRepresentationIndex; -}(); +var ReplaySubject = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(ReplaySubject, _super); + function ReplaySubject(bufferSize, windowTime, scheduler) { + if (bufferSize === void 0) { + bufferSize = Number.POSITIVE_INFINITY; + } + if (windowTime === void 0) { + windowTime = Number.POSITIVE_INFINITY; + } + var _this = _super.call(this) || this; + _this.scheduler = scheduler; + _this._events = []; + _this._infiniteTimeWindow = false; + _this._bufferSize = bufferSize < 1 ? 1 : bufferSize; + _this._windowTime = windowTime < 1 ? 1 : windowTime; + if (windowTime === Number.POSITIVE_INFINITY) { + _this._infiniteTimeWindow = true; + _this.next = _this.nextInfiniteTimeWindow; + } + else { + _this.next = _this.nextTimeWindow; + } + return _this; + } + ReplaySubject.prototype.nextInfiniteTimeWindow = function (value) { + if (!this.isStopped) { + var _events = this._events; + _events.push(value); + if (_events.length > this._bufferSize) { + _events.shift(); + } + } + _super.prototype.next.call(this, value); + }; + ReplaySubject.prototype.nextTimeWindow = function (value) { + if (!this.isStopped) { + this._events.push(new ReplayEvent(this._getNow(), value)); + this._trimBufferThenGetEvents(); + } + _super.prototype.next.call(this, value); + }; + ReplaySubject.prototype._subscribe = function (subscriber) { + var _infiniteTimeWindow = this._infiniteTimeWindow; + var _events = _infiniteTimeWindow ? this._events : this._trimBufferThenGetEvents(); + var scheduler = this.scheduler; + var len = _events.length; + var subscription; + if (this.closed) { + throw new ObjectUnsubscribedError/* ObjectUnsubscribedError */.N(); + } + else if (this.isStopped || this.hasError) { + subscription = Subscription/* Subscription.EMPTY */.w.EMPTY; + } + else { + this.observers.push(subscriber); + subscription = new SubjectSubscription/* SubjectSubscription */.W(this, subscriber); + } + if (scheduler) { + subscriber.add(subscriber = new ObserveOnSubscriber(subscriber, scheduler)); + } + if (_infiniteTimeWindow) { + for (var i = 0; i < len && !subscriber.closed; i++) { + subscriber.next(_events[i]); + } + } + else { + for (var i = 0; i < len && !subscriber.closed; i++) { + subscriber.next(_events[i].value); + } + } + if (this.hasError) { + subscriber.error(this.thrownError); + } + else if (this.isStopped) { + subscriber.complete(); + } + return subscription; + }; + ReplaySubject.prototype._getNow = function () { + return (this.scheduler || queue).now(); + }; + ReplaySubject.prototype._trimBufferThenGetEvents = function () { + var now = this._getNow(); + var _bufferSize = this._bufferSize; + var _windowTime = this._windowTime; + var _events = this._events; + var eventsCount = _events.length; + var spliceCount = 0; + while (spliceCount < eventsCount) { + if ((now - _events[spliceCount].time) < _windowTime) { + break; + } + spliceCount++; + } + if (eventsCount > _bufferSize) { + spliceCount = Math.max(spliceCount, eventsCount - _bufferSize); + } + if (spliceCount > 0) { + _events.splice(0, spliceCount); + } + return _events; + }; + return ReplaySubject; +}(Subject/* Subject */.xQ)); +var ReplayEvent = /*@__PURE__*/ (function () { + function ReplayEvent(time, value) { + this.time = time; + this.value = value; + } + return ReplayEvent; +}()); +//# sourceMappingURL=ReplaySubject.js.map -// EXTERNAL MODULE: ./src/errors/network_error.ts -var network_error = __webpack_require__(9362); -// EXTERNAL MODULE: ./src/parsers/manifest/utils/clear_timeline_from_position.ts -var clear_timeline_from_position = __webpack_require__(8232); -// EXTERNAL MODULE: ./src/parsers/manifest/utils/is_segment_still_available.ts -var is_segment_still_available = __webpack_require__(1091); -// EXTERNAL MODULE: ./src/parsers/manifest/utils/update_segment_timeline.ts -var update_segment_timeline = __webpack_require__(5505); -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/convert_element_to_index_segment.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. - */ -/** - * Translate parsed `S` node into Segment compatible with this index: - * Find out the start, repeatCount and duration of each of these. - * - * @param {Object} item - parsed `S` node - * @param {Object|null} previousItem - the previously parsed Segment (related - * to the `S` node coming just before). If `null`, we're talking about the first - * segment. - * @param {Object|null} nextItem - the `S` node coming next. If `null`, we're - * talking about the last segment. - * @param {number} timelineStart - Absolute start for the timeline. In the same - * timescale than the given `S` nodes. - * @returns {Object|null} - */ +/***/ }), -function convertElementsToIndexSegment(item, previousItem, nextItem, timelineStart) { - var start = item.start; - var duration = item.duration; - var repeatCount = item.repeatCount; +/***/ 211: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - if (start == null) { - if (previousItem == null) { - start = timelineStart; - } else if (previousItem.duration != null) { - start = previousItem.start + previousItem.duration * (previousItem.repeatCount + 1); - } - } +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Yc": () => (/* binding */ SubjectSubscriber), +/* harmony export */ "xQ": () => (/* binding */ Subject) +/* harmony export */ }); +/* unused harmony export AnonymousSubject */ +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(4379); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3884); +/* harmony import */ var _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1016); +/* harmony import */ var _SubjectSubscription__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8253); +/* harmony import */ var _internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3142); +/** PURE_IMPORTS_START tslib,_Observable,_Subscriber,_Subscription,_util_ObjectUnsubscribedError,_SubjectSubscription,_internal_symbol_rxSubscriber PURE_IMPORTS_END */ - if ((duration == null || isNaN(duration)) && nextItem != null && nextItem.start != null && !isNaN(nextItem.start) && start != null && !isNaN(start)) { - duration = nextItem.start - start; - } - if (start != null && !isNaN(start) && duration != null && !isNaN(duration) && (repeatCount == null || !isNaN(repeatCount))) { - return { - start: start, - duration: duration, - repeatCount: repeatCount === undefined ? 0 : repeatCount - }; - } - log/* default.warn */.Z.warn("DASH: A \"S\" Element could not have been parsed."); - return null; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/parse_s_element.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. - */ -/** - * Parse a given element in the MPD into a JS Object. - * @param {Element} root - * @returns {Object} - */ -function parseSElement(root) { - var parsedS = {}; - for (var j = 0; j < root.attributes.length; j++) { - var attribute = root.attributes[j]; - switch (attribute.name) { - case "t": - var start = parseInt(attribute.value, 10); +var SubjectSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(SubjectSubscriber, _super); + function SubjectSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.destination = destination; + return _this; + } + return SubjectSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); - if (isNaN(start)) { - log/* default.warn */.Z.warn("DASH: invalid t (\"" + attribute.value + "\")"); - } else { - parsedS.start = start; +var Subject = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(Subject, _super); + function Subject() { + var _this = _super.call(this) || this; + _this.observers = []; + _this.closed = false; + _this.isStopped = false; + _this.hasError = false; + _this.thrownError = null; + return _this; + } + Subject.prototype[_internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_2__/* .rxSubscriber */ .b] = function () { + return new SubjectSubscriber(this); + }; + Subject.prototype.lift = function (operator) { + var subject = new AnonymousSubject(this, this); + subject.operator = operator; + return subject; + }; + Subject.prototype.next = function (value) { + if (this.closed) { + throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__/* .ObjectUnsubscribedError */ .N(); } - - break; - - case "d": - var duration = parseInt(attribute.value, 10); - - if (isNaN(duration)) { - log/* default.warn */.Z.warn("DASH: invalid d (\"" + attribute.value + "\")"); - } else { - parsedS.duration = duration; + if (!this.isStopped) { + var observers = this.observers; + var len = observers.length; + var copy = observers.slice(); + for (var i = 0; i < len; i++) { + copy[i].next(value); + } } - - break; - - case "r": - var repeatCount = parseInt(attribute.value, 10); - - if (isNaN(repeatCount)) { - log/* default.warn */.Z.warn("DASH: invalid r (\"" + attribute.value + "\")"); - } else { - parsedS.repeatCount = repeatCount; + }; + Subject.prototype.error = function (err) { + if (this.closed) { + throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__/* .ObjectUnsubscribedError */ .N(); + } + this.hasError = true; + this.thrownError = err; + this.isStopped = true; + var observers = this.observers; + var len = observers.length; + var copy = observers.slice(); + for (var i = 0; i < len; i++) { + copy[i].error(err); + } + this.observers.length = 0; + }; + Subject.prototype.complete = function () { + if (this.closed) { + throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__/* .ObjectUnsubscribedError */ .N(); + } + this.isStopped = true; + var observers = this.observers; + var len = observers.length; + var copy = observers.slice(); + for (var i = 0; i < len; i++) { + copy[i].complete(); } + this.observers.length = 0; + }; + Subject.prototype.unsubscribe = function () { + this.isStopped = true; + this.closed = true; + this.observers = null; + }; + Subject.prototype._trySubscribe = function (subscriber) { + if (this.closed) { + throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__/* .ObjectUnsubscribedError */ .N(); + } + else { + return _super.prototype._trySubscribe.call(this, subscriber); + } + }; + Subject.prototype._subscribe = function (subscriber) { + if (this.closed) { + throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__/* .ObjectUnsubscribedError */ .N(); + } + else if (this.hasError) { + subscriber.error(this.thrownError); + return _Subscription__WEBPACK_IMPORTED_MODULE_4__/* .Subscription.EMPTY */ .w.EMPTY; + } + else if (this.isStopped) { + subscriber.complete(); + return _Subscription__WEBPACK_IMPORTED_MODULE_4__/* .Subscription.EMPTY */ .w.EMPTY; + } + else { + this.observers.push(subscriber); + return new _SubjectSubscription__WEBPACK_IMPORTED_MODULE_5__/* .SubjectSubscription */ .W(this, subscriber); + } + }; + Subject.prototype.asObservable = function () { + var observable = new _Observable__WEBPACK_IMPORTED_MODULE_6__/* .Observable */ .y(); + observable.source = this; + return observable; + }; + Subject.create = function (destination, source) { + return new AnonymousSubject(destination, source); + }; + return Subject; +}(_Observable__WEBPACK_IMPORTED_MODULE_6__/* .Observable */ .y)); - break; +var AnonymousSubject = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__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 destination = this.destination; + if (destination && destination.next) { + destination.next(value); + } + }; + AnonymousSubject.prototype.error = function (err) { + var destination = this.destination; + if (destination && destination.error) { + this.destination.error(err); + } + }; + AnonymousSubject.prototype.complete = function () { + var destination = this.destination; + if (destination && destination.complete) { + this.destination.complete(); + } + }; + AnonymousSubject.prototype._subscribe = function (subscriber) { + var source = this.source; + if (source) { + return this.source.subscribe(subscriber); + } + else { + return _Subscription__WEBPACK_IMPORTED_MODULE_4__/* .Subscription.EMPTY */ .w.EMPTY; + } + }; + return AnonymousSubject; +}(Subject)); - return parsedS; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/construct_timeline_from_elements.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. - */ +//# sourceMappingURL=Subject.js.map -/** - * Allows to generate the "timeline" for the "Timeline" RepresentationIndex. - * Call this function when the timeline is unknown. - * This function was added to only perform that task lazily, i.e. only when - * first needed. - * @param {HTMLCollection} elements - All S nodes constituting the corresponding - * SegmentTimeline node. - * @param {number} scaledPeriodStart - Absolute start of the concerned Period, - * in the same scale than the segments found in `elements`. - * @returns {Array.} - */ +/***/ }), -function constructTimelineFromElements(elements, scaledPeriodStart) { - var initialTimeline = []; +/***/ 8253: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - for (var i = 0; i < elements.length; i++) { - initialTimeline.push(parseSElement(elements[i])); - } +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "W": () => (/* binding */ SubjectSubscription) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3884); +/** PURE_IMPORTS_START tslib,_Subscription PURE_IMPORTS_END */ - var timeline = []; - for (var _i = 0; _i < initialTimeline.length; _i++) { - var item = initialTimeline[_i]; - var previousItem = timeline[timeline.length - 1] === undefined ? null : timeline[timeline.length - 1]; - var nextItem = initialTimeline[_i + 1] === undefined ? null : initialTimeline[_i + 1]; - var timelineElement = convertElementsToIndexSegment(item, previousItem, nextItem, scaledPeriodStart); - - if (timelineElement != null) { - timeline.push(timelineElement); +var SubjectSubscription = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(SubjectSubscription, _super); + function SubjectSubscription(subject, subscriber) { + var _this = _super.call(this) || this; + _this.subject = subject; + _this.subscriber = subscriber; + _this.closed = false; + return _this; } - } + SubjectSubscription.prototype.unsubscribe = function () { + if (this.closed) { + return; + } + this.closed = true; + var subject = this.subject; + var observers = subject.observers; + this.subject = null; + if (!observers || observers.length === 0 || subject.isStopped || subject.closed) { + return; + } + var subscriberIndex = observers.indexOf(this.subscriber); + if (subscriberIndex !== -1) { + observers.splice(subscriberIndex, 1); + } + }; + return SubjectSubscription; +}(_Subscription__WEBPACK_IMPORTED_MODULE_1__/* .Subscription */ .w)); - return timeline; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/find_first_common_start_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. - */ +//# sourceMappingURL=SubjectSubscription.js.map -/** - * By comparing two timelines for the same content at different points in time, - * retrieve the index in both timelines of the first segment having the same - * starting time. - * Returns `null` if not found. - * @param {Array.} prevTimeline - * @param {HTMLCollection} newElements - * @returns {Object|null} - */ -function findFirstCommonStartTime(prevTimeline, newElements) { - if (prevTimeline.length === 0 || newElements.length === 0) { - return null; - } - var prevInitialStart = prevTimeline[0].start; - var newFirstTAttr = newElements[0].getAttribute("t"); - var newInitialStart = newFirstTAttr === null ? null : parseInt(newFirstTAttr, 10); +/***/ }), - if (newInitialStart === null || Number.isNaN(newInitialStart)) { - return null; - } +/***/ 979: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - if (prevInitialStart === newInitialStart) { - return { - prevSegmentsIdx: 0, - newElementsIdx: 0, - repeatNumberInPrevSegments: 0, - repeatNumberInNewElements: 0 - }; - } else if (prevInitialStart < newInitialStart) { - var prevElt = prevTimeline[0]; - var prevElementIndex = 0; +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "L": () => (/* binding */ Subscriber) +/* harmony export */ }); +/* unused harmony export SafeSubscriber */ +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4156); +/* harmony import */ var _Observer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2174); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3884); +/* harmony import */ var _internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3142); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(150); +/* harmony import */ var _util_hostReportError__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1644); +/** PURE_IMPORTS_START tslib,_util_isFunction,_Observer,_Subscription,_internal_symbol_rxSubscriber,_config,_util_hostReportError PURE_IMPORTS_END */ - while (true) { - if (prevElt.repeatCount > 0) { - var diff = newInitialStart - prevElt.start; - if (diff % prevElt.duration === 0 && diff / prevElt.duration <= prevElt.repeatCount) { - var repeatNumberInPrevSegments = diff / prevElt.duration; - return { - repeatNumberInPrevSegments: repeatNumberInPrevSegments, - prevSegmentsIdx: prevElementIndex, - newElementsIdx: 0, - repeatNumberInNewElements: 0 - }; - } - } - prevElementIndex++; - if (prevElementIndex >= prevTimeline.length) { - return null; - } - prevElt = prevTimeline[prevElementIndex]; - if (prevElt.start === newInitialStart) { - return { - prevSegmentsIdx: prevElementIndex, - newElementsIdx: 0, - repeatNumberInPrevSegments: 0, - repeatNumberInNewElements: 0 - }; - } else if (prevElt.start > newInitialStart) { - return null; - } + +var Subscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(Subscriber, _super); + function Subscriber(destinationOrNext, error, complete) { + var _this = _super.call(this) || this; + _this.syncErrorValue = null; + _this.syncErrorThrown = false; + _this.syncErrorThrowable = false; + _this.isStopped = false; + switch (arguments.length) { + case 0: + _this.destination = _Observer__WEBPACK_IMPORTED_MODULE_1__/* .empty */ .c; + break; + case 1: + if (!destinationOrNext) { + _this.destination = _Observer__WEBPACK_IMPORTED_MODULE_1__/* .empty */ .c; + break; + } + if (typeof destinationOrNext === 'object') { + if (destinationOrNext instanceof Subscriber) { + _this.syncErrorThrowable = destinationOrNext.syncErrorThrowable; + _this.destination = destinationOrNext; + destinationOrNext.add(_this); + } + else { + _this.syncErrorThrowable = true; + _this.destination = new SafeSubscriber(_this, destinationOrNext); + } + break; + } + default: + _this.syncErrorThrowable = true; + _this.destination = new SafeSubscriber(_this, destinationOrNext, error, complete); + break; + } + return _this; } - } else { - var newElementsIdx = 0; - var newElt = newElements[0]; - var currentTimeOffset = newInitialStart; + Subscriber.prototype[_internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_2__/* .rxSubscriber */ .b] = function () { return this; }; + Subscriber.create = function (next, error, complete) { + var subscriber = new Subscriber(next, error, complete); + subscriber.syncErrorThrowable = false; + return subscriber; + }; + Subscriber.prototype.next = function (value) { + if (!this.isStopped) { + this._next(value); + } + }; + Subscriber.prototype.error = function (err) { + if (!this.isStopped) { + this.isStopped = true; + this._error(err); + } + }; + Subscriber.prototype.complete = function () { + if (!this.isStopped) { + this.isStopped = true; + this._complete(); + } + }; + Subscriber.prototype.unsubscribe = function () { + if (this.closed) { + return; + } + this.isStopped = true; + _super.prototype.unsubscribe.call(this); + }; + Subscriber.prototype._next = function (value) { + this.destination.next(value); + }; + Subscriber.prototype._error = function (err) { + this.destination.error(err); + this.unsubscribe(); + }; + Subscriber.prototype._complete = function () { + this.destination.complete(); + this.unsubscribe(); + }; + Subscriber.prototype._unsubscribeAndRecycle = function () { + var _parentOrParents = this._parentOrParents; + this._parentOrParents = null; + this.unsubscribe(); + this.closed = false; + this.isStopped = false; + this._parentOrParents = _parentOrParents; + return this; + }; + return Subscriber; +}(_Subscription__WEBPACK_IMPORTED_MODULE_3__/* .Subscription */ .w)); - while (true) { - var dAttr = newElt.getAttribute("d"); - var duration = dAttr === null ? null : parseInt(dAttr, 10); +var SafeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(SafeSubscriber, _super); + function SafeSubscriber(_parentSubscriber, observerOrNext, error, complete) { + var _this = _super.call(this) || this; + _this._parentSubscriber = _parentSubscriber; + var next; + var context = _this; + if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_4__/* .isFunction */ .m)(observerOrNext)) { + next = observerOrNext; + } + else if (observerOrNext) { + next = observerOrNext.next; + error = observerOrNext.error; + complete = observerOrNext.complete; + if (observerOrNext !== _Observer__WEBPACK_IMPORTED_MODULE_1__/* .empty */ .c) { + context = Object.create(observerOrNext); + if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_4__/* .isFunction */ .m)(context.unsubscribe)) { + _this.add(context.unsubscribe.bind(context)); + } + context.unsubscribe = _this.unsubscribe.bind(_this); + } + } + _this._context = context; + _this._next = next; + _this._error = error; + _this._complete = complete; + return _this; + } + SafeSubscriber.prototype.next = function (value) { + if (!this.isStopped && this._next) { + var _parentSubscriber = this._parentSubscriber; + if (!_config__WEBPACK_IMPORTED_MODULE_5__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { + this.__tryOrUnsub(this._next, value); + } + else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) { + this.unsubscribe(); + } + } + }; + SafeSubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var _parentSubscriber = this._parentSubscriber; + var useDeprecatedSynchronousErrorHandling = _config__WEBPACK_IMPORTED_MODULE_5__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling; + if (this._error) { + if (!useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { + this.__tryOrUnsub(this._error, err); + this.unsubscribe(); + } + else { + this.__tryOrSetError(_parentSubscriber, this._error, err); + this.unsubscribe(); + } + } + else if (!_parentSubscriber.syncErrorThrowable) { + this.unsubscribe(); + if (useDeprecatedSynchronousErrorHandling) { + throw err; + } + (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__/* .hostReportError */ .z)(err); + } + else { + if (useDeprecatedSynchronousErrorHandling) { + _parentSubscriber.syncErrorValue = err; + _parentSubscriber.syncErrorThrown = true; + } + else { + (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__/* .hostReportError */ .z)(err); + } + this.unsubscribe(); + } + } + }; + SafeSubscriber.prototype.complete = function () { + var _this = this; + if (!this.isStopped) { + var _parentSubscriber = this._parentSubscriber; + if (this._complete) { + var wrappedComplete = function () { return _this._complete.call(_this._context); }; + if (!_config__WEBPACK_IMPORTED_MODULE_5__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { + this.__tryOrUnsub(wrappedComplete); + this.unsubscribe(); + } + else { + this.__tryOrSetError(_parentSubscriber, wrappedComplete); + this.unsubscribe(); + } + } + else { + this.unsubscribe(); + } + } + }; + SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) { + try { + fn.call(this._context, value); + } + catch (err) { + this.unsubscribe(); + if (_config__WEBPACK_IMPORTED_MODULE_5__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling) { + throw err; + } + else { + (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__/* .hostReportError */ .z)(err); + } + } + }; + SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) { + if (!_config__WEBPACK_IMPORTED_MODULE_5__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling) { + throw new Error('bad call'); + } + try { + fn.call(this._context, value); + } + catch (err) { + if (_config__WEBPACK_IMPORTED_MODULE_5__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling) { + parent.syncErrorValue = err; + parent.syncErrorThrown = true; + return true; + } + else { + (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__/* .hostReportError */ .z)(err); + return true; + } + } + return false; + }; + SafeSubscriber.prototype._unsubscribe = function () { + var _parentSubscriber = this._parentSubscriber; + this._context = null; + this._parentSubscriber = null; + _parentSubscriber.unsubscribe(); + }; + return SafeSubscriber; +}(Subscriber)); - if (duration === null || Number.isNaN(duration)) { - return null; - } +//# sourceMappingURL=Subscriber.js.map - var rAttr = newElt.getAttribute("r"); - var repeatCount = rAttr === null ? null : parseInt(rAttr, 10); - if (repeatCount !== null) { - if (Number.isNaN(repeatCount) || repeatCount < 0) { - return null; - } +/***/ }), - if (repeatCount > 0) { - var _diff = prevInitialStart - currentTimeOffset; +/***/ 3884: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - if (_diff % duration === 0 && _diff / duration <= repeatCount) { - var repeatNumberInNewElements = _diff / duration; - return { - repeatNumberInPrevSegments: 0, - repeatNumberInNewElements: repeatNumberInNewElements, - prevSegmentsIdx: 0, - newElementsIdx: newElementsIdx - }; - } - } +"use strict"; - currentTimeOffset += duration * (repeatCount + 1); - } else { - currentTimeOffset += duration; - } +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "w": () => (/* binding */ Subscription) +}); - newElementsIdx++; +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isArray.js +var isArray = __webpack_require__(9026); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isObject.js +var isObject = __webpack_require__(2009); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isFunction.js +var isFunction = __webpack_require__(4156); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/UnsubscriptionError.js +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var UnsubscriptionErrorImpl = /*@__PURE__*/ (function () { + function UnsubscriptionErrorImpl(errors) { + Error.call(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; + return this; + } + UnsubscriptionErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); + return UnsubscriptionErrorImpl; +})(); +var UnsubscriptionError = UnsubscriptionErrorImpl; +//# sourceMappingURL=UnsubscriptionError.js.map - if (newElementsIdx >= newElements.length) { - return null; - } +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/Subscription.js +/** PURE_IMPORTS_START _util_isArray,_util_isObject,_util_isFunction,_util_UnsubscriptionError PURE_IMPORTS_END */ - newElt = newElements[newElementsIdx]; - var tAttr = newElt.getAttribute("t"); - var time = tAttr === null ? null : parseInt(tAttr, 10); - if (time !== null) { - if (Number.isNaN(time)) { - return null; - } - currentTimeOffset = time; - } - if (currentTimeOffset === prevInitialStart) { - return { - newElementsIdx: newElementsIdx, - prevSegmentsIdx: 0, - repeatNumberInPrevSegments: 0, - repeatNumberInNewElements: 0 - }; - } else if (currentTimeOffset > newInitialStart) { - return null; - } +var Subscription = /*@__PURE__*/ (function () { + function Subscription(unsubscribe) { + this.closed = false; + this._parentOrParents = null; + this._subscriptions = null; + if (unsubscribe) { + this._ctorUnsubscribe = true; + this._unsubscribe = unsubscribe; + } } - } -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/construct_timeline_from_previous_timeline.ts + Subscription.prototype.unsubscribe = function () { + var errors; + if (this.closed) { + return; + } + var _a = this, _parentOrParents = _a._parentOrParents, _ctorUnsubscribe = _a._ctorUnsubscribe, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions; + this.closed = true; + this._parentOrParents = null; + this._subscriptions = null; + if (_parentOrParents instanceof Subscription) { + _parentOrParents.remove(this); + } + else if (_parentOrParents !== null) { + for (var index = 0; index < _parentOrParents.length; ++index) { + var parent_1 = _parentOrParents[index]; + parent_1.remove(this); + } + } + if ((0,isFunction/* isFunction */.m)(_unsubscribe)) { + if (_ctorUnsubscribe) { + this._unsubscribe = undefined; + } + try { + _unsubscribe.call(this); + } + catch (e) { + errors = e instanceof UnsubscriptionError ? flattenUnsubscriptionErrors(e.errors) : [e]; + } + } + if ((0,isArray/* isArray */.k)(_subscriptions)) { + var index = -1; + var len = _subscriptions.length; + while (++index < len) { + var sub = _subscriptions[index]; + if ((0,isObject/* isObject */.K)(sub)) { + try { + sub.unsubscribe(); + } + catch (e) { + errors = errors || []; + if (e instanceof UnsubscriptionError) { + errors = errors.concat(flattenUnsubscriptionErrors(e.errors)); + } + else { + errors.push(e); + } + } + } + } + } + if (errors) { + throw new UnsubscriptionError(errors); + } + }; + Subscription.prototype.add = function (teardown) { + var subscription = teardown; + if (!teardown) { + return Subscription.EMPTY; + } + switch (typeof teardown) { + case 'function': + subscription = new Subscription(teardown); + case 'object': + if (subscription === this || subscription.closed || typeof subscription.unsubscribe !== 'function') { + return subscription; + } + else if (this.closed) { + subscription.unsubscribe(); + return subscription; + } + else if (!(subscription instanceof Subscription)) { + var tmp = subscription; + subscription = new Subscription(); + subscription._subscriptions = [tmp]; + } + break; + default: { + throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.'); + } + } + var _parentOrParents = subscription._parentOrParents; + if (_parentOrParents === null) { + subscription._parentOrParents = this; + } + else if (_parentOrParents instanceof Subscription) { + if (_parentOrParents === this) { + return subscription; + } + subscription._parentOrParents = [_parentOrParents, this]; + } + else if (_parentOrParents.indexOf(this) === -1) { + _parentOrParents.push(this); + } + else { + return subscription; + } + var subscriptions = this._subscriptions; + if (subscriptions === null) { + this._subscriptions = [subscription]; + } + else { + subscriptions.push(subscription); + } + return subscription; + }; + Subscription.prototype.remove = function (subscription) { + var subscriptions = this._subscriptions; + if (subscriptions) { + var subscriptionIndex = subscriptions.indexOf(subscription); + if (subscriptionIndex !== -1) { + subscriptions.splice(subscriptionIndex, 1); + } + } + }; + Subscription.EMPTY = (function (empty) { + empty.closed = true; + return empty; + }(new Subscription())); + return Subscription; +}()); + +function flattenUnsubscriptionErrors(errors) { + return errors.reduce(function (errs, err) { return errs.concat((err instanceof UnsubscriptionError) ? err.errors : err); }, []); +} +//# sourceMappingURL=Subscription.js.map + + +/***/ }), + +/***/ 150: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "v": () => (/* binding */ config) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var _enable_super_gross_mode_that_will_cause_bad_things = false; +var config = { + Promise: undefined, + set useDeprecatedSynchronousErrorHandling(value) { + if (value) { + var error = /*@__PURE__*/ new Error(); + /*@__PURE__*/ console.warn('DEPRECATED! RxJS was set to use deprecated synchronous error handling behavior by code at: \n' + error.stack); + } + else if (_enable_super_gross_mode_that_will_cause_bad_things) { + /*@__PURE__*/ console.log('RxJS: Back to a better error behavior. Thank you. <3'); + } + _enable_super_gross_mode_that_will_cause_bad_things = value; + }, + get useDeprecatedSynchronousErrorHandling() { + return _enable_super_gross_mode_that_will_cause_bad_things; + }, +}; +//# sourceMappingURL=config.js.map + + +/***/ }), + +/***/ 7604: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "IY": () => (/* binding */ SimpleInnerSubscriber), +/* harmony export */ "Ds": () => (/* binding */ SimpleOuterSubscriber), +/* harmony export */ "ft": () => (/* binding */ innerSubscribe) +/* harmony export */ }); +/* unused harmony exports ComplexInnerSubscriber, ComplexOuterSubscriber */ +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4379); +/* harmony import */ var _util_subscribeTo__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7843); +/** PURE_IMPORTS_START tslib,_Subscriber,_Observable,_util_subscribeTo PURE_IMPORTS_END */ + + + + +var SimpleInnerSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(SimpleInnerSubscriber, _super); + function SimpleInnerSubscriber(parent) { + var _this = _super.call(this) || this; + _this.parent = parent; + return _this; + } + SimpleInnerSubscriber.prototype._next = function (value) { + this.parent.notifyNext(value); + }; + SimpleInnerSubscriber.prototype._error = function (error) { + this.parent.notifyError(error); + this.unsubscribe(); + }; + SimpleInnerSubscriber.prototype._complete = function () { + this.parent.notifyComplete(); + this.unsubscribe(); + }; + return SimpleInnerSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); + +var ComplexInnerSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(ComplexInnerSubscriber, _super); + function ComplexInnerSubscriber(parent, outerValue, outerIndex) { + var _this = _super.call(this) || this; + _this.parent = parent; + _this.outerValue = outerValue; + _this.outerIndex = outerIndex; + return _this; + } + ComplexInnerSubscriber.prototype._next = function (value) { + this.parent.notifyNext(this.outerValue, value, this.outerIndex, this); + }; + ComplexInnerSubscriber.prototype._error = function (error) { + this.parent.notifyError(error); + this.unsubscribe(); + }; + ComplexInnerSubscriber.prototype._complete = function () { + this.parent.notifyComplete(this); + this.unsubscribe(); + }; + return ComplexInnerSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); + +var SimpleOuterSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(SimpleOuterSubscriber, _super); + function SimpleOuterSubscriber() { + return _super !== null && _super.apply(this, arguments) || this; + } + SimpleOuterSubscriber.prototype.notifyNext = function (innerValue) { + this.destination.next(innerValue); + }; + SimpleOuterSubscriber.prototype.notifyError = function (err) { + this.destination.error(err); + }; + SimpleOuterSubscriber.prototype.notifyComplete = function () { + this.destination.complete(); + }; + return SimpleOuterSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); + +var ComplexOuterSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(ComplexOuterSubscriber, _super); + function ComplexOuterSubscriber() { + return _super !== null && _super.apply(this, arguments) || this; + } + ComplexOuterSubscriber.prototype.notifyNext = function (_outerValue, innerValue, _outerIndex, _innerSub) { + this.destination.next(innerValue); + }; + ComplexOuterSubscriber.prototype.notifyError = function (error) { + this.destination.error(error); + }; + ComplexOuterSubscriber.prototype.notifyComplete = function (_innerSub) { + this.destination.complete(); + }; + return ComplexOuterSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); + +function innerSubscribe(result, innerSubscriber) { + if (innerSubscriber.closed) { + return undefined; + } + if (result instanceof _Observable__WEBPACK_IMPORTED_MODULE_2__/* .Observable */ .y) { + return result.subscribe(innerSubscriber); + } + var subscription; + try { + subscription = (0,_util_subscribeTo__WEBPACK_IMPORTED_MODULE_3__/* .subscribeTo */ .s)(result)(innerSubscriber); + } + catch (error) { + innerSubscriber.error(error); + } + return subscription; +} +//# sourceMappingURL=innerSubscribe.js.map + + +/***/ }), + +/***/ 5142: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "aj": () => (/* binding */ combineLatest) +/* harmony export */ }); +/* unused harmony exports CombineLatestOperator, CombineLatestSubscriber */ +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(655); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7507); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9026); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2039); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2080); +/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3375); +/** PURE_IMPORTS_START tslib,_util_isScheduler,_util_isArray,_OuterSubscriber,_util_subscribeToResult,_fromArray PURE_IMPORTS_END */ + + + + + + +var NONE = {}; +function combineLatest() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + var resultSelector = undefined; + var scheduler = undefined; + if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__/* .isScheduler */ .K)(observables[observables.length - 1])) { + scheduler = observables.pop(); + } + if (typeof observables[observables.length - 1] === 'function') { + resultSelector = observables.pop(); + } + if (observables.length === 1 && (0,_util_isArray__WEBPACK_IMPORTED_MODULE_1__/* .isArray */ .k)(observables[0])) { + observables = observables[0]; + } + return (0,_fromArray__WEBPACK_IMPORTED_MODULE_2__/* .fromArray */ .n)(observables, scheduler).lift(new CombineLatestOperator(resultSelector)); +} +var CombineLatestOperator = /*@__PURE__*/ (function () { + function CombineLatestOperator(resultSelector) { + this.resultSelector = resultSelector; + } + CombineLatestOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new CombineLatestSubscriber(subscriber, this.resultSelector)); + }; + return CombineLatestOperator; +}()); + +var CombineLatestSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_3__/* .__extends */ .ZT(CombineLatestSubscriber, _super); + function CombineLatestSubscriber(destination, resultSelector) { + var _this = _super.call(this, destination) || this; + _this.resultSelector = resultSelector; + _this.active = 0; + _this.values = []; + _this.observables = []; + return _this; + } + CombineLatestSubscriber.prototype._next = function (observable) { + this.values.push(NONE); + this.observables.push(observable); + }; + CombineLatestSubscriber.prototype._complete = function () { + var observables = this.observables; + var len = observables.length; + if (len === 0) { + this.destination.complete(); + } + else { + this.active = len; + this.toRespond = len; + for (var i = 0; i < len; i++) { + var observable = observables[i]; + this.add((0,_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__/* .subscribeToResult */ .D)(this, observable, undefined, i)); + } + } + }; + CombineLatestSubscriber.prototype.notifyComplete = function (unused) { + if ((this.active -= 1) === 0) { + this.destination.complete(); + } + }; + CombineLatestSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { + var values = this.values; + var oldVal = values[outerIndex]; + var toRespond = !this.toRespond + ? 0 + : oldVal === NONE ? --this.toRespond : this.toRespond; + values[outerIndex] = innerValue; + if (toRespond === 0) { + if (this.resultSelector) { + this._tryResultSelector(values); + } + else { + this.destination.next(values.slice()); + } + } + }; + CombineLatestSubscriber.prototype._tryResultSelector = function (values) { + var result; + try { + result = this.resultSelector.apply(this, values); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(result); + }; + return CombineLatestSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_5__/* .OuterSubscriber */ .L)); + +//# sourceMappingURL=combineLatest.js.map + + +/***/ }), + +/***/ 9795: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "z": () => (/* binding */ concat) +/* harmony export */ }); +/* harmony import */ var _of__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8170); +/* harmony import */ var _operators_concatAll__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2257); +/** PURE_IMPORTS_START _of,_operators_concatAll PURE_IMPORTS_END */ + + +function concat() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + return (0,_operators_concatAll__WEBPACK_IMPORTED_MODULE_0__/* .concatAll */ .u)()(_of__WEBPACK_IMPORTED_MODULE_1__.of.apply(void 0, observables)); +} +//# sourceMappingURL=concat.js.map + + +/***/ }), + +/***/ 1410: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "P": () => (/* binding */ defer) +/* harmony export */ }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4379); +/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4072); +/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5631); +/** PURE_IMPORTS_START _Observable,_from,_empty PURE_IMPORTS_END */ + + + +function defer(observableFactory) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) { + var input; + try { + input = observableFactory(); + } + catch (err) { + subscriber.error(err); + return undefined; + } + var source = input ? (0,_from__WEBPACK_IMPORTED_MODULE_1__/* .from */ .D)(input) : (0,_empty__WEBPACK_IMPORTED_MODULE_2__/* .empty */ .c)(); + return source.subscribe(subscriber); + }); +} +//# sourceMappingURL=defer.js.map + + +/***/ }), + +/***/ 5631: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "E": () => (/* binding */ EMPTY), +/* harmony export */ "c": () => (/* binding */ empty) +/* harmony export */ }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4379); +/** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ + +var EMPTY = /*@__PURE__*/ 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__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) { return scheduler.schedule(function () { return subscriber.complete(); }); }); +} +//# sourceMappingURL=empty.js.map + + +/***/ }), + +/***/ 4072: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "D": () => (/* binding */ from) +}); + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules +var Observable = __webpack_require__(4379); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeTo.js + 3 modules +var subscribeTo = __webpack_require__(7843); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscription.js + 1 modules +var Subscription = __webpack_require__(3884); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/symbol/observable.js +var symbol_observable = __webpack_require__(5050); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduled/scheduleObservable.js +/** PURE_IMPORTS_START _Observable,_Subscription,_symbol_observable PURE_IMPORTS_END */ + + + +function scheduleObservable(input, scheduler) { + return new Observable/* Observable */.y(function (subscriber) { + var sub = new Subscription/* Subscription */.w(); + sub.add(scheduler.schedule(function () { + var observable = input[symbol_observable/* observable */.L](); + sub.add(observable.subscribe({ + next: function (value) { sub.add(scheduler.schedule(function () { return subscriber.next(value); })); }, + error: function (err) { sub.add(scheduler.schedule(function () { return subscriber.error(err); })); }, + complete: function () { sub.add(scheduler.schedule(function () { return subscriber.complete(); })); }, + })); + })); + return sub; + }); +} +//# sourceMappingURL=scheduleObservable.js.map + +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduled/schedulePromise.js +/** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ + + +function schedulePromise(input, scheduler) { + return new Observable/* Observable */.y(function (subscriber) { + var sub = new Subscription/* Subscription */.w(); + sub.add(scheduler.schedule(function () { + return input.then(function (value) { + sub.add(scheduler.schedule(function () { + subscriber.next(value); + sub.add(scheduler.schedule(function () { return subscriber.complete(); })); + })); + }, function (err) { + sub.add(scheduler.schedule(function () { return subscriber.error(err); })); + }); + })); + return sub; + }); +} +//# sourceMappingURL=schedulePromise.js.map + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/scheduled/scheduleArray.js +var scheduleArray = __webpack_require__(3109); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/symbol/iterator.js +var symbol_iterator = __webpack_require__(999); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduled/scheduleIterable.js +/** PURE_IMPORTS_START _Observable,_Subscription,_symbol_iterator PURE_IMPORTS_END */ + + + +function scheduleIterable(input, scheduler) { + if (!input) { + throw new Error('Iterable cannot be null'); + } + return new Observable/* Observable */.y(function (subscriber) { + var sub = new Subscription/* Subscription */.w(); + var iterator; + sub.add(function () { + if (iterator && typeof iterator.return === 'function') { + iterator.return(); + } + }); + sub.add(scheduler.schedule(function () { + iterator = input[symbol_iterator/* iterator */.hZ](); + sub.add(scheduler.schedule(function () { + if (subscriber.closed) { + return; + } + var value; + var done; + try { + var result = iterator.next(); + value = result.value; + done = result.done; + } + catch (err) { + subscriber.error(err); + return; + } + if (done) { + subscriber.complete(); + } + else { + subscriber.next(value); + this.schedule(); + } + })); + })); + return sub; + }); +} +//# sourceMappingURL=scheduleIterable.js.map + +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/isInteropObservable.js +/** PURE_IMPORTS_START _symbol_observable PURE_IMPORTS_END */ + +function isInteropObservable(input) { + return input && typeof input[symbol_observable/* observable */.L] === 'function'; +} +//# sourceMappingURL=isInteropObservable.js.map + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isPromise.js +var isPromise = __webpack_require__(336); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isArrayLike.js +var isArrayLike = __webpack_require__(9217); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/isIterable.js +/** PURE_IMPORTS_START _symbol_iterator PURE_IMPORTS_END */ + +function isIterable(input) { + return input && typeof input[symbol_iterator/* iterator */.hZ] === 'function'; +} +//# sourceMappingURL=isIterable.js.map + +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduled/scheduled.js +/** PURE_IMPORTS_START _scheduleObservable,_schedulePromise,_scheduleArray,_scheduleIterable,_util_isInteropObservable,_util_isPromise,_util_isArrayLike,_util_isIterable PURE_IMPORTS_END */ + + + + + + + + +function scheduled(input, scheduler) { + if (input != null) { + if (isInteropObservable(input)) { + return scheduleObservable(input, scheduler); + } + else if ((0,isPromise/* isPromise */.t)(input)) { + return schedulePromise(input, scheduler); + } + else if ((0,isArrayLike/* isArrayLike */.z)(input)) { + return (0,scheduleArray/* scheduleArray */.r)(input, scheduler); + } + else if (isIterable(input) || typeof input === 'string') { + return scheduleIterable(input, scheduler); + } + } + throw new TypeError((input !== null && typeof input || input) + ' is not observable'); +} +//# sourceMappingURL=scheduled.js.map + +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/observable/from.js +/** PURE_IMPORTS_START _Observable,_util_subscribeTo,_scheduled_scheduled PURE_IMPORTS_END */ + + + +function from(input, scheduler) { + if (!scheduler) { + if (input instanceof Observable/* Observable */.y) { + return input; + } + return new Observable/* Observable */.y((0,subscribeTo/* subscribeTo */.s)(input)); + } + else { + return scheduled(input, scheduler); + } +} +//# sourceMappingURL=from.js.map + + +/***/ }), + +/***/ 3375: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "n": () => (/* binding */ fromArray) +/* harmony export */ }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4379); +/* harmony import */ var _util_subscribeToArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6900); +/* harmony import */ var _scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3109); +/** PURE_IMPORTS_START _Observable,_util_subscribeToArray,_scheduled_scheduleArray PURE_IMPORTS_END */ + + + +function fromArray(input, scheduler) { + if (!scheduler) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y((0,_util_subscribeToArray__WEBPACK_IMPORTED_MODULE_1__/* .subscribeToArray */ .V)(input)); + } + else { + return (0,_scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__/* .scheduleArray */ .r)(input, scheduler); + } +} +//# sourceMappingURL=fromArray.js.map + + +/***/ }), + +/***/ 7027: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "R": () => (/* binding */ fromEvent) +/* harmony export */ }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4379); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9026); +/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4156); +/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5709); +/** PURE_IMPORTS_START _Observable,_util_isArray,_util_isFunction,_operators_map PURE_IMPORTS_END */ + + + + +var toString = /*@__PURE__*/ (/* unused pure expression or super */ null && ((function () { return Object.prototype.toString; })())); +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,_operators_map__WEBPACK_IMPORTED_MODULE_1__/* .map */ .U)(function (args) { return (0,_util_isArray__WEBPACK_IMPORTED_MODULE_2__/* .isArray */ .k)(args) ? resultSelector.apply(void 0, args) : resultSelector(args); })); + } + return new _Observable__WEBPACK_IMPORTED_MODULE_3__/* .Observable */ .y(function (subscriber) { + function handler(e) { + if (arguments.length > 1) { + subscriber.next(Array.prototype.slice.call(arguments)); + } + else { + subscriber.next(e); + } + } + setupSubscription(target, eventName, handler, subscriber, options); + }); +} +function setupSubscription(sourceObj, eventName, handler, subscriber, options) { + var unsubscribe; + if (isEventTarget(sourceObj)) { + var source_1 = sourceObj; + sourceObj.addEventListener(eventName, handler, options); + unsubscribe = function () { return source_1.removeEventListener(eventName, handler, options); }; + } + else if (isJQueryStyleEventEmitter(sourceObj)) { + var source_2 = sourceObj; + sourceObj.on(eventName, handler); + unsubscribe = function () { return source_2.off(eventName, handler); }; + } + else if (isNodeStyleEventEmitter(sourceObj)) { + var source_3 = sourceObj; + sourceObj.addListener(eventName, handler); + unsubscribe = function () { return source_3.removeListener(eventName, handler); }; + } + else if (sourceObj && sourceObj.length) { + for (var i = 0, len = sourceObj.length; i < len; i++) { + setupSubscription(sourceObj[i], eventName, handler, subscriber, options); + } + } + else { + throw new TypeError('Invalid event target'); + } + subscriber.add(unsubscribe); +} +function isNodeStyleEventEmitter(sourceObj) { + return sourceObj && typeof sourceObj.addListener === 'function' && typeof sourceObj.removeListener === 'function'; +} +function isJQueryStyleEventEmitter(sourceObj) { + return sourceObj && typeof sourceObj.on === 'function' && typeof sourceObj.off === 'function'; +} +function isEventTarget(sourceObj) { + return sourceObj && typeof sourceObj.addEventListener === 'function' && typeof sourceObj.removeEventListener === 'function'; +} +//# sourceMappingURL=fromEvent.js.map + + +/***/ }), + +/***/ 6564: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "F": () => (/* binding */ interval) +/* harmony export */ }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4379); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(964); +/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5812); +/** PURE_IMPORTS_START _Observable,_scheduler_async,_util_isNumeric PURE_IMPORTS_END */ + + + +function interval(period, scheduler) { + if (period === void 0) { + period = 0; + } + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__/* .async */ .P; + } + if (!(0,_util_isNumeric__WEBPACK_IMPORTED_MODULE_1__/* .isNumeric */ .k)(period) || period < 0) { + period = 0; + } + if (!scheduler || typeof scheduler.schedule !== 'function') { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__/* .async */ .P; + } + return new _Observable__WEBPACK_IMPORTED_MODULE_2__/* .Observable */ .y(function (subscriber) { + subscriber.add(scheduler.schedule(dispatch, period, { subscriber: subscriber, counter: 0, period: period })); + return subscriber; + }); +} +function dispatch(state) { + var subscriber = state.subscriber, counter = state.counter, period = state.period; + subscriber.next(counter); + this.schedule({ subscriber: subscriber, counter: counter + 1, period: period }, period); +} +//# sourceMappingURL=interval.js.map + + +/***/ }), + +/***/ 4370: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "T": () => (/* binding */ merge) +/* harmony export */ }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4379); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7507); +/* harmony import */ var _operators_mergeAll__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2556); +/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3375); +/** PURE_IMPORTS_START _Observable,_util_isScheduler,_operators_mergeAll,_fromArray PURE_IMPORTS_END */ + + + + +function merge() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + var concurrent = Number.POSITIVE_INFINITY; + var scheduler = null; + var last = observables[observables.length - 1]; + if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__/* .isScheduler */ .K)(last)) { + scheduler = observables.pop(); + if (observables.length > 1 && typeof observables[observables.length - 1] === 'number') { + concurrent = observables.pop(); + } + } + else if (typeof last === 'number') { + concurrent = observables.pop(); + } + if (scheduler === null && observables.length === 1 && observables[0] instanceof _Observable__WEBPACK_IMPORTED_MODULE_1__/* .Observable */ .y) { + return observables[0]; + } + return (0,_operators_mergeAll__WEBPACK_IMPORTED_MODULE_2__/* .mergeAll */ .J)(concurrent)((0,_fromArray__WEBPACK_IMPORTED_MODULE_3__/* .fromArray */ .n)(observables, scheduler)); +} +//# sourceMappingURL=merge.js.map + + +/***/ }), + +/***/ 8170: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "of": () => (/* binding */ of) +/* harmony export */ }); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7507); +/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3375); +/* harmony import */ var _scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3109); +/** PURE_IMPORTS_START _util_isScheduler,_fromArray,_scheduled_scheduleArray PURE_IMPORTS_END */ + + + +function of() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var scheduler = args[args.length - 1]; + if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__/* .isScheduler */ .K)(scheduler)) { + args.pop(); + return (0,_scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_1__/* .scheduleArray */ .r)(args, scheduler); + } + else { + return (0,_fromArray__WEBPACK_IMPORTED_MODULE_2__/* .fromArray */ .n)(args); + } +} +//# sourceMappingURL=of.js.map + + +/***/ }), + +/***/ 8821: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "S3": () => (/* binding */ race) +/* harmony export */ }); +/* unused harmony exports RaceOperator, RaceSubscriber */ +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(655); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9026); +/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3375); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2039); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2080); +/** PURE_IMPORTS_START tslib,_util_isArray,_fromArray,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ + + + + + +function race() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + if (observables.length === 1) { + if ((0,_util_isArray__WEBPACK_IMPORTED_MODULE_0__/* .isArray */ .k)(observables[0])) { + observables = observables[0]; + } + else { + return observables[0]; + } + } + return (0,_fromArray__WEBPACK_IMPORTED_MODULE_1__/* .fromArray */ .n)(observables, undefined).lift(new RaceOperator()); +} +var RaceOperator = /*@__PURE__*/ (function () { + function RaceOperator() { + } + RaceOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new RaceSubscriber(subscriber)); + }; + return RaceOperator; +}()); + +var RaceSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_2__/* .__extends */ .ZT(RaceSubscriber, _super); + function RaceSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.hasFirst = false; + _this.observables = []; + _this.subscriptions = []; + return _this; + } + RaceSubscriber.prototype._next = function (observable) { + this.observables.push(observable); + }; + RaceSubscriber.prototype._complete = function () { + var observables = this.observables; + var len = observables.length; + if (len === 0) { + this.destination.complete(); + } + else { + for (var i = 0; i < len && !this.hasFirst; i++) { + var observable = observables[i]; + var subscription = (0,_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__/* .subscribeToResult */ .D)(this, observable, undefined, i); + if (this.subscriptions) { + this.subscriptions.push(subscription); + } + this.add(subscription); + } + this.observables = null; + } + }; + RaceSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { + if (!this.hasFirst) { + this.hasFirst = true; + for (var i = 0; i < this.subscriptions.length; i++) { + if (i !== outerIndex) { + var subscription = this.subscriptions[i]; + subscription.unsubscribe(); + this.remove(subscription); + } + } + this.subscriptions = null; + } + this.destination.next(innerValue); + }; + return RaceSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_4__/* .OuterSubscriber */ .L)); + +//# sourceMappingURL=race.js.map + + +/***/ }), + +/***/ 4944: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "_": () => (/* binding */ throwError) +/* harmony export */ }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4379); +/** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ + +function throwError(error, scheduler) { + if (!scheduler) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) { return subscriber.error(error); }); + } + else { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) { return scheduler.schedule(dispatch, 0, { error: error, subscriber: subscriber }); }); + } +} +function dispatch(_a) { + var error = _a.error, subscriber = _a.subscriber; + subscriber.error(error); +} +//# sourceMappingURL=throwError.js.map + + +/***/ }), + +/***/ 9604: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "H": () => (/* binding */ timer) +/* harmony export */ }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4379); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(964); +/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5812); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7507); +/** PURE_IMPORTS_START _Observable,_scheduler_async,_util_isNumeric,_util_isScheduler PURE_IMPORTS_END */ + + + + +function timer(dueTime, periodOrScheduler, scheduler) { + if (dueTime === void 0) { + dueTime = 0; + } + var period = -1; + if ((0,_util_isNumeric__WEBPACK_IMPORTED_MODULE_0__/* .isNumeric */ .k)(periodOrScheduler)) { + period = Number(periodOrScheduler) < 1 && 1 || Number(periodOrScheduler); + } + else if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__/* .isScheduler */ .K)(periodOrScheduler)) { + scheduler = periodOrScheduler; + } + if (!(0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__/* .isScheduler */ .K)(scheduler)) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__/* .async */ .P; + } + return new _Observable__WEBPACK_IMPORTED_MODULE_3__/* .Observable */ .y(function (subscriber) { + var due = (0,_util_isNumeric__WEBPACK_IMPORTED_MODULE_0__/* .isNumeric */ .k)(dueTime) + ? dueTime + : (+dueTime - scheduler.now()); + return scheduler.schedule(dispatch, due, { + index: 0, period: period, subscriber: subscriber + }); + }); +} +function dispatch(state) { + var index = state.index, period = state.period, subscriber = state.subscriber; + subscriber.next(index); + if (subscriber.closed) { + return; + } + else if (period === -1) { + return subscriber.complete(); + } + state.index = index + 1; + this.schedule(state, period); +} +//# sourceMappingURL=timer.js.map + + +/***/ }), + +/***/ 486: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "K": () => (/* binding */ catchError) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7604); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + + +function catchError(selector) { + return function catchErrorOperatorFunction(source) { + var operator = new CatchOperator(selector); + var caught = source.lift(operator); + return (operator.caught = caught); + }; +} +var CatchOperator = /*@__PURE__*/ (function () { + function CatchOperator(selector) { + this.selector = selector; + } + CatchOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new CatchSubscriber(subscriber, this.selector, this.caught)); + }; + return CatchOperator; +}()); +var CatchSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(CatchSubscriber, _super); + function CatchSubscriber(destination, selector, caught) { + var _this = _super.call(this, destination) || this; + _this.selector = selector; + _this.caught = caught; + return _this; + } + CatchSubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var result = void 0; + try { + result = this.selector(err, this.caught); + } + catch (err2) { + _super.prototype.error.call(this, err2); + return; + } + this._unsubscribeAndRecycle(); + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__/* .SimpleInnerSubscriber */ .IY(this); + this.add(innerSubscriber); + var innerSubscription = (0,_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__/* .innerSubscribe */ .ft)(result, innerSubscriber); + if (innerSubscription !== innerSubscriber) { + this.add(innerSubscription); + } + } + }; + return CatchSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__/* .SimpleOuterSubscriber */ .Ds)); +//# sourceMappingURL=catchError.js.map + + +/***/ }), + +/***/ 2257: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "u": () => (/* binding */ concatAll) +/* harmony export */ }); +/* harmony import */ var _mergeAll__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2556); +/** PURE_IMPORTS_START _mergeAll PURE_IMPORTS_END */ + +function concatAll() { + return (0,_mergeAll__WEBPACK_IMPORTED_MODULE_0__/* .mergeAll */ .J)(1); +} +//# sourceMappingURL=concatAll.js.map + + +/***/ }), + +/***/ 1931: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "x": () => (/* binding */ distinctUntilChanged) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function distinctUntilChanged(compare, keySelector) { + return function (source) { return source.lift(new DistinctUntilChangedOperator(compare, keySelector)); }; +} +var DistinctUntilChangedOperator = /*@__PURE__*/ (function () { + function DistinctUntilChangedOperator(compare, keySelector) { + this.compare = compare; + this.keySelector = keySelector; + } + DistinctUntilChangedOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DistinctUntilChangedSubscriber(subscriber, this.compare, this.keySelector)); + }; + return DistinctUntilChangedOperator; +}()); +var DistinctUntilChangedSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(DistinctUntilChangedSubscriber, _super); + function DistinctUntilChangedSubscriber(destination, compare, keySelector) { + var _this = _super.call(this, destination) || this; + _this.keySelector = keySelector; + _this.hasKey = false; + if (typeof compare === 'function') { + _this.compare = compare; + } + return _this; + } + DistinctUntilChangedSubscriber.prototype.compare = function (x, y) { + return x === y; + }; + DistinctUntilChangedSubscriber.prototype._next = function (value) { + var key; + try { + var keySelector = this.keySelector; + key = keySelector ? keySelector(value) : value; + } + catch (err) { + return this.destination.error(err); + } + var result = false; + if (this.hasKey) { + try { + var compare = this.compare; + result = compare(this.key, key); + } + catch (err) { + return this.destination.error(err); + } + } + else { + this.hasKey = true; + } + if (!result) { + this.key = key; + this.destination.next(value); + } + }; + return DistinctUntilChangedSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); +//# sourceMappingURL=distinctUntilChanged.js.map + + +/***/ }), + +/***/ 6008: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "h": () => (/* binding */ filter) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function filter(predicate, thisArg) { + return function filterOperatorFunction(source) { + return source.lift(new FilterOperator(predicate, thisArg)); + }; +} +var FilterOperator = /*@__PURE__*/ (function () { + function FilterOperator(predicate, thisArg) { + this.predicate = predicate; + this.thisArg = thisArg; + } + FilterOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new FilterSubscriber(subscriber, this.predicate, this.thisArg)); + }; + return FilterOperator; +}()); +var FilterSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(FilterSubscriber, _super); + function FilterSubscriber(destination, predicate, thisArg) { + var _this = _super.call(this, destination) || this; + _this.predicate = predicate; + _this.thisArg = thisArg; + _this.count = 0; + return _this; + } + FilterSubscriber.prototype._next = function (value) { + var result; + try { + result = this.predicate.call(this.thisArg, value, this.count++); + } + catch (err) { + this.destination.error(err); + return; + } + if (result) { + this.destination.next(value); + } + }; + return FilterSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); +//# sourceMappingURL=filter.js.map + + +/***/ }), + +/***/ 6738: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "l": () => (/* binding */ ignoreElements) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function ignoreElements() { + return function ignoreElementsOperatorFunction(source) { + return source.lift(new IgnoreElementsOperator()); + }; +} +var IgnoreElementsOperator = /*@__PURE__*/ (function () { + function IgnoreElementsOperator() { + } + IgnoreElementsOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new IgnoreElementsSubscriber(subscriber)); + }; + return IgnoreElementsOperator; +}()); +var IgnoreElementsSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(IgnoreElementsSubscriber, _super); + function IgnoreElementsSubscriber() { + return _super !== null && _super.apply(this, arguments) || this; + } + IgnoreElementsSubscriber.prototype._next = function (unused) { + }; + return IgnoreElementsSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); +//# sourceMappingURL=ignoreElements.js.map + + +/***/ }), + +/***/ 5709: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "U": () => (/* binding */ map) +/* harmony export */ }); +/* unused harmony export MapOperator */ +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function map(project, thisArg) { + return function mapOperation(source) { + if (typeof project !== 'function') { + throw new TypeError('argument is not a function. Are you looking for `mapTo()`?'); + } + return source.lift(new MapOperator(project, thisArg)); + }; +} +var MapOperator = /*@__PURE__*/ (function () { + function MapOperator(project, thisArg) { + this.project = project; + this.thisArg = thisArg; + } + MapOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new MapSubscriber(subscriber, this.project, this.thisArg)); + }; + return MapOperator; +}()); + +var MapSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(MapSubscriber, _super); + function MapSubscriber(destination, project, thisArg) { + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.count = 0; + _this.thisArg = thisArg || _this; + return _this; + } + MapSubscriber.prototype._next = function (value) { + var result; + try { + result = this.project.call(this.thisArg, value, this.count++); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(result); + }; + return MapSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); +//# sourceMappingURL=map.js.map + + +/***/ }), + +/***/ 5602: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "h": () => (/* binding */ mapTo) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function mapTo(value) { + return function (source) { return source.lift(new MapToOperator(value)); }; +} +var MapToOperator = /*@__PURE__*/ (function () { + function MapToOperator(value) { + this.value = value; + } + MapToOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new MapToSubscriber(subscriber, this.value)); + }; + return MapToOperator; +}()); +var MapToSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(MapToSubscriber, _super); + function MapToSubscriber(destination, value) { + var _this = _super.call(this, destination) || this; + _this.value = value; + return _this; + } + MapToSubscriber.prototype._next = function (x) { + this.destination.next(this.value); + }; + return MapToSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); +//# sourceMappingURL=mapTo.js.map + + +/***/ }), + +/***/ 2556: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "J": () => (/* binding */ mergeAll) +/* harmony export */ }); +/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7746); +/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3608); +/** PURE_IMPORTS_START _mergeMap,_util_identity PURE_IMPORTS_END */ + + +function mergeAll(concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + return (0,_mergeMap__WEBPACK_IMPORTED_MODULE_0__/* .mergeMap */ .zg)(_util_identity__WEBPACK_IMPORTED_MODULE_1__/* .identity */ .y, concurrent); +} +//# sourceMappingURL=mergeAll.js.map + + +/***/ }), + +/***/ 7746: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "zg": () => (/* binding */ mergeMap) +/* harmony export */ }); +/* unused harmony exports MergeMapOperator, MergeMapSubscriber, flatMap */ +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(655); +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5709); +/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4072); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7604); +/** PURE_IMPORTS_START tslib,_map,_observable_from,_innerSubscribe PURE_IMPORTS_END */ + + + + +function mergeMap(project, resultSelector, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + if (typeof resultSelector === 'function') { + return function (source) { return source.pipe(mergeMap(function (a, i) { return (0,_observable_from__WEBPACK_IMPORTED_MODULE_0__/* .from */ .D)(project(a, i)).pipe((0,_map__WEBPACK_IMPORTED_MODULE_1__/* .map */ .U)(function (b, ii) { return resultSelector(a, b, i, ii); })); }, concurrent)); }; + } + else if (typeof resultSelector === 'number') { + concurrent = resultSelector; + } + return function (source) { return source.lift(new MergeMapOperator(project, concurrent)); }; +} +var MergeMapOperator = /*@__PURE__*/ (function () { + function MergeMapOperator(project, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + this.project = project; + this.concurrent = concurrent; + } + MergeMapOperator.prototype.call = function (observer, source) { + return source.subscribe(new MergeMapSubscriber(observer, this.project, this.concurrent)); + }; + return MergeMapOperator; +}()); + +var MergeMapSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_2__/* .__extends */ .ZT(MergeMapSubscriber, _super); + function MergeMapSubscriber(destination, project, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.concurrent = concurrent; + _this.hasCompleted = false; + _this.buffer = []; + _this.active = 0; + _this.index = 0; + return _this; + } + MergeMapSubscriber.prototype._next = function (value) { + if (this.active < this.concurrent) { + this._tryNext(value); + } + else { + this.buffer.push(value); + } + }; + MergeMapSubscriber.prototype._tryNext = function (value) { + var result; + var index = this.index++; + try { + result = this.project(value, index); + } + catch (err) { + this.destination.error(err); + return; + } + this.active++; + this._innerSub(result); + }; + MergeMapSubscriber.prototype._innerSub = function (ish) { + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__/* .SimpleInnerSubscriber */ .IY(this); + var destination = this.destination; + destination.add(innerSubscriber); + var innerSubscription = (0,_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__/* .innerSubscribe */ .ft)(ish, innerSubscriber); + if (innerSubscription !== innerSubscriber) { + destination.add(innerSubscription); + } + }; + MergeMapSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (this.active === 0 && this.buffer.length === 0) { + this.destination.complete(); + } + this.unsubscribe(); + }; + MergeMapSubscriber.prototype.notifyNext = function (innerValue) { + this.destination.next(innerValue); + }; + MergeMapSubscriber.prototype.notifyComplete = function () { + var buffer = this.buffer; + this.active--; + if (buffer.length > 0) { + this._next(buffer.shift()); + } + else if (this.active === 0 && this.hasCompleted) { + this.destination.complete(); + } + }; + return MergeMapSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__/* .SimpleOuterSubscriber */ .Ds)); + +var flatMap = (/* unused pure expression or super */ null && (mergeMap)); +//# sourceMappingURL=mergeMap.js.map + + +/***/ }), + +/***/ 3756: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "j": () => (/* binding */ mergeMapTo) +/* harmony export */ }); +/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7746); +/** PURE_IMPORTS_START _mergeMap PURE_IMPORTS_END */ + +function mergeMapTo(innerObservable, resultSelector, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + if (typeof resultSelector === 'function') { + return (0,_mergeMap__WEBPACK_IMPORTED_MODULE_0__/* .mergeMap */ .zg)(function () { return innerObservable; }, resultSelector, concurrent); + } + if (typeof resultSelector === 'number') { + concurrent = resultSelector; + } + return (0,_mergeMap__WEBPACK_IMPORTED_MODULE_0__/* .mergeMap */ .zg)(function () { return innerObservable; }, concurrent); +} +//# sourceMappingURL=mergeMapTo.js.map + + +/***/ }), + +/***/ 1421: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "O": () => (/* binding */ multicast) +}); + +// UNUSED EXPORTS: MulticastOperator + +// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js +var tslib_es6 = __webpack_require__(655); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subject.js +var Subject = __webpack_require__(211); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules +var Observable = __webpack_require__(4379); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscriber.js +var Subscriber = __webpack_require__(979); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscription.js + 1 modules +var Subscription = __webpack_require__(3884); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/refCount.js +var refCount = __webpack_require__(3018); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/observable/ConnectableObservable.js +/** PURE_IMPORTS_START tslib,_Subject,_Observable,_Subscriber,_Subscription,_operators_refCount PURE_IMPORTS_END */ + + + + + + +var ConnectableObservable = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(ConnectableObservable, _super); + function ConnectableObservable(source, subjectFactory) { + var _this = _super.call(this) || this; + _this.source = source; + _this.subjectFactory = subjectFactory; + _this._refCount = 0; + _this._isComplete = false; + return _this; + } + ConnectableObservable.prototype._subscribe = function (subscriber) { + return this.getSubject().subscribe(subscriber); + }; + ConnectableObservable.prototype.getSubject = function () { + var subject = this._subject; + if (!subject || subject.isStopped) { + this._subject = this.subjectFactory(); + } + return this._subject; + }; + ConnectableObservable.prototype.connect = function () { + var connection = this._connection; + if (!connection) { + this._isComplete = false; + connection = this._connection = new Subscription/* Subscription */.w(); + connection.add(this.source + .subscribe(new ConnectableSubscriber(this.getSubject(), this))); + if (connection.closed) { + this._connection = null; + connection = Subscription/* Subscription.EMPTY */.w.EMPTY; + } + } + return connection; + }; + ConnectableObservable.prototype.refCount = function () { + return (0,refCount/* refCount */.x)()(this); + }; + return ConnectableObservable; +}(Observable/* Observable */.y)); + +var connectableObservableDescriptor = /*@__PURE__*/ (function () { + var connectableProto = ConnectableObservable.prototype; + return { + operator: { value: null }, + _refCount: { value: 0, writable: true }, + _subject: { value: null, writable: true }, + _connection: { value: null, writable: true }, + _subscribe: { value: connectableProto._subscribe }, + _isComplete: { value: connectableProto._isComplete, writable: true }, + getSubject: { value: connectableProto.getSubject }, + connect: { value: connectableProto.connect }, + refCount: { value: connectableProto.refCount } + }; +})(); +var ConnectableSubscriber = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(ConnectableSubscriber, _super); + function ConnectableSubscriber(destination, connectable) { + var _this = _super.call(this, destination) || this; + _this.connectable = connectable; + return _this; + } + ConnectableSubscriber.prototype._error = function (err) { + this._unsubscribe(); + _super.prototype._error.call(this, err); + }; + ConnectableSubscriber.prototype._complete = function () { + this.connectable._isComplete = true; + this._unsubscribe(); + _super.prototype._complete.call(this); + }; + ConnectableSubscriber.prototype._unsubscribe = function () { + var connectable = this.connectable; + if (connectable) { + this.connectable = null; + var connection = connectable._connection; + connectable._refCount = 0; + connectable._subject = null; + connectable._connection = null; + if (connection) { + connection.unsubscribe(); + } + } + }; + return ConnectableSubscriber; +}(Subject/* SubjectSubscriber */.Yc)); +var RefCountOperator = /*@__PURE__*/ ((/* unused pure expression or super */ null && (function () { + function RefCountOperator(connectable) { + this.connectable = connectable; + } + RefCountOperator.prototype.call = function (subscriber, source) { + var connectable = this.connectable; + connectable._refCount++; + var refCounter = new RefCountSubscriber(subscriber, connectable); + var subscription = source.subscribe(refCounter); + if (!refCounter.closed) { + refCounter.connection = connectable.connect(); + } + return subscription; + }; + return RefCountOperator; +}()))); +var RefCountSubscriber = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(RefCountSubscriber, _super); + function RefCountSubscriber(destination, connectable) { + var _this = _super.call(this, destination) || this; + _this.connectable = connectable; + return _this; + } + RefCountSubscriber.prototype._unsubscribe = function () { + var connectable = this.connectable; + if (!connectable) { + this.connection = null; + return; + } + this.connectable = null; + var refCount = connectable._refCount; + if (refCount <= 0) { + this.connection = null; + return; + } + connectable._refCount = refCount - 1; + if (refCount > 1) { + this.connection = null; + return; + } + var connection = this.connection; + var sharedConnection = connectable._connection; + this.connection = null; + if (sharedConnection && (!connection || sharedConnection === connection)) { + sharedConnection.unsubscribe(); + } + }; + return RefCountSubscriber; +}(Subscriber/* Subscriber */.L)); +//# sourceMappingURL=ConnectableObservable.js.map + +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/multicast.js +/** PURE_IMPORTS_START _observable_ConnectableObservable PURE_IMPORTS_END */ + +function multicast(subjectOrSubjectFactory, selector) { + return function multicastOperatorFunction(source) { + var subjectFactory; + if (typeof subjectOrSubjectFactory === 'function') { + subjectFactory = subjectOrSubjectFactory; + } + else { + subjectFactory = function subjectFactory() { + return subjectOrSubjectFactory; + }; + } + if (typeof selector === 'function') { + return source.lift(new MulticastOperator(subjectFactory, selector)); + } + var connectable = Object.create(source, connectableObservableDescriptor); + connectable.source = source; + connectable.subjectFactory = subjectFactory; + return connectable; + }; +} +var MulticastOperator = /*@__PURE__*/ (function () { + function MulticastOperator(subjectFactory, selector) { + this.subjectFactory = subjectFactory; + this.selector = selector; + } + MulticastOperator.prototype.call = function (subscriber, source) { + var selector = this.selector; + var subject = this.subjectFactory(); + var subscription = selector(subject).subscribe(subscriber); + subscription.add(source.subscribe(subject)); + return subscription; + }; + return MulticastOperator; +}()); + +//# sourceMappingURL=multicast.js.map + + +/***/ }), + +/***/ 3018: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "x": () => (/* binding */ refCount) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function refCount() { + return function refCountOperatorFunction(source) { + return source.lift(new RefCountOperator(source)); + }; +} +var RefCountOperator = /*@__PURE__*/ (function () { + function RefCountOperator(connectable) { + this.connectable = connectable; + } + RefCountOperator.prototype.call = function (subscriber, source) { + var connectable = this.connectable; + connectable._refCount++; + var refCounter = new RefCountSubscriber(subscriber, connectable); + var subscription = source.subscribe(refCounter); + if (!refCounter.closed) { + refCounter.connection = connectable.connect(); + } + return subscription; + }; + return RefCountOperator; +}()); +var RefCountSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(RefCountSubscriber, _super); + function RefCountSubscriber(destination, connectable) { + var _this = _super.call(this, destination) || this; + _this.connectable = connectable; + return _this; + } + RefCountSubscriber.prototype._unsubscribe = function () { + var connectable = this.connectable; + if (!connectable) { + this.connection = null; + return; + } + this.connectable = null; + var refCount = connectable._refCount; + if (refCount <= 0) { + this.connection = null; + return; + } + connectable._refCount = refCount - 1; + if (refCount > 1) { + this.connection = null; + return; + } + var connection = this.connection; + var sharedConnection = connectable._connection; + this.connection = null; + if (sharedConnection && (!connection || sharedConnection === connection)) { + sharedConnection.unsubscribe(); + } + }; + return RefCountSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); +//# sourceMappingURL=refCount.js.map + + +/***/ }), + +/***/ 2807: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "R": () => (/* binding */ scan) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function scan(accumulator, seed) { + var hasSeed = false; + if (arguments.length >= 2) { + hasSeed = true; + } + return function scanOperatorFunction(source) { + return source.lift(new ScanOperator(accumulator, seed, hasSeed)); + }; +} +var ScanOperator = /*@__PURE__*/ (function () { + function ScanOperator(accumulator, seed, hasSeed) { + if (hasSeed === void 0) { + hasSeed = false; + } + this.accumulator = accumulator; + this.seed = seed; + this.hasSeed = hasSeed; + } + ScanOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ScanSubscriber(subscriber, this.accumulator, this.seed, this.hasSeed)); + }; + return ScanOperator; +}()); +var ScanSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(ScanSubscriber, _super); + function ScanSubscriber(destination, accumulator, _seed, hasSeed) { + var _this = _super.call(this, destination) || this; + _this.accumulator = accumulator; + _this._seed = _seed; + _this.hasSeed = hasSeed; + _this.index = 0; + return _this; + } + Object.defineProperty(ScanSubscriber.prototype, "seed", { + get: function () { + return this._seed; + }, + set: function (value) { + this.hasSeed = true; + this._seed = value; + }, + enumerable: true, + configurable: true + }); + ScanSubscriber.prototype._next = function (value) { + if (!this.hasSeed) { + this.seed = value; + this.destination.next(value); + } + else { + return this._tryNext(value); + } + }; + ScanSubscriber.prototype._tryNext = function (value) { + var index = this.index++; + var result; + try { + result = this.accumulator(this.seed, value, index); + } + catch (err) { + this.destination.error(err); + } + this.seed = result; + this.destination.next(result); + }; + return ScanSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); +//# sourceMappingURL=scan.js.map + + +/***/ }), + +/***/ 9095: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "B": () => (/* binding */ share) +/* harmony export */ }); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1421); +/* harmony import */ var _refCount__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3018); +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(211); +/** PURE_IMPORTS_START _multicast,_refCount,_Subject PURE_IMPORTS_END */ + + + +function shareSubjectFactory() { + return new _Subject__WEBPACK_IMPORTED_MODULE_0__/* .Subject */ .xQ(); +} +function share() { + return function (source) { return (0,_refCount__WEBPACK_IMPORTED_MODULE_1__/* .refCount */ .x)()((0,_multicast__WEBPACK_IMPORTED_MODULE_2__/* .multicast */ .O)(shareSubjectFactory)(source)); }; +} +//# sourceMappingURL=share.js.map + + +/***/ }), + +/***/ 7006: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "d": () => (/* binding */ shareReplay) +/* harmony export */ }); +/* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2135); +/** PURE_IMPORTS_START _ReplaySubject PURE_IMPORTS_END */ + +function shareReplay(configOrBufferSize, windowTime, scheduler) { + var config; + if (configOrBufferSize && typeof configOrBufferSize === 'object') { + config = configOrBufferSize; + } + else { + config = { + bufferSize: configOrBufferSize, + windowTime: windowTime, + refCount: false, + scheduler: scheduler, + }; + } + return function (source) { return source.lift(shareReplayOperator(config)); }; +} +function shareReplayOperator(_a) { + var _b = _a.bufferSize, bufferSize = _b === void 0 ? Number.POSITIVE_INFINITY : _b, _c = _a.windowTime, windowTime = _c === void 0 ? Number.POSITIVE_INFINITY : _c, useRefCount = _a.refCount, scheduler = _a.scheduler; + var subject; + var refCount = 0; + var subscription; + var hasError = false; + var isComplete = false; + return function shareReplayOperation(source) { + refCount++; + var innerSub; + if (!subject || hasError) { + hasError = false; + subject = new _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__/* .ReplaySubject */ .t(bufferSize, windowTime, scheduler); + innerSub = subject.subscribe(this); + subscription = source.subscribe({ + next: function (value) { + subject.next(value); + }, + error: function (err) { + hasError = true; + subject.error(err); + }, + complete: function () { + isComplete = true; + subscription = undefined; + subject.complete(); + }, + }); + if (isComplete) { + subscription = undefined; + } + } + else { + innerSub = subject.subscribe(this); + } + this.add(function () { + refCount--; + innerSub.unsubscribe(); + innerSub = undefined; + if (subscription && !isComplete && useRefCount && refCount === 0) { + subscription.unsubscribe(); + subscription = undefined; + subject = undefined; + } + }); + }; +} +//# sourceMappingURL=shareReplay.js.map + + +/***/ }), + +/***/ 3485: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "O": () => (/* binding */ startWith) +/* harmony export */ }); +/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9795); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7507); +/** PURE_IMPORTS_START _observable_concat,_util_isScheduler PURE_IMPORTS_END */ + + +function startWith() { + var array = []; + for (var _i = 0; _i < arguments.length; _i++) { + array[_i] = arguments[_i]; + } + var scheduler = array[array.length - 1]; + if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__/* .isScheduler */ .K)(scheduler)) { + array.pop(); + return function (source) { return (0,_observable_concat__WEBPACK_IMPORTED_MODULE_1__/* .concat */ .z)(array, source, scheduler); }; + } + else { + return function (source) { return (0,_observable_concat__WEBPACK_IMPORTED_MODULE_1__/* .concat */ .z)(array, source); }; + } +} +//# sourceMappingURL=startWith.js.map + + +/***/ }), + +/***/ 6381: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "w": () => (/* binding */ switchMap) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(655); +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5709); +/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4072); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7604); +/** PURE_IMPORTS_START tslib,_map,_observable_from,_innerSubscribe PURE_IMPORTS_END */ + + + + +function switchMap(project, resultSelector) { + if (typeof resultSelector === 'function') { + return function (source) { return source.pipe(switchMap(function (a, i) { return (0,_observable_from__WEBPACK_IMPORTED_MODULE_0__/* .from */ .D)(project(a, i)).pipe((0,_map__WEBPACK_IMPORTED_MODULE_1__/* .map */ .U)(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; + } + return function (source) { return source.lift(new SwitchMapOperator(project)); }; +} +var SwitchMapOperator = /*@__PURE__*/ (function () { + function SwitchMapOperator(project) { + this.project = project; + } + SwitchMapOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SwitchMapSubscriber(subscriber, this.project)); + }; + return SwitchMapOperator; +}()); +var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_2__/* .__extends */ .ZT(SwitchMapSubscriber, _super); + function SwitchMapSubscriber(destination, project) { + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.index = 0; + return _this; + } + SwitchMapSubscriber.prototype._next = function (value) { + var result; + var index = this.index++; + try { + result = this.project(value, index); + } + catch (error) { + this.destination.error(error); + return; + } + this._innerSub(result); + }; + SwitchMapSubscriber.prototype._innerSub = function (result) { + var innerSubscription = this.innerSubscription; + if (innerSubscription) { + innerSubscription.unsubscribe(); + } + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__/* .SimpleInnerSubscriber */ .IY(this); + var destination = this.destination; + destination.add(innerSubscriber); + this.innerSubscription = (0,_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__/* .innerSubscribe */ .ft)(result, innerSubscriber); + if (this.innerSubscription !== innerSubscriber) { + destination.add(this.innerSubscription); + } + }; + SwitchMapSubscriber.prototype._complete = function () { + var innerSubscription = this.innerSubscription; + if (!innerSubscription || innerSubscription.closed) { + _super.prototype._complete.call(this); + } + this.unsubscribe(); + }; + SwitchMapSubscriber.prototype._unsubscribe = function () { + this.innerSubscription = undefined; + }; + SwitchMapSubscriber.prototype.notifyComplete = function () { + this.innerSubscription = undefined; + if (this.isStopped) { + _super.prototype._complete.call(this); + } + }; + SwitchMapSubscriber.prototype.notifyNext = function (innerValue) { + this.destination.next(innerValue); + }; + return SwitchMapSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__/* .SimpleOuterSubscriber */ .Ds)); +//# sourceMappingURL=switchMap.js.map + + +/***/ }), + +/***/ 1198: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "c": () => (/* binding */ switchMapTo) +/* harmony export */ }); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6381); +/** PURE_IMPORTS_START _switchMap PURE_IMPORTS_END */ + +function switchMapTo(innerObservable, resultSelector) { + return resultSelector ? (0,_switchMap__WEBPACK_IMPORTED_MODULE_0__/* .switchMap */ .w)(function () { return innerObservable; }, resultSelector) : (0,_switchMap__WEBPACK_IMPORTED_MODULE_0__/* .switchMap */ .w)(function () { return innerObservable; }); +} +//# sourceMappingURL=switchMapTo.js.map + + +/***/ }), + +/***/ 1015: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "q": () => (/* binding */ take) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(655); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(979); +/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6565); +/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5631); +/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ + + + + +function take(count) { + return function (source) { + if (count === 0) { + return (0,_observable_empty__WEBPACK_IMPORTED_MODULE_0__/* .empty */ .c)(); + } + else { + return source.lift(new TakeOperator(count)); + } + }; +} +var TakeOperator = /*@__PURE__*/ (function () { + function TakeOperator(total) { + this.total = total; + if (this.total < 0) { + throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_1__/* .ArgumentOutOfRangeError */ .W; + } + } + TakeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TakeSubscriber(subscriber, this.total)); + }; + return TakeOperator; +}()); +var TakeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_2__/* .__extends */ .ZT(TakeSubscriber, _super); + function TakeSubscriber(destination, total) { + var _this = _super.call(this, destination) || this; + _this.total = total; + _this.count = 0; + return _this; + } + TakeSubscriber.prototype._next = function (value) { + var total = this.total; + var count = ++this.count; + if (count <= total) { + this.destination.next(value); + if (count === total) { + this.destination.complete(); + this.unsubscribe(); + } + } + }; + return TakeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__/* .Subscriber */ .L)); +//# sourceMappingURL=take.js.map + + +/***/ }), + +/***/ 1558: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "R": () => (/* binding */ takeUntil) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(655); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7604); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + + +function takeUntil(notifier) { + return function (source) { return source.lift(new TakeUntilOperator(notifier)); }; +} +var TakeUntilOperator = /*@__PURE__*/ (function () { + function TakeUntilOperator(notifier) { + this.notifier = notifier; + } + TakeUntilOperator.prototype.call = function (subscriber, source) { + var takeUntilSubscriber = new TakeUntilSubscriber(subscriber); + var notifierSubscription = (0,_innerSubscribe__WEBPACK_IMPORTED_MODULE_0__/* .innerSubscribe */ .ft)(this.notifier, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_0__/* .SimpleInnerSubscriber */ .IY(takeUntilSubscriber)); + if (notifierSubscription && !takeUntilSubscriber.seenValue) { + takeUntilSubscriber.add(notifierSubscription); + return source.subscribe(takeUntilSubscriber); + } + return takeUntilSubscriber; + }; + return TakeUntilOperator; +}()); +var TakeUntilSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_1__/* .__extends */ .ZT(TakeUntilSubscriber, _super); + function TakeUntilSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.seenValue = false; + return _this; + } + TakeUntilSubscriber.prototype.notifyNext = function () { + this.seenValue = true; + this.complete(); + }; + TakeUntilSubscriber.prototype.notifyComplete = function () { + }; + return TakeUntilSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_0__/* .SimpleOuterSubscriber */ .Ds)); +//# sourceMappingURL=takeUntil.js.map + + +/***/ }), + +/***/ 3068: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "b": () => (/* binding */ tap) +/* harmony export */ }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(979); +/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3306); +/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4156); +/** PURE_IMPORTS_START tslib,_Subscriber,_util_noop,_util_isFunction PURE_IMPORTS_END */ + + + + +function tap(nextOrObserver, error, complete) { + return function tapOperatorFunction(source) { + return source.lift(new DoOperator(nextOrObserver, error, complete)); + }; +} +var DoOperator = /*@__PURE__*/ (function () { + function DoOperator(nextOrObserver, error, complete) { + this.nextOrObserver = nextOrObserver; + this.error = error; + this.complete = complete; + } + DoOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TapSubscriber(subscriber, this.nextOrObserver, this.error, this.complete)); + }; + return DoOperator; +}()); +var TapSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(TapSubscriber, _super); + function TapSubscriber(destination, observerOrNext, error, complete) { + var _this = _super.call(this, destination) || this; + _this._tapNext = _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; + _this._tapError = _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; + _this._tapComplete = _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; + _this._tapError = error || _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; + _this._tapComplete = complete || _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; + if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_2__/* .isFunction */ .m)(observerOrNext)) { + _this._context = _this; + _this._tapNext = observerOrNext; + } + else if (observerOrNext) { + _this._context = observerOrNext; + _this._tapNext = observerOrNext.next || _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; + _this._tapError = observerOrNext.error || _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; + _this._tapComplete = observerOrNext.complete || _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; + } + return _this; + } + TapSubscriber.prototype._next = function (value) { + try { + this._tapNext.call(this._context, value); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(value); + }; + TapSubscriber.prototype._error = function (err) { + try { + this._tapError.call(this._context, err); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.error(err); + }; + TapSubscriber.prototype._complete = function () { + try { + this._tapComplete.call(this._context); + } + catch (err) { + this.destination.error(err); + return; + } + return this.destination.complete(); + }; + return TapSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__/* .Subscriber */ .L)); +//# sourceMappingURL=tap.js.map + + +/***/ }), + +/***/ 3109: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "r": () => (/* binding */ scheduleArray) +/* harmony export */ }); +/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4379); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3884); +/** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ + + +function scheduleArray(input, scheduler) { + return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) { + var sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__/* .Subscription */ .w(); + var i = 0; + sub.add(scheduler.schedule(function () { + if (i === input.length) { + subscriber.complete(); + return; + } + subscriber.next(input[i++]); + if (!subscriber.closed) { + sub.add(this.schedule()); + } + })); + return sub; + }); +} +//# sourceMappingURL=scheduleArray.js.map + + +/***/ }), + +/***/ 6114: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "o": () => (/* binding */ AsyncAction) +}); + +// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js +var tslib_es6 = __webpack_require__(655); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscription.js + 1 modules +var Subscription = __webpack_require__(3884); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/Action.js +/** PURE_IMPORTS_START tslib,_Subscription PURE_IMPORTS_END */ + + +var Action = /*@__PURE__*/ (function (_super) { + 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 */.w)); + +//# sourceMappingURL=Action.js.map + +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsyncAction.js +/** PURE_IMPORTS_START tslib,_Action PURE_IMPORTS_END */ + + +var AsyncAction = /*@__PURE__*/ (function (_super) { + 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) { + 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 = this.id || this.requestAsyncId(scheduler, this.id, delay); + return this; + }; + AsyncAction.prototype.requestAsyncId = function (scheduler, id, delay) { + if (delay === void 0) { + delay = 0; + } + return 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; + } + 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 = undefined; + try { + this.work(state); + } + catch (e) { + errored = true; + errorValue = !!e && e || new Error(e); + } + if (errored) { + this.unsubscribe(); + return errorValue; + } + }; + AsyncAction.prototype._unsubscribe = function () { + var id = this.id; + var scheduler = this.scheduler; + var actions = scheduler.actions; + var index = actions.indexOf(this); + this.work = null; + this.state = null; + this.pending = false; + this.scheduler = null; + if (index !== -1) { + actions.splice(index, 1); + } + if (id != null) { + this.id = this.recycleAsyncId(scheduler, id, null); + } + this.delay = null; + }; + return AsyncAction; +}(Action)); + +//# sourceMappingURL=AsyncAction.js.map + + +/***/ }), + +/***/ 2980: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "v": () => (/* binding */ AsyncScheduler) +}); + +// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js +var tslib_es6 = __webpack_require__(655); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/Scheduler.js +var Scheduler = /*@__PURE__*/ (function () { + function Scheduler(SchedulerAction, now) { + if (now === void 0) { + now = Scheduler.now; + } + this.SchedulerAction = SchedulerAction; + this.now = now; + } + Scheduler.prototype.schedule = function (work, delay, state) { + if (delay === void 0) { + delay = 0; + } + return new this.SchedulerAction(this, work).schedule(state, delay); + }; + Scheduler.now = function () { return Date.now(); }; + return Scheduler; +}()); + +//# sourceMappingURL=Scheduler.js.map + +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsyncScheduler.js +/** PURE_IMPORTS_START tslib,_Scheduler PURE_IMPORTS_END */ + + +var AsyncScheduler = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(AsyncScheduler, _super); + function AsyncScheduler(SchedulerAction, now) { + if (now === void 0) { + now = Scheduler.now; + } + var _this = _super.call(this, SchedulerAction, function () { + if (AsyncScheduler.delegate && AsyncScheduler.delegate !== _this) { + return AsyncScheduler.delegate.now(); + } + else { + return now(); + } + }) || this; + _this.actions = []; + _this.active = false; + _this.scheduled = undefined; + return _this; + } + AsyncScheduler.prototype.schedule = function (work, delay, state) { + if (delay === void 0) { + delay = 0; + } + if (AsyncScheduler.delegate && AsyncScheduler.delegate !== this) { + return AsyncScheduler.delegate.schedule(work, delay, state); + } + else { + return _super.prototype.schedule.call(this, work, delay, state); + } + }; + 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 + + +/***/ }), + +/***/ 964: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "P": () => (/* binding */ async) +/* harmony export */ }); +/* unused harmony export asyncScheduler */ +/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6114); +/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2980); +/** PURE_IMPORTS_START _AsyncAction,_AsyncScheduler PURE_IMPORTS_END */ + + +var asyncScheduler = /*@__PURE__*/ new _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__/* .AsyncScheduler */ .v(_AsyncAction__WEBPACK_IMPORTED_MODULE_1__/* .AsyncAction */ .o); +var async = asyncScheduler; +//# sourceMappingURL=async.js.map + + +/***/ }), + +/***/ 999: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "hZ": () => (/* binding */ iterator) +/* harmony export */ }); +/* unused harmony exports getSymbolIterator, $$iterator */ +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function getSymbolIterator() { + if (typeof Symbol !== 'function' || !Symbol.iterator) { + return '@@iterator'; + } + return Symbol.iterator; +} +var iterator = /*@__PURE__*/ getSymbolIterator(); +var $$iterator = (/* unused pure expression or super */ null && (iterator)); +//# sourceMappingURL=iterator.js.map + + +/***/ }), + +/***/ 5050: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "L": () => (/* binding */ observable) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var observable = /*@__PURE__*/ (function () { return typeof Symbol === 'function' && Symbol.observable || '@@observable'; })(); +//# sourceMappingURL=observable.js.map + + +/***/ }), + +/***/ 3142: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "b": () => (/* binding */ rxSubscriber) +/* harmony export */ }); +/* unused harmony export $$rxSubscriber */ +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var rxSubscriber = /*@__PURE__*/ (function () { + return typeof Symbol === 'function' + ? /*@__PURE__*/ Symbol('rxSubscriber') + : '@@rxSubscriber_' + /*@__PURE__*/ Math.random(); +})(); +var $$rxSubscriber = (/* unused pure expression or super */ null && (rxSubscriber)); +//# sourceMappingURL=rxSubscriber.js.map + + +/***/ }), + +/***/ 6565: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "W": () => (/* binding */ ArgumentOutOfRangeError) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var ArgumentOutOfRangeErrorImpl = /*@__PURE__*/ (function () { + function ArgumentOutOfRangeErrorImpl() { + Error.call(this); + this.message = 'argument out of range'; + this.name = 'ArgumentOutOfRangeError'; + return this; + } + ArgumentOutOfRangeErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); + return ArgumentOutOfRangeErrorImpl; +})(); +var ArgumentOutOfRangeError = ArgumentOutOfRangeErrorImpl; +//# sourceMappingURL=ArgumentOutOfRangeError.js.map + + +/***/ }), + +/***/ 1016: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "N": () => (/* binding */ ObjectUnsubscribedError) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var ObjectUnsubscribedErrorImpl = /*@__PURE__*/ (function () { + function ObjectUnsubscribedErrorImpl() { + Error.call(this); + this.message = 'object unsubscribed'; + this.name = 'ObjectUnsubscribedError'; + return this; + } + ObjectUnsubscribedErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); + return ObjectUnsubscribedErrorImpl; +})(); +var ObjectUnsubscribedError = ObjectUnsubscribedErrorImpl; +//# sourceMappingURL=ObjectUnsubscribedError.js.map + + +/***/ }), + +/***/ 1644: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "z": () => (/* binding */ hostReportError) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function hostReportError(err) { + setTimeout(function () { throw err; }, 0); +} +//# sourceMappingURL=hostReportError.js.map + + +/***/ }), + +/***/ 3608: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "y": () => (/* binding */ identity) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function identity(x) { + return x; +} +//# sourceMappingURL=identity.js.map + + +/***/ }), + +/***/ 9026: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "k": () => (/* binding */ isArray) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var isArray = /*@__PURE__*/ (function () { return Array.isArray || (function (x) { return x && typeof x.length === 'number'; }); })(); +//# sourceMappingURL=isArray.js.map + + +/***/ }), + +/***/ 9217: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "z": () => (/* binding */ isArrayLike) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var isArrayLike = (function (x) { return x && typeof x.length === 'number' && typeof x !== 'function'; }); +//# sourceMappingURL=isArrayLike.js.map + + +/***/ }), + +/***/ 9914: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "J": () => (/* binding */ isDate) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function isDate(value) { + return value instanceof Date && !isNaN(+value); +} +//# sourceMappingURL=isDate.js.map + + +/***/ }), + +/***/ 4156: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "m": () => (/* binding */ isFunction) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function isFunction(x) { + return typeof x === 'function'; +} +//# sourceMappingURL=isFunction.js.map + + +/***/ }), + +/***/ 5812: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "k": () => (/* binding */ isNumeric) +/* harmony export */ }); +/* harmony import */ var _isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9026); +/** PURE_IMPORTS_START _isArray PURE_IMPORTS_END */ + +function isNumeric(val) { + return !(0,_isArray__WEBPACK_IMPORTED_MODULE_0__/* .isArray */ .k)(val) && (val - parseFloat(val) + 1) >= 0; +} +//# sourceMappingURL=isNumeric.js.map + + +/***/ }), + +/***/ 2009: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "K": () => (/* binding */ isObject) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function isObject(x) { + return x !== null && typeof x === 'object'; +} +//# sourceMappingURL=isObject.js.map + + +/***/ }), + +/***/ 336: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "t": () => (/* binding */ isPromise) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function isPromise(value) { + return !!value && typeof value.subscribe !== 'function' && typeof value.then === 'function'; +} +//# sourceMappingURL=isPromise.js.map + + +/***/ }), + +/***/ 7507: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "K": () => (/* binding */ isScheduler) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function isScheduler(value) { + return value && typeof value.schedule === 'function'; +} +//# sourceMappingURL=isScheduler.js.map + + +/***/ }), + +/***/ 3306: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (/* binding */ noop) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function noop() { } +//# sourceMappingURL=noop.js.map + + +/***/ }), + +/***/ 7843: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "s": () => (/* binding */ subscribeTo) +}); + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeToArray.js +var subscribeToArray = __webpack_require__(6900); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/hostReportError.js +var hostReportError = __webpack_require__(1644); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeToPromise.js +/** PURE_IMPORTS_START _hostReportError PURE_IMPORTS_END */ + +var subscribeToPromise = function (promise) { + return function (subscriber) { + promise.then(function (value) { + if (!subscriber.closed) { + subscriber.next(value); + subscriber.complete(); + } + }, function (err) { return subscriber.error(err); }) + .then(null, hostReportError/* hostReportError */.z); + return subscriber; + }; +}; +//# sourceMappingURL=subscribeToPromise.js.map + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/symbol/iterator.js +var symbol_iterator = __webpack_require__(999); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeToIterable.js +/** PURE_IMPORTS_START _symbol_iterator PURE_IMPORTS_END */ + +var subscribeToIterable = function (iterable) { + return function (subscriber) { + var iterator = iterable[symbol_iterator/* iterator */.hZ](); + do { + var item = void 0; + try { + item = iterator.next(); + } + catch (err) { + subscriber.error(err); + return subscriber; + } + if (item.done) { + subscriber.complete(); + break; + } + subscriber.next(item.value); + if (subscriber.closed) { + break; + } + } while (true); + if (typeof iterator.return === 'function') { + subscriber.add(function () { + if (iterator.return) { + iterator.return(); + } + }); + } + return subscriber; + }; +}; +//# sourceMappingURL=subscribeToIterable.js.map + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/symbol/observable.js +var observable = __webpack_require__(5050); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeToObservable.js +/** PURE_IMPORTS_START _symbol_observable PURE_IMPORTS_END */ + +var subscribeToObservable = function (obj) { + return function (subscriber) { + var obs = obj[observable/* observable */.L](); + if (typeof obs.subscribe !== 'function') { + throw new TypeError('Provided object does not correctly implement Symbol.observable'); + } + else { + return obs.subscribe(subscriber); + } + }; +}; +//# sourceMappingURL=subscribeToObservable.js.map + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isArrayLike.js +var isArrayLike = __webpack_require__(9217); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isPromise.js +var isPromise = __webpack_require__(336); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isObject.js +var isObject = __webpack_require__(2009); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeTo.js +/** PURE_IMPORTS_START _subscribeToArray,_subscribeToPromise,_subscribeToIterable,_subscribeToObservable,_isArrayLike,_isPromise,_isObject,_symbol_iterator,_symbol_observable PURE_IMPORTS_END */ + + + + + + + + + +var subscribeTo = function (result) { + if (!!result && typeof result[observable/* observable */.L] === 'function') { + return subscribeToObservable(result); + } + else if ((0,isArrayLike/* isArrayLike */.z)(result)) { + return (0,subscribeToArray/* subscribeToArray */.V)(result); + } + else if ((0,isPromise/* isPromise */.t)(result)) { + return subscribeToPromise(result); + } + else if (!!result && typeof result[symbol_iterator/* iterator */.hZ] === 'function') { + return subscribeToIterable(result); + } + else { + var value = (0,isObject/* isObject */.K)(result) ? 'an invalid object' : "'" + result + "'"; + var msg = "You provided " + value + " where a stream was expected." + + ' You can provide an Observable, Promise, Array, or Iterable.'; + throw new TypeError(msg); + } +}; +//# sourceMappingURL=subscribeTo.js.map + + +/***/ }), + +/***/ 6900: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "V": () => (/* binding */ subscribeToArray) +/* harmony export */ }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +var subscribeToArray = function (array) { + return function (subscriber) { + for (var i = 0, len = array.length; i < len && !subscriber.closed; i++) { + subscriber.next(array[i]); + } + subscriber.complete(); + }; +}; +//# sourceMappingURL=subscribeToArray.js.map + + +/***/ }), + +/***/ 2080: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "D": () => (/* binding */ subscribeToResult) +}); + +// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js +var tslib_es6 = __webpack_require__(655); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscriber.js +var Subscriber = __webpack_require__(979); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/InnerSubscriber.js +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +var InnerSubscriber = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(InnerSubscriber, _super); + function InnerSubscriber(parent, outerValue, outerIndex) { + var _this = _super.call(this) || this; + _this.parent = parent; + _this.outerValue = outerValue; + _this.outerIndex = outerIndex; + _this.index = 0; + return _this; + } + InnerSubscriber.prototype._next = function (value) { + this.parent.notifyNext(this.outerValue, value, this.outerIndex, this.index++, this); + }; + InnerSubscriber.prototype._error = function (error) { + this.parent.notifyError(error, this); + this.unsubscribe(); + }; + InnerSubscriber.prototype._complete = function () { + this.parent.notifyComplete(this); + this.unsubscribe(); + }; + return InnerSubscriber; +}(Subscriber/* Subscriber */.L)); + +//# sourceMappingURL=InnerSubscriber.js.map + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeTo.js + 3 modules +var subscribeTo = __webpack_require__(7843); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules +var Observable = __webpack_require__(4379); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeToResult.js +/** PURE_IMPORTS_START _InnerSubscriber,_subscribeTo,_Observable PURE_IMPORTS_END */ + + + +function subscribeToResult(outerSubscriber, result, outerValue, outerIndex, innerSubscriber) { + if (innerSubscriber === void 0) { + innerSubscriber = new InnerSubscriber(outerSubscriber, outerValue, outerIndex); + } + if (innerSubscriber.closed) { + return undefined; + } + if (result instanceof Observable/* Observable */.y) { + return result.subscribe(innerSubscriber); + } + return (0,subscribeTo/* subscribeTo */.s)(result)(innerSubscriber); +} +//# sourceMappingURL=subscribeToResult.js.map + + +/***/ }), + +/***/ 655: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "ZT": () => (/* binding */ __extends) +/* harmony export */ }); +/* unused harmony exports __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __createBinding, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __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 (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); +}; + +function __extends(d, b) { + 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 }; + } +} + +function __createBinding(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +} + +function __exportStar(m, exports) { + for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) exports[p] = 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; +} + +function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; +} + +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 __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; +}; + +function __importStar(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result.default = 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; +} + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // 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 */ +/******/ (() => { +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = (module) => { +/******/ var getter = module && module.__esModule ? +/******/ () => (module['default']) : +/******/ () => (module); +/******/ __webpack_require__.d(getter, { a: getter }); +/******/ return getter; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (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/global */ +/******/ (() => { +/******/ __webpack_require__.g = (function() { +/******/ if (typeof globalThis === 'object') return globalThis; +/******/ try { +/******/ return this || new Function('return this')(); +/******/ } catch (e) { +/******/ if (typeof window === 'object') return window; +/******/ } +/******/ })(); +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (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. +(() => { +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "default": () => (/* binding */ src) +}); + +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/createClass.js +var createClass = __webpack_require__(5991); +// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js +var inheritsLoose = __webpack_require__(1788); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subject.js +var Subject = __webpack_require__(211); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/ReplaySubject.js + 4 modules +var ReplaySubject = __webpack_require__(2135); +// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js +var tslib_es6 = __webpack_require__(655); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/ObjectUnsubscribedError.js +var ObjectUnsubscribedError = __webpack_require__(1016); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/BehaviorSubject.js +/** PURE_IMPORTS_START tslib,_Subject,_util_ObjectUnsubscribedError PURE_IMPORTS_END */ + + + +var BehaviorSubject = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(BehaviorSubject, _super); + function BehaviorSubject(_value) { + var _this = _super.call(this) || this; + _this._value = _value; + return _this; + } + Object.defineProperty(BehaviorSubject.prototype, "value", { + get: function () { + return this.getValue(); + }, + enumerable: true, + configurable: true + }); + BehaviorSubject.prototype._subscribe = function (subscriber) { + var subscription = _super.prototype._subscribe.call(this, subscriber); + if (subscription && !subscription.closed) { + subscriber.next(this._value); + } + return subscription; + }; + BehaviorSubject.prototype.getValue = function () { + if (this.hasError) { + throw this.thrownError; + } + else if (this.closed) { + throw new ObjectUnsubscribedError/* ObjectUnsubscribedError */.N(); + } + else { + return this._value; + } + }; + BehaviorSubject.prototype.next = function (value) { + _super.prototype.next.call(this, this._value = value); + }; + return BehaviorSubject; +}(Subject/* Subject */.xQ)); + +//# sourceMappingURL=BehaviorSubject.js.map + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js +var of = __webpack_require__(8170); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/combineLatest.js +var combineLatest = __webpack_require__(5142); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/concat.js +var concat = __webpack_require__(9795); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/merge.js +var merge = __webpack_require__(4370); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/empty.js +var empty = __webpack_require__(5631); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/takeUntil.js +var takeUntil = __webpack_require__(1558); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/map.js +var map = __webpack_require__(5709); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/distinctUntilChanged.js +var distinctUntilChanged = __webpack_require__(1931); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMap.js +var mergeMap = __webpack_require__(7746); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/shareReplay.js +var shareReplay = __webpack_require__(7006); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/multicast.js + 1 modules +var multicast = __webpack_require__(1421); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/publish.js +/** PURE_IMPORTS_START _Subject,_multicast PURE_IMPORTS_END */ + + +function publish(selector) { + return selector ? + (0,multicast/* multicast */.O)(function () { return new Subject/* Subject */.xQ(); }, selector) : + (0,multicast/* multicast */.O)(new Subject/* Subject */.xQ()); +} +//# sourceMappingURL=publish.js.map + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/filter.js +var filter = __webpack_require__(6008); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/share.js +var share = __webpack_require__(9095); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/startWith.js +var startWith = __webpack_require__(3485); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/take.js +var take = __webpack_require__(1015); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mapTo.js +var mapTo = __webpack_require__(5602); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscriber.js +var Subscriber = __webpack_require__(979); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/skipWhile.js +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function skipWhile(predicate) { + return function (source) { return source.lift(new SkipWhileOperator(predicate)); }; +} +var SkipWhileOperator = /*@__PURE__*/ (function () { + function SkipWhileOperator(predicate) { + this.predicate = predicate; + } + SkipWhileOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SkipWhileSubscriber(subscriber, this.predicate)); + }; + return SkipWhileOperator; +}()); +var SkipWhileSubscriber = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(SkipWhileSubscriber, _super); + function SkipWhileSubscriber(destination, predicate) { + var _this = _super.call(this, destination) || this; + _this.predicate = predicate; + _this.skipping = true; + _this.index = 0; + return _this; + } + SkipWhileSubscriber.prototype._next = function (value) { + var destination = this.destination; + if (this.skipping) { + this.tryCallPredicate(value); + } + if (!this.skipping) { + destination.next(value); + } + }; + SkipWhileSubscriber.prototype.tryCallPredicate = function (value) { + try { + var result = this.predicate(value, this.index++); + this.skipping = Boolean(result); + } + catch (err) { + this.destination.error(err); + } + }; + return SkipWhileSubscriber; +}(Subscriber/* Subscriber */.L)); +//# sourceMappingURL=skipWhile.js.map + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/switchMapTo.js +var switchMapTo = __webpack_require__(1198); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMapTo.js +var mergeMapTo = __webpack_require__(3756); +// EXTERNAL MODULE: ./src/compat/event_listeners.ts + 4 modules +var event_listeners = __webpack_require__(1473); +;// CONCATENATED MODULE: ./src/compat/fullscreen.ts /** * Copyright 2015 CANAL+ Group * @@ -40638,83 +43569,125 @@ function findFirstCommonStartTime(prevTimeline, newElements) { * 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") { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + elt.webkitRequestFullscreen // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + (Element.ALLOW_KEYBOARD_INPUT); + } + } +} +/** + * Exit fullscreen if an element is currently in fullscreen. + */ -function constructTimelineFromPreviousTimeline(newElements, prevTimeline, scaledPeriodStart) { - var _a; // Find first index in both timeline where a common segment is found. - +function fullscreen_exitFullscreen() { + if (fullscreen_isFullscreen()) { + var doc = document; + /* eslint-disable @typescript-eslint/unbound-method */ - var commonStartInfo = findFirstCommonStartTime(prevTimeline, newElements); + if (typeof doc.exitFullscreen === "function") { + /* eslint-enable @typescript-eslint/unbound-method */ - if (commonStartInfo === null) { - log/* default.warn */.Z.warn("DASH: Cannot perform \"based\" update. Common segment not found."); - return constructTimelineFromElements(newElements, scaledPeriodStart); + /* 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} + */ - var prevSegmentsIdx = commonStartInfo.prevSegmentsIdx, - newElementsIdx = commonStartInfo.newElementsIdx, - repeatNumberInPrevSegments = commonStartInfo.repeatNumberInPrevSegments, - repeatNumberInNewElements = commonStartInfo.repeatNumberInNewElements; - /** Guess of the number of elements in common. */ - var numberCommonEltGuess = prevTimeline.length - prevSegmentsIdx; - var lastCommonEltNewEltsIdx = numberCommonEltGuess + newElementsIdx - 1; +function fullscreen_isFullscreen() { + var doc = document; + return doc.fullscreenElement != null || doc.mozFullScreenElement != null || doc.webkitFullscreenElement != null || doc.msFullscreenElement != null; +} - if (lastCommonEltNewEltsIdx >= newElements.length) { - log/* default.info */.Z.info("DASH: Cannot perform \"based\" update. New timeline too short"); - return constructTimelineFromElements(newElements, scaledPeriodStart); - } // Remove elements which are not available anymore +// 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. + */ - var newTimeline = prevTimeline.slice(prevSegmentsIdx); - if (repeatNumberInPrevSegments > 0) { - var commonEltInOldTimeline = newTimeline[0]; - commonEltInOldTimeline.start += commonEltInOldTimeline.duration * repeatNumberInPrevSegments; - newTimeline[0].repeatCount -= repeatNumberInPrevSegments; - } +/** + * 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} + */ - if (repeatNumberInNewElements > 0 && newElementsIdx !== 0) { - log/* default.info */.Z.info("DASH: Cannot perform \"based\" update. " + "The new timeline has a different form."); - return constructTimelineFromElements(newElements, scaledPeriodStart); +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 prevLastElement = newTimeline[newTimeline.length - 1]; - var newCommonElt = parseSElement(newElements[lastCommonEltNewEltsIdx]); - var newRepeatCountOffseted = ((_a = newCommonElt.repeatCount) !== null && _a !== void 0 ? _a : 0) - repeatNumberInNewElements; - - if (newCommonElt.duration !== prevLastElement.duration || prevLastElement.repeatCount > newRepeatCountOffseted) { - log/* default.info */.Z.info("DASH: Cannot perform \"based\" update. " + "The new timeline has a different form at the beginning."); - return constructTimelineFromElements(newElements, scaledPeriodStart); - } + var userAgent = navigator.userAgent; + var match = /Firefox\/([0-9]+)\./.exec(userAgent); - if (newCommonElt.repeatCount !== undefined && newCommonElt.repeatCount > prevLastElement.repeatCount) { - prevLastElement.repeatCount = newCommonElt.repeatCount; + if (match === null) { + return -1; } - var newEltsToPush = []; - var items = []; + var result = parseInt(match[1], 10); - for (var i = lastCommonEltNewEltsIdx + 1; i < newElements.length; i++) { - items.push(parseSElement(newElements[i])); + if (isNaN(result)) { + return -1; } - for (var _i = 0; _i < items.length; _i++) { - var item = items[_i]; - var previousItem = newEltsToPush[newEltsToPush.length - 1] === undefined ? prevLastElement : newEltsToPush[newEltsToPush.length - 1]; - var nextItem = items[_i + 1] === undefined ? null : items[_i + 1]; - var timelineElement = convertElementsToIndexSegment(item, previousItem, nextItem, scaledPeriodStart); + return result; +} - if (timelineElement !== null) { - newEltsToPush.push(timelineElement); - } - } - return newTimeline.concat(newEltsToPush); -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/timeline_representation_index.ts +;// CONCATENATED MODULE: ./src/compat/can_rely_on_video_visibility_and_size.ts /** * Copyright 2015 CANAL+ Group * @@ -40732,392 +43705,364 @@ function constructTimelineFromPreviousTimeline(newElements, prevTimeline, scaled */ +/** + * 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() { + var _a, _b; + /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - - - - - - // eslint-disable-next-line max-len - - -var MIN_DASH_S_ELEMENTS_TO_PARSE_UNSAFELY = config/* default.MIN_DASH_S_ELEMENTS_TO_PARSE_UNSAFELY */.Z.MIN_DASH_S_ELEMENTS_TO_PARSE_UNSAFELY; - -var TimelineRepresentationIndex = /*#__PURE__*/function () { - /** - * @param {Object} index - * @param {Object} context - */ - function TimelineRepresentationIndex(index, timelineParser, context) { - var _a; - - var manifestBoundsCalculator = context.manifestBoundsCalculator, - isDynamic = context.isDynamic, - representationBaseURLs = context.representationBaseURLs, - representationId = context.representationId, - representationBitrate = context.representationBitrate, - periodStart = context.periodStart, - periodEnd = context.periodEnd; - var timescale = (_a = index.timescale) !== null && _a !== void 0 ? _a : 1; - var presentationTimeOffset = index.presentationTimeOffset != null ? index.presentationTimeOffset : 0; - var scaledStart = periodStart * timescale; - var indexTimeOffset = presentationTimeOffset - scaledStart; - this._manifestBoundsCalculator = manifestBoundsCalculator; - this._lastUpdate = context.receivedTime == null ? performance.now() : context.receivedTime; - this._unsafelyBaseOnPreviousIndex = null; - - if (context.unsafelyBaseOnPreviousRepresentation !== null && context.unsafelyBaseOnPreviousRepresentation.index instanceof TimelineRepresentationIndex) { - // avoid too much nested references, to keep memory down - context.unsafelyBaseOnPreviousRepresentation.index._unsafelyBaseOnPreviousIndex = null; - this._unsafelyBaseOnPreviousIndex = context.unsafelyBaseOnPreviousRepresentation.index; - } - - this._isDynamic = isDynamic; - this._parseTimeline = timelineParser; - this._index = { - indexRange: index.indexRange, - indexTimeOffset: indexTimeOffset, - initialization: index.initialization == null ? undefined : { - mediaURLs: createIndexURLs(representationBaseURLs, index.initialization.media, representationId, representationBitrate), - range: index.initialization.range - }, - mediaURLs: createIndexURLs(representationBaseURLs, index.media, representationId, representationBitrate), - startNumber: index.startNumber, - timeline: null, - timescale: timescale - }; - this._scaledPeriodStart = (0,index_helpers/* toIndexTime */.gT)(periodStart, this._index); - this._scaledPeriodEnd = periodEnd == null ? undefined : (0,index_helpers/* toIndexTime */.gT)(periodEnd, this._index); - } - /** - * Construct init Segment. - * @returns {Object} - */ - - - var _proto = TimelineRepresentationIndex.prototype; - - _proto.getInitSegment = function getInitSegment() { - return get_init_segment_getInitSegment(this._index); - } - /** - * Asks for segments to download for a given time range. - * @param {Number} from - Beginning of the time wanted, in seconds - * @param {Number} duration - duration wanted, in seconds - * @returns {Array.} - */ - ; - - _proto.getSegments = function getSegments(from, duration) { - this._refreshTimeline(); // clear timeline if needed - - - if (this._index.timeline === null) { - this._index.timeline = this._getTimeline(); - } // destructuring to please TypeScript - - - var _this$_index = this._index, - mediaURLs = _this$_index.mediaURLs, - startNumber = _this$_index.startNumber, - timeline = _this$_index.timeline, - timescale = _this$_index.timescale, - indexTimeOffset = _this$_index.indexTimeOffset; - return getSegmentsFromTimeline({ - mediaURLs: mediaURLs, - startNumber: startNumber, - timeline: timeline, - timescale: timescale, - indexTimeOffset: indexTimeOffset - }, from, duration, this._scaledPeriodEnd); - } - /** - * Returns true if the index should be refreshed. - * @param {Number} _up - * @param {Number} to - * @returns {Boolean} - */ - ; - - _proto.shouldRefresh = function shouldRefresh() { - // DASH Manifest based on a SegmentTimeline should have minimumUpdatePeriod - // attribute which should be sufficient to know when to refresh it. - return false; + if (!browser_detection/* isFirefox */.vU) { + return true; } - /** - * Returns the starting time, in seconds, of the earliest segment currently - * available. - * Returns null if nothing is in the index - * @returns {Number|null} - */ - ; - - _proto.getFirstPosition = function getFirstPosition() { - this._refreshTimeline(); - if (this._index.timeline === null) { - this._index.timeline = this._getTimeline(); - } + var firefoxVersion = getFirefoxVersion(); - var timeline = this._index.timeline; - return timeline.length === 0 ? null : (0,index_helpers/* fromIndexTime */.zG)(timeline[0].start, this._index); + if (firefoxVersion === null || firefoxVersion < 67) { + return true; } - /** - * Returns the ending time, in seconds, of the last segment currently - * available. - * Returns null if nothing is in the index - * @returns {Number|null} - */ - ; - - _proto.getLastPosition = function getLastPosition() { - this._refreshTimeline(); - - if (this._index.timeline === null) { - this._index.timeline = this._getTimeline(); - } - var lastTime = TimelineRepresentationIndex.getIndexEnd(this._index.timeline, this._scaledPeriodStart); - return lastTime === null ? null : (0,index_helpers/* fromIndexTime */.zG)(lastTime, this._index); - } - /** - * Returns true if a Segment returned by this index is still considered - * available. - * Returns false if it is not available anymore. - * Returns undefined if we cannot know whether it is still available or not. - * @param {Object} segment - * @returns {Boolean|undefined} - */ - ; + return ((_b = (_a = HTMLVideoElement) === null || _a === void 0 ? void 0 : _a.prototype) === null || _b === void 0 ? void 0 : _b.requirePictureInPicture) !== undefined; + /* eslint-enable @typescript-eslint/no-unsafe-member-access */ +} +// EXTERNAL MODULE: ./src/config.ts +var config = __webpack_require__(944); +// EXTERNAL MODULE: ./src/errors/media_error.ts +var media_error = __webpack_require__(3714); +// EXTERNAL MODULE: ./src/errors/is_known_error.ts +var is_known_error = __webpack_require__(9822); +// EXTERNAL MODULE: ./src/errors/other_error.ts +var other_error = __webpack_require__(5389); +;// CONCATENATED MODULE: ./src/errors/format_error.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. + */ - _proto.isSegmentStillAvailable = function isSegmentStillAvailable(segment) { - if (segment.isInit) { - return true; - } - this._refreshTimeline(); +/* + * Format an unknown error into an API-defined error. + * @param {*} error + * @returns {Error} + */ - if (this._index.timeline === null) { - this._index.timeline = this._getTimeline(); - } +function formatError(error, _ref) { + var defaultCode = _ref.defaultCode, + defaultReason = _ref.defaultReason; - var _this$_index2 = this._index, - timeline = _this$_index2.timeline, - timescale = _this$_index2.timescale, - indexTimeOffset = _this$_index2.indexTimeOffset; - return (0,is_segment_still_available/* default */.Z)(segment, timeline, timescale, indexTimeOffset); + if ((0,is_known_error/* default */.Z)(error)) { + return error; } - /** - * Checks if the time given is in a discontinuity. That is: - * - We're on the upper bound of the current range (end of the range - time - * is inferior to the timescale) - * - The next range starts after the end of the current range. - * @param {Number} time - * @returns {Number|null} - */ - ; - - _proto.checkDiscontinuity = function checkDiscontinuity(time) { - this._refreshTimeline(); - var timeline = this._index.timeline; - - if (timeline === null) { - timeline = this._getTimeline(); - this._index.timeline = timeline; - } + var reason = error instanceof Error ? error.toString() : defaultReason; + return new other_error/* default */.Z(defaultCode, reason); +} +// 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 + 10 modules +var manifest = __webpack_require__(1966); +// 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/noop.ts +var noop = __webpack_require__(8894); +// EXTERNAL MODULE: ./src/utils/object_assign.ts +var object_assign = __webpack_require__(8026); +// EXTERNAL MODULE: ./src/utils/promise.ts +var promise = __webpack_require__(9589); +// EXTERNAL MODULE: ./src/utils/ranges.ts +var ranges = __webpack_require__(2829); +// EXTERNAL MODULE: ./src/utils/warn_once.ts +var warn_once = __webpack_require__(8806); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/defer.js +var defer = __webpack_require__(1410); +// EXTERNAL MODULE: ./src/compat/eme/custom_media_keys/index.ts + 7 modules +var custom_media_keys = __webpack_require__(6139); +// EXTERNAL MODULE: ./src/core/eme/media_keys_infos_store.ts +var media_keys_infos_store = __webpack_require__(6033); +;// CONCATENATED MODULE: ./src/core/eme/dispose_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. + */ - return (0,index_helpers/* checkDiscontinuity */._j)({ - timeline: timeline, - timescale: this._index.timescale, - indexTimeOffset: this._index.indexTimeOffset - }, time, this._scaledPeriodEnd); - } - /** - * @param {Error} error - * @returns {Boolean} - */ - ; - _proto.canBeOutOfSyncError = function canBeOutOfSyncError(error) { - if (!this._isDynamic) { - return false; - } - return error instanceof network_error/* default */.Z && error.isHttpError(404); - }; - _proto.areSegmentsChronologicallyGenerated = function areSegmentsChronologicallyGenerated() { - return true; - } - /** - * Replace this RepresentationIndex with one from a new version of the - * Manifest. - * @param {Object} newIndex - */ - ; - _proto._replace = function _replace(newIndex) { - this._parseTimeline = newIndex._parseTimeline; - this._index = newIndex._index; - this._isDynamic = newIndex._isDynamic; - this._scaledPeriodStart = newIndex._scaledPeriodStart; - this._scaledPeriodEnd = newIndex._scaledPeriodEnd; - this._lastUpdate = newIndex._lastUpdate; - this._manifestBoundsCalculator = newIndex._manifestBoundsCalculator; - } - /** - * Update this RepresentationIndex with a shorter version of it coming from a - * new version of the MPD. - * @param {Object} newIndex - */ - ; +/** + * @param {Object} mediaKeysInfos + * @returns {Observable} + */ - _proto._update = function _update(newIndex) { - if (this._index.timeline === null) { - this._index.timeline = this._getTimeline(); - } +function disposeMediaKeys(mediaElement) { + return (0,defer/* defer */.P)(function () { + var currentState = media_keys_infos_store/* default.getState */.Z.getState(mediaElement); - if (newIndex._index.timeline === null) { - newIndex._index.timeline = newIndex._getTimeline(); + if (currentState === null) { + return (0,of.of)(null); } - (0,update_segment_timeline/* default */.Z)(this._index.timeline, newIndex._index.timeline); - this._isDynamic = newIndex._isDynamic; - this._scaledPeriodStart = newIndex._scaledPeriodStart; - this._scaledPeriodEnd = newIndex._scaledPeriodEnd; - this._lastUpdate = newIndex._lastUpdate; - } - /** - * Returns `true` if this RepresentationIndex currently contains its last - * segment. - * Returns `false` if it's still pending. - * @returns {Boolean} - */ - ; + log/* default.info */.Z.info("EME: Disposing of the current MediaKeys"); + var loadedSessionsStore = currentState.loadedSessionsStore; + media_keys_infos_store/* default.clearState */.Z.clearState(mediaElement); + return loadedSessionsStore.closeAllSessions().pipe((0,mergeMapTo/* mergeMapTo */.j)((0,custom_media_keys/* setMediaKeys */.Y)(mediaElement, null))); + }); +} +;// CONCATENATED MODULE: ./src/core/eme/dispose_eme.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. + */ - _proto.isFinished = function isFinished() { - if (!this._isDynamic) { - return true; - } - if (this._index.timeline === null) { - this._index.timeline = this._getTimeline(); - } +/** + * Free up all ressources taken by the EME management. + */ - var timeline = this._index.timeline; +function disposeEME(mediaElement) { + disposeMediaKeys(mediaElement).subscribe(noop/* default */.Z); +} +;// CONCATENATED MODULE: ./src/core/eme/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. + */ - if (this._scaledPeriodEnd === undefined || timeline.length === 0) { - return false; - } +/** + * Returns the name of the current key system used. + * @param {HTMLMediaElement} mediaElement + * @returns {string|null} + */ - var lastTimelineElement = timeline[timeline.length - 1]; - var lastTime = (0,index_helpers/* getIndexSegmentEnd */.jH)(lastTimelineElement, null, this._scaledPeriodEnd); // We can never be truly sure if a SegmentTimeline-based index is finished - // or not (1 / 60 for possible rounding errors) +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; +} +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/ignoreElements.js +var ignoreElements = __webpack_require__(6738); +;// 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. + */ - return lastTime + 1 / 60 >= this._scaledPeriodEnd; - } - /** - * @returns {Boolean} - */ - ; +/** + * Returns true if the mediakeys associated to a media element should be + * unset once the content is stopped. + * Depends on the target. + * @returns {Boolean} + */ - _proto.isInitialized = function isInitialized() { - return true; - } - /** - * Clean-up timeline to remove segment information which should not be - * available due to timeshifting. - */ - ; +function shouldUnsetMediaKeys() { + return browser_detection/* isIE11 */.fq; +} +;// CONCATENATED MODULE: ./src/core/eme/clear_eme_session.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. + */ - _proto._refreshTimeline = function _refreshTimeline() { - if (this._index.timeline === null) { - this._index.timeline = this._getTimeline(); - } - var firstPosition = this._manifestBoundsCalculator.estimateMinimumBound(); - if (firstPosition == null) { - return; // we don't know yet - } - var scaledFirstPosition = (0,index_helpers/* toIndexTime */.gT)(firstPosition, this._index); - (0,clear_timeline_from_position/* default */.Z)(this._index.timeline, scaledFirstPosition); - }; - TimelineRepresentationIndex.getIndexEnd = function getIndexEnd(timeline, scaledPeriodEnd) { - if (timeline.length <= 0) { - return null; - } - return (0,index_helpers/* getIndexSegmentEnd */.jH)(timeline[timeline.length - 1], null, scaledPeriodEnd); - } - /** - * Allows to generate the "timeline" for this RepresentationIndex. - * Call this function when the timeline is unknown. - * This function was added to only perform that task lazily, i.e. only when - * first needed. - * After calling it, every now unneeded variable will be freed from memory. - * This means that calling _getTimeline more than once will just return an - * empty array. - * - * /!\ Please note that this structure should follow the exact same structure - * than a SegmentTimeline element in the corresponding MPD. - * This means: - * - It should have the same amount of elements in its array than there was - * `` elements in the SegmentTimeline. - * - Each of those same elements should have the same start time, the same - * duration and the same repeat counter than what could be deduced from - * the SegmentTimeline. - * This is needed to be able to run parsing optimization when refreshing the - * MPD. Not doing so could lead to the RxPlayer not being able to play the - * stream anymore. - * @returns {Array.} - */ - ; +/** + * Clear EME ressources that should be cleared when the current content stops + * its playback. + * @param {HTMLMediaElement} mediaElement + * @returns {Observable} + */ - _proto._getTimeline = function _getTimeline() { - if (this._parseTimeline === null) { - if (this._index.timeline !== null) { - return this._index.timeline; - } +function clearEMESession(mediaElement) { + return (0,defer/* defer */.P)(function () { + log/* default.info */.Z.info("EME: Clearing-up EME session."); - log/* default.error */.Z.error("DASH: Timeline already lazily parsed."); - return []; + if (shouldUnsetMediaKeys()) { + log/* default.info */.Z.info("EME: disposing current MediaKeys."); + return disposeMediaKeys(mediaElement).pipe((0,ignoreElements/* ignoreElements */.l)()); } - var newElements = this._parseTimeline(); + var currentState = media_keys_infos_store/* default.getState */.Z.getState(mediaElement); - this._parseTimeline = null; // Free memory + if (currentState !== null && currentState.keySystemOptions.closeSessionsOnStop === true) { + log/* default.info */.Z.info("EME: closing all current sessions."); + return currentState.loadedSessionsStore.closeAllSessions().pipe((0,ignoreElements/* ignoreElements */.l)()); + } - if (this._unsafelyBaseOnPreviousIndex === null || newElements.length < MIN_DASH_S_ELEMENTS_TO_PARSE_UNSAFELY) { - // Just completely parse the current timeline - return constructTimelineFromElements(newElements, this._scaledPeriodStart); - } // Construct previously parsed timeline if not already done + log/* default.info */.Z.info("EME: Nothing to clear. Returning right away. No state =", currentState === null); + return empty/* EMPTY */.E; + }); +} +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/catchError.js +var catchError = __webpack_require__(486); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscription.js + 1 modules +var Subscription = __webpack_require__(3884); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/finalize.js +/** PURE_IMPORTS_START tslib,_Subscriber,_Subscription PURE_IMPORTS_END */ - var prevTimeline; - if (this._unsafelyBaseOnPreviousIndex._index.timeline === null) { - prevTimeline = this._unsafelyBaseOnPreviousIndex._getTimeline(); - this._unsafelyBaseOnPreviousIndex._index.timeline = prevTimeline; - } else { - prevTimeline = this._unsafelyBaseOnPreviousIndex._index.timeline; +function finalize(callback) { + return function (source) { return source.lift(new FinallyOperator(callback)); }; +} +var FinallyOperator = /*@__PURE__*/ (function () { + function FinallyOperator(callback) { + this.callback = callback; } + FinallyOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new FinallySubscriber(subscriber, this.callback)); + }; + return FinallyOperator; +}()); +var FinallySubscriber = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(FinallySubscriber, _super); + function FinallySubscriber(destination, callback) { + var _this = _super.call(this, destination) || this; + _this.add(new Subscription/* Subscription */.w(callback)); + return _this; + } + return FinallySubscriber; +}(Subscriber/* Subscriber */.L)); +//# sourceMappingURL=finalize.js.map - this._unsafelyBaseOnPreviousIndex = null; // Free memory - - return constructTimelineFromPreviousTimeline(newElements, prevTimeline, this._scaledPeriodStart); - }; +// EXTERNAL MODULE: ./src/utils/rx-try_catch.ts +var rx_try_catch = __webpack_require__(5561); +// EXTERNAL MODULE: ./src/utils/filter_map.ts +var filter_map = __webpack_require__(2793); +// 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. + */ - return TimelineRepresentationIndex; -}(); +/** + * 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); + } -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/timeline/index.ts + return formatError(error, { + defaultCode: "PIPELINE_LOAD_ERROR", + defaultReason: "Unknown error when fetching the Manifest" + }); +} +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/timer.js +var timer = __webpack_require__(9604); +;// CONCATENATED MODULE: ./src/compat/is_offline.ts /** * Copyright 2015 CANAL+ Group * @@ -41134,8 +44079,37 @@ var TimelineRepresentationIndex = /*#__PURE__*/function () { * limitations under the License. */ -/* harmony default export */ const timeline = (TimelineRepresentationIndex); -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/indexes/template.ts +/** + * 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/utils/get_fuzzed_delay.ts +var get_fuzzed_delay = __webpack_require__(2572); +;// CONCATENATED MODULE: ./src/core/fetchers/utils/try_urls_with_backoff.ts /** * Copyright 2015 CANAL+ Group * @@ -41154,398 +44128,474 @@ var TimelineRepresentationIndex = /*#__PURE__*/function () { -var MINIMUM_SEGMENT_SIZE = config/* default.MINIMUM_SEGMENT_SIZE */.Z.MINIMUM_SEGMENT_SIZE; -/** - * IRepresentationIndex implementation for DASH' SegmentTemplate without a - * SegmentTimeline. - * @class TemplateRepresentationIndex - */ -var TemplateRepresentationIndex = /*#__PURE__*/function () { - /** - * @param {Object} index - * @param {Object} context - */ - function TemplateRepresentationIndex(index, context) { - var _a; - var aggressiveMode = context.aggressiveMode, - availabilityTimeOffset = context.availabilityTimeOffset, - manifestBoundsCalculator = context.manifestBoundsCalculator, - isDynamic = context.isDynamic, - periodEnd = context.periodEnd, - periodStart = context.periodStart, - representationBaseURLs = context.representationBaseURLs, - representationId = context.representationId, - representationBitrate = context.representationBitrate; - var timescale = (_a = index.timescale) !== null && _a !== void 0 ? _a : 1; - this._availabilityTimeOffset = availabilityTimeOffset; - this._manifestBoundsCalculator = manifestBoundsCalculator; - this._aggressiveMode = aggressiveMode; - var presentationTimeOffset = index.presentationTimeOffset != null ? index.presentationTimeOffset : 0; - var scaledStart = periodStart * timescale; - var indexTimeOffset = presentationTimeOffset - scaledStart; - if (index.duration === undefined) { - throw new Error("Invalid SegmentTemplate: no duration"); +/** + * Called on a loader error. + * Returns whether the loader request should be retried. + * @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; } - this._index = { - duration: index.duration, - timescale: timescale, - indexRange: index.indexRange, - indexTimeOffset: indexTimeOffset, - initialization: index.initialization == null ? undefined : { - mediaURLs: createIndexURLs(representationBaseURLs, index.initialization.media, representationId, representationBitrate), - range: index.initialization.range - }, - mediaURLs: createIndexURLs(representationBaseURLs, index.media, representationId, representationBitrate), - presentationTimeOffset: presentationTimeOffset, - startNumber: index.startNumber - }; - this._isDynamic = isDynamic; - this._periodStart = periodStart; - this._relativePeriodEnd = periodEnd == null ? undefined : periodEnd - periodStart; + return error.type === error_codes/* NetworkErrorTypes.TIMEOUT */.br.TIMEOUT || error.type === error_codes/* NetworkErrorTypes.ERROR_EVENT */.br.ERROR_EVENT; } - /** - * Construct init Segment. - * @returns {Object} - */ + 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} + */ - var _proto = TemplateRepresentationIndex.prototype; - _proto.getInitSegment = function getInitSegment() { - return get_init_segment_getInitSegment(this._index); - } - /** - * @param {Number} fromTime - * @param {Number} dur - * @returns {Array.} - */ - ; +function isOfflineRequestError(error) { + return error.type === error_codes/* NetworkErrorTypes.ERROR_EVENT */.br.ERROR_EVENT && isOffline(); +} - _proto.getSegments = function getSegments(fromTime, dur) { - var index = this._index; - var duration = index.duration, - startNumber = index.startNumber, - timescale = index.timescale, - mediaURLs = index.mediaURLs; - var scaledStart = this._periodStart * timescale; - var scaledEnd = this._relativePeriodEnd == null ? undefined : this._relativePeriodEnd * timescale; // Convert the asked position to the right timescales, and consider them - // relatively to the Period's start. +var REQUEST_ERROR_TYPES; - var upFromPeriodStart = fromTime * timescale - scaledStart; - var toFromPeriodStart = (fromTime + dur) * timescale - scaledStart; +(function (REQUEST_ERROR_TYPES) { + REQUEST_ERROR_TYPES[REQUEST_ERROR_TYPES["None"] = 0] = "None"; + REQUEST_ERROR_TYPES[REQUEST_ERROR_TYPES["Regular"] = 1] = "Regular"; + REQUEST_ERROR_TYPES[REQUEST_ERROR_TYPES["Offline"] = 2] = "Offline"; +})(REQUEST_ERROR_TYPES || (REQUEST_ERROR_TYPES = {})); +/** + * Guess the type of error obtained. + * @param {*} error + * @returns {number} + */ - var firstSegmentStart = this._getFirstSegmentStart(); - var lastSegmentStart = this._getLastSegmentStart(); +function getRequestErrorType(error) { + return error instanceof request_error/* default */.Z && isOfflineRequestError(error) ? REQUEST_ERROR_TYPES.Offline : REQUEST_ERROR_TYPES.Regular; +} +/** + * Specific algorithm used to perform segment and manifest requests. + * + * Here how it works: + * + * 1. we give it one or multiple URLs available for the element we want to + * request, the request callback and some options + * + * 2. it tries to call the request callback with the first URL: + * - if it works as expected, it wrap the response in a `response` event. + * - if it fails, it emits a `retry` event and try with the next one. + * + * 3. When all URLs have been tested (and failed), it decides - according to + * the error counters, configuration and errors received - if it can retry + * at least one of them, in the same order: + * - If it can, it increments the corresponding error counter, wait a + * delay (based on an exponential backoff) and restart the same logic + * for all retry-able URL. + * - If it can't it just throws the error. + * + * Note that there are in fact two separate counters: + * - one for "offline" errors + * - one for other xhr errors + * Both counters are resetted if the error type changes from an error to the + * next. + * @param {Array. scaledEnd ? scaledEnd - timeFromPeriodStart : duration; - var realTime = timeFromPeriodStart + scaledStart; - var manifestTime = timeFromPeriodStart + this._index.presentationTimeOffset; - var detokenizedURLs = mediaURLs === null ? null : mediaURLs.map(createDashUrlDetokenizer(manifestTime, realNumber)); - var args = { - id: String(realNumber), - number: realNumber, - time: realTime / timescale, - end: (realTime + realDuration) / timescale, - duration: realDuration / timescale, - timescale: 1, - isInit: false, - scaledDuration: realDuration / timescale, - mediaURLs: detokenizedURLs, - timestampOffset: -(index.indexTimeOffset / timescale) - }; - segments.push(args); - numberIndexedToZero++; - } + urlsToTry.splice(index, 1); + var newIndex = index >= urlsToTry.length - 1 ? 0 : index; + return tryURLsRecursively(urlsToTry[newIndex], newIndex).pipe((0,startWith/* startWith */.O)({ + type: "retry", + value: error + })); + } - return segments; - } - /** - * Returns first possible position in the index, in seconds. - * @returns {number|null|undefined} - */ - ; + var currentError = getRequestErrorType(error); + var maxRetry = currentError === REQUEST_ERROR_TYPES.Offline ? maxRetryOffline : maxRetryRegular; - _proto.getFirstPosition = function getFirstPosition() { - var firstSegmentStart = this._getFirstSegmentStart(); + if (currentError !== lastError) { + retryCount = 0; + lastError = currentError; + } - if (firstSegmentStart == null) { - return firstSegmentStart; // return undefined or null - } + if (index < urlsToTry.length - 1) { + // there is still URLs to test + var _newIndex = index + 1; - return firstSegmentStart / this._index.timescale + this._periodStart; - } - /** - * Returns last possible position in the index, in seconds. - * @returns {number|null} - */ - ; + return tryURLsRecursively(urlsToTry[_newIndex], _newIndex).pipe((0,startWith/* startWith */.O)({ + type: "retry", + value: error + })); + } // Here, we were using the last element of the `urlsToTry` array. + // Increment counter and restart with the first URL - _proto.getLastPosition = function getLastPosition() { - var lastSegmentStart = this._getLastSegmentStart(); - if (lastSegmentStart == null) { - // In that case (null or undefined), getLastPosition should reflect - // the result of getLastSegmentStart, as the meaning is the same for - // the two functions. So, we return the result of the latter. - return lastSegmentStart; - } + retryCount++; - var lastSegmentEnd = lastSegmentStart + this._index.duration; - return lastSegmentEnd / this._index.timescale + this._periodStart; - } - /** - * Returns true if, based on the arguments, the index should be refreshed. - * We never have to refresh a SegmentTemplate-based manifest. - * @returns {Boolean} - */ - ; + if (retryCount > maxRetry) { + throw error; + } - _proto.shouldRefresh = function shouldRefresh() { - return false; + var delay = Math.min(baseDelay * Math.pow(2, retryCount - 1), maxDelay); + var fuzzedDelay = (0,get_fuzzed_delay/* default */.Z)(delay); + var nextURL = urlsToTry[0]; + return (0,timer/* timer */.H)(fuzzedDelay).pipe((0,mergeMap/* mergeMap */.zg)(function () { + return tryURLsRecursively(nextURL, 0); + }), (0,startWith/* startWith */.O)({ + type: "retry", + value: error + })); + })); } - /** - * We cannot check for discontinuity in SegmentTemplate-based indexes. - * @returns {null} - */ - ; +} +/** + * Lightweight version of the request algorithm, this time with only a simple + * Observable given. + * @param {Function} request$ + * @param {Object} options + * @returns {Observable} + */ - _proto.checkDiscontinuity = function checkDiscontinuity() { - return null; - } - /** - * @returns {Boolean} - */ - ; +function tryRequestObservableWithBackoff(request$, options) { + // same than for a single unknown URL + return tryURLsWithBackoff([null], function () { + return request$; + }, options); +} +;// CONCATENATED MODULE: ./src/core/fetchers/utils/create_request_scheduler.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. + */ - _proto.areSegmentsChronologicallyGenerated = function areSegmentsChronologicallyGenerated() { - return true; - } - /** - * Returns `true` if the given segment should still be available as of now - * (not removed since and still request-able). - * Returns `false` if that's not the case. - * Returns `undefined` if we do not know whether that's the case or not. - * @param {Object} segment - * @returns {boolean|undefined} - */ - ; - _proto.isSegmentStillAvailable = function isSegmentStillAvailable(segment) { - if (segment.isInit) { - return true; - } - var segmentsForTime = this.getSegments(segment.time, 0.1); - if (segmentsForTime.length === 0) { - return false; - } - return segmentsForTime[0].time === segment.time && segmentsForTime[0].end === segment.end && segmentsForTime[0].number === segment.number; - } +function createRequestScheduler(backoffOptions, warning$) { /** - * SegmentTemplate without a SegmentTimeline should not be updated. - * @returns {Boolean} + * Allow the parser to schedule a new request. + * @param {Function} request - Function performing the request. + * @returns {Function} */ - ; + return function scheduleRequest(request) { + return tryRequestObservableWithBackoff((0,rx_try_catch/* default */.Z)(request, undefined), backoffOptions).pipe((0,filter_map/* default */.Z)(function (evt) { + if (evt.type === "retry") { + warning$.next(errorSelector(evt.value)); + return null; + } - _proto.canBeOutOfSyncError = function canBeOutOfSyncError() { - return false; - } - /** - * @returns {Boolean} - */ - ; + return evt.value; + }, null), (0,catchError/* catchError */.K)(function (error) { + throw errorSelector(error); + })); + }; +} +;// CONCATENATED MODULE: ./src/core/fetchers/manifest/get_manifest_backoff_options.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. + */ - _proto.isFinished = function isFinished() { - if (!this._isDynamic) { - return true; - } +var DEFAULT_MAX_MANIFEST_REQUEST_RETRY = config/* default.DEFAULT_MAX_MANIFEST_REQUEST_RETRY */.Z.DEFAULT_MAX_MANIFEST_REQUEST_RETRY, + DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE = config/* default.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE */.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE, + INITIAL_BACKOFF_DELAY_BASE = config/* default.INITIAL_BACKOFF_DELAY_BASE */.Z.INITIAL_BACKOFF_DELAY_BASE, + MAX_BACKOFF_DELAY_BASE = config/* default.MAX_BACKOFF_DELAY_BASE */.Z.MAX_BACKOFF_DELAY_BASE; +/** + * Parse config to replace missing manifest backoff options. + * @param {Object} backoffOptions + * @returns {Object} + */ - if (this._relativePeriodEnd == null) { - return false; - } +function getManifestBackoffOptions(_ref) { + var maxRetryRegular = _ref.maxRetryRegular, + maxRetryOffline = _ref.maxRetryOffline, + lowLatencyMode = _ref.lowLatencyMode; + 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; + return { + baseDelay: baseDelay, + maxDelay: maxDelay, + maxRetryRegular: maxRetryRegular !== undefined ? maxRetryRegular : DEFAULT_MAX_MANIFEST_REQUEST_RETRY, + maxRetryOffline: maxRetryOffline !== undefined ? maxRetryOffline : DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE + }; +} +;// CONCATENATED MODULE: ./src/core/fetchers/manifest/manifest_fetcher.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 timescale = this._index.timescale; - var lastSegmentStart = this._getLastSegmentStart(); // As last segment start is null if live time is before - // current period, consider the index not to be finished. - if (lastSegmentStart == null) { - return false; - } - var lastSegmentEnd = lastSegmentStart + this._index.duration; // (1 / 60 for possible rounding errors) - var roundingError = 1 / 60 * timescale; - return lastSegmentEnd + roundingError >= this._relativePeriodEnd * timescale; - } - /** - * @returns {Boolean} - */ - ; - _proto.isInitialized = function isInitialized() { - return true; - } - /** - * @param {Object} newIndex - */ - ; - _proto._replace = function _replace(newIndex) { - this._index = newIndex._index; - this._aggressiveMode = newIndex._aggressiveMode; - this._isDynamic = newIndex._isDynamic; - this._periodStart = newIndex._periodStart; - this._relativePeriodEnd = newIndex._relativePeriodEnd; - this._manifestBoundsCalculator = newIndex._manifestBoundsCalculator; - } +/** + * 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); + * }); + * ``` + */ + +var ManifestFetcher = /*#__PURE__*/function () { /** - * @param {Object} newIndex + * @param {string | undefined} url + * @param {Object} pipelines + * @param {Object} backoffOptions */ - ; - - _proto._update = function _update(newIndex) { - // As segments are not declared individually, as long as this Representation - // is present, we have every information we need - this._replace(newIndex); + function ManifestFetcher(url, pipelines, backoffOptions) { + this._manifestUrl = url; + this._pipelines = pipelines.manifest; + this._backoffOptions = getManifestBackoffOptions(backoffOptions); } /** - * Returns the timescaled start of the first segment that should be available, - * relatively to the start of the Period. - * @returns {number | null | undefined} + * (re-)Load the Manifest without yet parsing it. + * + * 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} [url] + * @returns {Observable} */ - ; - - _proto._getFirstSegmentStart = function _getFirstSegmentStart() { - if (!this._isDynamic) { - return 0; // it is the start of the Period - } // 1 - check that this index is already available - - if (this._relativePeriodEnd === 0 || this._relativePeriodEnd == null) { - // /!\ The scaled max position augments continuously and might not - // reflect exactly the real server-side value. As segments are - // generated discretely. - var maximumBound = this._manifestBoundsCalculator.estimateMaximumBound(); - if (maximumBound !== undefined && maximumBound < this._periodStart) { - // Maximum position is before this period. - // No segment is yet available here - return null; - } - } + var _proto = ManifestFetcher.prototype; - var _this$_index = this._index, - duration = _this$_index.duration, - timescale = _this$_index.timescale; + _proto.fetch = function fetch(url) { + var _this = this; - var firstPosition = this._manifestBoundsCalculator.estimateMinimumBound(); + var _a; - if (firstPosition === undefined) { - return undefined; - } + var requestUrl = url !== null && url !== void 0 ? url : this._manifestUrl; // TODO Remove the resolver completely in the next major version - var segmentTime = firstPosition > this._periodStart ? (firstPosition - this._periodStart) * timescale : 0; - var numberIndexedToZero = Math.floor(segmentTime / duration); - return numberIndexedToZero * duration; + var resolver = (_a = this._pipelines.resolver) !== null && _a !== void 0 ? _a : of.of; + var loader = this._pipelines.loader; + return (0,rx_try_catch/* default */.Z)(resolver, { + url: requestUrl + }).pipe((0,catchError/* catchError */.K)(function (error) { + throw errorSelector(error); + }), (0,mergeMap/* mergeMap */.zg)(function (loaderArgument) { + var loader$ = (0,rx_try_catch/* default */.Z)(loader, loaderArgument); + return tryRequestObservableWithBackoff(loader$, _this._backoffOptions).pipe((0,catchError/* catchError */.K)(function (error) { + throw errorSelector(error); + }), (0,map/* map */.U)(function (evt) { + return evt.type === "retry" ? { + type: "warning", + value: errorSelector(evt.value) + } : { + type: "response", + parse: function parse(parserOptions) { + return _this._parseLoadedManifest(evt.value.value, parserOptions); + } + }; + })); + })); } /** - * Returns the timescaled start of the last segment that should be available, - * relatively to the start of the Period. - * Returns null if live time is before current period. - * @returns {number|null|undefined} + * 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} */ ; - _proto._getLastSegmentStart = function _getLastSegmentStart() { - var _this$_index2 = this._index, - duration = _this$_index2.duration, - timescale = _this$_index2.timescale; - - if (this._isDynamic) { - var lastPos = this._manifestBoundsCalculator.estimateMaximumBound(); - - if (lastPos === undefined) { - return undefined; - } - - var agressiveModeOffset = this._aggressiveMode ? duration / timescale : 0; - - if (this._relativePeriodEnd != null && this._relativePeriodEnd < lastPos + agressiveModeOffset - this._periodStart) { - var scaledRelativePeriodEnd = this._relativePeriodEnd * timescale; - - if (scaledRelativePeriodEnd < duration) { - return null; - } - - return (Math.floor(scaledRelativePeriodEnd / duration) - 1) * duration; - } // /!\ The scaled last position augments continuously and might not - // reflect exactly the real server-side value. As segments are - // generated discretely. - - - var scaledLastPosition = (lastPos - this._periodStart) * timescale; // Maximum position is before this period. - // No segment is yet available here - - if (scaledLastPosition < 0) { - return null; - } - - var availabilityTimeOffset = ((this._availabilityTimeOffset !== undefined ? this._availabilityTimeOffset : 0) + agressiveModeOffset) * timescale; - var numberOfSegmentsAvailable = Math.floor((scaledLastPosition + availabilityTimeOffset) / duration); - return numberOfSegmentsAvailable <= 0 ? null : (numberOfSegmentsAvailable - 1) * duration; - } else { - var maximumTime = (this._relativePeriodEnd === undefined ? 0 : this._relativePeriodEnd) * timescale; - var numberIndexedToZero = Math.ceil(maximumTime / duration) - 1; - var regularLastSegmentStart = numberIndexedToZero * duration; // In some SegmentTemplate, we could think that there is one more - // segment that there actually is due to a very little difference between - // the period's duration and a multiple of a segment's duration. - // Check that we're within a good margin + _proto.parse = function parse(manifest, parserOptions) { + return this._parseLoadedManifest({ + responseData: manifest, + size: undefined, + duration: undefined + }, parserOptions); + } + /** + * 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} + */ + ; - var minimumDuration = MINIMUM_SEGMENT_SIZE * timescale; + _proto._parseLoadedManifest = function _parseLoadedManifest(loaded, parserOptions) { + var sendingTime = loaded.sendingTime, + receivedTime = loaded.receivedTime; + var parsingTimeStart = performance.now(); + var schedulerWarnings$ = new Subject/* Subject */.xQ(); + var scheduleRequest = createRequestScheduler(this._backoffOptions, schedulerWarnings$); + return (0,merge/* merge */.T)(schedulerWarnings$.pipe((0,map/* map */.U)(function (err) { + return { + type: "warning", + value: err + }; + })), this._pipelines.parser({ + response: loaded, + url: this._manifestUrl, + externalClockOffset: parserOptions.externalClockOffset, + previousManifest: parserOptions.previousManifest, + scheduleRequest: scheduleRequest, + unsafeMode: parserOptions.unsafeMode + }).pipe((0,catchError/* catchError */.K)(function (error) { + throw formatError(error, { + defaultCode: "PIPELINE_PARSE_ERROR", + defaultReason: "Unknown error when parsing the Manifest" + }); + }), (0,map/* map */.U)(function (parsingEvt) { + if (parsingEvt.type === "warning") { + var formatted = formatError(parsingEvt.value, { + defaultCode: "PIPELINE_PARSE_ERROR", + defaultReason: "Unknown error when parsing the Manifest" + }); + return { + type: "warning", + value: formatted + }; + } // 2 - send response - if (maximumTime - regularLastSegmentStart > minimumDuration || numberIndexedToZero === 0) { - return regularLastSegmentStart; - } - return (numberIndexedToZero - 1) * duration; - } + var parsingTime = performance.now() - parsingTimeStart; + return { + type: "parsed", + manifest: parsingEvt.value.manifest, + sendingTime: sendingTime, + receivedTime: receivedTime, + parsingTime: parsingTime + }; + }), finalize(function () { + schedulerWarnings$.complete(); + }))); }; - return TemplateRepresentationIndex; + return ManifestFetcher; }(); -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/resolve_base_urls.ts +;// CONCATENATED MODULE: ./src/core/fetchers/manifest/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 */ const fetchers_manifest = (ManifestFetcher); +;// CONCATENATED MODULE: ./src/core/fetchers/segment/get_segment_backoff_options.ts /** * Copyright 2015 CANAL+ Group * @@ -41562,43 +44612,28 @@ var TemplateRepresentationIndex = /*#__PURE__*/function () { * limitations under the License. */ - +var DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR = config/* default.DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR */.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR, + get_segment_backoff_options_DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE = config/* default.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE */.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE, + get_segment_backoff_options_INITIAL_BACKOFF_DELAY_BASE = config/* default.INITIAL_BACKOFF_DELAY_BASE */.Z.INITIAL_BACKOFF_DELAY_BASE, + get_segment_backoff_options_MAX_BACKOFF_DELAY_BASE = config/* default.MAX_BACKOFF_DELAY_BASE */.Z.MAX_BACKOFF_DELAY_BASE; /** - * @param {Array.} currentBaseURLs - * @param {Array.} newBaseURLs - * @returns {Array.} + * @param {string} bufferType + * @param {Object} + * @returns {Object} */ -function resolveBaseURLs(currentBaseURLs, newBaseURLs) { - var result = []; - - if (newBaseURLs.length === 0) { - return currentBaseURLs; - } else if (currentBaseURLs.length === 0) { - for (var i = 0; i < newBaseURLs.length; i++) { - if (!(0,array_includes/* default */.Z)(result, newBaseURLs[i].value)) { - result.push(newBaseURLs[i].value); - } - } - - return result; - } else { - for (var _i = 0; _i < currentBaseURLs.length; _i++) { - var rootURL = currentBaseURLs[_i]; - - for (var j = 0; j < newBaseURLs.length; j++) { - var newURL = (0,resolve_url/* default */.Z)(rootURL, newBaseURLs[j].value); - - if (!(0,array_includes/* default */.Z)(result, newURL)) { - result.push(newURL); - } - } - } - } - - return result; +function getSegmentBackoffOptions(bufferType, _ref) { + var maxRetryRegular = _ref.maxRetryRegular, + maxRetryOffline = _ref.maxRetryOffline, + lowLatencyMode = _ref.lowLatencyMode; + return { + maxRetryRegular: bufferType === "image" ? 0 : maxRetryRegular !== null && maxRetryRegular !== void 0 ? maxRetryRegular : DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR, + maxRetryOffline: maxRetryOffline !== null && maxRetryOffline !== void 0 ? maxRetryOffline : get_segment_backoff_options_DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE, + baseDelay: lowLatencyMode ? get_segment_backoff_options_INITIAL_BACKOFF_DELAY_BASE.LOW_LATENCY : get_segment_backoff_options_INITIAL_BACKOFF_DELAY_BASE.REGULAR, + maxDelay: lowLatencyMode ? get_segment_backoff_options_MAX_BACKOFF_DELAY_BASE.LOW_LATENCY : get_segment_backoff_options_MAX_BACKOFF_DELAY_BASE.REGULAR + }; } -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_representation_index.ts +;// CONCATENATED MODULE: ./src/core/fetchers/segment/prioritized_segment_fetcher.ts /** * Copyright 2015 CANAL+ Group * @@ -41614,92 +44649,70 @@ function resolveBaseURLs(currentBaseURLs, newBaseURLs) { * See the License for the specific language governing permissions and * limitations under the License. */ - // eslint-disable-next-line max-len - - /** - * Parse the specific segment indexing information found in a representation - * into a IRepresentationIndex implementation. - * @param {Array.} representation - * @param {Object} representationInfos - * @returns {Array.} + * This function basically put in relation: + * - a SegmentFetcher, which will be used to perform the segment request + * - a prioritizer, which will handle the priority of a segment request + * + * and returns functions to fetch segments with a given priority. + * @param {Object} prioritizer + * @param {Object} fetcher + * @returns {Object} */ -function parseRepresentationIndex(representation, representationInfos) { - var _a, _b; - - var representationBaseURLs = resolveBaseURLs(representationInfos.baseURLs, representation.children.baseURLs); - var aggressiveMode = representationInfos.aggressiveMode, - availabilityTimeOffset = representationInfos.availabilityTimeOffset, - manifestBoundsCalculator = representationInfos.manifestBoundsCalculator, - isDynamic = representationInfos.isDynamic, - periodEnd = representationInfos.end, - periodStart = representationInfos.start, - receivedTime = representationInfos.receivedTime, - timeShiftBufferDepth = representationInfos.timeShiftBufferDepth, - unsafelyBaseOnPreviousRepresentation = representationInfos.unsafelyBaseOnPreviousRepresentation; - var context = { - aggressiveMode: aggressiveMode, - availabilityTimeOffset: availabilityTimeOffset, - unsafelyBaseOnPreviousRepresentation: unsafelyBaseOnPreviousRepresentation, - manifestBoundsCalculator: manifestBoundsCalculator, - isDynamic: isDynamic, - periodEnd: periodEnd, - periodStart: periodStart, - receivedTime: receivedTime, - representationBaseURLs: representationBaseURLs, - representationBitrate: representation.attributes.bitrate, - representationId: representation.attributes.id, - timeShiftBufferDepth: timeShiftBufferDepth - }; - var representationIndex; +function applyPrioritizerToSegmentFetcher(prioritizer, fetcher) { + /** + * The Observables returned by `createRequest` are not exactly the same than + * the one created by the `ObservablePrioritizer`. Because we still have to + * keep a handle on that value. + */ + var taskHandlers = new WeakMap(); + return { + /** + * Create a Segment request with a given priority. + * @param {Object} content - content to request + * @param {Number} priority - priority at which the content should be requested. + * Lower number == higher priority. + * @returns {Observable} + */ + createRequest: function createRequest(content, priority) { + if (priority === void 0) { + priority = 0; + } - if (representation.children.segmentBase !== undefined) { - var segmentBase = representation.children.segmentBase; - context.availabilityTimeOffset = representationInfos.availabilityTimeOffset + extractMinimumAvailabilityTimeOffset(representation.children.baseURLs) + ((_a = segmentBase.availabilityTimeOffset) !== null && _a !== void 0 ? _a : 0); - representationIndex = new BaseRepresentationIndex(segmentBase, context); - } else if (representation.children.segmentList !== undefined) { - var segmentList = representation.children.segmentList; - representationIndex = new ListRepresentationIndex(segmentList, context); - } else if (representation.children.segmentTemplate !== undefined || representationInfos.parentSegmentTemplates.length > 0) { - var segmentTemplates = representationInfos.parentSegmentTemplates.slice(); - var childSegmentTemplate = representation.children.segmentTemplate; + var task = prioritizer.create(fetcher(content), priority); + var flattenTask = task.pipe((0,map/* map */.U)(function (evt) { + return evt.type === "data" ? evt.value : evt; + })); + taskHandlers.set(flattenTask, task); + return flattenTask; + }, - if (childSegmentTemplate !== undefined) { - segmentTemplates.push(childSegmentTemplate); - } + /** + * Update the priority of a pending request, created through + * `createRequest`. + * @param {Observable} observable - The Observable returned by `createRequest`. + * @param {Number} priority - The new priority value. + */ + updatePriority: function updatePriority(observable, priority) { + var correspondingTask = taskHandlers.get(observable); - var segmentTemplate = object_assign/* default.apply */.Z.apply(void 0, [{}].concat(segmentTemplates)); - context.availabilityTimeOffset = representationInfos.availabilityTimeOffset + extractMinimumAvailabilityTimeOffset(representation.children.baseURLs) + ((_b = segmentTemplate.availabilityTimeOffset) !== null && _b !== void 0 ? _b : 0); - var timelineParser = segmentTemplate.timelineParser; - representationIndex = timelineParser !== undefined ? new timeline(segmentTemplate, timelineParser, context) : new TemplateRepresentationIndex(segmentTemplate, context); - } else { - var adaptationChildren = representationInfos.adaptation.children; + if (correspondingTask === undefined) { + log/* default.warn */.Z.warn("Fetchers: Cannot update the priority of a request: task not found."); + return; + } - if (adaptationChildren.segmentBase !== undefined) { - var _segmentBase = adaptationChildren.segmentBase; - representationIndex = new BaseRepresentationIndex(_segmentBase, context); - } else if (adaptationChildren.segmentList !== undefined) { - var _segmentList = adaptationChildren.segmentList; - representationIndex = new ListRepresentationIndex(_segmentList, context); - } else { - representationIndex = new TemplateRepresentationIndex({ - duration: Number.MAX_VALUE, - timescale: 1, - startNumber: 0, - initialization: { - media: "" - }, - media: "" - }, context); + prioritizer.updatePriority(correspondingTask, priority); } - } - - return representationIndex; + }; } -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_representations.ts +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules +var Observable = __webpack_require__(4379); +// EXTERNAL MODULE: ./src/utils/array_find_index.ts +var array_find_index = __webpack_require__(5138); +;// CONCATENATED MODULE: ./src/core/fetchers/segment/prioritizer.ts /** * Copyright 2015 CANAL+ Group * @@ -41719,525 +44732,586 @@ function parseRepresentationIndex(representation, representationInfos) { /** - * Process intermediate representations to create final parsed representations. - * @param {Array.} representationsIR - * @param {Object} adaptationInfos - * @returns {Array.} + * Create Observables which can be priorized between one another. + * + * With this class, you can link an Observables to a priority number. + * The lower this number is, the more priority the resulting Observable will + * have. + * + * Such returned Observables - called "tasks" - will then basically wait for + * pending task with more priority (i.e. a lower priority number) to finish + * before "starting". + * + * This only applies for non-pending tasks. For pending tasks, those are usually + * not interrupted except in the following case: + * + * When a task with a "high priority" (which is a configurable priority + * value) is created, pending tasks with a "low priority" (also configurable) + * will be interrupted. Those tasks will be restarted when all tasks with a + * higher priority are finished. + * + * You can also update the priority of an already-created task. + * + * ```js + * const observable1 = Observable.timer(100).pipe(mapTo(1)); + * const observable2 = Observable.timer(100).pipe(mapTo(2)); + * const observable3 = Observable.timer(100).pipe(mapTo(3)); + * const observable4 = Observable.timer(100).pipe(mapTo(4)); + * const observable5 = Observable.timer(100).pipe(mapTo(5)); + * + * // Instanciate ObservablePrioritizer. + * // Also provide a `high` priority step - the maximum priority number a "high + * // priority task" has and a `low` priority step - the minimum priority number + * // a "low priority task" has. + * const prioritizer = new ObservablePrioritizer({ + * prioritySteps: { high: 0, low: 20 } + * }); + * + * const pObservable1 = prioritizer.create(observable1, 4); + * const pObservable2 = prioritizer.create(observable2, 2); + * const pObservable3 = prioritizer.create(observable3, 1); + * const pObservable4 = prioritizer.create(observable4, 3); + * const pObservable5 = prioritizer.create(observable5, 2); + * + * // start every Observables at the same time + * observableMerge( + * pObservable1, + * pObservable2, + * pObservable3, + * pObservable4, + * pObservable5 + * ).subscribe((evt) => { + * if (evt.type === "data") { + * console.log(i); + * + * // To spice things up, update pObservable1 priority to go before + * // pObservable4 + * if (i === 5) { // if pObservable5 is currently emitting + * prioritizer.updatePriority(pObservable1, 1); + * } + * } + * }); + * + * // Result: + * // 3 + * // 2 + * // 5 + * // 1 + * // 4 + * + * // Note: here "1" goes before "4" only because the former's priority has been + * // updated before the latter was started. + * // It would be the other way around if not. + * ``` + * + * @class ObservablePrioritizer */ -function parseRepresentations(representationsIR, adaptation, adaptationInfos) { - var _a, _b; - - var parsedRepresentations = []; - - var _loop = function _loop(reprIdx) { - var representation = representationsIR[reprIdx]; // Compute Representation ID - - var representationID = representation.attributes.id != null ? representation.attributes.id : String(representation.attributes.bitrate) + (representation.attributes.height != null ? "-" + representation.attributes.height : "") + (representation.attributes.width != null ? "-" + representation.attributes.width : "") + (representation.attributes.mimeType != null ? "-" + representation.attributes.mimeType : "") + (representation.attributes.codecs != null ? "-" + representation.attributes.codecs : ""); // Avoid duplicate IDs - - while (parsedRepresentations.some(function (r) { - return r.id === representationID; - })) { - representationID += "-dup"; - } // Retrieve previous version of the Representation, if one. - - - var unsafelyBaseOnPreviousRepresentation = (_b = (_a = adaptationInfos.unsafelyBaseOnPreviousAdaptation) === null || _a === void 0 ? void 0 : _a.getRepresentation(representationID)) !== null && _b !== void 0 ? _b : null; - var representationInfos = (0,object_assign/* default */.Z)({}, adaptationInfos, { - unsafelyBaseOnPreviousRepresentation: unsafelyBaseOnPreviousRepresentation, - adaptation: adaptation - }); - var representationIndex = parseRepresentationIndex(representation, representationInfos); // Find bitrate - - var representationBitrate = void 0; - - if (representation.attributes.bitrate == null) { - log/* default.warn */.Z.warn("DASH: No usable bitrate found in the Representation."); - representationBitrate = 0; - } else { - representationBitrate = representation.attributes.bitrate; - } // Construct Representation Base - - - var parsedRepresentation = { - bitrate: representationBitrate, - index: representationIndex, - id: representationID - }; // Add optional attributes - - var codecs = void 0; - - if (representation.attributes.codecs != null) { - codecs = representation.attributes.codecs; - } else if (adaptation.attributes.codecs != null) { - codecs = adaptation.attributes.codecs; - } - - if (codecs != null) { - codecs = codecs === "mp4a.40.02" ? "mp4a.40.2" : codecs; - parsedRepresentation.codecs = codecs; - } - - if (representation.attributes.frameRate != null) { - parsedRepresentation.frameRate = representation.attributes.frameRate; - } else if (adaptation.attributes.frameRate != null) { - parsedRepresentation.frameRate = adaptation.attributes.frameRate; - } - - if (representation.attributes.height != null) { - parsedRepresentation.height = representation.attributes.height; - } else if (adaptation.attributes.height != null) { - parsedRepresentation.height = adaptation.attributes.height; - } - - if (representation.attributes.mimeType != null) { - parsedRepresentation.mimeType = representation.attributes.mimeType; - } else if (adaptation.attributes.mimeType != null) { - parsedRepresentation.mimeType = adaptation.attributes.mimeType; - } +var ObservablePrioritizer = /*#__PURE__*/function () { + /** + * @param {Options} prioritizerOptions + */ + function ObservablePrioritizer(_ref) { + var prioritySteps = _ref.prioritySteps; + this._minPendingPriority = null; + this._waitingQueue = []; + this._pendingTasks = []; + this._prioritySteps = prioritySteps; - if (representation.attributes.width != null) { - parsedRepresentation.width = representation.attributes.width; - } else if (adaptation.attributes.width != null) { - parsedRepresentation.width = adaptation.attributes.width; + if (this._prioritySteps.high >= this._prioritySteps.low) { + throw new Error("FP Error: the max high level priority should be given a lower" + "priority number than the min low priority."); } + } + /** + * Create a priorized Observable from a base Observable. + * + * When subscribed to, this Observable will have its priority compared to + * all the already-running Observables created from this class. + * + * Only if this number is inferior or equal to the priority of the + * currently-running Observables will it be immediately started. + * In the opposite case, we will wait for higher-priority Observables to + * finish before starting it. + * + * Note that while this Observable is waiting for its turn, it is possible + * to update its property through the updatePriority method, by providing + * the Observable returned by this function and its new priority number. + * + * @param {Observable} obs + * @param {number} priority + * @returns {Observable} + */ - if (adaptation.children.contentProtections != null) { - var contentProtections = adaptation.children.contentProtections.reduce(function (acc, cp) { - var systemId; - if (cp.attributes.schemeIdUri !== undefined && cp.attributes.schemeIdUri.substring(0, 9) === "urn:uuid:") { - systemId = cp.attributes.schemeIdUri.substring(9).replace(/-/g, "").toLowerCase(); - } + var _proto = ObservablePrioritizer.prototype; - if (cp.attributes.keyId !== undefined && cp.attributes.keyId.length > 0) { - acc.keyIds.push({ - keyId: cp.attributes.keyId, - systemId: systemId - }); - } + _proto.create = function create(obs, priority) { + var _this = this; - if (systemId !== undefined) { - var cencPssh = cp.children.cencPssh; + var pObs$ = new Observable/* Observable */.y(function (subscriber) { + var isStillSubscribed = true; // eslint-disable-next-line prefer-const - for (var i = 0; i < cencPssh.length; i++) { - var data = cencPssh[i]; + var newTask; + /** + * Function allowing to start / interrupt the underlying Observable. + * @param {Boolean} shouldRun - If `true`, the observable can run. If + * `false` it means that it just needs to be interrupted if already + * starte. + */ - if (acc.initData.cenc === undefined) { - acc.initData.cenc = []; - } + var trigger = function trigger(shouldRun) { + if (newTask.subscription !== null) { + newTask.subscription.unsubscribe(); + newTask.subscription = null; - acc.initData.cenc.push({ - systemId: systemId, - data: data + if (isStillSubscribed) { + subscriber.next({ + type: "interrupted" }); } } - return acc; - }, { - keyIds: [], - initData: {} - }); - - if (Object.keys(contentProtections.initData).length > 0 || contentProtections.keyIds.length > 0) { - parsedRepresentation.contentProtections = contentProtections; - } - } - - parsedRepresentations.push(parsedRepresentation); - }; - - for (var reprIdx = 0; reprIdx < representationsIR.length; reprIdx++) { - _loop(reprIdx); - } - - return parsedRepresentations; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_adaptation_sets.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. - */ - - - - // eslint-disable-next-line max-len + if (!shouldRun) { + return; + } + _this._minPendingPriority = _this._minPendingPriority === null ? newTask.priority : Math.min(_this._minPendingPriority, newTask.priority); + _this._pendingTasks.push(newTask); + newTask.subscription = obs.subscribe(function (evt) { + return subscriber.next({ + type: "data", + value: evt + }); + }, function (error) { + subscriber.error(error); + newTask.subscription = null; + newTask.finished = true; + _this._onTaskEnd(newTask); + }, function () { + subscriber.next({ + type: "ended" + }); -/** - * Detect if the accessibility given defines an adaptation for the visually - * impaired. - * Based on DVB Document A168 (DVB-DASH). - * @param {Object} accessibility - * @returns {Boolean} - */ + if (isStillSubscribed) { + subscriber.complete(); + } -function isVisuallyImpaired(accessibility) { - if (accessibility == null) { - return false; - } + newTask.subscription = null; + newTask.finished = true; - return accessibility.schemeIdUri === "urn:tva:metadata:cs:AudioPurposeCS:2007" && accessibility.value === "1"; -} -/** - * Detect if the accessibility given defines an adaptation for the hard of - * hearing. - * Based on DVB Document A168 (DVB-DASH). - * @param {Object} accessibility - * @returns {Boolean} - */ + _this._onTaskEnd(newTask); + }); + }; + newTask = { + observable: pObs$, + priority: priority, + trigger: trigger, + subscription: null, + finished: false + }; -function isHardOfHearing(accessibility) { - if (accessibility == null) { - return false; - } + if (!_this._canBeStartedNow(newTask)) { + _this._waitingQueue.push(newTask); + } else { + newTask.trigger(true); - return accessibility.schemeIdUri === "urn:tva:metadata:cs:AudioPurposeCS:2007" && accessibility.value === "2"; -} -/** - * Detect if the accessibility given defines an AdaptationSet containing a sign - * language interpretation. - * Based on DASH-IF 4.3. - * @param {Object} accessibility - * @returns {Boolean} - */ + if (_this._isRunningHighPriorityTasks()) { + // Note: we want to begin interrupting low-priority tasks just + // after starting the current one because the interrupting + // logic can call external code. + // This would mean re-entrancy, itself meaning that some weird + // half-state could be reached unless we're very careful. + // To be sure no harm is done, we put that code at the last + // possible position (the previous Observable sould be + // performing all its initialization synchronously). + _this._interruptCancellableTasks(); + } + } + /** Callback called when this Observable is unsubscribed to. */ -function hasSignLanguageInterpretation(accessibility) { - if (accessibility == null) { - return false; - } + return function () { + isStillSubscribed = false; - return accessibility.schemeIdUri === "urn:mpeg:dash:role:2011" && accessibility.value === "sign"; -} -/** - * Contruct Adaptation ID from the information we have. - * @param {Object} adaptation - * @param {Array.} representations - * @param {Object} infos - * @returns {string} - */ + if (newTask.subscription !== null) { + newTask.subscription.unsubscribe(); + newTask.subscription = null; + } + if (newTask.finished) { + // Task already finished, we're good + return; + } // remove it from waiting queue if in it -function getAdaptationID(adaptation, infos) { - if ((0,is_non_empty_string/* default */.Z)(adaptation.attributes.id)) { - return adaptation.attributes.id; - } - var idString = infos.type; + var waitingQueueIndex = (0,array_find_index/* default */.Z)(_this._waitingQueue, function (elt) { + return elt.observable === pObs$; + }); - if ((0,is_non_empty_string/* default */.Z)(adaptation.attributes.language)) { - idString += "-" + adaptation.attributes.language; - } + if (waitingQueueIndex >= 0) { + // If it was still waiting for its turn + _this._waitingQueue.splice(waitingQueueIndex, 1); + } else { + // remove it from pending queue if in it + var pendingTasksIndex = (0,array_find_index/* default */.Z)(_this._pendingTasks, function (elt) { + return elt.observable === pObs$; + }); - if (infos.isClosedCaption === true) { - idString += "-cc"; - } + if (pendingTasksIndex < 0) { + log/* default.warn */.Z.warn("FP: unsubscribing non-existent task"); + return; + } - if (infos.isAudioDescription === true) { - idString += "-ad"; - } + var pendingTask = _this._pendingTasks.splice(pendingTasksIndex, 1)[0]; - if (infos.isSignInterpreted === true) { - idString += "-si"; - } + if (_this._pendingTasks.length === 0) { + _this._minPendingPriority = null; - if ((0,is_non_empty_string/* default */.Z)(adaptation.attributes.contentType)) { - idString += "-" + adaptation.attributes.contentType; - } + _this._loopThroughWaitingQueue(); + } else if (_this._minPendingPriority === pendingTask.priority) { + _this._minPendingPriority = Math.min.apply(Math, _this._pendingTasks.map(function (t) { + return t.priority; + })); - if ((0,is_non_empty_string/* default */.Z)(adaptation.attributes.codecs)) { - idString += "-" + adaptation.attributes.codecs; + _this._loopThroughWaitingQueue(); + } + } + }; + }); + return pObs$; } + /** + * Update the priority of an Observable created through the `create` method. + * @param {Observable} obs + * @param {number} priority + */ + ; - if ((0,is_non_empty_string/* default */.Z)(adaptation.attributes.mimeType)) { - idString += "-" + adaptation.attributes.mimeType; - } + _proto.updatePriority = function updatePriority(obs, priority) { + var waitingQueueIndex = (0,array_find_index/* default */.Z)(this._waitingQueue, function (elt) { + return elt.observable === obs; + }); - if ((0,is_non_empty_string/* default */.Z)(adaptation.attributes.frameRate)) { - idString += "-" + adaptation.attributes.frameRate; - } + if (waitingQueueIndex >= 0) { + // If it was still waiting for its turn + var waitingQueueElt = this._waitingQueue[waitingQueueIndex]; - return idString; -} -/** - * Returns a list of ID this adaptation can be seamlessly switched to - * @param {Object} adaptation - * @returns {Array.} - */ + if (waitingQueueElt.priority === priority) { + return; + } + waitingQueueElt.priority = priority; -function getAdaptationSetSwitchingIDs(adaptation) { - if (adaptation.children.supplementalProperties != null) { - var supplementalProperties = adaptation.children.supplementalProperties; + if (!this._canBeStartedNow(waitingQueueElt)) { + return; + } - for (var j = 0; j < supplementalProperties.length; j++) { - var supplementalProperty = supplementalProperties[j]; + this._startWaitingQueueTask(waitingQueueIndex); - if (supplementalProperty.schemeIdUri === "urn:mpeg:dash:adaptation-set-switching:2016" && supplementalProperty.value != null) { - return supplementalProperty.value.split(",").map(function (id) { - return id.trim(); - }).filter(function (id) { - return id; - }); + if (this._isRunningHighPriorityTasks()) { + // Re-check to cancel every "cancellable" pending task + // + // Note: We start the task before interrupting cancellable tasks on + // purpose. + // Because both `_startWaitingQueueTask` and + // `_interruptCancellableTasks` can emit events and thus call external + // code, we could retrieve ourselves in a very weird state at this point + // (for example, the different Observable priorities could all be + // shuffled up, new Observables could have been started in the + // meantime, etc.). + // + // By starting the task first, we ensure that this is manageable: + // `_minPendingPriority` has already been updated to the right value at + // the time we reached external code, the priority of the current + // Observable has just been updated, and `_interruptCancellableTasks` + // will ensure that we're basing ourselves on the last `priority` value + // each time. + // Doing it in the reverse order is an order of magnitude more difficult + // to write and to reason about. + this._interruptCancellableTasks(); } + + return; } - } - return []; -} -/** - * Process AdaptationSets intermediate representations to return under its final - * form. - * Note that the AdaptationSets returned are sorted by priority (from the most - * priority to the least one). - * @param {Array.} adaptationsIR - * @param {Object} periodInfos - * @returns {Array.} - */ + var pendingTasksIndex = (0,array_find_index/* default */.Z)(this._pendingTasks, function (elt) { + return elt.observable === obs; + }); + if (pendingTasksIndex < 0) { + log/* default.warn */.Z.warn("FP: request to update the priority of a non-existent task"); + return; + } -function parseAdaptationSets(adaptationsIR, periodInfos) { - var _a, _b, _c, _d; + var task = this._pendingTasks[pendingTasksIndex]; - var parsedAdaptations = {}; - var adaptationSwitchingInfos = {}; - var parsedAdaptationsIDs = []; - /** - * Index of the last parsed AdaptationSet with a Role set as "main" in - * `parsedAdaptations` for a given type. - * Not defined for a type with no main Adaptation inside. - * This is used to put main AdaptationSet first in the resulting array of - * Adaptation while still preserving the MPD order among them. - */ + if (task.priority === priority) { + return; + } - var lastMainAdaptationIndex = {}; // first sort AdaptationSets by absolute priority. + var prevPriority = task.priority; + task.priority = priority; - adaptationsIR.sort(function (a, b) { - var _a, _b; - /* As of DASH-IF 4.3, `1` is the default value. */ + if (this._minPendingPriority === null || priority < this._minPendingPriority) { + this._minPendingPriority = priority; + } else if (this._minPendingPriority === prevPriority) { + // was highest priority + if (this._pendingTasks.length === 1) { + this._minPendingPriority = priority; + } else { + this._minPendingPriority = Math.min.apply(Math, this._pendingTasks.map(function (t) { + return t.priority; + })); + } + this._loopThroughWaitingQueue(); + } else { + // We updated a task which already had a priority value higher than the + // minimum to a value still superior to the minimum. Nothing can happen. + return; + } - var priority1 = (_a = a.attributes.selectionPriority) !== null && _a !== void 0 ? _a : 1; - var priority2 = (_b = b.attributes.selectionPriority) !== null && _b !== void 0 ? _b : 1; - return priority2 - priority1; - }); + if (this._isRunningHighPriorityTasks()) { + // Always interrupt cancellable tasks after all other side-effects, to + // avoid re-entrancy issues + this._interruptCancellableTasks(); + } + } + /** + * Browse the current waiting queue and start all task in it that needs to be + * started: start the ones with the lowest priority value below + * `_minPendingPriority`. + * + * Private properties, such as `_minPendingPriority` are updated accordingly + * while this method is called. + */ + ; - for (var i = 0; i < adaptationsIR.length; i++) { - var adaptation = adaptationsIR[i]; - var adaptationChildren = adaptation.children; - var essentialProperties = adaptationChildren.essentialProperties, - roles = adaptationChildren.roles; - var isExclusivelyTrickModeTrack = Array.isArray(essentialProperties) && essentialProperties.some(function (ep) { - return ep.schemeIdUri === "http://dashif.org/guidelines/trickmode"; - }); + _proto._loopThroughWaitingQueue = function _loopThroughWaitingQueue() { + var minWaitingPriority = this._waitingQueue.reduce(function (acc, elt) { + return acc === null || acc > elt.priority ? elt.priority : acc; + }, null); - if (isExclusivelyTrickModeTrack) { - // We do not for the moment parse trickmode tracks - continue; + if (minWaitingPriority === null || this._minPendingPriority !== null && this._minPendingPriority < minWaitingPriority) { + return; } - var isMainAdaptation = Array.isArray(roles) && roles.some(function (role) { - return role.value === "main"; - }) && roles.some(function (role) { - return role.schemeIdUri === "urn:mpeg:dash:role:2011"; - }); - var representationsIR = adaptation.children.representations; - var availabilityTimeOffset = extractMinimumAvailabilityTimeOffset(adaptation.children.baseURLs) + periodInfos.availabilityTimeOffset; - var adaptationMimeType = adaptation.attributes.mimeType; - var adaptationCodecs = adaptation.attributes.codecs; - var type = inferAdaptationType(representationsIR, (0,is_non_empty_string/* default */.Z)(adaptationMimeType) ? adaptationMimeType : null, (0,is_non_empty_string/* default */.Z)(adaptationCodecs) ? adaptationCodecs : null, adaptationChildren.roles != null ? adaptationChildren.roles : null); + for (var i = 0; i < this._waitingQueue.length; i++) { + var priorityToCheck = this._minPendingPriority === null ? minWaitingPriority : Math.min(this._minPendingPriority, minWaitingPriority); + var elt = this._waitingQueue[i]; - if (type === undefined) { - continue; + if (elt.priority <= priorityToCheck) { + this._startWaitingQueueTask(i); + + i--; // previous operation should have removed that element from the + // the waiting queue + } } + } + /** + * Interrupt and move back to the waiting queue all pending tasks that are + * low priority (having a higher priority number than + * `this._prioritySteps.low`). + */ + ; - var originalID = adaptation.attributes.id; - var newID = void 0; - var adaptationSetSwitchingIDs = getAdaptationSetSwitchingIDs(adaptation); - var parentSegmentTemplates = []; + _proto._interruptCancellableTasks = function _interruptCancellableTasks() { + for (var i = 0; i < this._pendingTasks.length; i++) { + var pendingObj = this._pendingTasks[i]; - if (periodInfos.segmentTemplate !== undefined) { - parentSegmentTemplates.push(periodInfos.segmentTemplate); - } + if (pendingObj.priority >= this._prioritySteps.low) { + this._interruptPendingTask(pendingObj); // The previous call could have a lot of potential side-effects. + // It is safer to re-start the function to not miss any pending + // task that needs to be cancelled. - if (adaptation.children.segmentTemplate !== undefined) { - parentSegmentTemplates.push(adaptation.children.segmentTemplate); + + return this._interruptCancellableTasks(); + } } + } + /** + * Start task which is at the given index in the waiting queue. + * The task will be removed from the waiting queue in the process. + * @param {number} index + */ + ; - var adaptationInfos = { - aggressiveMode: periodInfos.aggressiveMode, - availabilityTimeOffset: availabilityTimeOffset, - baseURLs: resolveBaseURLs(periodInfos.baseURLs, adaptationChildren.baseURLs), - manifestBoundsCalculator: periodInfos.manifestBoundsCalculator, - end: periodInfos.end, - isDynamic: periodInfos.isDynamic, - parentSegmentTemplates: parentSegmentTemplates, - receivedTime: periodInfos.receivedTime, - start: periodInfos.start, - timeShiftBufferDepth: periodInfos.timeShiftBufferDepth, - unsafelyBaseOnPreviousAdaptation: null - }; + _proto._startWaitingQueueTask = function _startWaitingQueueTask(index) { + var task = this._waitingQueue.splice(index, 1)[0]; - if (type === "video" && isMainAdaptation && parsedAdaptations.video !== undefined && parsedAdaptations.video.length > 0 && lastMainAdaptationIndex.video !== undefined) { - var _videoMainAdaptation$; + task.trigger(true); + } + /** + * Move back pending task to the waiting queue and interrupt it. + * @param {object} task + */ + ; - // Add to the already existing main video adaptation - // TODO remove that ugly custom logic? - var videoMainAdaptation = parsedAdaptations.video[lastMainAdaptationIndex.video]; - adaptationInfos.unsafelyBaseOnPreviousAdaptation = (_b = (_a = periodInfos.unsafelyBaseOnPreviousPeriod) === null || _a === void 0 ? void 0 : _a.getAdaptation(videoMainAdaptation.id)) !== null && _b !== void 0 ? _b : null; - var representations = parseRepresentations(representationsIR, adaptation, adaptationInfos); + _proto._interruptPendingTask = function _interruptPendingTask(task) { + var pendingTasksIndex = (0,array_find_index/* default */.Z)(this._pendingTasks, function (elt) { + return elt.observable === task.observable; + }); - (_videoMainAdaptation$ = videoMainAdaptation.representations).push.apply(_videoMainAdaptation$, representations); + if (pendingTasksIndex < 0) { + log/* default.warn */.Z.warn("FP: Interrupting a non-existent pending task. Aborting..."); + return; + } // Stop task and put it back in the waiting queue - newID = videoMainAdaptation.id; - } else { - var accessibility = adaptationChildren.accessibility; - var isDub = void 0; - if (roles !== undefined && roles.some(function (role) { - return role.value === "dub"; - })) { - isDub = true; - } + this._pendingTasks.splice(pendingTasksIndex, 1); - var isClosedCaption = type === "text" && accessibility != null && isHardOfHearing(accessibility) ? true : undefined; - var isAudioDescription = type === "audio" && accessibility != null && isVisuallyImpaired(accessibility) ? true : undefined; - var isSignInterpreted = type === "video" && accessibility != null && hasSignLanguageInterpretation(accessibility) ? true : undefined; - var adaptationID = getAdaptationID(adaptation, { - isAudioDescription: isAudioDescription, - isClosedCaption: isClosedCaption, - isSignInterpreted: isSignInterpreted, - type: type - }); // Avoid duplicate IDs + this._waitingQueue.push(task); - while ((0,array_includes/* default */.Z)(parsedAdaptationsIDs, adaptationID)) { - adaptationID += "-dup"; - } + if (this._pendingTasks.length === 0) { + this._minPendingPriority = null; + } else if (this._minPendingPriority === task.priority) { + this._minPendingPriority = Math.min.apply(Math, this._pendingTasks.map(function (t) { + return t.priority; + })); + } - newID = adaptationID; - parsedAdaptationsIDs.push(adaptationID); - adaptationInfos.unsafelyBaseOnPreviousAdaptation = (_d = (_c = periodInfos.unsafelyBaseOnPreviousPeriod) === null || _c === void 0 ? void 0 : _c.getAdaptation(adaptationID)) !== null && _d !== void 0 ? _d : null; + task.trigger(false); // Interrupt at last step because it calls external code + } + /** + * Logic ran when a task has ended (either errored or completed). + * @param {Object} task + */ + ; - var _representations = parseRepresentations(representationsIR, adaptation, adaptationInfos); + _proto._onTaskEnd = function _onTaskEnd(task) { + var pendingTasksIndex = (0,array_find_index/* default */.Z)(this._pendingTasks, function (elt) { + return elt.observable === task.observable; + }); - var parsedAdaptationSet = { - id: adaptationID, - representations: _representations, - type: type - }; + if (pendingTasksIndex < 0) { + return; // Happen for example when the task has been interrupted + } - if (adaptation.attributes.language != null) { - parsedAdaptationSet.language = adaptation.attributes.language; - } + this._pendingTasks.splice(pendingTasksIndex, 1); - if (isClosedCaption != null) { - parsedAdaptationSet.closedCaption = isClosedCaption; + if (this._pendingTasks.length > 0) { + if (this._minPendingPriority === task.priority) { + this._minPendingPriority = Math.min.apply(Math, this._pendingTasks.map(function (t) { + return t.priority; + })); } - if (isAudioDescription != null) { - parsedAdaptationSet.audioDescription = isAudioDescription; - } + return; // still waiting for Observables to finish + } - if (isDub === true) { - parsedAdaptationSet.isDub = true; - } + this._minPendingPriority = null; - if (isSignInterpreted === true) { - parsedAdaptationSet.isSignInterpreted = true; - } + this._loopThroughWaitingQueue(); + } + /** + * Return `true` if the given task can be started immediately based on its + * priority. + * @param {Object} task + * @returns {boolean} + */ + ; - var adaptationsOfTheSameType = parsedAdaptations[type]; + _proto._canBeStartedNow = function _canBeStartedNow(task) { + return this._minPendingPriority === null || task.priority <= this._minPendingPriority; + } + /** + * Returns `true` if any running task is considered "high priority". + * returns `false` otherwise. + * @param {Object} task + * @returns {boolean} + */ + ; - if (adaptationsOfTheSameType === undefined) { - parsedAdaptations[type] = [parsedAdaptationSet]; + _proto._isRunningHighPriorityTasks = function _isRunningHighPriorityTasks() { + return this._minPendingPriority !== null && this._minPendingPriority <= this._prioritySteps.high; + }; - if (isMainAdaptation) { - lastMainAdaptationIndex[type] = 0; - } - } else { - var mergedInto = null; // look if we have to merge this into another Adaptation + return ObservablePrioritizer; +}(); - var _loop = function _loop(k) { - var id = adaptationSetSwitchingIDs[k]; - var switchingInfos = adaptationSwitchingInfos[id]; - if (switchingInfos != null && switchingInfos.newID !== newID && (0,array_includes/* default */.Z)(switchingInfos.adaptationSetSwitchingIDs, originalID)) { - var adaptationToMergeInto = (0,array_find/* default */.Z)(adaptationsOfTheSameType, function (a) { - return a.id === id; - }); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/tap.js +var tap = __webpack_require__(3068); +// EXTERNAL MODULE: ./src/utils/array_includes.ts +var array_includes = __webpack_require__(7714); +// EXTERNAL MODULE: ./src/utils/assert_unreachable.ts +var assert_unreachable = __webpack_require__(8418); +// 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 + * + * 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. + */ - if (adaptationToMergeInto != null && adaptationToMergeInto.audioDescription === parsedAdaptationSet.audioDescription && adaptationToMergeInto.closedCaption === parsedAdaptationSet.closedCaption && adaptationToMergeInto.language === parsedAdaptationSet.language) { - var _adaptationToMergeInt; +/** + * Caching object used to cache initialization segments. + * This allow to have a faster representation switch and faster seeking. + * @class InitializationSegmentCache + */ +var InitializationSegmentCache = /*#__PURE__*/function () { + function InitializationSegmentCache() { + this._cache = new WeakMap(); + } + /** + * @param {Object} obj + * @param {*} response + */ - log/* default.info */.Z.info("DASH Parser: merging \"switchable\" AdaptationSets", originalID, id); - (_adaptationToMergeInt = adaptationToMergeInto.representations).push.apply(_adaptationToMergeInt, parsedAdaptationSet.representations); + var _proto = InitializationSegmentCache.prototype; - mergedInto = adaptationToMergeInto; - } - } - }; + _proto.add = function add(_ref, response) { + var representation = _ref.representation, + segment = _ref.segment; - for (var k = 0; k < adaptationSetSwitchingIDs.length; k++) { - _loop(k); - } + if (segment.isInit) { + this._cache.set(representation, response); + } + } + /** + * @param {Object} obj + * @returns {*} response + */ + ; - if (isMainAdaptation) { - var oldLastMainIdx = lastMainAdaptationIndex[type]; - var newLastMainIdx = oldLastMainIdx === undefined ? 0 : oldLastMainIdx + 1; + _proto.get = function get(_ref2) { + var representation = _ref2.representation, + segment = _ref2.segment; - if (mergedInto === null) { - // put "main" Adaptation after all other Main Adaptations - adaptationsOfTheSameType.splice(newLastMainIdx, 0, parsedAdaptationSet); - lastMainAdaptationIndex[type] = newLastMainIdx; - } else { - var indexOf = adaptationsOfTheSameType.indexOf(mergedInto); + if (segment.isInit) { + var value = this._cache.get(representation); - if (indexOf < 0) { - // Weird, not found - adaptationsOfTheSameType.splice(newLastMainIdx, 0, parsedAdaptationSet); - lastMainAdaptationIndex[type] = newLastMainIdx; - } else if (oldLastMainIdx === undefined || indexOf > oldLastMainIdx) { - // Found but was not main - adaptationsOfTheSameType.splice(indexOf, 1); - adaptationsOfTheSameType.splice(newLastMainIdx, 0, mergedInto); - lastMainAdaptationIndex[type] = newLastMainIdx; - } - } - } else if (mergedInto === null) { - adaptationsOfTheSameType.push(parsedAdaptationSet); - } + if (value !== undefined) { + return value; } } - if (originalID != null && adaptationSwitchingInfos[originalID] == null) { - adaptationSwitchingInfos[originalID] = { - newID: newID, - adaptationSetSwitchingIDs: adaptationSetSwitchingIDs - }; - } - } + return null; + }; - return parsedAdaptations; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_periods.ts + return InitializationSegmentCache; +}(); + +/* harmony default export */ const initialization_segment_cache = (InitializationSegmentCache); +// EXTERNAL MODULE: ./src/utils/cast_to_observable.ts +var cast_to_observable = __webpack_require__(8117); +;// CONCATENATED MODULE: ./src/core/fetchers/segment/create_segment_loader.ts /** * Copyright 2015 CANAL+ Group * @@ -42256,251 +45330,339 @@ function parseAdaptationSets(adaptationsIR, periodInfos) { - // eslint-disable-next-line max-len - - -var generatePeriodID = (0,id_generator/* default */.Z)(); /** - * Process intermediate periods to create final parsed periods. - * @param {Array.} periodsIR - * @param {Object} contextInfos - * @returns {Array.} + * Returns a function allowing to load any wanted segment. + * + * The function returned takes in argument information about the wanted segment + * and returns an Observable which will emit various events related to the + * segment request (see ISegmentLoaderEvent). + * + * This observable will throw if, following the options given, the request and + * possible retry all failed. + * + * This observable will complete after emitting all the segment's data. + * + * Type parameters: + * - T: type of the data emitted + * + * @param {Function} loader + * @param {Object | undefined} cache + * @param {Object} options + * @returns {Function} */ -function parsePeriods(periodsIR, contextInfos) { - var _a, _b, _c; - - var parsedPeriods = []; - var periodsTimeInformation = getPeriodsTimeInformation(periodsIR, contextInfos); - - if (periodsTimeInformation.length !== periodsIR.length) { - throw new Error("MPD parsing error: the time information are incoherent."); - } - - var isDynamic = contextInfos.isDynamic, - timeShiftBufferDepth = contextInfos.timeShiftBufferDepth; - var manifestBoundsCalculator = new ManifestBoundsCalculator({ - isDynamic: isDynamic, - timeShiftBufferDepth: timeShiftBufferDepth - }); - - if (!isDynamic && contextInfos.duration != null) { - manifestBoundsCalculator.setLastPosition(contextInfos.duration); - } // We parse it in reverse because we might need to deduce the buffer depth from - // the last Periods' indexes +function createSegmentLoader(loader, cache, backoffOptions) { + /** + * Try to retrieve the segment from the cache and if not found call the + * pipeline's loader (with possible retries) to load it. + * @param {Object} loaderArgument - Context for the wanted segment. + * @returns {Observable} + */ + function loadData(wantedContent) { + /** + * Call the Pipeline's loader with an exponential Backoff. + * @returns {Observable} + */ + function startLoaderWithBackoff() { + var _a; + var request$ = function request$(url) { + var loaderArgument = (0,object_assign/* default */.Z)({ + url: url + }, wantedContent); + return (0,concat/* concat */.z)((0,of.of)({ + type: "request", + value: loaderArgument + }), (0,rx_try_catch/* default */.Z)(loader, loaderArgument)); + }; - var _loop = function _loop(i) { - var periodIR = periodsIR[i]; - var xlinkInfos = contextInfos.xlinkInfos.get(periodIR); - var periodBaseURLs = resolveBaseURLs(contextInfos.baseURLs, periodIR.children.baseURLs); - var _periodsTimeInformati = periodsTimeInformation[i], - periodStart = _periodsTimeInformati.periodStart, - periodDuration = _periodsTimeInformati.periodDuration, - periodEnd = _periodsTimeInformati.periodEnd; - var periodID = void 0; + return tryURLsWithBackoff((_a = wantedContent.segment.mediaURLs) !== null && _a !== void 0 ? _a : [null], request$, backoffOptions).pipe((0,catchError/* catchError */.K)(function (error) { + throw errorSelector(error); + }), (0,map/* map */.U)(function (evt) { + if (evt.type === "retry") { + return { + type: "warning", + value: errorSelector(evt.value) + }; + } else if (evt.value.type === "request") { + return evt.value; + } - if (periodIR.attributes.id == null) { - log/* default.warn */.Z.warn("DASH: No usable id found in the Period. Generating one."); - periodID = "gen-dash-period-" + generatePeriodID(); - } else { - periodID = periodIR.attributes.id; - } // Avoid duplicate IDs + var response = evt.value; + if (response.type === "data-loaded" && cache != null) { + cache.add(wantedContent, response.value); + } - while (parsedPeriods.some(function (p) { - return p.id === periodID; - })) { - periodID += "-dup"; + return evt.value; + })); } - var receivedTime = xlinkInfos !== undefined ? xlinkInfos.receivedTime : contextInfos.receivedTime; - var availabilityTimeOffset = extractMinimumAvailabilityTimeOffset(periodIR.children.baseURLs) + contextInfos.availabilityTimeOffset; - var unsafelyBaseOnPreviousPeriod = (_b = (_a = contextInfos.unsafelyBaseOnPreviousManifest) === null || _a === void 0 ? void 0 : _a.getPeriod(periodID)) !== null && _b !== void 0 ? _b : null; - var periodInfos = { - aggressiveMode: contextInfos.aggressiveMode, - availabilityTimeOffset: availabilityTimeOffset, - baseURLs: periodBaseURLs, - manifestBoundsCalculator: manifestBoundsCalculator, - end: periodEnd, - isDynamic: isDynamic, - receivedTime: receivedTime, - segmentTemplate: periodIR.children.segmentTemplate, - start: periodStart, - timeShiftBufferDepth: timeShiftBufferDepth, - unsafelyBaseOnPreviousPeriod: unsafelyBaseOnPreviousPeriod - }; - var adaptations = parseAdaptationSets(periodIR.children.adaptations, periodInfos); - var streamEvents = (_c = periodIR.children.streamEvents) === null || _c === void 0 ? void 0 : _c.map(function (event) { - var _a; + var dataFromCache = cache != null ? cache.get(wantedContent) : null; - var start = ((_a = event.eventPresentationTime) !== null && _a !== void 0 ? _a : 0) / event.timescale + periodStart; - var end = event.duration !== undefined ? start + event.duration / event.timescale : undefined; - return { - start: start, - end: end, - data: event.data, - id: event.id - }; - }); - var parsedPeriod = { - id: periodID, - start: periodStart, - end: periodEnd, - duration: periodDuration, - adaptations: adaptations, - streamEvents: streamEvents - }; - parsedPeriods.unshift(parsedPeriod); + if (dataFromCache != null) { + return (0,cast_to_observable/* default */.Z)(dataFromCache).pipe((0,map/* map */.U)(function (response) { + return { + type: "cache", + value: response + }; + }), (0,catchError/* catchError */.K)(startLoaderWithBackoff)); + } - if (!manifestBoundsCalculator.lastPositionIsKnown()) { - var _lastPosition = getMaximumLastPosition(adaptations); + return startLoaderWithBackoff(); + } + /** + * Load the corresponding segment. + * @param {Object} content + * @returns {Observable} + */ - if (!isDynamic) { - if (typeof _lastPosition === "number") { - manifestBoundsCalculator.setLastPosition(_lastPosition); - } - } else { - if (typeof _lastPosition === "number") { - var _positionTime = performance.now() / 1000; - manifestBoundsCalculator.setLastPosition(_lastPosition, _positionTime); - } else { - var _guessedLastPositionFromClock = guessLastPositionFromClock(contextInfos, periodStart); + return function loadSegment(content) { + return loadData(content).pipe((0,mergeMap/* mergeMap */.zg)(function (arg) { + var metrics$; - if (_guessedLastPositionFromClock !== undefined) { - var guessedLastPosition = _guessedLastPositionFromClock[0], - guessedPositionTime = _guessedLastPositionFromClock[1]; - manifestBoundsCalculator.setLastPosition(guessedLastPosition, guessedPositionTime); + if ((arg.type === "data-chunk-complete" || arg.type === "data-loaded") && arg.value.size !== undefined && arg.value.duration !== undefined) { + metrics$ = (0,of.of)({ + type: "metrics", + value: { + size: arg.value.size, + duration: arg.value.duration, + content: content } - } + }); + } else { + metrics$ = empty/* EMPTY */.E; } - } - }; - for (var i = periodsIR.length - 1; i >= 0; i--) { - _loop(i); - } + switch (arg.type) { + case "warning": + case "request": + case "progress": + return (0,of.of)(arg); - if (contextInfos.isDynamic && !manifestBoundsCalculator.lastPositionIsKnown()) { - // Guess a last time the last position - var guessedLastPositionFromClock = guessLastPositionFromClock(contextInfos, 0); + case "cache": + case "data-created": + case "data-loaded": + return (0,concat/* concat */.z)((0,of.of)({ + type: "data", + value: arg.value + }), metrics$); - if (guessedLastPositionFromClock !== undefined) { - var lastPosition = guessedLastPositionFromClock[0], - positionTime = guessedLastPositionFromClock[1]; - manifestBoundsCalculator.setLastPosition(lastPosition, positionTime); - } - } + case "data-chunk": + return (0,of.of)({ + type: "chunk", + value: arg.value + }); - return flattenOverlappingPeriods(parsedPeriods); + case "data-chunk-complete": + return (0,concat/* concat */.z)((0,of.of)({ + type: "chunk-complete", + value: null + }), metrics$); + + default: + (0,assert_unreachable/* default */.Z)(arg); + } + })); + }; } +;// CONCATENATED MODULE: ./src/core/fetchers/segment/segment_fetcher.ts /** - * Try to guess the "last position", which is the last position - * available in the manifest in seconds, and the "position time", the time - * (`performance.now()`) in which the last position was collected. - * - * These values allows to retrieve at any time in the future the new last - * position, by substracting the position time to the last position, and - * adding to it the new value returned by `performance.now`. - * - * The last position and position time are returned by this function if and only if - * it would indicate a last position superior to the `minimumTime` given. + * Copyright 2015 CANAL+ Group * - * This last part allows for example to detect which Period is likely to be the - * "current" one in multi-periods contents. By giving the Period's start as a - * `minimumTime`, you ensure that you will get a value only if the current time - * is in that period. + * 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 * - * This is useful as guessing the live time from the clock can be seen as a last - * resort. By detecting that the current time is before the currently considered - * Period, we can just parse and look at the previous Period. If we can guess - * the live time more directly from that previous one, we might be better off - * than just using the clock. + * http://www.apache.org/licenses/LICENSE-2.0 * - * @param {Object} contextInfos - * @param {number} minimumTime - * @returns {Array.} + * 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 guessLastPositionFromClock(contextInfos, minimumTime) { - if (contextInfos.clockOffset != null) { - var lastPosition = contextInfos.clockOffset / 1000 - contextInfos.availabilityStartTime; - var positionTime = performance.now() / 1000; - var timeInSec = positionTime + lastPosition; - if (timeInSec >= minimumTime) { - return [timeInSec, positionTime]; - } - } else { - var now = Date.now() / 1000; - if (now >= minimumTime) { - log/* default.warn */.Z.warn("DASH Parser: no clock synchronization mechanism found." + " Using the system clock instead."); - var _lastPosition2 = now - contextInfos.availabilityStartTime; - var _positionTime2 = performance.now() / 1000; - return [_lastPosition2, _positionTime2]; - } - } - return undefined; -} + +var generateRequestID = (0,id_generator/* default */.Z)(); /** - * Try to extract the last position declared for any segments in a Period: - * - If at least a single index' last position is defined, take the maximum - * among them. - * - If segments are available but we cannot define the last position - * return undefined. - * - If no segment are available in that period, return null - * @param {Object} adaptationsPerType - * @returns {number|null|undefined} + * Create a function which will fetch and parse segments. + * @param {string} bufferType + * @param {Object} transport + * @param {Subject} requests$ + * @param {Object} options + * @returns {Function} */ +function segment_fetcher_createSegmentFetcher(bufferType, transport, requests$, options) { + var cache = (0,array_includes/* default */.Z)(["audio", "video"], bufferType) ? new initialization_segment_cache() : undefined; + var segmentLoader = createSegmentLoader(transport[bufferType].loader, cache, options); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -function getMaximumLastPosition(adaptationsPerType) { - var maxEncounteredPosition = null; - var allIndexAreEmpty = true; - var adaptationsVal = (0,object_values/* default */.Z)(adaptationsPerType).filter(function (ada) { - return ada != null; - }); - var allAdaptations = (0,flat_map/* default */.Z)(adaptationsVal, function (adaptationsForType) { - return adaptationsForType; - }); + var segmentParser = transport[bufferType].parser; // deal with it - for (var adapIndex = 0; adapIndex < allAdaptations.length; adapIndex++) { - var representations = allAdaptations[adapIndex].representations; + /** + * Process the segmentLoader observable to adapt it to the the rest of the + * code: + * - use the requests subject for network requests and their progress + * - use the warning$ subject for retries' error messages + * - only emit the data + * @param {Object} content + * @returns {Observable} + */ - for (var repIndex = 0; repIndex < representations.length; repIndex++) { - var representation = representations[repIndex]; - var position = representation.index.getLastPosition(); + return function fetchSegment(content) { + var id = generateRequestID(); + var requestBeginSent = false; + return segmentLoader(content).pipe((0,tap/* tap */.b)(function (arg) { + switch (arg.type) { + case "metrics": + { + requests$.next(arg); + break; + } - if (position !== null) { - allIndexAreEmpty = false; + case "request": + { + var value = arg.value; // format it for ABR Handling - if (typeof position === "number") { - maxEncounteredPosition = maxEncounteredPosition == null ? position : Math.max(maxEncounteredPosition, position); - } + var segment = value.segment; + + if (segment === undefined) { + return; + } + + requestBeginSent = true; + requests$.next({ + type: "requestBegin", + value: { + duration: segment.duration, + time: segment.time, + requestTimestamp: performance.now(), + id: id + } + }); + break; + } + + case "progress": + { + var _value = arg.value; + + if (_value.totalSize != null && _value.size < _value.totalSize) { + requests$.next({ + type: "progress", + value: { + duration: _value.duration, + size: _value.size, + totalSize: _value.totalSize, + timestamp: performance.now(), + id: id + } + }); + } + + break; + } } - } - } + }), finalize(function () { + if (requestBeginSent) { + requests$.next({ + type: "requestEnd", + value: { + id: id + } + }); + } + }), (0,filter/* filter */.h)(function (e) { + switch (e.type) { + case "warning": + case "chunk": + case "chunk-complete": + case "data": + return true; - if (maxEncounteredPosition != null) { - return maxEncounteredPosition; - } else if (allIndexAreEmpty) { - return null; - } + case "progress": + case "metrics": + case "request": + return false; + + default: + (0,assert_unreachable/* default */.Z)(e); + } + }), (0,mergeMap/* mergeMap */.zg)(function (evt) { + if (evt.type === "warning") { + return (0,of.of)(evt); + } + + if (evt.type === "chunk-complete") { + return (0,of.of)({ + type: "chunk-complete" + }); + } + + var isChunked = evt.type === "chunk"; + var data = { + type: "chunk", + + /** + * Parse the loaded data. + * @param {Object} [initTimescale] + * @returns {Observable} + */ + parse: function parse(initTimescale) { + var response = { + data: evt.value.responseData, + isChunked: isChunked + }; + /* eslint-disable @typescript-eslint/no-unsafe-call */ + + /* eslint-disable @typescript-eslint/no-unsafe-member-access */ + + /* eslint-disable @typescript-eslint/no-unsafe-return */ + + return segmentParser({ + response: response, + initTimescale: initTimescale, + content: content + }) + /* eslint-enable @typescript-eslint/no-unsafe-call */ + + /* eslint-enable @typescript-eslint/no-unsafe-member-access */ + + /* eslint-enable @typescript-eslint/no-unsafe-return */ + .pipe((0,catchError/* catchError */.K)(function (error) { + throw formatError(error, { + defaultCode: "PIPELINE_PARSE_ERROR", + defaultReason: "Unknown parsing error" + }); + })); + } + }; + + if (isChunked) { + return (0,of.of)(data); + } - return undefined; + return (0,concat/* concat */.z)((0,of.of)(data), (0,of.of)({ + type: "chunk-complete" + })); + }), (0,share/* share */.B)() // avoid multiple side effects if multiple subs + ); + }; } -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_mpd.ts +;// CONCATENATED MODULE: ./src/core/fetchers/segment/segment_fetcher_creator.ts /** * Copyright 2015 CANAL+ Group * @@ -42519,287 +45681,77 @@ function getMaximumLastPosition(adaptationsPerType) { - // eslint-disable-next-line max-len - - - - - - - - -var DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0 = config/* default.DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0 */.Z.DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0; -/** - * @param {Element} root - The MPD root. - * @param {Object} args - * @returns {Object} - */ - -function parseMPD(root, args) { - // Transform whole MPD into a parsed JS object representation - var _createMPDIntermediat = createMPDIntermediateRepresentation(root), - mpdIR = _createMPDIntermediat[0], - warnings = _createMPDIntermediat[1]; - - return loadExternalRessourcesAndParse(mpdIR, args, warnings); -} +var MIN_CANCELABLE_PRIORITY = config/* default.MIN_CANCELABLE_PRIORITY */.Z.MIN_CANCELABLE_PRIORITY, + MAX_HIGH_PRIORITY_LEVEL = config/* default.MAX_HIGH_PRIORITY_LEVEL */.Z.MAX_HIGH_PRIORITY_LEVEL; /** - * Checks if xlinks needs to be loaded before actually parsing the manifest. - * @param {Object} mpdIR - * @param {Object} args - * @param {Array.} warnings - * @returns {Object} + * Interact with the transport pipelines to download segments with the right + * priority. + * + * @class SegmentFetcherCreator + * + * @example + * ```js + * const creator = new SegmentFetcherCreator(transport); + * + * // 2 - create a new fetcher with its backoff options + * const fetcher = creator.createSegmentFetcher("audio", { + * maxRetryRegular: Infinity, + * maxRetryOffline: Infinity, + * }); + * + * // 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)); + * ``` */ -function loadExternalRessourcesAndParse(mpdIR, args, warnings, hasLoadedClock) { - var rootChildren = mpdIR.children, - rootAttributes = mpdIR.attributes; - var xlinkInfos = new WeakMap(); - - if (args.externalClockOffset == null) { - var isDynamic = rootAttributes.type === "dynamic"; - var directTiming = (0,array_find/* default */.Z)(rootChildren.utcTimings, function (utcTiming) { - return utcTiming.schemeIdUri === "urn:mpeg:dash:utc:direct:2014" && utcTiming.value != null; - }); - var clockOffsetFromDirectUTCTiming = directTiming != null && directTiming.value != null ? getClockOffset(directTiming.value) : undefined; - var clockOffset = clockOffsetFromDirectUTCTiming != null && !isNaN(clockOffsetFromDirectUTCTiming) ? clockOffsetFromDirectUTCTiming : undefined; - - if (clockOffset != null) { - args.externalClockOffset = clockOffset; - } else if (isDynamic && hasLoadedClock !== true) { - var UTCTimingHTTPURL = getHTTPUTCTimingURL(mpdIR); - - if (UTCTimingHTTPURL != null && UTCTimingHTTPURL.length > 0) { - // TODO fetch UTCTiming and XLinks at the same time - return { - type: "needs-ressources", - value: { - ressources: [UTCTimingHTTPURL], - "continue": function continueParsingMPD(loadedRessources) { - if (loadedRessources.length !== 1) { - throw new Error("DASH parser: wrong number of loaded ressources."); - } - - clockOffset = getClockOffset(loadedRessources[0].responseData); - args.externalClockOffset = clockOffset; - return loadExternalRessourcesAndParse(mpdIR, args, warnings, true); - } - } - }; +var SegmentFetcherCreator = /*#__PURE__*/function () { + /** + * @param {Object} transport + */ + function SegmentFetcherCreator(transport, options) { + this._transport = transport; + this._prioritizer = new ObservablePrioritizer({ + prioritySteps: { + high: MAX_HIGH_PRIORITY_LEVEL, + low: MIN_CANCELABLE_PRIORITY } - } - } - - var xlinksToLoad = []; - - for (var i = 0; i < rootChildren.periods.length; i++) { - var _rootChildren$periods = rootChildren.periods[i].attributes, - xlinkHref = _rootChildren$periods.xlinkHref, - xlinkActuate = _rootChildren$periods.xlinkActuate; - - if (xlinkHref != null && xlinkActuate === "onLoad") { - xlinksToLoad.push({ - index: i, - ressource: xlinkHref - }); - } - } - - if (xlinksToLoad.length === 0) { - return parseCompleteIntermediateRepresentation(mpdIR, args, warnings, xlinkInfos); + }); + this._backoffOptions = options; } + /** + * Create a segment fetcher, allowing to easily perform segment requests. + * @param {string} bufferType - The type of buffer concerned (e.g. "audio", + * "video", etc.) + * @param {Subject} requests$ - Subject through which request-related events + * (such as those needed by the ABRManager) will be sent. + * @returns {Object} + */ - return { - type: "needs-ressources", - value: { - ressources: xlinksToLoad.map(function (_ref) { - var ressource = _ref.ressource; - return ressource; - }), - "continue": function continueParsingMPD(loadedRessources) { - if (loadedRessources.length !== xlinksToLoad.length) { - throw new Error("DASH parser: wrong number of loaded ressources."); - } // Note: It is important to go from the last index to the first index in - // the resulting array, as we will potentially add elements to the array - - - for (var _i = loadedRessources.length - 1; _i >= 0; _i--) { - var _rootChildren$periods2; - - var index = xlinksToLoad[_i].index; - var _loadedRessources$_i = loadedRessources[_i], - xlinkData = _loadedRessources$_i.responseData, - receivedTime = _loadedRessources$_i.receivedTime, - sendingTime = _loadedRessources$_i.sendingTime, - url = _loadedRessources$_i.url; - var wrappedData = "" + xlinkData + ""; - var dataAsXML = new DOMParser().parseFromString(wrappedData, "text/xml"); - - if (dataAsXML == null || dataAsXML.children.length === 0) { - throw new Error("DASH parser: Invalid external ressources"); - } - - var periods = dataAsXML.children[0].children; - var periodsIR = []; - - for (var j = 0; j < periods.length; j++) { - if (periods[j].nodeType === Node.ELEMENT_NODE) { - var _createPeriodIntermed = createPeriodIntermediateRepresentation(periods[j]), - periodIR = _createPeriodIntermed[0], - periodWarnings = _createPeriodIntermed[1]; - - xlinkInfos.set(periodIR, { - receivedTime: receivedTime, - sendingTime: sendingTime, - url: url - }); - periodsIR.push(periodIR); - - if (periodWarnings.length > 0) { - warnings.push.apply(warnings, periodWarnings); - } - } - } // replace original "xlinked" periods by the real deal - - - (_rootChildren$periods2 = rootChildren.periods).splice.apply(_rootChildren$periods2, [index, 1].concat(periodsIR)); - } - return loadExternalRessourcesAndParse(mpdIR, args, warnings); - } - } - }; -} -/** - * Parse the MPD intermediate representation into a regular Manifest. - * @param {Object} mpdIR - * @param {Object} args - * @param {Array.} warnings - * @param {Object} xlinkInfos - * @returns {Object} - */ + var _proto = SegmentFetcherCreator.prototype; + _proto.createSegmentFetcher = function createSegmentFetcher(bufferType, requests$) { + var backoffOptions = getSegmentBackoffOptions(bufferType, this._backoffOptions); -function parseCompleteIntermediateRepresentation(mpdIR, args, warnings, xlinkInfos) { - var _a, _b; + var segmentFetcher = segment_fetcher_createSegmentFetcher(bufferType, this._transport, requests$, backoffOptions); - var rootChildren = mpdIR.children, - rootAttributes = mpdIR.attributes; - var isDynamic = rootAttributes.type === "dynamic"; - var baseURLs = resolveBaseURLs(args.url === undefined ? [] : [(0,resolve_url/* normalizeBaseURL */.f)(args.url)], rootChildren.baseURLs); - var availabilityStartTime = parseAvailabilityStartTime(rootAttributes, args.referenceDateTime); - var timeShiftBufferDepth = rootAttributes.timeShiftBufferDepth; - var clockOffset = args.externalClockOffset, - unsafelyBaseOnPreviousManifest = args.unsafelyBaseOnPreviousManifest; - var availabilityTimeOffset = extractMinimumAvailabilityTimeOffset(rootChildren.baseURLs); - var manifestInfos = { - aggressiveMode: args.aggressiveMode, - availabilityStartTime: availabilityStartTime, - availabilityTimeOffset: availabilityTimeOffset, - baseURLs: baseURLs, - clockOffset: clockOffset, - duration: rootAttributes.duration, - isDynamic: isDynamic, - receivedTime: args.manifestReceivedTime, - timeShiftBufferDepth: timeShiftBufferDepth, - unsafelyBaseOnPreviousManifest: unsafelyBaseOnPreviousManifest, - xlinkInfos: xlinkInfos + return applyPrioritizerToSegmentFetcher(this._prioritizer, segmentFetcher); }; - var parsedPeriods = parsePeriods(rootChildren.periods, manifestInfos); - var mediaPresentationDuration = rootAttributes.duration; - var lifetime; - var minimumTime; - var timeshiftDepth = null; - var maximumTimeData; - - if (rootAttributes.minimumUpdatePeriod !== undefined && rootAttributes.minimumUpdatePeriod >= 0) { - lifetime = rootAttributes.minimumUpdatePeriod === 0 ? DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0 : rootAttributes.minimumUpdatePeriod; - } - - var _getMinimumAndMaximum = getMinimumAndMaximumPosition(parsedPeriods), - contentStart = _getMinimumAndMaximum[0], - contentEnd = _getMinimumAndMaximum[1]; - - var now = performance.now(); - - if (!isDynamic) { - minimumTime = contentStart !== undefined ? contentStart : ((_a = parsedPeriods[0]) === null || _a === void 0 ? void 0 : _a.start) !== undefined ? parsedPeriods[0].start : 0; - var maximumTime; - if (contentEnd !== undefined) { - maximumTime = contentEnd; - } else if (mediaPresentationDuration !== undefined) { - maximumTime = mediaPresentationDuration; - } else if (parsedPeriods[parsedPeriods.length - 1] !== undefined) { - var lastPeriod = parsedPeriods[parsedPeriods.length - 1]; - maximumTime = (_b = lastPeriod.end) !== null && _b !== void 0 ? _b : lastPeriod.duration !== undefined ? lastPeriod.start + lastPeriod.duration : undefined; - } - - maximumTimeData = { - isLinear: false, - value: maximumTime !== null && maximumTime !== void 0 ? maximumTime : Infinity, - time: now - }; - } else { - minimumTime = contentStart; - timeshiftDepth = timeShiftBufferDepth !== null && timeShiftBufferDepth !== void 0 ? timeShiftBufferDepth : null; - - var _maximumTime; - - if (contentEnd !== undefined) { - _maximumTime = contentEnd; - } else { - var ast = availabilityStartTime !== null && availabilityStartTime !== void 0 ? availabilityStartTime : 0; - var externalClockOffset = args.externalClockOffset; - - if (externalClockOffset === undefined) { - log/* default.warn */.Z.warn("DASH Parser: use system clock to define maximum position"); - _maximumTime = Date.now() / 1000 - ast; - } else { - var serverTime = performance.now() + externalClockOffset; - _maximumTime = serverTime / 1000 - ast; - } - } - - maximumTimeData = { - isLinear: true, - value: _maximumTime, - time: now - }; // if the minimum calculated time is even below the buffer depth, perhaps we - // can go even lower in terms of depth + return SegmentFetcherCreator; +}(); - if (timeshiftDepth !== null && minimumTime !== undefined && _maximumTime - minimumTime > timeshiftDepth) { - timeshiftDepth = _maximumTime - minimumTime; - } - } - var parsedMPD = { - availabilityStartTime: availabilityStartTime, - clockOffset: args.externalClockOffset, - isDynamic: isDynamic, - isLive: isDynamic, - periods: parsedPeriods, - suggestedPresentationDelay: rootAttributes.suggestedPresentationDelay, - transportType: "dash", - timeBounds: { - absoluteMinimumTime: minimumTime, - timeshiftDepth: timeshiftDepth, - maximumTimeData: maximumTimeData - }, - lifetime: lifetime, - uris: args.url == null ? rootChildren.locations : [args.url].concat(rootChildren.locations) - }; - return { - type: "done", - value: { - parsed: parsedMPD, - warnings: warnings - } - }; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/parse_from_document.ts +;// CONCATENATED MODULE: ./src/core/fetchers/segment/index.ts /** * Copyright 2015 CANAL+ Group * @@ -42816,22 +45768,195 @@ function parseCompleteIntermediateRepresentation(mpdIR, args, warnings, xlinkInf * limitations under the License. */ -/** - * @param {Document} manifest - Original manifest as returned by the server - * @param {Object} args - * @returns {Object} - parsed manifest - */ +/* harmony default export */ const segment = (SegmentFetcherCreator); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/innerSubscribe.js +var innerSubscribe = __webpack_require__(7604); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeScan.js +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ -function parseFromDocument(document, args) { - var root = document.documentElement; - if (root == null || root.nodeName !== "MPD") { - throw new Error("DASH Parser: document root should be MPD"); - } +function mergeScan(accumulator, seed, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + return function (source) { return source.lift(new MergeScanOperator(accumulator, seed, concurrent)); }; +} +var MergeScanOperator = /*@__PURE__*/ (function () { + function MergeScanOperator(accumulator, seed, concurrent) { + this.accumulator = accumulator; + this.seed = seed; + this.concurrent = concurrent; + } + MergeScanOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new MergeScanSubscriber(subscriber, this.accumulator, this.seed, this.concurrent)); + }; + return MergeScanOperator; +}()); - return parseMPD(root, args); +var MergeScanSubscriber = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(MergeScanSubscriber, _super); + function MergeScanSubscriber(destination, accumulator, acc, concurrent) { + var _this = _super.call(this, destination) || this; + _this.accumulator = accumulator; + _this.acc = acc; + _this.concurrent = concurrent; + _this.hasValue = false; + _this.hasCompleted = false; + _this.buffer = []; + _this.active = 0; + _this.index = 0; + return _this; + } + MergeScanSubscriber.prototype._next = function (value) { + if (this.active < this.concurrent) { + var index = this.index++; + var destination = this.destination; + var ish = void 0; + try { + var accumulator = this.accumulator; + ish = accumulator(this.acc, value, index); + } + catch (e) { + return destination.error(e); + } + this.active++; + this._innerSub(ish); + } + else { + this.buffer.push(value); + } + }; + MergeScanSubscriber.prototype._innerSub = function (ish) { + var innerSubscriber = new innerSubscribe/* SimpleInnerSubscriber */.IY(this); + var destination = this.destination; + destination.add(innerSubscriber); + var innerSubscription = (0,innerSubscribe/* innerSubscribe */.ft)(ish, innerSubscriber); + if (innerSubscription !== innerSubscriber) { + destination.add(innerSubscription); + } + }; + MergeScanSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (this.active === 0 && this.buffer.length === 0) { + if (this.hasValue === false) { + this.destination.next(this.acc); + } + this.destination.complete(); + } + this.unsubscribe(); + }; + MergeScanSubscriber.prototype.notifyNext = function (innerValue) { + var destination = this.destination; + this.acc = innerValue; + this.hasValue = true; + destination.next(innerValue); + }; + MergeScanSubscriber.prototype.notifyComplete = function () { + var buffer = this.buffer; + this.active--; + if (buffer.length > 0) { + this._next(buffer.shift()); + } + else if (this.active === 0 && this.hasCompleted) { + if (this.hasValue === false) { + this.destination.next(this.acc); + } + this.destination.complete(); + } + }; + return MergeScanSubscriber; +}(innerSubscribe/* SimpleOuterSubscriber */.Ds)); + +//# sourceMappingURL=mergeScan.js.map + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/from.js + 6 modules +var from = __webpack_require__(4072); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/exhaustMap.js +/** PURE_IMPORTS_START tslib,_map,_observable_from,_innerSubscribe PURE_IMPORTS_END */ + + + + +function exhaustMap(project, resultSelector) { + if (resultSelector) { + return function (source) { return source.pipe(exhaustMap(function (a, i) { return (0,from/* from */.D)(project(a, i)).pipe((0,map/* map */.U)(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; + } + return function (source) { + return source.lift(new ExhaustMapOperator(project)); + }; } -;// CONCATENATED MODULE: ./src/parsers/manifest/dash/index.ts +var ExhaustMapOperator = /*@__PURE__*/ (function () { + function ExhaustMapOperator(project) { + this.project = project; + } + ExhaustMapOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ExhaustMapSubscriber(subscriber, this.project)); + }; + return ExhaustMapOperator; +}()); +var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(ExhaustMapSubscriber, _super); + function ExhaustMapSubscriber(destination, project) { + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.hasSubscription = false; + _this.hasCompleted = false; + _this.index = 0; + return _this; + } + ExhaustMapSubscriber.prototype._next = function (value) { + if (!this.hasSubscription) { + this.tryNext(value); + } + }; + ExhaustMapSubscriber.prototype.tryNext = function (value) { + var result; + var index = this.index++; + try { + result = this.project(value, index); + } + catch (err) { + this.destination.error(err); + return; + } + this.hasSubscription = true; + this._innerSub(result); + }; + ExhaustMapSubscriber.prototype._innerSub = function (result) { + var innerSubscriber = new innerSubscribe/* SimpleInnerSubscriber */.IY(this); + var destination = this.destination; + destination.add(innerSubscriber); + var innerSubscription = (0,innerSubscribe/* innerSubscribe */.ft)(result, innerSubscriber); + if (innerSubscription !== innerSubscriber) { + destination.add(innerSubscription); + } + }; + ExhaustMapSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (!this.hasSubscription) { + this.destination.complete(); + } + this.unsubscribe(); + }; + ExhaustMapSubscriber.prototype.notifyNext = function (innerValue) { + this.destination.next(innerValue); + }; + ExhaustMapSubscriber.prototype.notifyError = function (err) { + this.destination.error(err); + }; + ExhaustMapSubscriber.prototype.notifyComplete = function () { + this.hasSubscription = false; + if (this.hasCompleted) { + this.destination.complete(); + } + }; + return ExhaustMapSubscriber; +}(innerSubscribe/* SimpleOuterSubscriber */.Ds)); +//# sourceMappingURL=exhaustMap.js.map + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/switchMap.js +var switchMap = __webpack_require__(6381); +;// CONCATENATED MODULE: ./src/compat/should_reload_media_source_on_decipherability_update.ts /** * Copyright 2015 CANAL+ Group * @@ -42848,12 +45973,24 @@ function parseFromDocument(document, args) { * limitations under the License. */ - -/* harmony default export */ const dash = (parseFromDocument); - -// EXTERNAL MODULE: ./src/transports/utils/return_parsed_manifest.ts -var return_parsed_manifest = __webpack_require__(7445); -;// CONCATENATED MODULE: ./src/transports/dash/manifest_parser.ts +/** + * 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} + */ +function shouldReloadMediaSourceOnDecipherabilityUpdate(currentKeySystem) { + return currentKeySystem === null || currentKeySystem.indexOf("widevine") < 0; +} +// EXTERNAL MODULE: ./src/utils/defer_subscriptions.ts + 6 modules +var defer_subscriptions = __webpack_require__(8025); +// EXTERNAL MODULE: ./src/utils/take_first_set.ts +var take_first_set = __webpack_require__(5278); +;// CONCATENATED MODULE: ./src/core/abr/ewma.ts /** * Copyright 2015 CANAL+ Group * @@ -42870,122 +46007,54 @@ var return_parsed_manifest = __webpack_require__(7445); * limitations under the License. */ - - - - - - -/** - * Request external "xlink" ressource from a MPD. - * @param {string} xlinkURL - * @returns {Observable} - */ - -function requestStringResource(url) { - return (0,request/* default */.ZP)({ - url: url, - responseType: "text" - }).pipe((0,filter/* filter */.h)(function (e) { - return e.type === "data-loaded"; - }), (0,map/* map */.U)(function (e) { - return e.value; - })); -} /** - * @param {Object} options - * @returns {Function} + * Tweaked implementation of an exponential weighted Moving Average. + * Heavily "inspired" from the shaka-player one (Ewma). + * @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 + */ -function generateManifestParser(options) { - var aggressiveMode = options.aggressiveMode, - referenceDateTime = options.referenceDateTime; - var serverTimeOffset = options.serverSyncInfos !== undefined ? options.serverSyncInfos.serverTimestamp - options.serverSyncInfos.clientTime : undefined; - return function manifestParser(args) { - var _a; - - var response = args.response, - scheduleRequest = args.scheduleRequest; - var argClockOffset = args.externalClockOffset; - var loaderURL = args.url; - var url = (_a = response.url) !== null && _a !== void 0 ? _a : loaderURL; - var data = typeof response.responseData === "string" ? new DOMParser().parseFromString(response.responseData, "text/xml") : // TODO find a way to check if Document? - response.responseData; - var externalClockOffset = serverTimeOffset !== null && serverTimeOffset !== void 0 ? serverTimeOffset : argClockOffset; - var unsafelyBaseOnPreviousManifest = args.unsafeMode ? args.previousManifest : null; - var parsedManifest = dash(data, { - aggressiveMode: aggressiveMode === true, - unsafelyBaseOnPreviousManifest: unsafelyBaseOnPreviousManifest, - url: url, - referenceDateTime: referenceDateTime, - externalClockOffset: externalClockOffset - }); - return loadExternalResources(parsedManifest); - - function loadExternalResources(parserResponse) { - if (parserResponse.type === "done") { - var _parserResponse$value = parserResponse.value, - warnings = _parserResponse$value.warnings, - parsed = _parserResponse$value.parsed; - var warningEvents = warnings.map(function (warning) { - return { - type: "warning", - value: warning - }; - }); - var manifest = new src_manifest/* default */.ZP(parsed, options); - return (0,concat/* concat */.z)(of.of.apply(void 0, warningEvents), (0,return_parsed_manifest/* default */.Z)(manifest, url)); - } - - var _parserResponse$value2 = parserResponse.value, - ressources = _parserResponse$value2.ressources, - continueParsing = _parserResponse$value2["continue"]; - var externalResources$ = ressources.map(function (resource) { - return scheduleRequest(function () { - return requestStringResource(resource); - }); - }); - return (0,combineLatest/* combineLatest */.aj)(externalResources$).pipe((0,mergeMap/* mergeMap */.zg)(function (loadedResources) { - var resources = []; - - for (var i = 0; i < loadedResources.length; i++) { - var resource = loadedResources[i]; - - if (typeof resource.responseData !== "string") { - throw new Error("External DASH resources should only be strings"); - } // Normally not needed but TypeScript is just dumb here - + var _proto = EWMA.prototype; - resources.push((0,object_assign/* default */.Z)(resource, { - responseData: resource.responseData - })); - } + _proto.addSample = function addSample(weight, value) { + var adjAlpha = Math.pow(this._alpha, weight); + var newEstimate = value * (1 - adjAlpha) + adjAlpha * this._lastEstimate; - return loadExternalResources(continueParsing(resources)); - })); + 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; }; -} -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules -var Observable = __webpack_require__(4379); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/regenerator/index.js -var regenerator = __webpack_require__(7757); -var regenerator_default = /*#__PURE__*/__webpack_require__.n(regenerator); -// EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/asyncToGenerator.js -var asyncToGenerator = __webpack_require__(8926); -var asyncToGenerator_default = /*#__PURE__*/__webpack_require__.n(asyncToGenerator); -// EXTERNAL MODULE: ./src/errors/request_error.ts -var request_error = __webpack_require__(9105); -// EXTERNAL MODULE: ./src/errors/error_codes.ts -var error_codes = __webpack_require__(5992); -// EXTERNAL MODULE: ./src/utils/is_null_or_undefined.ts -var is_null_or_undefined = __webpack_require__(1946); -;// CONCATENATED MODULE: ./src/utils/request/fetch.ts + return EWMA; +}(); -/* +;// CONCATENATED MODULE: ./src/core/abr/bandwidth_estimator.ts +/** * Copyright 2015 CANAL+ Group * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -43002,191 +46071,93 @@ var is_null_or_undefined = __webpack_require__(1946); */ +var ABR_MINIMUM_TOTAL_BYTES = config/* default.ABR_MINIMUM_TOTAL_BYTES */.Z.ABR_MINIMUM_TOTAL_BYTES, + ABR_MINIMUM_CHUNK_SIZE = config/* default.ABR_MINIMUM_CHUNK_SIZE */.Z.ABR_MINIMUM_CHUNK_SIZE, + ABR_FAST_EMA = config/* default.ABR_FAST_EMA */.Z.ABR_FAST_EMA, + ABR_SLOW_EMA = config/* default.ABR_SLOW_EMA */.Z.ABR_SLOW_EMA; +/** + * Calculate a mean bandwidth based on the bytes downloaded and the amount + * of time needed to do so. + * + * Heavily "inspired" from the Shaka-Player's "ewma bandwidth estimator". + * @class BandwidthEstimator + */ - - -var DEFAULT_REQUEST_TIMEOUT = config/* default.DEFAULT_REQUEST_TIMEOUT */.Z.DEFAULT_REQUEST_TIMEOUT; - -var _Headers = typeof Headers === "function" ? Headers : null; - -var _AbortController = typeof AbortController === "function" ? AbortController : null; - -function fetchRequest(options) { - var headers; - - if (!(0,is_null_or_undefined/* default */.Z)(options.headers)) { - if ((0,is_null_or_undefined/* default */.Z)(_Headers)) { - headers = options.headers; - } else { - headers = new _Headers(); - var headerNames = Object.keys(options.headers); - - for (var i = 0; i < headerNames.length; i++) { - var headerName = headerNames[i]; - headers.append(headerName, options.headers[headerName]); - } - } - } - - return new Observable/* Observable */.y(function (obs) { - log/* default.debug */.Z.debug("Fetch: Called with URL", options.url); - var hasAborted = false; - var timeouted = false; - var isDone = false; - var sendingTime = performance.now(); - var abortController = !(0,is_null_or_undefined/* default */.Z)(_AbortController) ? new _AbortController() : null; +var BandwidthEstimator = /*#__PURE__*/function () { + function BandwidthEstimator() { /** - * Abort current fetchRequest by triggering AbortController signal. - * @returns {void} + * A fast-moving average. + * @private + */ + this._fastEWMA = new EWMA(ABR_FAST_EMA); + /** + * A slow-moving average. + * @private */ - function abortRequest() { - if (!isDone) { - if (!(0,is_null_or_undefined/* default */.Z)(abortController)) { - abortController.abort(); - return; - } - - log/* default.warn */.Z.warn("Fetch: AbortController API not available."); - } - } - - var requestTimeout = (0,is_null_or_undefined/* default */.Z)(options.timeout) ? DEFAULT_REQUEST_TIMEOUT : options.timeout; - var timeout = window.setTimeout(function () { - timeouted = true; - abortRequest(); - }, requestTimeout); - fetch(options.url, { - headers: headers, - method: "GET", - signal: !(0,is_null_or_undefined/* default */.Z)(abortController) ? abortController.signal : undefined - }).then(function (response) { - if (!(0,is_null_or_undefined/* default */.Z)(timeout)) { - clearTimeout(timeout); - } + this._slowEWMA = new EWMA(ABR_SLOW_EMA); + /** + * Number of bytes sampled. + * @private + */ - if (response.status >= 300) { - log/* default.warn */.Z.warn("Fetch: Request HTTP Error", response); - obs.error(new request_error/* default */.Z(response.url, response.status, error_codes/* NetworkErrorTypes.ERROR_HTTP_CODE */.br.ERROR_HTTP_CODE)); - return undefined; - } + this._bytesSampled = 0; + } + /** + * Takes a bandwidth sample. + * @param {number} durationMs - The amount of time, in milliseconds, for a + * particular request. + * @param {number} numBytes - The total number of bytes transferred in that + * request. + */ - if ((0,is_null_or_undefined/* default */.Z)(response.body)) { - obs.error(new request_error/* default */.Z(response.url, response.status, error_codes/* NetworkErrorTypes.PARSE_ERROR */.br.PARSE_ERROR)); - return undefined; - } - var contentLengthHeader = response.headers.get("Content-Length"); - var contentLength = !(0,is_null_or_undefined/* default */.Z)(contentLengthHeader) && !isNaN(+contentLengthHeader) ? +contentLengthHeader : undefined; - var reader = response.body.getReader(); - var size = 0; - return readBufferAndSendEvents(); + var _proto = BandwidthEstimator.prototype; - function readBufferAndSendEvents() { - return _readBufferAndSendEvents.apply(this, arguments); - } + _proto.addSample = function addSample(durationInMs, numberOfBytes) { + if (numberOfBytes < ABR_MINIMUM_CHUNK_SIZE) { + return; + } - function _readBufferAndSendEvents() { - _readBufferAndSendEvents = asyncToGenerator_default()( /*#__PURE__*/regenerator_default().mark(function _callee() { - var data, currentTime, dataChunk, receivedTime, duration; - return regenerator_default().wrap(function _callee$(_context) { - while (1) { - switch (_context.prev = _context.next) { - case 0: - _context.next = 2; - return reader.read(); + var bandwidth = numberOfBytes * 8000 / durationInMs; + var weight = durationInMs / 1000; + this._bytesSampled += numberOfBytes; - case 2: - data = _context.sent; + this._fastEWMA.addSample(weight, bandwidth); - if (!(!data.done && !(0,is_null_or_undefined/* default */.Z)(data.value))) { - _context.next = 11; - break; - } + this._slowEWMA.addSample(weight, bandwidth); + } + /** + * Get estimate of the bandwidth, in bits per seconds. + * @returns {Number|undefined} + */ + ; - size += data.value.byteLength; - currentTime = performance.now(); - dataChunk = { - type: "data-chunk", - value: { - url: response.url, - currentTime: currentTime, - duration: currentTime - sendingTime, - sendingTime: sendingTime, - chunkSize: data.value.byteLength, - chunk: data.value.buffer, - size: size, - totalSize: contentLength - } - }; - obs.next(dataChunk); - return _context.abrupt("return", readBufferAndSendEvents()); + _proto.getEstimate = function getEstimate() { + 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. - case 11: - if (data.done) { - receivedTime = performance.now(); - duration = receivedTime - sendingTime; - isDone = true; - obs.next({ - type: "data-complete", - value: { - duration: duration, - receivedTime: receivedTime, - sendingTime: sendingTime, - size: size, - status: response.status, - url: response.url - } - }); - obs.complete(); - } - case 12: - case "end": - return _context.stop(); - } - } - }, _callee); - })); - return _readBufferAndSendEvents.apply(this, arguments); - } - })["catch"](function (err) { - if (hasAborted) { - log/* default.debug */.Z.debug("Fetch: Request aborted."); - return; - } + return Math.min(this._fastEWMA.getEstimate(), this._slowEWMA.getEstimate()); + } + /** + * Reset the bandwidth estimation. + */ + ; - if (timeouted) { - log/* default.warn */.Z.warn("Fetch: Request timeouted."); - obs.error(new request_error/* default */.Z(options.url, 0, error_codes/* NetworkErrorTypes.TIMEOUT */.br.TIMEOUT)); - return; - } + _proto.reset = function reset() { + this._fastEWMA = new EWMA(ABR_FAST_EMA); + this._slowEWMA = new EWMA(ABR_SLOW_EMA); + this._bytesSampled = 0; + }; - log/* default.warn */.Z.warn("Fetch: Request Error", err instanceof Error ? err.toString() : ""); - obs.error(new request_error/* default */.Z(options.url, 0, error_codes/* NetworkErrorTypes.ERROR_EVENT */.br.ERROR_EVENT)); - return; - }); - return function () { - hasAborted = true; - abortRequest(); - }; - }); -} -/** - * Returns true if fetch should be supported in the current browser. - * @return {boolean} - */ + return BandwidthEstimator; +}(); -function fetchIsSupported() { - return typeof window.fetch === "function" && !(0,is_null_or_undefined/* default */.Z)(_AbortController) && !(0,is_null_or_undefined/* default */.Z)(_Headers); -} -/* harmony default export */ const request_fetch = (fetchRequest); -// EXTERNAL MODULE: ./src/utils/warn_once.ts -var warn_once = __webpack_require__(8806); -// EXTERNAL MODULE: ./src/transports/utils/byte_range.ts -var byte_range = __webpack_require__(281); -;// CONCATENATED MODULE: ./src/transports/utils/is_webm_embedded_track.ts +;// CONCATENATED MODULE: ./src/core/abr/create_filters.ts /** * Copyright 2015 CANAL+ Group * @@ -43203,18 +46174,141 @@ var byte_range = __webpack_require__(281); * limitations under the License. */ + + /** - * @param {Object} representation - * @returns {boolean} + * Create Observable that merge several throttling Observables into one. + * @param {Observable} limitWidth$ - Emit the width at which the chosen + * Representation should be limited. + * @param {Observable} throttleBitrate$ - Emit the maximum bitrate authorized. + * @param {Observable} throttle$ - Also emit the maximum bitrate authorized. + * Here for legacy reasons. + * @returns {Observable} */ -function isWEBMEmbeddedTrack(representation) { - return representation.mimeType === "video/webm" || representation.mimeType === "audio/webm"; + +function createFilters(limitWidth$, throttleBitrate$, throttle$) { + var deviceEventsArray = []; + + if (limitWidth$ != null) { + deviceEventsArray.push(limitWidth$.pipe((0,map/* map */.U)(function (width) { + return { + width: width + }; + }))); + } + + if (throttle$ != null) { + deviceEventsArray.push(throttle$.pipe((0,map/* map */.U)(function (bitrate) { + return { + bitrate: bitrate + }; + }))); + } + + if (throttleBitrate$ != null) { + deviceEventsArray.push(throttleBitrate$.pipe((0,map/* map */.U)(function (bitrate) { + return { + bitrate: bitrate + }; + }))); + } // Emit restrictions on the pools of available representations to choose + // from. + + + return deviceEventsArray.length > 0 ? (0,combineLatest/* combineLatest */.aj)(deviceEventsArray).pipe((0,map/* map */.U)(function (args) { + return object_assign/* default.apply */.Z.apply(void 0, [{}].concat(args)); + })) : (0,of.of)({}); } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/tap.js -var tap = __webpack_require__(3068); -// EXTERNAL MODULE: ./src/transports/utils/check_isobmff_integrity.ts -var check_isobmff_integrity = __webpack_require__(4460); -;// CONCATENATED MODULE: ./src/transports/dash/add_segment_integrity_checks_to_loader.ts +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/OuterSubscriber.js +var OuterSubscriber = __webpack_require__(2039); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeToResult.js + 1 modules +var subscribeToResult = __webpack_require__(2080); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/withLatestFrom.js +/** PURE_IMPORTS_START tslib,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ + + + +function withLatestFrom() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return function (source) { + var project; + if (typeof args[args.length - 1] === 'function') { + project = args.pop(); + } + var observables = args; + return source.lift(new WithLatestFromOperator(observables, project)); + }; +} +var WithLatestFromOperator = /*@__PURE__*/ (function () { + function WithLatestFromOperator(observables, project) { + this.observables = observables; + this.project = project; + } + WithLatestFromOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new WithLatestFromSubscriber(subscriber, this.observables, this.project)); + }; + return WithLatestFromOperator; +}()); +var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(WithLatestFromSubscriber, _super); + function WithLatestFromSubscriber(destination, observables, project) { + var _this = _super.call(this, destination) || this; + _this.observables = observables; + _this.project = project; + _this.toRespond = []; + var len = observables.length; + _this.values = new Array(len); + for (var i = 0; i < len; i++) { + _this.toRespond.push(i); + } + for (var i = 0; i < len; i++) { + var observable = observables[i]; + _this.add((0,subscribeToResult/* subscribeToResult */.D)(_this, observable, undefined, i)); + } + return _this; + } + WithLatestFromSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { + this.values[outerIndex] = innerValue; + var toRespond = this.toRespond; + if (toRespond.length > 0) { + var found = toRespond.indexOf(outerIndex); + if (found !== -1) { + toRespond.splice(found, 1); + } + } + }; + WithLatestFromSubscriber.prototype.notifyComplete = function () { + }; + WithLatestFromSubscriber.prototype._next = function (value) { + if (this.toRespond.length === 0) { + var args = [value].concat(this.values); + if (this.project) { + this._tryProject(args); + } + else { + this.destination.next(args); + } + } + }; + WithLatestFromSubscriber.prototype._tryProject = function (args) { + var result; + try { + result = this.project.apply(this, args); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(result); + }; + return WithLatestFromSubscriber; +}(OuterSubscriber/* OuterSubscriber */.L)); +//# sourceMappingURL=withLatestFrom.js.map + +;// CONCATENATED MODULE: ./src/core/abr/get_buffer_levels.ts /** * Copyright 2015 CANAL+ Group * @@ -43231,20 +46325,43 @@ var check_isobmff_integrity = __webpack_require__(4460); * 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 addSegmentIntegrityChecks(segmentLoader) { - return function (content) { - return segmentLoader(content).pipe((0,tap/* tap */.b)(function (res) { - if ((res.type === "data-loaded" || res.type === "data-chunk") && res.value.responseData !== null && typeof res.value.responseData !== "string" && !isWEBMEmbeddedTrack(content.representation)) { - (0,check_isobmff_integrity/* default */.Z)(new Uint8Array(res.value.responseData), content.segment.isInit); - } - })); - }; + function minBufferLevelForBitrate(index) { + if (index === 0) { + return 0; + } + + var boundedIndex = Math.min(Math.max(1, index), bitrates.length - 1); + return Vp * (gp + (bitrates[boundedIndex] * utilities[boundedIndex - 1] - bitrates[boundedIndex - 1] * utilities[boundedIndex]) / (bitrates[boundedIndex] - bitrates[boundedIndex - 1])) + 4; + } } -// EXTERNAL MODULE: ./src/utils/byte_parsing.ts -var byte_parsing = __webpack_require__(6968); -;// CONCATENATED MODULE: ./src/transports/dash/init_segment_loader.ts +;// CONCATENATED MODULE: ./src/core/abr/get_estimate_from_buffer_levels.ts /** * Copyright 2015 CANAL+ Group * @@ -43262,164 +46379,76 @@ var byte_parsing = __webpack_require__(6968); */ - - - /** - * Perform a request for an initialization segment, agnostic to the container. - * @param {string} url - * @param {Object} content + * From the buffer gap, choose a representation. + * @param {Object} clockTick + * @param {Array.} bitrates + * @param {Array.} bufferLevels + * @returns {Object|undefined} */ -function initSegmentLoader(url, _ref) { - var segment = _ref.segment; - - if (segment.range === undefined) { - return (0,request/* default */.ZP)({ - url: url, - responseType: "arraybuffer", - sendProgressEvents: true - }); - } - - if (segment.indexRange === undefined) { - return (0,request/* default */.ZP)({ - url: url, - headers: { - Range: (0,byte_range/* default */.Z)(segment.range) - }, - responseType: "arraybuffer", - sendProgressEvents: true - }); - } // range and indexRange are contiguous (99% of the cases) - +function getEstimateFromBufferLevels(clockTick, bitrates, bufferLevels) { + var bufferGap = clockTick.bufferGap, + currentBitrate = clockTick.currentBitrate, + currentScore = clockTick.currentScore, + speed = clockTick.speed; - if (segment.range[1] + 1 === segment.indexRange[0]) { - return (0,request/* default */.ZP)({ - url: url, - headers: { - Range: (0,byte_range/* default */.Z)([segment.range[0], segment.indexRange[1]]) - }, - responseType: "arraybuffer", - sendProgressEvents: true - }); + if (currentBitrate == null) { + return bitrates[0]; } - var rangeRequest$ = (0,request/* default */.ZP)({ - url: url, - headers: { - Range: (0,byte_range/* default */.Z)(segment.range) - }, - responseType: "arraybuffer", - sendProgressEvents: false - }); - var indexRequest$ = (0,request/* default */.ZP)({ - url: url, - headers: { - Range: (0,byte_range/* default */.Z)(segment.indexRange) - }, - responseType: "arraybuffer", - sendProgressEvents: false + var currentBitrateIndex = (0,array_find_index/* default */.Z)(bitrates, function (b) { + return b === currentBitrate; }); - return (0,combineLatest/* combineLatest */.aj)([rangeRequest$, indexRequest$]).pipe((0,map/* map */.U)(function (_ref2) { - var initData = _ref2[0], - indexData = _ref2[1]; - var data = (0,byte_parsing/* concat */.zo)(new Uint8Array(initData.value.responseData), new Uint8Array(indexData.value.responseData)); - var sendingTime = Math.min(initData.value.sendingTime, indexData.value.sendingTime); - var receivedTime = Math.max(initData.value.receivedTime, indexData.value.receivedTime); - return { - type: "data-loaded", - value: { - url: url, - responseData: data, - size: initData.value.size + indexData.value.size, - duration: receivedTime - sendingTime, - sendingTime: sendingTime, - receivedTime: receivedTime - } - }; - })); -} -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/scan.js -var scan = __webpack_require__(2807); -// EXTERNAL MODULE: ./src/transports/utils/find_complete_box.ts -var find_complete_box = __webpack_require__(8766); -;// CONCATENATED MODULE: ./src/transports/dash/extract_complete_chunks.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. - */ + if (currentBitrateIndex < 0 || bitrates.length !== bufferLevels.length) { + log/* default.error */.Z.error("ABR: Current Bitrate not found in the calculated levels"); + return bitrates[0]; + } -/** - * Take a chunk of ISOBMFF data and extract complete `moof`+`mdat` subsegments - * which are ready to be decoded. - * Returns a tuple of two containing first an array of those subsegments - * followed by tha last un-decodable part. - * @param {Uint8Array} buffer - * @returns {Array} - */ + var scaledScore; -function extractCompleteChunks(buffer) { - var _position = 0; - var chunks = []; + if (currentScore != null) { + scaledScore = speed === 0 ? currentScore : currentScore / speed; + } - while (_position < buffer.length) { - var currentBuffer = buffer.subarray(_position, Infinity); - var moofIndex = (0,find_complete_box/* default */.Z)(currentBuffer, 0x6D6F6F66 - /* moof */ - ); + if (scaledScore != null && scaledScore > 1) { + var currentBufferLevel = bufferLevels[currentBitrateIndex]; - if (moofIndex < 0) { - // no moof, not a segment. - return [chunks, currentBuffer]; - } + var nextIndex = function () { + for (var i = currentBitrateIndex + 1; i < bufferLevels.length; i++) { + if (bufferLevels[i] > currentBufferLevel) { + return i; + } + } + }(); - var moofLen = (0,byte_parsing/* be4toi */.pX)(buffer, moofIndex + _position); - var moofEnd = _position + moofIndex + moofLen; + if (nextIndex != null) { + var nextBufferLevel = bufferLevels[nextIndex]; - if (moofEnd > buffer.length) { - // not a complete moof segment - return [chunks, currentBuffer]; + if (bufferGap >= nextBufferLevel) { + return bitrates[nextIndex]; + } } + } - var mdatIndex = (0,find_complete_box/* default */.Z)(currentBuffer, 0x6D646174 - /* mdat */ - ); - - if (mdatIndex < 0) { - // no mdat, not a segment. - return [chunks, currentBuffer]; - } + if (scaledScore == null || scaledScore < 1.15) { + var _currentBufferLevel = bufferLevels[currentBitrateIndex]; - var mdatLen = (0,byte_parsing/* be4toi */.pX)(buffer, mdatIndex + _position); - var mdatEnd = _position + mdatIndex + mdatLen; + if (bufferGap < _currentBufferLevel) { + for (var i = currentBitrateIndex - 1; i >= 0; i--) { + if (bitrates[i] < currentBitrate) { + return bitrates[i]; + } + } - if (mdatEnd > buffer.length) { - // not a complete mdat segment - return [chunks, currentBuffer]; + return currentBitrate; } - - var maxEnd = Math.max(moofEnd, mdatEnd); - var chunk = buffer.subarray(_position, maxEnd); - chunks.push(chunk); - _position = maxEnd; } - return [chunks, null]; + return currentBitrate; } -;// CONCATENATED MODULE: ./src/transports/dash/low_latency_segment_loader.ts +;// CONCATENATED MODULE: ./src/core/abr/buffer_based_chooser.ts /** * Copyright 2015 CANAL+ Group * @@ -43439,88 +46468,35 @@ function extractCompleteChunks(buffer) { +/** + * Choose a bitrate based on the currently available buffer. + * + * This algorithm is based on the 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. + * + * @param {Observable} update$ + * @param {Array.} bitrates + * @returns {Observable} + */ - - -function lowLatencySegmentLoader(url, args) { - var segment = args.segment; - var headers = segment.range !== undefined ? { - Range: (0,byte_range/* default */.Z)(segment.range) - } : undefined; - return request_fetch({ - url: url, - headers: headers - }).pipe((0,scan/* scan */.R)(function (acc, evt) { - if (evt.type === "data-complete") { - if (acc.partialChunk !== null) { - log/* default.warn */.Z.warn("DASH Pipelines: remaining chunk does not belong to any segment"); - } - - return { - event: evt, - completeChunks: [], - partialChunk: null - }; - } - - var data = new Uint8Array(evt.value.chunk); - var concatenated = acc.partialChunk !== null ? (0,byte_parsing/* concat */.zo)(acc.partialChunk, data) : data; - - var _extractCompleteChunk = extractCompleteChunks(concatenated), - completeChunks = _extractCompleteChunk[0], - partialChunk = _extractCompleteChunk[1]; - +function BufferBasedChooser(update$, bitrates) { + var levelsMap = getBufferLevels(bitrates); + log/* default.debug */.Z.debug("ABR: Steps for buffer based chooser.", levelsMap.map(function (l, i) { return { - event: evt, - completeChunks: completeChunks, - partialChunk: partialChunk + bufferLevel: l, + bitrate: bitrates[i] }; - }, { - event: null, - completeChunks: [], - partialChunk: null - }), (0,mergeMap/* mergeMap */.zg)(function (evt) { - var emitted = []; - - for (var i = 0; i < evt.completeChunks.length; i++) { - emitted.push({ - type: "data-chunk", - value: { - responseData: evt.completeChunks[i] - } - }); - } - - var event = evt.event; - - if (event !== null && event.type === "data-chunk") { - var value = event.value; - emitted.push({ - type: "progress", - value: { - duration: value.duration, - size: value.size, - totalSize: value.totalSize - } - }); - } else if (event !== null && event.type === "data-complete") { - var _value = event.value; - emitted.push({ - type: "data-chunk-complete", - value: { - duration: _value.duration, - receivedTime: _value.receivedTime, - sendingTime: _value.sendingTime, - size: _value.size, - url: _value.url - } - }); - } - - return of.of.apply(void 0, emitted); + })); + return update$.pipe((0,map/* map */.U)(function (clockTick) { + return getEstimateFromBufferLevels(clockTick, bitrates, levelsMap); })); } -;// CONCATENATED MODULE: ./src/transports/dash/segment_loader.ts +;// CONCATENATED MODULE: ./src/core/abr/cached_segment_detector.ts /** * Copyright 2015 CANAL+ Group * @@ -43537,177 +46513,60 @@ function lowLatencySegmentLoader(url, args) { * limitations under the License. */ - - - - - - - +var CACHE_LOAD_DURATION_THRESHOLDS = config/* default.CACHE_LOAD_DURATION_THRESHOLDS */.Z.CACHE_LOAD_DURATION_THRESHOLDS; /** - * Segment loader triggered if there was no custom-defined one in the API. - * @param {Object} opt - * @returns {Observable} + * From segment download duration, tells if a segment + * may have been loaded from cache. + * @param {string} contentType + * @param {number} downloadDuration */ -function regularSegmentLoader(url, args, lowLatencyMode) { - if (args.segment.isInit) { - return initSegmentLoader(url, args); - } - - var isWEBM = isWEBMEmbeddedTrack(args.representation); - - if (lowLatencyMode && !isWEBM) { - if (fetchIsSupported()) { - return lowLatencySegmentLoader(url, args); - } else { - (0,warn_once/* default */.Z)("DASH: Your browser does not have the fetch API. You will have " + "a higher chance of rebuffering when playing close to the live edge"); - } - } - - var segment = args.segment; - return (0,request/* default */.ZP)({ - url: url, - responseType: "arraybuffer", - sendProgressEvents: true, - headers: segment.range !== undefined ? { - Range: (0,byte_range/* default */.Z)(segment.range) - } : undefined - }); +function mayBeFromCache(contentType, downloadDuration) { + var cacheLoadDurationThreshold = CACHE_LOAD_DURATION_THRESHOLDS[contentType]; + return downloadDuration < cacheLoadDurationThreshold; } /** - * @param {Object} config - * @returns {Function} + * Returns a function used to determine if a segment was loaded + * from cache or not. + * @returns {function} */ -function generateSegmentLoader(_ref) { - var lowLatencyMode = _ref.lowLatencyMode, - customSegmentLoader = _ref.segmentLoader, - checkMediaSegmentIntegrity = _ref.checkMediaSegmentIntegrity; - return checkMediaSegmentIntegrity !== true ? segmentLoader : addSegmentIntegrityChecks(segmentLoader); +function generateCachedSegmentDetector() { + var hasAlreadyLoadedNonCachedContent = false; /** + * Determines with request duration if a loaded chunk may have been loaded + * from cache, and return true if should ignore the metrics for representation + * chooser. * @param {Object} content - * @returns {Observable} + * @param {number} duration + * @returns {boolean} */ - function segmentLoader(content) { - var url = content.url; - - if (url == null) { - return (0,of.of)({ - type: "data-created", - value: { - responseData: null - } - }); - } + return function shouldIgnoreMetrics(content, downloadDuration) { + var contentType = content.adaptation.type; - if (lowLatencyMode || customSegmentLoader === undefined) { - return regularSegmentLoader(url, content, lowLatencyMode); + if (contentType === "text" || contentType === "image") { + return false; } - var args = { - adaptation: content.adaptation, - manifest: content.manifest, - period: content.period, - representation: content.representation, - segment: content.segment, - transport: "dash", - url: url - }; - return new Observable/* Observable */.y(function (obs) { - var hasFinished = false; - var hasFallbacked = false; - /** - * Callback triggered when the custom segment loader has a response. - * @param {Object} args - */ - - var resolve = function resolve(_args) { - if (!hasFallbacked) { - hasFinished = true; - obs.next({ - type: "data-loaded", - value: { - responseData: _args.data, - size: _args.size, - duration: _args.duration - } - }); - obs.complete(); - } - }; - /** - * Callback triggered when the custom segment loader fails - * @param {*} err - The corresponding error encountered - */ - - - var reject = function reject(err) { - if (err === void 0) { - err = {}; - } - - if (!hasFallbacked) { - hasFinished = true; - obs.error(err); - } - }; - - var progress = function progress(_args) { - if (!hasFallbacked) { - obs.next({ - type: "progress", - value: { - duration: _args.duration, - size: _args.size, - totalSize: _args.totalSize - } - }); - } - }; - /** - * Callback triggered when the custom segment loader wants to fallback to - * the "regular" implementation - */ - - - var fallback = function fallback() { - hasFallbacked = true; - var regular$ = regularSegmentLoader(url, content, lowLatencyMode); // HACK What is TypeScript/RxJS doing here?????? - - /* eslint-disable import/no-deprecated */ - - /* eslint-disable @typescript-eslint/ban-ts-comment */ - // @ts-ignore - - regular$.subscribe(obs); - /* eslint-enable import/no-deprecated */ + var segmentMayBeFromCache = mayBeFromCache(contentType, downloadDuration); - /* eslint-enable @typescript-eslint/ban-ts-comment */ - }; + if (segmentMayBeFromCache && hasAlreadyLoadedNonCachedContent) { + // We already loaded not cached segments. + // Do not consider cached segments anymore. + return true; + } - var callbacks = { - reject: reject, - resolve: resolve, - progress: progress, - fallback: fallback - }; - var abort = customSegmentLoader(args, callbacks); - return function () { - if (!hasFinished && !hasFallbacked && typeof abort === "function") { - abort(); - } - }; - }); - } + if (!segmentMayBeFromCache && !hasAlreadyLoadedNonCachedContent) { + // First segment not loaded from cache. + hasAlreadyLoadedNonCachedContent = true; + } + + return false; + }; } -// EXTERNAL MODULE: ./src/parsers/containers/isobmff/utils.ts -var utils = __webpack_require__(4644); -// EXTERNAL MODULE: ./src/parsers/containers/isobmff/take_pssh_out.ts + 1 modules -var take_pssh_out = __webpack_require__(6490); -;// CONCATENATED MODULE: ./src/parsers/containers/matroska/utils.ts +;// CONCATENATED MODULE: ./src/core/abr/filter_by_bitrate.ts /** * Copyright 2015 CANAL+ Group * @@ -43724,502 +46583,420 @@ var take_pssh_out = __webpack_require__(6490); * limitations under the License. */ -var SEGMENT_ID = 0x18538067; -var INFO_ID = 0x1549A966; -var TIMECODESCALE_ID = 0x2AD7B1; -var DURATION_ID = 0x4489; -var CUES_ID = 0x1C53BB6B; -var CUE_POINT_ID = 0xBB; -var CUE_TIME_ID = 0xB3; -var CUE_TRACK_POSITIONS_ID = 0xB7; -var CUE_CLUSTER_POSITIONS_ID = 0xF1; /** - * Find the offsets of the value linked to the given element ID. - * @param {number} elementID - ID for the searched element. - * @param {Array.} parents - eventual IDs of the parent elements. From - * top level to lower level (from the furthest to the closest). - * @param {Uint8Array} buffer - buffer where the ID will be searched - * @param {Array.} range - start and end offsets in the buffer where the - * ID will be searched. - * @returns {Array.|null} + * 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 findNextElement(elementID, parents, buffer, _ref) { - var initialOffset = _ref[0], - maxOffset = _ref[1]; - var currentOffset = initialOffset; - - while (currentOffset < maxOffset) { - var parsedID = getEBMLID(buffer, currentOffset); - - if (parsedID == null) { - return null; - } - - var ebmlTagID = parsedID.value, - ebmlTagLength = parsedID.length; - var sizeOffset = currentOffset + ebmlTagLength; - var parsedValue = getEBMLValue(buffer, sizeOffset); - - if (parsedValue == null) { - return null; - } - - var valueLengthLength = parsedValue.length, - valueLength = parsedValue.value; - var valueOffset = sizeOffset + valueLengthLength; - var valueEndOffset = valueOffset + valueLength; +function filterByBitrate(representations, bitrate) { + if (representations.length === 0) { + return []; + } - if (ebmlTagID === elementID) { - return [valueOffset, valueEndOffset]; - } else if (parents.length > 0) { - for (var i = 0; i < parents.length; i++) { - if (ebmlTagID === parents[i]) { - var newParents = parents.slice(i + 1, parents.length); - return findNextElement(elementID, newParents, buffer, [valueOffset, valueEndOffset]); - } - } - } + 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; + }); - currentOffset = valueEndOffset; + if (firstSuperiorBitrateIndex === -1) { + return representations; // All representations have lower bitrates. } - return null; + return representations.slice(0, firstSuperiorBitrateIndex); } +// EXTERNAL MODULE: ./src/utils/array_find.ts +var array_find = __webpack_require__(3274); +;// CONCATENATED MODULE: ./src/core/abr/filter_by_width.ts /** - * Return the timecode scale (basically timescale) of the whole file. - * @param {Uint8Array} buffer - * @param {number} initialOffset - * @returns {number|null} + * 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 getTimeCodeScale(buffer, initialOffset) { - var timeCodeScaleOffsets = findNextElement(TIMECODESCALE_ID, [SEGMENT_ID, INFO_ID], buffer, [initialOffset, buffer.length]); - - if (timeCodeScaleOffsets == null) { - return null; - } - - var length = timeCodeScaleOffsets[1] - timeCodeScaleOffsets[0]; - return 1e9 / bytesToNumber(buffer, timeCodeScaleOffsets[0], length); -} /** - * Return the duration of the concerned media. - * @param {Uint8Array} buffer - * @param {number} initialOffset - * @returns {number|null} + * 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 getDuration(buffer, initialOffset) { - var timeCodeScaleOffsets = findNextElement(DURATION_ID, [SEGMENT_ID, INFO_ID], buffer, [initialOffset, buffer.length]); - - if (timeCodeScaleOffsets == null) { - return null; - } - - var length = timeCodeScaleOffsets[1] - timeCodeScaleOffsets[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 repWithMaxWidth = (0,array_find/* default */.Z)(sortedRepsByWidth, function (representation) { + return typeof representation.width === "number" && representation.width >= width; + }); - if (length === 4) { - return get_IEEE754_32Bits(buffer, timeCodeScaleOffsets[0]); - } else if (length === 8) { - return get_IEEE754_64Bits(buffer, timeCodeScaleOffsets[0]); + if (repWithMaxWidth === undefined) { + return representations; } - return null; + 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/abr/network_analyzer.ts /** - * @param {Uint8Array} buffer - * @param {number} initialOffset - * @returns {Array.|null} + * 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 getSegmentsFromCues(buffer, initialOffset) { - var segmentRange = findNextElement(SEGMENT_ID, [], buffer, [initialOffset, buffer.length]); - - if (segmentRange == null) { - return null; - } - - var segmentRangeStart = segmentRange[0], - segmentRangeEnd = segmentRange[1]; - var timescale = getTimeCodeScale(buffer, segmentRangeStart); - - if (timescale == null) { - return null; - } - - var duration = getDuration(buffer, segmentRangeStart); - - if (duration == null) { - return null; - } - - var cuesRange = findNextElement(CUES_ID, [], buffer, [segmentRangeStart, segmentRangeEnd]); - - if (cuesRange == null) { - return null; - } - - var rawInfos = []; - var currentOffset = cuesRange[0]; - while (currentOffset < cuesRange[1]) { - var cuePointRange = findNextElement(CUE_POINT_ID, [], buffer, [currentOffset, cuesRange[1]]); - if (cuePointRange == null) { - break; - } - var cueTimeRange = findNextElement(CUE_TIME_ID, [], buffer, [cuePointRange[0], cuePointRange[1]]); +var ABR_REGULAR_FACTOR = config/* default.ABR_REGULAR_FACTOR */.Z.ABR_REGULAR_FACTOR, + ABR_STARVATION_DURATION_DELTA = config/* default.ABR_STARVATION_DURATION_DELTA */.Z.ABR_STARVATION_DURATION_DELTA, + ABR_STARVATION_FACTOR = config/* default.ABR_STARVATION_FACTOR */.Z.ABR_STARVATION_FACTOR, + ABR_STARVATION_GAP = config/* default.ABR_STARVATION_GAP */.Z.ABR_STARVATION_GAP, + OUT_OF_STARVATION_GAP = config/* default.OUT_OF_STARVATION_GAP */.Z.OUT_OF_STARVATION_GAP; +/** + * Get pending segment request(s) starting with the asked segment position. + * @param {Object} requests + * @param {number} position + * @returns {Array.} + */ - if (cueTimeRange == null) { - return null; +function getConcernedRequests(requests, neededPosition) { + /** Index of the request for the next needed segment, in `requests`. */ + var nextSegmentIndex = (0,array_find_index/* default */.Z)(requests, function (request) { + if (request.duration <= 0) { + return false; } - var time = bytesToNumber(buffer, cueTimeRange[0], cueTimeRange[1] - cueTimeRange[0]); - var cueOffsetRange = findNextElement(CUE_CLUSTER_POSITIONS_ID, [CUE_TRACK_POSITIONS_ID], buffer, [cuePointRange[0], cuePointRange[1]]); - - if (cueOffsetRange == null) { - return null; - } + var segmentEnd = request.time + request.duration; + return segmentEnd > neededPosition && neededPosition - request.time > -1.2; + }); - var rangeStart = bytesToNumber(buffer, cueOffsetRange[0], cueOffsetRange[1] - cueOffsetRange[0]) + segmentRangeStart; - rawInfos.push({ - time: time, - rangeStart: rangeStart - }); - currentOffset = cuePointRange[1]; + if (nextSegmentIndex < 0) { + // Not found + return []; } - var segments = []; - - for (var i = 0; i < rawInfos.length; i++) { - var currentSegment = rawInfos[i]; + var nextRequest = requests[nextSegmentIndex]; + var segmentTime = nextRequest.time; + var filteredRequests = [nextRequest]; // Get the possibly multiple requests for that segment's position - if (i === rawInfos.length - 1) { - segments.push({ - time: currentSegment.time, - count: 0, - timescale: timescale, - duration: i === 0 ? duration : duration - currentSegment.time, - range: [currentSegment.rangeStart, Infinity] - }); + for (var i = nextSegmentIndex + 1; i < requests.length; i++) { + if (requests[i].time === segmentTime) { + filteredRequests.push(requests[i]); } else { - segments.push({ - time: currentSegment.time, - count: 0, - timescale: timescale, - duration: rawInfos[i + 1].time - currentSegment.time, - range: [currentSegment.rangeStart, rawInfos[i + 1].rangeStart - 1] - }); + break; } } - return segments; + return filteredRequests; } +/** + * 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 getLength(buffer, offset) { - for (var length = 1; length <= 8; length++) { - if (buffer[offset] >= Math.pow(2, 8 - length)) { - return length; - } - } - return 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 -function getEBMLID(buffer, offset) { - var length = getLength(buffer, offset); - if (length == null) { - log/* default.warn */.Z.warn("webm: unrepresentable length"); - return null; - } + var ewma1 = new EWMA(2); + var progress = request.progress; - if (offset + length > buffer.length) { - log/* default.warn */.Z.warn("webm: impossible length"); - return null; + 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); } - var value = 0; + return ewma1.getEstimate(); +} +/** + * Estimate remaining time for a pending request from a progress event. + * @param {Object} lastProgressEvent + * @param {number} bandwidthEstimate + * @returns {number} + */ - for (var i = 0; i < length; i++) { - value = buffer[offset + i] * Math.pow(2, (length - i - 1) * 8) + value; - } - return { - length: length, - value: value - }; +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 - Current pending requests. + * @param {Object} playbackInfo - Information on the current playback. + * @param {Object|null} currentRepresentation - The Representation being + * presently being loaded. + * @param {Number} lastEstimatedBitrate - Last bitrate estimate emitted. + * @returns {Number|undefined} + */ -function getEBMLValue(buffer, offset) { - var length = getLength(buffer, offset); - if (length == null) { - log/* default.warn */.Z.warn("webm: unrepresentable length"); - return null; - } +function estimateStarvationModeBitrate(pendingRequests, playbackInfo, currentRepresentation, lastEstimatedBitrate) { + var bufferGap = playbackInfo.bufferGap, + speed = playbackInfo.speed, + position = playbackInfo.position; + var realBufferGap = isFinite(bufferGap) ? bufferGap : 0; + var nextNeededPosition = position + realBufferGap; + var concernedRequests = getConcernedRequests(pendingRequests, nextNeededPosition); - if (offset + length > buffer.length) { - log/* default.warn */.Z.warn("webm: impossible length"); - return null; + if (concernedRequests.length !== 1) { + // 0 == no request + // 2+ == too complicated to calculate + return undefined; } - var value = (buffer[offset] & (1 << 8 - length) - 1) * Math.pow(2, (length - 1) * 8); + var concernedRequest = concernedRequests[0]; + var chunkDuration = concernedRequest.duration; + 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 - for (var i = 1; i < length; i++) { - value = buffer[offset + i] * Math.pow(2, (length - i - 1) * 8) + value; - } + var bandwidthEstimate = estimateRequestBandwidth(concernedRequest); - return { - length: length, - value: value - }; -} -/** - * Convert a IEEE754 32 bits floating number as an Uint8Array into its - * corresponding Number. - * @param {Uint8Array} buffer - * @param {number} offset - * @returns {number} - */ + 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; -function get_IEEE754_32Bits(buffer, offset) { - return new DataView(buffer.buffer).getFloat32(offset); -} -/** - * Convert a IEEE754 64 bits floating number as an Uint8Array into its - * corresponding Number. - * @param {Uint8Array} buffer - * @param {number} offset - * @returns {number} - */ + if (expectedRebufferingTime > 2000) { + return bandwidthEstimate; + } + } + } + var requestElapsedTime = (now - concernedRequest.requestTimestamp) / 1000; + var reasonableElapsedTime = requestElapsedTime <= (chunkDuration * 1.5 + 2) / speed; -function get_IEEE754_64Bits(buffer, offset) { - return new DataView(buffer.buffer).getFloat64(offset); -} + if (currentRepresentation == null || reasonableElapsedTime) { + return undefined; + } // calculate a reduced bitrate from the current one -function bytesToNumber(buffer, offset, length) { - var value = 0; - for (var i = 0; i < length; i++) { - value = buffer[offset + i] * Math.pow(2, (length - i - 1) * 8) + value; - } + var factor = chunkDuration / requestElapsedTime; + var reducedBitrate = currentRepresentation.bitrate * Math.min(0.7, factor); - return value; + if (lastEstimatedBitrate === undefined || reducedBitrate < lastEstimatedBitrate) { + return reducedBitrate; + } } -;// CONCATENATED MODULE: ./src/transports/utils/get_isobmff_timing_infos.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, 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 + * @param {Object} requests - Every requests pending, in a chronological + * order in terms of segment time. + * @param {number} abrStarvationGap - "Buffer gap" from which we enter a + * "starvation mode". + * @returns {boolean} */ -/** - * Get precize start and duration of a chunk. - * @param {UInt8Array} buffer - An ISOBMFF container (at least a `moof` + a - * `mdat` box. - * @param {Boolean} isChunked - If true, the whole segment was chunked into - * multiple parts and buffer is one of them. If false, buffer is the whole - * segment. - * @param {Object} segment - * @param {Array.|undefined} sidxSegments - Segments from sidx. Here - * pre-parsed for performance reasons as it is usually available when - * this function is called. - * @param {number|undefined} initTimescale - * @returns {Object} - */ -function getISOBMFFTimingInfos(buffer, isChunked, segment, initTimescale) { - var baseDecodeTime = (0,utils/* getTrackFragmentDecodeTime */.Qx)(buffer); +function shouldDirectlySwitchToLowBitrate(playbackInfo, requests) { + var realBufferGap = isFinite(playbackInfo.bufferGap) ? playbackInfo.bufferGap : 0; + var nextNeededPosition = playbackInfo.position + realBufferGap; + var nextRequest = (0,array_find/* default */.Z)(requests, function (r) { + return r.duration > 0 && r.time + r.duration > nextNeededPosition; + }); - if (baseDecodeTime === undefined || initTimescale === undefined) { - return null; + if (nextRequest === undefined) { + return true; } - var startTime = segment.timestampOffset !== undefined ? baseDecodeTime + segment.timestampOffset * initTimescale : baseDecodeTime; - var trunDuration = (0,utils/* getDurationFromTrun */.MM)(buffer); + 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 - if (isChunked) { - // when chunked, no mean to know the duration for now - return { - time: startTime / initTimescale, - duration: trunDuration !== undefined ? trunDuration / initTimescale : undefined - }; - } + var bandwidthEstimate = estimateRequestBandwidth(nextRequest); - var duration; - var segmentDuration = segment.duration * initTimescale; // we could always make a mistake when reading a container. - // If the estimate is too far from what the segment seems to imply, take - // the segment infos instead. + if (lastProgressEvent === undefined || bandwidthEstimate === undefined) { + return true; + } - var maxDecodeTimeDelta = Math.min(initTimescale * 0.9, segmentDuration / 4); + var remainingTime = estimateRemainingTime(lastProgressEvent, bandwidthEstimate); - if (trunDuration !== undefined && Math.abs(trunDuration - segmentDuration) <= maxDecodeTimeDelta) { - duration = trunDuration; + if ((now - lastProgressEvent.timestamp) / 1000 > remainingTime * 1.2) { + return true; } - return { - time: startTime / initTimescale, - duration: duration !== undefined ? duration / initTimescale : duration - }; + var expectedRebufferingTime = remainingTime - realBufferGap / playbackInfo.speed; + return expectedRebufferingTime > -1.5; } -;// CONCATENATED MODULE: ./src/transports/dash/segment_parser.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. + * 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) { + this._initialBitrate = initialBitrate; + this._inStarvationMode = false; + 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 + }; + } + } + /** + * 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 + * @param {Object|null} currentRepresentation + * @param {Array.} currentRequests + * @param {number|undefined} lastEstimatedBitrate + * @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; // check if should get in/out of starvation mode -/** - * @param {Object} config - * @returns {Function} - */ - -function generateAudioVideoSegmentParser(_ref) { - var __priv_patchLastSegmentInSidx = _ref.__priv_patchLastSegmentInSidx; - return function audioVideoSegmentParser(_ref2) { - var content = _ref2.content, - response = _ref2.response, - initTimescale = _ref2.initTimescale; - var period = content.period, - representation = content.representation, - segment = content.segment; - var data = response.data, - isChunked = response.isChunked; - var appendWindow = [period.start, period.end]; - - if (data === null) { - if (segment.isInit) { - var _segmentProtections = representation.getProtectionsInitializationData(); - - return (0,of.of)({ - type: "parsed-init-segment", - value: { - initializationData: null, - segmentProtections: _segmentProtections, - initTimescale: undefined - } - }); + if (isNaN(duration) || realBufferGap + position < 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 - return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: null, - chunkInfos: null, - chunkOffset: 0, - appendWindow: appendWindow - } - }); - } - - var chunkData = data instanceof Uint8Array ? data : new Uint8Array(data); - var isWEBM = isWEBMEmbeddedTrack(representation); - - if (!segment.isInit) { - var chunkInfos = isWEBM ? null : // TODO extract time info from webm - getISOBMFFTimingInfos(chunkData, isChunked, segment, initTimescale); - var chunkOffset = (0,take_first_set/* default */.Z)(segment.timestampOffset, 0); - return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: chunkData, - chunkInfos: chunkInfos, - chunkOffset: chunkOffset, - appendWindow: appendWindow - } - }); - } // we're handling an initialization segment + if (this._inStarvationMode) { + bandwidthEstimate = estimateStarvationModeBitrate(currentRequests, playbackInfo, currentRepresentation, lastEstimatedBitrate); - var indexRange = segment.indexRange; - var nextSegments; + 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 (isWEBM) { - nextSegments = getSegmentsFromCues(chunkData, 0); - } else { - nextSegments = (0,utils/* getSegmentsFromSidx */.Wf)(chunkData, Array.isArray(indexRange) ? indexRange[0] : 0); // This is a very specific handling for streams we know have a very - // specific problem at Canal+: The last reference gives a truncated - // segment. - // Sadly, people on the packaging side could not fix all legacy contents. - // This is an easy-but-ugly fix for those. - // TODO Cleaner way? I tried to always check the obtained segment after - // a byte-range request but it leads to a lot of code. - if (__priv_patchLastSegmentInSidx === true && nextSegments !== null && nextSegments.length > 0) { - var lastSegment = nextSegments[nextSegments.length - 1]; + if (newBitrateCeil == null) { + bandwidthEstimate = bandwidthEstimator.getEstimate(); - if (Array.isArray(lastSegment.range)) { - lastSegment.range[1] = Infinity; - } + 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 (representation.index instanceof BaseRepresentationIndex && nextSegments !== null && nextSegments.length > 0) { - representation.index._addSegments(nextSegments); + if (playbackInfo.speed > 1) { + newBitrateCeil /= playbackInfo.speed; } - var timescale = isWEBM ? getTimeCodeScale(chunkData, 0) : (0,utils/* getMDHDTimescale */.LD)(chunkData); - var parsedTimescale = (0,is_null_or_undefined/* default */.Z)(timescale) ? undefined : timescale; - - if (!isWEBM) { - // TODO extract webm protection information - var psshInfo = (0,take_pssh_out/* default */.Z)(chunkData); - - for (var i = 0; i < psshInfo.length; i++) { - var _psshInfo$i = psshInfo[i], - systemID = _psshInfo$i.systemID, - psshData = _psshInfo$i.data; + return { + bandwidthEstimate: bandwidthEstimate, + bitrateChosen: newBitrateCeil + }; + } + /** + * For a given wanted bitrate, tells if should switch urgently. + * @param {number} bitrate + * @param {Object} playbackInfo + * @returns {boolean} + */ + ; - representation._addProtectionData("cenc", systemID, psshData); - } + _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; } - var segmentProtections = representation.getProtectionsInitializationData(); - return (0,of.of)({ - type: "parsed-init-segment", - value: { - initializationData: chunkData, - segmentProtections: segmentProtections, - initTimescale: parsedTimescale - } - }); + return shouldDirectlySwitchToLowBitrate(playbackInfo, currentRequests); }; -} -;// CONCATENATED MODULE: ./src/transports/utils/is_mp4_embedded_text_track.ts + + return NetworkAnalyzer; +}(); + + +// EXTERNAL MODULE: ./src/utils/object_values.ts +var object_values = __webpack_require__(1679); +;// CONCATENATED MODULE: ./src/core/abr/pending_requests_store.ts /** * Copyright 2015 CANAL+ Group * @@ -44236,96 +47013,92 @@ function generateAudioVideoSegmentParser(_ref) { * limitations under the License. */ + /** - * Returns true if the given texttrack segment represents a textrack embedded - * in a mp4 file. - * @param {Representation} representation - * @returns {Boolean} - */ -function isMP4EmbeddedTextTrack(representation) { - return representation.mimeType === "application/mp4"; -} -;// CONCATENATED MODULE: ./src/transports/dash/text_loader.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. + * Store information about pending requests, like information about: + * - for which segments they are + * - how the request's progress goes + * @class PendingRequestsStore */ +var PendingRequestsStore = /*#__PURE__*/function () { + function PendingRequestsStore() { + this._currentRequests = {}; + } + /** + * Add information about a new pending request. + * @param {string} id + * @param {Object} payload + */ + var _proto = PendingRequestsStore.prototype; + _proto.add = function add(payload) { + var id = payload.id, + time = payload.time, + duration = payload.duration, + requestTimestamp = payload.requestTimestamp; + this._currentRequests[id] = { + time: time, + duration: duration, + requestTimestamp: requestTimestamp, + progress: [] + }; + } + /** + * 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; + } -/** - * Perform requests for "text" segments - * @param {boolean} lowLatencyMode - * @returns {Function} - */ - -function generateTextTrackLoader(_ref) { - var lowLatencyMode = _ref.lowLatencyMode, - checkMediaSegmentIntegrity = _ref.checkMediaSegmentIntegrity; - return checkMediaSegmentIntegrity !== true ? textTrackLoader : addSegmentIntegrityChecks(textTrackLoader); + request.progress.push(progress); + } /** - * @param {Object} args - * @returns {Observable} + * Remove a request previously set as pending. + * @param {string} id */ + ; - function textTrackLoader(args) { - var range = args.segment.range; - var url = args.url; + _proto.remove = function remove(id) { + if (this._currentRequests[id] == null) { + if (false) {} - if (url === null) { - return (0,of.of)({ - type: "data-created", - value: { - responseData: null - } - }); + log/* default.warn */.Z.warn("ABR: can't remove unknown request"); } - if (args.segment.isInit) { - return initSegmentLoader(url, args); - } + delete this._currentRequests[id]; + } + /** + * Returns information about all pending requests, in segment's chronological + * order. + * @returns {Array.} + */ + ; - var isMP4Embedded = isMP4EmbeddedTextTrack(args.representation); + _proto.getRequests = function getRequests() { + return (0,object_values/* default */.Z)(this._currentRequests).filter(function (x) { + return x != null; + }).sort(function (reqA, reqB) { + return reqA.time - reqB.time; + }); + }; - if (lowLatencyMode && isMP4Embedded) { - if (fetchIsSupported()) { - return lowLatencySegmentLoader(url, args); - } else { - (0,warn_once/* default */.Z)("DASH: Your browser does not have the fetch API. You will have " + "a higher chance of rebuffering when playing close to the live edge"); - } - } // ArrayBuffer when in mp4 to parse isobmff manually, text otherwise + return PendingRequestsStore; +}(); - var responseType = isMP4Embedded ? "arraybuffer" : "text"; - return (0,request/* default */.ZP)({ - url: url, - responseType: responseType, - headers: Array.isArray(range) ? { - Range: (0,byte_range/* default */.Z)(range) - } : null, - sendProgressEvents: true - }); - } -} -// EXTERNAL MODULE: ./src/parsers/containers/isobmff/read.ts -var read = __webpack_require__(6807); -;// CONCATENATED MODULE: ./src/transports/utils/parse_text_track.ts +;// CONCATENATED MODULE: ./src/core/abr/representation_score_calculator.ts /** * Copyright 2015 CANAL+ Group * @@ -44343,152 +47116,174 @@ var read = __webpack_require__(6807); */ - -/** - * Return plain text text track from the given ISOBMFF. - * @param {Uint8Array} chunkBytes - * @returns {string} - */ - -function extractTextTrackFromISOBMFF(chunkBytes) { - var mdat = (0,read/* getMDAT */.Le)(chunkBytes); - return mdat === null ? "" : (0,string_parsing/* utf8ToStr */.uR)(mdat); -} /** - * Returns the a string expliciting the format of a text track when that text - * track is embedded into a ISOBMFF file. - * @param {Object} representation - * @returns {string} + * 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 + * + * 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 getISOBMFFTextTrackFormat(representation) { - var codec = representation.codec; - - if (codec === undefined) { - throw new Error("Cannot parse subtitles: unknown format"); +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. + */ - switch (codec.toLowerCase()) { - case "stpp": // stpp === TTML in MP4 - - case "stpp.ttml.im1t": - return "ttml"; - case "wvtt": - // wvtt === WebVTT in MP4 - return "vtt"; - } + var _proto = RepresentationScoreCalculator.prototype; - throw new Error("The codec used for the subtitles " + ("\"" + codec + "\" is not managed yet.")); -} -/** - * Returns the a string expliciting the format of a text track in plain text. - * @param {Object} representation - * @returns {string} - */ + _proto.addSample = function addSample(representation, requestDuration, segmentDuration) { + var ratio = segmentDuration / requestDuration; -function getPlainTextTrackFormat(representation) { - var _representation$mimeT = representation.mimeType, - mimeType = _representation$mimeT === void 0 ? "" : _representation$mimeT; + var oldEwma = this._getEWMA(representation); - switch (representation.mimeType) { - case "application/ttml+xml": - return "ttml"; + var currentEWMA; - case "application/x-sami": - case "application/smil": - return "sami"; + if (oldEwma != null) { + currentEWMA = oldEwma; + oldEwma.addSample(requestDuration, ratio); + } else { + currentEWMA = new EWMA(5); + currentEWMA.addSample(requestDuration, ratio); + this._currentRepresentationData = { + representation: representation, + ewma: currentEWMA + }; + } - case "text/vtt": - return "vtt"; + if (currentEWMA.getEstimate() > 1 && this._lastRepresentationWithGoodScore !== representation) { + log/* default.debug */.Z.debug("ABR: New last stable representation", representation); + this._lastRepresentationWithGoodScore = representation; + } } + /** + * Get score estimate for the given Representation. + * undefined if no estimate is available. + * @param {Representation} representation + * @returns {number|undefined} + */ + ; - var _representation$codec = representation.codec, - codec = _representation$codec === void 0 ? "" : _representation$codec; - var codeLC = codec.toLowerCase(); + _proto.getEstimate = function getEstimate(representation) { + var ewma = this._getEWMA(representation); - if (codeLC === "srt") { - return "srt"; + if (ewma != null) { + return ewma.getEstimate(); + } } + /** + * 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} + */ + ; - throw new Error("could not find a text-track parser for the type " + mimeType); -} -/** - * @param {Object} content - * @param {ArrayBuffer|UInt8Array|null} chunkData - * @param {Object|null} chunkInfos - * @param {boolean} isChunked - * @returns {Object|null} - */ + _proto.getLastStableRepresentation = function getLastStableRepresentation() { + return this._lastRepresentationWithGoodScore; + } + /** + * Returns EWMA for the given Representation. + * null if no EWMA is currently stored for it. + * @param {Representation} representation + * @returns {EWMA|null} + */ + ; -function getISOBMFFEmbeddedTextTrackData(_ref, chunkBytes, chunkInfos, isChunked) { - var segment = _ref.segment, - adaptation = _ref.adaptation, - representation = _ref.representation; + _proto._getEWMA = function _getEWMA(representation) { + if (this._currentRepresentationData != null && this._currentRepresentationData.representation.id === representation.id) { + return this._currentRepresentationData.ewma; + } - if (segment.isInit) { return null; - } - - var startTime; - var endTime; + }; - if (chunkInfos === null) { - if (!isChunked) { - log/* default.warn */.Z.warn("Transport: Unavailable time data for current text track."); - } else { - startTime = segment.time; - endTime = segment.end; - } - } else { - startTime = chunkInfos.time; + return RepresentationScoreCalculator; +}(); - if (chunkInfos.duration !== undefined) { - endTime = startTime + chunkInfos.duration; - } else if (!isChunked) { - endTime = startTime + segment.duration; - } - } - var type = getISOBMFFTextTrackFormat(representation); - var textData = extractTextTrackFromISOBMFF(chunkBytes); - return { - data: textData, - type: type, - language: adaptation.language, - start: startTime, - end: endTime - }; -} +;// CONCATENATED MODULE: ./src/core/abr/select_optimal_representation.ts /** - * @param {Object} content - * @param {ArrayBuffer|UInt8Array|null} chunkData - * @param {Object|null} chunkInfos - * @param {boolean} isChunked - * @returns {Object|null} + * 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 getPlainTextTrackData(_ref2, textTrackData, isChunked) { - var segment = _ref2.segment, - adaptation = _ref2.adaptation, - representation = _ref2.representation; +/** + * 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} + */ - if (segment.isInit) { - return null; - } +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 (isChunked) { - log/* default.warn */.Z.warn("Transport: Unavailable time data for current text track."); + if (firstIndexTooHigh === -1) { + return representations[representations.length - 1]; + } else if (firstIndexTooHigh === 0) { + return representations[0]; } - var type = getPlainTextTrackFormat(representation); - return { - data: textTrackData, - type: type, - language: adaptation.language - }; + return representations[firstIndexTooHigh - 1]; } -;// CONCATENATED MODULE: ./src/transports/dash/text_parser.ts +;// CONCATENATED MODULE: ./src/core/abr/representation_estimator.ts /** * Copyright 2015 CANAL+ Group * @@ -44512,318 +47307,239 @@ function getPlainTextTrackData(_ref2, textTrackData, isChunked) { -/** - * Parse TextTrack data when it is embedded in an ISOBMFF file. - * @param {Object} infos - * @returns {Observable.} - */ -function parseISOBMFFEmbeddedTextTrack(_ref, __priv_patchLastSegmentInSidx) { - var response = _ref.response, - content = _ref.content, - initTimescale = _ref.initTimescale; - var period = content.period, - representation = content.representation, - segment = content.segment; - var isInit = segment.isInit, - indexRange = segment.indexRange; - var data = response.data, - isChunked = response.isChunked; - var chunkBytes = typeof data === "string" ? (0,string_parsing/* strToUtf8 */.tG)(data) : data instanceof Uint8Array ? data : new Uint8Array(data); - if (isInit) { - var sidxSegments = (0,utils/* getSegmentsFromSidx */.Wf)(chunkBytes, Array.isArray(indexRange) ? indexRange[0] : 0); // This is a very specific handling for streams we know have a very - // specific problem at Canal+: The last reference gives a truncated - // segment. - // Sadly, people on the packaging side could not fix all legacy contents. - // This is an easy-but-ugly fix for those. - // TODO Cleaner way? I tried to always check the obtained segment after - // a byte-range request but it leads to a lot of code. - if (__priv_patchLastSegmentInSidx === true && sidxSegments !== null && sidxSegments.length > 0) { - var lastSegment = sidxSegments[sidxSegments.length - 1]; - if (Array.isArray(lastSegment.range)) { - lastSegment.range[1] = Infinity; - } - } +/** + * Filter representations given through filters options. + * @param {Array.} representations + * @param {Object} filters - Filter Object. + * @returns {Array.} + */ - var mdhdTimescale = (0,utils/* getMDHDTimescale */.LD)(chunkBytes); +function getFilteredRepresentations(representations, filters) { + var _representations = representations; - if (representation.index instanceof BaseRepresentationIndex && sidxSegments !== null && sidxSegments.length > 0) { - representation.index._addSegments(sidxSegments); - } + if (filters.bitrate != null) { + _representations = filterByBitrate(_representations, filters.bitrate); + } - return (0,of.of)({ - type: "parsed-init-segment", - value: { - initializationData: null, - segmentProtections: [], - initTimescale: mdhdTimescale - } - }); + if (filters.width != null) { + _representations = filterByWidth(_representations, filters.width); } - var chunkInfos = getISOBMFFTimingInfos(chunkBytes, isChunked, segment, initTimescale); - var chunkData = getISOBMFFEmbeddedTextTrackData(content, chunkBytes, chunkInfos, isChunked); - var chunkOffset = (0,take_first_set/* default */.Z)(segment.timestampOffset, 0); - return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: chunkData, - chunkInfos: chunkInfos, - chunkOffset: chunkOffset, - appendWindow: [period.start, period.end] - } - }); + return _representations; } /** - * Parse TextTrack data in plain text form. - * @param {Object} infos - * @returns {Observable.} + * Estimate regularly the current network bandwidth and the best Representation + * that can be played according to the current network and playback conditions. + * + * A `RepresentationEstimator` 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 + * create as many `RepresentationEstimator`. + * @param {Object} args + * @returns {Observable} */ -function parsePlainTextTrack(_ref2) { - var response = _ref2.response, - content = _ref2.content; - var period = content.period, - segment = content.segment; - var _segment$timestampOff = segment.timestampOffset, - timestampOffset = _segment$timestampOff === void 0 ? 0 : _segment$timestampOff; +function RepresentationEstimator(_ref) { + var bandwidthEstimator = _ref.bandwidthEstimator, + clock$ = _ref.clock$, + filters$ = _ref.filters$, + initialBitrate = _ref.initialBitrate, + lowLatencyMode = _ref.lowLatencyMode, + manualBitrate$ = _ref.manualBitrate$, + minAutoBitrate$ = _ref.minAutoBitrate$, + maxAutoBitrate$ = _ref.maxAutoBitrate$, + representations = _ref.representations, + streamEvents$ = _ref.streamEvents$; + var scoreCalculator = new RepresentationScoreCalculator(); + var networkAnalyzer = new NetworkAnalyzer(initialBitrate == null ? 0 : initialBitrate, lowLatencyMode); + var requestsStore = new PendingRequestsStore(); + var shouldIgnoreMetrics = generateCachedSegmentDetector(); + /** + * Callback to call when new metrics are available + * @param {Object} value + */ - if (segment.isInit) { - return (0,of.of)({ - type: "parsed-init-segment", - value: { - initializationData: null, - segmentProtections: [], - initTimescale: undefined - } - }); - } + function onMetric(value) { + var duration = value.duration, + size = value.size, + content = value.content; - var data = response.data, - isChunked = response.isChunked; - var textTrackData; + if (shouldIgnoreMetrics(content, duration)) { + // We already loaded not cached segments. + // Do not consider cached segments anymore. + return; + } // calculate bandwidth - if (typeof data !== "string") { - var bytesData = data instanceof Uint8Array ? data : new Uint8Array(data); - textTrackData = (0,string_parsing/* utf8ToStr */.uR)(bytesData); - } else { - textTrackData = data; - } - var chunkData = getPlainTextTrackData(content, textTrackData, isChunked); - return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: chunkData, - chunkInfos: null, - chunkOffset: timestampOffset, - appendWindow: [period.start, period.end] - } - }); -} -/** - * @param {Object} config - * @returns {Function} - */ + bandwidthEstimator.addSample(duration, size); // calculate "maintainability score" + var segment = content.segment; + var requestDuration = duration / 1000; + var segmentDuration = segment.duration; + var representation = content.representation; + scoreCalculator.addSample(representation, requestDuration, segmentDuration); + } -function generateTextTrackParser(_ref3) { - var __priv_patchLastSegmentInSidx = _ref3.__priv_patchLastSegmentInSidx; + var metrics$ = streamEvents$.pipe((0,filter/* filter */.h)(function (e) { + return e.type === "metrics"; + }), (0,tap/* tap */.b)(function (_ref2) { + var value = _ref2.value; + return onMetric(value); + }), (0,ignoreElements/* ignoreElements */.l)()); + var requests$ = streamEvents$.pipe((0,tap/* tap */.b)(function (evt) { + switch (evt.type) { + case "requestBegin": + requestsStore.add(evt.value); + break; - /** - * Parse TextTrack data. - * @param {Object} infos - * @returns {Observable.} - */ - return function textTrackParser(_ref4) { - var response = _ref4.response, - content = _ref4.content, - initTimescale = _ref4.initTimescale; - var period = content.period, - representation = content.representation, - segment = content.segment; - var _segment$timestampOff2 = segment.timestampOffset, - timestampOffset = _segment$timestampOff2 === void 0 ? 0 : _segment$timestampOff2; - var data = response.data, - isChunked = response.isChunked; + case "requestEnd": + requestsStore.remove(evt.value.id); + break; - if (data === null) { - // No data, just return empty infos - if (segment.isInit) { - return (0,of.of)({ - type: "parsed-init-segment", - value: { - initializationData: null, - segmentProtections: [], - initTimescale: undefined - } - }); - } + case "progress": + requestsStore.addProgress(evt.value); + break; + } + }), (0,ignoreElements/* ignoreElements */.l)()); + var currentRepresentation$ = streamEvents$.pipe((0,filter/* filter */.h)(function (e) { + return e.type === "representationChange"; + }), (0,map/* map */.U)(function (e) { + return e.value.representation; + }), (0,startWith/* startWith */.O)(null)); + var estimate$ = (0,defer/* defer */.P)(function () { + if (representations.length === 0) { + throw new Error("ABRManager: no representation choice given"); + } + if (representations.length === 1) { return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: null, - chunkInfos: null, - chunkOffset: timestampOffset, - appendWindow: [period.start, period.end] - } + bitrate: undefined, + representation: representations[0], + manual: false, + urgent: true, + knownStableBitrate: undefined }); } - var isMP4 = isMP4EmbeddedTextTrack(representation); - - if (isMP4) { - return parseISOBMFFEmbeddedTextTrack({ - response: { - data: data, - isChunked: isChunked - }, - content: content, - initTimescale: initTimescale - }, __priv_patchLastSegmentInSidx); - } else { - return parsePlainTextTrack({ - response: { - data: data, - isChunked: isChunked - }, - content: content - }); - } - }; -} -;// CONCATENATED MODULE: ./src/transports/dash/pipelines.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 manualBitrate$.pipe((0,switchMap/* switchMap */.w)(function (manualBitrate) { + if (manualBitrate >= 0) { + // -- MANUAL mode -- + var manualRepresentation = selectOptimalRepresentation(representations, manualBitrate, 0, Infinity); + return (0,of.of)({ + representation: manualRepresentation, + bitrate: undefined, + knownStableBitrate: undefined, + manual: true, + urgent: true // a manual bitrate switch should happen immediately + }); + } // -- AUTO mode -- + var lastEstimatedBitrate; + var forceBandwidthMode = true; // Emit each time a buffer-based estimation should be actualized (each + // time a segment is added). + var bufferBasedClock$ = streamEvents$.pipe((0,filter/* filter */.h)(function (e) { + return e.type === "added-segment"; + }), withLatestFrom(clock$), (0,map/* map */.U)(function (_ref3) { + var evtValue = _ref3[0].value, + _ref3$ = _ref3[1], + speed = _ref3$.speed, + position = _ref3$.position; + var timeRanges = evtValue.buffered; + var bufferGap = (0,ranges/* getLeftSizeOfRange */.L7)(timeRanges, position); + var representation = evtValue.content.representation; + var currentScore = scoreCalculator.getEstimate(representation); + var currentBitrate = representation.bitrate; + return { + bufferGap: bufferGap, + currentBitrate: currentBitrate, + currentScore: currentScore, + speed: speed + }; + })); + var bitrates = representations.map(function (r) { + return r.bitrate; + }); + var bufferBasedEstimation$ = BufferBasedChooser(bufferBasedClock$, bitrates).pipe((0,startWith/* startWith */.O)(undefined)); + return (0,combineLatest/* combineLatest */.aj)([clock$, minAutoBitrate$, maxAutoBitrate$, filters$, bufferBasedEstimation$]).pipe(withLatestFrom(currentRepresentation$), (0,map/* map */.U)(function (_ref4) { + var _ref4$ = _ref4[0], + clock = _ref4$[0], + minAutoBitrate = _ref4$[1], + maxAutoBitrate = _ref4$[2], + filters = _ref4$[3], + bufferBasedBitrate = _ref4$[4], + currentRepresentation = _ref4[1]; + var _representations = getFilteredRepresentations(representations, filters); + var requests = requestsStore.getRequests(); -/** - * Returns pipelines used for DASH streaming. - * @param {Object} options - * implementation. Used for each generated http request. - * @returns {Object} - */ + var _networkAnalyzer$getB = networkAnalyzer.getBandwidthEstimate(clock, bandwidthEstimator, currentRepresentation, requests, lastEstimatedBitrate), + bandwidthEstimate = _networkAnalyzer$getB.bandwidthEstimate, + bitrateChosen = _networkAnalyzer$getB.bitrateChosen; -/* harmony default export */ function pipelines(options) { - var manifestLoader = (0,text_manifest_loader/* default */.Z)({ - customManifestLoader: options.manifestLoader - }); - var manifestParser = generateManifestParser(options); - var segmentLoader = generateSegmentLoader(options); - var audioVideoSegmentParser = generateAudioVideoSegmentParser(options); - var textTrackLoader = generateTextTrackLoader(options); - var textTrackParser = generateTextTrackParser(options); - return { - manifest: { - loader: manifestLoader, - parser: manifestParser - }, - audio: { - loader: segmentLoader, - parser: audioVideoSegmentParser - }, - video: { - loader: segmentLoader, - parser: audioVideoSegmentParser - }, - text: { - loader: textTrackLoader, - parser: textTrackParser - }, - image: { - loader: imageLoader, - parser: imageParser - } - }; -} -;// CONCATENATED MODULE: ./src/transports/dash/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. - */ + lastEstimatedBitrate = bandwidthEstimate; + var stableRepresentation = scoreCalculator.getLastStableRepresentation(); + var knownStableBitrate = stableRepresentation == null ? undefined : stableRepresentation.bitrate / (clock.speed > 0 ? clock.speed : 1); + var bufferGap = clock.bufferGap; -/** - * /!\ This file is feature-switchable. - * It always should be imported through the `features` object. - */ + if (!forceBandwidthMode && bufferGap <= 5) { + forceBandwidthMode = true; + } else if (forceBandwidthMode && isFinite(bufferGap) && bufferGap > 10) { + forceBandwidthMode = false; + } -/* harmony default export */ const transports_dash = (pipelines); + var chosenRepFromBandwidth = selectOptimalRepresentation(_representations, bitrateChosen, minAutoBitrate, maxAutoBitrate); -/***/ }), + if (forceBandwidthMode) { + log/* default.debug */.Z.debug("ABR: Choosing representation with bandwidth estimation.", chosenRepFromBandwidth); + return { + bitrate: bandwidthEstimate, + representation: chosenRepFromBandwidth, + urgent: networkAnalyzer.isUrgent(chosenRepFromBandwidth.bitrate, currentRepresentation, requests, clock), + manual: false, + knownStableBitrate: knownStableBitrate + }; + } -/***/ 2339: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (bufferBasedBitrate == null || chosenRepFromBandwidth.bitrate >= bufferBasedBitrate) { + log/* default.debug */.Z.debug("ABR: Choosing representation with bandwidth estimation.", chosenRepFromBandwidth); + return { + bitrate: bandwidthEstimate, + representation: chosenRepFromBandwidth, + urgent: networkAnalyzer.isUrgent(chosenRepFromBandwidth.bitrate, currentRepresentation, requests, clock), + manual: false, + knownStableBitrate: knownStableBitrate + }; + } -"use strict"; + var chosenRepresentation = selectOptimalRepresentation(_representations, bufferBasedBitrate, minAutoBitrate, maxAutoBitrate); -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ transports_smooth -}); + if (bufferBasedBitrate <= maxAutoBitrate) { + log/* default.debug */.Z.debug("ABR: Choosing representation with buffer based bitrate ceiling.", chosenRepresentation); + } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js -var of = __webpack_require__(8170); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/map.js -var map = __webpack_require__(5709); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/tap.js -var tap = __webpack_require__(3068); -// EXTERNAL MODULE: ./src/features/index.ts -var features = __webpack_require__(7874); -// EXTERNAL MODULE: ./src/log.ts + 1 modules -var log = __webpack_require__(3887); -// EXTERNAL MODULE: ./src/manifest/index.ts + 10 modules -var src_manifest = __webpack_require__(1966); -// EXTERNAL MODULE: ./src/parsers/containers/isobmff/take_pssh_out.ts + 1 modules -var take_pssh_out = __webpack_require__(6490); -// EXTERNAL MODULE: ./src/parsers/containers/isobmff/read.ts -var read = __webpack_require__(6807); -// EXTERNAL MODULE: ./src/utils/array_includes.ts -var array_includes = __webpack_require__(7714); -// EXTERNAL MODULE: ./src/utils/assert.ts -var assert = __webpack_require__(811); -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -// EXTERNAL MODULE: ./src/utils/object_assign.ts -var object_assign = __webpack_require__(8026); -// EXTERNAL MODULE: ./src/utils/resolve_url.ts -var resolve_url = __webpack_require__(9829); -// EXTERNAL MODULE: ./src/utils/take_first_set.ts -var take_first_set = __webpack_require__(5278); -;// CONCATENATED MODULE: ./src/parsers/manifest/utils/check_manifest_ids.ts + return { + bitrate: bandwidthEstimate, + representation: chosenRepresentation, + urgent: networkAnalyzer.isUrgent(bufferBasedBitrate, currentRepresentation, requests, clock), + manual: false, + knownStableBitrate: knownStableBitrate + }; + })); + })); + }); + return (0,merge/* merge */.T)(metrics$, requests$, estimate$); +} +;// CONCATENATED MODULE: ./src/core/abr/abr_manager.ts /** * Copyright 2015 CANAL+ Group * @@ -44841,75 +47557,90 @@ var take_first_set = __webpack_require__(5278); */ + + + + /** - * Ensure that no two periods, adaptations from the same period and - * representations from the same adaptation, have the same ID. - * - * Log and mutate their ID if not until this is verified. + * Adaptive BitRate Manager. * - * @param {Object} manifest + * Select the right Representation from the network and buffer infos it + * receives. + * @class ABRManager */ -function checkManifestIDs(manifest) { - var periodIDS = []; - manifest.periods.forEach(function (period) { - var periodID = period.id; - - if ((0,array_includes/* default */.Z)(periodIDS, periodID)) { - log/* default.warn */.Z.warn("Two periods with the same ID found. Updating."); - var newID = periodID + "-dup"; - period.id = newID; - checkManifestIDs(manifest); - periodIDS.push(newID); - } else { - periodIDS.push(periodID); - } +var ABRManager = /*#__PURE__*/function () { + /** + * @param {Object} options + */ + function ABRManager(options) { + this._manualBitrates = options.manualBitrates; + this._minAutoBitrates = options.minAutoBitrates; + this._maxAutoBitrates = options.maxAutoBitrates; + this._initialBitrates = options.initialBitrates; + this._throttlers = options.throttlers; + this._bandwidthEstimators = {}; + this._lowLatencyMode = options.lowLatencyMode; + } + /** + * Take type and an array of the available representations, spit out an + * observable emitting the best representation (given the network/buffer + * state). + * @param {string} type + * @param {Array.} representations + * @param {Observable} clock$ + * @param {Observable} streamEvents$ + * @returns {Observable} + */ - var adaptations = period.adaptations; - var adaptationIDs = []; - Object.keys(adaptations).forEach(function (type) { - var adaptationsForType = adaptations[type]; - if (adaptationsForType === undefined) { - return; - } + var _proto = ABRManager.prototype; - adaptationsForType.forEach(function (adaptation) { - var adaptationID = adaptation.id; + _proto.get$ = function get$(type, representations, clock$, streamEvents$) { + var bandwidthEstimator = this._getBandwidthEstimator(type); - if ((0,array_includes/* default */.Z)(adaptationIDs, adaptationID)) { - log/* default.warn */.Z.warn("Two adaptations with the same ID found. Updating.", adaptationID); + var manualBitrate$ = (0,take_first_set/* default */.Z)(this._manualBitrates[type], (0,of.of)(-1)); + var minAutoBitrate$ = (0,take_first_set/* default */.Z)(this._minAutoBitrates[type], (0,of.of)(0)); + var maxAutoBitrate$ = (0,take_first_set/* default */.Z)(this._maxAutoBitrates[type], (0,of.of)(Infinity)); + var initialBitrate = (0,take_first_set/* default */.Z)(this._initialBitrates[type], 0); + var filters$ = createFilters(this._throttlers.limitWidth[type], this._throttlers.throttleBitrate[type], this._throttlers.throttle[type]); + return RepresentationEstimator({ + bandwidthEstimator: bandwidthEstimator, + streamEvents$: streamEvents$, + clock$: clock$, + filters$: filters$, + initialBitrate: initialBitrate, + manualBitrate$: manualBitrate$, + minAutoBitrate$: minAutoBitrate$, + maxAutoBitrate$: maxAutoBitrate$, + representations: representations, + lowLatencyMode: this._lowLatencyMode + }); + } + /** + * @param {string} bufferType + * @returns {Object} + */ + ; - var _newID = adaptationID + "-dup"; + _proto._getBandwidthEstimator = function _getBandwidthEstimator(bufferType) { + var originalBandwidthEstimator = this._bandwidthEstimators[bufferType]; - adaptation.id = _newID; - checkManifestIDs(manifest); - adaptationIDs.push(_newID); - } else { - adaptationIDs.push(adaptationID); - } + if (originalBandwidthEstimator == null) { + log/* default.debug */.Z.debug("ABR: Creating new BandwidthEstimator for ", bufferType); + var bandwidthEstimator = new BandwidthEstimator(); + this._bandwidthEstimators[bufferType] = bandwidthEstimator; + return bandwidthEstimator; + } - var representationIDs = []; - adaptation.representations.forEach(function (representation) { - var representationID = representation.id; + return originalBandwidthEstimator; + }; - if ((0,array_includes/* default */.Z)(representationIDs, representationID)) { - log/* default.warn */.Z.warn("Two representations with the same ID found. Updating.", representationID); + return ABRManager; +}(); - var _newID2 = representationID + "-dup"; - representation.id = _newID2; - checkManifestIDs(manifest); - representationIDs.push(_newID2); - } else { - representationIDs.push(representationID); - } - }); - }); - }); - }); -} -;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/get_codecs.ts +;// CONCATENATED MODULE: ./src/core/abr/index.ts /** * Copyright 2015 CANAL+ Group * @@ -44926,45 +47657,16 @@ function checkManifestIDs(manifest) { * limitations under the License. */ -/** - * @param {string} codecPrivateData - * @param {string|undefined} fourCC - * @returns {string} - */ - -function getAudioCodecs(codecPrivateData, fourCC) { - var mpProfile; - - if (fourCC === "AACH") { - mpProfile = 5; // High Efficiency AAC Profile - } else { - mpProfile = (0,is_non_empty_string/* default */.Z)(codecPrivateData) ? (parseInt(codecPrivateData.substring(0, 2), 16) & 0xF8) >> 3 : 2; - } - - if (mpProfile === 0) { - // Return default audio codec - return "mp4a.40.2"; - } - - return "mp4a.40." + mpProfile; -} -/** - * @param {string} codecPrivateData - * @returns {string} - */ - -function getVideoCodecs(codecPrivateData) { - // we can extract codes only if fourCC is on of "H264", "X264", "DAVC", "AVC1" - var arr = /00000001\d7([0-9a-fA-F]{6})/.exec(codecPrivateData); - - if (arr === null || !(0,is_non_empty_string/* default */.Z)(arr[1])) { - // Return default video codec - return "avc1.4D401E"; - } - - return "avc1." + arr[1]; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/parse_C_nodes.ts +/* harmony default export */ const abr = (ABRManager); +// EXTERNAL MODULE: ./src/core/init/create_eme_manager.ts + 1 modules +var create_eme_manager = __webpack_require__(4507); +// 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 * @@ -44981,107 +47683,111 @@ function getVideoCodecs(codecPrivateData) { * limitations under the License. */ + + + + + +var onSourceOpen$ = event_listeners/* onSourceOpen$ */.ym; /** - * Parse C nodes to build index timeline. - * @param {Element} nodes + * 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 parseCNodes(nodes) { - return nodes.reduce(function (timeline, node, i) { - var dAttr = node.getAttribute("d"); - var tAttr = node.getAttribute("t"); - var rAttr = node.getAttribute("r"); - var repeatCount = rAttr !== null ? +rAttr - 1 : 0; - var start = tAttr !== null ? +tAttr : undefined; - var duration = dAttr !== null ? +dAttr : undefined; +function resetMediaSource(mediaElement, mediaSource, mediaSourceURL) { + if (mediaSource !== null && mediaSource.readyState !== "closed") { + var readyState = mediaSource.readyState, + sourceBuffers = mediaSource.sourceBuffers; - if (i === 0) { - // first node - start = start === undefined || isNaN(start) ? 0 : start; - } else { - // from second node to the end - var prev = timeline[i - 1]; + for (var i = sourceBuffers.length - 1; i >= 0; i--) { + var sourceBuffer = sourceBuffers[i]; - if (start == null || isNaN(start)) { - if (prev.duration == null || isNaN(prev.duration)) { - throw new Error("Smooth: Invalid CNodes. Missing timestamp."); + try { + if (readyState === "open") { + log/* default.info */.Z.info("Init: Removing SourceBuffer from mediaSource", sourceBuffer); + sourceBuffer.abort(); } - start = prev.start + prev.duration * (prev.repeatCount + 1); + mediaSource.removeSourceBuffer(sourceBuffer); + } catch (e) { + log/* default.warn */.Z.warn("Init: Error while disposing SourceBuffer", e); } } - if (duration == null || isNaN(duration)) { - var nextNode = nodes[i + 1]; - - if (nextNode !== undefined) { - var nextTAttr = nextNode.getAttribute("t"); - var nextStart = (0,is_non_empty_string/* default */.Z)(nextTAttr) ? +nextTAttr : null; + if (sourceBuffers.length > 0) { + log/* default.warn */.Z.warn("Init: Not all SourceBuffers could have been removed."); + } + } - if (nextStart === null) { - throw new Error("Can't build index timeline from Smooth Manifest."); - } + (0,clear_element_src/* default */.Z)(mediaElement); - duration = nextStart - start; - } else { - return timeline; - } + 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); } - - timeline.push({ - duration: duration, - start: start, - repeatCount: repeatCount - }); - return timeline; - }, []); + } } -// EXTERNAL MODULE: ./src/utils/base64.ts -var base64 = __webpack_require__(9689); -// EXTERNAL MODULE: ./src/utils/byte_parsing.ts -var byte_parsing = __webpack_require__(6968); -// EXTERNAL MODULE: ./src/utils/string_parsing.ts -var string_parsing = __webpack_require__(3635); -;// CONCATENATED MODULE: ./src/parsers/containers/isobmff/drm/playready.ts /** - * Copyright 2015 CANAL+ Group + * Create, on subscription, a MediaSource instance and attach it to the given + * mediaElement element's src attribute. * - * 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 + * 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. * - * http://www.apache.org/licenses/LICENSE-2.0 + * On unsubscription, the mediaElement.src is cleaned, MediaSource SourceBuffers + * are aborted and some minor cleaning is done. * - * 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 {HTMLMediaElement} mediaElement + * @returns {Observable} */ +function createMediaSource(mediaElement) { + return new Observable/* Observable */.y(function (observer) { + if (browser_compatibility_types/* MediaSource_ */.JJ == 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_ */.JJ(); + 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); + }; + }); +} /** - * Parse PlayReady privateData to get its Hexa-coded KeyID. - * @param {Uint8Array} privateData - * @returns {string} + * Create and open a new MediaSource object on the given media element. + * Emit the MediaSource when done. + * @param {HTMLMediaElement} mediaElement + * @returns {Observable} */ -function getPlayReadyKIDFromPrivateData(data) { - var xmlLength = (0,byte_parsing/* le2toi */.qb)(data, 8); - var xml = (0,string_parsing/* utf16LEToStr */.wV)(data.subarray(10, xmlLength + 10)); - var doc = new DOMParser().parseFromString(xml, "application/xml"); - var kidElement = doc.querySelector("KID"); - - if (kidElement === null) { - throw new Error("Cannot parse PlayReady private data: invalid XML"); - } - var b64guidKid = kidElement.textContent === null ? "" : kidElement.textContent; - var uuidKid = (0,string_parsing/* guidToUuid */.wO)((0,base64/* base64ToBytes */.K)(b64guidKid)); - return (0,string_parsing/* bytesToHex */.ci)(uuidKid).toLowerCase(); +function openMediaSource(mediaElement) { + return createMediaSource(mediaElement).pipe((0,mergeMap/* mergeMap */.zg)(function (mediaSource) { + return onSourceOpen$(mediaSource).pipe((0,take/* take */.q)(1), (0,mapTo/* mapTo */.h)(mediaSource)); + })); } -;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/parse_protection_node.ts +// 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 * @@ -45099,129 +47805,96 @@ function getPlayReadyKIDFromPrivateData(data) { */ - - +var DEFAULT_LIVE_GAP = config/* default.DEFAULT_LIVE_GAP */.Z.DEFAULT_LIVE_GAP; /** - * @param {Uint8Array} keyIdBytes - * @returns {Array.} + * 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 createWidevineKeySystem(keyIdBytes) { - return [{ - systemId: "edef8ba9-79d6-4ace-a3c8-27dcd51d21ed", - privateData: (0,byte_parsing/* concat */.zo)([0x08, 0x01, 0x12, 0x10], keyIdBytes) - }]; -} -/** - * Parse "Protection" Node, which contains DRM information - * @param {Element} protectionNode - * @returns {Object} - */ +function getInitialTime(manifest, lowLatencyMode, startAt) { + log/* default.debug */.Z.debug("Init: calculating initial time"); + if (startAt != null) { + var min = manifest.getMinimumPosition(); + var max = manifest.getMaximumPosition(); -function parseProtectionNode(protectionNode, keySystemCreator) { - if (keySystemCreator === void 0) { - keySystemCreator = createWidevineKeySystem; - } + if (startAt.position != null) { + log/* default.debug */.Z.debug("Init: using startAt.minimumPosition"); + return Math.max(Math.min(startAt.position, max), min); + } else if (startAt.wallClockTime != null) { + log/* default.debug */.Z.debug("Init: using startAt.wallClockTime"); + var ast = manifest.availabilityStartTime == null ? 0 : manifest.availabilityStartTime; + var position = startAt.wallClockTime - ast; + return Math.max(Math.min(position, max), min); + } else if (startAt.fromFirstPosition != null) { + log/* default.debug */.Z.debug("Init: using startAt.fromFirstPosition"); + var fromFirstPosition = startAt.fromFirstPosition; + return fromFirstPosition <= 0 ? min : Math.min(max, min + fromFirstPosition); + } else if (startAt.fromLastPosition != null) { + log/* default.debug */.Z.debug("Init: using startAt.fromLastPosition"); + var fromLastPosition = startAt.fromLastPosition; + return fromLastPosition >= 0 ? max : Math.max(min, max + fromLastPosition); + } else if (startAt.percentage != null) { + log/* default.debug */.Z.debug("Init: using startAt.percentage"); + var percentage = startAt.percentage; - if (protectionNode.firstElementChild === null || protectionNode.firstElementChild.nodeName !== "ProtectionHeader") { - throw new Error("Protection should have ProtectionHeader child"); + if (percentage > 100) { + return max; + } else if (percentage < 0) { + return min; + } + + var ratio = +percentage / 100; + var extent = max - min; + return min + extent * ratio; + } } - var header = protectionNode.firstElementChild; - var privateData = (0,base64/* base64ToBytes */.K)(header.textContent === null ? "" : header.textContent); - var keyIdHex = getPlayReadyKIDFromPrivateData(privateData); - var keyIdBytes = (0,string_parsing/* hexToBytes */.nr)(keyIdHex); // remove possible braces + var minimumPosition = manifest.getMinimumPosition(); - var systemIdAttr = header.getAttribute("SystemID"); - var systemId = (systemIdAttr !== null ? systemIdAttr : "").toLowerCase().replace(/\{|\}/g, ""); - return { - keyId: keyIdBytes, - keySystems: [{ - systemId: systemId, - privateData: privateData - }].concat(keySystemCreator(keyIdBytes)) - }; -} -// EXTERNAL MODULE: ./src/errors/network_error.ts -var network_error = __webpack_require__(9362); -// EXTERNAL MODULE: ./src/parsers/manifest/utils/clear_timeline_from_position.ts -var clear_timeline_from_position = __webpack_require__(8232); -// EXTERNAL MODULE: ./src/parsers/manifest/utils/index_helpers.ts -var index_helpers = __webpack_require__(3911); -// EXTERNAL MODULE: ./src/parsers/manifest/utils/is_segment_still_available.ts -var is_segment_still_available = __webpack_require__(1091); -// EXTERNAL MODULE: ./src/parsers/manifest/utils/update_segment_timeline.ts -var update_segment_timeline = __webpack_require__(5505); -;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/utils/add_segment_infos.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. - */ + if (manifest.isLive) { + var suggestedPresentationDelay = manifest.suggestedPresentationDelay, + clockOffset = manifest.clockOffset; + var maximumPosition = manifest.getMaximumPosition(); + var liveTime; -/** - * Add a new segment to the index. - * - * /!\ Mutate the given index - * @param {Object} index - * @param {Object} newSegment - * @param {Object} currentSegment - * @returns {Boolean} - true if the segment has been added - */ + if (clockOffset == null) { + 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"); -function _addSegmentInfos(index, newSegment, currentSegment) { - var timeline = index.timeline, - timescale = index.timescale; - var timelineLength = timeline.length; - var last = timeline[timelineLength - 1]; - var scaledNewSegment = newSegment.timescale === timescale ? { - time: newSegment.time, - duration: newSegment.duration - } : { - time: newSegment.time / newSegment.timescale * timescale, - duration: newSegment.duration / newSegment.timescale * timescale - }; // in some circumstances, the new segment information are only duration - // information that we could use to deduct the start of the next segment. - // This is the case where the new segment are associated to a current - // segment and have the same start. - // However, we prefer to be sure of the duration of the new segments - // before adding such segments. + var _ast = manifest.availabilityStartTime == null ? 0 : manifest.availabilityStartTime; - var shouldDeductNextSegment = currentSegment.time === scaledNewSegment.time; + var clockRelativeLiveTime = (performance.now() + clockOffset) / 1000 - _ast; - if (shouldDeductNextSegment) { - return false; - } else if (scaledNewSegment.time >= (0,index_helpers/* getIndexSegmentEnd */.jH)(last, null)) { - // if the given timing has a timestamp after the timeline end we - // just need to push a new element in the timeline, or increase - // the @r attribute of the last element. - if (last.duration === scaledNewSegment.duration) { - last.repeatCount++; - } else { - index.timeline.push({ - duration: scaledNewSegment.duration, - start: scaledNewSegment.time, - repeatCount: 0 - }); + liveTime = Math.min(maximumPosition, clockRelativeLiveTime); } - return true; + 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); } - return false; + log/* default.info */.Z.info("Init: starting at the minimum available position:", minimumPosition); + return minimumPosition; } -;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/utils/tokens.ts +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/throwError.js +var throwError = __webpack_require__(4944); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/interval.js +var observable_interval = __webpack_require__(6564); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/fromEvent.js +var fromEvent = __webpack_require__(7027); +;// CONCATENATED MODULE: ./src/compat/change_source_buffer_type.ts /** * Copyright 2015 CANAL+ Group * @@ -45233,32 +47906,43 @@ function _addSegmentInfos(index, newSegment, currentSegment) { * * 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 {string} url - * @param {string|number} bitrate - * @returns {string} + * 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 replaceRepresentationSmoothTokens(url, bitrate, customAttributes) { - return url.replace(/\{bitrate\}/g, String(bitrate)).replace(/{CustomAttributes}/g, customAttributes.length > 0 ? customAttributes[0] : ""); -} + /** - * @param {string} url - * @param {number} time - * @returns {string} + * If the changeType MSE API is implemented, update the current codec of the + * SourceBuffer and return true if it succeeded. + * In any other cases, return false. + * @param {Object} sourceBuffer + * @param {string} codec + * @returns {boolean} */ +function tryToChangeSourceBufferType(sourceBuffer, codec) { + if (typeof sourceBuffer.changeType === "function") { + try { + sourceBuffer.changeType(codec); + } catch (e) { + log/* default.warn */.Z.warn("Could not call 'changeType' on the given SourceBuffer:", e); + return false; + } -function replaceSegmentSmoothTokens(url, time) { - return url.replace(/\{start time\}/g, String(time)); + return true; + } + + return false; } +// EXTERNAL MODULE: ./src/utils/byte_parsing.ts +var byte_parsing = __webpack_require__(6968); +// EXTERNAL MODULE: ./src/utils/hash_buffer.ts +var hash_buffer = __webpack_require__(2870); +// EXTERNAL MODULE: ./src/core/segment_buffers/implementations/types.ts + 1 modules +var types = __webpack_require__(4123); +;// CONCATENATED MODULE: ./src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts -;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/representation_index.ts /** * Copyright 2015 CANAL+ Group * @@ -45282,463 +47966,504 @@ function replaceSegmentSmoothTokens(url, time) { -/** - * @param {Number} start - * @param {Number} up - * @param {Number} duration - * @returns {Number} - */ - -function getSegmentNumber(start, up, duration) { - var diff = up - start; - return diff > 0 ? Math.floor(diff / duration) : 0; -} -/** - * Convert second-based start time and duration to the timescale of the - * manifest's index. - * @param {Object} index - * @param {Number} start - * @param {Number} duration - * @returns {Object} - Object with two properties: - * - up {Number}: timescaled timestamp of the beginning time - * - to {Number}: timescaled timestamp of the end time (start time + duration) - */ - - -function normalizeRange(index, start, duration) { - var timescale = index.timescale === undefined || index.timescale === 0 ? 1 : index.timescale; - return { - up: start * timescale, - to: (start + duration) * timescale - }; -} -/** - * Calculate the number of times a segment repeat based on the next segment. - * @param {Object} segment - * @param {Object} nextSegment - * @returns {Number} - */ - -function calculateRepeat(segment, nextSegment) { - var repeatCount = segment.repeatCount; // A negative value of the @r attribute of the S element indicates - // that the duration indicated in @d attribute repeats until the - // start of the next S element, the end of the Period or until the - // next MPD update. - // TODO Also for SMOOTH???? - if (segment.duration != null && repeatCount < 0) { - var repeatEnd = nextSegment !== undefined ? nextSegment.start : Infinity; - repeatCount = Math.ceil((repeatEnd - segment.start) / segment.duration) - 1; - } - return repeatCount; -} +var SOURCE_BUFFER_FLUSHING_INTERVAL = config/* default.SOURCE_BUFFER_FLUSHING_INTERVAL */.Z.SOURCE_BUFFER_FLUSHING_INTERVAL; /** - * RepresentationIndex implementation for Smooth Manifests. + * 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 + * been pushed and what is being pushed. * - * Allows to interact with the index to create new Segments. + * To work correctly, only a single AudioVideoSegmentBuffer per SourceBuffer + * should be created. * - * @class SmoothRepresentationIndex + * @class AudioVideoSegmentBuffer */ +var AudioVideoSegmentBuffer = /*#__PURE__*/function (_SegmentBuffer) { + (0,inheritsLoose/* default */.Z)(AudioVideoSegmentBuffer, _SegmentBuffer); -var SmoothRepresentationIndex = /*#__PURE__*/function () { - function SmoothRepresentationIndex(index, options) { - var aggressiveMode = options.aggressiveMode, - isLive = options.isLive, - segmentPrivateInfos = options.segmentPrivateInfos; - var estimatedReceivedTime = index.manifestReceivedTime == null ? performance.now() : index.manifestReceivedTime; - this._index = index; - this._indexValidityTime = estimatedReceivedTime; - this._initSegmentInfos = { - bitsPerSample: segmentPrivateInfos.bitsPerSample, - channels: segmentPrivateInfos.channels, - codecPrivateData: segmentPrivateInfos.codecPrivateData, - packetSize: segmentPrivateInfos.packetSize, - samplingRate: segmentPrivateInfos.samplingRate, - timescale: index.timescale, - protection: segmentPrivateInfos.protection - }; - this._isAggressiveMode = aggressiveMode; - this._isLive = isLive; + /** + * @constructor + * @param {string} bufferType + * @param {string} codec + * @param {SourceBuffer} sourceBuffer + */ + function AudioVideoSegmentBuffer(bufferType, codec, mediaSource) { + var _this; - if (index.timeline.length !== 0) { - var lastItem = index.timeline[index.timeline.length - 1]; - var scaledEnd = (0,index_helpers/* getIndexSegmentEnd */.jH)(lastItem, null); - this._initialScaledLastPosition = scaledEnd; + _this = _SegmentBuffer.call(this) || this; + var sourceBuffer = mediaSource.addSourceBuffer(codec); + _this._destroy$ = new Subject/* Subject */.xQ(); + _this.bufferType = bufferType; + _this._mediaSource = mediaSource; + _this._sourceBuffer = sourceBuffer; + _this._queue = []; + _this._pendingTask = null; + _this._lastInitSegment = null; + _this.codec = codec; // Some browsers (happened with firefox 66) sometimes "forget" to send us + // `update` or `updateend` events. + // In that case, we're completely unable to continue the queue here and + // stay locked in a waiting state. + // This interval is here to check at regular intervals if the underlying + // SourceBuffer is currently updating. - if (index.isLive) { - var scaledReceivedTime = estimatedReceivedTime / 1000 * index.timescale; - this._scaledLiveGap = scaledReceivedTime - scaledEnd; - } - } + (0,observable_interval/* interval */.F)(SOURCE_BUFFER_FLUSHING_INTERVAL).pipe((0,tap/* tap */.b)(function () { + return _this._flush(); + }), (0,takeUntil/* takeUntil */.R)(_this._destroy$)).subscribe(); + (0,fromEvent/* fromEvent */.R)(_this._sourceBuffer, "error").pipe((0,tap/* tap */.b)(function (err) { + return _this._onPendingTaskError(err); + }), (0,takeUntil/* takeUntil */.R)(_this._destroy$)).subscribe(); + (0,fromEvent/* fromEvent */.R)(_this._sourceBuffer, "updateend").pipe((0,tap/* tap */.b)(function () { + return _this._flush(); + }), (0,takeUntil/* takeUntil */.R)(_this._destroy$)).subscribe(); + return _this; } /** - * Construct init Segment compatible with a Smooth Manifest. - * @returns {Object} + * Push a chunk of the media segment given to the attached SourceBuffer, in a + * FIFO queue. + * + * Once all chunks of a single Segment have been given to `pushChunk`, you + * should call `endOfSegment` to indicate that the whole Segment has been + * pushed. + * + * Depending on the type of data appended, the pushed chunk might rely on an + * initialization segment, given through the `data.initSegment` property. + * + * Such initialization segment will be first pushed to the SourceBuffer if the + * last pushed segment was associated to another initialization segment. + * This detection rely on the initialization segment's reference so you need + * to avoid mutating in-place a initialization segment given to that function + * (to avoid having two different values which have the same reference). + * + * If you don't need any initialization segment to push the wanted chunk, you + * can just set `data.initSegment` to `null`. + * + * You can also only push an initialization segment by setting the + * `data.chunk` argument to null. + * + * @param {Object} infos + * @returns {Observable} */ - var _proto = SmoothRepresentationIndex.prototype; + var _proto = AudioVideoSegmentBuffer.prototype; - _proto.getInitSegment = function getInitSegment() { - return { - id: "init", - isInit: true, - privateInfos: { - smoothInitSegment: this._initSegmentInfos - }, - mediaURLs: null, - time: 0, - end: 0, - duration: 0, - timescale: 1 - }; + _proto.pushChunk = function pushChunk(infos) { + log/* default.debug */.Z.debug("AVSB: receiving order to push data to the SourceBuffer", this.bufferType, infos); + return this._addToQueue({ + type: types/* SegmentBufferOperation.Push */.f.Push, + value: infos + }); } /** - * Generate a list of Segments for a particular period of time. - * - * @param {Number} _up - * @param {Number} _to - * @returns {Array.} + * Remove buffered data (added to the same FIFO queue than `pushChunk`). + * @param {number} start - start position, in seconds + * @param {number} end - end position, in seconds + * @returns {Observable} */ ; - _proto.getSegments = function getSegments(_up, _to) { - this._refreshTimeline(); - - var _normalizeRange = normalizeRange(this._index, _up, _to), - up = _normalizeRange.up, - to = _normalizeRange.to; + _proto.removeBuffer = function removeBuffer(start, end) { + log/* default.debug */.Z.debug("AVSB: receiving order to remove data from the SourceBuffer", this.bufferType, start, end); + return this._addToQueue({ + type: types/* SegmentBufferOperation.Remove */.f.Remove, + value: { + start: start, + end: end + } + }); + } + /** + * Indicate that every chunks from a Segment has been given to pushChunk so + * far. + * This will update our internal Segment inventory accordingly. + * The returned Observable will emit and complete successively once the whole + * segment has been pushed and this indication is acknowledged. + * @param {Object} infos + * @returns {Observable} + */ + ; - var _this$_index = this._index, - timeline = _this$_index.timeline, - timescale = _this$_index.timescale, - media = _this$_index.media; - var isAggressive = this._isAggressiveMode; - var currentNumber; - var segments = []; - var timelineLength = timeline.length; - var maxPosition = this._scaledLiveGap == null ? undefined : performance.now() / 1000 * timescale - this._scaledLiveGap; + _proto.endOfSegment = function endOfSegment(infos) { + log/* default.debug */.Z.debug("AVSB: receiving order for validating end of segment", this.bufferType, infos.segment); + return this._addToQueue({ + type: types/* SegmentBufferOperation.EndOfSegment */.f.EndOfSegment, + value: infos + }); + } + /** + * Returns the currently buffered data, in a TimeRanges object. + * @returns {TimeRanges} + */ + ; - for (var i = 0; i < timelineLength; i++) { - var segmentRange = timeline[i]; - var duration = segmentRange.duration, - start = segmentRange.start; - var repeat = calculateRepeat(segmentRange, timeline[i + 1]); - var segmentNumberInCurrentRange = getSegmentNumber(start, up, duration); - var segmentTime = start + segmentNumberInCurrentRange * duration; - var timeToAddToCheckMaxPosition = isAggressive ? 0 : duration; + _proto.getBufferedRanges = function getBufferedRanges() { + return this._sourceBuffer.buffered; + } + /** + * Returns the list of every operations that the `AudioVideoSegmentBuffer` is + * still processing. From the one with the highest priority (like the one + * being processed) + * @returns {Array.} + */ + ; - while (segmentTime < to && segmentNumberInCurrentRange <= repeat && (maxPosition == null || segmentTime + timeToAddToCheckMaxPosition <= maxPosition)) { - var time = segmentTime; - var number = currentNumber != null ? currentNumber + segmentNumberInCurrentRange : undefined; - var segment = { - id: String(segmentTime), - isInit: false, - time: time / timescale, - end: (time + duration) / timescale, - duration: duration / timescale, - timescale: 1, - number: number, - mediaURLs: [replaceSegmentSmoothTokens(media, time)], - privateInfos: { - smoothMediaSegment: { - time: time, - duration: duration - } - } - }; - segments.push(segment); // update segment number and segment time for the next segment + _proto.getPendingOperations = function getPendingOperations() { + var parseQueuedOperation = function parseQueuedOperation(op) { + // Had to be written that way for TypeScrypt + switch (op.type) { + case types/* SegmentBufferOperation.Push */.f.Push: + return { + type: op.type, + value: op.value + }; - segmentNumberInCurrentRange++; - segmentTime = start + segmentNumberInCurrentRange * duration; - } + case types/* SegmentBufferOperation.Remove */.f.Remove: + return { + type: op.type, + value: op.value + }; - if (segmentTime >= to) { - // we reached ``to``, we're done - return segments; + case types/* SegmentBufferOperation.EndOfSegment */.f.EndOfSegment: + return { + type: op.type, + value: op.value + }; } + }; - if (currentNumber != null) { - currentNumber += repeat + 1; - } - } + var queued = this._queue.map(parseQueuedOperation); - return segments; + return this._pendingTask === null ? queued : [parseQueuedOperation(this._pendingTask)].concat(queued); } /** - * Returns true if, based on the arguments, the index should be refreshed. - * (If we should re-fetch the manifest) - * @param {Number} up - * @param {Number} to - * @returns {Boolean} + * Dispose of the resources used by this AudioVideoSegmentBuffer. + * + * /!\ You won't be able to use the AudioVideoSegmentBuffer after calling this + * function. + * @private */ ; - _proto.shouldRefresh = function shouldRefresh(up, to) { - this._refreshTimeline(); + _proto.dispose = function dispose() { + this._destroy$.next(); - if (!this._index.isLive) { - return false; - } + this._destroy$.complete(); - var _this$_index2 = this._index, - timeline = _this$_index2.timeline, - timescale = _this$_index2.timescale; - var lastSegmentInCurrentTimeline = timeline[timeline.length - 1]; + if (this._pendingTask !== null) { + this._pendingTask.subject.complete(); - if (lastSegmentInCurrentTimeline === undefined) { - return false; + this._pendingTask = null; } - var repeat = lastSegmentInCurrentTimeline.repeatCount; - var endOfLastSegmentInCurrentTimeline = lastSegmentInCurrentTimeline.start + (repeat + 1) * lastSegmentInCurrentTimeline.duration; + while (this._queue.length > 0) { + var nextElement = this._queue.shift(); - if (to * timescale < endOfLastSegmentInCurrentTimeline) { - return false; + if (nextElement !== undefined) { + nextElement.subject.complete(); + } } - if (up * timescale >= endOfLastSegmentInCurrentTimeline) { - return true; - } // ---- + if (this._mediaSource.readyState === "open") { + try { + this._sourceBuffer.abort(); + } catch (e) { + log/* default.warn */.Z.warn("AVSB: Failed to abort a " + this.bufferType + " SourceBuffer:", e); + } + } + } + /** + * Called when an error arised that made the current task fail. + * @param {Event} error + */ + ; + _proto._onPendingTaskError = function _onPendingTaskError(err) { + this._lastInitSegment = null; // initialize init segment as a security - var startOfLastSegmentInCurrentTimeline = lastSegmentInCurrentTimeline.start + repeat * lastSegmentInCurrentTimeline.duration; - return up * timescale > startOfLastSegmentInCurrentTimeline; + if (this._pendingTask !== null) { + var error = err instanceof Error ? err : new Error("An unknown error occured when doing operations " + "on the SourceBuffer"); + + this._pendingTask.subject.error(error); + } } /** - * Returns first position available in the index. + * When the returned observable is subscribed: + * 1. Add your operation to the queue. + * 2. Begin the queue if not pending. * - * @param {Object} index - * @returns {Number|null} + * Cancel queued operation on unsubscription. + * @private + * @param {Object} operation + * @returns {Observable} */ ; - _proto.getFirstPosition = function getFirstPosition() { - this._refreshTimeline(); + _proto._addToQueue = function _addToQueue(operation) { + var _this2 = this; - var index = this._index; + return new Observable/* Observable */.y(function (obs) { + var shouldRestartQueue = _this2._queue.length === 0 && _this2._pendingTask === null; + var subject = new Subject/* Subject */.xQ(); + var queueItem = (0,object_assign/* default */.Z)({ + subject: subject + }, operation); - if (index.timeline.length === 0) { - return null; - } + _this2._queue.push(queueItem); - return index.timeline[0].start / index.timescale; + var subscription = subject.subscribe(obs); + + if (shouldRestartQueue) { + _this2._flush(); + } + + return function () { + subscription.unsubscribe(); // Remove the corresponding element from the AudioVideoSegmentBuffer's + // queue. + // If the operation was a pending task, it should still continue to not + // let the AudioVideoSegmentBuffer in a weird state. + + var index = _this2._queue.indexOf(queueItem); + + if (index >= 0) { + _this2._queue.splice(index, 1); + } + }; + }); } /** - * Returns last position available in the index. - * @param {Object} index - * @returns {Number} + * Perform next task if one. + * @private */ ; - _proto.getLastPosition = function getLastPosition() { - this._refreshTimeline(); + _proto._flush = function _flush() { + if (this._sourceBuffer.updating) { + return; // still processing `this._pendingTask` + } - var index = this._index; + if (this._pendingTask !== null) { + var task = this._pendingTask; + + if (task.type !== types/* SegmentBufferOperation.Push */.f.Push || task.data.length === 0) { + // If we're here, we've finished processing the task + switch (task.type) { + case types/* SegmentBufferOperation.Push */.f.Push: + if (task.inventoryData !== null) { + this._segmentInventory.insertChunk(task.inventoryData); + } + + break; + + case types/* SegmentBufferOperation.EndOfSegment */.f.EndOfSegment: + this._segmentInventory.completeSegment(task.value); + + break; + + case types/* SegmentBufferOperation.Remove */.f.Remove: + this.synchronizeInventory(); + break; + + default: + (0,assert_unreachable/* default */.Z)(task); + } + + var subject = task.subject; + this._pendingTask = null; + subject.next(); + subject.complete(); + + this._flush(); // Go to next item in queue + + + return; + } + } else { + // if this._pendingTask is null, go to next item in queue + var nextItem = this._queue.shift(); + + if (nextItem === undefined) { + return; // we have nothing left to do + } else if (nextItem.type !== types/* SegmentBufferOperation.Push */.f.Push) { + this._pendingTask = nextItem; + } else { + var itemValue = nextItem.value; + var dataToPush; + + try { + dataToPush = this._preparePushOperation(itemValue.data); + } catch (e) { + this._pendingTask = (0,object_assign/* default */.Z)({ + data: [], + inventoryData: itemValue.inventoryInfos + }, nextItem); + var error = e instanceof Error ? e : new Error("An unknown error occured when preparing a push operation"); + this._lastInitSegment = null; // initialize init segment as a security + + nextItem.subject.error(error); + return; + } - if (this._scaledLiveGap == null) { - var lastTimelineElement = index.timeline[index.timeline.length - 1]; - return (0,index_helpers/* getIndexSegmentEnd */.jH)(lastTimelineElement, null) / index.timescale; + this._pendingTask = (0,object_assign/* default */.Z)({ + data: dataToPush, + inventoryData: itemValue.inventoryInfos + }, nextItem); + } } - for (var i = index.timeline.length - 1; i >= 0; i--) { - var timelineElt = index.timeline[i]; - var timescaledNow = performance.now() / 1000 * index.timescale; - var start = timelineElt.start, - duration = timelineElt.duration, - repeatCount = timelineElt.repeatCount; + try { + switch (this._pendingTask.type) { + case types/* SegmentBufferOperation.EndOfSegment */.f.EndOfSegment: + // nothing to do, we will just acknowledge the segment. + log/* default.debug */.Z.debug("AVSB: Acknowledging complete segment", this._pendingTask.value); - for (var j = repeatCount; j >= 0; j--) { - var end = start + duration * (j + 1); - var positionToReach = this._isAggressiveMode ? end - duration : end; + this._flush(); - if (positionToReach <= timescaledNow - this._scaledLiveGap) { - return end / index.timescale; - } - } - } + return; - return undefined; - } - /** - * @param {number} timeSec - * @returns {number|null} - */ - ; + case types/* SegmentBufferOperation.Push */.f.Push: + var segmentData = this._pendingTask.data.shift(); - _proto.checkDiscontinuity = function checkDiscontinuity(timeSec) { - this._refreshTimeline(); + if (segmentData === undefined) { + this._flush(); - return (0,index_helpers/* checkDiscontinuity */._j)(this._index, timeSec, undefined); - } - /** - * @returns {boolean} - */ - ; + return; + } - _proto.areSegmentsChronologicallyGenerated = function areSegmentsChronologicallyGenerated() { - return true; - }; + this._sourceBuffer.appendBuffer(segmentData); - _proto.isSegmentStillAvailable = function isSegmentStillAvailable(segment) { - if (segment.isInit) { - return true; - } + break; - this._refreshTimeline(); + case types/* SegmentBufferOperation.Remove */.f.Remove: + var _this$_pendingTask$va = this._pendingTask.value, + start = _this$_pendingTask$va.start, + end = _this$_pendingTask$va.end; + log/* default.debug */.Z.debug("AVSB: removing data from SourceBuffer", this.bufferType, start, end); - var _this$_index3 = this._index, - timeline = _this$_index3.timeline, - timescale = _this$_index3.timescale; - return (0,is_segment_still_available/* default */.Z)(segment, timeline, timescale, 0); - } - /** - * @param {Error} error - * @returns {Boolean} - */ - ; + this._sourceBuffer.remove(start, end); - _proto.canBeOutOfSyncError = function canBeOutOfSyncError(error) { - if (!this._isLive) { - return false; - } + break; - return error instanceof network_error/* default */.Z && (error.isHttpError(404) || error.isHttpError(412)); + default: + (0,assert_unreachable/* default */.Z)(this._pendingTask); + } + } catch (e) { + this._onPendingTaskError(e); + } } /** - * Replace this RepresentationIndex by a newly downloaded one. - * Check if the old index had more information about new segments and re-add - * them if that's the case. - * @param {Object} newIndex + * A push Operation might necessitate to mutate some `SourceBuffer` and/or + * `AudioVideoSegmentBuffer` properties and also might need to be divided into + * multiple segments to push (exemple: when first pushing the initialization + * data before the segment data). + * + * This method allows to "prepare" that push operation so that all is left is + * to push the returned segment data one after the other (from first to last). + * @param {Object} item + * @returns {Object} */ ; - _proto._replace = function _replace(newIndex) { - var oldTimeline = this._index.timeline; - var newTimeline = newIndex._index.timeline; - var oldTimescale = this._index.timescale; - var newTimescale = newIndex._index.timescale; - this._index = newIndex._index; - this._initialScaledLastPosition = newIndex._initialScaledLastPosition; - this._indexValidityTime = newIndex._indexValidityTime; - this._scaledLiveGap = newIndex._scaledLiveGap; - - if (oldTimeline.length === 0 || newTimeline.length === 0 || oldTimescale !== newTimescale) { - return; // don't take risk, if something is off, take the new one - } + _proto._preparePushOperation = function _preparePushOperation(data) { + // Push operation with both an init segment and a regular segment might + // need to be separated into two steps + var dataToPush = []; + var codec = data.codec, + timestampOffset = data.timestampOffset, + appendWindow = data.appendWindow; + var hasUpdatedSourceBufferType = false; - var lastOldTimelineElement = oldTimeline[oldTimeline.length - 1]; - var lastNewTimelineElement = newTimeline[newTimeline.length - 1]; - var newEnd = (0,index_helpers/* getIndexSegmentEnd */.jH)(lastNewTimelineElement, null); + if (codec !== this.codec) { + log/* default.debug */.Z.debug("AVSB: updating codec", codec); + hasUpdatedSourceBufferType = tryToChangeSourceBufferType(this._sourceBuffer, codec); - if ((0,index_helpers/* getIndexSegmentEnd */.jH)(lastOldTimelineElement, null) <= newEnd) { - return; + if (hasUpdatedSourceBufferType) { + this.codec = codec; + } else { + log/* default.debug */.Z.debug("AVSB: could not update codec", codec, this.codec); + } } - for (var i = 0; i < oldTimeline.length; i++) { - var oldTimelineRange = oldTimeline[i]; - var oldEnd = (0,index_helpers/* getIndexSegmentEnd */.jH)(oldTimelineRange, null); + if (this._sourceBuffer.timestampOffset !== timestampOffset) { + var newTimestampOffset = timestampOffset; + log/* default.debug */.Z.debug("AVSB: updating timestampOffset", this.bufferType, this._sourceBuffer.timestampOffset, newTimestampOffset); + this._sourceBuffer.timestampOffset = newTimestampOffset; + } - if (oldEnd === newEnd) { - // just add the supplementary segments - this._index.timeline = this._index.timeline.concat(oldTimeline.slice(i + 1)); - return; + if (appendWindow[0] === undefined) { + if (this._sourceBuffer.appendWindowStart > 0) { + this._sourceBuffer.appendWindowStart = 0; + } + } else if (appendWindow[0] !== this._sourceBuffer.appendWindowStart) { + if (appendWindow[0] >= this._sourceBuffer.appendWindowEnd) { + this._sourceBuffer.appendWindowEnd = appendWindow[0] + 1; } - if (oldEnd > newEnd) { - // adjust repeatCount + add supplementary segments - if (oldTimelineRange.duration !== lastNewTimelineElement.duration) { - return; - } - - var rangeDuration = newEnd - oldTimelineRange.start; - - if (rangeDuration === 0) { - log/* default.warn */.Z.warn("Smooth Parser: a discontinuity detected in the previous manifest" + " has been resolved."); - this._index.timeline = this._index.timeline.concat(oldTimeline.slice(i)); - return; - } - - if (rangeDuration < 0 || rangeDuration % oldTimelineRange.duration !== 0) { - return; - } - - var repeatWithOld = rangeDuration / oldTimelineRange.duration - 1; - var relativeRepeat = oldTimelineRange.repeatCount - repeatWithOld; - - if (relativeRepeat < 0) { - return; - } + this._sourceBuffer.appendWindowStart = appendWindow[0]; + } - lastNewTimelineElement.repeatCount += relativeRepeat; - var supplementarySegments = oldTimeline.slice(i + 1); - this._index.timeline = this._index.timeline.concat(supplementarySegments); - return; + if (appendWindow[1] === undefined) { + if (this._sourceBuffer.appendWindowEnd !== Infinity) { + this._sourceBuffer.appendWindowEnd = Infinity; } + } else if (appendWindow[1] !== this._sourceBuffer.appendWindowEnd) { + this._sourceBuffer.appendWindowEnd = appendWindow[1]; } - }; - _proto._update = function _update(newIndex) { - (0,update_segment_timeline/* default */.Z)(this._index.timeline, newIndex._index.timeline); - this._initialScaledLastPosition = newIndex._initialScaledLastPosition; - this._indexValidityTime = newIndex._indexValidityTime; - this._scaledLiveGap = newIndex._scaledLiveGap; - } - /** - * @returns {Boolean} - */ - ; + if (data.initSegment !== null && (hasUpdatedSourceBufferType || !this._isLastInitSegment(data.initSegment))) { + // Push initialization segment before the media segment + var segmentData = data.initSegment; + dataToPush.push(segmentData); + var initU8 = (0,byte_parsing/* toUint8Array */._f)(segmentData); + this._lastInitSegment = { + data: initU8, + hash: (0,hash_buffer/* default */.Z)(initU8) + }; + } - _proto.isFinished = function isFinished() { - return !this._isLive; + if (data.chunk !== null) { + dataToPush.push(data.chunk); + } + + return dataToPush; } /** - * @returns {Boolean} + * Return `true` if the given `segmentData` is the same segment than the last + * initialization segment pushed to the `AudioVideoSegmentBuffer`. + * @param {BufferSource} segmentData + * @returns {boolean} */ ; - _proto.isInitialized = function isInitialized() { - return true; - }; - - _proto._addSegments = function _addSegments(nextSegments, currentSegment) { - this._refreshTimeline(); - - for (var i = 0; i < nextSegments.length; i++) { - _addSegmentInfos(this._index, nextSegments[i], currentSegment); + _proto._isLastInitSegment = function _isLastInitSegment(segmentData) { + if (this._lastInitSegment === null) { + return false; } - } - /** - * Clean-up timeline to remove segment information which should not be - * available due to the timeshift window - */ - ; - _proto._refreshTimeline = function _refreshTimeline() { - // clean segments before time shift buffer depth - if (this._initialScaledLastPosition == null) { - return; + if (this._lastInitSegment.data === segmentData) { + return true; } - var index = this._index; - var timeShiftBufferDepth = index.timeShiftBufferDepth; - var timeSinceLastRealUpdate = (performance.now() - this._indexValidityTime) / 1000; - var lastPositionEstimate = timeSinceLastRealUpdate + this._initialScaledLastPosition / index.timescale; + var oldInit = this._lastInitSegment.data; - if (timeShiftBufferDepth != null) { - var minimumPosition = (lastPositionEstimate - timeShiftBufferDepth) * index.timescale; - (0,clear_timeline_from_position/* default */.Z)(index.timeline, minimumPosition); + if (oldInit.byteLength === segmentData.byteLength) { + var newInitU8 = (0,byte_parsing/* toUint8Array */._f)(segmentData); + + if ((0,hash_buffer/* default */.Z)(newInitU8) === this._lastInitSegment.hash && (0,are_arrays_of_numbers_equal/* default */.Z)(oldInit, newInitU8)) { + return true; + } } + + return false; }; - return SmoothRepresentationIndex; -}(); + return AudioVideoSegmentBuffer; +}(types/* SegmentBuffer */.C); -;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/utils/parseBoolean.ts +;// CONCATENATED MODULE: ./src/core/segment_buffers/implementations/audio_video/index.ts /** * Copyright 2015 CANAL+ Group * @@ -45755,20 +48480,8 @@ var SmoothRepresentationIndex = /*#__PURE__*/function () { * limitations under the License. */ -/** - * @param {*} parseBoolean - * @returns {Boolean} - */ -function parseBoolean(val) { - if (typeof val === "boolean") { - return val; - } else if (typeof val === "string") { - return val.toUpperCase() === "TRUE"; - } else { - return false; - } -} -;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/utils/reduceChildren.ts +/* harmony default export */ const audio_video = (AudioVideoSegmentBuffer); +;// CONCATENATED MODULE: ./src/core/segment_buffers/segment_buffers_store.ts /** * Copyright 2015 CANAL+ Group * @@ -45785,563 +48498,352 @@ function parseBoolean(val) { * limitations under the License. */ -/** - * Reduce implementation for the children of the given element. - * @param {Element} root - * @param {Function} fn - * @param {*} init - * @returns {*} - */ -function reduceChildren(root, fn, init) { - var node = root.firstElementChild; - var accumulator = init; - while (node !== null) { - accumulator = fn(accumulator, node.nodeName, node); - node = node.nextElementSibling; - } - return accumulator; -} -;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/create_parser.ts + + +var POSSIBLE_BUFFER_TYPES = ["audio", "video", "text", "image"]; /** - * Copyright 2015 CANAL+ Group + * Allows to easily create and dispose SegmentBuffers, which are interfaces to + * push and remove segments. * - * 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 + * Only one SegmentBuffer per type is allowed at the same time: * - * http://www.apache.org/licenses/LICENSE-2.0 + * - SegmentBuffers linked to a "native" media buffer (relying on a + * SourceBuffer: "audio" and "video" here) are reused if one is + * re-created. * - * 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. - */ - - - - - - - - - - - - - - - -/** - * Default value for the aggressive `mode`. - * In this mode, segments will be returned even if we're not sure those had time - * to be generated. - */ - -var DEFAULT_AGGRESSIVE_MODE = false; -var KNOWN_ADAPTATION_TYPES = ["audio", "video", "text", "image"]; -var DEFAULT_MIME_TYPES = { - audio: "audio/mp4", - video: "video/mp4", - text: "application/ttml+xml" -}; -var MIME_TYPES = { - AACL: "audio/mp4", - AVC1: "video/mp4", - H264: "video/mp4", - TTML: "application/ttml+xml+mp4" -}; -/** - * @param {Object|undefined} parserOptions - * @returns {Function} + * - SegmentBuffers for custom types (the other types of media) are aborted + * each time a new one of the same type is created. + * + * To be able to use a SegmentBuffer linked to a native media buffer, you + * will first need to create it, but also wait until the other one is either + * created or explicitely disabled through the `disableSegmentBuffer` method. + * The Observable returned by `waitForUsableBuffers` will emit when + * that is the case. + * + * @class SegmentBuffersStore */ -function createSmoothStreamingParser(parserOptions) { - if (parserOptions === void 0) { - parserOptions = {}; - } - - var referenceDateTime = parserOptions.referenceDateTime === undefined ? Date.UTC(1970, 0, 1, 0, 0, 0, 0) / 1000 : parserOptions.referenceDateTime; - var minRepresentationBitrate = parserOptions.minRepresentationBitrate === undefined ? 0 : parserOptions.minRepresentationBitrate; - var _parserOptions = parserOptions, - serverSyncInfos = _parserOptions.serverSyncInfos; - var serverTimeOffset = serverSyncInfos !== undefined ? serverSyncInfos.serverTimestamp - serverSyncInfos.clientTime : undefined; +var SegmentBuffersStore = /*#__PURE__*/function () { /** - * @param {Element} q - * @param {string} streamType - * @return {Object} + * @param {HTMLMediaElement} mediaElement + * @param {MediaSource} mediaSource + * @constructor */ - - function parseQualityLevel(q, streamType) { - var customAttributes = reduceChildren(q, function (acc, qName, qNode) { - if (qName === "CustomAttributes") { - acc.push.apply(acc, reduceChildren(qNode, function (cAttrs, cName, cNode) { - if (cName === "Attribute") { - var name = cNode.getAttribute("Name"); - var value = cNode.getAttribute("Value"); - - if (name !== null && value !== null) { - cAttrs.push(name + "=" + value); - } - } - - return cAttrs; - }, [])); - } - - return acc; - }, []); - /** - * @param {string} name - * @returns {string|undefined} - */ - - function getAttribute(name) { - var attr = q.getAttribute(name); - return attr == null ? undefined : attr; - } - - switch (streamType) { - case "audio": - { - var audiotag = getAttribute("AudioTag"); - var bitsPerSample = getAttribute("BitsPerSample"); - var channels = getAttribute("Channels"); - var codecPrivateData = getAttribute("CodecPrivateData"); - var fourCC = getAttribute("FourCC"); - var packetSize = getAttribute("PacketSize"); - var samplingRate = getAttribute("SamplingRate"); - var bitrateAttr = getAttribute("Bitrate"); - var bitrate = bitrateAttr === undefined ? 0 : isNaN(parseInt(bitrateAttr, 10)) ? 0 : parseInt(bitrateAttr, 10); - - if (fourCC !== undefined && MIME_TYPES[fourCC] === undefined || codecPrivateData === undefined) { - log/* default.warn */.Z.warn("Smooth parser: Unsupported audio codec. Ignoring quality level."); - return null; - } - - var codecs = getAudioCodecs(codecPrivateData, fourCC); - return { - audiotag: audiotag !== undefined ? parseInt(audiotag, 10) : audiotag, - bitrate: bitrate, - bitsPerSample: bitsPerSample !== undefined ? parseInt(bitsPerSample, 10) : bitsPerSample, - channels: channels !== undefined ? parseInt(channels, 10) : channels, - codecPrivateData: codecPrivateData, - codecs: codecs, - customAttributes: customAttributes, - mimeType: fourCC !== undefined ? MIME_TYPES[fourCC] : fourCC, - packetSize: packetSize !== undefined ? parseInt(packetSize, 10) : packetSize, - samplingRate: samplingRate !== undefined ? parseInt(samplingRate, 10) : samplingRate - }; - } - - case "video": - { - var _codecPrivateData = getAttribute("CodecPrivateData"); - - var _fourCC = getAttribute("FourCC"); - - var width = getAttribute("MaxWidth"); - var height = getAttribute("MaxHeight"); - - var _bitrateAttr = getAttribute("Bitrate"); - - var _bitrate = _bitrateAttr === undefined ? 0 : isNaN(parseInt(_bitrateAttr, 10)) ? 0 : parseInt(_bitrateAttr, 10); - - if (_fourCC !== undefined && MIME_TYPES[_fourCC] === undefined || _codecPrivateData === undefined) { - log/* default.warn */.Z.warn("Smooth parser: Unsupported video codec. Ignoring quality level."); - return null; - } - - var _codecs = getVideoCodecs(_codecPrivateData); - - return { - bitrate: _bitrate, - customAttributes: customAttributes, - mimeType: _fourCC !== undefined ? MIME_TYPES[_fourCC] : _fourCC, - codecPrivateData: _codecPrivateData, - codecs: _codecs, - width: width !== undefined ? parseInt(width, 10) : undefined, - height: height !== undefined ? parseInt(height, 10) : undefined - }; - } - - case "text": - { - var _codecPrivateData2 = getAttribute("CodecPrivateData"); - - var _fourCC2 = getAttribute("FourCC"); - - var _bitrateAttr2 = getAttribute("Bitrate"); - - var _bitrate2 = _bitrateAttr2 === undefined ? 0 : isNaN(parseInt(_bitrateAttr2, 10)) ? 0 : parseInt(_bitrateAttr2, 10); - - return { - bitrate: _bitrate2, - customAttributes: customAttributes, - mimeType: _fourCC2 !== undefined ? MIME_TYPES[_fourCC2] : _fourCC2, - codecPrivateData: (0,take_first_set/* default */.Z)(_codecPrivateData2, "") - }; - } - - default: - log/* default.error */.Z.error("Smooth Parser: Unrecognized StreamIndex type: " + streamType); - return null; - } + function SegmentBuffersStore(mediaElement, mediaSource) { + this._mediaElement = mediaElement; + this._mediaSource = mediaSource; + this._initializedSegmentBuffers = {}; + this._onNativeBufferAddedOrDisabled = []; } /** - * Parse the adaptations () tree containing - * representations () and timestamp indexes (). - * Indexes can be quite huge, and this function needs to - * to be optimized. - * @param {Object} args - * @returns {Object} + * Returns true if the type is linked to a "native" media buffer (i.e. relying + * on a SourceBuffer object, native to the browser). + * Native media buffers needed for the current content must all be created + * before the content begins to be played and cannot be disposed during + * playback. + * @param {string} bufferType + * @returns {Boolean} */ - function parseAdaptation(args) { - var root = args.root, - timescale = args.timescale, - rootURL = args.rootURL, - protections = args.protections, - timeShiftBufferDepth = args.timeShiftBufferDepth, - manifestReceivedTime = args.manifestReceivedTime, - isLive = args.isLive; - var timescaleAttr = root.getAttribute("Timescale"); + SegmentBuffersStore.isNative = function isNative(bufferType) { + return shouldHaveNativeBuffer(bufferType); + } + /** + * Get all currently available buffer types. + * /!\ This list can evolve at runtime depending on feature switching. + * @returns {Array.} + */ + ; - var _timescale = timescaleAttr === null ? timescale : isNaN(+timescaleAttr) ? timescale : +timescaleAttr; + var _proto = SegmentBuffersStore.prototype; - var typeAttribute = root.getAttribute("Type"); + _proto.getBufferTypes = function getBufferTypes() { + var bufferTypes = this.getNativeBufferTypes(); - if (typeAttribute === null) { - throw new Error("StreamIndex without type."); + if (features/* default.nativeTextTracksBuffer */.Z.nativeTextTracksBuffer != null || features/* default.htmlTextTracksBuffer */.Z.htmlTextTracksBuffer != null) { + bufferTypes.push("text"); } - if (!(0,array_includes/* default */.Z)(KNOWN_ADAPTATION_TYPES, typeAttribute)) { - log/* default.warn */.Z.warn("Smooth Parser: Unrecognized adaptation type:", typeAttribute); + if (features/* default.imageBuffer */.Z.imageBuffer != null) { + bufferTypes.push("image"); } - var adaptationType = typeAttribute; - var subType = root.getAttribute("Subtype"); - var language = root.getAttribute("Language"); - var baseURLAttr = root.getAttribute("Url"); - var baseURL = baseURLAttr === null ? "" : baseURLAttr; - - if (false) {} - - var _reduceChildren = reduceChildren(root, function (res, _name, node) { - switch (_name) { - case "QualityLevel": - var qualityLevel = parseQualityLevel(node, adaptationType); - - if (qualityLevel === null) { - return res; - } // filter out video qualityLevels with small bitrates - - - if (adaptationType !== "video" || qualityLevel.bitrate > minRepresentationBitrate) { - res.qualityLevels.push(qualityLevel); - } - - break; - - case "c": - res.cNodes.push(node); - break; - } + return bufferTypes; + } + /** + * Get all "native" buffer types that should be created before beginning to + * push contents. + * @returns {Array.} + */ + ; - return res; - }, { - qualityLevels: [], - cNodes: [] - }), - qualityLevels = _reduceChildren.qualityLevels, - cNodes = _reduceChildren.cNodes; + _proto.getNativeBufferTypes = function getNativeBufferTypes() { + return this._mediaElement.nodeName === "AUDIO" ? ["audio"] : ["video", "audio"]; + } + /** + * Returns the current "status" of the SegmentBuffer linked to the buffer + * type given. + * + * This function will return an object containing a key named `type` which + * can be equal to either one of those three value: + * + * - "initialized": A SegmentBuffer has been created for that type. + * You will in this case also have a second key, `value`, which will + * contain the related SegmentBuffer instance. + * Please note that you will need to wait until + * `this.waitForUsableBuffers()` has emitted before pushing segment + * data to a SegmentBuffer relying on a SourceBuffer. + * + * - "disabled": The SegmentBuffer has been explicitely disabled for this + * type. + * + * - "uninitialized": No action has yet been yet for that SegmentBuffer. + * + * @param {string} bufferType + * @returns {Object|null} + */ + ; - var index = { - timeline: parseCNodes(cNodes), - timescale: _timescale - }; // we assume that all qualityLevels have the same - // codec and mimeType + _proto.getStatus = function getStatus(bufferType) { + var initializedBuffer = this._initializedSegmentBuffers[bufferType]; + return initializedBuffer === undefined ? { + type: "uninitialized" + } : initializedBuffer === null ? { + type: "disabled" + } : { + type: "initialized", + value: initializedBuffer + }; + } + /** + * Native media buffers (audio and video) needed for playing the current + * content need to all be created (by creating SegmentBuffers linked to them) + * before any one can be used. + * + * This function will return an Observable emitting when any and all native + * SourceBuffers can be used. + * + * From https://w3c.github.io/media-source/#methods + * For example, a user agent may throw a QuotaExceededError + * exception if the media element has reached the HAVE_METADATA + * readyState. This can occur if the user agent's media engine + * does not support adding more tracks during playback. + * @return {Observable} + */ + ; - (0,assert/* default */.Z)(qualityLevels.length !== 0, "Adaptation should have at least one playable representation."); - var adaptationID = adaptationType + ((0,is_non_empty_string/* default */.Z)(language) ? "_" + language : ""); - var representations = qualityLevels.map(function (qualityLevel) { - var path = (0,resolve_url/* default */.Z)(rootURL, baseURL); - var repIndex = { - timeline: index.timeline, - timescale: index.timescale, - media: replaceRepresentationSmoothTokens(path, qualityLevel.bitrate, qualityLevel.customAttributes), - isLive: isLive, - timeShiftBufferDepth: timeShiftBufferDepth, - manifestReceivedTime: manifestReceivedTime - }; - var mimeType = (0,is_non_empty_string/* default */.Z)(qualityLevel.mimeType) ? qualityLevel.mimeType : DEFAULT_MIME_TYPES[adaptationType]; - var codecs = qualityLevel.codecs; - var id = adaptationID + "_" + (adaptationType != null ? adaptationType + "-" : "") + (mimeType != null ? mimeType + "-" : "") + (codecs != null ? codecs + "-" : "") + String(qualityLevel.bitrate); - var keyIDs = []; - var firstProtection; + _proto.waitForUsableBuffers = function waitForUsableBuffers() { + var _this = this; - if (protections.length > 0) { - firstProtection = protections[0]; - protections.forEach(function (protection) { - var keyId = protection.keyId; - protection.keySystems.forEach(function (keySystem) { - keyIDs.push({ - keyId: keyId, - systemId: keySystem.systemId - }); - }); - }); - } + if (this._areNativeBuffersUsable()) { + return (0,of.of)(undefined); + } - var segmentPrivateInfos = { - bitsPerSample: qualityLevel.bitsPerSample, - channels: qualityLevel.channels, - codecPrivateData: qualityLevel.codecPrivateData, - packetSize: qualityLevel.packetSize, - samplingRate: qualityLevel.samplingRate, - // TODO set multiple protections here - // instead of the first one - protection: firstProtection != null ? { - keyId: firstProtection.keyId, - keySystems: firstProtection.keySystems - } : undefined - }; - var aggressiveMode = parserOptions.aggressiveMode == null ? DEFAULT_AGGRESSIVE_MODE : parserOptions.aggressiveMode; - var reprIndex = new SmoothRepresentationIndex(repIndex, { - aggressiveMode: aggressiveMode, - isLive: isLive, - segmentPrivateInfos: segmentPrivateInfos - }); - var representation = (0,object_assign/* default */.Z)({}, qualityLevel, { - index: reprIndex, - mimeType: mimeType, - codecs: codecs, - id: id + return new Observable/* Observable */.y(function (obs) { + _this._onNativeBufferAddedOrDisabled.push(function () { + if (_this._areNativeBuffersUsable()) { + obs.next(undefined); + obs.complete(); + } }); + }); + } + /** + * Explicitely disable the SegmentBuffer for a given buffer type. + * A call to this function is needed at least for unused native buffer types + * (usually "audio" and "video"), to be able to emit through + * `waitForUsableBuffers` when conditions are met. + * @param {string} + */ + ; - if (keyIDs.length > 0) { - representation.contentProtections = { - keyIds: keyIDs, - initData: {} - }; - } - - return representation; - }); // TODO(pierre): real ad-insert support + _proto.disableSegmentBuffer = function disableSegmentBuffer(bufferType) { + var currentValue = this._initializedSegmentBuffers[bufferType]; - if (subType === "ADVT") { - return null; + if (currentValue === null) { + log/* default.warn */.Z.warn("SBS: The " + bufferType + " SegmentBuffer was already disabled."); + return; } - var parsedAdaptation = { - id: adaptationID, - type: adaptationType, - representations: representations, - language: language == null ? undefined : language - }; - - if (adaptationType === "text" && subType === "DESC") { - parsedAdaptation.closedCaption = true; + if (currentValue !== undefined) { + throw new Error("Cannot disable an active SegmentBuffer."); } - return parsedAdaptation; - } - - function parseFromDocument(doc, url, manifestReceivedTime) { - var rootURL = (0,resolve_url/* normalizeBaseURL */.f)(url == null ? "" : url); - var root = doc.documentElement; + this._initializedSegmentBuffers[bufferType] = null; - if (root == null || root.nodeName !== "SmoothStreamingMedia") { - throw new Error("document root should be SmoothStreamingMedia"); + if (SegmentBuffersStore.isNative(bufferType)) { + this._onNativeBufferAddedOrDisabled.forEach(function (cb) { + return cb(); + }); } + } + /** + * Creates a new SegmentBuffer associated to a type. + * Reuse an already created one if a SegmentBuffer for the given type + * already exists. + * + * Please note that you will need to wait until `this.waitForUsableBuffers()` + * has emitted before pushing segment data to a SegmentBuffer of a native + * type. + * @param {string} bufferType + * @param {string} codec + * @param {Object|undefined} options + * @returns {Object} + */ + ; - var majorVersionAttr = root.getAttribute("MajorVersion"); - var minorVersionAttr = root.getAttribute("MinorVersion"); - - if (majorVersionAttr === null || minorVersionAttr === null || !/^[2]-[0-2]$/.test(majorVersionAttr + "-" + minorVersionAttr)) { - throw new Error("Version should be 2.0, 2.1 or 2.2"); + _proto.createSegmentBuffer = function createSegmentBuffer(bufferType, codec, options) { + if (options === void 0) { + options = {}; } - var timescaleAttr = root.getAttribute("Timescale"); - var timescale = !(0,is_non_empty_string/* default */.Z)(timescaleAttr) ? 10000000 : isNaN(+timescaleAttr) ? 10000000 : +timescaleAttr; + var memorizedSegmentBuffer = this._initializedSegmentBuffers[bufferType]; - var _reduceChildren2 = reduceChildren(root, function (res, name, node) { - switch (name) { - case "Protection": - { - res.protections.push(parseProtectionNode(node, parserOptions.keySystems)); - break; - } + if (shouldHaveNativeBuffer(bufferType)) { + if (memorizedSegmentBuffer != null) { + if (memorizedSegmentBuffer instanceof audio_video && memorizedSegmentBuffer.codec !== codec) { + log/* default.warn */.Z.warn("SB: Reusing native SegmentBuffer with codec", memorizedSegmentBuffer.codec, "for codec", codec); + } else { + log/* default.info */.Z.info("SB: Reusing native SegmentBuffer with codec", codec); + } - case "StreamIndex": - res.adaptationNodes.push(node); - break; + return memorizedSegmentBuffer; } - return res; - }, { - adaptationNodes: [], - protections: [] - }), - protections = _reduceChildren2.protections, - adaptationNodes = _reduceChildren2.adaptationNodes; + log/* default.info */.Z.info("SB: Adding native SegmentBuffer with codec", codec); + var nativeSegmentBuffer = new audio_video(bufferType, codec, this._mediaSource); + this._initializedSegmentBuffers[bufferType] = nativeSegmentBuffer; - var initialAdaptations = {}; - var isLive = parseBoolean(root.getAttribute("IsLive")); - var timeShiftBufferDepth; + this._onNativeBufferAddedOrDisabled.forEach(function (cb) { + return cb(); + }); - if (isLive) { - var dvrWindowLength = root.getAttribute("DVRWindowLength"); + return nativeSegmentBuffer; + } - if (dvrWindowLength != null && !isNaN(+dvrWindowLength) && +dvrWindowLength !== 0) { - timeShiftBufferDepth = +dvrWindowLength / timescale; - } + if (memorizedSegmentBuffer != null) { + log/* default.info */.Z.info("SB: Reusing a previous custom SegmentBuffer for the type", bufferType); + return memorizedSegmentBuffer; } - var adaptations = adaptationNodes.reduce(function (acc, node) { - var adaptation = parseAdaptation({ - root: node, - rootURL: rootURL, - timescale: timescale, - protections: protections, - isLive: isLive, - timeShiftBufferDepth: timeShiftBufferDepth, - manifestReceivedTime: manifestReceivedTime - }); + var segmentBuffer; - if (adaptation === null) { - return acc; - } + if (bufferType === "text") { + log/* default.info */.Z.info("SB: Creating a new text SegmentBuffer"); - var type = adaptation.type; - var adaps = acc[type]; + if (options.textTrackMode === "html") { + if (features/* default.htmlTextTracksBuffer */.Z.htmlTextTracksBuffer == null) { + throw new Error("HTML Text track feature not activated"); + } - if (adaps === undefined) { - acc[type] = [adaptation]; + segmentBuffer = new features/* default.htmlTextTracksBuffer */.Z.htmlTextTracksBuffer(this._mediaElement, options.textTrackElement); } else { - adaps.push(adaptation); - } - - return acc; - }, initialAdaptations); - var suggestedPresentationDelay; - var availabilityStartTime; - var minimumTime; - var timeshiftDepth = null; - var maximumTimeData; - var firstVideoAdaptation = adaptations.video !== undefined ? adaptations.video[0] : undefined; - var firstAudioAdaptation = adaptations.audio !== undefined ? adaptations.audio[0] : undefined; - var firstTimeReference; - var lastTimeReference; - - if (firstVideoAdaptation !== undefined || firstAudioAdaptation !== undefined) { - var firstTimeReferences = []; - var lastTimeReferences = []; + if (features/* default.nativeTextTracksBuffer */.Z.nativeTextTracksBuffer == null) { + throw new Error("Native Text track feature not activated"); + } - if (firstVideoAdaptation !== undefined) { - var firstVideoRepresentation = firstVideoAdaptation.representations[0]; + segmentBuffer = new features/* default.nativeTextTracksBuffer */.Z.nativeTextTracksBuffer(this._mediaElement, options.hideNativeSubtitle === true); + } - if (firstVideoRepresentation !== undefined) { - var firstVideoTimeReference = firstVideoRepresentation.index.getFirstPosition(); - var lastVideoTimeReference = firstVideoRepresentation.index.getLastPosition(); + this._initializedSegmentBuffers.text = segmentBuffer; + return segmentBuffer; + } else if (bufferType === "image") { + if (features/* default.imageBuffer */.Z.imageBuffer == null) { + throw new Error("Image buffer feature not activated"); + } - if (firstVideoTimeReference != null) { - firstTimeReferences.push(firstVideoTimeReference); - } + log/* default.info */.Z.info("SB: Creating a new image SegmentBuffer"); + segmentBuffer = new features/* default.imageBuffer */.Z.imageBuffer(); + this._initializedSegmentBuffers.image = segmentBuffer; + return segmentBuffer; + } - if (lastVideoTimeReference != null) { - lastTimeReferences.push(lastVideoTimeReference); - } - } - } + log/* default.error */.Z.error("SB: Unknown buffer type:", bufferType); + throw new media_error/* default */.Z("BUFFER_TYPE_UNKNOWN", "The player wants to create a SegmentBuffer " + "of an unknown type."); + } + /** + * Dispose of the active SegmentBuffer for the given type. + * @param {string} bufferType + */ + ; - if (firstAudioAdaptation !== undefined) { - var firstAudioRepresentation = firstAudioAdaptation.representations[0]; + _proto.disposeSegmentBuffer = function disposeSegmentBuffer(bufferType) { + var memorizedSegmentBuffer = this._initializedSegmentBuffers[bufferType]; - if (firstAudioRepresentation !== undefined) { - var firstAudioTimeReference = firstAudioRepresentation.index.getFirstPosition(); - var lastAudioTimeReference = firstAudioRepresentation.index.getLastPosition(); + if (memorizedSegmentBuffer == null) { + log/* default.warn */.Z.warn("SB: Trying to dispose a SegmentBuffer that does not exist"); + return; + } - if (firstAudioTimeReference != null) { - firstTimeReferences.push(firstAudioTimeReference); - } + log/* default.info */.Z.info("SB: Aborting SegmentBuffer", bufferType); + memorizedSegmentBuffer.dispose(); + delete this._initializedSegmentBuffers[bufferType]; + } + /** + * Dispose of all SegmentBuffer created on this SegmentBuffersStore. + */ + ; - if (lastAudioTimeReference != null) { - lastTimeReferences.push(lastAudioTimeReference); - } - } - } + _proto.disposeAll = function disposeAll() { + var _this2 = this; - if (firstTimeReferences.length > 0) { - firstTimeReference = Math.max.apply(Math, firstTimeReferences); + POSSIBLE_BUFFER_TYPES.forEach(function (bufferType) { + if (_this2.getStatus(bufferType).type === "initialized") { + _this2.disposeSegmentBuffer(bufferType); } + }); + } + /** + * Returns `true` when we're ready to push and decode contents to + * SourceBuffers created by SegmentBuffers of a native buffer type. + */ + ; - if (lastTimeReferences.length > 0) { - lastTimeReference = Math.min.apply(Math, lastTimeReferences); - } - } + _proto._areNativeBuffersUsable = function _areNativeBuffersUsable() { + var _this3 = this; - var manifestDuration = root.getAttribute("Duration"); - var duration = manifestDuration != null && +manifestDuration !== 0 ? +manifestDuration / timescale : undefined; + var nativeBufferTypes = this.getNativeBufferTypes(); + var hasUnitializedBuffers = nativeBufferTypes.some(function (sbType) { + return _this3._initializedSegmentBuffers[sbType] === undefined; + }); - if (isLive) { - suggestedPresentationDelay = parserOptions.suggestedPresentationDelay; - availabilityStartTime = referenceDateTime; - minimumTime = firstTimeReference !== null && firstTimeReference !== void 0 ? firstTimeReference : availabilityStartTime; - var maximumTime = lastTimeReference != null ? lastTimeReference : Date.now() / 1000 - availabilityStartTime; - maximumTimeData = { - isLinear: true, - value: maximumTime, - time: performance.now() - }; - timeshiftDepth = timeShiftBufferDepth !== null && timeShiftBufferDepth !== void 0 ? timeShiftBufferDepth : null; - } else { - minimumTime = firstTimeReference !== null && firstTimeReference !== void 0 ? firstTimeReference : 0; + if (hasUnitializedBuffers) { + // one is not yet initialized/disabled + return false; + } - var _maximumTime = lastTimeReference !== undefined ? lastTimeReference : duration !== undefined ? minimumTime + duration : Infinity; + var areAllDisabled = nativeBufferTypes.every(function (sbType) { + return _this3._initializedSegmentBuffers[sbType] === null; + }); - maximumTimeData = { - isLinear: false, - value: _maximumTime, - time: performance.now() - }; + if (areAllDisabled) { + // they all are disabled: we can't play the content + return false; } - var periodStart = isLive ? 0 : minimumTime; - var periodEnd = isLive ? undefined : maximumTimeData.value; - var manifest = { - availabilityStartTime: availabilityStartTime === undefined ? 0 : availabilityStartTime, - clockOffset: serverTimeOffset, - isLive: isLive, - isDynamic: isLive, - timeBounds: { - absoluteMinimumTime: minimumTime, - timeshiftDepth: timeshiftDepth, - maximumTimeData: maximumTimeData - }, - periods: [{ - adaptations: adaptations, - duration: periodEnd !== undefined ? periodEnd - periodStart : duration, - end: periodEnd, - id: "gen-smooth-period-0", - start: periodStart - }], - suggestedPresentationDelay: suggestedPresentationDelay, - transportType: "smooth", - uris: url == null ? [] : [url] - }; - checkManifestIDs(manifest); - return manifest; - } + return true; + }; + + return SegmentBuffersStore; +}(); +/** + * Returns true if the given buffeType has a linked SourceBuffer implementation, + * false otherwise. + * SourceBuffers are directly added to the MediaSource. + * @param {string} bufferType + * @returns {Boolean} + */ - return parseFromDocument; -} -/* harmony default export */ const create_parser = (createSmoothStreamingParser); -;// CONCATENATED MODULE: ./src/parsers/manifest/smooth/index.ts + + +function shouldHaveNativeBuffer(bufferType) { + return bufferType === "audio" || bufferType === "video"; +} +;// CONCATENATED MODULE: ./src/core/segment_buffers/index.ts /** * Copyright 2015 CANAL+ Group * @@ -46359,23 +48861,10 @@ function createSmoothStreamingParser(parserOptions) { */ -/* harmony default export */ const smooth = (create_parser); -// EXTERNAL MODULE: ./src/utils/request/index.ts + 1 modules -var request = __webpack_require__(4597); -// EXTERNAL MODULE: ./src/utils/warn_once.ts -var warn_once = __webpack_require__(8806); -// EXTERNAL MODULE: ./src/transports/utils/check_isobmff_integrity.ts -var check_isobmff_integrity = __webpack_require__(4460); -// EXTERNAL MODULE: ./src/transports/utils/return_parsed_manifest.ts -var return_parsed_manifest = __webpack_require__(7445); -// EXTERNAL MODULE: ./src/transports/utils/text_manifest_loader.ts + 1 modules -var text_manifest_loader = __webpack_require__(7278); -// EXTERNAL MODULE: ./src/parsers/containers/isobmff/utils.ts -var utils = __webpack_require__(4644); -// EXTERNAL MODULE: ./src/parsers/containers/isobmff/get_box.ts -var get_box = __webpack_require__(2297); -;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/parse_tfrf.ts +/* harmony default export */ const segment_buffers = (SegmentBuffersStore); + +;// CONCATENATED MODULE: ./src/utils/sorted_list.ts /** * Copyright 2015 CANAL+ Group * @@ -46394,182 +48883,201 @@ var get_box = __webpack_require__(2297); /** - * @param {Uint8Array} traf - * @returns {Array.} + * Creates an Array automatically sorted with the sorting function given to the + * constructor when the add method is called. + * + * @example + * ```js + * const sortedList = new SortedList((a, b) => a.start - b.start); + * const element1 = { start: 20 }; + * const element2 = { start: 10 }; + * const element3 = { start: 15 }; + * + * sortedList.add(element1, element2); + * console.log(sortedList.unwrap()); + * // -> [{ start: 10 }, { start : 20 }] + * + * sortedList.add(element3); + * console.log(sortedList.unwrap()); + * // -> [{ start: 10 }, { start : 15 }, { start: 20 }] + * + * sortedList.removeElement(element2); + * // -> [{ start: 10 }, { start: 15 }] + * ``` + * @class SortedList */ -function parseTfrf(traf) { - var tfrf = (0,get_box/* getUuidContent */.nR)(traf, 0xD4807EF2, 0xCA394695, 0x8E5426CB, 0x9E46A79F); - - if (tfrf === undefined) { - return []; +var SortedList = /*#__PURE__*/function () { + /** + * @param {Function} sortingFunction + */ + function SortedList(sortingFunction) { + this._array = []; + this._sortingFn = sortingFunction; } + /** + * Add a new element to the List at the right place for the List to stay + * sorted. + * + * /!\ The added Element will share the same reference than the given + * argument, any mutation on your part can lead to an un-sorted SortedList. + * You can still re-force the sorting to happen by calling forceSort. + * @param {...*} elements + */ - var frags = []; - var version = tfrf[0]; - var fragCount = tfrf[4]; - for (var i = 0; i < fragCount; i++) { - var duration = void 0; - var time = void 0; + var _proto = SortedList.prototype; - if (version === 1) { - time = (0,byte_parsing/* be8toi */.pV)(tfrf, i * 16 + 5); - duration = (0,byte_parsing/* be8toi */.pV)(tfrf, i * 16 + 5 + 8); - } else { - time = (0,byte_parsing/* be4toi */.pX)(tfrf, i * 8 + 5); - duration = (0,byte_parsing/* be4toi */.pX)(tfrf, i * 8 + 5 + 4); + _proto.add = function add() { + for (var _len = arguments.length, elements = new Array(_len), _key = 0; _key < _len; _key++) { + elements[_key] = arguments[_key]; } - frags.push({ - time: time, - duration: duration - }); - } - - return frags; -} -;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/parse_tfxd.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. - */ + elements.sort(this._sortingFn); + var j = 0; + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + var inserted = false; -/** - * @param {Uint8Array} traf - * @returns {Object|undefined} - */ + while (!inserted && j < this._array.length) { + if (this._sortingFn(element, this._array[j]) < 0) { + this._array.splice(j, 0, element); -function parseTfxd(traf) { - var tfxd = (0,get_box/* getUuidContent */.nR)(traf, 0x6D1D9B05, 0x42D544E6, 0x80E2141D, 0xAFF757B2); + inserted = true; + } else { + j++; + } + } - if (tfxd === undefined) { - return undefined; + if (!inserted) { + this._array.push(element); + } + } } + /** + * Returns the current length of the list. + * @returns {number} + */ + ; - return { - duration: (0,byte_parsing/* be8toi */.pV)(tfxd, 12), - time: (0,byte_parsing/* be8toi */.pV)(tfxd, 4) - }; -} -;// CONCATENATED MODULE: ./src/transports/smooth/extract_timings_infos.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. - */ + _proto.length = function length() { + return this._array.length; + } + /** + * Returns the nth element. Throws if the index does not exist. + * + * /!\ The returned Element shares the same reference with what is used + * internally, any mutation on your part can lead to an un-sorted SortedList. + * You can still re-force the sorting to happen by calling forceSort. + * @throws Error - Throws if the given index is negative or superior to the + * array's length. + * @param {number} index + * @returns {*} + */ + ; + _proto.get = function get(index) { + if (index < 0 || index >= this._array.length) { + throw new Error("Invalid index."); + } + return this._array[index]; + } + /** + * Find the first element corresponding to the given predicate. + * + * /!\ The returned element shares the same reference with what is used + * internally, any mutation on your part can lead to an un-sorted SortedList. + * You can still re-force the sorting to happen by calling forceSort. + * @param {Function} fn + * @returns {*} + */ + ; -/** - * Try to obtain time information from the given data. - * @param {Uint8Array} data - * @param {boolean} isChunked - * @param {Object} segment - * @param {boolean} isLive - * @returns {Object} - */ + _proto.findFirst = function findFirst(fn) { + return (0,array_find/* default */.Z)(this._array, fn); + } + /** + * Returns true if the List contains the given element. + * @param {*} element + * @returns {Boolean} + */ + ; -function extractTimingsInfos(data, isChunked, initTimescale, segment, isLive) { - var _a; + _proto.has = function has(element) { + return (0,array_includes/* default */.Z)(this._array, element); + } + /** + * Remove the first occurence of the given element. + * Returns the index of the removed element. Undefined if not found. + * @returns {number|undefined} + */ + ; - var nextSegments = []; - var chunkInfos; - var tfxdSegment; - var tfrfSegments; + _proto.removeElement = function removeElement(element) { + var indexOf = this._array.indexOf(element); - if (isLive) { - var traf = (0,read/* getTRAF */.XA)(data); + if (indexOf >= 0) { + this._array.splice(indexOf, 1); - if (traf !== null) { - tfrfSegments = parseTfrf(traf); - tfxdSegment = parseTfxd(traf); - } else { - log/* default.warn */.Z.warn("smooth: could not find traf atom"); + return indexOf; } + + return undefined; } + /** + * Returns the first element. + * + * /!\ The returned Element shares the same reference with what is used + * internally, any mutation on your part can lead to an un-sorted SortedList. + * You can still re-force the sorting to happen by calling forceSort. + * @returns {*} + */ + ; - if (tfrfSegments !== undefined) { - for (var i = 0; i < tfrfSegments.length; i++) { - nextSegments.push({ - time: tfrfSegments[i].time, - duration: tfrfSegments[i].duration, - timescale: initTimescale - }); - } + _proto.head = function head() { + return this._array[0]; } + /** + * Returns the last element. + * + * /!\ The returned Element shares the same reference with what is used + * internally, any mutation on your part can lead to an un-sorted SortedList. + * You can still re-force the sorting to happen by calling forceSort. + * @returns {*} + */ + ; - if (tfxdSegment !== undefined) { - chunkInfos = { - time: tfxdSegment.time / initTimescale, - duration: tfxdSegment.duration / initTimescale - }; - return { - nextSegments: nextSegments, - chunkInfos: chunkInfos, - scaledSegmentTime: tfxdSegment.time - }; + _proto.last = function last() { + return this._array[this._array.length - 1]; } + /** + * Remove the first element. + * Returns the element removed or undefined if no element were removed. + * @returns {*} + */ + ; - if (isChunked) { - return { - nextSegments: nextSegments, - chunkInfos: null, - scaledSegmentTime: undefined - }; + _proto.shift = function shift() { + return this._array.shift(); } + /** + * Remove the last element. + * Returns the element removed or undefined if no element were removed. + * @returns {*} + */ + ; - var segmentDuration = segment.duration * initTimescale; // we could always make a mistake when reading a container. - // If the estimate is too far from what the segment seems to imply, take - // the segment infos instead. + _proto.pop = function pop() { + return this._array.pop(); + }; - var maxDecodeTimeDelta = Math.min(initTimescale * 0.9, segmentDuration / 4); - var trunDuration = (0,utils/* getDurationFromTrun */.MM)(data); - var scaledSegmentTime = ((_a = segment.privateInfos) === null || _a === void 0 ? void 0 : _a.smoothMediaSegment) !== undefined ? segment.privateInfos.smoothMediaSegment.time : Math.round(segment.time * initTimescale); + return SortedList; +}(); - if (trunDuration !== undefined && Math.abs(trunDuration - segmentDuration) <= maxDecodeTimeDelta) { - chunkInfos = { - time: segment.time, - duration: trunDuration / initTimescale - }; - } else { - chunkInfos = { - time: segment.time, - duration: segment.duration - }; - } - return { - nextSegments: nextSegments, - chunkInfos: chunkInfos, - scaledSegmentTime: scaledSegmentTime - }; -} -// EXTERNAL MODULE: ./src/compat/browser_detection.ts -var browser_detection = __webpack_require__(3666); -;// CONCATENATED MODULE: ./src/compat/can_patch_isobmff.ts +;// CONCATENATED MODULE: ./src/utils/weak_map_memory.ts /** * Copyright 2015 CANAL+ Group * @@ -46587,530 +49095,711 @@ var browser_detection = __webpack_require__(3666); */ /** - * TODO(pierre): fix patchSegmentInPlace to work with IE11. Maybe - * try to put free atom inside traf children - * - * Returns true if the current target is tolerant enough for us to - * simply be able to "patch" an ISOBMFF segment or if we have to create a - * new one from scratch instead. - * @returns {Boolean} - */ - -function canPatchISOBMFFSegment() { - return !browser_detection/* isIEOrEdge */.YM; -} -// EXTERNAL MODULE: ./src/parsers/containers/isobmff/constants.ts -var constants = __webpack_require__(2689); -;// CONCATENATED MODULE: ./src/parsers/containers/isobmff/create_box.ts -/** - * Copyright 2015 CANAL+ Group + * Memoize Function results linked to an object, through a WeakMap. * - * 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 + * @example + * ```js + * // Initialize the WeakMapMemory with its logic: + * const memory = new WeakMapMemory(arg => { + * console.log("side-effect"); + * return [arg.a, arg.b]; + * }); * - * http://www.apache.org/licenses/LICENSE-2.0 + * const obj = { a: 1, b: 2 }; * - * 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. - */ - - - -/** - * Speed up string to bytes conversion by memorizing the result + * // first time obj is given: call the function, save the result and return it: + * const arr1 = memory.get(obj); + * // > "side-effect" + * // <- [1, 2] * - * The keys here are ISOBMFF box names. The values are the corresponding - * bytes conversion for putting as an ISOBMFF boxes. + * // nth time obj is given, returns the saved result without calling the + * // function: + * const arr2 = memory.get(obj); + * // <- [1, 2] * - * Used by the boxName method. - * @type {Object} - */ - -var boxNamesMem = {}; -/** - * Convert the string name of an ISOBMFF box into the corresponding bytes. - * Has a memorization mechanism to speed-up if you want to translate the - * same string multiple times. - * @param {string} str - * @returns {Uint8Array} - */ - -function boxName(str) { - if (boxNamesMem[str] != null) { - return boxNamesMem[str]; - } - - var nameInBytes = (0,string_parsing/* strToUtf8 */.tG)(str); - boxNamesMem[str] = nameInBytes; - return nameInBytes; -} -/** - * Create a new ISOBMFF "box" with the given name. - * @param {string} name - name of the box you want to create, must always - * be 4 characters (uuid boxes not supported) - * @param {Uint8Array} buff - content of the box - * @returns {Uint8Array} - The entire ISOBMFF box (length+name+content) - */ - - -function createBox(name, buff) { - var len = buff.length + 8; - return len <= constants/* MAX_32_BIT_INT */.s ? (0,byte_parsing/* concat */.zo)((0,byte_parsing/* itobe4 */.kh)(len), boxName(name), buff) : (0,byte_parsing/* concat */.zo)((0,byte_parsing/* itobe4 */.kh)(1), boxName(name), (0,byte_parsing/* itobe8 */.el)(len + 8), buff); -} -/** - * @param {string} name - * @param {Array.} children - * @returns {Uint8Array} - */ - - -function createBoxWithChildren(name, children) { - return createBox(name, byte_parsing/* concat.apply */.zo.apply(void 0, children)); -} - - -;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/create_boxes.ts -/** - * Copyright 2015 CANAL+ Group + * // both of these use the same object, so the result is also the exact same + * // one + * console.log(arr1 === arr2); // => true * - * 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 + * // /!\ with a new object however: + * const obj2 = { a: 1, b: 2 }; * - * http://www.apache.org/licenses/LICENSE-2.0 + * const arr3 = memory.get(obj2); + * // > "side-effect" + * // <- [1, 2] * - * 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. + * console.log(arr1 === arr3); // => false + * ``` + * @class WeakMapMemory */ +// eslint-disable-next-line @typescript-eslint/ban-types +var WeakMapMemory = /*#__PURE__*/function () { + /** + * @param {Function} + */ + function WeakMapMemory(fn) { + this._weakMap = new WeakMap(); + this._fn = fn; + } + /** + * @param {Object} obj + * @returns {*} + */ + var _proto = WeakMapMemory.prototype; -/** - * @param {Number} width - * @param {Number} height - * @param {Number} hRes - horizontal resolution, eg 72 - * @param {Number} vRes - vertical resolution, eg 72 - * @param {string} encDepth - * @param {Number} colorDepth - eg 24 - * @param {Uint8Array} avcc - Uint8Array representing the avcC atom - * @returns {Uint8Array} - */ - -function createAVC1Box(width, height, hRes, vRes, encName, colorDepth, avcc) { - return createBox("avc1", (0,byte_parsing/* concat */.zo)(6, // 6 bytes reserved - (0,byte_parsing/* itobe2 */.XT)(1), 16, // drefIdx + QuickTime reserved, zeroes - (0,byte_parsing/* itobe2 */.XT)(width), // size 2 w - (0,byte_parsing/* itobe2 */.XT)(height), // size 2 h - (0,byte_parsing/* itobe2 */.XT)(hRes), 2, // reso 4 h - (0,byte_parsing/* itobe2 */.XT)(vRes), 2 + 4, // reso 4 v + QuickTime reserved, zeroes - [0, 1, encName.length], // frame count (default 1) - (0,string_parsing/* strToUtf8 */.tG)(encName), // 1byte len + encoder name str - 31 - encName.length, // + padding - (0,byte_parsing/* itobe2 */.XT)(colorDepth), // color depth - [0xFF, 0xFF], // reserved ones - avcc // avcc atom, - )); -} -/** - * @param {Number} width - * @param {Number} height - * @param {Number} hRes - horizontal resolution, eg 72 - * @param {Number} vRes - vertical resolution, eg 72 - * @param {string} encDepth - * @param {Number} colorDepth - eg 24 - * @param {Uint8Array} avcc - Uint8Array representing the avcC atom - * @param {Uint8Array} sinf - Uint8Array representing the sinf atom - * @returns {Uint8Array} - */ + _proto.get = function get(obj) { + var fromMemory = this._weakMap.get(obj); + if (fromMemory === undefined) { + var newElement = this._fn(obj); -function createENCVBox(width, height, hRes, vRes, encName, colorDepth, avcc, sinf) { - return createBox("encv", (0,byte_parsing/* concat */.zo)(6, // 6 bytes reserved - (0,byte_parsing/* itobe2 */.XT)(1), 16, // drefIdx + QuickTime reserved, zeroes - (0,byte_parsing/* itobe2 */.XT)(width), // size 2 w - (0,byte_parsing/* itobe2 */.XT)(height), // size 2 h - (0,byte_parsing/* itobe2 */.XT)(hRes), 2, // reso 4 h - (0,byte_parsing/* itobe2 */.XT)(vRes), 2 + 4, // reso 4 v + QuickTime reserved, zeroes - [0, 1, encName.length], // frame count (default 1) - (0,string_parsing/* strToUtf8 */.tG)(encName), // 1byte len + encoder name str - 31 - encName.length, // + padding - (0,byte_parsing/* itobe2 */.XT)(colorDepth), // color depth - [0xFF, 0xFF], // reserved ones - avcc, // avcc atom, - sinf)); -} -/** - * @param {Number} drefIdx - * @param {Number} channelsCount - * @param {Number} sampleSize - * @param {Number} packetSize - * @param {Number} sampleRate - * @param {Uint8Array} esds - Uint8Array representing the esds atom - * @param {Uint8Array} [sinf] - Uint8Array representing the sinf atom, - * only if name == "enca" - * @returns {Uint8Array} - */ + this._weakMap.set(obj, newElement); + + return newElement; + } else { + return fromMemory; + } + } + /** + * @param {Object} obj + */ + ; + _proto.destroy = function destroy(obj) { + this._weakMap["delete"](obj); + }; -function createMP4ABox(drefIdx, channelsCount, sampleSize, packetSize, sampleRate, esds) { - return createBox("mp4a", (0,byte_parsing/* concat */.zo)(6, (0,byte_parsing/* itobe2 */.XT)(drefIdx), 8, (0,byte_parsing/* itobe2 */.XT)(channelsCount), (0,byte_parsing/* itobe2 */.XT)(sampleSize), 2, (0,byte_parsing/* itobe2 */.XT)(packetSize), (0,byte_parsing/* itobe2 */.XT)(sampleRate), 2, esds)); -} -/** - * @param {Number} drefIdx - * @param {Number} channelsCount - * @param {Number} sampleSize - * @param {Number} packetSize - * @param {Number} sampleRate - * @param {Uint8Array} esds - Uint8Array representing the esds atom - * @param {Uint8Array} [sinf] - Uint8Array representing the sinf atom, - * only if name == "enca" - * @returns {Uint8Array} - */ + return WeakMapMemory; +}(); -function createENCABox(drefIdx, channelsCount, sampleSize, packetSize, sampleRate, esds, sinf) { - return createBox("enca", (0,byte_parsing/* concat */.zo)(6, (0,byte_parsing/* itobe2 */.XT)(drefIdx), 8, (0,byte_parsing/* itobe2 */.XT)(channelsCount), (0,byte_parsing/* itobe2 */.XT)(sampleSize), 2, (0,byte_parsing/* itobe2 */.XT)(packetSize), (0,byte_parsing/* itobe2 */.XT)(sampleRate), 2, esds, sinf)); -} +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/concatAll.js +var concatAll = __webpack_require__(2257); +;// CONCATENATED MODULE: ./src/core/segment_buffers/garbage_collector.ts /** - * @param {url} Uint8Array - * @returns {Uint8Array} + * 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 createDREFBox(url) { - // only one description here... FIXME - return createBox("dref", (0,byte_parsing/* concat */.zo)(7, [1], url)); -} -/** - * @param {string} majorBrand - * @param {Array.} brands - * @returns {Uint8Array} - */ -function createFTYPBox(majorBrand, brands) { - var content = byte_parsing/* concat.apply */.zo.apply(void 0, [(0,string_parsing/* strToUtf8 */.tG)(majorBrand), [0, 0, 0, 1]].concat(brands.map(string_parsing/* strToUtf8 */.tG))); - return createBox("ftyp", content); -} /** - * @param {string} schemeType - four letters (eg "cenc" for Common Encryption) - * @param {Number} schemeVersion - eg 65536 - * @returns {Uint8Array} + * Perform cleaning of the buffer according to the values set by the user + * at each clock tick and each times the maxBufferBehind/maxBufferAhead values + * change. + * + * @param {Object} opt + * @returns {Observable} */ - -function createSCHMBox(schemeType, schemeVersion) { - return createBox("schm", (0,byte_parsing/* concat */.zo)(4, (0,string_parsing/* strToUtf8 */.tG)(schemeType), (0,byte_parsing/* itobe4 */.kh)(schemeVersion))); +function BufferGarbageCollector(_ref) { + var segmentBuffer = _ref.segmentBuffer, + clock$ = _ref.clock$, + maxBufferBehind$ = _ref.maxBufferBehind$, + maxBufferAhead$ = _ref.maxBufferAhead$; + return (0,combineLatest/* combineLatest */.aj)([clock$, maxBufferBehind$, maxBufferAhead$]).pipe((0,mergeMap/* mergeMap */.zg)(function (_ref2) { + var currentTime = _ref2[0], + maxBufferBehind = _ref2[1], + maxBufferAhead = _ref2[2]; + return clearBuffer(segmentBuffer, currentTime, maxBufferBehind, maxBufferAhead); + })); } /** - * Create tfdt box from a decoding time. - * @param {number} decodeTime - * @returns {Uint8Array} + * Remove buffer from the browser's memory based on the user's + * maxBufferAhead / maxBufferBehind settings. + * + * Normally, the browser garbage-collect automatically old-added chunks of + * buffer data when memory is scarce. However, you might want to control + * the size of memory allocated. This function takes the current position + * and a "depth" behind and ahead wanted for the buffer, in seconds. + * + * Anything older than the depth will be removed from the buffer. + * @param {Object} segmentBuffer + * @param {Number} position - The current position + * @param {Number} maxBufferBehind + * @param {Number} maxBufferAhead + * @returns {Observable} */ +function clearBuffer(segmentBuffer, position, maxBufferBehind, maxBufferAhead) { + if (!isFinite(maxBufferBehind) && !isFinite(maxBufferAhead)) { + return empty/* EMPTY */.E; + } -function createTfdtBox(decodeTime) { - return createBox("tfdt", (0,byte_parsing/* concat */.zo)([1, 0, 0, 0], (0,byte_parsing/* itobe8 */.el)(decodeTime))); -} -/** - * @returns {Uint8Array} - */ + var cleanedupRanges = []; + var _getInnerAndOuterTime = (0,ranges/* getInnerAndOuterTimeRanges */.F_)(segmentBuffer.getBufferedRanges(), position), + innerRange = _getInnerAndOuterTime.innerRange, + outerRanges = _getInnerAndOuterTime.outerRanges; -function createVMHDBox() { - var arr = new Uint8Array(12); - arr[3] = 1; // QuickTime... + var collectBufferBehind = function collectBufferBehind() { + if (!isFinite(maxBufferBehind)) { + return; + } // begin from the oldest - return createBox("vmhd", arr); -} -/** - * @param {Number} trackId - * @returns {Uint8Array} - */ + for (var i = 0; i < outerRanges.length; i++) { + var outerRange = outerRanges[i]; -function createTREXBox(trackId) { - // default sample desc idx = 1 - return createBox("trex", (0,byte_parsing/* concat */.zo)(4, (0,byte_parsing/* itobe4 */.kh)(trackId), [0, 0, 0, 1], 12)); -} -/** - * @param {Number} length - * @returns {Uint8Array} - */ + if (position - maxBufferBehind >= outerRange.end) { + cleanedupRanges.push(outerRange); + } else if (position >= outerRange.end && position - maxBufferBehind > outerRange.start && position - maxBufferBehind < outerRange.end) { + cleanedupRanges.push({ + start: outerRange.start, + end: position - maxBufferBehind + }); + } + } + if (innerRange != null) { + if (position - maxBufferBehind > innerRange.start) { + cleanedupRanges.push({ + start: innerRange.start, + end: position - maxBufferBehind + }); + } + } + }; -function createFreeBox(length) { - return createBox("free", new Uint8Array(length - 8)); -} -/** - * @param {Number} stream - * @param {string} codecPrivateData - hex string - * @returns {Uint8Array} - */ + var collectBufferAhead = function collectBufferAhead() { + if (!isFinite(maxBufferAhead)) { + return; + } // begin from the oldest -function createESDSBox(stream, codecPrivateData) { - return createBox("esds", (0,byte_parsing/* concat */.zo)(4, [0x03, 0x19], (0,byte_parsing/* itobe2 */.XT)(stream), [0x00, 0x04, 0x11, 0x40, 0x15], 11, [0x05, 0x02], (0,string_parsing/* hexToBytes */.nr)(codecPrivateData), [0x06, 0x01, 0x02])); -} -/** - * @param {string} dataFormat - four letters (eg "avc1") - * @returns {Uint8Array} - */ + for (var i = 0; i < outerRanges.length; i++) { + var outerRange = outerRanges[i]; + if (position + maxBufferAhead <= outerRange.start) { + cleanedupRanges.push(outerRange); + } else if (position <= outerRange.start && position + maxBufferAhead < outerRange.end && position + maxBufferAhead > outerRange.start) { + cleanedupRanges.push({ + start: position + maxBufferAhead, + end: outerRange.end + }); + } + } -function createFRMABox(dataFormat) { - return createBox("frma", (0,string_parsing/* strToUtf8 */.tG)(dataFormat)); + if (innerRange != null) { + if (position + maxBufferAhead < innerRange.end) { + cleanedupRanges.push({ + start: position + maxBufferAhead, + end: innerRange.end + }); + } + } + }; + + collectBufferBehind(); + collectBufferAhead(); + var clean$ = (0,from/* from */.D)(cleanedupRanges.map(function (range) { + log/* default.debug */.Z.debug("GC: cleaning range from SegmentBuffer", range); + return segmentBuffer.removeBuffer(range.start, range.end); + })).pipe((0,concatAll/* concatAll */.u)(), (0,ignoreElements/* ignoreElements */.l)()); + return clean$; } +;// CONCATENATED MODULE: ./src/core/stream/events_generators.ts /** - * @param {Uint8Array} sps - * @param {Uint8Array} pps - * @param {Number} nalLen - NAL Unit length: 1, 2 or 4 bytes - * eg: avcc(0x4d, 0x40, 0x0d, 4, 0xe1, "674d400d96560c0efcb80a70505050a0", - * 1, "68ef3880") - * @returns {Uint8Array} + * 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 EVENTS = { + activePeriodChanged: function activePeriodChanged(period) { + return { + type: "activePeriodChanged", + value: { + period: period + } + }; + }, + adaptationChange: function adaptationChange(bufferType, adaptation, period) { + return { + type: "adaptationChange", + value: { + type: bufferType, + adaptation: adaptation, + period: period + } + }; + }, + addedSegment: function addedSegment(content, segment, buffered, segmentData) { + return { + type: "added-segment", + value: { + content: content, + segment: segment, + segmentData: segmentData, + buffered: buffered + } + }; + }, + bitrateEstimationChange: function bitrateEstimationChange(type, bitrate) { + return { + type: "bitrateEstimationChange", + value: { + type: type, + bitrate: bitrate + } + }; + }, + streamComplete: function streamComplete(bufferType) { + return { + type: "complete-stream", + value: { + type: bufferType + } + }; + }, + endOfStream: function endOfStream() { + return { + type: "end-of-stream", + value: undefined + }; + }, + needsManifestRefresh: function needsManifestRefresh() { + return { + type: "needs-manifest-refresh", + value: undefined + }; + }, + manifestMightBeOufOfSync: function manifestMightBeOufOfSync() { + return { + type: "manifest-might-be-out-of-sync", + value: undefined + }; + }, + /** + * @param {Object} period - The Period to which the stream logic asking for a + * media source reload is linked. + * @param {number} reloadAt - Position at which we should reload + * @param {boolean} reloadOnPause - If `false`, stay on pause after reloading. + * if `true`, automatically play once reloaded. + * @returns {Object} + */ + needsMediaSourceReload: function needsMediaSourceReload(period, reloadAt, reloadOnPause) { + return { + type: "needs-media-source-reload", + value: { + position: reloadAt, + autoPlay: reloadOnPause, + period: period + } + }; + }, + needsDecipherabilityFlush: function needsDecipherabilityFlush(position, autoPlay, duration) { + return { + type: "needs-decipherability-flush", + value: { + position: position, + autoPlay: autoPlay, + duration: duration + } + }; + }, + periodStreamReady: function periodStreamReady(type, period, adaptation$) { + return { + type: "periodStreamReady", + value: { + type: type, + period: period, + adaptation$: adaptation$ + } + }; + }, + periodStreamCleared: function periodStreamCleared(type, period) { + return { + type: "periodStreamCleared", + value: { + type: type, + period: period + } + }; + }, + encryptionDataEncountered: function encryptionDataEncountered(initDataInfo) { + return { + type: "encryption-data-encountered", + value: initDataInfo + }; + }, + representationChange: function representationChange(type, period, representation) { + return { + type: "representationChange", + value: { + type: type, + period: period, + representation: representation + } + }; + }, + streamTerminating: function streamTerminating() { + return { + type: "stream-terminating", + value: undefined + }; + }, + resumeStream: function resumeStream() { + return { + type: "resume-stream", + value: undefined + }; + }, + warning: function warning(value) { + return { + type: "warning", + value: value + }; + } +}; +/* harmony default export */ const stream_events_generators = (EVENTS); +// 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: ./node_modules/rxjs/_esm5/internal/operators/takeWhile.js +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function createAVCCBox(sps, pps, nalLen) { - var nal = nalLen === 2 ? 0x1 : nalLen === 4 ? 0x3 : 0x0; // Deduce AVC Profile from SPS - var h264Profile = sps[1]; - var h264CompatibleProfile = sps[2]; - var h264Level = sps[3]; - return createBox("avcC", (0,byte_parsing/* concat */.zo)([1, h264Profile, h264CompatibleProfile, h264Level, 0x3F << 2 | nal, 0xE0 | 1], (0,byte_parsing/* itobe2 */.XT)(sps.length), sps, [1], (0,byte_parsing/* itobe2 */.XT)(pps.length), pps)); +function takeWhile(predicate, inclusive) { + if (inclusive === void 0) { + inclusive = false; + } + return function (source) { + return source.lift(new TakeWhileOperator(predicate, inclusive)); + }; } +var TakeWhileOperator = /*@__PURE__*/ (function () { + function TakeWhileOperator(predicate, inclusive) { + this.predicate = predicate; + this.inclusive = inclusive; + } + TakeWhileOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TakeWhileSubscriber(subscriber, this.predicate, this.inclusive)); + }; + return TakeWhileOperator; +}()); +var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(TakeWhileSubscriber, _super); + function TakeWhileSubscriber(destination, predicate, inclusive) { + var _this = _super.call(this, destination) || this; + _this.predicate = predicate; + _this.inclusive = inclusive; + _this.index = 0; + return _this; + } + TakeWhileSubscriber.prototype._next = function (value) { + var destination = this.destination; + var result; + try { + result = this.predicate(value, this.index++); + } + catch (err) { + destination.error(err); + return; + } + this.nextOrComplete(value, result); + }; + TakeWhileSubscriber.prototype.nextOrComplete = function (value, predicateResult) { + var destination = this.destination; + if (Boolean(predicateResult)) { + destination.next(value); + } + else { + if (this.inclusive) { + destination.next(value); + } + destination.complete(); + } + }; + return TakeWhileSubscriber; +}(Subscriber/* Subscriber */.L)); +//# sourceMappingURL=takeWhile.js.map + +;// CONCATENATED MODULE: ./src/core/stream/representation/check_for_discontinuity.ts /** - * @param {string} type - "video"/"audio"/"hint" - * @returns {Uint8Array} + * 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. */ +/** + * Check if there is a soon-to-be-encountered discontinuity in the buffer that + * won't be filled by any future segment. + * This function will only check discontinuities for the given `checkedRange`. + * + * @param {Object} content - The content we are currently loading. + * @param {Object} checkedRange - The time range that will be checked for + * discontinuities. + * Both `nextSegmentStart` and `bufferedSegments` arguments can only refer to + * that range. + * @param {number|null} nextSegmentStart - The start time in seconds of the next + * not-yet-pushed segment that can be pushed, in the limits of `checkedRange`. + * This includes segments which have not been loaded or pushed yet, but also + * segments which might be re-downloaded because currently incomplete in the + * buffer, the point being to know what is the earliest time in the buffer where + * a segment might be pushed in the future. + * `null` if no segment in `checkedRange` will be pushed under current buffer's + * conditions. + * @param {boolean} hasFinishedLoading - if `true`, all segments for the current + * Period have been loaded and none will be loaded in the future under the + * current buffer's state. + * @param {Array.} bufferedSegments - Information about every segments + * currently in the buffer, in chronological order. + * Only segments overlapping with the given `checkedRange` will be looked at, + * though the array given can be larger. + */ -function createHDLRBox(type) { - var name; - var handlerName; - - switch (type) { - case "video": - name = "vide"; - handlerName = "VideoHandler"; - break; +function checkForDiscontinuity(content, checkedRange, nextSegmentStart, hasFinishedLoading, bufferedSegments) { + var period = content.period, + adaptation = content.adaptation, + representation = content.representation; // `bufferedSegments` might also contains segments which are before + // `checkedRange`. + // Here we want the first one that goes over `checkedRange.start`, to see + // if there's a discontinuity at the beginning in the buffer - case "audio": - name = "soun"; - handlerName = "SoundHandler"; - break; + var nextBufferedInRangeIdx = getIndexOfFirstChunkInRange(bufferedSegments, checkedRange); - default: - name = "hint"; - handlerName = ""; - break; - } + if (nextBufferedInRangeIdx === null) { + // There's no segment currently buffered for the current range. + if (nextSegmentStart === null) { + // No segment to load in that range + // Check if we are in a discontinuity at the end of the current Period + if (hasFinishedLoading && period.end !== undefined && checkedRange.end >= period.end) { + return { + start: undefined, + end: null + }; // discontinuity to Period's end + } // Check that there is a discontinuity announced in the Manifest there - return createBox("hdlr", (0,byte_parsing/* concat */.zo)(8, (0,string_parsing/* strToUtf8 */.tG)(name), 12, (0,string_parsing/* strToUtf8 */.tG)(handlerName), 1 // handler name is C-style string (0 terminated) - )); -} -/** - * @param {number} timescale - * @returns {Uint8Array} - */ + var discontinuityEnd = representation.index.checkDiscontinuity(checkedRange.start); -function createMDHDBox(timescale) { - return createBox("mdhd", (0,byte_parsing/* concat */.zo)(12, (0,byte_parsing/* itobe4 */.kh)(timescale), 8)); -} -/** - * @param {Number} timescale - * @param {Number} trackId - * @returns {Uint8Array} - */ + if (discontinuityEnd !== null) { + return { + start: undefined, + end: discontinuityEnd + }; + } + } + return null; + } -function createMVHDBox(timescale, trackId) { - return createBox("mvhd", (0,byte_parsing/* concat */.zo)(12, (0,byte_parsing/* itobe4 */.kh)(timescale), 4, [0, 1], 2, // we assume rate = 1; - [1, 0], 10, // we assume volume = 100%; - [0, 1], 14, // default matrix - [0, 1], 14, // default matrix - [64, 0, 0, 0], 26, (0,byte_parsing/* itobe2 */.XT)(trackId + 1) // next trackId (=trackId + 1); - )); -} -/** - * @param {string} systemId - Hex string representing the CDM, 16 bytes. - * @param {Uint8Array|undefined} privateData - Data associated to protection - * specific system. - * @param {Array.} keyIds - List of key ids contained in the PSSH - * @returns {Uint8Array} - */ + var nextBufferedSegment = bufferedSegments[nextBufferedInRangeIdx]; // Check if there is a hole that won't be filled before `nextSegmentStart` + if ( // Next buffered segment starts after the start of the current range + nextBufferedSegment.bufferedStart !== undefined && nextBufferedSegment.bufferedStart > checkedRange.start && ( // and no segment will fill in that hole + nextSegmentStart === null || nextBufferedSegment.infos.segment.end <= nextSegmentStart)) { + log/* default.debug */.Z.debug("RS: current discontinuity encountered", adaptation.type, nextBufferedSegment.bufferedStart); + return { + start: undefined, + end: nextBufferedSegment.bufferedStart + }; + } // Check if there's a discontinuity BETWEEN segments of the current range -function createPSSHBox(systemId, privateData, keyIds) { - if (privateData === void 0) { - privateData = new Uint8Array(0); - } - if (keyIds === void 0) { - keyIds = new Uint8Array(0); - } + var nextHoleIdx = getIndexOfFirstDiscontinuityBetweenChunks(bufferedSegments, checkedRange, nextBufferedInRangeIdx + 1); // If there was a hole between two consecutives segments, and if this hole + // comes before the next segment to load, there is a discontinuity (that hole!) - var _systemId = systemId.replace(/-/g, ""); + if (nextHoleIdx !== null && (nextSegmentStart === null || bufferedSegments[nextHoleIdx].infos.segment.end <= nextSegmentStart)) { + var start = bufferedSegments[nextHoleIdx - 1].bufferedEnd; + var end = bufferedSegments[nextHoleIdx].bufferedStart; + log/* default.debug */.Z.debug("RS: future discontinuity encountered", adaptation.type, start, end); + return { + start: start, + end: end + }; + } else if (nextSegmentStart === null) { + // If no hole between segments and no segment to load, check for a + // discontinuity at the end of the Period + if (hasFinishedLoading && period.end !== undefined) { + // Period is finished + if (checkedRange.end < period.end) { + // We've not reached the Period's end yet + return null; + } // Check if the last buffered segment ends before this Period's end + // In which case there is a discontinuity between those - if (_systemId.length !== 32) { - throw new Error("HSS: wrong system id length"); - } - var version; - var kidList; - var kidCount = keyIds.length; + var lastBufferedInPeriodIdx = getIndexOfLastChunkInPeriod(bufferedSegments, period.end); - if (kidCount > 0) { - version = 1; - kidList = byte_parsing/* concat.apply */.zo.apply(void 0, [(0,byte_parsing/* itobe4 */.kh)(kidCount)].concat(keyIds)); - } else { - version = 0; - kidList = []; - } + if (lastBufferedInPeriodIdx !== null) { + var lastSegment = bufferedSegments[lastBufferedInPeriodIdx]; - return createBox("pssh", (0,byte_parsing/* concat */.zo)([version, 0, 0, 0], (0,string_parsing/* hexToBytes */.nr)(_systemId), kidList, (0,byte_parsing/* itobe4 */.kh)(privateData.length), privateData)); -} -/** - * @param {Uint8Array} mfhd - * @param {Uint8Array} tfhd - * @param {Uint8Array} tfdt - * @param {Uint8Array} trun - * @returns {Uint8Array} - */ + if (lastSegment.bufferedEnd !== undefined && lastSegment.bufferedEnd < period.end) { + log/* default.debug */.Z.debug("RS: discontinuity encountered at the end of the current period", adaptation.type, lastSegment.bufferedEnd, period.end); + return { + start: lastSegment.bufferedEnd, + end: null + }; + } + } + } // At last, check if we don't have a discontinuity at the end of the current + // range, announced in the Manifest, that is too big to be detected through + // the previous checks. -function createSAIOBox(mfhd, tfhd, tfdt, trun) { - return createBox("saio", (0,byte_parsing/* concat */.zo)(4, [0, 0, 0, 1], // ?? - (0,byte_parsing/* itobe4 */.kh)(mfhd.length + tfhd.length + tfdt.length + trun.length + 8 + 8 + 8 + 8))); -} -/** - * @param {Uint8Array} sencContent - including 8 bytes flags and entries count - * @returns {Uint8Array} - */ + if (period.end !== undefined && checkedRange.end >= period.end) { + return null; // The previous checks should have taken care of those + } + for (var bufIdx = bufferedSegments.length - 1; bufIdx >= 0; bufIdx--) { + var bufSeg = bufferedSegments[bufIdx]; -function createSAIZBox(sencContent) { - if (sencContent.length === 0) { - return createBox("saiz", new Uint8Array(0)); - } + if (bufSeg.bufferedStart === undefined) { + break; + } - var flags = (0,byte_parsing/* be4toi */.pX)(sencContent, 0); - var entries = (0,byte_parsing/* be4toi */.pX)(sencContent, 4); - var arr = new Uint8Array(entries + 9); - arr.set((0,byte_parsing/* itobe4 */.kh)(entries), 5); - var i = 9; - var j = 8; - var pairsCnt; - var pairsLen; + if (bufSeg.bufferedStart < checkedRange.end) { + if (bufSeg.bufferedEnd !== undefined && bufSeg.bufferedEnd < checkedRange.end) { + var _discontinuityEnd = representation.index.checkDiscontinuity(checkedRange.end); - while (j < sencContent.length) { - j += 8; // assuming IV is 8 bytes TODO handle 16 bytes IV - // if we have extradata for each entry + if (_discontinuityEnd !== null) { + return { + start: bufSeg.bufferedEnd, + end: _discontinuityEnd + }; + } + } - if ((flags & 0x2) === 0x2) { - pairsLen = 2; - pairsCnt = (0,byte_parsing/* be2toi */.zK)(sencContent, j); - j += pairsCnt * 6 + 2; - } else { - pairsCnt = 0; - pairsLen = 0; + return null; + } } - - arr[i] = pairsCnt * 6 + 8 + pairsLen; - i++; } - return createBox("saiz", arr); + return null; } /** - * @returns {Uint8Array} + * Returns the index of the first element in `bufferedChunks` that is part of + * `range` (starts before it ends and ends after it starts). + * + * Returns `null` if no element is found in that range or if we cannot know the + * index of the first element in it. + * @param {Array.} bufferedChunks + * @param {Object} range + * @returns {number|null} */ +function getIndexOfFirstChunkInRange(bufferedChunks, range) { + for (var bufIdx = 0; bufIdx < bufferedChunks.length; bufIdx++) { + var bufSeg = bufferedChunks[bufIdx]; -function createSMHDBox() { - return createBox("smhd", new Uint8Array(8)); -} -/** - * @param {Array.} representations - arrays of Uint8Array, - * typically [avc1] or [encv, avc1] - * @returns {Uint8Array} - */ + if (bufSeg.bufferedStart === undefined || bufSeg.bufferedEnd === undefined || bufSeg.bufferedStart >= range.end) { + return null; + } + if (bufSeg.bufferedEnd > range.start) { + return bufIdx; + } + } -function createSTSDBox(reps) { - // only one description here... FIXME - var arrBase = [7, [reps.length]]; - return createBox("stsd", byte_parsing/* concat.apply */.zo.apply(void 0, arrBase.concat(reps))); + return null; } /** - * @param {Number} width - * @param {Number} height - * @param {Number} trackId - * @returns {Uint8Array} + * Returns the index of the first element in `bufferedChunks` which is not + * immediately consecutive to the one before it. + * + * `startFromIndex` is the index of the first segment that will be checked with + * the element coming before it. As such, it has to be superior to 0. + * + * If the element at `startFromIndex` comes immediately after the one before it, + * the element at `startFromIndex + 1` will be checked instead and so on until a + * segment completely out of `checkedRange` (which starts after it) is detected. + * + * If no hole between elements is found, `null` is returned. + * @param {Array.} bufferedChunks + * @param {Object} range + * @param {number} startFromIndex + * @returns {number|null} */ -function createTKHDBox(width, height, trackId) { - return createBox("tkhd", (0,byte_parsing/* concat */.zo)((0,byte_parsing/* itobe4 */.kh)(1 + 2 + 4), 8, // we assume track is enabled, - // in media and in preview. - (0,byte_parsing/* itobe4 */.kh)(trackId), 20, // we assume trackId = 1; - [1, 0, 0, 0], // we assume volume = 100%; - [0, 1, 0, 0], 12, // default matrix - [0, 1, 0, 0], 12, // default matrix - [64, 0, 0, 0], // ?? - (0,byte_parsing/* itobe2 */.XT)(width), 2, // width (TODO handle fixed) - (0,byte_parsing/* itobe2 */.XT)(height), 2 // height (TODO handle fixed) - )); -} -/** - * @param {Number} algId - eg 1 - * @param {Number} ivSize - eg 8 - * @param {string} keyId - Hex KID 93789920e8d6520098577df8f2dd5546 - * @returns {Uint8Array} - */ +function getIndexOfFirstDiscontinuityBetweenChunks(bufferedChunks, range, startFromIndex) { + if (startFromIndex <= 0) { + log/* default.error */.Z.error("RS: Asked to check a discontinuity before the first chunk."); + return null; + } + for (var bufIdx = startFromIndex; bufIdx < bufferedChunks.length; bufIdx++) { + var currSegment = bufferedChunks[bufIdx]; + var prevSegment = bufferedChunks[bufIdx - 1]; // Exit as soon we miss information or when we go further than `checkedRange` -function createTENCBox(algId, ivSize, keyId) { - return createBox("tenc", (0,byte_parsing/* concat */.zo)(6, [algId, ivSize], keyId)); -} + if (currSegment.bufferedStart === undefined || prevSegment.bufferedEnd === undefined || currSegment.bufferedStart >= range.end) { + return null; + } // If there is a hole between two consecutive buffered segment -;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/create_traf_box.ts + if (currSegment.bufferedStart - prevSegment.bufferedEnd > 0) { + return bufIdx; + } + } + + return null; +} /** - * 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 + * Returns the index of the last element in `bufferedChunks` that is part of + * `range` (starts before it ends and ends after it starts). * - * 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 `null` if no element is found in that range or if we cannot know the + * index of the last element in it. + * @param {Array.} bufferedChunks + * @param {number} periodEnd + * @returns {number|null} */ -function createTrafBox(tfhd, tfdt, trun, mfhd, senc) { - var trafs = [tfhd, tfdt, trun]; +function getIndexOfLastChunkInPeriod(bufferedChunks, periodEnd) { + for (var bufIdx = bufferedChunks.length - 1; bufIdx >= 0; bufIdx--) { + var bufSeg = bufferedChunks[bufIdx]; - if (senc !== undefined) { - trafs.push(createBox("senc", senc), createSAIZBox(senc), createSAIOBox(mfhd, tfhd, tfdt, trun)); + if (bufSeg.bufferedStart === undefined) { + return null; + } + + if (bufSeg.bufferedStart < periodEnd) { + return bufIdx; + } } - return createBoxWithChildren("traf", trafs); + return null; } -;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/patch_segment.ts +// EXTERNAL MODULE: ./src/manifest/are_same_content.ts +var are_same_content = __webpack_require__(5952); +;// CONCATENATED MODULE: ./src/core/stream/representation/get_needed_segments.ts /** * Copyright 2015 CANAL+ Group * @@ -47126,344 +49815,269 @@ function createTrafBox(tfhd, tfdt, trun, mfhd, senc) { * See the License for the specific language governing permissions and * limitations under the License. */ +// eslint-disable-next-line max-len - +var CONTENT_REPLACEMENT_PADDING = config/* default.CONTENT_REPLACEMENT_PADDING */.Z.CONTENT_REPLACEMENT_PADDING, + BITRATE_REBUFFERING_RATIO = config/* default.BITRATE_REBUFFERING_RATIO */.Z.BITRATE_REBUFFERING_RATIO, + MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT = config/* default.MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT */.Z.MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT, + MINIMUM_SEGMENT_SIZE = config/* default.MINIMUM_SEGMENT_SIZE */.Z.MINIMUM_SEGMENT_SIZE; /** - * Update ISOBMFF Segment downloaded in Smooth Streaming so it is playable on - * the browser. - * @param {Uint8Array} segment - * @param {Number} decodeTime - * @return {Uint8Array} + * Epsilon compensating for rounding errors when comparing the start and end + * time of multiple segments. */ -function patchSegment(segment, decodeTime) { - var oldMoofOffsets = (0,get_box/* getBoxOffsets */.Qy)(segment, 0x6D6F6F66 - /* moof */ - ); +var ROUNDING_ERROR = Math.min(1 / 60, MINIMUM_SEGMENT_SIZE); +/** + * Return the list of segments that can currently be downloaded to fill holes + * in the buffer in the given range, including already-pushed segments currently + * incomplete in the buffer. + * This list might also include already-loaded segments in a higher bitrate, + * according to the given configuration. + * Excludes segment that are already being pushed. + * @param {Object} args + * @returns {Array.} + */ - if (oldMoofOffsets === null) { - throw new Error("Smooth: Invalid ISOBMFF given"); - } +function getNeededSegments(_ref) { + var content = _ref.content, + currentPlaybackTime = _ref.currentPlaybackTime, + fastSwitchThreshold = _ref.fastSwitchThreshold, + neededRange = _ref.neededRange, + segmentsBeingPushed = _ref.segmentsBeingPushed, + bufferedSegments = _ref.bufferedSegments; + var representation = content.representation; + var availableSegmentsForRange = representation.index.getSegments(neededRange.start, neededRange.end - neededRange.start); // Remove from `bufferedSegments` any segments we would prefer to replace: + // - segments in the wrong track / bad quality + // - garbage-collected segments - var oldMoofContent = segment.subarray(oldMoofOffsets[1], oldMoofOffsets[2]); - var mfhdBox = (0,get_box/* getBox */.iz)(oldMoofContent, 0x6D666864 - /* mfhd */ - ); - var trafContent = (0,get_box/* getBoxContent */.t_)(oldMoofContent, 0x74726166 - /* traf */ - ); + var segmentsToKeep = bufferedSegments.filter(function (bufferedSegment) { + return !shouldContentBeReplaced(bufferedSegment.infos, content, currentPlaybackTime, fastSwitchThreshold); + }).filter(function (currentSeg, i, consideredSegments) { + var prevSeg = i === 0 ? null : consideredSegments[i - 1]; + var nextSeg = i >= consideredSegments.length - 1 ? null : consideredSegments[i + 1]; + return !isStartGarbageCollected(currentSeg, prevSeg, neededRange.start) && !isEndGarbageCollected(currentSeg, nextSeg, neededRange.end); + }); + var segmentsToDownload = availableSegmentsForRange.filter(function (segment) { + var contentObject = (0,object_assign/* default */.Z)({ + segment: segment + }, content); // First, check that the segment is not already being pushed - if (trafContent === null || mfhdBox === null) { - throw new Error("Smooth: Invalid ISOBMFF given"); - } + if (segmentsBeingPushed.length > 0) { + var isAlreadyBeingPushed = segmentsBeingPushed.some(function (pendingSegment) { + return (0,are_same_content/* default */.Z)(contentObject, pendingSegment); + }); - var tfhdOffsets = (0,get_box/* getBoxOffsets */.Qy)(trafContent, 0x74666864 - /* tfhd */ - ); - var oldTrunOffsets = (0,get_box/* getBoxOffsets */.Qy)(trafContent, 0x7472756E - /* trun */ - ); + if (isAlreadyBeingPushed) { + return false; + } + } - if (tfhdOffsets === null || oldTrunOffsets === null) { - throw new Error("Smooth: Invalid ISOBMFF given"); - } + var duration = segment.duration, + time = segment.time, + end = segment.end; - var tfhdBox = trafContent.subarray(tfhdOffsets[0], tfhdOffsets[2]); - var oldTrunBox = trafContent.subarray(oldTrunOffsets[0], oldTrunOffsets[2]); // force trackId=1 since trackIds are not always reliable... + if (segment.isInit) { + return true; // never skip initialization segments + } - tfhdBox.set([0, 0, 0, 1], tfhdOffsets[1] - tfhdOffsets[0] + 4 - /* version + flags */ - ); - var tfdtBox = createTfdtBox(decodeTime); - var newTrunBox = updateTrunDataOffset(oldTrunBox, oldTrunOffsets[1] - oldTrunOffsets[0]); - var sencContent = (0,get_box/* getUuidContent */.nR)(trafContent, 0xA2394F52, 0x5A9B4F14, 0xA2446C42, 0x7C648DF4); - var newTrafBox = createTrafBox(tfhdBox, tfdtBox, newTrunBox, mfhdBox, sencContent); - var newMoof = createBoxWithChildren("moof", [mfhdBox, newTrafBox]); - var newMoofOffsets = (0,get_box/* getBoxOffsets */.Qy)(newMoof, 0x6D6F6F66 - /* moof */ - ); - var newTrafOffsets = (0,get_box/* getBoxOffsets */.Qy)(newTrafBox, 0x74726166 - /* traf */ - ); - var newTrunOffsets = (0,get_box/* getBoxOffsets */.Qy)(newTrunBox, 0x7472756E - /* trun */ - ); + if (duration < MINIMUM_SEGMENT_SIZE) { + return false; // too small, don't download + } // Check if the same segment from another Representation is not already + // being pushed. - if (newMoofOffsets === null || newTrafOffsets === null || newTrunOffsets === null) { - throw new Error("Smooth: Invalid moof, trun or traf generation"); - } - /** index of the `data_offset` property from the trun box in the whole "moof". */ + if (segmentsBeingPushed.length > 0) { + var waitForPushedSegment = segmentsBeingPushed.some(function (pendingSegment) { + if (pendingSegment.period.id !== content.period.id || pendingSegment.adaptation.id !== content.adaptation.id) { + return false; + } - var indexOfTrunDataOffsetInMoof = newMoofOffsets[1] - newMoofOffsets[0] + mfhdBox.length + ( - /* new traf size + name */ - newTrafOffsets[1] - newTrafOffsets[0]) + tfhdBox.length + tfdtBox.length + ( - /* new trun size + name */ - newTrunOffsets[1] - newTrunOffsets[0]) + 8 - /* trun version + flags + `sample_count` */ - ; - var oldMoofLength = oldMoofOffsets[2] - oldMoofOffsets[0]; - var newMoofSizeDiff = newMoof.length - oldMoofLength; - var oldMdatOffset = (0,get_box/* getBoxOffsets */.Qy)(segment, 0x6D646174 - /* "mdat" */ - ); + var oldSegment = pendingSegment.segment; - if (oldMdatOffset === null) { - throw new Error("Smooth: Invalid ISOBMFF given"); - } + if (oldSegment.time - ROUNDING_ERROR > time) { + return false; + } - if (canPatchISOBMFFSegment() && (newMoofSizeDiff === 0 || newMoofSizeDiff <= -8)) { - // patch trun data_offset - var mdatContentOffset = oldMdatOffset[1]; - newMoof.set((0,byte_parsing/* itobe4 */.kh)(mdatContentOffset), indexOfTrunDataOffsetInMoof); - segment.set(newMoof, oldMoofOffsets[0]); // add "free" box for the remaining space + if (oldSegment.end + ROUNDING_ERROR < end) { + return false; + } - if (newMoofSizeDiff <= -8) { - segment.set(createFreeBox(-newMoofSizeDiff), newMoof.length); - } + return !shouldContentBeReplaced(pendingSegment, contentObject, currentPlaybackTime, fastSwitchThreshold); + }); - return segment; - } else { - // patch trun data_offset - var _mdatContentOffset = oldMdatOffset[1] + newMoofSizeDiff; + if (waitForPushedSegment) { + return false; + } + } // check if the segment is already downloaded - newMoof.set((0,byte_parsing/* itobe4 */.kh)(_mdatContentOffset), indexOfTrunDataOffsetInMoof); - var newSegment = new Uint8Array(segment.length + newMoofSizeDiff); - var beforeMoof = segment.subarray(0, oldMoofOffsets[0]); - var afterMoof = segment.subarray(oldMoofOffsets[2], segment.length); - newSegment.set(beforeMoof, 0); - newSegment.set(newMoof, beforeMoof.length); - newSegment.set(afterMoof, beforeMoof.length + newMoof.length); - return newSegment; - } -} -/** - * Update `trun` box given or create a new one from it to add a data offset - * flag and the corresponding space to set a data offset. - * Do not do anything if the flag is already set. - * - * Note that the `oldTrunBox` given should not be mutated by this function but - * the returned value CAN point to the exact same `Uint8Array`. - * - * @param {Uint8Array} oldTrunBox - The whole original trun box - * @param {number} initialDataOffset - Offset at which the first value of the - * "trun" box (the "version") is set. - * @returns {Uint8Array} - */ -function updateTrunDataOffset(oldTrunBox, initialDataOffset) { - var trunHasDataOffset = (oldTrunBox[initialDataOffset + 3 - /* last flag */ - ] & 0x01) > 0; + for (var i = 0; i < segmentsToKeep.length; i++) { + var completeSeg = segmentsToKeep[i]; + var areFromSamePeriod = completeSeg.infos.period.id === content.period.id; // Check if content are from same period, as there can't be overlapping + // periods, we should consider a segment as already downloaded if + // it is from same period (but can be from different adaptation or + // representation) - if (trunHasDataOffset) { - return oldTrunBox; - } // If no data_offset is present, we create another "trun" with one + if (areFromSamePeriod) { + var completeSegInfos = completeSeg.infos.segment; + if (time - completeSegInfos.time > -ROUNDING_ERROR && completeSegInfos.end - end > -ROUNDING_ERROR) { + return false; // already downloaded + } + } + } // check if there is an hole in place of the segment currently - var newTrunBox = new Uint8Array(oldTrunBox.length + 4); // copy size + name + version=1 + flags=3 + sample_count=4 - newTrunBox.set(oldTrunBox.subarray(0, initialDataOffset + 8), 0); // add data_offset flag + for (var _i = 0; _i < segmentsToKeep.length; _i++) { + var _completeSeg = segmentsToKeep[_i]; - newTrunBox[initialDataOffset + 3] = newTrunBox[initialDataOffset + 3] | 0x01; - newTrunBox.set([0, 0, 0, 0], initialDataOffset + 8); // add data offset - // add the rest + if (_completeSeg.end > time) { + // `true` if `completeSeg` starts too far after `time` + return _completeSeg.start > time + ROUNDING_ERROR || // `true` if `completeSeg` ends too soon before `end` + getLastContiguousSegment(segmentsToKeep, _i).end < end - ROUNDING_ERROR; + } + } - newTrunBox.set(oldTrunBox.subarray(initialDataOffset + 8, oldTrunBox.length), initialDataOffset + 12); - return (0,utils/* updateBoxLength */.J6)(newTrunBox); // update the trun box's length + return true; + }); + return segmentsToDownload; } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules -var Observable = __webpack_require__(4379); -// EXTERNAL MODULE: ./src/transports/utils/byte_range.ts -var byte_range = __webpack_require__(281); -;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/create_init_segment.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 buffered chunks (`bufferedSegments`) returns the last + * buffered chunk contiguous with the one at the `startIndex` index given. + * @param {Array.} + * @param {number} startIndex + * @returns {Object} */ +function getLastContiguousSegment(bufferedSegments, startIndex) { + var j = startIndex + 1; // go through all contiguous segments and take the last one + while (j < bufferedSegments.length - 1 && bufferedSegments[j - 1].end + ROUNDING_ERROR > bufferedSegments[j].start) { + j++; + } -/** - * @param {Uint8Array} mvhd - * @param {Uint8Array} mvex - * @param {Uint8Array} trak - * @param {Object} pssList - * @returns {Array.} - */ + j--; // index of last contiguous segment -function createMOOVBox(mvhd, mvex, trak, pssList) { - var children = [mvhd, mvex, trak]; - pssList.forEach(function (pss) { - var pssh = createPSSHBox(pss.systemId, pss.privateData, pss.keyIds); - children.push(pssh); - }); - return createBoxWithChildren("moov", children); + return bufferedSegments[j]; } /** - * Create an initialization segment with the information given. - * @param {Number} timescale - * @param {string} type - * @param {Uint8Array} stsd - * @param {Uint8Array} mhd - * @param {Number} width - * @param {Number} height - * @param {Array.} pssList - List of dict, example: - * {systemId: "DEADBEEF", codecPrivateData: "DEAFBEEF} - * @returns {Uint8Array} + * Returns `true` if segments linked to the given `oldContent` currently present + * in the buffer should be replaced by segments coming from `currentContent`. + * @param {Object} oldContent + * @param {Object} currentContent + * @param {number} currentPlaybackTime + * @param {number} [fastSwitchThreshold] + * @returns {boolean} */ -function createInitSegment(timescale, type, stsd, mhd, width, height, pssList) { - var stbl = createBoxWithChildren("stbl", [stsd, createBox("stts", new Uint8Array(0x08)), createBox("stsc", new Uint8Array(0x08)), createBox("stsz", new Uint8Array(0x0C)), createBox("stco", new Uint8Array(0x08))]); - var url = createBox("url ", new Uint8Array([0, 0, 0, 1])); - var dref = createDREFBox(url); - var dinf = createBoxWithChildren("dinf", [dref]); - var minf = createBoxWithChildren("minf", [mhd, dinf, stbl]); - var hdlr = createHDLRBox(type); - var mdhd = createMDHDBox(timescale); // this one is really important +function shouldContentBeReplaced(oldContent, currentContent, currentPlaybackTime, fastSwitchThreshold) { + if (oldContent.period.id !== currentContent.period.id) { + return false; // keep segments from another Period by default. + } - var mdia = createBoxWithChildren("mdia", [mdhd, hdlr, minf]); - var tkhd = createTKHDBox(width, height, 1); - var trak = createBoxWithChildren("trak", [tkhd, mdia]); - var trex = createTREXBox(1); - var mvex = createBoxWithChildren("mvex", [trex]); - var mvhd = createMVHDBox(timescale, 1); // in fact, we don't give a sh** about - // this value :O + var segment = oldContent.segment; - var moov = createMOOVBox(mvhd, mvex, trak, pssList); - var ftyp = createFTYPBox("isom", ["isom", "iso2", "iso6", "avc1", "dash"]); - return (0,byte_parsing/* concat */.zo)(ftyp, moov); + if (segment.time < currentPlaybackTime + CONTENT_REPLACEMENT_PADDING) { + return false; + } + + if (oldContent.adaptation.id !== currentContent.adaptation.id) { + return true; // replace segments from another Adaptation + } + + return canFastSwitch(oldContent.representation, currentContent.representation, fastSwitchThreshold); } -;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/create_video_init_segment.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 + * Returns `true` if segments from the new Representation can replace + * previously-loaded segments from the old Representation given. * - * 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 behavior is called "fast-switching". + * @param {Object} oldSegmentRepresentation + * @param {Object} newSegmentRepresentation + * @param {number|undefined} fastSwitchThreshold + * @returns {boolean} */ +function canFastSwitch(oldSegmentRepresentation, newSegmentRepresentation, fastSwitchThreshold) { + var oldContentBitrate = oldSegmentRepresentation.bitrate; + if (fastSwitchThreshold === undefined) { + // only re-load comparatively-poor bitrates for the same Adaptation. + var bitrateCeil = oldContentBitrate * BITRATE_REBUFFERING_RATIO; + return newSegmentRepresentation.bitrate > bitrateCeil; + } + return oldContentBitrate < fastSwitchThreshold && newSegmentRepresentation.bitrate > oldContentBitrate; +} /** - * Return full video Init segment as Uint8Array - * @param {Number} timescale - lowest number, this one will be set into mdhd - * *10000 in mvhd, e.g. 1000 - * @param {Number} width - * @param {Number} height - * @param {Number} hRes - * @param {Number} vRes - * @param {Number} nalLength (1, 2 or 4) - * @param {string} codecPrivateData - * @param {Uint8Array} keyId - hex string representing the key Id, - * 32 chars. eg. a800dbed49c12c4cb8e0b25643844b9b - * @param {Array.} [pssList] - List of dict, example: - * {systemId: "DEADBEEF", codecPrivateData: "DEAFBEEF} - * @returns {Uint8Array} + * From buffered segment information, return `true` if the given `currentSeg` + * might have been garbage collected at the start. + * Return `false` if the segment is complete at least from `maximumStartTime`. + * @param {Object} currentSeg - The segment information for the segment in + * question. + * @param {Object|null} prevSeg - The segment information for the previous + * buffered segment, if one (`null` if none). + * @param {number} maximumStartTime - Only consider the data after that time. + * If `currentSeg` has only been garbage collected for some data which is before + * that time, we will return `false`. */ -function createVideoInitSegment(timescale, width, height, hRes, vRes, nalLength, codecPrivateData, keyId, pssList) { - var _pssList = pssList === undefined ? [] : pssList; - - var _codecPrivateData$spl = codecPrivateData.split("00000001"), - spsHex = _codecPrivateData$spl[1], - ppsHex = _codecPrivateData$spl[2]; - if (spsHex === undefined || ppsHex === undefined) { - throw new Error("Smooth: unsupported codec private data."); +function isStartGarbageCollected(currentSeg, prevSeg, maximumStartTime) { + if (currentSeg.bufferedStart === undefined) { + log/* default.warn */.Z.warn("Stream: Start of a segment unknown. " + "Assuming it is garbage collected by default.", currentSeg); + return true; } - var sps = (0,string_parsing/* hexToBytes */.nr)(spsHex); - var pps = (0,string_parsing/* hexToBytes */.nr)(ppsHex); // TODO NAL length is forced to 4 - - var avcc = createAVCCBox(sps, pps, nalLength); - var stsd; + if (prevSeg !== null && prevSeg.bufferedEnd !== undefined && currentSeg.bufferedStart - prevSeg.bufferedEnd < 0.1) { + return false; + } - if (_pssList.length === 0 || keyId === undefined) { - var avc1 = createAVC1Box(width, height, hRes, vRes, "AVC Coding", 24, avcc); - stsd = createSTSDBox([avc1]); - } else { - var tenc = createTENCBox(1, 8, keyId); - var schi = createBoxWithChildren("schi", [tenc]); - var schm = createSCHMBox("cenc", 65536); - var frma = createFRMABox("avc1"); - var sinf = createBoxWithChildren("sinf", [frma, schm, schi]); - var encv = createENCVBox(width, height, hRes, vRes, "AVC Coding", 24, avcc, sinf); - stsd = createSTSDBox([encv]); + if (maximumStartTime < currentSeg.bufferedStart && currentSeg.bufferedStart - currentSeg.start > MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT) { + log/* default.info */.Z.info("Stream: The start of the wanted segment has been garbage collected", currentSeg); + return true; } - return createInitSegment(timescale, "video", stsd, createVMHDBox(), width, height, _pssList); + return false; } -;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/get_aaces_header.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 buffered segment information, return `true` if the given `currentSeg` + * might have been garbage collected at the end. + * Return `false` if the segment is complete at least until `minimumEndTime`. + * @param {Object} currentSeg - The segment information for the segment in + * question. + * @param {Object|null} nextSeg - The segment information for the next buffered + * segment, if one (`null` if none). + * @param {number} minimumEndTime - Only consider the data before that time. + * If `currentSeg` has only been garbage collected for some data which is after + * that time, we will return `false`. */ -/** - * Sampling frequencies defined in MPEG-4 Audio. - * @type {Array.} - */ +function isEndGarbageCollected(currentSeg, nextSeg, minimumEndTime) { + if (currentSeg.bufferedEnd === undefined) { + log/* default.warn */.Z.warn("Stream: End of a segment unknown. " + "Assuming it is garbage collected by default.", currentSeg); + return true; + } -var SAMPLING_FREQUENCIES = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350]; -/** - * Return AAC ES Header (hexstr form) - * - * @param {Number} type - * 1 = AAC Main - * 2 = AAC LC - * cf http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio - * @param {Number} frequency - * @param {Number} chans (1 or 2) - * @returns {string} - */ + if (nextSeg !== null && nextSeg.bufferedStart !== undefined && nextSeg.bufferedStart - currentSeg.bufferedEnd < 0.1) { + return false; + } -function getAacesHeader(type, frequency, chans) { - var freq = SAMPLING_FREQUENCIES.indexOf(frequency); // TODO : handle Idx = 15... + if (minimumEndTime > currentSeg.bufferedEnd && currentSeg.end - currentSeg.bufferedEnd > MAX_TIME_MISSING_FROM_COMPLETE_SEGMENT) { + log/* default.info */.Z.info("Stream: The end of the wanted segment has been garbage collected", currentSeg); + return true; + } - var val; - val = (type & 0x3F) << 0x4; - val = (val | freq & 0x1F) << 0x4; - val = (val | chans & 0x1F) << 0x3; - return (0,string_parsing/* bytesToHex */.ci)((0,byte_parsing/* itobe2 */.XT)(val)); + return false; } -;// CONCATENATED MODULE: ./src/transports/smooth/isobmff/create_audio_init_segment.ts +;// CONCATENATED MODULE: ./src/core/stream/representation/get_segment_priority.ts /** * Copyright 2015 CANAL+ Group * @@ -47480,50 +50094,33 @@ function getAacesHeader(type, frequency, chans) { * limitations under the License. */ - - - +var SEGMENT_PRIORITIES_STEPS = config/* default.SEGMENT_PRIORITIES_STEPS */.Z.SEGMENT_PRIORITIES_STEPS; /** - * Return full audio initialization segment as Uint8Array. - * @param {Number} timescale - * @param {Number} channelsCount - * @param {Number} sampleSize - * @param {Number} packetSize - * @param {Number} sampleRate - * @param {string} codecPrivateData - * @param {Uint8Array} keyId - hex string representing the key Id, 32 chars. - * eg. a800dbed49c12c4cb8e0b25643844b9b - * @param {Array.} [pssList] - * @returns {Uint8Array} + * Calculate the priority number for a given time, in function of the distance + * with the current time. + * + * The lower is this number, the higher should be the priority of the request. + * + * Note that a `timeWanted` given behind the current time will always have the + * highest priority. + * @param {number} timeWanted + * @param {Object} clockTick + * @returns {number} */ -function createAudioInitSegment(timescale, channelsCount, sampleSize, packetSize, sampleRate, codecPrivateData, keyId, pssList) { - if (pssList === void 0) { - pssList = []; - } - - var _codecPrivateData = codecPrivateData.length === 0 ? getAacesHeader(2, sampleRate, channelsCount) : codecPrivateData; - - var esds = createESDSBox(1, _codecPrivateData); +function getSegmentPriority(timeWanted, clockTick) { + var currentTime = clockTick.position + clockTick.wantedTimeOffset; + var distance = timeWanted - currentTime; - var stsd = function () { - if (pssList.length === 0 || keyId === undefined) { - var mp4a = createMP4ABox(1, channelsCount, sampleSize, packetSize, sampleRate, esds); - return createSTSDBox([mp4a]); + for (var priority = 0; priority < SEGMENT_PRIORITIES_STEPS.length; priority++) { + if (distance < SEGMENT_PRIORITIES_STEPS[priority]) { + return priority; } + } - var tenc = createTENCBox(1, 8, keyId); - var schi = createBoxWithChildren("schi", [tenc]); - var schm = createSCHMBox("cenc", 65536); - var frma = createFRMABox("mp4a"); - var sinf = createBoxWithChildren("sinf", [frma, schm, schi]); - var enca = createENCABox(1, channelsCount, sampleSize, packetSize, sampleRate, esds, sinf); - return createSTSDBox([enca]); - }(); - - return createInitSegment(timescale, "audio", stsd, createSMHDBox(), 0, 0, pssList); + return SEGMENT_PRIORITIES_STEPS.length; } -;// CONCATENATED MODULE: ./src/transports/smooth/segment_loader.ts +;// CONCATENATED MODULE: ./src/core/stream/representation/get_buffer_status.ts /** * Copyright 2015 CANAL+ Group * @@ -47544,210 +50141,162 @@ function createAudioInitSegment(timescale, channelsCount, sampleSize, packetSize +var get_buffer_status_MINIMUM_SEGMENT_SIZE = config/* default.MINIMUM_SEGMENT_SIZE */.Z.MINIMUM_SEGMENT_SIZE; /** - * Segment loader triggered if there was no custom-defined one in the API. - * @param {Object} opt - * @returns {Observable} + * Checks on the current buffered data for the given type and Period + * and returns what should be done to fill the buffer according to the buffer + * goal, the Representation chosen, etc. + * Also emits discontinuities if found, which are parts of the buffer that won't + * be filled by any segment, even in the future. + * + * @param {Object} content + * @param {Object} tick + * @param {number|undefined} fastSwitchThreshold + * @param {number} bufferGoal + * @param {Object} segmentBuffer + * @returns {Object} */ -function regularSegmentLoader(_ref) { - var url = _ref.url, - segment = _ref.segment; - var headers; - var range = segment.range; +function getBufferStatus(content, tick, fastSwitchThreshold, bufferGoal, segmentBuffer) { + var _a; - if (Array.isArray(range)) { - headers = { - Range: (0,byte_range/* default */.Z)(range) - }; - } + var period = content.period, + representation = content.representation; + segmentBuffer.synchronizeInventory(); + var wantedStartPosition = tick.position + tick.wantedTimeOffset; + var wantedEndPosition = wantedStartPosition + bufferGoal; + var neededRange = { + start: Math.max(wantedStartPosition, period.start), + end: Math.min(wantedEndPosition, (_a = period.end) !== null && _a !== void 0 ? _a : Infinity) + }; + var shouldRefreshManifest = representation.index.shouldRefresh(wantedStartPosition, wantedEndPosition); + /** + * Every segment awaiting an "EndOfSegment" operation, which indicates that a + * completely-loaded segment is still being pushed to the SegmentBuffer. + */ - return (0,request/* default */.ZP)({ - url: url, - responseType: "arraybuffer", - headers: headers, - sendProgressEvents: true + var segmentsBeingPushed = segmentBuffer.getPendingOperations().filter(function (operation) { + return operation.type === types/* SegmentBufferOperation.EndOfSegment */.f.EndOfSegment; + }).map(function (operation) { + return operation.value; }); -} -/** - * Defines the url for the request, load the right loader (custom/default - * one). - */ - - -var generateSegmentLoader = function generateSegmentLoader(customSegmentLoader) { - return function (_ref2) { - var segment = _ref2.segment, - representation = _ref2.representation, - adaptation = _ref2.adaptation, - period = _ref2.period, - manifest = _ref2.manifest, - url = _ref2.url; - - if (segment.isInit) { - if (segment.privateInfos === undefined || segment.privateInfos.smoothInitSegment === undefined) { - throw new Error("Smooth: Invalid segment format"); - } - - var smoothInitPrivateInfos = segment.privateInfos.smoothInitSegment; - var responseData; - var codecPrivateData = smoothInitPrivateInfos.codecPrivateData, - timescale = smoothInitPrivateInfos.timescale, - _smoothInitPrivateInf = smoothInitPrivateInfos.protection, - protection = _smoothInitPrivateInf === void 0 ? { - keyId: undefined, - keySystems: undefined - } : _smoothInitPrivateInf; - - if (codecPrivateData === undefined) { - throw new Error("Smooth: no codec private data."); - } - - switch (adaptation.type) { - case "video": - { - var _representation$width = representation.width, - width = _representation$width === void 0 ? 0 : _representation$width, - _representation$heigh = representation.height, - height = _representation$heigh === void 0 ? 0 : _representation$heigh; - responseData = createVideoInitSegment(timescale, width, height, 72, 72, 4, // vRes, hRes, nal - codecPrivateData, protection.keyId, protection.keySystems); - break; - } + /** Data on every segments buffered around `neededRange`. */ - case "audio": - { - var _smoothInitPrivateInf2 = smoothInitPrivateInfos.channels, - channels = _smoothInitPrivateInf2 === void 0 ? 0 : _smoothInitPrivateInf2, - _smoothInitPrivateInf3 = smoothInitPrivateInfos.bitsPerSample, - bitsPerSample = _smoothInitPrivateInf3 === void 0 ? 0 : _smoothInitPrivateInf3, - _smoothInitPrivateInf4 = smoothInitPrivateInfos.packetSize, - packetSize = _smoothInitPrivateInf4 === void 0 ? 0 : _smoothInitPrivateInf4, - _smoothInitPrivateInf5 = smoothInitPrivateInfos.samplingRate, - samplingRate = _smoothInitPrivateInf5 === void 0 ? 0 : _smoothInitPrivateInf5; - responseData = createAudioInitSegment(timescale, channels, bitsPerSample, packetSize, samplingRate, codecPrivateData, protection.keyId, protection.keySystems); - break; - } + var bufferedSegments = getPlayableBufferedSegments({ + start: Math.max(neededRange.start - 0.5, 0), + end: neededRange.end + 0.5 + }, segmentBuffer.getInventory()); + /** List of segments we will need to download. */ - default: - if (false) {} + var neededSegments = getNeededSegments({ + content: content, + currentPlaybackTime: tick.getCurrentTime(), + fastSwitchThreshold: fastSwitchThreshold, + neededRange: neededRange, + bufferedSegments: bufferedSegments, + segmentsBeingPushed: segmentsBeingPushed + }).map(function (segment) { + return { + priority: getSegmentPriority(segment.time, tick), + segment: segment + }; + }); + /** + * `true` if the current `RepresentationStream` has loaded all the + * needed segments for this Representation until the end of the Period. + */ - responseData = new Uint8Array(0); - } + var hasFinishedLoading; + var lastPosition = representation.index.getLastPosition(); - return (0,of.of)({ - type: "data-created", - value: { - responseData: responseData - } - }); - } else if (url === null) { - return (0,of.of)({ - type: "data-created", - value: { - responseData: null - } - }); + if (!representation.index.isInitialized() || period.end === undefined || neededSegments.length > 0) { + hasFinishedLoading = false; + } else { + if (lastPosition === undefined) { + // We do not know the end of this index. + // If we reached the end of the period, check that all segments are + // available. + hasFinishedLoading = neededRange.end >= period.end && representation.index.isFinished(); + } else if (lastPosition === null) { + // There is no available segment in the index currently. If the index + // tells us it has finished generating new segments, we're done. + hasFinishedLoading = representation.index.isFinished(); } else { - var args = { - adaptation: adaptation, - manifest: manifest, - period: period, - representation: representation, - segment: segment, - transport: "smooth", - url: url - }; - - if (typeof customSegmentLoader !== "function") { - return regularSegmentLoader(args); - } - - return new Observable/* Observable */.y(function (obs) { - var hasFinished = false; - var hasFallbacked = false; - /** - * Callback triggered when the custom segment loader has a response. - * @param {Object} args - */ - - var resolve = function resolve(_args) { - if (!hasFallbacked) { - hasFinished = true; - obs.next({ - type: "data-loaded", - value: { - responseData: _args.data, - size: _args.size, - duration: _args.duration - } - }); - obs.complete(); - } - }; - /** - * Callback triggered when the custom segment loader fails - * @param {*} err - The corresponding error encountered - */ + // We have a declared end. Check that our range went until the last + // position available in the index. If that's the case and we're left + // with no segments after filtering them, it means we already have + // downloaded the last segments and have nothing left to do: full. + var endOfRange = period.end !== undefined ? Math.min(period.end, lastPosition) : lastPosition; + hasFinishedLoading = neededRange.end >= endOfRange && representation.index.isFinished(); + } + } + var imminentDiscontinuity; - var reject = function reject(err) { - if (err === void 0) { - err = {}; - } + if (!representation.index.isInitialized() || // TODO better handle contents not chronologically generated + !representation.index.areSegmentsChronologicallyGenerated() && !hasFinishedLoading) { + // We might be missing information about future segments + imminentDiscontinuity = null; + } else { + /** + * Start time in seconds of the next available not-yet pushed segment. + * `null` if no segment is wanted for the current wanted range. + */ + var nextSegmentStart = null; - if (!hasFallbacked) { - hasFinished = true; - obs.error(err); - } - }; + if (segmentsBeingPushed.length > 0) { + nextSegmentStart = Math.min.apply(Math, segmentsBeingPushed.map(function (info) { + return info.segment.time; + })); + } - var progress = function progress(_args) { - if (!hasFallbacked) { - obs.next({ - type: "progress", - value: { - duration: _args.duration, - size: _args.size, - totalSize: _args.totalSize - } - }); - } - }; + if (neededSegments.length > 0) { + nextSegmentStart = nextSegmentStart !== null ? Math.min(nextSegmentStart, neededSegments[0].segment.time) : neededSegments[0].segment.time; + } - var fallback = function fallback() { - hasFallbacked = true; // HACK What is TypeScript/RxJS doing here?????? + imminentDiscontinuity = checkForDiscontinuity(content, neededRange, nextSegmentStart, hasFinishedLoading, bufferedSegments); + } - /* eslint-disable import/no-deprecated */ + return { + imminentDiscontinuity: imminentDiscontinuity, + hasFinishedLoading: hasFinishedLoading, + neededSegments: neededSegments, + shouldRefreshManifest: shouldRefreshManifest + }; +} +/** + * From the given SegmentInventory, filters the "playable" (in a supported codec + * and not known to be undecipherable) buffered Segment Objects which overlap + * with the given range. + * @param {Object} neededRange + * @param {Array.} segmentInventory + * @returns {Array.} + */ - /* eslint-disable @typescript-eslint/ban-ts-comment */ - // @ts-ignore +function getPlayableBufferedSegments(neededRange, segmentInventory) { + var segmentRoundingError = Math.max(1 / 60, get_buffer_status_MINIMUM_SEGMENT_SIZE); + var minEnd = neededRange.start + segmentRoundingError; + var maxStart = neededRange.end - segmentRoundingError; + var overlappingChunks = []; - regularSegmentLoader(args).subscribe(obs); - /* eslint-enable import/no-deprecated */ + for (var i = segmentInventory.length - 1; i >= 0; i--) { + var eltInventory = segmentInventory[i]; + var representation = eltInventory.infos.representation; - /* eslint-enable @typescript-eslint/ban-ts-comment */ - }; + if (!eltInventory.partiallyPushed && representation.decipherable !== false && representation.isSupported) { + var inventorySegment = eltInventory.infos.segment; + var eltInventoryStart = inventorySegment.time / inventorySegment.timescale; + var eltInventoryEnd = inventorySegment.duration == null ? eltInventory.end : eltInventoryStart + inventorySegment.duration / inventorySegment.timescale; - var callbacks = { - reject: reject, - resolve: resolve, - fallback: fallback, - progress: progress - }; - var abort = customSegmentLoader(args, callbacks); - return function () { - if (!hasFinished && !hasFallbacked && typeof abort === "function") { - abort(); - } - }; - }); + if (eltInventoryEnd > minEnd && eltInventoryStart < maxStart || eltInventory.end > minEnd && eltInventory.start < maxStart) { + overlappingChunks.unshift(eltInventory); + } } - }; -}; + } -/* harmony default export */ const segment_loader = (generateSegmentLoader); -;// CONCATENATED MODULE: ./src/transports/smooth/utils.ts + return overlappingChunks; +} +;// CONCATENATED MODULE: ./src/core/stream/representation/force_garbage_collection.ts /** * Copyright 2015 CANAL+ Group * @@ -47765,70 +50314,96 @@ var generateSegmentLoader = function generateSegmentLoader(customSegmentLoader) */ -var ISM_REG = /(\.isml?)(\?token=\S+)?$/; -var TOKEN_REG = /\?token=(\S+)/; + + + +var GC_GAP_CALM = config/* default.BUFFER_GC_GAPS.CALM */.Z.BUFFER_GC_GAPS.CALM; +var GC_GAP_BEEFY = config/* default.BUFFER_GC_GAPS.BEEFY */.Z.BUFFER_GC_GAPS.BEEFY; /** - * TODO Remove this logic completely from the player - * @param {Document} doc - * @returns {string|null} + * Run the garbage collector. + * + * Try to clean up buffered ranges from a low gcGap at first. + * If it does not succeed to clean up space, use a higher gcCap. + * + * @param {Observable} timings$ + * @param {Object} bufferingQueue + * @returns {Observable} */ -function extractISML(doc) { - return doc.getElementsByTagName("media")[0].getAttribute("src"); +function forceGarbageCollection(timings$, bufferingQueue) { + // wait for next timing event + return timings$.pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.zg)(function (timing) { + log/* default.warn */.Z.warn("Stream: Running garbage collector"); + var buffered = bufferingQueue.getBufferedRanges(); + var cleanedupRanges = selectGCedRanges(timing.position, buffered, GC_GAP_CALM); // more aggressive GC if we could not find any range to clean + + if (cleanedupRanges.length === 0) { + cleanedupRanges = selectGCedRanges(timing.position, buffered, GC_GAP_BEEFY); + } + + log/* default.debug */.Z.debug("Stream: GC cleaning", cleanedupRanges); + return (0,from/* from */.D)(cleanedupRanges.map(function (_ref) { + var start = _ref.start, + end = _ref.end; + return bufferingQueue.removeBuffer(start, end); + })).pipe((0,concatAll/* concatAll */.u)()); + })); } /** - * Returns string corresponding to the token contained in the url's querystring. - * Empty string if no token is found. - * @param {string} url - * @returns {string} + * Buffer garbage collector algorithm. + * + * Tries to free up some part of the ranges that are distant from the current + * playing time. + * See: https://w3c.github.io/media-source/#sourcebuffer-prepare-append + * + * @param {Number} position + * @param {TimeRanges} buffered - current buffered ranges + * @param {Number} gcGap - delta gap from current timestamp from which we + * should consider cleaning up. + * @returns {Array.} - Ranges selected for clean up */ +function selectGCedRanges(position, buffered, gcGap) { + var _getInnerAndOuterTime = (0,ranges/* getInnerAndOuterTimeRanges */.F_)(buffered, position), + innerRange = _getInnerAndOuterTime.innerRange, + outerRanges = _getInnerAndOuterTime.outerRanges; -function extractToken(url) { - var tokenMatch = TOKEN_REG.exec(url); + var cleanedupRanges = []; // start by trying to remove all ranges that do not contain the + // current time and respect the gcGap + // respect the gcGap? FIXME? - if (tokenMatch !== null) { - var match = tokenMatch[1]; + for (var i = 0; i < outerRanges.length; i++) { + var outerRange = outerRanges[i]; - if (match !== undefined) { - return match; + if (position - gcGap < outerRange.end) { + cleanedupRanges.push(outerRange); + } else if (position + gcGap > outerRange.start) { + cleanedupRanges.push(outerRange); } - } - - return ""; -} -/** - * Replace/Remove token from the url's querystring - * @param {string} url - * @param {string} [token] - * @returns {string} - */ + } // try to clean up some space in the current range -function replaceToken(url, token) { - if ((0,is_non_empty_string/* default */.Z)(token)) { - return url.replace(TOKEN_REG, "?token=" + token); - } else { - return url.replace(TOKEN_REG, ""); - } -} -/** - * @param {string} url - * @returns {string} - */ + if (innerRange != null) { + log/* default.debug */.Z.debug("Stream: GC removing part of inner range", cleanedupRanges); + if (position - gcGap > innerRange.start) { + cleanedupRanges.push({ + start: innerRange.start, + end: position - gcGap + }); + } -function resolveManifest(url) { - if (ISM_REG.test(url)) { - (0,warn_once/* default */.Z)("Giving a isml URL to loadVideo is deprecated." + " Please give the Manifest URL directly"); - return url.replace(ISM_REG, "$1/manifest$2"); + if (position + gcGap < innerRange.end) { + cleanedupRanges.push({ + start: position + gcGap, + end: innerRange.end + }); + } } - return url; + return cleanedupRanges; } - - -;// CONCATENATED MODULE: ./src/transports/smooth/pipelines.ts +;// CONCATENATED MODULE: ./src/core/stream/representation/append_segment_to_buffer.ts /** * Copyright 2015 CANAL+ Group * @@ -47845,503 +50420,566 @@ function resolveManifest(url) { * limitations under the License. */ +/** + * This file allows any Stream to push data to a SegmentBuffer. + */ +/** + * 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} clock$ + * @param {Object} segmentBuffer + * @param {Object} dataInfos + * @returns {Observable} + */ +function appendSegmentToBuffer(clock$, segmentBuffer, dataInfos) { + var append$ = segmentBuffer.pushChunk(dataInfos); + return append$.pipe((0,catchError/* catchError */.K)(function (appendError) { + if (!(appendError instanceof Error) || appendError.name !== "QuotaExceededError") { + var reason = appendError instanceof Error ? appendError.toString() : "An unknown error happened when pushing content"; + throw new media_error/* default */.Z("BUFFER_APPEND_ERROR", reason); + } + return (0,concat/* concat */.z)(forceGarbageCollection(clock$, segmentBuffer).pipe((0,ignoreElements/* ignoreElements */.l)()), append$).pipe((0,catchError/* catchError */.K)(function (forcedGCError) { + var reason = forcedGCError instanceof Error ? forcedGCError.toString() : "Could not clean the buffer"; + throw new media_error/* default */.Z("BUFFER_FULL_ERROR", reason); + })); + })); +} +;// CONCATENATED MODULE: ./src/core/stream/representation/push_init_segment.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 WSX_REG = /\.wsx?(\?token=\S+)?/; /** - * @param {Object} adaptation - * @param {Object} dlSegment - * @param {Object} nextSegments + * 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} */ -function addNextSegments(adaptation, nextSegments, dlSegment) { - var _a; - - log/* default.debug */.Z.debug("Smooth Parser: update segments information."); - var representations = adaptation.representations; - - for (var i = 0; i < representations.length; i++) { - var representation = representations[i]; - - if (representation.index instanceof SmoothRepresentationIndex && ((_a = dlSegment === null || dlSegment === void 0 ? void 0 : dlSegment.privateInfos) === null || _a === void 0 ? void 0 : _a.smoothMediaSegment) !== undefined) { - representation.index._addSegments(nextSegments, dlSegment.privateInfos.smoothMediaSegment); - } else { - log/* default.warn */.Z.warn("Smooth Parser: should only encounter SmoothRepresentationIndex"); +function pushInitSegment(_ref) { + var clock$ = _ref.clock$, + 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; } - } -} -/* harmony default export */ function pipelines(options) { - var smoothManifestParser = smooth(options); - var segmentLoader = segment_loader(options.segmentLoader); - var manifestLoaderOptions = { - customManifestLoader: options.manifestLoader - }; - var manifestLoader = (0,text_manifest_loader/* default */.Z)(manifestLoaderOptions); - var manifestPipeline = { - resolver: function resolver(_ref) { - var url = _ref.url; + var codec = content.representation.getMimeTypeString(); + var data = { + initSegment: segmentData, + chunk: null, + timestampOffset: 0, + appendWindow: [undefined, undefined], + codec: codec + }; + return appendSegmentToBuffer(clock$, segmentBuffer, { + data: data, + inventoryInfos: null + }).pipe((0,map/* map */.U)(function () { + var buffered = segmentBuffer.getBufferedRanges(); + return stream_events_generators.addedSegment(content, segment, buffered, segmentData); + })); + }); +} +;// CONCATENATED MODULE: ./src/core/stream/representation/push_media_segment.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. + */ - if (url === undefined) { - return (0,of.of)({ - url: undefined - }); - } // TODO Remove WSX logic - var resolving; - if (WSX_REG.test(url)) { - (0,warn_once/* default */.Z)("Giving WSX URL to loadVideo is deprecated." + " You should only give Manifest URLs."); - resolving = (0,request/* default */.ZP)({ - url: replaceToken(url, ""), - responseType: "document" - }).pipe((0,map/* map */.U)(function (_ref2) { - var value = _ref2.value; - var extractedURL = extractISML(value.responseData); - if (extractedURL === null || extractedURL.length === 0) { - throw new Error("Invalid ISML"); - } - return extractedURL; - })); - } else { - resolving = (0,of.of)(url); - } +var APPEND_WINDOW_SECURITIES = config/* default.APPEND_WINDOW_SECURITIES */.Z.APPEND_WINDOW_SECURITIES; +/** + * 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} + */ - var token = extractToken(url); - return resolving.pipe((0,map/* map */.U)(function (_url) { - return { - url: replaceToken(resolveManifest(_url), token) - }; - })); - }, - loader: manifestLoader, - parser: function parser(_ref3) { - var response = _ref3.response, - reqURL = _ref3.url; - var url = response.url === undefined ? reqURL : response.url; - var data = typeof response.responseData === "string" ? new DOMParser().parseFromString(response.responseData, "text/xml") : response.responseData; // TODO find a way to check if Document? +function pushMediaSegment(_ref) { + var clock$ = _ref.clock$, + content = _ref.content, + initSegmentData = _ref.initSegmentData, + parsedSegment = _ref.parsedSegment, + segment = _ref.segment, + segmentBuffer = _ref.segmentBuffer; + return (0,defer/* defer */.P)(function () { + var _a, _b; - var manifestReceivedTime = response.receivedTime; - var parserResult = smoothManifestParser(data, url, manifestReceivedTime); - var manifest = new src_manifest/* default */.ZP(parserResult, { - representationFilter: options.representationFilter, - supplementaryImageTracks: options.supplementaryImageTracks, - supplementaryTextTracks: options.supplementaryTextTracks - }); - return (0,return_parsed_manifest/* default */.Z)(manifest, url); + if (parsedSegment.chunkData === null) { + return empty/* EMPTY */.E; } - }; - var segmentPipeline = { - loader: function loader(content) { - if (content.segment.isInit || options.checkMediaSegmentIntegrity !== true) { - return segmentLoader(content); - } - return segmentLoader(content).pipe((0,tap/* tap */.b)(function (res) { - if ((res.type === "data-loaded" || res.type === "data-chunk") && res.value.responseData !== null) { - (0,check_isobmff_integrity/* default */.Z)(new Uint8Array(res.value.responseData), content.segment.isInit); - } - })); - }, - parser: function parser(_ref4) { - var content = _ref4.content, - response = _ref4.response, - initTimescale = _ref4.initTimescale; + var chunkData = parsedSegment.chunkData, + chunkInfos = parsedSegment.chunkInfos, + chunkOffset = parsedSegment.chunkOffset, + appendWindow = parsedSegment.appendWindow; + var codec = content.representation.getMimeTypeString(); // 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 _a, _b; + 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; - var segment = content.segment, - representation = content.representation, - adaptation = content.adaptation, - manifest = content.manifest; - var data = response.data, - isChunked = response.isChunked; + if (safeAppendWindow[0] !== undefined) { + estimatedStart = Math.max(estimatedStart, safeAppendWindow[0]); + } - if (data === null) { - if (segment.isInit) { - var segmentProtections = representation.getProtectionsInitializationData(); - return (0,of.of)({ - type: "parsed-init-segment", - value: { - initializationData: null, - segmentProtections: segmentProtections, - initTimescale: undefined - } - }); - } + if (safeAppendWindow[1] !== undefined) { + estimatedEnd = Math.min(estimatedEnd, safeAppendWindow[1]); + } - return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: null, - chunkInfos: null, - chunkOffset: 0, - appendWindow: [undefined, undefined] - } - }); - } + var inventoryInfos = (0,object_assign/* default */.Z)({ + segment: segment, + start: estimatedStart, + end: estimatedEnd + }, content); + return appendSegmentToBuffer(clock$, segmentBuffer, { + data: data, + inventoryInfos: inventoryInfos + }).pipe((0,map/* map */.U)(function () { + var buffered = segmentBuffer.getBufferedRanges(); + return stream_events_generators.addedSegment(content, segment, buffered, chunkData); + })); + }); +} +;// CONCATENATED MODULE: ./src/core/stream/representation/representation_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. + */ - var responseBuffer = data instanceof Uint8Array ? data : new Uint8Array(data); +/** + * This file allows to create RepresentationStreams. + * + * A RepresentationStream downloads and push segment for a single + * Representation (e.g. a single video stream of a given quality). + * It chooses which segments should be downloaded according to the current + * position and what is currently buffered. + */ - if (segment.isInit) { - var psshInfo = (0,take_pssh_out/* default */.Z)(responseBuffer); - if (psshInfo.length > 0) { - for (var i = 0; i < psshInfo.length; i++) { - var _psshInfo$i = psshInfo[i], - systemID = _psshInfo$i.systemID, - psshData = _psshInfo$i.data; - representation._addProtectionData("cenc", systemID, psshData); - } - } - var _segmentProtections = representation.getProtectionsInitializationData(); - var timescale = (_b = (_a = segment.privateInfos) === null || _a === void 0 ? void 0 : _a.smoothInitSegment) === null || _b === void 0 ? void 0 : _b.timescale; - return (0,of.of)({ - type: "parsed-init-segment", - value: { - initializationData: data, - // smooth init segments are crafted by hand. - // Their timescale is the one from the manifest. - initTimescale: timescale, - segmentProtections: _segmentProtections - } - }); - } - var timingInfos = initTimescale !== undefined ? extractTimingsInfos(responseBuffer, isChunked, initTimescale, segment, manifest.isLive) : null; - if (timingInfos === null || timingInfos.chunkInfos === null || timingInfos.scaledSegmentTime === undefined) { - throw new Error("Smooth Segment without time information"); - } - var nextSegments = timingInfos.nextSegments, - chunkInfos = timingInfos.chunkInfos, - scaledSegmentTime = timingInfos.scaledSegmentTime; - var chunkData = patchSegment(responseBuffer, scaledSegmentTime); - if (nextSegments.length > 0) { - addNextSegments(adaptation, nextSegments, segment); - } - return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: chunkData, - chunkInfos: chunkInfos, - chunkOffset: 0, - appendWindow: [undefined, undefined] - } - }); - } - }; - var textTrackPipeline = { - loader: function loader(_ref5) { - var segment = _ref5.segment, - representation = _ref5.representation, - url = _ref5.url; - if (segment.isInit || url === null) { - return (0,of.of)({ - type: "data-created", - value: { - responseData: null - } - }); - } +/** + * Build up buffer for a single Representation. + * + * Download and push segments linked to the given Representation according + * to what is already in the SegmentBuffer and where the playback currently is. + * + * Multiple RepresentationStream observables can run on the same SegmentBuffer. + * This allows for example smooth transitions between multiple periods. + * + * @param {Object} args + * @returns {Observable} + */ - var isMP4 = isMP4EmbeddedTrack(representation); +function RepresentationStream(_ref) { + var clock$ = _ref.clock$, + content = _ref.content, + segmentBuffer = _ref.segmentBuffer, + segmentFetcher = _ref.segmentFetcher, + terminate$ = _ref.terminate$, + options = _ref.options; + var manifest = content.manifest, + period = content.period, + adaptation = content.adaptation, + representation = content.representation; + var bufferGoal$ = options.bufferGoal$, + drmSystemId = options.drmSystemId, + fastSwitchThreshold$ = options.fastSwitchThreshold$; + var bufferType = adaptation.type; + var initSegment = representation.index.getInitSegment(); + /** + * Saved initialization segment state for this representation. + * `null` if the initialization segment hasn't been loaded yet. + */ - if (!isMP4 || options.checkMediaSegmentIntegrity !== true) { - return (0,request/* default */.ZP)({ - url: url, - responseType: isMP4 ? "arraybuffer" : "text", - sendProgressEvents: true - }); - } + var initSegmentObject = initSegment === null ? { + initializationData: null, + protectionDataUpdate: false, + initTimescale: undefined + } : null; + /** Segments queued for download in this RepresentationStream. */ - return (0,request/* default */.ZP)({ - url: url, - responseType: "arraybuffer", - sendProgressEvents: true - }).pipe((0,tap/* tap */.b)(function (res) { - if (res.type === "data-loaded") { - (0,check_isobmff_integrity/* default */.Z)(new Uint8Array(res.value.responseData), segment.isInit); - } - })); - }, - parser: function parser(_ref6) { - var content = _ref6.content, - response = _ref6.response, - initTimescale = _ref6.initTimescale; + var downloadQueue = []; + /** Emit to start/restart a downloading Queue. */ - var _a; + var startDownloadingQueue$ = new ReplaySubject/* ReplaySubject */.t(1); + /** Emit when the RepresentationStream asks to re-check which segments are needed. */ - var manifest = content.manifest, - adaptation = content.adaptation, - representation = content.representation, - segment = content.segment; - var language = adaptation.language; - var isMP4 = isMP4EmbeddedTrack(representation); - var _representation$mimeT = representation.mimeType, - mimeType = _representation$mimeT === void 0 ? "" : _representation$mimeT, - _representation$codec = representation.codec, - codec = _representation$codec === void 0 ? "" : _representation$codec; - var data = response.data, - isChunked = response.isChunked; + var reCheckNeededSegments$ = new Subject/* Subject */.xQ(); + /** + * Keep track of the information about the pending segment request. + * `null` if no segment request is pending in that RepresentationStream. + */ - if (segment.isInit) { - // text init segment has no use in HSS - return (0,of.of)({ - type: "parsed-init-segment", - value: { - initializationData: null, - segmentProtections: [], - initTimescale: undefined - } - }); - } + var currentSegmentRequest = null; + var status$ = (0,combineLatest/* combineLatest */.aj)([clock$, bufferGoal$, terminate$.pipe((0,take/* take */.q)(1), (0,startWith/* startWith */.O)(null)), reCheckNeededSegments$.pipe((0,startWith/* startWith */.O)(undefined))]).pipe(withLatestFrom(fastSwitchThreshold$), (0,mergeMap/* mergeMap */.zg)(function (_ref2) { + var _ref2$ = _ref2[0], + tick = _ref2$[0], + bufferGoal = _ref2$[1], + terminate = _ref2$[2], + fastSwitchThreshold = _ref2[1]; + var status = getBufferStatus(content, tick, fastSwitchThreshold, bufferGoal, segmentBuffer); + var neededSegments = status.neededSegments; // Add initialization segment if required - if (data === null) { - return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: null, - chunkInfos: null, - chunkOffset: 0, - appendWindow: [undefined, undefined] - } + if (!representation.index.isInitialized()) { + if (initSegment === null) { + log/* default.warn */.Z.warn("Stream: Uninitialized index without an initialization segment"); + } else if (initSegmentObject !== null) { + log/* default.warn */.Z.warn("Stream: Uninitialized index with an already loaded " + "initialization segment"); + } else { + neededSegments.unshift({ + segment: initSegment, + priority: getSegmentPriority(period.start, tick) }); } + } else if (neededSegments.length > 0 && initSegment !== null && initSegmentObject === null) { + // prepend initialization segment + var initSegmentPriority = neededSegments[0].priority; + neededSegments.unshift({ + segment: initSegment, + priority: initSegmentPriority + }); + } - var nextSegments; - var chunkInfos = null; - var segmentStart; - var segmentEnd; + var mostNeededSegment = neededSegments[0]; - var _sdData; + if (terminate !== null) { + downloadQueue = []; - var _sdType; + if (terminate.urgent) { + log/* default.debug */.Z.debug("Stream: urgent termination request, terminate.", bufferType); + startDownloadingQueue$.next(); // interrupt current requests - if (isMP4) { - var chunkBytes; + startDownloadingQueue$.complete(); // complete the downloading queue - if (typeof data === "string") { - chunkBytes = (0,string_parsing/* strToUtf8 */.tG)(data); - } else { - chunkBytes = data instanceof Uint8Array ? data : new Uint8Array(data); - } + return (0,of.of)(stream_events_generators.streamTerminating()); + } else if (currentSegmentRequest === null || mostNeededSegment === undefined || currentSegmentRequest.segment.id !== mostNeededSegment.segment.id) { + log/* default.debug */.Z.debug("Stream: cancel request and terminate.", currentSegmentRequest === null, bufferType); + startDownloadingQueue$.next(); // interrupt the current request - var timingInfos = initTimescale !== undefined ? extractTimingsInfos(chunkBytes, isChunked, initTimescale, segment, manifest.isLive) : null; - nextSegments = timingInfos === null || timingInfos === void 0 ? void 0 : timingInfos.nextSegments; - chunkInfos = (_a = timingInfos === null || timingInfos === void 0 ? void 0 : timingInfos.chunkInfos) !== null && _a !== void 0 ? _a : null; + startDownloadingQueue$.complete(); // complete the downloading queue - if (chunkInfos === null) { - if (isChunked) { - log/* default.warn */.Z.warn("Smooth: Unavailable time data for current text track."); - } else { - segmentStart = segment.time; - segmentEnd = segment.end; - } - } else { - segmentStart = chunkInfos.time; - segmentEnd = chunkInfos.duration !== undefined ? chunkInfos.time + chunkInfos.duration : segment.end; - } + return (0,of.of)(stream_events_generators.streamTerminating()); + } else if (currentSegmentRequest.priority !== mostNeededSegment.priority) { + var _currentSegmentReques = currentSegmentRequest, + request$ = _currentSegmentReques.request$; + currentSegmentRequest.priority = mostNeededSegment.priority; + segmentFetcher.updatePriority(request$, mostNeededSegment.priority); + } - var lcCodec = codec.toLowerCase(); + log/* default.debug */.Z.debug("Stream: terminate after request.", bufferType); + } else if (mostNeededSegment === undefined) { + if (currentSegmentRequest !== null) { + log/* default.debug */.Z.debug("Stream: interrupt segment request.", bufferType); + } - if (mimeType === "application/ttml+xml+mp4" || lcCodec === "stpp" || lcCodec === "stpp.ttml.im1t") { - _sdType = "ttml"; - } else if (lcCodec === "wvtt") { - _sdType = "vtt"; - } else { - throw new Error("could not find a text-track parser for the type " + mimeType); - } + downloadQueue = []; + startDownloadingQueue$.next(); // (re-)start with an empty queue + } else if (currentSegmentRequest === null) { + log/* default.debug */.Z.debug("Stream: start downloading queue.", bufferType); + downloadQueue = neededSegments; + startDownloadingQueue$.next(); // restart the queue + } else if (currentSegmentRequest.segment.id !== mostNeededSegment.segment.id) { + log/* default.debug */.Z.debug("Stream: restart download queue.", bufferType); + downloadQueue = neededSegments; + startDownloadingQueue$.next(); // restart the queue + } else if (currentSegmentRequest.priority !== mostNeededSegment.priority) { + log/* default.debug */.Z.debug("Stream: update request priority.", bufferType); + var _currentSegmentReques2 = currentSegmentRequest, + _request$ = _currentSegmentReques2.request$; + currentSegmentRequest.priority = mostNeededSegment.priority; + segmentFetcher.updatePriority(_request$, mostNeededSegment.priority); + } else { + log/* default.debug */.Z.debug("Stream: update downloading queue", bufferType); // Update the previous queue to be all needed segments but the first one, + // for which a request is already pending - var mdat = (0,read/* getMDAT */.Le)(chunkBytes); - _sdData = mdat === null ? "" : (0,string_parsing/* utf8ToStr */.uR)(mdat); - } else { - // not MP4 - segmentStart = segment.time; - segmentEnd = segment.end; - var chunkString; + downloadQueue = neededSegments.slice().splice(1, neededSegments.length); + } - if (typeof data !== "string") { - var bytesData = data instanceof Uint8Array ? data : new Uint8Array(data); - chunkString = (0,string_parsing/* utf8ToStr */.uR)(bytesData); - } else { - chunkString = data; - } + var bufferStatusEvt = (0,of.of)({ + type: "stream-status", + value: { + period: period, + position: tick.position, + bufferType: bufferType, + imminentDiscontinuity: status.imminentDiscontinuity, + hasFinishedLoading: status.hasFinishedLoading, + neededSegments: status.neededSegments + } + }); + return status.shouldRefreshManifest ? (0,concat/* concat */.z)((0,of.of)(stream_events_generators.needsManifestRefresh()), bufferStatusEvt) : bufferStatusEvt; + }), takeWhile(function (e) { + return e.type !== "stream-terminating"; + }, true)); + /** + * `true` if the event notifying about encryption data has already been + * constructed. + * Allows to avoid sending multiple times protection events. + */ - switch (mimeType) { - case "application/x-sami": - case "application/smil": - // TODO SMIL should be its own format, no? - _sdType = "sami"; - break; + var hasSentEncryptionData = false; + var encryptionEvent$ = empty/* EMPTY */.E; - case "application/ttml+xml": - _sdType = "ttml"; - break; + if (drmSystemId !== undefined) { + var encryptionData = representation.getEncryptionData(drmSystemId); - case "text/vtt": - _sdType = "vtt"; - break; - } + if (encryptionData.length > 0) { + encryptionEvent$ = of.of.apply(void 0, encryptionData.map(function (d) { + return stream_events_generators.encryptionDataEncountered(d); + })); + hasSentEncryptionData = true; + } + } + /** + * Stream Queue: + * - download every segments queued sequentially + * - when a segment is loaded, append it to the SegmentBuffer + */ - if (_sdType === undefined) { - var _lcCodec = codec.toLowerCase(); - if (_lcCodec === "srt") { - _sdType = "srt"; - } else { - throw new Error("could not find a text-track parser for the type " + mimeType); - } - } + var streamQueue$ = startDownloadingQueue$.pipe((0,switchMap/* switchMap */.w)(function () { + return downloadQueue.length > 0 ? loadSegmentsFromQueue() : empty/* EMPTY */.E; + }), (0,mergeMap/* mergeMap */.zg)(onLoaderEvent)); + return (0,concat/* concat */.z)(encryptionEvent$, (0,merge/* merge */.T)(status$, streamQueue$).pipe((0,share/* share */.B)())); + /** + * Request every Segment in the ``downloadQueue`` on subscription. + * Emit the data of a segment when a request succeeded. + * + * Important side-effects: + * - Mutates `currentSegmentRequest` when doing and finishing a request. + * - Will emit from reCheckNeededSegments$ Subject when it's done. + * + * Might emit warnings when a request is retried. + * + * Throws when the request will not be retried (configuration or un-retryable + * error). + * @returns {Observable} + */ - _sdData = chunkString; - } + function loadSegmentsFromQueue() { + var requestNextSegment$ = (0,defer/* defer */.P)(function () { + var currentNeededSegment = downloadQueue.shift(); - if (chunkInfos !== null && Array.isArray(nextSegments) && nextSegments.length > 0) { - addNextSegments(adaptation, nextSegments, segment); + if (currentNeededSegment === undefined) { + next_tick_default()(function () { + reCheckNeededSegments$.next(); + }); + return empty/* EMPTY */.E; } - var chunkOffset = segmentStart !== null && segmentStart !== void 0 ? segmentStart : 0; - return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: { - type: _sdType, - data: _sdData, - start: segmentStart, - end: segmentEnd, - language: language - }, - chunkInfos: chunkInfos, - chunkOffset: chunkOffset, - appendWindow: [undefined, undefined] - } - }); - } - }; - var imageTrackPipeline = { - loader: function loader(_ref7) { - var segment = _ref7.segment, - url = _ref7.url; + var segment = currentNeededSegment.segment, + priority = currentNeededSegment.priority; + var context = { + manifest: manifest, + period: period, + adaptation: adaptation, + representation: representation, + segment: segment + }; + var request$ = segmentFetcher.createRequest(context, priority); + currentSegmentRequest = { + segment: segment, + priority: priority, + request$: request$ + }; + return request$.pipe((0,mergeMap/* mergeMap */.zg)(function (evt) { + switch (evt.type) { + case "warning": + return (0,of.of)({ + type: "retry", + value: { + segment: segment, + error: evt.value + } + }); - if (segment.isInit || url === null) { - // image do not need an init segment. Passthrough directly to the parser - return (0,of.of)({ - type: "data-created", - value: { - responseData: null - } - }); - } + case "chunk-complete": + currentSegmentRequest = null; + return (0,of.of)({ + type: "end-of-segment", + value: { + segment: segment + } + }); - return (0,request/* default */.ZP)({ - url: url, - responseType: "arraybuffer", - sendProgressEvents: true - }); - }, - parser: function parser(_ref8) { - var response = _ref8.response, - content = _ref8.content; - var data = response.data, - isChunked = response.isChunked; + case "interrupted": + log/* default.info */.Z.info("Stream: segment request interrupted temporarly.", segment); + return empty/* EMPTY */.E; - if (content.segment.isInit) { - // image init segment has no use - return (0,of.of)({ - type: "parsed-init-segment", - value: { - initializationData: null, - segmentProtections: [], - initTimescale: undefined - } - }); - } + case "chunk": + var initTimescale = initSegmentObject === null || initSegmentObject === void 0 ? void 0 : initSegmentObject.initTimescale; + return evt.parse(initTimescale).pipe((0,map/* map */.U)(function (parserResponse) { + return (0,object_assign/* default */.Z)({ + segment: segment + }, parserResponse); + })); - if (isChunked) { - throw new Error("Image data should not be downloaded in chunks"); - } // TODO image Parsing should be more on the buffer side, no? + case "ended": + return requestNextSegment$; + + default: + (0,assert_unreachable/* default */.Z)(evt); + } + })); + }); + return requestNextSegment$.pipe(finalize(function () { + currentSegmentRequest = null; + })); + } + /** + * React to event from `loadSegmentsFromQueue`. + * @param {Object} evt + * @returns {Observable} + */ - if (data === null || features/* default.imageParser */.Z.imageParser === null) { - return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: null, - chunkInfos: null, - chunkOffset: 0, - appendWindow: [undefined, undefined] + function onLoaderEvent(evt) { + var _a; + + 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.manifestMightBeOufOfSync()); } - }); - } - var bifObject = features/* default.imageParser */.Z.imageParser(new Uint8Array(data)); - var thumbsData = bifObject.thumbs; - return (0,of.of)({ - type: "parsed-segment", - value: { - chunkData: { - data: thumbsData, - start: 0, - end: Number.MAX_VALUE, - timescale: 1, - type: "bif" - }, - chunkInfos: { - time: 0, - duration: Number.MAX_VALUE, - timescale: bifObject.timescale - }, - chunkOffset: 0, - segmentProtections: [], - appendWindow: [undefined, undefined] + return empty/* EMPTY */.E; // else, ignore. + })); + + case "parsed-init-segment": + initSegmentObject = evt.value; // 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.encryptionDataEncountered(p); + })) : empty/* EMPTY */.E; + var pushEvent$ = pushInitSegment({ + clock$: clock$, + content: content, + segment: evt.segment, + segmentData: evt.value.initializationData, + segmentBuffer: segmentBuffer + }); + return (0,merge/* merge */.T)(initEncEvt$, pushEvent$); + + case "parsed-segment": + var initSegmentData = (_a = initSegmentObject === null || initSegmentObject === void 0 ? void 0 : initSegmentObject.initializationData) !== null && _a !== void 0 ? _a : null; + var _evt$value = evt.value, + inbandEvents = _evt$value.inbandEvents, + needsManifestRefresh = _evt$value.needsManifestRefresh; + var manifestRefresh$ = needsManifestRefresh === true ? (0,of.of)(stream_events_generators.needsManifestRefresh()) : empty/* EMPTY */.E; + var inbandEvents$ = inbandEvents !== undefined && inbandEvents.length > 0 ? (0,of.of)({ + type: "inband-events", + value: inbandEvents + }) : empty/* EMPTY */.E; + return (0,concat/* concat */.z)(manifestRefresh$, inbandEvents$, pushMediaSegment({ + clock$: clock$, + content: content, + initSegmentData: initSegmentData, + parsedSegment: evt.value, + segment: evt.segment, + segmentBuffer: segmentBuffer + })); + + case "end-of-segment": + { + var segment = evt.value.segment; + return segmentBuffer.endOfSegment((0,object_assign/* default */.Z)({ + segment: segment + }, content)).pipe((0,ignoreElements/* ignoreElements */.l)()); } - }); - } - }; - return { - manifest: manifestPipeline, - audio: segmentPipeline, - video: segmentPipeline, - text: textTrackPipeline, - image: imageTrackPipeline - }; -} -/** - * Returns true if the given texttrack segment represents a textrack embedded - * in a mp4 file. - * @param {Representation} representation - * @returns {Boolean} - */ -function isMP4EmbeddedTrack(representation) { - return typeof representation.mimeType === "string" && representation.mimeType.indexOf("mp4") >= 0; + default: + (0,assert_unreachable/* default */.Z)(evt); + } + } } -;// CONCATENATED MODULE: ./src/transports/smooth/index.ts +;// CONCATENATED MODULE: ./src/core/stream/representation/index.ts /** * Copyright 2015 CANAL+ Group * @@ -48358,22 +50996,8 @@ function isMP4EmbeddedTrack(representation) { * limitations under the License. */ -/** - * /!\ This file is feature-switchable. - * It always should be imported through the `features` object. - */ - -/* harmony default export */ const transports_smooth = (pipelines); - -/***/ }), - -/***/ 281: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ byteRange -/* harmony export */ }); +/* harmony default export */ const stream_representation = (RepresentationStream); +;// CONCATENATED MODULE: ./src/core/stream/utils.ts /** * Copyright 2015 CANAL+ Group * @@ -48390,99 +51014,65 @@ function isMP4EmbeddedTrack(representation) { * limitations under the License. */ -/** - * Returns text-formatted byteRange (`bytes=$start-$end?)` - * @param {Array.} arr - * @returns {string} - */ -function byteRange(_ref) { - var start = _ref[0], - end = _ref[1]; - return end === Infinity ? "bytes=" + start + "-" : "bytes=" + start + "-" + end; -} - -/***/ }), -/***/ 4460: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ checkISOBMFFIntegrity -/* harmony export */ }); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5389); -/* harmony import */ var _find_complete_box__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8766); /** - * Copyright 2015 CANAL+ Group + * Switching to another `Adaptation` and or `Representation` can necessitate a + * complete reload of the MediaSource. * - * 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 + * This is done through the `INeedsMediaSourceReload` event which among other + * things indicate the position the player should seek to after "reloading". + * That position depends on the playback conditions at the time of the switch. * - * http://www.apache.org/licenses/LICENSE-2.0 + * When you already know you have to reload, you can call this function to take + * care of that complex behavior: * - * 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. - */ - - -/** - * Check if an ISOBMFF segment has all the right box needed to be decoded. - * Throw if that's not the case. - * @param {Uint8Array} buffer - The whole ISOBMFF segment - * @param {boolean} isInitSegment - `true` if this is an initialization segment, - * `false` otherwise. + * - If `period` is not being played when that function is called, this + * function will emit regularly the `INeedsMediaSourceReload` event after + * applying the given `deltaPos` value to the reloading position. + * + * - If `period` is not being when that function is called, it emits regularly + * the `INeedsMediaSourceReload` without applying the given `deltaPos` value + * to the reloading position. + * This is because that value is only applied when the previous Adaptation + * or Representation for the current Period was being played and should not + * be for cases like entering the current Period, or seeking _into_ th + * current Period. + * The main point of that configuration variable being to give back some + * context, there is no context to give back on those cases (as the Period + * was not already playing). + * + * @param {Object} period - The Period linked to the Adaptation or + * Representation that you want to switch to. + * @param {Observable} clock$ - Observable emitting 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 checkISOBMFFIntegrity(buffer, isInitSegment) { - if (isInitSegment) { - var ftypIndex = (0,_find_complete_box__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(buffer, 0x66747970 - /* ftyp */ - ); - - if (ftypIndex < 0) { - throw new _errors__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z("INTEGRITY_ERROR", "Incomplete `ftyp` box"); - } - - var moovIndex = (0,_find_complete_box__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(buffer, 0x6D6F6F76 - /* moov */ - ); - - if (moovIndex < 0) { - throw new _errors__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z("INTEGRITY_ERROR", "Incomplete `moov` box"); - } - } else { - var moofIndex = (0,_find_complete_box__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(buffer, 0x6D6F6F66 - /* moof */ - ); +function reloadAfterSwitch(period, clock$, deltaPos) { + return clock$.pipe((0,take/* take */.q)(1), // only the first (current) event interests us here + (0,mergeMap/* mergeMap */.zg)(function (initialTick) { + var _a; - if (moofIndex < 0) { - throw new _errors__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z("INTEGRITY_ERROR", "Incomplete `moof` box"); - } + if (period.start <= initialTick.position && (period.end === undefined || period.end > initialTick.position)) { + // if the Period was playing at the time of the switch + var pos = initialTick.getCurrentTime() + deltaPos; + var reloadAt = Math.min(Math.max(period.start, pos), (_a = period.end) !== null && _a !== void 0 ? _a : Infinity); + return (0,of.of)(stream_events_generators.needsMediaSourceReload(period, reloadAt, !initialTick.isPaused)); + } // If the Period was not playing, just ask to reload to the exact same position - var mdatIndex = (0,_find_complete_box__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(buffer, 0x6D646174 - /* mdat */ - ); - if (mdatIndex < 0) { - throw new _errors__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z("INTEGRITY_ERROR", "Incomplete `mdat` box"); - } - } + return clock$.pipe((0,map/* map */.U)(function (tick) { + return stream_events_generators.needsMediaSourceReload(period, tick.getCurrentTime(), !tick.isPaused); + })); + })); } - -/***/ }), - -/***/ 8766: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ findCompleteBox -/* harmony export */ }); -/* harmony import */ var _utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6968); +;// CONCATENATED MODULE: ./src/core/stream/adaptation/create_representation_estimator.ts /** * Copyright 2015 CANAL+ Group * @@ -48499,65 +51089,73 @@ function checkISOBMFFIntegrity(buffer, isInitSegment) { * limitations under the License. */ + + + /** - * Find the offset for the first declaration of the given box in an isobmff. - * Returns -1 if not found or if incomplete. + * Create an "estimator$" Observable which will emit which Representation (from + * the given `Adaptation`) is the best fit (see `IABREstimate` type definition) + * corresponding to the current network and playback conditions. * - * This function does not throw or log in case of partial segments. - * @param {Uint8Array} buf - the isobmff - * @param {Number} wantedName - * @returns {Number} - Offset where the box begins. -1 if not found. + * This function also returns two subjects that should be used to add feedback + * helping the estimator to make its choices: + * + * - `requestFeedback$`: Subject through which information about new requests + * and network metrics should be emitted. + * + * - `streamFeedback$`: Subject through which stream-related events should be + * emitted. + * + * You can look at the types defined for both of those Subjects to have more + * information on what data is expected. The idea is to provide as much data as + * possible so the estimation is as adapted as possible. + * + * @param {Object} content + * @param {Object} abrManager + * @param {Observable} clock$ + * @returns {Object} */ -function findCompleteBox(buf, wantedName) { - var len = buf.length; - var i = 0; - - while (i + 8 <= len) { - var size = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, i); - - if (size === 0) { - size = len - i; - } else if (size === 1) { - if (i + 16 > len) { - return -1; - } +function createRepresentationEstimator(_ref, abrManager, clock$) { + var manifest = _ref.manifest, + adaptation = _ref.adaptation; + var streamFeedback$ = new Subject/* Subject */.xQ(); + var requestFeedback$ = new Subject/* Subject */.xQ(); + var abrEvents$ = (0,merge/* merge */.T)(streamFeedback$, requestFeedback$); + var estimator$ = (0,concat/* concat */.z)((0,of.of)(null), // Emit directly a first time on subscription + (0,event_emitter/* fromEvent */.R)(manifest, "decipherabilityUpdate") // then each time this event is triggered + ).pipe((0,map/* map */.U)(function () { + /** Representations for which a `RepresentationStream` can be created. */ + var playableRepresentations = adaptation.getPlayableRepresentations(); - size = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be8toi */ .pV)(buf, i + 8); + if (playableRepresentations.length <= 0) { + var noRepErr = new media_error/* default */.Z("NO_PLAYABLE_REPRESENTATION", "No Representation in the chosen " + "Adaptation can be played"); + throw noRepErr; } - if (isNaN(size) || size <= 0) { - // should not happen - return -1; + return playableRepresentations; + }), (0,distinctUntilChanged/* distinctUntilChanged */.x)(function (prevRepr, newRepr) { + if (prevRepr.length !== newRepr.length) { + return false; } - var name = (0,_utils_byte_parsing__WEBPACK_IMPORTED_MODULE_0__/* .be4toi */ .pX)(buf, i + 4); - - if (name === wantedName) { - if (i + size <= len) { - return i; + for (var i = 0; i < newRepr.length; i++) { + if (prevRepr[i].id !== newRepr[i].id) { + return false; } - - return -1; } - i += size; - } - - return -1; + return true; + }), (0,switchMap/* switchMap */.w)(function (playableRepresentations) { + return abrManager.get$(adaptation.type, playableRepresentations, clock$, abrEvents$); + })); + return { + estimator$: estimator$, + streamFeedback$: streamFeedback$, + requestFeedback$: requestFeedback$ + }; } - -/***/ }), - -/***/ 7445: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ returnParsedManifest -/* harmony export */ }); -/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8170); -/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9795); +;// CONCATENATED MODULE: ./src/core/stream/adaptation/adaptation_stream.ts /** * Copyright 2015 CANAL+ Group * @@ -48575,241 +51173,242 @@ function findCompleteBox(buf, wantedName) { */ /** - * As a Manifest instance is obtained, emit the right `warning` events - * (according to the Manifest's `parsingErrors` property`) followed by the right - * `parsed` event, as expected from a Manifest parser. - * @param {Manifest} manifest - * @param {string|undefined} url - * @returns {Observable} + * 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 + * ABRManager, and orchestrates a RepresentationStream, which will download and + * push segments corresponding to a chosen Representation. */ -function returnParsedManifest(manifest, url) { - var warningEvts$ = rxjs__WEBPACK_IMPORTED_MODULE_0__.of.apply(void 0, manifest.parsingErrors.map(function (error) { - return { - type: "warning", - value: error - }; - })); - return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__/* .concat */ .z)(warningEvts$, (0,rxjs__WEBPACK_IMPORTED_MODULE_0__.of)({ - type: "parsed", - value: { - manifest: manifest, - url: url - } - })); -} -/***/ }), -/***/ 7278: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ generateManifestLoader -}); -// EXTERNAL MODULE: ./src/utils/is_null_or_undefined.ts -var is_null_or_undefined = __webpack_require__(1946); -// EXTERNAL MODULE: ./src/utils/request/index.ts + 1 modules -var request = __webpack_require__(4597); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules -var Observable = __webpack_require__(4379); -;// CONCATENATED MODULE: ./src/transports/utils/call_custom_manifest_loader.ts + + + + +var DELTA_POSITION_AFTER_RELOAD = config/* default.DELTA_POSITION_AFTER_RELOAD */.Z.DELTA_POSITION_AFTER_RELOAD; /** - * Copyright 2015 CANAL+ Group + * Create new AdaptationStream Observable, which task will be to download the + * media data for a given Adaptation (i.e. "track"). * - * 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 + * It will rely on the ABRManager 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. * - * http://www.apache.org/licenses/LICENSE-2.0 + * After being subscribed to, it will start running and will emit various events + * to report its current status. * - * 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 {Object} args + * @returns {Observable} */ -function callCustomManifestLoader(customManifestLoader, fallbackManifestLoader) { - return function (args) { - return new Observable/* Observable */.y(function (obs) { - var url = args.url; - var timeAPIsDelta = Date.now() - performance.now(); - var hasFinished = false; - var hasFallbacked = false; - /** - * Callback triggered when the custom manifest loader has a response. - * @param {Object} args - */ +function AdaptationStream(_ref) { + var abrManager = _ref.abrManager, + clock$ = _ref.clock$, + content = _ref.content, + options = _ref.options, + segmentBuffer = _ref.segmentBuffer, + segmentFetcherCreator = _ref.segmentFetcherCreator, + wantedBufferAhead$ = _ref.wantedBufferAhead$; + var directManualBitrateSwitching = options.manualBitrateSwitchingMode === "direct"; + var manifest = content.manifest, + period = content.period, + adaptation = content.adaptation; + /** + * The buffer goal ratio base itself on the value given by `wantedBufferAhead` + * to determine a more dynamic buffer goal for a given Representation. + * + * It can help in cases such as : the current browser has issues with + * buffering and tells us that we should try to bufferize less data : + * https://developers.google.com/web/updates/2017/10/quotaexceedederror + */ - var resolve = function resolve(_args) { - if (!hasFallbacked) { - hasFinished = true; - var receivedTime = _args.receivingTime !== undefined ? _args.receivingTime - timeAPIsDelta : undefined; - var sendingTime = _args.sendingTime !== undefined ? _args.sendingTime - timeAPIsDelta : undefined; - obs.next({ - type: "data-loaded", - value: { - responseData: _args.data, - size: _args.size, - duration: _args.duration, - url: _args.url, - receivedTime: receivedTime, - sendingTime: sendingTime - } - }); - obs.complete(); - } - }; - /** - * Callback triggered when the custom manifest loader fails - * @param {*} err - The corresponding error encountered - */ + var bufferGoalRatioMap = {}; + var _createRepresentation = createRepresentationEstimator(content, abrManager, clock$), + estimator$ = _createRepresentation.estimator$, + requestFeedback$ = _createRepresentation.requestFeedback$, + streamFeedback$ = _createRepresentation.streamFeedback$; + /** Allows the `RepresentationStream` to easily fetch media segments. */ - var reject = function reject(err) { - if (!hasFallbacked) { - hasFinished = true; - obs.error(err); - } - }; - /** - * Callback triggered when the custom manifest loader wants to fallback to - * the "regular" implementation - */ + var segmentFetcher = segmentFetcherCreator.createSegmentFetcher(adaptation.type, requestFeedback$); + /** + * Emits each time an estimate is made through the `abrEstimate$` Observable, + * starting with the last one. + * This allows to easily rely on that value in inner Observables which might also + * need the last already-considered value. + */ - var fallback = function fallback() { - hasFallbacked = true; - fallbackManifestLoader(args).subscribe(obs); - }; + var lastEstimate$ = new BehaviorSubject(null); + /** Emits abr estimates on Subscription. */ - var callbacks = { - reject: reject, - resolve: resolve, - fallback: fallback - }; - var abort = customManifestLoader(url, callbacks); - return function () { - if (!hasFinished && !hasFallbacked && typeof abort === "function") { - abort(); - } - }; - }); - }; -} -;// CONCATENATED MODULE: ./src/transports/utils/text_manifest_loader.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 abrEstimate$ = estimator$.pipe((0,tap/* tap */.b)(function (estimate) { + lastEstimate$.next(estimate); + }), (0,defer_subscriptions/* default */.Z)(), (0,share/* share */.B)()); + /** Emit at each bitrate estimate done by the ABRManager. */ + var bitrateEstimate$ = abrEstimate$.pipe((0,filter/* filter */.h)(function (_ref2) { + var bitrate = _ref2.bitrate; + return bitrate != null; + }), (0,distinctUntilChanged/* distinctUntilChanged */.x)(function (old, current) { + return old.bitrate === current.bitrate; + }), (0,map/* map */.U)(function (_ref3) { + var bitrate = _ref3.bitrate; + log/* default.debug */.Z.debug("Stream: new " + adaptation.type + " bitrate estimate", bitrate); + return stream_events_generators.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)(representationStreams$, bitrateEstimate$); + /** + * Create `RepresentationStream`s starting with the Representation indicated in + * `fromEstimate` argument. + * 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`. + * 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} + */ -/** - * Manifest loader triggered if there was no custom-defined one in the API. - * @param {string} url - * @returns {Observable} - */ + function recursivelyCreateRepresentationStreams(fromEstimate, isFirstEstimate) { + var representation = fromEstimate.representation; // A manual bitrate switch might need an immediate feedback. + // To do that properly, we need to reload the MediaSource -function regularManifestLoader(_ref) { - var url = _ref.url; + if (directManualBitrateSwitching && fromEstimate.manual && !isFirstEstimate) { + return reloadAfterSwitch(period, clock$, DELTA_POSITION_AFTER_RELOAD.bitrateSwitch); + } + /** + * Emit when the current RepresentationStream should be terminated to make + * place for a new one (e.g. when switching quality). + */ - if (url === undefined) { - throw new Error("Cannot perform HTTP(s) request. URL not known"); - } - return (0,request/* default */.ZP)({ - url: url, - responseType: "text" - }); -} -/** - * Generate a manifest loader for the application - * @param {Function} [customManifestLoader] - * @returns {Function} - */ + var terminateCurrentStream$ = lastEstimate$.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 + }; + } + + if (newEstimate.urgent) { + log/* default.info */.Z.info("Stream: urgent Representation switch", adaptation.type); + return { + urgent: true + }; + } else { + log/* default.info */.Z.info("Stream: slow Representation switch", adaptation.type); + return { + urgent: false + }; + } + })); + /** + * "Fast-switching" is a behavior allowing to replace low-quality segments + * (i.e. with a low bitrate) with higher-quality segments (higher bitrate) in + * the buffer. + * This threshold defines a bitrate from which "fast-switching" is disabled. + * For example with a fastSwitchThreshold set to `100`, segments with a + * bitrate of `90` can be replaced. But segments with a bitrate of `100` + * onward won't be replaced by higher quality segments. + * 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$.pipe((0,map/* map */.U)(function (estimate) { + return estimate === null ? undefined : estimate.knownStableBitrate; + }), (0,distinctUntilChanged/* distinctUntilChanged */.x)()); + var representationChange$ = (0,of.of)(stream_events_generators.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 === "representationChange" || evt.type === "added-segment") { + return streamFeedback$.next(evt); + } + }), (0,mergeMap/* mergeMap */.zg)(function (evt) { + if (evt.type === "stream-terminating") { + var lastEstimate = lastEstimate$.getValue(); + if (lastEstimate === null) { + return empty/* EMPTY */.E; + } -function generateManifestLoader(_ref2) { - var customManifestLoader = _ref2.customManifestLoader; + return recursivelyCreateRepresentationStreams(lastEstimate, false); + } - if ((0,is_null_or_undefined/* default */.Z)(customManifestLoader)) { - return regularManifestLoader; + return (0,of.of)(evt); + })); } + /** + * Create and returns a new RepresentationStream Observable, linked to the + * given Representation. + * @param {Representation} representation + * @returns {Observable} + */ - return callCustomManifestLoader(customManifestLoader, regularManifestLoader); -} -/***/ }), + 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$.pipe((0,map/* map */.U)(function (wba) { + return wba * bufferGoalRatio; + })); + log/* default.info */.Z.info("Stream: changing representation", adaptation.type, representation); + return stream_representation({ + clock$: clock$, + content: { + representation: representation, + adaptation: adaptation, + period: period, + manifest: manifest + }, + segmentBuffer: segmentBuffer, + segmentFetcher: segmentFetcher, + terminate$: terminateCurrentStream$, + options: { + bufferGoal$: bufferGoal$, + drmSystemId: options.drmSystemId, + fastSwitchThreshold$: fastSwitchThreshold$ + } + }).pipe((0,catchError/* catchError */.K)(function (err) { + var formattedError = formatError(err, { + defaultCode: "NONE", + defaultReason: "Unknown `RepresentationStream` error" + }); -/***/ 4791: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (formattedError.code === "BUFFER_FULL_ERROR") { + var wantedBufferAhead = wantedBufferAhead$.getValue(); + var lastBufferGoalRatio = bufferGoalRatio; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ areArraysOfNumbersEqual -/* harmony export */ }); -/** - * 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. - */ + if (lastBufferGoalRatio <= 0.25 || wantedBufferAhead * lastBufferGoalRatio <= 2) { + throw formattedError; + } -/** - * Check if two two arrays containing only numbers are equal. - * @param {Array.|TypedArray} arr1 - * @param {Array.|TypedArray} arr2 - * @returns {Boolean} - */ -function areArraysOfNumbersEqual(arr1, arr2) { - if (arr1.length !== arr2.length) { - return false; - } + bufferGoalRatioMap[representation.id] = lastBufferGoalRatio - 0.25; + return createRepresentationStream(representation, terminateCurrentStream$, fastSwitchThreshold$); + } - for (var i = arr1.length - 1; i >= 0; i--) { - if (arr1[i] !== arr2[i]) { - return false; - } + throw formattedError; + })); + }); } - - return true; } - -/***/ }), - -/***/ 3274: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ arrayFind -/* harmony export */ }); +;// CONCATENATED MODULE: ./src/core/stream/adaptation/index.ts /** * Copyright 2015 CANAL+ Group * @@ -48826,50 +51425,8 @@ function areArraysOfNumbersEqual(arr1, arr2) { * limitations under the License. */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ - -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ - -/* eslint-disable @typescript-eslint/no-unsafe-call */ - -/* eslint-disable @typescript-eslint/no-unsafe-return */ - -/* eslint-disable no-restricted-properties */ - -/** - * Array.prototype.find ponyfill. - * @param {Array} arr - * @param {Function} predicate - * @param {*} context - * @returns {boolean} - */ -function arrayFind(arr, predicate, thisArg) { - if (typeof Array.prototype.find === "function") { - return arr.find(predicate, thisArg); - } - - var len = arr.length >>> 0; - - for (var i = 0; i < len; i++) { - var val = arr[i]; - - if (predicate.call(thisArg, val, i, arr)) { - return val; - } - } - - return undefined; -} - -/***/ }), - -/***/ 5138: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ arrayFindIndex -/* harmony export */ }); +/* harmony default export */ const stream_adaptation = (AdaptationStream); +;// CONCATENATED MODULE: ./src/core/stream/period/create_empty_adaptation_stream.ts /** * Copyright 2015 CANAL+ Group * @@ -48886,48 +51443,50 @@ function arrayFind(arr, predicate, thisArg) { * limitations under the License. */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ - -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ - -/* eslint-disable @typescript-eslint/no-unsafe-call */ - -/* eslint-disable @typescript-eslint/no-unsafe-return */ -/* eslint-disable no-restricted-properties */ /** - * Array.prototype.find ponyfill. - * @param {Array} arr - * @param {Function} predicate - * @param {*} context - * @returns {boolean} + * 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} streamClock$ + * @param {Observable} wantedBufferAhead$ + * @param {string} bufferType + * @param {Object} content + * @returns {Observable} */ -function arrayFindIndex(arr, predicate, thisArg) { - if (typeof Array.prototype.findIndex === "function") { - return arr.findIndex(predicate, thisArg); - } - var len = arr.length >>> 0; +function createEmptyAdaptationStream(streamClock$, wantedBufferAhead$, bufferType, content) { + var period = content.period; + var hasFinishedLoading = false; + return (0,combineLatest/* combineLatest */.aj)([streamClock$, wantedBufferAhead$]).pipe((0,mergeMap/* mergeMap */.zg)(function (_ref) { + var clockTick = _ref[0], + wantedBufferAhead = _ref[1]; + var position = clockTick.position; - for (var i = 0; i < len; i++) { - if (predicate.call(thisArg, arr[i], i, arr)) { - return i; + if (period.end !== undefined && position + wantedBufferAhead >= period.end) { + log/* default.debug */.Z.debug("Stream: full \"empty\" AdaptationStream", bufferType); + hasFinishedLoading = true; } - } - return -1; + return (0,of.of)({ + type: "stream-status", + value: { + period: period, + bufferType: bufferType, + position: clockTick.position, + imminentDiscontinuity: null, + hasFinishedLoading: hasFinishedLoading, + neededSegments: [], + shouldRefreshManifest: false + } + }); + })); } - -/***/ }), - -/***/ 7714: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ arrayIncludes -/* harmony export */ }); +// EXTERNAL MODULE: ./src/utils/starts_with.ts +var starts_with = __webpack_require__(9252); +;// CONCATENATED MODULE: ./src/utils/are_codecs_compatible.ts /** * Copyright 2015 CANAL+ Group * @@ -48944,89 +51503,52 @@ function arrayFindIndex(arr, predicate, thisArg) { * limitations under the License. */ + /** - * Array.prototype.includes ponyfill. - * Returns ``true`` if the given array ``arr`` contains the element - * ``searchElement``. false ``otherwise``. - * - * Inspired from MDN polyfill, but ponyfilled instead - * - * @example - * ```js - * arrayIncludes([1, 2, 3], 3); - * // => true - * - * arrayIncludes([1, 2, 3], 7); - * // => false - * - * const obj = { a: 4 }; - * arrayIncludes([obj, { b: 7 }, { a: 3 }], obj); - * // => true - * - * // does not perform deep equality - * arrayIncludes([{ a: 4 }, { b: 7 }, { a: 3 }], { a: 4 }); - * // => false - * - * // the third argument state the starting index. 0 if not set. - * - * arrayIncludes([1, 2, 3], 2, 1); - * // => true - * - * arrayIncludes([1, 2, 3], 2, 2); - * // => false - * ``` + * This function is a shortcut that helps differentiate two codecs + * of the form "audio/mp4;codecs=\"av1.40.2\"". * - * @param {Array} arr - * @param {*} searchElement - * @param {number} [fromIndex] - * @returns {boolean} + * @param codecA + * @param codecB + * @returns A boolean that tell whether or not those two codecs provided are even. */ -function arrayIncludes(arr, searchElement, fromIndex) { - /* eslint-disable @typescript-eslint/unbound-method */ - // eslint-disable-next-line no-restricted-properties - if (typeof Array.prototype.includes === "function") { - /* eslint-enable @typescript-eslint/unbound-method */ - // eslint-disable-next-line no-restricted-properties - return arr.includes(searchElement, fromIndex); - } - var len = arr.length >>> 0; +function areCodecsCompatible(a, b) { + var _a$split = a.split(";"), + mimeTypeA = _a$split[0], + propsA = _a$split.slice(1); - if (len === 0) { + var _b$split = b.split(";"), + mimeTypeB = _b$split[0], + propsB = _b$split.slice(1); + + if (mimeTypeA !== mimeTypeB) { return false; } - var n = fromIndex | 0; - var k = n >= 0 ? Math.min(n, len - 1) : Math.max(len + n, 0); + var codecsA = (0,array_find/* default */.Z)(propsA, function (prop) { + return (0,starts_with/* default */.Z)(prop, "codecs="); + }); + var codecsB = (0,array_find/* default */.Z)(propsB, function (prop) { + return (0,starts_with/* default */.Z)(prop, "codecs="); + }); - var areTheSame = function areTheSame(x, y) { - return x === y || // Viva las JavaScriptas! - typeof x === "number" && typeof y === "number" && isNaN(x) && isNaN(y); - }; + if (codecsA === undefined || codecsB === undefined) { + return false; + } - while (k < len) { - if (areTheSame(arr[k], searchElement)) { - return true; - } + var codecA = codecsA.substring(7); + var codecB = codecsB.substring(7); - k++; + if (codecA.split(".")[0] !== codecB.split(".")[0]) { + return false; } - return false; + return true; } -/***/ }), - -/***/ 811: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ assert, -/* harmony export */ "u": () => /* binding */ assertInterface -/* harmony export */ }); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3801); -/* harmony import */ var _is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1946); +/* harmony default export */ const are_codecs_compatible = (areCodecsCompatible); +;// CONCATENATED MODULE: ./src/core/stream/period/get_adaptation_switch_strategy.ts /** * Copyright 2015 CANAL+ Group * @@ -49044,284 +51566,259 @@ function arrayIncludes(arr, searchElement, fromIndex) { */ + +var ADAPTATION_SWITCH_BUFFER_PADDINGS = config/* default.ADAPTATION_SWITCH_BUFFER_PADDINGS */.Z.ADAPTATION_SWITCH_BUFFER_PADDINGS; /** - * Throw an AssertionError if the given assertion is false. - * @param {boolean} assertion - * @param {string} [message] - Optional message property for the AssertionError. - * @throws AssertionError - Throws if the assertion given is false + * Find out what to do when switching Adaptation, based on the current + * situation. + * @param {Object} segmentBuffer + * @param {Object} period + * @param {Object} adaptation + * @param {Object} playbackInfo + * @returns {Object} */ -function assert(assertion, message) { - if (!assertion) { - throw new _errors__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z(message === undefined ? "invalid assertion" : message); +function getAdaptationSwitchStrategy(segmentBuffer, period, adaptation, playbackInfo, options) { + if (segmentBuffer.codec !== undefined && options.onCodecSwitch === "reload" && !hasCompatibleCodec(adaptation, segmentBuffer.codec)) { + return { + type: "needs-reload", + value: undefined + }; } -} -/** - * Throws if the given Object does not respect the interface. - * @param {Object} o - * @param {Object} iface - Contains the checked keynames of o and link them - * to their types (obtained through the typeof operator). - * @param {string} [name="object"] - name of the _interface_ - * @throws AssertionError - The argument o given is not an object - * @throws AssertionError - The _interface_ is not respected. - */ -function assertInterface(o, iface, name) { - if (name === void 0) { - name = "object"; + var buffered = segmentBuffer.getBufferedRanges(); + + if (buffered.length === 0) { + return { + type: "continue", + value: undefined + }; } - assert(!(0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(o), name + " should be an object"); + var bufferedRanges = (0,ranges/* convertToRanges */.JN)(buffered); + var start = period.start; + var end = period.end == null ? Infinity : period.end; + var intersection = (0,ranges/* keepRangeIntersection */.tn)(bufferedRanges, [{ + start: start, + end: end + }]); - for (var k in iface) { - if (iface.hasOwnProperty(k)) { - /* eslint-disable max-len */ + if (intersection.length === 0) { + return { + type: "continue", + value: undefined + }; + } - /* eslint-disable @typescript-eslint/restrict-template-expressions */ - assert(typeof o[k] === iface[k], name + " should have property " + k + " as a " + iface[k]); - /* eslint-enable max-len */ + segmentBuffer.synchronizeInventory(); + var inventory = segmentBuffer.getInventory(); // Continue if we have no other Adaptation buffered in the current Period - /* eslint-enable @typescript-eslint/restrict-template-expressions */ - } + if (!inventory.some(function (buf) { + return buf.infos.period.id === period.id && buf.infos.adaptation.id !== adaptation.id; + })) { + return { + type: "continue", + value: undefined + }; } -} + /** Data already in the right Adaptation */ -/***/ }), -/***/ 8418: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var adaptationInBuffer = getBufferedRangesFromAdaptation(inventory, period, adaptation); + /** + * Data different from the wanted Adaptation in the Period's range. + * /!\ Could contain some data at the end of the previous Period or at the + * beginning of the next one. + */ -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ assertUnreachable -/* harmony export */ }); -/* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3801); -/** - * 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 unwantedRange = (0,ranges/* excludeFromRanges */.uH)(intersection, adaptationInBuffer); -/** - * TypeScript hack to make sure a code path is never taken. - * - * This can for example be used to ensure that a switch statement handle all - * possible cases by adding a default clause calling assertUnreachable with - * an argument (it doesn't matter which one). - * - * @example - * function parseBinary(str : "0" | "1") : number { - * switch (str) { - * case "0: - * return 0; - * case "1": - * return 1; - * default: - * // branch never taken. If it can be, TypeScript will yell at us because - * // its argument (here, `str`) is not of the right type. - * assertUnreachable(str); - * } - * } - * @param {*} _ - * @throws AssertionError - Throw an AssertionError when called. If we're - * sufficiently strict with how we use TypeScript, this should never happen. - */ + if (unwantedRange.length === 0) { + return { + type: "continue", + value: undefined + }; + } + + var currentTime = playbackInfo.currentTime; + + if (adaptation.type === "video" && // We're playing the current Period + (0,ranges/* isTimeInRange */.Ti)({ + start: start, + end: end + }, currentTime) && ( // There is data for the current position or the codecs are differents + playbackInfo.readyState > 1 || !adaptation.getPlayableRepresentations().some(function (rep) { + var _a; + + return are_codecs_compatible(rep.getMimeTypeString(), (_a = segmentBuffer.codec) !== null && _a !== void 0 ? _a : ""); + })) && // We're not playing the current wanted video Adaptation + !(0,ranges/* isTimeInRanges */.A1)(adaptationInBuffer, currentTime)) { + return { + type: "needs-reload", + value: undefined + }; + } + + if (adaptation.type === "audio" && segmentBuffer.codec !== undefined && // We have been explicitly asked to reload + options.audioTrackSwitchingMode === "direct" && // We're playing the current Period + (0,ranges/* isTimeInRange */.Ti)({ + start: start, + end: end + }, currentTime) && ( // There is data for the current position or the codecs are differents + playbackInfo.readyState > 1 || !hasCompatibleCodec(adaptation, segmentBuffer.codec)) && // We're not playing the current wanted audio Adaptation yet + !(0,ranges/* isTimeInRanges */.A1)(adaptationInBuffer, currentTime)) { + return { + type: "needs-reload", + value: undefined + }; + } // From here, clean-up data from the previous Adaptation, if one -function assertUnreachable(_) { - throw new _errors__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z("Unreachable path taken"); -} -/***/ }), + var rangesToExclude = []; // First, we don't want to accidentally remove some segments from the previous + // Period (which overlap a little with this one) -/***/ 9689: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + /** Last segment before one for the current period. */ -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "J": () => /* binding */ bytesToBase64, -/* harmony export */ "K": () => /* binding */ base64ToBytes -/* harmony export */ }); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3887); -/* eslint-disable */ + var lastSegmentBefore = getLastSegmentBeforePeriod(inventory, period); -/* -MIT License -Copyright (c) 2020 Egor Nepomnyaschih -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ + if (lastSegmentBefore !== null && (lastSegmentBefore.bufferedEnd === undefined || period.start - lastSegmentBefore.bufferedEnd < 1)) // Close to Period's start + { + // Exclude data close to the period's start to avoid cleaning + // to much + rangesToExclude.push({ + start: 0, + end: period.start + 1 + }); + } // Next, exclude data around current position to avoid decoding issues -/* -// This constant can also be computed with the following algorithm: -const base64abc = [], - A = "A".charCodeAt(0), - a = "a".charCodeAt(0), - n = "0".charCodeAt(0); -for (let i = 0; i < 26; ++i) { - base64abc.push(String.fromCharCode(A + i)); -} -for (let i = 0; i < 26; ++i) { - base64abc.push(String.fromCharCode(a + i)); -} -for (let i = 0; i < 10; ++i) { - base64abc.push(String.fromCharCode(n + i)); -} -base64abc.push("+"); -base64abc.push("/"); - */ -var base64abc = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"]; -/* -// This constant can also be computed with the following algorithm: -const l = 256, base64codes = new Uint8Array(l); -for (let i = 0; i < l; ++i) { - base64codes[i] = 255; // invalid character -} -base64abc.forEach((char, index) => { - base64codes[char.charCodeAt(0)] = index; -}); -base64codes["=".charCodeAt(0)] = 0; // ignored anyway, so we just need to prevent an error - */ + var bufferType = adaptation.type; + /** Ranges that won't be cleaned from the current buffer. */ -var base64codes = [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 0, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51]; -/** - * Obtain the value corresponding to a base64 char code. - * /!\ Can throw if the char code given is invalid. - * @param {number} charCode - * @returns {number} - */ + var paddingBefore = ADAPTATION_SWITCH_BUFFER_PADDINGS[bufferType].before; -function getBase64Code(charCode) { - if (charCode >= base64codes.length) { - throw new Error("Unable to parse base64 string."); + if (paddingBefore == null) { + paddingBefore = 0; } - var code = base64codes[charCode]; + var paddingAfter = ADAPTATION_SWITCH_BUFFER_PADDINGS[bufferType].after; - if (code === 255) { - throw new Error("Unable to parse base64 string."); + if (paddingAfter == null) { + paddingAfter = 0; } - return code; + rangesToExclude.push({ + start: currentTime - paddingBefore, + end: currentTime + paddingAfter + }); // Now remove possible small range from the end if there is a segment from the + // next Period + + if (period.end !== undefined) { + /** first segment after for the current period. */ + var firstSegmentAfter = getFirstSegmentAfterPeriod(inventory, period); + + if (firstSegmentAfter !== null && (firstSegmentAfter.bufferedStart === undefined || firstSegmentAfter.bufferedStart - period.end < 1)) // Close to Period's end + { + rangesToExclude.push({ + start: period.end - 1, + end: Number.MAX_VALUE + }); + } + } + + var toRemove = (0,ranges/* excludeFromRanges */.uH)(unwantedRange, rangesToExclude); + return toRemove.length > 0 ? { + type: "clean-buffer", + value: toRemove + } : { + type: "continue", + value: undefined + }; } /** - * Convert an array of bytes into a base64 string. - * @param {Array.|Uint8Array} bytes - * @returns {string} + * Returns `true` if at least one codec of the Representations in the given + * Adaptation has a codec compatible with the given SegmentBuffer's codec. + * @param {Object} adaptation + * @param {string} segmentBufferCodec + * @returns {boolean} */ +function hasCompatibleCodec(adaptation, segmentBufferCodec) { + return adaptation.getPlayableRepresentations().some(function (rep) { + return are_codecs_compatible(rep.getMimeTypeString(), segmentBufferCodec); + }); +} +/** + * Returns buffered ranges of what we know correspond to the given `adaptation` + * in the SegmentBuffer. + * @param {Object} segmentBuffer + * @param {Object} period + * @param {Object} adaptation + * @returns {Array.} + */ -function bytesToBase64(bytes) { - var result = ""; - var i; - var length = bytes.length; - for (i = 2; i < length; i += 3) { - result += base64abc[bytes[i - 2] >> 2]; - result += base64abc[(bytes[i - 2] & 0x03) << 4 | bytes[i - 1] >> 4]; - result += base64abc[(bytes[i - 1] & 0x0F) << 2 | bytes[i] >> 6]; - result += base64abc[bytes[i] & 0x3F]; - } +function getBufferedRangesFromAdaptation(inventory, period, adaptation) { + return inventory.reduce(function (acc, chunk) { + if (chunk.infos.period.id !== period.id || chunk.infos.adaptation.id !== adaptation.id) { + return acc; + } - if (i === length + 1) { - // 1 octet yet to write - result += base64abc[bytes[i - 2] >> 2]; - result += base64abc[(bytes[i - 2] & 0x03) << 4]; - result += "=="; - } + var bufferedStart = chunk.bufferedStart, + bufferedEnd = chunk.bufferedEnd; - if (i === length) { - // 2 octets yet to write - result += base64abc[bytes[i - 2] >> 2]; - result += base64abc[(bytes[i - 2] & 0x03) << 4 | bytes[i - 1] >> 4]; - result += base64abc[(bytes[i - 1] & 0x0F) << 2]; - result += "="; - } + if (bufferedStart === undefined || bufferedEnd === undefined) { + return acc; + } - return result; + acc.push({ + start: bufferedStart, + end: bufferedEnd + }); + return acc; + }, []); } /** - * Convert a base64 string into the corresponding Uint8Array containing its - * corresponding binary data. - * /!\ Can throw if an invalid base64 string was given. - * @param {Array.|Uint8Array} bytes - * @returns {string} + * Returns the last segment in the `inventory` which is linked to a Period + * before `period`. + * @param {Array.} inventory + * @param {Object} period + * @returns {Object|null} */ -function base64ToBytes(str) { - var paddingNeeded = str.length % 4; - var paddedStr = str; - - if (paddingNeeded !== 0) { - _log__WEBPACK_IMPORTED_MODULE_0__/* .default.warn */ .Z.warn("base64ToBytes: base64 given miss padding"); - paddedStr += paddingNeeded === 3 ? "=" : paddingNeeded === 2 ? "==" : "==="; // invalid, but we will catch it - } - - var index = paddedStr.indexOf("="); - - if (index !== -1 && index < paddedStr.length - 2) { - throw new Error("Unable to parse base64 string."); - } - var missingOctets = paddedStr.endsWith("==") ? 2 : paddedStr.endsWith("=") ? 1 : 0; - var n = paddedStr.length; - var result = new Uint8Array(n / 4 * 3); - var buffer; +function getLastSegmentBeforePeriod(inventory, period) { + for (var i = 0; i < inventory.length; i++) { + if (inventory[i].infos.period.start >= period.start) { + if (i > 0) { + return inventory[i - 1]; + } - for (var i = 0, j = 0; i < n; i += 4, j += 3) { - buffer = getBase64Code(paddedStr.charCodeAt(i)) << 18 | getBase64Code(paddedStr.charCodeAt(i + 1)) << 12 | getBase64Code(paddedStr.charCodeAt(i + 2)) << 6 | getBase64Code(paddedStr.charCodeAt(i + 3)); - result[j] = buffer >> 16; - result[j + 1] = buffer >> 8 & 0xFF; - result[j + 2] = buffer & 0xFF; + return null; + } } - return result.subarray(0, result.length - missingOctets); + return inventory.length > 0 ? inventory[inventory.length - 1] : null; } +/** + * Returns the first segment in the `inventory` which is linked to a Period + * after `period`. + * @param {Array.} inventory + * @param {Object} period + * @returns {Object|null} + */ -/***/ }), -/***/ 6968: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +function getFirstSegmentAfterPeriod(inventory, period) { + for (var i = 0; i < inventory.length; i++) { + if (inventory[i].infos.period.start > period.start) { + return inventory[i]; + } + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "zo": () => /* binding */ concat, -/* harmony export */ "zK": () => /* binding */ be2toi, -/* harmony export */ "QI": () => /* binding */ be3toi, -/* harmony export */ "pX": () => /* binding */ be4toi, -/* harmony export */ "pV": () => /* binding */ be8toi, -/* harmony export */ "qb": () => /* binding */ le2toi, -/* harmony export */ "dN": () => /* binding */ le4toi, -/* harmony export */ "XT": () => /* binding */ itobe2, -/* harmony export */ "kh": () => /* binding */ itobe4, -/* harmony export */ "el": () => /* binding */ itobe8, -/* harmony export */ "O_": () => /* binding */ itole4, -/* harmony export */ "_f": () => /* binding */ toUint8Array -/* harmony export */ }); -/* unused harmony exports le8toi, itole2, isABEqualBytes */ + return null; +} +;// CONCATENATED MODULE: ./src/core/stream/period/period_stream.ts /** * Copyright 2015 CANAL+ Group * @@ -49338,227 +51835,196 @@ function base64ToBytes(str) { * limitations under the License. */ -/** - * Returns a Uint8Array from the arguments given, in order: - * - if the next argument given is a number N set the N next bytes to 0. - * - else set the next bytes to the argument given. - * @param {...(Number|Uint8Array)} args - * @returns {Uint8Array} - */ -function concat() { - var l = arguments.length; - var i = -1; - var len = 0; - var arg; - - while (++i < l) { - arg = i < 0 || arguments.length <= i ? undefined : arguments[i]; - len += typeof arg === "number" ? arg : arg.length; - } - - var arr = new Uint8Array(len); - var offset = 0; - i = -1; - while (++i < l) { - arg = i < 0 || arguments.length <= i ? undefined : arguments[i]; - - if (typeof arg === "number") { - offset += arg; - } else if (arg.length > 0) { - arr.set(arg, offset); - offset += arg.length; - } - } - return arr; -} -/** - * Translate groups of 2 big-endian bytes to Integer (from 0 up to 65535). - * @param {Uint8Array} bytes - * @param {Number} offset - The offset (from the start of the given array) - * @returns {Number} - */ -function be2toi(bytes, offset) { - return (bytes[offset + 0] << 8) + (bytes[offset + 1] << 0); -} -/** - * Translate groups of 3 big-endian bytes to Integer. - * @param {Uint8Array} bytes - * @param {Number} offset - The offset (from the start of the given array) - * @returns {Number} - */ -function be3toi(bytes, offset) { - return bytes[offset + 0] * 0x0010000 + bytes[offset + 1] * 0x0000100 + bytes[offset + 2]; -} -/** - * Translate groups of 4 big-endian bytes to Integer. - * @param {Uint8Array} bytes - * @param {Number} offset - The offset (from the start of the given array) - * @returns {Number} - */ -function be4toi(bytes, offset) { - return bytes[offset + 0] * 0x1000000 + bytes[offset + 1] * 0x0010000 + bytes[offset + 2] * 0x0000100 + bytes[offset + 3]; -} -/** - * Translate groups of 8 big-endian bytes to Integer. - * @param {Uint8Array} bytes - * @param {Number} offset - The offset (from the start of the given array) - * @returns {Number} - */ -function be8toi(bytes, offset) { - return (bytes[offset + 0] * 0x1000000 + bytes[offset + 1] * 0x0010000 + bytes[offset + 2] * 0x0000100 + bytes[offset + 3]) * 0x100000000 + bytes[offset + 4] * 0x1000000 + bytes[offset + 5] * 0x0010000 + bytes[offset + 6] * 0x0000100 + bytes[offset + 7]; -} -/** - * Translate Integer (from 0 up to 65535) to a Uint8Array of length 2 of - * the corresponding big-endian bytes. - * @param {Number} num - * @returns {Uint8Array} - */ -function itobe2(num) { - return new Uint8Array([num >>> 8 & 0xFF, num & 0xFF]); -} +var period_stream_DELTA_POSITION_AFTER_RELOAD = config/* default.DELTA_POSITION_AFTER_RELOAD */.Z.DELTA_POSITION_AFTER_RELOAD; /** - * Translate Integer to a Uint8Array of length 4 of the corresponding big-endian - * bytes. - * @param {Number} num - * @returns {Uint8Array} + * Create single PeriodStream Observable: + * - 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) { + var abrManager = _ref.abrManager, + bufferType = _ref.bufferType, + clock$ = _ref.clock$, + content = _ref.content, + garbageCollectors = _ref.garbageCollectors, + segmentFetcherCreator = _ref.segmentFetcherCreator, + segmentBuffersStore = _ref.segmentBuffersStore, + options = _ref.options, + wantedBufferAhead$ = _ref.wantedBufferAhead$; + var period = content.period; // Emits the chosen Adaptation for the current type. + // `null` when no Adaptation is chosen (e.g. no subtitles) -function itobe4(num) { - return new Uint8Array([num >>> 24 & 0xFF, num >>> 16 & 0xFF, num >>> 8 & 0xFF, num & 0xFF]); -} -/** - * Translate Integer to a Uint8Array of length 8 of the corresponding big-endian - * bytes. - * /!\ If the top-most bytes are set, this might go over MAX_SAFE_INTEGER, thus - * leading to a "bad" value. - * @param {Number} num - * @returns {Uint8Array} - */ + 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 relativePosAfterSwitch = switchNb === 0 ? 0 : bufferType === "audio" ? period_stream_DELTA_POSITION_AFTER_RELOAD.trackSwitch.audio : bufferType === "video" ? period_stream_DELTA_POSITION_AFTER_RELOAD.trackSwitch.video : period_stream_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", period); + var segmentBufferStatus = segmentBuffersStore.getStatus(bufferType); + var cleanBuffer$; -function itobe8(num) { - var l = num % 0x100000000; - var h = (num - l) / 0x100000000; - return new Uint8Array([h >>> 24 & 0xFF, h >>> 16 & 0xFF, h >>> 8 & 0xFF, h & 0xFF, l >>> 24 & 0xFF, l >>> 16 & 0xFF, l >>> 8 & 0xFF, l & 0xFF]); -} -/** - * Translate groups of 2 little-endian bytes to Integer (from 0 up to 65535). - * @param {Uint8Array} bytes - * @param {Number} offset - The offset (from the start of the given array) - * @returns {Number} - */ + if (segmentBufferStatus.type === "initialized") { + log/* default.info */.Z.info("Stream: Clearing previous " + bufferType + " SegmentBuffer"); + if (segment_buffers.isNative(bufferType)) { + return reloadAfterSwitch(period, clock$, relativePosAfterSwitch); + } -function le2toi(bytes, offset) { - return (bytes[offset + 0] << 0) + (bytes[offset + 1] << 8); -} -/** - * Translate groups of 4 little-endian bytes to Integer. - * @param {Uint8Array} bytes - * @param {Number} offset - The offset (from the start of the given array) - * @returns {Number} - */ + cleanBuffer$ = segmentBufferStatus.value.removeBuffer(period.start, period.end == null ? Infinity : period.end); + } else { + if (segmentBufferStatus.type === "uninitialized") { + segmentBuffersStore.disableSegmentBuffer(bufferType); + } + cleanBuffer$ = (0,of.of)(null); + } -function le4toi(bytes, offset) { - return bytes[offset + 0] + bytes[offset + 1] * 0x0000100 + bytes[offset + 2] * 0x0010000 + bytes[offset + 3] * 0x1000000; -} -/** - * Translate groups of 8 little-endian bytes to Integer. - * @param {Uint8Array} bytes - * @param {Number} offset - The offset (from the start of the given array) - * @returns {Number} - */ + return (0,concat/* concat */.z)(cleanBuffer$.pipe((0,mapTo/* mapTo */.h)(stream_events_generators.adaptationChange(bufferType, null, period))), createEmptyAdaptationStream(clock$, wantedBufferAhead$, bufferType, { + period: period + })); + } + if (segment_buffers.isNative(bufferType) && segmentBuffersStore.getStatus(bufferType).type === "disabled") { + return reloadAfterSwitch(period, clock$, relativePosAfterSwitch); + } -function le8toi(bytes, offset) { - return bytes[offset + 0] + bytes[offset + 1] * 0x0000100 + bytes[offset + 2] * 0x0010000 + bytes[offset + 3] * 0x1000000 + (bytes[offset + 4] + bytes[offset + 5] * 0x0000100 + bytes[offset + 6] * 0x0010000 + bytes[offset + 7] * 0x1000000) * 0x100000000; -} -/** - * Translate Integer (from 0 up to 65535) to a Uint8Array of length 2 of - * the corresponding little-endian bytes. - * @param {Number} num - * @returns {Uint8Array} - */ + log/* default.info */.Z.info("Stream: Updating " + bufferType + " adaptation", adaptation, period); + var newStream$ = clock$.pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.zg)(function (tick) { + var segmentBuffer = createOrReuseSegmentBuffer(segmentBuffersStore, bufferType, adaptation, options); + var playbackInfos = { + currentTime: tick.getCurrentTime(), + readyState: tick.readyState + }; + var strategy = getAdaptationSwitchStrategy(segmentBuffer, period, adaptation, playbackInfos, options); + if (strategy.type === "needs-reload") { + return reloadAfterSwitch(period, clock$, relativePosAfterSwitch); + } -function itole2(num) { - return new Uint8Array([num & 0xFF, num >>> 8 & 0xFF]); -} -/** - * Translate Integer to a Uint8Array of length 4 of the corresponding - * little-endian bytes. - * @param {Number} num - * @returns {Uint8Array} - */ + var cleanBuffer$ = strategy.type === "clean-buffer" ? concat/* concat.apply */.z.apply(void 0, strategy.value.map(function (_ref2) { + var start = _ref2.start, + end = _ref2.end; + return segmentBuffer.removeBuffer(start, end); + })).pipe((0,ignoreElements/* ignoreElements */.l)()) : empty/* EMPTY */.E; + var bufferGarbageCollector$ = garbageCollectors.get(segmentBuffer); + var adaptationStream$ = createAdaptationStream(adaptation, segmentBuffer); + return segmentBuffersStore.waitForUsableBuffers().pipe((0,mergeMap/* mergeMap */.zg)(function () { + return (0,concat/* concat */.z)(cleanBuffer$, (0,merge/* merge */.T)(adaptationStream$, bufferGarbageCollector$)); + })); + })); + return (0,concat/* concat */.z)((0,of.of)(stream_events_generators.adaptationChange(bufferType, adaptation, period)), newStream$); + }), (0,startWith/* startWith */.O)(stream_events_generators.periodStreamReady(bufferType, period, adaptation$))); + /** + * @param {Object} adaptation + * @param {Object} segmentBuffer + * @returns {Observable} + */ + function createAdaptationStream(adaptation, segmentBuffer) { + var manifest = content.manifest; + var adaptationStreamClock$ = clock$.pipe((0,map/* map */.U)(function (tick) { + var buffered = segmentBuffer.getBufferedRanges(); + return (0,object_assign/* default */.Z)({}, tick, { + bufferGap: (0,ranges/* getLeftSizeOfRange */.L7)(buffered, tick.position) + }); + })); + return stream_adaptation({ + abrManager: abrManager, + clock$: adaptationStreamClock$, + content: { + manifest: manifest, + period: period, + adaptation: adaptation + }, + options: options, + segmentBuffer: segmentBuffer, + segmentFetcherCreator: segmentFetcherCreator, + wantedBufferAhead$: wantedBufferAhead$ + }).pipe((0,catchError/* catchError */.K)(function (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 + if (!segment_buffers.isNative(bufferType)) { + log/* default.error */.Z.error("Stream: " + bufferType + " Stream crashed. Aborting it.", error); + segmentBuffersStore.disposeSegmentBuffer(bufferType); + var formattedError = formatError(error, { + defaultCode: "NONE", + defaultReason: "Unknown `AdaptationStream` error" + }); + return (0,concat/* concat */.z)((0,of.of)(stream_events_generators.warning(formattedError)), createEmptyAdaptationStream(clock$, wantedBufferAhead$, bufferType, { + period: period + })); + } -function itole4(num) { - return new Uint8Array([num & 0xFF, num >>> 8 & 0xFF, num >>> 16 & 0xFF, num >>> 24 & 0xFF]); + log/* default.error */.Z.error("Stream: " + bufferType + " Stream crashed. Stopping playback.", error); + throw error; + })); + } } /** - * Check if an ArrayBuffer is equal to the bytes given. - * @param {ArrayBuffer} buffer - * @param {Uint8Array} bytes - * @returns {Boolean} + * @param {string} bufferType + * @param {Object} adaptation + * @returns {Object} */ +function createOrReuseSegmentBuffer(segmentBuffersStore, bufferType, adaptation, options) { + var segmentBufferStatus = segmentBuffersStore.getStatus(bufferType); -function isABEqualBytes(buffer, bytes) { - var view = new DataView(buffer); - var len = view.byteLength; + if (segmentBufferStatus.type === "initialized") { + log/* default.info */.Z.info("Stream: Reusing a previous SegmentBuffer for the type", bufferType); // eslint-disable-next-line @typescript-eslint/no-unsafe-return - if (len !== bytes.length) { - return false; + return segmentBufferStatus.value; } - for (var i = 0; i < len; i++) { - if (view.getUint8(i) !== bytes[i]) { - return false; - } - } + var codec = getFirstDeclaredMimeType(adaptation); + var sbOptions = bufferType === "text" ? options.textTrackOptions : undefined; // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return true; + return segmentBuffersStore.createSegmentBuffer(bufferType, codec, sbOptions); } /** - * Convert any BufferSource-typed structure into the corresponding Uint8Array. - * @param {BufferSource} input - * @returns {Uint8Array} + * Get mime-type string of the first representation declared in the given + * adaptation. + * @param {Adaptation} adaptation + * @returns {string} */ -function toUint8Array(input) { - return input instanceof Uint8Array ? input : input instanceof ArrayBuffer ? new Uint8Array(input) : new Uint8Array(input.buffer); -} - - - -/***/ }), +function getFirstDeclaredMimeType(adaptation) { + var representations = adaptation.representations; -/***/ 8117: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (representations[0] == null) { + return ""; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ -/* harmony export */ }); -/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4379); -/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4072); -/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8170); -/* harmony import */ var _is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1946); + return representations[0].getMimeTypeString(); +} +;// CONCATENATED MODULE: ./src/core/stream/period/index.ts /** * Copyright 2015 CANAL+ Group * @@ -49575,260 +52041,153 @@ function toUint8Array(input) { * limitations under the License. */ - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - -function castToObservable(value) { - if (value instanceof rxjs__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y) { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return value; - } - /* eslint-disable-next-line @typescript-eslint/no-unsafe-member-access */ - - - if (!(0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(value) && typeof value.subscribe === "function") { - var valObsLike = value; - return new rxjs__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (obs) { - var sub = valObsLike.subscribe(function (val) { - obs.next(val); - }, function (err) { - obs.error(err); - }, function () { - obs.complete(); - }); - return function () { - if (!(0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(sub) && typeof sub.dispose === "function") { - sub.dispose(); - } else if (!(0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(sub) && typeof sub.unsubscribe === "function") { - sub.unsubscribe(); - } - }; - }); - } // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - - - if (!(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); - } // eslint-disable-next-line @typescript-eslint/no-unsafe-return - - - return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.of)(value); -} - -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castToObservable); - -/***/ }), - -/***/ 8025: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => /* binding */ deferSubscriptions -}); - -// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js -var tslib_es6 = __webpack_require__(655); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/Immediate.js -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var nextHandle = 1; -var RESOLVED = /*@__PURE__*/ (function () { return /*@__PURE__*/ Promise.resolve(); })(); -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; - RESOLVED.then(function () { return findAndClearHandle(handle) && cb(); }); - return handle; - }, - clearImmediate: function (handle) { - findAndClearHandle(handle); - }, -}; -var TestTools = { - pending: function () { - return Object.keys(activeHandles).length; - } -}; -//# sourceMappingURL=Immediate.js.map - -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsyncAction.js + 1 modules -var AsyncAction = __webpack_require__(6114); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsapAction.js -/** PURE_IMPORTS_START tslib,_util_Immediate,_AsyncAction PURE_IMPORTS_END */ - - +/* harmony default export */ const period = (PeriodStream); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/scan.js +var scan = __webpack_require__(2807); +;// 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. + */ -var AsapAction = /*@__PURE__*/ (function (_super) { - 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; - } - 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 = Immediate.setImmediate(scheduler.flush.bind(scheduler, null))); - }; - AsapAction.prototype.recycleAsyncId = function (scheduler, id, delay) { - if (delay === void 0) { - delay = 0; - } - if ((delay !== null && delay > 0) || (delay === null && this.delay > 0)) { - return _super.prototype.recycleAsyncId.call(this, scheduler, id, delay); - } - if (scheduler.actions.length === 0) { - Immediate.clearImmediate(id); - scheduler.scheduled = undefined; - } - return undefined; - }; - return AsapAction; -}(AsyncAction/* AsyncAction */.o)); -//# sourceMappingURL=AsapAction.js.map +/** + * 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.} bufferTypes - Every buffer types in the content. + * @param {Observable} addPeriodStream$ - Emit PeriodStream information when + * one is added. + * @param {Observable} removePeriodStream$ - Emit PeriodStream information when + * one is removed. + * @returns {Observable} + */ -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsyncScheduler.js + 1 modules -var AsyncScheduler = __webpack_require__(2980); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsapScheduler.js -/** PURE_IMPORTS_START tslib,_AsyncScheduler PURE_IMPORTS_END */ +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); -var AsapScheduler = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(AsapScheduler, _super); - function AsapScheduler() { - return _super !== null && _super.apply(this, arguments) || this; - } - AsapScheduler.prototype.flush = function (action) { - this.active = true; - this.scheduled = undefined; - var actions = this.actions; - var error; - var index = -1; - var count = actions.length; - action = action || actions.shift(); - do { - if (error = action.execute(action.state, action.delay)) { - break; - } - } while (++index < count && (action = actions.shift())); - this.active = false; - if (error) { - while (++index < count && (action = actions.shift())) { - action.unsubscribe(); + if (currentInfos.buffers.size === 0) { + delete acc[period.id]; } - throw error; + } } - }; - return AsapScheduler; -}(AsyncScheduler/* AsyncScheduler */.v)); - -//# sourceMappingURL=AsapScheduler.js.map - -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/asap.js -/** PURE_IMPORTS_START _AsapAction,_AsapScheduler PURE_IMPORTS_END */ - - -var asapScheduler = /*@__PURE__*/ new AsapScheduler(AsapAction); -var asap = asapScheduler; -//# sourceMappingURL=asap.js.map - -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules -var Observable = __webpack_require__(4379); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isNumeric.js -var isNumeric = __webpack_require__(5812); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/observable/SubscribeOnObservable.js -/** PURE_IMPORTS_START tslib,_Observable,_scheduler_asap,_util_isNumeric PURE_IMPORTS_END */ - + 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]; -var SubscribeOnObservable = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(SubscribeOnObservable, _super); - function SubscribeOnObservable(source, delayTime, scheduler) { - if (delayTime === void 0) { - delayTime = 0; - } - if (scheduler === void 0) { - scheduler = asap; - } - var _this = _super.call(this) || this; - _this.source = source; - _this.delayTime = delayTime; - _this.scheduler = scheduler; - if (!(0,isNumeric/* isNumeric */.k)(delayTime) || delayTime < 0) { - _this.delayTime = 0; - } - if (!scheduler || typeof scheduler.schedule !== 'function') { - _this.scheduler = asap; + if (_currentInfos !== undefined && !_currentInfos.buffers.has(_type)) { + _currentInfos.buffers.add(_type); + } else { + var bufferSet = new Set(); + bufferSet.add(_type); + acc[_period.id] = { + period: _period, + buffers: bufferSet + }; + } } - return _this; + break; } - SubscribeOnObservable.create = function (source, delay, scheduler) { - if (delay === void 0) { - delay = 0; - } - if (scheduler === void 0) { - scheduler = asap; - } - return new SubscribeOnObservable(source, delay, scheduler); - }; - SubscribeOnObservable.dispatch = function (arg) { - var source = arg.source, subscriber = arg.subscriber; - return this.add(source.subscribe(subscriber)); - }; - SubscribeOnObservable.prototype._subscribe = function (subscriber) { - var delay = this.delayTime; - var source = this.source; - var scheduler = this.scheduler; - return scheduler.schedule(SubscribeOnObservable.dispatch, delay, { - source: source, subscriber: subscriber - }); - }; - return SubscribeOnObservable; -}(Observable/* Observable */.y)); -//# sourceMappingURL=SubscribeOnObservable.js.map + return acc; + }, {}), (0,map/* map */.U)(function (list) { + var activePeriodIDs = Object.keys(list); + var completePeriods = []; -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/subscribeOn.js -/** PURE_IMPORTS_START _observable_SubscribeOnObservable PURE_IMPORTS_END */ + for (var i = 0; i < activePeriodIDs.length; i++) { + var periodInfos = list[activePeriodIDs[i]]; -function subscribeOn(scheduler, delay) { - if (delay === void 0) { - delay = 0; - } - return function subscribeOnOperatorFunction(source) { - return source.lift(new SubscribeOnOperator(scheduler, delay)); - }; -} -var SubscribeOnOperator = /*@__PURE__*/ (function () { - function SubscribeOnOperator(scheduler, delay) { - this.scheduler = scheduler; - this.delay = delay; + if (periodInfos !== undefined && periodInfos.buffers.size === numberOfStreams) { + completePeriods.push(periodInfos.period); + } } - SubscribeOnOperator.prototype.call = function (subscriber, source) { - return new SubscribeOnObservable(source, this.delay, this.scheduler).subscribe(subscriber); - }; - return SubscribeOnOperator; -}()); -//# sourceMappingURL=subscribeOn.js.map -;// CONCATENATED MODULE: ./src/utils/defer_subscriptions.ts + return completePeriods.reduce(function (acc, period) { + if (acc === null) { + return period; + } + + return period.start < acc.start ? period : acc; + }, null); + }), (0,distinctUntilChanged/* distinctUntilChanged */.x)(function (a, b) { + return a === null && b === null || a !== null && b !== null && a.id === b.id; + })); +} +;// CONCATENATED MODULE: ./src/core/stream/orchestrator/are_streams_complete.ts /** * Copyright 2015 CANAL+ Group * @@ -49847,93 +52206,48 @@ var SubscribeOnOperator = /*@__PURE__*/ (function () { /** - * 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); + * Returns an Observable which emits ``true`` when all PeriodStreams given are + * _complete_. + * Returns false otherwise. * - * // 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(subscribeOn(asapScheduler)); - }; -} - -/***/ }), + * 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} + */ -/***/ 1959: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +function areStreamsComplete() { + for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) { + streams[_key] = arguments[_key]; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ EventEmitter, -/* harmony export */ "R": () => /* binding */ fromEvent -/* harmony export */ }); -/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4379); -/* 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); + /** + * 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), (0,distinctUntilChanged/* distinctUntilChanged */.x)()); + }); + return (0,combineLatest/* combineLatest */.aj)(isCompleteArray).pipe((0,map/* map */.U)(function (areComplete) { + return areComplete.every(function (isComplete) { + return isComplete; + }); + }), (0,distinctUntilChanged/* distinctUntilChanged */.x)()); +} +;// CONCATENATED MODULE: ./src/core/stream/orchestrator/get_blacklisted_ranges.ts /** * Copyright 2015 CANAL+ Group * @@ -49950,137 +52264,74 @@ function deferSubscriptions() { * limitations under the License. */ - - /** - * Simple but fully type-safe EventEmitter implementation. - * @class EventEmitter + * Returns the buffered ranges which hold the given content. + * Returns the whole buffered ranges if some of it is unknown. + * @param {Object} segmentBuffer + * @param {Array.} contents + * @returns {Array.} */ -var EventEmitter = /*#__PURE__*/function () { - function EventEmitter() { - this._listeners = {}; - } - /** - * Register a new callback for an event. - * - * @param {string} evt - The event to register a callback to - * @param {Function} fn - The callback to call as that event is triggered. - * The callback will take as argument the eventual payload of the event - * (single argument). - */ - - - var _proto = EventEmitter.prototype; - - _proto.addEventListener = function addEventListener(evt, fn) { - var listeners = this._listeners[evt]; - - if (!Array.isArray(listeners)) { - this._listeners[evt] = [fn]; - } else { - listeners.push(fn); - } +function getBlacklistedRanges(segmentBuffer, contents) { + if (contents.length === 0) { + return []; } - /** - * Unregister callbacks linked to events. - * @param {string} [evt] - The event for which the callback[s] should be - * unregistered. Set it to null or undefined to remove all callbacks - * currently registered (for any event). - * @param {Function} [fn] - The callback to unregister. If set to null - * or undefined while the evt argument is set, all callbacks linked to that - * event will be unregistered. - */ - ; - - _proto.removeEventListener = function removeEventListener(evt, fn) { - if ((0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(evt)) { - this._listeners = {}; - return; - } - - var listeners = this._listeners[evt]; - if (!Array.isArray(listeners)) { - return; - } + segmentBuffer.synchronizeInventory(); + var accumulator = []; + var inventory = segmentBuffer.getInventory(); - if ((0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(fn)) { - delete this._listeners[evt]; - return; - } + var _loop = function _loop(i) { + var chunk = inventory[i]; + var hasContent = contents.some(function (content) { + return chunk.infos.period.id === content.period.id && chunk.infos.adaptation.id === content.adaptation.id && chunk.infos.representation.id === content.representation.id; + }); - var index = listeners.indexOf(fn); + if (hasContent) { + var bufferedStart = chunk.bufferedStart, + bufferedEnd = chunk.bufferedEnd; - if (index !== -1) { - listeners.splice(index, 1); - } + if (bufferedStart === undefined || bufferedEnd === undefined) { + log/* default.warn */.Z.warn("SO: No buffered start or end found from a segment."); + var buffered = segmentBuffer.getBufferedRanges(); + var len = buffered.length; - if (listeners.length === 0) { - delete this._listeners[evt]; - } - } - /** - * Trigger every registered callbacks for a given event - * @param {string} evt - The event to trigger - * @param {*} arg - The eventual payload for that event. All triggered - * callbacks will recieve this payload as argument. - */ - ; + if (len === 0) { + return { + v: [] + }; + } - _proto.trigger = function trigger(evt, arg) { - var listeners = this._listeners[evt]; + return { + v: [{ + start: buffered.start(0), + end: buffered.end(len - 1) + }] + }; + } - if (!Array.isArray(listeners)) { - return; - } + var previousLastElement = accumulator[accumulator.length - 1]; - listeners.slice().forEach(function (listener) { - try { - listener(arg); - } catch (e) { - _log__WEBPACK_IMPORTED_MODULE_1__/* .default.error */ .Z.error(e, e instanceof Error ? e.stack : null); + if (previousLastElement !== undefined && previousLastElement.end === bufferedStart) { + previousLastElement.end = bufferedEnd; + } else { + accumulator.push({ + start: bufferedStart, + end: bufferedEnd + }); } - }); + } }; - 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} - */ - - + for (var i = 0; i < inventory.length; i++) { + var _ret = _loop(i); -function fromEvent(target, eventName) { - return new rxjs__WEBPACK_IMPORTED_MODULE_2__/* .Observable */ .y(function (obs) { - function handler(event) { - obs.next(event); - } + if (typeof _ret === "object") return _ret.v; + } - target.addEventListener(eventName, handler); - return function () { - target.removeEventListener(eventName, handler); - }; - }); + return accumulator; } - -/***/ }), - -/***/ 2793: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ filterMap -/* harmony export */ }); -/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1410); -/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5709); -/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6008); +;// CONCATENATED MODULE: ./src/core/stream/orchestrator/stream_orchestrator.ts /** * Copyright 2015 CANAL+ Group * @@ -50098,192 +52349,361 @@ function fromEvent(target, eventName) { */ -/** - * 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_operators__WEBPACK_IMPORTED_MODULE_1__/* .map */ .U)(callback), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__/* .filter */ .h)(function (x) { - return x !== filteringToken; - })); - }); - }; -} -/***/ }), -/***/ 9592: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ flatMap -/* harmony export */ }); + + + + + + + + + + +var MAXIMUM_MAX_BUFFER_AHEAD = config/* default.MAXIMUM_MAX_BUFFER_AHEAD */.Z.MAXIMUM_MAX_BUFFER_AHEAD, + MAXIMUM_MAX_BUFFER_BEHIND = config/* default.MAXIMUM_MAX_BUFFER_BEHIND */.Z.MAXIMUM_MAX_BUFFER_BEHIND; /** - * Copyright 2015 CANAL+ Group + * Create and manage the various Stream Observables needed for the content to + * play: * - * 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 + * - Create or dispose SegmentBuffers depending on the chosen Adaptations. * - * http://www.apache.org/licenses/LICENSE-2.0 + * - Push the right segments to those SegmentBuffers depending on the user's + * preferences, the current position, the bandwidth, the decryption + * conditions... * - * 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. + * - 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 + * + * @param {Object} content + * @param {Observable} clock$ - Emit position information + * @param {Object} abrManager - 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} */ -/** - * Map each element using a mapping function, then flat the result into - * a new array. - * @param {Array.<*>} originalArray - * @param {Function} fn - */ -function flatMap(originalArray, fn) { - /* eslint-disable @typescript-eslint/unbound-method */ +function StreamOrchestrator(content, clock$, abrManager, segmentBuffersStore, segmentFetcherCreator, options) { + var manifest = content.manifest, + initialPeriod = content.initialPeriod; + var maxBufferAhead$ = options.maxBufferAhead$, + maxBufferBehind$ = options.maxBufferBehind$, + wantedBufferAhead$ = options.wantedBufferAhead$; // Keep track of a unique BufferGarbageCollector created per + // SegmentBuffer. - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ + var garbageCollectors = new WeakMapMemory(function (segmentBuffer) { + 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 BufferGarbageCollector({ + segmentBuffer: segmentBuffer, + clock$: clock$.pipe((0,map/* map */.U)(function (tick) { + return tick.position + tick.wantedTimeOffset; + })), + maxBufferBehind$: maxBufferBehind$.pipe((0,map/* map */.U)(function (val) { + return Math.min(val, defaultMaxBehind); + })), + maxBufferAhead$: maxBufferAhead$.pipe((0,map/* map */.U)(function (val) { + return Math.min(val, defaultMaxAhead); + })) + }); + }); // trigger warnings when the wanted time is before or after the manifest's + // segments - /* eslint-disable @typescript-eslint/no-unsafe-return */ + var outOfManifest$ = clock$.pipe((0,filter_map/* default */.Z)(function (_ref) { + var position = _ref.position, + wantedTimeOffset = _ref.wantedTimeOffset; + var offsetedPosition = wantedTimeOffset + position; - /* eslint-disable @typescript-eslint/no-unsafe-call */ - if (typeof Array.prototype.flatMap === "function") { - return originalArray.flatMap(fn); - } - /* eslint-enable @typescript-eslint/unbound-method */ + if (offsetedPosition < manifest.getMinimumPosition()) { + var warning = new media_error/* default */.Z("MEDIA_TIME_BEFORE_MANIFEST", "The current position is behind the " + "earliest time announced in the Manifest."); + return stream_events_generators.warning(warning); + } else if (offsetedPosition > manifest.getMaximumPosition()) { + var _warning = new media_error/* default */.Z("MEDIA_TIME_AFTER_MANIFEST", "The current position is after the latest " + "time announced in the Manifest."); - /* eslint-enable @typescript-eslint/no-unsafe-member-access */ + return stream_events_generators.warning(_warning); + } - /* eslint-enable @typescript-eslint/no-unsafe-return */ + return null; + }, null)); + var bufferTypes = segmentBuffersStore.getBufferTypes(); // Every PeriodStreams for every possible types - /* eslint-enable @typescript-eslint/no-unsafe-call */ + var streamsArray = bufferTypes.map(function (bufferType) { + return manageEveryStreams(bufferType, initialPeriod).pipe((0,defer_subscriptions/* default */.Z)(), (0,share/* share */.B)()); + }); // 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); + return stream_events_generators.activePeriodChanged(period); + })); // Emits an "end-of-stream" event once every PeriodStream are complete. + // Emits a 'resume-stream" when it's not + + var endOfStream$ = areStreamsComplete.apply(void 0, streamsArray).pipe((0,map/* map */.U)(function (areComplete) { + return areComplete ? stream_events_generators.endOfStream() : stream_events_generators.resumeStream(); + })); + return merge/* merge.apply */.T.apply(void 0, streamsArray.concat([activePeriodChanged$, endOfStream$, outOfManifest$])); + /** + * Manage creation and removal of Streams for every Periods for a given type. + * + * Works by creating consecutive Streams through the + * `manageConsecutivePeriodStreams` function, and restarting it when the clock + * 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 + var periodList = new SortedList(function (a, b) { + return a.start - b.start; + }); + var destroyStreams$ = new Subject/* Subject */.xQ(); // 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; + /** + * @param {Object} period + * @returns {Observable} + */ + + function launchConsecutiveStreamsForPeriod(period) { + return manageConsecutivePeriodStreams(bufferType, period, destroyStreams$).pipe((0,filter_map/* default */.Z)(function (message) { + switch (message.type) { + case "needs-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 null; + } + + break; + + case "periodStreamReady": + enableOutOfBoundsCheck = true; + periodList.add(message.value.period); + break; + + case "periodStreamCleared": + periodList.removeElement(message.value.period); + break; + } + + return message; + }, null), (0,share/* share */.B)()); + } + /** + * Returns true if the given time is either: + * - less than the start of the chronologically first Period + * - more than the end of the chronologically last Period + * @param {number} time + * @returns {boolean} + */ + + + function isOutOfPeriodList(time) { + var head = periodList.head(); + var last = periodList.last(); + + if (head == null || last == null) { + // if no period + return true; + } + + 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 restartStreamsWhenOutOfBounds$ = clock$.pipe((0,filter_map/* default */.Z)(function (_ref2) { + var position = _ref2.position, + wantedTimeOffset = _ref2.wantedTimeOffset; + + var _a; + + var time = wantedTimeOffset + position; + + if (!enableOutOfBoundsCheck || !isOutOfPeriodList(time)) { + return null; + } + + var nextPeriod = (_a = manifest.getPeriodForTime(time)) !== null && _a !== void 0 ? _a : 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, position + wantedTimeOffset); + enableOutOfBoundsCheck = false; + destroyStreams$.next(); + return nextPeriod; + }, null), (0,mergeMap/* mergeMap */.zg)(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); + })); // Free the buffer of undecipherable data + + var handleDecipherabilityUpdate$ = (0,event_emitter/* fromEvent */.R)(manifest, "decipherabilityUpdate").pipe((0,mergeMap/* mergeMap */.zg)(function (updates) { + var segmentBufferStatus = segmentBuffersStore.getStatus(bufferType); + var hasType = updates.some(function (update) { + return update.adaptation.type === bufferType; + }); + + if (!hasType || segmentBufferStatus.type !== "initialized") { + return empty/* EMPTY */.E; // no need to stop the current Streams. + } + + var undecipherableUpdates = updates.filter(function (update) { + return update.representation.decipherable === false; + }); + var segmentBuffer = segmentBufferStatus.value; + var rangesToClean = getBlacklistedRanges(segmentBuffer, undecipherableUpdates); + + if (rangesToClean.length === 0) { + // Nothing to clean => no buffer to flush. + return empty/* EMPTY */.E; + } // We have to remove the undecipherable media data and then ask the + // current media element to be "flushed" + + + enableOutOfBoundsCheck = false; + destroyStreams$.next(); + return concat/* concat.apply */.z.apply(void 0, rangesToClean.map(function (_ref3) { + var start = _ref3.start, + end = _ref3.end; + return segmentBuffer.removeBuffer(start, end).pipe((0,ignoreElements/* ignoreElements */.l)()); + }).concat([clock$.pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.zg)(function (lastTick) { + return (0,concat/* concat */.z)((0,of.of)(stream_events_generators.needsDecipherabilityFlush(lastTick.position, !lastTick.isPaused, lastTick.duration)), (0,defer/* defer */.P)(function () { + var lastPosition = lastTick.position + lastTick.wantedTimeOffset; + 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."); + } + + return launchConsecutiveStreamsForPeriod(newInitialPeriod); + })); + }))])); + })); + return (0,merge/* merge */.T)(restartStreamsWhenOutOfBounds$, handleDecipherabilityUpdate$, launchConsecutiveStreamsForPeriod(basePeriod)); + } + /** + * Create lazily consecutive PeriodStreams: + * + * 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 + * full. + * + * 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 clock announces a time 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. + * + * A "periodStreamCleared" event is sent each times a PeriodStream is + * destroyed. + * @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} + */ - return originalArray.reduce(function (acc, arg) { - var r = fn(arg); + function manageConsecutivePeriodStreams(bufferType, basePeriod, destroy$) { + log/* default.info */.Z.info("SO: Creating new Stream for", bufferType, basePeriod); // Emits the Period of the next Period Stream when it can be created. - if (Array.isArray(r)) { - acc.push.apply(acc, r); - return acc; - } + var createNextPeriodStream$ = new Subject/* Subject */.xQ(); // Emits when the Streams for the next Periods should be destroyed, if + // created. - acc.push(r); - return acc; - }, []); -} + var destroyNextStreams$ = new Subject/* Subject */.xQ(); // Emits when the current position goes over the end of the current Stream. -/***/ }), + var endOfCurrentStream$ = clock$.pipe((0,filter/* filter */.h)(function (_ref4) { + var position = _ref4.position, + wantedTimeOffset = _ref4.wantedTimeOffset; + return basePeriod.end != null && position + wantedTimeOffset >= basePeriod.end; + })); // Create Period Stream for the next Period. -/***/ 2572: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + 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. -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ getFuzzedDelay -/* harmony export */ }); -/** - * 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 FUZZ_FACTOR = 0.3; -/** - * Perform "fuzzing" on the delay given. - * @param {Number} retryDelay - * @returns {Number} - */ + 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 -function getFuzzedDelay(retryDelay) { - var fuzzingFactor = (Math.random() * 2 - 1) * FUZZ_FACTOR; - return retryDelay * (fuzzingFactor + 1); // Max 1.3 Min 0.7 -} + 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({ + abrManager: abrManager, + bufferType: bufferType, + clock$: clock$, + content: { + manifest: manifest, + period: basePeriod + }, + garbageCollectors: garbageCollectors, + segmentFetcherCreator: segmentFetcherCreator, + segmentBuffersStore: segmentBuffersStore, + options: options, + wantedBufferAhead$: wantedBufferAhead$ + }).pipe((0,mergeMap/* mergeMap */.zg)(function (evt) { + if (evt.type === "stream-status") { + if (evt.value.hasFinishedLoading) { + var nextPeriod = manifest.getPeriodAfter(basePeriod); -/***/ 2870: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (nextPeriod === null) { + return (0,concat/* concat */.z)((0,of.of)(evt), (0,of.of)(stream_events_generators.streamComplete(bufferType))); + } // current Stream is full, create the next one if not -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ hashBuffer -/* harmony export */ }); -/** - * 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. - */ -/** - * Convert given buffer to a 32bit integer hash - * - * This algorithm is the same one that Java `String.hashCode()` one which - * is a fast hashing function adapted to short ASCII strings. - * This consequently might not be the most adapted to buffers of various length - * containing a various amount of data but still has the advantage of being - * fast. - * - * As this function is used in persistent MediaKeySession storage, we probably - * should keep this function somewhere as long as we want to support - * MediaKeySessions persisted in old versions of the RxPlayer. - * - * @param {Array.|TypedArray} buffer - * @returns {number} - */ -function hashBuffer(buffer) { - var hash = 0; + createNextPeriodStream$.next(nextPeriod); + } else { + // current Stream is active, destroy next Stream if created + destroyNextStreams$.next(); + } + } - var _char; + return (0,of.of)(evt); + }), (0,share/* share */.B)()); // Stream for the current Period. - for (var i = 0; i < buffer.length; i++) { - _char = buffer[i]; - hash = (hash << 5) - hash + _char; - hash = hash & hash; // Convert to 32bit integer + var currentStream$ = (0,concat/* concat */.z)(periodStream$.pipe((0,takeUntil/* takeUntil */.R)(killCurrentStream$)), (0,of.of)(stream_events_generators.periodStreamCleared(bufferType, basePeriod)).pipe((0,tap/* tap */.b)(function () { + log/* default.info */.Z.info("SO: Destroying Stream for", bufferType, basePeriod); + }))); + return (0,merge/* merge */.T)(currentStream$, nextPeriodStream$, destroyAll$.pipe((0,ignoreElements/* ignoreElements */.l)())); } - - return hash; } - -/***/ }), - -/***/ 908: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ idGenerator -/* harmony export */ }); +;// CONCATENATED MODULE: ./src/core/stream/orchestrator/index.ts /** * Copyright 2015 CANAL+ Group * @@ -50300,36 +52720,8 @@ function hashBuffer(buffer) { * limitations under the License. */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ - -/** - * Creates an ID generator which generates an ID each time you call it. - * @returns {Function} - */ -function idGenerator() { - var prefix = ""; - var currId = -1; - return function generateNewId() { - currId++; - - if (currId >= Number.MAX_SAFE_INTEGER) { - prefix += "0"; - currId = 0; - } - - return prefix + String(currId); - }; -} - -/***/ }), - -/***/ 6923: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ isNonEmptyString -/* harmony export */ }); +/* harmony default export */ const orchestrator = (StreamOrchestrator); +;// CONCATENATED MODULE: ./src/core/stream/index.ts /** * Copyright 2015 CANAL+ Group * @@ -50346,23 +52738,9 @@ function idGenerator() { * limitations under the License. */ -/** - * @param {*} x - * @returns {string} - */ -function isNonEmptyString(x) { - return typeof x === "string" && x.length > 0; -} - -/***/ }), - -/***/ 1946: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ isNullOrUndefined -/* harmony export */ }); +/* harmony default export */ const stream = (orchestrator); +;// CONCATENATED MODULE: ./src/core/init/duration_updater.ts /** * Copyright 2015 CANAL+ Group * @@ -50379,66 +52757,109 @@ function isNonEmptyString(x) { * limitations under the License. */ -/** - * Returns true if the argument given is either null or undefined. - * This function was added to have a clearer alternative to `== null` which is - * not always understood by newcomers to the code, and which can be overused when - * only one of the possibility can arise. - * @param {*} x - * @returns {*} - */ -function isNullOrUndefined(x) { - return x === null || x === undefined; -} -/***/ }), -/***/ 7829: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +/** Number of seconds in a regular year. */ -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "ZP": () => __WEBPACK_DEFAULT_EXPORT__ -/* harmony export */ }); -/* harmony import */ var _normalize__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5553); +var YEAR_IN_SECONDS = 365 * 24 * 3600; /** - * 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. + * Keep the MediaSource duration up-to-date with the Manifest one on + * subscription: + * Set the current duration initially and then update if needed after + * each Manifest updates. + * @param {Object} manifest + * @param {MediaSource} mediaSource + * @returns {Observable} */ -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_normalize__WEBPACK_IMPORTED_MODULE_0__/* .default */ .ZP); +function DurationUpdater(manifest, mediaSource) { + return (0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,startWith/* startWith */.O)(null), (0,tap/* tap */.b)(function () { + var maximumPosition = manifest.getMaximumPosition(); // Some targets poorly support setting a very high number for durations. + // Yet, in live 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. + var newDuration = !manifest.isLive ? maximumPosition : Math.max(Math.pow(2, 32), maximumPosition + YEAR_IN_SECONDS); -/***/ }), + if (isNaN(mediaSource.duration) || !isFinite(mediaSource.duration) || Math.abs(mediaSource.duration - newDuration) > 0.01) { + log/* default.info */.Z.info("Init: Updating duration", newDuration); + mediaSource.duration = newDuration; + } + }), (0,ignoreElements/* ignoreElements */.l)()); +} +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/race.js +var race = __webpack_require__(8821); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/ArgumentOutOfRangeError.js +var ArgumentOutOfRangeError = __webpack_require__(6565); +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/takeLast.js +/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ -/***/ 5553: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "ZP": () => /* binding */ normalize, - "iH": () => /* binding */ normalizeAudioTrack, - "Y1": () => /* binding */ normalizeTextTrack -}); -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -// EXTERNAL MODULE: ./src/utils/is_null_or_undefined.ts -var is_null_or_undefined = __webpack_require__(1946); -;// CONCATENATED MODULE: ./src/utils/languages/ISO_639-1_to_ISO_639-3.ts +function takeLast(count) { + return function takeLastOperatorFunction(source) { + if (count === 0) { + return (0,empty/* empty */.c)(); + } + else { + return source.lift(new TakeLastOperator(count)); + } + }; +} +var TakeLastOperator = /*@__PURE__*/ (function () { + function TakeLastOperator(total) { + this.total = total; + if (this.total < 0) { + throw new ArgumentOutOfRangeError/* ArgumentOutOfRangeError */.W; + } + } + TakeLastOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TakeLastSubscriber(subscriber, this.total)); + }; + return TakeLastOperator; +}()); +var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(TakeLastSubscriber, _super); + function TakeLastSubscriber(destination, total) { + var _this = _super.call(this, destination) || this; + _this.total = total; + _this.ring = new Array(); + _this.count = 0; + return _this; + } + TakeLastSubscriber.prototype._next = function (value) { + var ring = this.ring; + var total = this.total; + var count = this.count++; + if (ring.length < total) { + ring.push(value); + } + else { + var index = count % total; + ring[index] = value; + } + }; + TakeLastSubscriber.prototype._complete = function () { + var destination = this.destination; + var count = this.count; + if (count > 0) { + var total = this.count >= this.total ? this.total : this.count; + var ring = this.ring; + for (var i = 0; i < total; i++) { + var idx = (count++) % total; + destination.next(ring[idx]); + } + } + destination.complete(); + }; + return TakeLastSubscriber; +}(Subscriber/* Subscriber */.L)); +//# sourceMappingURL=takeLast.js.map + +;// CONCATENATED MODULE: ./src/core/init/end_of_stream.ts /** * Copyright 2015 CANAL+ Group * @@ -50454,198 +52875,85 @@ var is_null_or_undefined = __webpack_require__(1946); * See the License for the specific language governing permissions and * limitations under the License. */ - -/** - * Translate ISO 639-1 language codes into ISO 639-3 ones. - */ -var ISO_MAP_1_TO_3 = { - aa: "aar", - ab: "abk", - ae: "ave", - af: "afr", - ak: "aka", - am: "amh", - an: "arg", - ar: "ara", - as: "asm", - av: "ava", - ay: "aym", - az: "aze", - ba: "bak", - be: "bel", - bg: "bul", - bi: "bis", - bm: "bam", - bn: "ben", - bo: "bod", - br: "bre", - bs: "bos", - ca: "cat", - ce: "che", - ch: "cha", - co: "cos", - cr: "cre", - cs: "ces", - cu: "chu", - // Old Slavonic, Old Bulgarian - cv: "chv", - cy: "cym", - da: "dan", - de: "deu", - dv: "div", - dz: "dzo", - ee: "ewe", - el: "ell", - en: "eng", - eo: "epo", - es: "spa", - et: "est", - eu: "eus", - fa: "fas", - ff: "ful", - fi: "fin", - fj: "fij", - fo: "fao", - fr: "fra", - fy: "fry", - ga: "gle", - gd: "gla", - gl: "glg", - gn: "grn", - gu: "guj", - gv: "glv", - ha: "hau", - he: "heb", - hi: "hin", - ho: "hmo", - hr: "hrv", - ht: "hat", - hu: "hun", - hy: "hye", - hz: "her", - ia: "ina", - id: "ind", - ie: "ile", - ig: "ibo", - ii: "iii", - ik: "ipk", - io: "ido", - is: "isl", - it: "ita", - iu: "iku", - ja: "jpn", - jv: "jav", - ka: "kat", - kg: "kon", - ki: "kik", - kj: "kua", - kk: "kaz", - kl: "kal", - km: "khm", - kn: "kan", - ko: "kor", - kr: "kau", - ks: "kas", - ku: "kur", - kv: "kom", - kw: "cor", - ky: "kir", - la: "lat", - lb: "ltz", - lg: "lug", - li: "lim", - ln: "lin", - lo: "lao", - lt: "lit", - lu: "lub", - lv: "lav", - mg: "mlg", - mh: "mah", - mi: "mri", - mk: "mkd", - ml: "mal", - mn: "mon", - mr: "mar", - ms: "msa", - mt: "mlt", - my: "mya", - na: "nau", - nb: "nob", - nd: "nde", - ne: "nep", - ng: "ndo", - nl: "nld", - nn: "nno", - no: "nor", - nr: "nbl", - nv: "nav", - ny: "nya", - oc: "oci", - oj: "oji", - om: "orm", - or: "ori", - os: "oss", - pa: "pan", - pi: "pli", - pl: "pol", - ps: "pus", - pt: "por", - qu: "que", - rm: "roh", - rn: "run", - ro: "ron", - ru: "rus", - rw: "kin", - sa: "san", - sc: "srd", - sd: "snd", - se: "sme", - sg: "sag", - si: "sin", - sk: "slk", - sl: "slv", - sm: "smo", - sn: "sna", - so: "som", - sq: "sqi", - sr: "srp", - ss: "ssw", - st: "sot", - su: "sun", - sv: "swe", - sw: "swa", - ta: "tam", - te: "tel", - tg: "tgk", - th: "tha", - ti: "tir", - tk: "tuk", - tl: "tgl", - tn: "tsn", - to: "ton", - tr: "tur", - ts: "tso", - tt: "tat", - tw: "twi", - ty: "tah", - ug: "uig", - uk: "ukr", - ur: "urd", - uz: "uzb", - ve: "ven", - vi: "vie", - vo: "vol", - wa: "wln", - wo: "wol", - xh: "xho", - yi: "yid", - yo: "yor", - za: "zha", - zh: "zho", - zu: "zul" -}; -/* harmony default export */ const ISO_639_1_to_ISO_639_3 = (ISO_MAP_1_TO_3); -;// CONCATENATED MODULE: ./src/utils/languages/ISO_639-2_to_ISO_639-3.ts + + + + +var onRemoveSourceBuffers$ = event_listeners/* onRemoveSourceBuffers$ */.gg, + end_of_stream_onSourceOpen$ = event_listeners/* onSourceOpen$ */.ym, + onUpdate$ = event_listeners/* onUpdate$ */._E; +/** + * Get "updating" SourceBuffers from a SourceBufferList. + * @param {SourceBufferList} sourceBuffers + * @returns {Array.} + */ + +function getUpdatingSourceBuffers(sourceBuffers) { + var updatingSourceBuffers = []; + + for (var i = 0; i < sourceBuffers.length; i++) { + var SourceBuffer = sourceBuffers[i]; + + if (SourceBuffer.updating) { + updatingSourceBuffers.push(SourceBuffer); + } + } + + return updatingSourceBuffers; +} +/** + * Trigger the `endOfStream` method of a MediaSource. + * + * If the MediaSource is ended/closed, do not call this method. + * 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 (0,race/* race */.S3)(merge/* merge.apply */.T.apply(void 0, updatedSourceBuffers$).pipe(takeLast(1)), onRemoveSourceBuffers$(sourceBuffers).pipe((0,take/* take */.q)(1))).pipe((0,mergeMap/* mergeMap */.zg)(function () { + return triggerEndOfStream(mediaSource); + })); + }); +} +/** + * Trigger the `endOfStream` method of a MediaSource each times it opens. + * @see triggerEndOfStream + * @param {MediaSource} mediaSource + * @returns {Observable} + */ + +function maintainEndOfStream(mediaSource) { + return end_of_stream_onSourceOpen$(mediaSource).pipe((0,startWith/* startWith */.O)(null), (0,switchMap/* switchMap */.w)(function () { + return triggerEndOfStream(mediaSource); + })); +} +// EXTERNAL MODULE: ./src/core/init/emit_loaded_event.ts + 3 modules +var emit_loaded_event = __webpack_require__(7247); +;// CONCATENATED MODULE: ./src/core/init/initial_seek_and_play.ts /** * Copyright 2015 CANAL+ Group * @@ -50662,33 +52970,118 @@ var ISO_MAP_1_TO_3 = { * limitations under the License. */ + + + /** - * Translate ISO 639-2 synonyms to their ISO 639-3 counterparts. + * When the HTMLMediaElement is ready, perform if needed: + * - the initial seek + * - the initial autoplay operation + * + * Returns the following Observables: + * + * - `clock$`: The central observable performing both the seek and autoPlay. + * Also returns an updated clock's tick (which includes information such as + * the position offset until the seek is taken into account or the last + * wanted playback speed). + * + * - `loaded$`: An observable emitting events specifically related to the + * loading status. Will always emit its last value on subscription. + * + * @see ILoadEvents for more information. + * + * @param {HTMLMediaElement} mediaElement + * @param {Observable} initClock$ + * @param {Object} streamClockArgument + * @returns {Observable} */ -var ISO_MAP_2_TO_3 = { - alb: "sqi", - arm: "hye", - baq: "eus", - bur: "mya", - chi: "zho", - cze: "ces", - dut: "nld", - fre: "fra", - geo: "kat", - ger: "deu", - gre: "ell", - ice: "isl", - mac: "mkd", - mao: "mri", - may: "msa", - per: "fas", - slo: "slk", - rum: "ron", - tib: "bod", - wel: "cym" -}; -/* harmony default export */ const ISO_639_2_to_ISO_639_3 = (ISO_MAP_2_TO_3); -;// CONCATENATED MODULE: ./src/utils/languages/normalize.ts + +function initialSeekAndPlay(mediaElement, initClock$, _ref) { + var autoPlay = _ref.autoPlay, + manifest = _ref.manifest, + speed$ = _ref.speed$, + startTime = _ref.startTime, + setCurrentTime = _ref.setCurrentTime; + + /** + * `true` once the content is considered "loaded". + * This means it can begin to play. + */ + var isLoaded = false; + /** `true` once the seek to a protential initial position has been performed. */ + + var isSeekDone = false; + /** + * Emit loading-related events. + * As its own ReplaySubject to avoid polluting the more general clock$ + * Observable. + */ + + var loaded$ = new ReplaySubject/* ReplaySubject */.t(1); + /** + * Silent Observable (does not emit anything) which performs autoPlay if + * needed and which emits through `loaded$` the current loading status. + * Completes when done. + */ + + var load$ = (0,emit_loaded_event/* default */.Z)(initClock$, mediaElement, autoPlay, false).pipe((0,tap/* tap */.b)(function (evt) { + isLoaded = true; + loaded$.next(evt); + }), (0,ignoreElements/* ignoreElements */.l)()); + /** + * Observable trying to perform the initial seek and emitting updated clock + * ticks. + */ + + var clock$ = (0,combineLatest/* combineLatest */.aj)([initClock$, speed$]).pipe((0,map/* map */.U)(function (_ref2) { + var tick = _ref2[0], + speed = _ref2[1]; + + /** + * When this value is `false`, the `startTime` should be considered as + * the current position instead of the clock tick's `position` property. + * This is because that clock tick was triggered before the initial seek + * was done. + */ + var isTickPositionRight = isSeekDone; // perform initial seek, if ready and not already done + + if (!isSeekDone && (tick.readyState > 0 || tick.event === "loadedmetadata")) { + if (mediaElement.currentTime !== startTime) { + log/* default.info */.Z.info("Init: Set initial time", startTime); + setCurrentTime(startTime); + } + + isSeekDone = true; + } + + var liveGap = !manifest.isLive ? Infinity : isTickPositionRight ? manifest.getMaximumPosition() - tick.position : manifest.getMaximumPosition() - startTime; + return { + position: tick.position, + getCurrentTime: tick.getCurrentTime, + duration: tick.duration, + isPaused: isLoaded ? tick.paused : !autoPlay, + liveGap: liveGap, + readyState: tick.readyState, + speed: speed, + stalled: tick.stalled, + // wantedTimeOffset is an offset to add to the timing's current time to have + // the "real" wanted position. + // For now, this is seen when the media element has not yet seeked to its + // initial position, the currentTime will most probably be 0 where the + // effective starting position will be _startTime_. + // Thus we initially set a wantedTimeOffset equal to startTime. + wantedTimeOffset: isTickPositionRight ? 0 : startTime + }; + })); + return { + loaded$: loaded$, + clock$: (0,merge/* merge */.T)(load$, clock$).pipe((0,shareReplay/* shareReplay */.d)({ + bufferSize: 1, + refCount: true + })) + }; +} +;// CONCATENATED MODULE: ./src/compat/is_playback_stuck.ts /** * Copyright 2015 CANAL+ Group * @@ -50705,145 +53098,414 @@ var ISO_MAP_2_TO_3 = { * limitations under the License. */ +/** + * firefox fix: sometimes playback can be stalled, even if we are in a buffer. + * TODO This seems to be about an old Firefox version. Delete it? + * @param {number} time + * @param {Object|null} currentRange + * @param {string} state + * @param {Boolean} isStalled + * @returns {Boolean} + */ +function isPlaybackStuck(time, currentRange, state, isStalled) { + var FREEZE_THRESHOLD = 10; // freeze threshold in seconds + return browser_detection/* isFirefox */.vU && isStalled && state === "timeupdate" && currentRange != null && currentRange.end - time > FREEZE_THRESHOLD; +} +;// CONCATENATED MODULE: ./src/compat/is_seeking_approximate.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. + */ /** - * Normalize language given. - * Basically: - * - converts it to lowercase. - * - normalize "base" (what is before the possible first "-") to an ISO639-3 - * compatible string. - * @param {string} _language - * @returns {string} + * On some devices (right now only seen on Tizen), seeking through the + * `currentTime` property can lead to the browser re-seeking once the + * segments have been loaded to improve seeking performances (for + * example, by seeking right to an intra video frame). + * + * This can lead to conflicts with the RxPlayer code. + * + * This boolean is only `true` on the devices where this behavior has been + * observed. */ -function normalizeLanguage(_language) { - if ((0,is_null_or_undefined/* default */.Z)(_language) || _language === "") { - return ""; - } +var isSeekingApproximate = browser_detection/* isTizen */.yS; +/* harmony default export */ const is_seeking_approximate = (isSeekingApproximate); +;// CONCATENATED MODULE: ./src/core/init/stall_avoider.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 fields = ("" + _language).toLowerCase().split("-"); - var base = fields[0]; - var normalizedBase = normalizeBase(base); - if ((0,is_non_empty_string/* default */.Z)(normalizedBase)) { - return normalizedBase; - } - return _language; -} -/** - * Normalize language into an ISO639-3 format. - * Returns undefined if it failed to do so - * @param {string} base - * @returns {string} - */ -function normalizeBase(base) { - var result; - switch (base.length) { - case 2: - result = ISO_639_1_to_ISO_639_3[base]; - break; - case 3: - result = ISO_639_2_to_ISO_639_3[base]; - break; - } +var BUFFER_DISCONTINUITY_THRESHOLD = config/* default.BUFFER_DISCONTINUITY_THRESHOLD */.Z.BUFFER_DISCONTINUITY_THRESHOLD, + FORCE_DISCONTINUITY_SEEK_DELAY = config/* default.FORCE_DISCONTINUITY_SEEK_DELAY */.Z.FORCE_DISCONTINUITY_SEEK_DELAY; +/** + * Work-around rounding errors with floating points by setting an acceptable, + * very short, deviation when checking equalities. + */ - return result; -} +var EPSILON = 1 / 60; /** - * Normalize text track from a user given input into an object - * with three properties: - * - language {string}: The language the user gave us - * - normalized {string}: An attempt to normalize the language into an - * ISO 639-3 code - * - closedCaption {Boolean}: Whether the track is a closed caption track - * @param {Object|string|null|undefined} _language - * @returns {Object|null|undefined} + * Monitor situations where playback is stalled and try to get out of those. + * Emit "stalled" then "unstalled" respectably when an unavoidable stall is + * encountered and exited. + * @param {Observable} clock$ - Observable emitting the current playback + * conditions. + * @param {HTMLMediaElement} mediaElement - The HTMLMediaElement on which the + * media is played. + * @param {Object} manifest - The Manifest of the currently-played content. + * @param {Observable} discontinuityUpdate$ - Observable emitting encountered + * discontinuities for loaded Period and buffer types. + * @returns {Observable} */ +function StallAvoider(clock$, mediaElement, manifest, discontinuityUpdate$, setCurrentTime) { + var initialDiscontinuitiesStore = []; + /** + * Emit every known audio and video buffer discontinuities in chronological + * order (first ordered by Period's start, then by bufferType in any order. + */ -function normalizeTextTrack(_language) { - if (!(0,is_null_or_undefined/* default */.Z)(_language)) { - var language; - var closedCaption = false; + var discontinuitiesStore$ = discontinuityUpdate$.pipe(withLatestFrom(clock$), // listen to clock to clean-up old discontinuities + (0,scan/* scan */.R)(function (discontinuitiesStore, _ref) { + var evt = _ref[0], + tick = _ref[1]; + return updateDiscontinuitiesStore(discontinuitiesStore, evt, tick); + }, initialDiscontinuitiesStore)); + /** + * On some devices (right now only seen on Tizen), seeking through the + * `currentTime` property can lead to the browser re-seeking once the + * segments have been loaded to improve seeking performances (for + * example, by seeking right to an intra video frame). + * In that case, we risk being in a conflict with that behavior: if for + * example we encounter a small discontinuity at the position the browser + * seeks to, we will seek over it, the browser would seek back and so on. + * + * This variable allows to store the last known position we were seeking to + * so we can detect when the browser seeked back (to avoid performing another + * seek after that). When browsers seek back to a position behind a + * discontinuity, they are usually able to skip them without our help. + */ - if (typeof _language === "string") { - language = _language; - } else { - language = _language.language; + var lastSeekingPosition = null; + /** + * In some conditions (see `lastSeekingPosition`), we might want to not + * automatically seek over discontinuities because the browser might do it + * itself instead. + * In that case, we still want to perform the seek ourselves if the browser + * doesn't do it after sufficient time. + * This variable allows to store the timestamp at which a discontinuity began + * to be ignored. + */ - if (_language.closedCaption === true) { - closedCaption = true; + var ignoredStallTimeStamp = null; + return clock$.pipe(withLatestFrom(discontinuitiesStore$), (0,map/* map */.U)(function (_ref2) { + var tick = _ref2[0], + discontinuitiesStore = _ref2[1]; + var buffered = tick.buffered, + currentRange = tick.currentRange, + position = tick.position, + event = tick.event, + stalled = tick.stalled; + + if (stalled === null) { + return { + type: "unstalled", + value: null + }; + } + + if (tick.seeking) { + lastSeekingPosition = tick.position; + } else if (lastSeekingPosition !== null) { + var now = performance.now(); + + if (ignoredStallTimeStamp === null) { + ignoredStallTimeStamp = now; + } + + if (is_seeking_approximate && tick.position < lastSeekingPosition && now - ignoredStallTimeStamp < FORCE_DISCONTINUITY_SEEK_DELAY) { + return { + type: "stalled", + value: stalled + }; + } + + lastSeekingPosition = null; + } + + ignoredStallTimeStamp = null; + /** Position at which data is awaited. */ + + var stalledPosition = stalled.position; + + if (stalledPosition !== null) { + var skippableDiscontinuity = findSeekableDiscontinuity(discontinuitiesStore, manifest, stalledPosition); + + if (skippableDiscontinuity !== null) { + var realSeekTime = skippableDiscontinuity + 0.001; + + if (realSeekTime <= mediaElement.currentTime) { + log/* default.info */.Z.info("Init: position to seek already reached, no seeking", mediaElement.currentTime, realSeekTime); + } else { + log/* default.warn */.Z.warn("SA: skippable discontinuity found in the stream", position, realSeekTime); + setCurrentTime(realSeekTime); + return stream_events_generators.warning(generateDiscontinuityError(stalledPosition, realSeekTime)); + } + } + } // Is it a browser bug? -> force seek at the same current time + + + if (isPlaybackStuck(position, currentRange, event, stalled !== null)) { + log/* default.warn */.Z.warn("Init: After freeze seek", position, currentRange); + setCurrentTime(position); + return stream_events_generators.warning(generateDiscontinuityError(position, position)); + } + + var freezePosition = stalledPosition !== null && stalledPosition !== void 0 ? stalledPosition : position; // Is it a very short discontinuity in buffer ? -> Seek at the beginning of the + // next range + // + // Discontinuity check in case we are close a buffered range but still + // calculate a stalled state. This is useful for some + // implementation that might drop an injected segment, or in + // case of small discontinuity in the content. + + var nextBufferRangeGap = (0,ranges/* getNextRangeGap */.XS)(buffered, freezePosition); + + if (nextBufferRangeGap < BUFFER_DISCONTINUITY_THRESHOLD) { + var seekTo = freezePosition + nextBufferRangeGap + EPSILON; + + if (mediaElement.currentTime < seekTo) { + log/* default.warn */.Z.warn("Init: discontinuity encountered inferior to the threshold", freezePosition, seekTo, BUFFER_DISCONTINUITY_THRESHOLD); + setCurrentTime(seekTo); + return stream_events_generators.warning(generateDiscontinuityError(freezePosition, seekTo)); + } + } // Are we in a discontinuity between periods ? -> Seek at the beginning of the + // next period + + + for (var i = manifest.periods.length - 2; i >= 0; i--) { + var period = manifest.periods[i]; + + if (period.end !== undefined && period.end <= freezePosition) { + if (manifest.periods[i + 1].start > freezePosition && manifest.periods[i + 1].start > mediaElement.currentTime) { + var nextPeriod = manifest.periods[i + 1]; + setCurrentTime(nextPeriod.start); + return stream_events_generators.warning(generateDiscontinuityError(freezePosition, nextPeriod.start)); + } + + break; } } return { - language: language, - closedCaption: closedCaption, - normalized: normalizeLanguage(language) + type: "stalled", + value: stalled }; + })); +} +/** + * @param {Array.} discontinuitiesStore + * @param {Object} manifest + * @param {number} stalledPosition + * @returns {number|null} + */ + +function findSeekableDiscontinuity(discontinuitiesStore, manifest, stalledPosition) { + if (discontinuitiesStore.length === 0) { + return null; } - return _language; + var maxDiscontinuityEnd = null; + + for (var i = 0; i < discontinuitiesStore.length; i++) { + var period = discontinuitiesStore[i].period; + + if (period.start > stalledPosition) { + return maxDiscontinuityEnd; + } + + var discontinuityEnd = void 0; + + if (period.end === undefined || period.end > stalledPosition) { + var _discontinuitiesStore = discontinuitiesStore[i], + discontinuity = _discontinuitiesStore.discontinuity, + position = _discontinuitiesStore.position; + var start = discontinuity.start, + end = discontinuity.end; + var discontinuityLowerLimit = start !== null && start !== void 0 ? start : position; + + if (stalledPosition >= discontinuityLowerLimit - EPSILON) { + if (end === null) { + var nextPeriod = manifest.getPeriodAfter(period); + + if (nextPeriod !== null) { + discontinuityEnd = nextPeriod.start + EPSILON; + } else { + log/* default.warn */.Z.warn("Init: discontinuity at Period's end but no next Period"); + } + } else if (stalledPosition < end + EPSILON) { + discontinuityEnd = end + EPSILON; + } + } + + if (discontinuityEnd !== undefined) { + log/* default.info */.Z.info("Init: discontinuity found", stalledPosition, discontinuityEnd); + maxDiscontinuityEnd = maxDiscontinuityEnd !== null && maxDiscontinuityEnd > discontinuityEnd ? maxDiscontinuityEnd : discontinuityEnd; + } + } + } + + return maxDiscontinuityEnd; } /** - * Normalize audio track from a user given input into an object - * with the following properties: - * - language {string}: The language the user gave us - * - normalized {string}: An attempt to normalize the language into an - * ISO 639-3 code - * - audioDescription {Boolean}: Whether the track is a closed caption track - * - isDub {Boolean|undefined}: if true, this is a dub. - * @param {Object|string|null|undefined} _language - * @returns {Object|null|undefined} + * Return `true` if the given event indicates that a discontinuity is present. + * @param {Object} evt + * @returns {Array.} */ -function normalizeAudioTrack(_language) { - if ((0,is_null_or_undefined/* default */.Z)(_language)) { - return _language; +function eventContainsDiscontinuity(evt) { + return evt.discontinuity !== null; +} +/** + * Update the `discontinuitiesStore` Object with the given event information: + * + * - If that event indicates than no discontinuity is found for a Period + * and buffer type, remove a possible existing discontinuity for that + * combination. + * + * - If that event indicates that a discontinuity can be found for a Period + * and buffer type, replace previous occurences for that combination and + * store it in Period's chronological order in the Array. + * @param {Array.} discontinuitiesStore + * @param {Object} evt + * @param {Object} tick + * @returns {Array.} + */ + + +function updateDiscontinuitiesStore(discontinuitiesStore, evt, tick) { + // First, perform clean-up of old discontinuities + while (discontinuitiesStore.length > 0 && discontinuitiesStore[0].period.end !== undefined && discontinuitiesStore[0].period.end + 10 < tick.position) { + discontinuitiesStore.shift(); } - if (typeof _language === "string") { - return { - language: _language, - audioDescription: false, - normalized: normalizeLanguage(_language) - }; + var period = evt.period, + bufferType = evt.bufferType; + + if (bufferType !== "audio" && bufferType !== "video") { + return discontinuitiesStore; } - var normalized = { - language: _language.language, - audioDescription: _language.audioDescription === true, - normalized: normalizeLanguage(normalizeLanguage(_language.language)) - }; + for (var i = 0; i < discontinuitiesStore.length; i++) { + if (discontinuitiesStore[i].period.id === period.id) { + if (discontinuitiesStore[i].bufferType === bufferType) { + if (!eventContainsDiscontinuity(evt)) { + discontinuitiesStore.splice(i, 1); + } else { + discontinuitiesStore[i] = evt; + } - if (_language.isDub === true) { - normalized.isDub = true; + return discontinuitiesStore; + } + } else if (discontinuitiesStore[i].period.start > period.start) { + if (eventContainsDiscontinuity(evt)) { + discontinuitiesStore.splice(i, 0, evt); + } + + return discontinuitiesStore; + } } - return normalized; + if (eventContainsDiscontinuity(evt)) { + discontinuitiesStore.push(evt); + } + + return discontinuitiesStore; } +/** + * Generate error emitted when a discontinuity has been encountered. + * @param {number} stalledPosition + * @param {number} seekTo + * @returns {Error} + */ -/* harmony default export */ const normalize = (normalizeLanguage); +function generateDiscontinuityError(stalledPosition, seekTo) { + return new media_error/* default */.Z("DISCONTINUITY_ENCOUNTERED", "A discontinuity has been encountered at position " + String(stalledPosition) + ", seeked at position " + String(seekTo)); +} +;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/pairwise.js +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -/***/ }), -/***/ 8894: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +function pairwise() { + return function (source) { return source.lift(new PairwiseOperator()); }; +} +var PairwiseOperator = /*@__PURE__*/ (function () { + function PairwiseOperator() { + } + PairwiseOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new PairwiseSubscriber(subscriber)); + }; + return PairwiseOperator; +}()); +var PairwiseSubscriber = /*@__PURE__*/ (function (_super) { + tslib_es6/* __extends */.ZT(PairwiseSubscriber, _super); + function PairwiseSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.hasPrev = false; + return _this; + } + PairwiseSubscriber.prototype._next = function (value) { + var pair; + if (this.hasPrev) { + pair = [this.prev, value]; + } + else { + this.hasPrev = true; + } + this.prev = value; + if (pair) { + this.destination.next(pair); + } + }; + return PairwiseSubscriber; +}(Subscriber/* Subscriber */.L)); +//# sourceMappingURL=pairwise.js.map -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* export default binding */ __WEBPACK_DEFAULT_EXPORT__ -/* harmony export */ }); +;// CONCATENATED MODULE: ./src/core/init/stream_events_emitter/are_same_stream_events.ts /** * Copyright 2015 CANAL+ Group * @@ -50861,26 +53523,25 @@ function normalizeAudioTrack(_language) { */ /** - * Do nothing (but do it well). - * - * Having this definition here allow to use the same reference each time a noop - * is needed. - * Also, it allows to avoid telling eslint to ignore empty blocks everywhere. + * Compare 2 events. + * As the payload of two events may be the same, but the JS objects may not + * have the same references, it may be difficult to compare them. + * If two events start and end at the same moment, and possess the same id, + * we consider the two to be the same. + * /!\ However, the DASH-if spec does not say that the event payload + * may be the same if these conditions are met. Thus, there are high chances + * that it may be the case. + * TODO See if we can compare payloads + * @param {Object} evt1 + * @param {Object} evt2 + * @returns {Boolean} */ +function areSameStreamEvents(evt1, evt2) { + return evt1.id === evt2.id && evt1.start === evt2.start && evt1.end === evt2.end; +} -/* eslint-disable no-empty,@typescript-eslint/no-empty-function */ -/* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__() {} -/* eslint-enable no-empty, @typescript-eslint/no-empty-function */ - -/***/ }), - -/***/ 8026: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ -/* harmony export */ }); +/* harmony default export */ const are_same_stream_events = (areSameStreamEvents); +;// CONCATENATED MODULE: ./src/core/init/stream_events_emitter/refresh_scheduled_events_list.ts /** * Copyright 2015 CANAL+ Group * @@ -50896,45 +53557,73 @@ function normalizeAudioTrack(_language) { * See the License for the specific language governing permissions and * limitations under the License. */ -function objectAssign(target) { - if (target === null || target === undefined) { - throw new TypeError("Cannot convert undefined or null to object"); - } // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment +/** + * Refresh local scheduled events list + * @param {Array.} oldScheduledEvents + * @param {Object} manifest + * @returns {Array.} + */ - var to = Object(target); - - for (var i = 0; i < (arguments.length <= 1 ? 0 : arguments.length - 1); i++) { - var source = i + 1 < 1 || arguments.length <= i + 1 ? undefined : arguments[i + 1]; - - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ - // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion - to[key] = source[key]; - /* eslint-enable @typescript-eslint/no-unsafe-member-access */ - } - } - } +function refreshScheduledEventsList(oldScheduledEvents, manifest) { + var scheduledEvents = []; + var periods = manifest.periods; - return to; -} // eslint-disable-next-line @typescript-eslint/unbound-method, no-restricted-properties + for (var i = 0; i < periods.length; i++) { + var period = periods[i]; + var streamEvents = period.streamEvents; + streamEvents.forEach(function (_ref) { + var start = _ref.start, + end = _ref.end, + id = _ref.id, + data = _ref.data; + for (var j = 0; j < oldScheduledEvents.length; j++) { + var currentScheduledEvent = oldScheduledEvents[j]; -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (typeof Object.assign === "function" ? // eslint-disable-next-line no-restricted-properties -Object.assign : // eslint-disable-next-line @typescript-eslint/unbound-method -objectAssign); + if (are_same_stream_events(currentScheduledEvent, { + id: id, + start: start, + end: end + })) { + scheduledEvents.push(currentScheduledEvent); + return; + } + } -/***/ }), + if (end === undefined) { + var newScheduledEvent = { + start: start, + id: id, + data: data, + publicEvent: { + start: start, + data: data + } + }; + scheduledEvents.push(newScheduledEvent); + } else { + var _newScheduledEvent = { + start: start, + end: end, + id: id, + data: data, + publicEvent: { + start: start, + end: end, + data: data + } + }; + scheduledEvents.push(_newScheduledEvent); + } + }); + } -/***/ 1679: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + return scheduledEvents; +} -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ -/* harmony export */ }); -/* unused harmony export objectValues */ +/* harmony default export */ const refresh_scheduled_events_list = (refreshScheduledEventsList); +;// CONCATENATED MODULE: ./src/core/init/stream_events_emitter/stream_events_emitter.ts /** * Copyright 2015 CANAL+ Group * @@ -50951,31 +53640,128 @@ objectAssign); * limitations under the License. */ + + + + +var STREAM_EVENT_EMITTER_POLL_INTERVAL = config/* default.STREAM_EVENT_EMITTER_POLL_INTERVAL */.Z.STREAM_EVENT_EMITTER_POLL_INTERVAL; /** - * @param {Object|Array} o - * @returns {Array.<*>} + * Tells if a stream event has a duration + * @param {Object} evt + * @returns {Boolean} */ -function objectValues(o) { - return Object.keys(o).map(function (k) { - return o[k]; - }); -} // eslint-disable-next-line @typescript-eslint/unbound-method, no-restricted-properties +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} + */ -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (typeof Object.values === "function" ? Object.values : objectValues); +function streamEventsEmitter(manifest, mediaElement, clock$) { + 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); + }, [])); + /** + * Examine playback situation from clock ticks to emit stream events and + * prepare set onExit callbacks if needed. + * @param {Array.} scheduledEvents + * @param {Object} oldTick + * @param {Object} newTick + * @returns {Observable} + */ -/***/ }), + function emitStreamEvents$(scheduledEvents, oldClockTick, newClockTick) { + var previousTime = oldClockTick.currentTime; + var isSeeking = newClockTick.isSeeking, + currentTime = newClockTick.currentTime; + var eventsToSend = []; + var eventsToExit = []; -/***/ 9589: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + for (var i = 0; i < scheduledEvents.length; i++) { + var event = scheduledEvents[i]; + var start = event.start; + var end = isFiniteStreamEvent(event) ? event.end : undefined; + var isBeingPlayed = eventsBeingPlayed.has(event); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => __WEBPACK_DEFAULT_EXPORT__ -/* harmony export */ }); -/* harmony import */ var pinkie__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8555); -/* harmony import */ var pinkie__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(pinkie__WEBPACK_IMPORTED_MODULE_0__); + if (isBeingPlayed) { + if (start > currentTime || end !== undefined && currentTime >= end) { + if (isFiniteStreamEvent(event)) { + eventsToExit.push(event.publicEvent); + } + + eventsBeingPlayed["delete"](event); + } + } else if (start <= currentTime && end !== undefined && currentTime < end) { + eventsToSend.push({ + type: "stream-event", + value: event.publicEvent + }); + eventsBeingPlayed.set(event, true); + } else if (previousTime < start && currentTime >= (end !== null && end !== void 0 ? end : start)) { + if (isSeeking) { + eventsToSend.push({ + type: "stream-event-skip", + 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(); + } + }), (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; + }), (0,distinctUntilChanged/* distinctUntilChanged */.x)(), (0,switchMap/* switchMap */.w)(function (hasEvents) { + if (!hasEvents) { + return empty/* EMPTY */.E; + } + + return (0,combineLatest/* combineLatest */.aj)([(0,observable_interval/* interval */.F)(STREAM_EVENT_EMITTER_POLL_INTERVAL).pipe((0,startWith/* startWith */.O)(null)), clock$]).pipe((0,map/* map */.U)(function (_ref) { + var _ = _ref[0], + clockTick = _ref[1]; + var seeking = clockTick.seeking; + return { + isSeeking: seeking, + currentTime: mediaElement.currentTime + }; + }), pairwise(), (0,mergeMap/* mergeMap */.zg)(function (_ref2) { + var oldTick = _ref2[0], + newTick = _ref2[1]; + return emitStreamEvents$(lastScheduledEvents, oldTick, newTick); + })); + })); +} + +/* harmony default export */ const stream_events_emitter = (streamEventsEmitter); +;// CONCATENATED MODULE: ./src/core/init/stream_events_emitter/index.ts /** * Copyright 2015 CANAL+ Group * @@ -50992,29 +53778,10 @@ function objectValues(o) { * limitations under the License. */ -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (typeof Promise === "function" ? Promise : (pinkie__WEBPACK_IMPORTED_MODULE_0___default())); - -/***/ }), - -/***/ 2829: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "JN": () => /* binding */ convertToRanges, -/* harmony export */ "uH": () => /* binding */ excludeFromRanges, -/* harmony export */ "F_": () => /* binding */ getInnerAndOuterTimeRanges, -/* harmony export */ "L7": () => /* binding */ getLeftSizeOfRange, -/* harmony export */ "XS": () => /* binding */ getNextRangeGap, -/* harmony export */ "DD": () => /* binding */ getPlayedSizeOfRange, -/* harmony export */ "rx": () => /* binding */ getRange, -/* harmony export */ "at": () => /* binding */ getSizeOfRange, -/* harmony export */ "kR": () => /* binding */ insertInto, -/* harmony export */ "Ti": () => /* binding */ isTimeInRange, -/* harmony export */ "A1": () => /* binding */ isTimeInRanges, -/* harmony export */ "tn": () => /* binding */ keepRangeIntersection -/* harmony export */ }); -/* unused harmony exports isAfter, isBefore, isTimeInTimeRanges, mergeContiguousRanges, removeEmptyRanges */ +/* harmony default export */ const init_stream_events_emitter = (stream_events_emitter); +// EXTERNAL MODULE: ./src/core/init/update_playback_rate.ts +var update_playback_rate = __webpack_require__(2983); +;// CONCATENATED MODULE: ./src/core/init/load_on_media_source.ts /** * Copyright 2015 CANAL+ Group * @@ -51031,534 +53798,421 @@ function objectValues(o) { * limitations under the License. */ -/** - * This file contains functions helping with TimeRanges management. - * - * For simplicity/performance reasons, many of those work with a simplified - * "Range" object, which is an object with two keys: - * - start {Number} - * - end {Number} - * - * Those two corresponds to what is returned by the start and end methods of a - * TimeRanges Object. - * - * You can convert from TimeRanges to Range object(s) with the getRange/ - * convertToRanges methods. - */ -// Factor for rounding errors -var EPSILON = 1 / 60; -/** - * Check equality with a tolerance of EPSILON. - * Used for various functions with this sort of tolerance regarding the - * start/end of contiguous ranges. - * @param {Number} a - * @param {Number} b - * @returns {Boolean} - */ - -function nearlyEqual(a, b) { - return Math.abs(a - b) < EPSILON; -} -/** - * Construct a new range which will have, as start/end, the min/max - * of both the range given, and the given bitrate. - * @param {Object} range1 - * @param {Object} range2 - * @returns {Object} - */ - - -function createRangeUnion(range1, range2) { - var start = Math.min(range1.start, range2.start); - var end = Math.max(range1.end, range2.end); - return { - start: start, - end: end - }; -} -/** - * Clean array ranges from "empty" ranges. - * That is, range objects which have their start equal to their end. - * /!\ Mutate the array of ranges. - * @param {Array} ranges - * @returns {Array} - */ -function removeEmptyRanges(ranges) { - for (var index = 0; index < ranges.length; index++) { - var range = ranges[index]; - if (range.start === range.end) { - ranges.splice(index--, 1); - } - } - return ranges; -} -/** - * /!\ Mutate the array of ranges. - * @param {Array} ranges - * @returns {Array} - */ -function mergeContiguousRanges(ranges) { - for (var index = 1; index < ranges.length; index++) { - var prevRange = ranges[index - 1]; - var currRange = ranges[index]; - if (areRangesNearlyContiguous(prevRange, currRange)) { - var unionRange = createRangeUnion(prevRange, currRange); - ranges.splice(--index, 2, unionRange); - } - } - return ranges; -} -/** - * True if range1 is considered _after_ range2. - * @param {Object} range1 - * @param {Object} range2 - * @returns {Boolean} - */ -function isAfter(range1, range2) { - return range1.start >= range2.end; -} -/** - * True if range1 is considered _before_ range2. - * @param {Object} range1 - * @param {Object} range2 - * @returns {Boolean} - */ -function isBefore(range1, range2) { - return range1.end <= range2.start; -} /** - * Returns true if the time given can be considered as part of any of the given - * ranges. - * @param {Array.} ranges - * @param {number} time - * @returns {boolean} + * 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, + clock$ = _ref.clock$, + speed$ = _ref.speed$, + bufferOptions = _ref.bufferOptions, + abrManager = _ref.abrManager, + segmentFetcherCreator = _ref.segmentFetcherCreator, + setCurrentTime = _ref.setCurrentTime; -function isTimeInRanges(ranges, time) { - for (var i = 0; i < ranges.length; i++) { - if (isTimeInRange(ranges[i], time)) { - return true; - } - } - - return false; -} -/** - * Returns true if the time given can be considered as part of the given range. - * @param {Object} range1 - * @param {Number} Time - * @returns {Boolean} - */ - + /** + * 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 */ -function isTimeInRange(_ref, time) { - var start = _ref.start, - end = _ref.end; - return start <= time && time < end; -} -/** - * Returns true if the two ranges given are overlapping. - * @param {Object} range1 - * @param {Object} range2 - * @returns {Boolean} - */ + var durationUpdater$ = DurationUpdater(manifest, mediaSource); + var initialPeriod = (_a = manifest.getPeriodForTime(initialTime)) !== null && _a !== void 0 ? _a : manifest.getNextPeriod(initialTime); -function areRangesOverlapping(range1, range2) { - return isTimeInRange(range1, range2.start) || range1.start < range2.end && range2.end < range1.end || isTimeInRange(range2, range1.start); -} -/** - * Returns true if the two ranges given can be considered contiguous. - * @param {Object} range1 - * @param {Object} range2 - * @returns {Boolean} - */ + 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 */._)(error); + } + /** Interface to create media buffers for loaded segments. */ -function areRangesNearlyContiguous(range1, range2) { - return nearlyEqual(range2.start, range1.end) || nearlyEqual(range2.end, range1.start); -} -/** - * Convert from a TimeRanges object to an array of Ranges. - * @param {TimeRanges} timeRanges - * @returns {Array.} - */ + var segmentBuffersStore = new segment_buffers(mediaElement, mediaSource); + var _initialSeekAndPlay = initialSeekAndPlay(mediaElement, clock$, { + autoPlay: autoPlay, + manifest: manifest, + setCurrentTime: setCurrentTime, + speed$: speed$, + startTime: initialTime + }), + loaded$ = _initialSeekAndPlay.loaded$, + updatedClock$ = _initialSeekAndPlay.clock$; -function convertToRanges(timeRanges) { - var ranges = []; + var isLoaded$ = loaded$.pipe((0,filter/* filter */.h)(function (evt) { + return evt !== "not-loaded-metadata"; + })); + var streamEvents$ = isLoaded$.pipe((0,mergeMap/* mergeMap */.zg)(function () { + return init_stream_events_emitter(manifest, mediaElement, clock$); + })); + /** Cancel endOfStream calls when streams become active again. */ - for (var i = 0; i < timeRanges.length; i++) { - ranges.push({ - start: timeRanges.start(i), - end: timeRanges.end(i) - }); - } + var cancelEndOfStream$ = new Subject/* Subject */.xQ(); + /** Emits discontinuities detected by the StreamOrchestrator. */ - return ranges; -} -/** - * Get range object of a specific time in a TimeRanges object. - * @param {TimeRanges} timeRanges - * @returns {Object} - */ + var discontinuityUpdate$ = new Subject/* Subject */.xQ(); // Creates Observable which will manage every Stream for the given Content. + var streams$ = stream({ + manifest: manifest, + initialPeriod: initialPeriod + }, updatedClock$, abrManager, segmentBuffersStore, segmentFetcherCreator, bufferOptions).pipe((0,mergeMap/* mergeMap */.zg)(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$)); -function getRange(timeRanges, time) { - for (var i = timeRanges.length - 1; i >= 0; i--) { - var start = timeRanges.start(i); + case "resume-stream": + log/* default.debug */.Z.debug("Init: resume-stream order received."); + cancelEndOfStream$.next(null); + return empty/* EMPTY */.E; - if (time >= start) { - var end = timeRanges.end(i); + 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 + }); + return empty/* EMPTY */.E; - if (time < end) { - return { - start: start, - end: end - }; + default: + return (0,of.of)(evt); } - } - } - - return null; -} -/** - * Get gap from a specific time until the start of the next Range. - * @param {TimeRanges} timeRanges - * @param {Number} time - * @returns {Number} - */ + })); + /** + * On subscription, keep the playback speed synchronized to the speed set by + * the user on the media element and force a speed of `0` when the buffer is + * empty, so it can build back buffer. + */ + var playbackRate$ = (0,update_playback_rate/* default */.Z)(mediaElement, speed$, clock$, { + pauseWhenStalled: true + }).pipe((0,ignoreElements/* ignoreElements */.l)()); + /** + * Observable trying to avoid various stalling situations, emitting "stalled" + * events when it cannot, as well as "unstalled" events when it get out of one. + */ -function getNextRangeGap(timeRanges, time) { - var len = timeRanges.length; + var stallAvoider$ = StallAvoider(clock$, mediaElement, manifest, discontinuityUpdate$, setCurrentTime); + var loadedEvent$ = loaded$.pipe((0,mergeMap/* mergeMap */.zg)(function (evt) { + if (evt === "autoplay-blocked") { + var _error = new media_error/* default */.Z("MEDIA_ERR_BLOCKED_AUTOPLAY", "Cannot trigger auto-play automatically: " + "your browser does not allow it."); - for (var i = 0; i < len; i++) { - var start = timeRanges.start(i); + return (0,of.of)(events_generators/* default.warning */.Z.warning(_error), events_generators/* default.loaded */.Z.loaded(segmentBuffersStore)); + } else if (evt === "not-loaded-metadata") { + var _error2 = new media_error/* default */.Z("MEDIA_ERR_NOT_LOADED_METADATA", "Cannot load automatically: your browser " + "falsely announced having loaded the content."); - if (time < start) { - return start - time; - } - } + return (0,of.of)(events_generators/* default.warning */.Z.warning(_error2)); + } - return Infinity; + log/* default.debug */.Z.debug("Init: The current content is loaded."); + return (0,of.of)(events_generators/* default.loaded */.Z.loaded(segmentBuffersStore)); + })); + return (0,merge/* merge */.T)(durationUpdater$, loadedEvent$, playbackRate$, stallAvoider$, streams$, streamEvents$).pipe(finalize(function () { + // clean-up every created SegmentBuffers + segmentBuffersStore.disposeAll(); + })); + }; } +;// CONCATENATED MODULE: ./src/utils/rx-throttle.ts /** - * @param {TimeRanges} timeRanges - * @param {Number} time - * @returns {Object} - Object with two properties: - * - outerRanges {Array.}: every ranges which does not contain the - * given time. - * - innerRange {Object|null}: the range which contain the given time. + * 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 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]; + } -function getInnerAndOuterTimeRanges(timeRanges, time) { - var innerRange = null; - var outerRanges = []; - - for (var i = 0; i < timeRanges.length; i++) { - var start = timeRanges.start(i); - var end = timeRanges.end(i); + return new Observable/* Observable */.y(function (obs) { + if (isPending) { + obs.complete(); + return undefined; + } - if (time < start || time >= end) { - outerRanges.push({ - start: start, - end: end + isPending = true; + var funcSubscription = func.apply(void 0, args).subscribe(function (i) { + obs.next(i); + }, function (e) { + isPending = false; + obs.error(e); + }, function () { + isPending = false; + obs.complete(); }); - } else { - innerRange = { - start: start, - end: end + return function () { + funcSubscription.unsubscribe(); + isPending = false; }; - } - } - - return { - outerRanges: outerRanges, - innerRange: innerRange + }); }; } +;// CONCATENATED MODULE: ./src/core/init/manifest_update_scheduler.ts /** - * Get "size" (difference between end and start) of the range containing the - * given time. 0 if the range is not found. - * @param {TimeRanges} timeRanges - * @param {Number} currentTime - * @returns {Number} + * 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 getSizeOfRange(timeRanges, currentTime) { - var range = getRange(timeRanges, currentTime); - return range !== null ? range.end - range.start : 0; -} -/** - * Get "currently played" (difference between time given and start) of the - * range containing the given time. 0 if the range is not found. - * @param {TimeRanges} timeRanges - * @param {Number} currentTime - * @returns {Number} - */ - -function getPlayedSizeOfRange(timeRanges, currentTime) { - var range = getRange(timeRanges, currentTime); - return range !== null ? currentTime - range.start : 0; -} -/** - * Get "left to play" (difference between end and time given) of the range - * containing the given time. Infinity if the range is not found. - * @param {TimeRanges} timeRanges - * @param {Number} currentTime - * @returns {Number} - */ -function getLeftSizeOfRange(timeRanges, currentTime) { - var range = getRange(timeRanges, currentTime); - return range !== null ? range.end - currentTime : Infinity; -} +var FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY = config/* default.FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY */.Z.FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY, + MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE = config/* default.MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE */.Z.MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE, + MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE = config/* default.MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE */.Z.MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE; /** - * Insert a range object into an array of ranges objects, at the right place. - * /!\ Mutate the array of ranges. - * @param {Array.} ranges - * @param {Object} rangeToAddArg - * @returns {Array.} + * 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$; -function insertInto(ranges, rangeToAddArg) { - if (rangeToAddArg.start === rangeToAddArg.end) { - return ranges; - } + /** + * 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 */.zg)(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 Manifest - var rangeToAdd = rangeToAddArg; // For each present range check if we need to: - // - In case we are overlapping or contiguous: - // - if added range has the same bitrate as the overlapped or - // contiguous one, we can merge themcurrentRange - // - if added range has a different bitrate we need to insert it - // in place - // - Need to insert in place, we we are completely, not overlapping - // and not contiguous in between two ranges. + var manifest = initialManifest.manifest; + /** Number of consecutive times the parsing has been done in `unsafeMode`. */ - var index = 0; + var consecutiveUnsafeMode = 0; - for (; index < ranges.length; index++) { - var range = ranges[index]; - var overlapping = areRangesOverlapping(rangeToAdd, range); - var contiguous = areRangesNearlyContiguous(rangeToAdd, range); // We assume ranges are ordered and two ranges can not be - // completely overlapping. + function handleManifestRefresh$(manifestInfos) { + var sendingTime = manifestInfos.sendingTime, + parsingTime = manifestInfos.parsingTime, + updatingTime = manifestInfos.updatingTime; + /** + * Total time taken to fully update the last Manifest. + * Note: this time also includes possible requests done by the parsers. + */ - if (overlapping || contiguous) { - rangeToAdd = createRangeUnion(rangeToAdd, range); - ranges.splice(index--, 1); - } else { - // Check the case for which there is no more to do - if (index === 0) { - if (isBefore(rangeToAdd, ranges[0])) { - // First index, and we are completely before that range (and - // not contiguous, nor overlapping). We just need to be - // inserted here. - break; - } - } else { - if (isBefore(ranges[index - 1], rangeToAdd) && isBefore(rangeToAdd, range)) { - // We are exactly after the current previous range, and - // before the current range, while not overlapping with none - // of them. Insert here. - break; - } - } - } - } // Now that we are sure we don't overlap with any range, just add it. + var totalUpdateTime = parsingTime !== undefined ? parsingTime + (updatingTime !== null && updatingTime !== void 0 ? updatingTime : 0) : undefined; // 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; + var internalRefresh$ = scheduleRefresh$.pipe((0,mergeMap/* mergeMap */.zg)(function (_ref2) { + var completeRefresh = _ref2.completeRefresh, + delay = _ref2.delay, + canUseUnsafeMode = _ref2.canUseUnsafeMode; + var unsafeMode = canUseUnsafeMode && unsafeModeEnabled; + return startManualRefreshTimer(delay !== null && delay !== void 0 ? delay : 0, minimumManifestUpdateInterval, sendingTime).pipe((0,mapTo/* mapTo */.h)({ + completeRefresh: completeRefresh, + unsafeMode: unsafeMode + })); + })); + var timeSinceRequest = sendingTime === undefined ? 0 : performance.now() - sendingTime; + var minInterval = Math.max(minimumManifestUpdateInterval - timeSinceRequest, 0); + var autoRefresh$; - ranges.splice(index, 0, rangeToAdd); - return mergeContiguousRanges(removeEmptyRanges(ranges)); -} -/** - * Returns range, from a range objects array overlapping with a range given - * in argument. null if none is found. - * @param {Object} range - * @param {Array.} ranges - * @returns {Array.} - */ + if (manifest.lifetime === undefined || manifest.lifetime < 0) { + autoRefresh$ = empty/* EMPTY */.E; + } else { + var autoRefreshInterval = manifest.lifetime * 1000 - timeSinceRequest; + if (totalUpdateTime !== undefined) { + if (manifest.lifetime < 3 && totalUpdateTime >= 100) { + var defaultDelay = (3 - manifest.lifetime) * 1000 + autoRefreshInterval; + var newInterval = Math.max(defaultDelay, Math.max(autoRefreshInterval, 0) + totalUpdateTime); + log/* default.info */.Z.info("MUS: Manifest update rythm is too frequent. Postponing next request.", autoRefreshInterval, newInterval); + autoRefreshInterval = newInterval; + } else if (totalUpdateTime >= manifest.lifetime * 1000 / 10) { + var _newInterval = Math.max(autoRefreshInterval, 0) + totalUpdateTime; -function findOverlappingRanges(range, ranges) { - var resultingRanges = []; + log/* default.info */.Z.info("MUS: Manifest took too long to parse. Postponing next request", autoRefreshInterval, _newInterval); + autoRefreshInterval = _newInterval; + } + } - for (var i = 0; i < ranges.length; i++) { - if (areRangesOverlapping(range, ranges[i])) { - resultingRanges.push(ranges[i]); + autoRefresh$ = (0,timer/* timer */.H)(Math.max(autoRefreshInterval, minInterval)).pipe((0,mapTo/* mapTo */.h)({ + completeRefresh: false, + unsafeMode: unsafeModeEnabled + })); } - } - - return resultingRanges; -} -/** - * Returns only the intersection between the two ranges, from the first - * ranges argument given. - * @param {Array.} ranges1 - * @param {Array.} ranges2 - * @returns {Array.} - */ - -function keepRangeIntersection(ranges1, ranges2) { - var result = []; - - for (var i = 0; i < ranges1.length; i++) { - var range = ranges1[i]; - var overlappingRanges = findOverlappingRanges(range, ranges2); + var expired$ = manifest.expired === null ? empty/* EMPTY */.E : (0,timer/* timer */.H)(minInterval).pipe((0,mergeMapTo/* mergeMapTo */.j)((0,from/* from */.D)(manifest.expired)), (0,mapTo/* mapTo */.h)({ + completeRefresh: true, + unsafeMode: unsafeModeEnabled + })); // Emit when the manifest should be refreshed. Either when: + // - A Stream asks for it to be refreshed + // - its lifetime expired. - if (overlappingRanges.length > 0) { - for (var j = 0; j < overlappingRanges.length; j++) { - var overlappingRange = overlappingRanges[j]; - result.push({ - start: Math.max(range.start, overlappingRange.start), - end: Math.min(range.end, overlappingRange.end) - }); + return (0,merge/* merge */.T)(autoRefresh$, internalRefresh$, expired$).pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.zg)(function (_ref3) { + var completeRefresh = _ref3.completeRefresh, + unsafeMode = _ref3.unsafeMode; + return refreshManifest({ + completeRefresh: completeRefresh, + unsafeMode: unsafeMode + }); + }), (0,mergeMap/* mergeMap */.zg)(function (evt) { + if (evt.type === "warning") { + return (0,of.of)(evt); } - } - } - return result; -} -/** - * Exclude from the `baseRanges` everything that is in `rangesToExclude`. - * Example: - * - * Let's say we have the following base ranges: - * |==========| |===============| |======| |==========| - * - * From which we want to "exclude" the following ranges: - * |=========| |==| |===| |=====| - * - * We will obtain the first ranges from which we remove the second ranges: - * ----------------------------------------------------------------------- - * |==========| |===============| |======| |==========| - * |=========| |==| |===| |=====| - * _______________________________________________________________________ - * | - * | - * V - * ----------------------------------------------------------------------- - * |==| |======| |==| |====| |==========| - * ----------------------------------------------------------------------- - * - * @param {Array.} - */ + return handleManifestRefresh$(evt); + })); + } + return (0,defer/* defer */.P)(function () { + return handleManifestRefresh$(initialManifest); + }); + /** + * Refresh the Manifest. + * Perform a full update if a partial update failed. + * @param {boolean} completeRefresh + * @returns {Observable} + */ -function excludeFromRanges(baseRanges, rangesToExclude) { - var result = []; // For every range in `baseRanges`, find overlapping ranges with - // `rangesToExclude` and remove them. + function refreshManifest(_ref4) { + var completeRefresh = _ref4.completeRefresh, + unsafeMode = _ref4.unsafeMode; + var manifestUpdateUrl = manifest.updateUrl; + var fullRefresh = completeRefresh || manifestUpdateUrl === undefined; + var refreshURL = fullRefresh ? manifest.getUrl() : manifestUpdateUrl; + var externalClockOffset = manifest.clockOffset; - for (var i = 0; i < baseRanges.length; i++) { - var range = baseRanges[i]; - var intersections = []; - var overlappingRanges = findOverlappingRanges(range, rangesToExclude); + 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; + } - if (overlappingRanges.length > 0) { - for (var j = 0; j < overlappingRanges.length; j++) { - var overlappingRange = overlappingRanges[j]; - intersections.push({ - start: Math.max(range.start, overlappingRange.start), - end: Math.min(range.end, overlappingRange.end) - }); + return fetchManifest(refreshURL, { + externalClockOffset: externalClockOffset, + previousManifest: manifest, + unsafeMode: unsafeMode + }).pipe((0,mergeMap/* mergeMap */.zg)(function (value) { + if (value.type === "warning") { + return (0,of.of)(value); } - } - if (intersections.length === 0) { - result.push(range); - } else { - var lastStart = range.start; + var newManifest = value.manifest, + newSendingTime = value.sendingTime, + receivedTime = value.receivedTime, + parsingTime = value.parsingTime; + var updateTimeStart = performance.now(); - for (var _j = 0; _j < intersections.length; _j++) { - if (intersections[_j].start > lastStart) { - result.push({ - start: lastStart, - end: intersections[_j].start - }); + 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"); + return startManualRefreshTimer(FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY, minimumManifestUpdateInterval, newSendingTime).pipe((0,mergeMap/* mergeMap */.zg)(function () { + return refreshManifest({ + completeRefresh: true, + unsafeMode: false + }); + })); } - - lastStart = intersections[_j].end; } - if (lastStart < range.end) { - result.push({ - start: lastStart, - end: range.end - }); - } - } + return (0,of.of)({ + type: "parsed", + manifest: manifest, + sendingTime: newSendingTime, + receivedTime: receivedTime, + parsingTime: parsingTime, + updatingTime: performance.now() - updateTimeStart + }); + })); } - - return result; } /** - * Returns `true` if the given `time` is available in the TimeRanges object - * given. - * Returns `false` otherwise. - * @param {TimeRanges} ranges - * @param {Number} time - * @returns {boolean} + * 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; -function isTimeInTimeRanges(ranges, time) { - for (var i = 0; i < ranges.length; i++) { - if (ranges.start(i) <= time && time < ranges.end(i)) { - return true; - } - } + var _minInterval = Math.max(minimumManifestUpdateInterval - timeSinceLastRefresh, 0); - return false; + return (0,timer/* timer */.H)(Math.max(wantedDelay - timeSinceLastRefresh, _minInterval)); + }); } - - - -/***/ }), - -/***/ 4597: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "ZP": () => /* binding */ utils_request -}); - -// UNUSED EXPORTS: fetchIsSupported, fetchRequest, xhr - -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules -var Observable = __webpack_require__(4379); -// EXTERNAL MODULE: ./src/config.ts -var config = __webpack_require__(944); -// EXTERNAL MODULE: ./src/errors/request_error.ts -var request_error = __webpack_require__(9105); -// EXTERNAL MODULE: ./src/utils/is_non_empty_string.ts -var is_non_empty_string = __webpack_require__(6923); -// EXTERNAL MODULE: ./src/utils/is_null_or_undefined.ts -var is_null_or_undefined = __webpack_require__(1946); -;// CONCATENATED MODULE: ./src/utils/request/xhr.ts +// 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 * @@ -51579,350 +54233,283 @@ var is_null_or_undefined = __webpack_require__(1946); -var DEFAULT_REQUEST_TIMEOUT = config/* default.DEFAULT_REQUEST_TIMEOUT */.Z.DEFAULT_REQUEST_TIMEOUT; -var DEFAULT_RESPONSE_TYPE = "json"; -/** - * @param {string} data - * @returns {Object|null} - */ - -function toJSONForIE(data) { - try { - return JSON.parse(data); - } catch (e) { - return null; - } -} - -function request(options) { - var requestOptions = { - url: options.url, - headers: options.headers, - responseType: (0,is_null_or_undefined/* default */.Z)(options.responseType) ? DEFAULT_RESPONSE_TYPE : options.responseType, - timeout: (0,is_null_or_undefined/* default */.Z)(options.timeout) ? DEFAULT_REQUEST_TIMEOUT : options.timeout - }; - return new Observable/* Observable */.y(function (obs) { - var url = requestOptions.url, - headers = requestOptions.headers, - responseType = requestOptions.responseType, - timeout = requestOptions.timeout; - var xhr = new XMLHttpRequest(); - xhr.open("GET", url, true); - - if (timeout >= 0) { - xhr.timeout = timeout; - } - - xhr.responseType = responseType; - - if (xhr.responseType === "document") { - xhr.overrideMimeType("text/xml"); - } - - if (!(0,is_null_or_undefined/* default */.Z)(headers)) { - var _headers = headers; - for (var key in _headers) { - if (_headers.hasOwnProperty(key)) { - xhr.setRequestHeader(key, _headers[key]); - } - } - } - var sendingTime = performance.now(); - xhr.onerror = function onXHRError() { - obs.error(new request_error/* default */.Z(url, xhr.status, "ERROR_EVENT", xhr)); - }; - xhr.ontimeout = function onXHRTimeout() { - obs.error(new request_error/* default */.Z(url, xhr.status, "TIMEOUT", xhr)); - }; - if (options.sendProgressEvents === true) { - xhr.onprogress = function onXHRProgress(event) { - var currentTime = performance.now(); - obs.next({ - type: "progress", - value: { - url: url, - duration: currentTime - sendingTime, - sendingTime: sendingTime, - currentTime: currentTime, - size: event.loaded, - totalSize: event.total - } - }); - }; - } - xhr.onload = function onXHRLoad(event) { - if (xhr.readyState === 4) { - if (xhr.status >= 200 && xhr.status < 300) { - var receivedTime = performance.now(); - var totalSize = xhr.response instanceof ArrayBuffer ? xhr.response.byteLength : event.total; - var status = xhr.status; - var loadedResponseType = xhr.responseType; - var _url = (0,is_non_empty_string/* default */.Z)(xhr.responseURL) ? xhr.responseURL : url; - var responseData; - if (loadedResponseType === "json") { - // IE bug where response is string with responseType json - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - responseData = typeof xhr.response === "object" ? xhr.response : toJSONForIE(xhr.responseText); - } else { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - responseData = xhr.response; - } - if ((0,is_null_or_undefined/* default */.Z)(responseData)) { - obs.error(new request_error/* default */.Z(url, xhr.status, "PARSE_ERROR", xhr)); - return; - } - obs.next({ - type: "data-loaded", - value: { - status: status, - url: _url, - responseType: loadedResponseType, - sendingTime: sendingTime, - receivedTime: receivedTime, - duration: receivedTime - sendingTime, - size: totalSize, - responseData: responseData - } - }); - obs.complete(); - } else { - obs.error(new request_error/* default */.Z(url, xhr.status, "ERROR_HTTP_CODE", xhr)); - } - } - }; - xhr.send(); - return function () { - if (!(0,is_null_or_undefined/* default */.Z)(xhr) && xhr.readyState !== 4) { - xhr.abort(); - } - }; - }); -} -/* harmony default export */ const xhr = (request); -;// CONCATENATED MODULE: ./src/utils/request/index.ts +var OUT_OF_SYNC_MANIFEST_REFRESH_DELAY = config/* default.OUT_OF_SYNC_MANIFEST_REFRESH_DELAY */.Z.OUT_OF_SYNC_MANIFEST_REFRESH_DELAY; /** - * Copyright 2015 CANAL+ Group + * Begin content playback. * - * 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 + * Returns an Observable emitting notifications about the content lifecycle. + * On subscription, it will perform every necessary tasks so the content can + * play. Among them: * - * http://www.apache.org/licenses/LICENSE-2.0 + * - Creates a MediaSource on the given `mediaElement` and attach to it the + * necessary SourceBuffer instances. * - * 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 */ const utils_request = (xhr); - - -/***/ }), - -/***/ 9829: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ resolveURL, -/* harmony export */ "f": () => /* binding */ normalizeBaseURL -/* harmony export */ }); -/** - * Copyright 2015 CANAL+ Group + * - download the content's Manifest and handle its refresh logic * - * 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 + * - Perform EME management if needed * - * http://www.apache.org/licenses/LICENSE-2.0 + * - ask for the choice of the wanted Adaptation through events (e.g. to + * choose a language) * - * 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. - */ -// Scheme part of an url (e.g. "http://"). -var schemeRe = /^(?:[a-z]+:)?\/\//i; // Captures "/../" or "/./". - -var selfDirRe = /\/\.{1,2}\//; -/** - * Resolve self directory and previous directory references to obtain a - * "normalized" url. - * @example "https://foo.bar/baz/booz/../biz" => "https://foo.bar/baz/biz" - * @param {string} url - * @returns {string} + * - 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} */ -function _normalizeUrl(url) { - // fast path if no ./ or ../ are present in the url - if (!selfDirRe.test(url)) { - return url; - } +function InitializeOnMediaSource(_ref) { + var adaptiveOptions = _ref.adaptiveOptions, + autoPlay = _ref.autoPlay, + bufferOptions = _ref.bufferOptions, + clock$ = _ref.clock$, + keySystems = _ref.keySystems, + lowLatencyMode = _ref.lowLatencyMode, + manifest$ = _ref.manifest$, + manifestFetcher = _ref.manifestFetcher, + mediaElement = _ref.mediaElement, + minimumManifestUpdateInterval = _ref.minimumManifestUpdateInterval, + segmentFetcherCreator = _ref.segmentFetcherCreator, + setCurrentTime = _ref.setCurrentTime, + speed$ = _ref.speed$, + startAt = _ref.startAt, + textTrackOptions = _ref.textTrackOptions; - var newUrl = []; - var oldUrl = url.split("/"); + /** Choose the right "Representation" for a given "Adaptation". */ + var abrManager = new abr(adaptiveOptions); + /** + * 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. + */ - for (var i = 0, l = oldUrl.length; i < l; i++) { - if (oldUrl[i] === "..") { - newUrl.pop(); - } else if (oldUrl[i] === ".") { - continue; - } else { - newUrl.push(oldUrl[i]); - } - } + var openMediaSource$ = openMediaSource(mediaElement).pipe((0,shareReplay/* shareReplay */.d)({ + refCount: true + })); + /** Send content protection data to the `EMEManager`. */ - return newUrl.join("/"); -} -/** - * Construct an url from the arguments given. - * Basically: - * - The last arguments that contains a scheme (e.g. "http://") is the base - * of the url. - * - every subsequent string arguments are concatened to it. - * @param {...string|undefined} args - * @returns {string} - */ + var protectedSegments$ = new Subject/* Subject */.xQ(); + /** Create `EMEManager`, an observable which will handle content DRM. */ + var emeManager$ = (0,create_eme_manager/* default */.Z)(mediaElement, keySystems, protectedSegments$).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 `emeManager$` 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 + // `emeManager$` 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. + */ -function resolveURL() { - var len = arguments.length; + var mediaError$ = (0,throw_on_media_error/* default */.Z)(mediaElement); + /** + * Wait for the MediaKeys to have been created before opening the MediaSource, + * after that second step is done, ask the EMEManager to attach the MediaKeys. + * Steps are done in that specific order to avoid compatibility issues. + * + * This Observable will emit when ready both the MediaSource and useful + * DRM-specific information. + */ - if (len === 0) { - return ""; - } + var prepareMediaSource$ = emeManager$.pipe(mergeScan(function (acc, evt) { + switch (evt.type) { + case "eme-disabled": + case "attached-media-keys": + return (0,of.of)({ + isEmeReady: true, + drmSystemId: acc.drmSystemId + }); - var base = ""; + case "created-media-keys": + var drmSystemId = evt.value.initializationDataSystemId; + return openMediaSource$.pipe((0,mergeMap/* mergeMap */.zg)(function () { + // Now that the MediaSource has been opened and linked to the media + // element we can attach the MediaKeys instance to the latter. + evt.value.attachMediaKeys$.next(); // If the `disableMediaKeysAttachmentLock` option has been set to + // `true`, we should not wait until the MediaKeys instance has been + // attached to start loading the content. - for (var i = 0; i < len; i++) { - var part = i < 0 || arguments.length <= i ? undefined : arguments[i]; + var shouldDisableLock = evt.value.options.disableMediaKeysAttachmentLock === true; + return shouldDisableLock ? (0,of.of)({ + isEmeReady: true, + drmSystemId: drmSystemId + }) : empty/* EMPTY */.E; + }), (0,startWith/* startWith */.O)({ + isEmeReady: false, + drmSystemId: drmSystemId + })); - if (typeof part !== "string" || part === "") { - continue; + default: + return empty/* EMPTY */.E; } + }, { + isEmeReady: false, + drmSystemId: undefined + }), (0,filter/* filter */.h)(function (emitted) { + return emitted.isEmeReady; + }), (0,take/* take */.q)(1), exhaustMap(function (_ref2) { + var drmSystemId = _ref2.drmSystemId; + return openMediaSource$.pipe((0,map/* map */.U)(function (mediaSource) { + return { + mediaSource: mediaSource, + drmSystemId: drmSystemId + }; + })); + })); + /** Load and play the content asked. */ - if (schemeRe.test(part)) { - base = part; - } else { - // trim if begins with "/" - if (part[0] === "/") { - part = part.substring(1); - } // trim if ends with "/" - - - if (base[base.length - 1] === "/") { - base = base.substring(0, base.length - 1); - } + var loadContent$ = (0,combineLatest/* combineLatest */.aj)([manifest$, prepareMediaSource$]).pipe((0,mergeMap/* mergeMap */.zg)(function (_ref3) { + var manifestEvt = _ref3[0], + mediaSourceInfo = _ref3[1]; - base = base + "/" + part; + if (manifestEvt.type === "warning") { + return (0,of.of)(manifestEvt); } - } - - return _normalizeUrl(base); -} -/** - * Remove string after the last '/'. - * @param {string} url - * @returns {string} - */ - -function normalizeBaseURL(url) { - var indexOfLastSlash = url.lastIndexOf("/"); - - if (indexOfLastSlash < 0) { - return url; - } - - if (schemeRe.test(url)) { - var firstSlashIndex = url.indexOf("/"); - if (firstSlashIndex >= 0 && indexOfLastSlash === firstSlashIndex + 1) { - // The "/" detected is actually the one from the protocol part of the URL - // ("https://") - return url; - } - } + var manifest = manifestEvt.manifest; + var initialMediaSource = mediaSourceInfo.mediaSource, + drmSystemId = mediaSourceInfo.drmSystemId; + 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 mediaSourceLoader = createMediaSourceLoader({ + abrManager: abrManager, + bufferOptions: (0,object_assign/* default */.Z)({ + textTrackOptions: textTrackOptions, + drmSystemId: drmSystemId + }, bufferOptions), + clock$: clock$, + manifest: manifest, + mediaElement: mediaElement, + segmentFetcherCreator: segmentFetcherCreator, + speed$: speed$, + setCurrentTime: setCurrentTime + }); // handle initial load and reloads - var indexOfQuestionMark = url.indexOf("?"); + var recursiveLoad$ = recursivelyLoadOnMediaSource(initialMediaSource, initialTime, autoPlay); // Emit when we want to manually update the manifest. - if (indexOfQuestionMark >= 0 && indexOfQuestionMark < indexOfLastSlash) { - // There are query parameters. Let's ignore them and re-run the logic - // without - return normalizeBaseURL(url.substring(0, indexOfQuestionMark)); - } + var scheduleRefresh$ = new Subject/* Subject */.xQ(); + var manifestUpdate$ = manifestUpdateScheduler({ + initialManifest: manifestEvt, + manifestFetcher: manifestFetcher, + minimumManifestUpdateInterval: minimumManifestUpdateInterval, + scheduleRefresh$: scheduleRefresh$ + }); + var manifestEvents$ = (0,merge/* merge */.T)((0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,mapTo/* mapTo */.h)(events_generators/* default.manifestUpdate */.Z.manifestUpdate())), (0,event_emitter/* fromEvent */.R)(manifest, "decipherabilityUpdate").pipe((0,map/* map */.U)(events_generators/* default.decipherabilityUpdate */.Z.decipherabilityUpdate))); + var setUndecipherableRepresentations$ = emeManager$.pipe((0,tap/* tap */.b)(function (evt) { + if (evt.type === "keys-update") { + manifest.updateDeciperabilitiesBasedOnKeyIds(evt.value); + } else if (evt.type === "blacklist-protection-data") { + log/* default.info */.Z.info("Init: blacklisting Representations based on protection data."); + manifest.addUndecipherableProtectionData(evt.value); + } + }), (0,ignoreElements/* ignoreElements */.l)()); + return (0,merge/* merge */.T)(manifestEvents$, manifestUpdate$, setUndecipherableRepresentations$, recursiveLoad$).pipe((0,startWith/* startWith */.O)(events_generators/* default.manifestReady */.Z.manifestReady(manifest)), finalize(function () { + scheduleRefresh$.complete(); + })); + /** + * 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} + */ - return url.substring(0, indexOfLastSlash + 1); -} + function recursivelyLoadOnMediaSource(mediaSource, startingPos, shouldPlay) { + var reloadMediaSource$ = new Subject/* Subject */.xQ(); + 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": + 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); -/***/ 5561: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (shouldReloadMediaSourceOnDecipherabilityUpdate(keySystem)) { + reloadMediaSource$.next(evt.value); + return null; + } // simple seek close to the current position + // to flush the buffers -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ tryCatch -/* harmony export */ }); -/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4944); -/** - * 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). - */ + var position = evt.value.position; -function tryCatch(func, argsForFunc) { - try { - return func(argsForFunc); - } catch (e) { - return (0,rxjs__WEBPACK_IMPORTED_MODULE_0__/* .throwError */ ._)(e); - } -} + if (position + 0.001 < evt.value.duration) { + setCurrentTime(mediaElement.currentTime + 0.001); + } else { + setCurrentTime(position); + } -/***/ }), + return null; -/***/ 9252: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + case "encryption-data-encountered": + protectedSegments$.next(evt.value); + return null; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ startsWith -/* harmony export */ }); + 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 */.zg)(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$, emeManager$); +} +;// CONCATENATED MODULE: ./src/core/init/index.ts /** * Copyright 2015 CANAL+ Group * @@ -51939,46 +54526,11 @@ function tryCatch(func, argsForFunc) { * limitations under the License. */ -/** - * String.prototype.startsWith ponyfill. - * Indicates Whether a string starts with another substring. - * - * Inspired from MDN polyfill, but ponyfilled instead. - * @param {string} completeString - * @param {string} searchString - * @param {number} [position] - * @returns {boolean} - */ -function startsWith(completeString, searchString, position) { - // eslint-disable-next-line @typescript-eslint/unbound-method - // eslint-disable-next-line no-restricted-properties - if (typeof String.prototype.startsWith === "function") { - // eslint-disable-next-line no-restricted-properties - return completeString.startsWith(searchString, position); - } - - var initialPosition = typeof position === "number" ? Math.max(position, 0) : 0; - return completeString.substring(initialPosition, initialPosition + searchString.length) === searchString; -} - -/***/ }), - -/***/ 3635: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "ci": () => /* binding */ bytesToHex, -/* harmony export */ "nr": () => /* binding */ hexToBytes, -/* harmony export */ "tG": () => /* binding */ strToUtf8, -/* harmony export */ "uR": () => /* binding */ utf8ToStr, -/* harmony export */ "TZ": () => /* binding */ strToUtf16LE, -/* harmony export */ "wV": () => /* binding */ utf16LEToStr, -/* harmony export */ "wO": () => /* binding */ guidToUuid -/* harmony export */ }); -/* unused harmony exports strToBeUtf16, beUtf16ToStr */ -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3887); -/* harmony import */ var _assert__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(811); +/* harmony default export */ const init = (InitializeOnMediaSource); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/refCount.js +var refCount = __webpack_require__(3018); +;// CONCATENATED MODULE: ./src/core/api/clock.ts /** * Copyright 2015 CANAL+ Group * @@ -51995,381 +54547,405 @@ function startsWith(completeString, searchString, position) { * limitations under the License. */ - -var hasTextDecoder = typeof window === "object" && typeof window.TextDecoder === "function"; -var hasTextEncoder = typeof window === "object" && typeof window.TextEncoder === "function"; /** - * Convert a string to an Uint8Array containing the corresponding UTF-16 code - * units in little-endian. - * @param {string} str - * @returns {Uint8Array} + * This file defines a global clock for the RxPlayer. + * + * Each clock tick also pass information about the current state of the + * media element to sub-parts of the player. */ -function strToUtf16LE(str) { - var buffer = new ArrayBuffer(str.length * 2); - var res = new Uint8Array(buffer); - - for (var i = 0; i < res.length; i += 2) { - var value = str.charCodeAt(i / 2); - res[i] = value & 0xFF; - res[i + 1] = value >> 8 & 0xFF; - } - return res; -} -/** - * Convert a string to an Uint8Array containing the corresponding UTF-16 code - * units in little-endian. - * @param {string} str - * @returns {Uint8Array} - */ -function strToBeUtf16(str) { - var buffer = new ArrayBuffer(str.length * 2); - var res = new Uint8Array(buffer); - for (var i = 0; i < res.length; i += 2) { - var value = str.charCodeAt(i / 2); - res[i + 1] = value & 0xFF; - res[i] = value >> 8 & 0xFF; - } - return res; -} +var SAMPLING_INTERVAL_MEDIASOURCE = config/* default.SAMPLING_INTERVAL_MEDIASOURCE */.Z.SAMPLING_INTERVAL_MEDIASOURCE, + SAMPLING_INTERVAL_LOW_LATENCY = config/* default.SAMPLING_INTERVAL_LOW_LATENCY */.Z.SAMPLING_INTERVAL_LOW_LATENCY, + SAMPLING_INTERVAL_NO_MEDIASOURCE = config/* default.SAMPLING_INTERVAL_NO_MEDIASOURCE */.Z.SAMPLING_INTERVAL_NO_MEDIASOURCE, + RESUME_GAP_AFTER_SEEKING = config/* default.RESUME_GAP_AFTER_SEEKING */.Z.RESUME_GAP_AFTER_SEEKING, + RESUME_GAP_AFTER_NOT_ENOUGH_DATA = config/* default.RESUME_GAP_AFTER_NOT_ENOUGH_DATA */.Z.RESUME_GAP_AFTER_NOT_ENOUGH_DATA, + RESUME_GAP_AFTER_BUFFERING = config/* default.RESUME_GAP_AFTER_BUFFERING */.Z.RESUME_GAP_AFTER_BUFFERING, + STALL_GAP = config/* default.STALL_GAP */.Z.STALL_GAP; /** - * Construct string from the little-endian UTF-16 code units given. - * @param {Uint8Array} bytes - * @returns {string} + * HTMLMediaElement Events for which timings are calculated and emitted. + * @type {Array.} */ +var SCANNED_MEDIA_ELEMENTS_EVENTS = ["canplay", "play", "seeking", "seeked", "loadedmetadata", "ratechange"]; +/** + * Returns the amount of time in seconds the buffer should have ahead of the + * current position before resuming playback. Based on the infos of the stall. + * Waiting time differs between a "seeking" stall and a buffering stall. + * @param {Object|null} stalled + * @param {Boolean} lowLatencyMode + * @returns {Number} + */ -function utf16LEToStr(bytes) { - if (hasTextDecoder) { - try { - // instanciation throws if the encoding is unsupported - var decoder = new TextDecoder("utf-16le"); - return decoder.decode(bytes); - } catch (e) { - _log__WEBPACK_IMPORTED_MODULE_0__/* .default.warn */ .Z.warn("Utils: could not use TextDecoder to parse UTF-16LE, " + "fallbacking to another implementation", e); - } +function getResumeGap(stalled, lowLatencyMode) { + if (stalled === null) { + return 0; } - var str = ""; + var suffix = lowLatencyMode ? "LOW_LATENCY" : "DEFAULT"; - for (var i = 0; i < bytes.length; i += 2) { - str += String.fromCharCode((bytes[i + 1] << 8) + bytes[i]); - } + switch (stalled.reason) { + case "seeking": + case "internal-seek": + return RESUME_GAP_AFTER_SEEKING[suffix]; - return str; + case "not-ready": + return RESUME_GAP_AFTER_NOT_ENOUGH_DATA[suffix]; + + case "buffering": + return RESUME_GAP_AFTER_BUFFERING[suffix]; + } } /** - * Construct string from the little-endian UTF-16 code units given. - * @param {Uint8Array} bytes - * @returns {string} + * @param {Object} currentRange + * @param {Number} duration + * @param {Boolean} lowLatencyMode + * @returns {Boolean} */ -function beUtf16ToStr(bytes) { - if (hasTextDecoder) { - try { - // instanciation throws if the encoding is unsupported - var decoder = new TextDecoder("utf-16be"); - return decoder.decode(bytes); - } catch (e) { - log.warn("Utils: could not use TextDecoder to parse UTF-16BE, " + "fallbacking to another implementation", e); - } - } - - var str = ""; - - for (var i = 0; i < bytes.length; i += 2) { - str += String.fromCharCode((bytes[i] << 8) + bytes[i + 1]); - } - - return str; +function hasLoadedUntilTheEnd(currentRange, duration, lowLatencyMode) { + var suffix = lowLatencyMode ? "LOW_LATENCY" : "DEFAULT"; + return currentRange !== null && duration - currentRange.end <= STALL_GAP[suffix]; } /** - * Convert a string to an Uint8Array containing the corresponding UTF-8 code - * units. - * @param {string} str - * @returns {Uint8Array} + * Generate a basic timings object from the media element and the eventName + * which triggered the request. + * @param {HTMLMediaElement} mediaElement + * @param {string} event + * @returns {Object} */ -function strToUtf8(str) { - if (hasTextEncoder) { - try { - var encoder = new TextEncoder(); - return encoder.encode(str); - } catch (e) { - _log__WEBPACK_IMPORTED_MODULE_0__/* .default.warn */ .Z.warn("Utils: could not use TextEncoder to encode string into UTF-8, " + "fallbacking to another implementation", e); - } - } // http://stackoverflow.com/a/13691499 provides an ugly but functional solution. - // (Note you have to dig deeper to understand it but I have more faith in - // stackoverflow not going down in the future so I leave that link.) - // Briefly said, `utf8Str` will contain a version of `str` where every - // non-ASCII characters will be replaced by an escape sequence of the - // corresponding representation of those characters in UTF-8. - // It does sound weird and unnecessarily complicated, but it works! - // - // Here is actually what happens with more words. We will rely on two browser - // APIs: - // - // - `encodeURIComponent` will take a string and convert the non-ASCII - // characters in it into the percent-encoded version of the corresponding - // UTF-8 bytes - // Example: encodeURIComponent("é") => 0xC3 0xA9 => `"%C3%A9"` - // - // - `unescape` unescapes (so far so good) a percent-encoded string. But it - // does it in a really simple way: percent-encoded byte by percent-encoded - // byte into the corresponding extended ASCII representation on 8 bits. - // As a result, we end-up with a string which actually contains instead of - // each of its original characters, the UTF-8 code units (8 bits) of - // those characters. - // Let's take our previous `"é" => "%C3%A9"` example. Here we would get: - // unecape("%C3%A9") => "\u00c3\u00a9" === "é" (in extended ASCII) - // - // By iterating on the resulting string, we will then be able to generate a - // Uint8Array containing the UTF-8 representation of that original string, by - // just calling the charCodeAt API on it. - - - var utf8Str; - var pcStr = encodeURIComponent(str); // As "unescape" is a deprecated function we want to declare a fallback in the - // case a browser decide to not implement it. - - if (typeof unescape === "function") { - utf8Str = unescape(pcStr); - } else { - // Let's implement a simple unescape function (got to admit it was for the challenge) - // http://ecma-international.org/ecma-262/9.0/#sec-unescape-string - var isHexChar = /[0-9a-fA-F]/; - var pcStrLen = pcStr.length; - utf8Str = ""; +function getMediaInfos(mediaElement, event) { + var buffered = mediaElement.buffered, + currentTime = mediaElement.currentTime, + duration = mediaElement.duration, + ended = mediaElement.ended, + paused = mediaElement.paused, + playbackRate = mediaElement.playbackRate, + readyState = mediaElement.readyState, + seeking = mediaElement.seeking; + var currentRange = (0,ranges/* getRange */.rx)(buffered, currentTime); + return { + bufferGap: currentRange !== null ? currentRange.end - currentTime : // TODO null/0 would probably be + // more appropriate + Infinity, + buffered: buffered, + currentRange: currentRange, + position: currentTime, + duration: duration, + ended: ended, + paused: paused, + playbackRate: playbackRate, + readyState: readyState, + seeking: seeking, + event: event + }; +} +/** + * Infer stalled status of the media based on: + * - the return of the function getMediaInfos + * - the previous timings object. + * + * @param {Object} prevTimings - Previous timings object. See function to know + * the different properties needed. + * @param {Object} currentTimings - Current timings object. This does not need + * to have every single infos, see function to know which properties are needed. + * @param {Object} options + * @returns {Object|null} + */ - for (var i = 0; i < pcStr.length; i++) { - var wasPercentEncoded = false; - if (pcStr[i] === "%") { - if (i <= pcStrLen - 6 && pcStr[i + 1] === "u" && isHexChar.test(pcStr[i + 2]) && isHexChar.test(pcStr[i + 3]) && isHexChar.test(pcStr[i + 4]) && isHexChar.test(pcStr[i + 5])) { - var charCode = parseInt(pcStr.substring(i + 1, i + 6), 16); - utf8Str += String.fromCharCode(charCode); - wasPercentEncoded = true; - i += 5; // Skip the next 5 chars - } else if (i <= pcStrLen - 3 && isHexChar.test(pcStr[i + 1]) && isHexChar.test(pcStr[i + 2])) { - var _charCode = parseInt(pcStr.substring(i + 1, i + 3), 16); +function getStalledStatus(prevTimings, currentTimings, _ref) { + var withMediaSource = _ref.withMediaSource, + lowLatencyMode = _ref.lowLatencyMode; + var currentEvt = currentTimings.event, + currentTime = currentTimings.position, + bufferGap = currentTimings.bufferGap, + currentRange = currentTimings.currentRange, + duration = currentTimings.duration, + paused = currentTimings.paused, + readyState = currentTimings.readyState, + ended = currentTimings.ended; + var prevStalled = prevTimings.stalled, + prevEvt = prevTimings.event, + prevTime = prevTimings.position; + var fullyLoaded = hasLoadedUntilTheEnd(currentRange, duration, lowLatencyMode); + var canStall = readyState >= 1 && currentEvt !== "loadedmetadata" && prevStalled === null && !(fullyLoaded || ended); + var stalledPosition = null; + var shouldStall; + var shouldUnstall; + var stallGap = lowLatencyMode ? STALL_GAP.LOW_LATENCY : STALL_GAP.DEFAULT; - utf8Str += String.fromCharCode(_charCode); - wasPercentEncoded = true; - i += 2; // Skip the next 2 chars - } + if (withMediaSource) { + if (canStall) { + if (bufferGap <= stallGap) { + shouldStall = true; + stalledPosition = currentTime + bufferGap; + } else if (bufferGap === Infinity) { + shouldStall = true; + stalledPosition = currentTime; + } else if (readyState === 1) { + shouldStall = true; } + } else if (prevStalled !== null) { + var resumeGap = getResumeGap(prevStalled, lowLatencyMode); - if (!wasPercentEncoded) { - utf8Str += pcStr[i]; + if (shouldStall !== true && prevStalled !== null && readyState > 1 && (fullyLoaded || ended || bufferGap < Infinity && bufferGap > resumeGap)) { + shouldUnstall = true; + } else if (bufferGap === Infinity || bufferGap <= resumeGap) { + stalledPosition = bufferGap === Infinity ? currentTime : currentTime + bufferGap; + } + } + } // when using a direct file, the media will stall and unstall on its + // own, so we only try to detect when the media timestamp has not changed + // between two consecutive timeupdates + else { + if (canStall && (!paused && currentEvt === "timeupdate" && prevEvt === "timeupdate" && currentTime === prevTime || currentEvt === "seeking" && bufferGap === Infinity)) { + shouldStall = true; + } else if (prevStalled !== null && (currentEvt !== "seeking" && currentTime !== prevTime || currentEvt === "canplay" || bufferGap < Infinity && (bufferGap > getResumeGap(prevStalled, lowLatencyMode) || fullyLoaded || ended))) { + shouldUnstall = true; } } - } // Now let's just build our array from every other bytes of that string's - // UTF-16 representation - - - var res = new Uint8Array(utf8Str.length); - - for (var _i = 0; _i < utf8Str.length; _i++) { - res[_i] = utf8Str.charCodeAt(_i) & 0xFF; // first byte should be 0x00 anyway - } - - return res; -} -/** - * Creates a new string from the given array of char codes. - * @param {Uint8Array} args - * @returns {string} - */ + if (shouldUnstall === true) { + return null; + } else if (shouldStall === true || prevStalled !== null) { + var reason; -function stringFromCharCodes(args) { - var max = 16000; - var ret = ""; + if (currentEvt === "seeking" || prevStalled !== null && prevStalled.reason === "seeking") { + reason = "seeking"; + } else if (currentTimings.seeking && (currentEvt === "internal-seeking" || prevStalled !== null && prevStalled.reason === "internal-seek")) { + reason = "internal-seek"; + } else if (currentTimings.seeking) { + reason = "seeking"; + } else if (readyState === 1) { + reason = "not-ready"; + } else { + reason = "buffering"; + } - for (var i = 0; i < args.length; i += max) { - var subArray = args.subarray(i, i + max); // NOTE: ugly I know, but TS is problematic here (you can try) + if (prevStalled !== null && prevStalled.reason === reason) { + return { + reason: prevStalled.reason, + timestamp: prevStalled.timestamp, + position: stalledPosition + }; + } - ret += String.fromCharCode.apply(null, subArray); + return { + reason: reason, + timestamp: performance.now(), + position: stalledPosition + }; } - return ret; + return null; } /** - * Transform an integer into an hexadecimal string of the given length, padded - * to the left with `0` if needed. - * @example - * ``` - * intToHex(5, 4); // => "0005" - * intToHex(5, 2); // => "05" - * intToHex(10, 1); // => "a" - * intToHex(268, 3); // => "10c" - * intToHex(4584, 6) // => "0011e8" - * intToHex(123456, 4); // => "1e240" (we do nothing when going over 4 chars) - * ``` - * @param {number} num - * @param {number} size - * @returns {string} + * Timings observable. + * + * This Observable samples snapshots of player's current state: + * * time position + * * playback rate + * * current buffered range + * * gap with current buffered range ending + * * media duration + * + * In addition to sampling, this Observable also reacts to "seeking" and "play" + * events. + * + * Observable is shared for performance reason: reduces the number of event + * listeners and intervals/timeouts but also limit access to the media element + * properties and gap calculations. + * + * The sampling is manual instead of based on "timeupdate" to reduce the + * number of events. + * @param {HTMLMediaElement} mediaElement + * @param {Object} options + * @returns {Observable} */ -function intToHex(num, size) { - var toStr = num.toString(16); - return toStr.length >= size ? toStr : new Array(size - toStr.length + 1).join("0") + toStr; -} -/** - * Creates a string from the given Uint8Array containing utf-8 code units. - * @param {Uint8Array} bytes - * @returns {string} - */ - +function createClock(mediaElement, options) { + // Allow us to identify seek performed internally by the player. + var internalSeekingComingCounter = 0; -function utf8ToStr(data) { - if (hasTextDecoder) { - try { - // TextDecoder use UTF-8 by default - var decoder = new TextDecoder(); - return decoder.decode(data); - } catch (e) { - _log__WEBPACK_IMPORTED_MODULE_0__/* .default.warn */ .Z.warn("Utils: could not use TextDecoder to parse UTF-8, " + "fallbacking to another implementation", e); - } + function setCurrentTime(time) { + mediaElement.currentTime = time; + internalSeekingComingCounter += 1; } - var uint8 = data; // If present, strip off the UTF-8 BOM. - - if (uint8[0] === 0xEF && uint8[1] === 0xBB && uint8[2] === 0xBF) { - uint8 = uint8.subarray(3); - } // We're basically doing strToUtf8 in reverse. - // You can look at that other function for the whole story. - // Generate string containing escaped UTF-8 code units - - - var utf8Str = stringFromCharCodes(uint8); - var escaped; - - if (typeof escape === "function") { - // Transform UTF-8 escape sequence into percent-encoded escape sequences. - escaped = escape(utf8Str); - } else { - // Let's implement a simple escape function - // http://ecma-international.org/ecma-262/9.0/#sec-escape-string - var nonEscapedChar = /[A-Za-z0-9*_\+-\.\/]/; - escaped = ""; - - for (var i = 0; i < utf8Str.length; i++) { - if (nonEscapedChar.test(utf8Str[i])) { - escaped += utf8Str[i]; - } else { - var charCode = utf8Str.charCodeAt(i); - escaped += charCode >= 256 ? "%u" + intToHex(charCode, 4) : "%" + intToHex(charCode, 2); + var clock$ = (0,defer/* defer */.P)(function () { + var lastTimings = (0,object_assign/* default */.Z)(getMediaInfos(mediaElement, "init"), { + stalled: null, + getCurrentTime: function getCurrentTime() { + return mediaElement.currentTime; } - } - } // Decode the percent-encoded UTF-8 string into the proper JS string. - // Example: "g#%E3%82%AC" -> "g#€" + }); + function getCurrentClockTick(event) { + var tmpEvt = event; - return decodeURIComponent(escaped); -} -/** - * Convert hex codes in a string form into the corresponding bytes. - * @param {string} str - * @returns {Uint8Array} - * @throws TypeError - str.length is odd - */ + if (tmpEvt === "seeking" && internalSeekingComingCounter > 0) { + tmpEvt = "internal-seeking"; + internalSeekingComingCounter -= 1; + } + var mediaTimings = getMediaInfos(mediaElement, tmpEvt); + var stalledState = getStalledStatus(lastTimings, mediaTimings, options); + var timings = (0,object_assign/* default */.Z)({}, { + stalled: stalledState, + getCurrentTime: function getCurrentTime() { + return mediaElement.currentTime; + } + }, mediaTimings); + log/* default.debug */.Z.debug("API: current media element state", timings); + return timings; + } -function hexToBytes(str) { - var len = str.length; - var arr = new Uint8Array(len / 2); + var eventObs = SCANNED_MEDIA_ELEMENTS_EVENTS.map(function (eventName) { + return (0,fromEvent/* fromEvent */.R)(mediaElement, eventName).pipe((0,mapTo/* mapTo */.h)(eventName)); + }); + var interval = options.lowLatencyMode ? SAMPLING_INTERVAL_LOW_LATENCY : options.withMediaSource ? SAMPLING_INTERVAL_MEDIASOURCE : SAMPLING_INTERVAL_NO_MEDIASOURCE; + var interval$ = (0,observable_interval/* interval */.F)(interval).pipe((0,mapTo/* mapTo */.h)("timeupdate")); + return merge/* merge.apply */.T.apply(void 0, [interval$].concat(eventObs)).pipe((0,map/* map */.U)(function (event) { + lastTimings = getCurrentClockTick(event); - for (var i = 0, j = 0; i < len; i += 2, j++) { - arr[j] = parseInt(str.substring(i, i + 2), 16) & 0xFF; - } + if (log/* default.getLevel */.Z.getLevel() === "DEBUG") { + log/* default.debug */.Z.debug("API: current playback timeline:\n" + prettyPrintBuffered(lastTimings.buffered, lastTimings.position), "\n" + event); + } - return arr; + return lastTimings; + }), (0,startWith/* startWith */.O)(lastTimings)); + }).pipe((0,multicast/* multicast */.O)(function () { + return new ReplaySubject/* ReplaySubject */.t(1); + }), // Always emit the last + (0,refCount/* refCount */.x)()); + return { + clock$: clock$, + setCurrentTime: setCurrentTime + }; } /** - * Convert bytes into the corresponding hex string, with the possibility - * to add a separator. - * @param {Uint8Array} bytes - * @param {string} [sep=""] - separator. Separate each two hex character. + * Pretty print a TimeRanges Object, to see the current content of it in a + * one-liner string. + * + * @example + * This function is called by giving it directly the TimeRanges, such as: + * ```js + * prettyPrintBuffered(document.getElementsByTagName("video")[0].buffered); + * ``` + * + * Let's consider this possible return: + * + * ``` + * 0.00|==29.95==|29.95 ~30.05~ 60.00|==29.86==|89.86 + * ^14 + * ``` + * This means that our video element has 29.95 seconds of buffer between 0 and + * 29.95 seconds. + * Then 30.05 seconds where no buffer is found. + * Then 29.86 seconds of buffer between 60.00 and 89.86 seconds. + * + * A caret on the second line indicates the current time we're at. + * The number coming after it is the current time. + * @param {TimeRanges} buffered + * @param {number} currentTime * @returns {string} */ -function bytesToHex(bytes, sep) { - if (sep === void 0) { - sep = ""; - } - - var hex = ""; +function prettyPrintBuffered(buffered, currentTime) { + var str = ""; + var currentTimeStr = ""; - for (var i = 0; i < bytes.byteLength; i++) { - hex += (bytes[i] >>> 4).toString(16); - hex += (bytes[i] & 0xF).toString(16); + for (var i = 0; i < buffered.length; i++) { + var start = buffered.start(i); + var end = buffered.end(i); + var fixedStart = start.toFixed(2); + var fixedEnd = end.toFixed(2); + var fixedDuration = (end - start).toFixed(2); + var newIntervalStr = fixedStart + "|==" + fixedDuration + "==|" + fixedEnd; + str += newIntervalStr; - if (sep.length > 0 && i < bytes.byteLength - 1) { - hex += sep; + if (currentTimeStr.length === 0 && end > currentTime) { + var padBefore = str.length - Math.floor(newIntervalStr.length / 2); + currentTimeStr = " ".repeat(padBefore) + ("^" + currentTime); } - } - - return hex; -} -/** - * Convert little-endian GUID into big-endian UUID. - * @param {Uint8Array} guid - * @returns {Uint8Array} - uuid - * @throws AssertionError - The guid length is not 16 - */ + if (i < buffered.length - 1) { + var nextStart = buffered.start(i + 1); + var fixedDiff = (nextStart - end).toFixed(2); + var holeStr = " ~" + fixedDiff + "~ "; + str += holeStr; -function guidToUuid(guid) { - (0,_assert__WEBPACK_IMPORTED_MODULE_1__/* .default */ .Z)(guid.length === 16, "GUID length should be 16"); - var p1A = guid[0]; - var p1B = guid[1]; - var p1C = guid[2]; - var p1D = guid[3]; - var p2A = guid[4]; - var p2B = guid[5]; - var p3A = guid[6]; - var p3B = guid[7]; - var uuid = new Uint8Array(16); // swapping byte endian on 4 bytes - // [1, 2, 3, 4] => [4, 3, 2, 1] + if (currentTimeStr.length === 0 && currentTime < nextStart) { + var _padBefore = str.length - Math.floor(holeStr.length / 2); - uuid[0] = p1D; - uuid[1] = p1C; - uuid[2] = p1B; - uuid[3] = p1A; // swapping byte endian on 2 bytes - // [5, 6] => [6, 5] + currentTimeStr = " ".repeat(_padBefore) + ("^" + currentTime); + } + } + } - uuid[4] = p2B; - uuid[5] = p2A; // swapping byte endian on 2 bytes - // [7, 8] => [8, 7] + if (currentTimeStr.length === 0) { + currentTimeStr = " ".repeat(str.length) + ("^" + currentTime); + } - uuid[6] = p3B; - uuid[7] = p3A; - uuid.set(guid.subarray(8, 16), 8); - return uuid; + return str + "\n" + currentTimeStr; } +/* harmony default export */ const clock = (createClock); +;// CONCATENATED MODULE: ./src/core/api/emit_seek_events.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 Observable which will emit: + * - `"seeking"` when we are seeking in the given mediaElement + * - `"seeked"` when a seek is considered as finished by the given clock$ + * Observable. + * @param {HTMLMediaElement} mediaElement + * @param {Observable} clock$ + * @returns {Observable} + */ -/***/ 5278: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +function emitSeekEvents(mediaElement, clock$) { + return (0,defer/* defer */.P)(function () { + if (mediaElement === null) { + return empty/* EMPTY */.E; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ takeFirstSet -/* harmony export */ }); -/* harmony import */ var _is_null_or_undefined__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1946); + var isSeeking$ = clock$.pipe((0,filter/* filter */.h)(function (tick) { + return tick.event === "seeking"; + }), (0,mapTo/* mapTo */.h)("seeking")); + var hasSeeked$ = isSeeking$.pipe((0,switchMapTo/* switchMapTo */.c)(clock$.pipe((0,filter/* filter */.h)(function (tick) { + return tick.event === "seeked"; + }), (0,mapTo/* mapTo */.h)("seeked"), (0,take/* take */.q)(1)))); + var seekingEvents$ = (0,merge/* merge */.T)(isSeeking$, hasSeeked$); + return mediaElement.seeking ? seekingEvents$.pipe((0,startWith/* startWith */.O)("seeking")) : seekingEvents$; + }); +} +;// CONCATENATED MODULE: ./src/core/api/get_player_state.ts /** * Copyright 2015 CANAL+ Group * @@ -52386,38 +54962,60 @@ function guidToUuid(guid) { * limitations under the License. */ -function takeFirstSet() { - var i = 0; +var FORCED_ENDED_THRESHOLD = config/* default.FORCED_ENDED_THRESHOLD */.Z.FORCED_ENDED_THRESHOLD; +/** Player state dictionnary. */ - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } +var PLAYER_STATES = { + STOPPED: "STOPPED", + LOADED: "LOADED", + LOADING: "LOADING", + PLAYING: "PLAYING", + PAUSED: "PAUSED", + ENDED: "ENDED", + BUFFERING: "BUFFERING", + SEEKING: "SEEKING", + RELOADING: "RELOADING" +}; +/** + * Get state string for a _loaded_ content. + * @param {HTMLMediaElement} mediaElement + * @param {boolean} isPlaying - false when the player is paused. true otherwise. + * @param {Object} stalledStatus - Current stalled state: + * - null when not stalled + * - an object with a description of the situation if stalled. + * @returns {string} + */ - var len = args.length; +function getLoadedContentState(mediaElement, isPlaying, stalledStatus) { + if (mediaElement.ended) { + return PLAYER_STATES.ENDED; + } - while (i < len) { - var arg = args[i]; + if (stalledStatus !== null) { + // On some old browsers (e.g. Chrome 54), the browser does not + // emit an 'ended' event in some conditions. Detect if we + // reached the end by comparing the current position and the + // duration instead. + var gapBetweenDurationAndCurrentTime = Math.abs(mediaElement.duration - mediaElement.currentTime); - if (!(0,_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(arg)) { - return arg; + if (FORCED_ENDED_THRESHOLD != null && gapBetweenDurationAndCurrentTime < FORCED_ENDED_THRESHOLD) { + return PLAYER_STATES.ENDED; } - i++; + return stalledStatus.reason === "seeking" ? PLAYER_STATES.SEEKING : PLAYER_STATES.BUFFERING; } - return undefined; + return isPlaying ? PLAYER_STATES.PLAYING : PLAYER_STATES.PAUSED; } +// EXTERNAL MODULE: ./src/utils/languages/normalize.ts + 2 modules +var normalize = __webpack_require__(5553); +;// CONCATENATED MODULE: ./src/core/api/option_utils.ts +function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { 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."); } it = o[Symbol.iterator](); return it.next.bind(it); } -/***/ }), +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); } -/***/ 8806: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +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; } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ warnOnce -/* harmony export */ }); -/* harmony import */ var _array_includes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7714); /** * Copyright 2015 CANAL+ Group * @@ -52434,5793 +55032,4604 @@ function takeFirstSet() { * limitations under the License. */ -var WARNED_MESSAGES = []; /** - * Perform a console.warn only once in the application lifetime. - * - * Useful for deprecated messages, for example. + * This file exports various helpers to parse options given to various APIs, + * throw if something is wrong, and return a normalized option object. + */ + + + + + + + +var DEFAULT_AUDIO_TRACK_SWITCHING_MODE = config/* default.DEFAULT_AUDIO_TRACK_SWITCHING_MODE */.Z.DEFAULT_AUDIO_TRACK_SWITCHING_MODE, + DEFAULT_AUTO_PLAY = config/* default.DEFAULT_AUTO_PLAY */.Z.DEFAULT_AUTO_PLAY, + DEFAULT_CODEC_SWITCHING_BEHAVIOR = config/* default.DEFAULT_CODEC_SWITCHING_BEHAVIOR */.Z.DEFAULT_CODEC_SWITCHING_BEHAVIOR, + DEFAULT_ENABLE_FAST_SWITCHING = config/* default.DEFAULT_ENABLE_FAST_SWITCHING */.Z.DEFAULT_ENABLE_FAST_SWITCHING, + DEFAULT_INITIAL_BITRATES = config/* default.DEFAULT_INITIAL_BITRATES */.Z.DEFAULT_INITIAL_BITRATES, + DEFAULT_LIMIT_VIDEO_WIDTH = config/* default.DEFAULT_LIMIT_VIDEO_WIDTH */.Z.DEFAULT_LIMIT_VIDEO_WIDTH, + DEFAULT_MANUAL_BITRATE_SWITCHING_MODE = config/* default.DEFAULT_MANUAL_BITRATE_SWITCHING_MODE */.Z.DEFAULT_MANUAL_BITRATE_SWITCHING_MODE, + DEFAULT_MIN_BITRATES = config/* default.DEFAULT_MIN_BITRATES */.Z.DEFAULT_MIN_BITRATES, + DEFAULT_MAX_BITRATES = config/* default.DEFAULT_MAX_BITRATES */.Z.DEFAULT_MAX_BITRATES, + DEFAULT_MAX_BUFFER_AHEAD = config/* default.DEFAULT_MAX_BUFFER_AHEAD */.Z.DEFAULT_MAX_BUFFER_AHEAD, + DEFAULT_MAX_BUFFER_BEHIND = config/* default.DEFAULT_MAX_BUFFER_BEHIND */.Z.DEFAULT_MAX_BUFFER_BEHIND, + DEFAULT_SHOW_NATIVE_SUBTITLE = config/* default.DEFAULT_SHOW_NATIVE_SUBTITLE */.Z.DEFAULT_SHOW_NATIVE_SUBTITLE, + DEFAULT_STOP_AT_END = config/* default.DEFAULT_STOP_AT_END */.Z.DEFAULT_STOP_AT_END, + DEFAULT_TEXT_TRACK_MODE = config/* default.DEFAULT_TEXT_TRACK_MODE */.Z.DEFAULT_TEXT_TRACK_MODE, + DEFAULT_THROTTLE_WHEN_HIDDEN = config/* default.DEFAULT_THROTTLE_WHEN_HIDDEN */.Z.DEFAULT_THROTTLE_WHEN_HIDDEN, + DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN = config/* default.DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN */.Z.DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN, + DEFAULT_WANTED_BUFFER_AHEAD = config/* default.DEFAULT_WANTED_BUFFER_AHEAD */.Z.DEFAULT_WANTED_BUFFER_AHEAD; +/** + * Parse options given to the API constructor and set default options as found + * in the config. * - * @param {string} message + * Do not mutate anything, only cross the given options and sane default options + * (most coming from the config). + * @param {Object|undefined} options + * @returns {Object} */ -function warnOnce(message) { - if (!(0,_array_includes__WEBPACK_IMPORTED_MODULE_0__/* .default */ .Z)(WARNED_MESSAGES, message)) { - // eslint-disable-next-line no-console - console.warn(message); - WARNED_MESSAGES.push(message); +function parseConstructorOptions(options) { + var maxBufferAhead; + var maxBufferBehind; + var wantedBufferAhead; + var throttleWhenHidden; + var throttleVideoBitrateWhenHidden; + var preferredAudioTracks; + var preferredTextTracks; + var preferredVideoTracks; + var videoElement; + var initialVideoBitrate; + var initialAudioBitrate; + var minAudioBitrate; + var minVideoBitrate; + var maxAudioBitrate; + var maxVideoBitrate; + + if ((0,is_null_or_undefined/* default */.Z)(options.maxBufferAhead)) { + maxBufferAhead = DEFAULT_MAX_BUFFER_AHEAD; + } else { + maxBufferAhead = Number(options.maxBufferAhead); + + if (isNaN(maxBufferAhead)) { + throw new Error("Invalid maxBufferAhead parameter. Should be a number."); + } } -} -/***/ }), + if ((0,is_null_or_undefined/* default */.Z)(options.maxBufferBehind)) { + maxBufferBehind = DEFAULT_MAX_BUFFER_BEHIND; + } else { + maxBufferBehind = Number(options.maxBufferBehind); -/***/ 7473: -/***/ ((module) => { + if (isNaN(maxBufferBehind)) { + throw new Error("Invalid maxBufferBehind parameter. Should be a number."); + } + } -"use strict"; + if ((0,is_null_or_undefined/* default */.Z)(options.wantedBufferAhead)) { + wantedBufferAhead = DEFAULT_WANTED_BUFFER_AHEAD; + } else { + wantedBufferAhead = Number(options.wantedBufferAhead); + if (isNaN(wantedBufferAhead)) { + /* eslint-disable max-len */ + throw new Error("Invalid wantedBufferAhead parameter. Should be a number."); + /* eslint-enable max-len */ + } + } -var ensureCallable = function (fn) { - if (typeof fn !== 'function') throw new TypeError(fn + " is not a function"); - return fn; -}; + var limitVideoWidth = (0,is_null_or_undefined/* default */.Z)(options.limitVideoWidth) ? DEFAULT_LIMIT_VIDEO_WIDTH : !!options.limitVideoWidth; -var byObserver = function (Observer) { - var node = document.createTextNode(''), queue, currentQueue, i = 0; - new Observer(function () { - var callback; - if (!queue) { - if (!currentQueue) return; - queue = currentQueue; - } else if (currentQueue) { - queue = currentQueue.concat(queue); - } - currentQueue = queue; - queue = null; - if (typeof currentQueue === 'function') { - callback = currentQueue; - currentQueue = null; - callback(); - return; - } - node.data = (i = ++i % 2); // Invoke other batch, to handle leftover callbacks in case of crash - while (currentQueue) { - callback = currentQueue.shift(); - if (!currentQueue.length) currentQueue = null; - callback(); - } - }).observe(node, { characterData: true }); - return function (fn) { - ensureCallable(fn); - if (queue) { - if (typeof queue === 'function') queue = [queue, fn]; - else queue.push(fn); - return; - } - queue = fn; - node.data = (i = ++i % 2); - }; -}; + if (!(0,is_null_or_undefined/* default */.Z)(options.throttleWhenHidden)) { + (0,warn_once/* default */.Z)("`throttleWhenHidden` API is deprecated. Consider using " + "`throttleVideoBitrateWhenHidden` instead."); + throttleWhenHidden = !!options.throttleWhenHidden; + } else { + throttleWhenHidden = DEFAULT_THROTTLE_WHEN_HIDDEN; + } // `throttleWhenHidden` and `throttleVideoBitrateWhenHidden` can be in conflict + // Do not activate the latter if the former is -module.exports = (function () { - // Node.js - if ((typeof process === 'object') && process && (typeof process.nextTick === 'function')) { - return process.nextTick; - } - // queueMicrotask - if (typeof queueMicrotask === "function") { - return function (cb) { queueMicrotask(ensureCallable(cb)); }; - } + if (throttleWhenHidden) { + throttleVideoBitrateWhenHidden = false; + } else { + throttleVideoBitrateWhenHidden = (0,is_null_or_undefined/* default */.Z)(options.throttleVideoBitrateWhenHidden) ? DEFAULT_THROTTLE_VIDEO_BITRATE_WHEN_HIDDEN : !!options.throttleVideoBitrateWhenHidden; + } - // MutationObserver - if ((typeof document === 'object') && document) { - if (typeof MutationObserver === 'function') return byObserver(MutationObserver); - if (typeof WebKitMutationObserver === 'function') return byObserver(WebKitMutationObserver); - } + if (options.preferredTextTracks !== undefined) { + if (!Array.isArray(options.preferredTextTracks)) { + (0,warn_once/* default */.Z)("Invalid `preferredTextTracks` option, it should be an Array"); + preferredTextTracks = []; + } else { + preferredTextTracks = options.preferredTextTracks; + } + } else { + preferredTextTracks = []; + } - // W3C Draft - // http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html - if (typeof setImmediate === 'function') { - return function (cb) { setImmediate(ensureCallable(cb)); }; - } + if (options.preferredAudioTracks !== undefined) { + if (!Array.isArray(options.preferredAudioTracks)) { + (0,warn_once/* default */.Z)("Invalid `preferredAudioTracks` option, it should be an Array"); + preferredAudioTracks = []; + } else { + preferredAudioTracks = options.preferredAudioTracks; + } + } else { + preferredAudioTracks = []; + } + + if (options.preferredVideoTracks !== undefined) { + if (!Array.isArray(options.preferredVideoTracks)) { + (0,warn_once/* default */.Z)("Invalid `preferredVideoTracks` option, it should be an Array"); + preferredVideoTracks = []; + } else { + preferredVideoTracks = options.preferredVideoTracks; + } + } else { + preferredVideoTracks = []; + } + + if ((0,is_null_or_undefined/* default */.Z)(options.videoElement)) { + videoElement = document.createElement("video"); + } else if (options.videoElement instanceof HTMLMediaElement) { + videoElement = options.videoElement; + } else { + /* eslint-disable max-len */ + throw new Error("Invalid videoElement parameter. Should be a HTMLMediaElement."); + /* eslint-enable max-len */ + } + + if ((0,is_null_or_undefined/* default */.Z)(options.initialVideoBitrate)) { + initialVideoBitrate = DEFAULT_INITIAL_BITRATES.video; + } else { + initialVideoBitrate = Number(options.initialVideoBitrate); + + if (isNaN(initialVideoBitrate)) { + /* eslint-disable max-len */ + throw new Error("Invalid initialVideoBitrate parameter. Should be a number."); + /* eslint-enable max-len */ + } + } + + if ((0,is_null_or_undefined/* default */.Z)(options.initialAudioBitrate)) { + initialAudioBitrate = DEFAULT_INITIAL_BITRATES.audio; + } else { + initialAudioBitrate = Number(options.initialAudioBitrate); + + if (isNaN(initialAudioBitrate)) { + /* eslint-disable max-len */ + throw new Error("Invalid initialAudioBitrate parameter. Should be a number."); + /* eslint-enable max-len */ + } + } + + if ((0,is_null_or_undefined/* default */.Z)(options.minVideoBitrate)) { + minVideoBitrate = DEFAULT_MIN_BITRATES.video; + } else { + minVideoBitrate = Number(options.minVideoBitrate); + + if (isNaN(minVideoBitrate)) { + throw new Error("Invalid maxVideoBitrate parameter. Should be a number."); + } + } + + if ((0,is_null_or_undefined/* default */.Z)(options.minAudioBitrate)) { + minAudioBitrate = DEFAULT_MIN_BITRATES.audio; + } else { + minAudioBitrate = Number(options.minAudioBitrate); + + if (isNaN(minAudioBitrate)) { + throw new Error("Invalid minAudioBitrate parameter. Should be a number."); + } + } + + if ((0,is_null_or_undefined/* default */.Z)(options.maxVideoBitrate)) { + maxVideoBitrate = DEFAULT_MAX_BITRATES.video; + } else { + maxVideoBitrate = Number(options.maxVideoBitrate); + + if (isNaN(maxVideoBitrate)) { + throw new Error("Invalid maxVideoBitrate parameter. Should be a number."); + } else if (minVideoBitrate > maxVideoBitrate) { + throw new Error("Invalid maxVideoBitrate parameter. Its value, \"" + (maxVideoBitrate + "\", is inferior to the set minVideoBitrate, \"") + (minVideoBitrate + "\"")); + } + } + + if ((0,is_null_or_undefined/* default */.Z)(options.maxAudioBitrate)) { + maxAudioBitrate = DEFAULT_MAX_BITRATES.audio; + } else { + maxAudioBitrate = Number(options.maxAudioBitrate); + + if (isNaN(maxAudioBitrate)) { + throw new Error("Invalid maxAudioBitrate parameter. Should be a number."); + } else if (minAudioBitrate > maxAudioBitrate) { + throw new Error("Invalid maxAudioBitrate parameter. Its value, \"" + (maxAudioBitrate + "\", is inferior to the set minAudioBitrate, \"") + (minAudioBitrate + "\"")); + } + } + + var stopAtEnd = (0,is_null_or_undefined/* default */.Z)(options.stopAtEnd) ? DEFAULT_STOP_AT_END : !!options.stopAtEnd; + return { + maxBufferAhead: maxBufferAhead, + maxBufferBehind: maxBufferBehind, + limitVideoWidth: limitVideoWidth, + videoElement: videoElement, + wantedBufferAhead: wantedBufferAhead, + throttleWhenHidden: throttleWhenHidden, + throttleVideoBitrateWhenHidden: throttleVideoBitrateWhenHidden, + preferredAudioTracks: preferredAudioTracks, + preferredTextTracks: preferredTextTracks, + preferredVideoTracks: preferredVideoTracks, + initialAudioBitrate: initialAudioBitrate, + initialVideoBitrate: initialVideoBitrate, + minAudioBitrate: minAudioBitrate, + minVideoBitrate: minVideoBitrate, + maxAudioBitrate: maxAudioBitrate, + maxVideoBitrate: maxVideoBitrate, + stopAtEnd: stopAtEnd + }; +} +/** + * Check the format of given reload options. + * Throw if format in invalid. + * @param {object | undefined} options + */ + + +function checkReloadOptions(options) { + var _a, _b, _c, _d; + + if (options === null || typeof options !== "object" && options !== undefined) { + throw new Error("API: reload - Invalid options format."); + } + + if ((options === null || options === void 0 ? void 0 : options.reloadAt) === null || typeof (options === null || options === void 0 ? void 0 : options.reloadAt) !== "object" && (options === null || options === void 0 ? void 0 : options.reloadAt) !== undefined) { + throw new Error("API: reload - Invalid 'reloadAt' option format."); + } + + if (typeof ((_a = options === null || options === void 0 ? void 0 : options.reloadAt) === null || _a === void 0 ? void 0 : _a.position) !== "number" && ((_b = options === null || options === void 0 ? void 0 : options.reloadAt) === null || _b === void 0 ? void 0 : _b.position) !== undefined) { + throw new Error("API: reload - Invalid 'reloadAt.position' option format."); + } + + if (typeof ((_c = options === null || options === void 0 ? void 0 : options.reloadAt) === null || _c === void 0 ? void 0 : _c.relative) !== "number" && ((_d = options === null || options === void 0 ? void 0 : options.reloadAt) === null || _d === void 0 ? void 0 : _d.relative) !== undefined) { + throw new Error("API: reload - Invalid 'reloadAt.relative' option format."); + } +} +/** + * Parse options given to loadVideo and set default options as found + * in the config. + * + * Do not mutate anything, only cross the given options and sane default options + * (most coming from the config). + * + * Throws if any mandatory option is not set. + * @param {Object|undefined} options + * @param {Object} ctx - The player context, needed for some default values. + * @returns {Object} + */ - // Wide available standard - if ((typeof setTimeout === 'function') || (typeof setTimeout === 'object')) { - return function (cb) { setTimeout(ensureCallable(cb), 0); }; - } - return null; -}()); +function parseLoadVideoOptions(options) { + var _a, _b, _c, _d, _e, _f; + var url; + var transport; + var keySystems; + var textTrackMode; + var textTrackElement; + var startAt; -/***/ }), + if ((0,is_null_or_undefined/* default */.Z)(options)) { + throw new Error("No option set on loadVideo"); + } -/***/ 8555: -/***/ ((module, __unused_webpack_exports, __webpack_require__) => { + if (!(0,is_null_or_undefined/* default */.Z)(options.url)) { + url = String(options.url); + } else if ((0,is_null_or_undefined/* default */.Z)((_a = options.transportOptions) === null || _a === void 0 ? void 0 : _a.initialManifest) && (0,is_null_or_undefined/* default */.Z)((_b = options.transportOptions) === null || _b === void 0 ? void 0 : _b.manifestLoader)) { + throw new Error("Unable to load a content: no url set on loadVideo.\n" + "Please provide at least either an `url` argument, a " + "`transportOptions.initialManifest` option or a " + "`transportOptions.manifestLoader` option so the RxPlayer " + "can load the content."); + } -"use strict"; + if ((0,is_null_or_undefined/* default */.Z)(options.transport)) { + throw new Error("No transport set on loadVideo"); + } else { + transport = String(options.transport); + } + var autoPlay = (0,is_null_or_undefined/* default */.Z)(options.autoPlay) ? DEFAULT_AUTO_PLAY : !!options.autoPlay; -var PENDING = 'pending'; -var SETTLED = 'settled'; -var FULFILLED = 'fulfilled'; -var REJECTED = 'rejected'; -var NOOP = function () {}; -var isNode = typeof __webpack_require__.g !== 'undefined' && typeof __webpack_require__.g.process !== 'undefined' && typeof __webpack_require__.g.process.emit === 'function'; + if ((0,is_null_or_undefined/* default */.Z)(options.keySystems)) { + keySystems = []; + } else { + keySystems = Array.isArray(options.keySystems) ? options.keySystems : [options.keySystems]; -var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate; -var asyncQueue = []; -var asyncTimer; + for (var _iterator = _createForOfIteratorHelperLoose(keySystems), _step; !(_step = _iterator()).done;) { + var keySystem = _step.value; -function asyncFlush() { - // run promise callbacks - for (var i = 0; i < asyncQueue.length; i++) { - asyncQueue[i][0](asyncQueue[i][1]); - } + if (typeof keySystem.type !== "string" || typeof keySystem.getLicense !== "function") { + throw new Error("Invalid key system given: Missing type string or " + "getLicense callback"); + } + } + } - // reset async asyncQueue - asyncQueue = []; - asyncTimer = false; -} + 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 audioTrackSwitchingMode = (0,is_null_or_undefined/* default */.Z)(options.audioTrackSwitchingMode) ? DEFAULT_AUDIO_TRACK_SWITCHING_MODE : options.audioTrackSwitchingMode; -function asyncCall(callback, arg) { - asyncQueue.push([callback, arg]); + if (!(0,array_includes/* default */.Z)(["seamless", "direct"], audioTrackSwitchingMode)) { + log/* default.warn */.Z.warn("The `audioTrackSwitchingMode` loadVideo option must match one of " + "the following strategy name:\n" + "- `seamless`\n" + "- `direct`\n" + "If badly set, " + DEFAULT_AUDIO_TRACK_SWITCHING_MODE + " strategy will be used as default"); + audioTrackSwitchingMode = DEFAULT_AUDIO_TRACK_SWITCHING_MODE; + } - if (!asyncTimer) { - asyncTimer = true; - asyncSetTimer(asyncFlush, 0); - } -} + var onCodecSwitch = (0,is_null_or_undefined/* default */.Z)(options.onCodecSwitch) ? DEFAULT_CODEC_SWITCHING_BEHAVIOR : options.onCodecSwitch; -function invokeResolver(resolver, promise) { - function resolvePromise(value) { - resolve(promise, value); - } + if (!(0,array_includes/* default */.Z)(["continue", "reload"], onCodecSwitch)) { + log/* default.warn */.Z.warn("The `onCodecSwitch` loadVideo option must match one of " + "the following string:\n" + "- `continue`\n" + "- `reload`\n" + "If badly set, " + DEFAULT_CODEC_SWITCHING_BEHAVIOR + " will be used as default"); + onCodecSwitch = DEFAULT_CODEC_SWITCHING_BEHAVIOR; + } - function rejectPromise(reason) { - reject(promise, reason); - } + var transportOptions = (0,object_assign/* default */.Z)({}, transportOptsArg, { + /* eslint-disable import/no-deprecated */ + supplementaryImageTracks: [], + supplementaryTextTracks: [], - try { - resolver(resolvePromise, rejectPromise); - } catch (e) { - rejectPromise(e); - } -} + /* eslint-enable import/no-deprecated */ + lowLatencyMode: lowLatencyMode + }); // remove already parsed data to simplify the `transportOptions` object -function invokeCallback(subscriber) { - var owner = subscriber.owner; - var settled = owner._state; - var value = owner._data; - var callback = subscriber[settled]; - var promise = subscriber.then; + delete transportOptions.initialManifest; + delete transportOptions.minimumManifestUpdateInterval; - if (typeof callback === 'function') { - settled = FULFILLED; - try { - value = callback(value); - } catch (e) { - reject(promise, e); - } - } + if (options.supplementaryTextTracks !== undefined) { + (0,warn_once/* default */.Z)("The `supplementaryTextTracks` loadVideo option is deprecated.\n" + "Please use the `TextTrackRenderer` tool instead."); + var supplementaryTextTracks = Array.isArray(options.supplementaryTextTracks) ? options.supplementaryTextTracks : [options.supplementaryTextTracks]; - if (!handleThenable(promise, value)) { - if (settled === FULFILLED) { - resolve(promise, value); - } + for (var _iterator2 = _createForOfIteratorHelperLoose(supplementaryTextTracks), _step2; !(_step2 = _iterator2()).done;) { + var supplementaryTextTrack = _step2.value; - if (settled === REJECTED) { - reject(promise, value); - } - } -} + if (typeof supplementaryTextTrack.language !== "string" || typeof supplementaryTextTrack.mimeType !== "string" || typeof supplementaryTextTrack.url !== "string") { + throw new Error("Invalid supplementary text track given. " + "Missing either language, mimetype or url"); + } + } -function handleThenable(promise, value) { - var resolved; + transportOptions.supplementaryTextTracks = supplementaryTextTracks; + } - try { - if (promise === value) { - throw new TypeError('A promises callback cannot return that same promise.'); - } + if (options.supplementaryImageTracks !== undefined) { + (0,warn_once/* default */.Z)("The `supplementaryImageTracks` loadVideo option is deprecated.\n" + "Please use the `parseBifThumbnails` tool instead."); + var supplementaryImageTracks = Array.isArray(options.supplementaryImageTracks) ? options.supplementaryImageTracks : [options.supplementaryImageTracks]; - if (value && (typeof value === 'function' || typeof value === 'object')) { - // then should be retrieved only once - var then = value.then; + for (var _iterator3 = _createForOfIteratorHelperLoose(supplementaryImageTracks), _step3; !(_step3 = _iterator3()).done;) { + var supplementaryImageTrack = _step3.value; - if (typeof then === 'function') { - then.call(value, function (val) { - if (!resolved) { - resolved = true; + if (typeof supplementaryImageTrack.mimeType !== "string" || typeof supplementaryImageTrack.url !== "string") { + throw new Error("Invalid supplementary image track given. " + "Missing either mimetype or url"); + } + } - if (value === val) { - fulfill(promise, val); - } else { - resolve(promise, val); - } - } - }, function (reason) { - if (!resolved) { - resolved = true; + transportOptions.supplementaryImageTracks = supplementaryImageTracks; + } - reject(promise, reason); - } - }); + if ((0,is_null_or_undefined/* default */.Z)(options.textTrackMode)) { + textTrackMode = DEFAULT_TEXT_TRACK_MODE; + } else { + if (options.textTrackMode !== "native" && options.textTrackMode !== "html") { + throw new Error("Invalid textTrackMode."); + } - return true; - } - } - } catch (e) { - if (!resolved) { - reject(promise, e); - } + textTrackMode = options.textTrackMode; + } - return true; - } + if (!(0,is_null_or_undefined/* default */.Z)(options.defaultAudioTrack)) { + (0,warn_once/* default */.Z)("The `defaultAudioTrack` loadVideo option is deprecated.\n" + "Please use the `preferredAudioTracks` constructor option or the" + "`setPreferredAudioTracks` method instead"); + } - return false; -} + var defaultAudioTrack = (0,normalize/* normalizeAudioTrack */.iH)(options.defaultAudioTrack); -function resolve(promise, value) { - if (promise === value || !handleThenable(promise, value)) { - fulfill(promise, value); - } -} + if (!(0,is_null_or_undefined/* default */.Z)(options.defaultTextTrack)) { + (0,warn_once/* default */.Z)("The `defaultTextTrack` loadVideo option is deprecated.\n" + "Please use the `preferredTextTracks` constructor option or the" + "`setPreferredTextTracks` method instead"); + } -function fulfill(promise, value) { - if (promise._state === PENDING) { - promise._state = SETTLED; - promise._data = value; + var defaultTextTrack = (0,normalize/* normalizeTextTrack */.Y1)(options.defaultTextTrack); + var hideNativeSubtitle = !DEFAULT_SHOW_NATIVE_SUBTITLE; - asyncCall(publishFulfillment, promise); - } -} + if (!(0,is_null_or_undefined/* default */.Z)(options.hideNativeSubtitle)) { + (0,warn_once/* default */.Z)("The `hideNativeSubtitle` loadVideo option is deprecated"); + hideNativeSubtitle = !!options.hideNativeSubtitle; + } -function reject(promise, reason) { - if (promise._state === PENDING) { - promise._state = SETTLED; - promise._data = reason; + var manualBitrateSwitchingMode = (_f = options.manualBitrateSwitchingMode) !== null && _f !== void 0 ? _f : DEFAULT_MANUAL_BITRATE_SWITCHING_MODE; + var enableFastSwitching = (0,is_null_or_undefined/* default */.Z)(options.enableFastSwitching) ? DEFAULT_ENABLE_FAST_SWITCHING : options.enableFastSwitching; - asyncCall(publishRejection, promise); - } -} + if (textTrackMode === "html") { + // TODO Better way to express that in TypeScript? + if ((0,is_null_or_undefined/* default */.Z)(options.textTrackElement)) { + throw new Error("You have to provide a textTrackElement " + "in \"html\" textTrackMode."); + } else if (!(options.textTrackElement instanceof HTMLElement)) { + throw new Error("textTrackElement should be an HTMLElement."); + } else { + textTrackElement = options.textTrackElement; + } + } else if (!(0,is_null_or_undefined/* default */.Z)(options.textTrackElement)) { + log/* default.warn */.Z.warn("API: You have set a textTrackElement without being in " + "an \"html\" textTrackMode. It will be ignored."); + } -function publish(promise) { - promise._then = promise._then.forEach(invokeCallback); -} + if (!(0,is_null_or_undefined/* default */.Z)(options.startAt)) { + // TODO Better way to express that in TypeScript? + if (options.startAt.wallClockTime instanceof Date) { + var wallClockTime = options.startAt.wallClockTime.getTime() / 1000; + startAt = (0,object_assign/* default */.Z)({}, options.startAt, { + wallClockTime: wallClockTime + }); + } else { + startAt = options.startAt; + } + } -function publishFulfillment(promise) { - promise._state = FULFILLED; - publish(promise); -} + var networkConfig = (0,is_null_or_undefined/* default */.Z)(options.networkConfig) ? {} : { + manifestRetry: options.networkConfig.manifestRetry, + offlineRetry: options.networkConfig.offlineRetry, + segmentRetry: options.networkConfig.segmentRetry + }; // TODO without cast -function publishRejection(promise) { - promise._state = REJECTED; - publish(promise); - if (!promise._handled && isNode) { - __webpack_require__.g.process.emit('unhandledRejection', promise._data, promise); - } -} + /* eslint-disable @typescript-eslint/consistent-type-assertions */ -function notifyRejectionHandled(promise) { - __webpack_require__.g.process.emit('rejectionHandled', promise); + return { + autoPlay: autoPlay, + defaultAudioTrack: defaultAudioTrack, + defaultTextTrack: defaultTextTrack, + enableFastSwitching: enableFastSwitching, + hideNativeSubtitle: hideNativeSubtitle, + keySystems: keySystems, + initialManifest: initialManifest, + lowLatencyMode: lowLatencyMode, + manualBitrateSwitchingMode: manualBitrateSwitchingMode, + audioTrackSwitchingMode: audioTrackSwitchingMode, + minimumManifestUpdateInterval: minimumManifestUpdateInterval, + networkConfig: networkConfig, + onCodecSwitch: onCodecSwitch, + startAt: startAt, + textTrackElement: textTrackElement, + textTrackMode: textTrackMode, + transport: transport, + transportOptions: transportOptions, + url: url + }; + /* eslint-enable @typescript-eslint/consistent-type-assertions */ } + +// EXTERNAL MODULE: ./src/utils/languages/index.ts +var languages = __webpack_require__(7829); +;// CONCATENATED MODULE: ./src/core/api/track_choice_manager.ts /** - * @class + * 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 Promise(resolver) { - if (typeof resolver !== 'function') { - throw new TypeError('Promise resolver ' + resolver + ' is not a function'); - } - - if (this instanceof Promise === false) { - throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); - } - this._then = []; - invokeResolver(resolver, this); -} -Promise.prototype = { - constructor: Promise, - _state: PENDING, - _then: null, - _data: undefined, - _handled: false, - then: function (onFulfillment, onRejection) { - var subscriber = { - owner: this, - then: new this.constructor(NOOP), - fulfilled: onFulfillment, - rejected: onRejection - }; - if ((onRejection || onFulfillment) && !this._handled) { - this._handled = true; - if (this._state === REJECTED && isNode) { - asyncCall(notifyRejectionHandled, this); - } - } +/** + * Transform an array of IAudioTrackPreference into an array of + * INormalizedPreferredAudioTrack to be exploited by the TrackChoiceManager. + * @param {Array.} + * @returns {Array.} + */ - if (this._state === FULFILLED || this._state === REJECTED) { - // already resolved, call callback async - asyncCall(invokeCallback, subscriber); - } else { - // subscribe - this._then.push(subscriber); - } +function normalizeAudioTracks(tracks) { + return tracks.map(function (t) { + return t == null ? t : { + normalized: t.language === undefined ? undefined : (0,languages/* default */.ZP)(t.language), + audioDescription: t.audioDescription, + codec: t.codec + }; + }); +} +/** + * Transform an array of ITextTrackPreference into an array of + * INormalizedPreferredTextTrack to be exploited by the TrackChoiceManager. + * @param {Array.} tracks + * @returns {Array.} + */ - return subscriber.then; - }, - catch: function (onRejection) { - return this.then(null, onRejection); - } -}; +function normalizeTextTracks(tracks) { + return tracks.map(function (t) { + return t == null ? t : { + normalized: (0,languages/* default */.ZP)(t.language), + closedCaption: t.closedCaption + }; + }); +} +/** + * Manage audio and text tracks for all active periods. + * Choose the audio and text tracks for each period and record this choice. + * @class TrackChoiceManager + */ -Promise.all = function (promises) { - if (!Array.isArray(promises)) { - throw new TypeError('You must pass an array to Promise.all().'); - } - return new Promise(function (resolve, reject) { - var results = []; - var remaining = 0; +var TrackChoiceManager = /*#__PURE__*/function () { + function TrackChoiceManager() { + this._periods = new SortedList(function (a, b) { + return a.period.start - b.period.start; + }); + this._audioChoiceMemory = new WeakMap(); + this._textChoiceMemory = new WeakMap(); + this._videoChoiceMemory = new WeakMap(); + this._preferredAudioTracks = []; + this._preferredTextTracks = []; + this._preferredVideoTracks = []; + } + /** + * Set the list of preferred audio tracks, in preference order. + * @param {Array.} preferredAudioTracks + * @param {boolean} shouldApply - `true` if those preferences should be + * applied on the currently loaded Period. `false` if it should only + * be applied to new content. + */ - function resolver(index) { - remaining++; - return function (value) { - results[index] = value; - if (!--remaining) { - resolve(results); - } - }; - } - for (var i = 0, promise; i < promises.length; i++) { - promise = promises[i]; + var _proto = TrackChoiceManager.prototype; - if (promise && typeof promise.then === 'function') { - promise.then(resolver(i), reject); - } else { - results[i] = promise; - } - } + _proto.setPreferredAudioTracks = function setPreferredAudioTracks(preferredAudioTracks, shouldApply) { + this._preferredAudioTracks = preferredAudioTracks; - if (!remaining) { - resolve(results); - } - }); -}; + if (shouldApply) { + this._applyAudioPreferences(); + } + } + /** + * Set the list of preferred text tracks, in preference order. + * @param {Array.} preferredTextTracks + * @param {boolean} shouldApply - `true` if those preferences should be + * applied on the currently loaded Periods. `false` if it should only + * be applied to new content. + */ + ; -Promise.race = function (promises) { - if (!Array.isArray(promises)) { - throw new TypeError('You must pass an array to Promise.race().'); - } + _proto.setPreferredTextTracks = function setPreferredTextTracks(preferredTextTracks, shouldApply) { + this._preferredTextTracks = preferredTextTracks; - return new Promise(function (resolve, reject) { - for (var i = 0, promise; i < promises.length; i++) { - promise = promises[i]; + if (shouldApply) { + this._applyTextPreferences(); + } + } + /** + * Set the list of preferred text tracks, in preference order. + * @param {Array.} tracks + * @param {boolean} shouldApply - `true` if those preferences should be + * applied on the currently loaded Period. `false` if it should only + * be applied to new content. + */ + ; - if (promise && typeof promise.then === 'function') { - promise.then(resolve, reject); - } else { - resolve(promise); - } - } - }); -}; + _proto.setPreferredVideoTracks = function setPreferredVideoTracks(preferredVideoTracks, shouldApply) { + this._preferredVideoTracks = preferredVideoTracks; -Promise.resolve = function (value) { - if (value && typeof value === 'object' && value.constructor === Promise) { - return value; - } + if (shouldApply) { + this._applyVideoPreferences(); + } + } + /** + * Add Subject 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 + */ + ; - return new Promise(function (resolve) { - resolve(value); - }); -}; + _proto.addPeriod = function addPeriod(bufferType, period, adaptation$) { + var periodItem = getPeriodItem(this._periods, period); + var adaptations = period.getPlayableAdaptations(bufferType); -Promise.reject = function (reason) { - return new Promise(function (resolve, reject) { - reject(reason); - }); -}; + if (periodItem != null) { + if (periodItem[bufferType] != null) { + log/* default.warn */.Z.warn("TrackChoiceManager: " + bufferType + " already added for period", period); + return; + } else { + periodItem[bufferType] = { + adaptations: adaptations, + adaptation$: adaptation$ + }; + } + } else { + var _this$_periods$add; -module.exports = Promise; + this._periods.add((_this$_periods$add = { + period: period + }, _this$_periods$add[bufferType] = { + adaptations: adaptations, + adaptation$: adaptation$ + }, _this$_periods$add)); + } + } + /** + * Remove Subject to choose an "audio", "video" or "text" Adaptation for a + * Period. + * @param {string} bufferType - The concerned buffer type + * @param {Period} period - The concerned Period. + */ + ; + _proto.removePeriod = function removePeriod(bufferType, period) { + var periodIndex = findPeriodIndex(this._periods, period); -/***/ }), + if (periodIndex == null) { + log/* default.warn */.Z.warn("TrackChoiceManager: " + bufferType + " not found for period", period); + return; + } -/***/ 5666: -/***/ ((module) => { + var periodItem = this._periods.get(periodIndex); -/** - * Copyright (c) 2014-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ + if (periodItem[bufferType] == null) { + log/* default.warn */.Z.warn("TrackChoiceManager: " + bufferType + " already removed for period", period); + return; + } -var runtime = (function (exports) { - "use strict"; + delete periodItem[bufferType]; - var Op = Object.prototype; - var hasOwn = Op.hasOwnProperty; - var undefined; // More compressible than void 0. - var $Symbol = typeof Symbol === "function" ? Symbol : {}; - var iteratorSymbol = $Symbol.iterator || "@@iterator"; - var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator"; - var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; + if (periodItem.audio == null && periodItem.text == null && periodItem.video == null) { + this._periods.removeElement(periodItem); + } + }; - function define(obj, key, value) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - return obj[key]; - } - try { - // IE 8 has a broken Object.defineProperty that only works on DOM objects. - define({}, ""); - } catch (err) { - define = function(obj, key, value) { - return obj[key] = value; - }; + _proto.resetPeriods = function resetPeriods() { + while (this._periods.length() > 0) { + this._periods.pop(); + } } + /** + * Update the choice of all added Periods based on: + * 1. What was the last chosen adaptation + * 2. If not found, the preferences + */ + ; - function wrap(innerFn, outerFn, self, tryLocsList) { - // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. - var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; - var generator = Object.create(protoGenerator.prototype); - var context = new Context(tryLocsList || []); + _proto.update = function update() { + this._resetChosenAudioTracks(); - // The ._invoke method unifies the implementations of the .next, - // .throw, and .return methods. - generator._invoke = makeInvokeMethod(innerFn, self, context); + this._resetChosenTextTracks(); - return generator; + this._resetChosenVideoTracks(); } - exports.wrap = wrap; + /** + * Emit initial audio Adaptation through the given Subject based on: + * - the preferred audio tracks + * - the last choice for this period, if one + * @param {Period} period - The concerned Period. + */ + ; - // Try/catch helper to minimize deoptimizations. Returns a completion - // record like context.tryEntries[i].completion. This interface could - // have been (and was previously) designed to take a closure to be - // invoked without arguments, but in all the cases we care about we - // already have an existing method we want to call, so there's no need - // to create a new function object. We can even get away with assuming - // the method takes exactly one argument, since that happens to be true - // in every case, so we don't have to touch the arguments object. The - // only additional allocation required is the completion record, which - // has a stable shape and so hopefully should be cheap to allocate. - function tryCatch(fn, obj, arg) { - try { - return { type: "normal", arg: fn.call(obj, arg) }; - } catch (err) { - return { type: "throw", arg: err }; + _proto.setInitialAudioTrack = function setInitialAudioTrack(period) { + var periodItem = getPeriodItem(this._periods, period); + var audioInfos = periodItem != null ? periodItem.audio : null; + + if (audioInfos == null || periodItem == null) { + throw new Error("TrackChoiceManager: Given Period not found."); } - } - var GenStateSuspendedStart = "suspendedStart"; - var GenStateSuspendedYield = "suspendedYield"; - var GenStateExecuting = "executing"; - var GenStateCompleted = "completed"; + var audioAdaptations = period.getPlayableAdaptations("audio"); - // Returning this object from the innerFn has the same effect as - // breaking out of the dispatch switch statement. - var ContinueSentinel = {}; + var chosenAudioAdaptation = this._audioChoiceMemory.get(period); - // Dummy constructor functions that we use as the .constructor and - // .constructor.prototype properties for functions that return Generator - // objects. For full spec compliance, you may wish to configure your - // minifier not to mangle the names of these two functions. - function Generator() {} - function GeneratorFunction() {} - function GeneratorFunctionPrototype() {} + if (chosenAudioAdaptation === null) { + // If the Period was previously without audio, keep it that way + audioInfos.adaptation$.next(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 is a polyfill for %IteratorPrototype% for environments that - // don't natively support it. - var IteratorPrototype = {}; - IteratorPrototype[iteratorSymbol] = function () { - return this; - }; + this._audioChoiceMemory.set(period, optimalAdaptation); - var getProto = Object.getPrototypeOf; - var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); - if (NativeIteratorPrototype && - NativeIteratorPrototype !== Op && - hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { - // This environment has a native %IteratorPrototype%; use it instead - // of the polyfill. - IteratorPrototype = NativeIteratorPrototype; + audioInfos.adaptation$.next(optimalAdaptation); + } else { + audioInfos.adaptation$.next(chosenAudioAdaptation); // set last one + } } + /** + * Emit initial text Adaptation through the given Subject based on: + * - the preferred text tracks + * - the last choice for this period, if one + * @param {Period} period - The concerned Period. + */ + ; - var Gp = GeneratorFunctionPrototype.prototype = - Generator.prototype = Object.create(IteratorPrototype); - GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; - GeneratorFunctionPrototype.constructor = GeneratorFunction; - GeneratorFunction.displayName = define( - GeneratorFunctionPrototype, - toStringTagSymbol, - "GeneratorFunction" - ); + _proto.setInitialTextTrack = function setInitialTextTrack(period) { + var periodItem = getPeriodItem(this._periods, period); + var textInfos = periodItem != null ? periodItem.text : null; - // Helper for defining the .next, .throw, and .return methods of the - // Iterator interface in terms of a single ._invoke method. - function defineIteratorMethods(prototype) { - ["next", "throw", "return"].forEach(function(method) { - define(prototype, method, function(arg) { - return this._invoke(method, arg); - }); - }); - } + if (textInfos == null || periodItem == null) { + throw new Error("TrackChoiceManager: Given Period not found."); + } - exports.isGeneratorFunction = function(genFun) { - var ctor = typeof genFun === "function" && genFun.constructor; - return ctor - ? ctor === GeneratorFunction || - // For the native GeneratorFunction constructor, the best we can - // do is to check its .name property. - (ctor.displayName || ctor.name) === "GeneratorFunction" - : false; - }; + var textAdaptations = period.getPlayableAdaptations("text"); - exports.mark = function(genFun) { - if (Object.setPrototypeOf) { - Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); - } else { - genFun.__proto__ = GeneratorFunctionPrototype; - define(genFun, toStringTagSymbol, "GeneratorFunction"); - } - genFun.prototype = Object.create(Gp); - return genFun; - }; + var chosenTextAdaptation = this._textChoiceMemory.get(period); - // Within the body of any async function, `await x` is transformed to - // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test - // `hasOwn.call(value, "__await")` to determine if the yielded value is - // meant to be awaited. - exports.awrap = function(arg) { - return { __await: arg }; - }; + if (chosenTextAdaptation === null) { + // If the Period was previously without text, keep it that way + textInfos.adaptation$.next(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); - function AsyncIterator(generator, PromiseImpl) { - function invoke(method, arg, resolve, reject) { - var record = tryCatch(generator[method], generator, arg); - if (record.type === "throw") { - reject(record.arg); - } else { - var result = record.arg; - var value = result.value; - if (value && - typeof value === "object" && - hasOwn.call(value, "__await")) { - return PromiseImpl.resolve(value.__await).then(function(value) { - invoke("next", value, resolve, reject); - }, function(err) { - invoke("throw", err, resolve, reject); - }); - } + this._textChoiceMemory.set(period, optimalAdaptation); - return PromiseImpl.resolve(value).then(function(unwrapped) { - // When a yielded Promise is resolved, its final value becomes - // the .value of the Promise<{value,done}> result for the - // current iteration. - result.value = unwrapped; - resolve(result); - }, function(error) { - // If a rejected Promise was yielded, throw the rejection back - // into the async generator function so it can be handled there. - return invoke("throw", error, resolve, reject); - }); - } + textInfos.adaptation$.next(optimalAdaptation); + } else { + textInfos.adaptation$.next(chosenTextAdaptation); // set last one } + } + /** + * Emit initial video Adaptation through the given Subject based on: + * - the preferred video tracks + * - the last choice for this period, if one + * @param {Period} period - The concerned Period. + */ + ; - var previousPromise; - - function enqueue(method, arg) { - function callInvokeWithMethodAndArg() { - return new PromiseImpl(function(resolve, reject) { - invoke(method, arg, resolve, reject); - }); - } + _proto.setInitialVideoTrack = function setInitialVideoTrack(period) { + var periodItem = getPeriodItem(this._periods, period); + var videoInfos = periodItem != null ? periodItem.video : null; - return previousPromise = - // If enqueue has been called before, then we want to wait until - // all previous Promises have been resolved before calling invoke, - // so that results are always delivered in the correct order. If - // enqueue has not been called before, then it is important to - // call invoke immediately, without waiting on a callback to fire, - // so that the async generator function has the opportunity to do - // any necessary setup in a predictable way. This predictability - // is why the Promise constructor synchronously invokes its - // executor callback, and why async functions synchronously - // execute code before the first await. Since we implement simple - // async functions in terms of async generators, it is especially - // important to get this right, even though it requires care. - previousPromise ? previousPromise.then( - callInvokeWithMethodAndArg, - // Avoid propagating failures to Promises returned by later - // invocations of the iterator. - callInvokeWithMethodAndArg - ) : callInvokeWithMethodAndArg(); + if (videoInfos == null || periodItem == null) { + throw new Error("TrackChoiceManager: Given Period not found."); } - // Define the unified helper method that is used to implement .next, - // .throw, and .return (see defineIteratorMethods). - this._invoke = enqueue; - } + var videoAdaptations = period.getPlayableAdaptations("video"); - defineIteratorMethods(AsyncIterator.prototype); - AsyncIterator.prototype[asyncIteratorSymbol] = function () { - return this; - }; - exports.AsyncIterator = AsyncIterator; + var chosenVideoAdaptation = this._videoChoiceMemory.get(period); - // Note that simple async functions are implemented on top of - // AsyncIterator objects; they just return a Promise for the value of - // the final result produced by the iterator. - exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) { - if (PromiseImpl === void 0) PromiseImpl = Promise; + if (chosenVideoAdaptation === null) { + // If the Period was previously without video, keep it that way + videoInfos.adaptation$.next(null); + } else if (chosenVideoAdaptation === undefined || !(0,array_includes/* default */.Z)(videoAdaptations, chosenVideoAdaptation)) { + var preferredVideoTracks = this._preferredVideoTracks; + var optimalAdaptation = findFirstOptimalVideoAdaptation(videoAdaptations, preferredVideoTracks); - var iter = new AsyncIterator( - wrap(innerFn, outerFn, self, tryLocsList), - PromiseImpl - ); + this._videoChoiceMemory.set(period, optimalAdaptation); - return exports.isGeneratorFunction(outerFn) - ? iter // If outerFn is a generator, return the full iterator. - : iter.next().then(function(result) { - return result.done ? result.value : iter.next(); - }); - }; + videoInfos.adaptation$.next(optimalAdaptation); + } else { + videoInfos.adaptation$.next(chosenVideoAdaptation); // set last one + } + } + /** + * Set audio track based on the ID of its adaptation for a given added Period. + * @param {Period} period - The concerned Period. + * @param {string} wantedId - adaptation id of the wanted track + */ + ; - function makeInvokeMethod(innerFn, self, context) { - var state = GenStateSuspendedStart; + _proto.setAudioTrackByID = function setAudioTrackByID(period, wantedId) { + var periodItem = getPeriodItem(this._periods, period); + var audioInfos = periodItem != null ? periodItem.audio : null; - return function invoke(method, arg) { - if (state === GenStateExecuting) { - throw new Error("Generator is already running"); - } + if (audioInfos == null) { + throw new Error("TrackChoiceManager: Given Period not found."); + } - if (state === GenStateCompleted) { - if (method === "throw") { - throw arg; - } + var wantedAdaptation = (0,array_find/* default */.Z)(audioInfos.adaptations, function (_ref) { + var id = _ref.id; + return id === wantedId; + }); - // Be forgiving, per 25.3.3.3.3 of the spec: - // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume - return doneResult(); - } + if (wantedAdaptation === undefined) { + throw new Error("Audio Track not found."); + } - context.method = method; - context.arg = arg; + var chosenAudioAdaptation = this._audioChoiceMemory.get(period); - while (true) { - var delegate = context.delegate; - if (delegate) { - var delegateResult = maybeInvokeDelegate(delegate, context); - if (delegateResult) { - if (delegateResult === ContinueSentinel) continue; - return delegateResult; - } - } + if (chosenAudioAdaptation === wantedAdaptation) { + return; + } - if (context.method === "next") { - // Setting context._sent for legacy support of Babel's - // function.sent implementation. - context.sent = context._sent = context.arg; + this._audioChoiceMemory.set(period, wantedAdaptation); - } else if (context.method === "throw") { - if (state === GenStateSuspendedStart) { - state = GenStateCompleted; - throw context.arg; - } + audioInfos.adaptation$.next(wantedAdaptation); + } + /** + * Set text track based on the ID of its adaptation for a given added Period. + * @param {Period} period - The concerned Period. + * @param {string} wantedId - adaptation id of the wanted track + */ + ; - context.dispatchException(context.arg); + _proto.setTextTrackByID = function setTextTrackByID(period, wantedId) { + var periodItem = getPeriodItem(this._periods, period); + var textInfos = periodItem != null ? periodItem.text : null; - } else if (context.method === "return") { - context.abrupt("return", context.arg); - } + if (textInfos == null) { + throw new Error("TrackChoiceManager: Given Period not found."); + } - state = GenStateExecuting; + var wantedAdaptation = (0,array_find/* default */.Z)(textInfos.adaptations, function (_ref2) { + var id = _ref2.id; + return id === wantedId; + }); - var record = tryCatch(innerFn, self, context); - if (record.type === "normal") { - // If an exception is thrown from innerFn, we leave state === - // GenStateExecuting and loop back for another invocation. - state = context.done - ? GenStateCompleted - : GenStateSuspendedYield; + if (wantedAdaptation === undefined) { + throw new Error("Text Track not found."); + } - if (record.arg === ContinueSentinel) { - continue; - } + var chosenTextAdaptation = this._textChoiceMemory.get(period); - return { - value: record.arg, - done: context.done - }; + if (chosenTextAdaptation === wantedAdaptation) { + return; + } - } else if (record.type === "throw") { - state = GenStateCompleted; - // Dispatch the exception by looping back around to the - // context.dispatchException(context.arg) call above. - context.method = "throw"; - context.arg = record.arg; - } - } - }; - } + this._textChoiceMemory.set(period, wantedAdaptation); - // Call delegate.iterator[context.method](context.arg) and handle the - // result, either by returning a { value, done } result from the - // delegate iterator, or by modifying context.method and context.arg, - // setting context.delegate to null, and returning the ContinueSentinel. - function maybeInvokeDelegate(delegate, context) { - var method = delegate.iterator[context.method]; - if (method === undefined) { - // A .throw or .return when the delegate iterator has no .throw - // method always terminates the yield* loop. - context.delegate = null; + textInfos.adaptation$.next(wantedAdaptation); + } + /** + * Set video track based on the ID of its adaptation for a given added Period. + * @param {Period} period - The concerned Period. + * @param {string} wantedId - adaptation id of the wanted track + * + * @throws Error - Throws if the period given has not been added + * @throws Error - Throws if the given id is not found in any video adaptation + * of the given Period. + */ + ; - if (context.method === "throw") { - // Note: ["return"] must be used for ES3 parsing compatibility. - if (delegate.iterator["return"]) { - // If the delegate iterator has a return method, give it a - // chance to clean up. - context.method = "return"; - context.arg = undefined; - maybeInvokeDelegate(delegate, context); + _proto.setVideoTrackByID = function setVideoTrackByID(period, wantedId) { + var periodItem = getPeriodItem(this._periods, period); + var videoInfos = periodItem != null ? periodItem.video : null; - if (context.method === "throw") { - // If maybeInvokeDelegate(context) changed context.method from - // "return" to "throw", let that override the TypeError below. - return ContinueSentinel; - } - } + if (videoInfos == null) { + throw new Error("LanguageManager: Given Period not found."); + } - context.method = "throw"; - context.arg = new TypeError( - "The iterator does not provide a 'throw' method"); - } + var wantedAdaptation = (0,array_find/* default */.Z)(videoInfos.adaptations, function (_ref3) { + var id = _ref3.id; + return id === wantedId; + }); - return ContinueSentinel; + if (wantedAdaptation === undefined) { + throw new Error("Video Track not found."); } - var record = tryCatch(method, delegate.iterator, context.arg); + var chosenVideoAdaptation = this._videoChoiceMemory.get(period); - if (record.type === "throw") { - context.method = "throw"; - context.arg = record.arg; - context.delegate = null; - return ContinueSentinel; + if (chosenVideoAdaptation === wantedAdaptation) { + return; } - var info = record.arg; + this._videoChoiceMemory.set(period, wantedAdaptation); - if (! info) { - context.method = "throw"; - context.arg = new TypeError("iterator result is not an object"); - context.delegate = null; - return ContinueSentinel; - } + videoInfos.adaptation$.next(wantedAdaptation); + } + /** + * Disable the current text track for a given period. + * + * @param {Period} period - The concerned Period. + * + * @throws Error - Throws if the period given has not been added + */ + ; - if (info.done) { - // Assign the result of the finished delegate to the temporary - // variable specified by delegate.resultName (see delegateYield). - context[delegate.resultName] = info.value; + _proto.disableTextTrack = function disableTextTrack(period) { + var periodItem = getPeriodItem(this._periods, period); + var textInfos = periodItem != null ? periodItem.text : null; - // Resume execution at the desired location (see delegateYield). - context.next = delegate.nextLoc; + if (textInfos == null) { + throw new Error("TrackChoiceManager: Given Period not found."); + } - // If context.method was "throw" but the delegate handled the - // exception, let the outer generator proceed normally. If - // context.method was "next", forget context.arg since it has been - // "consumed" by the delegate iterator. If context.method was - // "return", allow the original .return call to continue in the - // outer generator. - if (context.method !== "return") { - context.method = "next"; - context.arg = undefined; - } + var chosenTextAdaptation = this._textChoiceMemory.get(period); - } else { - // Re-yield the result returned by the delegate method. - return info; + if (chosenTextAdaptation === null) { + return; } - // The delegate iterator is finished, so forget it and continue with - // the outer generator. - context.delegate = null; - return ContinueSentinel; + this._textChoiceMemory.set(period, null); + + textInfos.adaptation$.next(null); } + /** + * Disable the current video track for a given period. + * @param {Object} period + * @throws Error - Throws if the period given has not been added + */ + ; - // Define Generator.prototype.{next,throw,return} in terms of the - // unified ._invoke helper method. - defineIteratorMethods(Gp); + _proto.disableVideoTrack = function disableVideoTrack(period) { + var periodItem = getPeriodItem(this._periods, period); + var videoInfos = periodItem === null || periodItem === void 0 ? void 0 : periodItem.video; - define(Gp, toStringTagSymbol, "Generator"); + if (videoInfos === undefined) { + throw new Error("TrackManager: Given Period not found."); + } - // A Generator should always return itself as the iterator object when the - // @@iterator function is called on it. Some browsers' implementations of the - // iterator prototype chain incorrectly implement this, causing the Generator - // object to not be returned from this call. This ensures that doesn't happen. - // See https://github.com/facebook/regenerator/issues/274 for more details. - Gp[iteratorSymbol] = function() { - return this; - }; + var chosenVideoAdaptation = this._videoChoiceMemory.get(period); - Gp.toString = function() { - return "[object Generator]"; - }; + if (chosenVideoAdaptation === null) { + return; + } - function pushTryEntry(locs) { - var entry = { tryLoc: locs[0] }; + this._videoChoiceMemory.set(period, null); - if (1 in locs) { - entry.catchLoc = locs[1]; + videoInfos.adaptation$.next(null); + } + /** + * Returns an object describing the chosen audio track for the given audio + * Period. + * + * Returns null is the the current audio track is disabled or not + * set yet. + * + * @param {Period} period - The concerned Period. + * @returns {Object|null} - The audio track chosen for this Period + */ + ; + + _proto.getChosenAudioTrack = function getChosenAudioTrack(period) { + var periodItem = getPeriodItem(this._periods, period); + var audioInfos = periodItem != null ? periodItem.audio : null; + + if (audioInfos == null) { + return null; } - if (2 in locs) { - entry.finallyLoc = locs[2]; - entry.afterLoc = locs[3]; + var chosenTrack = this._audioChoiceMemory.get(period); + + if (chosenTrack == null) { + return null; } - this.tryEntries.push(entry); - } + var audioTrack = { + language: (0,take_first_set/* default */.Z)(chosenTrack.language, ""), + normalized: (0,take_first_set/* default */.Z)(chosenTrack.normalizedLanguage, ""), + audioDescription: chosenTrack.isAudioDescription === true, + id: chosenTrack.id, + representations: chosenTrack.representations.map(parseAudioRepresentation) + }; - function resetTryEntry(entry) { - var record = entry.completion || {}; - record.type = "normal"; - delete record.arg; - entry.completion = record; - } + if (chosenTrack.isDub === true) { + audioTrack.dub = true; + } - function Context(tryLocsList) { - // The root entry object (effectively a try statement without a catch - // or a finally block) gives us a place to store values thrown from - // locations where there is no enclosing try statement. - this.tryEntries = [{ tryLoc: "root" }]; - tryLocsList.forEach(pushTryEntry, this); - this.reset(true); + return audioTrack; } + /** + * Returns an object describing the chosen text track for the given text + * Period. + * + * Returns null is the the current text track is disabled or not + * set yet. + * + * @param {Period} period - The concerned Period. + * @returns {Object|null} - The text track chosen for this Period + */ + ; - exports.keys = function(object) { - var keys = []; - for (var key in object) { - keys.push(key); + _proto.getChosenTextTrack = function getChosenTextTrack(period) { + var periodItem = getPeriodItem(this._periods, period); + var textInfos = periodItem != null ? periodItem.text : null; + + if (textInfos == null) { + return null; } - keys.reverse(); - // Rather than returning an object with a next method, we keep - // things simple and return the next function itself. - return function next() { - while (keys.length) { - var key = keys.pop(); - if (key in object) { - next.value = key; - next.done = false; - return next; - } - } + var chosenTextAdaptation = this._textChoiceMemory.get(period); - // To avoid creating an additional object, we just hang the .value - // and .done properties off the next function object itself. This - // also ensures that the minifier will not anonymize the function. - next.done = true; - return next; + if (chosenTextAdaptation == null) { + return null; + } + + return { + 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 }; - }; + } + /** + * Returns an object describing the chosen video track for the given video + * Period. + * + * Returns null is the the current video track is disabled or not + * set yet. + * + * @param {Period} period - The concerned Period. + * @returns {Object|null} - The video track chosen for this Period + */ + ; - function values(iterable) { - if (iterable) { - var iteratorMethod = iterable[iteratorSymbol]; - if (iteratorMethod) { - return iteratorMethod.call(iterable); - } + _proto.getChosenVideoTrack = function getChosenVideoTrack(period) { + var periodItem = getPeriodItem(this._periods, period); + var videoInfos = periodItem != null ? periodItem.video : null; - if (typeof iterable.next === "function") { - return iterable; - } + if (videoInfos == null) { + return null; + } - if (!isNaN(iterable.length)) { - var i = -1, next = function next() { - while (++i < iterable.length) { - if (hasOwn.call(iterable, i)) { - next.value = iterable[i]; - next.done = false; - return next; - } - } + var chosenVideoAdaptation = this._videoChoiceMemory.get(period); - next.value = undefined; - next.done = true; + if (chosenVideoAdaptation == null) { + return null; + } - return next; - }; + var videoTrack = { + id: chosenVideoAdaptation.id, + representations: chosenVideoAdaptation.representations.map(parseVideoRepresentation) + }; - return next.next = next; - } + if (chosenVideoAdaptation.isSignInterpreted === true) { + videoTrack.signInterpreted = true; } - // Return an iterator with no values. - return { next: doneResult }; - } - exports.values = values; - - function doneResult() { - return { value: undefined, done: true }; + return videoTrack; } + /** + * Returns all available audio tracks for a given Period, as an array of + * objects. + * + * @returns {Array.} + */ + ; - Context.prototype = { - constructor: Context, + _proto.getAvailableAudioTracks = function getAvailableAudioTracks(period) { + var periodItem = getPeriodItem(this._periods, period); + var audioInfos = periodItem != null ? periodItem.audio : null; - reset: function(skipTempReset) { - this.prev = 0; - this.next = 0; - // Resetting context._sent for legacy support of Babel's - // function.sent implementation. - this.sent = this._sent = undefined; - this.done = false; - this.delegate = null; + if (audioInfos == null) { + return []; + } - this.method = "next"; - this.arg = undefined; + var chosenAudioAdaptation = this._audioChoiceMemory.get(period); - this.tryEntries.forEach(resetTryEntry); + var currentId = chosenAudioAdaptation != null ? chosenAudioAdaptation.id : null; + return audioInfos.adaptations.map(function (adaptation) { + var formatted = { + language: (0,take_first_set/* default */.Z)(adaptation.language, ""), + normalized: (0,take_first_set/* default */.Z)(adaptation.normalizedLanguage, ""), + audioDescription: adaptation.isAudioDescription === true, + id: adaptation.id, + active: currentId == null ? false : currentId === adaptation.id, + representations: adaptation.representations.map(parseAudioRepresentation) + }; - if (!skipTempReset) { - for (var name in this) { - // Not sure about the optimal order of these conditions: - if (name.charAt(0) === "t" && - hasOwn.call(this, name) && - !isNaN(+name.slice(1))) { - this[name] = undefined; - } - } + if (adaptation.isDub === true) { + formatted.dub = true; } - }, - stop: function() { - this.done = true; + return formatted; + }); + } + /** + * Returns all available text tracks for a given Period, as an array of + * objects. + * + * @param {Period} period + * @returns {Array.} + */ + ; - var rootEntry = this.tryEntries[0]; - var rootRecord = rootEntry.completion; - if (rootRecord.type === "throw") { - throw rootRecord.arg; - } + _proto.getAvailableTextTracks = function getAvailableTextTracks(period) { + var periodItem = getPeriodItem(this._periods, period); + var textInfos = periodItem != null ? periodItem.text : null; - return this.rval; - }, + if (textInfos == null) { + return []; + } - dispatchException: function(exception) { - if (this.done) { - throw exception; - } + var chosenTextAdaptation = this._textChoiceMemory.get(period); - var context = this; - function handle(loc, caught) { - record.type = "throw"; - record.arg = exception; - context.next = loc; + var currentId = chosenTextAdaptation != null ? chosenTextAdaptation.id : null; + return textInfos.adaptations.map(function (adaptation) { + return { + language: (0,take_first_set/* default */.Z)(adaptation.language, ""), + normalized: (0,take_first_set/* default */.Z)(adaptation.normalizedLanguage, ""), + closedCaption: adaptation.isClosedCaption === true, + id: adaptation.id, + active: currentId == null ? false : currentId === adaptation.id + }; + }); + } + /** + * Returns all available video tracks for a given Period, as an array of + * objects. + * + * @returns {Array.} + */ + ; - if (caught) { - // If the dispatched exception was caught by a catch block, - // then let that catch block handle the exception normally. - context.method = "next"; - context.arg = undefined; - } + _proto.getAvailableVideoTracks = function getAvailableVideoTracks(period) { + var periodItem = getPeriodItem(this._periods, period); + var videoInfos = periodItem != null ? periodItem.video : null; - return !! caught; - } + if (videoInfos == null) { + return []; + } - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - var record = entry.completion; + var chosenVideoAdaptation = this._videoChoiceMemory.get(period); - if (entry.tryLoc === "root") { - // Exception thrown outside of any try block that could handle - // it, so set the completion value of the entire function to - // throw the exception. - return handle("end"); - } + var currentId = chosenVideoAdaptation != null ? chosenVideoAdaptation.id : null; + return videoInfos.adaptations.map(function (adaptation) { + var formatted = { + id: adaptation.id, + active: currentId === null ? false : currentId === adaptation.id, + representations: adaptation.representations.map(parseVideoRepresentation) + }; - if (entry.tryLoc <= this.prev) { - var hasCatch = hasOwn.call(entry, "catchLoc"); - var hasFinally = hasOwn.call(entry, "finallyLoc"); + if (adaptation.isSignInterpreted === true) { + formatted.signInterpreted = true; + } - if (hasCatch && hasFinally) { - if (this.prev < entry.catchLoc) { - return handle(entry.catchLoc, true); - } else if (this.prev < entry.finallyLoc) { - return handle(entry.finallyLoc); - } + return formatted; + }); + } + /** + * Reset all audio tracks choices to corresponds to the current preferences. + */ + ; - } else if (hasCatch) { - if (this.prev < entry.catchLoc) { - return handle(entry.catchLoc, true); - } + _proto._applyAudioPreferences = function _applyAudioPreferences() { + // Remove all memorized choices and start over + this._audioChoiceMemory = new WeakMap(); - } else if (hasFinally) { - if (this.prev < entry.finallyLoc) { - return handle(entry.finallyLoc); - } + this._resetChosenAudioTracks(); + } + /** + * Reset all text tracks choices to corresponds to the current preferences. + */ + ; - } else { - throw new Error("try statement without catch or finally"); - } - } - } - }, + _proto._applyTextPreferences = function _applyTextPreferences() { + // Remove all memorized choices and start over + this._textChoiceMemory = new WeakMap(); - abrupt: function(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; - } - } + this._resetChosenTextTracks(); + } + /** + * Reset all video tracks choices to corresponds to the current preferences. + */ + ; - if (finallyEntry && - (type === "break" || - type === "continue") && - finallyEntry.tryLoc <= arg && - arg <= finallyEntry.finallyLoc) { - // Ignore the finally entry if control is not jumping to a - // location outside the try/catch block. - finallyEntry = null; - } + _proto._applyVideoPreferences = function _applyVideoPreferences() { + // Remove all memorized choices and start over + this._videoChoiceMemory = new WeakMap(); - var record = finallyEntry ? finallyEntry.completion : {}; - record.type = type; - record.arg = arg; + this._resetChosenVideoTracks(); + } + /** + * Choose again the best audio tracks for all current Periods. + * This is based on two things: + * 1. what was the track previously chosen for that Period (by checking + * `this._audioChoiceMemory`). + * 2. If no track were previously chosen or if it is not available anymore + * we check the audio preferences. + */ + ; - if (finallyEntry) { - this.method = "next"; - this.next = finallyEntry.finallyLoc; - return ContinueSentinel; - } + _proto._resetChosenAudioTracks = function _resetChosenAudioTracks() { + var _this = this; - return this.complete(record); - }, + var preferredAudioTracks = this._preferredAudioTracks; + var normalizedPref = normalizeAudioTracks(preferredAudioTracks); - complete: function(record, afterLoc) { - if (record.type === "throw") { - throw record.arg; + var recursiveUpdateAudioTrack = function recursiveUpdateAudioTrack(index) { + if (index >= _this._periods.length()) { + // we did all audio Periods, exit + return; } - if (record.type === "break" || - record.type === "continue") { - this.next = record.arg; - } else if (record.type === "return") { - this.rval = this.arg = record.arg; - this.method = "return"; - this.next = "end"; - } else if (record.type === "normal" && afterLoc) { - this.next = afterLoc; + var periodItem = _this._periods.get(index); + + if (periodItem.audio == null) { + // No audio choice for this period, check next one + recursiveUpdateAudioTrack(index + 1); + return; } - return ContinueSentinel; - }, + var period = periodItem.period, + audioItem = periodItem.audio; + var audioAdaptations = period.getPlayableAdaptations("audio"); - finish: function(finallyLoc) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - if (entry.finallyLoc === finallyLoc) { - this.complete(entry.completion, entry.afterLoc); - resetTryEntry(entry); - return ContinueSentinel; - } - } - }, + var chosenAudioAdaptation = _this._audioChoiceMemory.get(period); - "catch": function(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 (record.type === "throw") { - var thrown = record.arg; - resetTryEntry(entry); - } - return thrown; - } + if (chosenAudioAdaptation === null || chosenAudioAdaptation !== undefined && (0,array_includes/* default */.Z)(audioAdaptations, chosenAudioAdaptation)) { + // Already best audio for this Period, check next one + recursiveUpdateAudioTrack(index + 1); + return; } - // The context.catch method must only be called with a location - // argument that corresponds to a known catch block. - throw new Error("illegal catch attempt"); - }, + var optimalAdaptation = findFirstOptimalAudioAdaptation(audioAdaptations, normalizedPref); - delegateYield: function(iterable, resultName, nextLoc) { - this.delegate = { - iterator: values(iterable), - resultName: resultName, - nextLoc: nextLoc - }; + _this._audioChoiceMemory.set(period, optimalAdaptation); - if (this.method === "next") { - // Deliberately forget the last sent value so that we don't - // accidentally pass it on to the delegate. - this.arg = undefined; - } + audioItem.adaptation$.next(optimalAdaptation); // previous "next" call could have changed everything, start over - return ContinueSentinel; - } - }; + recursiveUpdateAudioTrack(0); + }; - // Regardless of whether this script is executing as a CommonJS module - // or not, return the runtime object so that we can declare the variable - // regeneratorRuntime in the outer scope, which allows this module to be - // injected easily by `bin/regenerator --include-runtime script.js`. - return exports; + recursiveUpdateAudioTrack(0); + } + /** + * Choose again the best text tracks for all current Periods. + * This is based on two things: + * 1. what was the track previously chosen for that Period (by checking + * `this._textChoiceMemory`). + * 2. If no track were previously chosen or if it is not available anymore + * we check the text preferences. + */ + ; -}( - // If this script is executing as a CommonJS module, use module.exports - // as the regeneratorRuntime namespace. Otherwise create a new empty - // object. Either way, the resulting object will be used to initialize - // the regeneratorRuntime variable at the top of this file. - true ? module.exports : 0 -)); + _proto._resetChosenTextTracks = function _resetChosenTextTracks() { + var _this2 = this; -try { - regeneratorRuntime = runtime; -} catch (accidentalStrictMode) { - // This module should not be running in strict mode, so the above - // assignment should always work unless something is misconfigured. Just - // in case runtime.js accidentally runs in strict mode, we can escape - // strict mode using a global Function call. This could conceivably fail - // if a Content Security Policy forbids using Function, but in that case - // the proper solution is to fix the accidental strict mode problem. If - // you've misconfigured your bundler to force strict mode and applied a - // CSP to forbid Function, and you're not willing to fix either of those - // problems, please detail your unique predicament in a GitHub issue. - Function("r", "regeneratorRuntime = r")(runtime); -} + var preferredTextTracks = this._preferredTextTracks; + var normalizedPref = normalizeTextTracks(preferredTextTracks); + var recursiveUpdateTextTrack = function recursiveUpdateTextTrack(index) { + if (index >= _this2._periods.length()) { + // we did all text Periods, exit + return; + } -/***/ }), + var periodItem = _this2._periods.get(index); -/***/ 2632: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (periodItem.text == null) { + // No text choice for this period, check next one + recursiveUpdateTextTrack(index + 1); + return; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "P": () => /* binding */ Notification -/* harmony export */ }); -/* unused harmony export NotificationKind */ -/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5631); -/* harmony import */ var _observable_of__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8170); -/* harmony import */ var _observable_throwError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4944); -/** PURE_IMPORTS_START _observable_empty,_observable_of,_observable_throwError PURE_IMPORTS_END */ + var period = periodItem.period, + textItem = periodItem.text; + var textAdaptations = period.getPlayableAdaptations("text"); + var chosenTextAdaptation = _this2._textChoiceMemory.get(period); + if (chosenTextAdaptation === null || chosenTextAdaptation !== undefined && (0,array_includes/* default */.Z)(textAdaptations, chosenTextAdaptation)) { + // Already best text for this Period, check next one + recursiveUpdateTextTrack(index + 1); + return; + } -var NotificationKind; -/*@__PURE__*/ (function (NotificationKind) { - NotificationKind["NEXT"] = "N"; - NotificationKind["ERROR"] = "E"; - NotificationKind["COMPLETE"] = "C"; -})(NotificationKind || (NotificationKind = {})); -var Notification = /*@__PURE__*/ (function () { - function Notification(kind, value, error) { - this.kind = kind; - this.value = value; - this.error = error; - this.hasValue = kind === 'N'; - } - Notification.prototype.observe = function (observer) { - switch (this.kind) { - case 'N': - return observer.next && observer.next(this.value); - case 'E': - return observer.error && observer.error(this.error); - case 'C': - return observer.complete && observer.complete(); - } - }; - Notification.prototype.do = function (next, error, complete) { - var kind = this.kind; - switch (kind) { - case 'N': - return next && next(this.value); - case 'E': - return error && error(this.error); - case 'C': - return complete && complete(); - } - }; - Notification.prototype.accept = function (nextOrObserver, error, complete) { - if (nextOrObserver && typeof nextOrObserver.next === 'function') { - return this.observe(nextOrObserver); - } - else { - return this.do(nextOrObserver, error, complete); - } - }; - Notification.prototype.toObservable = function () { - var kind = this.kind; - switch (kind) { - case 'N': - return (0,_observable_of__WEBPACK_IMPORTED_MODULE_0__.of)(this.value); - case 'E': - return (0,_observable_throwError__WEBPACK_IMPORTED_MODULE_1__/* .throwError */ ._)(this.error); - case 'C': - return (0,_observable_empty__WEBPACK_IMPORTED_MODULE_2__/* .empty */ .c)(); - } - throw new Error('unexpected notification kind value'); - }; - Notification.createNext = function (value) { - if (typeof value !== 'undefined') { - return new Notification('N', value); - } - return Notification.undefinedValueNotification; - }; - Notification.createError = function (err) { - return new Notification('E', undefined, err); - }; - Notification.createComplete = function () { - return Notification.completeNotification; - }; - Notification.completeNotification = new Notification('C'); - Notification.undefinedValueNotification = new Notification('N', undefined); - return Notification; -}()); + var optimalAdaptation = findFirstOptimalTextAdaptation(textAdaptations, normalizedPref); -//# sourceMappingURL=Notification.js.map + _this2._textChoiceMemory.set(period, optimalAdaptation); + textItem.adaptation$.next(optimalAdaptation); // previous "next" call could have changed everything, start over -/***/ }), + recursiveUpdateTextTrack(0); + }; -/***/ 4379: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + recursiveUpdateTextTrack(0); + } + /** + * Choose again the best video tracks for all current Periods. + * This is based on two things: + * 1. what was the track previously chosen for that Period (by checking + * `this._videoChoiceMemory`). + * 2. If no track were previously chosen or if it is not available anymore + * we check the video preferences. + */ + ; -"use strict"; + _proto._resetChosenVideoTracks = function _resetChosenVideoTracks() { + var _this3 = this; -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "y": () => /* binding */ Observable -}); + var preferredVideoTracks = this._preferredVideoTracks; -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscriber.js -var Subscriber = __webpack_require__(979); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/canReportError.js -/** PURE_IMPORTS_START _Subscriber PURE_IMPORTS_END */ + var recursiveUpdateVideoTrack = function recursiveUpdateVideoTrack(index) { + if (index >= _this3._periods.length()) { + // we did all video Periods, exit + return; + } -function canReportError(observer) { - while (observer) { - var _a = observer, closed_1 = _a.closed, destination = _a.destination, isStopped = _a.isStopped; - if (closed_1 || isStopped) { - return false; - } - else if (destination && destination instanceof Subscriber/* Subscriber */.L) { - observer = destination; - } - else { - observer = null; - } - } - return true; -} -//# sourceMappingURL=canReportError.js.map + var periodItem = _this3._periods.get(index); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/symbol/rxSubscriber.js -var rxSubscriber = __webpack_require__(3142); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observer.js -var Observer = __webpack_require__(2174); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/toSubscriber.js -/** PURE_IMPORTS_START _Subscriber,_symbol_rxSubscriber,_Observer PURE_IMPORTS_END */ + if (periodItem.video == null) { + // No video choice for this period, check next one + recursiveUpdateVideoTrack(index + 1); + return; + } + var period = periodItem.period, + videoItem = periodItem.video; + var videoAdaptations = period.getPlayableAdaptations("video"); + var chosenVideoAdaptation = _this3._videoChoiceMemory.get(period); -function toSubscriber(nextOrObserver, error, complete) { - if (nextOrObserver) { - if (nextOrObserver instanceof Subscriber/* Subscriber */.L) { - return nextOrObserver; - } - if (nextOrObserver[rxSubscriber/* rxSubscriber */.b]) { - return nextOrObserver[rxSubscriber/* rxSubscriber */.b](); - } - } - if (!nextOrObserver && !error && !complete) { - return new Subscriber/* Subscriber */.L(Observer/* empty */.c); - } - return new Subscriber/* Subscriber */.L(nextOrObserver, error, complete); -} -//# sourceMappingURL=toSubscriber.js.map + if (chosenVideoAdaptation === null || chosenVideoAdaptation !== undefined && (0,array_includes/* default */.Z)(videoAdaptations, chosenVideoAdaptation)) { + // Already best video for this Period, check next one + recursiveUpdateVideoTrack(index + 1); + return; + } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/symbol/observable.js -var observable = __webpack_require__(5050); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/identity.js -var identity = __webpack_require__(3608); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/pipe.js -/** PURE_IMPORTS_START _identity PURE_IMPORTS_END */ + var optimalAdaptation = findFirstOptimalVideoAdaptation(videoAdaptations, preferredVideoTracks); -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); + _this3._videoChoiceMemory.set(period, optimalAdaptation); + + videoItem.adaptation$.next(optimalAdaptation); // previous "next" call could have changed everything, start over + + recursiveUpdateVideoTrack(0); }; -} -//# sourceMappingURL=pipe.js.map -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/config.js -var config = __webpack_require__(150); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js -/** PURE_IMPORTS_START _util_canReportError,_util_toSubscriber,_symbol_observable,_util_pipe,_config PURE_IMPORTS_END */ + recursiveUpdateVideoTrack(0); + }; + return TrackChoiceManager; +}(); +/** + * Create a function allowing to compare audio Adaptations with a given + * `preferredAudioTrack` preference to see if they match. + * + * This function is curried to be easily and optimally used in a loop context. + * + * @param {Object} preferredAudioTrack - The audio track preference you want to + * compare audio Adaptations to. + * @returns {Function} - Function taking in argument an audio Adaptation and + * returning `true` if it matches the `preferredAudioTrack` preference (and + * `false` otherwise. + */ -var Observable = /*@__PURE__*/ (function () { - function Observable(subscribe) { - this._isScalar = false; - if (subscribe) { - this._subscribe = subscribe; - } - } - 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 operator = this.operator; - var sink = toSubscriber(observerOrNext, error, complete); - if (operator) { - sink.add(operator.call(sink, this.source)); - } - else { - sink.add(this.source || (config/* config.useDeprecatedSynchronousErrorHandling */.v.useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ? - this._subscribe(sink) : - this._trySubscribe(sink)); - } - if (config/* config.useDeprecatedSynchronousErrorHandling */.v.useDeprecatedSynchronousErrorHandling) { - if (sink.syncErrorThrowable) { - sink.syncErrorThrowable = false; - if (sink.syncErrorThrown) { - throw sink.syncErrorValue; - } - } - } - return sink; - }; - Observable.prototype._trySubscribe = function (sink) { - try { - return this._subscribe(sink); - } - catch (err) { - if (config/* config.useDeprecatedSynchronousErrorHandling */.v.useDeprecatedSynchronousErrorHandling) { - sink.syncErrorThrown = true; - sink.syncErrorValue = err; - } - if (canReportError(sink)) { - sink.error(err); - } - else { - console.warn(err); - } - } - }; - Observable.prototype.forEach = function (next, promiseCtor) { - var _this = this; - promiseCtor = getPromiseCtor(promiseCtor); - return new promiseCtor(function (resolve, reject) { - var subscription; - subscription = _this.subscribe(function (value) { - try { - next(value); - } - catch (err) { - reject(err); - if (subscription) { - subscription.unsubscribe(); - } - } - }, reject, resolve); - }); - }; - Observable.prototype._subscribe = function (subscriber) { - var source = this.source; - return source && source.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]; - } - if (operations.length === 0) { - return this; - } - 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); }); - }); - }; - Observable.create = function (subscribe) { - return new Observable(subscribe); - }; - return Observable; -}()); +function createAudioPreferenceMatcher(preferredAudioTrack) { + /** + * Compares an audio Adaptation to the given `preferredAudioTrack` preference. + * Returns `true` if it matches, false otherwise. + * @param {Object} audioAdaptation + * @returns {boolean} + */ + return function matchAudioPreference(audioAdaptation) { + var _a; -function getPromiseCtor(promiseCtor) { - if (!promiseCtor) { - promiseCtor = config/* config.Promise */.v.Promise || Promise; - } - if (!promiseCtor) { - throw new Error('no Promise impl found'); + if (preferredAudioTrack.normalized !== undefined) { + var language = (_a = audioAdaptation.normalizedLanguage) !== null && _a !== void 0 ? _a : ""; + + if (language !== preferredAudioTrack.normalized) { + return false; + } } - return promiseCtor; -} -//# sourceMappingURL=Observable.js.map + if (preferredAudioTrack.audioDescription !== undefined) { + if (preferredAudioTrack.audioDescription) { + if (audioAdaptation.isAudioDescription !== true) { + return false; + } + } else if (audioAdaptation.isAudioDescription === true) { + return false; + } + } -/***/ }), + if (preferredAudioTrack.codec === undefined) { + return true; + } -/***/ 2174: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var regxp = preferredAudioTrack.codec.test; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "c": () => /* binding */ empty -/* harmony export */ }); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(150); -/* harmony import */ var _util_hostReportError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1644); -/** PURE_IMPORTS_START _config,_util_hostReportError PURE_IMPORTS_END */ + var codecTestingFn = function codecTestingFn(rep) { + return rep.codec !== undefined && regxp.test(rep.codec); + }; + if (preferredAudioTrack.codec.all) { + return audioAdaptation.representations.every(codecTestingFn); + } -var empty = { - closed: true, - next: function (value) { }, - error: function (err) { - if (_config__WEBPACK_IMPORTED_MODULE_0__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling) { - throw err; - } - else { - (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_1__/* .hostReportError */ .z)(err); - } - }, - complete: function () { } -}; -//# sourceMappingURL=Observer.js.map + return audioAdaptation.representations.some(codecTestingFn); + }; +} +/** + * Find an optimal audio adaptation given their list and the array of preferred + * audio tracks sorted from the most preferred to the least preferred. + * + * `null` if the most optimal audio adaptation is no audio adaptation. + * @param {Array.} audioAdaptations + * @param {Array.} preferredAudioTracks + * @returns {Adaptation|null} + */ -/***/ }), +function findFirstOptimalAudioAdaptation(audioAdaptations, preferredAudioTracks) { + if (audioAdaptations.length === 0) { + return null; + } -/***/ 2039: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + for (var i = 0; i < preferredAudioTracks.length; i++) { + var preferredAudioTrack = preferredAudioTracks[i]; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "L": () => /* binding */ OuterSubscriber -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + if (preferredAudioTrack === null) { + return null; + } + var matchPreferredAudio = createAudioPreferenceMatcher(preferredAudioTrack); + var foundAdaptation = (0,array_find/* default */.Z)(audioAdaptations, matchPreferredAudio); -var OuterSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(OuterSubscriber, _super); - function OuterSubscriber() { - return _super !== null && _super.apply(this, arguments) || this; + if (foundAdaptation !== undefined) { + return foundAdaptation; } - OuterSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.destination.next(innerValue); - }; - OuterSubscriber.prototype.notifyError = function (error, innerSub) { - this.destination.error(error); - }; - OuterSubscriber.prototype.notifyComplete = function (innerSub) { - this.destination.complete(); - }; - return OuterSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); + } // no optimal adaptation, just return the first one -//# sourceMappingURL=OuterSubscriber.js.map + return audioAdaptations[0]; +} +/** + * Create a function allowing to compare text Adaptations with a given + * `preferredTextTrack` preference to see if they match. + * + * This function is curried to be easily and optimally used in a loop context. + * + * @param {Object} preferredTextTrack - The text track preference you want to + * compare text Adaptations to. + * @returns {Function} - Function taking in argument a text Adaptation and + * returning `true` if it matches the `preferredTextTrack` preference (and + * `false` otherwise. + */ -/***/ }), -/***/ 2135: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { +function createTextPreferenceMatcher(preferredTextTrack) { + /** + * Compares a text Adaptation to the given `preferredTextTrack` preference. + * Returns `true` if it matches, false otherwise. + * @param {Object} textAdaptation + * @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); + }; +} +/** + * Find an optimal text adaptation given their list and the array of preferred + * text tracks sorted from the most preferred to the least preferred. + * + * `null` if the most optimal text adaptation is no text adaptation. + * @param {Array.} textAdaptations + * @param {Array.} preferredTextTracks + * @returns {Adaptation|null} + */ -"use strict"; -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "t": () => /* binding */ ReplaySubject -}); +function findFirstOptimalTextAdaptation(textAdaptations, preferredTextTracks) { + if (textAdaptations.length === 0) { + return null; + } -// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js -var tslib_es6 = __webpack_require__(655); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subject.js -var Subject = __webpack_require__(211); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsyncAction.js + 1 modules -var AsyncAction = __webpack_require__(6114); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/QueueAction.js -/** PURE_IMPORTS_START tslib,_AsyncAction PURE_IMPORTS_END */ + for (var i = 0; i < preferredTextTracks.length; i++) { + var preferredTextTrack = preferredTextTracks[i]; + if (preferredTextTrack === null) { + return null; + } -var QueueAction = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(QueueAction, _super); - function QueueAction(scheduler, work) { - var _this = _super.call(this, scheduler, work) || this; - _this.scheduler = scheduler; - _this.work = work; - return _this; + var matchPreferredText = createTextPreferenceMatcher(preferredTextTrack); + var foundAdaptation = (0,array_find/* default */.Z)(textAdaptations, matchPreferredText); + + if (foundAdaptation !== undefined) { + return foundAdaptation; } - QueueAction.prototype.schedule = function (state, delay) { - if (delay === void 0) { - delay = 0; - } - if (delay > 0) { - return _super.prototype.schedule.call(this, state, delay); - } - this.delay = delay; - this.state = state; - this.scheduler.flush(this); - return this; - }; - QueueAction.prototype.execute = function (state, delay) { - return (delay > 0 || this.closed) ? - _super.prototype.execute.call(this, state, delay) : - this._execute(state, delay); - }; - QueueAction.prototype.requestAsyncId = function (scheduler, id, delay) { - if (delay === void 0) { - delay = 0; - } - if ((delay !== null && delay > 0) || (delay === null && this.delay > 0)) { - return _super.prototype.requestAsyncId.call(this, scheduler, id, delay); - } - return scheduler.flush(this); - }; - return QueueAction; -}(AsyncAction/* AsyncAction */.o)); + } // no optimal adaptation -//# sourceMappingURL=QueueAction.js.map -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsyncScheduler.js + 1 modules -var AsyncScheduler = __webpack_require__(2980); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/QueueScheduler.js -/** PURE_IMPORTS_START tslib,_AsyncScheduler PURE_IMPORTS_END */ + return null; +} +/** + * Create a function allowing to compare video Adaptations with a given + * `preferredVideoTrack` preference to see if they match. + * + * This function is curried to be easily and optimally used in a loop context. + * + * @param {Object} preferredVideoTrack - The video track preference you want to + * compare video Adaptations to. + * @returns {Function} - Function taking in argument a video Adaptation and + * returning `true` if it matches the `preferredVideoTrack` preference (and + * `false` otherwise. + */ -var QueueScheduler = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(QueueScheduler, _super); - function QueueScheduler() { - return _super !== null && _super.apply(this, arguments) || this; +function createVideoPreferenceMatcher(preferredVideoTrack) { + /** + * Compares a video Adaptation to the given `preferredVideoTrack` preference. + * Returns `true` if it matches, false otherwise. + * @param {Object} videoAdaptation + * @returns {boolean} + */ + return function matchVideoPreference(videoAdaptation) { + if (preferredVideoTrack.signInterpreted !== undefined && preferredVideoTrack.signInterpreted !== videoAdaptation.isSignInterpreted) { + return false; } - return QueueScheduler; -}(AsyncScheduler/* AsyncScheduler */.v)); -//# sourceMappingURL=QueueScheduler.js.map + if (preferredVideoTrack.codec === undefined) { + return true; + } -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/queue.js -/** PURE_IMPORTS_START _QueueAction,_QueueScheduler PURE_IMPORTS_END */ + var regxp = preferredVideoTrack.codec.test; + var codecTestingFn = function codecTestingFn(rep) { + return rep.codec !== undefined && regxp.test(rep.codec); + }; -var queueScheduler = /*@__PURE__*/ new QueueScheduler(QueueAction); -var queue = queueScheduler; -//# sourceMappingURL=queue.js.map + if (preferredVideoTrack.codec.all) { + return videoAdaptation.representations.every(codecTestingFn); + } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscription.js + 1 modules -var Subscription = __webpack_require__(3884); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscriber.js -var Subscriber = __webpack_require__(979); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Notification.js -var Notification = __webpack_require__(2632); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/observeOn.js -/** PURE_IMPORTS_START tslib,_Subscriber,_Notification PURE_IMPORTS_END */ + return videoAdaptation.representations.some(codecTestingFn); + }; +} +/** + * Find an optimal video adaptation given their list and the array of preferred + * video tracks sorted from the most preferred to the least preferred. + * + * `null` if the most optimal video adaptation is no video adaptation. + * @param {Array.} videoAdaptations + * @param {Array.} preferredvideoTracks + * @returns {Adaptation|null} + */ +function findFirstOptimalVideoAdaptation(videoAdaptations, preferredVideoTracks) { + if (videoAdaptations.length === 0) { + return null; + } -function observeOn(scheduler, delay) { - if (delay === void 0) { - delay = 0; - } - return function observeOnOperatorFunction(source) { - return source.lift(new ObserveOnOperator(scheduler, delay)); - }; -} -var ObserveOnOperator = /*@__PURE__*/ ((/* unused pure expression or super */ null && (function () { - function ObserveOnOperator(scheduler, delay) { - if (delay === void 0) { - delay = 0; - } - this.scheduler = scheduler; - this.delay = delay; - } - ObserveOnOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ObserveOnSubscriber(subscriber, this.scheduler, this.delay)); - }; - return ObserveOnOperator; -}()))); + for (var i = 0; i < preferredVideoTracks.length; i++) { + var preferredVideoTrack = preferredVideoTracks[i]; -var ObserveOnSubscriber = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(ObserveOnSubscriber, _super); - function ObserveOnSubscriber(destination, scheduler, delay) { - if (delay === void 0) { - delay = 0; - } - var _this = _super.call(this, destination) || this; - _this.scheduler = scheduler; - _this.delay = delay; - return _this; + if (preferredVideoTrack === null) { + return null; } - ObserveOnSubscriber.dispatch = function (arg) { - var notification = arg.notification, destination = arg.destination; - notification.observe(destination); - this.unsubscribe(); - }; - ObserveOnSubscriber.prototype.scheduleMessage = function (notification) { - var destination = this.destination; - destination.add(this.scheduler.schedule(ObserveOnSubscriber.dispatch, this.delay, new ObserveOnMessage(notification, this.destination))); - }; - ObserveOnSubscriber.prototype._next = function (value) { - this.scheduleMessage(Notification/* Notification.createNext */.P.createNext(value)); - }; - ObserveOnSubscriber.prototype._error = function (err) { - this.scheduleMessage(Notification/* Notification.createError */.P.createError(err)); - this.unsubscribe(); - }; - ObserveOnSubscriber.prototype._complete = function () { - this.scheduleMessage(Notification/* Notification.createComplete */.P.createComplete()); - this.unsubscribe(); - }; - return ObserveOnSubscriber; -}(Subscriber/* Subscriber */.L)); -var ObserveOnMessage = /*@__PURE__*/ (function () { - function ObserveOnMessage(notification, destination) { - this.notification = notification; - this.destination = destination; - } - return ObserveOnMessage; -}()); + var matchPreferredVideo = createVideoPreferenceMatcher(preferredVideoTrack); + var foundAdaptation = (0,array_find/* default */.Z)(videoAdaptations, matchPreferredVideo); -//# sourceMappingURL=observeOn.js.map + if (foundAdaptation !== undefined) { + return foundAdaptation; + } + } // no optimal adaptation, just return the first one -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/ObjectUnsubscribedError.js -var ObjectUnsubscribedError = __webpack_require__(1016); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/SubjectSubscription.js -var SubjectSubscription = __webpack_require__(8253); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/ReplaySubject.js -/** PURE_IMPORTS_START tslib,_Subject,_scheduler_queue,_Subscription,_operators_observeOn,_util_ObjectUnsubscribedError,_SubjectSubscription PURE_IMPORTS_END */ + return videoAdaptations[0]; +} +/** + * Returns the index of the given `period` in the given `periods` + * SortedList. + * Returns `undefined` if that `period` is not found. + * @param {Object} periods + * @param {Object} period + * @returns {number|undefined} + */ +function findPeriodIndex(periods, period) { + for (var i = 0; i < periods.length(); i++) { + var periodI = periods.get(i); + if (periodI.period.id === period.id) { + return i; + } + } +} +/** + * Returns element in the given `periods` SortedList that corresponds to the + * `period` given. + * Returns `undefined` if that `period` is not found. + * @param {Object} periods + * @param {Object} period + * @returns {Object|undefined} + */ +function getPeriodItem(periods, period) { + for (var i = 0; i < periods.length(); i++) { + var periodI = periods.get(i); -var ReplaySubject = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(ReplaySubject, _super); - function ReplaySubject(bufferSize, windowTime, scheduler) { - if (bufferSize === void 0) { - bufferSize = Number.POSITIVE_INFINITY; - } - if (windowTime === void 0) { - windowTime = Number.POSITIVE_INFINITY; - } - var _this = _super.call(this) || this; - _this.scheduler = scheduler; - _this._events = []; - _this._infiniteTimeWindow = false; - _this._bufferSize = bufferSize < 1 ? 1 : bufferSize; - _this._windowTime = windowTime < 1 ? 1 : windowTime; - if (windowTime === Number.POSITIVE_INFINITY) { - _this._infiniteTimeWindow = true; - _this.next = _this.nextInfiniteTimeWindow; - } - else { - _this.next = _this.nextTimeWindow; - } - return _this; + if (periodI.period.id === period.id) { + return periodI; } - ReplaySubject.prototype.nextInfiniteTimeWindow = function (value) { - if (!this.isStopped) { - var _events = this._events; - _events.push(value); - if (_events.length > this._bufferSize) { - _events.shift(); - } - } - _super.prototype.next.call(this, value); - }; - ReplaySubject.prototype.nextTimeWindow = function (value) { - if (!this.isStopped) { - this._events.push(new ReplayEvent(this._getNow(), value)); - this._trimBufferThenGetEvents(); - } - _super.prototype.next.call(this, value); - }; - ReplaySubject.prototype._subscribe = function (subscriber) { - var _infiniteTimeWindow = this._infiniteTimeWindow; - var _events = _infiniteTimeWindow ? this._events : this._trimBufferThenGetEvents(); - var scheduler = this.scheduler; - var len = _events.length; - var subscription; - if (this.closed) { - throw new ObjectUnsubscribedError/* ObjectUnsubscribedError */.N(); - } - else if (this.isStopped || this.hasError) { - subscription = Subscription/* Subscription.EMPTY */.w.EMPTY; - } - else { - this.observers.push(subscriber); - subscription = new SubjectSubscription/* SubjectSubscription */.W(this, subscriber); - } - if (scheduler) { - subscriber.add(subscriber = new ObserveOnSubscriber(subscriber, scheduler)); - } - if (_infiniteTimeWindow) { - for (var i = 0; i < len && !subscriber.closed; i++) { - subscriber.next(_events[i]); - } - } - else { - for (var i = 0; i < len && !subscriber.closed; i++) { - subscriber.next(_events[i].value); - } - } - if (this.hasError) { - subscriber.error(this.thrownError); - } - else if (this.isStopped) { - subscriber.complete(); - } - return subscription; - }; - ReplaySubject.prototype._getNow = function () { - return (this.scheduler || queue).now(); - }; - ReplaySubject.prototype._trimBufferThenGetEvents = function () { - var now = this._getNow(); - var _bufferSize = this._bufferSize; - var _windowTime = this._windowTime; - var _events = this._events; - var eventsCount = _events.length; - var spliceCount = 0; - while (spliceCount < eventsCount) { - if ((now - _events[spliceCount].time) < _windowTime) { - break; - } - spliceCount++; - } - if (eventsCount > _bufferSize) { - spliceCount = Math.max(spliceCount, eventsCount - _bufferSize); - } - if (spliceCount > 0) { - _events.splice(0, spliceCount); - } - return _events; - }; - return ReplaySubject; -}(Subject/* Subject */.xQ)); + } +} +/** + * Parse video Representation into a ITMVideoRepresentation. + * @param {Object} representation + * @returns {Object} + */ -var ReplayEvent = /*@__PURE__*/ (function () { - function ReplayEvent(time, value) { - this.time = time; - this.value = value; - } - return ReplayEvent; -}()); -//# sourceMappingURL=ReplaySubject.js.map + +function parseVideoRepresentation(_ref4) { + var id = _ref4.id, + bitrate = _ref4.bitrate, + frameRate = _ref4.frameRate, + width = _ref4.width, + height = _ref4.height, + codec = _ref4.codec; + return { + id: id, + bitrate: bitrate, + frameRate: frameRate, + width: width, + height: height, + codec: codec + }; +} +/** + * Parse audio Representation into a ITMAudioRepresentation. + * @param {Object} representation + * @returns {Object} + */ -/***/ }), +function parseAudioRepresentation(_ref5) { + var id = _ref5.id, + bitrate = _ref5.bitrate, + codec = _ref5.codec; + return { + id: id, + bitrate: bitrate, + codec: codec + }; +} +;// CONCATENATED MODULE: ./src/core/api/public_api.ts -/***/ 211: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Yc": () => /* binding */ SubjectSubscriber, -/* harmony export */ "xQ": () => /* binding */ Subject -/* harmony export */ }); -/* unused harmony export AnonymousSubject */ -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(4379); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3884); -/* harmony import */ var _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(1016); -/* harmony import */ var _SubjectSubscription__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8253); -/* harmony import */ var _internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3142); -/** PURE_IMPORTS_START tslib,_Observable,_Subscriber,_Subscription,_util_ObjectUnsubscribedError,_SubjectSubscription,_internal_symbol_rxSubscriber PURE_IMPORTS_END */ + +/** + * 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 file defines the public API for the RxPlayer. + * It also starts the different sub-parts of the player on various API calls. + */ + +/* eslint-disable-next-line max-len */ -var SubjectSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(SubjectSubscriber, _super); - function SubjectSubscriber(destination) { - var _this = _super.call(this, destination) || this; - _this.destination = destination; - return _this; - } - return SubjectSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); -var Subject = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(Subject, _super); - function Subject() { - var _this = _super.call(this) || this; - _this.observers = []; - _this.closed = false; - _this.isStopped = false; - _this.hasError = false; - _this.thrownError = null; - return _this; - } - Subject.prototype[_internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_2__/* .rxSubscriber */ .b] = function () { - return new SubjectSubscriber(this); - }; - Subject.prototype.lift = function (operator) { - var subject = new AnonymousSubject(this, this); - subject.operator = operator; - return subject; - }; - Subject.prototype.next = function (value) { - if (this.closed) { - throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__/* .ObjectUnsubscribedError */ .N(); - } - if (!this.isStopped) { - var observers = this.observers; - var len = observers.length; - var copy = observers.slice(); - for (var i = 0; i < len; i++) { - copy[i].next(value); - } - } - }; - Subject.prototype.error = function (err) { - if (this.closed) { - throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__/* .ObjectUnsubscribedError */ .N(); - } - this.hasError = true; - this.thrownError = err; - this.isStopped = true; - var observers = this.observers; - var len = observers.length; - var copy = observers.slice(); - for (var i = 0; i < len; i++) { - copy[i].error(err); - } - this.observers.length = 0; - }; - Subject.prototype.complete = function () { - if (this.closed) { - throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__/* .ObjectUnsubscribedError */ .N(); - } - this.isStopped = true; - var observers = this.observers; - var len = observers.length; - var copy = observers.slice(); - for (var i = 0; i < len; i++) { - copy[i].complete(); - } - this.observers.length = 0; - }; - Subject.prototype.unsubscribe = function () { - this.isStopped = true; - this.closed = true; - this.observers = null; - }; - Subject.prototype._trySubscribe = function (subscriber) { - if (this.closed) { - throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__/* .ObjectUnsubscribedError */ .N(); - } - else { - return _super.prototype._trySubscribe.call(this, subscriber); - } - }; - Subject.prototype._subscribe = function (subscriber) { - if (this.closed) { - throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_3__/* .ObjectUnsubscribedError */ .N(); - } - else if (this.hasError) { - subscriber.error(this.thrownError); - return _Subscription__WEBPACK_IMPORTED_MODULE_4__/* .Subscription.EMPTY */ .w.EMPTY; - } - else if (this.isStopped) { - subscriber.complete(); - return _Subscription__WEBPACK_IMPORTED_MODULE_4__/* .Subscription.EMPTY */ .w.EMPTY; - } - else { - this.observers.push(subscriber); - return new _SubjectSubscription__WEBPACK_IMPORTED_MODULE_5__/* .SubjectSubscription */ .W(this, subscriber); - } - }; - Subject.prototype.asObservable = function () { - var observable = new _Observable__WEBPACK_IMPORTED_MODULE_6__/* .Observable */ .y(); - observable.source = this; - return observable; - }; - Subject.create = function (destination, source) { - return new AnonymousSubject(destination, source); - }; - return Subject; -}(_Observable__WEBPACK_IMPORTED_MODULE_6__/* .Observable */ .y)); -var AnonymousSubject = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__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 destination = this.destination; - if (destination && destination.next) { - destination.next(value); - } - }; - AnonymousSubject.prototype.error = function (err) { - var destination = this.destination; - if (destination && destination.error) { - this.destination.error(err); - } - }; - AnonymousSubject.prototype.complete = function () { - var destination = this.destination; - if (destination && destination.complete) { - this.destination.complete(); - } - }; - AnonymousSubject.prototype._subscribe = function (subscriber) { - var source = this.source; - if (source) { - return this.source.subscribe(subscriber); - } - else { - return _Subscription__WEBPACK_IMPORTED_MODULE_4__/* .Subscription.EMPTY */ .w.EMPTY; - } - }; - return AnonymousSubject; -}(Subject)); -//# sourceMappingURL=Subject.js.map -/***/ }), -/***/ 8253: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "W": () => /* binding */ SubjectSubscription -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3884); -/** PURE_IMPORTS_START tslib,_Subscription PURE_IMPORTS_END */ -var SubjectSubscription = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(SubjectSubscription, _super); - function SubjectSubscription(subject, subscriber) { - var _this = _super.call(this) || this; - _this.subject = subject; - _this.subscriber = subscriber; - _this.closed = false; - return _this; - } - SubjectSubscription.prototype.unsubscribe = function () { - if (this.closed) { - return; - } - this.closed = true; - var subject = this.subject; - var observers = subject.observers; - this.subject = null; - if (!observers || observers.length === 0 || subject.isStopped || subject.closed) { - return; - } - var subscriberIndex = observers.indexOf(this.subscriber); - if (subscriberIndex !== -1) { - observers.splice(subscriberIndex, 1); - } - }; - return SubjectSubscription; -}(_Subscription__WEBPACK_IMPORTED_MODULE_1__/* .Subscription */ .w)); -//# sourceMappingURL=SubjectSubscription.js.map -/***/ }), -/***/ 979: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "L": () => /* binding */ Subscriber -/* harmony export */ }); -/* unused harmony export SafeSubscriber */ -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4156); -/* harmony import */ var _Observer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2174); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3884); -/* harmony import */ var _internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3142); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(150); -/* harmony import */ var _util_hostReportError__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(1644); -/** PURE_IMPORTS_START tslib,_util_isFunction,_Observer,_Subscription,_internal_symbol_rxSubscriber,_config,_util_hostReportError PURE_IMPORTS_END */ +/* eslint-disable @typescript-eslint/naming-convention */ +var DEFAULT_UNMUTED_VOLUME = config/* default.DEFAULT_UNMUTED_VOLUME */.Z.DEFAULT_UNMUTED_VOLUME; +var isActive = event_listeners/* isActive */.zh, + isVideoVisible = event_listeners/* isVideoVisible */._K, + onEnded$ = event_listeners/* onEnded$ */.C1, + onFullscreenChange$ = event_listeners/* onFullscreenChange$ */.Q1, + onPlayPause$ = event_listeners/* onPlayPause$ */.Qt, + onPictureInPictureEvent$ = event_listeners/* onPictureInPictureEvent$ */.yj, + onSeeking$ = event_listeners/* onSeeking$ */.d5, + onTextTrackChanges$ = event_listeners/* onTextTrackChanges$ */.UA, + videoWidth$ = event_listeners/* videoWidth$ */.$x; +/** + * @class Player + * @extends EventEmitter + */ +var Player = /*#__PURE__*/function (_EventEmitter) { + (0,inheritsLoose/* default */.Z)(Player, _EventEmitter); -var Subscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(Subscriber, _super); - function Subscriber(destinationOrNext, error, complete) { - var _this = _super.call(this) || this; - _this.syncErrorValue = null; - _this.syncErrorThrown = false; - _this.syncErrorThrowable = false; - _this.isStopped = false; - switch (arguments.length) { - case 0: - _this.destination = _Observer__WEBPACK_IMPORTED_MODULE_1__/* .empty */ .c; - break; - case 1: - if (!destinationOrNext) { - _this.destination = _Observer__WEBPACK_IMPORTED_MODULE_1__/* .empty */ .c; - break; - } - if (typeof destinationOrNext === 'object') { - if (destinationOrNext instanceof Subscriber) { - _this.syncErrorThrowable = destinationOrNext.syncErrorThrowable; - _this.destination = destinationOrNext; - destinationOrNext.add(_this); - } - else { - _this.syncErrorThrowable = true; - _this.destination = new SafeSubscriber(_this, destinationOrNext); - } - break; - } - default: - _this.syncErrorThrowable = true; - _this.destination = new SafeSubscriber(_this, destinationOrNext, error, complete); - break; - } - return _this; - } - Subscriber.prototype[_internal_symbol_rxSubscriber__WEBPACK_IMPORTED_MODULE_2__/* .rxSubscriber */ .b] = function () { return this; }; - Subscriber.create = function (next, error, complete) { - var subscriber = new Subscriber(next, error, complete); - subscriber.syncErrorThrowable = false; - return subscriber; - }; - Subscriber.prototype.next = function (value) { - if (!this.isStopped) { - this._next(value); - } - }; - Subscriber.prototype.error = function (err) { - if (!this.isStopped) { - this.isStopped = true; - this._error(err); - } - }; - Subscriber.prototype.complete = function () { - if (!this.isStopped) { - this.isStopped = true; - this._complete(); - } - }; - Subscriber.prototype.unsubscribe = function () { - if (this.closed) { - return; - } - this.isStopped = true; - _super.prototype.unsubscribe.call(this); - }; - Subscriber.prototype._next = function (value) { - this.destination.next(value); - }; - Subscriber.prototype._error = function (err) { - this.destination.error(err); - this.unsubscribe(); - }; - Subscriber.prototype._complete = function () { - this.destination.complete(); - this.unsubscribe(); - }; - Subscriber.prototype._unsubscribeAndRecycle = function () { - var _parentOrParents = this._parentOrParents; - this._parentOrParents = null; - this.unsubscribe(); - this.closed = false; - this.isStopped = false; - this._parentOrParents = _parentOrParents; - return this; - }; - return Subscriber; -}(_Subscription__WEBPACK_IMPORTED_MODULE_3__/* .Subscription */ .w)); + /** + * @constructor + * @param {Object} options + */ + function Player(options) { + var _this; -var SafeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(SafeSubscriber, _super); - function SafeSubscriber(_parentSubscriber, observerOrNext, error, complete) { - var _this = _super.call(this) || this; - _this._parentSubscriber = _parentSubscriber; - var next; - var context = _this; - if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_4__/* .isFunction */ .m)(observerOrNext)) { - next = observerOrNext; - } - else if (observerOrNext) { - next = observerOrNext.next; - error = observerOrNext.error; - complete = observerOrNext.complete; - if (observerOrNext !== _Observer__WEBPACK_IMPORTED_MODULE_1__/* .empty */ .c) { - context = Object.create(observerOrNext); - if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_4__/* .isFunction */ .m)(context.unsubscribe)) { - _this.add(context.unsubscribe.bind(context)); - } - context.unsubscribe = _this.unsubscribe.bind(_this); - } - } - _this._context = context; - _this._next = next; - _this._error = error; - _this._complete = complete; - return _this; + if (options === void 0) { + options = {}; } - SafeSubscriber.prototype.next = function (value) { - if (!this.isStopped && this._next) { - var _parentSubscriber = this._parentSubscriber; - if (!_config__WEBPACK_IMPORTED_MODULE_5__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { - this.__tryOrUnsub(this._next, value); - } - else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) { - this.unsubscribe(); - } - } - }; - SafeSubscriber.prototype.error = function (err) { - if (!this.isStopped) { - var _parentSubscriber = this._parentSubscriber; - var useDeprecatedSynchronousErrorHandling = _config__WEBPACK_IMPORTED_MODULE_5__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling; - if (this._error) { - if (!useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { - this.__tryOrUnsub(this._error, err); - this.unsubscribe(); - } - else { - this.__tryOrSetError(_parentSubscriber, this._error, err); - this.unsubscribe(); - } - } - else if (!_parentSubscriber.syncErrorThrowable) { - this.unsubscribe(); - if (useDeprecatedSynchronousErrorHandling) { - throw err; - } - (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__/* .hostReportError */ .z)(err); - } - else { - if (useDeprecatedSynchronousErrorHandling) { - _parentSubscriber.syncErrorValue = err; - _parentSubscriber.syncErrorThrown = true; - } - else { - (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__/* .hostReportError */ .z)(err); - } - this.unsubscribe(); - } - } - }; - SafeSubscriber.prototype.complete = function () { - var _this = this; - if (!this.isStopped) { - var _parentSubscriber = this._parentSubscriber; - if (this._complete) { - var wrappedComplete = function () { return _this._complete.call(_this._context); }; - if (!_config__WEBPACK_IMPORTED_MODULE_5__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { - this.__tryOrUnsub(wrappedComplete); - this.unsubscribe(); - } - else { - this.__tryOrSetError(_parentSubscriber, wrappedComplete); - this.unsubscribe(); - } - } - else { - this.unsubscribe(); - } - } - }; - SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) { - try { - fn.call(this._context, value); - } - catch (err) { - this.unsubscribe(); - if (_config__WEBPACK_IMPORTED_MODULE_5__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling) { - throw err; - } - else { - (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__/* .hostReportError */ .z)(err); - } - } - }; - SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) { - if (!_config__WEBPACK_IMPORTED_MODULE_5__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling) { - throw new Error('bad call'); - } - try { - fn.call(this._context, value); - } - catch (err) { - if (_config__WEBPACK_IMPORTED_MODULE_5__/* .config.useDeprecatedSynchronousErrorHandling */ .v.useDeprecatedSynchronousErrorHandling) { - parent.syncErrorValue = err; - parent.syncErrorThrown = true; - return true; - } - else { - (0,_util_hostReportError__WEBPACK_IMPORTED_MODULE_6__/* .hostReportError */ .z)(err); - return true; - } - } + + _this = _EventEmitter.call(this) || this; + + var _parseConstructorOpti = parseConstructorOptions(options), + initialAudioBitrate = _parseConstructorOpti.initialAudioBitrate, + initialVideoBitrate = _parseConstructorOpti.initialVideoBitrate, + limitVideoWidth = _parseConstructorOpti.limitVideoWidth, + minAudioBitrate = _parseConstructorOpti.minAudioBitrate, + minVideoBitrate = _parseConstructorOpti.minVideoBitrate, + maxAudioBitrate = _parseConstructorOpti.maxAudioBitrate, + maxBufferAhead = _parseConstructorOpti.maxBufferAhead, + maxBufferBehind = _parseConstructorOpti.maxBufferBehind, + maxVideoBitrate = _parseConstructorOpti.maxVideoBitrate, + preferredAudioTracks = _parseConstructorOpti.preferredAudioTracks, + preferredTextTracks = _parseConstructorOpti.preferredTextTracks, + preferredVideoTracks = _parseConstructorOpti.preferredVideoTracks, + throttleWhenHidden = _parseConstructorOpti.throttleWhenHidden, + throttleVideoBitrateWhenHidden = _parseConstructorOpti.throttleVideoBitrateWhenHidden, + videoElement = _parseConstructorOpti.videoElement, + wantedBufferAhead = _parseConstructorOpti.wantedBufferAhead, + stopAtEnd = _parseConstructorOpti.stopAtEnd; // 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.24.0"; + _this.log = log/* default */.Z; + _this.state = "STOPPED"; + _this.videoElement = videoElement; + _this._priv_destroy$ = new Subject/* Subject */.xQ(); + _this._priv_pictureInPictureEvent$ = new ReplaySubject/* ReplaySubject */.t(1); + onPictureInPictureEvent$(videoElement).pipe((0,takeUntil/* takeUntil */.R)(_this._priv_destroy$)).subscribe(_this._priv_pictureInPictureEvent$); + /** @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) { + 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. + (0,distinctUntilChanged/* distinctUntilChanged */.x)(function (textTracksA, textTracksB) { + if (textTracksA.length !== textTracksB.length) { return false; + } + + for (var i = 0; i < textTracksA.length; i++) { + if (textTracksA[i] !== textTracksB[i]) { + return false; + } + } + + return true; + })).subscribe(function (x) { + return _this._priv_onNativeTextTracksNext(x); + }); + _this._priv_playing$ = new ReplaySubject/* ReplaySubject */.t(1); + _this._priv_speed$ = new BehaviorSubject(videoElement.playbackRate); + _this._priv_contentLock$ = new BehaviorSubject(false); + _this._priv_bufferOptions = { + wantedBufferAhead$: new BehaviorSubject(wantedBufferAhead), + maxBufferAhead$: new BehaviorSubject(maxBufferAhead), + maxBufferBehind$: new BehaviorSubject(maxBufferBehind) }; - SafeSubscriber.prototype._unsubscribe = function () { - var _parentSubscriber = this._parentSubscriber; - this._context = null; - this._parentSubscriber = null; - _parentSubscriber.unsubscribe(); + _this._priv_bitrateInfos = { + lastBitrates: { + audio: initialAudioBitrate, + video: initialVideoBitrate + }, + minAutoBitrates: { + audio: new BehaviorSubject(minAudioBitrate), + video: new BehaviorSubject(minVideoBitrate) + }, + maxAutoBitrates: { + audio: new BehaviorSubject(maxAudioBitrate), + video: new BehaviorSubject(maxVideoBitrate) + }, + manualBitrates: { + audio: new BehaviorSubject(-1), + video: new BehaviorSubject(-1) + } }; - return SafeSubscriber; -}(Subscriber)); + _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 = {}; + _this._priv_stopAtEnd = stopAtEnd; -//# sourceMappingURL=Subscriber.js.map + _this._priv_setPlayerState(PLAYER_STATES.STOPPED); + _this._priv_preferredAudioTracks = preferredAudioTracks; + _this._priv_preferredTextTracks = preferredTextTracks; + _this._priv_preferredVideoTracks = preferredVideoTracks; + _this._priv_lastContentPlaybackInfos = {}; + return _this; + } + /** All possible Error types emitted by the RxPlayer. */ -/***/ }), -/***/ 3884: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var _proto = Player.prototype; -"use strict"; + /** + * Stop the playback for the current content. + */ + _proto.stop = function stop() { + if (this._priv_contentInfos !== null) { + this._priv_contentInfos.stop$.next(); -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "w": () => /* binding */ Subscription -}); + this._priv_contentInfos.stop$.complete(); + } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isArray.js -var isArray = __webpack_require__(9026); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isObject.js -var isObject = __webpack_require__(2009); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isFunction.js -var isFunction = __webpack_require__(4156); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/UnsubscriptionError.js -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var UnsubscriptionErrorImpl = /*@__PURE__*/ (function () { - function UnsubscriptionErrorImpl(errors) { - Error.call(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; - return this; + this._priv_cleanUpCurrentContentState(); + + if (this.state !== PLAYER_STATES.STOPPED) { + this._priv_setPlayerState(PLAYER_STATES.STOPPED); } - UnsubscriptionErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); - return UnsubscriptionErrorImpl; -})(); -var UnsubscriptionError = UnsubscriptionErrorImpl; -//# sourceMappingURL=UnsubscriptionError.js.map + } + /** + * Free the resources used by the player. + * /!\ The player cannot be "used" anymore after this method has been called. + */ + ; -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/Subscription.js -/** PURE_IMPORTS_START _util_isArray,_util_isObject,_util_isFunction,_util_UnsubscriptionError PURE_IMPORTS_END */ + _proto.dispose = function dispose() { + // free resources linked to the loaded content + this.stop(); + if (this.videoElement !== null) { + // free resources used for EME management + disposeEME(this.videoElement); + } // free Observables linked to the Player instance + this._priv_destroy$.next(); -var Subscription = /*@__PURE__*/ (function () { - function Subscription(unsubscribe) { - this.closed = false; - this._parentOrParents = null; - this._subscriptions = null; - if (unsubscribe) { - this._ctorUnsubscribe = true; - this._unsubscribe = unsubscribe; - } - } - Subscription.prototype.unsubscribe = function () { - var errors; - if (this.closed) { - return; - } - var _a = this, _parentOrParents = _a._parentOrParents, _ctorUnsubscribe = _a._ctorUnsubscribe, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions; - this.closed = true; - this._parentOrParents = null; - this._subscriptions = null; - if (_parentOrParents instanceof Subscription) { - _parentOrParents.remove(this); - } - else if (_parentOrParents !== null) { - for (var index = 0; index < _parentOrParents.length; ++index) { - var parent_1 = _parentOrParents[index]; - parent_1.remove(this); - } - } - if ((0,isFunction/* isFunction */.m)(_unsubscribe)) { - if (_ctorUnsubscribe) { - this._unsubscribe = undefined; - } - try { - _unsubscribe.call(this); - } - catch (e) { - errors = e instanceof UnsubscriptionError ? flattenUnsubscriptionErrors(e.errors) : [e]; - } - } - if ((0,isArray/* isArray */.k)(_subscriptions)) { - var index = -1; - var len = _subscriptions.length; - while (++index < len) { - var sub = _subscriptions[index]; - if ((0,isObject/* isObject */.K)(sub)) { - try { - sub.unsubscribe(); - } - catch (e) { - errors = errors || []; - if (e instanceof UnsubscriptionError) { - errors = errors.concat(flattenUnsubscriptionErrors(e.errors)); - } - else { - errors.push(e); - } - } - } - } - } - if (errors) { - throw new UnsubscriptionError(errors); - } - }; - Subscription.prototype.add = function (teardown) { - var subscription = teardown; - if (!teardown) { - return Subscription.EMPTY; - } - switch (typeof teardown) { - case 'function': - subscription = new Subscription(teardown); - case 'object': - if (subscription === this || subscription.closed || typeof subscription.unsubscribe !== 'function') { - return subscription; - } - else if (this.closed) { - subscription.unsubscribe(); - return subscription; - } - else if (!(subscription instanceof Subscription)) { - var tmp = subscription; - subscription = new Subscription(); - subscription._subscriptions = [tmp]; - } - break; - default: { - throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.'); - } - } - var _parentOrParents = subscription._parentOrParents; - if (_parentOrParents === null) { - subscription._parentOrParents = this; - } - else if (_parentOrParents instanceof Subscription) { - if (_parentOrParents === this) { - return subscription; - } - subscription._parentOrParents = [_parentOrParents, this]; - } - else if (_parentOrParents.indexOf(this) === -1) { - _parentOrParents.push(this); - } - else { - return subscription; - } - var subscriptions = this._subscriptions; - if (subscriptions === null) { - this._subscriptions = [subscription]; - } - else { - subscriptions.push(subscription); - } - return subscription; - }; - Subscription.prototype.remove = function (subscription) { - var subscriptions = this._subscriptions; - if (subscriptions) { - var subscriptionIndex = subscriptions.indexOf(subscription); - if (subscriptionIndex !== -1) { - subscriptions.splice(subscriptionIndex, 1); - } - } - }; - Subscription.EMPTY = (function (empty) { - empty.closed = true; - return empty; - }(new Subscription())); - return Subscription; -}()); + this._priv_destroy$.complete(); // Complete all subjects -function flattenUnsubscriptionErrors(errors) { - return errors.reduce(function (errs, err) { return errs.concat((err instanceof UnsubscriptionError) ? err.errors : err); }, []); -} -//# sourceMappingURL=Subscription.js.map + this._priv_playing$.complete(); -/***/ }), + this._priv_speed$.complete(); -/***/ 150: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + this._priv_contentLock$.complete(); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "v": () => /* binding */ config -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var _enable_super_gross_mode_that_will_cause_bad_things = false; -var config = { - Promise: undefined, - set useDeprecatedSynchronousErrorHandling(value) { - if (value) { - var error = /*@__PURE__*/ new Error(); - /*@__PURE__*/ console.warn('DEPRECATED! RxJS was set to use deprecated synchronous error handling behavior by code at: \n' + error.stack); - } - else if (_enable_super_gross_mode_that_will_cause_bad_things) { - /*@__PURE__*/ console.log('RxJS: Back to a better error behavior. Thank you. <3'); - } - _enable_super_gross_mode_that_will_cause_bad_things = value; - }, - get useDeprecatedSynchronousErrorHandling() { - return _enable_super_gross_mode_that_will_cause_bad_things; - }, -}; -//# sourceMappingURL=config.js.map + this._priv_bufferOptions.wantedBufferAhead$.complete(); + this._priv_bufferOptions.maxBufferAhead$.complete(); -/***/ }), + this._priv_bufferOptions.maxBufferBehind$.complete(); -/***/ 7604: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + this._priv_pictureInPictureEvent$.complete(); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "IY": () => /* binding */ SimpleInnerSubscriber, -/* harmony export */ "Ds": () => /* binding */ SimpleOuterSubscriber, -/* harmony export */ "ft": () => /* binding */ innerSubscribe -/* harmony export */ }); -/* unused harmony exports ComplexInnerSubscriber, ComplexOuterSubscriber */ -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4379); -/* harmony import */ var _util_subscribeTo__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7843); -/** PURE_IMPORTS_START tslib,_Subscriber,_Observable,_util_subscribeTo PURE_IMPORTS_END */ + this._priv_bitrateInfos.manualBitrates.video.complete(); + this._priv_bitrateInfos.manualBitrates.audio.complete(); + this._priv_bitrateInfos.minAutoBitrates.video.complete(); + this._priv_bitrateInfos.minAutoBitrates.audio.complete(); -var SimpleInnerSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(SimpleInnerSubscriber, _super); - function SimpleInnerSubscriber(parent) { - var _this = _super.call(this) || this; - _this.parent = parent; - return _this; - } - SimpleInnerSubscriber.prototype._next = function (value) { - this.parent.notifyNext(value); - }; - SimpleInnerSubscriber.prototype._error = function (error) { - this.parent.notifyError(error); - this.unsubscribe(); - }; - SimpleInnerSubscriber.prototype._complete = function () { - this.parent.notifyComplete(); - this.unsubscribe(); + this._priv_bitrateInfos.maxAutoBitrates.video.complete(); + + this._priv_bitrateInfos.maxAutoBitrates.audio.complete(); + + this._priv_lastContentPlaybackInfos = {}; // un-attach video element + + this.videoElement = null; + } + /** + * Load a new video. + * @param {Object} opts + */ + ; + + _proto.loadVideo = function loadVideo(opts) { + var options = parseLoadVideoOptions(opts); + log/* default.info */.Z.info("API: Calling loadvideo", options); + this._priv_lastContentPlaybackInfos = { + options: options }; - return SimpleInnerSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); -var ComplexInnerSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(ComplexInnerSubscriber, _super); - function ComplexInnerSubscriber(parent, outerValue, outerIndex) { - var _this = _super.call(this) || this; - _this.parent = parent; - _this.outerValue = outerValue; - _this.outerIndex = outerIndex; - return _this; + this._priv_initializeContentPlayback(options); + } + /** + * Reload last content. Init media playback without fetching again + * the manifest. + * @param {Object} reloadOpts + */ + ; + + _proto.reload = function reload(reloadOpts) { + var _this$_priv_lastConte = this._priv_lastContentPlaybackInfos, + options = _this$_priv_lastConte.options, + manifest = _this$_priv_lastConte.manifest, + lastPlaybackPosition = _this$_priv_lastConte.lastPlaybackPosition; + + if (options === undefined || manifest === undefined || lastPlaybackPosition === undefined) { + throw new Error("API: Can't reload without having previously loaded a content."); } - ComplexInnerSubscriber.prototype._next = function (value) { - this.parent.notifyNext(this.outerValue, value, this.outerIndex, this); - }; - ComplexInnerSubscriber.prototype._error = function (error) { - this.parent.notifyError(error); - this.unsubscribe(); - }; - ComplexInnerSubscriber.prototype._complete = function () { - this.parent.notifyComplete(this); - this.unsubscribe(); - }; - return ComplexInnerSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); -var SimpleOuterSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(SimpleOuterSubscriber, _super); - function SimpleOuterSubscriber() { - return _super !== null && _super.apply(this, arguments) || this; + checkReloadOptions(reloadOpts); + var startAtPositon; + + if (reloadOpts !== undefined && reloadOpts.reloadAt !== undefined && reloadOpts.reloadAt.position !== undefined) { + startAtPositon = reloadOpts.reloadAt.position; + } else { + var playbackPosition; + + if (this.state === "STOPPED" || this.state === "ENDED") { + playbackPosition = lastPlaybackPosition; + } else { + if (this.videoElement === null) { + throw new Error("Can't reload when video element does not exist."); + } + + playbackPosition = this.videoElement.currentTime; + } + + if (reloadOpts !== undefined && reloadOpts.reloadAt !== undefined && reloadOpts.reloadAt.relative !== undefined) { + startAtPositon = reloadOpts.reloadAt.relative + playbackPosition; + } else { + startAtPositon = playbackPosition; + } } - SimpleOuterSubscriber.prototype.notifyNext = function (innerValue) { - this.destination.next(innerValue); - }; - SimpleOuterSubscriber.prototype.notifyError = function (err) { - this.destination.error(err); - }; - SimpleOuterSubscriber.prototype.notifyComplete = function () { - this.destination.complete(); + + var newOptions = Object.assign(Object.assign({}, options), { + initialManifest: manifest + }); + newOptions.startAt = { + position: startAtPositon }; - return SimpleOuterSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); -var ComplexOuterSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(ComplexOuterSubscriber, _super); - function ComplexOuterSubscriber() { - return _super !== null && _super.apply(this, arguments) || this; + this._priv_initializeContentPlayback(newOptions); + } + /** + * From given options, initialize content playback. + * @param {Object} options + */ + ; + + _proto._priv_initializeContentPlayback = function _priv_initializeContentPlayback(options) { + var _this2 = this; + + var _a, _b, _c; + + var autoPlay = options.autoPlay, + audioTrackSwitchingMode = options.audioTrackSwitchingMode, + defaultAudioTrack = options.defaultAudioTrack, + defaultTextTrack = options.defaultTextTrack, + enableFastSwitching = options.enableFastSwitching, + initialManifest = options.initialManifest, + keySystems = options.keySystems, + lowLatencyMode = options.lowLatencyMode, + manualBitrateSwitchingMode = options.manualBitrateSwitchingMode, + minimumManifestUpdateInterval = options.minimumManifestUpdateInterval, + networkConfig = options.networkConfig, + onCodecSwitch = options.onCodecSwitch, + startAt = options.startAt, + transport = options.transport, + transportOptions = options.transportOptions, + url = options.url; // Perform multiple checks on the given options + + if (this.videoElement === null) { + throw new Error("the attached video element is disposed"); } - ComplexOuterSubscriber.prototype.notifyNext = function (_outerValue, innerValue, _outerIndex, _innerSub) { - this.destination.next(innerValue); - }; - ComplexOuterSubscriber.prototype.notifyError = function (error) { - this.destination.error(error); - }; - ComplexOuterSubscriber.prototype.notifyComplete = function (_innerSub) { - this.destination.complete(); + + var isDirectFile = transport === "directfile"; + /** Subject which will emit to stop the current content. */ + + var stopContent$ = new Subject/* Subject */.xQ(); + /** Future `this._priv_contentInfos` related to this content. */ + + var contentInfos = { + url: url, + stop$: stopContent$, + isDirectFile: isDirectFile, + segmentBuffersStore: null, + thumbnails: null, + manifest: null, + currentPeriod: null, + activeAdaptations: null, + activeRepresentations: null, + initialAudioTrack: defaultAudioTrack, + initialTextTrack: defaultTextTrack }; - return ComplexOuterSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); + var videoElement = this.videoElement; + /** Global "clock" used for content playback */ -function innerSubscribe(result, innerSubscriber) { - if (innerSubscriber.closed) { - return undefined; - } - if (result instanceof _Observable__WEBPACK_IMPORTED_MODULE_2__/* .Observable */ .y) { - return result.subscribe(innerSubscriber); - } - return (0,_util_subscribeTo__WEBPACK_IMPORTED_MODULE_3__/* .subscribeTo */ .s)(result)(innerSubscriber); -} -//# sourceMappingURL=innerSubscribe.js.map + var _createClock = clock(videoElement, { + withMediaSource: !isDirectFile, + lowLatencyMode: lowLatencyMode + }), + setCurrentTime = _createClock.setCurrentTime, + clock$ = _createClock.clock$; + /** Emit playback events. */ -/***/ }), + var playback$; -/***/ 5142: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (!isDirectFile) { + var transportFn = features/* default.transports */.Z.transports[transport]; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "aj": () => /* binding */ combineLatest -/* harmony export */ }); -/* unused harmony exports CombineLatestOperator, CombineLatestSubscriber */ -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(655); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7507); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9026); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(2039); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2080); -/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3375); -/** PURE_IMPORTS_START tslib,_util_isScheduler,_util_isArray,_OuterSubscriber,_util_subscribeToResult,_fromArray PURE_IMPORTS_END */ + if (typeof transportFn !== "function") { + // Stop previous content and reset its state + this.stop(); + this._priv_currentError = null; + + this._priv_playing$.next(false); + throw new Error("transport \"" + transport + "\" not supported"); + } + + var transportPipelines = transportFn(transportOptions); + var offlineRetry = networkConfig.offlineRetry, + segmentRetry = networkConfig.segmentRetry, + manifestRetry = networkConfig.manifestRetry; + /** Interface used to load and refresh the Manifest. */ + + var manifestFetcher = new fetchers_manifest(url, transportPipelines, { + lowLatencyMode: lowLatencyMode, + maxRetryRegular: manifestRetry, + maxRetryOffline: offlineRetry + }); + /** Interface used to download segments. */ + + var segmentFetcherCreator = new segment(transportPipelines, { + lowLatencyMode: lowLatencyMode, + maxRetryOffline: offlineRetry, + maxRetryRegular: segmentRetry + }); + /** 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 */.zg)(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)(stopContent$), (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_playing$.next(false); -var NONE = {}; -function combineLatest() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - var resultSelector = undefined; - var scheduler = undefined; - if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__/* .isScheduler */ .K)(observables[observables.length - 1])) { - scheduler = observables.pop(); - } - if (typeof observables[observables.length - 1] === 'function') { - resultSelector = observables.pop(); - } - if (observables.length === 1 && (0,_util_isArray__WEBPACK_IMPORTED_MODULE_1__/* .isArray */ .k)(observables[0])) { - observables = observables[0]; - } - return (0,_fromArray__WEBPACK_IMPORTED_MODULE_2__/* .fromArray */ .n)(observables, scheduler).lift(new CombineLatestOperator(resultSelector)); -} -var CombineLatestOperator = /*@__PURE__*/ (function () { - function CombineLatestOperator(resultSelector) { - this.resultSelector = resultSelector; - } - CombineLatestOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new CombineLatestSubscriber(subscriber, this.resultSelector)); - }; - return CombineLatestOperator; -}()); + this._priv_contentInfos = contentInfos; + var relyOnVideoVisibilityAndSize = canRelyOnVideoVisibilityAndSize(); + var throttlers = { + throttle: {}, + throttleBitrate: {}, + limitWidth: {} + }; -var CombineLatestSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_3__/* .__extends */ .ZT(CombineLatestSubscriber, _super); - function CombineLatestSubscriber(destination, resultSelector) { - var _this = _super.call(this, destination) || this; - _this.resultSelector = resultSelector; - _this.active = 0; - _this.values = []; - _this.observables = []; - return _this; - } - CombineLatestSubscriber.prototype._next = function (observable) { - this.values.push(NONE); - this.observables.push(observable); - }; - CombineLatestSubscriber.prototype._complete = function () { - var observables = this.observables; - var len = observables.length; - if (len === 0) { - this.destination.complete(); - } - else { - this.active = len; - this.toRespond = len; - for (var i = 0; i < len; i++) { - var observable = observables[i]; - this.add((0,_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__/* .subscribeToResult */ .D)(this, observable, undefined, i)); - } - } - }; - CombineLatestSubscriber.prototype.notifyComplete = function (unused) { - if ((this.active -= 1) === 0) { - this.destination.complete(); - } - }; - CombineLatestSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { - var values = this.values; - var oldVal = values[outerIndex]; - var toRespond = !this.toRespond - ? 0 - : oldVal === NONE ? --this.toRespond : this.toRespond; - values[outerIndex] = innerValue; - if (toRespond === 0) { - if (this.resultSelector) { - this._tryResultSelector(values); - } - else { - this.destination.next(values.slice()); - } + if (this._priv_throttleWhenHidden) { + if (!relyOnVideoVisibilityAndSize) { + log/* default.warn */.Z.warn("API: Can't apply throttleWhenHidden because " + "browser can't be trusted for visibility."); + } else { + throttlers.throttle = { + video: isActive().pipe((0,map/* map */.U)(function (active) { + return active ? Infinity : 0; + }), (0,takeUntil/* takeUntil */.R)(stopContent$)) + }; } - }; - CombineLatestSubscriber.prototype._tryResultSelector = function (values) { - var result; - try { - result = this.resultSelector.apply(this, values); + } + + if (this._priv_throttleVideoBitrateWhenHidden) { + if (!relyOnVideoVisibilityAndSize) { + log/* default.warn */.Z.warn("API: Can't apply throttleVideoBitrateWhenHidden because " + "browser can't be trusted for visibility."); + } else { + throttlers.throttleBitrate = { + video: isVideoVisible(this._priv_pictureInPictureEvent$).pipe((0,map/* map */.U)(function (active) { + return active ? Infinity : 0; + }), (0,takeUntil/* takeUntil */.R)(stopContent$)) + }; } - catch (err) { - this.destination.error(err); - return; + } + + if (this._priv_limitVideoWidth) { + if (!relyOnVideoVisibilityAndSize) { + log/* default.warn */.Z.warn("API: Can't apply limitVideoWidth because browser can't be " + "trusted for video size."); + } else { + throttlers.limitWidth = { + video: videoWidth$(videoElement, this._priv_pictureInPictureEvent$).pipe((0,takeUntil/* takeUntil */.R)(stopContent$)) + }; } - this.destination.next(result); - }; - return CombineLatestSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_5__/* .OuterSubscriber */ .L)); + } + /** Options used by the ABR Manager. */ -//# sourceMappingURL=combineLatest.js.map + var adaptiveOptions = { + initialBitrates: this._priv_bitrateInfos.lastBitrates, + lowLatencyMode: lowLatencyMode, + manualBitrates: this._priv_bitrateInfos.manualBitrates, + minAutoBitrates: this._priv_bitrateInfos.minAutoBitrates, + maxAutoBitrates: this._priv_bitrateInfos.maxAutoBitrates, + throttlers: throttlers + }; + /** Options used by the TextTrack SegmentBuffer. */ -/***/ }), + var textTrackOptions = options.textTrackMode === "native" ? { + textTrackMode: "native", + hideNativeSubtitle: options.hideNativeSubtitle + } : { + textTrackMode: "html", + textTrackElement: options.textTrackElement + }; + var bufferOptions = (0,object_assign/* default */.Z)({ + audioTrackSwitchingMode: audioTrackSwitchingMode, + enableFastSwitching: enableFastSwitching, + manualBitrateSwitchingMode: manualBitrateSwitchingMode, + onCodecSwitch: onCodecSwitch + }, this._priv_bufferOptions); // We've every options set up. Start everything now -/***/ 9795: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var init$ = init({ + adaptiveOptions: adaptiveOptions, + autoPlay: autoPlay, + bufferOptions: bufferOptions, + clock$: clock$, + keySystems: keySystems, + lowLatencyMode: lowLatencyMode, + manifest$: manifest$, + manifestFetcher: manifestFetcher, + mediaElement: videoElement, + minimumManifestUpdateInterval: minimumManifestUpdateInterval, + segmentFetcherCreator: segmentFetcherCreator, + setCurrentTime: setCurrentTime, + speed$: this._priv_speed$, + startAt: startAt, + textTrackOptions: textTrackOptions + }).pipe((0,takeUntil/* takeUntil */.R)(stopContent$)); + playback$ = publish()(init$); + } else { + // Stop previous content and reset its state + this.stop(); + this._priv_currentError = null; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "z": () => /* binding */ concat -/* harmony export */ }); -/* harmony import */ var _of__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8170); -/* harmony import */ var _operators_concatAll__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2257); -/** PURE_IMPORTS_START _of,_operators_concatAll PURE_IMPORTS_END */ + this._priv_playing$.next(false); + if (features/* default.directfile */.Z.directfile === null) { + throw new Error("DirectFile feature not activated in your build."); + } -function concat() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - return (0,_operators_concatAll__WEBPACK_IMPORTED_MODULE_0__/* .concatAll */ .u)()(_of__WEBPACK_IMPORTED_MODULE_1__.of.apply(void 0, observables)); -} -//# sourceMappingURL=concat.js.map + 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]; -/***/ 1410: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + this._priv_mediaElementTrackChoiceManager.setPreferredTextTracks(preferredTextTracks, true); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "P": () => /* binding */ defer -/* harmony export */ }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4379); -/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4072); -/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5631); -/** PURE_IMPORTS_START _Observable,_from,_empty PURE_IMPORTS_END */ + 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); + }); -function defer(observableFactory) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) { - var input; - try { - input = observableFactory(); - } - catch (err) { - subscriber.error(err); - return undefined; - } - var source = input ? (0,_from__WEBPACK_IMPORTED_MODULE_1__/* .from */ .D)(input) : (0,_empty__WEBPACK_IMPORTED_MODULE_2__/* .empty */ .c)(); - return source.subscribe(subscriber); - }); -} -//# sourceMappingURL=defer.js.map + 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); + }); -/***/ 5631: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + this._priv_mediaElementTrackChoiceManager.addEventListener("videoTrackChange", function (val) { + return _this2.trigger("videoTrackChange", val); + }); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "E": () => /* binding */ EMPTY, -/* harmony export */ "c": () => /* binding */ empty -/* harmony export */ }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4379); -/** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ + this._priv_mediaElementTrackChoiceManager.addEventListener("textTrackChange", function (val) { + return _this2.trigger("textTrackChange", val); + }); -var EMPTY = /*@__PURE__*/ 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__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) { return scheduler.schedule(function () { return subscriber.complete(); }); }); -} -//# sourceMappingURL=empty.js.map + var directfileInit$ = features/* default.directfile.initDirectFile */.Z.directfile.initDirectFile({ + autoPlay: autoPlay, + clock$: clock$, + keySystems: keySystems, + mediaElement: videoElement, + speed$: this._priv_speed$, + startAt: startAt, + setCurrentTime: setCurrentTime, + url: url + }).pipe((0,takeUntil/* takeUntil */.R)(stopContent$)); + playback$ = publish()(directfileInit$); + } + /** 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; + }), (0,distinctUntilChanged/* distinctUntilChanged */.x)(function (wasStalled, isStalled) { + return wasStalled === null && isStalled === null || wasStalled !== null && isStalled !== null && wasStalled.reason === isStalled.reason; + })); + /** Emit when the content is considered "loaded". */ -/***/ 4072: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + 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. */ -"use strict"; + 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 an "ended" event. */ -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "D": () => /* binding */ from -}); + var endedEvent$ = onEnded$(videoElement); + /** Emit when the media element emits a "seeking" event. */ -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules -var Observable = __webpack_require__(4379); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeTo.js + 3 modules -var subscribeTo = __webpack_require__(7843); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscription.js + 1 modules -var Subscription = __webpack_require__(3884); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/symbol/observable.js -var symbol_observable = __webpack_require__(5050); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduled/scheduleObservable.js -/** PURE_IMPORTS_START _Observable,_Subscription,_symbol_observable PURE_IMPORTS_END */ + var seekingEvent$ = onSeeking$(videoElement); + /** Emit state updates once the content is considered "loaded". */ + var loadedStateUpdates$ = (0,combineLatest/* combineLatest */.aj)([this._priv_playing$, stalled$.pipe((0,startWith/* startWith */.O)(null)), endedEvent$.pipe((0,startWith/* startWith */.O)(null)), seekingEvent$.pipe((0,startWith/* startWith */.O)(null))]).pipe((0,takeUntil/* takeUntil */.R)(stopContent$), (0,map/* map */.U)(function (_ref) { + var isPlaying = _ref[0], + stalledStatus = _ref[1]; + return getLoadedContentState(videoElement, isPlaying, stalledStatus); + })); + /** Emit all player "state" updates. */ + var playerState$ = (0,concat/* concat */.z)((0,of.of)(PLAYER_STATES.LOADING), // Begin with LOADING + // LOADED as soon as the first "loaded" event is sent + loaded$.pipe((0,take/* take */.q)(1), (0,mapTo/* mapTo */.h)(PLAYER_STATES.LOADED)), (0,merge/* merge */.T)(loadedStateUpdates$.pipe( // From the first reload onward, we enter another dynamic (below) + (0,takeUntil/* takeUntil */.R)(reloading$), skipWhile(function (state) { + return state === PLAYER_STATES.PAUSED; + })), // when reloading + reloading$.pipe((0,switchMapTo/* switchMapTo */.c)(loaded$.pipe((0,take/* take */.q)(1), // wait for the next loaded event + (0,mergeMapTo/* mergeMapTo */.j)(loadedStateUpdates$), // to update the state as usual + (0,startWith/* startWith */.O)(PLAYER_STATES.RELOADING) // Starts with "RELOADING" state + ))))).pipe((0,distinctUntilChanged/* distinctUntilChanged */.x)()); + var playbackSubscription; + stopContent$.pipe((0,take/* take */.q)(1)).subscribe(function () { + if (playbackSubscription !== undefined) { + playbackSubscription.unsubscribe(); + } + }); // Link `_priv_onPlayPauseNext` Observable to "play"/"pause" events -function scheduleObservable(input, scheduler) { - return new Observable/* Observable */.y(function (subscriber) { - var sub = new Subscription/* Subscription */.w(); - sub.add(scheduler.schedule(function () { - var observable = input[symbol_observable/* observable */.L](); - sub.add(observable.subscribe({ - next: function (value) { sub.add(scheduler.schedule(function () { return subscriber.next(value); })); }, - error: function (err) { sub.add(scheduler.schedule(function () { return subscriber.error(err); })); }, - complete: function () { sub.add(scheduler.schedule(function () { return subscriber.complete(); })); }, - })); - })); - return sub; - }); -} -//# sourceMappingURL=scheduleObservable.js.map + onPlayPause$(videoElement).pipe((0,takeUntil/* takeUntil */.R)(stopContent$)).subscribe(function (e) { + return _this2._priv_onPlayPauseNext(e.type === "play"); + }, noop/* default */.Z); // Link "positionUpdate" events to the clock -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduled/schedulePromise.js -/** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ + clock$.pipe((0,takeUntil/* takeUntil */.R)(stopContent$)).subscribe(function (x) { + return _this2._priv_triggerPositionUpdate(x); + }, noop/* default */.Z); // Link "seeking" and "seeked" events (once the content is loaded) + loaded$.pipe((0,switchMapTo/* switchMapTo */.c)(emitSeekEvents(this.videoElement, clock$)), (0,takeUntil/* takeUntil */.R)(stopContent$)).subscribe(function (evt) { + log/* default.info */.Z.info("API: Triggering \"" + evt + "\" event"); -function schedulePromise(input, scheduler) { - return new Observable/* Observable */.y(function (subscriber) { - var sub = new Subscription/* Subscription */.w(); - sub.add(scheduler.schedule(function () { - return input.then(function (value) { - sub.add(scheduler.schedule(function () { - subscriber.next(value); - sub.add(scheduler.schedule(function () { return subscriber.complete(); })); - })); - }, function (err) { - sub.add(scheduler.schedule(function () { return subscriber.error(err); })); - }); - })); - return sub; + _this2.trigger(evt, null); + }); // Handle state updates + + playerState$.pipe((0,takeUntil/* takeUntil */.R)(stopContent$)).subscribe(function (x) { + return _this2._priv_setPlayerState(x); + }, noop/* default */.Z); + (this._priv_stopAtEnd ? onEnded$(videoElement) : empty/* EMPTY */.E).pipe((0,takeUntil/* takeUntil */.R)(stopContent$)).subscribe(function () { + stopContent$.next(); + stopContent$.complete(); + }); // Link playback events to the corresponding callbacks + + playback$.subscribe(function (x) { + return _this2._priv_onPlaybackEvent(x); + }, function (err) { + return _this2._priv_onPlaybackError(err); + }, function () { + return _this2._priv_onPlaybackFinished(); + }); // initialize the content only when the lock is inactive + + this._priv_contentLock$.pipe((0,filter/* filter */.h)(function (isLocked) { + return !isLocked; + }), (0,take/* take */.q)(1), (0,takeUntil/* takeUntil */.R)(stopContent$)).subscribe(function () { + // start playback! + playbackSubscription = playback$.connect(); }); -} -//# sourceMappingURL=schedulePromise.js.map + } + /** + * Returns fatal error if one for the current content. + * null otherwise. + * @returns {Object|null} - The current Error (`null` when no error). + */ + ; -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/scheduled/scheduleArray.js -var scheduleArray = __webpack_require__(3109); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/symbol/iterator.js -var symbol_iterator = __webpack_require__(999); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduled/scheduleIterable.js -/** PURE_IMPORTS_START _Observable,_Subscription,_symbol_iterator PURE_IMPORTS_END */ + _proto.getError = function getError() { + return this._priv_currentError; + } + /** + * Returns manifest/playlist object. + * null if the player is STOPPED. + * @deprecated + * @returns {Manifest|null} - The current Manifest (`null` when not known). + */ + ; + + _proto.getManifest = function getManifest() { + (0,warn_once/* default */.Z)("getManifest is deprecated." + " Please open an issue if you used this API."); + if (this._priv_contentInfos === null) { + return null; + } + return this._priv_contentInfos.manifest; + } + /** + * Returns Adaptations (tracks) for every currently playing type + * (audio/video/text...). + * @deprecated + * @returns {Object|null} - The current Adaptation objects, per type (`null` + * when none is known for now. + */ + ; -function scheduleIterable(input, scheduler) { - if (!input) { - throw new Error('Iterable cannot be null'); + _proto.getCurrentAdaptations = function getCurrentAdaptations() { + (0,warn_once/* default */.Z)("getCurrentAdaptations is deprecated." + " Please open an issue if you used this API."); + + if (this._priv_contentInfos === null) { + return null; } - return new Observable/* Observable */.y(function (subscriber) { - var sub = new Subscription/* Subscription */.w(); - var iterator; - sub.add(function () { - if (iterator && typeof iterator.return === 'function') { - iterator.return(); - } - }); - sub.add(scheduler.schedule(function () { - iterator = input[symbol_iterator/* iterator */.hZ](); - sub.add(scheduler.schedule(function () { - if (subscriber.closed) { - return; - } - var value; - var done; - try { - var result = iterator.next(); - value = result.value; - done = result.done; - } - catch (err) { - subscriber.error(err); - return; - } - if (done) { - subscriber.complete(); - } - else { - subscriber.next(value); - this.schedule(); - } - })); - })); - return sub; - }); -} -//# sourceMappingURL=scheduleIterable.js.map -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/isInteropObservable.js -/** PURE_IMPORTS_START _symbol_observable PURE_IMPORTS_END */ + var _this$_priv_contentIn = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn.currentPeriod, + activeAdaptations = _this$_priv_contentIn.activeAdaptations; -function isInteropObservable(input) { - return input && typeof input[symbol_observable/* observable */.L] === 'function'; -} -//# sourceMappingURL=isInteropObservable.js.map + if (currentPeriod === null || activeAdaptations === null || (0,is_null_or_undefined/* default */.Z)(activeAdaptations[currentPeriod.id])) { + return null; + } -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isPromise.js -var isPromise = __webpack_require__(336); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isArrayLike.js -var isArrayLike = __webpack_require__(9217); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/isIterable.js -/** PURE_IMPORTS_START _symbol_iterator PURE_IMPORTS_END */ + return activeAdaptations[currentPeriod.id]; + } + /** + * Returns representations (qualities) for every currently playing type + * (audio/video/text...). + * @deprecated + * @returns {Object|null} - The current Representation objects, per type + * (`null` when none is known for now. + */ + ; -function isIterable(input) { - return input && typeof input[symbol_iterator/* iterator */.hZ] === 'function'; -} -//# sourceMappingURL=isIterable.js.map + _proto.getCurrentRepresentations = function getCurrentRepresentations() { + (0,warn_once/* default */.Z)("getCurrentRepresentations is deprecated." + " Please open an issue if you used this API."); + return this._priv_getCurrentRepresentations(); + } + /** + * Returns the media DOM element used by the player. + * You should not its HTML5 API directly and use the player's method instead, + * to ensure a well-behaved player. + * @returns {HTMLMediaElement|null} - The HTMLMediaElement used (`null` when + * disposed) + */ + ; -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduled/scheduled.js -/** PURE_IMPORTS_START _scheduleObservable,_schedulePromise,_scheduleArray,_scheduleIterable,_util_isInteropObservable,_util_isPromise,_util_isArrayLike,_util_isIterable PURE_IMPORTS_END */ + _proto.getVideoElement = function getVideoElement() { + return this.videoElement; + } + /** + * If one returns the first native text-track element attached to the media element. + * @deprecated + * @returns {TextTrack} - The native TextTrack attached (`null` when none) + */ + ; + _proto.getNativeTextTrack = function getNativeTextTrack() { + (0,warn_once/* default */.Z)("getNativeTextTrack is deprecated." + " Please open an issue if you used this API."); + if (this.videoElement === null) { + throw new Error("Disposed player"); + } + var videoElement = this.videoElement; + var textTracks = videoElement.textTracks; + if (textTracks.length > 0) { + return videoElement.textTracks[0]; + } else { + return null; + } + } + /** + * Returns the player's current state. + * @returns {string} - The current Player's state + */ + ; + _proto.getPlayerState = function getPlayerState() { + return this.state; + } + /** + * Returns true if both: + * - a content is loaded + * - the content loaded is a live content + * @returns {Boolean} - `true` if we're playing a live content, `false` otherwise. + */ + ; + _proto.isLive = function isLive() { + if (this._priv_contentInfos === null) { + return false; + } + var _this$_priv_contentIn2 = this._priv_contentInfos, + isDirectFile = _this$_priv_contentIn2.isDirectFile, + manifest = _this$_priv_contentIn2.manifest; -function scheduled(input, scheduler) { - if (input != null) { - if (isInteropObservable(input)) { - return scheduleObservable(input, scheduler); - } - else if ((0,isPromise/* isPromise */.t)(input)) { - return schedulePromise(input, scheduler); - } - else if ((0,isArrayLike/* isArrayLike */.z)(input)) { - return (0,scheduleArray/* scheduleArray */.r)(input, scheduler); - } - else if (isIterable(input) || typeof input === 'string') { - return scheduleIterable(input, scheduler); - } + if (isDirectFile || manifest === null) { + return false; } - throw new TypeError((input !== null && typeof input || input) + ' is not observable'); -} -//# sourceMappingURL=scheduled.js.map -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/observable/from.js -/** PURE_IMPORTS_START _Observable,_util_subscribeTo,_scheduled_scheduled PURE_IMPORTS_END */ + return manifest.isLive; + } + /** + * Returns the url of the content's manifest + * @returns {string|undefined} - Current URL. `undefined` if not known or no + * URL yet. + */ + ; + _proto.getUrl = function getUrl() { + if (this._priv_contentInfos === null) { + return undefined; + } + var _this$_priv_contentIn3 = this._priv_contentInfos, + isDirectFile = _this$_priv_contentIn3.isDirectFile, + manifest = _this$_priv_contentIn3.manifest, + url = _this$_priv_contentIn3.url; -function from(input, scheduler) { - if (!scheduler) { - if (input instanceof Observable/* Observable */.y) { - return input; - } - return new Observable/* Observable */.y((0,subscribeTo/* subscribeTo */.s)(input)); - } - else { - return scheduled(input, scheduler); + if (isDirectFile) { + return url; } -} -//# sourceMappingURL=from.js.map + if (manifest !== null) { + return manifest.getUrl(); + } -/***/ }), + return undefined; + } + /** + * Returns the video duration, in seconds. + * NaN if no video is playing. + * @returns {Number} + */ + ; -/***/ 3375: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.getVideoDuration = function getVideoDuration() { + if (this.videoElement === null) { + throw new Error("Disposed player"); + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "n": () => /* binding */ fromArray -/* harmony export */ }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4379); -/* harmony import */ var _util_subscribeToArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6900); -/* harmony import */ var _scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3109); -/** PURE_IMPORTS_START _Observable,_util_subscribeToArray,_scheduled_scheduleArray PURE_IMPORTS_END */ + return this.videoElement.duration; + } + /** + * Returns in seconds the difference between: + * - the end of the current contiguous loaded range. + * - the current time + * @returns {Number} + */ + ; + _proto.getVideoBufferGap = function getVideoBufferGap() { + if (this.videoElement === null) { + throw new Error("Disposed player"); + } + var videoElement = this.videoElement; + return (0,ranges/* getLeftSizeOfRange */.L7)(videoElement.buffered, videoElement.currentTime); + } + /** + * Returns in seconds the difference between: + * - the end of the current contiguous loaded range. + * - the start of the current contiguous loaded range. + * @returns {Number} + */ + ; -function fromArray(input, scheduler) { - if (!scheduler) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y((0,_util_subscribeToArray__WEBPACK_IMPORTED_MODULE_1__/* .subscribeToArray */ .V)(input)); - } - else { - return (0,_scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_2__/* .scheduleArray */ .r)(input, scheduler); + _proto.getVideoLoadedTime = function getVideoLoadedTime() { + if (this.videoElement === null) { + throw new Error("Disposed player"); } -} -//# sourceMappingURL=fromArray.js.map + var videoElement = this.videoElement; + return (0,ranges/* getSizeOfRange */.at)(videoElement.buffered, videoElement.currentTime); + } + /** + * Returns in seconds the difference between: + * - the current time. + * - the start of the current contiguous loaded range. + * @returns {Number} + */ + ; -/***/ }), - -/***/ 7027: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.getVideoPlayedTime = function getVideoPlayedTime() { + if (this.videoElement === null) { + throw new Error("Disposed player"); + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "R": () => /* binding */ fromEvent -/* harmony export */ }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4379); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9026); -/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4156); -/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5709); -/** PURE_IMPORTS_START _Observable,_util_isArray,_util_isFunction,_operators_map PURE_IMPORTS_END */ + var videoElement = this.videoElement; + return (0,ranges/* getPlayedSizeOfRange */.DD)(videoElement.buffered, videoElement.currentTime); + } + /** + * Get the current position, in s, in wall-clock time. + * That is: + * - for live content, get a timestamp, in s, of the current played content. + * - for static content, returns the position from beginning in s. + * + * If you do not know if you want to use this method or getPosition: + * - If what you want is to display the current time to the user, use this + * one. + * - If what you want is to interact with the player's API or perform other + * actions (like statistics) with the real player data, use getPosition. + * + * @returns {Number} + */ + ; + _proto.getWallClockTime = function getWallClockTime() { + if (this.videoElement === null) { + throw new Error("Disposed player"); + } + if (this._priv_contentInfos === null) { + return this.videoElement.currentTime; + } + var _this$_priv_contentIn4 = this._priv_contentInfos, + isDirectFile = _this$_priv_contentIn4.isDirectFile, + manifest = _this$_priv_contentIn4.manifest; -var toString = /*@__PURE__*/ (/* unused pure expression or super */ null && ((function () { return Object.prototype.toString; })())); -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,_operators_map__WEBPACK_IMPORTED_MODULE_1__/* .map */ .U)(function (args) { return (0,_util_isArray__WEBPACK_IMPORTED_MODULE_2__/* .isArray */ .k)(args) ? resultSelector.apply(void 0, args) : resultSelector(args); })); - } - return new _Observable__WEBPACK_IMPORTED_MODULE_3__/* .Observable */ .y(function (subscriber) { - function handler(e) { - if (arguments.length > 1) { - subscriber.next(Array.prototype.slice.call(arguments)); - } - else { - subscriber.next(e); - } - } - setupSubscription(target, eventName, handler, subscriber, options); - }); -} -function setupSubscription(sourceObj, eventName, handler, subscriber, options) { - var unsubscribe; - if (isEventTarget(sourceObj)) { - var source_1 = sourceObj; - sourceObj.addEventListener(eventName, handler, options); - unsubscribe = function () { return source_1.removeEventListener(eventName, handler, options); }; - } - else if (isJQueryStyleEventEmitter(sourceObj)) { - var source_2 = sourceObj; - sourceObj.on(eventName, handler); - unsubscribe = function () { return source_2.off(eventName, handler); }; - } - else if (isNodeStyleEventEmitter(sourceObj)) { - var source_3 = sourceObj; - sourceObj.addListener(eventName, handler); - unsubscribe = function () { return source_3.removeListener(eventName, handler); }; + if (isDirectFile) { + return this.videoElement.currentTime; } - else if (sourceObj && sourceObj.length) { - for (var i = 0, len = sourceObj.length; i < len; i++) { - setupSubscription(sourceObj[i], eventName, handler, subscriber, options); - } + + if (manifest !== null) { + var currentTime = this.videoElement.currentTime; + var ast = manifest.availabilityStartTime !== undefined ? manifest.availabilityStartTime : 0; + return currentTime + ast; } - else { - throw new TypeError('Invalid event target'); + + return 0; + } + /** + * Get the current position, in seconds, of the video element. + * + * If you do not know if you want to use this method or getWallClockTime: + * - If what you want is to display the current time to the user, use + * getWallClockTime. + * - If what you want is to interact with the player's API or perform other + * actions (like statistics) with the real player data, use this one. + * + * @returns {Number} + */ + ; + + _proto.getPosition = function getPosition() { + if (this.videoElement === null) { + throw new Error("Disposed player"); } - subscriber.add(unsubscribe); -} -function isNodeStyleEventEmitter(sourceObj) { - return sourceObj && typeof sourceObj.addListener === 'function' && typeof sourceObj.removeListener === 'function'; -} -function isJQueryStyleEventEmitter(sourceObj) { - return sourceObj && typeof sourceObj.on === 'function' && typeof sourceObj.off === 'function'; -} -function isEventTarget(sourceObj) { - return sourceObj && typeof sourceObj.addEventListener === 'function' && typeof sourceObj.removeEventListener === 'function'; -} -//# sourceMappingURL=fromEvent.js.map + return this.videoElement.currentTime; + } + /** + * Returns the current speed at which the video plays. + * @returns {Number} + */ + ; + + _proto.getPlaybackRate = function getPlaybackRate() { + return this._priv_speed$.getValue(); + } + /** + * Update the playback rate of the video. + * @param {Number} rate + */ + ; -/***/ }), + _proto.setPlaybackRate = function setPlaybackRate(rate) { + this._priv_speed$.next(rate); + } + /** + * Returns all available bitrates for the current video Adaptation. + * @returns {Array.} + */ + ; -/***/ 6564: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.getAvailableVideoBitrates = function getAvailableVideoBitrates() { + if (this._priv_contentInfos === null) { + return []; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "F": () => /* binding */ interval -/* harmony export */ }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4379); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(964); -/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5812); -/** PURE_IMPORTS_START _Observable,_scheduler_async,_util_isNumeric PURE_IMPORTS_END */ + var _this$_priv_contentIn5 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn5.currentPeriod, + activeAdaptations = _this$_priv_contentIn5.activeAdaptations; + if (currentPeriod === null || activeAdaptations === null) { + return []; + } + var adaptations = activeAdaptations[currentPeriod.id]; -function interval(period, scheduler) { - if (period === void 0) { - period = 0; + if (adaptations === undefined || (0,is_null_or_undefined/* default */.Z)(adaptations.video)) { + return []; } - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__/* .async */ .P; + + return adaptations.video.getAvailableBitrates(); + } + /** + * Returns all available bitrates for the current audio Adaptation. + * @returns {Array.} + */ + ; + + _proto.getAvailableAudioBitrates = function getAvailableAudioBitrates() { + if (this._priv_contentInfos === null) { + return []; } - if (!(0,_util_isNumeric__WEBPACK_IMPORTED_MODULE_1__/* .isNumeric */ .k)(period) || period < 0) { - period = 0; + + var _this$_priv_contentIn6 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn6.currentPeriod, + activeAdaptations = _this$_priv_contentIn6.activeAdaptations; + + if (currentPeriod === null || activeAdaptations === null) { + return []; } - if (!scheduler || typeof scheduler.schedule !== 'function') { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__/* .async */ .P; + + var adaptations = activeAdaptations[currentPeriod.id]; + + if (adaptations === undefined || (0,is_null_or_undefined/* default */.Z)(adaptations.audio)) { + return []; } - return new _Observable__WEBPACK_IMPORTED_MODULE_2__/* .Observable */ .y(function (subscriber) { - subscriber.add(scheduler.schedule(dispatch, period, { subscriber: subscriber, counter: 0, period: period })); - return subscriber; - }); -} -function dispatch(state) { - var subscriber = state.subscriber, counter = state.counter, period = state.period; - subscriber.next(counter); - this.schedule({ subscriber: subscriber, counter: counter + 1, period: period }, period); -} -//# sourceMappingURL=interval.js.map + return adaptations.audio.getAvailableBitrates(); + } + /** + * Returns the manual audio bitrate set. -1 if in AUTO mode. + * @returns {Number} + */ + ; -/***/ }), + _proto.getManualAudioBitrate = function getManualAudioBitrate() { + return this._priv_bitrateInfos.manualBitrates.audio.getValue(); + } + /** + * Returns the manual video bitrate set. -1 if in AUTO mode. + * @returns {Number} + */ + ; -/***/ 4370: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.getManualVideoBitrate = function getManualVideoBitrate() { + return this._priv_bitrateInfos.manualBitrates.video.getValue(); + } + /** + * Returns currently considered bitrate for video segments. + * @returns {Number|undefined} + */ + ; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "T": () => /* binding */ merge -/* harmony export */ }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4379); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7507); -/* harmony import */ var _operators_mergeAll__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2556); -/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3375); -/** PURE_IMPORTS_START _Observable,_util_isScheduler,_operators_mergeAll,_fromArray PURE_IMPORTS_END */ + _proto.getVideoBitrate = function getVideoBitrate() { + var representations = this._priv_getCurrentRepresentations(); + if (representations === null || (0,is_null_or_undefined/* default */.Z)(representations.video)) { + return undefined; + } + return representations.video.bitrate; + } + /** + * Returns currently considered bitrate for audio segments. + * @returns {Number|undefined} + */ + ; + _proto.getAudioBitrate = function getAudioBitrate() { + var representations = this._priv_getCurrentRepresentations(); -function merge() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - var concurrent = Number.POSITIVE_INFINITY; - var scheduler = null; - var last = observables[observables.length - 1]; - if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__/* .isScheduler */ .K)(last)) { - scheduler = observables.pop(); - if (observables.length > 1 && typeof observables[observables.length - 1] === 'number') { - concurrent = observables.pop(); - } - } - else if (typeof last === 'number') { - concurrent = observables.pop(); - } - if (scheduler === null && observables.length === 1 && observables[0] instanceof _Observable__WEBPACK_IMPORTED_MODULE_1__/* .Observable */ .y) { - return observables[0]; + if (representations === null || (0,is_null_or_undefined/* default */.Z)(representations.audio)) { + return undefined; } - return (0,_operators_mergeAll__WEBPACK_IMPORTED_MODULE_2__/* .mergeAll */ .J)(concurrent)((0,_fromArray__WEBPACK_IMPORTED_MODULE_3__/* .fromArray */ .n)(observables, scheduler)); -} -//# sourceMappingURL=merge.js.map + return representations.audio.bitrate; + } + /** + * Returns minimum wanted video bitrate currently set. + * @returns {Number} + */ + ; -/***/ }), + _proto.getMinVideoBitrate = function getMinVideoBitrate() { + return this._priv_bitrateInfos.minAutoBitrates.video.getValue(); + } + /** + * Returns minimum wanted audio bitrate currently set. + * @returns {Number} + */ + ; -/***/ 8170: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.getMinAudioBitrate = function getMinAudioBitrate() { + return this._priv_bitrateInfos.minAutoBitrates.audio.getValue(); + } + /** + * Returns maximum wanted video bitrate currently set. + * @returns {Number} + */ + ; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "of": () => /* binding */ of -/* harmony export */ }); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7507); -/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3375); -/* harmony import */ var _scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3109); -/** PURE_IMPORTS_START _util_isScheduler,_fromArray,_scheduled_scheduleArray PURE_IMPORTS_END */ + _proto.getMaxVideoBitrate = function getMaxVideoBitrate() { + return this._priv_bitrateInfos.maxAutoBitrates.video.getValue(); + } + /** + * Returns maximum wanted audio bitrate currently set. + * @returns {Number} + */ + ; + _proto.getMaxAudioBitrate = function getMaxAudioBitrate() { + return this._priv_bitrateInfos.maxAutoBitrates.audio.getValue(); + } + /** + * Play/Resume the current video. + * @returns {Promise} + */ + ; + _proto.play = function play() { + var _this3 = this; -function of() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - var scheduler = args[args.length - 1]; - if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__/* .isScheduler */ .K)(scheduler)) { - args.pop(); - return (0,_scheduled_scheduleArray__WEBPACK_IMPORTED_MODULE_1__/* .scheduleArray */ .r)(args, scheduler); - } - else { - return (0,_fromArray__WEBPACK_IMPORTED_MODULE_2__/* .fromArray */ .n)(args); + if (this.videoElement === null) { + throw new Error("Disposed player"); } -} -//# sourceMappingURL=of.js.map - -/***/ }), + var playPromise = this.videoElement.play(); + /* eslint-disable @typescript-eslint/unbound-method */ -/***/ 8821: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if ((0,is_null_or_undefined/* default */.Z)(playPromise) || typeof playPromise["catch"] !== "function") { + /* eslint-enable @typescript-eslint/unbound-method */ + return promise/* default.resolve */.Z.resolve(); + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "S3": () => /* binding */ race -/* harmony export */ }); -/* unused harmony exports RaceOperator, RaceSubscriber */ -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(655); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9026); -/* harmony import */ var _fromArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3375); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(2039); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2080); -/** PURE_IMPORTS_START tslib,_util_isArray,_fromArray,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ + return playPromise["catch"](function (error) { + if (error.name === "NotAllowedError") { + var warning = new media_error/* default */.Z("MEDIA_ERR_PLAY_NOT_ALLOWED", error.toString()); + _this3.trigger("warning", warning); + } + throw error; + }); + } + /** + * Pause the current video. + */ + ; + _proto.pause = function pause() { + if (this.videoElement === null) { + throw new Error("Disposed player"); + } + this.videoElement.pause(); + } + /** + * Seek to a given absolute position. + * @param {Number|Object} time + * @returns {Number} - The time the player has seek to + */ + ; -function race() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - if (observables.length === 1) { - if ((0,_util_isArray__WEBPACK_IMPORTED_MODULE_0__/* .isArray */ .k)(observables[0])) { - observables = observables[0]; - } - else { - return observables[0]; - } - } - return (0,_fromArray__WEBPACK_IMPORTED_MODULE_1__/* .fromArray */ .n)(observables, undefined).lift(new RaceOperator()); -} -var RaceOperator = /*@__PURE__*/ (function () { - function RaceOperator() { + _proto.seekTo = function seekTo(time) { + if (this.videoElement === null) { + throw new Error("Disposed player"); } - RaceOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new RaceSubscriber(subscriber)); - }; - return RaceOperator; -}()); -var RaceSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_2__/* .__extends */ .ZT(RaceSubscriber, _super); - function RaceSubscriber(destination) { - var _this = _super.call(this, destination) || this; - _this.hasFirst = false; - _this.observables = []; - _this.subscriptions = []; - return _this; + if (this._priv_contentInfos === null) { + throw new Error("player: no content loaded"); } - RaceSubscriber.prototype._next = function (observable) { - this.observables.push(observable); - }; - RaceSubscriber.prototype._complete = function () { - var observables = this.observables; - var len = observables.length; - if (len === 0) { - this.destination.complete(); - } - else { - for (var i = 0; i < len && !this.hasFirst; i++) { - var observable = observables[i]; - var subscription = (0,_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__/* .subscribeToResult */ .D)(this, observable, undefined, i); - if (this.subscriptions) { - this.subscriptions.push(subscription); - } - this.add(subscription); - } - this.observables = null; - } - }; - RaceSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { - if (!this.hasFirst) { - this.hasFirst = true; - for (var i = 0; i < this.subscriptions.length; i++) { - if (i !== outerIndex) { - var subscription = this.subscriptions[i]; - subscription.unsubscribe(); - this.remove(subscription); - } - } - this.subscriptions = null; - } - this.destination.next(innerValue); - }; - return RaceSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_4__/* .OuterSubscriber */ .L)); - -//# sourceMappingURL=race.js.map + var _this$_priv_contentIn7 = this._priv_contentInfos, + isDirectFile = _this$_priv_contentIn7.isDirectFile, + manifest = _this$_priv_contentIn7.manifest; -/***/ }), + if (!isDirectFile && manifest === null) { + throw new Error("player: the content did not load yet"); + } -/***/ 4944: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var positionWanted; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "_": () => /* binding */ throwError -/* harmony export */ }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4379); -/** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ + if (typeof time === "number") { + positionWanted = time; + } else if (typeof time === "object") { + var timeObj = time; + var currentTs = this.videoElement.currentTime; -function throwError(error, scheduler) { - if (!scheduler) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) { return subscriber.error(error); }); + if (!(0,is_null_or_undefined/* default */.Z)(timeObj.relative)) { + positionWanted = currentTs + timeObj.relative; + } else if (!(0,is_null_or_undefined/* default */.Z)(timeObj.position)) { + positionWanted = timeObj.position; + } else if (!(0,is_null_or_undefined/* default */.Z)(timeObj.wallClockTime)) { + positionWanted = isDirectFile || manifest === null ? timeObj.wallClockTime : timeObj.wallClockTime - (manifest.availabilityStartTime !== undefined ? manifest.availabilityStartTime : 0); + } else { + throw new Error("invalid time object. You must set one of the " + "following properties: \"relative\", \"position\" or " + "\"wallClockTime\""); + } } - else { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) { return scheduler.schedule(dispatch, 0, { error: error, subscriber: subscriber }); }); + + if (positionWanted === undefined) { + throw new Error("invalid time given"); } -} -function dispatch(_a) { - var error = _a.error, subscriber = _a.subscriber; - subscriber.error(error); -} -//# sourceMappingURL=throwError.js.map + this.videoElement.currentTime = positionWanted; + return positionWanted; + } + /** + * Returns true if the media element is full screen. + * @deprecated + * @returns {Boolean} + */ + ; -/***/ }), + _proto.isFullscreen = function isFullscreen() { + (0,warn_once/* default */.Z)("isFullscreen is deprecated." + " Fullscreen management should now be managed by the application"); + return fullscreen_isFullscreen(); + } + /** + * Set/exit fullScreen. + * @deprecated + * @param {Boolean} [goFull=true] - if false, exit full screen. + */ + ; -/***/ 9604: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.setFullscreen = function setFullscreen(goFull) { + if (goFull === void 0) { + goFull = true; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "H": () => /* binding */ timer -/* harmony export */ }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4379); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(964); -/* harmony import */ var _util_isNumeric__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5812); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7507); -/** PURE_IMPORTS_START _Observable,_scheduler_async,_util_isNumeric,_util_isScheduler PURE_IMPORTS_END */ + (0,warn_once/* default */.Z)("setFullscreen is deprecated." + " Fullscreen management should now be managed by the application"); + if (this.videoElement === null) { + throw new Error("Disposed player"); + } + if (goFull) { + requestFullscreen(this.videoElement); + } else { + fullscreen_exitFullscreen(); + } + } + /** + * Exit from full screen mode. + * @deprecated + */ + ; + _proto.exitFullscreen = function exitFullscreen() { + (0,warn_once/* default */.Z)("exitFullscreen is deprecated." + " Fullscreen management should now be managed by the application"); -function timer(dueTime, periodOrScheduler, scheduler) { - if (dueTime === void 0) { - dueTime = 0; - } - var period = -1; - if ((0,_util_isNumeric__WEBPACK_IMPORTED_MODULE_0__/* .isNumeric */ .k)(periodOrScheduler)) { - period = Number(periodOrScheduler) < 1 && 1 || Number(periodOrScheduler); - } - else if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__/* .isScheduler */ .K)(periodOrScheduler)) { - scheduler = periodOrScheduler; - } - if (!(0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__/* .isScheduler */ .K)(scheduler)) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__/* .async */ .P; - } - return new _Observable__WEBPACK_IMPORTED_MODULE_3__/* .Observable */ .y(function (subscriber) { - var due = (0,_util_isNumeric__WEBPACK_IMPORTED_MODULE_0__/* .isNumeric */ .k)(dueTime) - ? dueTime - : (+dueTime - scheduler.now()); - return scheduler.schedule(dispatch, due, { - index: 0, period: period, subscriber: subscriber - }); - }); -} -function dispatch(state) { - var index = state.index, period = state.period, subscriber = state.subscriber; - subscriber.next(index); - if (subscriber.closed) { - return; + fullscreen_exitFullscreen(); + } + /** + * Returns the current player's audio volume on the media element. + * From 0 (no audio) to 1 (maximum volume). + * @returns {Number} + */ + ; + + _proto.getVolume = function getVolume() { + if (this.videoElement === null) { + throw new Error("Disposed player"); } - else if (period === -1) { - return subscriber.complete(); + + return this.videoElement.volume; + } + /** + * Set the player's audio volume. From 0 (no volume) to 1 (maximum volume). + * @param {Number} volume + */ + ; + + _proto.setVolume = function setVolume(volume) { + if (this.videoElement === null) { + throw new Error("Disposed player"); } - state.index = index + 1; - this.schedule(state, period); -} -//# sourceMappingURL=timer.js.map + var videoElement = this.videoElement; -/***/ }), + if (volume !== videoElement.volume) { + videoElement.volume = volume; + this.trigger("volumeChange", volume); + } + } + /** + * Returns true if the volume is set to 0. false otherwise. + * @returns {Boolean} + */ + ; -/***/ 486: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.isMute = function isMute() { + return this.getVolume() === 0; + } + /** + * Set the volume to 0 and save current one for when unmuted. + */ + ; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "K": () => /* binding */ catchError -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7604); -/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + _proto.mute = function mute() { + this._priv_mutedMemory = this.getVolume(); + this.setVolume(0); + } + /** + * Set the volume back to when it was when mute was last called. + * If the volume was set to 0, set a default volume instead (see config). + */ + ; + _proto.unMute = function unMute() { + var vol = this.getVolume(); -function catchError(selector) { - return function catchErrorOperatorFunction(source) { - var operator = new CatchOperator(selector); - var caught = source.lift(operator); - return (operator.caught = caught); - }; -} -var CatchOperator = /*@__PURE__*/ (function () { - function CatchOperator(selector) { - this.selector = selector; - } - CatchOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new CatchSubscriber(subscriber, this.selector, this.caught)); - }; - return CatchOperator; -}()); -var CatchSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(CatchSubscriber, _super); - function CatchSubscriber(destination, selector, caught) { - var _this = _super.call(this, destination) || this; - _this.selector = selector; - _this.caught = caught; - return _this; + if (vol === 0) { + this.setVolume(this._priv_mutedMemory === 0 ? DEFAULT_UNMUTED_VOLUME : this._priv_mutedMemory); } - CatchSubscriber.prototype.error = function (err) { - if (!this.isStopped) { - var result = void 0; - try { - result = this.selector(err, this.caught); - } - catch (err2) { - _super.prototype.error.call(this, err2); - return; - } - this._unsubscribeAndRecycle(); - var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__/* .SimpleInnerSubscriber */ .IY(this); - this.add(innerSubscriber); - var innerSubscription = (0,_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__/* .innerSubscribe */ .ft)(result, innerSubscriber); - if (innerSubscription !== innerSubscriber) { - this.add(innerSubscription); - } - } - }; - return CatchSubscriber; -}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__/* .SimpleOuterSubscriber */ .Ds)); -//# sourceMappingURL=catchError.js.map - + } + /** + * Force the video bitrate to a given value. Act as a ceil. + * -1 to set it on AUTO Mode + * @param {Number} btr + */ + ; -/***/ }), + _proto.setVideoBitrate = function setVideoBitrate(btr) { + this._priv_bitrateInfos.manualBitrates.video.next(btr); + } + /** + * Force the audio bitrate to a given value. Act as a ceil. + * -1 to set it on AUTO Mode + * @param {Number} btr + */ + ; -/***/ 2257: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.setAudioBitrate = function setAudioBitrate(btr) { + this._priv_bitrateInfos.manualBitrates.audio.next(btr); + } + /** + * Update the minimum video bitrate the user can switch to. + * @param {Number} btr + */ + ; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "u": () => /* binding */ concatAll -/* harmony export */ }); -/* harmony import */ var _mergeAll__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2556); -/** PURE_IMPORTS_START _mergeAll PURE_IMPORTS_END */ + _proto.setMinVideoBitrate = function setMinVideoBitrate(btr) { + var maxVideoBitrate = this._priv_bitrateInfos.maxAutoBitrates.video.getValue(); -function concatAll() { - return (0,_mergeAll__WEBPACK_IMPORTED_MODULE_0__/* .mergeAll */ .J)(1); -} -//# sourceMappingURL=concatAll.js.map + if (btr > maxVideoBitrate) { + throw new Error("Invalid minimum video bitrate given. " + ("Its value, \"" + btr + "\" is superior the current maximum ") + ("video birate, \"" + maxVideoBitrate + "\".")); + } + this._priv_bitrateInfos.minAutoBitrates.video.next(btr); + } + /** + * Update the minimum audio bitrate the user can switch to. + * @param {Number} btr + */ + ; -/***/ }), + _proto.setMinAudioBitrate = function setMinAudioBitrate(btr) { + var maxAudioBitrate = this._priv_bitrateInfos.maxAutoBitrates.audio.getValue(); -/***/ 1931: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (btr > maxAudioBitrate) { + throw new Error("Invalid minimum audio bitrate given. " + ("Its value, \"" + btr + "\" is superior the current maximum ") + ("audio birate, \"" + maxAudioBitrate + "\".")); + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "x": () => /* binding */ distinctUntilChanged -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + this._priv_bitrateInfos.minAutoBitrates.audio.next(btr); + } + /** + * Update the maximum video bitrate the user can switch to. + * @param {Number} btr + */ + ; + _proto.setMaxVideoBitrate = function setMaxVideoBitrate(btr) { + var minVideoBitrate = this._priv_bitrateInfos.minAutoBitrates.video.getValue(); -function distinctUntilChanged(compare, keySelector) { - return function (source) { return source.lift(new DistinctUntilChangedOperator(compare, keySelector)); }; -} -var DistinctUntilChangedOperator = /*@__PURE__*/ (function () { - function DistinctUntilChangedOperator(compare, keySelector) { - this.compare = compare; - this.keySelector = keySelector; + if (btr < minVideoBitrate) { + throw new Error("Invalid maximum video bitrate given. " + ("Its value, \"" + btr + "\" is inferior the current minimum ") + ("video birate, \"" + minVideoBitrate + "\".")); } - DistinctUntilChangedOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DistinctUntilChangedSubscriber(subscriber, this.compare, this.keySelector)); - }; - return DistinctUntilChangedOperator; -}()); -var DistinctUntilChangedSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(DistinctUntilChangedSubscriber, _super); - function DistinctUntilChangedSubscriber(destination, compare, keySelector) { - var _this = _super.call(this, destination) || this; - _this.keySelector = keySelector; - _this.hasKey = false; - if (typeof compare === 'function') { - _this.compare = compare; - } - return _this; + + this._priv_bitrateInfos.maxAutoBitrates.video.next(btr); + } + /** + * Update the maximum audio bitrate the user can switch to. + * @param {Number} btr + */ + ; + + _proto.setMaxAudioBitrate = function setMaxAudioBitrate(btr) { + var minAudioBitrate = this._priv_bitrateInfos.minAutoBitrates.audio.getValue(); + + if (btr < minAudioBitrate) { + throw new Error("Invalid maximum audio bitrate given. " + ("Its value, \"" + btr + "\" is inferior the current minimum ") + ("audio birate, \"" + minAudioBitrate + "\".")); } - DistinctUntilChangedSubscriber.prototype.compare = function (x, y) { - return x === y; - }; - DistinctUntilChangedSubscriber.prototype._next = function (value) { - var key; - try { - var keySelector = this.keySelector; - key = keySelector ? keySelector(value) : value; - } - catch (err) { - return this.destination.error(err); - } - var result = false; - if (this.hasKey) { - try { - var compare = this.compare; - result = compare(this.key, key); - } - catch (err) { - return this.destination.error(err); - } - } - else { - this.hasKey = true; - } - if (!result) { - this.key = key; - this.destination.next(value); - } - }; - return DistinctUntilChangedSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); -//# sourceMappingURL=distinctUntilChanged.js.map + this._priv_bitrateInfos.maxAutoBitrates.audio.next(btr); + } + /** + * Set the max buffer size for the buffer behind the current position. + * Every buffer data before will be removed. + * @param {Number} depthInSeconds + */ + ; + + _proto.setMaxBufferBehind = function setMaxBufferBehind(depthInSeconds) { + this._priv_bufferOptions.maxBufferBehind$.next(depthInSeconds); + } + /** + * Set the max buffer size for the buffer behind the current position. + * Every buffer data before will be removed. + * @param {Number} depthInSeconds + */ + ; + + _proto.setMaxBufferAhead = function setMaxBufferAhead(depthInSeconds) { + this._priv_bufferOptions.maxBufferAhead$.next(depthInSeconds); + } + /** + * Set the max buffer size for the buffer ahead of the current position. + * The player will stop downloading chunks when this size is reached. + * @param {Number} sizeInSeconds + */ + ; -/***/ }), + _proto.setWantedBufferAhead = function setWantedBufferAhead(sizeInSeconds) { + this._priv_bufferOptions.wantedBufferAhead$.next(sizeInSeconds); + } + /** + * Returns the max buffer size for the buffer behind the current position. + * @returns {Number} + */ + ; -/***/ 6008: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.getMaxBufferBehind = function getMaxBufferBehind() { + return this._priv_bufferOptions.maxBufferBehind$.getValue(); + } + /** + * Returns the max buffer size for the buffer behind the current position. + * @returns {Number} + */ + ; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "h": () => /* binding */ filter -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + _proto.getMaxBufferAhead = function getMaxBufferAhead() { + return this._priv_bufferOptions.maxBufferAhead$.getValue(); + } + /** + * Returns the max buffer size for the buffer ahead of the current position. + * @returns {Number} + */ + ; + _proto.getWantedBufferAhead = function getWantedBufferAhead() { + return this._priv_bufferOptions.wantedBufferAhead$.getValue(); + } + /** + * Returns type of current keysystem (e.g. playready, widevine) if the content + * is encrypted. null otherwise. + * @returns {string|null} + */ + ; -function filter(predicate, thisArg) { - return function filterOperatorFunction(source) { - return source.lift(new FilterOperator(predicate, thisArg)); - }; -} -var FilterOperator = /*@__PURE__*/ (function () { - function FilterOperator(predicate, thisArg) { - this.predicate = predicate; - this.thisArg = thisArg; - } - FilterOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new FilterSubscriber(subscriber, this.predicate, this.thisArg)); - }; - return FilterOperator; -}()); -var FilterSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(FilterSubscriber, _super); - function FilterSubscriber(destination, predicate, thisArg) { - var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.thisArg = thisArg; - _this.count = 0; - return _this; + _proto.getCurrentKeySystem = function getCurrentKeySystem() { + if (this.videoElement === null) { + throw new Error("Disposed player"); } - FilterSubscriber.prototype._next = function (value) { - var result; - try { - result = this.predicate.call(this.thisArg, value, this.count++); - } - catch (err) { - this.destination.error(err); - return; - } - if (result) { - this.destination.next(value); - } - }; - return FilterSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); -//# sourceMappingURL=filter.js.map - -/***/ }), + return get_current_key_system_getCurrentKeySystem(this.videoElement); + } + /** + * Returns every available audio tracks for the current Period. + * @returns {Array.|null} + */ + ; -/***/ 6738: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.getAvailableAudioTracks = function getAvailableAudioTracks() { + var _a, _b; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "l": () => /* binding */ ignoreElements -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + if (this._priv_contentInfos === null) { + return []; + } + var _this$_priv_contentIn8 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn8.currentPeriod, + isDirectFile = _this$_priv_contentIn8.isDirectFile; -function ignoreElements() { - return function ignoreElementsOperatorFunction(source) { - return source.lift(new IgnoreElementsOperator()); - }; -} -var IgnoreElementsOperator = /*@__PURE__*/ (function () { - function IgnoreElementsOperator() { - } - IgnoreElementsOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new IgnoreElementsSubscriber(subscriber)); - }; - return IgnoreElementsOperator; -}()); -var IgnoreElementsSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(IgnoreElementsSubscriber, _super); - function IgnoreElementsSubscriber() { - return _super !== null && _super.apply(this, arguments) || this; + if (isDirectFile) { + return (_b = (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.getAvailableAudioTracks()) !== null && _b !== void 0 ? _b : []; } - IgnoreElementsSubscriber.prototype._next = function (unused) { - }; - return IgnoreElementsSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); -//# sourceMappingURL=ignoreElements.js.map + if (this._priv_trackChoiceManager === null || currentPeriod === null) { + return []; + } -/***/ }), + return this._priv_trackChoiceManager.getAvailableAudioTracks(currentPeriod); + } + /** + * Returns every available text tracks for the current Period. + * @returns {Array.|null} + */ + ; -/***/ 5709: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.getAvailableTextTracks = function getAvailableTextTracks() { + var _a, _b; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "U": () => /* binding */ map -/* harmony export */ }); -/* unused harmony export MapOperator */ -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + if (this._priv_contentInfos === null) { + return []; + } + var _this$_priv_contentIn9 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn9.currentPeriod, + isDirectFile = _this$_priv_contentIn9.isDirectFile; -function map(project, thisArg) { - return function mapOperation(source) { - if (typeof project !== 'function') { - throw new TypeError('argument is not a function. Are you looking for `mapTo()`?'); - } - return source.lift(new MapOperator(project, thisArg)); - }; -} -var MapOperator = /*@__PURE__*/ (function () { - function MapOperator(project, thisArg) { - this.project = project; - this.thisArg = thisArg; + if (isDirectFile) { + return (_b = (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.getAvailableTextTracks()) !== null && _b !== void 0 ? _b : []; } - MapOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new MapSubscriber(subscriber, this.project, this.thisArg)); - }; - return MapOperator; -}()); -var MapSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(MapSubscriber, _super); - function MapSubscriber(destination, project, thisArg) { - var _this = _super.call(this, destination) || this; - _this.project = project; - _this.count = 0; - _this.thisArg = thisArg || _this; - return _this; + if (this._priv_trackChoiceManager === null || currentPeriod === null) { + return []; } - MapSubscriber.prototype._next = function (value) { - var result; - try { - result = this.project.call(this.thisArg, value, this.count++); - } - catch (err) { - this.destination.error(err); - return; - } - this.destination.next(result); - }; - return MapSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); -//# sourceMappingURL=map.js.map - -/***/ }), + return this._priv_trackChoiceManager.getAvailableTextTracks(currentPeriod); + } + /** + * Returns every available video tracks for the current Period. + * @returns {Array.|null} + */ + ; -/***/ 5602: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.getAvailableVideoTracks = function getAvailableVideoTracks() { + var _a, _b; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "h": () => /* binding */ mapTo -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + if (this._priv_contentInfos === null) { + return []; + } + var _this$_priv_contentIn10 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn10.currentPeriod, + isDirectFile = _this$_priv_contentIn10.isDirectFile; -function mapTo(value) { - return function (source) { return source.lift(new MapToOperator(value)); }; -} -var MapToOperator = /*@__PURE__*/ (function () { - function MapToOperator(value) { - this.value = value; + if (isDirectFile) { + return (_b = (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.getAvailableVideoTracks()) !== null && _b !== void 0 ? _b : []; } - MapToOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new MapToSubscriber(subscriber, this.value)); - }; - return MapToOperator; -}()); -var MapToSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(MapToSubscriber, _super); - function MapToSubscriber(destination, value) { - var _this = _super.call(this, destination) || this; - _this.value = value; - return _this; + + if (this._priv_trackChoiceManager === null || currentPeriod === null) { + return []; } - MapToSubscriber.prototype._next = function (x) { - this.destination.next(this.value); - }; - return MapToSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); -//# sourceMappingURL=mapTo.js.map + return this._priv_trackChoiceManager.getAvailableVideoTracks(currentPeriod); + } + /** + * Returns currently chosen audio language for the current Period. + * @returns {string} + */ + ; -/***/ }), + _proto.getAudioTrack = function getAudioTrack() { + if (this._priv_contentInfos === null) { + return undefined; + } -/***/ 2556: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var _this$_priv_contentIn11 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn11.currentPeriod, + isDirectFile = _this$_priv_contentIn11.isDirectFile; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "J": () => /* binding */ mergeAll -/* harmony export */ }); -/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7746); -/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3608); -/** PURE_IMPORTS_START _mergeMap,_util_identity PURE_IMPORTS_END */ + if (isDirectFile) { + if (this._priv_mediaElementTrackChoiceManager === null) { + return undefined; + } + return this._priv_mediaElementTrackChoiceManager.getChosenAudioTrack(); + } -function mergeAll(concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; + if (this._priv_trackChoiceManager === null || currentPeriod === null) { + return undefined; } - return (0,_mergeMap__WEBPACK_IMPORTED_MODULE_0__/* .mergeMap */ .zg)(_util_identity__WEBPACK_IMPORTED_MODULE_1__/* .identity */ .y, concurrent); -} -//# sourceMappingURL=mergeAll.js.map + return this._priv_trackChoiceManager.getChosenAudioTrack(currentPeriod); + } + /** + * Returns currently chosen subtitle for the current Period. + * @returns {string} + */ + ; -/***/ }), + _proto.getTextTrack = function getTextTrack() { + if (this._priv_contentInfos === null) { + return undefined; + } -/***/ 7746: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var _this$_priv_contentIn12 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn12.currentPeriod, + isDirectFile = _this$_priv_contentIn12.isDirectFile; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "zg": () => /* binding */ mergeMap -/* harmony export */ }); -/* unused harmony exports MergeMapOperator, MergeMapSubscriber, flatMap */ -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(655); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5709); -/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4072); -/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7604); -/** PURE_IMPORTS_START tslib,_map,_observable_from,_innerSubscribe PURE_IMPORTS_END */ + if (isDirectFile) { + if (this._priv_mediaElementTrackChoiceManager === null) { + return undefined; + } + return this._priv_mediaElementTrackChoiceManager.getChosenTextTrack(); + } + if (this._priv_trackChoiceManager === null || currentPeriod === null) { + return undefined; + } + return this._priv_trackChoiceManager.getChosenTextTrack(currentPeriod); + } + /** + * Returns currently chosen video track for the current Period. + * @returns {string} + */ + ; -function mergeMap(project, resultSelector, concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; - } - if (typeof resultSelector === 'function') { - return function (source) { return source.pipe(mergeMap(function (a, i) { return (0,_observable_from__WEBPACK_IMPORTED_MODULE_0__/* .from */ .D)(project(a, i)).pipe((0,_map__WEBPACK_IMPORTED_MODULE_1__/* .map */ .U)(function (b, ii) { return resultSelector(a, b, i, ii); })); }, concurrent)); }; - } - else if (typeof resultSelector === 'number') { - concurrent = resultSelector; - } - return function (source) { return source.lift(new MergeMapOperator(project, concurrent)); }; -} -var MergeMapOperator = /*@__PURE__*/ (function () { - function MergeMapOperator(project, concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; - } - this.project = project; - this.concurrent = concurrent; + _proto.getVideoTrack = function getVideoTrack() { + if (this._priv_contentInfos === null) { + return undefined; } - MergeMapOperator.prototype.call = function (observer, source) { - return source.subscribe(new MergeMapSubscriber(observer, this.project, this.concurrent)); - }; - return MergeMapOperator; -}()); -var MergeMapSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_2__/* .__extends */ .ZT(MergeMapSubscriber, _super); - function MergeMapSubscriber(destination, project, concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; - } - var _this = _super.call(this, destination) || this; - _this.project = project; - _this.concurrent = concurrent; - _this.hasCompleted = false; - _this.buffer = []; - _this.active = 0; - _this.index = 0; - return _this; - } - MergeMapSubscriber.prototype._next = function (value) { - if (this.active < this.concurrent) { - this._tryNext(value); - } - else { - this.buffer.push(value); - } - }; - MergeMapSubscriber.prototype._tryNext = function (value) { - var result; - var index = this.index++; - try { - result = this.project(value, index); - } - catch (err) { - this.destination.error(err); - return; - } - this.active++; - this._innerSub(result); - }; - MergeMapSubscriber.prototype._innerSub = function (ish) { - var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__/* .SimpleInnerSubscriber */ .IY(this); - var destination = this.destination; - destination.add(innerSubscriber); - var innerSubscription = (0,_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__/* .innerSubscribe */ .ft)(ish, innerSubscriber); - if (innerSubscription !== innerSubscriber) { - destination.add(innerSubscription); - } - }; - MergeMapSubscriber.prototype._complete = function () { - this.hasCompleted = true; - if (this.active === 0 && this.buffer.length === 0) { - this.destination.complete(); - } - this.unsubscribe(); - }; - MergeMapSubscriber.prototype.notifyNext = function (innerValue) { - this.destination.next(innerValue); - }; - MergeMapSubscriber.prototype.notifyComplete = function () { - var buffer = this.buffer; - this.active--; - if (buffer.length > 0) { - this._next(buffer.shift()); - } - else if (this.active === 0 && this.hasCompleted) { - this.destination.complete(); - } - }; - return MergeMapSubscriber; -}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__/* .SimpleOuterSubscriber */ .Ds)); + var _this$_priv_contentIn13 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn13.currentPeriod, + isDirectFile = _this$_priv_contentIn13.isDirectFile; -var flatMap = (/* unused pure expression or super */ null && (mergeMap)); -//# sourceMappingURL=mergeMap.js.map + if (isDirectFile) { + if (this._priv_mediaElementTrackChoiceManager === null) { + return undefined; + } + return this._priv_mediaElementTrackChoiceManager.getChosenVideoTrack(); + } -/***/ }), + if (this._priv_trackChoiceManager === null || currentPeriod === null) { + return undefined; + } -/***/ 3756: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + return this._priv_trackChoiceManager.getChosenVideoTrack(currentPeriod); + } + /** + * Update the audio language for the current Period. + * @param {string} audioId + * @throws Error - the current content has no TrackChoiceManager. + * @throws Error - the given id is linked to no audio track. + */ + ; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "j": () => /* binding */ mergeMapTo -/* harmony export */ }); -/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7746); -/** PURE_IMPORTS_START _mergeMap PURE_IMPORTS_END */ + _proto.setAudioTrack = function setAudioTrack(audioId) { + var _a; -function mergeMapTo(innerObservable, resultSelector, concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; - } - if (typeof resultSelector === 'function') { - return (0,_mergeMap__WEBPACK_IMPORTED_MODULE_0__/* .mergeMap */ .zg)(function () { return innerObservable; }, resultSelector, concurrent); - } - if (typeof resultSelector === 'number') { - concurrent = resultSelector; + if (this._priv_contentInfos === null) { + throw new Error("No content loaded"); } - return (0,_mergeMap__WEBPACK_IMPORTED_MODULE_0__/* .mergeMap */ .zg)(function () { return innerObservable; }, concurrent); -} -//# sourceMappingURL=mergeMapTo.js.map + var _this$_priv_contentIn14 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn14.currentPeriod, + isDirectFile = _this$_priv_contentIn14.isDirectFile; -/***/ }), + if (isDirectFile) { + try { + (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.setAudioTrackById(audioId); + return; + } catch (e) { + throw new Error("player: unknown audio track"); + } + } -/***/ 1421: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (this._priv_trackChoiceManager === null || currentPeriod === null) { + throw new Error("No compatible content launched."); + } + + try { + this._priv_trackChoiceManager.setAudioTrackByID(currentPeriod, audioId); + } catch (e) { + throw new Error("player: unknown audio track"); + } + } + /** + * Update the text language for the current Period. + * @param {string} sub + * @throws Error - the current content has no TrackChoiceManager. + * @throws Error - the given id is linked to no text track. + */ + ; -"use strict"; + _proto.setTextTrack = function setTextTrack(textId) { + var _a; -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "O": () => /* binding */ multicast -}); + if (this._priv_contentInfos === null) { + throw new Error("No content loaded"); + } -// UNUSED EXPORTS: MulticastOperator + var _this$_priv_contentIn15 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn15.currentPeriod, + isDirectFile = _this$_priv_contentIn15.isDirectFile; -// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js -var tslib_es6 = __webpack_require__(655); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subject.js -var Subject = __webpack_require__(211); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules -var Observable = __webpack_require__(4379); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscriber.js -var Subscriber = __webpack_require__(979); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscription.js + 1 modules -var Subscription = __webpack_require__(3884); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/refCount.js -var refCount = __webpack_require__(3018); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/observable/ConnectableObservable.js -/** PURE_IMPORTS_START tslib,_Subject,_Observable,_Subscriber,_Subscription,_operators_refCount PURE_IMPORTS_END */ + if (isDirectFile) { + try { + (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.setTextTrackById(textId); + return; + } catch (e) { + throw new Error("player: unknown text track"); + } + } + if (this._priv_trackChoiceManager === null || currentPeriod === null) { + throw new Error("No compatible content launched."); + } + try { + this._priv_trackChoiceManager.setTextTrackByID(currentPeriod, textId); + } catch (e) { + throw new Error("player: unknown text track"); + } + } + /** + * 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; -var ConnectableObservable = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(ConnectableObservable, _super); - function ConnectableObservable(source, subjectFactory) { - var _this = _super.call(this) || this; - _this.source = source; - _this.subjectFactory = subjectFactory; - _this._refCount = 0; - _this._isComplete = false; - return _this; + if (isDirectFile) { + (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.disableTextTrack(); + return; } - ConnectableObservable.prototype._subscribe = function (subscriber) { - return this.getSubject().subscribe(subscriber); - }; - ConnectableObservable.prototype.getSubject = function () { - var subject = this._subject; - if (!subject || subject.isStopped) { - this._subject = this.subjectFactory(); - } - return this._subject; - }; - ConnectableObservable.prototype.connect = function () { - var connection = this._connection; - if (!connection) { - this._isComplete = false; - connection = this._connection = new Subscription/* Subscription */.w(); - connection.add(this.source - .subscribe(new ConnectableSubscriber(this.getSubject(), this))); - if (connection.closed) { - this._connection = null; - connection = Subscription/* Subscription.EMPTY */.w.EMPTY; - } - } - return connection; - }; - ConnectableObservable.prototype.refCount = function () { - return (0,refCount/* refCount */.x)()(this); - }; - return ConnectableObservable; -}(Observable/* Observable */.y)); -var connectableObservableDescriptor = /*@__PURE__*/ (function () { - var connectableProto = ConnectableObservable.prototype; - return { - operator: { value: null }, - _refCount: { value: 0, writable: true }, - _subject: { value: null, writable: true }, - _connection: { value: null, writable: true }, - _subscribe: { value: connectableProto._subscribe }, - _isComplete: { value: connectableProto._isComplete, writable: true }, - getSubject: { value: connectableProto.getSubject }, - connect: { value: connectableProto.connect }, - refCount: { value: connectableProto.refCount } - }; -})(); -var ConnectableSubscriber = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(ConnectableSubscriber, _super); - function ConnectableSubscriber(destination, connectable) { - var _this = _super.call(this, destination) || this; - _this.connectable = connectable; - return _this; - } - ConnectableSubscriber.prototype._error = function (err) { - this._unsubscribe(); - _super.prototype._error.call(this, err); - }; - ConnectableSubscriber.prototype._complete = function () { - this.connectable._isComplete = true; - this._unsubscribe(); - _super.prototype._complete.call(this); - }; - ConnectableSubscriber.prototype._unsubscribe = function () { - var connectable = this.connectable; - if (connectable) { - this.connectable = null; - var connection = connectable._connection; - connectable._refCount = 0; - connectable._subject = null; - connectable._connection = null; - if (connection) { - connection.unsubscribe(); - } - } - }; - return ConnectableSubscriber; -}(Subject/* SubjectSubscriber */.Yc)); -var RefCountOperator = /*@__PURE__*/ ((/* unused pure expression or super */ null && (function () { - function RefCountOperator(connectable) { - this.connectable = connectable; - } - RefCountOperator.prototype.call = function (subscriber, source) { - var connectable = this.connectable; - connectable._refCount++; - var refCounter = new RefCountSubscriber(subscriber, connectable); - var subscription = source.subscribe(refCounter); - if (!refCounter.closed) { - refCounter.connection = connectable.connect(); - } - return subscription; - }; - return RefCountOperator; -}()))); -var RefCountSubscriber = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(RefCountSubscriber, _super); - function RefCountSubscriber(destination, connectable) { - var _this = _super.call(this, destination) || this; - _this.connectable = connectable; - return _this; + if (this._priv_trackChoiceManager === null || currentPeriod === null) { + return; } - RefCountSubscriber.prototype._unsubscribe = function () { - var connectable = this.connectable; - if (!connectable) { - this.connection = null; - return; - } - this.connectable = null; - var refCount = connectable._refCount; - if (refCount <= 0) { - this.connection = null; - return; - } - connectable._refCount = refCount - 1; - if (refCount > 1) { - this.connection = null; - return; - } - var connection = this.connection; - var sharedConnection = connectable._connection; - this.connection = null; - if (sharedConnection && (!connection || sharedConnection === connection)) { - sharedConnection.unsubscribe(); - } - }; - return RefCountSubscriber; -}(Subscriber/* Subscriber */.L)); -//# sourceMappingURL=ConnectableObservable.js.map -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/operators/multicast.js -/** PURE_IMPORTS_START _observable_ConnectableObservable PURE_IMPORTS_END */ + return this._priv_trackChoiceManager.disableTextTrack(currentPeriod); + } + /** + * Update the video track for the current Period. + * @param {string} videoId + * @throws Error - the current content has no TrackChoiceManager. + * @throws Error - the given id is linked to no video track. + */ + ; -function multicast(subjectOrSubjectFactory, selector) { - return function multicastOperatorFunction(source) { - var subjectFactory; - if (typeof subjectOrSubjectFactory === 'function') { - subjectFactory = subjectOrSubjectFactory; - } - else { - subjectFactory = function subjectFactory() { - return subjectOrSubjectFactory; - }; - } - if (typeof selector === 'function') { - return source.lift(new MulticastOperator(subjectFactory, selector)); - } - var connectable = Object.create(source, connectableObservableDescriptor); - connectable.source = source; - connectable.subjectFactory = subjectFactory; - return connectable; - }; -} -var MulticastOperator = /*@__PURE__*/ (function () { - function MulticastOperator(subjectFactory, selector) { - this.subjectFactory = subjectFactory; - this.selector = selector; + _proto.setVideoTrack = function setVideoTrack(videoId) { + var _a; + + if (this._priv_contentInfos === null) { + throw new Error("No content loaded"); } - MulticastOperator.prototype.call = function (subscriber, source) { - var selector = this.selector; - var subject = this.subjectFactory(); - var subscription = selector(subject).subscribe(subscriber); - subscription.add(source.subscribe(subject)); - return subscription; - }; - return MulticastOperator; -}()); -//# sourceMappingURL=multicast.js.map + var _this$_priv_contentIn17 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn17.currentPeriod, + isDirectFile = _this$_priv_contentIn17.isDirectFile; + if (isDirectFile) { + try { + (_a = this._priv_mediaElementTrackChoiceManager) === null || _a === void 0 ? void 0 : _a.setVideoTrackById(videoId); + return; + } catch (e) { + throw new Error("player: unknown video track"); + } + } -/***/ }), + if (this._priv_trackChoiceManager === null || currentPeriod === null) { + throw new Error("No compatible content launched."); + } -/***/ 3018: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + try { + this._priv_trackChoiceManager.setVideoTrackByID(currentPeriod, videoId); + } catch (e) { + throw new Error("player: unknown video track"); + } + } + /** + * Disable video track for the current content. + */ + ; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "x": () => /* binding */ refCount -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + _proto.disableVideoTrack = function disableVideoTrack() { + if (this._priv_contentInfos === null) { + return; + } + var _this$_priv_contentIn18 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn18.currentPeriod, + isDirectFile = _this$_priv_contentIn18.isDirectFile; -function refCount() { - return function refCountOperatorFunction(source) { - return source.lift(new RefCountOperator(source)); - }; -} -var RefCountOperator = /*@__PURE__*/ (function () { - function RefCountOperator(connectable) { - this.connectable = connectable; - } - RefCountOperator.prototype.call = function (subscriber, source) { - var connectable = this.connectable; - connectable._refCount++; - var refCounter = new RefCountSubscriber(subscriber, connectable); - var subscription = source.subscribe(refCounter); - if (!refCounter.closed) { - refCounter.connection = connectable.connect(); - } - return subscription; - }; - return RefCountOperator; -}()); -var RefCountSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(RefCountSubscriber, _super); - function RefCountSubscriber(destination, connectable) { - var _this = _super.call(this, destination) || this; - _this.connectable = connectable; - return _this; + if (isDirectFile && this._priv_mediaElementTrackChoiceManager !== null) { + return this._priv_mediaElementTrackChoiceManager.disableVideoTrack(); } - RefCountSubscriber.prototype._unsubscribe = function () { - var connectable = this.connectable; - if (!connectable) { - this.connection = null; - return; - } - this.connectable = null; - var refCount = connectable._refCount; - if (refCount <= 0) { - this.connection = null; - return; - } - connectable._refCount = refCount - 1; - if (refCount > 1) { - this.connection = null; - return; - } - var connection = this.connection; - var sharedConnection = connectable._connection; - this.connection = null; - if (sharedConnection && (!connection || sharedConnection === connection)) { - sharedConnection.unsubscribe(); - } - }; - return RefCountSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); -//# sourceMappingURL=refCount.js.map + if (this._priv_trackChoiceManager === null || currentPeriod === null) { + return; + } -/***/ }), + return this._priv_trackChoiceManager.disableVideoTrack(currentPeriod); + } + /** + * Returns the current list of preferred audio tracks, in preference order. + * @returns {Array.} + */ + ; -/***/ 2807: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.getPreferredAudioTracks = function getPreferredAudioTracks() { + return this._priv_preferredAudioTracks; + } + /** + * Returns the current list of preferred text tracks, in preference order. + * @returns {Array.} + */ + ; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "R": () => /* binding */ scan -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(979); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + _proto.getPreferredTextTracks = function getPreferredTextTracks() { + return this._priv_preferredTextTracks; + } + /** + * Returns the current list of preferred text tracks, in preference order. + * @returns {Array.} + */ + ; + _proto.getPreferredVideoTracks = function getPreferredVideoTracks() { + return this._priv_preferredVideoTracks; + } + /** + * Set the list of preferred audio tracks, in preference order. + * @param {Array.} tracks + * @param {boolean} shouldApply - `true` if those preferences should be + * applied on the currently loaded Period. `false` if it should only + * be applied to new content. + */ + ; -function scan(accumulator, seed) { - var hasSeed = false; - if (arguments.length >= 2) { - hasSeed = true; - } - return function scanOperatorFunction(source) { - return source.lift(new ScanOperator(accumulator, seed, hasSeed)); - }; -} -var ScanOperator = /*@__PURE__*/ (function () { - function ScanOperator(accumulator, seed, hasSeed) { - if (hasSeed === void 0) { - hasSeed = false; - } - this.accumulator = accumulator; - this.seed = seed; - this.hasSeed = hasSeed; + _proto.setPreferredAudioTracks = function setPreferredAudioTracks(tracks, shouldApply) { + if (shouldApply === void 0) { + shouldApply = false; } - ScanOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ScanSubscriber(subscriber, this.accumulator, this.seed, this.hasSeed)); - }; - return ScanOperator; -}()); -var ScanSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(ScanSubscriber, _super); - function ScanSubscriber(destination, accumulator, _seed, hasSeed) { - var _this = _super.call(this, destination) || this; - _this.accumulator = accumulator; - _this._seed = _seed; - _this.hasSeed = hasSeed; - _this.index = 0; - return _this; + + if (!Array.isArray(tracks)) { + throw new Error("Invalid `setPreferredAudioTracks` argument. " + "Should have been an Array."); } - Object.defineProperty(ScanSubscriber.prototype, "seed", { - get: function () { - return this._seed; - }, - set: function (value) { - this.hasSeed = true; - this._seed = value; - }, - enumerable: true, - configurable: true - }); - ScanSubscriber.prototype._next = function (value) { - if (!this.hasSeed) { - this.seed = value; - this.destination.next(value); - } - else { - return this._tryNext(value); - } - }; - ScanSubscriber.prototype._tryNext = function (value) { - var index = this.index++; - var result; - try { - result = this.accumulator(this.seed, value, index); - } - catch (err) { - this.destination.error(err); - } - this.seed = result; - this.destination.next(result); - }; - return ScanSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__/* .Subscriber */ .L)); -//# sourceMappingURL=scan.js.map + 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); + } + } + /** + * Set the list of preferred text tracks, in preference order. + * @param {Array.} tracks + * @param {boolean} shouldApply - `true` if those preferences should be + * applied on the currently loaded Periods. `false` if it should only + * be applied to new content. + */ + ; -/***/ 9095: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.setPreferredTextTracks = function setPreferredTextTracks(tracks, shouldApply) { + if (shouldApply === void 0) { + shouldApply = false; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "B": () => /* binding */ share -/* harmony export */ }); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1421); -/* harmony import */ var _refCount__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3018); -/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(211); -/** PURE_IMPORTS_START _multicast,_refCount,_Subject PURE_IMPORTS_END */ + if (!Array.isArray(tracks)) { + 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); + } + } + /** + * Set the list of preferred text tracks, in preference order. + * @param {Array.} tracks + * @param {boolean} shouldApply - `true` if those preferences should be + * applied on the currently loaded Period. `false` if it should only + * be applied to new content. + */ + ; -function shareSubjectFactory() { - return new _Subject__WEBPACK_IMPORTED_MODULE_0__/* .Subject */ .xQ(); -} -function share() { - return function (source) { return (0,_refCount__WEBPACK_IMPORTED_MODULE_1__/* .refCount */ .x)()((0,_multicast__WEBPACK_IMPORTED_MODULE_2__/* .multicast */ .O)(shareSubjectFactory)(source)); }; -} -//# sourceMappingURL=share.js.map + _proto.setPreferredVideoTracks = function setPreferredVideoTracks(tracks, shouldApply) { + if (shouldApply === void 0) { + shouldApply = false; + } + if (!Array.isArray(tracks)) { + throw new Error("Invalid `setPreferredVideoTracks` argument. " + "Should have been an Array."); + } -/***/ }), + this._priv_preferredVideoTracks = tracks; -/***/ 7006: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (this._priv_trackChoiceManager !== null) { + this._priv_trackChoiceManager.setPreferredVideoTracks(tracks, shouldApply); + } else if (this._priv_mediaElementTrackChoiceManager !== null) { + this._priv_mediaElementTrackChoiceManager.setPreferredVideoTracks(tracks, shouldApply); + } + } + /** + * @returns {Array.|null} + * @deprecated + */ + ; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "d": () => /* binding */ shareReplay -/* harmony export */ }); -/* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2135); -/** PURE_IMPORTS_START _ReplaySubject PURE_IMPORTS_END */ + _proto.getImageTrackData = function getImageTrackData() { + (0,warn_once/* default */.Z)("`getImageTrackData` is deprecated." + "Please use the `parseBifThumbnails` tool instead."); -function shareReplay(configOrBufferSize, windowTime, scheduler) { - var config; - if (configOrBufferSize && typeof configOrBufferSize === 'object') { - config = configOrBufferSize; - } - else { - config = { - bufferSize: configOrBufferSize, - windowTime: windowTime, - refCount: false, - scheduler: scheduler - }; + if (this._priv_contentInfos === null) { + return null; } - return function (source) { return source.lift(shareReplayOperator(config)); }; -} -function shareReplayOperator(_a) { - var _b = _a.bufferSize, bufferSize = _b === void 0 ? Number.POSITIVE_INFINITY : _b, _c = _a.windowTime, windowTime = _c === void 0 ? Number.POSITIVE_INFINITY : _c, useRefCount = _a.refCount, scheduler = _a.scheduler; - var subject; - var refCount = 0; - var subscription; - var hasError = false; - var isComplete = false; - return function shareReplayOperation(source) { - refCount++; - var innerSub; - if (!subject || hasError) { - hasError = false; - subject = new _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__/* .ReplaySubject */ .t(bufferSize, windowTime, scheduler); - innerSub = subject.subscribe(this); - subscription = source.subscribe({ - next: function (value) { subject.next(value); }, - error: function (err) { - hasError = true; - subject.error(err); - }, - complete: function () { - isComplete = true; - subscription = undefined; - subject.complete(); - }, - }); - } - else { - innerSub = subject.subscribe(this); - } - this.add(function () { - refCount--; - innerSub.unsubscribe(); - if (subscription && !isComplete && useRefCount && refCount === 0) { - subscription.unsubscribe(); - subscription = undefined; - subject = undefined; - } - }); - }; -} -//# sourceMappingURL=shareReplay.js.map + /* eslint-disable import/no-deprecated */ -/***/ }), + return this._priv_contentInfos.thumbnails; + /* eslint-enable import/no-deprecated */ + } + /** + * Get minimum seek-able position. + * @returns {number} + */ + ; -/***/ 3485: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto.getMinimumPosition = function getMinimumPosition() { + if (this._priv_contentInfos === null) { + return null; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "O": () => /* binding */ startWith -/* harmony export */ }); -/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9795); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7507); -/** PURE_IMPORTS_START _observable_concat,_util_isScheduler PURE_IMPORTS_END */ + if (this._priv_contentInfos.isDirectFile) { + return 0; + } + var manifest = this._priv_contentInfos.manifest; -function startWith() { - var array = []; - for (var _i = 0; _i < arguments.length; _i++) { - array[_i] = arguments[_i]; - } - var scheduler = array[array.length - 1]; - if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_0__/* .isScheduler */ .K)(scheduler)) { - array.pop(); - return function (source) { return (0,_observable_concat__WEBPACK_IMPORTED_MODULE_1__/* .concat */ .z)(array, source, scheduler); }; - } - else { - return function (source) { return (0,_observable_concat__WEBPACK_IMPORTED_MODULE_1__/* .concat */ .z)(array, source); }; + if (manifest !== null) { + return manifest.getMinimumPosition(); } -} -//# sourceMappingURL=startWith.js.map + return null; + } + /** + * Get maximum seek-able position. + * @returns {number} + */ + ; -/***/ }), + _proto.getMaximumPosition = function getMaximumPosition() { + if (this._priv_contentInfos === null) { + return null; + } -/***/ 6381: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var _this$_priv_contentIn19 = this._priv_contentInfos, + isDirectFile = _this$_priv_contentIn19.isDirectFile, + manifest = _this$_priv_contentIn19.manifest; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "w": () => /* binding */ switchMap -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(655); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5709); -/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4072); -/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7604); -/** PURE_IMPORTS_START tslib,_map,_observable_from,_innerSubscribe PURE_IMPORTS_END */ + if (isDirectFile) { + if (this.videoElement === null) { + throw new Error("Disposed player"); + } + return this.videoElement.duration; + } + if (manifest !== null) { + return manifest.getMaximumPosition(); + } + return null; + } + /** + * /!\ For demo use only! Do not touch! + * + * Returns every chunk buffered for a given buffer type. + * Returns `null` if no SegmentBuffer was created for this type of buffer. + * @param {string} bufferType + * @returns {Array.|null} + */ + ; -function switchMap(project, resultSelector) { - if (typeof resultSelector === 'function') { - return function (source) { return source.pipe(switchMap(function (a, i) { return (0,_observable_from__WEBPACK_IMPORTED_MODULE_0__/* .from */ .D)(project(a, i)).pipe((0,_map__WEBPACK_IMPORTED_MODULE_1__/* .map */ .U)(function (b, ii) { return resultSelector(a, b, i, ii); })); })); }; - } - return function (source) { return source.lift(new SwitchMapOperator(project)); }; -} -var SwitchMapOperator = /*@__PURE__*/ (function () { - function SwitchMapOperator(project) { - this.project = project; - } - SwitchMapOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SwitchMapSubscriber(subscriber, this.project)); - }; - return SwitchMapOperator; -}()); -var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_2__/* .__extends */ .ZT(SwitchMapSubscriber, _super); - function SwitchMapSubscriber(destination, project) { - var _this = _super.call(this, destination) || this; - _this.project = project; - _this.index = 0; - return _this; + _proto.__priv_getSegmentBufferContent = function __priv_getSegmentBufferContent(bufferType) { + if (this._priv_contentInfos === null || this._priv_contentInfos.segmentBuffersStore === null) { + return null; } - SwitchMapSubscriber.prototype._next = function (value) { - var result; - var index = this.index++; - try { - result = this.project(value, index); - } - catch (error) { - this.destination.error(error); - return; - } - this._innerSub(result); - }; - SwitchMapSubscriber.prototype._innerSub = function (result) { - var innerSubscription = this.innerSubscription; - if (innerSubscription) { - innerSubscription.unsubscribe(); - } - var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__/* .SimpleInnerSubscriber */ .IY(this); - var destination = this.destination; - destination.add(innerSubscriber); - this.innerSubscription = (0,_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__/* .innerSubscribe */ .ft)(result, innerSubscriber); - if (this.innerSubscription !== innerSubscriber) { - destination.add(this.innerSubscription); - } - }; - SwitchMapSubscriber.prototype._complete = function () { - var innerSubscription = this.innerSubscription; - if (!innerSubscription || innerSubscription.closed) { - _super.prototype._complete.call(this); - } - this.unsubscribe(); - }; - SwitchMapSubscriber.prototype._unsubscribe = function () { - this.innerSubscription = undefined; - }; - SwitchMapSubscriber.prototype.notifyComplete = function () { - this.innerSubscription = undefined; - if (this.isStopped) { - _super.prototype._complete.call(this); - } - }; - SwitchMapSubscriber.prototype.notifyNext = function (innerValue) { - this.destination.next(innerValue); - }; - return SwitchMapSubscriber; -}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__/* .SimpleOuterSubscriber */ .Ds)); -//# sourceMappingURL=switchMap.js.map + var segmentBufferStatus = this._priv_contentInfos.segmentBuffersStore.getStatus(bufferType); -/***/ }), + return segmentBufferStatus.type === "initialized" ? segmentBufferStatus.value.getInventory() : null; + } + /** + * Reset all state properties relative to a playing content. + */ + ; -/***/ 1198: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto._priv_cleanUpCurrentContentState = function _priv_cleanUpCurrentContentState() { + var _this4 = this; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "c": () => /* binding */ switchMapTo -/* harmony export */ }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6381); -/** PURE_IMPORTS_START _switchMap PURE_IMPORTS_END */ + var _a; -function switchMapTo(innerObservable, resultSelector) { - return resultSelector ? (0,_switchMap__WEBPACK_IMPORTED_MODULE_0__/* .switchMap */ .w)(function () { return innerObservable; }, resultSelector) : (0,_switchMap__WEBPACK_IMPORTED_MODULE_0__/* .switchMap */ .w)(function () { return innerObservable; }); -} -//# sourceMappingURL=switchMapTo.js.map + 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$.next(true); -/***/ }), + 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 = {}; // EME cleaning -/***/ 1015: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var freeUpContentLock = function freeUpContentLock() { + log/* default.debug */.Z.debug("Unlocking `contentLock`. Next content can begin."); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "q": () => /* binding */ take -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(655); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(979); -/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6565); -/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5631); -/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ + _this4._priv_contentLock$.next(false); + }; + if (!(0,is_null_or_undefined/* default */.Z)(this.videoElement)) { + clearEMESession(this.videoElement).subscribe(noop/* default */.Z, function (err) { + log/* default.error */.Z.error("API: An error arised when trying to clean-up the EME session:" + (err instanceof Error ? err.toString() : "Unknown Error")); + freeUpContentLock(); + }, function () { + log/* default.debug */.Z.debug("API: EME session cleaned-up with success!"); + freeUpContentLock(); + }); + } else { + 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; -function take(count) { - return function (source) { - if (count === 0) { - return (0,_observable_empty__WEBPACK_IMPORTED_MODULE_0__/* .empty */ .c)(); - } - else { - return source.lift(new TakeOperator(count)); - } - }; -} -var TakeOperator = /*@__PURE__*/ (function () { - function TakeOperator(total) { - this.total = total; - if (this.total < 0) { - throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_1__/* .ArgumentOutOfRangeError */ .W; - } - } - TakeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TakeSubscriber(subscriber, this.total)); - }; - return TakeOperator; -}()); -var TakeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_2__/* .__extends */ .ZT(TakeSubscriber, _super); - function TakeSubscriber(destination, total) { - var _this = _super.call(this, destination) || this; - _this.total = total; - _this.count = 0; - return _this; - } - TakeSubscriber.prototype._next = function (value) { - var total = this.total; - var count = ++this.count; - if (count <= total) { - this.destination.next(value); - if (count === total) { - this.destination.complete(); - this.unsubscribe(); - } - } - }; - return TakeSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__/* .Subscriber */ .L)); -//# sourceMappingURL=take.js.map + case "stream-event-skip": + this.trigger("streamEventSkip", event.value); + break; + case "activePeriodChanged": + this._priv_onActivePeriodChanged(event.value); -/***/ }), + break; -/***/ 1558: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + case "periodStreamReady": + this._priv_onPeriodStreamReady(event.value); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "R": () => /* binding */ takeUntil -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(655); -/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7604); -/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + break; + case "periodStreamCleared": + this._priv_onPeriodStreamCleared(event.value); -function takeUntil(notifier) { - return function (source) { return source.lift(new TakeUntilOperator(notifier)); }; -} -var TakeUntilOperator = /*@__PURE__*/ (function () { - function TakeUntilOperator(notifier) { - this.notifier = notifier; - } - TakeUntilOperator.prototype.call = function (subscriber, source) { - var takeUntilSubscriber = new TakeUntilSubscriber(subscriber); - var notifierSubscription = (0,_innerSubscribe__WEBPACK_IMPORTED_MODULE_0__/* .innerSubscribe */ .ft)(this.notifier, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_0__/* .SimpleInnerSubscriber */ .IY(takeUntilSubscriber)); - if (notifierSubscription && !takeUntilSubscriber.seenValue) { - takeUntilSubscriber.add(notifierSubscription); - return source.subscribe(takeUntilSubscriber); - } - return takeUntilSubscriber; - }; - return TakeUntilOperator; -}()); -var TakeUntilSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_1__/* .__extends */ .ZT(TakeUntilSubscriber, _super); - function TakeUntilSubscriber(destination) { - var _this = _super.call(this, destination) || this; - _this.seenValue = false; - return _this; - } - TakeUntilSubscriber.prototype.notifyNext = function () { - this.seenValue = true; - this.complete(); - }; - TakeUntilSubscriber.prototype.notifyComplete = function () { - }; - return TakeUntilSubscriber; -}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_0__/* .SimpleOuterSubscriber */ .Ds)); -//# sourceMappingURL=takeUntil.js.map + break; + case "reloading-media-source": + this._priv_onReloadingMediaSource(); -/***/ }), + break; -/***/ 3068: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + case "representationChange": + this._priv_onRepresentationChange(event.value); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "b": () => /* binding */ tap -/* harmony export */ }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(979); -/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3306); -/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4156); -/** PURE_IMPORTS_START tslib,_Subscriber,_util_noop,_util_isFunction PURE_IMPORTS_END */ + break; + case "adaptationChange": + this._priv_onAdaptationChange(event.value); + break; + case "bitrateEstimationChange": + this._priv_onBitrateEstimationChange(event.value); -function tap(nextOrObserver, error, complete) { - return function tapOperatorFunction(source) { - return source.lift(new DoOperator(nextOrObserver, error, complete)); - }; -} -var DoOperator = /*@__PURE__*/ (function () { - function DoOperator(nextOrObserver, error, complete) { - this.nextOrObserver = nextOrObserver; - this.error = error; - this.complete = complete; - } - DoOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TapSubscriber(subscriber, this.nextOrObserver, this.error, this.complete)); - }; - return DoOperator; -}()); -var TapSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__/* .__extends */ .ZT(TapSubscriber, _super); - function TapSubscriber(destination, observerOrNext, error, complete) { - var _this = _super.call(this, destination) || this; - _this._tapNext = _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; - _this._tapError = _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; - _this._tapComplete = _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; - _this._tapError = error || _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; - _this._tapComplete = complete || _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; - if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_2__/* .isFunction */ .m)(observerOrNext)) { - _this._context = _this; - _this._tapNext = observerOrNext; - } - else if (observerOrNext) { - _this._context = observerOrNext; - _this._tapNext = observerOrNext.next || _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; - _this._tapError = observerOrNext.error || _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; - _this._tapComplete = observerOrNext.complete || _util_noop__WEBPACK_IMPORTED_MODULE_1__/* .noop */ .Z; - } - return _this; - } - TapSubscriber.prototype._next = function (value) { - try { - this._tapNext.call(this._context, value); - } - catch (err) { - this.destination.error(err); - return; - } - this.destination.next(value); - }; - TapSubscriber.prototype._error = function (err) { - try { - this._tapError.call(this._context, err); - } - catch (err) { - this.destination.error(err); - return; - } - this.destination.error(err); - }; - TapSubscriber.prototype._complete = function () { - try { - this._tapComplete.call(this._context); - } - catch (err) { - this.destination.error(err); - return; + 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; } - return this.destination.complete(); - }; - return TapSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__/* .Subscriber */ .L)); -//# sourceMappingURL=tap.js.map + this._priv_contentInfos.segmentBuffersStore = event.value.segmentBuffersStore; + break; -/***/ }), + case "decipherabilityUpdate": + this.trigger("decipherabilityUpdate", event.value); + break; -/***/ 3109: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + 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 -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "r": () => /* binding */ scheduleArray -/* harmony export */ }); -/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4379); -/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3884); -/** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ + var _event$value = event.value, + content = _event$value.content, + segmentData = _event$value.segmentData; -function scheduleArray(input, scheduler) { - return new _Observable__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (subscriber) { - var sub = new _Subscription__WEBPACK_IMPORTED_MODULE_1__/* .Subscription */ .w(); - var i = 0; - sub.add(scheduler.schedule(function () { - if (i === input.length) { - subscriber.complete(); - return; - } - subscriber.next(input[i++]); - if (!subscriber.closed) { - sub.add(this.schedule()); - } - })); - return sub; + 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 = formatError(error, { + defaultCode: "NONE", + defaultReason: "An unknown error stopped content playback." }); -} -//# sourceMappingURL=scheduleArray.js.map + formattedError.fatal = true; + if (this._priv_contentInfos !== null) { + this._priv_contentInfos.stop$.next(); -/***/ }), + this._priv_contentInfos.stop$.complete(); + } -/***/ 6114: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + this._priv_cleanUpCurrentContentState(); -"use strict"; + this._priv_currentError = formattedError; + log/* default.error */.Z.error("API: The player stopped because of an error:", error); -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "o": () => /* binding */ AsyncAction -}); + this._priv_setPlayerState(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 -// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js -var tslib_es6 = __webpack_require__(655); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscription.js + 1 modules -var Subscription = __webpack_require__(3884); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/Action.js -/** PURE_IMPORTS_START tslib,_Subscription PURE_IMPORTS_END */ + if (this._priv_currentError === formattedError) { + this.trigger("error", formattedError); + } + } + /** + * Triggered when the playback Observable completes. + * Clean-up ressources and signal that the content has ended. + */ + ; + + _proto._priv_onPlaybackFinished = function _priv_onPlaybackFinished() { + log/* default.info */.Z.info("API: Previous playback finished. Stopping and cleaning-up..."); -var Action = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(Action, _super); - function Action(scheduler, work) { - return _super.call(this) || this; + if (this._priv_contentInfos !== null) { + this._priv_contentInfos.stop$.next(); + + this._priv_contentInfos.stop$.complete(); } - Action.prototype.schedule = function (state, delay) { - if (delay === void 0) { - delay = 0; - } - return this; - }; - return Action; -}(Subscription/* Subscription */.w)); -//# sourceMappingURL=Action.js.map + this._priv_cleanUpCurrentContentState(); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsyncAction.js -/** PURE_IMPORTS_START tslib,_Action PURE_IMPORTS_END */ + this._priv_setPlayerState(PLAYER_STATES.ENDED); + } + /** + * 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 = formatError(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 + */ + ; -var AsyncAction = /*@__PURE__*/ (function (_super) { - 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; + _proto._priv_onManifestReady = function _priv_onManifestReady(_ref2) { + 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; } - AsyncAction.prototype.schedule = function (state, delay) { - 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 = this.id || this.requestAsyncId(scheduler, this.id, delay); - return this; - }; - AsyncAction.prototype.requestAsyncId = function (scheduler, id, delay) { - if (delay === void 0) { - delay = 0; - } - return 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; - } - 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 = undefined; - try { - this.work(state); - } - catch (e) { - errored = true; - errorValue = !!e && e || new Error(e); - } - if (errored) { - this.unsubscribe(); - return errorValue; - } - }; - AsyncAction.prototype._unsubscribe = function () { - var id = this.id; - var scheduler = this.scheduler; - var actions = scheduler.actions; - var index = actions.indexOf(this); - this.work = null; - this.state = null; - this.pending = false; - this.scheduler = null; - if (index !== -1) { - actions.splice(index, 1); - } - if (id != null) { - this.id = this.recycleAsyncId(scheduler, id, null); - } - this.delay = null; - }; - return AsyncAction; -}(Action)); -//# sourceMappingURL=AsyncAction.js.map + contentInfos.manifest = manifest; + this._priv_lastContentPlaybackInfos.manifest = manifest; + var initialAudioTrack = contentInfos.initialAudioTrack, + initialTextTrack = contentInfos.initialTextTrack; + this._priv_trackChoiceManager = new TrackChoiceManager(); + var preferredAudioTracks = initialAudioTrack === undefined ? this._priv_preferredAudioTracks : [initialAudioTrack]; + this._priv_trackChoiceManager.setPreferredAudioTracks(preferredAudioTracks, true); -/***/ }), + var preferredTextTracks = initialTextTrack === undefined ? this._priv_preferredTextTracks : [initialTextTrack]; -/***/ 2980: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + this._priv_trackChoiceManager.setPreferredTextTracks(preferredTextTracks, true); -"use strict"; + this._priv_trackChoiceManager.setPreferredVideoTracks(this._priv_preferredVideoTracks, true); -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "v": () => /* binding */ AsyncScheduler -}); + (0,event_emitter/* fromEvent */.R)(manifest, "manifestUpdate").pipe((0,takeUntil/* takeUntil */.R)(contentInfos.stop$)).subscribe(function () { + // Update the tracks chosen if it changed + if (_this5._priv_trackChoiceManager !== null) { + _this5._priv_trackChoiceManager.update(); + } + }); + } + /** + * Triggered each times the current Period Changed. + * Store and emit initial state for the Period. + * + * @param {Object} value + */ + ; -// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js -var tslib_es6 = __webpack_require__(655); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/Scheduler.js -var Scheduler = /*@__PURE__*/ (function () { - function Scheduler(SchedulerAction, now) { - if (now === void 0) { - now = Scheduler.now; - } - this.SchedulerAction = SchedulerAction; - this.now = now; - } - Scheduler.prototype.schedule = function (work, delay, state) { - if (delay === void 0) { - delay = 0; - } - return new this.SchedulerAction(this, work).schedule(state, delay); - }; - Scheduler.now = function () { return Date.now(); }; - return Scheduler; -}()); + _proto._priv_onActivePeriodChanged = function _priv_onActivePeriodChanged(_ref3) { + var period = _ref3.period; -//# sourceMappingURL=Scheduler.js.map + var _a, _b, _c, _d, _e, _f; -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/scheduler/AsyncScheduler.js -/** PURE_IMPORTS_START tslib,_Scheduler PURE_IMPORTS_END */ + if (this._priv_contentInfos === null) { + log/* default.error */.Z.error("API: The active period changed but no content is loaded"); + return; + } + this._priv_contentInfos.currentPeriod = period; -var AsyncScheduler = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(AsyncScheduler, _super); - function AsyncScheduler(SchedulerAction, now) { - if (now === void 0) { - now = Scheduler.now; - } - var _this = _super.call(this, SchedulerAction, function () { - if (AsyncScheduler.delegate && AsyncScheduler.delegate !== _this) { - return AsyncScheduler.delegate.now(); - } - else { - return now(); - } - }) || this; - _this.actions = []; - _this.active = false; - _this.scheduled = undefined; - return _this; + if (this._priv_contentEventsMemory.periodChange !== period) { + this._priv_contentEventsMemory.periodChange = period; + this.trigger("periodChange", period); } - AsyncScheduler.prototype.schedule = function (work, delay, state) { - if (delay === void 0) { - delay = 0; - } - if (AsyncScheduler.delegate && AsyncScheduler.delegate !== this) { - return AsyncScheduler.delegate.schedule(work, delay, state); - } - else { - return _super.prototype.schedule.call(this, work, delay, state); - } - }; - 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 + this.trigger("availableAudioTracksChange", this.getAvailableAudioTracks()); + this.trigger("availableTextTracksChange", this.getAvailableTextTracks()); + this.trigger("availableVideoTracksChange", this.getAvailableVideoTracks()); // 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); -/***/ 964: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var videoTrack = this._priv_trackChoiceManager.getChosenVideoTrack(period); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "P": () => /* binding */ async -/* harmony export */ }); -/* unused harmony export asyncScheduler */ -/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6114); -/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2980); -/** PURE_IMPORTS_START _AsyncAction,_AsyncScheduler PURE_IMPORTS_END */ + this.trigger("audioTrackChange", audioTrack); + this.trigger("textTrackChange", textTrack); + this.trigger("videoTrackChange", videoTrack); + } else { + this.trigger("audioTrackChange", null); + this.trigger("textTrackChange", null); + this.trigger("videoTrackChange", null); + } + this._priv_triggerAvailableBitratesChangeEvent("availableAudioBitratesChange", this.getAvailableAudioBitrates()); -var asyncScheduler = /*@__PURE__*/ new _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__/* .AsyncScheduler */ .v(_AsyncAction__WEBPACK_IMPORTED_MODULE_1__/* .AsyncAction */ .o); -var async = asyncScheduler; -//# sourceMappingURL=async.js.map + 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); -/***/ 999: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + 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; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "hZ": () => /* binding */ iterator -/* harmony export */ }); -/* unused harmony exports getSymbolIterator, $$iterator */ -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function getSymbolIterator() { - if (typeof Symbol !== 'function' || !Symbol.iterator) { - return '@@iterator'; - } - return Symbol.iterator; -} -var iterator = /*@__PURE__*/ getSymbolIterator(); -var $$iterator = (/* unused pure expression or super */ null && (iterator)); -//# sourceMappingURL=iterator.js.map + this._priv_triggerCurrentBitrateChangeEvent("videoBitrateChange", videoBitrate); + } + /** + * Triggered each times a new "PeriodStream" is ready. + * Choose the right Adaptation for the Period and emit it. + * @param {Object} value + */ + ; + _proto._priv_onPeriodStreamReady = function _priv_onPeriodStreamReady(value) { + var type = value.type, + period = value.period, + adaptation$ = value.adaptation$; -/***/ }), + switch (type) { + case "video": + if (this._priv_trackChoiceManager === null) { + log/* default.error */.Z.error("API: TrackChoiceManager not instanciated for a new video period"); + adaptation$.next(null); + } else { + this._priv_trackChoiceManager.addPeriod(type, period, adaptation$); -/***/ 5050: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + this._priv_trackChoiceManager.setInitialVideoTrack(period); + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "L": () => /* binding */ observable -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var observable = /*@__PURE__*/ (function () { return typeof Symbol === 'function' && Symbol.observable || '@@observable'; })(); -//# sourceMappingURL=observable.js.map + break; + case "audio": + if (this._priv_trackChoiceManager === null) { + log/* default.error */.Z.error("API: TrackChoiceManager not instanciated for a new " + type + " period"); + adaptation$.next(null); + } else { + this._priv_trackChoiceManager.addPeriod(type, period, adaptation$); -/***/ }), + this._priv_trackChoiceManager.setInitialAudioTrack(period); + } -/***/ 3142: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + break; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "b": () => /* binding */ rxSubscriber -/* harmony export */ }); -/* unused harmony export $$rxSubscriber */ -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var rxSubscriber = /*@__PURE__*/ (function () { - return typeof Symbol === 'function' - ? /*@__PURE__*/ Symbol('rxSubscriber') - : '@@rxSubscriber_' + /*@__PURE__*/ Math.random(); -})(); -var $$rxSubscriber = (/* unused pure expression or super */ null && (rxSubscriber)); -//# sourceMappingURL=rxSubscriber.js.map + case "text": + if (this._priv_trackChoiceManager === null) { + log/* default.error */.Z.error("API: TrackChoiceManager not instanciated for a new " + type + " period"); + adaptation$.next(null); + } else { + this._priv_trackChoiceManager.addPeriod(type, period, adaptation$); + + this._priv_trackChoiceManager.setInitialTextTrack(period); + } + break; -/***/ }), + default: + var adaptations = period.adaptations[type]; -/***/ 6565: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (!(0,is_null_or_undefined/* default */.Z)(adaptations) && adaptations.length > 0) { + adaptation$.next(adaptations[0]); + } else { + adaptation$.next(null); + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "W": () => /* binding */ ArgumentOutOfRangeError -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var ArgumentOutOfRangeErrorImpl = /*@__PURE__*/ (function () { - function ArgumentOutOfRangeErrorImpl() { - Error.call(this); - this.message = 'argument out of range'; - this.name = 'ArgumentOutOfRangeError'; - return this; + break; } - ArgumentOutOfRangeErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); - return ArgumentOutOfRangeErrorImpl; -})(); -var ArgumentOutOfRangeError = ArgumentOutOfRangeErrorImpl; -//# sourceMappingURL=ArgumentOutOfRangeError.js.map + } + /** + * Triggered each times we "remove" a PeriodStream. + * @param {Object} value + */ + ; + _proto._priv_onPeriodStreamCleared = function _priv_onPeriodStreamCleared(value) { + var type = value.type, + period = value.period; // 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); + } -/***/ 1016: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + break; + } // Clean-up stored Representation and Adaptation information -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "N": () => /* binding */ ObjectUnsubscribedError -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var ObjectUnsubscribedErrorImpl = /*@__PURE__*/ (function () { - function ObjectUnsubscribedErrorImpl() { - Error.call(this); - this.message = 'object unsubscribed'; - this.name = 'ObjectUnsubscribedError'; - return this; + + if (this._priv_contentInfos === null) { + return; } - ObjectUnsubscribedErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); - return ObjectUnsubscribedErrorImpl; -})(); -var ObjectUnsubscribedError = ObjectUnsubscribedErrorImpl; -//# sourceMappingURL=ObjectUnsubscribedError.js.map + var _this$_priv_contentIn20 = this._priv_contentInfos, + activeAdaptations = _this$_priv_contentIn20.activeAdaptations, + activeRepresentations = _this$_priv_contentIn20.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]; -/***/ 1644: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (Object.keys(activePeriodAdaptations).length === 0) { + delete activeAdaptations[period.id]; + } + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "z": () => /* binding */ hostReportError -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function hostReportError(err) { - setTimeout(function () { throw err; }, 0); -} -//# sourceMappingURL=hostReportError.js.map + if (!(0,is_null_or_undefined/* default */.Z)(activeRepresentations) && !(0,is_null_or_undefined/* default */.Z)(activeRepresentations[period.id])) { + var activePeriodRepresentations = activeRepresentations[period.id]; + delete activePeriodRepresentations[type]; + if (Object.keys(activePeriodRepresentations).length === 0) { + delete activeRepresentations[period.id]; + } + } + } + /** + * 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; + } -/***/ 3608: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + 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} value + */ + ; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "y": () => /* binding */ identity -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function identity(x) { - return x; -} -//# sourceMappingURL=identity.js.map + _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; + } // lazily create this._priv_contentInfos.activeAdaptations -/***/ }), -/***/ 9026: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (this._priv_contentInfos.activeAdaptations === null) { + this._priv_contentInfos.activeAdaptations = {}; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "k": () => /* binding */ isArray -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var isArray = /*@__PURE__*/ (function () { return Array.isArray || (function (x) { return x && typeof x.length === 'number'; }); })(); -//# sourceMappingURL=isArray.js.map + var _this$_priv_contentIn21 = this._priv_contentInfos, + activeAdaptations = _this$_priv_contentIn21.activeAdaptations, + currentPeriod = _this$_priv_contentIn21.currentPeriod; + var activePeriodAdaptations = activeAdaptations[period.id]; + if ((0,is_null_or_undefined/* default */.Z)(activePeriodAdaptations)) { + var _activeAdaptations$pe; -/***/ }), + activeAdaptations[period.id] = (_activeAdaptations$pe = {}, _activeAdaptations$pe[type] = adaptation, _activeAdaptations$pe); + } else { + activePeriodAdaptations[type] = adaptation; + } -/***/ 9217: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (this._priv_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); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "z": () => /* binding */ isArrayLike -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var isArrayLike = (function (x) { return x && typeof x.length === 'number' && typeof x !== 'function'; }); -//# sourceMappingURL=isArrayLike.js.map + this.trigger("audioTrackChange", audioTrack); + var availableAudioBitrates = this.getAvailableAudioBitrates(); + this._priv_triggerAvailableBitratesChangeEvent("availableAudioBitratesChange", availableAudioBitrates); -/***/ }), + break; -/***/ 9914: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + case "text": + var textTrack = this._priv_trackChoiceManager.getChosenTextTrack(currentPeriod); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "J": () => /* binding */ isDate -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function isDate(value) { - return value instanceof Date && !isNaN(+value); -} -//# sourceMappingURL=isDate.js.map + this.trigger("textTrackChange", textTrack); + break; + case "video": + var videoTrack = this._priv_trackChoiceManager.getChosenVideoTrack(currentPeriod); -/***/ }), + this.trigger("videoTrackChange", videoTrack); + var availableVideoBitrates = this.getAvailableVideoBitrates(); -/***/ 4156: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + this._priv_triggerAvailableBitratesChangeEvent("availableVideoBitratesChange", availableVideoBitrates); -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "m": () => /* binding */ isFunction -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function isFunction(x) { - return typeof x === 'function'; -} -//# sourceMappingURL=isFunction.js.map + break; + } + } + } + /** + * Triggered each times a new Representation is considered during playback. + * + * Store given Representation and emit it if from the current Period. + * + * @param {Object} obj + */ + ; + _proto._priv_onRepresentationChange = function _priv_onRepresentationChange(_ref5) { + var type = _ref5.type, + period = _ref5.period, + representation = _ref5.representation; -/***/ }), + var _a; -/***/ 5812: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (this._priv_contentInfos === null) { + log/* default.error */.Z.error("API: The representations changed but no content is loaded"); + return; + } // lazily create this._priv_contentInfos.activeRepresentations -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "k": () => /* binding */ isNumeric -/* harmony export */ }); -/* harmony import */ var _isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9026); -/** PURE_IMPORTS_START _isArray PURE_IMPORTS_END */ -function isNumeric(val) { - return !(0,_isArray__WEBPACK_IMPORTED_MODULE_0__/* .isArray */ .k)(val) && (val - parseFloat(val) + 1) >= 0; -} -//# sourceMappingURL=isNumeric.js.map + if (this._priv_contentInfos.activeRepresentations === null) { + this._priv_contentInfos.activeRepresentations = {}; + } + var _this$_priv_contentIn22 = this._priv_contentInfos, + activeRepresentations = _this$_priv_contentIn22.activeRepresentations, + currentPeriod = _this$_priv_contentIn22.currentPeriod; + var activePeriodRepresentations = activeRepresentations[period.id]; -/***/ }), + if ((0,is_null_or_undefined/* default */.Z)(activePeriodRepresentations)) { + var _activeRepresentation; -/***/ 2009: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + activeRepresentations[period.id] = (_activeRepresentation = {}, _activeRepresentation[type] = representation, _activeRepresentation); + } else { + activePeriodRepresentations[type] = representation; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "K": () => /* binding */ isObject -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function isObject(x) { - return x !== null && typeof x === 'object'; -} -//# sourceMappingURL=isObject.js.map + var bitrate = (_a = representation === null || representation === void 0 ? void 0 : representation.bitrate) !== null && _a !== void 0 ? _a : -1; + if (!(0,is_null_or_undefined/* default */.Z)(period) && currentPeriod !== null && currentPeriod.id === period.id) { + if (type === "video") { + this._priv_triggerCurrentBitrateChangeEvent("videoBitrateChange", bitrate); + } else if (type === "audio") { + this._priv_triggerCurrentBitrateChangeEvent("audioBitrateChange", bitrate); + } + } + } + /** + * Triggered each time a bitrate estimate is calculated. + * + * Emit it. + * + * @param {Object} value + */ + ; -/***/ }), + _proto._priv_onBitrateEstimationChange = function _priv_onBitrateEstimationChange(_ref6) { + var type = _ref6.type, + bitrate = _ref6.bitrate; -/***/ 336: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (bitrate !== undefined) { + this._priv_bitrateInfos.lastBitrates[type] = bitrate; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "t": () => /* binding */ isPromise -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function isPromise(value) { - return !!value && typeof value.subscribe !== 'function' && typeof value.then === 'function'; -} -//# sourceMappingURL=isPromise.js.map + this.trigger("bitrateEstimationChange", { + type: type, + bitrate: bitrate + }); + } + /** + * Triggered each time the videoElement alternates between play and pause. + * + * Emit the info through the right Subject. + * + * @param {Boolean} isPlaying + */ + ; + _proto._priv_onPlayPauseNext = function _priv_onPlayPauseNext(isPlaying) { + if (this.videoElement === null) { + throw new Error("Disposed player"); + } -/***/ }), + this._priv_playing$.next(isPlaying); + } + /** + * Triggered each time a textTrack is added to the video DOM Element. + * + * Trigger the right Player Event. + * + * @param {Array.} tracks + */ + ; -/***/ 7507: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + _proto._priv_onNativeTextTracksNext = function _priv_onNativeTextTracksNext(tracks) { + this.trigger("nativeTextTracksChange", tracks); + } + /** + * Triggered each time the player state updates. + * + * Trigger the right Player Event. + * + * @param {string} newState + */ + ; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "K": () => /* binding */ isScheduler -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function isScheduler(value) { - return value && typeof value.schedule === 'function'; -} -//# sourceMappingURL=isScheduler.js.map + _proto._priv_setPlayerState = function _priv_setPlayerState(newState) { + if (this.state !== newState) { + this.state = newState; + log/* default.info */.Z.info("API: playerStateChange event", newState); + this.trigger("playerStateChange", newState); + } + } + /** + * Triggered each time a new clock tick object is emitted. + * + * Trigger the right Player Event + * + * @param {Object} clockTick + */ + ; + _proto._priv_triggerPositionUpdate = function _priv_triggerPositionUpdate(clockTick) { + var _a; -/***/ }), + if (this._priv_contentInfos === null) { + log/* default.warn */.Z.warn("API: Cannot perform time update: no content loaded."); + return; + } -/***/ 3306: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (this.state === PLAYER_STATES.RELOADING) { + return; + } -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => /* binding */ noop -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function noop() { } -//# sourceMappingURL=noop.js.map + var _this$_priv_contentIn23 = this._priv_contentInfos, + isDirectFile = _this$_priv_contentIn23.isDirectFile, + manifest = _this$_priv_contentIn23.manifest; + if (!isDirectFile && manifest === null || (0,is_null_or_undefined/* default */.Z)(clockTick)) { + return; + } -/***/ }), + this._priv_lastContentPlaybackInfos.lastPlaybackPosition = clockTick.position; + var maximumPosition = manifest !== null ? manifest.getMaximumPosition() : undefined; + var positionData = { + position: clockTick.position, + duration: clockTick.duration, + playbackRate: clockTick.playbackRate, + maximumBufferTime: maximumPosition, + // TODO fix higher up? + bufferGap: isFinite(clockTick.bufferGap) ? clockTick.bufferGap : 0 + }; -/***/ 7843: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (manifest !== null && maximumPosition !== undefined && manifest.isLive && clockTick.position > 0) { + var ast = (_a = manifest.availabilityStartTime) !== null && _a !== void 0 ? _a : 0; + positionData.wallClockTime = clockTick.position + ast; + positionData.liveGap = maximumPosition - clockTick.position; + } -"use strict"; + this.trigger("positionUpdate", positionData); + } + /** + * Trigger one of the "availableBitratesChange" event only if it changed from + * the previously stored value. + * @param {string} event + * @param {Array.} newVal + */ + ; -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "s": () => /* binding */ subscribeTo -}); + _proto._priv_triggerAvailableBitratesChangeEvent = function _priv_triggerAvailableBitratesChangeEvent(event, newVal) { + var prevVal = this._priv_contentEventsMemory[event]; -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeToArray.js -var subscribeToArray = __webpack_require__(6900); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/hostReportError.js -var hostReportError = __webpack_require__(1644); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeToPromise.js -/** PURE_IMPORTS_START _hostReportError PURE_IMPORTS_END */ + if (prevVal === undefined || (0,are_arrays_of_numbers_equal/* default */.Z)(newVal, prevVal)) { + this._priv_contentEventsMemory[event] = newVal; + this.trigger(event, newVal); + } + } + /** + * Trigger one of the "bitrateChange" event only if it changed from the + * previously stored value. + * @param {string} event + * @param {number} newVal + */ + ; -var subscribeToPromise = function (promise) { - return function (subscriber) { - promise.then(function (value) { - if (!subscriber.closed) { - subscriber.next(value); - subscriber.complete(); - } - }, function (err) { return subscriber.error(err); }) - .then(null, hostReportError/* hostReportError */.z); - return subscriber; - }; -}; -//# sourceMappingURL=subscribeToPromise.js.map + _proto._priv_triggerCurrentBitrateChangeEvent = function _priv_triggerCurrentBitrateChangeEvent(event, newVal) { + if (newVal !== this._priv_contentEventsMemory[event]) { + this._priv_contentEventsMemory[event] = newVal; + this.trigger(event, newVal); + } + }; -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/symbol/iterator.js -var symbol_iterator = __webpack_require__(999); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeToIterable.js -/** PURE_IMPORTS_START _symbol_iterator PURE_IMPORTS_END */ + _proto._priv_getCurrentRepresentations = function _priv_getCurrentRepresentations() { + if (this._priv_contentInfos === null) { + return null; + } -var subscribeToIterable = function (iterable) { - return function (subscriber) { - var iterator = iterable[symbol_iterator/* iterator */.hZ](); - do { - var item = void 0; - try { - item = iterator.next(); - } - catch (err) { - subscriber.error(err); - return subscriber; - } - if (item.done) { - subscriber.complete(); - break; - } - subscriber.next(item.value); - if (subscriber.closed) { - break; - } - } while (true); - if (typeof iterator.return === 'function') { - subscriber.add(function () { - if (iterator.return) { - iterator.return(); - } - }); - } - return subscriber; - }; -}; -//# sourceMappingURL=subscribeToIterable.js.map + var _this$_priv_contentIn24 = this._priv_contentInfos, + currentPeriod = _this$_priv_contentIn24.currentPeriod, + activeRepresentations = _this$_priv_contentIn24.activeRepresentations; -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/symbol/observable.js -var observable = __webpack_require__(5050); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeToObservable.js -/** PURE_IMPORTS_START _symbol_observable PURE_IMPORTS_END */ + if (currentPeriod === null || activeRepresentations === null || (0,is_null_or_undefined/* default */.Z)(activeRepresentations[currentPeriod.id])) { + return null; + } -var subscribeToObservable = function (obj) { - return function (subscriber) { - var obs = obj[observable/* observable */.L](); - if (typeof obs.subscribe !== 'function') { - throw new TypeError('Provided object does not correctly implement Symbol.observable'); - } - else { - return obs.subscribe(subscriber); - } - }; -}; -//# sourceMappingURL=subscribeToObservable.js.map + return activeRepresentations[currentPeriod.id]; + }; -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isArrayLike.js -var isArrayLike = __webpack_require__(9217); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isPromise.js -var isPromise = __webpack_require__(336); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/isObject.js -var isObject = __webpack_require__(2009); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeTo.js -/** PURE_IMPORTS_START _subscribeToArray,_subscribeToPromise,_subscribeToIterable,_subscribeToObservable,_isArrayLike,_isPromise,_isObject,_symbol_iterator,_symbol_observable PURE_IMPORTS_END */ + (0,createClass/* default */.Z)(Player, null, [{ + key: "ErrorTypes", + get: function get() { + return error_codes/* ErrorTypes */.ZB; + } + /** All possible Error codes emitted by the RxPlayer. */ + + }, { + key: "ErrorCodes", + get: function get() { + return error_codes/* ErrorCodes */.SM; + } + /** + * Current log level. + * Update current log level. + * Should be either (by verbosity ascending): + * - "NONE" + * - "ERROR" + * - "WARNING" + * - "INFO" + * - "DEBUG" + * Any other value will be translated to "NONE". + */ + }, { + key: "LogLevel", + get: function get() { + return log/* default.getLevel */.Z.getLevel(); + }, + set: function set(logLevel) { + log/* default.setLevel */.Z.setLevel(logLevel); + } + }]); + return Player; +}(event_emitter/* default */.Z); +Player.version = +/* PLAYER_VERSION */ +"3.24.0"; +/* harmony default export */ const public_api = (Player); +;// CONCATENATED MODULE: ./src/core/api/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 */ const api = (public_api); +// EXTERNAL MODULE: ./src/features/features_object.ts +var features_object = __webpack_require__(7273); +;// CONCATENATED MODULE: ./src/features/initialize_features.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. + */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-var-requires */ +/** + * Selects the features to include based on environment variables. + * + * @param {Object} features + */ -var subscribeTo = function (result) { - if (!!result && typeof result[observable/* observable */.L] === 'function') { - return subscribeToObservable(result); - } - else if ((0,isArrayLike/* isArrayLike */.z)(result)) { - return (0,subscribeToArray/* subscribeToArray */.V)(result); - } - else if ((0,isPromise/* isPromise */.t)(result)) { - return subscribeToPromise(result); - } - else if (!!result && typeof result[symbol_iterator/* iterator */.hZ] === 'function') { - return subscribeToIterable(result); - } - else { - var value = (0,isObject/* isObject */.K)(result) ? 'an invalid object' : "'" + result + "'"; - var msg = "You provided " + value + " where a stream was expected." - + ' You can provide an Observable, Promise, Array, or Iterable.'; - throw new TypeError(msg); - } -}; -//# sourceMappingURL=subscribeTo.js.map +function initializeFeaturesObject() { + if (true) { + features_object/* default.emeManager */.Z.emeManager = __webpack_require__(1603)/* .default */ .ZP; + } + if (true) { + features_object/* default.imageBuffer */.Z.imageBuffer = __webpack_require__(7127)/* .default */ .Z; + features_object/* default.imageParser */.Z.imageParser = __webpack_require__(3203)/* .default */ .Z; + } // Feature switching the Native TextTrack implementation -/***/ }), -/***/ 6900: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + var HAS_NATIVE_MODE = true || 0; -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "V": () => /* binding */ subscribeToArray -/* harmony export */ }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -var subscribeToArray = function (array) { - return function (subscriber) { - for (var i = 0, len = array.length; i < len && !subscriber.closed; i++) { - subscriber.next(array[i]); - } - subscriber.complete(); - }; -}; -//# sourceMappingURL=subscribeToArray.js.map + if (true) { + features_object/* default.transports.smooth */.Z.transports.smooth = __webpack_require__(2339)/* .default */ .Z; + } + if (true) { + features_object/* default.transports.dash */.Z.transports.dash = __webpack_require__(1923)/* .default */ .Z; + } -/***/ }), + if (false) {} -/***/ 2080: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + if (false) {} -"use strict"; + if (HAS_NATIVE_MODE) { + features_object/* default.nativeTextTracksBuffer */.Z.nativeTextTracksBuffer = __webpack_require__(9059)/* .default */ .Z; -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "D": () => /* binding */ subscribeToResult -}); + if (true) { + features_object/* default.nativeTextTracksParsers.vtt */.Z.nativeTextTracksParsers.vtt = __webpack_require__(9405)/* .default */ .Z; + } -// EXTERNAL MODULE: ./node_modules/tslib/tslib.es6.js -var tslib_es6 = __webpack_require__(655); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Subscriber.js -var Subscriber = __webpack_require__(979); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/InnerSubscriber.js -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + if (true) { + features_object/* default.nativeTextTracksParsers.ttml */.Z.nativeTextTracksParsers.ttml = __webpack_require__(1570)/* .default */ .Z; + } + if (true) { + features_object/* default.nativeTextTracksParsers.sami */.Z.nativeTextTracksParsers.sami = __webpack_require__(1812)/* .default */ .Z; + } -var InnerSubscriber = /*@__PURE__*/ (function (_super) { - tslib_es6/* __extends */.ZT(InnerSubscriber, _super); - function InnerSubscriber(parent, outerValue, outerIndex) { - var _this = _super.call(this) || this; - _this.parent = parent; - _this.outerValue = outerValue; - _this.outerIndex = outerIndex; - _this.index = 0; - return _this; + if (true) { + features_object/* default.nativeTextTracksParsers.srt */.Z.nativeTextTracksParsers.srt = __webpack_require__(8057)/* .default */ .Z; } - InnerSubscriber.prototype._next = function (value) { - this.parent.notifyNext(this.outerValue, value, this.outerIndex, this.index++, this); - }; - InnerSubscriber.prototype._error = function (error) { - this.parent.notifyError(error, this); - this.unsubscribe(); - }; - InnerSubscriber.prototype._complete = function () { - this.parent.notifyComplete(this); - this.unsubscribe(); - }; - return InnerSubscriber; -}(Subscriber/* Subscriber */.L)); + } // Feature switching the HTML TextTrack implementation -//# sourceMappingURL=InnerSubscriber.js.map -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeTo.js + 3 modules -var subscribeTo = __webpack_require__(7843); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules -var Observable = __webpack_require__(4379); -;// CONCATENATED MODULE: ./node_modules/rxjs/_esm5/internal/util/subscribeToResult.js -/** PURE_IMPORTS_START _InnerSubscriber,_subscribeTo,_Observable PURE_IMPORTS_END */ + 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; + } -function subscribeToResult(outerSubscriber, result, outerValue, outerIndex, innerSubscriber) { - if (innerSubscriber === void 0) { - innerSubscriber = new InnerSubscriber(outerSubscriber, outerValue, outerIndex); + if (true) { + features_object/* default.htmlTextTracksParsers.ttml */.Z.htmlTextTracksParsers.ttml = __webpack_require__(7439)/* .default */ .Z; } - if (innerSubscriber.closed) { - return undefined; + + if (true) { + features_object/* default.htmlTextTracksParsers.srt */.Z.htmlTextTracksParsers.srt = __webpack_require__(8675)/* .default */ .Z; } - if (result instanceof Observable/* Observable */.y) { - return result.subscribe(innerSubscriber); + + if (true) { + features_object/* default.htmlTextTracksParsers.vtt */.Z.htmlTextTracksParsers.vtt = __webpack_require__(4099)/* .default */ .Z; } - return (0,subscribeTo/* subscribeTo */.s)(result)(innerSubscriber); + } + + if (true) { + var initDirectFile = __webpack_require__(8969)/* .default */ .Z; + + var mediaElementTrackChoiceManager = __webpack_require__(7794)/* .default */ .Z; + + features_object/* default.directfile */.Z.directfile = { + initDirectFile: initDirectFile, + mediaElementTrackChoiceManager: mediaElementTrackChoiceManager + }; + } } -//# sourceMappingURL=subscribeToResult.js.map +;// CONCATENATED MODULE: ./src/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. + */ +/** + * This file exports a Player class with a default feature set (depends on the + * environment variables set at build). + * + * This is the class used from a regular build. + */ -/***/ }), -/***/ 655: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + // set initial features according to environment variables -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "ZT": () => /* binding */ __extends -/* harmony export */ }); -/* unused harmony exports __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __createBinding, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); -}; - -function __extends(d, b) { - 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 }; - } -} - -function __createBinding(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -} - -function __exportStar(m, exports) { - for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) exports[p] = 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; -} - -function __spread() { - for (var ar = [], i = 0; i < arguments.length; i++) - ar = ar.concat(__read(arguments[i])); - return ar; -} - -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 __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; -}; - -function __importStar(mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; - result.default = 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; -} +initializeFeaturesObject(); +if (false) {} -/***/ }) +/* harmony default export */ const src = (api); +})(); -/******/ }); -/************************************************************************/ -/******/ // The module cache -/******/ var __webpack_module_cache__ = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ // Check if module is in cache -/******/ if(__webpack_module_cache__[moduleId]) { -/******/ return __webpack_module_cache__[moduleId].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 */ -/******/ (() => { -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = (module) => { -/******/ var getter = module && module.__esModule ? -/******/ () => module['default'] : -/******/ () => module; -/******/ __webpack_require__.d(getter, { a: getter }); -/******/ return getter; -/******/ }; -/******/ })(); -/******/ -/******/ /* webpack/runtime/define property getters */ -/******/ (() => { -/******/ // define getter functions for harmony exports -/******/ __webpack_require__.d = (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/global */ -/******/ (() => { -/******/ __webpack_require__.g = (function() { -/******/ if (typeof globalThis === 'object') return globalThis; -/******/ try { -/******/ return this || new Function('return this')(); -/******/ } catch (e) { -/******/ if (typeof window === 'object') return window; -/******/ } -/******/ })(); -/******/ })(); -/******/ -/******/ /* webpack/runtime/hasOwnProperty shorthand */ -/******/ (() => { -/******/ __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop) -/******/ })(); -/******/ -/************************************************************************/ -/******/ // module exports must be returned from runtime so entry inlining is disabled -/******/ // startup -/******/ // Load entry module and return exports -/******/ return __webpack_require__(1452); +__webpack_exports__ = __webpack_exports__.default; +/******/ return __webpack_exports__; /******/ })() -.default; +; }); \ No newline at end of file diff --git a/dist/rx-player.min.js b/dist/rx-player.min.js index 40bf993be8..745d54fe7b 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(()=>{var e={1506:e=>{e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}},8926:e=>{function t(e,t,n,r,i,a,o){try{var s=e[a](o),u=s.value}catch(e){return void n(e)}s.done?t(u):Promise.resolve(u).then(r,i)}e.exports=function(e){return function(){var n=this,r=arguments;return new Promise((function(i,a){var o=e.apply(n,r);function s(e){t(o,i,a,s,u,"next",e)}function u(e){t(o,i,a,s,u,"throw",e)}s(void 0)}))}}},9100:(e,t,n)=>{var r=n(9489),i=n(7067);function a(t,n,o){return i()?e.exports=a=Reflect.construct:e.exports=a=function(e,t,n){var i=[null];i.push.apply(i,t);var a=new(Function.bind.apply(e,i));return n&&r(a,n.prototype),a},a.apply(null,arguments)}e.exports=a},3913:e=>{function t(e,t){for(var n=0;n{function t(n){return e.exports=t=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},t(n)}e.exports=t},5354:e=>{e.exports=function(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}},430:e=>{e.exports=function(e){return-1!==Function.toString.call(e).indexOf("[native code]")}},7067:e=>{e.exports=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}},9489:e=>{function t(n,r){return e.exports=t=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},t(n,r)}e.exports=t},5957:(e,t,n)=>{var r=n(9754),i=n(9489),a=n(430),o=n(9100);function s(t){var n="function"==typeof Map?new Map:void 0;return e.exports=s=function(e){if(null===e||!a(e))return e;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==n){if(n.has(e))return n.get(e);n.set(e,t)}function t(){return o(e,arguments,r(this).constructor)}return t.prototype=Object.create(e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),i(t,e)},s(t)}e.exports=s},7757:(e,t,n)=>{e.exports=n(5666)},3774:(e,t,n)=>{"use strict";n.d(t,{DQ:()=>a,JJ:()=>s,cX:()=>u,w:()=>o});var r=n(1946),i=n(2203).Z?{}:window,a=i.HTMLElement,o=(0,r.Z)(i.VTTCue)?i.TextTrackCue:i.VTTCue,s=(0,r.Z)(i.MediaSource)?(0,r.Z)(i.MozMediaSource)?(0,r.Z)(i.WebKitMediaSource)?i.MSMediaSource:i.WebKitMediaSource:i.MozMediaSource:i.MediaSource,u={HAVE_NOTHING:0,HAVE_METADATA:1,HAVE_CURRENT_DATA:2,HAVE_FUTURE_DATA:3,HAVE_ENOUGH_DATA:4}},3666:(e,t,n)=>{"use strict";n.d(t,{kD:()=>s,fq:()=>a,YM:()=>o,vU:()=>u,G6:()=>c,SB:()=>d,op:()=>l});var r,i=n(2203),a=!i.Z&&!!window.MSInputMethodContext&&!!document.documentMode,o=!i.Z&&("Microsoft Internet Explorer"===navigator.appName||"Netscape"===navigator.appName&&/(Trident|Edge)\//.test(navigator.userAgent)),s=!i.Z&&-1!==navigator.userAgent.toLowerCase().indexOf("edg/"),u=!i.Z&&-1!==navigator.userAgent.toLowerCase().indexOf("firefox"),l=!i.Z&&/SamsungBrowser/.test(navigator.userAgent),c=!i.Z&&(Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>=0||"[object SafariRemoteNotification]"===(null===(r=window.safari)||void 0===r?void 0:r.pushNotification.toString())),d=!i.Z&&"string"==typeof navigator.platform&&/iPad|iPhone|iPod/.test(navigator.platform)},5767:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3887),i=n(3666);function a(e){if(i.vU){for(var t=e.textTracks,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:(e,t,n)=>{"use strict";n.d(t,{N:()=>B,Y:()=>j});var r,i=n(4944),a=n(8170),o=n(1410),s=n(3714),u=n(8117),l=n(3666),c=n(2203),d=n(5059),f=n(3913),p=n.n(f),h=n(9589),v=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 h.Z((function(t){return t(e._mediaKeys)}))},t.getConfiguration=function(){return this._configuration},p()(e,[{key:"keySystem",get:function(){return this._keyType}}]),e}(),m=n(5354),g=n.n(m),y=n(211),_=n(4370),b=n(1558),T=n(1959),E=n(1473);if(!c.Z){var w=window.MSMediaKeys;void 0!==w&&void 0!==w.prototype&&"function"==typeof w.isTypeSupported&&"function"==typeof w.prototype.createSession&&(r=w)}var S,k=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 y.xQ,n.closed=new h.Z((function(e){n._closeSession$.subscribe(e)})),n.update=function(e){return new h.Z((function(t,r){if(void 0===n._ss)return r("MediaKeySession not set.");try{t(n._ss.update(e,""))}catch(e){r(e)}}))},n}g()(t,e);var n=t.prototype;return n.generateRequest=function(e,t){var n=this;return new h.Z((function(e){n._ss=n._mk.createSession("video/mp4",t),(0,_.T)(E.GJ(n._ss),E.GV(n._ss),E.Xe(n._ss)).pipe((0,b.R)(n._closeSession$)).subscribe((function(e){return n.trigger(e.type,e)})),e()}))},n.close=function(){var e=this;return new h.Z((function(t){null!=e._ss&&(e._ss.close(),e._ss=void 0),e._closeSession$.next(),e._closeSession$.complete(),t()}))},n.load=function(){return h.Z.resolve(!1)},n.remove=function(){return h.Z.resolve()},p()(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}(T.Z),A=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 k(this._mediaKeys)},t.setServerCertificate=function(){throw new Error("Server certificate is not implemented in your browser")},e}();if(!c.Z){var x=window.MozMediaKeys;void 0!==x&&void 0!==x.prototype&&"function"==typeof x.isTypeSupported&&"function"==typeof x.prototype.createSession&&(S=x)}var Z=n(9689),I=n(3635);function R(e){return"function"==typeof e.webkitGenerateKeyRequest}var M=function(e){function t(t,n){var r;return(r=e.call(this)||this)._closeSession$=new y.xQ,r._vid=t,r._key=n,r.sessionId="",r.closed=new h.Z((function(e){r._closeSession$.subscribe(e)})),r.keyStatuses=new Map,r.expiration=NaN,(0,_.T)(E.GJ(t),E.GV(t),E.Xe(t)).pipe((0,b.R)(r._closeSession$)).subscribe((function(e){return r.trigger(e.type,e)})),r.update=function(e){return new h.Z((function(t,n){try{if(r._key.indexOf("clearkey")>=0){var i=e instanceof ArrayBuffer?new Uint8Array(e):e,a=JSON.parse((0,I.uR)(i)),o=(0,Z.K)(a.keys[0].k),s=(0,Z.K)(a.keys[0].kid);t(r._vid.webkitAddKey(r._key,o,s,""))}else t(r._vid.webkitAddKey(r._key,e,null,""))}catch(e){n(e)}}))},r}g()(t,e);var n=t.prototype;return n.generateRequest=function(e,t){var n=this;return new h.Z((function(e){n._vid.webkitGenerateKeyRequest(n._key,t),e()}))},n.close=function(){var e=this;return new h.Z((function(t){e._closeSession$.next(),e._closeSession$.complete(),t()}))},n.load=function(){return h.Z.resolve(!1)},n.remove=function(){return h.Z.resolve()},t}(T.Z),C=function(){function e(e){this._keySystem=e}var t=e.prototype;return t._setVideo=function(e){if(!R(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 M(this._videoElement,this._keySystem)},t.setServerCertificate=function(){throw new Error("Server certificate is not implemented in your browser")},e}();var N=n(6968);var P=n(158);function O(e,t){if(void 0===e.webkitSetMediaKeys)throw new Error("No webKitMediaKeys API.");return e.webkitSetMediaKeys(t)}var D=function(e){function t(t,n,r){var i;return(i=e.call(this)||this)._serverCertificate=r,i._closeSession$=new y.xQ,i._videoElement=t,i._keyType=n,i.closed=new h.Z((function(e){i._closeSession$.subscribe(e)})),i.keyStatuses=new Map,i.expiration=NaN,i.update=function(e){return new h.Z((function(t,n){if(void 0===i._nativeSession||void 0===i._nativeSession.update||"function"!=typeof i._nativeSession.update)return n("Unavailable WebKit key session.");try{t(i._nativeSession.update(e))}catch(e){n(e)}}))},i}g()(t,e);var n=t.prototype;return n.listenEvent=function(e){var t=this;(0,_.T)(E.GJ(e),E.GV(e),E.Xe(e)).pipe((0,b.R)(this._closeSession$)).subscribe((function(e){t.trigger(e.type,e)}))},n.generateRequest=function(e,t){var n=this;return new h.Z((function(e){if(void 0===n._videoElement.webkitKeys||void 0===n._videoElement.webkitKeys.createSession)throw new Error("No WebKitMediaKeys API.");var r,i;if("com.apple.fps.1_0"===(i=n._keyType)||"com.apple.fps.2_0"===i){if(void 0===n._serverCertificate)throw new Error("A server certificate is needed for creating fairplay session.");r=function(e,t){var n=e instanceof Uint8Array?e:new Uint8Array(e),r=t instanceof Uint8Array?t:new Uint8Array(t);if((0,N.dN)(n,0)+4!==n.length)throw new Error("Unsupported WebKit initData.");var i=(0,I.wV)(n),a=i.indexOf("skd://"),o=a>-1?i.substring(a+6):i,s=(0,I.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,N.O_)(s.byteLength),u),u+=4,l.set(s,u),u+=s.byteLength,l.set((0,N.O_)(r.byteLength),u),u+=4,l.set(r,u),l}(t,n._serverCertificate)}else r=t;var a=n._videoElement.webkitKeys.createSession("video/mp4",r);if(null==a)throw new Error("Impossible to get the key sessions");n.listenEvent(a),n._nativeSession=a,e()}))},n.close=function(){var e=this;return new h.Z((function(t,n){e._closeSession$.next(),e._closeSession$.complete(),void 0===e._nativeSession&&n("No session to close."),e._nativeSession.close(),t()}))},n.load=function(){return h.Z.resolve(!1)},n.remove=function(){return h.Z.resolve()},p()(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}(T.Z),L=function(){function e(e){if(void 0===P.t)throw new Error("No WebKitMediaKeys API.");this._keyType=e,this._mediaKeys=new P.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 O(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 D(this._videoElement,this._keyType,this._serverCertificate)},t.setServerCertificate=function(e){return this._serverCertificate=e,h.Z.resolve()},e}();var B=null,U=function(e,t){return"function"==typeof e.setMediaKeys?e.setMediaKeys(t):e.webkitSetMediaKeys?e.webkitSetMediaKeys(t):e.mozSetMediaKeys?e.mozSetMediaKeys(t):e.msSetMediaKeys&&null!==t?e.msSetMediaKeys(t):void 0};if(c.Z||null!=navigator.requestMediaKeySystemAccess&&!(0,d.Z)())B=function(e,t){return(0,u.Z)(navigator.requestMediaKeySystemAccess(e,t))};else{var F,z;if(R(HTMLVideoElement.prototype)){var V={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 C(e)},setMediaKeys:function(e,t){if(null!==t){if(!(t instanceof C))throw new Error("Custom setMediaKeys is supposed to be called with old webkit custom MediaKeys.");return t._setVideo(e)}}};F=V.isTypeSupported,z=V.createCustomMediaKeys,U=V.setMediaKeys}else if(void 0!==P.t){var K=function(){if(void 0===P.t)throw new Error("No WebKitMediaKeys API.");return{isTypeSupported:P.t.isTypeSupported,createCustomMediaKeys:function(e){return new L(e)},setMediaKeys:function(e,t){if(null===t)return O(e,t);if(!(t instanceof L))throw new Error("Custom setMediaKeys is supposed to be called with webkit custom MediaKeys.");return t._setVideo(e)}}}();F=K.isTypeSupported,z=K.createCustomMediaKeys,U=K.setMediaKeys}else if(l.fq&&void 0!==r){var H={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 A(e)},setMediaKeys:function(e,t){if(null!==t){if(!(t instanceof A))throw new Error("Custom setMediaKeys is supposed to be called with IE11 custom MediaKeys.");return t._setVideo(e)}}};F=H.isTypeSupported,z=H.createCustomMediaKeys,U=H.setMediaKeys}else if(void 0!==S){var W={isTypeSupported:function(e,t){if(void 0===S)throw new Error("No MozMediaKeys API.");return void 0!==t?S.isTypeSupported(e,t):S.isTypeSupported(e)},createCustomMediaKeys:function(e){if(void 0===S)throw new Error("No MozMediaKeys API.");return new S(e)},setMediaKeys:function(e,t){if(void 0===e.mozSetMediaKeys||"function"!=typeof e.mozSetMediaKeys)throw new Error("Can't set video on MozMediaKeys.");return e.mozSetMediaKeys(t)}};F=W.isTypeSupported,z=W.createCustomMediaKeys,U=W.setMediaKeys}else{var $=window.MediaKeys,G=function(){if(void 0===$)throw new s.Z("MEDIA_KEYS_NOT_SUPPORTED","No `MediaKeys` implementation found in the current browser.");if(void 0===$.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.")}};F=function(e){return G(),$.isTypeSupported(e)},z=function(e){return G(),new $(e)}}B=function(e,t){if(!F(e))return(0,i._)(void 0);for(var n=0;n{"use strict";var r;if(n.d(t,{t:()=>r}),!n(2203).Z){var i=window.WebKitMediaKeys;void 0!==i&&"function"==typeof i.isTypeSupported&&"function"==typeof i.prototype.createSession&&"function"==typeof HTMLMediaElement.prototype.webkitSetMediaKeys&&(r=i)}},1473:(e,t,n)=>{"use strict";n.d(t,{zh:()=>K,_K:()=>$,Oh:()=>ie,C1:()=>X,Q1:()=>Q,GV:()=>oe,Xe:()=>se,GJ:()=>ae,eX:()=>ue,K4:()=>j,yj:()=>W,Qt:()=>J,gg:()=>re,ik:()=>q,d5:()=>Y,ym:()=>te,UA:()=>ee,_E:()=>ne,$x:()=>G});var r=n(4379),i=n(3306),a=new r.y(i.Z);var o=n(7027),s=n(4370),u=n(1410),l=n(8170),c=n(5142),d=n(6564),f=n(655),p=n(964),h=n(9914),v=n(979),m=n(2632);function g(e,t){void 0===t&&(t=p.P);var n=(0,h.J)(e)?+e-t.now():Math.abs(e);return function(e){return e.lift(new y(n,t))}}var y=function(){function e(e,t){this.delay=e,this.scheduler=t}return e.prototype.call=function(e,t){return t.subscribe(new _(e,this.delay,this.scheduler))},e}(),_=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.delay=n,i.scheduler=r,i.queue=[],i.active=!1,i.errored=!1,i}return f.ZT(t,e),t.dispatch=function(e){for(var t=e.source,n=t.queue,r=e.scheduler,i=e.destination;n.length>0&&n[0].time-r.now()<=0;)n.shift().notification.observe(i);if(n.length>0){var a=Math.max(0,n[0].time-r.now());this.schedule(e,a)}else this.unsubscribe(),t.active=!1},t.prototype._schedule=function(e){this.active=!0,this.destination.add(e.schedule(t.dispatch,this.delay,{source:this,destination:this.destination,scheduler:e}))},t.prototype.scheduleNotification=function(e){if(!0!==this.errored){var t=this.scheduler,n=new b(t.now()+this.delay,e);this.queue.push(n),!1===this.active&&this._schedule(t)}},t.prototype._next=function(e){this.scheduleNotification(m.P.createNext(e))},t.prototype._error=function(e){this.errored=!0,this.queue=[],this.destination.error(e),this.unsubscribe()},t.prototype._complete=function(){this.scheduleNotification(m.P.createComplete()),this.unsubscribe()},t}(v.L),b=function(){return function(e,t){this.time=e,this.notification=t}}(),T=n(7604),E={leading:!0,trailing:!1};T.Ds;function w(e,t,n){return void 0===t&&(t=p.P),void 0===n&&(n=E),function(r){return r.lift(new S(e,t,n.leading,n.trailing))}}var S=function(){function e(e,t,n,r){this.duration=e,this.scheduler=t,this.leading=n,this.trailing=r}return e.prototype.call=function(e,t){return t.subscribe(new k(e,this.duration,this.scheduler,this.leading,this.trailing))},e}(),k=function(e){function t(t,n,r,i,a){var o=e.call(this,t)||this;return o.duration=n,o.scheduler=r,o.leading=i,o.trailing=a,o._hasTrailingValue=!1,o._trailingValue=null,o}return f.ZT(t,e),t.prototype._next=function(e){this.throttled?this.trailing&&(this._trailingValue=e,this._hasTrailingValue=!0):(this.add(this.throttled=this.scheduler.schedule(A,this.duration,{subscriber:this})),this.leading?this.destination.next(e):this.trailing&&(this._trailingValue=e,this._hasTrailingValue=!0))},t.prototype._complete=function(){this._hasTrailingValue?(this.destination.next(this._trailingValue),this.destination.complete()):this.destination.complete()},t.prototype.clearThrottle=function(){var e=this.throttled;e&&(this.trailing&&this._hasTrailingValue&&(this.destination.next(this._trailingValue),this._trailingValue=null,this._hasTrailingValue=!1),e.unsubscribe(),this.remove(e),this.throttled=null)},t}(v.L);function A(e){e.subscriber.clearThrottle()}var x=n(5709),Z=n(3485),I=n(1931),R=n(6381),M=n(5602),C=n(944),N=n(6923),P=n(3774),O=n(2203),D=n(5059),L=["","webkit","moz","ms"],B=C.Z.INACTIVITY_DELAY,U=O.Z||null==window.devicePixelRatio||0===window.devicePixelRatio?1:window.devicePixelRatio;function F(e,t){return t.filter((function(t){return function(e,t){var n=document.createElement(e.tagName),r="on"+t;return r in n||(n.setAttribute(r,"return;"),"function"==typeof n[r])}(e,t)}))[0]}function z(e,t){var n,r=function(e,t){return e.reduce((function(e,n){return e.concat((null==t?L:t).map((function(e){return e+n})))}),[])}(e,t);return function(e){return e instanceof P.DQ?(void 0===n&&(n=F(e,r)),(0,N.Z)(n)?(0,o.R)(e,n):a):s.T.apply(void 0,r.map((function(t){return(0,o.R)(e,t)})))}}function V(){var e,t=document;null!=t.hidden?e="":null!=t.mozHidden?e="moz":null!=t.msHidden?e="ms":null!=t.webkitHidden&&(e="webkit");var n=(0,N.Z)(e)?e+"Hidden":"hidden",r=(0,N.Z)(e)?e+"visibilitychange":"visibilitychange";return(0,u.P)((function(){var e=document[n];return(0,o.R)(document,r).pipe((0,x.U)((function(){return!document[n]})),(0,Z.O)(!e),(0,I.x)())}))}function K(){return V().pipe((0,R.w)((function(e){return e?(0,l.of)(e):(0,l.of)(e).pipe(g(B))})))}function H(e,t){var n=t.width,r=t.height/(e.clientHeight/e.clientWidth);return Math.min(n,r)}function W(e){return(0,u.P)((function(){if(e.webkitSupportsPresentationMode&&"function"==typeof e.webkitSetPresentationMode){var t="picture-in-picture"===e.webkitPresentationMode;return(0,o.R)(e,"webkitpresentationmodechanged").pipe((0,x.U)((function(){return{isEnabled:"picture-in-picture"===e.webkitPresentationMode,pipWindow:null}})),(0,Z.O)({isEnabled:t,pipWindow:null}))}var n={isEnabled:document.pictureInPictureElement&&document.pictureInPictureElement===e,pipWindow:null};return(0,s.T)((0,o.R)(e,"enterpictureinpicture").pipe((0,x.U)((function(e){return{isEnabled:!0,pipWindow:e.pictureInPictureWindow}}))),(0,o.R)(e,"leavepictureinpicture").pipe((0,M.h)({isEnabled:!1,pipWindow:null}))).pipe((0,Z.O)(n))}))}function $(e){return(0,c.aj)([V(),e]).pipe((0,R.w)((function(e){var t=e[0];return e[1].isEnabled||t?(0,l.of)(!0):(0,l.of)(!1).pipe(g(B))})),(0,I.x)())}function G(e,t){return(0,c.aj)([t,(0,d.F)(2e4).pipe((0,Z.O)(null)),(0,o.R)(window,"resize").pipe(w(500),(0,Z.O)(null))]).pipe((0,R.w)((function(t){var n=t[0];if(n.isEnabled){if(null!=n.pipWindow){var r=n.pipWindow,i=H(e,r);return(0,o.R)(r,"resize").pipe((0,Z.O)(i*U),(0,x.U)((function(){return H(e,r)*U})))}return(0,l.of)(1/0)}return(0,l.of)(e.clientWidth*U)})),(0,I.x)())}var j=z(["loadedmetadata"]),Y=z(["seeking"]),q=z(["seeked"]),X=z(["ended"]),Q=(z(["timeupdate"]),z(["fullscreenchange","FullscreenChange"],L.concat("MS"))),J=function(e){return(0,s.T)(z(["play"])(e),z(["pause"])(e))},ee=function(e){return(0,s.T)(z(["addtrack"])(e),z(["removetrack"])(e))},te=z(["sourceopen","webkitsourceopen"]),ne=z(["update"]),re=z(["onremovesourcebuffer"]),ie=z((0,D.Z)()?["needkey"]:["encrypted","needkey"]),ae=z(["keymessage","message"]),oe=z(["keyadded","ready"]),se=z(["keyerror","error"]),ue=z(["keystatuseschange"])},2203:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r="undefined"==typeof window},1988:(e,t,n)=>{"use strict";function r(e){return"function"==typeof window.VTTCue&&e instanceof window.VTTCue}n.d(t,{Z:()=>r})},7253:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3887),i=n(3774);function a(e,t,n){if(null==i.w)throw new Error("VTT cues not supported in your target");return e>=t?(r.Z.warn("Compat: Invalid cue times: "+e+" - "+t),null):new i.w(e,t,n)}},5059:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3666),i=n(158);function a(){return r.G6&&void 0!==i.t}},944:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const 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,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},BUFFER_DISCONTINUITY_THRESHOLD:.2,BITRATE_REBUFFERING_RATIO:1.5,BUFFER_GC_GAPS:{CALM:240,BEEFY:30},DEFAULT_MAX_MANIFEST_REQUEST_RETRY:4,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},STALL_GAP:{DEFAULT:.5,LOW_LATENCY:.2},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_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS:50,EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION:1e3,FORCED_ENDED_THRESHOLD:.001,ADAPTATION_SWITCH_BUFFER_PADDINGS:{video:{before:2,after:2.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:2,CACHE_LOAD_DURATION_THRESHOLDS:{video:50,audio:10},STREAM_EVENT_EMITTER_POLL_INTERVAL:250}},7794:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(5354),i=n.n(r),a=n(1959),o=n(7829);function s(e,t){var n;if(t.length!==e.length)return!0;for(var r=0;r{"use strict";n.d(t,{ZP:()=>je});var r=n(4370),i=n(4944),a=n(8170),o=n(5631),s=n(9795),u=n(7006),l=n(6008),c=n(1015),d=n(3068),f=n(7746),p=n(5709),h=n(486),v=n(6738),m=n(1473),g=n(3887),y=n(4791),_=n(6968),b=n(3635),T=(0,_.pX)((0,b.tG)("pssh"),0);function E(e){for(var t=new Uint8Array,n=[],r=0;re.length)return g.Z.warn("Compat: Unrecognized initialization data. Use as is."),e;var a=e.subarray(r,r+i);w(n,a)?g.Z.warn("Compat: Duplicated PSSH found in initialization data, removing it."):(t=(0,_.zo)(t,a),n.push(e)),r+=i}return r!==e.length?(g.Z.warn("Compat: Unrecognized initialization data. Use as is."),e):t}function w(e,t){for(var n=0;ne.length)throw g.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,k.Xj)(o),u=null===s?void 0:o[s[1]];g.Z.info("Compat: CENC PSSH found with version",u),void 0===u?g.Z.warn("Compat: could not read version of CENC PSSH"):t===(1===u)?n=(0,_.zo)(n,o):1===u?(g.Z.warn("Compat: cenc version 1 encountered, removing every other cenc pssh box."),n=o,t=!0):g.Z.warn("Compat: filtering out cenc pssh box with wrong version",u)}else r=(0,_.zo)(r,o);i+=a}if(i!==e.length)throw g.Z.warn("Compat: unrecognized initialization data. Cannot patch it."),new Error("Compat: unrecognized initialization data. Cannot patch it.");return(0,_.zo)(r,n)}(t.data)}catch(e){r=t.data}var i=null!==(n=t.type)&&void 0!==n?n:"";return(0,A.Z)(e.generateRequest(i,r)).pipe((0,h.K)((function(t){if(""!==i||!(t instanceof TypeError))throw t;return g.Z.warn('Compat: error while calling `generateRequest` with an empty initialization data type. Retrying with a default "cenc" value.',t),(0,A.Z)(e.generateRequest("cenc",r))})))}))}var Z=n(944),I=n(5157),R=n(7714),M=n(8418),C=n(2793),N=n(1946);var P=n(5602),O=n(3485);var D=n(4379),L=n(5561);function B(e){if(""===e.sessionId)return!1;var t=e.keyStatuses,n=[];return t.forEach((function(e){n.push(e)})),n.length<=0?(g.Z.debug("EME: isSessionUsable: MediaKeySession given has an empty keyStatuses",e),!1):(0,R.Z)(n,"expired")?(g.Z.debug("EME: isSessionUsable: MediaKeySession given has an expired key",e.sessionId),!1):(0,R.Z)(n,"internal-error")?(g.Z.debug("EME: isSessionUsable: MediaKeySession given has a key with an internal-error",e.sessionId),!1):(g.Z.debug("EME: isSessionUsable: MediaKeySession is usable",e.sessionId),!0)}function U(e,t,n){return(0,S.P)((function(){var r=e.loadedSessionsStore,i=e.persistentSessionsStore;return"temporary"===n?F(r,t):null===i?(g.Z.warn("EME: Cannot create persistent MediaKeySession, PersistentSessionsStore not created."),F(r,t)):function(e,t,n){return(0,S.P)((function(){g.Z.info("EME: Creating persistent MediaKeySession");var r=e.createSession(n,"persistent-license"),i=t.getAndReuse(n);if(null===i)return(0,a.of)({type:"created-session",value:{mediaKeySession:r,sessionType:"persistent-license"}});var o=function(){return g.Z.info("EME: Removing previous persistent session."),null!==t.get(n)&&t.delete(n),e.closeSession(n).pipe((0,p.U)((function(){return{type:"created-session",value:{mediaKeySession:e.createSession(n,"persistent-license"),sessionType:"persistent-license"}}})))};return function(e,t){return(0,S.P)((function(){return g.Z.info("Compat/EME: Load persisted session",t),(0,L.Z)((function(){return(0,A.Z)(e.load(t))}),void 0)})).pipe((0,f.zg)((function(t){return!t||e.keyStatuses.size>0?(0,a.of)(t):new D.y((function(e){var n=setTimeout((function(){e.next(t),e.complete()}),0);return function(){clearTimeout(n)}}))})))}(r,i.sessionId).pipe((0,f.zg)((function(e){return e?e&&B(r)?(t.add(n,r),g.Z.info("EME: Succeeded to load persistent session."),(0,a.of)({type:"loaded-persistent-session",value:{mediaKeySession:r,sessionType:"persistent-license"}})):(g.Z.warn("EME: Previous persistent session not usable anymore."),o()):(g.Z.warn("EME: No data stored for the loaded session"),t.delete(n),(0,a.of)({type:"created-session",value:{mediaKeySession:r,sessionType:"persistent-license"}}))})),(0,h.K)((function(e){return g.Z.warn("EME: Unable to load persistent session: "+(e instanceof Error?e.toString():"Unknown Error")),o()})))}))}(r,i,t)}))}function F(e,t){return(0,S.P)((function(){g.Z.info("EME: Creating a new temporary session");var n=e.createSession(t,"temporary");return(0,a.of)({type:"created-session",value:{mediaKeySession:n,sessionType:"temporary"}})}))}var z=Z.Z.EME_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS;function V(e,t,n){return(0,S.P)((function(){var i=null,u=t.loadedSessionsStore,l=t.persistentSessionsStore,c=u.getAndReuse(e);if(null!==c){if(B(i=c.mediaKeySession))return g.Z.info("EME: Reuse loaded session",i.sessionId),(0,a.of)({type:"loaded-open-session",value:{mediaKeySession:i,sessionType:c.sessionType,initializationData:e}});null!==l&&l.delete(e)}return(null!=i?u.closeSession(e):(0,a.of)(null)).pipe((0,f.zg)((function(){return(0,s.z)(function(e,t){if(t<0||t>=e.getLength())return o.E;for(var n=[],i=e.getAll().slice(),a=i.length-t,s=0;s=o.length){var n=new I.Z("INCOMPATIBLE_KEYSYSTEMS","No key system compatible with your wanted configuration has been found in the current browser.");return(0,i._)(n)}if(null==H.N){var r=Error("requestMediaKeySystemAccess is not implemented in your browser.");return(0,i._)(r)}var a=o[t],s=a.keyName,u=a.keyType,l=a.keySystemOptions,c=function(e,t){var n=["temporary"],r="optional",i="optional";!0===t.persistentLicense&&(r="required",n.push("persistent-license")),!0===t.persistentStateRequired&&(r="required"),!0===t.distinctiveIdentifierRequired&&(i="required");var a=null!=t.videoRobustnesses?t.videoRobustnesses:"widevine"===e?j:[],o=null!=t.audioRobustnesses?t.audioRobustnesses:"widevine"===e?j:[];return 0===a.length&&a.push(void 0),0===o.length&&o.push(void 0),[{initDataTypes:["cenc"],videoCapabilities:(0,G.Z)(a,(function(e){return[{contentType:'video/mp4;codecs="avc1.4d401e"',robustness:e},{contentType:'video/mp4;codecs="avc1.42e01e"',robustness:e},{contentType:'video/webm;codecs="vp8"',robustness:e}]})),audioCapabilities:(0,G.Z)(o,(function(e){return[{contentType:'audio/mp4;codecs="mp4a.40.2"',robustness:e},{contentType:"audio/webm;codecs=opus",robustness:e}]})),distinctiveIdentifier:i,persistentState:r,sessionTypes:n}]}(s,l);return g.Z.debug("EME: Request keysystem access "+u+","+(t+1)+" of "+o.length,c),(0,H.N)(u,c).pipe((0,p.U)((function(e){return g.Z.info("EME: Found compatible keysystem",u,c),{type:"create-media-key-system-access",value:{options:l,mediaKeySystemAccess:e}}})),(0,h.K)((function(){return g.Z.debug("EME: Rejected access to keysystem",u,c),e(t+1)})))}(0)}))}var Q=n(2870),J=new WeakMap;const ee=function(e){J.set(e,null)},te=function(e,t){var n=t instanceof Uint8Array?t:new Uint8Array(t instanceof ArrayBuffer?t:t.buffer),r=(0,Q.Z)(n);J.set(e,{hash:r,serverCertificate:n})},ne=function(e){var t=J.get(e);return void 0!==t&&(null!==t||void 0)},re=function(e,t){var n=J.get(e);if(null==n)return!1;var r=n.hash,i=n.serverCertificate,a=t instanceof Uint8Array?t:new Uint8Array(t instanceof ArrayBuffer?t:t.buffer);if((0,Q.Z)(a)!==r||i.length!==a.length)return!1;for(var o=0;o=0?this._storage[n].value:void 0},t.getAndReuse=function(e){var t=(0,Q.Z)(e.data),n=this._findIndex(e,t);if(-1!==n){var r=this._storage.splice(n,1)[0];return this._storage.push(r),r.value}},t.store=function(e,t){var n=(0,Q.Z)(e.data),r=this._findIndex(e,n);r>=0&&this._storage.splice(r,1),this._storage.push({initData:e.data,initDataType:e.type,initDataHash:n,value:t})},t.storeIfNone=function(e,t){var n=(0,Q.Z)(e.data);return!(this._findIndex(e,n)>=0)&&(this._storage.push({initData:e.data,initDataType:e.type,initDataHash:n,value:t}),!0)},t.remove=function(e){var t=(0,Q.Z)(e.data),n=this._findIndex(e,t);if(-1!==n)return this._storage.splice(n,1)[0].value},t._findIndex=function(e,t){for(var n=e.type,r=e.data,i=this._storage.length-1;i>=0;i--){var a=this._storage[i];if(t===a.initDataHash&&n===a.initDataType&&(0,y.Z)(r,a.initData))return i}return-1},e}(),se=function(){function e(e){this._mediaKeys=e,this._storage=new oe}var t=e.prototype;return t.get=function(e){var t=this._storage.get(e);return void 0===t?null:{mediaKeySession:t.mediaKeySession,sessionType:t.sessionType}},t.getAndReuse=function(e){var t=this._storage.getAndReuse(e);return void 0===t?null:{mediaKeySession:t.mediaKeySession,sessionType:t.sessionType}},t.createSession=function(e,t){var n=this;if(void 0!==this._storage.get(e))throw new I.Z("MULTIPLE_SESSIONS_SAME_INIT_DATA","This initialization data was already stored.");var r=this._mediaKeys.createSession(t),i={mediaKeySession:r,sessionType:t,initializationData:e};return(0,N.Z)(r.closed)||r.closed.then((function(){var t=n._storage.get(e);void 0!==t&&t.mediaKeySession===r&&n._storage.remove(e)})).catch((function(e){g.Z.warn("EME-LSS: MediaKeySession.closed rejected: "+e)})),g.Z.debug("EME-LSS: Add MediaKeySession",i),this._storage.store(e,i),r},t.closeSession=function(e){var t=this;return(0,S.P)((function(){var n=t._storage.remove(e);return void 0===n?(g.Z.warn("EME-LSS: No MediaKeySession found with the given initData and initDataType"),o.E):ue(n.mediaKeySession)}))},t.getLength=function(){return this._storage.getLength()},t.getAll=function(){return this._storage.getAll()},t.closeAllSessions=function(){var e=this;return(0,S.P)((function(){var t=e._storage.getAll().map((function(e){return ue(e.mediaKeySession)}));return g.Z.debug("EME-LSS: Closing all current MediaKeySessions",t.length),e._storage=new oe,(0,s.z)(r.T.apply(void 0,t).pipe((0,v.l)()),(0,a.of)(null))}))},e}();function ue(e){return g.Z.debug("EME-LSS: Close MediaKeySession",e),(t=e,(0,ie.S3)((0,A.Z)(t.close()),(0,ae.H)(1e3).pipe((0,f.zg)((function(){return(0,A.Z)(t.update(new Uint8Array(1))).pipe((0,p.U)((function(){throw new Error("Compat: Couldn't know if session is closed")})),(0,h.K)((function(e){if(e instanceof Error&&"The session is already closed."===e.message)return(0,a.of)(null);var n=(0,A.Z)(t.closed);return(0,ie.S3)(n,(0,ae.H)(1e3).pipe((0,p.U)((function(){throw new Error("Compat: Couldn't know if session is closed")}))))})))}))))).pipe((0,h.K)((function(e){return g.Z.error("EME-LSS: Could not close MediaKeySession: "+(e instanceof Error?e.toString():"Unknown error")),(0,a.of)(null)})));var t}var le=n(811),ce=n(9689),de=n(6923);var fe=function(){function e(e){this.initData=e}return e.prototype.toJSON=function(){return(0,ce.J)(this.initData)},e.decode=function(e){return(0,ce.K)(e)},e}(),pe=function(){function e(e){!function(e){(0,le.u)(e,{save:"function",load:"function"},"licenseStorage")}(e),this._entries=[],this._storage=e;try{this._entries=this._storage.load(),Array.isArray(this._entries)||(this._entries=[])}catch(e){g.Z.warn("EME-PSS: Could not get entries from license storage",e),this.dispose()}}var t=e.prototype;return t.getLength=function(){return this._entries.length},t.getAll=function(){return this._entries},t.get=function(e){var t=this._getIndex(e);return-1===t?null:this._entries[t]},t.getAndReuse=function(e){var t=this._getIndex(e);if(-1===t)return null;var n=this._entries.splice(t,1)[0];return this._entries.push(n),n},t.add=function(e,t){if(!(0,N.Z)(t)&&(0,de.Z)(t.sessionId)){var n=t.sessionId,r=this.get(e);if(null===r||r.sessionId!==n){null!==r&&this.delete(e);var i=(0,Q.Z)(e.data);g.Z.info("EME-PSS: Add new session",n,t),this._entries.push({version:2,sessionId:n,initData:new fe(e.data),initDataHash:i,initDataType:e.type}),this._save()}}else g.Z.warn("EME-PSS: Invalid Persisten Session given.")},t.delete=function(e){var t=this._getIndex(e);if(-1!==t){var n=this._entries[t];g.Z.warn("EME-PSS: Delete session from store",n),this._entries.splice(t,1),this._save()}else g.Z.warn("EME-PSS: initData to delete not found.")},t.deleteOldSessions=function(e){g.Z.info("EME-PSS: Deleting last "+e+" sessions."),e<=0||(e<=this._entries.length?this._entries.splice(0,e):(g.Z.warn("EME-PSS: Asked to remove more information that it contains",e,this._entries.length),this._entries=[]),this._save())},t.dispose=function(){this._entries=[],this._save()},t._getIndex=function(e){for(var t=(0,Q.Z)(e.data),n=0;n=0?Me(n):we.y)})),T=function(e,t){return{totalRetry:null!=t?t:2,baseDelay:200,maxDelay:3e3,shouldRetry:function(e){return e instanceof Se||(0,N.Z)(e)||!0!==e.noRetry},onRetry:function(t){return e.next({type:"warning",value:He(t)})}}}(c,m.retry);return(o=b,s=T,u=s.baseDelay,l=s.maxDelay,d=s.totalRetry,v=s.shouldRetry,y=s.onRetry,_=0,o.pipe((0,h.K)((function(e,t){if(!(0,N.Z)(v)&&!v(e)||_++>=d)throw e;"function"==typeof y&&y(e,_);var n=Math.min(u*Math.pow(2,_-1),l),r=(0,Ne.Z)(n);return(0,ae.H)(r).pipe((0,f.zg)((function(){return t})))})))).pipe((0,p.U)((function(t){return{type:"key-message-handled",value:{session:e,license:t}}})),(0,h.K)((function(e){var t=He(e);if(!(0,N.Z)(e)&&!0===e.fallbackOnLastTry)throw g.Z.warn("EME: Last `getLicense` attempt failed. Blacklisting the current session."),new ze(t);throw t})),(0,O.O)({type:"session-message",value:{messageType:a,initializationData:i}}))}))),T=(0,r.T)(b,_).pipe((u=function(t){switch(t.type){case"key-message-handled":case"key-status-change-handled":return function(e,t,n){return(0,N.Z)(t)?(g.Z.info("EME: No message given, skipping session.update"),(0,a.of)({type:"no-update",value:{initializationData:n}})):(g.Z.info("EME: Updating MediaKeySession with message"),(0,A.Z)(e.update(t)).pipe((0,h.K)((function(e){var t=e instanceof Error?e.toString():"`session.update` failed";throw new I.Z("KEY_UPDATE_ERROR",t)})),(0,d.b)((function(){g.Z.info("EME: MediaKeySession update succeeded.")})),(0,P.h)({type:"session-updated",value:{session:e,license:t,initializationData:n}})))}(e,t.value.license,i);default:return(0,a.of)(t)}},(0,f.zg)(u,l,1))),E=(0,r.T)(Ke(e,t,n),T,y,c);return(0,N.Z)(e.closed)?E:E.pipe((0,Ce.R)((0,A.Z)(e.closed)))}function Ke(e,t,n){return(0,S.P)((function(){var r=Le(e,t,n),i=r[0],u=r[1],l=i.length>0?a.of.apply(void 0,i):o.E,c=u.length>0?(0,a.of)({type:"blacklist-keys",value:u}):o.E;return(0,s.z)(l,c)}))}function He(e){if(e instanceof Se)return new I.Z("KEY_LOAD_TIMEOUT","The license server took too much time to respond.");var t=new I.Z("KEY_LOAD_ERROR","An error occured when calling `getLicense`.");return!(0,N.Z)(e)&&(0,de.Z)(e.message)&&(t.message=e.message),t}function We(e,t){return(0,S.P)((function(){return"function"!=typeof e.setServerCertificate?(g.Z.warn("EME: Could not set the server certificate. mediaKeys.setServerCertificate is not a function"),o.E):!0===ne(e)?(g.Z.info("EME: The MediaKeys already has a server certificate, skipping..."),o.E):(g.Z.info("EME: Setting server certificate on the MediaKeys"),ee(e),function(e,t){return(0,S.P)((function(){return(0,L.Z)((function(){return(0,A.Z)(e.setServerCertificate(t))}),void 0).pipe((0,h.K)((function(e){g.Z.warn("EME: mediaKeys.setServerCertificate returned an error",e);var t=e instanceof Error?e.toString():"`setServerCertificate` error";throw new I.Z("LICENSE_SERVER_CERTIFICATE_ERROR",t)})))}))}(e,t).pipe((0,d.b)((function(){te(e,t)})),(0,v.l)(),(0,h.K)((function(e){return(0,a.of)({type:"warning",value:e})}))))}))}var $e=Z.Z.EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION,Ge=m.Oh;const je=function(e,t,n){g.Z.debug("EME: Starting EMEManager logic.");var m=new oe,y=new oe,_=ve(e,t).pipe((0,u.d)()),b=_.pipe((0,l.h)((function(e){return"attached-media-keys"===e.type})),(0,c.q)(1)),T=Ge(e).pipe((0,d.b)((function(e){g.Z.debug("EME: Encrypted event received from media element.",e)})),(0,C.Z)((function(e){var t=function(e){var t=e.initData,n=e.initDataType;return null==t?(g.Z.warn("Compat: No init data found on media encrypted event."),{initData:t,initDataType:n}):{initData:E(new Uint8Array(t)),initDataType:e.initDataType}}(e),n=t.initData,r=t.initDataType;return null===n?null:{type:r,data:n}}),null),(0,u.d)({refCount:!0})),w=n.pipe((0,d.b)((function(e){g.Z.debug("EME: Encrypted event received from Player",e)}))),S=(0,r.T)(w,T).pipe((0,f.zg)((function(e){return b.pipe((0,p.U)((function(t){return[e,t]})))})),(0,f.zg)((function(e,t){var n=e[0],u=e[1].value,l=u.mediaKeys,c=u.mediaKeySystemAccess,p=u.stores,_=u.options,b=y.get(n);if(void 0!==b){if(void 0===n.type){g.Z.error("EME: The current session has already been blacklisted but the current content is not known. Throwing.");var T=b.sessionError;return T.fatal=!0,(0,i._)(T)}return g.Z.warn("EME: The current session has already been blacklisted. Blacklisting content."),(0,a.of)({type:"blacklist-protection-data",value:n})}if(!m.storeIfNone(n,!0))return g.Z.debug("EME: Init data already received. Skipping it."),(0,a.of)({type:"init-data-ignored",value:{initializationData:n}});var E,w=_.serverCertificate,S=0!==t||(0,N.Z)(w)?o.E:We(l,w);return!0!==_.persistentLicense?E="temporary":!function(e){var t=e.getConfiguration().sessionTypes;return void 0!==t&&(0,R.Z)(t,"persistent-license")}(c)?(g.Z.warn('EME: Cannot create "persistent-license" session: not supported'),E="temporary"):E="persistent-license",(0,s.z)(S,V(n,p,E)).pipe((0,f.zg)((function(e){switch(e.type){case"warning":return(0,a.of)(e);case"cleaning-old-session":return m.remove(e.value.initializationData),o.E;case"cleaned-old-session":return o.E;case"created-session":case"loaded-open-session":case"loaded-persistent-session":break;default:(0,M.Z)(e)}var t=e.value,i=t.mediaKeySession,s=t.sessionType,u="created-session"!==e.type?o.E:x(i,n).pipe((0,d.b)((function(){var e=p.persistentSessionsStore;"persistent-license"===s&&null!==e&&(!function(e,t){if(!(isNaN(t)||t<0||t>=e.getLength())){var n=e.getLength(),r=n-t;g.Z.info("EME: Too many stored persistent sessions, removing some.",n,r),e.deleteOldSessions(r)}}(e,$e-1),e.add(n,i))})),(0,h.K)((function(e){throw new I.Z("KEY_GENERATE_REQUEST_ERROR",e instanceof Error?e.toString():"Unknown error")})),(0,v.l)());return(0,r.T)(Ve(i,_,c.keySystem,n),u).pipe((0,h.K)((function(e){if(!(e instanceof ze))throw e;y.store(n,e);var t=e.sessionError;if(void 0===n.type)throw g.Z.error("EME: Current session blacklisted and content not known. Throwing."),t.fatal=!0,t;return g.Z.warn("EME: Current session blacklisted. Blacklisting content."),(0,a.of)({type:"warning",value:t},{type:"blacklist-protection-data",value:n})})))})))})));return(0,r.T)(_,T.pipe((0,p.U)((function(e){return{type:"encrypted-event-received",value:e}}))),S)}},6033:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=new WeakMap;const i={setState:function(e,t){r.set(e,t)},getState:function(e){var t=r.get(e);return void 0===t?null:t},clearState:function(e){r.set(e,null)}}},4507:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(4370),i=n(8170),a=n(5709),o=n(6139);var s=n(1473),u=n(5157),l=n(7874),c=n(3887),d=s.Oh;function f(e,t,n){var s=(0,r.T)(d(e),n);return null==l.Z.emeManager?(0,r.T)(s.pipe((0,a.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.")}))),(0,i.of)({type:"eme-disabled"})):0===t.length?(0,r.T)(s.pipe((0,a.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")}))),(0,i.of)({type:"eme-disabled"})):"function"!=typeof o.N?(0,r.T)(s.pipe((0,a.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.")}))),(0,i.of)({type:"eme-disabled"})):(c.Z.debug("Init: Creating EMEManager"),l.Z.emeManager(e,t,n))}},8343:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r={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}}}},2795:(e,t,n)=>{"use strict";n.d(t,{Z:()=>E});var r=n(9795),i=n(8170),a=n(6008),o=n(1015),s=n(5602),u=n(486),l=n(3068),c=n(7006),d=n(7746),f=n(3666);function p(){return f.op}var h=n(1410),v=n(8117),m=n(5561);var g=n(3774),y=n(1473);var _=n(3887);function b(e,t,n){var u=e.pipe((0,a.h)((function(e){var r=e.seeking,i=e.stalled,a=e.readyState,o=e.currentRange;return!r&&null===i&&(function(e,t){return!e||!f.SB||t}(n,t.hasAttribute("playsinline"))?(a>=4||3===a&&null!==o)&&(!p()||t.duration>0):a>=1&&t.duration>0)})),(0,o.q)(1),(0,s.h)("can-play"));return p()&&0===t.duration?(0,r.z)((0,i.of)("not-loaded-metadata"),u):u}function T(e){return function(e){return(0,h.P)((function(){return(0,m.Z)((function(){return(0,v.Z)(e.play())}),void 0)}))}(e).pipe((0,s.h)("autoplay"),(0,u.K)((function(e){if(e instanceof Error&&"NotAllowedError"===e.name)return _.Z.warn("Init: Media element can't play. It may be due to browser auto-play policies."),(0,i.of)("autoplay-blocked");throw e})))}function E(e){var t=e.clock$,n=e.mediaElement,r=e.startTime,a=e.mustAutoPlay,s=e.isDirectfile,u=function(e){return e.readyState>=g.cX.HAVE_METADATA?(0,i.of)(null):(0,y.K4)(e).pipe((0,o.q)(1))}(n).pipe((0,o.q)(1),(0,l.b)((function(){_.Z.info("Init: Set initial time",r),n.currentTime="function"==typeof r?r():r})),(0,c.d)({refCount:!0})),f=u.pipe((0,d.zg)((function(){return b(t,n,s).pipe((0,l.b)((function(){return _.Z.info("Init: Can begin to play content")})),(0,d.zg)((function(e){return"can-play"===e?a?T(n):(0,i.of)("loaded"):(0,i.of)(e)})))})),(0,c.d)({refCount:!0}));return{seek$:u,load$:f}}},8969:(e,t,n)=>{"use strict";n.d(t,{Z:()=>w});var r=n(5631),i=n(8170),a=n(4370),o=n(7746),s=n(9095),u=n(6738),l=n(5709),c=n(6008),d=n(1015),f=n(3756),p=n(4379),h=n(3887),v=n(5767);var m=n(3714),g=n(8025),y=n(4507),_=n(8343),b=n(2795),T=n(2447),E=n(2983);function w(e){var t=e.autoPlay,n=e.clock$,w=e.keySystems,S=e.mediaElement,k=e.speed$,A=e.startAt,x=e.url;if((0,v.Z)(S),null==x)throw new Error("No URL for a DirectFile content");var Z=function(e,t){return new p.y((function(n){return h.Z.info("Setting URL to Element",t,e),e.src=t,n.next(void 0),function(){(0,v.Z)(e)}}))}(S,x);h.Z.debug("Init: Calculating initial time");var I=function(){return 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 h.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}(S,A)};h.Z.debug("Init: Initial time calculated:",I);var R=(0,b.Z)({clock$:n,mediaElement:S,startTime:I,mustAutoPlay:t,isDirectfile:!0}),M=R.seek$,C=R.load$,N=Z.pipe((0,o.zg)((function(){return(0,y.Z)(S,w,r.E)})),(0,g.Z)(),(0,s.B)()),P=(0,T.Z)(S),O=(0,E.Z)(S,k,n,{pauseWhenStalled:!0}).pipe((0,u.l)()),D=n.pipe((0,l.U)((function(e){return null===e.stalled?_.Z.unstalled():_.Z.stalled(e.stalled)}))),L=N.pipe((0,c.h)((function(e){return"created-media-keys"===e.type?(e.value.attachMediaKeys$.next(),!0):"eme-disabled"===e.type||"attached-media-keys"===e.type})),(0,d.q)(1),(0,f.j)(C),(0,o.zg)((function(e){if("autoplay-blocked"===e){var t=new m.Z("MEDIA_ERR_BLOCKED_AUTOPLAY","Cannot trigger auto-play automatically: your browser does not allow it.");return(0,i.of)(_.Z.warning(t),_.Z.loaded(null))}if("not-loaded-metadata"===e){var n=new m.Z("MEDIA_ERR_NOT_LOADED_METADATA","Cannot load automatically: your browser falsely announced having loaded the content.");return(0,i.of)(_.Z.warning(n))}return(0,i.of)(_.Z.loaded(null))}))),B=M.pipe((0,u.l)());return(0,a.T)(L,B,N,P,O,D)}},2447:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7027),i=n(7746),a=n(3714);function o(e){return(0,r.R)(e,"error").pipe((0,i.zg)((function(){switch(null==e.error?0:e.error.code){case 1:throw new a.Z("MEDIA_ERR_ABORTED","The fetching of the associated resource was aborted by the user's request.");case 2:throw new a.Z("MEDIA_ERR_NETWORK","A network error occurred which prevented the media from being successfully fetched");case 3:throw new a.Z("MEDIA_ERR_DECODE","An error occurred while trying to decode the media resource");case 4:throw new a.Z("MEDIA_ERR_SRC_NOT_SUPPORTED","The media resource has been found to be unsuitable.");default:throw new a.Z("MEDIA_ERR_UNKNOWN","The HTMLMediaElement errored due to an unknown reason.")}})))}},2983:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(8170),i=n(1410),a=n(5709),o=n(3485),s=n(1931),u=n(6381),l=n(3068),c=n(3887);function d(e,t,n,d){var f=d.pauseWhenStalled;return(void 0===f||f?n.pipe((0,a.U)((function(e){return null!==e.stalled})),(0,o.O)(!1),(0,s.x)()):(0,r.of)(!1)).pipe((0,u.w)((function(n){return n?(0,i.P)((function(){return c.Z.info("Init: Pause playback to build buffer"),e.playbackRate=0,(0,r.of)(0)})):t.pipe((0,l.b)((function(t){c.Z.info("Init: Resume playback speed",t),e.playbackRate=t})))})))}},7127:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(5354),i=n.n(r),a=n(1410),o=n(8170),s=n(3887),u=n(4123),l=n(4309);const c=function(e){function t(){var t;return s.Z.debug("ISB: Creating ImageSegmentBuffer"),(t=e.call(this)||this).bufferType="image",t._buffered=new l.Z,t}i()(t,e);var n=t.prototype;return n.pushChunk=function(e){var t=this;return(0,a.P)((function(){var n,r;if(s.Z.debug("ISB: appending new data."),null===e.data.chunk)return(0,o.of)(void 0);var i=e.data,a=i.appendWindow,u=i.chunk,l=u.start,c=u.end,d=u.timescale,f=null!==(n=a[0])&&void 0!==n?n:0,p=null!==(r=a[1])&&void 0!==r?r:1/0,h=l/d,v=c/d,m=Math.max(f,h),g=Math.min(p,v);return t._buffered.insert(m,g),null!==e.inventoryInfos&&t._segmentInventory.insertChunk(e.inventoryInfos),(0,o.of)(void 0)}))},n.removeBuffer=function(e,t){return(0,a.P)((function(){return s.Z.info("ISB: ignored image data remove order",e,t),(0,o.of)(void 0)}))},n.endOfSegment=function(e){var t=this;return(0,a.P)((function(){return t._segmentInventory.completeSegment(e),(0,o.of)(void 0)}))},n.getBufferedRanges=function(){return this._buffered},n.dispose=function(){s.Z.debug("ISB: disposing image SegmentBuffer"),this._buffered.remove(0,1/0)},t}(u.C)},5192:(e,t,n)=>{"use strict";n.d(t,{Z:()=>B});var r=n(5354),i=n.n(r),a=n(4370),o=n(6564),s=n(9795),u=n(8170),l=n(211),c=n(1410),d=n(3485),f=n(1198),p=n(5602),h=n(1558),v=n(1473),m=n(4379),g=n(5709),y=n(1931),_=n(3887),b=n(2203).Z?void 0:window.ResizeObserver;var T=n(944),E=n(4123),w=n(4309),S=n(7874);function k(e,t){return Math.abs(e-t)<=.2}function A(e,t){for(var n=e.length-1;n>=0;n--){if(e[n].startt)return e.slice(n,e.length)}return[]}function Z(e,t,n){var r=Math.max(e.start,t),i=A(e.cues,t),a={start:e.start,end:r,cues:i},o=Math.min(n,e.end),s=x(e.cues,n);return[a,{start:o,end:e.end,cues:s}]}var I=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=x(a.cues,n),a.start=n;else{var o=Z(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=A(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||k(i.end,t.end)?r[e]=i:(t.start>=i.end||(t.cues=x(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(k(s.end,n))return s.cues=A(s.cues,t),s.end=t,void r.splice(o+1,0,i);if(s.end>n){var u=Z(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)}for(s.cues=A(s.cues,t),s.end=t,s=r[o+1];void 0!==s&&n>s.end;)r.splice(o,1),s=r[o];return void a(o)}}r.push(i)},e}();function R(e,t,n,r){for(var i=[t/n.columns,e/n.rows],a=r.getElementsByClassName("proportional-style"),o=0;o0}var M=v.C1,C=v.ik,N=v.d5,P=T.Z.MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL,O=T.Z.TEXT_TRACK_SIZE_CHECKS_INTERVAL;function D(e,t){try{e.removeChild(t)}catch(e){_.Z.warn("HTSB: Can't remove text track: not in the element.")}}function L(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}}const B=function(e){function t(t,n){var r;return _.Z.debug("HTSB: Creating HTMLTextSegmentBuffer"),(r=e.call(this)||this).bufferType="text",r._buffered=new w.Z,r._videoElement=t,r._textTrackElement=n,r._clearSizeUpdates$=new l.xQ,r._destroy$=new l.xQ,r._buffer=new I,r._currentCues=[],function(e){var t=N(e),n=C(e),r=M(e),i=(0,a.T)(n,r),l=(0,o.F)(P).pipe((0,d.O)(null));return i.pipe((0,d.O)(null),(0,f.c)((0,s.z)(l.pipe((0,p.h)(!0),(0,h.R)(t)),(0,u.of)(!1))))}(r._videoElement).pipe((0,h.R)(r._destroy$)).subscribe((function(e){if(e){var t=Math.max(r._videoElement.currentTime+P/1e3/2,0),n=r._buffer.get(t);0===n.length?r._disableCurrentCues():r._displayCues(n)}else r._disableCurrentCues()})),r}i()(t,e);var n=t.prototype;return n.pushChunk=function(e){var t=this;return(0,c.P)((function(){return t.pushChunkSync(e),(0,u.of)(void 0)}))},n.removeBuffer=function(e,t){var n=this;return(0,c.P)((function(){return n.removeBufferSync(e,t),(0,u.of)(void 0)}))},n.endOfSegment=function(e){var t=this;return(0,c.P)((function(){return t._segmentInventory.completeSegment(e),(0,u.of)(void 0)}))},n.getBufferedRanges=function(){return this._buffered},n.dispose=function(){_.Z.debug("HTSB: Disposing HTMLTextSegmentBuffer"),this._disableCurrentCues(),this._buffer.remove(0,1/0),this._buffered.remove(0,1/0),this._destroy$.next(),this._destroy$.complete()},n.pushChunkSync=function(e){var t,n;_.Z.debug("HTSB: Appending new html text tracks");var r=e.data,i=r.timestampOffset,a=r.appendWindow,o=r.chunk;if(null!==o){var s,u,l=o.start,c=o.end,d=o.data,f=o.type,p=o.language,h=null!==(t=a[0])&&void 0!==t?t:0,v=null!==(n=a[1])&&void 0!==n?n:1/0,m=function(e,t,n,r){_.Z.debug("HTSB: Finding parser for html text tracks:",e);var i=S.Z.htmlTextTracksParsers[e];if("function"!=typeof i)throw new Error("no parser found for the given text track");_.Z.debug("HTSB: Parser found, parsing...");var a=i(t,n,r);return _.Z.debug("HTTB: Parsed successfully!",a),a}(f,d,i,p);if(0!==h&&v!==1/0){for(var g=0;g=0&&m[g].start>=v;)g--;for(m.splice(g,m.length),g=m.length-1;g>=0&&m[g].end>v;)m[g].end=v,g--}if(void 0!==l)s=Math.max(h,l);else{if(m.length<=0)return void _.Z.warn("HTSB: Current text tracks have no cues nor start time. Aborting");_.Z.warn("HTSB: No start time given. Guessing from cues."),s=m[0].start}if(void 0!==c)u=Math.min(v,c);else{if(m.length<=0)return void _.Z.warn("HTSB: Current text tracks have no cues nor end time. Aborting");_.Z.warn("HTSB: No end time given. Guessing from cues."),u=m[m.length-1].end}u<=s?_.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(m,s,u),this._buffered.insert(s,u))}},n.removeBufferSync=function(e,t){_.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._clearSizeUpdates$.next(),this._currentCues.length>0){for(var e=0;e0&&function(e,t){return(0,c.P)((function(){if(void 0!==b){var n=-1,r=-1;return new m.y((function(t){var i=new b((function(e){if(0!==e.length){var i=e[0].contentRect,a=i.height,o=i.width;a===n&&o===r||(n=a,r=o,t.next({height:a,width:o}))}else _.Z.error("Compat: Resized but no observed element.")}));return i.observe(e),function(){i.disconnect()}}))}return(0,o.F)(t).pipe((0,d.O)(null),(0,g.U)((function(){var t=e.getBoundingClientRect();return{height:t.height,width:t.width}})),(0,y.x)((function(e,t){return e.height===t.height&&e.width===t.width})))}))}(this._textTrackElement,O).pipe((0,h.R)(this._clearSizeUpdates$),(0,h.R)(this._destroy$)).subscribe((function(e){for(var t=e.height,n=e.width,r=0;r{"use strict";n.d(t,{Z:()=>p});var r=n(5354),i=n.n(r),a=n(1410),o=n(8170),s=n(3666);var u=n(3887);function l(e,t){if(s.vU&&function(e,t){var n=e.activeCues;if(null===n)return!1;for(var r=0;r0?e.textTracks[u-1]:e.addTextTrack(o)).mode=t?null!==(n=i.HIDDEN)&&void 0!==n?n:"hidden":null!==(r=i.SHOWING)&&void 0!==r?r:"showing"}else a=document.createElement("track"),e.appendChild(a),i=a.track,a.kind=o,i.mode=t?"hidden":"showing";return{track:i,trackElement:a}}(t,n),a=i.track,o=i.trackElement;return r.bufferType="text",r._buffered=new d.Z,r._videoElement=t,r._track=a,r._trackElement=o,r}i()(t,e);var n=t.prototype;return n.pushChunk=function(e){var t=this;return(0,a.P)((function(){var n,r;if(u.Z.debug("NTSB: Appending new native text tracks"),null===e.data.chunk)return(0,o.of)(void 0);var i,a,s=e.data,l=s.timestampOffset,c=s.appendWindow,d=s.chunk,p=d.start,h=d.end,v=d.data,m=d.type,g=d.language,y=null!==(n=c[0])&&void 0!==n?n:0,_=null!==(r=c[1])&&void 0!==r?r:1/0,b=function(e,t,n,r){u.Z.debug("NTSB: Finding parser for native text tracks:",e);var i=f.Z.nativeTextTracksParsers[e];if("function"!=typeof i)throw new Error("no parser found for the given text track");u.Z.debug("NTSB: Parser found, parsing...");var a=i(t,n,r);return u.Z.debug("NTSB: Parsed successfully!",a),a}(m,v,l,g);if(0!==y&&_!==1/0){for(var T=0;T=0&&b[T].startTime>=_;)T--;for(b.splice(T,b.length),T=b.length-1;T>=0&&b[T].endTime>_;)b[T].endTime=_,T--}if(void 0!==p)i=Math.max(y,p);else{if(b.length<=0)return u.Z.warn("NTSB: Current text tracks have no cues nor start time. Aborting"),(0,o.of)(void 0);u.Z.warn("NTSB: No start time given. Guessing from cues."),i=b[0].startTime}if(void 0!==h)a=Math.min(_,h);else{if(b.length<=0)return u.Z.warn("NTSB: Current text tracks have no cues nor end time. Aborting"),(0,o.of)(void 0);u.Z.warn("NTSB: No end time given. Guessing from cues."),a=b[b.length-1].endTime}if(a<=i)return u.Z.warn("NTSB: Invalid text track appended: ","the start time is inferior or equal to the end time."),(0,o.of)(void 0);if(b.length>0){var E=b[0],w=t._track.cues;null!==w&&w.length>0&&E.startTime=0;i--){var a=r[i],o=a.startTime,s=a.endTime;o>=e&&o<=t&&s<=t&&l(n,a)}this._buffered.remove(e,t)},t}(c.C)},4123:(e,t,n)=>{"use strict";n.d(t,{C:()=>m,f:()=>v});var r=n(944),i=n(3887),a=n(5952),o=n(5278),s=r.Z.MAX_MANIFEST_BUFFERED_START_END_DIFFERENCE,u=r.Z.MAX_MANIFEST_BUFFERED_DURATION_DIFFERENCE,l=r.Z.MINIMUM_SEGMENT_SIZE,c=function(){function e(){this._inventory=[]}var t=e.prototype;return t.reset=function(){this._inventory.length=0},t.synchronizeBuffered=function(e){for(var t=this._inventory,n=0,r=t[0],a=null==r?void 0:r.infos.adaptation.type,s=e.length,u=0;u0){var g=t[f+m-1];v={end:(0,o.Z)(g.bufferedEnd,g.end),precizeEnd:g.precizeEnd},i.Z.debug("SI: "+m+" segments GCed.",a),t.splice(f,m),n=f}if(void 0===r)return;if(d-(0,o.Z)(r.bufferedStart,r.start)>=l){if(p(r,c,v,a),n===t.length-1)return void h(r,d,a);r=t[++n];for(var y=(0,o.Z)(r.bufferedStart,r.start),_=(0,o.Z)(r.bufferedEnd,r.end),b=u=l&&(void 0===b||d-y>=_-b);){var T=t[n-1];void 0===T.bufferedEnd&&(T.bufferedEnd=r.precizeStart?r.start:T.end,i.Z.debug("SI: calculating buffered end of contiguous segment",a,T.bufferedEnd,T.end)),r.bufferedStart=T.bufferedEnd,void 0!==(r=t[++n])&&(y=(0,o.Z)(r.bufferedStart,r.start),_=(0,o.Z)(r.bufferedEnd,r.end))}}var E=t[n-1];void 0!==E&&h(E,d,a)}}null!=r&&(i.Z.debug("SI: last segments have been GCed",a,n,t.length),t.splice(n,t.length-n)),void 0!==a&&"DEBUG"===i.Z.getLevel()&&i.Z.debug("SI: current "+a+" 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=s)i.Z.warn("SI: Invalid chunked inserted: starts before it ends",u,o,s);else{for(var l=this._inventory,c={partiallyPushed:!0,estimatedStart:o,start:o,end:s,precizeStart:!1,precizeEnd:!1,bufferedStart:void 0,bufferedEnd:void 0,infos:{segment:a,period:t,adaptation:n,representation:r}},d=l.length-1;d>=0;d--){var f=l[d];if(f.start<=o){if(f.end<=o){for(i.Z.debug("SI: Pushing segment strictly after previous one.",u,o,f.end),this._inventory.splice(d+1,0,c),d+=2;dc.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,c.end,l[d].start),l[d].start=c.end,l[d].bufferedStart=void 0,void(l[d].precizeStart=l[d].precizeStart&&c.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[d].start,l[d].end),l.splice(d,1)}return}if(f.start===o){if(f.end<=s){for(i.Z.debug("SI: Segment pushed replace another one",u,o,s,f.end),this._inventory.splice(d,1,c),d+=1;dc.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,c.end,l[d].start),l[d].start=c.end,l[d].bufferedStart=void 0,void(l[d].precizeStart=l[d].precizeStart&&c.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[d].start,l[d].end),l.splice(d,1)}return}return i.Z.debug("SI: Segment pushed ends before another with the same start",u,o,s,f.end),l.splice(d,0,c),f.start=c.end,f.bufferedStart=void 0,void(f.precizeStart=f.precizeStart&&c.precizeEnd)}if(f.end<=c.end){for(i.Z.debug("SI: Segment pushed updates end of previous one",u,o,s,f.start,f.end),this._inventory.splice(d+1,0,c),f.end=c.start,f.bufferedEnd=void 0,f.precizeEnd=f.precizeEnd&&c.precizeStart,d+=2;dc.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,c.end,l[d].start),l[d].start=c.end,l[d].bufferedStart=void 0,void(l[d].precizeStart=l[d].precizeStart&&c.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[d].start,l[d].end),l.splice(d,1)}return}i.Z.debug("SI: Segment pushed is contained in a previous one",u,o,s,f.start,f.end);var p={partiallyPushed:f.partiallyPushed,start:c.end,end:f.end,precizeStart:f.precizeStart&&f.precizeEnd&&c.precizeEnd,precizeEnd:f.precizeEnd,bufferedStart:void 0,bufferedEnd:f.end,infos:f.infos};return f.end=c.start,f.bufferedEnd=void 0,f.precizeEnd=f.precizeEnd&&c.precizeStart,l.splice(d+1,0,c),void l.splice(d+2,0,p)}}var h=this._inventory[0];if(void 0===h)return i.Z.debug("SI: first segment pushed",u,o,s),void this._inventory.push(c);if(!(h.start>=s)){if(h.end<=s){for(i.Z.debug("SI: Segment pushed starts before and completely recovers the previous first one",u,o,s,h.start,h.end),this._inventory.splice(0,1,c);l.length>1&&l[1].startc.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,c.end,l[1].start),l[1].start=c.end,l[1].bufferedStart=void 0,void(l[1].precizeStart=c.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[1].start,l[1].end),l.splice(1,1)}return}return i.Z.debug("SI: Segment pushed start of the next one",u,o,s,h.start,h.end),h.start=s,h.bufferedStart=void 0,h.precizeStart=c.precizeEnd,void this._inventory.splice(0,0,c)}i.Z.debug("SI: Segment pushed comes before all previous ones",u,o,s,h.start),this._inventory.splice(0,0,c)}}},t.completeSegment=function(e){if(!e.segment.isInit){for(var t=this._inventory,n=!1,r=0;r0&&(this._inventory.splice(o+1,u),r-=u),this._inventory[o].partiallyPushed=!1,this._inventory[o].end=l,this._inventory[o].bufferedEnd=c}n||i.Z.warn("SI: Completed Segment not found",e)}},t.getInventory=function(){return this._inventory},e}();function d(e){if(void 0===e.bufferedStart||e.partiallyPushed)return!1;var t=e.start,n=e.end-t;return Math.abs(t-e.bufferedStart)<=s&&(void 0===e.bufferedEnd||e.bufferedEnd>e.bufferedStart&&Math.abs(e.bufferedEnd-e.bufferedStart-n)<=Math.min(u,n/3))}function f(e){if(void 0===e.bufferedEnd||e.partiallyPushed)return!1;var t=e.start,n=e.end,r=n-t;return Math.abs(n-e.bufferedEnd)<=s&&null!=e.bufferedStart&&e.bufferedEnd>e.bufferedStart&&Math.abs(e.bufferedEnd-e.bufferedStart-r)<=Math.min(u,r/3)}function p(e,t,n,r){void 0!==e.bufferedStart?(e.bufferedStartt&&(n.precizeEnd||e.start-n.end<=s)?(i.Z.debug("SI: buffered start is end of previous segment",r,t,e.start,n.end),e.bufferedStart=n.end,d(e)&&(e.start=n.end,e.precizeStart=!0)):e.start-t<=s?(i.Z.debug("SI: found true buffered start",r,t,e.start),e.bufferedStart=t,d(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<=s&&f(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<=s?(i.Z.debug("SI: found true buffered end",n,t,e.end),e.bufferedEnd=t,f(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 v,m=function(){function e(){this._segmentInventory=new c}var t=e.prototype;return t.synchronizeInventory=function(){this._segmentInventory.synchronizeBuffered(this.getBufferedRanges())},t.getInventory=function(){return this._segmentInventory.getInventory()},t.getPendingOperations=function(){return[]},e}();!function(e){e[e.Push=0]="Push",e[e.Remove=1]="Remove",e[e.EndOfSegment=2]="EndOfSegment"}(v||(v={}))},4309:(e,t,n)=>{"use strict";n.d(t,{Z:()=>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}()},3801:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(1506),i=n.n(r),a=n(5354),o=n.n(a),s=n(5957),u=function(e){function t(n){var r;return r=e.call(this)||this,Object.setPrototypeOf(i()(r),t.prototype),r.name="AssertionError",r.message=n,r}return o()(t,e),t}(n.n(s)()(Error))},5157:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(1506),i=n.n(r),a=n(5354),o=n.n(a),s=n(5957),u=n.n(s),l=n(5992),c=n(7367),d=function(e){function t(n,r){var a;return a=e.call(this)||this,Object.setPrototypeOf(i()(a),t.prototype),a.name="EncryptedMediaError",a.type=l.ZB.ENCRYPTED_MEDIA_ERROR,a.code=n,a.message=(0,c.Z)(a.name,a.code,r),a.fatal=!1,a}return o()(t,e),t}(u()(Error))},5992:(e,t,n)=>{"use strict";n.d(t,{ZB:()=>r,br:()=>i,SM:()=>a});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:(e,t,n)=>{"use strict";function r(e,t,n){return e+" ("+t+") "+n}n.d(t,{Z:()=>r})},9822:(e,t,n)=>{"use strict";n.d(t,{Z:()=>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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(1506),i=n.n(r),a=n(5354),o=n.n(a),s=n(5957),u=n.n(s),l=n(5992),c=n(7367),d=function(e){function t(n,r){var a;return a=e.call(this)||this,Object.setPrototypeOf(i()(a),t.prototype),a.name="MediaError",a.type=l.ZB.MEDIA_ERROR,a.code=n,a.message=(0,c.Z)(a.name,a.code,r),a.fatal=!1,a}return o()(t,e),t}(u()(Error))},9362:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(1506),i=n.n(r),a=n(5354),o=n.n(a),s=n(5957),u=n.n(s),l=n(5992),c=n(7367),d=function(e){function t(n,r){var a;return a=e.call(this)||this,Object.setPrototypeOf(i()(a),t.prototype),a.name="NetworkError",a.type=l.ZB.NETWORK_ERROR,a.xhr=void 0===r.xhr?null:r.xhr,a.url=r.url,a.status=r.status,a.errorType=r.type,a.code=n,a.message=(0,c.Z)(a.name,a.code,r.message),a.fatal=!1,a}return o()(t,e),t.prototype.isHttpError=function(e){return this.errorType===l.br.ERROR_HTTP_CODE&&this.status===e},t}(u()(Error))},5389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(1506),i=n.n(r),a=n(5354),o=n.n(a),s=n(5957),u=n.n(s),l=n(5992),c=n(7367),d=function(e){function t(n,r){var a;return a=e.call(this)||this,Object.setPrototypeOf(i()(a),t.prototype),a.name="OtherError",a.type=l.ZB.OTHER_ERROR,a.code=n,a.message=(0,c.Z)(a.name,a.code,r),a.fatal=!1,a}return o()(t,e),t}(u()(Error))},9105:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(1506),i=n.n(r),a=n(5354),o=n.n(a),s=n(5957),u=function(e){function t(n,r,a,o){var s;return s=e.call(this)||this,Object.setPrototypeOf(i()(s),t.prototype),s.name="RequestError",s.url=n,s.xhr=o,s.status=r,s.type=a,s.message=a,s}return o()(t,e),t}(n.n(s)()(Error))},7273:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r={directfile:null,emeManager:null,htmlTextTracksBuffer:null,htmlTextTracksParsers:{},imageBuffer:null,imageParser:null,nativeTextTracksBuffer:null,nativeTextTracksParsers:{},transports:{}}},7874:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=n(7273).Z},1452:(e,t,n)=>{"use strict";n.d(t,{default:()=>Ui});var r=n(3913),i=n.n(r),a=n(5354),o=n.n(a),s=n(211),u=n(2135),l=n(655),c=n(1016),d=function(e){function t(t){var n=e.call(this)||this;return n._value=t,n}return l.ZT(t,e),Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!0,configurable:!0}),t.prototype._subscribe=function(t){var n=e.prototype._subscribe.call(this,t);return n&&!n.closed&&t.next(this._value),n},t.prototype.getValue=function(){if(this.hasError)throw this.thrownError;if(this.closed)throw new c.N;return this._value},t.prototype.next=function(t){e.prototype.next.call(this,this._value=t)},t}(s.xQ),f=n(4370),p=n(5631),h=n(5142),v=n(9795),m=n(8170),g=n(1558),y=n(5709),_=n(1931),b=n(1015),T=n(1421);function E(e){return e?(0,T.O)((function(){return new s.xQ}),e):(0,T.O)(new s.xQ)}var w=n(6008),S=n(9095),k=n(3485),A=n(5602),x=n(979);var Z=function(){function e(e){this.predicate=e}return e.prototype.call=function(e,t){return t.subscribe(new I(e,this.predicate))},e}(),I=function(e){function t(t,n){var r=e.call(this,t)||this;return r.predicate=n,r.skipping=!0,r.index=0,r}return l.ZT(t,e),t.prototype._next=function(e){var t=this.destination;this.skipping&&this.tryCallPredicate(e),this.skipping||t.next(e)},t.prototype.tryCallPredicate=function(e){try{var t=this.predicate(e,this.index++);this.skipping=Boolean(t)}catch(e){this.destination.error(e)}},t}(x.L),R=n(1198),M=n(3756),C=n(1473);function N(){if(P()){var e=document;"function"==typeof e.exitFullscreen?e.exitFullscreen():"function"==typeof e.msExitFullscreen?e.msExitFullscreen():"function"==typeof e.mozCancelFullScreen?e.mozCancelFullScreen():"function"==typeof e.webkitExitFullscreen&&e.webkitExitFullscreen()}}function P(){var e=document;return null!=e.fullscreenElement||null!=e.mozFullScreenElement||null!=e.webkitFullscreenElement||null!=e.msFullscreenElement}var O=n(3666),D=n(3887);function L(){var e,t;if(!O.vU)return!0;var n=function(){if(!O.vU)return D.Z.warn("Compat: Can't access Firefox version on no firefox browser."),null;var e=navigator.userAgent,t=/Firefox\/([0-9]+)\./.exec(e);if(null===t)return-1;var n=parseInt(t[1],10);return isNaN(n)?-1:n}();return null===n||n<67||void 0!==(null===(t=null===(e=HTMLVideoElement)||void 0===e?void 0:e.prototype)||void 0===t?void 0:t.requirePictureInPicture)}var B=n(944),U=n(3714),F=n(9822),z=n(5389);function V(e,t){var n=t.defaultCode,r=t.defaultReason;if((0,F.Z)(e))return e;var i=e instanceof Error?e.toString():r;return new z.Z(n,i)}var K=n(5992),H=n(7874),W=n(4791),$=n(1959),G=n(1946),j=n(8894),Y=n(8026),q=n(9589),X=n(2829),Q=n(8806),J=n(1410),ee=n(6139),te=n(6033);function ne(e){return(0,J.P)((function(){var t=te.Z.getState(e);if(null===t)return(0,m.of)(null);D.Z.info("EME: Disposing of the current MediaKeys");var n=t.loadedSessionsStore;return te.Z.clearState(e),n.closeAllSessions().pipe((0,M.j)((0,ee.Y)(e,null)))}))}function re(e){var t=te.Z.getState(e);return null==t?null:t.keySystemOptions.type}var ie=n(6738);function ae(e){return(0,J.P)((function(){if(D.Z.info("EME: Clearing-up EME session."),O.fq)return D.Z.info("EME: disposing current MediaKeys."),ne(e).pipe((0,ie.l)());var t=te.Z.getState(e);return null!==t&&!0===t.keySystemOptions.closeSessionsOnStop?(D.Z.info("EME: closing all current sessions."),t.loadedSessionsStore.closeAllSessions().pipe((0,ie.l)())):(D.Z.info("EME: Nothing to clear. Returning right away. No state =",null===t),p.E)}))}var oe=n(7746),se=n(7006),ue=n(4072),le=n(7604);function ce(e,t){return t?function(n){return n.pipe(ce((function(n,r){return(0,ue.D)(e(n,r)).pipe((0,y.U)((function(e,i){return t(n,e,r,i)})))})))}:function(t){return t.lift(new de(e))}}var de=function(){function e(e){this.project=e}return e.prototype.call=function(e,t){return t.subscribe(new fe(e,this.project))},e}(),fe=function(e){function t(t,n){var r=e.call(this,t)||this;return r.project=n,r.hasSubscription=!1,r.hasCompleted=!1,r.index=0,r}return l.ZT(t,e),t.prototype._next=function(e){this.hasSubscription||this.tryNext(e)},t.prototype.tryNext=function(e){var t,n=this.index++;try{t=this.project(e,n)}catch(e){return void this.destination.error(e)}this.hasSubscription=!0,this._innerSub(t)},t.prototype._innerSub=function(e){var t=new le.IY(this),n=this.destination;n.add(t);var r=(0,le.ft)(e,t);r!==t&&n.add(r)},t.prototype._complete=function(){this.hasCompleted=!0,this.hasSubscription||this.destination.complete(),this.unsubscribe()},t.prototype.notifyNext=function(e){this.destination.next(e)},t.prototype.notifyError=function(e){this.destination.error(e)},t.prototype.notifyComplete=function(){this.hasSubscription=!1,this.hasCompleted&&this.destination.complete()},t}(le.Ds),pe=n(3068),he=n(3884);function ve(e){return function(t){return t.lift(new me(e))}}var me=function(){function e(e){this.callback=e}return e.prototype.call=function(e,t){return t.subscribe(new ge(e,this.callback))},e}(),ge=function(e){function t(t,n){var r=e.call(this,t)||this;return r.add(new he.w(n)),r}return l.ZT(t,e),t}(x.L),ye=n(6381);var _e=n(1966),be=n(8025),Te=n(2793),Ee=n(4379);var we=n(5278),Se=function(){function e(e){this._alpha=Math.exp(Math.log(.5)/e),this._lastEstimate=0,this._totalWeight=0}var t=e.prototype;return t.addSample=function(e,t){var n=Math.pow(this._alpha,e),r=t*(1-n)+n*this._lastEstimate;isNaN(r)||(this._lastEstimate=r,this._totalWeight+=e)},t.getEstimate=function(){var e=1-Math.pow(this._alpha,this._totalWeight);return this._lastEstimate/e},e}(),ke=B.Z.ABR_MINIMUM_TOTAL_BYTES,Ae=B.Z.ABR_MINIMUM_CHUNK_SIZE,xe=B.Z.ABR_FAST_EMA,Ze=B.Z.ABR_SLOW_EMA,Ie=function(){function e(){this._fastEWMA=new Se(xe),this._slowEWMA=new Se(Ze),this._bytesSampled=0}var t=e.prototype;return t.addSample=function(e,t){if(!(t0){var i=r.indexOf(n);-1!==i&&r.splice(i,1)}},t.prototype.notifyComplete=function(){},t.prototype._next=function(e){if(0===this.toRespond.length){var t=[e].concat(this.values);this.project?this._tryProject(t):this.destination.next(t)}},t.prototype._tryProject=function(e){var t;try{t=this.project.apply(this,e)}catch(e){return void this.destination.error(e)}this.destination.next(t)},t}(Re.L);function Oe(e){var t=e.map((function(t){return Math.log(t/e[0])})),n=t.map((function(e){return e-t[0]+1})),r=(n[n.length-1]-1)/(2*e.length+10),i=1/r;return e.map((function(t,a){return function(t){if(0===t)return 0;var a=Math.min(Math.max(1,t),e.length-1);return i*(r+(e[a]*n[a-1]-e[a-1]*n[a])/(e[a]-e[a-1]))+4}(a)}))}var De=n(5138);function Le(e,t){var n=Oe(t);return D.Z.debug("ABR: Steps for buffer based chooser.",n.map((function(e,n){return{bufferLevel:e,bitrate:t[n]}}))),e.pipe((0,y.U)((function(e){return function(e,t,n){var r=e.bufferGap,i=e.currentBitrate,a=e.currentScore,o=e.speed;if(null==i)return t[0];var s,u=(0,De.Z)(t,(function(e){return e===i}));if(u<0||t.length!==n.length)return D.Z.error("ABR: Current Bitrate not found in the calculated levels"),t[0];if(null!=a&&(s=0===o?a:a/o),null!=s&&s>1){var l=n[u],c=function(){for(var e=u+1;el)return e}();if(null!=c&&r>=n[c])return t[c]}if((null==s||s<1.15)&&r=0;d--)if(t[d]t&&Math.abs(t-e.time)<-.3}));if(n<0)return[];for(var r=e[n],i=r.time,a=[r],o=n+1;o0?a.progress[a.progress.length-1]:void 0,l=$e(a);if(void 0!==u&&void 0!==l){var c=Ge(u,l);if((s-u.timestamp)/1e3<=c)if(c-t.bufferGap/t.speed>2e3)return l}var d=(s-a.requestTimestamp)/1e3,f=d<=(1.5*o+2)/t.speed;if(null!=n&&!f){var p=o/d,h=n.bitrate*Math.min(.7,p);return void 0===r||h=s.outOfStarvationGap&&(D.Z.info("ABR: exit starvation mode."),this._inStarvationMode=!1):this._inStarvationMode&&(D.Z.info("ABR: exit starvation mode."),this._inStarvationMode=!1),this._inStarvationMode&&null!=(o=je(r,e,n,i))&&(D.Z.info("ABR: starvation mode emergency estimate:",o),t.reset(),a=null==n?o:Math.min(o,n.bitrate)),null==a&&(a=null!=(o=t.getEstimate())?o*(this._inStarvationMode?s.starvationBitrateFactor:s.regularBitrateFactor):null!=i?i*(this._inStarvationMode?s.starvationBitrateFactor:s.regularBitrateFactor):this._initialBitrate),e.speed>1&&(a/=e.speed),{bandwidthEstimate:o,bitrateChosen:a}},t.isUrgent=function(e,t,n,r){return null===t||e!==t.bitrate&&(e>t.bitrate?!this._inStarvationMode:function(e,t){var n=e.position+e.bufferGap,r=(0,Fe.Z)(t,(function(e){return e.duration>0&&e.time+e.duration>n}));if(void 0===r)return!0;var i=performance.now(),a=r.progress.length>0?r.progress[r.progress.length-1]:void 0,o=$e(r);if(void 0===a||void 0===o)return!0;var s=Ge(a,o);return(i-a.timestamp)/1e3>1.2*s||s-e.bufferGap/e.speed>-1.5}(r,n))},e}(),qe=n(1679),Xe=function(){function e(){this._currentRequests={}}var t=e.prototype;return t.add=function(e){var t=e.id,n=e.time,r=e.duration,i=e.requestTimestamp;this._currentRequests[t]={time:n,duration:r,requestTimestamp:i,progress:[]}},t.addProgress=function(e){var t=this._currentRequests[e.id];null!=t?t.progress.push(e):D.Z.warn("ABR: progress for a request not added")},t.remove=function(e){null==this._currentRequests[e]&&D.Z.warn("ABR: can't remove unknown request"),delete this._currentRequests[e]},t.getRequests=function(){return(0,qe.Z)(this._currentRequests).filter((function(e){return null!=e})).sort((function(e,t){return e.time-t.time}))},e}(),Qe=function(){function e(){this._currentRepresentationData=null,this._lastRepresentationWithGoodScore=null}var t=e.prototype;return t.addSample=function(e,t,n){var r,i=n/t,a=this._getEWMA(e);null!=a?(r=a,a.addSample(t,i)):((r=new Se(5)).addSample(t,i),this._currentRepresentationData={representation:e,ewma:r}),r.getEstimate()>1&&this._lastRepresentationWithGoodScore!==e&&(D.Z.debug("ABR: New last stable representation",e),this._lastRepresentationWithGoodScore=e)},t.getEstimate=function(e){var t=this._getEWMA(e);if(null!=t)return t.getEstimate()},t.getLastStableRepresentation=function(){return this._lastRepresentationWithGoodScore},t._getEWMA=function(e){return null!=this._currentRepresentationData&&this._currentRepresentationData.representation.id===e.id?this._currentRepresentationData.ewma:null},e}();function Je(e,t,n,r){var i=t<=n?n:t>=r?r:t,a=(0,De.Z)(e,(function(e){return e.bitrate>i}));return-1===a?e[e.length-1]:0===a?e[0]:e[a-1]}function et(e,t){var n=e;return null!=t.bitrate&&(n=function(e,t){if(0===e.length)return[];e.sort((function(e,t){return e.bitrate-t.bitrate}));var n=e[0].bitrate,r=Math.max(t,n),i=(0,De.Z)(e,(function(e){return e.bitrate>r}));return-1===i?e:e.slice(0,i)}(n,t.bitrate)),null!=t.width&&(n=function(e,t){var n=e.slice().sort((function(e,t){return(0,we.Z)(e.width,0)-(0,we.Z)(t.width,0)})),r=(0,Fe.Z)(n,(function(e){return"number"==typeof e.width&&e.width>=t}));if(void 0===r)return e;var i="number"==typeof r.width?r.width:0;return e.filter((function(e){return"number"!=typeof e.width||e.width<=i}))}(n,t.width)),n}function tt(e){var t=e.bandwidthEstimator,n=e.clock$,r=e.filters$,i=e.initialBitrate,a=e.lowLatencyMode,o=e.manualBitrate$,s=e.minAutoBitrate$,u=e.maxAutoBitrate$,l=e.representations,c=e.streamEvents$,d=new Qe,p=new Ye(null==i?0:i,a),v=new Xe,g=Ue();var _=c.pipe((0,w.h)((function(e){return"metrics"===e.type})),(0,pe.b)((function(e){return function(e){var n=e.duration,r=e.size,i=e.content;if(!g(i,n)){t.addSample(n,r);var a=n/1e3,o=i.segment.duration,s=i.representation;d.addSample(s,a,o)}}(e.value)})),(0,ie.l)()),b=c.pipe((0,pe.b)((function(e){switch(e.type){case"requestBegin":v.add(e.value);break;case"requestEnd":v.remove(e.value.id);break;case"progress":v.addProgress(e.value)}})),(0,ie.l)()),T=c.pipe((0,w.h)((function(e){return"representationChange"===e.type})),(0,y.U)((function(e){return e.value.representation})),(0,k.O)(null)),E=(0,J.P)((function(){if(0===l.length)throw new Error("ABRManager: no representation choice given");return 1===l.length?(0,m.of)({bitrate:void 0,representation:l[0],manual:!1,urgent:!0,knownStableBitrate:void 0}):o.pipe((0,ye.w)((function(e){if(e>=0){var i=Je(l,e,0,1/0);return(0,m.of)({representation:i,bitrate:void 0,knownStableBitrate:void 0,manual:!0,urgent:!0})}var a,o=!0,f=Le(c.pipe((0,w.h)((function(e){return"added-segment"===e.type})),Ce(n),(0,y.U)((function(e){var t=e[0].value,n=e[1],r=n.speed,i=n.position,a=t.buffered,o=(0,X.L7)(a,i),s=t.content.representation,u=d.getEstimate(s);return{bufferGap:o,currentBitrate:s.bitrate,currentScore:u,speed:r}}))),l.map((function(e){return e.bitrate}))).pipe((0,k.O)(void 0));return(0,h.aj)([n,s,u,r,f]).pipe(Ce(T),(0,y.U)((function(e){var n=e[0],r=n[0],i=n[1],s=n[2],u=n[3],c=n[4],f=e[1],h=et(l,u),m=v.getRequests(),g=p.getBandwidthEstimate(r,t,f,m,a),y=g.bandwidthEstimate,_=g.bitrateChosen;a=y;var b=d.getLastStableRepresentation(),T=null==b?void 0:b.bitrate/(r.speed>0?r.speed:1),E=r.bufferGap;!o&&E<=5?o=!0:o&&isFinite(E)&&E>10&&(o=!1);var w=Je(h,_,i,s);if(o)return D.Z.debug("ABR: Choosing representation with bandwidth estimation.",w),{bitrate:y,representation:w,urgent:p.isUrgent(w.bitrate,f,m,r),manual:!1,knownStableBitrate:T};if(null==c||w.bitrate>=c)return D.Z.debug("ABR: Choosing representation with bandwidth estimation.",w),{bitrate:y,representation:w,urgent:p.isUrgent(w.bitrate,f,m,r),manual:!1,knownStableBitrate:T};var S=Je(h,c,i,s);return c<=s&&D.Z.debug("ABR: Choosing representation with buffer based bitrate ceiling.",S),{bitrate:y,representation:S,urgent:p.isUrgent(c,f,m,r),manual:!1,knownStableBitrate:T}})))})))}));return(0,f.T)(_,b,E)}const nt=function(){function e(e){this._manualBitrates=e.manualBitrates,this._minAutoBitrates=e.minAutoBitrates,this._maxAutoBitrates=e.maxAutoBitrates,this._initialBitrates=e.initialBitrates,this._throttlers=e.throttlers,this._bandwidthEstimators={},this._lowLatencyMode=e.lowLatencyMode}var t=e.prototype;return t.get$=function(e,t,n,r){var i,a,o,s,u=this._getBandwidthEstimator(e),l=(0,we.Z)(this._manualBitrates[e],(0,m.of)(-1)),c=(0,we.Z)(this._minAutoBitrates[e],(0,m.of)(0)),d=(0,we.Z)(this._maxAutoBitrates[e],(0,m.of)(1/0)),f=(0,we.Z)(this._initialBitrates[e],0);return tt({bandwidthEstimator:u,streamEvents$:r,clock$:n,filters$:(i=this._throttlers.limitWidth[e],a=this._throttlers.throttleBitrate[e],o=this._throttlers.throttle[e],s=[],null!=i&&s.push(i.pipe((0,y.U)((function(e){return{width:e}})))),null!=o&&s.push(o.pipe((0,y.U)((function(e){return{bitrate:e}})))),null!=a&&s.push(a.pipe((0,y.U)((function(e){return{bitrate:e}})))),s.length>0?(0,h.aj)(s).pipe((0,y.U)((function(e){return Y.Z.apply(void 0,[{}].concat(e))}))):(0,m.of)({})),initialBitrate:f,manualBitrate$:l,minAutoBitrate$:c,maxAutoBitrate$:d,representations:t,lowLatencyMode:this._lowLatencyMode})},t._getBandwidthEstimator=function(e){var t=this._bandwidthEstimators[e];if(null==t){D.Z.debug("ABR: Creating new BandwidthEstimator for ",e);var n=new Ie;return this._bandwidthEstimators[e]=n,n}return t},e}();var rt=n(486),it=n(5561),at=n(9105),ot=n(9362);function st(e){return e instanceof at.Z?new ot.Z("PIPELINE_LOAD_ERROR",e):V(e,{defaultCode:"PIPELINE_LOAD_ERROR",defaultReason:"Unknown error when fetching the Manifest"})}var ut=n(9604);var lt,ct=n(2572);function dt(e){return e.type===K.br.ERROR_EVENT&&!1===navigator.onLine}function ft(e,t,n){var r=n.baseDelay,i=n.maxDelay,a=n.maxRetryRegular,o=n.maxRetryOffline,s=0,u=lt.None,l=e.slice();return 0===l.length?(D.Z.warn("Fetchers: no URL given to `tryURLsWithBackoff`."),p.E):function e(n,c){return t(n).pipe((0,y.U)((function(e){return{type:"response",value:e}})),(0,rt.K)((function(t){if(!function(e){return e instanceof at.Z?e.type===K.br.ERROR_HTTP_CODE?e.status>=500||404===e.status||415===e.status||412===e.status:e.type===K.br.TIMEOUT||e.type===K.br.ERROR_EVENT:(0,F.Z)(e)&&"INTEGRITY_ERROR"===e.code}(t)){if(l.length<=1)throw t;l.splice(c,1);var n=c>=l.length-1?0:c;return e(l[n],n).pipe((0,k.O)({type:"retry",value:t}))}var d=function(e){return e instanceof at.Z&&dt(e)?lt.Offline:lt.Regular}(t),f=d===lt.Offline?o:a;if(d!==u&&(s=0,u=d),cf)throw t;var h=Math.min(r*Math.pow(2,s-1),i),v=(0,ct.Z)(h),m=l[0];return(0,ut.H)(v).pipe((0,oe.zg)((function(){return e(m,0)})),(0,k.O)({type:"retry",value:t}))})))}(l[0],0)}function pt(e,t){return ft([null],(function(){return e}),t)}!function(e){e[e.None=0]="None",e[e.Regular=1]="Regular",e[e.Offline=2]="Offline"}(lt||(lt={}));var ht=B.Z.DEFAULT_MAX_MANIFEST_REQUEST_RETRY,vt=B.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE,mt=B.Z.INITIAL_BACKOFF_DELAY_BASE,gt=B.Z.MAX_BACKOFF_DELAY_BASE;const yt=function(){function e(e,t,n){var r,i,a,o;this._manifestUrl=e,this._pipelines=t.manifest,this._backoffOptions=(i=(r=n).maxRetryRegular,a=r.maxRetryOffline,{baseDelay:(o=r.lowLatencyMode)?mt.LOW_LATENCY:mt.REGULAR,maxDelay:o?gt.LOW_LATENCY:gt.REGULAR,maxRetryRegular:void 0!==i?i:ht,maxRetryOffline:void 0!==a?a:vt})}var t=e.prototype;return t.fetch=function(e){var t,n=this,r=null!=e?e:this._manifestUrl,i=null!==(t=this._pipelines.resolver)&&void 0!==t?t:m.of,a=this._pipelines.loader;return(0,it.Z)(i,{url:r}).pipe((0,rt.K)((function(e){throw st(e)})),(0,oe.zg)((function(e){return pt((0,it.Z)(a,e),n._backoffOptions).pipe((0,rt.K)((function(e){throw st(e)})),(0,y.U)((function(e){return"retry"===e.type?{type:"warning",value:st(e.value)}:{type:"response",parse:function(t){return n._parseLoadedManifest(e.value.value,t)}}})))})))},t.parse=function(e,t){return this._parseLoadedManifest({responseData:e,size:void 0,duration:void 0},t)},t._parseLoadedManifest=function(e,t){var n,r,i=e.sendingTime,a=e.receivedTime,o=performance.now(),u=new s.xQ,l=(n=this._backoffOptions,r=u,function(e){return pt((0,it.Z)(e,void 0),n).pipe((0,Te.Z)((function(e){return"retry"===e.type?(r.next(st(e.value)),null):e.value}),null),(0,rt.K)((function(e){throw st(e)})))});return(0,f.T)(u.pipe((0,y.U)((function(e){return{type:"warning",value:e}}))),this._pipelines.parser({response:e,url:this._manifestUrl,externalClockOffset:t.externalClockOffset,previousManifest:t.previousManifest,scheduleRequest:l,unsafeMode:t.unsafeMode}).pipe((0,rt.K)((function(e){throw V(e,{defaultCode:"PIPELINE_PARSE_ERROR",defaultReason:"Unknown error when parsing the Manifest"})})),(0,y.U)((function(e){if("warning"===e.type)return{type:"warning",value:V(e.value,{defaultCode:"PIPELINE_PARSE_ERROR",defaultReason:"Unknown error when parsing the Manifest"})};var t=performance.now()-o;return{type:"parsed",manifest:e.value.manifest,sendingTime:i,receivedTime:a,parsingTime:t}})),ve((function(){u.complete()}))))},e}();var _t=B.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR,bt=B.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE,Tt=B.Z.INITIAL_BACKOFF_DELAY_BASE,Et=B.Z.MAX_BACKOFF_DELAY_BASE;var wt=function(){function e(e){var t=e.prioritySteps;if(this._minPendingPriority=null,this._waitingQueue=[],this._pendingTasks=[],this._prioritySteps=t,this._prioritySteps.high>=this._prioritySteps.low)throw new Error("FP Error: the max high level priority should be given a lowerpriority number than the min low priority.")}var t=e.prototype;return t.create=function(e,t){var n=this,r=new Ee.y((function(i){var a,o=!0;return a={observable:r,priority:t,trigger:function(t){null!==a.subscription&&(a.subscription.unsubscribe(),a.subscription=null,o&&i.next({type:"interrupted"})),t&&(n._minPendingPriority=null===n._minPendingPriority?a.priority:Math.min(n._minPendingPriority,a.priority),n._pendingTasks.push(a),a.subscription=e.subscribe((function(e){return i.next({type:"data",value:e})}),(function(e){i.error(e),a.subscription=null,a.finished=!0,n._onTaskEnd(a)}),(function(){i.next({type:"ended"}),o&&i.complete(),a.subscription=null,a.finished=!0,n._onTaskEnd(a)})))},subscription:null,finished:!1},n._canBeStartedNow(a)?(a.trigger(!0),n._isRunningHighPriorityTasks()&&n._interruptCancellableTasks()):n._waitingQueue.push(a),function(){if(o=!1,null!==a.subscription&&(a.subscription.unsubscribe(),a.subscription=null),!a.finished){var e=(0,De.Z)(n._waitingQueue,(function(e){return e.observable===r}));if(e>=0)n._waitingQueue.splice(e,1);else{var t=(0,De.Z)(n._pendingTasks,(function(e){return e.observable===r}));if(t<0)return void D.Z.warn("FP: unsubscribing non-existent task");var i=n._pendingTasks.splice(t,1)[0];0===n._pendingTasks.length?(n._minPendingPriority=null,n._loopThroughWaitingQueue()):n._minPendingPriority===i.priority&&(n._minPendingPriority=Math.min.apply(Math,n._pendingTasks.map((function(e){return e.priority}))),n._loopThroughWaitingQueue())}}}}));return r},t.updatePriority=function(e,t){var n=(0,De.Z)(this._waitingQueue,(function(t){return t.observable===e}));if(n>=0){var r=this._waitingQueue[n];if(r.priority===t)return;if(r.priority=t,!this._canBeStartedNow(r))return;return this._startWaitingQueueTask(n),void(this._isRunningHighPriorityTasks()&&this._interruptCancellableTasks())}var i=(0,De.Z)(this._pendingTasks,(function(t){return t.observable===e}));if(i<0)D.Z.warn("FP: request to update the priority of a non-existent task");else{var a=this._pendingTasks[i];if(a.priority!==t){var o=a.priority;if(a.priority=t,null===this._minPendingPriority||tt.priority?t.priority:e}),null);if(!(null===e||null!==this._minPendingPriority&&this._minPendingPriority=this._prioritySteps.low)return this._interruptPendingTask(t),this._interruptCancellableTasks()}},t._startWaitingQueueTask=function(e){this._waitingQueue.splice(e,1)[0].trigger(!0)},t._interruptPendingTask=function(e){var t=(0,De.Z)(this._pendingTasks,(function(t){return t.observable===e.observable}));t<0?D.Z.warn("FP: Interrupting a non-existent pending task. Aborting..."):(this._pendingTasks.splice(t,1),this._waitingQueue.push(e),0===this._pendingTasks.length?this._minPendingPriority=null:this._minPendingPriority===e.priority&&(this._minPendingPriority=Math.min.apply(Math,this._pendingTasks.map((function(e){return e.priority})))),e.trigger(!1))},t._onTaskEnd=function(e){var t=(0,De.Z)(this._pendingTasks,(function(t){return t.observable===e.observable}));t<0||(this._pendingTasks.splice(t,1),this._pendingTasks.length>0?this._minPendingPriority===e.priority&&(this._minPendingPriority=Math.min.apply(Math,this._pendingTasks.map((function(e){return e.priority})))):(this._minPendingPriority=null,this._loopThroughWaitingQueue()))},t._canBeStartedNow=function(e){return null===this._minPendingPriority||e.priority<=this._minPendingPriority},t._isRunningHighPriorityTasks=function(){return null!==this._minPendingPriority&&this._minPendingPriority<=this._prioritySteps.high},e}(),St=n(7714),kt=n(8418),At=n(908);const xt=function(){function e(){this._cache=new WeakMap}var t=e.prototype;return t.add=function(e,t){var n=e.representation;e.segment.isInit&&this._cache.set(n,t)},t.get=function(e){var t=e.representation;if(e.segment.isInit){var n=this._cache.get(t);if(void 0!==n)return n}return null},e}();var Zt=n(8117);function It(e,t,n){return function(r){return function(r){function i(){var i;return ft(null!==(i=r.segment.mediaURLs)&&void 0!==i?i:[null],(function(t){var n=(0,Y.Z)({url:t},r);return(0,v.z)((0,m.of)({type:"request",value:n}),(0,it.Z)(e,n))}),n).pipe((0,rt.K)((function(e){throw st(e)})),(0,y.U)((function(e){if("retry"===e.type)return{type:"warning",value:st(e.value)};if("request"===e.value.type)return e.value;var n=e.value;return"data-loaded"===n.type&&null!=t&&t.add(r,n.value),e.value})))}var a=null!=t?t.get(r):null;return null!=a?(0,Zt.Z)(a).pipe((0,y.U)((function(e){return{type:"cache",value:e}})),(0,rt.K)(i)):i()}(r).pipe((0,oe.zg)((function(e){var t;switch(t="data-chunk-complete"!==e.type&&"data-loaded"!==e.type||void 0===e.value.size||void 0===e.value.duration?p.E:(0,m.of)({type:"metrics",value:{size:e.value.size,duration:e.value.duration,content:r}}),e.type){case"warning":case"request":case"progress":return(0,m.of)(e);case"cache":case"data-created":case"data-loaded":return(0,v.z)((0,m.of)({type:"data",value:e.value}),t);case"data-chunk":return(0,m.of)({type:"chunk",value:e.value});case"data-chunk-complete":return(0,v.z)((0,m.of)({type:"chunk-complete",value:null}),t);default:(0,kt.Z)(e)}})))}}var Rt=(0,At.Z)();var Mt=B.Z.MIN_CANCELABLE_PRIORITY,Ct=B.Z.MAX_HIGH_PRIORITY_LEVEL;const Nt=function(){function e(e,t){this._transport=e,this._prioritizer=new wt({prioritySteps:{high:Ct,low:Mt}}),this._backoffOptions=t}return e.prototype.createSegmentFetcher=function(e,t){var n,r,i,a=function(e,t){var n=t.maxRetryRegular,r=t.maxRetryOffline,i=t.lowLatencyMode;return{maxRetryRegular:"image"===e?0:null!=n?n:_t,maxRetryOffline:null!=r?r:bt,baseDelay:i?Tt.LOW_LATENCY:Tt.REGULAR,maxDelay:i?Et.LOW_LATENCY:Et.REGULAR}}(e,this._backoffOptions),o=function(e,t,n,r){var i=(0,St.Z)(["audio","video"],e)?new xt:void 0,a=It(t[e].loader,i,r),o=t[e].parser;return function(e){var t=Rt(),r=!1;return a(e).pipe((0,pe.b)((function(e){switch(e.type){case"metrics":n.next(e);break;case"request":var i=e.value.segment;if(void 0===i)return;r=!0,n.next({type:"requestBegin",value:{duration:i.duration,time:i.time,requestTimestamp:performance.now(),id:t}});break;case"progress":var a=e.value;null!=a.totalSize&&a.size=0;a--){var o=i[a];try{"open"===r&&(D.Z.info("Init: Removing SourceBuffer from mediaSource",o),o.abort()),t.removeSourceBuffer(o)}catch(e){D.Z.warn("Init: Error while disposing SourceBuffer",e)}}i.length>0&&D.Z.warn("Init: Not all SourceBuffers could have been removed.")}if((0,Ot.Z)(e),null!==n)try{D.Z.debug("Init: Revoking previous URL"),URL.revokeObjectURL(n)}catch(e){D.Z.warn("Init: Error while revoking the media source URL",e)}}function Ft(e){return function(e){return new Ee.y((function(t){if(null==Dt.JJ)throw new U.Z("MEDIA_SOURCE_NOT_SUPPORTED","No MediaSource Object was found in the current browser.");var n=(0,Lt.Z)(e.src)?e.src:null;Ut(e,null,n),D.Z.info("Init: Creating MediaSource");var r=new Dt.JJ,i=URL.createObjectURL(r);return D.Z.info("Init: Attaching MediaSource URL to the media element",i),e.src=i,t.next(r),function(){Ut(e,r,i)}}))}(e).pipe((0,oe.zg)((function(e){return Bt(e).pipe((0,b.q)(1),(0,A.h)(e))})))}var zt=n(8343),Vt=B.Z.DEFAULT_LIVE_GAP;var Kt=n(4944),Ht=n(6564),Wt=n(7027);var $t=n(6968),Gt=n(2870),jt=n(4123),Yt=B.Z.SOURCE_BUFFER_FLUSHING_INTERVAL;const qt=function(e){function t(t,n,r){var i;i=e.call(this)||this;var a=r.addSourceBuffer(n);return i._destroy$=new s.xQ,i.bufferType=t,i._mediaSource=r,i._sourceBuffer=a,i._queue=[],i._pendingTask=null,i._lastInitSegment=null,i.codec=n,(0,Ht.F)(Yt).pipe((0,pe.b)((function(){return i._flush()})),(0,g.R)(i._destroy$)).subscribe(),(0,Wt.R)(i._sourceBuffer,"error").pipe((0,pe.b)((function(e){return i._onPendingTaskError(e)})),(0,g.R)(i._destroy$)).subscribe(),(0,Wt.R)(i._sourceBuffer,"updateend").pipe((0,pe.b)((function(){return i._flush()})),(0,g.R)(i._destroy$)).subscribe(),i}o()(t,e);var n=t.prototype;return n.pushChunk=function(e){return D.Z.debug("AVSB: receiving order to push data to the SourceBuffer",this.bufferType,e),this._addToQueue({type:jt.f.Push,value:e})},n.removeBuffer=function(e,t){return D.Z.debug("AVSB: receiving order to remove data from the SourceBuffer",this.bufferType,e,t),this._addToQueue({type:jt.f.Remove,value:{start:e,end:t}})},n.endOfSegment=function(e){return D.Z.debug("AVSB: receiving order for validating end of segment",this.bufferType,e.segment),this._addToQueue({type:jt.f.EndOfSegment,value:e})},n.getBufferedRanges=function(){return this._sourceBuffer.buffered},n.getPendingOperations=function(){var e=function(e){switch(e.type){case jt.f.Push:case jt.f.Remove:case jt.f.EndOfSegment:return{type:e.type,value:e.value}}},t=this._queue.map(e);return null===this._pendingTask?t:[e(this._pendingTask)].concat(t)},n.dispose=function(){for(this._destroy$.next(),this._destroy$.complete(),null!==this._pendingTask&&(this._pendingTask.subject.complete(),this._pendingTask=null);this._queue.length>0;){var e=this._queue.shift();void 0!==e&&e.subject.complete()}if("open"===this._mediaSource.readyState)try{this._sourceBuffer.abort()}catch(e){D.Z.warn("AVSB: Failed to abort a "+this.bufferType+" SourceBuffer:",e)}},n._onPendingTaskError=function(e){if(this._lastInitSegment=null,null!==this._pendingTask){var t=e instanceof Error?e:new Error("An unknown error occured when doing operations on the SourceBuffer");this._pendingTask.subject.error(t)}},n._addToQueue=function(e){var t=this;return new Ee.y((function(n){var r=0===t._queue.length&&null===t._pendingTask,i=new s.xQ,a=(0,Y.Z)({subject:i},e);t._queue.push(a);var o=i.subscribe(n);return r&&t._flush(),function(){o.unsubscribe();var e=t._queue.indexOf(a);e>=0&&t._queue.splice(e,1)}}))},n._flush=function(){if(!this._sourceBuffer.updating){if(null!==this._pendingTask){var e=this._pendingTask;if(e.type!==jt.f.Push||0===e.data.length){switch(e.type){case jt.f.Push:null!==e.inventoryData&&this._segmentInventory.insertChunk(e.inventoryData);break;case jt.f.EndOfSegment:this._segmentInventory.completeSegment(e.value);break;case jt.f.Remove:this.synchronizeInventory();break;default:(0,kt.Z)(e)}var t=e.subject;return this._pendingTask=null,t.next(),t.complete(),void this._flush()}}else{var n=this._queue.shift();if(void 0===n)return;if(n.type!==jt.f.Push)this._pendingTask=n;else{var r,i=n.value;try{r=this._preparePushOperation(i.data)}catch(e){this._pendingTask=(0,Y.Z)({data:[],inventoryData:i.inventoryInfos},n);var a=e instanceof Error?e:new Error("An unknown error occured when preparing a push operation");return this._lastInitSegment=null,void n.subject.error(a)}this._pendingTask=(0,Y.Z)({data:r,inventoryData:i.inventoryInfos},n)}}try{switch(this._pendingTask.type){case jt.f.EndOfSegment:return D.Z.debug("AVSB: Acknowledging complete segment",this._pendingTask.value),void this._flush();case jt.f.Push:var o=this._pendingTask.data.shift();if(void 0===o)return void this._flush();this._sourceBuffer.appendBuffer(o);break;case jt.f.Remove:var s=this._pendingTask.value,u=s.start,l=s.end;D.Z.debug("AVSB: removing data from SourceBuffer",this.bufferType,u,l),this._sourceBuffer.remove(u,l);break;default:(0,kt.Z)(this._pendingTask)}}catch(e){this._onPendingTaskError(e)}}},n._preparePushOperation=function(e){var t=[],n=e.codec,r=e.timestampOffset,i=e.appendWindow,a=!1;if(n!==this.codec&&(D.Z.debug("AVSB: updating codec",n),(a=function(e,t){if("function"==typeof e.changeType){try{e.changeType(t)}catch(e){return D.Z.warn("Could not call 'changeType' on the given SourceBuffer:",e),!1}return!0}return!1}(this._sourceBuffer,n))?this.codec=n:D.Z.debug("AVSB: could not update codec",n,this.codec)),this._sourceBuffer.timestampOffset!==r){var o=r;D.Z.debug("AVSB: updating timestampOffset",this.bufferType,this._sourceBuffer.timestampOffset,o),this._sourceBuffer.timestampOffset=o}if(void 0===i[0]?this._sourceBuffer.appendWindowStart>0&&(this._sourceBuffer.appendWindowStart=0):i[0]!==this._sourceBuffer.appendWindowStart&&(i[0]>=this._sourceBuffer.appendWindowEnd&&(this._sourceBuffer.appendWindowEnd=i[0]+1),this._sourceBuffer.appendWindowStart=i[0]),void 0===i[1]?this._sourceBuffer.appendWindowEnd!==1/0&&(this._sourceBuffer.appendWindowEnd=1/0):i[1]!==this._sourceBuffer.appendWindowEnd&&(this._sourceBuffer.appendWindowEnd=i[1]),null!==e.initSegment&&(a||!this._isLastInitSegment(e.initSegment))){var s=e.initSegment;t.push(s);var u=(0,$t._f)(s);this._lastInitSegment={data:u,hash:(0,Gt.Z)(u)}}return null!==e.chunk&&t.push(e.chunk),t},n._isLastInitSegment=function(e){if(null===this._lastInitSegment)return!1;if(this._lastInitSegment.data===e)return!0;var t=this._lastInitSegment.data;if(t.byteLength===e.byteLength){var n=(0,$t._f)(e);if((0,Gt.Z)(n)===this._lastInitSegment.hash&&(0,W.Z)(t,n))return!0}return!1},t}(jt.C);var Xt=["audio","video","text","image"];function Qt(e){return"audio"===e||"video"===e}const Jt=function(){function e(e,t){this._mediaElement=e,this._mediaSource=t,this._initializedSegmentBuffers={},this._onNativeBufferAddedOrDisabled=[]}e.isNative=function(e){return Qt(e)};var t=e.prototype;return t.getBufferTypes=function(){var e=this.getNativeBufferTypes();return null==H.Z.nativeTextTracksBuffer&&null==H.Z.htmlTextTracksBuffer||e.push("text"),null!=H.Z.imageBuffer&&e.push("image"),e},t.getNativeBufferTypes=function(){return"AUDIO"===this._mediaElement.nodeName?["audio"]:["video","audio"]},t.getStatus=function(e){var t=this._initializedSegmentBuffers[e];return void 0===t?{type:"uninitialized"}:null===t?{type:"disabled"}:{type:"initialized",value:t}},t.waitForUsableBuffers=function(){var e=this;return this._areNativeBuffersUsable()?(0,m.of)(void 0):new Ee.y((function(t){e._onNativeBufferAddedOrDisabled.push((function(){e._areNativeBuffersUsable()&&(t.next(void 0),t.complete())}))}))},t.disableSegmentBuffer=function(t){var n=this._initializedSegmentBuffers[t];if(null!==n){if(void 0!==n)throw new Error("Cannot disable an active SegmentBuffer.");this._initializedSegmentBuffers[t]=null,e.isNative(t)&&this._onNativeBufferAddedOrDisabled.forEach((function(e){return e()}))}else D.Z.warn("SBS: The "+t+" SegmentBuffer was already disabled.")},t.createSegmentBuffer=function(e,t,n){void 0===n&&(n={});var r,i=this._initializedSegmentBuffers[e];if(Qt(e)){if(null!=i)return i instanceof qt&&i.codec!==t?D.Z.warn("SB: Reusing native SegmentBuffer with codec",i.codec,"for codec",t):D.Z.info("SB: Reusing native SegmentBuffer with codec",t),i;D.Z.info("SB: Adding native SegmentBuffer with codec",t);var a=new qt(e,t,this._mediaSource);return this._initializedSegmentBuffers[e]=a,this._onNativeBufferAddedOrDisabled.forEach((function(e){return e()})),a}if(null!=i)return D.Z.info("SB: Reusing a previous custom SegmentBuffer for the type",e),i;if("text"===e){if(D.Z.info("SB: Creating a new text SegmentBuffer"),"html"===n.textTrackMode){if(null==H.Z.htmlTextTracksBuffer)throw new Error("HTML Text track feature not activated");r=new H.Z.htmlTextTracksBuffer(this._mediaElement,n.textTrackElement)}else{if(null==H.Z.nativeTextTracksBuffer)throw new Error("Native Text track feature not activated");r=new H.Z.nativeTextTracksBuffer(this._mediaElement,!0===n.hideNativeSubtitle)}return this._initializedSegmentBuffers.text=r,r}if("image"===e){if(null==H.Z.imageBuffer)throw new Error("Image buffer feature not activated");return D.Z.info("SB: Creating a new image SegmentBuffer"),r=new H.Z.imageBuffer,this._initializedSegmentBuffers.image=r,r}throw D.Z.error("SB: Unknown buffer type:",e),new U.Z("BUFFER_TYPE_UNKNOWN","The player wants to create a SegmentBuffer of an unknown type.")},t.disposeSegmentBuffer=function(e){var t=this._initializedSegmentBuffers[e];null!=t?(D.Z.info("SB: Aborting SegmentBuffer",e),t.dispose(),delete this._initializedSegmentBuffers[e]):D.Z.warn("SB: Trying to dispose a SegmentBuffer that does not exist")},t.disposeAll=function(){var e=this;Xt.forEach((function(t){"initialized"===e.getStatus(t).type&&e.disposeSegmentBuffer(t)}))},t._areNativeBuffersUsable=function(){var e=this,t=this.getNativeBufferTypes();return!t.some((function(t){return void 0===e._initializedSegmentBuffers[t]}))&&!t.every((function(t){return null===e._initializedSegmentBuffers[t]}))},e}();var en=function(){function e(e){this._array=[],this._sortingFn=e}var t=e.prototype;return t.add=function(){for(var e=arguments.length,t=new Array(e),n=0;n=this._array.length)throw new Error("Invalid index.");return this._array[e]},t.findFirst=function(e){return(0,Fe.Z)(this._array,e)},t.has=function(e){return(0,St.Z)(this._array,e)},t.removeElement=function(e){var t=this._array.indexOf(e);if(t>=0)return this._array.splice(t,1),t},t.head=function(){return this._array[0]},t.last=function(){return this._array[this._array.length-1]},t.shift=function(){return this._array.shift()},t.pop=function(){return this._array.pop()},e}(),tn=function(){function e(e){this._weakMap=new WeakMap,this._fn=e}var t=e.prototype;return t.get=function(e){var t=this._weakMap.get(e);if(void 0===t){var n=this._fn(e);return this._weakMap.set(e,n),n}return t},t.destroy=function(e){this._weakMap.delete(e)},e}(),nn=n(2257);function rn(e){var t=e.segmentBuffer,n=e.clock$,r=e.maxBufferBehind$,i=e.maxBufferAhead$;return(0,h.aj)([n,r,i]).pipe((0,oe.zg)((function(e){var n=e[0],r=e[1],i=e[2];return function(e,t,n,r){if(!isFinite(n)&&!isFinite(r))return p.E;var i=[],a=(0,X.F_)(e.getBufferedRanges(),t),o=a.innerRange,s=a.outerRanges,u=function(){if(isFinite(r)){for(var e=0;en.start&&i.push({start:t+r,end:n.end})}null!=o&&t+r=r.end?i.push(r):t>=r.end&&t-n>r.start&&t-no.start&&i.push({start:o.start,end:t-n})}}(),u(),(0,ue.D)(i.map((function(t){return D.Z.debug("GC: cleaning range from SegmentBuffer",t),e.removeBuffer(t.start,t.end)}))).pipe((0,nn.u)(),(0,ie.l)())}(t,n,r,i)})))}const an={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,n){return{type:"needs-media-source-reload",value:{position:t,autoPlay:n,period:e}}},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}}},protectedSegment:function(e){return{type:"protected-segment",value: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}}};var on=n(7473),sn=n.n(on);var un=function(){function e(e,t){this.predicate=e,this.inclusive=t}return e.prototype.call=function(e,t){return t.subscribe(new ln(e,this.predicate,this.inclusive))},e}(),ln=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.predicate=n,i.inclusive=r,i.index=0,i}return l.ZT(t,e),t.prototype._next=function(e){var t,n=this.destination;try{t=this.predicate(e,this.index++)}catch(e){return void n.error(e)}this.nextOrComplete(e,t)},t.prototype.nextOrComplete=function(e,t){var n=this.destination;Boolean(t)?n.next(e):(this.inclusive&&n.next(e),n.complete())},t}(x.L);function cn(e,t,n,r,i){var a=e.period,o=e.adaptation,s=e.representation,u=function(e,t){for(var n=0;n=t.end)return null;if(r.bufferedEnd>t.start)return n}return null}(i,t);if(null===u){if(null===n){if(r&&void 0!==a.end&&t.end>=a.end)return{start:void 0,end:null};var l=s.index.checkDiscontinuity(t.start);if(null!==l)return{start:void 0,end:l}}return null}var c=i[u];if(void 0!==c.bufferedStart&&c.bufferedStart>t.start&&(null===n||c.infos.segment.end<=n))return D.Z.debug("RS: current discontinuity encountered",o.type,c.bufferedStart),{start:void 0,end:c.bufferedStart};var d=function(e,t,n){if(n<=0)return D.Z.error("RS: Asked to check a discontinuity before the first chunk."),null;for(var r=n;r=t.end)return null;if(i.bufferedStart-a.bufferedEnd>0)return r}return null}(i,t,u+1);if(null!==d&&(null===n||i[d].infos.segment.end<=n)){var f=i[d-1].bufferedEnd,p=i[d].bufferedStart;return D.Z.debug("RS: future discontinuity encountered",o.type,f,p),{start:f,end:p}}if(null===n){if(r&&void 0!==a.end){if(t.end=0;n--){var r=e[n];if(void 0===r.bufferedStart)return null;if(r.bufferedStart=a.end)return null;for(var m=i.length-1;m>=0;m--){var g=i[m];if(void 0===g.bufferedStart)break;if(g.bufferedStart=n.length-1?null:n[t+1];return!function(e,t,n){if(void 0===e.bufferedStart)return D.Z.warn("Stream: Start of a segment unknown. Assuming it is garbage collected by default.",e),!0;if(null!==t&&void 0!==t.bufferedEnd&&e.bufferedStart-t.bufferedEnd<.1)return!1;if(nvn)return D.Z.info("Stream: The start of the wanted segment has been garbage collected",e),!0;return!1}(e,r,i.start)&&!function(e,t,n){if(void 0===e.bufferedEnd)return D.Z.warn("Stream: End of a segment unknown. Assuming it is garbage collected by default.",e),!0;if(null!==t&&void 0!==t.bufferedStart&&t.bufferedStart-e.bufferedEnd<.1)return!1;if(n>e.bufferedEnd&&e.end-e.bufferedEnd>vn)return D.Z.info("Stream: The end of the wanted segment has been garbage collected",e),!0;return!1}(e,a,i.end)}));return s.filter((function(e){var i=(0,Y.Z)({segment:e},t);if(a.length>0&&a.some((function(e){return(0,fn.Z)(i,e)})))return!1;var o=e.duration,s=e.time,l=e.end;if(e.isInit)return!0;if(o0&&a.some((function(e){if(e.period.id!==t.period.id||e.adaptation.id!==t.adaptation.id)return!1;var a=e.segment;return!(a.time-gn>s)&&(!(a.end+gn-gn&&f.end-l>-gn)return!1}}for(var p=0;ps)return h.start>s+gn||_n(u,p).ende[n].start;)n++;return e[--n]}function bn(e,t,n,r){if(e.period.id!==t.period.id)return!1;var i=e.segment;return!(dn&&i.timei}return rr}(e.representation,t.representation,r))}var Tn=B.Z.SEGMENT_PRIORITIES_STEPS;function En(e,t){for(var n=e-(t.position+t.wantedTimeOffset),r=0;r=0;o--){var s=t[o],u=s.infos.representation;if(!s.partiallyPushed&&!1!==u.decipherable&&u.isSupported){var l=s.infos.segment,c=l.time/l.timescale;((null==l.duration?s.end:c+l.duration/l.timescale)>r&&cr&&s.start0)u=!1;else if(void 0===g)u=f.end>=o.end&&s.index.isFinished();else if(null===g)u=s.index.isFinished();else{var y=void 0!==o.end?Math.min(o.end,g):g;u=f.end>=y&&s.index.isFinished()}if(s.index.isInitialized()&&(s.index.areSegmentsChronologicallyGenerated()||u)){var _=null;h.length>0&&(_=Math.min.apply(Math,h.map((function(e){return e.segment.time})))),m.length>0&&(_=null!==_?Math.min(_,m[0].segment.time):m[0].segment.time),l=cn(e,f,_,u,v)}else l=null;return{imminentDiscontinuity:l,hasFinishedLoading:u,neededSegments:m,shouldRefreshManifest:p}}var kn=B.Z.BUFFER_GC_GAPS.CALM,An=B.Z.BUFFER_GC_GAPS.BEEFY;function xn(e,t,n){for(var r=(0,X.F_)(t,e),i=r.innerRange,a=r.outerRanges,o=[],s=0;su.start)&&o.push(u)}return null!=i&&(D.Z.debug("Stream: GC removing part of inner range",o),e-n>i.start&&o.push({start:i.start,end:e-n}),e+n0&&null!==A&&null===x){var d=u[0].priority;u.unshift({segment:A,priority:d})}}else null===A?D.Z.warn("Stream: Uninitialized index without an initialization segment"):null!==x?D.Z.warn("Stream: Uninitialized index with an already loaded initialization segment"):u.unshift({segment:A,priority:En(_.start,n)});var f=u[0];if(null!==i){if(Z=[],i.urgent)return D.Z.debug("Stream: urgent termination request, terminate.",w),I.complete(),(0,m.of)(an.streamTerminating());if(null===M)return D.Z.debug("Stream: no request, terminate.",w),I.complete(),(0,m.of)(an.streamTerminating());if(void 0===f||M.segment.id!==f.segment.id)return D.Z.debug("Stream: cancel request and terminate.",w),I.next(),I.complete(),(0,m.of)(an.streamTerminating());if(M.priority!==f.priority){var p=M.request$;M.priority=f.priority,c.updatePriority(p,f.priority)}D.Z.debug("Stream: terminate after request.",w)}else if(void 0===f)null!==M&&D.Z.debug("Stream: interrupt segment request.",w),Z=[],I.next();else if(null===M)D.Z.debug("Stream: start downloading queue.",w),Z=u,I.next();else if(M.segment.id!==f.segment.id)D.Z.debug("Stream: restart download queue.",w),Z=u,I.next();else if(M.priority!==f.priority){D.Z.debug("Stream: update request priority.",w);var h=M.request$;M.priority=f.priority,c.updatePriority(h,f.priority)}else D.Z.debug("Stream: update downloading queue",w),Z=u.slice().splice(1,u.length);var g=(0,m.of)({type:"stream-status",value:{period:_,position:n.position,bufferType:w,imminentDiscontinuity:s.imminentDiscontinuity,hasFinishedLoading:s.hasFinishedLoading,neededSegments:s.neededSegments}});return s.shouldRefreshManifest?(0,v.z)((0,m.of)(an.needsManifestRefresh()),g):g})),(t=function(e){return"stream-terminating"!==e.type},void 0===(n=!0)&&(n=!1),function(e){return e.lift(new un(t,n))})),N=I.pipe((0,ye.w)((function(){return Z.length>0?(e=(0,J.P)((function(){var t=Z.shift();if(void 0===t)return sn()((function(){R.next()})),p.E;var n=t.segment,r=t.priority,i={manifest:g,period:_,adaptation:T,representation:E,segment:n},a=c.createRequest(i,r);return M={segment:n,priority:r,request$:a},a.pipe((0,oe.zg)((function(t){switch(t.type){case"warning":return(0,m.of)({type:"retry",value:{segment:n,error:t.value}});case"chunk-complete":return M=null,(0,m.of)({type:"end-of-segment",value:{segment:n}});case"interrupted":return D.Z.info("Stream: segment request interrupted temporarly.",n),p.E;case"chunk":var r=null==x?void 0:x.initTimescale;return t.parse(r).pipe((0,y.U)((function(e){return(0,Y.Z)({segment:n},e)})));case"ended":return e;default:(0,kt.Z)(t)}})))}))).pipe(ve((function(){M=null}))):p.E;var e})),(0,oe.zg)((function(e){var t;switch(e.type){case"retry":return(0,v.z)((0,m.of)({type:"warning",value:e.value.error}),(0,J.P)((function(){var t=e.value.segment,n=E.index;if(!1===n.isSegmentStillAvailable(t))R.next();else if(n.canBeOutOfSyncError(e.value.error,t))return(0,m.of)(an.manifestMightBeOufOfSync());return p.E})));case"parsed-init-segment":x=e.value;var n=m.of.apply(void 0,e.value.segmentProtections.map((function(e){return an.protectedSegment(e)}))),r=function(e){var t=e.clock$,n=e.content,r=e.segment,i=e.segmentData,a=e.segmentBuffer;return(0,J.P)((function(){if(null===i)return p.E;var e=n.representation.getMimeTypeString();return Zn(t,a,{data:{initSegment:i,chunk:null,timestampOffset:0,appendWindow:[void 0,void 0],codec:e},inventoryInfos:null}).pipe((0,y.U)((function(){var e=a.getBufferedRanges();return an.addedSegment(n,r,e,i)})))}))}({clock$:i,content:a,segment:e.segment,segmentData:e.value.initializationData,segmentBuffer:l});return(0,f.T)(n,r);case"parsed-segment":var o=null!==(t=null==x?void 0:x.initializationData)&&void 0!==t?t:null;return function(e){var t=e.clock$,n=e.content,r=e.initSegmentData,i=e.parsedSegment,a=e.segment,o=e.segmentBuffer;return(0,J.P)((function(){var e,s;if(null===i.chunkData)return p.E;var u=i.chunkData,l=i.chunkInfos,c=i.chunkOffset,d=i.appendWindow,f=n.representation.getMimeTypeString(),h=[void 0!==d[0]?Math.max(0,d[0]-In.START):void 0,void 0!==d[1]?d[1]+In.END:void 0],v={initSegment:r,chunk:u,timestampOffset:c,appendWindow:h,codec:f},m=null!==(e=null==l?void 0:l.time)&&void 0!==e?e:a.time,g=m+(null!==(s=null==l?void 0:l.duration)&&void 0!==s?s:a.duration);void 0!==h[0]&&(m=Math.max(m,h[0])),void 0!==h[1]&&(g=Math.min(g,h[1]));var _=(0,Y.Z)({segment:a,start:m,end:g},n);return Zn(t,o,{data:v,inventoryInfos:_}).pipe((0,y.U)((function(){var e=o.getBufferedRanges();return an.addedSegment(n,a,e,u)})))}))}({clock$:i,content:a,initSegmentData:o,parsedSegment:e.value,segment:e.segment,segmentBuffer:l});case"end-of-segment":var s=e.value.segment;return l.endOfSegment((0,Y.Z)({segment:s},a)).pipe((0,ie.l)());default:(0,kt.Z)(e)}})));return(0,f.T)(C,N).pipe((0,S.B)())};function Mn(e,t,n){return t.pipe((0,b.q)(1),(0,oe.zg)((function(r){var i;if(e.start<=r.position&&(void 0===e.end||e.end>r.position)){var a=r.getCurrentTime()+n,o=Math.min(Math.max(e.start,a),null!==(i=e.end)&&void 0!==i?i:1/0);return(0,m.of)(an.needsMediaSourceReload(e,o,!r.isPaused))}return t.pipe((0,y.U)((function(t){return an.needsMediaSourceReload(e,t.getCurrentTime(),!t.isPaused)})))})))}var Cn=B.Z.DELTA_POSITION_AFTER_RELOAD;const Nn=function(e){var t=e.abrManager,n=e.clock$,r=e.content,i=e.options,a=e.segmentBuffer,o=e.segmentFetcherCreator,u=e.wantedBufferAhead$,l="direct"===i.manualBitrateSwitchingMode,c=r.manifest,h=r.period,g=r.adaptation,T={},E=function(e,t,n){var r=new s.xQ,i=new s.xQ,a=(0,f.T)(r,i),o=e.getPlayableRepresentations();if(o.length<=0)throw new U.Z("NO_PLAYABLE_REPRESENTATION","No Representation in the chosen Adaptation can be played");return{estimator$:t.get$(e.type,o,n,a),streamFeedback$:r,requestFeedback$:i}}(g,t,n),k=E.estimator$,A=E.requestFeedback$,x=E.streamFeedback$,Z=o.createSegmentFetcher(g.type,A),I=new d(null),R=k.pipe((0,pe.b)((function(e){I.next(e)})),(0,be.Z)(),(0,S.B)()),M=R.pipe((0,w.h)((function(e){return null!=e.bitrate})),(0,_.x)((function(e,t){return e.bitrate===t.bitrate})),(0,y.U)((function(e){var t=e.bitrate;return D.Z.debug("Stream: new "+g.type+" bitrate estimate",t),an.bitrateEstimationChange(g.type,t)}))),C=R.pipe(ce((function(e,t){return N(e,0===t)})));return(0,f.T)(C,M);function N(e,t){var r=e.representation;if(l&&e.manual&&!t)return Mn(h,n,Cn.bitrateSwitch);var a=I.pipe((0,w.h)((function(t){return null===t||t.representation.id!==r.id||t.manual&&!e.manual})),(0,b.q)(1),(0,y.U)((function(e){return null===e?(D.Z.info("Stream: urgent Representation termination",g.type),{urgent:!0}):e.urgent?(D.Z.info("Stream: urgent Representation switch",g.type),{urgent:!0}):(D.Z.info("Stream: slow Representation switch",g.type),{urgent:!1})}))),o=i.enableFastSwitching?I.pipe((0,y.U)((function(e){return null===e?void 0:e.knownStableBitrate})),(0,_.x)()):(0,m.of)(0),s=(0,m.of)(an.representationChange(g.type,h,r));return(0,v.z)(s,P(r,a,o)).pipe((0,pe.b)((function(e){if("representationChange"===e.type||"added-segment"===e.type)return x.next(e)})),(0,oe.zg)((function(e){if("stream-terminating"===e.type){var t=I.getValue();return null===t?p.E:N(t,!1)}return(0,m.of)(e)})))}function P(e,t,r){return(0,J.P)((function(){var i=T[e.id],o=null!=i?i:1;T[e.id]=o;var s=u.pipe((0,y.U)((function(e){return e*o})));return D.Z.info("Stream: changing representation",g.type,e),Rn({clock$:n,content:{representation:e,adaptation:g,period:h,manifest:c},segmentBuffer:a,segmentFetcher:Z,terminate$:t,bufferGoal$:s,fastSwitchThreshold$:r}).pipe((0,rt.K)((function(n){var i=V(n,{defaultCode:"NONE",defaultReason:"Unknown `RepresentationStream` error"});if("BUFFER_FULL_ERROR"===i.code){var a=u.getValue(),s=o;if(s<=.25||a*s<=2)throw i;return T[e.id]=s-.25,P(e,t,r)}throw i})))}))}};function Pn(e,t,n,r){var i=r.period,a=!1;return(0,h.aj)([e,t]).pipe((0,oe.zg)((function(e){var t=e[0],r=e[1],o=t.position;return void 0!==i.end&&o+r>=i.end&&(D.Z.debug('Stream: full "empty" AdaptationStream',n),a=!0),(0,m.of)({type:"stream-status",value:{period:i,bufferType:n,position:t.position,imminentDiscontinuity:null,hasFinishedLoading:a,neededSegments:[],shouldRefreshManifest:!1}})})))}var On=n(9252);const Dn=function(e,t){var n=e.split(";"),r=n[0],i=n.slice(1),a=t.split(";"),o=a[0],s=a.slice(1);if(r!==o)return!1;var u=(0,Fe.Z)(i,(function(e){return(0,On.Z)(e,"codecs=")})),l=(0,Fe.Z)(s,(function(e){return(0,On.Z)(e,"codecs=")}));if(void 0===u||void 0===l)return!1;var c=u.substring(7),d=l.substring(7);return c.split(".")[0]===d.split(".")[0]};var Ln=B.Z.ADAPTATION_SWITCH_BUFFER_PADDINGS;function Bn(e,t,n,r,i){if(void 0!==e.codec&&"reload"===i.onCodecSwitch&&!Un(n,e.codec))return{type:"needs-reload",value:void 0};var a=e.getBufferedRanges();if(0===a.length)return{type:"continue",value:void 0};var o=(0,X.JN)(a),s=t.start,u=null==t.end?1/0:t.end,l=(0,X.tn)(o,[{start:s,end:u}]);if(0===l.length)return{type:"continue",value:void 0};e.synchronizeInventory();var c=e.getInventory();if(!c.some((function(e){return e.infos.period.id===t.id&&e.infos.adaptation.id!==n.id})))return{type:"continue",value:void 0};var d=function(e,t,n){return e.reduce((function(e,r){if(r.infos.period.id!==t.id||r.infos.adaptation.id!==n.id)return e;var i=r.bufferedStart,a=r.bufferedEnd;return void 0===i||void 0===a||e.push({start:i,end:a}),e}),[])}(c,t,n),f=(0,X.uH)(l,d);if(0===f.length)return{type:"continue",value:void 0};var p=r.currentTime;if("video"===n.type&&(0,X.Ti)({start:s,end:u},p)&&(r.readyState>1||!n.getPlayableRepresentations().some((function(t){var n;return Dn(t.getMimeTypeString(),null!==(n=e.codec)&&void 0!==n?n:"")})))&&!(0,X.A1)(d,p))return{type:"needs-reload",value:void 0};if("audio"===n.type&&void 0!==e.codec&&"direct"===i.audioTrackSwitchingMode&&(0,X.Ti)({start:s,end:u},p)&&(r.readyState>1||!Un(n,e.codec))&&!(0,X.A1)(d,p))return{type:"needs-reload",value:void 0};var h=[],v=function(e,t){for(var n=0;n=t.start)return n>0?e[n-1]:null;return e.length>0?e[e.length-1]:null}(c,t);null!==v&&(void 0===v.bufferedEnd||t.start-v.bufferedEnd<1)&&h.push({start:0,end:t.start+1});var m=n.type,g=Ln[m].before;null==g&&(g=0);var y=Ln[m].after;if(null==y&&(y=0),h.push({start:p-g,end:p+y}),void 0!==t.end){var _=function(e,t){for(var n=0;nt.start)return e[n];return null}(c,t);null!==_&&(void 0===_.bufferedStart||_.bufferedStart-t.end<1)&&h.push({start:t.end-1,end:Number.MAX_VALUE})}var b=(0,X.uH)(f,h);return b.length>0?{type:"clean-buffer",value:b}:{type:"continue",value:void 0}}function Un(e,t){return e.getPlayableRepresentations().some((function(e){return Dn(e.getMimeTypeString(),t)}))}var Fn=B.Z.DELTA_POSITION_AFTER_RELOAD;const zn=function(e){var t=e.abrManager,n=e.bufferType,r=e.clock$,i=e.content,a=e.garbageCollectors,o=e.segmentFetcherCreator,s=e.segmentBuffersStore,l=e.options,c=e.wantedBufferAhead$,d=i.period,h=new u.t(1);return h.pipe((0,ye.w)((function(e,u){var h=0===u?0:"audio"===n?Fn.trackSwitch.audio:"video"===n?Fn.trackSwitch.video:Fn.trackSwitch.other;if(null===e){D.Z.info("Stream: Set no "+n+" Adaptation",d);var g,_=s.getStatus(n);if("initialized"===_.type){if(D.Z.info("Stream: Clearing previous "+n+" SegmentBuffer"),Jt.isNative(n))return Mn(d,r,h);g=_.value.removeBuffer(d.start,null==d.end?1/0:d.end)}else"uninitialized"===_.type&&s.disableSegmentBuffer(n),g=(0,m.of)(null);return(0,v.z)(g.pipe((0,A.h)(an.adaptationChange(n,null,d))),Pn(r,c,n,{period:d}))}if(Jt.isNative(n)&&"disabled"===s.getStatus(n).type)return Mn(d,r,h);D.Z.info("Stream: Updating "+n+" adaptation",e,d);var T=r.pipe((0,b.q)(1),(0,oe.zg)((function(u){var g=function(e,t,n,r){var i=e.getStatus(t);if("initialized"===i.type)return D.Z.info("Stream: Reusing a previous SegmentBuffer for the type",t),i.value;var a=function(e){var t=e.representations;if(null==t[0])return"";return t[0].getMimeTypeString()}(n),o="text"===t?r.textTrackOptions:void 0;return e.createSegmentBuffer(t,a,o)}(s,n,e,l),_={currentTime:u.getCurrentTime(),readyState:u.readyState},b=Bn(g,d,e,_,l);if("needs-reload"===b.type)return Mn(d,r,h);var T="clean-buffer"===b.type?v.z.apply(void 0,b.value.map((function(e){var t=e.start,n=e.end;return g.removeBuffer(t,n)}))).pipe((0,ie.l)()):p.E,E=a.get(g),w=function(e,a){var u=i.manifest,f=r.pipe((0,y.U)((function(e){var t=a.getBufferedRanges();return(0,Y.Z)({},e,{bufferGap:(0,X.L7)(t,e.position)})})));return Nn({abrManager:t,clock$:f,content:{manifest:u,period:d,adaptation:e},options:l,segmentBuffer:a,segmentFetcherCreator:o,wantedBufferAhead$:c}).pipe((0,rt.K)((function(e){if(!Jt.isNative(n)){D.Z.error("Stream: "+n+" Stream crashed. Aborting it.",e),s.disposeSegmentBuffer(n);var t=V(e,{defaultCode:"NONE",defaultReason:"Unknown `AdaptationStream` error"});return(0,v.z)((0,m.of)(an.warning(t)),Pn(r,c,n,{period:d}))}throw D.Z.error("Stream: "+n+" Stream crashed. Stopping playback.",e),e})))}(e,g);return s.waitForUsableBuffers().pipe((0,oe.zg)((function(){return(0,v.z)(T,(0,f.T)(w,E))})))})));return(0,v.z)((0,m.of)(an.adaptationChange(n,e,d)),T)})),(0,k.O)(an.periodStreamReady(n,d,h)))};var Vn=n(2807);function Kn(){for(var e=arguments.length,t=new Array(e),n=0;nl.getMaximumPosition()){var i=new U.Z("MEDIA_TIME_AFTER_MANIFEST","The current position is after the latest time announced in the Manifest.");return an.warning(i)}return null}),null)),A=r.getBufferTypes().map((function(e){return function(e,n){var i=new en((function(e,t){return e.start-t.start})),a=new s.xQ,o=!1;function u(t){return I(e,t,a).pipe((0,Te.Z)((function(e){switch(e.type){case"needs-media-source-reload":var t=i.head();if(void 0===t||t.id!==e.value.period.id)return null;break;case"periodStreamReady":o=!0,i.add(e.value.period);break;case"periodStreamCleared":i.removeElement(e.value.period)}return e}),null),(0,S.B)())}function c(e){var t=i.head(),n=i.last();return null==t||null==n||(t.start>e||(null==n.end?1/0:n.end)=o.end}))),h=c.pipe(ce((function(t){return I(e,t,d)}))),y=u.pipe((0,b.q)(1),(0,pe.b)((function(){c.complete(),d.next(),d.complete()})),(0,S.B)()),_=(0,f.T)(p,y),k=zn({abrManager:n,bufferType:e,clock$:t,content:{manifest:l,period:o},garbageCollectors:E,segmentFetcherCreator:i,segmentBuffersStore:r,options:a,wantedBufferAhead$:T}).pipe((0,oe.zg)((function(t){if("stream-status"===t.type)if(t.value.hasFinishedLoading){var n=l.getPeriodAfter(o);if(null===n)return(0,v.z)((0,m.of)(t),(0,m.of)(an.streamComplete(e)));c.next(n)}else d.next();return(0,m.of)(t)})),(0,S.B)()),A=(0,v.z)(k.pipe((0,g.R)(_)),(0,m.of)(an.periodStreamCleared(e,o)).pipe((0,pe.b)((function(){D.Z.info("SO: Destroying Stream for",e,o)}))));return(0,f.T)(A,h,y.pipe((0,ie.l)()))}};var Gn=n(8821),jn=n(6565);var Yn=function(){function e(e){if(this.total=e,this.total<0)throw new jn.W}return e.prototype.call=function(e,t){return t.subscribe(new qn(e,this.total))},e}(),qn=function(e){function t(t,n){var r=e.call(this,t)||this;return r.total=n,r.ring=new Array,r.count=0,r}return l.ZT(t,e),t.prototype._next=function(e){var t=this.ring,n=this.total,r=this.count++;t.length0)for(var n=this.count>=this.total?this.total:this.count,r=this.ring,i=0;i0&&void 0!==e[0].period.end&&e[0].period.end+10r.start)return ar(t)&&e.splice(a,0,t),e;ar(t)&&e.push(t);return e}(e,t[0],t[1])}),[]));return e.pipe(Ce(i),(0,y.U)((function(e){var r=e[0],i=e[1],a=r.buffered,o=r.currentRange,s=r.position,u=r.state,l=r.stalled;if(null===l)return{type:"unstalled",value:null};var c=l.position;if(null!==c){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)-rr)if(null===d){var f=t.getPeriodAfter(a);null!==f?o=f.start+rr:D.Z.warn("Init: discontinuity at Period's end but no next Period")}else no?r:o)}}return r}(i,n,c);if(null!==d){var f=d+.001;if(!(f<=t.currentTime))return D.Z.warn("SA: skippable discontinuity found in the stream",s,f),t.currentTime=f,an.warning(or(c,f));D.Z.info("Init: position to seek already reached, no seeking",t.currentTime,f)}}if(function(e,t,n,r){return O.vU&&r&&"timeupdate"===n&&null!=t&&t.end-e>10}(s,o,u,null!==l))return D.Z.warn("Init: After freeze seek",s,o),t.currentTime=s,an.warning(or(s,s));var p=null!=c?c:s,h=(0,X.XS)(a,p);if(h=0;m--){var g=n.periods[m];if(void 0!==g.end&&g.end<=p){if(n.periods[m+1].start>p&&n.periods[m+1].start>t.currentTime){var y=n.periods[m+1];return t.currentTime=y.start,an.warning(or(p,y.start))}break}}return{type:"stalled",value:l}})))}function ar(e){return null!==e.discontinuity}function or(e,t){return new U.Z("DISCONTINUITY_ENCOUNTERED","A discontinuity has been encountered at position "+String(e)+", seeked at position "+String(t))}var sr=function(){function e(){}return e.prototype.call=function(e,t){return t.subscribe(new ur(e))},e}(),ur=function(e){function t(t){var n=e.call(this,t)||this;return n.hasPrev=!1,n}return l.ZT(t,e),t.prototype._next=function(e){var t;this.hasPrev?t=[this.prev,e]:this.hasPrev=!0,this.prev=e,t&&this.destination.next(t)},t}(x.L);const lr=function(e,t){return e.id===t.id&&e.start===t.start&&e.end===t.end};const cr=function(e,t){for(var n=[],r=t.periods,i=0;i0})),(0,_.x)(),(0,ye.w)((function(e){return e?(0,h.aj)([(0,Ht.F)(dr).pipe((0,k.O)(null)),n]).pipe((0,y.U)((function(e){e[0];return{isSeeking:e[1].seeking,currentTime:t.currentTime}})),(function(e){return e.lift(new sr)}),(0,oe.zg)((function(e){var t=e[0],n=e[1];return function(e,t,n){for(var i=t.currentTime,a=n.isSeeking,o=n.currentTime,s=[],u=[],l=0;lo||void 0!==f&&o>=f)&&(fr(c)&&u.push(c.publicEvent),r.delete(c)):d<=o&&void 0!==f&&o=(null!=f?f:d)&&(a?s.push({type:"stream-event-skip",value:c.publicEvent}):(s.push({type:"stream-event",value:c.publicEvent}),fr(c)&&u.push(c.publicEvent)))}return(0,v.z)(s.length>0?m.of.apply(void 0,s):p.E,u.length>0?m.of.apply(void 0,u).pipe((0,pe.b)((function(e){"function"==typeof e.onExit&&e.onExit()})),(0,ie.l)()):p.E)}(i,t,n)}))):p.E})))};var hr=n(2983);function vr(e){var t=e.mediaElement,n=e.manifest,r=e.clock$,i=e.speed$,a=e.bufferOptions,o=e.abrManager,u=e.segmentFetcherCreator;return function(e,l,c){var d,v=n.isLive?1/0:n.getMaximumPosition();!function(e,t){var n=t===1/0?Number.MAX_VALUE:t;e.duration!==n&&(D.Z.info("Init: Setting duration",n),e.duration=n)}(e,v);var _=null!==(d=n.getPeriodForTime(l))&&void 0!==d?d:n.getNextPeriod(l);if(void 0===_){var b=new U.Z("MEDIA_STARTING_TIME_NOT_FOUND","Wanted starting time not found in the Manifest.");return(0,Kt._)(b)}var T=new Jt(t,e),E=(0,tr.Z)({clock$:r,mediaElement:t,startTime:l,mustAutoPlay:c,isDirectfile:!1}),S=E.seek$,A=E.load$,x=A.pipe((0,w.h)((function(e){return"not-loaded-metadata"!==e}))),Z=x.pipe((0,oe.zg)((function(){return pr(n,t,r)}))),I=function(e,t){var n=t.autoPlay,r=t.initialPlay$,i=t.initialSeek$,a=t.manifest,o=t.speed$,s=t.startTime,u=!1,l=!1,c=r.pipe((0,pe.b)((function(){u=!0})),(0,ie.l)()),d=i.pipe((0,pe.b)((function(){l=!0})),(0,ie.l)()),p=(0,h.aj)([e,o]).pipe((0,y.U)((function(e){var t=e[0],r=e[1],i=a.isLive;return{position:t.position,getCurrentTime:t.getCurrentTime,duration:t.duration,isPaused:u?t.paused:!n,liveGap:i?a.getMaximumPosition()-t.position:1/0,readyState:t.readyState,speed:r,stalled:t.stalled,wantedTimeOffset:l?0:s-t.position}})));return(0,f.T)(c,d,p)}(r,{autoPlay:c,initialPlay$:x,initialSeek$:S,manifest:n,speed$:i,startTime:l}),R=new s.xQ,M=new s.xQ,C=$n({manifest:n,initialPeriod:_},I,o,T,u,a).pipe((0,oe.zg)((function(t){switch(t.type){case"end-of-stream":return D.Z.debug("Init: end-of-stream order received."),function(e){return Qn(e).pipe((0,k.O)(null),(0,ye.w)((function(){return er(e)})))}(e).pipe((0,ie.l)(),(0,g.R)(R));case"resume-stream":return D.Z.debug("Init: resume-stream order received."),R.next(null),p.E;case"stream-status":var n=t.value,r=n.period,i=n.bufferType,a=n.imminentDiscontinuity,o=n.position;return M.next({period:r,bufferType:i,discontinuity:a,position:o}),p.E;default:return(0,m.of)(t)}}))),N=(0,hr.Z)(t,i,r,{pauseWhenStalled:!0}).pipe((0,ie.l)()),P=ir(r,t,n,M),O=A.pipe((0,oe.zg)((function(e){if("autoplay-blocked"===e){var t=new U.Z("MEDIA_ERR_BLOCKED_AUTOPLAY","Cannot trigger auto-play automatically: your browser does not allow it.");return(0,m.of)(zt.Z.warning(t),zt.Z.loaded(T))}if("not-loaded-metadata"===e){var n=new U.Z("MEDIA_ERR_NOT_LOADED_METADATA","Cannot load automatically: your browser falsely announced having loaded the content.");return(0,m.of)(zt.Z.warning(n))}return D.Z.debug("Init: The current content is loaded."),(0,m.of)(zt.Z.loaded(T))})));return(0,f.T)(O,N,P,C,Z).pipe(ve((function(){T.disposeAll()})))}}var mr=B.Z.FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY,gr=B.Z.MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE,yr=B.Z.MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE;function _r(e){var t=e.fetchManifest,n=e.initialManifest,r=e.manifestUpdateUrl,i=e.minimumManifestUpdateInterval,a=e.scheduleRefresh$,o=n.manifest,s=0;function u(e){var t,n=e.sendingTime,r=e.parsingTime,c=e.updatingTime,d=void 0!==r?r+(null!=c?c:0):void 0,h=s>0?s=yr,v=a.pipe((0,oe.zg)((function(e){var t=e.completeRefresh,r=e.delay,a=e.canUseUnsafeMode&&h;return br(null!=r?r:0,i,n).pipe((0,A.h)({completeRefresh:t,unsafeMode:a}))}))),g=void 0===n?0:performance.now()-n,y=Math.max(i-g,0);if(void 0===o.lifetime||o.lifetime<0)t=p.E;else{var _=1e3*o.lifetime-g;if(void 0!==d)if(o.lifetime<3&&d>=100){var T=1e3*(3-o.lifetime)+_,E=Math.max(T,Math.max(_,0)+d);D.Z.info("MUS: Manifest update rythm is too frequent. Postponing next request.",_,E),_=E}else if(d>=1e3*o.lifetime/10){var w=Math.max(_,0)+d;D.Z.info("MUS: Manifest took too long to parse. Postponing next request",_,w),_=w}t=(0,ut.H)(Math.max(_,y)).pipe((0,A.h)({completeRefresh:!1,unsafeMode:h}))}var S=null===o.expired?p.E:(0,ut.H)(y).pipe((0,M.j)((0,ue.D)(o.expired)),(0,A.h)({completeRefresh:!0,unsafeMode:h}));return(0,f.T)(t,v,S).pipe((0,b.q)(1),(0,oe.zg)((function(e){return l({completeRefresh:e.completeRefresh,unsafeMode:e.unsafeMode})})),(0,oe.zg)((function(e){return"warning"===e.type?(0,m.of)(e):u(e)})))}return(0,J.P)((function(){return u(n)}));function l(e){var n=e.completeRefresh,a=e.unsafeMode,u=n||void 0===r,c=u?o.getUrl():r,d=o.clockOffset;return a?(s+=1,D.Z.info('Init: Refreshing the Manifest in "unsafeMode" for the '+String(s)+" consecutive time.")):s>0&&(D.Z.info('Init: Not parsing the Manifest in "unsafeMode" anymore after '+String(s)+" consecutive times."),s=0),t(c,{externalClockOffset:d,previousManifest:o,unsafeMode:a}).pipe((0,oe.zg)((function(e){if("warning"===e.type)return(0,m.of)(e);var t=e.manifest,n=e.sendingTime,r=e.receivedTime,a=e.parsingTime,s=performance.now();if(u)o.replace(t);else try{o.update(t)}catch(e){var c=e instanceof Error?e.message:"unknown error";return D.Z.warn("MUS: Attempt to update Manifest failed: "+c,"Re-downloading the Manifest fully"),br(mr,i,n).pipe((0,oe.zg)((function(){return l({completeRefresh:!0,unsafeMode:!1})})))}return(0,m.of)({type:"parsed",manifest:o,sendingTime:n,receivedTime:r,parsingTime:a,updatingTime:performance.now()-s})})))}}function br(e,t,n){return(0,J.P)((function(){var r=void 0===n?0:performance.now()-n,i=Math.max(t-r,0);return(0,ut.H)(Math.max(e-r,i))}))}var Tr=n(2447),Er=B.Z.OUT_OF_SYNC_MANIFEST_REFRESH_DELAY;const wr=function(e){var t,n,r,i=e.adaptiveOptions,a=e.autoPlay,o=e.bufferOptions,u=e.clock$,l=e.content,c=e.keySystems,d=e.lowLatencyMode,v=e.mediaElement,_=e.minimumManifestUpdateInterval,T=e.networkConfig,E=e.speed$,w=e.startAt,x=e.textTrackOptions,Z=e.transportPipelines,I=l.url,R=l.initialManifest,M=l.manifestUpdateUrl,C=T.offlineRetry,N=T.segmentRetry,P=T.manifestRetry,O=new yt(I,Z,{lowLatencyMode:d,maxRetryRegular:P,maxRetryOffline:C}),L=(t=function(e,t){return O.fetch(e).pipe((0,oe.zg)((function(e){return"warning"===e.type?(0,m.of)(e):e.parse(t)})),(0,S.B)())},n=!1,function(){for(var e=arguments.length,r=new Array(e),i=0;i=0?i:Math.max(r,i+u)}if(null!=n.percentage){D.Z.debug("Init: using startAt.percentage");var l=n.percentage;return l>100?i:l<0?r:r+ +l/100*(i-r)}}var c=e.getMinimumPosition();if(e.isLive){var d,f=e.suggestedPresentationDelay,p=e.clockOffset,h=e.getMaximumPosition();if(null==p)D.Z.info("Init: no clock offset found for a live content, starting close to maximum available position"),d=h;else{D.Z.info("Init: clock offset found for a live content, checking if we can start close to it");var v=null==e.availabilityStartTime?0:e.availabilityStartTime,m=(performance.now()+p)/1e3-v;d=Math.min(h,m)}var g=void 0!==f?f:t?Vt.LOW_LATENCY:Vt.DEFAULT;return D.Z.debug("Init: "+d+" defined as the live time, applying a live gap of "+g),Math.max(d-g,c)}return D.Z.info("Init: starting at the minimum available position:",c),c}(r,d,w);D.Z.debug("Init: Initial time calculated:",i);var l=vr({abrManager:U,bufferOptions:(0,Y.Z)({textTrackOptions:x},o),clock$:u,manifest:r,mediaElement:v,segmentFetcherCreator:B,speed$:E}),c=function e(t,n,r){var i=new s.xQ,a=l(t,n,r).pipe((0,Te.Z)((function(e){switch(e.type){case"needs-manifest-refresh":return p.next({completeRefresh:!1,canUseUnsafeMode:!0}),null;case"manifest-might-be-out-of-sync":return p.next({completeRefresh:!0,canUseUnsafeMode:!1,delay:Er}),null;case"needs-media-source-reload":return i.next(e.value),null;case"needs-decipherability-flush":var t=re(v);if(null===(r=t)||r.indexOf("widevine")<0)return i.next(e.value),null;var n=e.value.position;return n+.001=1&&"loadedmetadata"!==u&&null===m&&!(_||v),T=null,E=s?Mr.LOW_LATENCY:Mr.DEFAULT;if(o){if(b)c<=E?(r=!0,T=l+c):c===1/0?(r=!0,T=l):1===h&&(r=!0);else if(null!==m){var w=Nr(m,s);!0!==r&&null!==m&&h>1&&(_||v||c<1/0&&c>w)?i=!0:(c===1/0||c<=w)&&(T=c===1/0?l:l+c)}}else b&&(!p&&"timeupdate"===u&&"timeupdate"===g&&l===y||"seeking"===u&&c===1/0)?r=!0:null!==m&&("seeking"!==u&&l!==y||"canplay"===u||c<1/0&&(c>Nr(m,s)||_||v))&&(i=!0);return!0===i?null:!0===r||null!==m?(a="seeking"===u||t.seeking||null!==m&&"seeking"===m.reason?"seeking":1===h?"not-ready":"buffering",null!==m&&m.reason===a?{reason:m.reason,timestamp:m.timestamp,position:T}:{reason:a,timestamp:performance.now(),position:T}):null}const Dr=function(e,t){return(0,J.P)((function(){var n=(0,Y.Z)(Pr(e,"init"),{stalled:null,getCurrentTime:function(){return e.currentTime}});var r=Cr.map((function(t){return(0,Wt.R)(e,t).pipe((0,A.h)(t))})),i=t.lowLatencyMode?Ar:t.withMediaSource?kr:xr,a=(0,Ht.F)(i).pipe((0,A.h)("timeupdate"));return f.T.apply(void 0,[a].concat(r)).pipe((0,y.U)((function(r){return n=function(r){var i=Pr(e,r),a=Or(n,i,t),o=(0,Y.Z)({},{stalled:a,getCurrentTime:function(){return e.currentTime}},i);return D.Z.debug("API: current media element state",o),o}(r),"DEBUG"===D.Z.getLevel()&&D.Z.debug("API: current playback timeline:\n"+function(e,t){for(var n="",r="",i=0;it){var c=n.length-Math.floor(l.length/2);r=" ".repeat(c)+"^"+t}if(i=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.")}return(n=e[Symbol.iterator]()).next.bind(n)}function Yr(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0;)this._periods.pop()},t.update=function(){this._resetChosenAudioTracks(),this._resetChosenTextTracks(),this._resetChosenVideoTracks()},t.setInitialAudioTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.audio:null;if(null==n||null==t)throw new Error("TrackChoiceManager: Given Period not found.");var r=e.getPlayableAdaptations("audio"),i=this._audioChoiceMemory.get(e);if(null===i)n.adaptation$.next(null);else if(void 0!==i&&(0,St.Z)(r,i))n.adaptation$.next(i);else{var a=yi(r,hi(this._preferredAudioTracks));this._audioChoiceMemory.set(e,a),n.adaptation$.next(a)}},t.setInitialTextTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.text:null;if(null==n||null==t)throw new Error("TrackChoiceManager: Given Period not found.");var r=e.getPlayableAdaptations("text"),i=this._textChoiceMemory.get(e);if(null===i)n.adaptation$.next(null);else if(void 0!==i&&(0,St.Z)(r,i))n.adaptation$.next(i);else{var a=bi(r,vi(this._preferredTextTracks));this._textChoiceMemory.set(e,a),n.adaptation$.next(a)}},t.setInitialVideoTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.video:null;if(null==n||null==t)throw new Error("TrackChoiceManager: Given Period not found.");var r=e.getPlayableAdaptations("video"),i=this._videoChoiceMemory.get(e);if(null===i)n.adaptation$.next(null);else if(void 0!==i&&(0,St.Z)(r,i))n.adaptation$.next(i);else{var a=Ei(r,this._preferredVideoTracks);this._videoChoiceMemory.set(e,a),n.adaptation$.next(a)}},t.setAudioTrackByID=function(e,t){var n=wi(this._periods,e),r=null!=n?n.audio:null;if(null==r)throw new Error("TrackChoiceManager: Given Period not found.");var i=(0,Fe.Z)(r.adaptations,(function(e){return e.id===t}));if(void 0===i)throw new Error("Audio Track not found.");this._audioChoiceMemory.get(e)!==i&&(this._audioChoiceMemory.set(e,i),r.adaptation$.next(i))},t.setTextTrackByID=function(e,t){var n=wi(this._periods,e),r=null!=n?n.text:null;if(null==r)throw new Error("TrackChoiceManager: Given Period not found.");var i=(0,Fe.Z)(r.adaptations,(function(e){return e.id===t}));if(void 0===i)throw new Error("Text Track not found.");this._textChoiceMemory.get(e)!==i&&(this._textChoiceMemory.set(e,i),r.adaptation$.next(i))},t.setVideoTrackByID=function(e,t){var n=wi(this._periods,e),r=null!=n?n.video:null;if(null==r)throw new Error("LanguageManager: Given Period not found.");var i=(0,Fe.Z)(r.adaptations,(function(e){return e.id===t}));if(void 0===i)throw new Error("Video Track not found.");this._videoChoiceMemory.get(e)!==i&&(this._videoChoiceMemory.set(e,i),r.adaptation$.next(i))},t.disableTextTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.text:null;if(null==n)throw new Error("TrackChoiceManager: Given Period not found.");null!==this._textChoiceMemory.get(e)&&(this._textChoiceMemory.set(e,null),n.adaptation$.next(null))},t.disableVideoTrack=function(e){var t=wi(this._periods,e),n=null==t?void 0:t.video;if(void 0===n)throw new Error("TrackManager: Given Period not found.");null!==this._videoChoiceMemory.get(e)&&(this._videoChoiceMemory.set(e,null),n.adaptation$.next(null))},t.getChosenAudioTrack=function(e){var t=wi(this._periods,e);if(null==(null!=t?t.audio:null))return null;var n=this._audioChoiceMemory.get(e);if(null==n)return null;var r={language:(0,we.Z)(n.language,""),normalized:(0,we.Z)(n.normalizedLanguage,""),audioDescription:!0===n.isAudioDescription,id:n.id,representations:n.representations.map(ki)};return!0===n.isDub&&(r.dub=!0),r},t.getChosenTextTrack=function(e){var t=wi(this._periods,e);if(null==(null!=t?t.text:null))return null;var n=this._textChoiceMemory.get(e);return null==n?null:{language:(0,we.Z)(n.language,""),normalized:(0,we.Z)(n.normalizedLanguage,""),closedCaption:!0===n.isClosedCaption,id:n.id}},t.getChosenVideoTrack=function(e){var t=wi(this._periods,e);if(null==(null!=t?t.video:null))return null;var n=this._videoChoiceMemory.get(e);if(null==n)return null;var r={id:n.id,representations:n.representations.map(Si)};return!0===n.isSignInterpreted&&(r.signInterpreted=!0),r},t.getAvailableAudioTracks=function(e){var t=wi(this._periods,e),n=null!=t?t.audio:null;if(null==n)return[];var r=this._audioChoiceMemory.get(e),i=null!=r?r.id:null;return n.adaptations.map((function(e){var t={language:(0,we.Z)(e.language,""),normalized:(0,we.Z)(e.normalizedLanguage,""),audioDescription:!0===e.isAudioDescription,id:e.id,active:null!=i&&i===e.id,representations:e.representations.map(ki)};return!0===e.isDub&&(t.dub=!0),t}))},t.getAvailableTextTracks=function(e){var t=wi(this._periods,e),n=null!=t?t.text:null;if(null==n)return[];var r=this._textChoiceMemory.get(e),i=null!=r?r.id:null;return n.adaptations.map((function(e){return{language:(0,we.Z)(e.language,""),normalized:(0,we.Z)(e.normalizedLanguage,""),closedCaption:!0===e.isClosedCaption,id:e.id,active:null!=i&&i===e.id}}))},t.getAvailableVideoTracks=function(e){var t=wi(this._periods,e),n=null!=t?t.video:null;if(null==n)return[];var r=this._videoChoiceMemory.get(e),i=null!=r?r.id:null;return n.adaptations.map((function(e){var t={id:e.id,active:null!==i&&i===e.id,representations:e.representations.map(Si)};return!0===e.isSignInterpreted&&(t.signInterpreted=!0),t}))},t._applyAudioPreferences=function(){this._audioChoiceMemory=new WeakMap,this._resetChosenAudioTracks()},t._applyTextPreferences=function(){this._textChoiceMemory=new WeakMap,this._resetChosenTextTracks()},t._applyVideoPreferences=function(){this._videoChoiceMemory=new WeakMap,this._resetChosenVideoTracks()},t._resetChosenAudioTracks=function(){var e=this,t=hi(this._preferredAudioTracks);!function n(r){if(!(r>=e._periods.length())){var i=e._periods.get(r);if(null!=i.audio){var a=i.period,o=i.audio,s=a.getPlayableAdaptations("audio"),u=e._audioChoiceMemory.get(a);if(null===u||void 0!==u&&(0,St.Z)(s,u))n(r+1);else{var l=yi(s,t);e._audioChoiceMemory.set(a,l),o.adaptation$.next(l),n(0)}}else n(r+1)}}(0)},t._resetChosenTextTracks=function(){var e=this,t=vi(this._preferredTextTracks);!function n(r){if(!(r>=e._periods.length())){var i=e._periods.get(r);if(null!=i.text){var a=i.period,o=i.text,s=a.getPlayableAdaptations("text"),u=e._textChoiceMemory.get(a);if(null===u||void 0!==u&&(0,St.Z)(s,u))n(r+1);else{var l=bi(s,t);e._textChoiceMemory.set(a,l),o.adaptation$.next(l),n(0)}}else n(r+1)}}(0)},t._resetChosenVideoTracks=function(){var e=this,t=this._preferredVideoTracks;!function n(r){if(!(r>=e._periods.length())){var i=e._periods.get(r);if(null!=i.video){var a=i.period,o=i.video,s=a.getPlayableAdaptations("video"),u=e._videoChoiceMemory.get(a);if(null===u||void 0!==u&&(0,St.Z)(s,u))n(r+1);else{var l=Ei(s,t);e._videoChoiceMemory.set(a,l),o.adaptation$.next(l),n(0)}}else n(r+1)}}(0)},e}();function gi(e){return function(t){var n;if(void 0!==e.normalized&&(null!==(n=t.normalizedLanguage)&&void 0!==n?n:"")!==e.normalized)return!1;if(void 0!==e.audioDescription)if(e.audioDescription){if(!0!==t.isAudioDescription)return!1}else if(!0===t.isAudioDescription)return!1;if(void 0===e.codec)return!0;var r=e.codec.test,i=function(e){return void 0!==e.codec&&r.test(e.codec)};return e.codec.all?t.representations.every(i):t.representations.some(i)}}function yi(e,t){if(0===e.length)return null;for(var n=0;nv)throw new Error('Invalid maxVideoBitrate parameter. Its value, "'+v+'", is inferior to the set minVideoBitrate, "'+p+'"')}if((0,G.Z)(e.maxAudioBitrate))h=ii.audio;else{if(h=Number(e.maxAudioBitrate),isNaN(h))throw new Error("Invalid maxAudioBitrate parameter. Should be a number.");if(f>h)throw new Error('Invalid maxAudioBitrate parameter. Its value, "'+h+'", is inferior to the set minAudioBitrate, "'+f+'"')}return{maxBufferAhead:t,maxBufferBehind:n,limitVideoWidth:m,videoElement:l,wantedBufferAhead:r,throttleWhenHidden:i,throttleVideoBitrateWhenHidden:a,preferredAudioTracks:o,preferredTextTracks:s,preferredVideoTracks:u,initialAudioBitrate:d,initialVideoBitrate:c,minAudioBitrate:f,minVideoBitrate:p,maxAudioBitrate:h,maxVideoBitrate:v,stopAtEnd:(0,G.Z)(e.stopAtEnd)?ui:!!e.stopAtEnd}}(t),i=r.initialAudioBitrate,a=r.initialVideoBitrate,o=r.limitVideoWidth,l=r.minAudioBitrate,c=r.minVideoBitrate,f=r.maxAudioBitrate,p=r.maxBufferAhead,h=r.maxBufferBehind,v=r.maxVideoBitrate,m=r.preferredAudioTracks,b=r.preferredTextTracks,T=r.preferredVideoTracks,E=r.throttleWhenHidden,w=r.throttleVideoBitrateWhenHidden,S=r.videoElement,k=r.wantedBufferAhead,A=r.stopAtEnd;return S.preload="auto",n.version="3.23.1",n.log=D.Z,n.state="STOPPED",n.videoElement=S,n._priv_destroy$=new s.xQ,n._priv_pictureInPictureEvent$=new u.t(1),Ci(S).pipe((0,g.R)(n._priv_destroy$)).subscribe(n._priv_pictureInPictureEvent$),Ri(S).pipe((0,g.R)(n._priv_destroy$)).subscribe((function(){return n.trigger("fullscreenChange",n.isFullscreen())})),Pi(S.textTracks).pipe((0,g.R)(n._priv_destroy$),(0,y.U)((function(e){for(var t=e.target,n=[],r=0;r0?e.textTracks[0]:null},n.getPlayerState=function(){return this.state},n.isLive=function(){if(null===this._priv_contentInfos)return!1;var e=this._priv_contentInfos,t=e.isDirectFile,n=e.manifest;return!t&&null!==n&&n.isLive},n.getUrl=function(){if(null!==this._priv_contentInfos){var e=this._priv_contentInfos,t=e.isDirectFile,n=e.manifest,r=e.url;return t?r:null!==n?n.getUrl():void 0}},n.getVideoDuration=function(){if(null===this.videoElement)throw new Error("Disposed player");return this.videoElement.duration},n.getVideoBufferGap=function(){if(null===this.videoElement)throw new Error("Disposed player");var e=this.videoElement;return(0,X.L7)(e.buffered,e.currentTime)},n.getVideoLoadedTime=function(){if(null===this.videoElement)throw new Error("Disposed player");var e=this.videoElement;return(0,X.at)(e.buffered,e.currentTime)},n.getVideoPlayedTime=function(){if(null===this.videoElement)throw new Error("Disposed player");var e=this.videoElement;return(0,X.DD)(e.buffered,e.currentTime)},n.getWallClockTime=function(){if(null===this.videoElement)throw new Error("Disposed player");if(null===this._priv_contentInfos)return this.videoElement.currentTime;var e=this._priv_contentInfos,t=e.isDirectFile,n=e.manifest;return t?this.videoElement.currentTime:null!==n?this.videoElement.currentTime+(void 0!==n.availabilityStartTime?n.availabilityStartTime:0):0},n.getPosition=function(){if(null===this.videoElement)throw new Error("Disposed player");return this.videoElement.currentTime},n.getPlaybackRate=function(){return this._priv_speed$.getValue()},n.setPlaybackRate=function(e){this._priv_speed$.next(e)},n.getAvailableVideoBitrates=function(){if(null===this._priv_contentInfos)return[];var e=this._priv_contentInfos,t=e.currentPeriod,n=e.activeAdaptations;if(null===t||null===n)return[];var r=n[t.id];return void 0===r||(0,G.Z)(r.video)?[]:r.video.getAvailableBitrates()},n.getAvailableAudioBitrates=function(){if(null===this._priv_contentInfos)return[];var e=this._priv_contentInfos,t=e.currentPeriod,n=e.activeAdaptations;if(null===t||null===n)return[];var r=n[t.id];return void 0===r||(0,G.Z)(r.audio)?[]:r.audio.getAvailableBitrates()},n.getManualAudioBitrate=function(){return this._priv_bitrateInfos.manualBitrates.audio.getValue()},n.getManualVideoBitrate=function(){return this._priv_bitrateInfos.manualBitrates.video.getValue()},n.getVideoBitrate=function(){var e=this._priv_getCurrentRepresentations();if(null!==e&&!(0,G.Z)(e.video))return e.video.bitrate},n.getAudioBitrate=function(){var e=this._priv_getCurrentRepresentations();if(null!==e&&!(0,G.Z)(e.audio))return e.audio.bitrate},n.getMinVideoBitrate=function(){return this._priv_bitrateInfos.minAutoBitrates.video.getValue()},n.getMinAudioBitrate=function(){return this._priv_bitrateInfos.minAutoBitrates.audio.getValue()},n.getMaxVideoBitrate=function(){return this._priv_bitrateInfos.maxAutoBitrates.video.getValue()},n.getMaxAudioBitrate=function(){return this._priv_bitrateInfos.maxAutoBitrates.audio.getValue()},n.play=function(){var e=this;if(null===this.videoElement)throw new Error("Disposed player");var t=this.videoElement.play();return(0,G.Z)(t)||"function"!=typeof t.catch?q.Z.resolve():t.catch((function(t){if("NotAllowedError"===t.name){var n=new U.Z("MEDIA_ERR_PLAY_NOT_ALLOWED",t.toString());e.trigger("warning",n)}throw t}))},n.pause=function(){if(null===this.videoElement)throw new Error("Disposed player");this.videoElement.pause()},n.seekTo=function(e){if(null===this.videoElement)throw new Error("Disposed player");if(null===this._priv_contentInfos)throw new Error("player: no content loaded");var t,n=this._priv_contentInfos,r=n.isDirectFile,i=n.manifest;if(!r&&null===i)throw new Error("player: the content did not load yet");if("number"==typeof e)t=e;else if("object"==typeof e){var a=e,o=this.videoElement.currentTime;if((0,G.Z)(a.relative))if((0,G.Z)(a.position)){if((0,G.Z)(a.wallClockTime))throw new Error('invalid time object. You must set one of the following properties: "relative", "position" or "wallClockTime"');t=r||null===i?a.wallClockTime:a.wallClockTime-(void 0!==i.availabilityStartTime?i.availabilityStartTime:0)}else t=a.position;else t=o+a.relative}if(void 0===t)throw new Error("invalid time given");return this.videoElement.currentTime=t,t},n.isFullscreen=function(){return(0,Q.Z)("isFullscreen is deprecated. Fullscreen management should now be managed by the application"),P()},n.setFullscreen=function(e){if(void 0===e&&(e=!0),(0,Q.Z)("setFullscreen is deprecated. Fullscreen management should now be managed by the application"),null===this.videoElement)throw new Error("Disposed player");e?function(e){if(!P()){var t=e;"function"==typeof t.requestFullscreen?t.requestFullscreen():"function"==typeof t.msRequestFullscreen?t.msRequestFullscreen():"function"==typeof t.mozRequestFullScreen?t.mozRequestFullScreen():"function"==typeof t.webkitRequestFullscreen&&t.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}}(this.videoElement):N()},n.exitFullscreen=function(){(0,Q.Z)("exitFullscreen is deprecated. Fullscreen management should now be managed by the application"),N()},n.getVolume=function(){if(null===this.videoElement)throw new Error("Disposed player");return this.videoElement.volume},n.setVolume=function(e){if(null===this.videoElement)throw new Error("Disposed player");var t=this.videoElement;e!==t.volume&&(t.volume=e,this.trigger("volumeChange",e))},n.isMute=function(){return 0===this.getVolume()},n.mute=function(){this._priv_mutedMemory=this.getVolume(),this.setVolume(0)},n.unMute=function(){0===this.getVolume()&&this.setVolume(0===this._priv_mutedMemory?Ai:this._priv_mutedMemory)},n.setVideoBitrate=function(e){this._priv_bitrateInfos.manualBitrates.video.next(e)},n.setAudioBitrate=function(e){this._priv_bitrateInfos.manualBitrates.audio.next(e)},n.setMinVideoBitrate=function(e){var t=this._priv_bitrateInfos.maxAutoBitrates.video.getValue();if(e>t)throw new Error('Invalid minimum video bitrate given. Its value, "'+e+'" is superior the current maximum video birate, "'+t+'".');this._priv_bitrateInfos.minAutoBitrates.video.next(e)},n.setMinAudioBitrate=function(e){var t=this._priv_bitrateInfos.maxAutoBitrates.audio.getValue();if(e>t)throw new Error('Invalid minimum audio bitrate given. Its value, "'+e+'" is superior the current maximum audio birate, "'+t+'".');this._priv_bitrateInfos.minAutoBitrates.audio.next(e)},n.setMaxVideoBitrate=function(e){var t=this._priv_bitrateInfos.minAutoBitrates.video.getValue();if(e0?r.next(i[0]):r.next(null)}},n._priv_onPeriodStreamCleared=function(e){var t=e.type,n=e.period;switch(t){case"audio":case"text":case"video":null!==this._priv_trackChoiceManager&&this._priv_trackChoiceManager.removePeriod(t,n)}if(null!==this._priv_contentInfos){var r=this._priv_contentInfos,i=r.activeAdaptations,a=r.activeRepresentations;if(!(0,G.Z)(i)&&!(0,G.Z)(i[n.id])){var o=i[n.id];delete o[t],0===Object.keys(o).length&&delete i[n.id]}if(!(0,G.Z)(a)&&!(0,G.Z)(a[n.id])){var s=a[n.id];delete s[t],0===Object.keys(s).length&&delete a[n.id]}}},n._priv_onReloadingMediaSource=function(){null!==this._priv_contentInfos&&(this._priv_contentInfos.segmentBuffersStore=null),null!==this._priv_trackChoiceManager&&this._priv_trackChoiceManager.resetPeriods()},n._priv_onAdaptationChange=function(e){var t=e.type,n=e.adaptation,r=e.period;if(null!==this._priv_contentInfos){null===this._priv_contentInfos.activeAdaptations&&(this._priv_contentInfos.activeAdaptations={});var i,a=this._priv_contentInfos,o=a.activeAdaptations,s=a.currentPeriod,u=o[r.id];if((0,G.Z)(u))o[r.id]=((i={})[t]=n,i);else u[t]=n;if(null!==this._priv_trackChoiceManager&&null!==s&&!(0,G.Z)(r)&&r.id===s.id)switch(t){case"audio":var l=this._priv_trackChoiceManager.getChosenAudioTrack(s);this.trigger("audioTrackChange",l);var c=this.getAvailableAudioBitrates();this._priv_triggerAvailableBitratesChangeEvent("availableAudioBitratesChange",c);break;case"text":var d=this._priv_trackChoiceManager.getChosenTextTrack(s);this.trigger("textTrackChange",d);break;case"video":var f=this._priv_trackChoiceManager.getChosenVideoTrack(s);this.trigger("videoTrackChange",f);var p=this.getAvailableVideoBitrates();this._priv_triggerAvailableBitratesChangeEvent("availableVideoBitratesChange",p)}}else D.Z.error("API: The adaptations changed but no content is loaded")},n._priv_onRepresentationChange=function(e){var t,n=e.type,r=e.period,i=e.representation;if(null!==this._priv_contentInfos){null===this._priv_contentInfos.activeRepresentations&&(this._priv_contentInfos.activeRepresentations={});var a,o=this._priv_contentInfos,s=o.activeRepresentations,u=o.currentPeriod,l=s[r.id];if((0,G.Z)(l))s[r.id]=((a={})[n]=i,a);else l[n]=i;var c=null!==(t=null==i?void 0:i.bitrate)&&void 0!==t?t:-1;(0,G.Z)(r)||null===u||u.id!==r.id||("video"===n?this._priv_triggerCurrentBitrateChangeEvent("videoBitrateChange",c):"audio"===n&&this._priv_triggerCurrentBitrateChangeEvent("audioBitrateChange",c))}else D.Z.error("API: The representations changed but no content is loaded")},n._priv_onBitrateEstimationChange=function(e){var t=e.type,n=e.bitrate;void 0!==n&&(this._priv_bitrateInfos.lastBitrates[t]=n),this.trigger("bitrateEstimationChange",{type:t,bitrate:n})},n._priv_onPlayPauseNext=function(e){if(null===this.videoElement)throw new Error("Disposed player");this._priv_playing$.next(e)},n._priv_onNativeTextTracksNext=function(e){this.trigger("nativeTextTracksChange",e)},n._priv_setPlayerState=function(e){this.state!==e&&(this.state=e,D.Z.info("API: playerStateChange event",e),this.trigger("playerStateChange",e))},n._priv_triggerPositionUpdate=function(e){var t;if(null!==this._priv_contentInfos){if(this.state!==$r){var n=this._priv_contentInfos,r=n.isDirectFile,i=n.manifest;if((r||null!==i)&&!(0,G.Z)(e)){this._priv_lastContentPlaybackInfos.lastPlaybackPosition=e.position;var a=null!==i?i.getMaximumPosition():void 0,o={position:e.position,duration:e.duration,playbackRate:e.playbackRate,maximumBufferTime:a,bufferGap:isFinite(e.bufferGap)?e.bufferGap:0};if(null!==i&&void 0!==a&&i.isLive&&e.position>0){var s=null!==(t=i.availabilityStartTime)&&void 0!==t?t:0;o.wallClockTime=e.position+s,o.liveGap=a-e.position}this.trigger("positionUpdate",o)}}}else D.Z.warn("API: Cannot perform time update: no content loaded.")},n._priv_triggerAvailableBitratesChangeEvent=function(e,t){var n=this._priv_contentEventsMemory[e];(void 0===n||(0,W.Z)(t,n))&&(this._priv_contentEventsMemory[e]=t,this.trigger(e,t))},n._priv_triggerCurrentBitrateChangeEvent=function(e,t){t!==this._priv_contentEventsMemory[e]&&(this._priv_contentEventsMemory[e]=t,this.trigger(e,t))},n._priv_getCurrentRepresentations=function(){if(null===this._priv_contentInfos)return null;var e=this._priv_contentInfos,t=e.currentPeriod,n=e.activeRepresentations;return null===t||null===n||(0,G.Z)(n[t.id])?null:n[t.id]},i()(t,null,[{key:"ErrorTypes",get:function(){return K.ZB}},{key:"ErrorCodes",get:function(){return K.SM}},{key:"LogLevel",get:function(){return D.Z.getLevel()},set:function(e){D.Z.setLevel(e)}}]),t}($.Z);Di.version="3.23.1";const Li=Di;var Bi=n(7273);!function(){Bi.Z.emeManager=n(8745).ZP,Bi.Z.imageBuffer=n(7127).Z,Bi.Z.imageParser=n(3203).Z,Bi.Z.transports.smooth=n(2339).Z,Bi.Z.transports.dash=n(1459).Z,Bi.Z.nativeTextTracksBuffer=n(9059).Z,Bi.Z.nativeTextTracksParsers.vtt=n(9405).Z,Bi.Z.nativeTextTracksParsers.ttml=n(1570).Z,Bi.Z.nativeTextTracksParsers.sami=n(1812).Z,Bi.Z.nativeTextTracksParsers.srt=n(8057).Z,Bi.Z.htmlTextTracksBuffer=n(5192).Z,Bi.Z.htmlTextTracksParsers.sami=n(5734).Z,Bi.Z.htmlTextTracksParsers.ttml=n(7439).Z,Bi.Z.htmlTextTracksParsers.srt=n(8675).Z,Bi.Z.htmlTextTracksParsers.vtt=n(4099).Z;var e=n(8969).Z,t=n(7794).Z;Bi.Z.directfile={initDirectFile:e,mediaElementTrackChoiceManager:t}}();const Ui=Li},3887:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(8894);const 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},e}())},5952:(e,t,n)=>{"use strict";function r(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}n.d(t,{Z:()=>r})},1966:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>M});var r=n(5354),i=n.n(r),a=n(4791),o=n(3274),s=n(1959),u=n(908),l=n(8806),c=n(3714),d=n(3887),f=n(7714),p=n(1946),h=n(7829);const v="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}))};var m=n(3774);var g=n(6968);const y=function(){function e(e,t){var n;this.id=e.id,this.bitrate=e.bitrate,this.codec=e.codecs,null!=e.height&&(this.height=e.height),null!=e.width&&(this.width=e.width),null!=e.mimeType&&(this.mimeType=e.mimeType),void 0!==e.contentProtections&&(this.contentProtections=e.contentProtections),null!=e.frameRate&&(this.frameRate=e.frameRate),this.index=e.index,this.isSupported="audio"!==t.type&&"video"!==t.type||(n=this.getMimeTypeString(),null!=m.JJ&&("function"!=typeof m.JJ.isTypeSupported||m.JJ.isTypeSupported(n)))}var t=e.prototype;return t.getMimeTypeString=function(){var e,t;return(null!==(e=this.mimeType)&&void 0!==e?e:"")+';codecs="'+(null!==(t=this.codec)&&void 0!==t?t:"")+'"'},t.getProtectionsInitializationData=function(){var e=this.contentProtections;return void 0===e?[]:Object.keys(e.initData).reduce((function(t,n){var r=e.initData[n];if(void 0===r||0===r.length)return t;var i=g.zo.apply(void 0,r.map((function(e){return e.data})));return t.push({type:n,data:i}),t}),[])},t._addProtectionData=function(e,t,n){var r={systemId:t,data:n};if(void 0!==this.contentProtections){var i=this.contentProtections.initData[e];if(void 0!==i){for(var o=i.length-1;o>=0;o--)if(i[o].systemId===t){if((0,a.Z)(i[o].data,n))return;d.Z.warn("Manifest: Two PSSH for the same system ID")}i.push(r)}else this.contentProtections.initData[e]=[r]}else{var s;this.contentProtections={keyIds:[],initData:(s={},s[e]=[r],s)}}},e}();var _=["audio","video","text","image"];var b,T=function(){function e(e,t){void 0===t&&(t={});var n,r=t,i=r.representationFilter,a=r.isManuallyAdded;if(this.parsingErrors=[],this.id=e.id,n=e.type,!(0,f.Z)(_,n))throw d.Z.info("Manifest: Not supported adaptation type",e.type),new c.Z("MANIFEST_UNSUPPORTED_ADAPTATION_TYPE",'"'+e.type+'" is not a valid Adaptation type.');this.type=e.type,void 0!==e.language&&(this.language=e.language,this.normalizedLanguage=(0,h.ZP)(e.language)),void 0!==e.closedCaption&&(this.isClosedCaption=e.closedCaption),void 0!==e.audioDescription&&(this.isAudioDescription=e.audioDescription),void 0!==e.isDub&&(this.isDub=e.isDub),void 0!==e.isSignInterpreted&&(this.isSignInterpreted=e.isSignInterpreted);for(var o=e.representations,s=[],u=!1,l=!1,v=0;v0&&!l){d.Z.warn("Incompatible codecs for adaptation",e);var g=new c.Z("MANIFEST_INCOMPATIBLE_CODECS_ERROR","An Adaptation contains only incompatible codecs.");this.parsingErrors.push(g)}}var t=e.prototype;return t.getAvailableBitrates=function(){for(var e=[],t=0;t0}));if(o.every((function(e){return!e.isSupported}))&&a.length>0&&("video"===i||"audio"===i))throw new c.Z("MANIFEST_PARSE_ERROR","No supported "+i+" adaptations");return o.length>0&&(r[i]=o),r}),{}),!Array.isArray(this.adaptations.video)&&!Array.isArray(this.adaptations.audio))throw new c.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,w.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.getPlayableAdaptations=function(e){if(void 0===e)return this.getAdaptations().filter((function(e){return e.isSupported&&!1!==e.decipherable}));var t=this.adaptations[e];return void 0===t?[]:t.filter((function(e){return e.isSupported&&!1!==e.decipherable}))},e}(),k=function(){function e(e){this._mediaURLs=e.media}var t=e.prototype;return t.getInitSegment=function(){return null},t.getSegments=function(){return[{id:"0",isInit:!1,number:0,mediaURLs:[this._mediaURLs],time:0,end:Number.MAX_VALUE,duration:Number.MAX_VALUE,timescale:1}]},t.getFirstPosition=function(){},t.getLastPosition=function(){},t.shouldRefresh=function(){return!1},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},t.isSegmentStillAvailable=function(){return!0},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){return!0},t.isInitialized=function(){return!0},t._replace=function(){d.Z.warn("Tried to replace a static RepresentationIndex")},t._update=function(){d.Z.warn("Tried to update a static RepresentationIndex")},e}();!function(e){e[e.Full=0]="Full",e[e.Partial=1]="Partial"}(b||(b={}));var A=n(5138);function x(e,t,n){e.start=t.start,e.end=t.end,e.duration=t.duration;for(var r=e.getAdaptations(),i=t.getAdaptations(),a=function(e){var t=r[e],a=(0,o.Z)(i,(function(e){return e.id===t.id}));if(void 0===a)d.Z.warn('Manifest: Adaptation "'+r[e].id+'" not found when merging.');else for(var s=r[e].representations,u=a.representations,l=function(e){var t=s[e],r=(0,o.Z)(u,(function(e){return e.id===t.id}));void 0===r?d.Z.warn('Manifest: Representation "'+s[e].id+'" not found when merging.'):n===b.Full?t.index._replace(r.index):t.index._update(r.index)},c=0;c0&&r._addSupplementaryImageAdaptations(u),o.length>0&&r._addSupplementaryTextAdaptations(o),r}i()(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.addUndecipherableProtectionData=function(e,t){var n=R(this,(function(n){if(!1===n.decipherable)return!0;for(var r=n.getProtectionsInitializationData(),i=0;i0&&this.trigger("decipherabilityUpdate",n)},n.getAdaptations=function(){(0,l.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,l.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,l.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,r=e.mimeType,i=e.url,a="gen-image-ada-"+Z(),o="gen-image-rep-"+Z(),s=new T({id:a,type:"image",representations:[{bitrate:0,id:o,mimeType:r,index:new k({media:i})}]},{isManuallyAdded:!0});return(n=t.parsingErrors).push.apply(n,s.parsingErrors),s}));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,a=n.url,o=n.language,s=n.languages,u=n.closedCaption,l=null!=o?[o]:null!=s?s:[];return e.concat(l.map((function(e){var n,o="gen-text-ada-"+Z(),s="gen-text-rep-"+Z(),l=new T({id:o,type:"text",language:e,closedCaption:u,representations:[{bitrate:0,id:s,mimeType:r,codecs:i,index:new k({media:a})}]},{isManuallyAdded:!0});return(n=t.parsingErrors).push.apply(n,l.parsingErrors),l})))}),[]);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.lifetime=e.lifetime,this.parsingErrors=e.parsingErrors,this.suggestedPresentationDelay=e.suggestedPresentationDelay,this.transport=e.transport,t===b.Full)this._timeBounds=e._timeBounds,this.uris=e.uris,function(e,t){for(var n=0,r=0;re.length)d.Z.error("Manifest: error when updating Periods");else{n0&&e.push.apply(e,l)}}(this.periods,e.periods);else{this._timeBounds.maximumTimeData=e._timeBounds.maximumTimeData,function(e,t){if(0!==e.length){if(0!==t.length){var n=e[e.length-1];if(n.starti&&(e.splice(i,s-i),s=i),x(e[s],o,b.Full),i++}i0;){var r=this.periods[0];if(void 0===r.end||r.end>n)break;this.periods.shift()}}this.adaptations=void 0===this.periods[0]?{}:this.periods[0].adaptations,this.trigger("manifestUpdate",null)},t}(s.Z)},2689:(e,t,n)=>{"use strict";n.d(t,{s:()=>r});var r=Math.pow(2,32)-1},2297:(e,t,n)=>{"use strict";n.d(t,{iz:()=>o,t_:()=>a,Qy:()=>s,Xj:()=>l,nR:()=>u});var r=n(3887),i=n(6968);function a(e,t){var n=s(e,t);return null!==n?e.subarray(n[1],n[2]):null}function o(e,t){var n=s(e,t);return null!==n?e.subarray(n[0],n[2]):null}function s(e,t){for(var n,r,a=e.length,o=0,s=0;o+8<=a;){if(r=o,s=(0,i.pX)(e,r),r+=4,n=(0,i.pX)(e,r),r+=4,0===s)s=a-o;else if(1===s){if(r+8>a)return null;s=(0,i.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 u(e,t,n,r,a){for(var o,s=e.length,u=0;us)return;o=(0,i.pV)(e,l),l+=8}if(1970628964===c&&l+16<=s&&(0,i.pX)(e,l)===t&&(0,i.pX)(e,l+4)===n&&(0,i.pX)(e,l+8)===r&&(0,i.pX)(e,l+12)===a)return l+=16,e.subarray(l,u+o)}}function l(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,a=(0,i.pX)(e,n);n+=4;var o=(0,i.pX)(e,n);if(n+=4,0===a)a=t;else if(1===a){if(n+8>t)return r.Z.warn("ISOBMFF: box too short, cannot find offsets"),null;a=(0,i.pV)(e,n),n+=8}if(a<0)throw new Error("ISOBMFF: Size out of range");return 1970628964===o&&(n+=16),[0,n,a]}},6807:(e,t,n)=>{"use strict";n.d(t,{XA:()=>i,Le:()=>a,fs:()=>o});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.t_)(e,1835295092)}function o(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)}},6490:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(3887);const 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))};var 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)return r.Z.warn("ISOBMFF: un-handled PSSH version"),null;var n=t+4;if(n+16>e.length)return null;var o=i(e,n+16);return(0,a.ci)(o)}},4644:(e,t,n)=>{"use strict";n.d(t,{LD:()=>c,Qx:()=>u,MM:()=>l,Wf:()=>s,J6:()=>d});var r=n(6968),i=n(2689),a=n(2297),o=n(6807);function s(e,t){var n=(0,a.Qy)(e,1936286840);if(null===n)return null;var i=t,o=n[2]-n[0],s=n[1],u=e[s];s+=8;var l,c=(0,r.pX)(e,s);if(s+=4,0===u)l=(0,r.pX)(e,s),s+=4,i+=(0,r.pX)(e,s)+o,s+=4;else{if(1!==u)return null;l=(0,r.pV)(e,s),s+=8,i+=(0,r.pV)(e,s)+o,s+=8}var d=[];s+=2;var f=(0,r.zK)(e,s);for(s+=2;--f>=0;){var p=(0,r.pX)(e,s);s+=4;var h=2147483647&p;if(1===(2147483648&p)>>>31)throw new Error("sidx with reference_type `1` not yet implemented");var v=(0,r.pX)(e,s);s+=4,s+=4,d.push({time:l,duration:v,count:0,timescale:c,range:[i,i+h-1]}),l+=v,i+=h}return d}function u(e){var t=(0,o.XA)(e);if(null!==t){var n=(0,a.t_)(t,1952867444);if(null!==n){var i=n[0];return 1===i?(0,r.pV)(n,4):0===i?(0,r.pX)(n,4):void 0}}}function l(e){var t=(0,o.XA)(e);if(null!==t){var n=(0,a.t_)(t,1953658222);if(null!==n){var i=0,s=n[i];if(i+=1,!(s>1)){var u=(0,r.QI)(n,i);i+=3;var l=(256&u)>0,c=0;if(l||void 0!==(c=function(e){var t=(0,a.t_)(e,1952868452);if(null!==t){var n=1,i=(0,r.QI)(t,n);if(n+=3,(8&i)>0)return n+=4,(1&i)>0&&(n+=8),(2&i)>0&&(n+=4),(0,r.pX)(t,n)}}(t))){var d=(1&u)>0,f=(4&u)>0,p=(512&u)>0,h=(1024&u)>0,v=(2048&u)>0,m=(0,r.pX)(n,i);i+=4,d&&(i+=4),f&&(i+=4);for(var g=m,y=0;g-- >0;)l?(y+=(0,r.pX)(n,i),i+=4):y+=c,p&&(i+=4),h&&(i+=4),v&&(i+=4);return y}}}}}function c(e){var t=(0,o.fs)(e);if(null!==t){var n=(0,a.t_)(t,1835296868);if(null!==n){var i=0,s=n[i];return i+=4,1===s?(0,r.pX)(n,i+16):0===s?(0,r.pX)(n,i+8):void 0}}}function d(e){var t=e.length;if(t<4)throw new Error("Cannot update box length: box too short");var n=(0,r.pX)(e,0);if(0===n){if(t>i.s){var a=new Uint8Array(t+8);return a.set((0,r.kh)(1),0),a.set(e.subarray(4,8),4),a.set((0,r.el)(t+8),8),a.set(e.subarray(8,t),16),a}return e.set((0,r.kh)(t),0),e}if(1===n){if(t<16)throw new Error("Cannot update box length: box too short");return e.set((0,r.el)(t),8),e}if(t<=i.s)return e.set((0,r.kh)(t),0),e;var o=new Uint8Array(t+8);return o.set((0,r.kh)(1),0),o.set(e.subarray(4,8),4),o.set((0,r.el)(t+8),8),o.set(e.subarray(8,t),16),o}},3203:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(6968),i=n(3635);const a=function(e){var t=0,n=e.length,a=(0,i.uR)(e.subarray(t+1,t+8));if(t+=8,137!==e[0]||"BIF\r\n\n"!==a)throw new Error("Invalid BIF file");var o=e[t],s=e[t+=1],u=e[t+=1],l=e[t+=1];t+=1;var c=[o,s,u,l].join(".");if(s>0)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 p=(0,i.uR)(e.subarray(t,t+4));t+=4;var h=(0,r.qb)(e,t);t+=2;var v=(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;t{"use strict";function r(e,t){for(;e.length>0;){var n=e[0];if(n.start>=t)return;if(n.repeatCount<=0)e.shift();else{var r=e[1];if(null!=r&&r.start<=t)e.shift();else{if(n.duration<=0)return;for(var i=n.start+n.duration,a=1;in.repeatCount)){var o=n.repeatCount-a;return n.start=i,void(n.repeatCount=o)}e.shift()}}}}n.d(t,{Z:()=>r})},3911:(e,t,n)=>{"use strict";function r(e,t,n){var r,i=e.repeatCount;return i>=0?i:(r=null!=t?t.start:null!=n?n:Number.MAX_VALUE,Math.ceil((r-e.start)/e.duration)-1)}function i(e,t,n){var i=e.start,a=e.duration;return a<=0?i:i+(r(e,t,n)+1)*a}function a(e,t){var n;return e*t.timescale+(null!==(n=t.indexTimeOffset)&&void 0!==n?n:0)}function o(e,t){var n;return(e-(null!==(n=t.indexTimeOffset)&&void 0!==n?n:0))/t.timescale}function s(e,t,n){return[e*n,(e+t)*n]}function u(e,t,n){var r=e.timeline,s=a(t,e);if(s<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,s);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 s>=i(l,c,n)&&sr,jH:()=>i,gT:()=>a,zG:()=>o,PZ:()=>s,_j:()=>u})},1091:(e,t,n)=>{"use strict";function r(e,t,n,r){for(var i=0;ie.time)return!1;if(o===e.time)return a.duration/n===e.duration&&(null==a.range?null==e.range:null!=e.range&&a.range[0]===e.range[0]&&a.range[1]===e.range[1]);if(a.repeatCount>=0&&null!=a.duration){var s=(o-a.start)/a.duration-1;return s%1==0&&s<=a.repeatCount}}return!1}n.d(t,{Z:()=>r})},5505:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(3714),i=n(3887),a=n(3911);function o(e,t){var n=e.length;if(0!==e.length){if(0!==t.length){var 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)return void e.splice.apply(e,[u,n-u].concat(t));if(lo)return i.Z.warn("RepresentationIndex: Manifest update removed previous segments"),void e.splice.apply(e,[u,n-u].concat(t));if(void 0===c.repeatCount||c.repeatCount<=0)return c.repeatCount<0&&(c.repeatCount=Math.floor((o-c.start)/c.duration)-1),void e.splice.apply(e,[u+1,n-(u+1)].concat(t));if(c.start+c.duration*(c.repeatCount+1)<=o)return void e.splice.apply(e,[u+1,n-(u+1)].concat(t));var d=(o-c.start)/c.duration-1;if(d%1==0&&c.duration===t[0].duration){var f=t[0].repeatCount<0?-1:t[0].repeatCount+d+1;return e.splice.apply(e,[u,n-u].concat(t)),e[u].start=c.start,void(e[u].repeatCount=f)}return i.Z.warn("RepresentationIndex: Manifest update removed previous segments"),e[u].repeatCount=Math.floor(d),void e.splice.apply(e,[u+1,n-(u+1)].concat(t))}}var p=e[e.length-1],h=t[t.length-1];if(void 0!==p.repeatCount&&p.repeatCount<0)return p.start>h.start?void i.Z.warn("RepresentationIndex: The new index is older than the previous one"):(i.Z.warn('RepresentationIndex: The new index is "bigger" than the previous one'),void e.splice.apply(e,[0,n].concat(t)));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"):(i.Z.warn('RepresentationIndex: The new index is "bigger" than the previous one'),e.splice.apply(e,[0,n].concat(t)))}}else e.splice.apply(e,[0,n].concat(t))}},5734:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(6923),i=/&#([0-9]+);/g,a=/
/gi,o=/]*>([\s\S]*?)<\/style[^>]*>/i,s=/\s*

]+))?>(.*)/i,u=/]+?start="?([0-9]*)"?[^0-9]/i;function l(e,t){var n=new RegExp("\\s*"+t+":\\s*(\\S+);","i").exec(e);return Array.isArray(n)?n[1]:null}const c=function(e,t,n){var c,d,f=/]/gi,p=/]|<\/body>/gi,h=[],v=o.exec(e),m=Array.isArray(v)?v[1]:"";p.exec(e);var g,y=function(e){for(var t=/\.(\S+)\s*{([^}]*)}/gi,n={},r=t.exec(e);null!==r;){var i=r[1],a=l(r[2],"lang");null!=i&&null!=a&&(n[a]=i),r=t.exec(e)}return n}(m),_=function(e){var t=/p\s*{([^}]*)}/gi.exec(e);return null===t?"":t[1]}(m);if((0,r.Z)(n)&&void 0===(g=y[n]))throw new Error("sami: could not find lang "+n+" in CSS");for(;c=f.exec(e),d=p.exec(e),null!==c||null!==d;){if(null===c||null===d||c.index>=d.index)throw new Error("parse error");var b=e.slice(c.index,d.index),T=u.exec(b);if(!Array.isArray(T))throw new Error("parse error (sync time attribute)");var E=+T[1];if(isNaN(E))throw new Error("parse error (sync time attribute NaN)");w(b.split("\n"),E/1e3)}return h;function w(e,n){for(var o=e.length;--o>=0;){var u=s.exec(e[o]);if(Array.isArray(u)){var l=u[1],c=u[2];if(g===l)if(" "===c)h[h.length-1].end=n;else{var d=document.createElement("DIV");d.className="rxp-texttrack-region";var f=document.createElement("DIV");f.className="rxp-texttrack-div",f.style.position="absolute",f.style.bottom="0",f.style.width="100%",f.style.color="#fff",f.style.textShadow="-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000";var p=document.createElement("div");p.className="rxp-texttrack-p",(0,r.Z)(_)&&(p.style.cssText=_);for(var v=c.split(a),m=0;m{"use strict";n.d(t,{Z:()=>d});var r=n(7253),i=n(6923),a=/&#([0-9]+);/g,o=/
/gi,s=/]*>([\s\S]*?)<\/style[^>]*>/i,u=/\s*

]+))?>(.*)/i,l=/]+?start="?([0-9]*)"?[^0-9]/i;function c(e,t){var n=new RegExp("\\s*"+t+":\\s*(\\S+);","i").exec(e);return Array.isArray(n)?n[1]:null}const d=function(e,t,n){var d,f,p=/]/gi,h=/]|<\/body>/gi,v=[],m=s.exec(e),g=null!==m?m[1]:"";h.exec(e);var y,_=function(e){for(var t=/\.(\S+)\s*{([^}]*)}/gi,n={},r=t.exec(e);Array.isArray(r);){var i=r[1],a=c(r[2],"lang");null!=i&&null!=a&&(n[a]=i),r=t.exec(e)}return n}(g);if((0,i.Z)(n)&&void 0===(y=_[n]))throw new Error("sami: could not find lang "+n+" in CSS");for(;d=p.exec(e),f=h.exec(e),null!==d||null!==f;){if(null===d||null===f||d.index>=f.index)throw new Error("parse error");var b=e.slice(d.index,f.index),T=l.exec(b);if(null===T)throw new Error("parse error (sync time attribute)");var E=+T[1];if(isNaN(E))throw new Error("parse error (sync time attribute NaN)");w(b.split("\n"),E/1e3)}return function(e){for(var t=[],n=0;n=0;)if(null!==(r=u.exec(e[s]))){var l=r,c=l[1],d=l[2];y===c&&(" "===d?v[v.length-1].end=n:v.push({text:(i=d,i.replace(o,"\n").replace(a,(function(e,t){return String.fromCharCode(t)}))),start:n+t}))}}}},2061:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(6923);function i(e,t){for(var n=t+1;(0,r.Z)(e[n]);)n++;return n}function a(e){for(var t=[],n=0;n0&&(1===o.length?o[0].indexOf("--\x3e")>=0&&t.push(o):(o[1].indexOf("--\x3e")>=0||o[0].indexOf("--\x3e")>=0)&&t.push(o)),n=a}return t}},8675:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(2061),i=n(788);function a(e,t){for(var n=e.split(/\r\n|\n|\r/),a=(0,r.Z)(n),s=[],u=0;u0){var u=document.createTextNode(o[s]);r.appendChild(u)}}else if("B"===a.nodeName){var l=e(a);l.style.fontWeight="bold",r.appendChild(l)}else if("I"===a.nodeName){var c=e(a);c.style.fontStyle="italic",r.appendChild(c)}else if("U"===a.nodeName){var d=e(a);d.style.textDecoration="underline",r.appendChild(d)}else if("FONT"===a.nodeName&&null!=a.color){var f=e(a);f.style.color=a.color,r.appendChild(f)}else{var p=e(a);r.appendChild(p)}}return r}(t)}},8057:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7253),i=n(2061),a=n(788);function o(e,t){for(var n,o,s,u,l,c=e.split(/\r\n|\n|\r/),d=(0,i.Z)(c),f=[],p=0;p{"use strict";n.d(t,{Z:()=>a});var r=n(6923);function i(e){var t=e.split(":");if((0,r.Z)(t[2])){var n=parseInt(t[0],10),i=parseInt(t[1],10),a=parseFloat(t[2].replace(",","."));if(isNaN(n)||isNaN(i)||isNaN(a))return;return 60*n*60+60*i+a}}function a(e,t){if(0===e.length)return null;var n,a,o=[];if((0,r.Z)(e[1])&&-1!==e[1].indexOf("--\x3e")){var s=e[1].split("--\x3e").map((function(e){return e.trim()}));n=s[0],a=s[1],o=e.slice(2,e.length)}if(!(0,r.Z)(n)||!(0,r.Z)(a)){var u=e[0].split("--\x3e").map((function(e){return e.trim()}));n=u[0],a=u[1],o=e.slice(1,e.length)}if(!(0,r.Z)(n)||!(0,r.Z)(a))return null;var l=i(n),c=i(a);return void 0===l||void 0===c?null:{start:l+t,end:c+t,payload:o}}},2967:(e,t,n)=>{"use strict";function r(e,t){if(!(e.parentNode instanceof Element))return[];return function e(n){var r=[];n.tagName.toLowerCase()===t.toLowerCase()&&r.push(n);var i=n.parentNode;return i instanceof Element&&r.push.apply(r,e(i)),r}(e.parentNode)}n.d(t,{Z:()=>r})},3791:(e,t,n)=>{"use strict";n.d(t,{U:()=>s,b:()=>u});var r=n(3274),i=n(7714),a=n(6923),o=n(9252);function s(e,t,n,o){for(var s={},u=e.slice(),l=0;l<=t.length-1;l++){var c=t[l];if(void 0!==c){var d=function(){var e=void 0,t=void 0;if(c.nodeType===Node.ELEMENT_NODE)for(var l=c,d=0;d<=l.attributes.length-1;d++){var f=l.attributes[d],p=f.name;if("style"===p)e=f.value;else if("region"===p)t=f.value;else{var h=p.substring(4);if((0,i.Z)(u,h)&&(s[h]=f.value,u.splice(d,1),0===u.length))return{v:s}}}if((0,a.Z)(e)){var v=(0,r.Z)(n,(function(t){return t.id===e}));if(void 0!==v)for(var m=0;m<=u.length-1;m++){var g=u[m];if(!(0,a.Z)(s[g])&&(0,a.Z)(v.style[g])){if(s[g]=v.style[g],u.splice(m,1),0===u.length)return{v:s};m--}}}if((0,a.Z)(t)){var y=(0,r.Z)(o,(function(e){return e.id===t}));if(void 0!==y)for(var _=0;_<=u.length-1;_++){var b=u[_];if(!(0,a.Z)(s[b])&&(0,a.Z)(y.style[b])){if(s[b]=y.style[b],u.splice(_,1),0===u.length)return{v:s};_--}}}}();if("object"==typeof d)return d.v}}return s}function u(e){if(e.nodeType!==Node.ELEMENT_NODE)return{};for(var t=e,n={},r=0;r<=t.attributes.length-1;r++){var i=t.attributes[r];if((0,o.Z)(i.name,"tts"))n[i.name.substring(4)]=i.value}return n}},6177:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(6923),i=n(5336);function a(e,t){var n=e.exec(t);if(null===n||""===n[0])return null;var r=Number(n[1]);isNaN(r)&&(r=0);var i=Number(n[2]);isNaN(i)&&(i=0);var a=Number(n[3]);isNaN(a)&&(a=0);var o=Number(n[4]);return isNaN(o)&&(o=0),o/1e3+a+60*i+3600*r}const o=function(e,t){return i.gu.test(e)?function(e,t){var n=i.gu.exec(t),r=Number(n[1]),a=Number(n[2]),o=Number(n[3]),s=Number(n[4]),u=Number(n[5]);isNaN(u)&&(u=0);return s+=u/e.subFrameRate,(o+=s/e.frameRate)+60*a+3600*r}(t,e):i.KO.test(e)?a(i.KO,e):i.wf.test(e)?a(i.wf,e):i.jb.test(e)?function(e,t){var n=i.jb.exec(t);return Number(n[1])/e.frameRate}(t,e):i.Du.test(e)?function(e,t){var n=i.Du.exec(t);return Number(n[1])/e.tickRate}(t,e):i.te.test(e)?a(i.te,e):void 0};function s(e,t){var n=e.getAttribute("begin"),i=e.getAttribute("dur"),a=e.getAttribute("end"),s=(0,r.Z)(n)?o(n,t):null,u=(0,r.Z)(i)?o(i,t):null,l=(0,r.Z)(a)?o(a,t):null;if(null==s||null==l&&null==u)throw new Error("Invalid text cue");return{start:s,end:null==l?s+u:l}}},7439:(e,t,n)=>{"use strict";n.d(t,{Z:()=>S});var r=n(5403);function i(e){return void 0===e.extent&&void 0===e.origin&&void 0===e.displayAlign&&void 0===e.display&&void 0===e.textAlign&&void 0===e.fontSize}function a(e){e.extent="70% 20%",e.fontSize="1c",e.origin="15% 80%",e.displayAlign="before",e.textAlign="center"}var o,s=n(6177);function u(e,t){(void 0===o&&(o=void 0!==e.classList&&"function"==typeof e.classList.add),o)?e.classList.add(t):(" "+e.className+" ").indexOf(" "+t+" ")<0&&(e.className+=" "+t)}var l=n(6923),c=n(8026),d=n(2967),f=n(3791),p=n(3887),h=n(5336);function v(e,t){return"-1px -1px "+t+" "+e+",1px -1px "+t+" "+e+",-1px 1px "+t+" "+e+",1px 1px "+t+" "+e}function m(e){var t;return null!=(t=h.Dq.exec(e))?"rgba("+String(parseInt(t[1],16))+","+String(parseInt(t[2],16))+","+String(parseInt(t[3],16))+","+String(parseInt(t[4],16)/255)+")":null!=(t=h.YU.exec(e))?"rgba("+String(parseInt(t[1]+t[1],16))+","+String(parseInt(t[2]+t[2],16))+","+String(parseInt(t[3]+t[3],16))+","+String(parseInt(t[4]+t[4],16)/255)+")":null!=(t=h.GK.exec(e))?"rgb("+String(+t[1])+","+String(+t[2])+","+String(+t[3])+")":null!=(t=h.ev.exec(e))?"rgba("+String(+t[1])+","+String(+t[2])+","+String(+t[3])+","+String(+t[4]/255)+")":e}var g=["color","direction","display","fontFamily","fontSize","fontStyle","fontWeight","textDecoration","textOutline","unicodeBidi","visibility","wrapOption"];function y(e,t,n){var r=t.color;(0,l.Z)(r)&&(e.style.color=m(r));var i=t.backgroundColor;(0,l.Z)(i)&&(e.style.backgroundColor=m(i));var a=t.textOutline;if((0,l.Z)(a)){var o=a.trim().replace(/\s+/g," ").split(" "),s=o.length;if(3===s){var c=m(o[0]),d=o[1];e.style.textShadow=v(c,d)}else if((0,l.Z)(r)&&1===s){var f=o[0];e.style.textShadow=v(r,f)}else if(2===s){var g=/^[#A-Z]/i.test(o[0]);if(g!==/^[0-9]/.test(o[0]))if(g){var y=m(o[0]),_=o[1];e.style.textShadow=v(y,_)}else if((0,l.Z)(r)){var b=o[0];e.style.textShadow=v(r,b)}}}var T=t.textDecoration;if((0,l.Z)(T))switch(T){case"noUnderline":case"noLineThrough":case"noOverline":e.style.textDecoration="none";break;case"lineThrough":e.style.textDecoration="line-through";break;default:e.style.textDecoration=T}var E=t.fontFamily;if((0,l.Z)(E))switch(E){case"proportionalSansSerif":e.style.fontFamily="Arial, Helvetica, Liberation Sans, sans-serif";break;case"monospaceSansSerif":case"sansSerif":e.style.fontFamily="sans-serif";break;case"monospaceSerif":case"default":e.style.fontFamily="Courier New, Liberation Mono, monospace";break;case"proportionalSerif":e.style.fontFamily="serif";break;default:e.style.fontFamily=E}var w=t.fontStyle;(0,l.Z)(w)&&(e.style.fontStyle=w);var S=t.fontWeight;(0,l.Z)(S)&&(e.style.fontWeight=S);var k=t.fontSize;(0,l.Z)(k)?function(e,t){var n=t.trim().split(" ");if(0!==n.length){var r=h.eT.exec(n[0]);null!==r&&("px"===r[2]||"%"===r[2]||"em"===r[2]?e.style.fontSize=r[1]+r[2]:"c"===r[2]?(e.style.position="relative",u(e,"proportional-style"),e.setAttribute("data-proportional-font-size",r[1])):p.Z.warn("TTML Parser: unhandled fontSize unit:",r[2]))}}(e,k):(u(e,"proportional-style"),e.setAttribute("data-proportional-font-size","1"));var A=t.direction;(0,l.Z)(A)&&(e.style.direction=A);var x=t.unicodeBidi;if((0,l.Z)(x))switch(x){case"bidiOverride":e.style.unicodeBidi="bidi-override";break;case"embed":e.style.unicodeBidi="embed";break;default:e.style.unicodeBidi="normal"}var Z=t.visibility;(0,l.Z)(Z)&&(e.style.visibility=Z),"none"===t.display&&(e.style.display="none");var I=t.wrapOption;e.style.whiteSpace="noWrap"===I?n?"nowrap":"pre":n?"normal":"pre-wrap"}function _(e,t){e.style.color="white",e.style.position="absolute";var n=t.extent;(0,l.Z)(n)&&function(e,t){var n=t.trim();if("auto"!==n){var r=n.split(" ");if(2===r.length){var i=h.eT.exec(r[0]),a=h.eT.exec(r[1]);null!==i&&null!==a&&("px"===i[2]||"%"===i[2]||"em"===i[2]?e.style.width=i[1]+i[2]:"c"===i[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-width",i[1])):p.Z.warn("TTML Parser: unhandled extent unit:",i[2]),"px"===a[2]||"%"===a[2]||"em"===a[2]?e.style.height=a[1]+a[2]:"c"===a[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-height",a[1])):p.Z.warn("TTML Parser: unhandled extent unit:",a[2]))}}}(e,n);var r=t.writingMode;(0,l.Z)(r);var i=t.overflow;e.style.overflow=(0,l.Z)(i)?i:"hidden";var a=t.padding;(0,l.Z)(a)&&function(e,t){var n=t.trim().split(" ");if(!(n.length<1)){var r=h.eT.exec(n[0]);if(null!==r){if("px"===r[2]||"%"===r[2]||"em"===r[2]){var i=r[1]+r[2];1===n.length?e.style.padding=i:2===n.length?(e.style.paddingTop=i,e.style.paddingBottom=i):e.style.paddingTop=i}else"c"===r[2]?(u(e,"proportional-style"),1===n.length?(e.setAttribute("data-proportional-padding-top",r[1]),e.setAttribute("data-proportional-padding-bottom",r[1]),e.setAttribute("data-proportional-padding-left",r[1]),e.setAttribute("data-proportional-padding-right",r[1])):2===n.length?(e.setAttribute("data-proportional-padding-top",r[1]),e.setAttribute("data-proportional-padding-bottom",r[1])):e.setAttribute("data-proportional-padding-top",r[1])):p.Z.warn("TTML Parser: unhandled padding unit:",r[2]);if(1!==n.length){var a=h.eT.exec(n[1]);if(null!==a){if("px"===a[2]||"%"===a[2]||"em"===a[2]){var o=a[1]+a[2];n.length<4?(e.style.paddingLeft=o,e.style.paddingRight=o):e.style.paddingRight=o}else"c"===a[2]?(u(e,"proportional-style"),n.length<4?(e.setAttribute("data-proportional-padding-left",a[1]),e.setAttribute("data-proportional-padding-right",a[1])):e.setAttribute("data-proportional-padding-right",a[1])):p.Z.warn("TTML Parser: unhandled padding unit:",a[2]);if(2!==n.length){var s=h.eT.exec(n[2]);if(null!==s){if("px"===s[2]||"%"===s[2]||"em"===s[2]){var l=s[1]+s[2];e.style.paddingBottom=l}else"c"===s[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-padding-bottom",s[1])):p.Z.warn("TTML Parser: unhandled padding unit:",s[2]);if(3!==n.length){var c=h.eT.exec(n[3]);if(null!==c)if("px"===c[2]||"%"===c[2]||"em"===c[2]){var d=c[1]+c[2];e.style.paddingLeft=d}else"c"===c[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-padding-left",c[1])):p.Z.warn("TTML Parser: unhandled padding unit:",c[2])}}}}}}}}(e,a);var o=t.origin;(0,l.Z)(o)&&function(e,t){var n=t.trim();if("auto"!==n){var r=n.split(" ");if(2===r.length){var i=h.eT.exec(r[0]),a=h.eT.exec(r[1]);null!==i&&null!==a&&("px"===i[2]||"%"===i[2]||"em"===i[2]?e.style.left=i[1]+i[2]:"c"===i[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-left",i[1])):p.Z.warn("TTML Parser: unhandled origin unit:",i[2]),"px"===a[2]||"%"===a[2]||"em"===a[2]?e.style.top=a[1]+a[2]:"c"===a[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-top",a[1])):p.Z.warn("TTML Parser: unhandled origin unit:",a[2]))}}}(e,o);var s=t.displayAlign;if((0,l.Z)(s))switch(e.style.display="flex",e.style.flexDirection="column",s){case"before":e.style.justifyContent="flex-start";break;case"center":e.style.justifyContent="center";break;case"after":e.style.justifyContent="flex-end"}var c=t.opacity;(0,l.Z)(c)&&(e.style.opacity=c);var d=t.visibility;(0,l.Z)(d)&&(e.style.visibility=d),"none"===t.display&&(e.style.display="none")}function b(e,t){e.style.margin="0px";var n=t.backgroundColor;(0,l.Z)(n)&&(e.style.backgroundColor=m(n));var r=t.lineHeight;(0,l.Z)(r)&&function(e,t){var n=t.trim();if("auto"!==n){var r=h.eT.exec(n[0]);null!==r&&("px"===r[2]||"%"===r[2]||"em"===r[2]?e.style.lineHeight=r[1]+r[2]:"c"===r[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-line-height",r[1])):p.Z.warn("TTML Parser: unhandled lineHeight unit:",r[2]))}}(e,r);var i=t.textAlign;if((0,l.Z)(i))switch(i){case"center":e.style.textAlign="center";break;case"left":case"start":e.style.textAlign="left";break;case"right":case"end":e.style.textAlign="right"}}function T(e,t,n){var r=document.createElement("span"),i=null===e.textContent?"":e.textContent;if(n){var a=i.trim();i=a=a.replace(/\s+/g," ")}return r.innerHTML=i,r.className="rxp-texttrack-span",y(r,t,n),r}function E(e,t,n,r,i,a){var o=a.cellResolution,s=a.shouldTrimWhiteSpace,u=(0,d.Z)(e,"div"),p=document.createElement("DIV");if(p.className="rxp-texttrack-region",p.setAttribute("data-resolution-columns",String(o.columns)),p.setAttribute("data-resolution-rows",String(o.rows)),_(p,i),null!==t){var h=(0,f.U)(["backgroundColor"],[].concat(u,[t]),r,n).bodyBackgroundColor;(0,l.Z)(h)&&(p.style.backgroundColor=m(h))}var v=document.createElement("p");v.className="rxp-texttrack-p",b(v,i);for(var y=function(e,t,n,r,i){return function e(r,i,a,o){for(var s=r.childNodes,u=[],d=0;d0){var y=p.getAttribute("xml:space"),_=(0,l.Z)(y)?"default"===y:o,b=(0,c.Z)({},i,(0,f.U)(g,[p],n,t));u.push.apply(u,e(p,b,[p].concat(a),_))}}return u}(e,(0,c.Z)({},r),[],i)}(e,n,r,i,s),E=0;E{"use strict";n.d(t,{Z:()=>f});var r=n(5403),i=n(7253),a=n(1988),o=n(6923),s=n(6177),u=n(5336),l={left:"start",center:"center",right:"end",start:"start",end:"end"},c={left:"line-left",center:"center",right:"line-right"};function d(e){var t=e.paragraph,n=e.timeOffset,r=e.paragraphStyle,d=e.ttParams,f=e.shouldTrimWhiteSpace;if(!t.hasAttribute("begin")&&!t.hasAttribute("end")&&/^\s*$/.test(null===t.textContent?"":t.textContent))return null;var p=(0,s.Z)(t,d),h=p.start,v=p.end,m=function(e,t){function n(e,t){for(var r=e.childNodes,i="",a=0;a|\u2265/g,">").replace(/\u200E/g,"‎").replace(/\u200F/g,"‏").replace(/\u00A0/g," ")}else if("br"===s.nodeName)i+="\n";else if("span"===s.nodeName&&s.nodeType===Node.ELEMENT_NODE&&s.childNodes.length>0){var c=s.getAttribute("xml:space");i+=n(s,(0,o.Z)(c)?"default"===c:t)}}return i}return n(e,t)}(t,f),g=(0,i.Z)(h+n,v+n,m);return null===g?null:((0,a.Z)(g)&&function(e,t){var n=t.extent;if((0,o.Z)(n)){var r=u._0.exec(n);null!=r&&(e.size=Number(r[1]))}switch(t.writingMode){case"tb":case"tblr":e.vertical="lr";break;case"tbrl":e.vertical="rl"}var i=t.origin;if((0,o.Z)(i))u._0.exec(i);var a=t.align;if((0,o.Z)(a)){e.align=a,"center"===a&&("center"!==e.align&&(e.align="middle"),e.position="auto");var s=c[a];e.positionAlign=void 0===s?"":s;var d=l[a];e.lineAlign=void 0===d?"":d}}(g,r),g)}const f=function(e,t){for(var n=(0,r.Z)(e,t),i=[],a=0;a{"use strict";n.d(t,{Z:()=>p});var r=n(3274),i=n(6923),a=n(8026),o=n(3887),s=/(\d+) (\d+)/;var u=n(2967),l=n(3791);var c=n(5138),d=n(7714);var f=["align","backgroundColor","color","direction","display","displayAlign","extent","fontFamily","fontSize","fontStyle","fontWeight","lineHeight","opacity","origin","overflow","padding","textAlign","textDecoration","textOutline","unicodeBidi","visibility","wrapOption","writingMode"];function p(e,t){var n=[],p=(new DOMParser).parseFromString(e,"text/xml");if(null!=p){var h=p.getElementsByTagName("tt")[0];if(void 0===h)throw new Error("invalid XML");for(var v=function(e){return e.getElementsByTagName("body")[0]}(h),m=function(e){return e.getElementsByTagName("style")}(h),g=function(e){return e.getElementsByTagName("region")}(h),y=function(e){return e.getElementsByTagName("p")}(h),_=function(e){var t=e.getAttribute("ttp:frameRate"),n=e.getAttribute("ttp:subFramRate"),r=e.getAttribute("ttp:tickRate"),a=e.getAttribute("ttp:frameRateMultiplier"),u=e.getAttribute("xml:space"),l=e.getAttribute("ttp:cellResolution"),c={columns:32,rows:15};if(null!==l){var d=s.exec(l);if(null===d||d.length<3)o.Z.warn("TTML Parser: Invalid cellResolution");else{var f=parseInt(d[1],10),p=parseInt(d[2],10);isNaN(f)||isNaN(p)?o.Z.warn("TTML Parser: Invalid cellResolution"):c={columns:f,rows:p}}}if((0,i.Z)(u)&&"default"!==u&&"preserve"!==u)throw new Error("Invalid spacing style");var h=Number(t);(isNaN(h)||h<=0)&&(h=30);var v=Number(n);(isNaN(v)||v<=0)&&(v=1);var m=Number(r);(isNaN(m)||m<=0)&&(m=void 0);var g=h,y=null!=v?v:1,_=null!==u?u:"default",b=void 0!==m?m:h*v;if(null!==a){var T=/^(\d+) (\d+)$/g.exec(a);null!==T&&(g=h*(Number(T[1])/Number(T[2])))}return{cellResolution:c,tickRate:b,frameRate:g,subFrameRate:y,spaceStyle:_}}(h),b=[],T=0;T<=m.length-1;T++){var E=m[T];if(E instanceof Element){var w=E.getAttribute("xml:id");if(null!==w){var S=E.getAttribute("style"),k=null===S?[]:S.split(" ");b.push({id:w,style:(0,l.b)(E),extendsStyles:k})}}}!function(e){var t=[];function n(r,i){t.push(i);for(var s=function(i){var s=r.extendsStyles[i],u=(0,c.Z)(e,(function(e){return e.id===s}));if(u<0)o.Z.warn("TTML Parser: unknown style inheritance: "+s);else{var l=e[u];(0,d.Z)(t,u)?o.Z.warn("TTML Parser: infinite style inheritance loop avoided"):n(l,u),r.style=(0,a.Z)({},l.style,r.style)}},u=0;u{"use strict";n.d(t,{YU:()=>f,Dq:()=>d,GK:()=>p,ev:()=>h,eT:()=>c,_0:()=>l,KO:()=>i,gu:()=>r,wf:()=>a,jb:()=>o,te:()=>u,Du:()=>s});var r=/^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/,i=/^(?:(\d{2,}):)?(\d{2}):(\d{2})$/,a=/^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{2,})$/,o=/^(\d*\.?\d*)f$/,s=/^(\d*\.?\d*)t$/,u=/^(?:(\d*\.?\d*)h)?(?:(\d*\.?\d*)m)?(?:(\d*\.?\d*)s)?(?:(\d*\.?\d*)ms)?$/,l=/^(\d{1,2}|100)% (\d{1,2}|100)%$/,c=/^((?:\+|\-)?\d*(?:\.\d+)?)(px|em|c|%|rh|rw)$/,d=/^#([0-9A-f]{2})([0-9A-f]{2})([0-9A-f]{2})([0-9A-f]{2})$/,f=/^#([0-9A-f])([0-9A-f])([0-9A-f])([0-9A-f])$/,p=/^rgb\( *(\d+) *, *(\d+) *, *(\d+) *\)/,h=/^rgba\( *(\d+) *, *(\d+) *, *(\d+) *, *(\d+) *\)/},1138:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(6923),i=n(360);function a(e,t){for(var n=[],a=t;a{"use strict";n.d(t,{Z:()=>x});var r=n(1138),i=n(6923),a=n(360);var o=n(9525),s={white:"#ffffff",lime:"#00ff00",cyan:"#00ffff",red:"#ff0000",yellow:"#ffff00",magenta:"#ff00ff",blue:"#0000ff",black:"#000000"};function u(e){var t=Object.keys(s).reduce((function(e,t){return e[t]="color: "+s[t]+";",e["bg_"+t]="background-color: "+s[t]+";",e}),{}),n="";return e.forEach((function(e){if(e.length>=2)for(var r=1;r0&&n.appendChild(document.createElement("br")),o[s].length>0){var u=document.createTextNode(o[s]);n.appendChild(u)}}else{var d=e.nodeName.toLowerCase().split("."),f=[];if(d.forEach((function(e){(0,i.Z)(t[e])&&f.push(t[e])})),0!==f.length){var p=document.createAttribute("style");f.forEach((function(e){p.value+=e}));var h=(0,l.Z)(r,a)?a:"span";(n=document.createElement(h)).setAttributeNode(p)}else{var v=(0,l.Z)(r,a)?a:"span";n=document.createElement(v)}for(var m=0;m/,"").replace(/<([u,i,b,c])(\..*?)?(?: .*?)?>(.*?)<\/\1>/g,"<$1$2>$3"),r=(new DOMParser).parseFromString(n,"text/html").body.childNodes,i=[],a=0;a{"use strict";n.d(t,{Z:()=>d});var r=n(1988),i=n(1138),a=n(9525),o=n(360),s=n(7714),u=n(6923);function l(e,t){if(!(0,u.Z)(e.vertical)||"rl"!==e.vertical&&"lr"!==e.vertical||(t.vertical=e.vertical),(0,u.Z)(e.line)){var n=/^(\d+(\.\d+)?)%(,([a-z]+))?/.exec(e.line);if(Array.isArray(n))t.line=Number(n[1]),t.snapToLines=!1,(0,s.Z)(["start","center","end"],n[4])&&(t.lineAlign=n[4]);else{var r=/^(-?\d+)(,([a-z]+))?/.exec(e.line);Array.isArray(r)&&(t.line=Number(r[1]),t.snapToLines=!0,(0,s.Z)(["start","center","end"],r[3])&&(t.lineAlign=r[3]))}}if((0,u.Z)(e.position)){var i=/^([\d\.]+)%(?:,(line-left|line-right|center))?$/.exec(e.position);if(Array.isArray(i)&&i.length>=2){var a=parseInt(i[1],10);isNaN(a)||(t.position=a,void 0!==i[2]&&(t.positionAlign=i[2]))}}(0,u.Z)(e.size)&&(t.size=e.size),"string"==typeof e.align&&(0,s.Z)(["start","center","end","left"],e.align)&&(t.align=e.align)}var c=n(7253);const d=function(e,t){var n=e.split(/\r\n|\n|\r/);if(!/^WEBVTT($| |\t)/.test(n[0]))throw new Error("Can't parse WebVTT: Invalid file.");for(var s,u,d,f,p=(0,o.yE)(n),h=(0,i.Z)(n,p),v=[],m=0;m{"use strict";n.d(t,{Z:()=>a});var r=n(6923);function i(e){var t=e.split(":").reverse();if((0,r.Z)(t[2])||(0,r.Z)(t[1])){var n=(0,r.Z)(t[2])?parseInt(t[2],10):0,i=parseInt(t[1],10),a=parseFloat(t[0].replace(",","."));if(isNaN(n)||isNaN(i)||isNaN(a))return;return 60*n*60+60*i+a}}function a(e,t){var n,r,a,o=/-->/;if(o.test(e[0]))n=e[0],r=e.slice(1,e.length);else{if(!o.test(e[1]))return null;a=e[0],n=e[1],r=e.slice(2,e.length)}var s=function(e){var t=/^([\d:.]+)[ |\t]+-->[ |\t]+([\d:.]+)[ |\t]*(.*)$/.exec(e);if(null===t)return null;var n=i(t[1]),r=i(t[2]);return null==n||null==r?null:{start:n,end:r,settings:t[3].split(/ |\t/).reduce((function(e,t){var n=t.split(":");return 2===n.length&&(e[n[0]]=n[1]),e}),{})}}(n);return null===s?null:{start:s.start+t,end:s.end+t,settings:s.settings,payload:r,header:a}}},360:(e,t,n)=>{"use strict";n.d(t,{yE:()=>i,tq:()=>o,JF:()=>a,$4:()=>s});var r=n(6923);function i(e){for(var t=0;t=0)return!0;var r=e[t+1];return void 0!==r&&r.indexOf("--\x3e")>=0}function s(e,t){for(var n=t+1;(0,r.Z)(e[n]);)n++;return n}},1459:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Ht});var r=n(7278),i=n(8170),a=n(7874),o=n(4597),s=n(5278);function u(e){var t=e.segment,n=e.url;return t.isInit||null===n?(0,i.of)({type:"data-created",value:{responseData:null}}):(0,o.ZP)({url:n,responseType:"arraybuffer",sendProgressEvents:!0})}function l(e){var t=e.response,n=e.content,r=n.segment,o=n.period,u=t.data,l=t.isChunked;if(n.segment.isInit)return(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,segmentProtections:[],initTimescale:void 0}});if(l)throw new Error("Image data should not be downloaded in chunks");var c=(0,s.Z)(r.timestampOffset,0);if(null===u||null===a.Z.imageParser)return(0,i.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:{duration:r.duration,time:r.time},chunkOffset:c,appendWindow:[o.start,o.end]}});var d=a.Z.imageParser(new Uint8Array(u)),f=d.thumbs;return(0,i.of)({type:"parsed-segment",value:{chunkData:{data:f,start:0,end:Number.MAX_VALUE,timescale:1,type:"bif"},chunkInfos:{time:0,duration:Number.MAX_VALUE,timescale:d.timescale},chunkOffset:c,appendWindow:[o.start,o.end]}})}var c=n(9795),d=n(5142),f=n(6008),p=n(5709),h=n(7746),v=n(1966),m=n(944),g=n(3887),y=n(3274),_=n(9829);function b(e){return 0===e.length?0:e.reduce((function(e,t){var n;return Math.min(null!==(n=t.attributes.availabilityTimeOffset)&&void 0!==n?n:0,e)}),1/0)}function T(e){var t=Date.parse(e)-performance.now();if(!isNaN(t))return t;g.Z.warn("DASH Parser: Invalid clock received: ",e)}function E(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,o=null;if(void 0!==r){var s=E(r);if(void 0===s)return;a=s}if(void 0!==i){var u=E(i);if(void 0===u)return;o=u}if(void 0!==r&&null===a||void 0!==i&&null===o)return void g.Z.info("Parser utils: found Period with no segment. ","Going to previous one to calculate last position");if(null!==o)return null!==a?Math.min(a,o):o;if(null!==a)return a}}}function S(e){for(var t=e.representations,n=null,r=0;r0){var o=K(a,"cenc:pssh"),s=o[0],u=o[1];null!==u&&(g.Z.warn(u.message),t.push(u)),null!==s&&n.push(s)}}}return[{cencPssh:n},t]}(e.childNodes),n=t[0],r=t[1];return[{children:n,attributes:function(e){for(var t={},n=0;n0&&(n=n.concat(c));break;case"SegmentList":var d=te(i),f=d[0],p=d[1];n=n.concat(p),t.segmentList=f;break;case"SegmentTemplate":var h=re(i),v=h[0],m=h[1];n=n.concat(m),t.segmentTemplate=v}}return[t,n]}(e.childNodes),n=t[0],r=t[1],i=function(e){for(var t={},n=[],r=W(t,n),i=0;i0&&(r=r.concat(u));break;case"ContentComponent":t.contentComponent=j(a);break;case"EssentialProperty":null==t.essentialProperties?t.essentialProperties=[H(a)]:t.essentialProperties.push(H(a));break;case"Representation":var l=ie(a),c=l[0],d=l[1];t.representations.push(c),d.length>0&&(r=r.concat(d));break;case"Role":null==t.roles?t.roles=[H(a)]:t.roles.push(H(a));break;case"SupplementalProperty":null==t.supplementalProperties?t.supplementalProperties=[H(a)]:t.supplementalProperties.push(H(a));break;case"SegmentBase":var f=Q(a),p=f[0],h=f[1];t.segmentBase=p,h.length>0&&(r=r.concat(h));break;case"SegmentList":var v=te(a),m=v[0],g=v[1];t.segmentList=m,g.length>0&&(r=r.concat(g));break;case"SegmentTemplate":var y=re(a),_=y[0],b=y[1];t.segmentTemplate=_,b.length>0&&(r=r.concat(b));break;case"ContentProtection":var T=q(a),E=T[0],w=T[1];w.length>0&&(r=r.concat(w)),void 0!==E&&n.push(E)}}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=W(t,n),i=0;i0&&(i=i.concat(_))}}return[{baseURLs:n,adaptations:r,streamEvents:a,segmentTemplate:t},i]}(e.childNodes),n=t[0],r=t[1],i=function(e){for(var t={},n=[],r=W(t,n),i=0;i=a?o:(new Array(a+1).join("0")+o).slice(-a)}}function be(e,t,n,r){return 0===e.length?void 0!==t?[Te(t,n,r)]:null:e.map((function(e){return Te((0,_.Z)(e,t),n,r)}))}function Te(e,t,n){return-1===e.indexOf("$")?e:e.replace(/\$\$/g,"$").replace(/\$RepresentationID\$/g,String(t)).replace(/\$Bandwidth(|\%0(\d+)d)\$/g,_e(void 0===n?0:n))}function Ee(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 _e(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 _e(e)(t,n,r)}))}}function we(e,t,n,r){for(var i,a,o=(0,ge.gT)(t,e),s=(0,ge.gT)(t+n,e),u=e.timeline,l=e.timescale,c=e.mediaURLs,d=e.startNumber,f=null!=d?d:void 0,p=[],h=u.length,v=u.length>0&&null!=u[0].duration?u[0].duration:0,m=0;m0?Math.floor(a/i):0),w=_+E*y;w=s)return p;null!=f&&(f+=T+1)}return p}function Se(e,t){if(t.timescale!==e.timescale){var n=e.timescale;e.timeline.push({start:t.time/t.timescale*n,duration:t.duration/t.timescale*n,repeatCount:void 0===t.count?0:t.count,range:t.range})}else e.timeline.push({start:t.time,duration:t.duration,repeatCount:void 0===t.count?0:t.count,range:t.range});return!0}var ke=function(){function e(e,t){var n,r,i=t.periodStart,a=t.periodEnd,o=t.representationBaseURLs,s=t.representationId,u=t.representationBitrate,l=null!==(n=e.timescale)&&void 0!==n?n:1,c=(null!=e.presentationTimeOffset?e.presentationTimeOffset:0)-i*l,d=be(o,void 0!==e.initialization?e.initialization.media:void 0,s,u),f=void 0!==e.initialization?e.initialization.range:void 0!==e.indexRange?[0,e.indexRange[0]-1]:void 0;this._index={indexRange:e.indexRange,indexTimeOffset:c,initialization:{mediaURLs:d,range:f},mediaURLs:be(o,e.media,s,u),startNumber:e.startNumber,timeline:null!==(r=e.timeline)&&void 0!==r?r:[],timescale:l},this._scaledPeriodEnd=null==a?void 0:(0,ge.gT)(a,this._index),this._isInitialized=this._index.timeline.length>0}var t=e.prototype;return t.getInitSegment=function(){return ye(this._index)},t.getSegments=function(e,t){return we(this._index,e,t,this._scaledPeriodEnd)},t.shouldRefresh=function(){return!1},t.getFirstPosition=function(){var e=this._index;return 0===e.timeline.length?null:(0,ge.zG)(e.timeline[0].start,e)},t.getLastPosition=function(){var e=this._index.timeline;if(0===e.length)return null;var t=e[e.length-1],n=(0,ge.jH)(t,null,this._scaledPeriodEnd);return(0,ge.zG)(n,this._index)},t.isSegmentStillAvailable=function(){return!0},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},t._addSegments=function(e){for(var t=0;t0&&(this._isInitialized=!0)},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){return!0},t.isInitialized=function(){return this._isInitialized},t._replace=function(e){this._index=e._index},t._update=function(){g.Z.error("Base RepresentationIndex: Cannot update a SegmentList")},e}(),Ae=function(){function e(e,t){var n,r=t.periodStart,i=t.representationBaseURLs,a=t.representationId,o=t.representationBitrate;this._periodStart=r;var s=null!=e.presentationTimeOffset?e.presentationTimeOffset:0,u=null!==(n=e.timescale)&&void 0!==n?n:1,l=s-r*u,c=e.list.map((function(e){return{mediaURLs:be(i,e.media,a,o),mediaRange:e.mediaRange}}));this._index={list:c,timescale:u,duration:e.duration,indexTimeOffset:l,indexRange:e.indexRange,initialization:null==e.initialization?void 0:{mediaURLs:be(i,e.initialization.media,a,o),range:e.initialization.range}}}var t=e.prototype;return t.getInitSegment=function(){return ye(this._index)},t.getSegments=function(e,t){for(var n=this._index,r=n.duration,i=n.list,a=n.timescale,o=r/a,s=e-this._periodStart,u=(0,ge.PZ)(s,t,a),l=u[0],c=u[1],d=Math.min(i.length-1,Math.floor(c/r)),f=[],p=Math.floor(l/r);p<=d;){var h=i[p].mediaRange,v=i[p].mediaURLs,m=p*o+this._periodStart,g={id:String(p),time:m,isInit:!1,range:h,duration:o,timescale:1,end:m+o,mediaURLs:v,timestampOffset:-n.indexTimeOffset/a};f.push(g),p++}return f},t.shouldRefresh=function(e,t){var n=this._index,r=n.timescale,i=n.duration,a=n.list,o=t*r,s=Math.floor(o/i);return s<0||s>=a.length},t.getFirstPosition=function(){return this._periodStart},t.getLastPosition=function(){var e=this._index,t=e.duration;return e.list.length*t/e.timescale+this._periodStart},t.isSegmentStillAvailable=function(){return!0},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){return!0},t.isInitialized=function(){return!0},t._replace=function(e){this._index=e._index},t._update=function(){g.Z.error("List RepresentationIndex: Cannot update a SegmentList")},e}(),xe=n(9362),Ze=n(8232),Ie=n(1091),Re=n(5505);function Me(e,t,n,r){var i=e.start,a=e.duration,o=e.repeatCount;return null==i&&(null==t?i=r:null!=t.duration&&(i=t.start+t.duration*(t.repeatCount+1))),null!=a&&!isNaN(a)||null==n||null==n.start||isNaN(n.start)||null==i||isNaN(i)||(a=n.start-i),null==i||isNaN(i)||null==a||isNaN(a)||null!=o&&isNaN(o)?(g.Z.warn('DASH: A "S" Element could not have been parsed.'),null):{start:i,duration:a,repeatCount:void 0===o?0:o}}function Ce(e){for(var t={},n=0;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 p=l.getAttribute("r"),h=null===p?null:parseInt(p,10);if(null!==h){if(Number.isNaN(h)||h<0)return null;if(h>0){var v=n-c;if(v%f==0&&v/f<=h)return{repeatNumberInPrevSegments:0,repeatNumberInNewElements:v/f,prevSegmentsIdx:0,newElementsIdx:u}}c+=f*(h+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===i)return g.Z.warn('DASH: Cannot perform "based" update. Common segment not found.'),Ne(e,n);var a=i.prevSegmentsIdx,o=i.newElementsIdx,s=i.repeatNumberInPrevSegments,u=i.repeatNumberInNewElements,l=t.length-a+o-1;if(l>=e.length)return g.Z.info('DASH: Cannot perform "based" update. New timeline too short'),Ne(e,n);var c=t.slice(a);if(s>0){var d=c[0];d.start+=d.duration*s,c[0].repeatCount-=s}if(u>0&&0!==o)return g.Z.info('DASH: Cannot perform "based" update. The new timeline has a different form.'),Ne(e,n);var f=c[c.length-1],p=Ce(e[l]),h=(null!==(r=p.repeatCount)&&void 0!==r?r:0)-u;if(p.duration!==f.duration||f.repeatCount>h)return g.Z.info('DASH: Cannot perform "based" update. The new timeline has a different form at the beginning.'),Ne(e,n);void 0!==p.repeatCount&&p.repeatCount>f.repeatCount&&(f.repeatCount=p.repeatCount);for(var v=[],m=[],y=l+1;y=this._scaledPeriodEnd},t.isInitialized=function(){return!0},t._refreshTimeline=function(){null===this._index.timeline&&(this._index.timeline=this._getTimeline());var e=this._manifestBoundsCalculator.estimateMinimumBound();if(null!=e){var t=(0,ge.gT)(e,this._index);(0,Ze.Z)(this._index.timeline,t)}},e.getIndexEnd=function(e,t){return e.length<=0?null:(0,ge.jH)(e[e.length-1],null,t)},t._getTimeline=function(){if(null===this._parseTimeline)return null!==this._index.timeline?this._index.timeline:(g.Z.error("DASH: Timeline already lazily parsed."),[]);var e,t=this._parseTimeline();return this._parseTimeline=null,null===this._unsafelyBaseOnPreviousIndex||t.lengthu?u-y:r,T=y+s,E=y+this._index.presentationTimeOffset,w=null===o?null:o.map(Ee(E,_)),S={id:String(_),number:_,time:T/a,end:(T+b)/a,duration:b/a,timescale:1,isInit:!1,scaledDuration:b/a,mediaURLs:w,timestampOffset:-n.indexTimeOffset/a};v.push(S),g++}return v},t.getFirstPosition=function(){var e=this._getFirstSegmentStart();return null==e?e:e/this._index.timescale+this._periodStart},t.getLastPosition=function(){var e=this._getLastSegmentStart();return null==e?e:(e+this._index.duration)/this._index.timescale+this._periodStart},t.shouldRefresh=function(){return!1},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},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(null==this._relativePeriodEnd)return!1;var e=this._index.timescale,t=this._getLastSegmentStart();return null!=t&&t+this._index.duration+1/60*e>=this._relativePeriodEnd*e},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._relativePeriodEnd=e._relativePeriodEnd,this._manifestBoundsCalculator=e._manifestBoundsCalculator},t._update=function(e){this._replace(e)},t._getFirstSegmentStart=function(){if(!this._isDynamic)return 0;if(0===this._relativePeriodEnd||null==this._relativePeriodEnd){var e=this._manifestBoundsCalculator.estimateMaximumBound();if(void 0!==e&&ethis._periodStart?(i-this._periodStart)*r:0;return Math.floor(a/n)*n}},t._getLastSegmentStart=function(){var e=this._index,t=e.duration,n=e.timescale;if(this._isDynamic){var r=this._manifestBoundsCalculator.estimateMaximumBound();if(void 0===r)return;var i=this._aggressiveMode?t/n:0;if(null!=this._relativePeriodEnd&&this._relativePeriodEndLe*n||0===c?d:(c-1)*t},e}();function Ue(e,t){var n=[];if(0===t.length)return e;if(0===e.length){for(var r=0;r0){var g=t.parentSegmentTemplates.slice(),y=e.children.segmentTemplate;void 0!==y&&g.push(y);var _=J.Z.apply(void 0,[{}].concat(g));h.availabilityTimeOffset=t.availabilityTimeOffset+b(e.children.baseURLs)+(null!==(r=_.availabilityTimeOffset)&&void 0!==r?r:0);var T=_.timelineParser;i=void 0!==T?new De(_,T,h):new Be(_,h)}else{var E=t.adaptation.children;if(void 0!==E.segmentBase){var w=E.segmentBase;i=new ke(w,h)}else if(void 0!==E.segmentList){var S=E.segmentList;i=new Ae(S,h)}else i=new Be({duration:Number.MAX_VALUE,timescale:1,startNumber:0,initialization:{media:""},media:""},h)}return i}(s,(0,J.Z)({},n,{unsafelyBaseOnPreviousRepresentation:l,adaptation:t})),d=void 0;null==s.attributes.bitrate?(g.Z.warn("DASH: No usable bitrate found in the Representation."),d=0):d=s.attributes.bitrate;var f={bitrate:d,index:c,id:u},p=void 0;if(null!=s.attributes.codecs?p=s.attributes.codecs:null!=t.attributes.codecs&&(p=t.attributes.codecs),null!=p&&(p="mp4a.40.02"===p?"mp4a.40.2":p,f.codecs=p),null!=s.attributes.frameRate?f.frameRate=s.attributes.frameRate:null!=t.attributes.frameRate&&(f.frameRate=t.attributes.frameRate),null!=s.attributes.height?f.height=s.attributes.height:null!=t.attributes.height&&(f.height=t.attributes.height),null!=s.attributes.mimeType?f.mimeType=s.attributes.mimeType:null!=t.attributes.mimeType&&(f.mimeType=t.attributes.mimeType),null!=s.attributes.width?f.width=s.attributes.width:null!=t.attributes.width&&(f.width=t.attributes.width),null!=t.children.contentProtections){var h=t.children.contentProtections.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&&e.keyIds.push({keyId:t.attributes.keyId,systemId:n}),void 0!==n)for(var r=t.children.cencPssh,i=0;i0||h.keyIds.length>0)&&(f.contentProtections=h)}a.push(f)},s=0;s0&&void 0!==l.video){var I,R=o.video[l.video];Z.unsafelyBaseOnPreviousAdaptation=null!==(r=null===(n=t.unsafelyBaseOnPreviousPeriod)||void 0===n?void 0:n.getAdaptation(R.id))&&void 0!==r?r:null;var M=Fe(m,d,Z);(I=R.representations).push.apply(I,M),k=R.id}else{var C=f.accessibility,P=void 0;void 0!==h&&h.some((function(e){return"dub"===e.value}))&&(P=!0);for(var O=!("text"!==w||null==C||!Ve(C))||void 0,D=!("audio"!==w||null==C||!ze(C))||void 0,L=!("video"!==w||null==C||!Ke(C))||void 0,B=He(d,{isAudioDescription:D,isClosedCaption:O,isSignInterpreted:L,type:w});(0,pe.Z)(u,B);)B+="-dup";k=B,u.push(B),Z.unsafelyBaseOnPreviousAdaptation=null!==(a=null===(i=t.unsafelyBaseOnPreviousPeriod)||void 0===i?void 0:i.getAdaptation(B))&&void 0!==a?a:null;var U={id:B,representations:Fe(m,d,Z),type:w};null!=d.attributes.language&&(U.language=d.attributes.language),null!=O&&(U.closedCaption=O),null!=D&&(U.audioDescription=D),!0===P&&(U.isDub=!0),!0===L&&(U.isSignInterpreted=!0);var F=o[w];if(void 0===F)o[w]=[U],v&&(l[w]=0);else{for(var z=null,V=function(e){var t=A[e],n=s[t];if(null!=n&&n.newID!==k&&(0,pe.Z)(n.adaptationSetSwitchingIDs,S)){var r,i=(0,y.Z)(F,(function(e){return e.id===t}));null!=i&&i.audioDescription===U.audioDescription&&i.closedCaption===U.closedCaption&&i.language===U.language&&(g.Z.info('DASH Parser: merging "switchable" AdaptationSets',S,t),(r=i.representations).push.apply(r,U.representations),z=i)}},K=0;KH)&&(F.splice($,1),F.splice(W,0,z),l[w]=W)}}else null===z&&F.push(U)}}null!=S&&null==s[S]&&(s[S]={newID:k,adaptationSetSwitchingIDs:A})}}}return o}(d.children.adaptations,k),x=null===(i=d.children.streamEvents)||void 0===i?void 0:i.map((function(e){var t,n=(null!==(t=e.eventPresentationTime)&&void 0!==t?t:0)/e.timescale+v;return{start:n,end:void 0!==e.duration?n+e.duration/e.timescale:void 0,data:e.data,id:e.id}})),Z={id:T,start:v,end:_,duration:m,adaptations:A,streamEvents:x};if(a.unshift(Z),!l.lastPositionIsKnown()){var I=function(e){for(var t=null,n=!0,r=(0,de.Z)(e).filter((function(e){return null!=e})),i=(0,le.Z)(r,(function(e){return e})),a=0;a=0;d--)c(d);if(t.isDynamic&&!l.lastPositionIsKnown()){var f=je(t,0);if(void 0!==f){var p=f[0],h=f[1];l.setLastPosition(p,h)}}return function(e){if(0===e.length)return[];for(var t=[e[0]],n=1;nr.start;)g.Z.warn("DASH: Updating overlapping Periods.",i,r),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}(a)}function je(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 g.Z.warn("DASH Parser: no clock synchronization mechanism found. Using the system clock instead."),[a-e.availabilityStartTime,performance.now()/1e3]}}var Ye=m.Z.DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0;function qe(e,t){var n=ue(e);return Xe(n[0],t,n[1])}function Xe(e,t,n,r){var i=e.children,a=e.attributes,o=new WeakMap;if(null==t.externalClockOffset){var s="dynamic"===a.type,u=(0,y.Z)(i.utcTimings,(function(e){return"urn:mpeg:dash:utc:direct:2014"===e.schemeIdUri&&null!=e.value})),l=null!=u&&null!=u.value?T(u.value):void 0,c=null==l||isNaN(l)?void 0:l;if(null!=c)t.externalClockOffset=c;else if(s&&!0!==r){var d=function(e){var t=e.children.utcTimings.filter((function(e){return"urn:mpeg:dash:utc:http-iso:2014"===e.schemeIdUri&&void 0!==e.value}));return t.length>0?t[0].value:void 0}(e);if(null!=d&&d.length>0)return{type:"needs-ressources",value:{ressources:[d],continue:function(r){if(1!==r.length)throw new Error("DASH parser: wrong number of loaded ressources.");return c=T(r[0].responseData),t.externalClockOffset=c,Xe(e,t,n,!0)}}}}}for(var f=[],p=0;p=0&&(o=0===c.minimumUpdatePeriod?Ye:c.minimumUpdatePeriod);var x=function(e){if(0===e.length)throw new Error("DASH Parser: no period available for a dynamic content");return[k(e),w(e)]}(E),Z=x[0],I=x[1],R=performance.now();if(d){var M;if(s=Z,A=null!=h?h:null,void 0!==I)M=I;else{var C=null!=p?p:0,N=t.externalClockOffset;if(void 0===N)g.Z.warn("DASH Parser: use system clock to define maximum position"),M=Date.now()/1e3-C;else M=(performance.now()+N)/1e3-C}u={isLinear:!0,value:M,time:R},null!==A&&void 0!==s&&M-s>A&&(A=M-s)}else{var P;if(s=void 0!==Z?Z:void 0!==(null===(i=E[0])||void 0===i?void 0:i.start)?E[0].start:0,void 0!==I)P=I;else if(void 0!==S)P=S;else if(void 0!==E[E.length-1]){var O=E[E.length-1];P=null!==(a=O.end)&&void 0!==a?a:void 0!==O.duration?O.start+O.duration:void 0}u={isLinear:!1,value:null!=P?P:1/0,time:R}}return{type:"done",value:{parsed:{availabilityStartTime:p,clockOffset:t.externalClockOffset,isDynamic:d,isLive:d,periods:E,suggestedPresentationDelay:c.suggestedPresentationDelay,transportType:"dash",timeBounds:{absoluteMinimumTime:s,timeshiftDepth:A,maximumTimeData:u},lifetime:o,uris:null==t.url?l.locations:[t.url].concat(l.locations)},warnings:n}}}(e,t,n,o):{type:"needs-ressources",value:{ressources:f.map((function(e){return e.ressource})),continue:function(r){if(r.length!==f.length)throw new Error("DASH parser: wrong number of loaded ressources.");for(var a=r.length-1;a>=0;a--){var s,u=f[a].index,l=r[a],c=l.responseData,d=l.receivedTime,p=l.sendingTime,h=l.url,v=""+c+"",m=(new DOMParser).parseFromString(v,"text/xml");if(null==m||0===m.children.length)throw new Error("DASH parser: Invalid external ressources");for(var g=m.children[0].children,y=[],_=0;_0&&n.push.apply(n,E)}(s=i.periods).splice.apply(s,[u,1].concat(y))}return Xe(e,t,n)}}}}const Qe=function(e,t){var n=e.documentElement;if(null==n||"MPD"!==n.nodeName)throw new Error("DASH Parser: document root should be MPD");return qe(n,t)};var Je=n(7445);function et(e){var t=e.aggressiveMode,n=e.referenceDateTime,r=void 0!==e.serverSyncInfos?e.serverSyncInfos.serverTimestamp-e.serverSyncInfos.clientTime:void 0;return function(a){var s,u=a.response,l=a.scheduleRequest,m=a.externalClockOffset,g=a.url,y=null!==(s=u.url)&&void 0!==s?s:g,_="string"==typeof u.responseData?(new DOMParser).parseFromString(u.responseData,"text/xml"):u.responseData,b=null!=r?r:m,T=a.unsafeMode?a.previousManifest:null;return function t(n){if("done"===n.type){var r=n.value,a=r.warnings,s=r.parsed,u=a.map((function(e){return{type:"warning",value:e}})),m=new v.ZP(s,e);return(0,c.z)(i.of.apply(void 0,u),(0,Je.Z)(m,y))}var g=n.value,_=g.ressources,b=g.continue,T=_.map((function(e){return l((function(){return function(e){return(0,o.ZP)({url:e,responseType:"text"}).pipe((0,f.h)((function(e){return"data-loaded"===e.type})),(0,p.U)((function(e){return e.value})))}(e)}))}));return(0,d.aj)(T).pipe((0,h.zg)((function(e){for(var n=[],r=0;r=300)return g.Z.warn("Fetch: Request HTTP Error",e),void n.error(new ot.Z(e.url,e.status,st.br.ERROR_HTTP_CODE));if(!(0,ut.Z)(e.body)){var t=e.headers.get("Content-Length"),r=(0,ut.Z)(t)||isNaN(+t)?void 0:+t,i=e.body.getReader(),s=0;return u()}function u(){return l.apply(this,arguments)}function l(){return(l=at()(rt().mark((function t(){var l,c,d,f,p;return rt().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,i.read();case 2:if((l=t.sent).done||(0,ut.Z)(l.value)){t.next=11;break}return s+=l.value.byteLength,c=performance.now(),d={type:"data-chunk",value:{url:e.url,currentTime:c,duration:c-o,sendingTime:o,chunkSize:l.value.byteLength,chunk:l.value.buffer,size:s,totalSize:r}},n.next(d),t.abrupt("return",u());case 11:l.done&&(f=performance.now(),p=f-o,a=!0,n.next({type:"data-complete",value:{duration:p,receivedTime:f,sendingTime:o,size:s,status:e.status,url:e.url}}),n.complete());case 12:case"end":return t.stop()}}),t)})))).apply(this,arguments)}n.error(new ot.Z(e.url,e.status,st.br.PARSE_ERROR))})).catch((function(t){if(r)g.Z.debug("Fetch: Request aborted.");else{if(i)return g.Z.warn("Fetch: Request timeouted."),void n.error(new ot.Z(e.url,0,st.br.TIMEOUT));g.Z.warn("Fetch: Request Error",t instanceof Error?t.toString():""),n.error(new ot.Z(e.url,0,st.br.ERROR_EVENT))}})),function(){r=!0,u()}}))};var ht=n(8806),vt=n(281);function mt(e){return"video/webm"===e.mimeType||"audio/webm"===e.mimeType}var gt=n(3068),yt=n(4460);function _t(e){return function(t){return e(t).pipe((0,gt.b)((function(e){"data-loaded"!==e.type&&"data-chunk"!==e.type||null===e.value.responseData||"string"==typeof e.value.responseData||mt(t.representation)||(0,yt.Z)(new Uint8Array(e.value.responseData),t.segment.isInit)})))}}var bt=n(6968);function Tt(e,t){var n=t.segment;if(void 0===n.range)return(0,o.ZP)({url:e,responseType:"arraybuffer",sendProgressEvents:!0});if(void 0===n.indexRange)return(0,o.ZP)({url:e,headers:{Range:(0,vt.Z)(n.range)},responseType:"arraybuffer",sendProgressEvents:!0});if(n.range[1]+1===n.indexRange[0])return(0,o.ZP)({url:e,headers:{Range:(0,vt.Z)([n.range[0],n.indexRange[1]])},responseType:"arraybuffer",sendProgressEvents:!0});var r=(0,o.ZP)({url:e,headers:{Range:(0,vt.Z)(n.range)},responseType:"arraybuffer",sendProgressEvents:!1}),i=(0,o.ZP)({url:e,headers:{Range:(0,vt.Z)(n.indexRange)},responseType:"arraybuffer",sendProgressEvents:!1});return(0,d.aj)([r,i]).pipe((0,p.U)((function(t){var n=t[0],r=t[1],i=(0,bt.zo)(new Uint8Array(n.value.responseData),new Uint8Array(r.value.responseData)),a=Math.min(n.value.sendingTime,r.value.sendingTime),o=Math.max(n.value.receivedTime,r.value.receivedTime);return{type:"data-loaded",value:{url:e,responseData:i,size:n.value.size+r.value.size,duration:o-a,sendingTime:a,receivedTime:o}}})))}var Et=n(2807),wt=n(8766);function St(e,t){var n=t.segment,r=void 0!==n.range?{Range:(0,vt.Z)(n.range)}:void 0;return pt({url:e,headers:r}).pipe((0,Et.R)((function(e,t){if("data-complete"===t.type)return null!==e.partialChunk&&g.Z.warn("DASH Pipelines: remaining chunk does not belong to any segment"),{event:t,completeChunks:[],partialChunk:null};var n=new Uint8Array(t.value.chunk),r=function(e){for(var t=0,n=[];te.length)return[n,r];var o=(0,wt.Z)(r,1835295092);if(o<0)return[n,r];var s=t+o+(0,bt.pX)(e,o+t);if(s>e.length)return[n,r];var u=Math.max(a,s),l=e.subarray(t,u);n.push(l),t=u}return[n,null]}(null!==e.partialChunk?(0,bt.zo)(e.partialChunk,n):n);return{event:t,completeChunks:r[0],partialChunk:r[1]}}),{event:null,completeChunks:[],partialChunk:null}),(0,h.zg)((function(e){for(var t=[],n=0;n0)for(var p=0;p=Math.pow(2,8-n))return n}function Pt(e,t){var n=Nt(e,t);if(null==n)return g.Z.warn("webm: unrepresentable length"),null;if(t+n>e.length)return g.Z.warn("webm: impossible length"),null;for(var r=0,i=0;ie.length)return g.Z.warn("webm: impossible length"),null;for(var r=(e[t]&(1<<8-n)-1)*Math.pow(2,8*(n-1)),i=1;i0){var b=y[y.length-1];Array.isArray(b.range)&&(b.range[1]=1/0)}u.index instanceof ke&&null!==y&&y.length>0&&u.index._addSegments(y);var T=v?Mt(h,0):(0,At.LD)(h),E=(0,ut.Z)(T)?void 0:T;if(!v)for(var w=(0,xt.Z)(h),S=0;S0){var m=v[v.length-1];Array.isArray(m.range)&&(m.range[1]=1/0)}var g=(0,At.LD)(h);return u.index instanceof ke&&null!==v&&v.length>0&&u.index._addSegments(v),(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,segmentProtections:[],initTimescale:g}})}var y=Lt(h,p,l,a),_=zt(r,h,y,p),b=(0,s.Z)(l.timestampOffset,0);return(0,i.of)({type:"parsed-segment",value:{chunkData:_,chunkInfos:y,chunkOffset:b,appendWindow:[o.start,o.end]}})}({response:{data:f,isChunked:p},content:r,initTimescale:a},t):function(e){var t=e.response,n=e.content,r=n.period,a=n.segment,o=a.timestampOffset,s=void 0===o?0:o;if(a.isInit)return(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,segmentProtections:[],initTimescale:void 0}});var u,l=t.data,c=t.isChunked;if("string"!=typeof l){var d=l instanceof Uint8Array?l:new Uint8Array(l);u=(0,Y.uR)(d)}else u=l;var f=Vt(n,u,c);return(0,i.of)({type:"parsed-segment",value:{chunkData:f,chunkInfos:null,chunkOffset:s,appendWindow:[r.start,r.end]}})}({response:{data:f,isChunked:p},content:r})}}const Ht=function(e){var t=(0,r.Z)({customManifestLoader:e.manifestLoader}),n=et(e),a=function(e){var t=e.lowLatencyMode,n=e.segmentLoader;return!0!==e.checkMediaSegmentIntegrity?r:_t(r);function r(e){var r=e.url;if(null==r)return(0,i.of)({type:"data-created",value:{responseData:null}});if(t||void 0===n)return kt(r,e,t);var a={adaptation:e.adaptation,manifest:e.manifest,period:e.period,representation:e.representation,segment:e.segment,transport:"dash",url:r};return new tt.y((function(i){var o=!1,s=!1,u=n(a,{reject:function(e){void 0===e&&(e={}),s||(o=!0,i.error(e))},resolve:function(e){s||(o=!0,i.next({type:"data-loaded",value:{responseData:e.data,size:e.size,duration:e.duration}}),i.complete())},progress:function(e){s||i.next({type:"progress",value:{duration:e.duration,size:e.size,totalSize:e.totalSize}})},fallback:function(){s=!0,kt(r,e,t).subscribe(i)}});return function(){o||s||"function"!=typeof u||u()}}))}}(e),s=Bt(e);return{manifest:{loader:t,parser:n},audio:{loader:a,parser:s},video:{loader:a,parser:s},text:{loader:function(e){var t=e.lowLatencyMode;return!0!==e.checkMediaSegmentIntegrity?n:_t(n);function n(e){var n=e.segment.range,r=e.url;if(null===r)return(0,i.of)({type:"data-created",value:{responseData:null}});if(e.segment.isInit)return Tt(r,e);var a=Ut(e.representation);if(t&&a){if(ft())return St(r,e);(0,ht.Z)("DASH: Your browser does not have the fetch API. You will have a higher chance of rebuffering when playing close to the live edge")}var s=a?"arraybuffer":"text";return(0,o.ZP)({url:r,responseType:s,headers:Array.isArray(n)?{Range:(0,vt.Z)(n)}:null,sendProgressEvents:!0})}}(e),parser:Kt(e)},image:{loader:u,parser:l}}}},2339:(e,t,n)=>{"use strict";n.d(t,{Z:()=>be});var r=n(8170),i=n(5709),a=n(3068),o=n(7874),s=n(3887),u=n(1966),l=n(6490),c=n(6807),d=n(7714),f=n(811),p=n(6923),h=n(8026),v=n(9829),m=n(5278);function g(e){var t=[];e.periods.forEach((function(n){var r=n.id;if((0,d.Z)(t,r)){s.Z.warn("Two periods with the same ID found. Updating.");var i=r+"-dup";n.id=i,g(e),t.push(i)}else t.push(r);var a=n.adaptations,o=[];Object.keys(a).forEach((function(t){var n=a[t];void 0!==n&&n.forEach((function(t){var n=t.id;if((0,d.Z)(o,n)){s.Z.warn("Two adaptations with the same ID found. Updating.",n);var r=n+"-dup";t.id=r,g(e),o.push(r)}else o.push(n);var i=[];t.representations.forEach((function(t){var n=t.id;if((0,d.Z)(i,n)){s.Z.warn("Two representations with the same ID found. Updating.",n);var r=n+"-dup";t.id=r,g(e),i.push(r)}else i.push(n)}))}))}))}))}var y=n(9689),_=n(6968),b=n(3635);function T(e){return[{systemId:"edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",privateData:(0,_.zo)([8,1,18,16],e)}]}function E(e,t){if(void 0===t&&(t=T),null===e.firstElementChild||"ProtectionHeader"!==e.firstElementChild.nodeName)throw new Error("Protection should have ProtectionHeader child");var n=e.firstElementChild,r=(0,y.K)(null===n.textContent?"":n.textContent),i=function(e){var t=(0,_.qb)(e,8),n=(0,b.wV)(e.subarray(10,t+10)),r=(new DOMParser).parseFromString(n,"application/xml").querySelector("KID");if(null===r)throw new Error("Cannot parse PlayReady private data: invalid XML");var i=null===r.textContent?"":r.textContent,a=(0,b.wO)((0,y.K)(i));return(0,b.ci)(a).toLowerCase()}(r),a=(0,b.nr)(i),o=n.getAttribute("SystemID");return{keyId:a,keySystems:[{systemId:(null!==o?o:"").toLowerCase().replace(/\{|\}/g,""),privateData:r}].concat(t(a))}}var w=n(9362),S=n(8232),k=n(3911),A=n(1091),x=n(5505);function Z(e,t,n){var r=e.timeline,i=e.timescale,a=r[r.length-1],o=t.timescale===i?{time:t.time,duration:t.duration}:{time:t.time/t.timescale*i,duration:t.duration/t.timescale*i};return!(n.time===o.time)&&(o.time>=(0,k.jH)(a,null)&&(a.duration===o.duration?a.repeatCount++:e.timeline.push({duration:o.duration,start:o.time,repeatCount:0}),!0))}function I(e,t){return e.replace(/\{start time\}/g,String(t))}function R(e,t,n){var r=t-e;return r>0?Math.floor(r/n):0}function M(e,t){var n=e.repeatCount;if(null!=e.duration&&n<0){var r=void 0!==t?t.start:1/0;n=Math.ceil((r-e.start)/e.duration)-1}return n}var C=function(){function e(e,t){var n=t.aggressiveMode,r=t.isLive,i=t.segmentPrivateInfos,a=null==e.manifestReceivedTime?performance.now():e.manifestReceivedTime;if(this._index=e,this._indexValidityTime=a,this._initSegmentInfos={bitsPerSample:i.bitsPerSample,channels:i.channels,codecPrivateData:i.codecPrivateData,packetSize:i.packetSize,samplingRate:i.samplingRate,timescale:e.timescale,protection:i.protection},this._isAggressiveMode=n,this._isLive=r,0!==e.timeline.length){var o=e.timeline[e.timeline.length-1],s=(0,k.jH)(o,null);if(this._initialScaledLastPosition=s,e.isLive){var u=a/1e3*e.timescale;this._scaledLiveGap=u-s}}}var t=e.prototype;return t.getInitSegment=function(){return{id:"init",isInit:!0,privateInfos:{smoothInitSegment:this._initSegmentInfos},mediaURLs:null,time:0,end:0,duration:0,timescale:1}},t.getSegments=function(e,t){this._refreshTimeline();for(var n,r=function(e,t,n){var r=void 0===e.timescale||0===e.timescale?1:e.timescale;return{up:t*r,to:(t+n)*r}}(this._index,e,t),i=r.up,a=r.to,o=this._index,s=o.timeline,u=o.timescale,l=o.media,c=this._isAggressiveMode,d=[],f=s.length,p=null==this._scaledLiveGap?void 0:performance.now()/1e3*u-this._scaledLiveGap,h=0;h=a)return d;null!=n&&(n+=y+1)}return d},t.shouldRefresh=function(e,t){if(this._refreshTimeline(),!this._index.isLive)return!1;var n=this._index,r=n.timeline,i=n.timescale,a=r[r.length-1];if(void 0===a)return!1;var o=a.repeatCount,s=a.start+(o+1)*a.duration;return!(t*i=s||e*i>a.start+o*a.duration)},t.getFirstPosition=function(){this._refreshTimeline();var e=this._index;return 0===e.timeline.length?null:e.timeline[0].start/e.timescale},t.getLastPosition=function(){this._refreshTimeline();var e=this._index;if(null==this._scaledLiveGap){var t=e.timeline[e.timeline.length-1];return(0,k.jH)(t,null)/e.timescale}for(var n=e.timeline.length-1;n>=0;n--)for(var r=e.timeline[n],i=performance.now()/1e3*e.timescale,a=r.start,o=r.duration,s=r.repeatCount;s>=0;s--){var u=a+o*(s+1);if((this._isAggressiveMode?u-o:u)<=i-this._scaledLiveGap)return u/e.timescale}},t.checkDiscontinuity=function(e){return this._refreshTimeline(),(0,k._j)(this._index,e,void 0)},t.areSegmentsChronologicallyGenerated=function(){return!0},t.isSegmentStillAvailable=function(e){if(e.isInit)return!0;this._refreshTimeline();var t=this._index,n=t.timeline,r=t.timescale;return(0,A.Z)(e,n,r,0)},t.canBeOutOfSyncError=function(e){return!!this._isLive&&(e instanceof w.Z&&(e.isHttpError(404)||e.isHttpError(412)))},t._replace=function(e){var t=this._index.timeline,n=e._index.timeline,r=this._index.timescale,i=e._index.timescale;if(this._index=e._index,this._initialScaledLastPosition=e._initialScaledLastPosition,this._indexValidityTime=e._indexValidityTime,this._scaledLiveGap=e._scaledLiveGap,0!==t.length&&0!==n.length&&r===i){var a=t[t.length-1],o=n[n.length-1],u=(0,k.jH)(o,null);if(!((0,k.jH)(a,null)<=u))for(var l=0;lu){if(c.duration!==o.duration)return;var f=u-c.start;if(0===f)return s.Z.warn("Smooth Parser: a discontinuity detected in the previous manifest has been resolved."),void(this._index.timeline=this._index.timeline.concat(t.slice(l)));if(f<0||f%c.duration!=0)return;var p=f/c.duration-1,h=c.repeatCount-p;if(h<0)return;o.repeatCount+=h;var v=t.slice(l+1);return void(this._index.timeline=this._index.timeline.concat(v))}}}},t._update=function(e){(0,x.Z)(this._index.timeline,e._index.timeline),this._initialScaledLastPosition=e._initialScaledLastPosition,this._indexValidityTime=e._indexValidityTime,this._scaledLiveGap=e._scaledLiveGap},t.isFinished=function(){return!this._isLive},t.isInitialized=function(){return!0},t._addSegments=function(e,t){this._refreshTimeline();for(var n=0;n>3:2)?"mp4a.40.2":"mp4a.40."+n}(u,l);return{audiotag:void 0!==i?parseInt(i,10):i,bitrate:h,bitsPerSample:void 0!==a?parseInt(a,10):a,channels:void 0!==o?parseInt(o,10):o,codecPrivateData:u,codecs:v,customAttributes:n,mimeType:void 0!==l?D[l]:l,packetSize:void 0!==c?parseInt(c,10):c,samplingRate:void 0!==d?parseInt(d,10):d};case"video":var g=r("CodecPrivateData"),y=r("FourCC"),_=r("MaxWidth"),b=r("MaxHeight"),T=r("Bitrate"),E=void 0===T||isNaN(parseInt(T,10))?0:parseInt(T,10);if(void 0!==y&&void 0===D[y]||void 0===g)return s.Z.warn("Smooth parser: Unsupported video codec. Ignoring quality level."),null;var w=function(e){var t=/00000001\d7([0-9a-fA-F]{6})/.exec(e);return null!==t&&(0,p.Z)(t[1])?"avc1."+t[1]:"avc1.4D401E"}(g);return{bitrate:E,customAttributes:n,mimeType:void 0!==y?D[y]:y,codecPrivateData:g,codecs:w,width:void 0!==_?parseInt(_,10):void 0,height:void 0!==b?parseInt(b,10):void 0};case"text":var S=r("CodecPrivateData"),k=r("FourCC"),A=r("Bitrate");return{bitrate:void 0===A||isNaN(parseInt(A,10))?0:parseInt(A,10),customAttributes:n,mimeType:void 0!==k?D[k]:k,codecPrivateData:(0,m.Z)(S,"")};default:return s.Z.error("Smooth Parser: Unrecognized StreamIndex type: "+t),null}}return function(r,o,u){var l=(0,v.f)(null==o?"":o),c=r.documentElement;if(null==c||"SmoothStreamingMedia"!==c.nodeName)throw new Error("document root should be SmoothStreamingMedia");var m=c.getAttribute("MajorVersion"),y=c.getAttribute("MinorVersion");if(null===m||null===y||!/^[2]-[0-2]$/.test(m+"-"+y))throw new Error("Version should be 2.0, 2.1 or 2.2");var _,b,T=c.getAttribute("Timescale"),w=(0,p.Z)(T)?isNaN(+T)?1e7:+T:1e7,S=N(c,(function(t,n,r){switch(n){case"Protection":t.protections.push(E(r,e.keySystems));break;case"StreamIndex":t.adaptationNodes.push(r)}return t}),{adaptationNodes:[],protections:[]}),k=S.protections,A=S.adaptationNodes,x="boolean"==typeof(_=c.getAttribute("IsLive"))?_:"string"==typeof _&&"TRUE"===_.toUpperCase();if(x){var Z=c.getAttribute("DVRWindowLength");null==Z||isNaN(+Z)||0==+Z||(b=+Z/w)}var I,R,M,D,L,B,U=A.reduce((function(t,r){var i=function(t){var r=t.root,i=t.timescale,o=t.rootURL,u=t.protections,l=t.timeShiftBufferDepth,c=t.manifestReceivedTime,m=t.isLive,g=r.getAttribute("Timescale"),y=null===g||isNaN(+g)?i:+g,_=r.getAttribute("Type");if(null===_)throw new Error("StreamIndex without type.");(0,d.Z)(P,_)||s.Z.warn("Smooth Parser: Unrecognized adaptation type:",_);var b,T=_,E=r.getAttribute("Subtype"),w=r.getAttribute("Language"),S=r.getAttribute("Url"),k=null===S?"":S,A=N(r,(function(e,t,r){switch(t){case"QualityLevel":var i=a(r,T);if(null===i)return e;("video"!==T||i.bitrate>n)&&e.qualityLevels.push(i);break;case"c":e.cNodes.push(r)}return e}),{qualityLevels:[],cNodes:[]}),x=A.qualityLevels,Z=A.cNodes,I={timeline:(b=Z,b.reduce((function(e,t,n){var r=t.getAttribute("d"),i=t.getAttribute("t"),a=t.getAttribute("r"),o=null!==a?+a-1:0,s=null!==i?+i:void 0,u=null!==r?+r:void 0;if(0===n)s=void 0===s||isNaN(s)?0:s;else{var l=e[n-1];if(null==s||isNaN(s)){if(null==l.duration||isNaN(l.duration))throw new Error("Smooth: Invalid CNodes. Missing timestamp.");s=l.start+l.duration*(l.repeatCount+1)}}if(null==u||isNaN(u)){var c=b[n+1];if(void 0===c)return e;var d=c.getAttribute("t"),f=(0,p.Z)(d)?+d:null;if(null===f)throw new Error("Can't build index timeline from Smooth Manifest.");u=f-s}return e.push({duration:u,start:s,repeatCount:o}),e}),[])),timescale:y};(0,f.Z)(0!==x.length,"Adaptation should have at least one playable representation.");var R=T+((0,p.Z)(w)?"_"+w:""),M=x.map((function(t){var n,r,i,a,s=(0,v.Z)(o,k),d={timeline:I.timeline,timescale:I.timescale,media:(n=s,r=t.bitrate,i=t.customAttributes,n.replace(/\{bitrate\}/g,String(r)).replace(/{CustomAttributes}/g,i.length>0?i[0]:"")),isLive:m,timeShiftBufferDepth:l,manifestReceivedTime:c},f=(0,p.Z)(t.mimeType)?t.mimeType:O[T],g=t.codecs,y=R+"_"+(null!=T?T+"-":"")+(null!=f?f+"-":"")+(null!=g?g+"-":"")+String(t.bitrate),_=[];u.length>0&&(a=u[0],u.forEach((function(e){var t=e.keyId;e.keySystems.forEach((function(e){_.push({keyId:t,systemId:e.systemId})}))})));var b={bitsPerSample:t.bitsPerSample,channels:t.channels,codecPrivateData:t.codecPrivateData,packetSize:t.packetSize,samplingRate:t.samplingRate,protection:null!=a?{keyId:a.keyId,keySystems:a.keySystems}:void 0},E=null!=e.aggressiveMode&&e.aggressiveMode,w=new C(d,{aggressiveMode:E,isLive:m,segmentPrivateInfos:b}),S=(0,h.Z)({},t,{index:w,mimeType:f,codecs:g,id:y});return _.length>0&&(S.contentProtections={keyIds:_,initData:{}}),S}));if("ADVT"===E)return null;var D={id:R,type:T,representations:M,language:null==w?void 0:w};return"text"===T&&"DESC"===E&&(D.closedCaption=!0),D}({root:r,rootURL:l,timescale:w,protections:k,isLive:x,timeShiftBufferDepth:b,manifestReceivedTime:u});if(null===i)return t;var o=i.type,c=t[o];return void 0===c?t[o]=[i]:c.push(i),t}),{}),F=null,z=void 0!==U.video?U.video[0]:void 0,V=void 0!==U.audio?U.audio[0]:void 0;if(void 0!==z||void 0!==V){var K=[],H=[];if(void 0!==z){var W=z.representations[0];if(void 0!==W){var $=W.index.getFirstPosition(),G=W.index.getLastPosition();null!=$&&K.push($),null!=G&&H.push(G)}}if(void 0!==V){var j=V.representations[0];if(void 0!==j){var Y=j.index.getFirstPosition(),q=j.index.getLastPosition();null!=Y&&K.push(Y),null!=q&&H.push(q)}}K.length>0&&(L=Math.max.apply(Math,K)),H.length>0&&(B=Math.min.apply(Math,H))}var X=c.getAttribute("Duration"),Q=null!=X&&0!=+X?+X/w:void 0;x?(I=e.suggestedPresentationDelay,R=t,M=null!=L?L:R,D={isLinear:!0,value:null!=B?B:Date.now()/1e3-R,time:performance.now()},F=null!=b?b:null):(M=null!=L?L:0,D={isLinear:!1,value:void 0!==B?B:void 0!==Q?M+Q:1/0,time:performance.now()});var J=x?0:M,ee=x?void 0:D.value,te={availabilityStartTime:void 0===R?0:R,clockOffset:i,isLive:x,isDynamic:x,timeBounds:{absoluteMinimumTime:M,timeshiftDepth:F,maximumTimeData:D},periods:[{adaptations:U,duration:void 0!==ee?ee-J:Q,end:ee,id:"gen-smooth-period-0",start:J}],suggestedPresentationDelay:I,transportType:"smooth",uris:null==o?[]:[o]};return g(te),te}};var B=n(4597),U=n(8806),F=n(4460),z=n(7445),V=n(7278),K=n(4644),H=n(2297);function W(e,t,n,r,i){var a,o,u,l=[];if(i){var d=(0,c.XA)(e);null!==d?(u=function(e){var t=(0,H.nR)(e,3565190898,3392751253,2387879627,2655430559);if(void 0===t)return[];for(var n=[],r=t[0],i=t[4],a=0;a0)return e;var n=new Uint8Array(e.length+4);return n.set(e.subarray(0,t+8),0),n[t+3]=1|n[t+3],n.set([0,0,0,0],t+8),n.set(e.subarray(t+8,e.length),t+12),(0,K.J6)(n)}(l,s[1]-s[0]),f=ne(u,c,d,i,(0,H.nR)(a,2721664850,1520127764,2722393154,2086964724)),p=X("moof",[i,f]),h=(0,H.Qy)(p,1836019558),v=(0,H.Qy)(f,1953653094),m=(0,H.Qy)(d,1953658222);if(null===h||null===v||null===m)throw new Error("Smooth: Invalid moof, trun or traf generation");var g=h[1]-h[0]+i.length+(v[1]-v[0])+u.length+c.length+(m[1]-m[0])+8,y=n[2]-n[0],b=p.length-y,T=(0,H.Qy)(e,1835295092);if(null===T)throw new Error("Smooth: Invalid ISOBMFF given");if(!$.YM&&(0===b||b<=-8)){var E=T[1];return p.set((0,_.kh)(E),g),e.set(p,n[0]),b<=-8&&e.set(q("free",new Uint8Array(-b-8)),p.length),e}var w=T[1]+b;p.set((0,_.kh)(w),g);var S=new Uint8Array(e.length+b),k=e.subarray(0,n[0]),A=e.subarray(n[2],e.length);return S.set(k,0),S.set(p,k.length),S.set(A,k.length+p.length),S}var ie=n(4379),ae=n(281);function oe(e,t,n,r){var i=[e,t,n];return r.forEach((function(e){var t=function(e,t,n){void 0===t&&(t=new Uint8Array(0)),void 0===n&&(n=new Uint8Array(0));var r,i,a=e.replace(/-/g,"");if(32!==a.length)throw new Error("HSS: wrong system id length");var o=n.length;return o>0?(r=1,i=_.zo.apply(void 0,[(0,_.kh)(o)].concat(n))):(r=0,i=[]),q("pssh",(0,_.zo)([r,0,0,0],(0,b.nr)(a),i,(0,_.kh)(t.length),t))}(e.systemId,e.privateData,e.keyIds);i.push(t)})),X("moov",i)}function se(e,t,n,r,i,a,o){var s,u,l,c=X("stbl",[n,q("stts",new Uint8Array(8)),q("stsc",new Uint8Array(8)),q("stsz",new Uint8Array(12)),q("stco",new Uint8Array(8))]),d=X("dinf",[function(e){return q("dref",(0,_.zo)(7,[1],e))}(q("url ",new Uint8Array([0,0,0,1])))]),f=X("minf",[r,d,c]),p=function(e){var t,n;switch(e){case"video":t="vide",n="VideoHandler";break;case"audio":t="soun",n="SoundHandler";break;default:t="hint",n=""}return q("hdlr",(0,_.zo)(8,(0,b.tG)(t),12,(0,b.tG)(n),1))}(t),h=X("mdia",[function(e){return q("mdhd",(0,_.zo)(12,(0,_.kh)(e),8))}(e),p,f]),v=X("trak",[function(e,t,n){return q("tkhd",(0,_.zo)((0,_.kh)(7),8,(0,_.kh)(n),20,[1,0,0,0],[0,1,0,0],12,[0,1,0,0],12,[64,0,0,0],(0,_.XT)(e),2,(0,_.XT)(t),2))}(i,a,1),h]),m=X("mvex",[(s=1,q("trex",(0,_.zo)(4,(0,_.kh)(s),[0,0,0,1],12)))]),g=oe(function(e,t){return q("mvhd",(0,_.zo)(12,(0,_.kh)(e),4,[0,1],2,[1,0],10,[0,1],14,[0,1],14,[64,0,0,0],26,(0,_.XT)(t+1)))}(e,1),m,v,o),y=(u="isom",l=["isom","iso2","iso6","avc1","dash"],q("ftyp",_.zo.apply(void 0,[(0,b.tG)(u),[0,0,0,1]].concat(l.map(b.tG)))));return(0,_.zo)(y,g)}function ue(e,t,n,r,i,a,o,s,u){var l=void 0===u?[]:u,c=o.split("00000001"),d=c[1],f=c[2];if(void 0===d||void 0===f)throw new Error("Smooth: unsupported codec private data.");var p,h,v=function(e,t,n){var r=2===n?1:4===n?3:0,i=e[1],a=e[2],o=e[3];return q("avcC",(0,_.zo)([1,i,a,o,252|r,225],(0,_.XT)(e.length),e,[1],(0,_.XT)(t.length),t))}((0,b.nr)(d),(0,b.nr)(f),a);if(0===l.length||void 0===s){p=ee([function(e,t,n,r,i,a,o){return q("avc1",(0,_.zo)(6,(0,_.XT)(1),16,(0,_.XT)(e),(0,_.XT)(t),(0,_.XT)(n),2,(0,_.XT)(r),6,[0,1,i.length],(0,b.tG)(i),31-i.length,(0,_.XT)(a),[255,255],o))}(t,n,r,i,"AVC Coding",24,v)])}else{var m=X("schi",[te(1,8,s)]),g=Q("cenc",65536);p=ee([function(e,t,n,r,i,a,o,s){return q("encv",(0,_.zo)(6,(0,_.XT)(1),16,(0,_.XT)(e),(0,_.XT)(t),(0,_.XT)(n),2,(0,_.XT)(r),6,[0,1,i.length],(0,b.tG)(i),31-i.length,(0,_.XT)(a),[255,255],o,s))}(t,n,r,i,"AVC Coding",24,v,X("sinf",[J("avc1"),g,m]))])}return se(e,"video",p,((h=new Uint8Array(12))[3]=1,q("vmhd",h)),t,n,l)}var le=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];function ce(e,t,n,r,i,a,o,s){void 0===s&&(s=[]);var u,l,c,d=function(e,t){return q("esds",(0,_.zo)(4,[3,25],(0,_.XT)(e),[0,4,17,64,21],11,[5,2],(0,b.nr)(t),[6,1,2]))}(1,0===a.length?(u=i,l=t,c=((c=((c=(63&2)<<4)|31&le.indexOf(u))<<4)|31&l)<<3,(0,b.ci)((0,_.XT)(c))):a);return se(e,"audio",function(){if(0===s.length||void 0===o)return ee([function(e,t,n,r,i,a){return q("mp4a",(0,_.zo)(6,(0,_.XT)(e),8,(0,_.XT)(t),(0,_.XT)(n),2,(0,_.XT)(r),(0,_.XT)(i),2,a))}(1,t,n,r,i,d)]);var e=X("schi",[te(1,8,o)]),a=Q("cenc",65536),u=X("sinf",[J("mp4a"),a,e]);return ee([function(e,t,n,r,i,a,o){return q("enca",(0,_.zo)(6,(0,_.XT)(e),8,(0,_.XT)(t),(0,_.XT)(n),2,(0,_.XT)(r),(0,_.XT)(i),2,a,o))}(1,t,n,r,i,d,u)])}(),q("smhd",new Uint8Array(8)),0,0,s)}function de(e){var t,n=e.url,r=e.segment.range;return Array.isArray(r)&&(t={Range:(0,ae.Z)(r)}),(0,B.ZP)({url:n,responseType:"arraybuffer",headers:t,sendProgressEvents:!0})}const fe=function(e){return function(t){var n=t.segment,i=t.representation,a=t.adaptation,o=t.period,s=t.manifest,u=t.url;if(n.isInit){if(void 0===n.privateInfos||void 0===n.privateInfos.smoothInitSegment)throw new Error("Smooth: Invalid segment format");var l,c=n.privateInfos.smoothInitSegment,d=c.codecPrivateData,f=c.timescale,p=c.protection,h=void 0===p?{keyId:void 0,keySystems:void 0}:p;if(void 0===d)throw new Error("Smooth: no codec private data.");switch(a.type){case"video":var v=i.width,m=void 0===v?0:v,g=i.height;l=ue(f,m,void 0===g?0:g,72,72,4,d,h.keyId,h.keySystems);break;case"audio":var y=c.channels,_=void 0===y?0:y,b=c.bitsPerSample,T=void 0===b?0:b,E=c.packetSize,w=void 0===E?0:E,S=c.samplingRate;l=ce(f,_,T,w,void 0===S?0:S,d,h.keyId,h.keySystems);break;default:0,l=new Uint8Array(0)}return(0,r.of)({type:"data-created",value:{responseData:l}})}if(null===u)return(0,r.of)({type:"data-created",value:{responseData:null}});var k={adaptation:a,manifest:s,period:o,representation:i,segment:n,transport:"smooth",url:u};return"function"!=typeof e?de(k):new ie.y((function(t){var n=!1,r=!1,i=e(k,{reject:function(e){void 0===e&&(e={}),r||(n=!0,t.error(e))},resolve:function(e){r||(n=!0,t.next({type:"data-loaded",value:{responseData:e.data,size:e.size,duration:e.duration}}),t.complete())},fallback:function(){r=!0,de(k).subscribe(t)},progress:function(e){r||t.next({type:"progress",value:{duration:e.duration,size:e.size,totalSize:e.totalSize}})}});return function(){n||r||"function"!=typeof i||i()}}))}};var pe=/(\.isml?)(\?token=\S+)?$/,he=/\?token=(\S+)/;function ve(e,t){return(0,p.Z)(t)?e.replace(he,"?token="+t):e.replace(he,"")}function me(e){return pe.test(e)?((0,U.Z)("Giving a isml URL to loadVideo is deprecated. Please give the Manifest URL directly"),e.replace(pe,"$1/manifest$2")):e}var ge=/\.wsx?(\?token=\S+)?/;function ye(e,t,n){var r;s.Z.debug("Smooth Parser: update segments information.");for(var i=e.representations,a=0;a=0}const be=function(e){var t=L(e),n=fe(e.segmentLoader),d={customManifestLoader:e.manifestLoader},f={loader:function(t){return t.segment.isInit||!0!==e.checkMediaSegmentIntegrity?n(t):n(t).pipe((0,a.b)((function(e){"data-loaded"!==e.type&&"data-chunk"!==e.type||null===e.value.responseData||(0,F.Z)(new Uint8Array(e.value.responseData),t.segment.isInit)})))},parser:function(e){var t,n,i=e.content,a=e.response,o=e.initTimescale,s=i.segment,u=i.representation,c=i.adaptation,d=i.manifest,f=a.data,p=a.isChunked;if(null===f){if(s.isInit){var h=u.getProtectionsInitializationData();return(0,r.of)({type:"parsed-init-segment",value:{initializationData:null,segmentProtections:h,initTimescale:void 0}})}return(0,r.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:[void 0,void 0]}})}var v=f instanceof Uint8Array?f:new Uint8Array(f);if(s.isInit){var m=(0,l.Z)(v);if(m.length>0)for(var g=0;g0&&ye(c,S,s),(0,r.of)({type:"parsed-segment",value:{chunkData:A,chunkInfos:k,chunkOffset:0,appendWindow:[void 0,void 0]}})}};return{manifest:{resolver:function(e){var t,n=e.url;if(void 0===n)return(0,r.of)({url:void 0});ge.test(n)?((0,U.Z)("Giving WSX URL to loadVideo is deprecated. You should only give Manifest URLs."),t=(0,B.ZP)({url:ve(n,""),responseType:"document"}).pipe((0,i.U)((function(e){var t=e.value,n=t.responseData.getElementsByTagName("media")[0].getAttribute("src");if(null===n||0===n.length)throw new Error("Invalid ISML");return n})))):t=(0,r.of)(n);var a=function(e){var t=he.exec(e);if(null!==t){var n=t[1];if(void 0!==n)return n}return""}(n);return t.pipe((0,i.U)((function(e){return{url:ve(me(e),a)}})))},loader:(0,V.Z)(d),parser:function(n){var r=n.response,i=n.url,a=void 0===r.url?i:r.url,o="string"==typeof r.responseData?(new DOMParser).parseFromString(r.responseData,"text/xml"):r.responseData,s=r.receivedTime,l=t(o,a,s),c=new u.ZP(l,{representationFilter:e.representationFilter,supplementaryImageTracks:e.supplementaryImageTracks,supplementaryTextTracks:e.supplementaryTextTracks});return(0,z.Z)(c,a)}},audio:f,video:f,text:{loader:function(t){var n=t.segment,i=t.representation,o=t.url;if(n.isInit||null===o)return(0,r.of)({type:"data-created",value:{responseData:null}});var s=_e(i);return s&&!0===e.checkMediaSegmentIntegrity?(0,B.ZP)({url:o,responseType:"arraybuffer",sendProgressEvents:!0}).pipe((0,a.b)((function(e){"data-loaded"===e.type&&(0,F.Z)(new Uint8Array(e.value.responseData),n.isInit)}))):(0,B.ZP)({url:o,responseType:s?"arraybuffer":"text",sendProgressEvents:!0})},parser:function(e){var t,n,i=e.content,a=e.response,o=e.initTimescale,u=i.manifest,l=i.adaptation,d=i.representation,f=i.segment,p=l.language,h=_e(d),v=d.mimeType,m=void 0===v?"":v,g=d.codec,y=void 0===g?"":g,_=a.data,T=a.isChunked;if(f.isInit)return(0,r.of)({type:"parsed-init-segment",value:{initializationData:null,segmentProtections:[],initTimescale:void 0}});if(null===_)return(0,r.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:[void 0,void 0]}});var E,w,S,k,A=null;if(h){var x;x="string"==typeof _?(0,b.tG)(_):_ instanceof Uint8Array?_:new Uint8Array(_);var Z=void 0!==o?W(x,T,o,f,u.isLive):null;n=null==Z?void 0:Z.nextSegments,null===(A=null!==(t=null==Z?void 0:Z.chunkInfos)&&void 0!==t?t:null)?T?s.Z.warn("Smooth: Unavailable time data for current text track."):(E=f.time,w=f.end):(E=A.time,w=void 0!==A.duration?A.time+A.duration:f.end);var I=y.toLowerCase();if("application/ttml+xml+mp4"===m||"stpp"===I||"stpp.ttml.im1t"===I)k="ttml";else{if("wvtt"!==I)throw new Error("could not find a text-track parser for the type "+m);k="vtt"}var R=(0,c.Le)(x);S=null===R?"":(0,b.uR)(R)}else{var M;if(E=f.time,w=f.end,"string"!=typeof _){var C=_ instanceof Uint8Array?_:new Uint8Array(_);M=(0,b.uR)(C)}else M=_;switch(m){case"application/x-sami":case"application/smil":k="sami";break;case"application/ttml+xml":k="ttml";break;case"text/vtt":k="vtt"}if(void 0===k){if("srt"!==y.toLowerCase())throw new Error("could not find a text-track parser for the type "+m);k="srt"}S=M}null!==A&&Array.isArray(n)&&n.length>0&&ye(l,n,f);var N=null!=E?E:0;return(0,r.of)({type:"parsed-segment",value:{chunkData:{type:k,data:S,start:E,end:w,language:p},chunkInfos:A,chunkOffset:N,appendWindow:[void 0,void 0]}})}},image:{loader:function(e){var t=e.segment,n=e.url;return t.isInit||null===n?(0,r.of)({type:"data-created",value:{responseData:null}}):(0,B.ZP)({url:n,responseType:"arraybuffer",sendProgressEvents:!0})},parser:function(e){var t=e.response,n=e.content,i=t.data,a=t.isChunked;if(n.segment.isInit)return(0,r.of)({type:"parsed-init-segment",value:{initializationData:null,segmentProtections:[],initTimescale:void 0}});if(a)throw new Error("Image data should not be downloaded in chunks");if(null===i||null===o.Z.imageParser)return(0,r.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:[void 0,void 0]}});var s=o.Z.imageParser(new Uint8Array(i)),u=s.thumbs;return(0,r.of)({type:"parsed-segment",value:{chunkData:{data:u,start:0,end:Number.MAX_VALUE,timescale:1,type:"bif"},chunkInfos:{time:0,duration:Number.MAX_VALUE,timescale:s.timescale},chunkOffset:0,segmentProtections:[],appendWindow:[void 0,void 0]}})}}}}},281:(e,t,n)=>{"use strict";function r(e){var t=e[0],n=e[1];return n===1/0?"bytes="+t+"-":"bytes="+t+"-"+n}n.d(t,{Z:()=>r})},4460:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(5389),i=n(8766);function a(e,t){if(t){if((0,i.Z)(e,1718909296)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `ftyp` box");if((0,i.Z)(e,1836019574)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `moov` box")}else{if((0,i.Z)(e,1836019558)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `moof` box");if((0,i.Z)(e,1835295092)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `mdat` box")}}},8766:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(6968);function i(e,t){for(var n=e.length,i=0;i+8<=n;){var a=(0,r.pX)(e,i);if(0===a)a=n-i;else if(1===a){if(i+16>n)return-1;a=(0,r.pV)(e,i+8)}if(isNaN(a)||a<=0)return-1;if((0,r.pX)(e,i+4)===t)return i+a<=n?i:-1;i+=a}return-1}},7445:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(8170),i=n(9795);function a(e,t){var n=r.of.apply(void 0,e.parsingErrors.map((function(e){return{type:"warning",value:e}})));return(0,i.z)(n,(0,r.of)({type:"parsed",value:{manifest:e,url:t}}))}},7278:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(1946),i=n(4597),a=n(4379);function o(e){var t=e.url;if(void 0===t)throw new Error("Cannot perform HTTP(s) request. URL not known");return(0,i.ZP)({url:t,responseType:"text"})}function s(e){var t=e.customManifestLoader;return(0,r.Z)(t)?o:function(e,t){return function(n){return new a.y((function(r){var i=n.url,a=Date.now()-performance.now(),o=!1,s=!1,u=e(i,{reject:function(e){s||(o=!0,r.error(e))},resolve:function(e){if(!s){o=!0;var t=void 0!==e.receivingTime?e.receivingTime-a:void 0,n=void 0!==e.sendingTime?e.sendingTime-a:void 0;r.next({type:"data-loaded",value:{responseData:e.data,size:e.size,duration:e.duration,url:e.url,receivedTime:t,sendingTime:n}}),r.complete()}},fallback:function(){s=!0,t(n).subscribe(r)}});return function(){o||s||"function"!=typeof u||u()}}))}}(t,o)}},4791:(e,t,n)=>{"use strict";function r(e,t){if(e.length!==t.length)return!1;for(var n=e.length-1;n>=0;n--)if(e[n]!==t[n])return!1;return!0}n.d(t,{Z:()=>r})},3274:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof Array.prototype.find)return e.find(t,n);for(var r=e.length>>>0,i=0;ir})},5138:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof Array.prototype.findIndex)return e.findIndex(t,n);for(var r=e.length>>>0,i=0;ir})},7714:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof Array.prototype.includes)return e.includes(t,n);var r=e.length>>>0;if(0===r)return!1;for(var i,a,o=0|n,s=o>=0?Math.min(o,r-1):Math.max(r+o,0);sr})},811:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a,u:()=>o});var r=n(3801),i=n(1946);function a(e,t){if(!e)throw new r.Z(void 0===t?"invalid assertion":t)}function o(e,t,n){for(var r in void 0===n&&(n="object"),a(!(0,i.Z)(e),n+" should be an object"),t)t.hasOwnProperty(r)&&a(typeof e[r]===t[r],n+" should have property "+r+" as a "+t[r])}},8418:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(3801);function i(e){throw new r.Z("Unreachable path taken")}},9689:(e,t,n)=>{"use strict";n.d(t,{J:()=>s,K:()=>u});var r=n(3887),i=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/"],a=[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,62,255,255,255,63,52,53,54,55,56,57,58,59,60,61,255,255,255,0,255,255,255,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,255,255,255,255,255,255,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];function o(e){if(e>=a.length)throw new Error("Unable to parse base64 string.");var t=a[e];if(255===t)throw new Error("Unable to parse base64 string.");return t}function s(e){var t,n="",r=e.length;for(t=2;t>2],n+=i[(3&e[t-2])<<4|e[t-1]>>4],n+=i[(15&e[t-1])<<2|e[t]>>6],n+=i[63&e[t]];return t===r+1&&(n+=i[e[t-2]>>2],n+=i[(3&e[t-2])<<4],n+="=="),t===r&&(n+=i[e[t-2]>>2],n+=i[(3&e[t-2])<<4|e[t-1]>>4],n+=i[(15&e[t-1])<<2],n+="="),n}function u(e){var t=e.length%4,n=e;0!==t&&(r.Z.warn("base64ToBytes: base64 given miss padding"),n+=3===t?"=":2===t?"==":"===");var i=n.indexOf("=");if(-1!==i&&i>16,l[d+1]=a>>8&255,l[d+2]=255&a;return l.subarray(0,l.length-s)}},6968:(e,t,n)=>{"use strict";function r(){for(var e,t=arguments.length,n=-1,r=0;++n0&&(i.set(e,a),a+=e.length);return i}function i(e,t){return(e[t+0]<<8)+(e[t+1]<<0)}function a(e,t){return 65536*e[t+0]+256*e[t+1]+e[t+2]}function o(e,t){return 16777216*e[t+0]+65536*e[t+1]+256*e[t+2]+e[t+3]}function s(e,t){return 4294967296*(16777216*e[t+0]+65536*e[t+1]+256*e[t+2]+e[t+3])+16777216*e[t+4]+65536*e[t+5]+256*e[t+6]+e[t+7]}function u(e){return new Uint8Array([e>>>8&255,255&e])}function l(e){return new Uint8Array([e>>>24&255,e>>>16&255,e>>>8&255,255&e])}function c(e){var t=e%4294967296,n=(e-t)/4294967296;return new Uint8Array([n>>>24&255,n>>>16&255,n>>>8&255,255&n,t>>>24&255,t>>>16&255,t>>>8&255,255&t])}function d(e,t){return(e[t+0]<<0)+(e[t+1]<<8)}function f(e,t){return e[t+0]+256*e[t+1]+65536*e[t+2]+16777216*e[t+3]}function p(e){return new Uint8Array([255&e,e>>>8&255,e>>>16&255,e>>>24&255])}function h(e){return e instanceof Uint8Array?e:e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer)}n.d(t,{zo:()=>r,zK:()=>i,QI:()=>a,pX:()=>o,pV:()=>s,qb:()=>d,dN:()=>f,XT:()=>u,kh:()=>l,el:()=>c,O_:()=>p,_f:()=>h})},8117:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(4379),i=n(4072),a=n(8170),o=n(1946);const s=function(e){if(e instanceof r.y)return e;if(!(0,o.Z)(e)&&"function"==typeof e.subscribe){var t=e;return new r.y((function(e){var n=t.subscribe((function(t){e.next(t)}),(function(t){e.error(t)}),(function(){e.complete()}));return function(){(0,o.Z)(n)||"function"!=typeof n.dispose?(0,o.Z)(n)||"function"!=typeof n.unsubscribe||n.unsubscribe():n.dispose()}}))}return(0,o.Z)(e)||"function"!=typeof e.then?(0,a.of)(e):(0,i.D)(e)}},8025:(e,t,n)=>{"use strict";n.d(t,{Z:()=>g});var r=n(655),i=1,a=function(){return Promise.resolve()}(),o={};function s(e){return e in o&&(delete o[e],!0)}var u=function(e){var t=i++;return o[t]=!0,a.then((function(){return s(t)&&e()})),t},l=function(e){s(e)},c=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.scheduler=t,r.work=n,r}return r.ZT(t,e),t.prototype.requestAsyncId=function(t,n,r){return void 0===r&&(r=0),null!==r&&r>0?e.prototype.requestAsyncId.call(this,t,n,r):(t.actions.push(this),t.scheduled||(t.scheduled=u(t.flush.bind(t,null))))},t.prototype.recycleAsyncId=function(t,n,r){if(void 0===r&&(r=0),null!==r&&r>0||null===r&&this.delay>0)return e.prototype.recycleAsyncId.call(this,t,n,r);0===t.actions.length&&(l(n),t.scheduled=void 0)},t}(n(6114).o),d=new(function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype.flush=function(e){this.active=!0,this.scheduled=void 0;var t,n=this.actions,r=-1,i=n.length;e=e||n.shift();do{if(t=e.execute(e.state,e.delay))break}while(++r{"use strict";n.d(t,{Z:()=>o,R:()=>s});var r=n(4379),i=n(3887),a=n(1946),o=function(){function e(){this._listeners={}}var t=e.prototype;return t.addEventListener=function(e,t){var n=this._listeners[e];Array.isArray(n)?n.push(t):this._listeners[e]=[t]},t.removeEventListener=function(e,t){if((0,a.Z)(e))this._listeners={};else{var n=this._listeners[e];if(Array.isArray(n))if((0,a.Z)(t))delete this._listeners[e];else{var r=n.indexOf(t);-1!==r&&n.splice(r,1),0===n.length&&delete this._listeners[e]}}},t.trigger=function(e,t){var n=this._listeners[e];Array.isArray(n)&&n.slice().forEach((function(e){try{e(t)}catch(e){i.Z.error(e,e instanceof Error?e.stack:null)}}))},e}();function s(e,t){return new r.y((function(n){function r(e){n.next(e)}return e.addEventListener(t,r),function(){e.removeEventListener(t,r)}}))}},2793:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(1410),i=n(5709),a=n(6008);function o(e,t){return function(n){return(0,r.P)((function(){return n.pipe((0,i.U)(e),(0,a.h)((function(e){return e!==t})))}))}}},9592:(e,t,n)=>{"use strict";function r(e,t){return"function"==typeof Array.prototype.flatMap?e.flatMap(t):e.reduce((function(e,n){var r=t(n);return Array.isArray(r)?(e.push.apply(e,r),e):(e.push(r),e)}),[])}n.d(t,{Z:()=>r})},2572:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});function r(e){return e*(.3*(2*Math.random()-1)+1)}},2870:(e,t,n)=>{"use strict";function r(e){for(var t=0,n=0;nr})},908:(e,t,n)=>{"use strict";function r(){var e="",t=-1;return function(){return++t>=Number.MAX_SAFE_INTEGER&&(e+="0",t=0),e+String(t)}}n.d(t,{Z:()=>r})},6923:(e,t,n)=>{"use strict";function r(e){return"string"==typeof e&&e.length>0}n.d(t,{Z:()=>r})},1946:(e,t,n)=>{"use strict";function r(e){return null==e}n.d(t,{Z:()=>r})},7829:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>r});const r=n(5553).ZP},5553:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>c,iH:()=>l,Y1:()=>u});var r=n(6923),i=n(1946);const a={aa:"aar",ab:"abk",ae:"ave",af:"afr",ak:"aka",am:"amh",an:"arg",ar:"ara",as:"asm",av:"ava",ay:"aym",az:"aze",ba:"bak",be:"bel",bg:"bul",bi:"bis",bm:"bam",bn:"ben",bo:"bod",br:"bre",bs:"bos",ca:"cat",ce:"che",ch:"cha",co:"cos",cr:"cre",cs:"ces",cu:"chu",cv:"chv",cy:"cym",da:"dan",de:"deu",dv:"div",dz:"dzo",ee:"ewe",el:"ell",en:"eng",eo:"epo",es:"spa",et:"est",eu:"eus",fa:"fas",ff:"ful",fi:"fin",fj:"fij",fo:"fao",fr:"fra",fy:"fry",ga:"gle",gd:"gla",gl:"glg",gn:"grn",gu:"guj",gv:"glv",ha:"hau",he:"heb",hi:"hin",ho:"hmo",hr:"hrv",ht:"hat",hu:"hun",hy:"hye",hz:"her",ia:"ina",id:"ind",ie:"ile",ig:"ibo",ii:"iii",ik:"ipk",io:"ido",is:"isl",it:"ita",iu:"iku",ja:"jpn",jv:"jav",ka:"kat",kg:"kon",ki:"kik",kj:"kua",kk:"kaz",kl:"kal",km:"khm",kn:"kan",ko:"kor",kr:"kau",ks:"kas",ku:"kur",kv:"kom",kw:"cor",ky:"kir",la:"lat",lb:"ltz",lg:"lug",li:"lim",ln:"lin",lo:"lao",lt:"lit",lu:"lub",lv:"lav",mg:"mlg",mh:"mah",mi:"mri",mk:"mkd",ml:"mal",mn:"mon",mr:"mar",ms:"msa",mt:"mlt",my:"mya",na:"nau",nb:"nob",nd:"nde",ne:"nep",ng:"ndo",nl:"nld",nn:"nno",no:"nor",nr:"nbl",nv:"nav",ny:"nya",oc:"oci",oj:"oji",om:"orm",or:"ori",os:"oss",pa:"pan",pi:"pli",pl:"pol",ps:"pus",pt:"por",qu:"que",rm:"roh",rn:"run",ro:"ron",ru:"rus",rw:"kin",sa:"san",sc:"srd",sd:"snd",se:"sme",sg:"sag",si:"sin",sk:"slk",sl:"slv",sm:"smo",sn:"sna",so:"som",sq:"sqi",sr:"srp",ss:"ssw",st:"sot",su:"sun",sv:"swe",sw:"swa",ta:"tam",te:"tel",tg:"tgk",th:"tha",ti:"tir",tk:"tuk",tl:"tgl",tn:"tsn",to:"ton",tr:"tur",ts:"tso",tt:"tat",tw:"twi",ty:"tah",ug:"uig",uk:"ukr",ur:"urd",uz:"uzb",ve:"ven",vi:"vie",vo:"vol",wa:"wln",wo:"wol",xh:"xho",yi:"yid",yo:"yor",za:"zha",zh:"zho",zu:"zul"};const o={alb:"sqi",arm:"hye",baq:"eus",bur:"mya",chi:"zho",cze:"ces",dut:"nld",fre:"fra",geo:"kat",ger:"deu",gre:"ell",ice:"isl",mac:"mkd",mao:"mri",may:"msa",per:"fas",slo:"slk",rum:"ron",tib:"bod",wel:"cym"};function s(e){if((0,i.Z)(e)||""===e)return"";var t=function(e){var t;switch(e.length){case 2:t=a[e];break;case 3:t=o[e]}return t}((""+e).toLowerCase().split("-")[0]);return(0,r.Z)(t)?t:e}function u(e){if(!(0,i.Z)(e)){var t,n=!1;return"string"==typeof e?t=e:(t=e.language,!0===e.closedCaption&&(n=!0)),{language:t,closedCaption:n,normalized:s(t)}}return e}function l(e){if((0,i.Z)(e))return e;if("string"==typeof e)return{language:e,audioDescription:!1,normalized:s(e)};var t={language:e.language,audioDescription:!0===e.audioDescription,normalized:s(s(e.language))};return!0===e.isDub&&(t.isDub=!0),t}const c=s},8894:(e,t,n)=>{"use strict";function r(){}n.d(t,{Z:()=>r})},8026:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r="function"==typeof Object.assign?Object.assign:function(e){if(null==e)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(e),n=0;n<(arguments.length<=1?0:arguments.length-1);n++){var r=n+1<1||arguments.length<=n+1?void 0:arguments[n+1];for(var i in r)Object.prototype.hasOwnProperty.call(r,i)&&(t[i]=r[i])}return t}},1679:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r="function"==typeof Object.values?Object.values:function(e){return Object.keys(e).map((function(t){return e[t]}))}},9589:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(8555);const i="function"==typeof Promise?Promise:n.n(r)()},2829:(e,t,n)=>{"use strict";n.d(t,{JN:()=>c,uH:()=>b,F_:()=>p,L7:()=>m,XS:()=>f,DD:()=>v,rx:()=>d,at:()=>h,kR:()=>g,Ti:()=>s,A1:()=>o,tn:()=>_});function r(e,t){return Math.abs(e-t)<.016666666666666666}function i(e,t){return{start:Math.min(e.start,t.start),end:Math.max(e.end,t.end)}}function a(e,t){return e.end<=t.start}function o(e,t){for(var n=0;n=0;n--){var r=e.start(n);if(t>=r){var i=e.end(n);if(t=o?r.push({start:a,end:o}):n={start:a,end:o}}return{outerRanges:r,innerRange:n}}function h(e,t){var n=d(e,t);return null!==n?n.end-n.start:0}function v(e,t){var n=d(e,t);return null!==n?t-n.start:0}function m(e,t){var n=d(e,t);return null!==n?n.end-t:1/0}function g(e,t){if(t.start===t.end)return e;for(var n=t,r=0;r0)for(var o=0;o0)for(var s=0;sl&&n.push({start:l,end:a[c].start}),l=a[c].end;l{"use strict";n.d(t,{ZP:()=>l});var r=n(4379),i=n(944),a=n(9105),o=n(6923),s=n(1946),u=i.Z.DEFAULT_REQUEST_TIMEOUT;const l=function(e){var t={url:e.url,headers:e.headers,responseType:(0,s.Z)(e.responseType)?"json":e.responseType,timeout:(0,s.Z)(e.timeout)?u:e.timeout};return new r.y((function(n){var r=t.url,i=t.headers,u=t.responseType,l=t.timeout,c=new XMLHttpRequest;if(c.open("GET",r,!0),l>=0&&(c.timeout=l),c.responseType=u,"document"===c.responseType&&c.overrideMimeType("text/xml"),!(0,s.Z)(i)){var d=i;for(var f in d)d.hasOwnProperty(f)&&c.setRequestHeader(f,d[f])}var p=performance.now();return c.onerror=function(){n.error(new a.Z(r,c.status,"ERROR_EVENT",c))},c.ontimeout=function(){n.error(new a.Z(r,c.status,"TIMEOUT",c))},!0===e.sendProgressEvents&&(c.onprogress=function(e){var t=performance.now();n.next({type:"progress",value:{url:r,duration:t-p,sendingTime:p,currentTime:t,size:e.loaded,totalSize:e.total}})}),c.onload=function(e){if(4===c.readyState)if(c.status>=200&&c.status<300){var t,i=performance.now(),u=c.response instanceof ArrayBuffer?c.response.byteLength:e.total,l=c.status,d=c.responseType,f=(0,o.Z)(c.responseURL)?c.responseURL:r;if(t="json"===d?"object"==typeof c.response?c.response:function(e){try{return JSON.parse(e)}catch(e){return null}}(c.responseText):c.response,(0,s.Z)(t))return void n.error(new a.Z(r,c.status,"PARSE_ERROR",c));n.next({type:"data-loaded",value:{status:l,url:f,responseType:d,sendingTime:p,receivedTime:i,duration:i-p,size:u,responseData:t}}),n.complete()}else n.error(new a.Z(r,c.status,"ERROR_HTTP_CODE",c))},c.send(),function(){(0,s.Z)(c)||4===c.readyState||c.abort()}}))}},9829:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o,f:()=>s});var r=/^(?:[a-z]+:)?\/\//i,i=/\/\.{1,2}\//;function a(e){if(!i.test(e))return e;for(var t=[],n=e.split("/"),r=0,a=n.length;r=0&&t===n+1)return e}var i=e.indexOf("?");return i>=0&&i{"use strict";n.d(t,{Z:()=>i});var r=n(4944);function i(e,t){try{return e(t)}catch(e){return(0,r._)(e)}}},9252:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof String.prototype.startsWith)return e.startsWith(t,n);var r="number"==typeof n?Math.max(n,0):0;return e.substring(r,r+t.length)===t}n.d(t,{Z:()=>r})},3635:(e,t,n)=>{"use strict";n.d(t,{ci:()=>p,nr:()=>f,tG:()=>l,uR:()=>d,TZ:()=>s,wV:()=>u,wO:()=>h});var r=n(3887),i=n(811),a="object"==typeof window&&"function"==typeof window.TextDecoder,o="object"==typeof window&&"function"==typeof window.TextEncoder;function s(e){for(var t=new ArrayBuffer(2*e.length),n=new Uint8Array(t),r=0;r>8&255}return n}function u(e){if(a)try{return new TextDecoder("utf-16le").decode(e)}catch(e){r.Z.warn("Utils: could not use TextDecoder to parse UTF-16LE, fallbacking to another implementation",e)}for(var t="",n=0;n=t?n:new Array(t-n.length+1).join("0")+n}function d(e){if(a)try{return(new TextDecoder).decode(e)}catch(e){r.Z.warn("Utils: could not use TextDecoder to parse UTF-8, fallbacking to another implementation",e)}var t=e;239===t[0]&&187===t[1]&&191===t[2]&&(t=t.subarray(3));var n,i=function(e){for(var t="",n=0;n=256?"%u"+c(u,4):"%"+c(u,2)}}return decodeURIComponent(n)}function f(e){for(var t=e.length,n=new Uint8Array(t/2),r=0,i=0;r>>4).toString(16),n+=(15&e[r]).toString(16),t.length>0&&r{"use strict";n.d(t,{Z:()=>i});var r=n(1946);function i(){for(var e=0,t=arguments.length,n=new Array(t),i=0;i{"use strict";n.d(t,{Z:()=>a});var r=n(7714),i=[];function a(e){(0,r.Z)(i,e)||(console.warn(e),i.push(e))}},7473:e=>{"use strict";var t=function(e){if("function"!=typeof e)throw new TypeError(e+" is not a function");return e},n=function(e){var n,r,i=document.createTextNode(""),a=0;return new e((function(){var e;if(n)r&&(n=r.concat(n));else{if(!r)return;n=r}if(r=n,n=null,"function"==typeof r)return e=r,r=null,void e();for(i.data=a=++a%2;r;)e=r.shift(),r.length||(r=null),e()})).observe(i,{characterData:!0}),function(e){t(e),n?"function"==typeof n?n=[n,e]:n.push(e):(n=e,i.data=a=++a%2)}};e.exports=function(){if("object"==typeof process&&process&&"function"==typeof process.nextTick)return process.nextTick;if("function"==typeof queueMicrotask)return function(e){queueMicrotask(t(e))};if("object"==typeof document&&document){if("function"==typeof MutationObserver)return n(MutationObserver);if("function"==typeof WebKitMutationObserver)return n(WebKitMutationObserver)}return"function"==typeof setImmediate?function(e){setImmediate(t(e))}:"function"==typeof setTimeout||"object"==typeof setTimeout?function(e){setTimeout(t(e),0)}:null}()},8555:(e,t,n)=>{"use strict";var r,i="pending",a="settled",o="fulfilled",s="rejected",u=function(){},l=void 0!==n.g&&void 0!==n.g.process&&"function"==typeof n.g.process.emit,c="undefined"==typeof setImmediate?setTimeout:setImmediate,d=[];function f(){for(var e=0;e{var t=function(e){"use strict";var t,n=Object.prototype,r=n.hasOwnProperty,i="function"==typeof Symbol?Symbol:{},a=i.iterator||"@@iterator",o=i.asyncIterator||"@@asyncIterator",s=i.toStringTag||"@@toStringTag";function u(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{u({},"")}catch(e){u=function(e,t,n){return e[t]=n}}function l(e,t,n,r){var i=t&&t.prototype instanceof m?t:m,a=Object.create(i.prototype),o=new Z(r||[]);return a._invoke=function(e,t,n){var r=d;return function(i,a){if(r===p)throw new Error("Generator is already running");if(r===h){if("throw"===i)throw a;return R()}for(n.method=i,n.arg=a;;){var o=n.delegate;if(o){var s=k(o,n);if(s){if(s===v)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(r===d)throw r=h,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r=p;var u=c(e,t,n);if("normal"===u.type){if(r=n.done?h:f,u.arg===v)continue;return{value:u.arg,done:n.done}}"throw"===u.type&&(r=h,n.method="throw",n.arg=u.arg)}}}(e,n,o),a}function c(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}e.wrap=l;var d="suspendedStart",f="suspendedYield",p="executing",h="completed",v={};function m(){}function g(){}function y(){}var _={};_[a]=function(){return this};var b=Object.getPrototypeOf,T=b&&b(b(I([])));T&&T!==n&&r.call(T,a)&&(_=T);var E=y.prototype=m.prototype=Object.create(_);function w(e){["next","throw","return"].forEach((function(t){u(e,t,(function(e){return this._invoke(t,e)}))}))}function S(e,t){function n(i,a,o,s){var u=c(e[i],e,a);if("throw"!==u.type){var l=u.arg,d=l.value;return d&&"object"==typeof d&&r.call(d,"__await")?t.resolve(d.__await).then((function(e){n("next",e,o,s)}),(function(e){n("throw",e,o,s)})):t.resolve(d).then((function(e){l.value=e,o(l)}),(function(e){return n("throw",e,o,s)}))}s(u.arg)}var i;this._invoke=function(e,r){function a(){return new t((function(t,i){n(e,r,t,i)}))}return i=i?i.then(a,a):a()}}function k(e,n){var r=e.iterator[n.method];if(r===t){if(n.delegate=null,"throw"===n.method){if(e.iterator.return&&(n.method="return",n.arg=t,k(e,n),"throw"===n.method))return v;n.method="throw",n.arg=new TypeError("The iterator does not provide a 'throw' method")}return v}var i=c(r,e.iterator,n.arg);if("throw"===i.type)return n.method="throw",n.arg=i.arg,n.delegate=null,v;var a=i.arg;return a?a.done?(n[e.resultName]=a.value,n.next=e.nextLoc,"return"!==n.method&&(n.method="next",n.arg=t),n.delegate=null,v):a:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,v)}function A(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function x(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function Z(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(A,this),this.reset(!0)}function I(e){if(e){var n=e[a];if(n)return n.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var i=-1,o=function n(){for(;++i=0;--a){var o=this.tryEntries[a],s=o.completion;if("root"===o.tryLoc)return i("end");if(o.tryLoc<=this.prev){var u=r.call(o,"catchLoc"),l=r.call(o,"finallyLoc");if(u&&l){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),x(n),v}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var i=r.arg;x(n)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,n,r){return this.delegate={iterator:I(e),resultName:n,nextLoc:r},"next"===this.method&&(this.arg=t),v}},e}(e.exports);try{regeneratorRuntime=t}catch(e){Function("r","regeneratorRuntime = r")(t)}},2632:(e,t,n)=>{"use strict";n.d(t,{P:()=>s});var r,i=n(5631),a=n(8170),o=n(4944);r||(r={});var s=function(){function e(e,t,n){this.kind=e,this.value=t,this.error=n,this.hasValue="N"===e}return e.prototype.observe=function(e){switch(this.kind){case"N":return e.next&&e.next(this.value);case"E":return e.error&&e.error(this.error);case"C":return e.complete&&e.complete()}},e.prototype.do=function(e,t,n){switch(this.kind){case"N":return e&&e(this.value);case"E":return t&&t(this.error);case"C":return n&&n()}},e.prototype.accept=function(e,t,n){return e&&"function"==typeof e.next?this.observe(e):this.do(e,t,n)},e.prototype.toObservable=function(){switch(this.kind){case"N":return(0,a.of)(this.value);case"E":return(0,o._)(this.error);case"C":return(0,i.c)()}throw new Error("unexpected notification kind value")},e.createNext=function(t){return void 0!==t?new e("N",t):e.undefinedValueNotification},e.createError=function(t){return new e("E",void 0,t)},e.createComplete=function(){return e.completeNotification},e.completeNotification=new e("C"),e.undefinedValueNotification=new e("N",void 0),e}()},4379:(e,t,n)=>{"use strict";n.d(t,{y:()=>c});var r=n(979);var i=n(3142),a=n(2174);var o=n(5050),s=n(3608);function u(e){return 0===e.length?s.y:1===e.length?e[0]:function(t){return e.reduce((function(e,t){return t(e)}),t)}}var l=n(150),c=function(){function e(e){this._isScalar=!1,e&&(this._subscribe=e)}return e.prototype.lift=function(t){var n=new e;return n.source=this,n.operator=t,n},e.prototype.subscribe=function(e,t,n){var o=this.operator,s=function(e,t,n){if(e){if(e instanceof r.L)return e;if(e[i.b])return e[i.b]()}return e||t||n?new r.L(e,t,n):new r.L(a.c)}(e,t,n);if(o?s.add(o.call(s,this.source)):s.add(this.source||l.v.useDeprecatedSynchronousErrorHandling&&!s.syncErrorThrowable?this._subscribe(s):this._trySubscribe(s)),l.v.useDeprecatedSynchronousErrorHandling&&s.syncErrorThrowable&&(s.syncErrorThrowable=!1,s.syncErrorThrown))throw s.syncErrorValue;return s},e.prototype._trySubscribe=function(e){try{return this._subscribe(e)}catch(t){l.v.useDeprecatedSynchronousErrorHandling&&(e.syncErrorThrown=!0,e.syncErrorValue=t),!function(e){for(;e;){var t=e,n=t.closed,i=t.destination,a=t.isStopped;if(n||a)return!1;e=i&&i instanceof r.L?i:null}return!0}(e)?console.warn(t):e.error(t)}},e.prototype.forEach=function(e,t){var n=this;return new(t=d(t))((function(t,r){var i;i=n.subscribe((function(t){try{e(t)}catch(e){r(e),i&&i.unsubscribe()}}),r,t)}))},e.prototype._subscribe=function(e){var t=this.source;return t&&t.subscribe(e)},e.prototype[o.L]=function(){return this},e.prototype.pipe=function(){for(var e=[],t=0;t{"use strict";n.d(t,{c:()=>a});var r=n(150),i=n(1644),a={closed:!0,next:function(e){},error:function(e){if(r.v.useDeprecatedSynchronousErrorHandling)throw e;(0,i.z)(e)},complete:function(){}}},2039:(e,t,n)=>{"use strict";n.d(t,{L:()=>i});var r=n(655),i=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype.notifyNext=function(e,t,n,r,i){this.destination.next(t)},t.prototype.notifyError=function(e,t){this.destination.error(e)},t.prototype.notifyComplete=function(e){this.destination.complete()},t}(n(979).L)},2135:(e,t,n)=>{"use strict";n.d(t,{t:()=>h});var r=n(655),i=n(211),a=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.scheduler=t,r.work=n,r}return r.ZT(t,e),t.prototype.schedule=function(t,n){return void 0===n&&(n=0),n>0?e.prototype.schedule.call(this,t,n):(this.delay=n,this.state=t,this.scheduler.flush(this),this)},t.prototype.execute=function(t,n){return n>0||this.closed?e.prototype.execute.call(this,t,n):this._execute(t,n)},t.prototype.requestAsyncId=function(t,n,r){return void 0===r&&(r=0),null!==r&&r>0||null===r&&this.delay>0?e.prototype.requestAsyncId.call(this,t,n,r):t.flush(this)},t}(n(6114).o),o=new(function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t}(n(2980).v))(a),s=n(3884),u=n(979),l=n(2632);var c=function(e){function t(t,n,r){void 0===r&&(r=0);var i=e.call(this,t)||this;return i.scheduler=n,i.delay=r,i}return r.ZT(t,e),t.dispatch=function(e){var t=e.notification,n=e.destination;t.observe(n),this.unsubscribe()},t.prototype.scheduleMessage=function(e){this.destination.add(this.scheduler.schedule(t.dispatch,this.delay,new d(e,this.destination)))},t.prototype._next=function(e){this.scheduleMessage(l.P.createNext(e))},t.prototype._error=function(e){this.scheduleMessage(l.P.createError(e)),this.unsubscribe()},t.prototype._complete=function(){this.scheduleMessage(l.P.createComplete()),this.unsubscribe()},t}(u.L),d=function(){return function(e,t){this.notification=e,this.destination=t}}(),f=n(1016),p=n(8253),h=function(e){function t(t,n,r){void 0===t&&(t=Number.POSITIVE_INFINITY),void 0===n&&(n=Number.POSITIVE_INFINITY);var i=e.call(this)||this;return i.scheduler=r,i._events=[],i._infiniteTimeWindow=!1,i._bufferSize=t<1?1:t,i._windowTime=n<1?1:n,n===Number.POSITIVE_INFINITY?(i._infiniteTimeWindow=!0,i.next=i.nextInfiniteTimeWindow):i.next=i.nextTimeWindow,i}return r.ZT(t,e),t.prototype.nextInfiniteTimeWindow=function(t){if(!this.isStopped){var n=this._events;n.push(t),n.length>this._bufferSize&&n.shift()}e.prototype.next.call(this,t)},t.prototype.nextTimeWindow=function(t){this.isStopped||(this._events.push(new v(this._getNow(),t)),this._trimBufferThenGetEvents()),e.prototype.next.call(this,t)},t.prototype._subscribe=function(e){var t,n=this._infiniteTimeWindow,r=n?this._events:this._trimBufferThenGetEvents(),i=this.scheduler,a=r.length;if(this.closed)throw new f.N;if(this.isStopped||this.hasError?t=s.w.EMPTY:(this.observers.push(e),t=new p.W(this,e)),i&&e.add(e=new c(e,i)),n)for(var o=0;ot&&(a=Math.max(a,i-t)),a>0&&r.splice(0,a),r},t}(i.xQ),v=function(){return function(e,t){this.time=e,this.value=t}}()},211:(e,t,n)=>{"use strict";n.d(t,{Yc:()=>c,xQ:()=>d});var r=n(655),i=n(4379),a=n(979),o=n(3884),s=n(1016),u=n(8253),l=n(3142),c=function(e){function t(t){var n=e.call(this,t)||this;return n.destination=t,n}return r.ZT(t,e),t}(a.L),d=function(e){function t(){var t=e.call(this)||this;return t.observers=[],t.closed=!1,t.isStopped=!1,t.hasError=!1,t.thrownError=null,t}return r.ZT(t,e),t.prototype[l.b]=function(){return new c(this)},t.prototype.lift=function(e){var t=new f(this,this);return t.operator=e,t},t.prototype.next=function(e){if(this.closed)throw new s.N;if(!this.isStopped)for(var t=this.observers,n=t.length,r=t.slice(),i=0;i{"use strict";n.d(t,{W:()=>i});var r=n(655),i=function(e){function t(t,n){var r=e.call(this)||this;return r.subject=t,r.subscriber=n,r.closed=!1,r}return r.ZT(t,e),t.prototype.unsubscribe=function(){if(!this.closed){this.closed=!0;var e=this.subject,t=e.observers;if(this.subject=null,t&&0!==t.length&&!e.isStopped&&!e.closed){var n=t.indexOf(this.subscriber);-1!==n&&t.splice(n,1)}}},t}(n(3884).w)},979:(e,t,n)=>{"use strict";n.d(t,{L:()=>c});var r=n(655),i=n(4156),a=n(2174),o=n(3884),s=n(3142),u=n(150),l=n(1644),c=function(e){function t(n,r,i){var o=e.call(this)||this;switch(o.syncErrorValue=null,o.syncErrorThrown=!1,o.syncErrorThrowable=!1,o.isStopped=!1,arguments.length){case 0:o.destination=a.c;break;case 1:if(!n){o.destination=a.c;break}if("object"==typeof n){n instanceof t?(o.syncErrorThrowable=n.syncErrorThrowable,o.destination=n,n.add(o)):(o.syncErrorThrowable=!0,o.destination=new d(o,n));break}default:o.syncErrorThrowable=!0,o.destination=new d(o,n,r,i)}return o}return r.ZT(t,e),t.prototype[s.b]=function(){return this},t.create=function(e,n,r){var i=new t(e,n,r);return i.syncErrorThrowable=!1,i},t.prototype.next=function(e){this.isStopped||this._next(e)},t.prototype.error=function(e){this.isStopped||(this.isStopped=!0,this._error(e))},t.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},t.prototype.unsubscribe=function(){this.closed||(this.isStopped=!0,e.prototype.unsubscribe.call(this))},t.prototype._next=function(e){this.destination.next(e)},t.prototype._error=function(e){this.destination.error(e),this.unsubscribe()},t.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},t.prototype._unsubscribeAndRecycle=function(){var e=this._parentOrParents;return this._parentOrParents=null,this.unsubscribe(),this.closed=!1,this.isStopped=!1,this._parentOrParents=e,this},t}(o.w),d=function(e){function t(t,n,r,o){var s,u=e.call(this)||this;u._parentSubscriber=t;var l=u;return(0,i.m)(n)?s=n:n&&(s=n.next,r=n.error,o=n.complete,n!==a.c&&(l=Object.create(n),(0,i.m)(l.unsubscribe)&&u.add(l.unsubscribe.bind(l)),l.unsubscribe=u.unsubscribe.bind(u))),u._context=l,u._next=s,u._error=r,u._complete=o,u}return r.ZT(t,e),t.prototype.next=function(e){if(!this.isStopped&&this._next){var t=this._parentSubscriber;u.v.useDeprecatedSynchronousErrorHandling&&t.syncErrorThrowable?this.__tryOrSetError(t,this._next,e)&&this.unsubscribe():this.__tryOrUnsub(this._next,e)}},t.prototype.error=function(e){if(!this.isStopped){var t=this._parentSubscriber,n=u.v.useDeprecatedSynchronousErrorHandling;if(this._error)n&&t.syncErrorThrowable?(this.__tryOrSetError(t,this._error,e),this.unsubscribe()):(this.__tryOrUnsub(this._error,e),this.unsubscribe());else if(t.syncErrorThrowable)n?(t.syncErrorValue=e,t.syncErrorThrown=!0):(0,l.z)(e),this.unsubscribe();else{if(this.unsubscribe(),n)throw e;(0,l.z)(e)}}},t.prototype.complete=function(){var e=this;if(!this.isStopped){var t=this._parentSubscriber;if(this._complete){var n=function(){return e._complete.call(e._context)};u.v.useDeprecatedSynchronousErrorHandling&&t.syncErrorThrowable?(this.__tryOrSetError(t,n),this.unsubscribe()):(this.__tryOrUnsub(n),this.unsubscribe())}else this.unsubscribe()}},t.prototype.__tryOrUnsub=function(e,t){try{e.call(this._context,t)}catch(e){if(this.unsubscribe(),u.v.useDeprecatedSynchronousErrorHandling)throw e;(0,l.z)(e)}},t.prototype.__tryOrSetError=function(e,t,n){if(!u.v.useDeprecatedSynchronousErrorHandling)throw new Error("bad call");try{t.call(this._context,n)}catch(t){return u.v.useDeprecatedSynchronousErrorHandling?(e.syncErrorValue=t,e.syncErrorThrown=!0,!0):((0,l.z)(t),!0)}return!1},t.prototype._unsubscribe=function(){var e=this._parentSubscriber;this._context=null,this._parentSubscriber=null,e.unsubscribe()},t}(c)},3884:(e,t,n)=>{"use strict";n.d(t,{w:()=>s});var r=n(9026),i=n(2009),a=n(4156),o=function(){function e(e){return Error.call(this),this.message=e?e.length+" errors occurred during unsubscription:\n"+e.map((function(e,t){return t+1+") "+e.toString()})).join("\n "):"",this.name="UnsubscriptionError",this.errors=e,this}return e.prototype=Object.create(Error.prototype),e}(),s=function(){function e(e){this.closed=!1,this._parentOrParents=null,this._subscriptions=null,e&&(this._ctorUnsubscribe=!0,this._unsubscribe=e)}var t;return e.prototype.unsubscribe=function(){var t;if(!this.closed){var n=this,s=n._parentOrParents,l=n._ctorUnsubscribe,c=n._unsubscribe,d=n._subscriptions;if(this.closed=!0,this._parentOrParents=null,this._subscriptions=null,s instanceof e)s.remove(this);else if(null!==s)for(var f=0;f{"use strict";n.d(t,{v:()=>i});var r=!1,i={Promise:void 0,set useDeprecatedSynchronousErrorHandling(e){e&&(new Error).stack;r=e},get useDeprecatedSynchronousErrorHandling(){return r}}},7604:(e,t,n)=>{"use strict";n.d(t,{IY:()=>s,Ds:()=>u,ft:()=>l});var r=n(655),i=n(979),a=n(4379),o=n(7843),s=function(e){function t(t){var n=e.call(this)||this;return n.parent=t,n}return r.ZT(t,e),t.prototype._next=function(e){this.parent.notifyNext(e)},t.prototype._error=function(e){this.parent.notifyError(e),this.unsubscribe()},t.prototype._complete=function(){this.parent.notifyComplete(),this.unsubscribe()},t}(i.L),u=(i.L,function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype.notifyNext=function(e){this.destination.next(e)},t.prototype.notifyError=function(e){this.destination.error(e)},t.prototype.notifyComplete=function(){this.destination.complete()},t}(i.L));i.L;function l(e,t){if(!t.closed)return e instanceof a.y?e.subscribe(t):(0,o.s)(e)(t)}},5142:(e,t,n)=>{"use strict";n.d(t,{aj:()=>c});var r=n(655),i=n(7507),a=n(9026),o=n(2039),s=n(2080),u=n(3375),l={};function c(){for(var e=[],t=0;t{"use strict";n.d(t,{z:()=>a});var r=n(8170),i=n(2257);function a(){for(var e=[],t=0;t{"use strict";n.d(t,{P:()=>o});var r=n(4379),i=n(4072),a=n(5631);function o(e){return new r.y((function(t){var n;try{n=e()}catch(e){return void t.error(e)}return(n?(0,i.D)(n):(0,a.c)()).subscribe(t)}))}},5631:(e,t,n)=>{"use strict";n.d(t,{E:()=>i,c:()=>a});var r=n(4379),i=new r.y((function(e){return e.complete()}));function a(e){return e?function(e){return new r.y((function(t){return e.schedule((function(){return t.complete()}))}))}(e):i}},4072:(e,t,n)=>{"use strict";n.d(t,{D:()=>f});var r=n(4379),i=n(7843),a=n(3884),o=n(5050);var s=n(3109),u=n(999);var l=n(336),c=n(9217);function d(e,t){if(null!=e){if(function(e){return e&&"function"==typeof e[o.L]}(e))return function(e,t){return new r.y((function(n){var r=new a.w;return r.add(t.schedule((function(){var i=e[o.L]();r.add(i.subscribe({next:function(e){r.add(t.schedule((function(){return n.next(e)})))},error:function(e){r.add(t.schedule((function(){return n.error(e)})))},complete:function(){r.add(t.schedule((function(){return n.complete()})))}}))}))),r}))}(e,t);if((0,l.t)(e))return function(e,t){return new r.y((function(n){var r=new a.w;return r.add(t.schedule((function(){return e.then((function(e){r.add(t.schedule((function(){n.next(e),r.add(t.schedule((function(){return n.complete()})))})))}),(function(e){r.add(t.schedule((function(){return n.error(e)})))}))}))),r}))}(e,t);if((0,c.z)(e))return(0,s.r)(e,t);if(function(e){return e&&"function"==typeof e[u.hZ]}(e)||"string"==typeof e)return function(e,t){if(!e)throw new Error("Iterable cannot be null");return new r.y((function(n){var r,i=new a.w;return i.add((function(){r&&"function"==typeof r.return&&r.return()})),i.add(t.schedule((function(){r=e[u.hZ](),i.add(t.schedule((function(){if(!n.closed){var e,t;try{var i=r.next();e=i.value,t=i.done}catch(e){return void n.error(e)}t?n.complete():(n.next(e),this.schedule())}})))}))),i}))}(e,t)}throw new TypeError((null!==e&&typeof e||e)+" is not observable")}function f(e,t){return t?d(e,t):e instanceof r.y?e:new r.y((0,i.s)(e))}},3375:(e,t,n)=>{"use strict";n.d(t,{n:()=>o});var r=n(4379),i=n(6900),a=n(3109);function o(e,t){return t?(0,a.r)(e,t):new r.y((0,i.V)(e))}},7027:(e,t,n)=>{"use strict";n.d(t,{R:()=>s});var r=n(4379),i=n(9026),a=n(4156),o=n(5709);function s(e,t,n,l){return(0,a.m)(n)&&(l=n,n=void 0),l?s(e,t,n).pipe((0,o.U)((function(e){return(0,i.k)(e)?l.apply(void 0,e):l(e)}))):new r.y((function(r){u(e,t,(function(e){arguments.length>1?r.next(Array.prototype.slice.call(arguments)):r.next(e)}),r,n)}))}function u(e,t,n,r,i){var a;if(function(e){return e&&"function"==typeof e.addEventListener&&"function"==typeof e.removeEventListener}(e)){var o=e;e.addEventListener(t,n,i),a=function(){return o.removeEventListener(t,n,i)}}else if(function(e){return e&&"function"==typeof e.on&&"function"==typeof e.off}(e)){var s=e;e.on(t,n),a=function(){return s.off(t,n)}}else if(function(e){return e&&"function"==typeof e.addListener&&"function"==typeof e.removeListener}(e)){var l=e;e.addListener(t,n),a=function(){return l.removeListener(t,n)}}else{if(!e||!e.length)throw new TypeError("Invalid event target");for(var c=0,d=e.length;c{"use strict";n.d(t,{F:()=>o});var r=n(4379),i=n(964),a=n(5812);function o(e,t){return void 0===e&&(e=0),void 0===t&&(t=i.P),(!(0,a.k)(e)||e<0)&&(e=0),t&&"function"==typeof t.schedule||(t=i.P),new r.y((function(n){return n.add(t.schedule(s,e,{subscriber:n,counter:0,period:e})),n}))}function s(e){var t=e.subscriber,n=e.counter,r=e.period;t.next(n),this.schedule({subscriber:t,counter:n+1,period:r},r)}},4370:(e,t,n)=>{"use strict";n.d(t,{T:()=>s});var r=n(4379),i=n(7507),a=n(2556),o=n(3375);function s(){for(var e=[],t=0;t1&&"number"==typeof e[e.length-1]&&(n=e.pop())):"number"==typeof u&&(n=e.pop()),null===s&&1===e.length&&e[0]instanceof r.y?e[0]:(0,a.J)(n)((0,o.n)(e,s))}},8170:(e,t,n)=>{"use strict";n.d(t,{of:()=>o});var r=n(7507),i=n(3375),a=n(3109);function o(){for(var e=[],t=0;t{"use strict";n.d(t,{S3:()=>u});var r=n(655),i=n(9026),a=n(3375),o=n(2039),s=n(2080);function u(){for(var e=[],t=0;t{"use strict";n.d(t,{_:()=>i});var r=n(4379);function i(e,t){return t?new r.y((function(n){return t.schedule(a,0,{error:e,subscriber:n})})):new r.y((function(t){return t.error(e)}))}function a(e){var t=e.error;e.subscriber.error(t)}},9604:(e,t,n)=>{"use strict";n.d(t,{H:()=>s});var r=n(4379),i=n(964),a=n(5812),o=n(7507);function s(e,t,n){void 0===e&&(e=0);var s=-1;return(0,a.k)(t)?s=Number(t)<1?1:Number(t):(0,o.K)(t)&&(n=t),(0,o.K)(n)||(n=i.P),new r.y((function(t){var r=(0,a.k)(e)?e:+e-n.now();return n.schedule(u,r,{index:0,period:s,subscriber:t})}))}function u(e){var t=e.index,n=e.period,r=e.subscriber;if(r.next(t),!r.closed){if(-1===n)return r.complete();e.index=t+1,this.schedule(e,n)}}},486:(e,t,n)=>{"use strict";n.d(t,{K:()=>a});var r=n(655),i=n(7604);function a(e){return function(t){var n=new o(e),r=t.lift(n);return n.caught=r}}var o=function(){function e(e){this.selector=e}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.selector,this.caught))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.selector=n,i.caught=r,i}return r.ZT(t,e),t.prototype.error=function(t){if(!this.isStopped){var n=void 0;try{n=this.selector(t,this.caught)}catch(t){return void e.prototype.error.call(this,t)}this._unsubscribeAndRecycle();var r=new i.IY(this);this.add(r);var a=(0,i.ft)(n,r);a!==r&&this.add(a)}},t}(i.Ds)},2257:(e,t,n)=>{"use strict";n.d(t,{u:()=>i});var r=n(2556);function i(){return(0,r.J)(1)}},1931:(e,t,n)=>{"use strict";n.d(t,{x:()=>a});var r=n(655),i=n(979);function a(e,t){return function(n){return n.lift(new o(e,t))}}var o=function(){function e(e,t){this.compare=e,this.keySelector=t}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.compare,this.keySelector))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.keySelector=r,i.hasKey=!1,"function"==typeof n&&(i.compare=n),i}return r.ZT(t,e),t.prototype.compare=function(e,t){return e===t},t.prototype._next=function(e){var t;try{var n=this.keySelector;t=n?n(e):e}catch(e){return this.destination.error(e)}var r=!1;if(this.hasKey)try{r=(0,this.compare)(this.key,t)}catch(e){return this.destination.error(e)}else this.hasKey=!0;r||(this.key=t,this.destination.next(e))},t}(i.L)},6008:(e,t,n)=>{"use strict";n.d(t,{h:()=>a});var r=n(655),i=n(979);function a(e,t){return function(n){return n.lift(new o(e,t))}}var o=function(){function e(e,t){this.predicate=e,this.thisArg=t}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.predicate,this.thisArg))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.predicate=n,i.thisArg=r,i.count=0,i}return r.ZT(t,e),t.prototype._next=function(e){var t;try{t=this.predicate.call(this.thisArg,e,this.count++)}catch(e){return void this.destination.error(e)}t&&this.destination.next(e)},t}(i.L)},6738:(e,t,n)=>{"use strict";n.d(t,{l:()=>a});var r=n(655),i=n(979);function a(){return function(e){return e.lift(new o)}}var o=function(){function e(){}return e.prototype.call=function(e,t){return t.subscribe(new s(e))},e}(),s=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype._next=function(e){},t}(i.L)},5709:(e,t,n)=>{"use strict";n.d(t,{U:()=>a});var r=n(655),i=n(979);function a(e,t){return function(n){if("function"!=typeof e)throw new TypeError("argument is not a function. Are you looking for `mapTo()`?");return n.lift(new o(e,t))}}var o=function(){function e(e,t){this.project=e,this.thisArg=t}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.project,this.thisArg))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.project=n,i.count=0,i.thisArg=r||i,i}return r.ZT(t,e),t.prototype._next=function(e){var t;try{t=this.project.call(this.thisArg,e,this.count++)}catch(e){return void this.destination.error(e)}this.destination.next(t)},t}(i.L)},5602:(e,t,n)=>{"use strict";n.d(t,{h:()=>a});var r=n(655),i=n(979);function a(e){return function(t){return t.lift(new o(e))}}var o=function(){function e(e){this.value=e}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.value))},e}(),s=function(e){function t(t,n){var r=e.call(this,t)||this;return r.value=n,r}return r.ZT(t,e),t.prototype._next=function(e){this.destination.next(this.value)},t}(i.L)},2556:(e,t,n)=>{"use strict";n.d(t,{J:()=>a});var r=n(7746),i=n(3608);function a(e){return void 0===e&&(e=Number.POSITIVE_INFINITY),(0,r.zg)(i.y,e)}},7746:(e,t,n)=>{"use strict";n.d(t,{zg:()=>s});var r=n(655),i=n(5709),a=n(4072),o=n(7604);function s(e,t,n){return void 0===n&&(n=Number.POSITIVE_INFINITY),"function"==typeof t?function(r){return r.pipe(s((function(n,r){return(0,a.D)(e(n,r)).pipe((0,i.U)((function(e,i){return t(n,e,r,i)})))}),n))}:("number"==typeof t&&(n=t),function(t){return t.lift(new u(e,n))})}var u=function(){function e(e,t){void 0===t&&(t=Number.POSITIVE_INFINITY),this.project=e,this.concurrent=t}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.project,this.concurrent))},e}(),l=function(e){function t(t,n,r){void 0===r&&(r=Number.POSITIVE_INFINITY);var i=e.call(this,t)||this;return i.project=n,i.concurrent=r,i.hasCompleted=!1,i.buffer=[],i.active=0,i.index=0,i}return r.ZT(t,e),t.prototype._next=function(e){this.active0?this._next(e.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()},t}(o.Ds)},3756:(e,t,n)=>{"use strict";n.d(t,{j:()=>i});var r=n(7746);function i(e,t,n){return void 0===n&&(n=Number.POSITIVE_INFINITY),"function"==typeof t?(0,r.zg)((function(){return e}),t,n):("number"==typeof t&&(n=t),(0,r.zg)((function(){return e}),n))}},1421:(e,t,n)=>{"use strict";n.d(t,{O:()=>f});var r=n(655),i=n(211),a=n(4379),o=n(979),s=n(3884),u=n(3018),l=function(e){function t(t,n){var r=e.call(this)||this;return r.source=t,r.subjectFactory=n,r._refCount=0,r._isComplete=!1,r}return r.ZT(t,e),t.prototype._subscribe=function(e){return this.getSubject().subscribe(e)},t.prototype.getSubject=function(){var e=this._subject;return e&&!e.isStopped||(this._subject=this.subjectFactory()),this._subject},t.prototype.connect=function(){var e=this._connection;return e||(this._isComplete=!1,(e=this._connection=new s.w).add(this.source.subscribe(new d(this.getSubject(),this))),e.closed&&(this._connection=null,e=s.w.EMPTY)),e},t.prototype.refCount=function(){return(0,u.x)()(this)},t}(a.y),c=function(){var e=l.prototype;return{operator:{value:null},_refCount:{value:0,writable:!0},_subject:{value:null,writable:!0},_connection:{value:null,writable:!0},_subscribe:{value:e._subscribe},_isComplete:{value:e._isComplete,writable:!0},getSubject:{value:e.getSubject},connect:{value:e.connect},refCount:{value:e.refCount}}}(),d=function(e){function t(t,n){var r=e.call(this,t)||this;return r.connectable=n,r}return r.ZT(t,e),t.prototype._error=function(t){this._unsubscribe(),e.prototype._error.call(this,t)},t.prototype._complete=function(){this.connectable._isComplete=!0,this._unsubscribe(),e.prototype._complete.call(this)},t.prototype._unsubscribe=function(){var e=this.connectable;if(e){this.connectable=null;var t=e._connection;e._refCount=0,e._subject=null,e._connection=null,t&&t.unsubscribe()}},t}(i.Yc);o.L;function f(e,t){return function(n){var r;if(r="function"==typeof e?e:function(){return e},"function"==typeof t)return n.lift(new p(r,t));var i=Object.create(n,c);return i.source=n,i.subjectFactory=r,i}}var p=function(){function e(e,t){this.subjectFactory=e,this.selector=t}return e.prototype.call=function(e,t){var n=this.selector,r=this.subjectFactory(),i=n(r).subscribe(e);return i.add(t.subscribe(r)),i},e}()},3018:(e,t,n)=>{"use strict";n.d(t,{x:()=>a});var r=n(655),i=n(979);function a(){return function(e){return e.lift(new o(e))}}var o=function(){function e(e){this.connectable=e}return e.prototype.call=function(e,t){var n=this.connectable;n._refCount++;var r=new s(e,n),i=t.subscribe(r);return r.closed||(r.connection=n.connect()),i},e}(),s=function(e){function t(t,n){var r=e.call(this,t)||this;return r.connectable=n,r}return r.ZT(t,e),t.prototype._unsubscribe=function(){var e=this.connectable;if(e){this.connectable=null;var t=e._refCount;if(t<=0)this.connection=null;else if(e._refCount=t-1,t>1)this.connection=null;else{var n=this.connection,r=e._connection;this.connection=null,!r||n&&r!==n||r.unsubscribe()}}else this.connection=null},t}(i.L)},2807:(e,t,n)=>{"use strict";n.d(t,{R:()=>a});var r=n(655),i=n(979);function a(e,t){var n=!1;return arguments.length>=2&&(n=!0),function(r){return r.lift(new o(e,t,n))}}var o=function(){function e(e,t,n){void 0===n&&(n=!1),this.accumulator=e,this.seed=t,this.hasSeed=n}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.accumulator,this.seed,this.hasSeed))},e}(),s=function(e){function t(t,n,r,i){var a=e.call(this,t)||this;return a.accumulator=n,a._seed=r,a.hasSeed=i,a.index=0,a}return r.ZT(t,e),Object.defineProperty(t.prototype,"seed",{get:function(){return this._seed},set:function(e){this.hasSeed=!0,this._seed=e},enumerable:!0,configurable:!0}),t.prototype._next=function(e){if(this.hasSeed)return this._tryNext(e);this.seed=e,this.destination.next(e)},t.prototype._tryNext=function(e){var t,n=this.index++;try{t=this.accumulator(this.seed,e,n)}catch(e){this.destination.error(e)}this.seed=t,this.destination.next(t)},t}(i.L)},9095:(e,t,n)=>{"use strict";n.d(t,{B:()=>s});var r=n(1421),i=n(3018),a=n(211);function o(){return new a.xQ}function s(){return function(e){return(0,i.x)()((0,r.O)(o)(e))}}},7006:(e,t,n)=>{"use strict";n.d(t,{d:()=>i});var r=n(2135);function i(e,t,n){var i;return i=e&&"object"==typeof e?e:{bufferSize:e,windowTime:t,refCount:!1,scheduler:n},function(e){return e.lift(function(e){var t,n,i=e.bufferSize,a=void 0===i?Number.POSITIVE_INFINITY:i,o=e.windowTime,s=void 0===o?Number.POSITIVE_INFINITY:o,u=e.refCount,l=e.scheduler,c=0,d=!1,f=!1;return function(e){var i;c++,!t||d?(d=!1,t=new r.t(a,s,l),i=t.subscribe(this),n=e.subscribe({next:function(e){t.next(e)},error:function(e){d=!0,t.error(e)},complete:function(){f=!0,n=void 0,t.complete()}})):i=t.subscribe(this),this.add((function(){c--,i.unsubscribe(),n&&!f&&u&&0===c&&(n.unsubscribe(),n=void 0,t=void 0)}))}}(i))}}},3485:(e,t,n)=>{"use strict";n.d(t,{O:()=>a});var r=n(9795),i=n(7507);function a(){for(var e=[],t=0;t{"use strict";n.d(t,{w:()=>s});var r=n(655),i=n(5709),a=n(4072),o=n(7604);function s(e,t){return"function"==typeof t?function(n){return n.pipe(s((function(n,r){return(0,a.D)(e(n,r)).pipe((0,i.U)((function(e,i){return t(n,e,r,i)})))})))}:function(t){return t.lift(new u(e))}}var u=function(){function e(e){this.project=e}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.project))},e}(),l=function(e){function t(t,n){var r=e.call(this,t)||this;return r.project=n,r.index=0,r}return r.ZT(t,e),t.prototype._next=function(e){var t,n=this.index++;try{t=this.project(e,n)}catch(e){return void this.destination.error(e)}this._innerSub(t)},t.prototype._innerSub=function(e){var t=this.innerSubscription;t&&t.unsubscribe();var n=new o.IY(this),r=this.destination;r.add(n),this.innerSubscription=(0,o.ft)(e,n),this.innerSubscription!==n&&r.add(this.innerSubscription)},t.prototype._complete=function(){var t=this.innerSubscription;t&&!t.closed||e.prototype._complete.call(this),this.unsubscribe()},t.prototype._unsubscribe=function(){this.innerSubscription=void 0},t.prototype.notifyComplete=function(){this.innerSubscription=void 0,this.isStopped&&e.prototype._complete.call(this)},t.prototype.notifyNext=function(e){this.destination.next(e)},t}(o.Ds)},1198:(e,t,n)=>{"use strict";n.d(t,{c:()=>i});var r=n(6381);function i(e,t){return t?(0,r.w)((function(){return e}),t):(0,r.w)((function(){return e}))}},1015:(e,t,n)=>{"use strict";n.d(t,{q:()=>s});var r=n(655),i=n(979),a=n(6565),o=n(5631);function s(e){return function(t){return 0===e?(0,o.c)():t.lift(new u(e))}}var u=function(){function e(e){if(this.total=e,this.total<0)throw new a.W}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.total))},e}(),l=function(e){function t(t,n){var r=e.call(this,t)||this;return r.total=n,r.count=0,r}return r.ZT(t,e),t.prototype._next=function(e){var t=this.total,n=++this.count;n<=t&&(this.destination.next(e),n===t&&(this.destination.complete(),this.unsubscribe()))},t}(i.L)},1558:(e,t,n)=>{"use strict";n.d(t,{R:()=>a});var r=n(655),i=n(7604);function a(e){return function(t){return t.lift(new o(e))}}var o=function(){function e(e){this.notifier=e}return e.prototype.call=function(e,t){var n=new s(e),r=(0,i.ft)(this.notifier,new i.IY(n));return r&&!n.seenValue?(n.add(r),t.subscribe(n)):n},e}(),s=function(e){function t(t){var n=e.call(this,t)||this;return n.seenValue=!1,n}return r.ZT(t,e),t.prototype.notifyNext=function(){this.seenValue=!0,this.complete()},t.prototype.notifyComplete=function(){},t}(i.Ds)},3068:(e,t,n)=>{"use strict";n.d(t,{b:()=>s});var r=n(655),i=n(979),a=n(3306),o=n(4156);function s(e,t,n){return function(r){return r.lift(new u(e,t,n))}}var u=function(){function e(e,t,n){this.nextOrObserver=e,this.error=t,this.complete=n}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.nextOrObserver,this.error,this.complete))},e}(),l=function(e){function t(t,n,r,i){var s=e.call(this,t)||this;return s._tapNext=a.Z,s._tapError=a.Z,s._tapComplete=a.Z,s._tapError=r||a.Z,s._tapComplete=i||a.Z,(0,o.m)(n)?(s._context=s,s._tapNext=n):n&&(s._context=n,s._tapNext=n.next||a.Z,s._tapError=n.error||a.Z,s._tapComplete=n.complete||a.Z),s}return r.ZT(t,e),t.prototype._next=function(e){try{this._tapNext.call(this._context,e)}catch(e){return void this.destination.error(e)}this.destination.next(e)},t.prototype._error=function(e){try{this._tapError.call(this._context,e)}catch(e){return void this.destination.error(e)}this.destination.error(e)},t.prototype._complete=function(){try{this._tapComplete.call(this._context)}catch(e){return void this.destination.error(e)}return this.destination.complete()},t}(i.L)},3109:(e,t,n)=>{"use strict";n.d(t,{r:()=>a});var r=n(4379),i=n(3884);function a(e,t){return new r.y((function(n){var r=new i.w,a=0;return r.add(t.schedule((function(){a!==e.length?(n.next(e[a++]),n.closed||r.add(this.schedule())):n.complete()}))),r}))}},6114:(e,t,n)=>{"use strict";n.d(t,{o:()=>i});var r=n(655),i=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.scheduler=t,r.work=n,r.pending=!1,r}return r.ZT(t,e),t.prototype.schedule=function(e,t){if(void 0===t&&(t=0),this.closed)return this;this.state=e;var n=this.id,r=this.scheduler;return null!=n&&(this.id=this.recycleAsyncId(r,n,t)),this.pending=!0,this.delay=t,this.id=this.id||this.requestAsyncId(r,this.id,t),this},t.prototype.requestAsyncId=function(e,t,n){return void 0===n&&(n=0),setInterval(e.flush.bind(e,this),n)},t.prototype.recycleAsyncId=function(e,t,n){if(void 0===n&&(n=0),null!==n&&this.delay===n&&!1===this.pending)return t;clearInterval(t)},t.prototype.execute=function(e,t){if(this.closed)return new Error("executing a cancelled action");this.pending=!1;var n=this._execute(e,t);if(n)return n;!1===this.pending&&null!=this.id&&(this.id=this.recycleAsyncId(this.scheduler,this.id,null))},t.prototype._execute=function(e,t){var n=!1,r=void 0;try{this.work(e)}catch(e){n=!0,r=!!e&&e||new Error(e)}if(n)return this.unsubscribe(),r},t.prototype._unsubscribe=function(){var e=this.id,t=this.scheduler,n=t.actions,r=n.indexOf(this);this.work=null,this.state=null,this.pending=!1,this.scheduler=null,-1!==r&&n.splice(r,1),null!=e&&(this.id=this.recycleAsyncId(t,e,null)),this.delay=null},t}(function(e){function t(t,n){return e.call(this)||this}return r.ZT(t,e),t.prototype.schedule=function(e,t){return void 0===t&&(t=0),this},t}(n(3884).w))},2980:(e,t,n)=>{"use strict";n.d(t,{v:()=>a});var r=n(655),i=function(){function e(t,n){void 0===n&&(n=e.now),this.SchedulerAction=t,this.now=n}return e.prototype.schedule=function(e,t,n){return void 0===t&&(t=0),new this.SchedulerAction(this,e).schedule(n,t)},e.now=function(){return Date.now()},e}(),a=function(e){function t(n,r){void 0===r&&(r=i.now);var a=e.call(this,n,(function(){return t.delegate&&t.delegate!==a?t.delegate.now():r()}))||this;return a.actions=[],a.active=!1,a.scheduled=void 0,a}return r.ZT(t,e),t.prototype.schedule=function(n,r,i){return void 0===r&&(r=0),t.delegate&&t.delegate!==this?t.delegate.schedule(n,r,i):e.prototype.schedule.call(this,n,r,i)},t.prototype.flush=function(e){var t=this.actions;if(this.active)t.push(e);else{var n;this.active=!0;do{if(n=e.execute(e.state,e.delay))break}while(e=t.shift());if(this.active=!1,n){for(;e=t.shift();)e.unsubscribe();throw n}}},t}(i)},964:(e,t,n)=>{"use strict";n.d(t,{P:()=>i});var r=n(6114),i=new(n(2980).v)(r.o)},999:(e,t,n)=>{"use strict";function r(){return"function"==typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator"}n.d(t,{hZ:()=>i});var i=r()},5050:(e,t,n)=>{"use strict";n.d(t,{L:()=>r});var r=function(){return"function"==typeof Symbol&&Symbol.observable||"@@observable"}()},3142:(e,t,n)=>{"use strict";n.d(t,{b:()=>r});var r=function(){return"function"==typeof Symbol?Symbol("rxSubscriber"):"@@rxSubscriber_"+Math.random()}()},6565:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});var r=function(){function e(){return Error.call(this),this.message="argument out of range",this.name="ArgumentOutOfRangeError",this}return e.prototype=Object.create(Error.prototype),e}()},1016:(e,t,n)=>{"use strict";n.d(t,{N:()=>r});var r=function(){function e(){return Error.call(this),this.message="object unsubscribed",this.name="ObjectUnsubscribedError",this}return e.prototype=Object.create(Error.prototype),e}()},1644:(e,t,n)=>{"use strict";function r(e){setTimeout((function(){throw e}),0)}n.d(t,{z:()=>r})},3608:(e,t,n)=>{"use strict";function r(e){return e}n.d(t,{y:()=>r})},9026:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});var r=function(){return Array.isArray||function(e){return e&&"number"==typeof e.length}}()},9217:(e,t,n)=>{"use strict";n.d(t,{z:()=>r});var r=function(e){return e&&"number"==typeof e.length&&"function"!=typeof e}},9914:(e,t,n)=>{"use strict";function r(e){return e instanceof Date&&!isNaN(+e)}n.d(t,{J:()=>r})},4156:(e,t,n)=>{"use strict";function r(e){return"function"==typeof e}n.d(t,{m:()=>r})},5812:(e,t,n)=>{"use strict";n.d(t,{k:()=>i});var r=n(9026);function i(e){return!(0,r.k)(e)&&e-parseFloat(e)+1>=0}},2009:(e,t,n)=>{"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{K:()=>r})},336:(e,t,n)=>{"use strict";function r(e){return!!e&&"function"!=typeof e.subscribe&&"function"==typeof e.then}n.d(t,{t:()=>r})},7507:(e,t,n)=>{"use strict";function r(e){return e&&"function"==typeof e.schedule}n.d(t,{K:()=>r})},3306:(e,t,n)=>{"use strict";function r(){}n.d(t,{Z:()=>r})},7843:(e,t,n)=>{"use strict";n.d(t,{s:()=>c});var r=n(6900),i=n(1644),a=n(999),o=n(5050),s=n(9217),u=n(336),l=n(2009),c=function(e){if(e&&"function"==typeof e[o.L])return c=e,function(e){var t=c[o.L]();if("function"!=typeof t.subscribe)throw new TypeError("Provided object does not correctly implement Symbol.observable");return t.subscribe(e)};if((0,s.z)(e))return(0,r.V)(e);if((0,u.t)(e))return n=e,function(e){return n.then((function(t){e.closed||(e.next(t),e.complete())}),(function(t){return e.error(t)})).then(null,i.z),e};if(e&&"function"==typeof e[a.hZ])return t=e,function(e){for(var n=t[a.hZ]();;){var r=void 0;try{r=n.next()}catch(t){return e.error(t),e}if(r.done){e.complete();break}if(e.next(r.value),e.closed)break}return"function"==typeof n.return&&e.add((function(){n.return&&n.return()})),e};var t,n,c,d=(0,l.K)(e)?"an invalid object":"'"+e+"'";throw new TypeError("You provided "+d+" where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.")}},6900:(e,t,n)=>{"use strict";n.d(t,{V:()=>r});var r=function(e){return function(t){for(var n=0,r=e.length;n{"use strict";n.d(t,{D:()=>s});var r=n(655),i=function(e){function t(t,n,r){var i=e.call(this)||this;return i.parent=t,i.outerValue=n,i.outerIndex=r,i.index=0,i}return r.ZT(t,e),t.prototype._next=function(e){this.parent.notifyNext(this.outerValue,e,this.outerIndex,this.index++,this)},t.prototype._error=function(e){this.parent.notifyError(e,this),this.unsubscribe()},t.prototype._complete=function(){this.parent.notifyComplete(this),this.unsubscribe()},t}(n(979).L),a=n(7843),o=n(4379);function s(e,t,n,r,s){if(void 0===s&&(s=new i(e,n,r)),!s.closed)return t instanceof o.y?t.subscribe(s):(0,a.s)(t)(s)}},655:(e,t,n)=>{"use strict";n.d(t,{ZT:()=>i});var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function i(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}}},t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={exports:{}};return e[r](i,i.exports,n),i.exports}return n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n(1452)})().default})); \ No newline at end of file +!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(()=>{var e={3349:(e,t,n)=>{"use strict";function r(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}n.d(t,{Z:()=>r})},5991:(e,t,n)=>{"use strict";function r(e,t){for(var n=0;ni})},1788:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(4665);function i(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,(0,r.Z)(e,t)}},4665:(e,t,n)=>{"use strict";function r(e,t){return(r=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{Z:()=>r})},3786:(e,t,n)=>{"use strict";function r(e){return(r=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}n.d(t,{Z:()=>s});var i=n(4665);function a(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var a=new(Function.bind.apply(e,r));return n&&(0,i.Z)(a,n.prototype),a}).apply(null,arguments)}function s(e){var t="function"==typeof Map?new Map:void 0;return(s=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,a)}function a(){return o(e,arguments,r(this).constructor)}return a.prototype=Object.create(e.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),(0,i.Z)(a,e)})(e)}},7757:(e,t,n)=>{e.exports=n(5666)},3774:(e,t,n)=>{"use strict";n.d(t,{DQ:()=>a,JJ:()=>s,w:()=>o});var r=n(1946),i=n(2203).Z?{}:window,a=i.HTMLElement,o=(0,r.Z)(i.VTTCue)?i.TextTrackCue:i.VTTCue,s=(0,r.Z)(i.MediaSource)?(0,r.Z)(i.MozMediaSource)?(0,r.Z)(i.WebKitMediaSource)?i.MSMediaSource:i.WebKitMediaSource:i.MozMediaSource:i.MediaSource},3666:(e,t,n)=>{"use strict";n.d(t,{kD:()=>s,fq:()=>a,YM:()=>o,vU:()=>u,G6:()=>c,SB:()=>f,op:()=>l,yS:()=>d});var r,i=n(2203),a=!i.Z&&!!window.MSInputMethodContext&&!!document.documentMode,o=!i.Z&&("Microsoft Internet Explorer"===navigator.appName||"Netscape"===navigator.appName&&/(Trident|Edge)\//.test(navigator.userAgent)),s=!i.Z&&-1!==navigator.userAgent.toLowerCase().indexOf("edg/"),u=!i.Z&&-1!==navigator.userAgent.toLowerCase().indexOf("firefox"),l=!i.Z&&/SamsungBrowser/.test(navigator.userAgent),d=!i.Z&&/Tizen/.test(navigator.userAgent),c=!i.Z&&(Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>=0||"[object SafariRemoteNotification]"===(null===(r=window.safari)||void 0===r?void 0:r.pushNotification.toString())),f=!i.Z&&"string"==typeof navigator.platform&&/iPad|iPhone|iPod/.test(navigator.platform)},5767:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3887),i=n(3666);function a(e){if(i.vU){for(var t=e.textTracks,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:(e,t,n)=>{"use strict";n.d(t,{N:()=>D,Y:()=>H});var r,i=n(4944),a=n(8170),o=n(1410),s=n(3714),u=n(8117),l=n(3666),d=n(2203),c=n(5059),f=n(5991),p=n(9589),h=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 p.Z((function(t){return t(e._mediaKeys)}))},t.getConfiguration=function(){return this._configuration},(0,f.Z)(e,[{key:"keySystem",get:function(){return this._keyType}}]),e}(),v=n(1788),m=n(211),g=n(4370),y=n(1558),_=n(1959),b=n(1473);if(!d.Z){var T=window.MSMediaKeys;void 0!==T&&void 0!==T.prototype&&"function"==typeof T.isTypeSupported&&"function"==typeof T.prototype.createSession&&(r=T)}var E,w=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 m.xQ,n.closed=new p.Z((function(e){n._closeSession$.subscribe(e)})),n.update=function(e){return new p.Z((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 p.Z((function(e){n._ss=n._mk.createSession("video/mp4",t),(0,g.T)(b.GJ(n._ss),b.GV(n._ss),b.Xe(n._ss)).pipe((0,y.R)(n._closeSession$)).subscribe((function(e){return n.trigger(e.type,e)})),e()}))},n.close=function(){var e=this;return new p.Z((function(t){null!=e._ss&&(e._ss.close(),e._ss=void 0),e._closeSession$.next(),e._closeSession$.complete(),t()}))},n.load=function(){return p.Z.resolve(!1)},n.remove=function(){return p.Z.resolve()},(0,f.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}(_.Z),S=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 w(this._mediaKeys)},t.setServerCertificate=function(){throw new Error("Server certificate is not implemented in your browser")},e}();if(!d.Z){var k=window.MozMediaKeys;void 0!==k&&void 0!==k.prototype&&"function"==typeof k.isTypeSupported&&"function"==typeof k.prototype.createSession&&(E=k)}var A=n(9689),x=n(3635);function I(e){return"function"==typeof e.webkitGenerateKeyRequest}var Z=function(e){function t(t,n){var r;return(r=e.call(this)||this)._closeSession$=new m.xQ,r._vid=t,r._key=n,r.sessionId="",r.closed=new p.Z((function(e){r._closeSession$.subscribe(e)})),r.keyStatuses=new Map,r.expiration=NaN,(0,g.T)(b.GJ(t),b.GV(t),b.Xe(t)).pipe((0,y.R)(r._closeSession$)).subscribe((function(e){return r.trigger(e.type,e)})),r.update=function(e){return new p.Z((function(t,n){try{if(r._key.indexOf("clearkey")>=0){var i=e instanceof ArrayBuffer?new Uint8Array(e):e,a=JSON.parse((0,x.uR)(i)),o=(0,A.K)(a.keys[0].k),s=(0,A.K)(a.keys[0].kid);t(r._vid.webkitAddKey(r._key,o,s,""))}else t(r._vid.webkitAddKey(r._key,e,null,""))}catch(e){n(e)}}))},r}(0,v.Z)(t,e);var n=t.prototype;return n.generateRequest=function(e,t){var n=this;return new p.Z((function(e){n._vid.webkitGenerateKeyRequest(n._key,t),e()}))},n.close=function(){var e=this;return new p.Z((function(t){e._closeSession$.next(),e._closeSession$.complete(),t()}))},n.load=function(){return p.Z.resolve(!1)},n.remove=function(){return p.Z.resolve()},t}(_.Z),R=function(){function e(e){this._keySystem=e}var t=e.prototype;return t._setVideo=function(e){if(!I(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 Z(this._videoElement,this._keySystem)},t.setServerCertificate=function(){throw new Error("Server certificate is not implemented in your browser")},e}();var M=n(6968);var C=n(158);function N(e,t){if(void 0===e.webkitSetMediaKeys)throw new Error("No webKitMediaKeys API.");return e.webkitSetMediaKeys(t)}var P=function(e){function t(t,n,r){var i;return(i=e.call(this)||this)._serverCertificate=r,i._closeSession$=new m.xQ,i._videoElement=t,i._keyType=n,i.closed=new p.Z((function(e){i._closeSession$.subscribe(e)})),i.keyStatuses=new Map,i.expiration=NaN,i.update=function(e){return new p.Z((function(t,n){if(void 0===i._nativeSession||void 0===i._nativeSession.update||"function"!=typeof i._nativeSession.update)return n("Unavailable WebKit key session.");try{t(i._nativeSession.update(e))}catch(e){n(e)}}))},i}(0,v.Z)(t,e);var n=t.prototype;return n.listenEvent=function(e){var t=this;(0,g.T)(b.GJ(e),b.GV(e),b.Xe(e)).pipe((0,y.R)(this._closeSession$)).subscribe((function(e){t.trigger(e.type,e)}))},n.generateRequest=function(e,t){var n=this;return new p.Z((function(e){if(void 0===n._videoElement.webkitKeys||void 0===n._videoElement.webkitKeys.createSession)throw new Error("No WebKitMediaKeys API.");var r,i;if("com.apple.fps.1_0"===(i=n._keyType)||"com.apple.fps.2_0"===i){if(void 0===n._serverCertificate)throw new Error("A server certificate is needed for creating fairplay session.");r=function(e,t){var n=e instanceof Uint8Array?e:new Uint8Array(e),r=t instanceof Uint8Array?t:new Uint8Array(t);if((0,M.dN)(n,0)+4!==n.length)throw new Error("Unsupported WebKit initData.");var i=(0,x.wV)(n),a=i.indexOf("skd://"),o=a>-1?i.substring(a+6):i,s=(0,x.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,M.O_)(s.byteLength),u),u+=4,l.set(s,u),u+=s.byteLength,l.set((0,M.O_)(r.byteLength),u),u+=4,l.set(r,u),l}(t,n._serverCertificate)}else r=t;var a=n._videoElement.webkitKeys.createSession("video/mp4",r);if(null==a)throw new Error("Impossible to get the key sessions");n.listenEvent(a),n._nativeSession=a,e()}))},n.close=function(){var e=this;return new p.Z((function(t,n){e._closeSession$.next(),e._closeSession$.complete(),void 0===e._nativeSession&&n("No session to close."),e._nativeSession.close(),t()}))},n.load=function(){return p.Z.resolve(!1)},n.remove=function(){return p.Z.resolve()},(0,f.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}(_.Z),O=function(){function e(e){if(void 0===C.t)throw new Error("No WebKitMediaKeys API.");this._keyType=e,this._mediaKeys=new C.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 N(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 P(this._videoElement,this._keyType,this._serverCertificate)},t.setServerCertificate=function(e){return this._serverCertificate=e,p.Z.resolve()},e}();var D=null,L=function(e,t){return"function"==typeof e.setMediaKeys?e.setMediaKeys(t):e.webkitSetMediaKeys?e.webkitSetMediaKeys(t):e.mozSetMediaKeys?e.mozSetMediaKeys(t):e.msSetMediaKeys&&null!==t?e.msSetMediaKeys(t):void 0};if(d.Z||null!=navigator.requestMediaKeySystemAccess&&!(0,c.Z)())D=function(e,t){return(0,u.Z)(navigator.requestMediaKeySystemAccess(e,t))};else{var B,U;if(I(HTMLVideoElement.prototype)){var F={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 R(e)},setMediaKeys:function(e,t){if(null!==t){if(!(t instanceof R))throw new Error("Custom setMediaKeys is supposed to be called with old webkit custom MediaKeys.");return t._setVideo(e)}}};B=F.isTypeSupported,U=F.createCustomMediaKeys,L=F.setMediaKeys}else if(void 0!==C.t){var z=function(){if(void 0===C.t)throw new Error("No WebKitMediaKeys API.");return{isTypeSupported:C.t.isTypeSupported,createCustomMediaKeys:function(e){return new O(e)},setMediaKeys:function(e,t){if(null===t)return N(e,t);if(!(t instanceof O))throw new Error("Custom setMediaKeys is supposed to be called with webkit custom MediaKeys.");return t._setVideo(e)}}}();B=z.isTypeSupported,U=z.createCustomMediaKeys,L=z.setMediaKeys}else if(l.fq&&void 0!==r){var K={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 S(e)},setMediaKeys:function(e,t){if(null!==t){if(!(t instanceof S))throw new Error("Custom setMediaKeys is supposed to be called with IE11 custom MediaKeys.");return t._setVideo(e)}}};B=K.isTypeSupported,U=K.createCustomMediaKeys,L=K.setMediaKeys}else if(void 0!==E){var V={isTypeSupported:function(e,t){if(void 0===E)throw new Error("No MozMediaKeys API.");return void 0!==t?E.isTypeSupported(e,t):E.isTypeSupported(e)},createCustomMediaKeys:function(e){if(void 0===E)throw new Error("No MozMediaKeys API.");return new E(e)},setMediaKeys:function(e,t){if(void 0===e.mozSetMediaKeys||"function"!=typeof e.mozSetMediaKeys)throw new Error("Can't set video on MozMediaKeys.");return e.mozSetMediaKeys(t)}};B=V.isTypeSupported,U=V.createCustomMediaKeys,L=V.setMediaKeys}else{var W=window.MediaKeys,G=function(){if(void 0===W)throw new s.Z("MEDIA_KEYS_NOT_SUPPORTED","No `MediaKeys` implementation found in the current browser.");if(void 0===W.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.")}};B=function(e){return G(),W.isTypeSupported(e)},U=function(e){return G(),new W(e)}}D=function(e,t){if(!B(e))return(0,i._)(void 0);for(var n=0;n{"use strict";var r;if(n.d(t,{t:()=>r}),!n(2203).Z){var i=window.WebKitMediaKeys;void 0!==i&&"function"==typeof i.isTypeSupported&&"function"==typeof i.prototype.createSession&&"function"==typeof HTMLMediaElement.prototype.webkitSetMediaKeys&&(r=i)}},1473:(e,t,n)=>{"use strict";n.d(t,{zh:()=>V,_K:()=>H,Oh:()=>re,C1:()=>q,Q1:()=>X,GV:()=>ae,Xe:()=>oe,GJ:()=>ie,eX:()=>se,yj:()=>G,Qt:()=>Q,gg:()=>ne,ik:()=>Y,d5:()=>j,ym:()=>ee,UA:()=>J,_E:()=>te,$x:()=>$});var r=n(4379),i=n(3306),a=new r.y(i.Z);var o=n(7027),s=n(4370),u=n(1410),l=n(8170),d=n(5142),c=n(6564),f=n(655),p=n(964),h=n(9914),v=n(979),m=n(2632);function g(e,t){void 0===t&&(t=p.P);var n=(0,h.J)(e)?+e-t.now():Math.abs(e);return function(e){return e.lift(new y(n,t))}}var y=function(){function e(e,t){this.delay=e,this.scheduler=t}return e.prototype.call=function(e,t){return t.subscribe(new _(e,this.delay,this.scheduler))},e}(),_=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.delay=n,i.scheduler=r,i.queue=[],i.active=!1,i.errored=!1,i}return f.ZT(t,e),t.dispatch=function(e){for(var t=e.source,n=t.queue,r=e.scheduler,i=e.destination;n.length>0&&n[0].time-r.now()<=0;)n.shift().notification.observe(i);if(n.length>0){var a=Math.max(0,n[0].time-r.now());this.schedule(e,a)}else this.unsubscribe(),t.active=!1},t.prototype._schedule=function(e){this.active=!0,this.destination.add(e.schedule(t.dispatch,this.delay,{source:this,destination:this.destination,scheduler:e}))},t.prototype.scheduleNotification=function(e){if(!0!==this.errored){var t=this.scheduler,n=new b(t.now()+this.delay,e);this.queue.push(n),!1===this.active&&this._schedule(t)}},t.prototype._next=function(e){this.scheduleNotification(m.P.createNext(e))},t.prototype._error=function(e){this.errored=!0,this.queue=[],this.destination.error(e),this.unsubscribe()},t.prototype._complete=function(){this.scheduleNotification(m.P.createComplete()),this.unsubscribe()},t}(v.L),b=function(){return function(e,t){this.time=e,this.notification=t}}(),T=n(7604),E={leading:!0,trailing:!1};T.Ds;function w(e,t,n){return void 0===t&&(t=p.P),void 0===n&&(n=E),function(r){return r.lift(new S(e,t,n.leading,n.trailing))}}var S=function(){function e(e,t,n,r){this.duration=e,this.scheduler=t,this.leading=n,this.trailing=r}return e.prototype.call=function(e,t){return t.subscribe(new k(e,this.duration,this.scheduler,this.leading,this.trailing))},e}(),k=function(e){function t(t,n,r,i,a){var o=e.call(this,t)||this;return o.duration=n,o.scheduler=r,o.leading=i,o.trailing=a,o._hasTrailingValue=!1,o._trailingValue=null,o}return f.ZT(t,e),t.prototype._next=function(e){this.throttled?this.trailing&&(this._trailingValue=e,this._hasTrailingValue=!0):(this.add(this.throttled=this.scheduler.schedule(A,this.duration,{subscriber:this})),this.leading?this.destination.next(e):this.trailing&&(this._trailingValue=e,this._hasTrailingValue=!0))},t.prototype._complete=function(){this._hasTrailingValue?(this.destination.next(this._trailingValue),this.destination.complete()):this.destination.complete()},t.prototype.clearThrottle=function(){var e=this.throttled;e&&(this.trailing&&this._hasTrailingValue&&(this.destination.next(this._trailingValue),this._trailingValue=null,this._hasTrailingValue=!1),e.unsubscribe(),this.remove(e),this.throttled=null)},t}(v.L);function A(e){e.subscriber.clearThrottle()}var x=n(5709),I=n(3485),Z=n(1931),R=n(6381),M=n(5602),C=n(944),N=n(6923),P=n(3774),O=n(2203),D=n(5059),L=["","webkit","moz","ms"],B=C.Z.INACTIVITY_DELAY,U=O.Z||null==window.devicePixelRatio||0===window.devicePixelRatio?1:window.devicePixelRatio;function F(e,t){return t.filter((function(t){return function(e,t){var n=document.createElement(e.tagName),r="on"+t;return r in n||(n.setAttribute(r,"return;"),"function"==typeof n[r])}(e,t)}))[0]}function z(e,t){var n,r=function(e,t){return e.reduce((function(e,n){return e.concat((null==t?L:t).map((function(e){return e+n})))}),[])}(e,t);return function(e){return e instanceof P.DQ?(void 0===n&&(n=F(e,r)),(0,N.Z)(n)?(0,o.R)(e,n):a):s.T.apply(void 0,r.map((function(t){return(0,o.R)(e,t)})))}}function K(){var e,t=document;null!=t.hidden?e="":null!=t.mozHidden?e="moz":null!=t.msHidden?e="ms":null!=t.webkitHidden&&(e="webkit");var n=(0,N.Z)(e)?e+"Hidden":"hidden",r=(0,N.Z)(e)?e+"visibilitychange":"visibilitychange";return(0,u.P)((function(){var e=document[n];return(0,o.R)(document,r).pipe((0,x.U)((function(){return!document[n]})),(0,I.O)(!e),(0,Z.x)())}))}function V(){return K().pipe((0,R.w)((function(e){return e?(0,l.of)(e):(0,l.of)(e).pipe(g(B))})))}function W(e,t){var n=t.width,r=t.height/(e.clientHeight/e.clientWidth);return Math.min(n,r)}function G(e){return(0,u.P)((function(){if(e.webkitSupportsPresentationMode&&"function"==typeof e.webkitSetPresentationMode){var t="picture-in-picture"===e.webkitPresentationMode;return(0,o.R)(e,"webkitpresentationmodechanged").pipe((0,x.U)((function(){return{isEnabled:"picture-in-picture"===e.webkitPresentationMode,pipWindow:null}})),(0,I.O)({isEnabled:t,pipWindow:null}))}var n={isEnabled:document.pictureInPictureElement&&document.pictureInPictureElement===e,pipWindow:null};return(0,s.T)((0,o.R)(e,"enterpictureinpicture").pipe((0,x.U)((function(e){return{isEnabled:!0,pipWindow:e.pictureInPictureWindow}}))),(0,o.R)(e,"leavepictureinpicture").pipe((0,M.h)({isEnabled:!1,pipWindow:null}))).pipe((0,I.O)(n))}))}function H(e){return(0,d.aj)([K(),e]).pipe((0,R.w)((function(e){var t=e[0];return e[1].isEnabled||t?(0,l.of)(!0):(0,l.of)(!1).pipe(g(B))})),(0,Z.x)())}function $(e,t){return(0,d.aj)([t,(0,c.F)(2e4).pipe((0,I.O)(null)),(0,o.R)(window,"resize").pipe(w(500),(0,I.O)(null))]).pipe((0,R.w)((function(t){var n=t[0];if(n.isEnabled){if(null!=n.pipWindow){var r=n.pipWindow,i=W(e,r);return(0,o.R)(r,"resize").pipe((0,I.O)(i*U),(0,x.U)((function(){return W(e,r)*U})))}return(0,l.of)(1/0)}return(0,l.of)(e.clientWidth*U)})),(0,Z.x)())}z(["loadedmetadata"]);var j=z(["seeking"]),Y=z(["seeked"]),q=z(["ended"]),X=(z(["timeupdate"]),z(["fullscreenchange","FullscreenChange"],L.concat("MS"))),Q=function(e){return(0,s.T)(z(["play"])(e),z(["pause"])(e))},J=function(e){return(0,s.T)(z(["addtrack"])(e),z(["removetrack"])(e))},ee=z(["sourceopen","webkitsourceopen"]),te=z(["update"]),ne=z(["onremovesourcebuffer"]),re=z((0,D.Z)()?["needkey"]:["encrypted","needkey"]),ie=z(["keymessage","message"]),ae=z(["keyadded","ready"]),oe=z(["keyerror","error"]),se=z(["keystatuseschange"])},2203:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r="undefined"==typeof window},1988:(e,t,n)=>{"use strict";function r(e){return"function"==typeof window.VTTCue&&e instanceof window.VTTCue}n.d(t,{Z:()=>r})},7253:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3887),i=n(3774);function a(e,t,n){if(null==i.w)throw new Error("VTT cues not supported in your target");return e>=t?(r.Z.warn("Compat: Invalid cue times: "+e+" - "+t),null):new i.w(e,t,n)}},5059:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3666),i=n(158);function a(){return r.G6&&void 0!==i.t}},944:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const 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,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},BUFFER_DISCONTINUITY_THRESHOLD:.2,FORCE_DISCONTINUITY_SEEK_DELAY:2e3,BITRATE_REBUFFERING_RATIO:1.5,BUFFER_GC_GAPS:{CALM:240,BEEFY:30},DEFAULT_MAX_MANIFEST_REQUEST_RETRY:4,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},STALL_GAP:{DEFAULT:.5,LOW_LATENCY:.2},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_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS:50,EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION:1e3,EME_SESSION_CLOSING_MAX_RETRY:5,EME_SESSION_CLOSING_INITIAL_DELAY:100,EME_SESSION_CLOSING_MAX_DELAY:1e3,EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES:100,FORCED_ENDED_THRESHOLD:.001,ADAPTATION_SWITCH_BUFFER_PADDINGS:{video:{before:2,after:2.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}},7794:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(1788),i=n(1959),a=n(7829);function o(e,t){var n;if(t.length!==e.length)return!0;for(var r=0;r{"use strict";n.d(t,{ZP:()=>Qe});var r=n(8170),i=n(9795),a=n(4370),o=n(4944),s=n(2135),u=n(5631),l=n(7746),d=n(7006),c=n(6008),f=n(1015),p=n(3068),h=n(5709),v=n(486),m=n(6738),g=n(1473),y=n(3887),_=n(6490),b=n(4791),T=n(6968),E=n(3635),w=(0,T.pX)((0,E.tG)("pssh"),0);function S(e,t){for(var n=0;ne.length)return y.Z.warn("Compat: Unrecognized initialization data. Use as is."),[{systemId:void 0,data:e}];var i=e.subarray(n,n+r),a={systemId:(0,_.Y)(i,8),data:i};S(t,a)?y.Z.warn("Compat: Duplicated PSSH found in initialization data, removing it."):t.push(a),n+=r}return n!==e.length?(y.Z.warn("Compat: Unrecognized initialization data. Use as is."),[{systemId:void 0,data:e}]):t}(new Uint8Array(t))}}var A=n(1410),x=n(2297),I=n(8117);function Z(e,t,n){return(0,A.P)((function(){var r;y.Z.debug("Compat: Calling generateRequest on the MediaKeySession");try{r=function(e){y.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 y.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,x.Xj)(o),u=null===s?void 0:o[s[1]];y.Z.info("Compat: CENC PSSH found with version",u),void 0===u?y.Z.warn("Compat: could not read version of CENC PSSH"):t===(1===u)?n=(0,T.zo)(n,o):1===u?(y.Z.warn("Compat: cenc version 1 encountered, removing every other cenc pssh box."),n=o,t=!0):y.Z.warn("Compat: filtering out cenc pssh box with wrong version",u)}else r=(0,T.zo)(r,o);i+=a}if(i!==e.length)throw y.Z.warn("Compat: unrecognized initialization data. Cannot patch it."),new Error("Compat: unrecognized initialization data. Cannot patch it.");return(0,T.zo)(r,n)}(n)}catch(e){r=n}var i=null!=t?t:"";return(0,I.Z)(e.generateRequest(i,r)).pipe((0,v.K)((function(t){if(""!==i||!(t instanceof TypeError))throw t;return y.Z.warn('Compat: error while calling `generateRequest` with an empty initialization data type. Retrying with a default "cenc" value.',t),(0,I.Z)(e.generateRequest("cenc",r))})))}))}var R=n(944),M=n(5157),C=n(7714),N=n(8418),P=n(2793),O=n(1946);var D=n(5602),L=n(3485);var B=n(8821),U=n(9604),F=n(5561);function z(e){if(""===e.sessionId)return!1;var t=e.keyStatuses,n=[];return t.forEach((function(e){n.push(e)})),n.length<=0?(y.Z.debug("EME: isSessionUsable: MediaKeySession given has an empty keyStatuses",e),!1):(0,C.Z)(n,"expired")?(y.Z.debug("EME: isSessionUsable: MediaKeySession given has an expired key",e.sessionId),!1):(0,C.Z)(n,"internal-error")?(y.Z.debug("EME: isSessionUsable: MediaKeySession given has a key with an internal-error",e.sessionId),!1):(y.Z.debug("EME: isSessionUsable: MediaKeySession is usable",e.sessionId),!0)}function K(e,t,n){return(0,A.P)((function(){var i=e.loadedSessionsStore,a=e.persistentSessionsStore;return"temporary"===n?V(i,t):null===a?(y.Z.warn("EME: Cannot create persistent MediaKeySession, PersistentSessionsStore not created."),V(i,t)):function(e,t,n){return(0,A.P)((function(){y.Z.info("EME: Creating persistent MediaKeySession");var i=e.createSession(n,"persistent-license"),a=t.getAndReuse(n);if(null===a)return(0,r.of)({type:"created-session",value:{mediaKeySession:i,sessionType:"persistent-license"}});var o=function(){return y.Z.info("EME: Removing previous persistent session."),null!==t.get(n)&&t.delete(n),e.closeSession(n).pipe((0,h.U)((function(){return{type:"created-session",value:{mediaKeySession:e.createSession(n,"persistent-license"),sessionType:"persistent-license"}}})))};return function(e,t){return(0,A.P)((function(){return y.Z.info("Compat/EME: Load persisted session",t),(0,F.Z)((function(){return(0,I.Z)(e.load(t))}),void 0)})).pipe((0,l.zg)((function(t){return!t||e.keyStatuses.size>0?(0,r.of)(t):(0,B.S3)((0,U.H)(100),(0,g.eX)(e)).pipe((0,f.q)(1),(0,D.h)(t))})))}(i,a.sessionId).pipe((0,l.zg)((function(e){return e?e&&z(i)?(t.add(n,i),y.Z.info("EME: Succeeded to load persistent session."),(0,r.of)({type:"loaded-persistent-session",value:{mediaKeySession:i,sessionType:"persistent-license"}})):(y.Z.warn("EME: Previous persistent session not usable anymore."),o()):(y.Z.warn("EME: No data stored for the loaded session"),t.delete(n),(0,r.of)({type:"created-session",value:{mediaKeySession:i,sessionType:"persistent-license"}}))})),(0,v.K)((function(e){return y.Z.warn("EME: Unable to load persistent session: "+(e instanceof Error?e.toString():"Unknown Error")),o()})))}))}(i,a,t)}))}function V(e,t){return(0,A.P)((function(){y.Z.info("EME: Creating a new temporary session");var n=e.createSession(t,"temporary");return(0,r.of)({type:"created-session",value:{mediaKeySession:n,sessionType:"temporary"}})}))}var W=R.Z.EME_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS;function G(e,t,n){return(0,A.P)((function(){var o=null,s=t.loadedSessionsStore,d=t.persistentSessionsStore,c=s.getAndReuse(e);if(null!==c){if(z(o=c.mediaKeySession))return y.Z.info("EME: Reuse loaded session",o.sessionId),(0,r.of)({type:"loaded-open-session",value:{mediaKeySession:o,sessionType:c.sessionType,initializationData:e}});null!==d&&d.delete(e)}return(null!=o?s.closeSession(e):(0,r.of)(null)).pipe((0,l.zg)((function(){return(0,i.z)(function(e,t){if(t<0||t>=e.getLength())return u.E;for(var n=[],r=e.getAll().slice(),i=r.length-t,o=0;o=a.length){var n=new M.Z("INCOMPATIBLE_KEYSYSTEMS","No key system compatible with your wanted configuration has been found in the current browser.");return(0,o._)(n)}if(null==H.N){var r=Error("requestMediaKeySystemAccess is not implemented in your browser.");return(0,o._)(r)}var i=a[t],s=i.keyName,u=i.keyType,l=i.keySystemOptions,d=function(e,t){var n=["temporary"],r="optional",i="optional";!0===t.persistentLicense&&(r="required",n.push("persistent-license")),!0===t.persistentStateRequired&&(r="required"),!0===t.distinctiveIdentifierRequired&&(i="required");var a=null!=t.videoRobustnesses?t.videoRobustnesses:"widevine"===e?X:[],o=null!=t.audioRobustnesses?t.audioRobustnesses:"widevine"===e?X:[];return 0===a.length&&a.push(void 0),0===o.length&&o.push(void 0),[{initDataTypes:["cenc"],videoCapabilities:(0,q.Z)(a,(function(e){return[{contentType:'video/mp4;codecs="avc1.4d401e"',robustness:e},{contentType:'video/mp4;codecs="avc1.42e01e"',robustness:e},{contentType:'video/webm;codecs="vp8"',robustness:e}]})),audioCapabilities:(0,q.Z)(o,(function(e){return[{contentType:'audio/mp4;codecs="mp4a.40.2"',robustness:e},{contentType:"audio/webm;codecs=opus",robustness:e}]})),distinctiveIdentifier:i,persistentState:r,sessionTypes:n}]}(s,l);return y.Z.debug("EME: Request keysystem access "+u+","+(t+1)+" of "+a.length,d),(0,H.N)(u,d).pipe((0,h.U)((function(e){return y.Z.info("EME: Found compatible keysystem",u,d),{type:"create-media-key-system-access",value:{options:l,mediaKeySystemAccess:e}}})),(0,v.K)((function(){return y.Z.debug("EME: Rejected access to keysystem",u,d),e(t+1)})))}(0)}))}var te=n(2870),ne=new WeakMap;const re=function(e){ne.set(e,null)},ie=function(e,t){var n=t instanceof Uint8Array?t:new Uint8Array(t instanceof ArrayBuffer?t:t.buffer),r=(0,te.Z)(n);ne.set(e,{hash:r,serverCertificate:n})},ae=function(e){var t=ne.get(e);return void 0!==t&&(null!==t||void 0)},oe=function(e,t){var n=ne.get(e);if(null==n)return!1;var r=n.hash,i=n.serverCertificate,a=t instanceof Uint8Array?t:new Uint8Array(t instanceof ArrayBuffer?t:t.buffer);if((0,te.Z)(a)!==r||i.length!==a.length)return!1;for(var o=0;ose)return t(r);var o=Math.min(Math.pow(2,i)*ue,le);return y.Z.warn("EME: attempt to close a mediaKeySession failed, scheduling retry...",o),(0,B.S3)([(0,U.H)(o),(0,g.eX)(e),(0,g.GJ)(e)]).pipe((0,f.q)(1),(0,l.zg)((function(){return n(a)})))})))}(0);function t(e){return y.Z.error("EME: Could not close MediaKeySession: "+(e instanceof Error?e.toString():"Unknown error")),(0,r.of)(null)}}var ce=n(9689),fe=function(){function e(e){this.initData=e}return e.prototype.toJSON=function(){return(0,ce.J)(this.initData)},e.decode=function(e){return(0,ce.K)(e)},e}();function pe(e,t){var n,r;return null!==(r=null!==(n=he(e,t))&&void 0!==n?n:he(t,e))&&void 0!==r&&r}function he(e,t){if(0===e.length)return!1;if(t.length=0?this._storage[t].payload:void 0},t.getAndReuse=function(e){var t=this._findIndex(e);if(-1!==t){var n=this._storage.splice(t,1)[0];return this._storage.push(n),n.payload}},t.store=function(e,t){var n=this._findIndex(e);n>=0&&this._storage.splice(n,1);var r=this._formatValuesForStore(e.values);this._storage.push({type:e.type,values:r,payload:t})},t.storeIfNone=function(e,t){if(this._findIndex(e)>=0)return!1;var n=this._formatValuesForStore(e.values);return this._storage.push({type:e.type,values:n,payload:t}),!0},t.remove=function(e){var t=this._findIndex(e);if(-1!==t)return this._storage.splice(t,1)[0].payload},t._findIndex=function(e){for(var t=this._formatValuesForStore(e.values),n=this._storage.length-1;n>=0;n--){var r=this._storage[n];if(r.type===e.type&&pe(r.values,t))return n}return-1},t._formatValuesForStore=function(e){return e.slice().sort((function(e,t){return e.systemId===t.systemId?0:void 0===e.systemId?1:void 0===t.systemId||e.systemId=0?Oe(n):xe.y)})),T=function(e,t){return{totalRetry:null!=t?t:2,baseDelay:200,maxDelay:3e3,shouldRetry:function(e){return e instanceof Ie||(0,O.Z)(e)||!0!==e.noRetry},onRetry:function(t){return e.next({type:"warning",value:je(t)})}}}(d,f.retry);return(o=b,s=T,u=s.baseDelay,c=s.maxDelay,p=s.totalRetry,m=s.shouldRetry,g=s.onRetry,_=0,o.pipe((0,v.K)((function(e,t){if(!(0,O.Z)(m)&&!m(e)||_++>=p)throw e;"function"==typeof g&&g(e,_);var n=Math.min(u*Math.pow(2,_-1),c),r=(0,Le.Z)(n);return(0,U.H)(r).pipe((0,l.zg)((function(){return t})))})))).pipe((0,h.U)((function(t){return{type:"key-message-handled",value:{session:e,license:t}}})),(0,v.K)((function(e){var t=je(e);if(!(0,O.Z)(e)&&!0===e.fallbackOnLastTry)throw y.Z.warn("EME: Last `getLicense` attempt failed. Blacklisting the current session."),new Ge(t);throw t})),(0,L.O)({type:"session-message",value:{messageType:a,initializationData:i}}))}))),b=(0,a.T)(_,g).pipe((o=function(t){switch(t.type){case"key-message-handled":case"key-status-change-handled":return function(e,t,n){return(0,O.Z)(t)?(y.Z.info("EME: No message given, skipping session.update"),(0,r.of)({type:"no-update",value:{initializationData:n}})):(y.Z.info("EME: Updating MediaKeySession with message"),(0,I.Z)(e.update(t)).pipe((0,v.K)((function(e){var t=e instanceof Error?e.toString():"`session.update` failed";throw new M.Z("KEY_UPDATE_ERROR",t)})),(0,p.b)((function(){y.Z.info("EME: MediaKeySession update succeeded.")})),(0,D.h)({type:"session-updated",value:{session:e,license:t,initializationData:n}})))}(e,t.value.license,i);default:return(0,r.of)(t)}},(0,l.zg)(o,s,1))),T=(0,a.T)($e(e,t,n),b,m,d);return(0,O.Z)(e.closed)?T:T.pipe((0,De.R)((0,I.Z)(e.closed)))}function $e(e,t,n){return(0,A.P)((function(){if(0===e.keyStatuses.size)return u.E;var a=ze(e,t,n),o=a.warnings,s=a.blacklistedKeyIDs,l=a.whitelistedKeyIds,d=o.length>0?r.of.apply(void 0,o):u.E,c=(0,r.of)({type:"keys-update",value:{whitelistedKeyIds:l,blacklistedKeyIDs:s}});return(0,i.z)(d,c)}))}function je(e){if(e instanceof Ie)return new M.Z("KEY_LOAD_TIMEOUT","The license server took too much time to respond.");var t=new M.Z("KEY_LOAD_ERROR","An error occured when calling `getLicense`.");return!(0,O.Z)(e)&&(0,ye.Z)(e.message)&&(t.message=e.message),t}function Ye(e,t){return(0,A.P)((function(){return"function"!=typeof e.setServerCertificate?(y.Z.warn("EME: Could not set the server certificate. mediaKeys.setServerCertificate is not a function"),u.E):!0===ae(e)?(y.Z.info("EME: The MediaKeys already has a server certificate, skipping..."),u.E):(y.Z.info("EME: Setting server certificate on the MediaKeys"),re(e),function(e,t){return(0,A.P)((function(){return(0,F.Z)((function(){return(0,I.Z)(e.setServerCertificate(t))}),void 0).pipe((0,v.K)((function(e){y.Z.warn("EME: mediaKeys.setServerCertificate returned an error",e);var t=e instanceof Error?e.toString():"`setServerCertificate` error";throw new M.Z("LICENSE_SERVER_CERTIFICATE_ERROR",t)})))}))}(e,t).pipe((0,p.b)((function(){ie(e,t)})),(0,m.l)(),(0,v.K)((function(e){return(0,r.of)({type:"warning",value:e})}))))}))}var qe=R.Z.EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION,Xe=g.Oh;const Qe=function(e,t,n){y.Z.debug("EME: Starting EMEManager logic.");var g=new ve,_=new ve,E=Ee(e,t).pipe((0,l.zg)((function(e){if("attached-media-keys"!==e.type)return(0,r.of)(e);var t=e.value,n=t.mediaKeys,a=t.options.serverCertificate;return(0,O.Z)(a)?(0,r.of)(e):(0,i.z)(Ye(n,a),(0,r.of)(e))})),(0,d.d)()),w=E.pipe((0,c.h)((function(e){return"attached-media-keys"===e.type})),(0,f.q)(1)),S=Xe(e).pipe((0,p.b)((function(e){y.Z.debug("EME: Encrypted event received from media element.",e)})),(0,P.Z)((function(e){return k(e)}),null),(0,d.d)({refCount:!0})),A=n.pipe((0,p.b)((function(e){y.Z.debug("EME: Encrypted event received from Player",e)}))),x=(0,a.T)(A,S).pipe((0,l.zg)((function(e){return w.pipe((0,h.U)((function(t){return[e,t]})))})),(0,l.zg)((function(e){var t=e[0],n=e[1],i=n.value,d=i.mediaKeySystemAccess,c=i.stores,f=i.options,h=_.get(t);if(void 0!==h){if(void 0===t.type){y.Z.error("EME: The current session has already been blacklisted but the current content is not known. Throwing.");var E=h.sessionError;return E.fatal=!0,(0,o._)(E)}return y.Z.warn("EME: The current session has already been blacklisted. Blacklisting content."),(0,r.of)({type:"blacklist-protection-data",value:t})}var w,S=new s.t(1);if("content"===f.singleLicensePer&&!g.isEmpty()){var k=t.keyIds;if(void 0===k)return y.Z.warn("EME: Initialization data linked to unknown key id, we'll not able to fallback from it."),(0,r.of)({type:"init-data-ignored",value:{initializationData:t}});var A=g.getAll()[0];return A.lastKeyUpdate$.pipe((0,l.zg)((function(e){return k.every((function(t){for(var n=0;n=e.getLength())){var n=e.getLength(),r=n-t;y.Z.info("EME: Too many stored persistent sessions, removing some.",n,r),e.deleteOldSessions(r)}}(n,qe-1),n.add(t,i),s=!0}})),(0,v.K)((function(e){if(!(e instanceof Ge))throw e;_.store(t,e);var n=e.sessionError;if(void 0===t.type)throw y.Z.error("EME: Current session blacklisted and content not known. Throwing."),n.fatal=!0,n;return y.Z.warn("EME: Current session blacklisted. Blacklisting content."),(0,r.of)({type:"warning",value:n},{type:"blacklist-protection-data",value:t})})))})))):(y.Z.debug("EME: Init data already received. Skipping it."),(0,r.of)({type:"init-data-ignored",value:{initializationData:t}}))})));return(0,a.T)(E,S.pipe((0,h.U)((function(e){return{type:"encrypted-event-received",value:e}}))),x)}},6033:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=new WeakMap;const i={setState:function(e,t){r.set(e,t)},getState:function(e){var t=r.get(e);return void 0===t?null:t},clearState:function(e){r.set(e,null)}}},4507:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(4370),i=n(8170),a=n(5709),o=n(6139);var s=n(1473),u=n(5157),l=n(7874),d=n(3887),c=s.Oh;function f(e,t,n){var s=(0,r.T)(c(e),n);return null==l.Z.emeManager?(0,r.T)(s.pipe((0,a.U)((function(){throw d.Z.error("Init: Encrypted event but EME feature not activated"),new u.Z("MEDIA_IS_ENCRYPTED_ERROR","EME feature not activated.")}))),(0,i.of)({type:"eme-disabled"})):0===t.length?(0,r.T)(s.pipe((0,a.U)((function(){throw d.Z.error("Init: Ciphered media and no keySystem passed"),new u.Z("MEDIA_IS_ENCRYPTED_ERROR","Media is encrypted and no `keySystems` given")}))),(0,i.of)({type:"eme-disabled"})):"function"!=typeof o.N?(0,r.T)(s.pipe((0,a.U)((function(){throw d.Z.error("Init: Encrypted event but no EME API available"),new u.Z("MEDIA_IS_ENCRYPTED_ERROR","Encryption APIs not found.")}))),(0,i.of)({type:"eme-disabled"})):(d.Z.debug("Init: Creating EMEManager"),l.Z.emeManager(e,t,n))}},7247:(e,t,n)=>{"use strict";n.d(t,{Z:()=>g});var r=n(8170),i=n(9795),a=n(5602),o=n(486),s=n(6008),u=n(1015),l=n(7746),d=n(1410),c=n(8117),f=n(5561);var p=n(3666);function h(){return p.op}var v=n(3887);function m(e){return function(e){return(0,d.P)((function(){return(0,f.Z)((function(){return(0,c.Z)(e.play())}),void 0)}))}(e).pipe((0,a.h)("autoplay"),(0,o.K)((function(e){if(e instanceof Error&&"NotAllowedError"===e.name)return v.Z.warn("Init: Media element can't play. It may be due to browser auto-play policies."),(0,r.of)("autoplay-blocked");throw e})))}function g(e,t,n,a){var o=e.pipe((0,s.h)((function(e){var n=e.seeking,r=e.stalled,i=e.readyState,o=e.currentRange;return!n&&null===r&&(function(e,t){return!e||!p.SB||t}(a,t.hasAttribute("playsinline"))?(i>=4||3===i&&null!==o)&&(!h()||t.duration>0):i>=1&&t.duration>0)})),(0,u.q)(1),(0,l.zg)((function(){return n?m(t):(t.autoplay&&v.Z.warn("Init: autoplay is enabled on HTML media element. Media will play as soon as possible."),(0,r.of)("loaded"))})));return h()?e.pipe((0,s.h)((function(e){return e.readyState>=1})),(0,l.zg)((function(){return 0===t.duration?(0,i.z)((0,r.of)("not-loaded-metadata"),o):o}))):o}},8343:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r={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}}}},8969:(e,t,n)=>{"use strict";n.d(t,{Z:()=>S});var r=n(5631),i=n(8170),a=n(4370),o=n(7746),s=n(9095),u=n(6738),l=n(5709),d=n(6008),c=n(1015),f=n(3756),p=n(3068),h=n(4379),v=n(3887),m=n(5767);var g=n(3714),y=n(8025),_=n(4507),b=n(7247),T=n(8343),E=n(2447),w=n(2983);function S(e){var t=e.autoPlay,n=e.clock$,S=e.keySystems,k=e.mediaElement,A=e.speed$,x=e.setCurrentTime,I=e.startAt,Z=e.url;if((0,m.Z)(k),null==Z)throw new Error("No URL for a DirectFile content");var R=function(e,t){return new h.y((function(n){return v.Z.info("Setting URL to Element",t,e),e.src=t,n.next(void 0),function(){(0,m.Z)(e)}}))}(k,Z);v.Z.debug("Init: Calculating initial time");var M=function(){return 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 v.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}(k,I)};v.Z.debug("Init: Initial time calculated:",M);var C=R.pipe((0,o.zg)((function(){return(0,_.Z)(k,S,r.E)})),(0,y.Z)(),(0,s.B)()),N=(0,E.Z)(k),P=(0,w.Z)(k,A,n,{pauseWhenStalled:!0}).pipe((0,u.l)()),O=n.pipe((0,l.U)((function(e){return null===e.stalled?T.Z.unstalled():T.Z.stalled(e.stalled)}))),D=C.pipe((0,d.h)((function(e){return"created-media-keys"===e.type?(e.value.attachMediaKeys$.next(),!0):"eme-disabled"===e.type||"attached-media-keys"===e.type})),(0,c.q)(1),(0,f.j)((0,b.Z)(n,k,t,!0)),(0,o.zg)((function(e){if("autoplay-blocked"===e){var t=new g.Z("MEDIA_ERR_BLOCKED_AUTOPLAY","Cannot trigger auto-play automatically: your browser does not allow it.");return(0,i.of)(T.Z.warning(t),T.Z.loaded(null))}if("not-loaded-metadata"===e){var n=new g.Z("MEDIA_ERR_NOT_LOADED_METADATA","Cannot load automatically: your browser falsely announced having loaded the content.");return(0,i.of)(T.Z.warning(n))}return(0,i.of)(T.Z.loaded(null))}))),L=n.pipe((0,d.h)((function(e){return e.readyState>0||"loadedmetadata"===e.event})),(0,c.q)(1),(0,p.b)((function(){var e=M();k.currentTime!==e&&(v.Z.info("Init: Set initial time",e),x(e))})),(0,u.l)());return(0,a.T)(D,L,C,N,P,O)}},2447:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7027),i=n(7746),a=n(3714);function o(e){return(0,r.R)(e,"error").pipe((0,i.zg)((function(){switch(null==e.error?0:e.error.code){case 1:throw new a.Z("MEDIA_ERR_ABORTED","The fetching of the associated resource was aborted by the user's request.");case 2:throw new a.Z("MEDIA_ERR_NETWORK","A network error occurred which prevented the media from being successfully fetched");case 3:throw new a.Z("MEDIA_ERR_DECODE","An error occurred while trying to decode the media resource");case 4:throw new a.Z("MEDIA_ERR_SRC_NOT_SUPPORTED","The media resource has been found to be unsuitable.");default:throw new a.Z("MEDIA_ERR_UNKNOWN","The HTMLMediaElement errored due to an unknown reason.")}})))}},2983:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(8170),i=n(1410),a=n(5709),o=n(3485),s=n(1931),u=n(6381),l=n(3068),d=n(3887);function c(e,t,n,c){var f=c.pauseWhenStalled;return(void 0===f||f?n.pipe((0,a.U)((function(e){return null!==e.stalled})),(0,o.O)(!1),(0,s.x)()):(0,r.of)(!1)).pipe((0,u.w)((function(n){return n?(0,i.P)((function(){return d.Z.info("Init: Pause playback to build buffer"),e.playbackRate=0,(0,r.of)(0)})):t.pipe((0,l.b)((function(t){d.Z.info("Init: Resume playback speed",t),e.playbackRate=t})))})))}},7127:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l});var r=n(1788),i=n(1410),a=n(8170),o=n(3887),s=n(4123),u=n(4309);const l=function(e){function t(){var t;return o.Z.debug("ISB: Creating ImageSegmentBuffer"),(t=e.call(this)||this).bufferType="image",t._buffered=new u.Z,t}(0,r.Z)(t,e);var n=t.prototype;return n.pushChunk=function(e){var t=this;return(0,i.P)((function(){var n,r;if(o.Z.debug("ISB: appending new data."),null===e.data.chunk)return(0,a.of)(void 0);var i=e.data,s=i.appendWindow,u=i.chunk,l=u.start,d=u.end,c=u.timescale,f=null!==(n=s[0])&&void 0!==n?n:0,p=null!==(r=s[1])&&void 0!==r?r:1/0,h=l/c,v=d/c,m=Math.max(f,h),g=Math.min(p,v);return t._buffered.insert(m,g),null!==e.inventoryInfos&&t._segmentInventory.insertChunk(e.inventoryInfos),(0,a.of)(void 0)}))},n.removeBuffer=function(e,t){return(0,i.P)((function(){return o.Z.info("ISB: ignored image data remove order",e,t),(0,a.of)(void 0)}))},n.endOfSegment=function(e){var t=this;return(0,i.P)((function(){return t._segmentInventory.completeSegment(e),(0,a.of)(void 0)}))},n.getBufferedRanges=function(){return this._buffered},n.dispose=function(){o.Z.debug("ISB: disposing image SegmentBuffer"),this._buffered.remove(0,1/0)},t}(s.C)},5192:(e,t,n)=>{"use strict";n.d(t,{Z:()=>L});var r=n(1788),i=n(4370),a=n(6564),o=n(9795),s=n(8170),u=n(211),l=n(1410),d=n(3485),c=n(1198),f=n(5602),p=n(1558),h=n(1473),v=n(4379),m=n(5709),g=n(1931),y=n(3887),_=n(2203).Z?void 0:window.ResizeObserver;var b=n(944),T=n(4123),E=n(4309),w=n(7874);function S(e,t){return Math.abs(e-t)<=.2}function k(e,t){for(var n=e.length-1;n>=0;n--){if(e[n].startt)return e.slice(n,e.length)}return[]}function x(e,t,n){var r=Math.max(e.start,t),i=k(e.cues,t),a={start:e.start,end:r,cues:i},o=Math.min(n,e.end),s=A(e.cues,n);return[a,{start:o,end:e.end,cues:s}]}var I=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=A(a.cues,n),a.start=n;else{var o=x(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=k(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||S(i.end,t.end)?r[e]=i:(t.start>=i.end||(t.cues=A(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(S(s.end,n))return s.cues=k(s.cues,t),s.end=t,void r.splice(o+1,0,i);if(s.end>n){var u=x(s,t,n),l=u[0],d=u[1];return this._cuesBuffer[o]=l,r.splice(o+1,0,i),void r.splice(o+2,0,d)}for(s.cues=k(s.cues,t),s.end=t,s=r[o+1];void 0!==s&&n>s.end;)r.splice(o,1),s=r[o];return void a(o)}}r.push(i)},e}();function Z(e,t,n,r){for(var i=[t/n.columns,e/n.rows],a=r.getElementsByClassName("proportional-style"),o=0;o0}var R=h.C1,M=h.ik,C=h.d5,N=b.Z.MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL,P=b.Z.TEXT_TRACK_SIZE_CHECKS_INTERVAL;function O(e,t){try{e.removeChild(t)}catch(e){y.Z.warn("HTSB: Can't remove text track: not in the element.")}}function D(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}}const L=function(e){function t(t,n){var r;return y.Z.debug("HTSB: Creating HTMLTextSegmentBuffer"),(r=e.call(this)||this).bufferType="text",r._buffered=new E.Z,r._videoElement=t,r._textTrackElement=n,r._clearSizeUpdates$=new u.xQ,r._destroy$=new u.xQ,r._buffer=new I,r._currentCues=[],function(e){var t=C(e),n=M(e),r=R(e),u=(0,i.T)(n,r),l=(0,a.F)(N).pipe((0,d.O)(null));return u.pipe((0,d.O)(null),(0,c.c)((0,o.z)(l.pipe((0,f.h)(!0),(0,p.R)(t)),(0,s.of)(!1))))}(r._videoElement).pipe((0,p.R)(r._destroy$)).subscribe((function(e){if(e){var t=Math.max(r._videoElement.currentTime+N/1e3/2,0),n=r._buffer.get(t);0===n.length?r._disableCurrentCues():r._displayCues(n)}else r._disableCurrentCues()})),r}(0,r.Z)(t,e);var n=t.prototype;return n.pushChunk=function(e){var t=this;return(0,l.P)((function(){return t.pushChunkSync(e),(0,s.of)(void 0)}))},n.removeBuffer=function(e,t){var n=this;return(0,l.P)((function(){return n.removeBufferSync(e,t),(0,s.of)(void 0)}))},n.endOfSegment=function(e){var t=this;return(0,l.P)((function(){return t._segmentInventory.completeSegment(e),(0,s.of)(void 0)}))},n.getBufferedRanges=function(){return this._buffered},n.dispose=function(){y.Z.debug("HTSB: Disposing HTMLTextSegmentBuffer"),this._disableCurrentCues(),this._buffer.remove(0,1/0),this._buffered.remove(0,1/0),this._destroy$.next(),this._destroy$.complete()},n.pushChunkSync=function(e){var t,n;y.Z.debug("HTSB: Appending new html text tracks");var r=e.data,i=r.timestampOffset,a=r.appendWindow,o=r.chunk;if(null!==o){var s,u,l=o.start,d=o.end,c=o.data,f=o.type,p=o.language,h=null!==(t=a[0])&&void 0!==t?t:0,v=null!==(n=a[1])&&void 0!==n?n:1/0,m=function(e,t,n,r){y.Z.debug("HTSB: Finding parser for html text tracks:",e);var i=w.Z.htmlTextTracksParsers[e];if("function"!=typeof i)throw new Error("no parser found for the given text track");y.Z.debug("HTSB: Parser found, parsing...");var a=i(t,n,r);return y.Z.debug("HTTB: Parsed successfully!",a),a}(f,c,i,p);if(0!==h&&v!==1/0){for(var g=0;g=0&&m[g].start>=v;)g--;for(m.splice(g,m.length),g=m.length-1;g>=0&&m[g].end>v;)m[g].end=v,g--}if(void 0!==l)s=Math.max(h,l);else{if(m.length<=0)return void y.Z.warn("HTSB: Current text tracks have no cues nor start time. Aborting");y.Z.warn("HTSB: No start time given. Guessing from cues."),s=m[0].start}if(void 0!==d)u=Math.min(v,d);else{if(m.length<=0)return void y.Z.warn("HTSB: Current text tracks have no cues nor end time. Aborting");y.Z.warn("HTSB: No end time given. Guessing from cues."),u=m[m.length-1].end}u<=s?y.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(m,s,u),this._buffered.insert(s,u))}},n.removeBufferSync=function(e,t){y.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._clearSizeUpdates$.next(),this._currentCues.length>0){for(var e=0;e0&&function(e,t){return(0,l.P)((function(){if(void 0!==_){var n=-1,r=-1;return new v.y((function(t){var i=new _((function(e){if(0!==e.length){var i=e[0].contentRect,a=i.height,o=i.width;a===n&&o===r||(n=a,r=o,t.next({height:a,width:o}))}else y.Z.error("Compat: Resized but no observed element.")}));return i.observe(e),function(){i.disconnect()}}))}return(0,a.F)(t).pipe((0,d.O)(null),(0,m.U)((function(){var t=e.getBoundingClientRect();return{height:t.height,width:t.width}})),(0,g.x)((function(e,t){return e.height===t.height&&e.width===t.width})))}))}(this._textTrackElement,P).pipe((0,p.R)(this._clearSizeUpdates$),(0,p.R)(this._destroy$)).subscribe((function(e){for(var t=e.height,n=e.width,r=0;r{"use strict";n.d(t,{Z:()=>f});var r=n(1788),i=n(1410),a=n(8170),o=n(3666);var s=n(3887);function u(e,t){if(o.vU&&function(e,t){var n=e.activeCues;if(null===n)return!1;for(var r=0;r0?e.textTracks[u-1]:e.addTextTrack(s)).mode=t?null!==(n=i.HIDDEN)&&void 0!==n?n:"hidden":null!==(r=i.SHOWING)&&void 0!==r?r:"showing"}else a=document.createElement("track"),e.appendChild(a),i=a.track,a.kind=s,i.mode=t?"hidden":"showing";return{track:i,trackElement:a}}(t,n),a=i.track,u=i.trackElement;return r.bufferType="text",r._buffered=new d.Z,r._videoElement=t,r._track=a,r._trackElement=u,r}(0,r.Z)(t,e);var n=t.prototype;return n.pushChunk=function(e){var t=this;return(0,i.P)((function(){var n,r;if(s.Z.debug("NTSB: Appending new native text tracks"),null===e.data.chunk)return(0,a.of)(void 0);var i,o,u=e.data,l=u.timestampOffset,d=u.appendWindow,f=u.chunk,p=f.start,h=f.end,v=f.data,m=f.type,g=f.language,y=null!==(n=d[0])&&void 0!==n?n:0,_=null!==(r=d[1])&&void 0!==r?r:1/0,b=function(e,t,n,r){s.Z.debug("NTSB: Finding parser for native text tracks:",e);var i=c.Z.nativeTextTracksParsers[e];if("function"!=typeof i)throw new Error("no parser found for the given text track");s.Z.debug("NTSB: Parser found, parsing...");var a=i(t,n,r);return s.Z.debug("NTSB: Parsed successfully!",a),a}(m,v,l,g);if(0!==y&&_!==1/0){for(var T=0;T=0&&b[T].startTime>=_;)T--;for(b.splice(T,b.length),T=b.length-1;T>=0&&b[T].endTime>_;)b[T].endTime=_,T--}if(void 0!==p)i=Math.max(y,p);else{if(b.length<=0)return s.Z.warn("NTSB: Current text tracks have no cues nor start time. Aborting"),(0,a.of)(void 0);s.Z.warn("NTSB: No start time given. Guessing from cues."),i=b[0].startTime}if(void 0!==h)o=Math.min(_,h);else{if(b.length<=0)return s.Z.warn("NTSB: Current text tracks have no cues nor end time. Aborting"),(0,a.of)(void 0);s.Z.warn("NTSB: No end time given. Guessing from cues."),o=b[b.length-1].endTime}if(o<=i)return s.Z.warn("NTSB: Invalid text track appended: ","the start time is inferior or equal to the end time."),(0,a.of)(void 0);if(b.length>0){var E=b[0],w=t._track.cues;null!==w&&w.length>0&&E.startTime=0;i--){var a=r[i],o=a.startTime,l=a.endTime;o>=e&&o<=t&&l<=t&&u(n,a)}this._buffered.remove(e,t)},t}(l.C)},4123:(e,t,n)=>{"use strict";n.d(t,{C:()=>m,f:()=>v});var r=n(944),i=n(3887),a=n(5952),o=n(5278),s=r.Z.MAX_MANIFEST_BUFFERED_START_END_DIFFERENCE,u=r.Z.MAX_MANIFEST_BUFFERED_DURATION_DIFFERENCE,l=r.Z.MINIMUM_SEGMENT_SIZE,d=function(){function e(){this._inventory=[]}var t=e.prototype;return t.reset=function(){this._inventory.length=0},t.synchronizeBuffered=function(e){for(var t=this._inventory,n=0,r=t[0],a=null==r?void 0:r.infos.adaptation.type,s=e.length,u=0;u0){var g=t[f+m-1];v={end:(0,o.Z)(g.bufferedEnd,g.end),precizeEnd:g.precizeEnd},i.Z.debug("SI: "+m+" segments GCed.",a),t.splice(f,m),n=f}if(void 0===r)return;if(c-(0,o.Z)(r.bufferedStart,r.start)>=l){if(p(r,d,v,a),n===t.length-1)return void h(r,c,a);r=t[++n];for(var y=(0,o.Z)(r.bufferedStart,r.start),_=(0,o.Z)(r.bufferedEnd,r.end),b=u=l&&(void 0===b||c-y>=_-b);){var T=t[n-1];void 0===T.bufferedEnd&&(T.bufferedEnd=r.precizeStart?r.start:T.end,i.Z.debug("SI: calculating buffered end of contiguous segment",a,T.bufferedEnd,T.end)),r.bufferedStart=T.bufferedEnd,void 0!==(r=t[++n])&&(y=(0,o.Z)(r.bufferedStart,r.start),_=(0,o.Z)(r.bufferedEnd,r.end))}}var E=t[n-1];void 0!==E&&h(E,c,a)}}null!=r&&(i.Z.debug("SI: last segments have been GCed",a,n,t.length),t.splice(n,t.length-n)),void 0!==a&&"DEBUG"===i.Z.getLevel()&&i.Z.debug("SI: current "+a+" 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=s)i.Z.warn("SI: Invalid chunked inserted: starts before it ends",u,o,s);else{for(var l=this._inventory,d={partiallyPushed:!0,estimatedStart:o,start:o,end:s,precizeStart:!1,precizeEnd:!1,bufferedStart:void 0,bufferedEnd:void 0,infos:{segment:a,period:t,adaptation:n,representation:r}},c=l.length-1;c>=0;c--){var f=l[c];if(f.start<=o){if(f.end<=o){for(i.Z.debug("SI: Pushing segment strictly after previous one.",u,o,f.end),this._inventory.splice(c+1,0,d),c+=2;cd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,d.end,l[c].start),l[c].start=d.end,l[c].bufferedStart=void 0,void(l[c].precizeStart=l[c].precizeStart&&d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[c].start,l[c].end),l.splice(c,1)}return}if(f.start===o){if(f.end<=s){for(i.Z.debug("SI: Segment pushed replace another one",u,o,s,f.end),this._inventory.splice(c,1,d),c+=1;cd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,d.end,l[c].start),l[c].start=d.end,l[c].bufferedStart=void 0,void(l[c].precizeStart=l[c].precizeStart&&d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[c].start,l[c].end),l.splice(c,1)}return}return i.Z.debug("SI: Segment pushed ends before another with the same start",u,o,s,f.end),l.splice(c,0,d),f.start=d.end,f.bufferedStart=void 0,void(f.precizeStart=f.precizeStart&&d.precizeEnd)}if(f.end<=d.end){for(i.Z.debug("SI: Segment pushed updates end of previous one",u,o,s,f.start,f.end),this._inventory.splice(c+1,0,d),f.end=d.start,f.bufferedEnd=void 0,f.precizeEnd=f.precizeEnd&&d.precizeStart,c+=2;cd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,d.end,l[c].start),l[c].start=d.end,l[c].bufferedStart=void 0,void(l[c].precizeStart=l[c].precizeStart&&d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[c].start,l[c].end),l.splice(c,1)}return}i.Z.debug("SI: Segment pushed is contained in a previous one",u,o,s,f.start,f.end);var p={partiallyPushed:f.partiallyPushed,start:d.end,end:f.end,precizeStart:f.precizeStart&&f.precizeEnd&&d.precizeEnd,precizeEnd:f.precizeEnd,bufferedStart:void 0,bufferedEnd:f.end,infos:f.infos};return f.end=d.start,f.bufferedEnd=void 0,f.precizeEnd=f.precizeEnd&&d.precizeStart,l.splice(c+1,0,d),void l.splice(c+2,0,p)}}var h=this._inventory[0];if(void 0===h)return i.Z.debug("SI: first segment pushed",u,o,s),void this._inventory.push(d);if(!(h.start>=s)){if(h.end<=s){for(i.Z.debug("SI: Segment pushed starts before and completely recovers the previous first one",u,o,s,h.start,h.end),this._inventory.splice(0,1,d);l.length>1&&l[1].startd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,d.end,l[1].start),l[1].start=d.end,l[1].bufferedStart=void 0,void(l[1].precizeStart=d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[1].start,l[1].end),l.splice(1,1)}return}return i.Z.debug("SI: Segment pushed start of the next one",u,o,s,h.start,h.end),h.start=s,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",u,o,s,h.start),this._inventory.splice(0,0,d)}}},t.completeSegment=function(e){if(!e.segment.isInit){for(var t=this._inventory,n=!1,r=0;r0&&(this._inventory.splice(o+1,u),r-=u),this._inventory[o].partiallyPushed=!1,this._inventory[o].end=l,this._inventory[o].bufferedEnd=d}n||i.Z.warn("SI: Completed Segment not found",e)}},t.getInventory=function(){return this._inventory},e}();function c(e){if(void 0===e.bufferedStart||e.partiallyPushed)return!1;var t=e.start,n=e.end-t;return Math.abs(t-e.bufferedStart)<=s&&(void 0===e.bufferedEnd||e.bufferedEnd>e.bufferedStart&&Math.abs(e.bufferedEnd-e.bufferedStart-n)<=Math.min(u,n/3))}function f(e){if(void 0===e.bufferedEnd||e.partiallyPushed)return!1;var t=e.start,n=e.end,r=n-t;return Math.abs(n-e.bufferedEnd)<=s&&null!=e.bufferedStart&&e.bufferedEnd>e.bufferedStart&&Math.abs(e.bufferedEnd-e.bufferedStart-r)<=Math.min(u,r/3)}function p(e,t,n,r){void 0!==e.bufferedStart?(e.bufferedStartt&&(n.precizeEnd||e.start-n.end<=s)?(i.Z.debug("SI: buffered start is end of previous segment",r,t,e.start,n.end),e.bufferedStart=n.end,c(e)&&(e.start=n.end,e.precizeStart=!0)):e.start-t<=s?(i.Z.debug("SI: found true buffered start",r,t,e.start),e.bufferedStart=t,c(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<=s&&f(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<=s?(i.Z.debug("SI: found true buffered end",n,t,e.end),e.bufferedEnd=t,f(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 v,m=function(){function e(){this._segmentInventory=new d}var t=e.prototype;return t.synchronizeInventory=function(){this._segmentInventory.synchronizeBuffered(this.getBufferedRanges())},t.getInventory=function(){return this._segmentInventory.getInventory()},t.getPendingOperations=function(){return[]},e}();!function(e){e[e.Push=0]="Push",e[e.Remove=1]="Remove",e[e.EndOfSegment=2]="EndOfSegment"}(v||(v={}))},4309:(e,t,n)=>{"use strict";n.d(t,{Z:()=>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}()},3801:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3349),i=n(1788),a=function(e){function t(n){var i;return i=e.call(this)||this,Object.setPrototypeOf((0,r.Z)(i),t.prototype),i.name="AssertionError",i.message=n,i}return(0,i.Z)(t,e),t}((0,n(3786).Z)(Error))},5157:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(3349),i=n(1788),a=n(3786),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="EncryptedMediaError",a.type=o.ZB.ENCRYPTED_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))},5992:(e,t,n)=>{"use strict";n.d(t,{ZB:()=>r,br:()=>i,SM:()=>a});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:(e,t,n)=>{"use strict";function r(e,t,n){return e+" ("+t+") "+n}n.d(t,{Z:()=>r})},9822:(e,t,n)=>{"use strict";n.d(t,{Z:()=>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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(3349),i=n(1788),a=n(3786),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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(3349),i=n(1788),a=n(3786),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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(3349),i=n(1788),a=n(3786),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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3349),i=n(1788),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,s.xhr=o,s.status=i,s.type=a,s.message=a,s}return(0,i.Z)(t,e),t}((0,n(3786).Z)(Error))},7273:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r={directfile:null,emeManager:null,htmlTextTracksBuffer:null,htmlTextTracksParsers:{},imageBuffer:null,imageParser:null,nativeTextTracksBuffer:null,nativeTextTracksParsers:{},transports:{}}},7874:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=n(7273).Z},3887:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(8894);const 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},e}())},5952:(e,t,n)=>{"use strict";function r(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}n.d(t,{Z:()=>r})},1966:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>Z});var r=n(1788),i=n(4791),a=n(3274),o=n(1959),s=n(908),u=n(8806),l=n(3714),d=n(3887),c=n(7714),f=n(1946),p=n(7829);const h="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}))};var v=n(3774);const m=function(){function e(e,t){var n;this.id=e.id,this.bitrate=e.bitrate,this.codec=e.codecs,null!=e.height&&(this.height=e.height),null!=e.width&&(this.width=e.width),null!=e.mimeType&&(this.mimeType=e.mimeType),void 0!==e.contentProtections&&(this.contentProtections=e.contentProtections),null!=e.frameRate&&(this.frameRate=e.frameRate),this.index=e.index,this.isSupported="audio"!==t.type&&"video"!==t.type||(n=this.getMimeTypeString(),null!=v.JJ&&("function"!=typeof v.JJ.isTypeSupported||v.JJ.isTypeSupported(n)))}var t=e.prototype;return t.getMimeTypeString=function(){var e,t;return(null!==(e=this.mimeType)&&void 0!==e?e:"")+';codecs="'+(null!==(t=this.codec)&&void 0!==t?t:"")+'"'},t.getEncryptionData=function(e){for(var t,n=this.getAllEncryptionData(),r=[],i=0;i0&&!u){d.Z.warn("Incompatible codecs for adaptation",e);var y=new l.Z("MANIFEST_INCOMPATIBLE_CODECS_ERROR","An Adaptation contains only incompatible codecs.");this.parsingErrors.push(y)}}var t=e.prototype;return t.getAvailableBitrates=function(){for(var e=[],t=0;t0}));if(o.every((function(e){return!e.isSupported}))&&a.length>0&&("video"===i||"audio"===i))throw new l.Z("MANIFEST_PARSE_ERROR","No supported "+i+" adaptations");return o.length>0&&(r[i]=o),r}),{}),!Array.isArray(this.adaptations.video)&&!Array.isArray(this.adaptations.audio))throw new l.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,T.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,a.Z)(this.getAdaptations(),(function(t){var n=t.id;return e===n}))},t.getPlayableAdaptations=function(e){if(void 0===e)return this.getAdaptations().filter((function(e){return e.getPlayableRepresentations().length>0}));var t=this.adaptations[e];return void 0===t?[]:t.filter((function(e){return e.getPlayableRepresentations().length>0}))},e}(),w=function(){function e(e){this._mediaURLs=e.media}var t=e.prototype;return t.getInitSegment=function(){return null},t.getSegments=function(){return[{id:"0",isInit:!1,number:0,mediaURLs:[this._mediaURLs],time:0,end:Number.MAX_VALUE,duration:Number.MAX_VALUE,timescale:1}]},t.getFirstPosition=function(){},t.getLastPosition=function(){},t.shouldRefresh=function(){return!1},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},t.isSegmentStillAvailable=function(){return!0},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){return!0},t.isInitialized=function(){return!0},t._replace=function(){d.Z.warn("Tried to replace a static RepresentationIndex")},t._update=function(){d.Z.warn("Tried to update a static RepresentationIndex")},e}();!function(e){e[e.Full=0]="Full",e[e.Partial=1]="Partial"}(y||(y={}));var S=n(5138);function k(e,t,n){e.start=t.start,e.end=t.end,e.duration=t.duration;for(var r=e.getAdaptations(),i=t.getAdaptations(),o=function(e){var t=r[e],o=(0,a.Z)(i,(function(e){return e.id===t.id}));if(void 0===o)d.Z.warn('Manifest: Adaptation "'+r[e].id+'" not found when merging.');else for(var s=r[e].representations,u=o.representations,l=function(e){var t=s[e],r=(0,a.Z)(u,(function(e){return e.id===t.id}));void 0===r?d.Z.warn('Manifest: Representation "'+s[e].id+'" not found when merging.'):n===y.Full?t.index._replace(r.index):t.index._update(r.index)},c=0;c0&&r._addSupplementaryImageAdaptations(u),o.length>0&&r._addSupplementaryTextAdaptations(o),r}(0,r.Z)(t,e);var n=t.prototype;return n.getPeriod=function(e){return(0,a.Z)(this.periods,(function(t){return e===t.id}))},n.getPeriodForTime=function(e){return(0,a.Z)(this.periods,(function(t){return e>=t.start&&(void 0===t.end||t.end>e)}))},n.getNextPeriod=function(e){return(0,a.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,a.Z)(this.periods,(function(e){return void 0===e.end||t0&&this.trigger("decipherabilityUpdate",r)},n.addUndecipherableProtectionData=function(e){var t=I(this,(function(t){var n,r;if(!1===t.decipherable)return!1;for(var a=null!==(r=null===(n=t.contentProtections)||void 0===n?void 0:n.initData)&&void 0!==r?r:[],o=function(t){if((void 0===e.type||a[t].type===e.type)&&e.values.every((function(e){return a[t].values.some((function(t){return(void 0===e.systemId||t.systemId===e.systemId)&&(0,i.Z)(t.data,e.data)}))})))return{v:!1}},s=0;s0&&this.trigger("decipherabilityUpdate",t)},n.getAdaptations=function(){(0,u.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,u.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,u.Z)("manifest.getAdaptation(id) is deprecated. Please use manifest.period[].getAdaptation(id) instead"),(0,a.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,r=e.mimeType,i=e.url,a="gen-image-ada-"+A(),o="gen-image-rep-"+A(),s=new _({id:a,type:"image",representations:[{bitrate:0,id:o,mimeType:r,index:new w({media:i})}]},{isManuallyAdded:!0});return(n=t.parsingErrors).push.apply(n,s.parsingErrors),s}));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,a=n.url,o=n.language,s=n.languages,u=n.closedCaption,l=null!=o?[o]:null!=s?s:[];return e.concat(l.map((function(e){var n,o="gen-text-ada-"+A(),s="gen-text-rep-"+A(),l=new _({id:o,type:"text",language:e,closedCaption:u,representations:[{bitrate:0,id:s,mimeType:r,codecs:i,index:new w({media:a})}]},{isManuallyAdded:!0});return(n=t.parsingErrors).push.apply(n,l.parsingErrors),l})))}),[]);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.lifetime=e.lifetime,this.parsingErrors=e.parsingErrors,this.suggestedPresentationDelay=e.suggestedPresentationDelay,this.transport=e.transport,this.publishTime=e.publishTime,t===y.Full)this._timeBounds=e._timeBounds,this.uris=e.uris,function(e,t){for(var n=0,r=0;re.length)d.Z.error("Manifest: error when updating Periods");else{n0&&e.push.apply(e,l)}}(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.starti&&(e.splice(i,s-i),s=i),k(e[s],o,y.Full),i++}i0;){var r=this.periods[0];if(void 0===r.end||r.end>n)break;this.periods.shift()}}this.adaptations=void 0===this.periods[0]?{}:this.periods[0].adaptations,this.trigger("manifestUpdate",null)},t}(o.Z)},2689:(e,t,n)=>{"use strict";n.d(t,{s:()=>r});var r=Math.pow(2,32)-1},2297:(e,t,n)=>{"use strict";n.d(t,{iz:()=>o,t_:()=>a,Qy:()=>s,Xj:()=>l,nR:()=>u});var r=n(3887),i=n(6968);function a(e,t){var n=s(e,t);return null!==n?e.subarray(n[1],n[2]):null}function o(e,t){var n=s(e,t);return null!==n?e.subarray(n[0],n[2]):null}function s(e,t){for(var n,r,a=e.length,o=0,s=0;o+8<=a;){if(r=o,s=(0,i.pX)(e,r),r+=4,n=(0,i.pX)(e,r),r+=4,0===s)s=a-o;else if(1===s){if(r+8>a)return null;s=(0,i.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 u(e,t,n,r,a){for(var o,s=e.length,u=0;us)return;o=(0,i.pV)(e,l),l+=8}if(1970628964===d&&l+16<=s&&(0,i.pX)(e,l)===t&&(0,i.pX)(e,l+4)===n&&(0,i.pX)(e,l+8)===r&&(0,i.pX)(e,l+12)===a)return l+=16,e.subarray(l,u+o)}}function l(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,a=(0,i.pX)(e,n);n+=4;var o=(0,i.pX)(e,n);if(n+=4,0===a)a=t;else if(1===a){if(n+8>t)return r.Z.warn("ISOBMFF: box too short, cannot find offsets"),null;a=(0,i.pV)(e,n),n+=8}if(a<0)throw new Error("ISOBMFF: Size out of range");return 1970628964===o&&(n+=16),[0,n,a]}},6807:(e,t,n)=>{"use strict";n.d(t,{XA:()=>i,Le:()=>a,fs:()=>o,E3:()=>s});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.t_)(e,1835295092)}function o(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 s(e,t){return void 0===t&&(t=0),(0,r.t_)(e.subarray(t),1701671783)}},6490:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s,Y:()=>u});var r=n(3887);const 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))};var 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:(e,t,n)=>{"use strict";n.d(t,{LD:()=>c,Qx:()=>l,MM:()=>d,Wf:()=>u,J6:()=>f,s9:()=>p});var r=n(6968),i=n(3635),a=n(2689),o=n(2297),s=n(6807);function u(e,t){var n=(0,o.Qy)(e,1936286840);if(null===n)return null;var i=t,a=n[2]-n[0],s=n[1],u=e[s];s+=8;var l,d=(0,r.pX)(e,s);if(s+=4,0===u)l=(0,r.pX)(e,s),s+=4,i+=(0,r.pX)(e,s)+a,s+=4;else{if(1!==u)return null;l=(0,r.pV)(e,s),s+=8,i+=(0,r.pV)(e,s)+a,s+=8}var c=[];s+=2;var f=(0,r.zK)(e,s);for(s+=2;--f>=0;){var p=(0,r.pX)(e,s);s+=4;var h=2147483647&p;if(1===(2147483648&p)>>>31)throw new Error("sidx with reference_type `1` not yet implemented");var v=(0,r.pX)(e,s);s+=4,s+=4,c.push({time:l,duration:v,count:0,timescale:d,range:[i,i+h-1]}),l+=v,i+=h}return c}function l(e){var t=(0,s.XA)(e);if(null!==t){var n=(0,o.t_)(t,1952867444);if(null!==n){var i=n[0];return 1===i?(0,r.pV)(n,4):0===i?(0,r.pX)(n,4):void 0}}}function d(e){var t=(0,s.XA)(e);if(null!==t){var n=(0,o.t_)(t,1953658222);if(null!==n){var i=0,a=n[i];if(i+=1,!(a>1)){var u=(0,r.QI)(n,i);i+=3;var l=(256&u)>0,d=0;if(l||void 0!==(d=function(e){var t=(0,o.t_)(e,1952868452);if(null!==t){var n=1,i=(0,r.QI)(t,n);if(n+=3,(8&i)>0)return n+=4,(1&i)>0&&(n+=8),(2&i)>0&&(n+=4),(0,r.pX)(t,n)}}(t))){var c=(1&u)>0,f=(4&u)>0,p=(512&u)>0,h=(1024&u)>0,v=(2048&u)>0,m=(0,r.pX)(n,i);i+=4,c&&(i+=4),f&&(i+=4);for(var g=m,y=0;g-- >0;)l?(y+=(0,r.pX)(n,i),i+=4):y+=d,p&&(i+=4),h&&(i+=4),v&&(i+=4);return y}}}}}function c(e){var t=(0,s.fs)(e);if(null!==t){var n=(0,o.t_)(t,1835296868);if(null!==n){var i=0,a=n[i];return i+=4,1===a?(0,r.pX)(n,i+16):0===a?(0,r.pX)(n,i+8):void 0}}}function f(e){var t=e.length;if(t<4)throw new Error("Cannot update box length: box too short");var n=(0,r.pX)(e,0);if(0===n){if(t>a.s){var i=new Uint8Array(t+8);return i.set((0,r.kh)(1),0),i.set(e.subarray(4,8),4),i.set((0,r.el)(t+8),8),i.set(e.subarray(8,t),16),i}return e.set((0,r.kh)(t),0),e}if(1===n){if(t<16)throw new Error("Cannot update box length: box too short");return e.set((0,r.el)(t),8),e}if(t<=a.s)return e.set((0,r.kh)(t),0),e;var o=new Uint8Array(t+8);return o.set((0,r.kh)(1),0),o.set(e.subarray(4,8),4),o.set((0,r.el)(t+8),8),o.set(e.subarray(8,t),16),o}function p(e){for(var t=[],n=0;n{"use strict";n.d(t,{Z:()=>a});var r=n(6968),i=n(3635);const a=function(e){var t=0,n=e.length,a=(0,i.uR)(e.subarray(t+1,t+8));if(t+=8,137!==e[0]||"BIF\r\n\n"!==a)throw new Error("Invalid BIF file");var o=e[t],s=e[t+=1],u=e[t+=1],l=e[t+=1];t+=1;var d=[o,s,u,l].join(".");if(s>0)throw new Error("Unhandled version: "+s);var c=(0,r.dN)(e,t);t+=4;var f=(0,r.dN)(e,t);t+=4;var p=(0,i.uR)(e.subarray(t,t+4));t+=4;var h=(0,r.qb)(e,t);t+=2;var v=(0,r.qb)(e,t),m=[e[t+=2],e[t+1]].join(":"),g=1===e[t+=2];t=64;var y=[];if(0===c)throw new Error("bif: no images to parse");for(var _=0,b=null;t{"use strict";function r(e,t){for(;e.length>0;){var n=e[0];if(n.start>=t)return;if(n.repeatCount<=0)e.shift();else{var r=e[1];if(null!=r&&r.start<=t)e.shift();else{if(n.duration<=0)return;for(var i=n.start+n.duration,a=1;in.repeatCount)){var o=n.repeatCount-a;return n.start=i,void(n.repeatCount=o)}e.shift()}}}}n.d(t,{Z:()=>r})},3911:(e,t,n)=>{"use strict";function r(e,t,n){var r,i=e.repeatCount;return i>=0?i:(r=null!=t?t.start:null!=n?n:Number.MAX_VALUE,Math.ceil((r-e.start)/e.duration)-1)}function i(e,t,n){var i=e.start,a=e.duration;return a<=0?i:i+(r(e,t,n)+1)*a}function a(e,t){var n;return e*t.timescale+(null!==(n=t.indexTimeOffset)&&void 0!==n?n:0)}function o(e,t){var n;return(e-(null!==(n=t.indexTimeOffset)&&void 0!==n?n:0))/t.timescale}function s(e,t,n){return[e*n,(e+t)*n]}function u(e,t,n){var r=e.timeline,s=a(t,e);if(s<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,s);if(u<0||u>=r.length-1)return null;var l=r[u];if(l.duration<=0)return null;var d=r[u+1];if(void 0===d)return null;var c=d.start;return s>=i(l,d,n)&&sr,jH:()=>i,gT:()=>a,zG:()=>o,PZ:()=>s,_j:()=>u})},1091:(e,t,n)=>{"use strict";function r(e,t,n,r){for(var i=0;ie.time)return!1;if(o===e.time)return a.duration/n===e.duration&&(null==a.range?null==e.range:null!=e.range&&a.range[0]===e.range[0]&&a.range[1]===e.range[1]);if(a.repeatCount>=0&&null!=a.duration){var s=(o-a.start)/a.duration-1;return s%1==0&&s<=a.repeatCount}}return!1}n.d(t,{Z:()=>r})},5505:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(3714),i=n(3887),a=n(3911);function o(e,t){var n=e.length;if(0!==e.length){if(0!==t.length){var 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)return void e.splice.apply(e,[u,n-u].concat(t));if(lo)return i.Z.warn("RepresentationIndex: Manifest update removed previous segments"),void e.splice.apply(e,[u,n-u].concat(t));if(void 0===d.repeatCount||d.repeatCount<=0)return d.repeatCount<0&&(d.repeatCount=Math.floor((o-d.start)/d.duration)-1),void e.splice.apply(e,[u+1,n-(u+1)].concat(t));if(d.start+d.duration*(d.repeatCount+1)<=o)return void e.splice.apply(e,[u+1,n-(u+1)].concat(t));var c=(o-d.start)/d.duration-1;if(c%1==0&&d.duration===t[0].duration){var f=t[0].repeatCount<0?-1:t[0].repeatCount+c+1;return e.splice.apply(e,[u,n-u].concat(t)),e[u].start=d.start,void(e[u].repeatCount=f)}return i.Z.warn("RepresentationIndex: Manifest update removed previous segments"),e[u].repeatCount=Math.floor(c),void e.splice.apply(e,[u+1,n-(u+1)].concat(t))}}var p=e[e.length-1],h=t[t.length-1];if(void 0!==p.repeatCount&&p.repeatCount<0)return p.start>h.start?void i.Z.warn("RepresentationIndex: The new index is older than the previous one"):(i.Z.warn('RepresentationIndex: The new index is "bigger" than the previous one'),void e.splice.apply(e,[0,n].concat(t)));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"):(i.Z.warn('RepresentationIndex: The new index is "bigger" than the previous one'),e.splice.apply(e,[0,n].concat(t)))}}else e.splice.apply(e,[0,n].concat(t))}},5734:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(6923),i=/&#([0-9]+);/g,a=/
/gi,o=/]*>([\s\S]*?)<\/style[^>]*>/i,s=/\s*

]+))?>(.*)/i,u=/]+?start="?([0-9]*)"?[^0-9]/i;function l(e,t){var n=new RegExp("\\s*"+t+":\\s*(\\S+);","i").exec(e);return Array.isArray(n)?n[1]:null}const d=function(e,t,n){var d,c,f=/]/gi,p=/]|<\/body>/gi,h=[],v=o.exec(e),m=Array.isArray(v)?v[1]:"";p.exec(e);var g,y=function(e){for(var t=/\.(\S+)\s*{([^}]*)}/gi,n={},r=t.exec(e);null!==r;){var i=r[1],a=l(r[2],"lang");null!=i&&null!=a&&(n[a]=i),r=t.exec(e)}return n}(m),_=function(e){var t=/p\s*{([^}]*)}/gi.exec(e);return null===t?"":t[1]}(m);if((0,r.Z)(n)&&void 0===(g=y[n]))throw new Error("sami: could not find lang "+n+" in CSS");for(;d=f.exec(e),c=p.exec(e),null!==d||null!==c;){if(null===d||null===c||d.index>=c.index)throw new Error("parse error");var b=e.slice(d.index,c.index),T=u.exec(b);if(!Array.isArray(T))throw new Error("parse error (sync time attribute)");var E=+T[1];if(isNaN(E))throw new Error("parse error (sync time attribute NaN)");w(b.split("\n"),E/1e3)}return h;function w(e,n){for(var o=e.length;--o>=0;){var u=s.exec(e[o]);if(Array.isArray(u)){var l=u[1],d=u[2];if(g===l)if(" "===d)h[h.length-1].end=n;else{var c=document.createElement("DIV");c.className="rxp-texttrack-region";var f=document.createElement("DIV");f.className="rxp-texttrack-div",f.style.position="absolute",f.style.bottom="0",f.style.width="100%",f.style.color="#fff",f.style.textShadow="-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000";var p=document.createElement("div");p.className="rxp-texttrack-p",(0,r.Z)(_)&&(p.style.cssText=_);for(var v=d.split(a),m=0;m{"use strict";n.d(t,{Z:()=>c});var r=n(7253),i=n(6923),a=/&#([0-9]+);/g,o=/
/gi,s=/]*>([\s\S]*?)<\/style[^>]*>/i,u=/\s*

]+))?>(.*)/i,l=/]+?start="?([0-9]*)"?[^0-9]/i;function d(e,t){var n=new RegExp("\\s*"+t+":\\s*(\\S+);","i").exec(e);return Array.isArray(n)?n[1]:null}const c=function(e,t,n){var c,f,p=/]/gi,h=/]|<\/body>/gi,v=[],m=s.exec(e),g=null!==m?m[1]:"";h.exec(e);var y,_=function(e){for(var t=/\.(\S+)\s*{([^}]*)}/gi,n={},r=t.exec(e);Array.isArray(r);){var i=r[1],a=d(r[2],"lang");null!=i&&null!=a&&(n[a]=i),r=t.exec(e)}return n}(g);if((0,i.Z)(n)&&void 0===(y=_[n]))throw new Error("sami: could not find lang "+n+" in CSS");for(;c=p.exec(e),f=h.exec(e),null!==c||null!==f;){if(null===c||null===f||c.index>=f.index)throw new Error("parse error");var b=e.slice(c.index,f.index),T=l.exec(b);if(null===T)throw new Error("parse error (sync time attribute)");var E=+T[1];if(isNaN(E))throw new Error("parse error (sync time attribute NaN)");w(b.split("\n"),E/1e3)}return function(e){for(var t=[],n=0;n=0;)if(null!==(r=u.exec(e[s]))){var l=r,d=l[1],c=l[2];y===d&&(" "===c?v[v.length-1].end=n:v.push({text:(i=c,i.replace(o,"\n").replace(a,(function(e,t){return String.fromCharCode(t)}))),start:n+t}))}}}},2061:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(6923);function i(e,t){for(var n=t+1;(0,r.Z)(e[n]);)n++;return n}function a(e){for(var t=[],n=0;n0&&(1===o.length?o[0].indexOf("--\x3e")>=0&&t.push(o):(o[1].indexOf("--\x3e")>=0||o[0].indexOf("--\x3e")>=0)&&t.push(o)),n=a}return t}},8675:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(2061),i=n(788);function a(e,t){for(var n=e.split(/\r\n|\n|\r/),a=(0,r.Z)(n),s=[],u=0;u0){var u=document.createTextNode(o[s]);r.appendChild(u)}}else if("B"===a.nodeName){var l=e(a);l.style.fontWeight="bold",r.appendChild(l)}else if("I"===a.nodeName){var d=e(a);d.style.fontStyle="italic",r.appendChild(d)}else if("U"===a.nodeName){var c=e(a);c.style.textDecoration="underline",r.appendChild(c)}else if("FONT"===a.nodeName&&null!=a.color){var f=e(a);f.style.color=a.color,r.appendChild(f)}else{var p=e(a);r.appendChild(p)}}return r}(t)}},8057:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7253),i=n(2061),a=n(788);function o(e,t){for(var n,o,s,u,l,d=e.split(/\r\n|\n|\r/),c=(0,i.Z)(d),f=[],p=0;p{"use strict";n.d(t,{Z:()=>a});var r=n(6923);function i(e){var t=e.split(":");if((0,r.Z)(t[2])){var n=parseInt(t[0],10),i=parseInt(t[1],10),a=parseFloat(t[2].replace(",","."));if(isNaN(n)||isNaN(i)||isNaN(a))return;return 60*n*60+60*i+a}}function a(e,t){if(0===e.length)return null;var n,a,o=[];if((0,r.Z)(e[1])&&-1!==e[1].indexOf("--\x3e")){var s=e[1].split("--\x3e").map((function(e){return e.trim()}));n=s[0],a=s[1],o=e.slice(2,e.length)}if(!(0,r.Z)(n)||!(0,r.Z)(a)){var u=e[0].split("--\x3e").map((function(e){return e.trim()}));n=u[0],a=u[1],o=e.slice(1,e.length)}if(!(0,r.Z)(n)||!(0,r.Z)(a))return null;var l=i(n),d=i(a);return void 0===l||void 0===d?null:{start:l+t,end:d+t,payload:o}}},2967:(e,t,n)=>{"use strict";function r(e,t){if(!(e.parentNode instanceof Element))return[];return function e(n){var r=[];n.tagName.toLowerCase()===t.toLowerCase()&&r.push(n);var i=n.parentNode;return i instanceof Element&&r.push.apply(r,e(i)),r}(e.parentNode)}n.d(t,{Z:()=>r})},3791:(e,t,n)=>{"use strict";n.d(t,{U:()=>s,b:()=>u});var r=n(3274),i=n(7714),a=n(6923),o=n(9252);function s(e,t,n,o){for(var s={},u=e.slice(),l=0;l<=t.length-1;l++){var d=t[l];if(void 0!==d){var c=function(){var e=void 0,t=void 0;if(d.nodeType===Node.ELEMENT_NODE)for(var l=d,c=0;c<=l.attributes.length-1;c++){var f=l.attributes[c],p=f.name;if("style"===p)e=f.value;else if("region"===p)t=f.value;else{var h=p.substring(4);if((0,i.Z)(u,h)&&(s[h]=f.value,u.splice(c,1),0===u.length))return{v:s}}}if((0,a.Z)(e)){var v=(0,r.Z)(n,(function(t){return t.id===e}));if(void 0!==v)for(var m=0;m<=u.length-1;m++){var g=u[m];if(!(0,a.Z)(s[g])&&(0,a.Z)(v.style[g])){if(s[g]=v.style[g],u.splice(m,1),0===u.length)return{v:s};m--}}}if((0,a.Z)(t)){var y=(0,r.Z)(o,(function(e){return e.id===t}));if(void 0!==y)for(var _=0;_<=u.length-1;_++){var b=u[_];if(!(0,a.Z)(s[b])&&(0,a.Z)(y.style[b])){if(s[b]=y.style[b],u.splice(_,1),0===u.length)return{v:s};_--}}}}();if("object"==typeof c)return c.v}}return s}function u(e){if(e.nodeType!==Node.ELEMENT_NODE)return{};for(var t=e,n={},r=0;r<=t.attributes.length-1;r++){var i=t.attributes[r];if((0,o.Z)(i.name,"tts"))n[i.name.substring(4)]=i.value}return n}},6177:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(6923),i=n(5336);function a(e,t){var n=e.exec(t);if(null===n||""===n[0])return null;var r=Number(n[1]);isNaN(r)&&(r=0);var i=Number(n[2]);isNaN(i)&&(i=0);var a=Number(n[3]);isNaN(a)&&(a=0);var o=Number(n[4]);return isNaN(o)&&(o=0),o/1e3+a+60*i+3600*r}const o=function(e,t){return i.gu.test(e)?function(e,t){var n=i.gu.exec(t),r=Number(n[1]),a=Number(n[2]),o=Number(n[3]),s=Number(n[4]),u=Number(n[5]);isNaN(u)&&(u=0);return s+=u/e.subFrameRate,(o+=s/e.frameRate)+60*a+3600*r}(t,e):i.KO.test(e)?a(i.KO,e):i.wf.test(e)?a(i.wf,e):i.jb.test(e)?function(e,t){var n=i.jb.exec(t);return Number(n[1])/e.frameRate}(t,e):i.Du.test(e)?function(e,t){var n=i.Du.exec(t);return Number(n[1])/e.tickRate}(t,e):i.te.test(e)?a(i.te,e):void 0};function s(e,t){var n=e.getAttribute("begin"),i=e.getAttribute("dur"),a=e.getAttribute("end"),s=(0,r.Z)(n)?o(n,t):null,u=(0,r.Z)(i)?o(i,t):null,l=(0,r.Z)(a)?o(a,t):null;if(null==s||null==l&&null==u)throw new Error("Invalid text cue");return{start:s,end:null==l?s+u:l}}},7439:(e,t,n)=>{"use strict";n.d(t,{Z:()=>S});var r=n(5403);function i(e){return void 0===e.extent&&void 0===e.origin&&void 0===e.displayAlign&&void 0===e.display&&void 0===e.textAlign&&void 0===e.fontSize}function a(e){e.extent="70% 20%",e.fontSize="1c",e.origin="15% 80%",e.displayAlign="before",e.textAlign="center"}var o,s=n(6177);function u(e,t){(void 0===o&&(o=void 0!==e.classList&&"function"==typeof e.classList.add),o)?e.classList.add(t):(" "+e.className+" ").indexOf(" "+t+" ")<0&&(e.className+=" "+t)}var l=n(6923),d=n(8026),c=n(2967),f=n(3791),p=n(3887),h=n(5336);function v(e,t){return"-1px -1px "+t+" "+e+",1px -1px "+t+" "+e+",-1px 1px "+t+" "+e+",1px 1px "+t+" "+e}function m(e){var t;return null!=(t=h.Dq.exec(e))?"rgba("+String(parseInt(t[1],16))+","+String(parseInt(t[2],16))+","+String(parseInt(t[3],16))+","+String(parseInt(t[4],16)/255)+")":null!=(t=h.YU.exec(e))?"rgba("+String(parseInt(t[1]+t[1],16))+","+String(parseInt(t[2]+t[2],16))+","+String(parseInt(t[3]+t[3],16))+","+String(parseInt(t[4]+t[4],16)/255)+")":null!=(t=h.GK.exec(e))?"rgb("+String(+t[1])+","+String(+t[2])+","+String(+t[3])+")":null!=(t=h.ev.exec(e))?"rgba("+String(+t[1])+","+String(+t[2])+","+String(+t[3])+","+String(+t[4]/255)+")":e}var g=["color","direction","display","fontFamily","fontSize","fontStyle","fontWeight","textDecoration","textOutline","unicodeBidi","visibility","wrapOption"];function y(e,t,n){var r=t.color;(0,l.Z)(r)&&(e.style.color=m(r));var i=t.backgroundColor;(0,l.Z)(i)&&(e.style.backgroundColor=m(i));var a=t.textOutline;if((0,l.Z)(a)){var o=a.trim().replace(/\s+/g," ").split(" "),s=o.length;if(3===s){var d=m(o[0]),c=o[1];e.style.textShadow=v(d,c)}else if((0,l.Z)(r)&&1===s){var f=o[0];e.style.textShadow=v(r,f)}else if(2===s){var g=/^[#A-Z]/i.test(o[0]);if(g!==/^[0-9]/.test(o[0]))if(g){var y=m(o[0]),_=o[1];e.style.textShadow=v(y,_)}else if((0,l.Z)(r)){var b=o[0];e.style.textShadow=v(r,b)}}}var T=t.textDecoration;if((0,l.Z)(T))switch(T){case"noUnderline":case"noLineThrough":case"noOverline":e.style.textDecoration="none";break;case"lineThrough":e.style.textDecoration="line-through";break;default:e.style.textDecoration=T}var E=t.fontFamily;if((0,l.Z)(E))switch(E){case"proportionalSansSerif":e.style.fontFamily="Arial, Helvetica, Liberation Sans, sans-serif";break;case"monospaceSansSerif":case"sansSerif":e.style.fontFamily="sans-serif";break;case"monospaceSerif":case"default":e.style.fontFamily="Courier New, Liberation Mono, monospace";break;case"proportionalSerif":e.style.fontFamily="serif";break;default:e.style.fontFamily=E}var w=t.fontStyle;(0,l.Z)(w)&&(e.style.fontStyle=w);var S=t.fontWeight;(0,l.Z)(S)&&(e.style.fontWeight=S);var k=t.fontSize;(0,l.Z)(k)?function(e,t){var n=t.trim().split(" ");if(0!==n.length){var r=h.eT.exec(n[0]);null!==r&&("px"===r[2]||"%"===r[2]||"em"===r[2]?e.style.fontSize=r[1]+r[2]:"c"===r[2]?(e.style.position="relative",u(e,"proportional-style"),e.setAttribute("data-proportional-font-size",r[1])):p.Z.warn("TTML Parser: unhandled fontSize unit:",r[2]))}}(e,k):(u(e,"proportional-style"),e.setAttribute("data-proportional-font-size","1"));var A=t.direction;(0,l.Z)(A)&&(e.style.direction=A);var x=t.unicodeBidi;if((0,l.Z)(x))switch(x){case"bidiOverride":e.style.unicodeBidi="bidi-override";break;case"embed":e.style.unicodeBidi="embed";break;default:e.style.unicodeBidi="normal"}var I=t.visibility;(0,l.Z)(I)&&(e.style.visibility=I),"none"===t.display&&(e.style.display="none");var Z=t.wrapOption;e.style.whiteSpace="noWrap"===Z?n?"nowrap":"pre":n?"normal":"pre-wrap"}function _(e,t){e.style.color="white",e.style.position="absolute";var n=t.extent;(0,l.Z)(n)&&function(e,t){var n=t.trim();if("auto"!==n){var r=n.split(" ");if(2===r.length){var i=h.eT.exec(r[0]),a=h.eT.exec(r[1]);null!==i&&null!==a&&("px"===i[2]||"%"===i[2]||"em"===i[2]?e.style.width=i[1]+i[2]:"c"===i[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-width",i[1])):p.Z.warn("TTML Parser: unhandled extent unit:",i[2]),"px"===a[2]||"%"===a[2]||"em"===a[2]?e.style.height=a[1]+a[2]:"c"===a[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-height",a[1])):p.Z.warn("TTML Parser: unhandled extent unit:",a[2]))}}}(e,n);var r=t.writingMode;(0,l.Z)(r);var i=t.overflow;e.style.overflow=(0,l.Z)(i)?i:"hidden";var a=t.padding;(0,l.Z)(a)&&function(e,t){var n=t.trim().split(" ");if(!(n.length<1)){var r=h.eT.exec(n[0]);if(null!==r){if("px"===r[2]||"%"===r[2]||"em"===r[2]){var i=r[1]+r[2];1===n.length?e.style.padding=i:2===n.length?(e.style.paddingTop=i,e.style.paddingBottom=i):e.style.paddingTop=i}else"c"===r[2]?(u(e,"proportional-style"),1===n.length?(e.setAttribute("data-proportional-padding-top",r[1]),e.setAttribute("data-proportional-padding-bottom",r[1]),e.setAttribute("data-proportional-padding-left",r[1]),e.setAttribute("data-proportional-padding-right",r[1])):2===n.length?(e.setAttribute("data-proportional-padding-top",r[1]),e.setAttribute("data-proportional-padding-bottom",r[1])):e.setAttribute("data-proportional-padding-top",r[1])):p.Z.warn("TTML Parser: unhandled padding unit:",r[2]);if(1!==n.length){var a=h.eT.exec(n[1]);if(null!==a){if("px"===a[2]||"%"===a[2]||"em"===a[2]){var o=a[1]+a[2];n.length<4?(e.style.paddingLeft=o,e.style.paddingRight=o):e.style.paddingRight=o}else"c"===a[2]?(u(e,"proportional-style"),n.length<4?(e.setAttribute("data-proportional-padding-left",a[1]),e.setAttribute("data-proportional-padding-right",a[1])):e.setAttribute("data-proportional-padding-right",a[1])):p.Z.warn("TTML Parser: unhandled padding unit:",a[2]);if(2!==n.length){var s=h.eT.exec(n[2]);if(null!==s){if("px"===s[2]||"%"===s[2]||"em"===s[2]){var l=s[1]+s[2];e.style.paddingBottom=l}else"c"===s[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-padding-bottom",s[1])):p.Z.warn("TTML Parser: unhandled padding unit:",s[2]);if(3!==n.length){var d=h.eT.exec(n[3]);if(null!==d)if("px"===d[2]||"%"===d[2]||"em"===d[2]){var c=d[1]+d[2];e.style.paddingLeft=c}else"c"===d[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-padding-left",d[1])):p.Z.warn("TTML Parser: unhandled padding unit:",d[2])}}}}}}}}(e,a);var o=t.origin;(0,l.Z)(o)&&function(e,t){var n=t.trim();if("auto"!==n){var r=n.split(" ");if(2===r.length){var i=h.eT.exec(r[0]),a=h.eT.exec(r[1]);null!==i&&null!==a&&("px"===i[2]||"%"===i[2]||"em"===i[2]?e.style.left=i[1]+i[2]:"c"===i[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-left",i[1])):p.Z.warn("TTML Parser: unhandled origin unit:",i[2]),"px"===a[2]||"%"===a[2]||"em"===a[2]?e.style.top=a[1]+a[2]:"c"===a[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-top",a[1])):p.Z.warn("TTML Parser: unhandled origin unit:",a[2]))}}}(e,o);var s=t.displayAlign;if((0,l.Z)(s))switch(e.style.display="flex",e.style.flexDirection="column",s){case"before":e.style.justifyContent="flex-start";break;case"center":e.style.justifyContent="center";break;case"after":e.style.justifyContent="flex-end"}var d=t.opacity;(0,l.Z)(d)&&(e.style.opacity=d);var c=t.visibility;(0,l.Z)(c)&&(e.style.visibility=c),"none"===t.display&&(e.style.display="none")}function b(e,t){e.style.margin="0px";var n=t.backgroundColor;(0,l.Z)(n)&&(e.style.backgroundColor=m(n));var r=t.lineHeight;(0,l.Z)(r)&&function(e,t){var n=t.trim();if("auto"!==n){var r=h.eT.exec(n[0]);null!==r&&("px"===r[2]||"%"===r[2]||"em"===r[2]?e.style.lineHeight=r[1]+r[2]:"c"===r[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-line-height",r[1])):p.Z.warn("TTML Parser: unhandled lineHeight unit:",r[2]))}}(e,r);var i=t.textAlign;if((0,l.Z)(i))switch(i){case"center":e.style.textAlign="center";break;case"left":case"start":e.style.textAlign="left";break;case"right":case"end":e.style.textAlign="right"}}function T(e,t,n){var r=document.createElement("span"),i=null===e.textContent?"":e.textContent;if(n){var a=i.trim();i=a=a.replace(/\s+/g," ")}return r.innerHTML=i,r.className="rxp-texttrack-span",y(r,t,n),r}function E(e,t,n,r,i,a){var o=a.cellResolution,s=a.shouldTrimWhiteSpace,u=(0,c.Z)(e,"div"),p=document.createElement("DIV");if(p.className="rxp-texttrack-region",p.setAttribute("data-resolution-columns",String(o.columns)),p.setAttribute("data-resolution-rows",String(o.rows)),_(p,i),null!==t){var h=(0,f.U)(["backgroundColor"],[].concat(u,[t]),r,n).bodyBackgroundColor;(0,l.Z)(h)&&(p.style.backgroundColor=m(h))}var v=document.createElement("p");v.className="rxp-texttrack-p",b(v,i);for(var y=function(e,t,n,r,i){return function e(r,i,a,o){for(var s=r.childNodes,u=[],c=0;c0){var y=p.getAttribute("xml:space"),_=(0,l.Z)(y)?"default"===y:o,b=(0,d.Z)({},i,(0,f.U)(g,[p],n,t));u.push.apply(u,e(p,b,[p].concat(a),_))}}return u}(e,(0,d.Z)({},r),[],i)}(e,n,r,i,s),E=0;E{"use strict";n.d(t,{Z:()=>f});var r=n(5403),i=n(7253),a=n(1988),o=n(6923),s=n(6177),u=n(5336),l={left:"start",center:"center",right:"end",start:"start",end:"end"},d={left:"line-left",center:"center",right:"line-right"};function c(e){var t=e.paragraph,n=e.timeOffset,r=e.paragraphStyle,c=e.ttParams,f=e.shouldTrimWhiteSpace;if(!t.hasAttribute("begin")&&!t.hasAttribute("end")&&/^\s*$/.test(null===t.textContent?"":t.textContent))return null;var p=(0,s.Z)(t,c),h=p.start,v=p.end,m=function(e,t){function n(e,t){for(var r=e.childNodes,i="",a=0;a|\u2265/g,">").replace(/\u200E/g,"‎").replace(/\u200F/g,"‏").replace(/\u00A0/g," ")}else if("br"===s.nodeName)i+="\n";else if("span"===s.nodeName&&s.nodeType===Node.ELEMENT_NODE&&s.childNodes.length>0){var d=s.getAttribute("xml:space");i+=n(s,(0,o.Z)(d)?"default"===d:t)}}return i}return n(e,t)}(t,f),g=(0,i.Z)(h+n,v+n,m);return null===g?null:((0,a.Z)(g)&&function(e,t){var n=t.extent;if((0,o.Z)(n)){var r=u._0.exec(n);null!=r&&(e.size=Number(r[1]))}switch(t.writingMode){case"tb":case"tblr":e.vertical="lr";break;case"tbrl":e.vertical="rl"}var i=t.origin;if((0,o.Z)(i))u._0.exec(i);var a=t.align;if((0,o.Z)(a)){e.align=a,"center"===a&&("center"!==e.align&&(e.align="middle"),e.position="auto");var s=d[a];e.positionAlign=void 0===s?"":s;var c=l[a];e.lineAlign=void 0===c?"":c}}(g,r),g)}const f=function(e,t){for(var n=(0,r.Z)(e,t),i=[],a=0;a{"use strict";n.d(t,{Z:()=>p});var r=n(3274),i=n(6923),a=n(8026),o=n(3887),s=/(\d+) (\d+)/;var u=n(2967),l=n(3791);var d=n(5138),c=n(7714);var f=["align","backgroundColor","color","direction","display","displayAlign","extent","fontFamily","fontSize","fontStyle","fontWeight","lineHeight","opacity","origin","overflow","padding","textAlign","textDecoration","textOutline","unicodeBidi","visibility","wrapOption","writingMode"];function p(e,t){var n=[],p=(new DOMParser).parseFromString(e,"text/xml");if(null!=p){var h=p.getElementsByTagName("tt")[0];if(void 0===h)throw new Error("invalid XML");for(var v=function(e){return e.getElementsByTagName("body")[0]}(h),m=function(e){return e.getElementsByTagName("style")}(h),g=function(e){return e.getElementsByTagName("region")}(h),y=function(e){return e.getElementsByTagName("p")}(h),_=function(e){var t=e.getAttribute("ttp:frameRate"),n=e.getAttribute("ttp:subFramRate"),r=e.getAttribute("ttp:tickRate"),a=e.getAttribute("ttp:frameRateMultiplier"),u=e.getAttribute("xml:space"),l=e.getAttribute("ttp:cellResolution"),d={columns:32,rows:15};if(null!==l){var c=s.exec(l);if(null===c||c.length<3)o.Z.warn("TTML Parser: Invalid cellResolution");else{var f=parseInt(c[1],10),p=parseInt(c[2],10);isNaN(f)||isNaN(p)?o.Z.warn("TTML Parser: Invalid cellResolution"):d={columns:f,rows:p}}}if((0,i.Z)(u)&&"default"!==u&&"preserve"!==u)throw new Error("Invalid spacing style");var h=Number(t);(isNaN(h)||h<=0)&&(h=30);var v=Number(n);(isNaN(v)||v<=0)&&(v=1);var m=Number(r);(isNaN(m)||m<=0)&&(m=void 0);var g=h,y=null!=v?v:1,_=null!==u?u:"default",b=void 0!==m?m:h*v;if(null!==a){var T=/^(\d+) (\d+)$/g.exec(a);null!==T&&(g=h*(Number(T[1])/Number(T[2])))}return{cellResolution:d,tickRate:b,frameRate:g,subFrameRate:y,spaceStyle:_}}(h),b=[],T=0;T<=m.length-1;T++){var E=m[T];if(E instanceof Element){var w=E.getAttribute("xml:id");if(null!==w){var S=E.getAttribute("style"),k=null===S?[]:S.split(" ");b.push({id:w,style:(0,l.b)(E),extendsStyles:k})}}}!function(e){var t=[];function n(r,i){t.push(i);for(var s=function(i){var s=r.extendsStyles[i],u=(0,d.Z)(e,(function(e){return e.id===s}));if(u<0)o.Z.warn("TTML Parser: unknown style inheritance: "+s);else{var l=e[u];(0,c.Z)(t,u)?o.Z.warn("TTML Parser: infinite style inheritance loop avoided"):n(l,u),r.style=(0,a.Z)({},l.style,r.style)}},u=0;u{"use strict";n.d(t,{YU:()=>f,Dq:()=>c,GK:()=>p,ev:()=>h,eT:()=>d,_0:()=>l,KO:()=>i,gu:()=>r,wf:()=>a,jb:()=>o,te:()=>u,Du:()=>s});var r=/^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/,i=/^(?:(\d{2,}):)?(\d{2}):(\d{2})$/,a=/^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{2,})$/,o=/^(\d*\.?\d*)f$/,s=/^(\d*\.?\d*)t$/,u=/^(?:(\d*\.?\d*)h)?(?:(\d*\.?\d*)m)?(?:(\d*\.?\d*)s)?(?:(\d*\.?\d*)ms)?$/,l=/^(\d{1,2}|100)% (\d{1,2}|100)%$/,d=/^((?:\+|\-)?\d*(?:\.\d+)?)(px|em|c|%|rh|rw)$/,c=/^#([0-9A-f]{2})([0-9A-f]{2})([0-9A-f]{2})([0-9A-f]{2})$/,f=/^#([0-9A-f])([0-9A-f])([0-9A-f])([0-9A-f])$/,p=/^rgb\( *(\d+) *, *(\d+) *, *(\d+) *\)/,h=/^rgba\( *(\d+) *, *(\d+) *, *(\d+) *, *(\d+) *\)/},1138:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(6923),i=n(360);function a(e,t){for(var n=[],a=t;a{"use strict";n.d(t,{Z:()=>x});var r=n(1138),i=n(6923),a=n(360);var o=n(9525),s={white:"#ffffff",lime:"#00ff00",cyan:"#00ffff",red:"#ff0000",yellow:"#ffff00",magenta:"#ff00ff",blue:"#0000ff",black:"#000000"};function u(e){var t=Object.keys(s).reduce((function(e,t){return e[t]="color: "+s[t]+";",e["bg_"+t]="background-color: "+s[t]+";",e}),{}),n="";return e.forEach((function(e){if(e.length>=2)for(var r=1;r0&&n.appendChild(document.createElement("br")),o[s].length>0){var u=document.createTextNode(o[s]);n.appendChild(u)}}else{var c=e.nodeName.toLowerCase().split("."),f=[];if(c.forEach((function(e){(0,i.Z)(t[e])&&f.push(t[e])})),0!==f.length){var p=document.createAttribute("style");f.forEach((function(e){p.value+=e}));var h=(0,l.Z)(r,a)?a:"span";(n=document.createElement(h)).setAttributeNode(p)}else{var v=(0,l.Z)(r,a)?a:"span";n=document.createElement(v)}for(var m=0;m/,"").replace(/<([u,i,b,c])(\..*?)?(?: .*?)?>(.*?)<\/\1>/g,"<$1$2>$3"),r=(new DOMParser).parseFromString(n,"text/html").body.childNodes,i=[],a=0;a{"use strict";n.d(t,{Z:()=>c});var r=n(1988),i=n(1138),a=n(9525),o=n(360),s=n(7714),u=n(6923);function l(e,t){if(!(0,u.Z)(e.vertical)||"rl"!==e.vertical&&"lr"!==e.vertical||(t.vertical=e.vertical),(0,u.Z)(e.line)){var n=/^(\d+(\.\d+)?)%(,([a-z]+))?/.exec(e.line);if(Array.isArray(n))t.line=Number(n[1]),t.snapToLines=!1,(0,s.Z)(["start","center","end"],n[4])&&(t.lineAlign=n[4]);else{var r=/^(-?\d+)(,([a-z]+))?/.exec(e.line);Array.isArray(r)&&(t.line=Number(r[1]),t.snapToLines=!0,(0,s.Z)(["start","center","end"],r[3])&&(t.lineAlign=r[3]))}}if((0,u.Z)(e.position)){var i=/^([\d\.]+)%(?:,(line-left|line-right|center))?$/.exec(e.position);if(Array.isArray(i)&&i.length>=2){var a=parseInt(i[1],10);isNaN(a)||(t.position=a,void 0!==i[2]&&(t.positionAlign=i[2]))}}(0,u.Z)(e.size)&&(t.size=e.size),"string"==typeof e.align&&(0,s.Z)(["start","center","end","left"],e.align)&&(t.align=e.align)}var d=n(7253);const c=function(e,t){var n=e.split(/\r\n|\n|\r/);if(!/^WEBVTT($| |\t)/.test(n[0]))throw new Error("Can't parse WebVTT: Invalid file.");for(var s,u,c,f,p=(0,o.yE)(n),h=(0,i.Z)(n,p),v=[],m=0;m{"use strict";n.d(t,{Z:()=>a});var r=n(6923);function i(e){var t=e.split(":").reverse();if((0,r.Z)(t[2])||(0,r.Z)(t[1])){var n=(0,r.Z)(t[2])?parseInt(t[2],10):0,i=parseInt(t[1],10),a=parseFloat(t[0].replace(",","."));if(isNaN(n)||isNaN(i)||isNaN(a))return;return 60*n*60+60*i+a}}function a(e,t){var n,r,a,o=/-->/;if(o.test(e[0]))n=e[0],r=e.slice(1,e.length);else{if(!o.test(e[1]))return null;a=e[0],n=e[1],r=e.slice(2,e.length)}var s=function(e){var t=/^([\d:.]+)[ |\t]+-->[ |\t]+([\d:.]+)[ |\t]*(.*)$/.exec(e);if(null===t)return null;var n=i(t[1]),r=i(t[2]);return null==n||null==r?null:{start:n,end:r,settings:t[3].split(/ |\t/).reduce((function(e,t){var n=t.split(":");return 2===n.length&&(e[n[0]]=n[1]),e}),{})}}(n);return null===s?null:{start:s.start+t,end:s.end+t,settings:s.settings,payload:r,header:a}}},360:(e,t,n)=>{"use strict";n.d(t,{yE:()=>i,tq:()=>o,JF:()=>a,$4:()=>s});var r=n(6923);function i(e){for(var t=0;t=0)return!0;var r=e[t+1];return void 0!==r&&r.indexOf("--\x3e")>=0}function s(e,t){for(var n=t+1;(0,r.Z)(e[n]);)n++;return n}},1923:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Wt});var r=n(7278),i=n(8170),a=n(7874),o=n(4597),s=n(5278);function u(e){var t=e.segment,n=e.url;return t.isInit||null===n?(0,i.of)({type:"data-created",value:{responseData:null}}):(0,o.ZP)({url:n,responseType:"arraybuffer",sendProgressEvents:!0})}function l(e){var t=e.response,n=e.content,r=n.segment,o=n.period,u=t.data,l=t.isChunked;if(n.segment.isInit)return(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}});if(l)throw new Error("Image data should not be downloaded in chunks");var d=(0,s.Z)(r.timestampOffset,0);if(null===u||null===a.Z.imageParser)return(0,i.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:{duration:r.duration,time:r.time},chunkOffset:d,appendWindow:[o.start,o.end]}});var c=a.Z.imageParser(new Uint8Array(u)),f=c.thumbs;return(0,i.of)({type:"parsed-segment",value:{chunkData:{data:f,start:0,end:Number.MAX_VALUE,timescale:1,type:"bif"},chunkInfos:{time:0,duration:Number.MAX_VALUE,timescale:c.timescale},chunkOffset:d,appendWindow:[o.start,o.end]}})}var d=n(9795),c=n(5142),f=n(6008),p=n(5709),h=n(7746),v=n(1966),m=n(944),g=n(3887),y=n(3274),_=n(9829);function b(e){return 0===e.length?0:e.reduce((function(e,t){var n;return Math.min(null!==(n=t.attributes.availabilityTimeOffset)&&void 0!==n?n:0,e)}),1/0)}function T(e){var t=Date.parse(e)-performance.now();if(!isNaN(t))return t;g.Z.warn("DASH Parser: Invalid clock received: ",e)}function E(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,o=null;if(void 0!==r){var s=E(r);if(void 0===s)return;a=s}if(void 0!==i){var u=E(i);if(void 0===u)return;o=u}if(void 0!==r&&null===a||void 0!==i&&null===o)return void g.Z.info("Parser utils: found Period with no segment. ","Going to previous one to calculate last position");if(null!==o)return null!==a?Math.min(a,o):o;if(null!==a)return a}}}function S(e){for(var t=e.representations,n=null,r=0;r0){var o=F(a,"cenc:pssh"),s=o[0],u=o[1];null!==u&&(g.Z.warn(u.message),t.push(u)),null!==s&&n.push(s)}}}return[{cencPssh:n},t]}(e.childNodes),n=t[0],r=t[1];return[{children:n,attributes:function(e){for(var t={},n=0;n0&&(n=n.concat(d));break;case"SegmentList":var c=Q(i),f=c[0],p=c[1];n=n.concat(p),t.segmentList=f;break;case"SegmentTemplate":var h=ee(i),v=h[0],m=h[1];n=n.concat(m),t.segmentTemplate=v}}return[t,n]}(e.childNodes),n=t[0],r=t[1],i=function(e){for(var t={},n=[],r=K(t,n),i=0;i0&&(r=r.concat(u));break;case"ContentComponent":t.contentComponent=G(a);break;case"EssentialProperty":null==t.essentialProperties?t.essentialProperties=[z(a)]:t.essentialProperties.push(z(a));break;case"InbandEventStream":void 0===t.inbandEventStreams&&(t.inbandEventStreams=[]),t.inbandEventStreams.push(z(a));break;case"Representation":var l=te(a),d=l[0],c=l[1];t.representations.push(d),c.length>0&&(r=r.concat(c));break;case"Role":null==t.roles?t.roles=[z(a)]:t.roles.push(z(a));break;case"SupplementalProperty":null==t.supplementalProperties?t.supplementalProperties=[z(a)]:t.supplementalProperties.push(z(a));break;case"SegmentBase":var f=Y(a),p=f[0],h=f[1];t.segmentBase=p,h.length>0&&(r=r.concat(h));break;case"SegmentList":var v=Q(a),m=v[0],g=v[1];t.segmentList=m,g.length>0&&(r=r.concat(g));break;case"SegmentTemplate":var y=ee(a),_=y[0],b=y[1];t.segmentTemplate=_,b.length>0&&(r=r.concat(b));break;case"ContentProtection":var T=$(a),E=T[0],w=T[1];w.length>0&&(r=r.concat(w)),void 0!==E&&n.push(E)}}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=K(t,n),i=0;i0&&(i=i.concat(_))}}return[{baseURLs:n,adaptations:r,streamEvents:a,segmentTemplate:t},i]}(e.childNodes),n=t[0],r=t[1],i=function(e){for(var t={},n=[],r=K(t,n),i=0;i=a?o:(new Array(a+1).join("0")+o).slice(-a)}}function ge(e,t,n,r){return 0===e.length?void 0!==t?[ye(t,n,r)]:null:e.map((function(e){return ye((0,_.Z)(e,t),n,r)}))}function ye(e,t,n){return-1===e.indexOf("$")?e:e.replace(/\$\$/g,"$").replace(/\$RepresentationID\$/g,String(t)).replace(/\$Bandwidth(|\%0(\d+)d)\$/g,me(void 0===n?0:n))}function _e(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 me(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 me(e)(t,n,r)}))}}function be(e,t,n,r,i){for(var a,o,s=(0,he.gT)(t,e),u=(0,he.gT)(t+n,e),l=e.timeline,d=e.timescale,c=e.mediaURLs,f=e.startNumber,p=null!=f?f:void 0,h=[],v=l.length,m=l.length>0&&null!=l[0].duration?l[0].duration:0,g=0;g0?Math.floor(o/a):0),S=b+w*_;S=u)return h;null!=p&&(p+=E+1)}return h}function Te(e,t){if(t.timescale!==e.timescale){var n=e.timescale;e.timeline.push({start:t.time/t.timescale*n,duration:t.duration/t.timescale*n,repeatCount:void 0===t.count?0:t.count,range:t.range})}else e.timeline.push({start:t.time,duration:t.duration,repeatCount:void 0===t.count?0:t.count,range:t.range});return!0}var Ee=function(){function e(e,t){var n,r,i=t.periodStart,a=t.periodEnd,o=t.representationBaseURLs,s=t.representationId,u=t.representationBitrate,l=t.isEMSGWhitelisted,d=null!==(n=e.timescale)&&void 0!==n?n:1,c=(null!=e.presentationTimeOffset?e.presentationTimeOffset:0)-i*d,f=ge(o,void 0!==e.initialization?e.initialization.media:void 0,s,u),p=void 0!==e.initialization?e.initialization.range:void 0!==e.indexRange?[0,e.indexRange[0]-1]:void 0;this._index={indexRange:e.indexRange,indexTimeOffset:c,initialization:{mediaURLs:f,range:p},mediaURLs:ge(o,e.media,s,u),startNumber:e.startNumber,timeline:null!==(r=e.timeline)&&void 0!==r?r:[],timescale:d},this._scaledPeriodEnd=null==a?void 0:(0,he.gT)(a,this._index),this._isInitialized=this._index.timeline.length>0,this._isEMSGWhitelisted=l}var t=e.prototype;return t.getInitSegment=function(){return ve(this._index,this._isEMSGWhitelisted)},t.getSegments=function(e,t){return be(this._index,e,t,this._isEMSGWhitelisted,this._scaledPeriodEnd)},t.shouldRefresh=function(){return!1},t.getFirstPosition=function(){var e=this._index;return 0===e.timeline.length?null:(0,he.zG)(e.timeline[0].start,e)},t.getLastPosition=function(){var e=this._index.timeline;if(0===e.length)return null;var t=e[e.length-1],n=(0,he.jH)(t,null,this._scaledPeriodEnd);return(0,he.zG)(n,this._index)},t.isSegmentStillAvailable=function(){return!0},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},t._addSegments=function(e){for(var t=0;t0&&(this._isInitialized=!0)},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){return!0},t.isInitialized=function(){return this._isInitialized},t._replace=function(e){this._index=e._index},t._update=function(){g.Z.error("Base RepresentationIndex: Cannot update a SegmentList")},e}(),we=function(){function e(e,t){var n,r=t.periodStart,i=t.representationBaseURLs,a=t.representationId,o=t.representationBitrate,s=t.isEMSGWhitelisted;this._isEMSGWhitelisted=s,this._periodStart=r;var u=null!=e.presentationTimeOffset?e.presentationTimeOffset:0,l=null!==(n=e.timescale)&&void 0!==n?n:1,d=u-r*l,c=e.list.map((function(e){return{mediaURLs:ge(i,e.media,a,o),mediaRange:e.mediaRange}}));this._index={list:c,timescale:l,duration:e.duration,indexTimeOffset:d,indexRange:e.indexRange,initialization:null==e.initialization?void 0:{mediaURLs:ge(i,e.initialization.media,a,o),range:e.initialization.range}}}var t=e.prototype;return t.getInitSegment=function(){var e=ve(this._index);return void 0===e.privateInfos&&(e.privateInfos={}),e.privateInfos.isEMSGWhitelisted=this._isEMSGWhitelisted,e},t.getSegments=function(e,t){for(var n=this._index,r=n.duration,i=n.list,a=n.timescale,o=r/a,s=e-this._periodStart,u=(0,he.PZ)(s,t,a),l=u[0],d=u[1],c=Math.min(i.length-1,Math.floor(d/r)),f=[],p=Math.floor(l/r);p<=c;){var h=i[p].mediaRange,v=i[p].mediaURLs,m=p*o+this._periodStart,g={id:String(p),time:m,isInit:!1,range:h,duration:o,timescale:1,end:m+o,mediaURLs:v,timestampOffset:-n.indexTimeOffset/a,privateInfos:{isEMSGWhitelisted:this._isEMSGWhitelisted}};f.push(g),p++}return f},t.shouldRefresh=function(e,t){var n=this._index,r=n.timescale,i=n.duration,a=n.list,o=t*r,s=Math.floor(o/i);return s<0||s>=a.length},t.getFirstPosition=function(){return this._periodStart},t.getLastPosition=function(){var e=this._index,t=e.duration;return e.list.length*t/e.timescale+this._periodStart},t.isSegmentStillAvailable=function(){return!0},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){return!0},t.isInitialized=function(){return!0},t._replace=function(e){this._index=e._index},t._update=function(){g.Z.error("List RepresentationIndex: Cannot update a SegmentList")},e}(),Se=n(9362),ke=n(8232),Ae=n(1091),xe=n(5505),Ie=m.Z.DEFAULT_MAXIMUM_TIME_ROUNDING_ERROR;function Ze(e,t,n){return t+Ie*e>=n}function Re(e,t,n,r){var i=e.start,a=e.duration,o=e.repeatCount;return null==i&&(null==t?i=r:null!=t.duration&&(i=t.start+t.duration*(t.repeatCount+1))),null!=a&&!isNaN(a)||null==n||null==n.start||isNaN(n.start)||null==i||isNaN(i)||(a=n.start-i),null==i||isNaN(i)||null==a||isNaN(a)||null!=o&&isNaN(o)?(g.Z.warn('DASH: A "S" Element could not have been parsed.'),null):{start:i,duration:a,repeatCount:void 0===o?0:o}}function Me(e){for(var t={},n=0;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],d=i;;){var c=l.getAttribute("d"),f=null===c?null:parseInt(c,10);if(null===f||Number.isNaN(f))return null;var p=l.getAttribute("r"),h=null===p?null:parseInt(p,10);if(null!==h){if(Number.isNaN(h)||h<0)return null;if(h>0){var v=n-d;if(v%f==0&&v/f<=h)return{repeatNumberInPrevSegments:0,repeatNumberInNewElements:v/f,prevSegmentsIdx:0,newElementsIdx:u}}d+=f*(h+1)}else d+=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;d=g}if(d===n)return{newElementsIdx:u,prevSegmentsIdx:0,repeatNumberInPrevSegments:0,repeatNumberInNewElements:0};if(d>i)return null}}(t,e);if(null===i)return g.Z.warn('DASH: Cannot perform "based" update. Common segment not found.'),Ce(e,n);var a=i.prevSegmentsIdx,o=i.newElementsIdx,s=i.repeatNumberInPrevSegments,u=i.repeatNumberInNewElements,l=t.length-a+o-1;if(l>=e.length)return g.Z.info('DASH: Cannot perform "based" update. New timeline too short'),Ce(e,n);var d=t.slice(a);if(s>0){var c=d[0];c.start+=c.duration*s,d[0].repeatCount-=s}if(u>0&&0!==o)return g.Z.info('DASH: Cannot perform "based" update. The new timeline has a different form.'),Ce(e,n);var f=d[d.length-1],p=Me(e[l]),h=(null!==(r=p.repeatCount)&&void 0!==r?r:0)-u;if(p.duration!==f.duration||f.repeatCount>h)return g.Z.info('DASH: Cannot perform "based" update. The new timeline has a different form at the beginning.'),Ce(e,n);void 0!==p.repeatCount&&p.repeatCount>f.repeatCount&&(f.repeatCount=p.repeatCount);for(var v=[],m=[],y=l+1;yu?u-y:r,T=y+s,E=y+this._index.presentationTimeOffset,w=null===o?null:o.map(_e(E,_)),S={id:String(_),number:_,time:T/a,end:(T+b)/a,duration:b/a,timescale:1,isInit:!1,scaledDuration:b/a,mediaURLs:w,timestampOffset:-n.indexTimeOffset/a,privateInfos:{isEMSGWhitelisted:this._isEMSGWhitelisted}};v.push(S),g++}return v},t.getFirstPosition=function(){var e=this._getFirstSegmentStart();return null==e?e:e/this._index.timescale+this._periodStart},t.getLastPosition=function(){var e=this._getLastSegmentStart();return null==e?e:(e+this._index.duration)/this._index.timescale+this._periodStart},t.shouldRefresh=function(){return!1},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},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._scaledPeriodEnd)return!1;var e=this._index.timescale,t=this._getLastSegmentStart();return null!=t&&Ze(e,t+this._index.duration,this._scaledPeriodEnd)},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._scaledPeriodEnd=e._scaledPeriodEnd,this._manifestBoundsCalculator=e._manifestBoundsCalculator},t._update=function(e){this._replace(e)},t._getFirstSegmentStart=function(){if(!this._isDynamic)return 0;if(0===this._scaledPeriodEnd||void 0===this._scaledPeriodEnd){var e=this._manifestBoundsCalculator.estimateMaximumBound();if(void 0!==e&&ethis._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 a=this._aggressiveMode?n/r:0;if(null!=this._scaledPeriodEnd&&this._scaledPeriodEnd<(i+a-this._periodStart)*this._index.timescale)return this._scaledPeriodEndDe*r||0===d?c:(d-1)*n},e}();function Be(e,t){var n=[];if(0===t.length)return e;if(0===e.length){for(var r=0;r0){var _=t.parentSegmentTemplates.slice(),T=e.children.segmentTemplate;void 0!==T&&_.push(T);var E=q.Z.apply(void 0,[{}].concat(_));m.availabilityTimeOffset=t.availabilityTimeOffset+b(e.children.baseURLs)+(null!==(r=E.availabilityTimeOffset)&&void 0!==r?r:0);var w=E.timelineParser;i=void 0!==w?new Oe(E,w,m):new Le(E,m)}else{var S=t.adaptation.children;if(void 0!==S.segmentBase){var k=S.segmentBase;i=new Ee(k,m)}else if(void 0!==S.segmentList){var A=S.segmentList;i=new we(A,m)}else i=new Le({duration:Number.MAX_VALUE,timescale:1,startNumber:0,initialization:{media:""},media:""},m)}return i}(s,(0,q.Z)({},n,{unsafelyBaseOnPreviousRepresentation:l,adaptation:t,inbandEventStreams:d})),f=void 0;null==s.attributes.bitrate?(g.Z.warn("DASH: No usable bitrate found in the Representation."),f=0):f=s.attributes.bitrate;var p={bitrate:f,index:c,id:u},h=void 0;if(null!=s.attributes.codecs?h=s.attributes.codecs:null!=t.attributes.codecs&&(h=t.attributes.codecs),null!=h&&(h="mp4a.40.02"===h?"mp4a.40.2":h,p.codecs=h),null!=s.attributes.frameRate?p.frameRate=s.attributes.frameRate:null!=t.attributes.frameRate&&(p.frameRate=t.attributes.frameRate),null!=s.attributes.height?p.height=s.attributes.height:null!=t.attributes.height&&(p.height=t.attributes.height),null!=s.attributes.mimeType?p.mimeType=s.attributes.mimeType:null!=t.attributes.mimeType&&(p.mimeType=t.attributes.mimeType),null!=s.attributes.width?p.width=s.attributes.width:null!=t.attributes.width&&(p.width=t.attributes.width),null!=t.children.contentProtections){var v=t.children.contentProtections.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&&e.keyIds.push({keyId:t.attributes.keyId,systemId:n}),void 0!==n){for(var r=t.children.cencPssh,i=[],a=0;a0){var s,u=(0,y.Z)(e.initData,(function(e){return"cenc"===e.type}));if(void 0===u)e.initData.push({type:"cenc",values:i});else(s=u.values).push.apply(s,i)}}return e}),{keyIds:[],initData:[]});(Object.keys(v.initData).length>0||v.keyIds.length>0)&&(p.contentProtections=v)}a.push(p)},s=0;s0&&void 0!==l.video){var Z,M=o.video[l.video];I.unsafelyBaseOnPreviousAdaptation=null!==(r=null===(n=t.unsafelyBaseOnPreviousPeriod)||void 0===n?void 0:n.getAdaptation(M.id))&&void 0!==r?r:null;var C=Ue(m,c,I);(Z=M.representations).push.apply(Z,C),k=M.id}else{var N=f.accessibilities,P=void 0;void 0!==h&&h.some((function(e){return"dub"===e.value}))&&(P=!0);var O=void 0;"text"!==w?O=!1:void 0!==N&&(O=N.some(ze));var D=void 0;"audio"!==w?D=!1:void 0!==N&&(D=N.some(Fe));var L=void 0;"video"!==w?L=!1:void 0!==N&&(L=N.some(Ke));for(var B=Ve(c,{isAudioDescription:D,isClosedCaption:O,isSignInterpreted:L,type:w});(0,de.Z)(u,B);)B+="-dup";k=B,u.push(B),I.unsafelyBaseOnPreviousAdaptation=null!==(a=null===(i=t.unsafelyBaseOnPreviousPeriod)||void 0===i?void 0:i.getAdaptation(B))&&void 0!==a?a:null;var U={id:B,representations:Ue(m,c,I),type:w};null!=c.attributes.language&&(U.language=c.attributes.language),null!=O&&(U.closedCaption=O),null!=D&&(U.audioDescription=D),!0===P&&(U.isDub=!0),!0===L&&(U.isSignInterpreted=!0);var F=o[w];if(void 0===F)o[w]=[U],v&&(l[w]=0);else{for(var z=null,K=function(e){var t=A[e],n=s[t];if(null!=n&&n.newID!==k&&(0,de.Z)(n.adaptationSetSwitchingIDs,S)){var r,i=(0,y.Z)(F,(function(e){return e.id===t}));null!=i&&i.audioDescription===U.audioDescription&&i.closedCaption===U.closedCaption&&i.language===U.language&&(g.Z.info('DASH Parser: merging "switchable" AdaptationSets',S,t),(r=i.representations).push.apply(r,U.representations),z=i)}},V=0;VW)&&(F.splice(H,1),F.splice(G,0,z),l[w]=G)}}else null===z&&F.push(U)}}null!=S&&null==s[S]&&(s[S]={newID:k,adaptationSetSwitchingIDs:A})}}}return o}(c.children.adaptations,k),x=null===(i=c.children.streamEvents)||void 0===i?void 0:i.map((function(e){var t,n=(null!==(t=e.eventPresentationTime)&&void 0!==t?t:0)/e.timescale+v;return{start:n,end:void 0!==e.duration?n+e.duration/e.timescale:void 0,data:e.data,id:e.id}})),I={id:T,start:v,end:_,duration:m,adaptations:A,streamEvents:x};if(a.unshift(I),!l.lastPositionIsKnown()){var Z=function(e){for(var t=null,n=!0,r=(0,ue.Z)(e).filter((function(e){return null!=e})),i=(0,oe.Z)(r,(function(e){return e})),a=0;a=0;c--)d(c);if(t.isDynamic&&!l.lastPositionIsKnown()){var f=$e(t,0);if(void 0!==f){var p=f[0],h=f[1];l.setLastPosition(p,h)}}return function(e){if(0===e.length)return[];for(var t=[e[0]],n=1;nr.start;)g.Z.warn("DASH: Updating overlapping Periods.",i,r),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}(a)}function $e(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 g.Z.warn("DASH Parser: no clock synchronization mechanism found. Using the system clock instead."),[a-e.availabilityStartTime,performance.now()/1e3]}}var je=m.Z.DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0;function Ye(e,t){var n=ae(e);return qe(n[0],t,n[1])}function qe(e,t,n,r){var i=e.children,a=e.attributes,o=new WeakMap;if(null==t.externalClockOffset){var s="dynamic"===a.type,u=(0,y.Z)(i.utcTimings,(function(e){return"urn:mpeg:dash:utc:direct:2014"===e.schemeIdUri&&null!=e.value})),l=null!=u&&null!=u.value?T(u.value):void 0,d=null==l||isNaN(l)?void 0:l;if(null!=d)t.externalClockOffset=d;else if(s&&!0!==r){var c=function(e){var t=e.children.utcTimings.filter((function(e){return"urn:mpeg:dash:utc:http-iso:2014"===e.schemeIdUri&&void 0!==e.value}));return t.length>0?t[0].value:void 0}(e);if(null!=c&&c.length>0)return{type:"needs-ressources",value:{ressources:[c],continue:function(r){if(1!==r.length)throw new Error("DASH parser: wrong number of loaded ressources.");return d=T(r[0].responseData),t.externalClockOffset=d,qe(e,t,n,!0)}}}}}for(var f=[],p=0;p=0&&(o=0===d.minimumUpdatePeriod?je:d.minimumUpdatePeriod);var x=function(e){if(0===e.length)throw new Error("DASH Parser: no period available for a dynamic content");return[k(e),w(e)]}(E),I=x[0],Z=x[1],R=performance.now();if(c){var M;if(s=I,A=null!=h?h:null,void 0!==Z)M=Z;else{var C=null!=p?p:0,N=t.externalClockOffset;if(void 0===N)g.Z.warn("DASH Parser: use system clock to define maximum position"),M=Date.now()/1e3-C;else M=(performance.now()+N)/1e3-C}u={isLinear:!0,value:M,time:R},null!==A&&void 0!==s&&M-s>A&&(A=M-s)}else{var P;if(s=void 0!==I?I:void 0!==(null===(i=E[0])||void 0===i?void 0:i.start)?E[0].start:0,void 0!==Z)P=Z;else if(void 0!==S)P=S;else if(void 0!==E[E.length-1]){var O=E[E.length-1];P=null!==(a=O.end)&&void 0!==a?a:void 0!==O.duration?O.start+O.duration:void 0}u={isLinear:!1,value:null!=P?P:1/0,time:R}}return{type:"done",value:{parsed:{availabilityStartTime:p,clockOffset:t.externalClockOffset,isDynamic:c,isLive:c,periods:E,publishTime:d.publishTime,suggestedPresentationDelay:d.suggestedPresentationDelay,transportType:"dash",timeBounds:{absoluteMinimumTime:s,timeshiftDepth:A,maximumTimeData:u},lifetime:o,uris:null==t.url?l.locations:[t.url].concat(l.locations)},warnings:n}}}(e,t,n,o):{type:"needs-ressources",value:{ressources:f.map((function(e){return e.ressource})),continue:function(r){if(r.length!==f.length)throw new Error("DASH parser: wrong number of loaded ressources.");for(var a=r.length-1;a>=0;a--){var s,u=f[a].index,l=r[a],d=l.responseData,c=l.receivedTime,p=l.sendingTime,h=l.url,v=""+d+"",m=(new DOMParser).parseFromString(v,"text/xml");if(null==m||0===m.children.length)throw new Error("DASH parser: Invalid external ressources");for(var g=m.children[0].children,y=[],_=0;_0&&n.push.apply(n,E)}(s=i.periods).splice.apply(s,[u,1].concat(y))}return qe(e,t,n)}}}}const Xe=function(e,t){var n=e.documentElement;if(null==n||"MPD"!==n.nodeName)throw new Error("DASH Parser: document root should be MPD");return Ye(n,t)};var Qe=n(7445);function Je(e){var t=e.aggressiveMode,n=e.referenceDateTime,r=void 0!==e.serverSyncInfos?e.serverSyncInfos.serverTimestamp-e.serverSyncInfos.clientTime:void 0;return function(a){var s,u=a.response,l=a.scheduleRequest,m=a.externalClockOffset,g=a.url,y=null!==(s=u.url)&&void 0!==s?s:g,_="string"==typeof u.responseData?(new DOMParser).parseFromString(u.responseData,"text/xml"):u.responseData,b=null!=r?r:m,T=a.unsafeMode?a.previousManifest:null;return function t(n){if("done"===n.type){var r=n.value,a=r.warnings,s=r.parsed,u=a.map((function(e){return{type:"warning",value:e}})),m=new v.ZP(s,e);return(0,d.z)(i.of.apply(void 0,u),(0,Qe.Z)(m,y))}var g=n.value,_=g.ressources,b=g.continue,T=_.map((function(e){return l((function(){return function(e){return(0,o.ZP)({url:e,responseType:"text"}).pipe((0,f.h)((function(e){return"data-loaded"===e.type})),(0,p.U)((function(e){return e.value})))}(e)}))}));return(0,c.aj)(T).pipe((0,h.zg)((function(e){for(var n=[],r=0;r=300)return g.Z.warn("Fetch: Request HTTP Error",e),void n.error(new at.Z(e.url,e.status,ot.br.ERROR_HTTP_CODE));if(!(0,st.Z)(e.body)){var t=e.headers.get("Content-Length"),r=(0,st.Z)(t)||isNaN(+t)?void 0:+t,i=e.body.getReader(),s=0;return u()}function u(){return l.apply(this,arguments)}function l(){return(l=nt(it().mark((function t(){var l,d,c,f,p;return it().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,i.read();case 2:if((l=t.sent).done||(0,st.Z)(l.value)){t.next=11;break}return s+=l.value.byteLength,d=performance.now(),c={type:"data-chunk",value:{url:e.url,currentTime:d,duration:d-o,sendingTime:o,chunkSize:l.value.byteLength,chunk:l.value.buffer,size:s,totalSize:r}},n.next(c),t.abrupt("return",u());case 11:l.done&&(f=performance.now(),p=f-o,a=!0,n.next({type:"data-complete",value:{duration:p,receivedTime:f,sendingTime:o,size:s,status:e.status,url:e.url}}),n.complete());case 12:case"end":return t.stop()}}),t)})))).apply(this,arguments)}n.error(new at.Z(e.url,e.status,ot.br.PARSE_ERROR))})).catch((function(t){if(r)g.Z.debug("Fetch: Request aborted.");else{if(i)return g.Z.warn("Fetch: Request timeouted."),void n.error(new at.Z(e.url,0,ot.br.TIMEOUT));g.Z.warn("Fetch: Request Error",t instanceof Error?t.toString():""),n.error(new at.Z(e.url,0,ot.br.ERROR_EVENT))}})),function(){r=!0,u()}}))};var pt=n(8806),ht=n(281);function vt(e){return"video/webm"===e.mimeType||"audio/webm"===e.mimeType}var mt=n(3068),gt=n(4460);function yt(e){return function(t){return e(t).pipe((0,mt.b)((function(e){"data-loaded"!==e.type&&"data-chunk"!==e.type||null===e.value.responseData||"string"==typeof e.value.responseData||vt(t.representation)||(0,gt.Z)(new Uint8Array(e.value.responseData),t.segment.isInit)})))}}var _t=n(6968);function bt(e,t){var n=t.segment;if(void 0===n.range)return(0,o.ZP)({url:e,responseType:"arraybuffer",sendProgressEvents:!0});if(void 0===n.indexRange)return(0,o.ZP)({url:e,headers:{Range:(0,ht.Z)(n.range)},responseType:"arraybuffer",sendProgressEvents:!0});if(n.range[1]+1===n.indexRange[0])return(0,o.ZP)({url:e,headers:{Range:(0,ht.Z)([n.range[0],n.indexRange[1]])},responseType:"arraybuffer",sendProgressEvents:!0});var r=(0,o.ZP)({url:e,headers:{Range:(0,ht.Z)(n.range)},responseType:"arraybuffer",sendProgressEvents:!1}),i=(0,o.ZP)({url:e,headers:{Range:(0,ht.Z)(n.indexRange)},responseType:"arraybuffer",sendProgressEvents:!1});return(0,c.aj)([r,i]).pipe((0,p.U)((function(t){var n=t[0],r=t[1],i=(0,_t.zo)(new Uint8Array(n.value.responseData),new Uint8Array(r.value.responseData)),a=Math.min(n.value.sendingTime,r.value.sendingTime),o=Math.max(n.value.receivedTime,r.value.receivedTime);return{type:"data-loaded",value:{url:e,responseData:i,size:n.value.size+r.value.size,duration:o-a,sendingTime:a,receivedTime:o}}})))}var Tt=n(2807),Et=n(8766);function wt(e,t){var n=t.segment,r=void 0!==n.range?{Range:(0,ht.Z)(n.range)}:void 0;return ft({url:e,headers:r}).pipe((0,Tt.R)((function(e,t){if("data-complete"===t.type)return null!==e.partialChunk&&g.Z.warn("DASH Pipelines: remaining chunk does not belong to any segment"),{event:t,completeChunks:[],partialChunk:null};var n=new Uint8Array(t.value.chunk),r=function(e){for(var t=0,n=[];te.length)return[n,r];var o=(0,Et.Z)(r,1835295092);if(o<0)return[n,r];var s=t+o+(0,_t.pX)(e,o+t);if(s>e.length)return[n,r];var u=Math.max(a,s),l=e.subarray(t,u);n.push(l),t=u}return[n,null]}(null!==e.partialChunk?(0,_t.zo)(e.partialChunk,n):n);return{event:t,completeChunks:r[0],partialChunk:r[1]}}),{event:null,completeChunks:[],partialChunk:null}),(0,h.zg)((function(e){for(var t=[],n=0;n0)for(var p=0;p=Math.pow(2,8-n))return n}function Nt(e,t){var n=Ct(e,t);if(null==n)return g.Z.warn("webm: unrepresentable length"),null;if(t+n>e.length)return g.Z.warn("webm: impossible length"),null;for(var r=0,i=0;ie.length)return g.Z.warn("webm: impossible length"),null;for(var r=(e[t]&(1<<8-n)-1)*Math.pow(2,8*(n-1)),i=1;i=i)return!0}return!1}(r,t)}}}function Bt(e){var t=e.__priv_patchLastSegmentInSidx;return function(e){var n=e.content,r=e.response,a=e.initTimescale,o=n.period,u=n.representation,l=n.segment,d=n.manifest,c=r.data,f=r.isChunked,p=[o.start,o.end];if(null===c)return l.isInit?(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}}):(0,i.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:p}});var h=c instanceof Uint8Array?c:new Uint8Array(c),v=vt(u);if(!l.isInit){var m=v?null:Dt(h,f,l,a),g=(0,s.Z)(l.timestampOffset,0);if(!v){var y=(0,kt.s9)(h);if(void 0!==y){var _=Lt(y.filter((function(e){return void 0!==l.privateInfos&&void 0!==l.privateInfos.isEMSGWhitelisted&&l.privateInfos.isEMSGWhitelisted(e)})),d.publishTime);if(void 0!==_){var b=_.needsManifestRefresh,T=_.inbandEvents;return(0,i.of)({type:"parsed-segment",value:{chunkData:h,chunkInfos:m,chunkOffset:g,appendWindow:p,inbandEvents:T,needsManifestRefresh:b}})}}}return(0,i.of)({type:"parsed-segment",value:{chunkData:h,chunkInfos:m,chunkOffset:g,appendWindow:p}})}var E,w=l.indexRange;if(v)E=function(e,t){var n=Zt(xt,[],e,[t,e.length]);if(null==n)return null;var r=n[0],i=n[1],a=Rt(e,r);if(null==a)return null;var o=Mt(e,r);if(null==o)return null;var s=Zt(475249515,[],e,[r,i]);if(null==s)return null;for(var u=[],l=s[0];l0){var S=E[E.length-1];Array.isArray(S.range)&&(S.range[1]=1/0)}u.index instanceof Ee&&null!==E&&E.length>0&&u.index._addSegments(E);var k=v?Rt(h,0):(0,kt.LD)(h),A=(0,st.Z)(k)?void 0:k,x=!1;if(!v){var I=(0,At.Z)(h);I.length>0&&(x=u._addProtectionData("cenc",I))}return(0,i.of)({type:"parsed-init-segment",value:{initializationData:h,protectionDataUpdate:x,initTimescale:A}})}}function Ut(e){return"application/mp4"===e.mimeType}var Ft=n(6807);function zt(e,t,n,r){var i,a,o=e.segment,s=e.adaptation,u=e.representation;if(o.isInit)return null;null===n?r?(i=o.time,a=o.end):g.Z.warn("Transport: Unavailable time data for current text track."):(i=n.time,void 0!==n.duration?a=i+n.duration:r||(a=i+o.duration));var l=function(e){var t=e.codec;if(void 0===t)throw new Error("Cannot parse subtitles: unknown format");switch(t.toLowerCase()){case"stpp":case"stpp.ttml.im1t":return"ttml";case"wvtt":return"vtt"}throw new Error('The codec used for the subtitles "'+t+'" is not managed yet.')}(u);return{data:function(e){var t=(0,Ft.Le)(e);return null===t?"":(0,H.uR)(t)}(t),type:l,language:s.language,start:i,end:a}}function Kt(e,t,n){var r=e.segment,i=e.adaptation,a=e.representation;return r.isInit?null:(n&&g.Z.warn("Transport: Unavailable time data for current text track."),{data:t,type:function(e){var t=e.mimeType,n=void 0===t?"":t;switch(e.mimeType){case"application/ttml+xml":return"ttml";case"application/x-sami":case"application/smil":return"sami";case"text/vtt":return"vtt"}var r=e.codec;if("srt"===(void 0===r?"":r).toLowerCase())return"srt";throw new Error("could not find a text-track parser for the type "+n)}(a),language:i.language})}function Vt(e){var t=e.__priv_patchLastSegmentInSidx;return function(e){var n=e.response,r=e.content,a=e.initTimescale,o=r.period,u=r.representation,l=r.segment,d=l.timestampOffset,c=void 0===d?0:d,f=n.data,p=n.isChunked;return null===f?l.isInit?(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}}):(0,i.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:c,appendWindow:[o.start,o.end]}}):Ut(u)?function(e,t){var n=e.response,r=e.content,a=e.initTimescale,o=r.period,u=r.representation,l=r.segment,d=l.isInit,c=l.indexRange,f=n.data,p=n.isChunked,h="string"==typeof f?(0,H.tG)(f):f instanceof Uint8Array?f:new Uint8Array(f);if(d){var v=(0,kt.Wf)(h,Array.isArray(c)?c[0]:0);if(!0===t&&null!==v&&v.length>0){var m=v[v.length-1];Array.isArray(m.range)&&(m.range[1]=1/0)}var g=(0,kt.LD)(h);return u.index instanceof Ee&&null!==v&&v.length>0&&u.index._addSegments(v),(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:g}})}var y=Dt(h,p,l,a),_=zt(r,h,y,p),b=(0,s.Z)(l.timestampOffset,0);return(0,i.of)({type:"parsed-segment",value:{chunkData:_,chunkInfos:y,chunkOffset:b,appendWindow:[o.start,o.end]}})}({response:{data:f,isChunked:p},content:r,initTimescale:a},t):function(e){var t=e.response,n=e.content,r=n.period,a=n.segment,o=a.timestampOffset,s=void 0===o?0:o;if(a.isInit)return(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}});var u,l=t.data,d=t.isChunked;if("string"!=typeof l){var c=l instanceof Uint8Array?l:new Uint8Array(l);u=(0,H.uR)(c)}else u=l;var f=Kt(n,u,d);return(0,i.of)({type:"parsed-segment",value:{chunkData:f,chunkInfos:null,chunkOffset:s,appendWindow:[r.start,r.end]}})}({response:{data:f,isChunked:p},content:r})}}const Wt=function(e){var t=(0,r.Z)({customManifestLoader:e.manifestLoader}),n=Je(e),a=function(e){var t=e.lowLatencyMode,n=e.segmentLoader;return!0!==e.checkMediaSegmentIntegrity?r:yt(r);function r(e){var r=e.url;if(null==r)return(0,i.of)({type:"data-created",value:{responseData:null}});if(t||void 0===n)return St(r,e,t);var a={adaptation:e.adaptation,manifest:e.manifest,period:e.period,representation:e.representation,segment:e.segment,transport:"dash",url:r};return new et.y((function(i){var o=!1,s=!1,u=n(a,{reject:function(e){void 0===e&&(e={}),s||(o=!0,i.error(e))},resolve:function(e){s||(o=!0,i.next({type:"data-loaded",value:{responseData:e.data,size:e.size,duration:e.duration}}),i.complete())},progress:function(e){s||i.next({type:"progress",value:{duration:e.duration,size:e.size,totalSize:e.totalSize}})},fallback:function(){s=!0,St(r,e,t).subscribe(i)}});return function(){o||s||"function"!=typeof u||u()}}))}}(e),s=Bt(e);return{manifest:{loader:t,parser:n},audio:{loader:a,parser:s},video:{loader:a,parser:s},text:{loader:function(e){var t=e.lowLatencyMode;return!0!==e.checkMediaSegmentIntegrity?n:yt(n);function n(e){var n=e.segment.range,r=e.url;if(null===r)return(0,i.of)({type:"data-created",value:{responseData:null}});if(e.segment.isInit)return bt(r,e);var a=Ut(e.representation);if(t&&a){if(ct())return wt(r,e);(0,pt.Z)("DASH: Your browser does not have the fetch API. You will have a higher chance of rebuffering when playing close to the live edge")}var s=a?"arraybuffer":"text";return(0,o.ZP)({url:r,responseType:s,headers:Array.isArray(n)?{Range:(0,ht.Z)(n)}:null,sendProgressEvents:!0})}}(e),parser:Vt(e)},image:{loader:u,parser:l}}}},2339:(e,t,n)=>{"use strict";n.d(t,{Z:()=>ye});var r=n(8170),i=n(5709),a=n(3068),o=n(7874),s=n(3887),u=n(1966),l=n(6807),d=n(7714),c=n(811),f=n(6968),p=n(6923),h=n(8026),v=n(9829),m=n(3635),g=n(5278),y=n(2689),_={};function b(e){if(null!=_[e])return _[e];var t=(0,m.tG)(e);return _[e]=t,t}function T(e,t){var n=t.length+8;return n<=y.s?(0,f.zo)((0,f.kh)(n),b(e),t):(0,f.zo)((0,f.kh)(1),b(e),(0,f.el)(n+8),t)}function E(e,t){return T(e,f.zo.apply(void 0,t))}function w(e){var t=[];e.periods.forEach((function(n){var r=n.id;if((0,d.Z)(t,r)){s.Z.warn("Two periods with the same ID found. Updating.");var i=r+"-dup";n.id=i,w(e),t.push(i)}else t.push(r);var a=n.adaptations,o=[];Object.keys(a).forEach((function(t){var n=a[t];void 0!==n&&n.forEach((function(t){var n=t.id;if((0,d.Z)(o,n)){s.Z.warn("Two adaptations with the same ID found. Updating.",n);var r=n+"-dup";t.id=r,w(e),o.push(r)}else o.push(n);var i=[];t.representations.forEach((function(t){var n=t.id;if((0,d.Z)(i,n)){s.Z.warn("Two representations with the same ID found. Updating.",n);var r=n+"-dup";t.id=r,w(e),i.push(r)}else i.push(n)}))}))}))}))}var S=n(9689);function k(e){return[{systemId:"edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",privateData:(0,f.zo)([8,1,18,16],e)}]}function A(e,t){if(void 0===t&&(t=k),null===e.firstElementChild||"ProtectionHeader"!==e.firstElementChild.nodeName)throw new Error("Protection should have ProtectionHeader child");var n=e.firstElementChild,r=(0,S.K)(null===n.textContent?"":n.textContent),i=function(e){var t=(0,f.qb)(e,8),n=(0,m.wV)(e.subarray(10,t+10)),r=(new DOMParser).parseFromString(n,"application/xml").querySelector("KID");if(null===r)throw new Error("Cannot parse PlayReady private data: invalid XML");var i=null===r.textContent?"":r.textContent,a=(0,m.wO)((0,S.K)(i));return(0,m.ci)(a).toLowerCase()}(r),a=(0,m.nr)(i),o=n.getAttribute("SystemID");return{keyId:a,keySystems:[{systemId:(null!==o?o:"").toLowerCase().replace(/\{|\}/g,""),privateData:r}].concat(t(a))}}var x=n(9362),I=n(8232),Z=n(3911),R=n(1091),M=n(5505);function C(e,t,n){var r=e.timeline,i=e.timescale,a=r[r.length-1],o=t.timescale===i?{time:t.time,duration:t.duration}:{time:t.time/t.timescale*i,duration:t.duration/t.timescale*i};return!(n.time===o.time)&&(o.time>=(0,Z.jH)(a,null)&&(a.duration===o.duration?a.repeatCount++:e.timeline.push({duration:o.duration,start:o.time,repeatCount:0}),!0))}function N(e,t){return e.replace(/\{start time\}/g,String(t))}function P(e,t,n){var r=t-e;return r>0?Math.floor(r/n):0}function O(e,t){var n=e.repeatCount;if(null!=e.duration&&n<0){var r=void 0!==t?t.start:1/0;n=Math.ceil((r-e.start)/e.duration)-1}return n}var D=function(){function e(e,t){var n=t.aggressiveMode,r=t.isLive,i=t.segmentPrivateInfos,a=null==e.manifestReceivedTime?performance.now():e.manifestReceivedTime;if(this._index=e,this._indexValidityTime=a,this._initSegmentInfos={bitsPerSample:i.bitsPerSample,channels:i.channels,codecPrivateData:i.codecPrivateData,packetSize:i.packetSize,samplingRate:i.samplingRate,timescale:e.timescale,protection:i.protection},this._isAggressiveMode=n,this._isLive=r,0!==e.timeline.length){var o=e.timeline[e.timeline.length-1],s=(0,Z.jH)(o,null);if(this._initialScaledLastPosition=s,e.isLive){var u=a/1e3*e.timescale;this._scaledLiveGap=u-s}}}var t=e.prototype;return t.getInitSegment=function(){return{id:"init",isInit:!0,privateInfos:{smoothInitSegment:this._initSegmentInfos},mediaURLs:null,time:0,end:0,duration:0,timescale:1}},t.getSegments=function(e,t){this._refreshTimeline();for(var n,r=function(e,t,n){var r=void 0===e.timescale||0===e.timescale?1:e.timescale;return{up:t*r,to:(t+n)*r}}(this._index,e,t),i=r.up,a=r.to,o=this._index,s=o.timeline,u=o.timescale,l=o.media,d=this._isAggressiveMode,c=[],f=s.length,p=null==this._scaledLiveGap?void 0:performance.now()/1e3*u-this._scaledLiveGap,h=0;h=a)return c;null!=n&&(n+=y+1)}return c},t.shouldRefresh=function(e,t){if(this._refreshTimeline(),!this._index.isLive)return!1;var n=this._index,r=n.timeline,i=n.timescale,a=r[r.length-1];if(void 0===a)return!1;var o=a.repeatCount,s=a.start+(o+1)*a.duration;return!(t*i=s||e*i>a.start+o*a.duration)},t.getFirstPosition=function(){this._refreshTimeline();var e=this._index;return 0===e.timeline.length?null:e.timeline[0].start/e.timescale},t.getLastPosition=function(){this._refreshTimeline();var e=this._index;if(null==this._scaledLiveGap){var t=e.timeline[e.timeline.length-1];return(0,Z.jH)(t,null)/e.timescale}for(var n=e.timeline.length-1;n>=0;n--)for(var r=e.timeline[n],i=performance.now()/1e3*e.timescale,a=r.start,o=r.duration,s=r.repeatCount;s>=0;s--){var u=a+o*(s+1);if((this._isAggressiveMode?u-o:u)<=i-this._scaledLiveGap)return u/e.timescale}},t.checkDiscontinuity=function(e){return this._refreshTimeline(),(0,Z._j)(this._index,e,void 0)},t.areSegmentsChronologicallyGenerated=function(){return!0},t.isSegmentStillAvailable=function(e){if(e.isInit)return!0;this._refreshTimeline();var t=this._index,n=t.timeline,r=t.timescale;return(0,R.Z)(e,n,r,0)},t.canBeOutOfSyncError=function(e){return!!this._isLive&&(e instanceof x.Z&&(e.isHttpError(404)||e.isHttpError(412)))},t._replace=function(e){var t=this._index.timeline,n=e._index.timeline,r=this._index.timescale,i=e._index.timescale;if(this._index=e._index,this._initialScaledLastPosition=e._initialScaledLastPosition,this._indexValidityTime=e._indexValidityTime,this._scaledLiveGap=e._scaledLiveGap,0!==t.length&&0!==n.length&&r===i){var a=t[t.length-1],o=n[n.length-1],u=(0,Z.jH)(o,null);if(!((0,Z.jH)(a,null)<=u))for(var l=0;lu){if(d.duration!==o.duration)return;var f=u-d.start;if(0===f)return s.Z.warn("Smooth Parser: a discontinuity detected in the previous manifest has been resolved."),void(this._index.timeline=this._index.timeline.concat(t.slice(l)));if(f<0||f%d.duration!=0)return;var p=f/d.duration-1,h=d.repeatCount-p;if(h<0)return;o.repeatCount+=h;var v=t.slice(l+1);return void(this._index.timeline=this._index.timeline.concat(v))}}}},t._update=function(e){(0,M.Z)(this._index.timeline,e._index.timeline),this._initialScaledLastPosition=e._initialScaledLastPosition,this._indexValidityTime=e._indexValidityTime,this._scaledLiveGap=e._scaledLiveGap},t.isFinished=function(){return!this._isLive},t.isInitialized=function(){return!0},t._addSegments=function(e,t){this._refreshTimeline();for(var n=0;n>3:2)?"mp4a.40.2":"mp4a.40."+n}(u,l);return{audiotag:void 0!==i?parseInt(i,10):i,bitrate:h,bitsPerSample:void 0!==a?parseInt(a,10):a,channels:void 0!==o?parseInt(o,10):o,codecPrivateData:u,codecs:v,customAttributes:n,mimeType:void 0!==l?F[l]:l,packetSize:void 0!==d?parseInt(d,10):d,samplingRate:void 0!==c?parseInt(c,10):c};case"video":var m=r("CodecPrivateData"),y=r("FourCC"),_=r("MaxWidth"),b=r("MaxHeight"),T=r("Bitrate"),E=void 0===T||isNaN(parseInt(T,10))?0:parseInt(T,10);if(void 0!==y&&void 0===F[y]||void 0===m)return s.Z.warn("Smooth parser: Unsupported video codec. Ignoring quality level."),null;var w=function(e){var t=/00000001\d7([0-9a-fA-F]{6})/.exec(e);return null!==t&&(0,p.Z)(t[1])?"avc1."+t[1]:"avc1.4D401E"}(m);return{bitrate:E,customAttributes:n,mimeType:void 0!==y?F[y]:y,codecPrivateData:m,codecs:w,width:void 0!==_?parseInt(_,10):void 0,height:void 0!==b?parseInt(b,10):void 0};case"text":var S=r("CodecPrivateData"),k=r("FourCC"),A=r("Bitrate");return{bitrate:void 0===A||isNaN(parseInt(A,10))?0:parseInt(A,10),customAttributes:n,mimeType:void 0!==k?F[k]:k,codecPrivateData:(0,g.Z)(S,"")};default:return s.Z.error("Smooth Parser: Unrecognized StreamIndex type: "+t),null}}function o(t){var r=t.root,i=t.timescale,o=t.rootURL,u=t.protections,l=t.timeShiftBufferDepth,g=t.manifestReceivedTime,y=t.isLive,_=r.getAttribute("Timescale"),b=null===_||isNaN(+_)?i:+_,E=r.getAttribute("Type");if(null===E)throw new Error("StreamIndex without type.");(0,d.Z)(B,E)||s.Z.warn("Smooth Parser: Unrecognized adaptation type:",E);var w=E,S=r.getAttribute("Subtype"),k=r.getAttribute("Language"),A=r.getAttribute("Url"),x=null===A?"":A;var I,Z=L(r,(function(e,t,r){switch(t){case"QualityLevel":var i=a(r,w);if(null===i)return e;("video"!==w||i.bitrate>n)&&e.qualityLevels.push(i);break;case"c":e.cNodes.push(r)}return e}),{qualityLevels:[],cNodes:[]}),R=Z.qualityLevels,M=Z.cNodes,C={timeline:(I=M,I.reduce((function(e,t,n){var r=t.getAttribute("d"),i=t.getAttribute("t"),a=t.getAttribute("r"),o=null!==a?+a-1:0,s=null!==i?+i:void 0,u=null!==r?+r:void 0;if(0===n)s=void 0===s||isNaN(s)?0:s;else{var l=e[n-1];if(null==s||isNaN(s)){if(null==l.duration||isNaN(l.duration))throw new Error("Smooth: Invalid CNodes. Missing timestamp.");s=l.start+l.duration*(l.repeatCount+1)}}if(null==u||isNaN(u)){var d=I[n+1];if(void 0===d)return e;var c=d.getAttribute("t"),f=(0,p.Z)(c)?+c:null;if(null===f)throw new Error("Can't build index timeline from Smooth Manifest.");u=f-s}return e.push({duration:u,start:s,repeatCount:o}),e}),[])),timescale:b};(0,c.Z)(0!==R.length,"Adaptation should have at least one playable representation.");var N=w+((0,p.Z)(k)?"_"+k:""),P=R.map((function(t){var n,r,i,a,s=(0,v.Z)(o,x),d={timeline:C.timeline,timescale:C.timescale,media:(n=s,r=t.bitrate,i=t.customAttributes,n.replace(/\{bitrate\}/g,String(r)).replace(/{CustomAttributes}/g,i.length>0?i[0]:"")),isLive:y,timeShiftBufferDepth:l,manifestReceivedTime:g},c=(0,p.Z)(t.mimeType)?t.mimeType:U[w],_=t.codecs,b=N+"_"+(null!=w?w+"-":"")+(null!=c?c+"-":"")+(null!=_?_+"-":"")+String(t.bitrate),E=[];u.length>0&&(a=u[0],u.forEach((function(e){var t=e.keyId;e.keySystems.forEach((function(e){E.push({keyId:t,systemId:e.systemId})}))})));var S={bitsPerSample:t.bitsPerSample,channels:t.channels,codecPrivateData:t.codecPrivateData,packetSize:t.packetSize,samplingRate:t.samplingRate,protection:null!=a?{keyId:a.keyId}:void 0},k=null!=e.aggressiveMode&&e.aggressiveMode,A=new D(d,{aggressiveMode:k,isLive:y,segmentPrivateInfos:S}),I=(0,h.Z)({},t,{index:A,mimeType:c,codecs:_,id:b});if(E.length>0||void 0!==a){var Z=void 0===a?[]:a.keySystems.map((function(e){var t=e.systemId,n=e.privateData,r=t.replace(/-/g,"");return{systemId:r,data:function(e,t){if(32!==e.length)throw new Error("HSS: wrong system id length");var n=0;return T("pssh",(0,f.zo)([n,0,0,0],(0,m.nr)(e),(0,f.kh)(t.length),t))}(r,n)}}));if(Z.length>0){var R=[{type:"cenc",values:Z}];I.contentProtections={keyIds:E,initData:R}}else I.contentProtections={keyIds:E,initData:[]}}return I}));if("ADVT"===S)return null;var O={id:N,type:w,representations:P,language:null==k?void 0:k};return"text"===w&&"DESC"===S&&(O.closedCaption=!0),O}return function(n,r,a){var s=(0,v.f)(null==r?"":r),u=n.documentElement;if(null==u||"SmoothStreamingMedia"!==u.nodeName)throw new Error("document root should be SmoothStreamingMedia");var l=u.getAttribute("MajorVersion"),d=u.getAttribute("MinorVersion");if(null===l||null===d||!/^[2]-[0-2]$/.test(l+"-"+d))throw new Error("Version should be 2.0, 2.1 or 2.2");var c,f,h=u.getAttribute("Timescale"),m=(0,p.Z)(h)?isNaN(+h)?1e7:+h:1e7,g=L(u,(function(t,n,r){switch(n){case"Protection":t.protections.push(A(r,e.keySystems));break;case"StreamIndex":t.adaptationNodes.push(r)}return t}),{adaptationNodes:[],protections:[]}),y=g.protections,_=g.adaptationNodes,b="boolean"==typeof(c=u.getAttribute("IsLive"))?c:"string"==typeof c&&"TRUE"===c.toUpperCase();if(b){var T=u.getAttribute("DVRWindowLength");null==T||isNaN(+T)||0==+T||(f=+T/m)}var E,S,k,x,I,Z,R=_.reduce((function(e,t){var n=o({root:t,rootURL:s,timescale:m,protections:y,isLive:b,timeShiftBufferDepth:f,manifestReceivedTime:a});if(null===n)return e;var r=n.type,i=e[r];return void 0===i?e[r]=[n]:i.push(n),e}),{}),M=null,C=void 0!==R.video?R.video[0]:void 0,N=void 0!==R.audio?R.audio[0]:void 0;if(void 0!==C||void 0!==N){var P=[],O=[];if(void 0!==C){var D=C.representations[0];if(void 0!==D){var B=D.index.getFirstPosition(),U=D.index.getLastPosition();null!=B&&P.push(B),null!=U&&O.push(U)}}if(void 0!==N){var F=N.representations[0];if(void 0!==F){var z=F.index.getFirstPosition(),K=F.index.getLastPosition();null!=z&&P.push(z),null!=K&&O.push(K)}}P.length>0&&(I=Math.max.apply(Math,P)),O.length>0&&(Z=Math.min.apply(Math,O))}var V=u.getAttribute("Duration"),W=null!=V&&0!=+V?+V/m:void 0;b?(E=e.suggestedPresentationDelay,S=t,k=null!=I?I:S,x={isLinear:!0,value:null!=Z?Z:Date.now()/1e3-S,time:performance.now()},M=null!=f?f:null):(k=null!=I?I:0,x={isLinear:!1,value:void 0!==Z?Z:void 0!==W?k+W:1/0,time:performance.now()});var G=b?0:k,H=b?void 0:x.value,$={availabilityStartTime:void 0===S?0:S,clockOffset:i,isLive:b,isDynamic:b,timeBounds:{absoluteMinimumTime:k,timeshiftDepth:M,maximumTimeData:x},periods:[{adaptations:R,duration:void 0!==H?H-G:W,end:H,id:"gen-smooth-period-0",start:G}],suggestedPresentationDelay:E,transportType:"smooth",uris:null==r?[]:[r]};return w($),$}};var K=n(4597),V=n(8806),W=n(4460),G=n(7445),H=n(7278),$=n(4644),j=n(2297);function Y(e,t,n,r,i){var a,o,u,d=[];if(i){var c=(0,l.XA)(e);null!==c?(u=function(e){var t=(0,j.nR)(e,3565190898,3392751253,2387879627,2655430559);if(void 0===t)return[];for(var n=[],r=t[0],i=t[4],a=0;a0)return e;var n=new Uint8Array(e.length+4);return n.set(e.subarray(0,t+8),0),n[t+3]=1|n[t+3],n.set([0,0,0,0],t+8),n.set(e.subarray(t+8,e.length),t+12),(0,$.J6)(n)}(l,s[1]-s[0]),p=te(u,d,c,i,(0,j.nR)(a,2721664850,1520127764,2722393154,2086964724)),h=E("moof",[i,p]),v=(0,j.Qy)(h,1836019558),m=(0,j.Qy)(p,1953653094),g=(0,j.Qy)(c,1953658222);if(null===v||null===m||null===g)throw new Error("Smooth: Invalid moof, trun or traf generation");var y=v[1]-v[0]+i.length+(m[1]-m[0])+u.length+d.length+(g[1]-g[0])+8,_=n[2]-n[0],b=h.length-_,w=(0,j.Qy)(e,1835295092);if(null===w)throw new Error("Smooth: Invalid ISOBMFF given");if(!q.YM&&(0===b||b<=-8)){var S=w[1];return h.set((0,f.kh)(S),y),e.set(h,n[0]),b<=-8&&e.set(T("free",new Uint8Array(-b-8)),h.length),e}var k=w[1]+b;h.set((0,f.kh)(k),y);var A=new Uint8Array(e.length+b),x=e.subarray(0,n[0]),I=e.subarray(n[2],e.length);return A.set(x,0),A.set(h,x.length),A.set(I,x.length+h.length),A}var re=n(4379),ie=n(281);function ae(e,t,n,r,i,a){var o,s,u,l=E("stbl",[n,T("stts",new Uint8Array(8)),T("stsc",new Uint8Array(8)),T("stsz",new Uint8Array(12)),T("stco",new Uint8Array(8))]),d=E("dinf",[function(e){return T("dref",(0,f.zo)(7,[1],e))}(T("url ",new Uint8Array([0,0,0,1])))]),c=E("minf",[r,d,l]),p=function(e){var t,n;switch(e){case"video":t="vide",n="VideoHandler";break;case"audio":t="soun",n="SoundHandler";break;default:t="hint",n=""}return T("hdlr",(0,f.zo)(8,(0,m.tG)(t),12,(0,m.tG)(n),1))}(t),h=E("mdia",[function(e){return T("mdhd",(0,f.zo)(12,(0,f.kh)(e),8))}(e),p,c]),v=E("trak",[function(e,t,n){return T("tkhd",(0,f.zo)((0,f.kh)(7),8,(0,f.kh)(n),20,[1,0,0,0],[0,1,0,0],12,[0,1,0,0],12,[64,0,0,0],(0,f.XT)(e),2,(0,f.XT)(t),2))}(i,a,1),h]),g=E("mvex",[(o=1,T("trex",(0,f.zo)(4,(0,f.kh)(o),[0,0,0,1],12)))]),y=function(e,t,n){return E("moov",[e,t,n])}(function(e,t){return T("mvhd",(0,f.zo)(12,(0,f.kh)(e),4,[0,1],2,[1,0],10,[0,1],14,[0,1],14,[64,0,0,0],26,(0,f.XT)(t+1)))}(e,1),g,v),_=(s="isom",u=["isom","iso2","iso6","avc1","dash"],T("ftyp",f.zo.apply(void 0,[(0,m.tG)(s),[0,0,0,1]].concat(u.map(m.tG)))));return(0,f.zo)(_,y)}function oe(e,t,n,r,i,a,o,s){var u=o.split("00000001"),l=u[1],d=u[2];if(void 0===l||void 0===d)throw new Error("Smooth: unsupported codec private data.");var c,p,h=function(e,t,n){var r=2===n?1:4===n?3:0,i=e[1],a=e[2],o=e[3];return T("avcC",(0,f.zo)([1,i,a,o,252|r,225],(0,f.XT)(e.length),e,[1],(0,f.XT)(t.length),t))}((0,m.nr)(l),(0,m.nr)(d),a);if(void 0===s){c=J([function(e,t,n,r,i,a,o){return T("avc1",(0,f.zo)(6,(0,f.XT)(1),16,(0,f.XT)(e),(0,f.XT)(t),(0,f.XT)(n),2,(0,f.XT)(r),6,[0,1,i.length],(0,m.tG)(i),31-i.length,(0,f.XT)(a),[255,255],o))}(t,n,r,i,"AVC Coding",24,h)])}else{var v=E("schi",[ee(1,8,s)]),g=X("cenc",65536);c=J([function(e,t,n,r,i,a,o,s){return T("encv",(0,f.zo)(6,(0,f.XT)(1),16,(0,f.XT)(e),(0,f.XT)(t),(0,f.XT)(n),2,(0,f.XT)(r),6,[0,1,i.length],(0,m.tG)(i),31-i.length,(0,f.XT)(a),[255,255],o,s))}(t,n,r,i,"AVC Coding",24,h,E("sinf",[Q("avc1"),g,v]))])}return ae(e,"video",c,((p=new Uint8Array(12))[3]=1,T("vmhd",p)),t,n)}var se=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];function ue(e,t,n,r,i,a,o){var s,u,l,d=function(e,t){return T("esds",(0,f.zo)(4,[3,25],(0,f.XT)(e),[0,4,17,64,21],11,[5,2],(0,m.nr)(t),[6,1,2]))}(1,0===a.length?(s=i,u=t,l=((l=((l=(63&2)<<4)|31&se.indexOf(s))<<4)|31&u)<<3,(0,m.ci)((0,f.XT)(l))):a);return ae(e,"audio",function(){if(void 0===o)return J([function(e,t,n,r,i,a){return T("mp4a",(0,f.zo)(6,(0,f.XT)(e),8,(0,f.XT)(t),(0,f.XT)(n),2,(0,f.XT)(r),(0,f.XT)(i),2,a))}(1,t,n,r,i,d)]);var e=E("schi",[ee(1,8,o)]),a=X("cenc",65536),s=E("sinf",[Q("mp4a"),a,e]);return J([function(e,t,n,r,i,a,o){return T("enca",(0,f.zo)(6,(0,f.XT)(e),8,(0,f.XT)(t),(0,f.XT)(n),2,(0,f.XT)(r),(0,f.XT)(i),2,a,o))}(1,t,n,r,i,d,s)])}(),T("smhd",new Uint8Array(8)),0,0)}function le(e){var t,n=e.url,r=e.segment.range;return Array.isArray(r)&&(t={Range:(0,ie.Z)(r)}),(0,K.ZP)({url:n,responseType:"arraybuffer",headers:t,sendProgressEvents:!0})}const de=function(e){return function(t){var n=t.segment,i=t.representation,a=t.adaptation,o=t.period,s=t.manifest,u=t.url;if(n.isInit){if(void 0===n.privateInfos||void 0===n.privateInfos.smoothInitSegment)throw new Error("Smooth: Invalid segment format");var l,d=n.privateInfos.smoothInitSegment,c=d.codecPrivateData,f=d.timescale,p=d.protection,h=void 0===p?{keyId:void 0,keySystems:void 0}:p;if(void 0===c)throw new Error("Smooth: no codec private data.");switch(a.type){case"video":var v=i.width,m=void 0===v?0:v,g=i.height;l=oe(f,m,void 0===g?0:g,72,72,4,c,h.keyId);break;case"audio":var y=d.channels,_=void 0===y?0:y,b=d.bitsPerSample,T=void 0===b?0:b,E=d.packetSize,w=void 0===E?0:E,S=d.samplingRate;l=ue(f,_,T,w,void 0===S?0:S,c,h.keyId);break;default:0,l=new Uint8Array(0)}return(0,r.of)({type:"data-created",value:{responseData:l}})}if(null===u)return(0,r.of)({type:"data-created",value:{responseData:null}});var k={adaptation:a,manifest:s,period:o,representation:i,segment:n,transport:"smooth",url:u};return"function"!=typeof e?le(k):new re.y((function(t){var n=!1,r=!1,i=e(k,{reject:function(e){void 0===e&&(e={}),r||(n=!0,t.error(e))},resolve:function(e){r||(n=!0,t.next({type:"data-loaded",value:{responseData:e.data,size:e.size,duration:e.duration}}),t.complete())},fallback:function(){r=!0,le(k).subscribe(t)},progress:function(e){r||t.next({type:"progress",value:{duration:e.duration,size:e.size,totalSize:e.totalSize}})}});return function(){n||r||"function"!=typeof i||i()}}))}};var ce=/(\.isml?)(\?token=\S+)?$/,fe=/\?token=(\S+)/;function pe(e,t){return(0,p.Z)(t)?e.replace(fe,"?token="+t):e.replace(fe,"")}function he(e){return ce.test(e)?((0,V.Z)("Giving a isml URL to loadVideo is deprecated. Please give the Manifest URL directly"),e.replace(ce,"$1/manifest$2")):e}var ve=/\.wsx?(\?token=\S+)?/;function me(e,t,n){var r;s.Z.debug("Smooth Parser: update segments information.");for(var i=e.representations,a=0;a=0}const ye=function(e){var t=z(e),n=de(e.segmentLoader),d={customManifestLoader:e.manifestLoader},c={loader:function(t){return t.segment.isInit||!0!==e.checkMediaSegmentIntegrity?n(t):n(t).pipe((0,a.b)((function(e){"data-loaded"!==e.type&&"data-chunk"!==e.type||null===e.value.responseData||(0,W.Z)(new Uint8Array(e.value.responseData),t.segment.isInit)})))},parser:function(e){var t,n,i=e.content,a=e.response,o=e.initTimescale,s=i.segment,u=i.adaptation,l=i.manifest,d=a.data,c=a.isChunked;if(null===d)return s.isInit?(0,r.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}}):(0,r.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:[void 0,void 0]}});var f=d instanceof Uint8Array?d:new Uint8Array(d);if(s.isInit){var p=null===(n=null===(t=s.privateInfos)||void 0===t?void 0:t.smoothInitSegment)||void 0===n?void 0:n.timescale;return(0,r.of)({type:"parsed-init-segment",value:{initializationData:d,initTimescale:p,protectionDataUpdate:!1}})}var h=void 0!==o?Y(f,c,o,s,l.isLive):null;if(null===h||null===h.chunkInfos||void 0===h.scaledSegmentTime)throw new Error("Smooth Segment without time information");var v=h.nextSegments,m=h.chunkInfos,g=ne(f,h.scaledSegmentTime);return v.length>0&&me(u,v,s),(0,r.of)({type:"parsed-segment",value:{chunkData:g,chunkInfos:m,chunkOffset:0,appendWindow:[void 0,void 0]}})}};return{manifest:{resolver:function(e){var t,n=e.url;if(void 0===n)return(0,r.of)({url:void 0});ve.test(n)?((0,V.Z)("Giving WSX URL to loadVideo is deprecated. You should only give Manifest URLs."),t=(0,K.ZP)({url:pe(n,""),responseType:"document"}).pipe((0,i.U)((function(e){var t=e.value,n=t.responseData.getElementsByTagName("media")[0].getAttribute("src");if(null===n||0===n.length)throw new Error("Invalid ISML");return n})))):t=(0,r.of)(n);var a=function(e){var t=fe.exec(e);if(null!==t){var n=t[1];if(void 0!==n)return n}return""}(n);return t.pipe((0,i.U)((function(e){return{url:pe(he(e),a)}})))},loader:(0,H.Z)(d),parser:function(n){var r=n.response,i=n.url,a=void 0===r.url?i:r.url,o="string"==typeof r.responseData?(new DOMParser).parseFromString(r.responseData,"text/xml"):r.responseData,s=r.receivedTime,l=t(o,a,s),d=new u.ZP(l,{representationFilter:e.representationFilter,supplementaryImageTracks:e.supplementaryImageTracks,supplementaryTextTracks:e.supplementaryTextTracks});return(0,G.Z)(d,a)}},audio:c,video:c,text:{loader:function(t){var n=t.segment,i=t.representation,o=t.url;if(n.isInit||null===o)return(0,r.of)({type:"data-created",value:{responseData:null}});var s=ge(i);return s&&!0===e.checkMediaSegmentIntegrity?(0,K.ZP)({url:o,responseType:"arraybuffer",sendProgressEvents:!0}).pipe((0,a.b)((function(e){"data-loaded"===e.type&&(0,W.Z)(new Uint8Array(e.value.responseData),n.isInit)}))):(0,K.ZP)({url:o,responseType:s?"arraybuffer":"text",sendProgressEvents:!0})},parser:function(e){var t,n,i=e.content,a=e.response,o=e.initTimescale,u=i.manifest,d=i.adaptation,c=i.representation,f=i.segment,p=d.language,h=ge(c),v=c.mimeType,g=void 0===v?"":v,y=c.codec,_=void 0===y?"":y,b=a.data,T=a.isChunked;if(f.isInit)return(0,r.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}});if(null===b)return(0,r.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:[void 0,void 0]}});var E,w,S,k,A=null;if(h){var x;x="string"==typeof b?(0,m.tG)(b):b instanceof Uint8Array?b:new Uint8Array(b);var I=void 0!==o?Y(x,T,o,f,u.isLive):null;n=null==I?void 0:I.nextSegments,null===(A=null!==(t=null==I?void 0:I.chunkInfos)&&void 0!==t?t:null)?T?s.Z.warn("Smooth: Unavailable time data for current text track."):(E=f.time,w=f.end):(E=A.time,w=void 0!==A.duration?A.time+A.duration:f.end);var Z=_.toLowerCase();if("application/ttml+xml+mp4"===g||"stpp"===Z||"stpp.ttml.im1t"===Z)k="ttml";else{if("wvtt"!==Z)throw new Error("could not find a text-track parser for the type "+g);k="vtt"}var R=(0,l.Le)(x);S=null===R?"":(0,m.uR)(R)}else{var M;if(E=f.time,w=f.end,"string"!=typeof b){var C=b instanceof Uint8Array?b:new Uint8Array(b);M=(0,m.uR)(C)}else M=b;switch(g){case"application/x-sami":case"application/smil":k="sami";break;case"application/ttml+xml":k="ttml";break;case"text/vtt":k="vtt"}if(void 0===k){if("srt"!==_.toLowerCase())throw new Error("could not find a text-track parser for the type "+g);k="srt"}S=M}null!==A&&Array.isArray(n)&&n.length>0&&me(d,n,f);var N=null!=E?E:0;return(0,r.of)({type:"parsed-segment",value:{chunkData:{type:k,data:S,start:E,end:w,language:p},chunkInfos:A,chunkOffset:N,appendWindow:[void 0,void 0]}})}},image:{loader:function(e){var t=e.segment,n=e.url;return t.isInit||null===n?(0,r.of)({type:"data-created",value:{responseData:null}}):(0,K.ZP)({url:n,responseType:"arraybuffer",sendProgressEvents:!0})},parser:function(e){var t=e.response,n=e.content,i=t.data,a=t.isChunked;if(n.segment.isInit)return(0,r.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}});if(a)throw new Error("Image data should not be downloaded in chunks");if(null===i||null===o.Z.imageParser)return(0,r.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:[void 0,void 0]}});var s=o.Z.imageParser(new Uint8Array(i)),u=s.thumbs;return(0,r.of)({type:"parsed-segment",value:{chunkData:{data:u,start:0,end:Number.MAX_VALUE,timescale:1,type:"bif"},chunkInfos:{time:0,duration:Number.MAX_VALUE,timescale:s.timescale},chunkOffset:0,protectionDataUpdate:!1,appendWindow:[void 0,void 0]}})}}}}},281:(e,t,n)=>{"use strict";function r(e){var t=e[0],n=e[1];return n===1/0?"bytes="+t+"-":"bytes="+t+"-"+n}n.d(t,{Z:()=>r})},4460:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(5389),i=n(8766);function a(e,t){if(t){if((0,i.Z)(e,1718909296)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `ftyp` box");if((0,i.Z)(e,1836019574)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `moov` box")}else{if((0,i.Z)(e,1836019558)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `moof` box");if((0,i.Z)(e,1835295092)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `mdat` box")}}},8766:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(6968);function i(e,t){for(var n=e.length,i=0;i+8<=n;){var a=(0,r.pX)(e,i);if(0===a)a=n-i;else if(1===a){if(i+16>n)return-1;a=(0,r.pV)(e,i+8)}if(isNaN(a)||a<=0)return-1;if((0,r.pX)(e,i+4)===t)return i+a<=n?i:-1;i+=a}return-1}},7445:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(8170),i=n(9795);function a(e,t){var n=r.of.apply(void 0,e.parsingErrors.map((function(e){return{type:"warning",value:e}})));return(0,i.z)(n,(0,r.of)({type:"parsed",value:{manifest:e,url:t}}))}},7278:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(1946),i=n(4597),a=n(4379);function o(e){var t=e.url;if(void 0===t)throw new Error("Cannot perform HTTP(s) request. URL not known");return(0,i.ZP)({url:t,responseType:"text"})}function s(e){var t=e.customManifestLoader;return(0,r.Z)(t)?o:function(e,t){return function(n){return new a.y((function(r){var i=n.url,a=Date.now()-performance.now(),o=!1,s=!1,u=e(i,{reject:function(e){s||(o=!0,r.error(e))},resolve:function(e){if(!s){o=!0;var t=void 0!==e.receivingTime?e.receivingTime-a:void 0,n=void 0!==e.sendingTime?e.sendingTime-a:void 0;r.next({type:"data-loaded",value:{responseData:e.data,size:e.size,duration:e.duration,url:e.url,receivedTime:t,sendingTime:n}}),r.complete()}},fallback:function(){s=!0,t(n).subscribe(r)}});return function(){o||s||"function"!=typeof u||u()}}))}}(t,o)}},4791:(e,t,n)=>{"use strict";function r(e,t){if(e.length!==t.length)return!1;for(var n=e.length-1;n>=0;n--)if(e[n]!==t[n])return!1;return!0}n.d(t,{Z:()=>r})},3274:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof Array.prototype.find)return e.find(t,n);for(var r=e.length>>>0,i=0;ir})},5138:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof Array.prototype.findIndex)return e.findIndex(t,n);for(var r=e.length>>>0,i=0;ir})},7714:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof Array.prototype.includes)return e.includes(t,n);var r=e.length>>>0;if(0===r)return!1;for(var i,a,o=0|n,s=o>=0?Math.min(o,r-1):Math.max(r+o,0);sr})},811:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a,u:()=>o});var r=n(3801),i=n(1946);function a(e,t){if(!e)throw new r.Z(void 0===t?"invalid assertion":t)}function o(e,t,n){for(var r in void 0===n&&(n="object"),a(!(0,i.Z)(e),n+" should be an object"),t)t.hasOwnProperty(r)&&a(typeof e[r]===t[r],n+" should have property "+r+" as a "+t[r])}},8418:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(3801);function i(e){throw new r.Z("Unreachable path taken")}},9689:(e,t,n)=>{"use strict";n.d(t,{J:()=>s,K:()=>u});var r=n(3887),i=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/"],a=[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,62,255,255,255,63,52,53,54,55,56,57,58,59,60,61,255,255,255,0,255,255,255,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,255,255,255,255,255,255,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];function o(e){if(e>=a.length)throw new Error("Unable to parse base64 string.");var t=a[e];if(255===t)throw new Error("Unable to parse base64 string.");return t}function s(e){var t,n="",r=e.length;for(t=2;t>2],n+=i[(3&e[t-2])<<4|e[t-1]>>4],n+=i[(15&e[t-1])<<2|e[t]>>6],n+=i[63&e[t]];return t===r+1&&(n+=i[e[t-2]>>2],n+=i[(3&e[t-2])<<4],n+="=="),t===r&&(n+=i[e[t-2]>>2],n+=i[(3&e[t-2])<<4|e[t-1]>>4],n+=i[(15&e[t-1])<<2],n+="="),n}function u(e){var t=e.length%4,n=e;0!==t&&(r.Z.warn("base64ToBytes: base64 given miss padding"),n+=3===t?"=":2===t?"==":"===");var i=n.indexOf("=");if(-1!==i&&i>16,l[c+1]=a>>8&255,l[c+2]=255&a;return l.subarray(0,l.length-s)}},6968:(e,t,n)=>{"use strict";function r(){for(var e,t=arguments.length,n=-1,r=0;++n0&&(i.set(e,a),a+=e.length);return i}function i(e,t){return(e[t+0]<<8)+(e[t+1]<<0)}function a(e,t){return 65536*e[t+0]+256*e[t+1]+e[t+2]}function o(e,t){return 16777216*e[t+0]+65536*e[t+1]+256*e[t+2]+e[t+3]}function s(e,t){return 4294967296*(16777216*e[t+0]+65536*e[t+1]+256*e[t+2]+e[t+3])+16777216*e[t+4]+65536*e[t+5]+256*e[t+6]+e[t+7]}function u(e){return new Uint8Array([e>>>8&255,255&e])}function l(e){return new Uint8Array([e>>>24&255,e>>>16&255,e>>>8&255,255&e])}function d(e){var t=e%4294967296,n=(e-t)/4294967296;return new Uint8Array([n>>>24&255,n>>>16&255,n>>>8&255,255&n,t>>>24&255,t>>>16&255,t>>>8&255,255&t])}function c(e,t){return(e[t+0]<<0)+(e[t+1]<<8)}function f(e,t){return e[t+0]+256*e[t+1]+65536*e[t+2]+16777216*e[t+3]}function p(e){return new Uint8Array([255&e,e>>>8&255,e>>>16&255,e>>>24&255])}function h(e){return e instanceof Uint8Array?e:e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer)}n.d(t,{zo:()=>r,zK:()=>i,QI:()=>a,pX:()=>o,pV:()=>s,qb:()=>c,dN:()=>f,XT:()=>u,kh:()=>l,el:()=>d,O_:()=>p,_f:()=>h})},8117:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(4379),i=n(4072),a=n(8170),o=n(1946);const s=function(e){if(e instanceof r.y)return e;if(!(0,o.Z)(e)&&"function"==typeof e.subscribe){var t=e;return new r.y((function(e){var n=t.subscribe((function(t){e.next(t)}),(function(t){e.error(t)}),(function(){e.complete()}));return function(){(0,o.Z)(n)||"function"!=typeof n.dispose?(0,o.Z)(n)||"function"!=typeof n.unsubscribe||n.unsubscribe():n.dispose()}}))}return(0,o.Z)(e)||"function"!=typeof e.then?(0,a.of)(e):(0,i.D)(e)}},8025:(e,t,n)=>{"use strict";n.d(t,{Z:()=>g});var r=n(655),i=1,a=function(){return Promise.resolve()}(),o={};function s(e){return e in o&&(delete o[e],!0)}var u=function(e){var t=i++;return o[t]=!0,a.then((function(){return s(t)&&e()})),t},l=function(e){s(e)},d=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.scheduler=t,r.work=n,r}return r.ZT(t,e),t.prototype.requestAsyncId=function(t,n,r){return void 0===r&&(r=0),null!==r&&r>0?e.prototype.requestAsyncId.call(this,t,n,r):(t.actions.push(this),t.scheduled||(t.scheduled=u(t.flush.bind(t,null))))},t.prototype.recycleAsyncId=function(t,n,r){if(void 0===r&&(r=0),null!==r&&r>0||null===r&&this.delay>0)return e.prototype.recycleAsyncId.call(this,t,n,r);0===t.actions.length&&(l(n),t.scheduled=void 0)},t}(n(6114).o),c=new(function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype.flush=function(e){this.active=!0,this.scheduled=void 0;var t,n=this.actions,r=-1,i=n.length;e=e||n.shift();do{if(t=e.execute(e.state,e.delay))break}while(++r{"use strict";n.d(t,{Z:()=>o,R:()=>s});var r=n(4379),i=n(3887),a=n(1946),o=function(){function e(){this._listeners={}}var t=e.prototype;return t.addEventListener=function(e,t){var n=this._listeners[e];Array.isArray(n)?n.push(t):this._listeners[e]=[t]},t.removeEventListener=function(e,t){if((0,a.Z)(e))this._listeners={};else{var n=this._listeners[e];if(Array.isArray(n))if((0,a.Z)(t))delete this._listeners[e];else{var r=n.indexOf(t);-1!==r&&n.splice(r,1),0===n.length&&delete this._listeners[e]}}},t.trigger=function(e,t){var n=this._listeners[e];Array.isArray(n)&&n.slice().forEach((function(e){try{e(t)}catch(e){i.Z.error(e,e instanceof Error?e.stack:null)}}))},e}();function s(e,t){return new r.y((function(n){function r(e){n.next(e)}return e.addEventListener(t,r),function(){e.removeEventListener(t,r)}}))}},2793:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(1410),i=n(5709),a=n(6008);function o(e,t){return function(n){return(0,r.P)((function(){return n.pipe((0,i.U)(e),(0,a.h)((function(e){return e!==t})))}))}}},9592:(e,t,n)=>{"use strict";function r(e,t){return"function"==typeof Array.prototype.flatMap?e.flatMap(t):e.reduce((function(e,n){var r=t(n);return Array.isArray(r)?(e.push.apply(e,r),e):(e.push(r),e)}),[])}n.d(t,{Z:()=>r})},2572:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});function r(e){return e*(.3*(2*Math.random()-1)+1)}},2870:(e,t,n)=>{"use strict";function r(e){for(var t=0,n=0;nr})},908:(e,t,n)=>{"use strict";function r(){var e="",t=-1;return function(){return++t>=Number.MAX_SAFE_INTEGER&&(e+="0",t=0),e+String(t)}}n.d(t,{Z:()=>r})},6923:(e,t,n)=>{"use strict";function r(e){return"string"==typeof e&&e.length>0}n.d(t,{Z:()=>r})},1946:(e,t,n)=>{"use strict";function r(e){return null==e}n.d(t,{Z:()=>r})},7829:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>r});const r=n(5553).ZP},5553:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>d,iH:()=>l,Y1:()=>u});var r=n(6923),i=n(1946);const a={aa:"aar",ab:"abk",ae:"ave",af:"afr",ak:"aka",am:"amh",an:"arg",ar:"ara",as:"asm",av:"ava",ay:"aym",az:"aze",ba:"bak",be:"bel",bg:"bul",bi:"bis",bm:"bam",bn:"ben",bo:"bod",br:"bre",bs:"bos",ca:"cat",ce:"che",ch:"cha",co:"cos",cr:"cre",cs:"ces",cu:"chu",cv:"chv",cy:"cym",da:"dan",de:"deu",dv:"div",dz:"dzo",ee:"ewe",el:"ell",en:"eng",eo:"epo",es:"spa",et:"est",eu:"eus",fa:"fas",ff:"ful",fi:"fin",fj:"fij",fo:"fao",fr:"fra",fy:"fry",ga:"gle",gd:"gla",gl:"glg",gn:"grn",gu:"guj",gv:"glv",ha:"hau",he:"heb",hi:"hin",ho:"hmo",hr:"hrv",ht:"hat",hu:"hun",hy:"hye",hz:"her",ia:"ina",id:"ind",ie:"ile",ig:"ibo",ii:"iii",ik:"ipk",io:"ido",is:"isl",it:"ita",iu:"iku",ja:"jpn",jv:"jav",ka:"kat",kg:"kon",ki:"kik",kj:"kua",kk:"kaz",kl:"kal",km:"khm",kn:"kan",ko:"kor",kr:"kau",ks:"kas",ku:"kur",kv:"kom",kw:"cor",ky:"kir",la:"lat",lb:"ltz",lg:"lug",li:"lim",ln:"lin",lo:"lao",lt:"lit",lu:"lub",lv:"lav",mg:"mlg",mh:"mah",mi:"mri",mk:"mkd",ml:"mal",mn:"mon",mr:"mar",ms:"msa",mt:"mlt",my:"mya",na:"nau",nb:"nob",nd:"nde",ne:"nep",ng:"ndo",nl:"nld",nn:"nno",no:"nor",nr:"nbl",nv:"nav",ny:"nya",oc:"oci",oj:"oji",om:"orm",or:"ori",os:"oss",pa:"pan",pi:"pli",pl:"pol",ps:"pus",pt:"por",qu:"que",rm:"roh",rn:"run",ro:"ron",ru:"rus",rw:"kin",sa:"san",sc:"srd",sd:"snd",se:"sme",sg:"sag",si:"sin",sk:"slk",sl:"slv",sm:"smo",sn:"sna",so:"som",sq:"sqi",sr:"srp",ss:"ssw",st:"sot",su:"sun",sv:"swe",sw:"swa",ta:"tam",te:"tel",tg:"tgk",th:"tha",ti:"tir",tk:"tuk",tl:"tgl",tn:"tsn",to:"ton",tr:"tur",ts:"tso",tt:"tat",tw:"twi",ty:"tah",ug:"uig",uk:"ukr",ur:"urd",uz:"uzb",ve:"ven",vi:"vie",vo:"vol",wa:"wln",wo:"wol",xh:"xho",yi:"yid",yo:"yor",za:"zha",zh:"zho",zu:"zul"};const o={alb:"sqi",arm:"hye",baq:"eus",bur:"mya",chi:"zho",cze:"ces",dut:"nld",fre:"fra",geo:"kat",ger:"deu",gre:"ell",ice:"isl",mac:"mkd",mao:"mri",may:"msa",per:"fas",slo:"slk",rum:"ron",tib:"bod",wel:"cym"};function s(e){if((0,i.Z)(e)||""===e)return"";var t=function(e){var t;switch(e.length){case 2:t=a[e];break;case 3:t=o[e]}return t}((""+e).toLowerCase().split("-")[0]);return(0,r.Z)(t)?t:e}function u(e){if(!(0,i.Z)(e)){var t,n=!1;return"string"==typeof e?t=e:(t=e.language,!0===e.closedCaption&&(n=!0)),{language:t,closedCaption:n,normalized:s(t)}}return e}function l(e){if((0,i.Z)(e))return e;if("string"==typeof e)return{language:e,audioDescription:!1,normalized:s(e)};var t={language:e.language,audioDescription:!0===e.audioDescription,normalized:s(s(e.language))};return!0===e.isDub&&(t.isDub=!0),t}const d=s},8894:(e,t,n)=>{"use strict";function r(){}n.d(t,{Z:()=>r})},8026:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r="function"==typeof Object.assign?Object.assign:function(e){if(null==e)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(e),n=0;n<(arguments.length<=1?0:arguments.length-1);n++){var r=n+1<1||arguments.length<=n+1?void 0:arguments[n+1];for(var i in r)Object.prototype.hasOwnProperty.call(r,i)&&(t[i]=r[i])}return t}},1679:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r="function"==typeof Object.values?Object.values:function(e){return Object.keys(e).map((function(t){return e[t]}))}},9589:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(8555);const i="function"==typeof Promise?Promise:n.n(r)()},2829:(e,t,n)=>{"use strict";n.d(t,{JN:()=>d,uH:()=>b,F_:()=>p,L7:()=>m,XS:()=>f,DD:()=>v,rx:()=>c,at:()=>h,kR:()=>g,Ti:()=>s,A1:()=>o,tn:()=>_});function r(e,t){return Math.abs(e-t)<.016666666666666666}function i(e,t){return{start:Math.min(e.start,t.start),end:Math.max(e.end,t.end)}}function a(e,t){return e.end<=t.start}function o(e,t){for(var n=0;n=0;n--){var r=e.start(n);if(t>=r){var i=e.end(n);if(t=o?r.push({start:a,end:o}):n={start:a,end:o}}return{outerRanges:r,innerRange:n}}function h(e,t){var n=c(e,t);return null!==n?n.end-n.start:0}function v(e,t){var n=c(e,t);return null!==n?t-n.start:0}function m(e,t){var n=c(e,t);return null!==n?n.end-t:1/0}function g(e,t){if(t.start===t.end)return e;for(var n=t,r=0;r0)for(var o=0;o0)for(var s=0;sl&&n.push({start:l,end:a[d].start}),l=a[d].end;l{"use strict";n.d(t,{ZP:()=>l});var r=n(4379),i=n(944),a=n(9105),o=n(6923),s=n(1946),u=i.Z.DEFAULT_REQUEST_TIMEOUT;const l=function(e){var t={url:e.url,headers:e.headers,responseType:(0,s.Z)(e.responseType)?"json":e.responseType,timeout:(0,s.Z)(e.timeout)?u:e.timeout};return new r.y((function(n){var r=t.url,i=t.headers,u=t.responseType,l=t.timeout,d=new XMLHttpRequest;if(d.open("GET",r,!0),l>=0&&(d.timeout=l),d.responseType=u,"document"===d.responseType&&d.overrideMimeType("text/xml"),!(0,s.Z)(i)){var c=i;for(var f in c)c.hasOwnProperty(f)&&d.setRequestHeader(f,c[f])}var p=performance.now();return d.onerror=function(){n.error(new a.Z(r,d.status,"ERROR_EVENT",d))},d.ontimeout=function(){n.error(new a.Z(r,d.status,"TIMEOUT",d))},!0===e.sendProgressEvents&&(d.onprogress=function(e){var t=performance.now();n.next({type:"progress",value:{url:r,duration:t-p,sendingTime:p,currentTime:t,size:e.loaded,totalSize:e.total}})}),d.onload=function(e){if(4===d.readyState)if(d.status>=200&&d.status<300){var t,i=performance.now(),u=d.response instanceof ArrayBuffer?d.response.byteLength:e.total,l=d.status,c=d.responseType,f=(0,o.Z)(d.responseURL)?d.responseURL:r;if(t="json"===c?"object"==typeof d.response?d.response:function(e){try{return JSON.parse(e)}catch(e){return null}}(d.responseText):d.response,(0,s.Z)(t))return void n.error(new a.Z(r,d.status,"PARSE_ERROR",d));n.next({type:"data-loaded",value:{status:l,url:f,responseType:c,sendingTime:p,receivedTime:i,duration:i-p,size:u,responseData:t}}),n.complete()}else n.error(new a.Z(r,d.status,"ERROR_HTTP_CODE",d))},d.send(),function(){(0,s.Z)(d)||4===d.readyState||d.abort()}}))}},9829:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o,f:()=>s});var r=/^(?:[a-z]+:)?\/\//i,i=/\/\.{1,2}\//;function a(e){if(!i.test(e))return e;for(var t=[],n=e.split("/"),r=0,a=n.length;r=0&&t===n+1)return e}var i=e.indexOf("?");return i>=0&&i{"use strict";n.d(t,{Z:()=>i});var r=n(4944);function i(e,t){try{return e(t)}catch(e){return(0,r._)(e)}}},9252:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof String.prototype.startsWith)return e.startsWith(t,n);var r="number"==typeof n?Math.max(n,0):0;return e.substring(r,r+t.length)===t}n.d(t,{Z:()=>r})},3635:(e,t,n)=>{"use strict";n.d(t,{ci:()=>p,nr:()=>f,tG:()=>l,uR:()=>c,TZ:()=>s,wV:()=>u,wO:()=>h,DM:()=>v});var r=n(3887),i=n(811),a="object"==typeof window&&"function"==typeof window.TextDecoder,o="object"==typeof window&&"function"==typeof window.TextEncoder;function s(e){for(var t=new ArrayBuffer(2*e.length),n=new Uint8Array(t),r=0;r>8&255}return n}function u(e){if(a)try{return new TextDecoder("utf-16le").decode(e)}catch(e){r.Z.warn("Utils: could not use TextDecoder to parse UTF-16LE, fallbacking to another implementation",e)}for(var t="",n=0;n=t?n:new Array(t-n.length+1).join("0")+n}function c(e){if(a)try{return(new TextDecoder).decode(e)}catch(e){r.Z.warn("Utils: could not use TextDecoder to parse UTF-8, fallbacking to another implementation",e)}var t=e;239===t[0]&&187===t[1]&&191===t[2]&&(t=t.subarray(3));var n,i=function(e){for(var t="",n=0;n=256?"%u"+d(u,4):"%"+d(u,2)}}return decodeURIComponent(n)}function f(e){for(var t=e.length,n=new Uint8Array(t/2),r=0,i=0;r>>4).toString(16),n+=(15&e[r]).toString(16),t.length>0&&r{"use strict";n.d(t,{Z:()=>i});var r=n(1946);function i(){for(var e=0,t=arguments.length,n=new Array(t),i=0;i{"use strict";n.d(t,{Z:()=>a});var r=n(7714),i=[];function a(e){(0,r.Z)(i,e)||(console.warn(e),i.push(e))}},7473:e=>{"use strict";var t=function(e){if("function"!=typeof e)throw new TypeError(e+" is not a function");return e},n=function(e){var n,r,i=document.createTextNode(""),a=0;return new e((function(){var e;if(n)r&&(n=r.concat(n));else{if(!r)return;n=r}if(r=n,n=null,"function"==typeof r)return e=r,r=null,void e();for(i.data=a=++a%2;r;)e=r.shift(),r.length||(r=null),e()})).observe(i,{characterData:!0}),function(e){t(e),n?"function"==typeof n?n=[n,e]:n.push(e):(n=e,i.data=a=++a%2)}};e.exports=function(){if("object"==typeof process&&process&&"function"==typeof process.nextTick)return process.nextTick;if("function"==typeof queueMicrotask)return function(e){queueMicrotask(t(e))};if("object"==typeof document&&document){if("function"==typeof MutationObserver)return n(MutationObserver);if("function"==typeof WebKitMutationObserver)return n(WebKitMutationObserver)}return"function"==typeof setImmediate?function(e){setImmediate(t(e))}:"function"==typeof setTimeout||"object"==typeof setTimeout?function(e){setTimeout(t(e),0)}:null}()},8555:(e,t,n)=>{"use strict";var r,i="pending",a="settled",o="fulfilled",s="rejected",u=function(){},l=void 0!==n.g&&void 0!==n.g.process&&"function"==typeof n.g.process.emit,d="undefined"==typeof setImmediate?setTimeout:setImmediate,c=[];function f(){for(var e=0;e{var t=function(e){"use strict";var t,n=Object.prototype,r=n.hasOwnProperty,i="function"==typeof Symbol?Symbol:{},a=i.iterator||"@@iterator",o=i.asyncIterator||"@@asyncIterator",s=i.toStringTag||"@@toStringTag";function u(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{u({},"")}catch(e){u=function(e,t,n){return e[t]=n}}function l(e,t,n,r){var i=t&&t.prototype instanceof m?t:m,a=Object.create(i.prototype),o=new I(r||[]);return a._invoke=function(e,t,n){var r=c;return function(i,a){if(r===p)throw new Error("Generator is already running");if(r===h){if("throw"===i)throw a;return R()}for(n.method=i,n.arg=a;;){var o=n.delegate;if(o){var s=k(o,n);if(s){if(s===v)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(r===c)throw r=h,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r=p;var u=d(e,t,n);if("normal"===u.type){if(r=n.done?h:f,u.arg===v)continue;return{value:u.arg,done:n.done}}"throw"===u.type&&(r=h,n.method="throw",n.arg=u.arg)}}}(e,n,o),a}function d(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}e.wrap=l;var c="suspendedStart",f="suspendedYield",p="executing",h="completed",v={};function m(){}function g(){}function y(){}var _={};_[a]=function(){return this};var b=Object.getPrototypeOf,T=b&&b(b(Z([])));T&&T!==n&&r.call(T,a)&&(_=T);var E=y.prototype=m.prototype=Object.create(_);function w(e){["next","throw","return"].forEach((function(t){u(e,t,(function(e){return this._invoke(t,e)}))}))}function S(e,t){function n(i,a,o,s){var u=d(e[i],e,a);if("throw"!==u.type){var l=u.arg,c=l.value;return c&&"object"==typeof c&&r.call(c,"__await")?t.resolve(c.__await).then((function(e){n("next",e,o,s)}),(function(e){n("throw",e,o,s)})):t.resolve(c).then((function(e){l.value=e,o(l)}),(function(e){return n("throw",e,o,s)}))}s(u.arg)}var i;this._invoke=function(e,r){function a(){return new t((function(t,i){n(e,r,t,i)}))}return i=i?i.then(a,a):a()}}function k(e,n){var r=e.iterator[n.method];if(r===t){if(n.delegate=null,"throw"===n.method){if(e.iterator.return&&(n.method="return",n.arg=t,k(e,n),"throw"===n.method))return v;n.method="throw",n.arg=new TypeError("The iterator does not provide a 'throw' method")}return v}var i=d(r,e.iterator,n.arg);if("throw"===i.type)return n.method="throw",n.arg=i.arg,n.delegate=null,v;var a=i.arg;return a?a.done?(n[e.resultName]=a.value,n.next=e.nextLoc,"return"!==n.method&&(n.method="next",n.arg=t),n.delegate=null,v):a:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,v)}function A(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function x(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function I(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(A,this),this.reset(!0)}function Z(e){if(e){var n=e[a];if(n)return n.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var i=-1,o=function n(){for(;++i=0;--a){var o=this.tryEntries[a],s=o.completion;if("root"===o.tryLoc)return i("end");if(o.tryLoc<=this.prev){var u=r.call(o,"catchLoc"),l=r.call(o,"finallyLoc");if(u&&l){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),x(n),v}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var i=r.arg;x(n)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,n,r){return this.delegate={iterator:Z(e),resultName:n,nextLoc:r},"next"===this.method&&(this.arg=t),v}},e}(e.exports);try{regeneratorRuntime=t}catch(e){Function("r","regeneratorRuntime = r")(t)}},2632:(e,t,n)=>{"use strict";n.d(t,{P:()=>s});var r,i=n(5631),a=n(8170),o=n(4944);r||(r={});var s=function(){function e(e,t,n){this.kind=e,this.value=t,this.error=n,this.hasValue="N"===e}return e.prototype.observe=function(e){switch(this.kind){case"N":return e.next&&e.next(this.value);case"E":return e.error&&e.error(this.error);case"C":return e.complete&&e.complete()}},e.prototype.do=function(e,t,n){switch(this.kind){case"N":return e&&e(this.value);case"E":return t&&t(this.error);case"C":return n&&n()}},e.prototype.accept=function(e,t,n){return e&&"function"==typeof e.next?this.observe(e):this.do(e,t,n)},e.prototype.toObservable=function(){switch(this.kind){case"N":return(0,a.of)(this.value);case"E":return(0,o._)(this.error);case"C":return(0,i.c)()}throw new Error("unexpected notification kind value")},e.createNext=function(t){return void 0!==t?new e("N",t):e.undefinedValueNotification},e.createError=function(t){return new e("E",void 0,t)},e.createComplete=function(){return e.completeNotification},e.completeNotification=new e("C"),e.undefinedValueNotification=new e("N",void 0),e}()},4379:(e,t,n)=>{"use strict";n.d(t,{y:()=>d});var r=n(979);var i=n(3142),a=n(2174);var o=n(5050),s=n(3608);function u(e){return 0===e.length?s.y:1===e.length?e[0]:function(t){return e.reduce((function(e,t){return t(e)}),t)}}var l=n(150),d=function(){function e(e){this._isScalar=!1,e&&(this._subscribe=e)}return e.prototype.lift=function(t){var n=new e;return n.source=this,n.operator=t,n},e.prototype.subscribe=function(e,t,n){var o=this.operator,s=function(e,t,n){if(e){if(e instanceof r.L)return e;if(e[i.b])return e[i.b]()}return e||t||n?new r.L(e,t,n):new r.L(a.c)}(e,t,n);if(o?s.add(o.call(s,this.source)):s.add(this.source||l.v.useDeprecatedSynchronousErrorHandling&&!s.syncErrorThrowable?this._subscribe(s):this._trySubscribe(s)),l.v.useDeprecatedSynchronousErrorHandling&&s.syncErrorThrowable&&(s.syncErrorThrowable=!1,s.syncErrorThrown))throw s.syncErrorValue;return s},e.prototype._trySubscribe=function(e){try{return this._subscribe(e)}catch(t){l.v.useDeprecatedSynchronousErrorHandling&&(e.syncErrorThrown=!0,e.syncErrorValue=t),!function(e){for(;e;){var t=e,n=t.closed,i=t.destination,a=t.isStopped;if(n||a)return!1;e=i&&i instanceof r.L?i:null}return!0}(e)?console.warn(t):e.error(t)}},e.prototype.forEach=function(e,t){var n=this;return new(t=c(t))((function(t,r){var i;i=n.subscribe((function(t){try{e(t)}catch(e){r(e),i&&i.unsubscribe()}}),r,t)}))},e.prototype._subscribe=function(e){var t=this.source;return t&&t.subscribe(e)},e.prototype[o.L]=function(){return this},e.prototype.pipe=function(){for(var e=[],t=0;t{"use strict";n.d(t,{c:()=>a});var r=n(150),i=n(1644),a={closed:!0,next:function(e){},error:function(e){if(r.v.useDeprecatedSynchronousErrorHandling)throw e;(0,i.z)(e)},complete:function(){}}},2039:(e,t,n)=>{"use strict";n.d(t,{L:()=>i});var r=n(655),i=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype.notifyNext=function(e,t,n,r,i){this.destination.next(t)},t.prototype.notifyError=function(e,t){this.destination.error(e)},t.prototype.notifyComplete=function(e){this.destination.complete()},t}(n(979).L)},2135:(e,t,n)=>{"use strict";n.d(t,{t:()=>h});var r=n(655),i=n(211),a=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.scheduler=t,r.work=n,r}return r.ZT(t,e),t.prototype.schedule=function(t,n){return void 0===n&&(n=0),n>0?e.prototype.schedule.call(this,t,n):(this.delay=n,this.state=t,this.scheduler.flush(this),this)},t.prototype.execute=function(t,n){return n>0||this.closed?e.prototype.execute.call(this,t,n):this._execute(t,n)},t.prototype.requestAsyncId=function(t,n,r){return void 0===r&&(r=0),null!==r&&r>0||null===r&&this.delay>0?e.prototype.requestAsyncId.call(this,t,n,r):t.flush(this)},t}(n(6114).o),o=new(function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t}(n(2980).v))(a),s=n(3884),u=n(979),l=n(2632);var d=function(e){function t(t,n,r){void 0===r&&(r=0);var i=e.call(this,t)||this;return i.scheduler=n,i.delay=r,i}return r.ZT(t,e),t.dispatch=function(e){var t=e.notification,n=e.destination;t.observe(n),this.unsubscribe()},t.prototype.scheduleMessage=function(e){this.destination.add(this.scheduler.schedule(t.dispatch,this.delay,new c(e,this.destination)))},t.prototype._next=function(e){this.scheduleMessage(l.P.createNext(e))},t.prototype._error=function(e){this.scheduleMessage(l.P.createError(e)),this.unsubscribe()},t.prototype._complete=function(){this.scheduleMessage(l.P.createComplete()),this.unsubscribe()},t}(u.L),c=function(){return function(e,t){this.notification=e,this.destination=t}}(),f=n(1016),p=n(8253),h=function(e){function t(t,n,r){void 0===t&&(t=Number.POSITIVE_INFINITY),void 0===n&&(n=Number.POSITIVE_INFINITY);var i=e.call(this)||this;return i.scheduler=r,i._events=[],i._infiniteTimeWindow=!1,i._bufferSize=t<1?1:t,i._windowTime=n<1?1:n,n===Number.POSITIVE_INFINITY?(i._infiniteTimeWindow=!0,i.next=i.nextInfiniteTimeWindow):i.next=i.nextTimeWindow,i}return r.ZT(t,e),t.prototype.nextInfiniteTimeWindow=function(t){if(!this.isStopped){var n=this._events;n.push(t),n.length>this._bufferSize&&n.shift()}e.prototype.next.call(this,t)},t.prototype.nextTimeWindow=function(t){this.isStopped||(this._events.push(new v(this._getNow(),t)),this._trimBufferThenGetEvents()),e.prototype.next.call(this,t)},t.prototype._subscribe=function(e){var t,n=this._infiniteTimeWindow,r=n?this._events:this._trimBufferThenGetEvents(),i=this.scheduler,a=r.length;if(this.closed)throw new f.N;if(this.isStopped||this.hasError?t=s.w.EMPTY:(this.observers.push(e),t=new p.W(this,e)),i&&e.add(e=new d(e,i)),n)for(var o=0;ot&&(a=Math.max(a,i-t)),a>0&&r.splice(0,a),r},t}(i.xQ),v=function(){return function(e,t){this.time=e,this.value=t}}()},211:(e,t,n)=>{"use strict";n.d(t,{Yc:()=>d,xQ:()=>c});var r=n(655),i=n(4379),a=n(979),o=n(3884),s=n(1016),u=n(8253),l=n(3142),d=function(e){function t(t){var n=e.call(this,t)||this;return n.destination=t,n}return r.ZT(t,e),t}(a.L),c=function(e){function t(){var t=e.call(this)||this;return t.observers=[],t.closed=!1,t.isStopped=!1,t.hasError=!1,t.thrownError=null,t}return r.ZT(t,e),t.prototype[l.b]=function(){return new d(this)},t.prototype.lift=function(e){var t=new f(this,this);return t.operator=e,t},t.prototype.next=function(e){if(this.closed)throw new s.N;if(!this.isStopped)for(var t=this.observers,n=t.length,r=t.slice(),i=0;i{"use strict";n.d(t,{W:()=>i});var r=n(655),i=function(e){function t(t,n){var r=e.call(this)||this;return r.subject=t,r.subscriber=n,r.closed=!1,r}return r.ZT(t,e),t.prototype.unsubscribe=function(){if(!this.closed){this.closed=!0;var e=this.subject,t=e.observers;if(this.subject=null,t&&0!==t.length&&!e.isStopped&&!e.closed){var n=t.indexOf(this.subscriber);-1!==n&&t.splice(n,1)}}},t}(n(3884).w)},979:(e,t,n)=>{"use strict";n.d(t,{L:()=>d});var r=n(655),i=n(4156),a=n(2174),o=n(3884),s=n(3142),u=n(150),l=n(1644),d=function(e){function t(n,r,i){var o=e.call(this)||this;switch(o.syncErrorValue=null,o.syncErrorThrown=!1,o.syncErrorThrowable=!1,o.isStopped=!1,arguments.length){case 0:o.destination=a.c;break;case 1:if(!n){o.destination=a.c;break}if("object"==typeof n){n instanceof t?(o.syncErrorThrowable=n.syncErrorThrowable,o.destination=n,n.add(o)):(o.syncErrorThrowable=!0,o.destination=new c(o,n));break}default:o.syncErrorThrowable=!0,o.destination=new c(o,n,r,i)}return o}return r.ZT(t,e),t.prototype[s.b]=function(){return this},t.create=function(e,n,r){var i=new t(e,n,r);return i.syncErrorThrowable=!1,i},t.prototype.next=function(e){this.isStopped||this._next(e)},t.prototype.error=function(e){this.isStopped||(this.isStopped=!0,this._error(e))},t.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},t.prototype.unsubscribe=function(){this.closed||(this.isStopped=!0,e.prototype.unsubscribe.call(this))},t.prototype._next=function(e){this.destination.next(e)},t.prototype._error=function(e){this.destination.error(e),this.unsubscribe()},t.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},t.prototype._unsubscribeAndRecycle=function(){var e=this._parentOrParents;return this._parentOrParents=null,this.unsubscribe(),this.closed=!1,this.isStopped=!1,this._parentOrParents=e,this},t}(o.w),c=function(e){function t(t,n,r,o){var s,u=e.call(this)||this;u._parentSubscriber=t;var l=u;return(0,i.m)(n)?s=n:n&&(s=n.next,r=n.error,o=n.complete,n!==a.c&&(l=Object.create(n),(0,i.m)(l.unsubscribe)&&u.add(l.unsubscribe.bind(l)),l.unsubscribe=u.unsubscribe.bind(u))),u._context=l,u._next=s,u._error=r,u._complete=o,u}return r.ZT(t,e),t.prototype.next=function(e){if(!this.isStopped&&this._next){var t=this._parentSubscriber;u.v.useDeprecatedSynchronousErrorHandling&&t.syncErrorThrowable?this.__tryOrSetError(t,this._next,e)&&this.unsubscribe():this.__tryOrUnsub(this._next,e)}},t.prototype.error=function(e){if(!this.isStopped){var t=this._parentSubscriber,n=u.v.useDeprecatedSynchronousErrorHandling;if(this._error)n&&t.syncErrorThrowable?(this.__tryOrSetError(t,this._error,e),this.unsubscribe()):(this.__tryOrUnsub(this._error,e),this.unsubscribe());else if(t.syncErrorThrowable)n?(t.syncErrorValue=e,t.syncErrorThrown=!0):(0,l.z)(e),this.unsubscribe();else{if(this.unsubscribe(),n)throw e;(0,l.z)(e)}}},t.prototype.complete=function(){var e=this;if(!this.isStopped){var t=this._parentSubscriber;if(this._complete){var n=function(){return e._complete.call(e._context)};u.v.useDeprecatedSynchronousErrorHandling&&t.syncErrorThrowable?(this.__tryOrSetError(t,n),this.unsubscribe()):(this.__tryOrUnsub(n),this.unsubscribe())}else this.unsubscribe()}},t.prototype.__tryOrUnsub=function(e,t){try{e.call(this._context,t)}catch(e){if(this.unsubscribe(),u.v.useDeprecatedSynchronousErrorHandling)throw e;(0,l.z)(e)}},t.prototype.__tryOrSetError=function(e,t,n){if(!u.v.useDeprecatedSynchronousErrorHandling)throw new Error("bad call");try{t.call(this._context,n)}catch(t){return u.v.useDeprecatedSynchronousErrorHandling?(e.syncErrorValue=t,e.syncErrorThrown=!0,!0):((0,l.z)(t),!0)}return!1},t.prototype._unsubscribe=function(){var e=this._parentSubscriber;this._context=null,this._parentSubscriber=null,e.unsubscribe()},t}(d)},3884:(e,t,n)=>{"use strict";n.d(t,{w:()=>s});var r=n(9026),i=n(2009),a=n(4156),o=function(){function e(e){return Error.call(this),this.message=e?e.length+" errors occurred during unsubscription:\n"+e.map((function(e,t){return t+1+") "+e.toString()})).join("\n "):"",this.name="UnsubscriptionError",this.errors=e,this}return e.prototype=Object.create(Error.prototype),e}(),s=function(){function e(e){this.closed=!1,this._parentOrParents=null,this._subscriptions=null,e&&(this._ctorUnsubscribe=!0,this._unsubscribe=e)}var t;return e.prototype.unsubscribe=function(){var t;if(!this.closed){var n=this,s=n._parentOrParents,l=n._ctorUnsubscribe,d=n._unsubscribe,c=n._subscriptions;if(this.closed=!0,this._parentOrParents=null,this._subscriptions=null,s instanceof e)s.remove(this);else if(null!==s)for(var f=0;f{"use strict";n.d(t,{v:()=>i});var r=!1,i={Promise:void 0,set useDeprecatedSynchronousErrorHandling(e){e&&(new Error).stack;r=e},get useDeprecatedSynchronousErrorHandling(){return r}}},7604:(e,t,n)=>{"use strict";n.d(t,{IY:()=>s,Ds:()=>u,ft:()=>l});var r=n(655),i=n(979),a=n(4379),o=n(7843),s=function(e){function t(t){var n=e.call(this)||this;return n.parent=t,n}return r.ZT(t,e),t.prototype._next=function(e){this.parent.notifyNext(e)},t.prototype._error=function(e){this.parent.notifyError(e),this.unsubscribe()},t.prototype._complete=function(){this.parent.notifyComplete(),this.unsubscribe()},t}(i.L),u=(i.L,function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype.notifyNext=function(e){this.destination.next(e)},t.prototype.notifyError=function(e){this.destination.error(e)},t.prototype.notifyComplete=function(){this.destination.complete()},t}(i.L));i.L;function l(e,t){if(!t.closed){if(e instanceof a.y)return e.subscribe(t);var n;try{n=(0,o.s)(e)(t)}catch(e){t.error(e)}return n}}},5142:(e,t,n)=>{"use strict";n.d(t,{aj:()=>d});var r=n(655),i=n(7507),a=n(9026),o=n(2039),s=n(2080),u=n(3375),l={};function d(){for(var e=[],t=0;t{"use strict";n.d(t,{z:()=>a});var r=n(8170),i=n(2257);function a(){for(var e=[],t=0;t{"use strict";n.d(t,{P:()=>o});var r=n(4379),i=n(4072),a=n(5631);function o(e){return new r.y((function(t){var n;try{n=e()}catch(e){return void t.error(e)}return(n?(0,i.D)(n):(0,a.c)()).subscribe(t)}))}},5631:(e,t,n)=>{"use strict";n.d(t,{E:()=>i,c:()=>a});var r=n(4379),i=new r.y((function(e){return e.complete()}));function a(e){return e?function(e){return new r.y((function(t){return e.schedule((function(){return t.complete()}))}))}(e):i}},4072:(e,t,n)=>{"use strict";n.d(t,{D:()=>f});var r=n(4379),i=n(7843),a=n(3884),o=n(5050);var s=n(3109),u=n(999);var l=n(336),d=n(9217);function c(e,t){if(null!=e){if(function(e){return e&&"function"==typeof e[o.L]}(e))return function(e,t){return new r.y((function(n){var r=new a.w;return r.add(t.schedule((function(){var i=e[o.L]();r.add(i.subscribe({next:function(e){r.add(t.schedule((function(){return n.next(e)})))},error:function(e){r.add(t.schedule((function(){return n.error(e)})))},complete:function(){r.add(t.schedule((function(){return n.complete()})))}}))}))),r}))}(e,t);if((0,l.t)(e))return function(e,t){return new r.y((function(n){var r=new a.w;return r.add(t.schedule((function(){return e.then((function(e){r.add(t.schedule((function(){n.next(e),r.add(t.schedule((function(){return n.complete()})))})))}),(function(e){r.add(t.schedule((function(){return n.error(e)})))}))}))),r}))}(e,t);if((0,d.z)(e))return(0,s.r)(e,t);if(function(e){return e&&"function"==typeof e[u.hZ]}(e)||"string"==typeof e)return function(e,t){if(!e)throw new Error("Iterable cannot be null");return new r.y((function(n){var r,i=new a.w;return i.add((function(){r&&"function"==typeof r.return&&r.return()})),i.add(t.schedule((function(){r=e[u.hZ](),i.add(t.schedule((function(){if(!n.closed){var e,t;try{var i=r.next();e=i.value,t=i.done}catch(e){return void n.error(e)}t?n.complete():(n.next(e),this.schedule())}})))}))),i}))}(e,t)}throw new TypeError((null!==e&&typeof e||e)+" is not observable")}function f(e,t){return t?c(e,t):e instanceof r.y?e:new r.y((0,i.s)(e))}},3375:(e,t,n)=>{"use strict";n.d(t,{n:()=>o});var r=n(4379),i=n(6900),a=n(3109);function o(e,t){return t?(0,a.r)(e,t):new r.y((0,i.V)(e))}},7027:(e,t,n)=>{"use strict";n.d(t,{R:()=>s});var r=n(4379),i=n(9026),a=n(4156),o=n(5709);function s(e,t,n,l){return(0,a.m)(n)&&(l=n,n=void 0),l?s(e,t,n).pipe((0,o.U)((function(e){return(0,i.k)(e)?l.apply(void 0,e):l(e)}))):new r.y((function(r){u(e,t,(function(e){arguments.length>1?r.next(Array.prototype.slice.call(arguments)):r.next(e)}),r,n)}))}function u(e,t,n,r,i){var a;if(function(e){return e&&"function"==typeof e.addEventListener&&"function"==typeof e.removeEventListener}(e)){var o=e;e.addEventListener(t,n,i),a=function(){return o.removeEventListener(t,n,i)}}else if(function(e){return e&&"function"==typeof e.on&&"function"==typeof e.off}(e)){var s=e;e.on(t,n),a=function(){return s.off(t,n)}}else if(function(e){return e&&"function"==typeof e.addListener&&"function"==typeof e.removeListener}(e)){var l=e;e.addListener(t,n),a=function(){return l.removeListener(t,n)}}else{if(!e||!e.length)throw new TypeError("Invalid event target");for(var d=0,c=e.length;d{"use strict";n.d(t,{F:()=>o});var r=n(4379),i=n(964),a=n(5812);function o(e,t){return void 0===e&&(e=0),void 0===t&&(t=i.P),(!(0,a.k)(e)||e<0)&&(e=0),t&&"function"==typeof t.schedule||(t=i.P),new r.y((function(n){return n.add(t.schedule(s,e,{subscriber:n,counter:0,period:e})),n}))}function s(e){var t=e.subscriber,n=e.counter,r=e.period;t.next(n),this.schedule({subscriber:t,counter:n+1,period:r},r)}},4370:(e,t,n)=>{"use strict";n.d(t,{T:()=>s});var r=n(4379),i=n(7507),a=n(2556),o=n(3375);function s(){for(var e=[],t=0;t1&&"number"==typeof e[e.length-1]&&(n=e.pop())):"number"==typeof u&&(n=e.pop()),null===s&&1===e.length&&e[0]instanceof r.y?e[0]:(0,a.J)(n)((0,o.n)(e,s))}},8170:(e,t,n)=>{"use strict";n.d(t,{of:()=>o});var r=n(7507),i=n(3375),a=n(3109);function o(){for(var e=[],t=0;t{"use strict";n.d(t,{S3:()=>u});var r=n(655),i=n(9026),a=n(3375),o=n(2039),s=n(2080);function u(){for(var e=[],t=0;t{"use strict";n.d(t,{_:()=>i});var r=n(4379);function i(e,t){return t?new r.y((function(n){return t.schedule(a,0,{error:e,subscriber:n})})):new r.y((function(t){return t.error(e)}))}function a(e){var t=e.error;e.subscriber.error(t)}},9604:(e,t,n)=>{"use strict";n.d(t,{H:()=>s});var r=n(4379),i=n(964),a=n(5812),o=n(7507);function s(e,t,n){void 0===e&&(e=0);var s=-1;return(0,a.k)(t)?s=Number(t)<1?1:Number(t):(0,o.K)(t)&&(n=t),(0,o.K)(n)||(n=i.P),new r.y((function(t){var r=(0,a.k)(e)?e:+e-n.now();return n.schedule(u,r,{index:0,period:s,subscriber:t})}))}function u(e){var t=e.index,n=e.period,r=e.subscriber;if(r.next(t),!r.closed){if(-1===n)return r.complete();e.index=t+1,this.schedule(e,n)}}},486:(e,t,n)=>{"use strict";n.d(t,{K:()=>a});var r=n(655),i=n(7604);function a(e){return function(t){var n=new o(e),r=t.lift(n);return n.caught=r}}var o=function(){function e(e){this.selector=e}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.selector,this.caught))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.selector=n,i.caught=r,i}return r.ZT(t,e),t.prototype.error=function(t){if(!this.isStopped){var n=void 0;try{n=this.selector(t,this.caught)}catch(t){return void e.prototype.error.call(this,t)}this._unsubscribeAndRecycle();var r=new i.IY(this);this.add(r);var a=(0,i.ft)(n,r);a!==r&&this.add(a)}},t}(i.Ds)},2257:(e,t,n)=>{"use strict";n.d(t,{u:()=>i});var r=n(2556);function i(){return(0,r.J)(1)}},1931:(e,t,n)=>{"use strict";n.d(t,{x:()=>a});var r=n(655),i=n(979);function a(e,t){return function(n){return n.lift(new o(e,t))}}var o=function(){function e(e,t){this.compare=e,this.keySelector=t}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.compare,this.keySelector))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.keySelector=r,i.hasKey=!1,"function"==typeof n&&(i.compare=n),i}return r.ZT(t,e),t.prototype.compare=function(e,t){return e===t},t.prototype._next=function(e){var t;try{var n=this.keySelector;t=n?n(e):e}catch(e){return this.destination.error(e)}var r=!1;if(this.hasKey)try{r=(0,this.compare)(this.key,t)}catch(e){return this.destination.error(e)}else this.hasKey=!0;r||(this.key=t,this.destination.next(e))},t}(i.L)},6008:(e,t,n)=>{"use strict";n.d(t,{h:()=>a});var r=n(655),i=n(979);function a(e,t){return function(n){return n.lift(new o(e,t))}}var o=function(){function e(e,t){this.predicate=e,this.thisArg=t}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.predicate,this.thisArg))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.predicate=n,i.thisArg=r,i.count=0,i}return r.ZT(t,e),t.prototype._next=function(e){var t;try{t=this.predicate.call(this.thisArg,e,this.count++)}catch(e){return void this.destination.error(e)}t&&this.destination.next(e)},t}(i.L)},6738:(e,t,n)=>{"use strict";n.d(t,{l:()=>a});var r=n(655),i=n(979);function a(){return function(e){return e.lift(new o)}}var o=function(){function e(){}return e.prototype.call=function(e,t){return t.subscribe(new s(e))},e}(),s=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype._next=function(e){},t}(i.L)},5709:(e,t,n)=>{"use strict";n.d(t,{U:()=>a});var r=n(655),i=n(979);function a(e,t){return function(n){if("function"!=typeof e)throw new TypeError("argument is not a function. Are you looking for `mapTo()`?");return n.lift(new o(e,t))}}var o=function(){function e(e,t){this.project=e,this.thisArg=t}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.project,this.thisArg))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.project=n,i.count=0,i.thisArg=r||i,i}return r.ZT(t,e),t.prototype._next=function(e){var t;try{t=this.project.call(this.thisArg,e,this.count++)}catch(e){return void this.destination.error(e)}this.destination.next(t)},t}(i.L)},5602:(e,t,n)=>{"use strict";n.d(t,{h:()=>a});var r=n(655),i=n(979);function a(e){return function(t){return t.lift(new o(e))}}var o=function(){function e(e){this.value=e}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.value))},e}(),s=function(e){function t(t,n){var r=e.call(this,t)||this;return r.value=n,r}return r.ZT(t,e),t.prototype._next=function(e){this.destination.next(this.value)},t}(i.L)},2556:(e,t,n)=>{"use strict";n.d(t,{J:()=>a});var r=n(7746),i=n(3608);function a(e){return void 0===e&&(e=Number.POSITIVE_INFINITY),(0,r.zg)(i.y,e)}},7746:(e,t,n)=>{"use strict";n.d(t,{zg:()=>s});var r=n(655),i=n(5709),a=n(4072),o=n(7604);function s(e,t,n){return void 0===n&&(n=Number.POSITIVE_INFINITY),"function"==typeof t?function(r){return r.pipe(s((function(n,r){return(0,a.D)(e(n,r)).pipe((0,i.U)((function(e,i){return t(n,e,r,i)})))}),n))}:("number"==typeof t&&(n=t),function(t){return t.lift(new u(e,n))})}var u=function(){function e(e,t){void 0===t&&(t=Number.POSITIVE_INFINITY),this.project=e,this.concurrent=t}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.project,this.concurrent))},e}(),l=function(e){function t(t,n,r){void 0===r&&(r=Number.POSITIVE_INFINITY);var i=e.call(this,t)||this;return i.project=n,i.concurrent=r,i.hasCompleted=!1,i.buffer=[],i.active=0,i.index=0,i}return r.ZT(t,e),t.prototype._next=function(e){this.active0?this._next(e.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()},t}(o.Ds)},3756:(e,t,n)=>{"use strict";n.d(t,{j:()=>i});var r=n(7746);function i(e,t,n){return void 0===n&&(n=Number.POSITIVE_INFINITY),"function"==typeof t?(0,r.zg)((function(){return e}),t,n):("number"==typeof t&&(n=t),(0,r.zg)((function(){return e}),n))}},1421:(e,t,n)=>{"use strict";n.d(t,{O:()=>f});var r=n(655),i=n(211),a=n(4379),o=n(979),s=n(3884),u=n(3018),l=function(e){function t(t,n){var r=e.call(this)||this;return r.source=t,r.subjectFactory=n,r._refCount=0,r._isComplete=!1,r}return r.ZT(t,e),t.prototype._subscribe=function(e){return this.getSubject().subscribe(e)},t.prototype.getSubject=function(){var e=this._subject;return e&&!e.isStopped||(this._subject=this.subjectFactory()),this._subject},t.prototype.connect=function(){var e=this._connection;return e||(this._isComplete=!1,(e=this._connection=new s.w).add(this.source.subscribe(new c(this.getSubject(),this))),e.closed&&(this._connection=null,e=s.w.EMPTY)),e},t.prototype.refCount=function(){return(0,u.x)()(this)},t}(a.y),d=function(){var e=l.prototype;return{operator:{value:null},_refCount:{value:0,writable:!0},_subject:{value:null,writable:!0},_connection:{value:null,writable:!0},_subscribe:{value:e._subscribe},_isComplete:{value:e._isComplete,writable:!0},getSubject:{value:e.getSubject},connect:{value:e.connect},refCount:{value:e.refCount}}}(),c=function(e){function t(t,n){var r=e.call(this,t)||this;return r.connectable=n,r}return r.ZT(t,e),t.prototype._error=function(t){this._unsubscribe(),e.prototype._error.call(this,t)},t.prototype._complete=function(){this.connectable._isComplete=!0,this._unsubscribe(),e.prototype._complete.call(this)},t.prototype._unsubscribe=function(){var e=this.connectable;if(e){this.connectable=null;var t=e._connection;e._refCount=0,e._subject=null,e._connection=null,t&&t.unsubscribe()}},t}(i.Yc);o.L;function f(e,t){return function(n){var r;if(r="function"==typeof e?e:function(){return e},"function"==typeof t)return n.lift(new p(r,t));var i=Object.create(n,d);return i.source=n,i.subjectFactory=r,i}}var p=function(){function e(e,t){this.subjectFactory=e,this.selector=t}return e.prototype.call=function(e,t){var n=this.selector,r=this.subjectFactory(),i=n(r).subscribe(e);return i.add(t.subscribe(r)),i},e}()},3018:(e,t,n)=>{"use strict";n.d(t,{x:()=>a});var r=n(655),i=n(979);function a(){return function(e){return e.lift(new o(e))}}var o=function(){function e(e){this.connectable=e}return e.prototype.call=function(e,t){var n=this.connectable;n._refCount++;var r=new s(e,n),i=t.subscribe(r);return r.closed||(r.connection=n.connect()),i},e}(),s=function(e){function t(t,n){var r=e.call(this,t)||this;return r.connectable=n,r}return r.ZT(t,e),t.prototype._unsubscribe=function(){var e=this.connectable;if(e){this.connectable=null;var t=e._refCount;if(t<=0)this.connection=null;else if(e._refCount=t-1,t>1)this.connection=null;else{var n=this.connection,r=e._connection;this.connection=null,!r||n&&r!==n||r.unsubscribe()}}else this.connection=null},t}(i.L)},2807:(e,t,n)=>{"use strict";n.d(t,{R:()=>a});var r=n(655),i=n(979);function a(e,t){var n=!1;return arguments.length>=2&&(n=!0),function(r){return r.lift(new o(e,t,n))}}var o=function(){function e(e,t,n){void 0===n&&(n=!1),this.accumulator=e,this.seed=t,this.hasSeed=n}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.accumulator,this.seed,this.hasSeed))},e}(),s=function(e){function t(t,n,r,i){var a=e.call(this,t)||this;return a.accumulator=n,a._seed=r,a.hasSeed=i,a.index=0,a}return r.ZT(t,e),Object.defineProperty(t.prototype,"seed",{get:function(){return this._seed},set:function(e){this.hasSeed=!0,this._seed=e},enumerable:!0,configurable:!0}),t.prototype._next=function(e){if(this.hasSeed)return this._tryNext(e);this.seed=e,this.destination.next(e)},t.prototype._tryNext=function(e){var t,n=this.index++;try{t=this.accumulator(this.seed,e,n)}catch(e){this.destination.error(e)}this.seed=t,this.destination.next(t)},t}(i.L)},9095:(e,t,n)=>{"use strict";n.d(t,{B:()=>s});var r=n(1421),i=n(3018),a=n(211);function o(){return new a.xQ}function s(){return function(e){return(0,i.x)()((0,r.O)(o)(e))}}},7006:(e,t,n)=>{"use strict";n.d(t,{d:()=>i});var r=n(2135);function i(e,t,n){var i;return i=e&&"object"==typeof e?e:{bufferSize:e,windowTime:t,refCount:!1,scheduler:n},function(e){return e.lift(function(e){var t,n,i=e.bufferSize,a=void 0===i?Number.POSITIVE_INFINITY:i,o=e.windowTime,s=void 0===o?Number.POSITIVE_INFINITY:o,u=e.refCount,l=e.scheduler,d=0,c=!1,f=!1;return function(e){var i;d++,!t||c?(c=!1,t=new r.t(a,s,l),i=t.subscribe(this),n=e.subscribe({next:function(e){t.next(e)},error:function(e){c=!0,t.error(e)},complete:function(){f=!0,n=void 0,t.complete()}}),f&&(n=void 0)):i=t.subscribe(this),this.add((function(){d--,i.unsubscribe(),i=void 0,n&&!f&&u&&0===d&&(n.unsubscribe(),n=void 0,t=void 0)}))}}(i))}}},3485:(e,t,n)=>{"use strict";n.d(t,{O:()=>a});var r=n(9795),i=n(7507);function a(){for(var e=[],t=0;t{"use strict";n.d(t,{w:()=>s});var r=n(655),i=n(5709),a=n(4072),o=n(7604);function s(e,t){return"function"==typeof t?function(n){return n.pipe(s((function(n,r){return(0,a.D)(e(n,r)).pipe((0,i.U)((function(e,i){return t(n,e,r,i)})))})))}:function(t){return t.lift(new u(e))}}var u=function(){function e(e){this.project=e}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.project))},e}(),l=function(e){function t(t,n){var r=e.call(this,t)||this;return r.project=n,r.index=0,r}return r.ZT(t,e),t.prototype._next=function(e){var t,n=this.index++;try{t=this.project(e,n)}catch(e){return void this.destination.error(e)}this._innerSub(t)},t.prototype._innerSub=function(e){var t=this.innerSubscription;t&&t.unsubscribe();var n=new o.IY(this),r=this.destination;r.add(n),this.innerSubscription=(0,o.ft)(e,n),this.innerSubscription!==n&&r.add(this.innerSubscription)},t.prototype._complete=function(){var t=this.innerSubscription;t&&!t.closed||e.prototype._complete.call(this),this.unsubscribe()},t.prototype._unsubscribe=function(){this.innerSubscription=void 0},t.prototype.notifyComplete=function(){this.innerSubscription=void 0,this.isStopped&&e.prototype._complete.call(this)},t.prototype.notifyNext=function(e){this.destination.next(e)},t}(o.Ds)},1198:(e,t,n)=>{"use strict";n.d(t,{c:()=>i});var r=n(6381);function i(e,t){return t?(0,r.w)((function(){return e}),t):(0,r.w)((function(){return e}))}},1015:(e,t,n)=>{"use strict";n.d(t,{q:()=>s});var r=n(655),i=n(979),a=n(6565),o=n(5631);function s(e){return function(t){return 0===e?(0,o.c)():t.lift(new u(e))}}var u=function(){function e(e){if(this.total=e,this.total<0)throw new a.W}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.total))},e}(),l=function(e){function t(t,n){var r=e.call(this,t)||this;return r.total=n,r.count=0,r}return r.ZT(t,e),t.prototype._next=function(e){var t=this.total,n=++this.count;n<=t&&(this.destination.next(e),n===t&&(this.destination.complete(),this.unsubscribe()))},t}(i.L)},1558:(e,t,n)=>{"use strict";n.d(t,{R:()=>a});var r=n(655),i=n(7604);function a(e){return function(t){return t.lift(new o(e))}}var o=function(){function e(e){this.notifier=e}return e.prototype.call=function(e,t){var n=new s(e),r=(0,i.ft)(this.notifier,new i.IY(n));return r&&!n.seenValue?(n.add(r),t.subscribe(n)):n},e}(),s=function(e){function t(t){var n=e.call(this,t)||this;return n.seenValue=!1,n}return r.ZT(t,e),t.prototype.notifyNext=function(){this.seenValue=!0,this.complete()},t.prototype.notifyComplete=function(){},t}(i.Ds)},3068:(e,t,n)=>{"use strict";n.d(t,{b:()=>s});var r=n(655),i=n(979),a=n(3306),o=n(4156);function s(e,t,n){return function(r){return r.lift(new u(e,t,n))}}var u=function(){function e(e,t,n){this.nextOrObserver=e,this.error=t,this.complete=n}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.nextOrObserver,this.error,this.complete))},e}(),l=function(e){function t(t,n,r,i){var s=e.call(this,t)||this;return s._tapNext=a.Z,s._tapError=a.Z,s._tapComplete=a.Z,s._tapError=r||a.Z,s._tapComplete=i||a.Z,(0,o.m)(n)?(s._context=s,s._tapNext=n):n&&(s._context=n,s._tapNext=n.next||a.Z,s._tapError=n.error||a.Z,s._tapComplete=n.complete||a.Z),s}return r.ZT(t,e),t.prototype._next=function(e){try{this._tapNext.call(this._context,e)}catch(e){return void this.destination.error(e)}this.destination.next(e)},t.prototype._error=function(e){try{this._tapError.call(this._context,e)}catch(e){return void this.destination.error(e)}this.destination.error(e)},t.prototype._complete=function(){try{this._tapComplete.call(this._context)}catch(e){return void this.destination.error(e)}return this.destination.complete()},t}(i.L)},3109:(e,t,n)=>{"use strict";n.d(t,{r:()=>a});var r=n(4379),i=n(3884);function a(e,t){return new r.y((function(n){var r=new i.w,a=0;return r.add(t.schedule((function(){a!==e.length?(n.next(e[a++]),n.closed||r.add(this.schedule())):n.complete()}))),r}))}},6114:(e,t,n)=>{"use strict";n.d(t,{o:()=>i});var r=n(655),i=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.scheduler=t,r.work=n,r.pending=!1,r}return r.ZT(t,e),t.prototype.schedule=function(e,t){if(void 0===t&&(t=0),this.closed)return this;this.state=e;var n=this.id,r=this.scheduler;return null!=n&&(this.id=this.recycleAsyncId(r,n,t)),this.pending=!0,this.delay=t,this.id=this.id||this.requestAsyncId(r,this.id,t),this},t.prototype.requestAsyncId=function(e,t,n){return void 0===n&&(n=0),setInterval(e.flush.bind(e,this),n)},t.prototype.recycleAsyncId=function(e,t,n){if(void 0===n&&(n=0),null!==n&&this.delay===n&&!1===this.pending)return t;clearInterval(t)},t.prototype.execute=function(e,t){if(this.closed)return new Error("executing a cancelled action");this.pending=!1;var n=this._execute(e,t);if(n)return n;!1===this.pending&&null!=this.id&&(this.id=this.recycleAsyncId(this.scheduler,this.id,null))},t.prototype._execute=function(e,t){var n=!1,r=void 0;try{this.work(e)}catch(e){n=!0,r=!!e&&e||new Error(e)}if(n)return this.unsubscribe(),r},t.prototype._unsubscribe=function(){var e=this.id,t=this.scheduler,n=t.actions,r=n.indexOf(this);this.work=null,this.state=null,this.pending=!1,this.scheduler=null,-1!==r&&n.splice(r,1),null!=e&&(this.id=this.recycleAsyncId(t,e,null)),this.delay=null},t}(function(e){function t(t,n){return e.call(this)||this}return r.ZT(t,e),t.prototype.schedule=function(e,t){return void 0===t&&(t=0),this},t}(n(3884).w))},2980:(e,t,n)=>{"use strict";n.d(t,{v:()=>a});var r=n(655),i=function(){function e(t,n){void 0===n&&(n=e.now),this.SchedulerAction=t,this.now=n}return e.prototype.schedule=function(e,t,n){return void 0===t&&(t=0),new this.SchedulerAction(this,e).schedule(n,t)},e.now=function(){return Date.now()},e}(),a=function(e){function t(n,r){void 0===r&&(r=i.now);var a=e.call(this,n,(function(){return t.delegate&&t.delegate!==a?t.delegate.now():r()}))||this;return a.actions=[],a.active=!1,a.scheduled=void 0,a}return r.ZT(t,e),t.prototype.schedule=function(n,r,i){return void 0===r&&(r=0),t.delegate&&t.delegate!==this?t.delegate.schedule(n,r,i):e.prototype.schedule.call(this,n,r,i)},t.prototype.flush=function(e){var t=this.actions;if(this.active)t.push(e);else{var n;this.active=!0;do{if(n=e.execute(e.state,e.delay))break}while(e=t.shift());if(this.active=!1,n){for(;e=t.shift();)e.unsubscribe();throw n}}},t}(i)},964:(e,t,n)=>{"use strict";n.d(t,{P:()=>i});var r=n(6114),i=new(n(2980).v)(r.o)},999:(e,t,n)=>{"use strict";function r(){return"function"==typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator"}n.d(t,{hZ:()=>i});var i=r()},5050:(e,t,n)=>{"use strict";n.d(t,{L:()=>r});var r=function(){return"function"==typeof Symbol&&Symbol.observable||"@@observable"}()},3142:(e,t,n)=>{"use strict";n.d(t,{b:()=>r});var r=function(){return"function"==typeof Symbol?Symbol("rxSubscriber"):"@@rxSubscriber_"+Math.random()}()},6565:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});var r=function(){function e(){return Error.call(this),this.message="argument out of range",this.name="ArgumentOutOfRangeError",this}return e.prototype=Object.create(Error.prototype),e}()},1016:(e,t,n)=>{"use strict";n.d(t,{N:()=>r});var r=function(){function e(){return Error.call(this),this.message="object unsubscribed",this.name="ObjectUnsubscribedError",this}return e.prototype=Object.create(Error.prototype),e}()},1644:(e,t,n)=>{"use strict";function r(e){setTimeout((function(){throw e}),0)}n.d(t,{z:()=>r})},3608:(e,t,n)=>{"use strict";function r(e){return e}n.d(t,{y:()=>r})},9026:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});var r=function(){return Array.isArray||function(e){return e&&"number"==typeof e.length}}()},9217:(e,t,n)=>{"use strict";n.d(t,{z:()=>r});var r=function(e){return e&&"number"==typeof e.length&&"function"!=typeof e}},9914:(e,t,n)=>{"use strict";function r(e){return e instanceof Date&&!isNaN(+e)}n.d(t,{J:()=>r})},4156:(e,t,n)=>{"use strict";function r(e){return"function"==typeof e}n.d(t,{m:()=>r})},5812:(e,t,n)=>{"use strict";n.d(t,{k:()=>i});var r=n(9026);function i(e){return!(0,r.k)(e)&&e-parseFloat(e)+1>=0}},2009:(e,t,n)=>{"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{K:()=>r})},336:(e,t,n)=>{"use strict";function r(e){return!!e&&"function"!=typeof e.subscribe&&"function"==typeof e.then}n.d(t,{t:()=>r})},7507:(e,t,n)=>{"use strict";function r(e){return e&&"function"==typeof e.schedule}n.d(t,{K:()=>r})},3306:(e,t,n)=>{"use strict";function r(){}n.d(t,{Z:()=>r})},7843:(e,t,n)=>{"use strict";n.d(t,{s:()=>d});var r=n(6900),i=n(1644),a=n(999),o=n(5050),s=n(9217),u=n(336),l=n(2009),d=function(e){if(e&&"function"==typeof e[o.L])return d=e,function(e){var t=d[o.L]();if("function"!=typeof t.subscribe)throw new TypeError("Provided object does not correctly implement Symbol.observable");return t.subscribe(e)};if((0,s.z)(e))return(0,r.V)(e);if((0,u.t)(e))return n=e,function(e){return n.then((function(t){e.closed||(e.next(t),e.complete())}),(function(t){return e.error(t)})).then(null,i.z),e};if(e&&"function"==typeof e[a.hZ])return t=e,function(e){for(var n=t[a.hZ]();;){var r=void 0;try{r=n.next()}catch(t){return e.error(t),e}if(r.done){e.complete();break}if(e.next(r.value),e.closed)break}return"function"==typeof n.return&&e.add((function(){n.return&&n.return()})),e};var t,n,d,c=(0,l.K)(e)?"an invalid object":"'"+e+"'";throw new TypeError("You provided "+c+" where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.")}},6900:(e,t,n)=>{"use strict";n.d(t,{V:()=>r});var r=function(e){return function(t){for(var n=0,r=e.length;n{"use strict";n.d(t,{D:()=>s});var r=n(655),i=function(e){function t(t,n,r){var i=e.call(this)||this;return i.parent=t,i.outerValue=n,i.outerIndex=r,i.index=0,i}return r.ZT(t,e),t.prototype._next=function(e){this.parent.notifyNext(this.outerValue,e,this.outerIndex,this.index++,this)},t.prototype._error=function(e){this.parent.notifyError(e,this),this.unsubscribe()},t.prototype._complete=function(){this.parent.notifyComplete(this),this.unsubscribe()},t}(n(979).L),a=n(7843),o=n(4379);function s(e,t,n,r,s){if(void 0===s&&(s=new i(e,n,r)),!s.closed)return t instanceof o.y?t.subscribe(s):(0,a.s)(t)(s)}},655:(e,t,n)=>{"use strict";n.d(t,{ZT:()=>i});var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function i(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var a=t[r]={exports:{}};return e[r](a,a.exports,n),a.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var r={};return(()=>{"use strict";n.d(r,{default:()=>Ui});var e=n(5991),t=n(1788),i=n(211),a=n(2135),o=n(655),s=n(1016),u=function(e){function t(t){var n=e.call(this)||this;return n._value=t,n}return o.ZT(t,e),Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!0,configurable:!0}),t.prototype._subscribe=function(t){var n=e.prototype._subscribe.call(this,t);return n&&!n.closed&&t.next(this._value),n},t.prototype.getValue=function(){if(this.hasError)throw this.thrownError;if(this.closed)throw new s.N;return this._value},t.prototype.next=function(t){e.prototype.next.call(this,this._value=t)},t}(i.xQ),l=n(8170),d=n(5142),c=n(9795),f=n(4370),p=n(5631),h=n(1558),v=n(5709),m=n(1931),g=n(7746),y=n(7006),_=n(1421);function b(e){return e?(0,_.O)((function(){return new i.xQ}),e):(0,_.O)(new i.xQ)}var T=n(6008),E=n(9095),w=n(3485),S=n(1015),k=n(5602),A=n(979);var x=function(){function e(e){this.predicate=e}return e.prototype.call=function(e,t){return t.subscribe(new I(e,this.predicate))},e}(),I=function(e){function t(t,n){var r=e.call(this,t)||this;return r.predicate=n,r.skipping=!0,r.index=0,r}return o.ZT(t,e),t.prototype._next=function(e){var t=this.destination;this.skipping&&this.tryCallPredicate(e),this.skipping||t.next(e)},t.prototype.tryCallPredicate=function(e){try{var t=this.predicate(e,this.index++);this.skipping=Boolean(t)}catch(e){this.destination.error(e)}},t}(A.L),Z=n(1198),R=n(3756),M=n(1473);function C(){if(N()){var e=document;"function"==typeof e.exitFullscreen?e.exitFullscreen():"function"==typeof e.msExitFullscreen?e.msExitFullscreen():"function"==typeof e.mozCancelFullScreen?e.mozCancelFullScreen():"function"==typeof e.webkitExitFullscreen&&e.webkitExitFullscreen()}}function N(){var e=document;return null!=e.fullscreenElement||null!=e.mozFullScreenElement||null!=e.webkitFullscreenElement||null!=e.msFullscreenElement}var P=n(3666),O=n(3887);function D(){var e,t;if(!P.vU)return!0;var n=function(){if(!P.vU)return O.Z.warn("Compat: Can't access Firefox version on no firefox browser."),null;var e=navigator.userAgent,t=/Firefox\/([0-9]+)\./.exec(e);if(null===t)return-1;var n=parseInt(t[1],10);return isNaN(n)?-1:n}();return null===n||n<67||void 0!==(null===(t=null===(e=HTMLVideoElement)||void 0===e?void 0:e.prototype)||void 0===t?void 0:t.requirePictureInPicture)}var L=n(944),B=n(3714),U=n(9822),F=n(5389);function z(e,t){var n=t.defaultCode,r=t.defaultReason;if((0,U.Z)(e))return e;var i=e instanceof Error?e.toString():r;return new F.Z(n,i)}var K=n(5992),V=n(7874),W=n(1966),G=n(4791),H=n(1959),$=n(1946),j=n(8894),Y=n(8026),q=n(9589),X=n(2829),Q=n(8806),J=n(1410),ee=n(6139),te=n(6033);function ne(e){return(0,J.P)((function(){var t=te.Z.getState(e);if(null===t)return(0,l.of)(null);O.Z.info("EME: Disposing of the current MediaKeys");var n=t.loadedSessionsStore;return te.Z.clearState(e),n.closeAllSessions().pipe((0,R.j)((0,ee.Y)(e,null)))}))}function re(e){var t=te.Z.getState(e);return null==t?null:t.keySystemOptions.type}var ie=n(6738);function ae(e){return(0,J.P)((function(){if(O.Z.info("EME: Clearing-up EME session."),P.fq)return O.Z.info("EME: disposing current MediaKeys."),ne(e).pipe((0,ie.l)());var t=te.Z.getState(e);return null!==t&&!0===t.keySystemOptions.closeSessionsOnStop?(O.Z.info("EME: closing all current sessions."),t.loadedSessionsStore.closeAllSessions().pipe((0,ie.l)())):(O.Z.info("EME: Nothing to clear. Returning right away. No state =",null===t),p.E)}))}var oe=n(486),se=n(3884);function ue(e){return function(t){return t.lift(new le(e))}}var le=function(){function e(e){this.callback=e}return e.prototype.call=function(e,t){return t.subscribe(new de(e,this.callback))},e}(),de=function(e){function t(t,n){var r=e.call(this,t)||this;return r.add(new se.w(n)),r}return o.ZT(t,e),t}(A.L),ce=n(5561),fe=n(2793),pe=n(9105),he=n(9362);function ve(e){return e instanceof pe.Z?new he.Z("PIPELINE_LOAD_ERROR",e):z(e,{defaultCode:"PIPELINE_LOAD_ERROR",defaultReason:"Unknown error when fetching the Manifest"})}var me=n(9604);var ge,ye=n(2572);function _e(e){return e.type===K.br.ERROR_EVENT&&!1===navigator.onLine}function be(e,t,n){var r=n.baseDelay,i=n.maxDelay,a=n.maxRetryRegular,o=n.maxRetryOffline,s=0,u=ge.None,l=e.slice();return 0===l.length?(O.Z.warn("Fetchers: no URL given to `tryURLsWithBackoff`."),p.E):function e(n,d){return t(n).pipe((0,v.U)((function(e){return{type:"response",value:e}})),(0,oe.K)((function(t){if(!function(e){return e instanceof pe.Z?e.type===K.br.ERROR_HTTP_CODE?e.status>=500||404===e.status||415===e.status||412===e.status:e.type===K.br.TIMEOUT||e.type===K.br.ERROR_EVENT:(0,U.Z)(e)&&"INTEGRITY_ERROR"===e.code}(t)){if(l.length<=1)throw t;l.splice(d,1);var n=d>=l.length-1?0:d;return e(l[n],n).pipe((0,w.O)({type:"retry",value:t}))}var c=function(e){return e instanceof pe.Z&&_e(e)?ge.Offline:ge.Regular}(t),f=c===ge.Offline?o:a;if(c!==u&&(s=0,u=c),df)throw t;var h=Math.min(r*Math.pow(2,s-1),i),v=(0,ye.Z)(h),m=l[0];return(0,me.H)(v).pipe((0,g.zg)((function(){return e(m,0)})),(0,w.O)({type:"retry",value:t}))})))}(l[0],0)}function Te(e,t){return be([null],(function(){return e}),t)}!function(e){e[e.None=0]="None",e[e.Regular=1]="Regular",e[e.Offline=2]="Offline"}(ge||(ge={}));var Ee=L.Z.DEFAULT_MAX_MANIFEST_REQUEST_RETRY,we=L.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE,Se=L.Z.INITIAL_BACKOFF_DELAY_BASE,ke=L.Z.MAX_BACKOFF_DELAY_BASE;const Ae=function(){function e(e,t,n){var r,i,a,o;this._manifestUrl=e,this._pipelines=t.manifest,this._backoffOptions=(i=(r=n).maxRetryRegular,a=r.maxRetryOffline,{baseDelay:(o=r.lowLatencyMode)?Se.LOW_LATENCY:Se.REGULAR,maxDelay:o?ke.LOW_LATENCY:ke.REGULAR,maxRetryRegular:void 0!==i?i:Ee,maxRetryOffline:void 0!==a?a:we})}var t=e.prototype;return t.fetch=function(e){var t,n=this,r=null!=e?e:this._manifestUrl,i=null!==(t=this._pipelines.resolver)&&void 0!==t?t:l.of,a=this._pipelines.loader;return(0,ce.Z)(i,{url:r}).pipe((0,oe.K)((function(e){throw ve(e)})),(0,g.zg)((function(e){return Te((0,ce.Z)(a,e),n._backoffOptions).pipe((0,oe.K)((function(e){throw ve(e)})),(0,v.U)((function(e){return"retry"===e.type?{type:"warning",value:ve(e.value)}:{type:"response",parse:function(t){return n._parseLoadedManifest(e.value.value,t)}}})))})))},t.parse=function(e,t){return this._parseLoadedManifest({responseData:e,size:void 0,duration:void 0},t)},t._parseLoadedManifest=function(e,t){var n,r,a=e.sendingTime,o=e.receivedTime,s=performance.now(),u=new i.xQ,l=(n=this._backoffOptions,r=u,function(e){return Te((0,ce.Z)(e,void 0),n).pipe((0,fe.Z)((function(e){return"retry"===e.type?(r.next(ve(e.value)),null):e.value}),null),(0,oe.K)((function(e){throw ve(e)})))});return(0,f.T)(u.pipe((0,v.U)((function(e){return{type:"warning",value:e}}))),this._pipelines.parser({response:e,url:this._manifestUrl,externalClockOffset:t.externalClockOffset,previousManifest:t.previousManifest,scheduleRequest:l,unsafeMode:t.unsafeMode}).pipe((0,oe.K)((function(e){throw z(e,{defaultCode:"PIPELINE_PARSE_ERROR",defaultReason:"Unknown error when parsing the Manifest"})})),(0,v.U)((function(e){if("warning"===e.type)return{type:"warning",value:z(e.value,{defaultCode:"PIPELINE_PARSE_ERROR",defaultReason:"Unknown error when parsing the Manifest"})};var t=performance.now()-s;return{type:"parsed",manifest:e.value.manifest,sendingTime:a,receivedTime:o,parsingTime:t}})),ue((function(){u.complete()}))))},e}();var xe=L.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR,Ie=L.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE,Ze=L.Z.INITIAL_BACKOFF_DELAY_BASE,Re=L.Z.MAX_BACKOFF_DELAY_BASE;var Me=n(4379),Ce=n(5138),Ne=function(){function e(e){var t=e.prioritySteps;if(this._minPendingPriority=null,this._waitingQueue=[],this._pendingTasks=[],this._prioritySteps=t,this._prioritySteps.high>=this._prioritySteps.low)throw new Error("FP Error: the max high level priority should be given a lowerpriority number than the min low priority.")}var t=e.prototype;return t.create=function(e,t){var n=this,r=new Me.y((function(i){var a,o=!0;return a={observable:r,priority:t,trigger:function(t){null!==a.subscription&&(a.subscription.unsubscribe(),a.subscription=null,o&&i.next({type:"interrupted"})),t&&(n._minPendingPriority=null===n._minPendingPriority?a.priority:Math.min(n._minPendingPriority,a.priority),n._pendingTasks.push(a),a.subscription=e.subscribe((function(e){return i.next({type:"data",value:e})}),(function(e){i.error(e),a.subscription=null,a.finished=!0,n._onTaskEnd(a)}),(function(){i.next({type:"ended"}),o&&i.complete(),a.subscription=null,a.finished=!0,n._onTaskEnd(a)})))},subscription:null,finished:!1},n._canBeStartedNow(a)?(a.trigger(!0),n._isRunningHighPriorityTasks()&&n._interruptCancellableTasks()):n._waitingQueue.push(a),function(){if(o=!1,null!==a.subscription&&(a.subscription.unsubscribe(),a.subscription=null),!a.finished){var e=(0,Ce.Z)(n._waitingQueue,(function(e){return e.observable===r}));if(e>=0)n._waitingQueue.splice(e,1);else{var t=(0,Ce.Z)(n._pendingTasks,(function(e){return e.observable===r}));if(t<0)return void O.Z.warn("FP: unsubscribing non-existent task");var i=n._pendingTasks.splice(t,1)[0];0===n._pendingTasks.length?(n._minPendingPriority=null,n._loopThroughWaitingQueue()):n._minPendingPriority===i.priority&&(n._minPendingPriority=Math.min.apply(Math,n._pendingTasks.map((function(e){return e.priority}))),n._loopThroughWaitingQueue())}}}}));return r},t.updatePriority=function(e,t){var n=(0,Ce.Z)(this._waitingQueue,(function(t){return t.observable===e}));if(n>=0){var r=this._waitingQueue[n];if(r.priority===t)return;if(r.priority=t,!this._canBeStartedNow(r))return;return this._startWaitingQueueTask(n),void(this._isRunningHighPriorityTasks()&&this._interruptCancellableTasks())}var i=(0,Ce.Z)(this._pendingTasks,(function(t){return t.observable===e}));if(i<0)O.Z.warn("FP: request to update the priority of a non-existent task");else{var a=this._pendingTasks[i];if(a.priority!==t){var o=a.priority;if(a.priority=t,null===this._minPendingPriority||tt.priority?t.priority:e}),null);if(!(null===e||null!==this._minPendingPriority&&this._minPendingPriority=this._prioritySteps.low)return this._interruptPendingTask(t),this._interruptCancellableTasks()}},t._startWaitingQueueTask=function(e){this._waitingQueue.splice(e,1)[0].trigger(!0)},t._interruptPendingTask=function(e){var t=(0,Ce.Z)(this._pendingTasks,(function(t){return t.observable===e.observable}));t<0?O.Z.warn("FP: Interrupting a non-existent pending task. Aborting..."):(this._pendingTasks.splice(t,1),this._waitingQueue.push(e),0===this._pendingTasks.length?this._minPendingPriority=null:this._minPendingPriority===e.priority&&(this._minPendingPriority=Math.min.apply(Math,this._pendingTasks.map((function(e){return e.priority})))),e.trigger(!1))},t._onTaskEnd=function(e){var t=(0,Ce.Z)(this._pendingTasks,(function(t){return t.observable===e.observable}));t<0||(this._pendingTasks.splice(t,1),this._pendingTasks.length>0?this._minPendingPriority===e.priority&&(this._minPendingPriority=Math.min.apply(Math,this._pendingTasks.map((function(e){return e.priority})))):(this._minPendingPriority=null,this._loopThroughWaitingQueue()))},t._canBeStartedNow=function(e){return null===this._minPendingPriority||e.priority<=this._minPendingPriority},t._isRunningHighPriorityTasks=function(){return null!==this._minPendingPriority&&this._minPendingPriority<=this._prioritySteps.high},e}(),Pe=n(3068),Oe=n(7714),De=n(8418),Le=n(908);const Be=function(){function e(){this._cache=new WeakMap}var t=e.prototype;return t.add=function(e,t){var n=e.representation;e.segment.isInit&&this._cache.set(n,t)},t.get=function(e){var t=e.representation;if(e.segment.isInit){var n=this._cache.get(t);if(void 0!==n)return n}return null},e}();var Ue=n(8117);function Fe(e,t,n){return function(r){return function(r){function i(){var i;return be(null!==(i=r.segment.mediaURLs)&&void 0!==i?i:[null],(function(t){var n=(0,Y.Z)({url:t},r);return(0,c.z)((0,l.of)({type:"request",value:n}),(0,ce.Z)(e,n))}),n).pipe((0,oe.K)((function(e){throw ve(e)})),(0,v.U)((function(e){if("retry"===e.type)return{type:"warning",value:ve(e.value)};if("request"===e.value.type)return e.value;var n=e.value;return"data-loaded"===n.type&&null!=t&&t.add(r,n.value),e.value})))}var a=null!=t?t.get(r):null;return null!=a?(0,Ue.Z)(a).pipe((0,v.U)((function(e){return{type:"cache",value:e}})),(0,oe.K)(i)):i()}(r).pipe((0,g.zg)((function(e){var t;switch(t="data-chunk-complete"!==e.type&&"data-loaded"!==e.type||void 0===e.value.size||void 0===e.value.duration?p.E:(0,l.of)({type:"metrics",value:{size:e.value.size,duration:e.value.duration,content:r}}),e.type){case"warning":case"request":case"progress":return(0,l.of)(e);case"cache":case"data-created":case"data-loaded":return(0,c.z)((0,l.of)({type:"data",value:e.value}),t);case"data-chunk":return(0,l.of)({type:"chunk",value:e.value});case"data-chunk-complete":return(0,c.z)((0,l.of)({type:"chunk-complete",value:null}),t);default:(0,De.Z)(e)}})))}}var ze=(0,Le.Z)();var Ke=L.Z.MIN_CANCELABLE_PRIORITY,Ve=L.Z.MAX_HIGH_PRIORITY_LEVEL;const We=function(){function e(e,t){this._transport=e,this._prioritizer=new Ne({prioritySteps:{high:Ve,low:Ke}}),this._backoffOptions=t}return e.prototype.createSegmentFetcher=function(e,t){var n,r,i,a=function(e,t){var n=t.maxRetryRegular,r=t.maxRetryOffline,i=t.lowLatencyMode;return{maxRetryRegular:"image"===e?0:null!=n?n:xe,maxRetryOffline:null!=r?r:Ie,baseDelay:i?Ze.LOW_LATENCY:Ze.REGULAR,maxDelay:i?Re.LOW_LATENCY:Re.REGULAR}}(e,this._backoffOptions),o=function(e,t,n,r){var i=(0,Oe.Z)(["audio","video"],e)?new Be:void 0,a=Fe(t[e].loader,i,r),o=t[e].parser;return function(e){var t=ze(),r=!1;return a(e).pipe((0,Pe.b)((function(e){switch(e.type){case"metrics":n.next(e);break;case"request":var i=e.value.segment;if(void 0===i)return;r=!0,n.next({type:"requestBegin",value:{duration:i.duration,time:i.time,requestTimestamp:performance.now(),id:t}});break;case"progress":var a=e.value;null!=a.totalSize&&a.size0?this._next(e.shift()):0===this.active&&this.hasCompleted&&(!1===this.hasValue&&this.destination.next(this.acc),this.destination.complete())},t}(Ge.Ds),je=n(4072);function Ye(e,t){return t?function(n){return n.pipe(Ye((function(n,r){return(0,je.D)(e(n,r)).pipe((0,v.U)((function(e,i){return t(n,e,r,i)})))})))}:function(t){return t.lift(new qe(e))}}var qe=function(){function e(e){this.project=e}return e.prototype.call=function(e,t){return t.subscribe(new Xe(e,this.project))},e}(),Xe=function(e){function t(t,n){var r=e.call(this,t)||this;return r.project=n,r.hasSubscription=!1,r.hasCompleted=!1,r.index=0,r}return o.ZT(t,e),t.prototype._next=function(e){this.hasSubscription||this.tryNext(e)},t.prototype.tryNext=function(e){var t,n=this.index++;try{t=this.project(e,n)}catch(e){return void this.destination.error(e)}this.hasSubscription=!0,this._innerSub(t)},t.prototype._innerSub=function(e){var t=new Ge.IY(this),n=this.destination;n.add(t);var r=(0,Ge.ft)(e,t);r!==t&&n.add(r)},t.prototype._complete=function(){this.hasCompleted=!0,this.hasSubscription||this.destination.complete(),this.unsubscribe()},t.prototype.notifyNext=function(e){this.destination.next(e)},t.prototype.notifyError=function(e){this.destination.error(e)},t.prototype.notifyComplete=function(){this.hasSubscription=!1,this.hasCompleted&&this.destination.complete()},t}(Ge.Ds),Qe=n(6381);var Je=n(8025),et=n(5278),tt=function(){function e(e){this._alpha=Math.exp(Math.log(.5)/e),this._lastEstimate=0,this._totalWeight=0}var t=e.prototype;return t.addSample=function(e,t){var n=Math.pow(this._alpha,e),r=t*(1-n)+n*this._lastEstimate;isNaN(r)||(this._lastEstimate=r,this._totalWeight+=e)},t.getEstimate=function(){var e=1-Math.pow(this._alpha,this._totalWeight);return this._lastEstimate/e},e}(),nt=L.Z.ABR_MINIMUM_TOTAL_BYTES,rt=L.Z.ABR_MINIMUM_CHUNK_SIZE,it=L.Z.ABR_FAST_EMA,at=L.Z.ABR_SLOW_EMA,ot=function(){function e(){this._fastEWMA=new tt(it),this._slowEWMA=new tt(at),this._bytesSampled=0}var t=e.prototype;return t.addSample=function(e,t){if(!(t0){var i=r.indexOf(n);-1!==i&&r.splice(i,1)}},t.prototype.notifyComplete=function(){},t.prototype._next=function(e){if(0===this.toRespond.length){var t=[e].concat(this.values);this.project?this._tryProject(t):this.destination.next(t)}},t.prototype._tryProject=function(e){var t;try{t=this.project.apply(this,e)}catch(e){return void this.destination.error(e)}this.destination.next(t)},t}(st.L);function ft(e){var t=e.map((function(t){return Math.log(t/e[0])})),n=t.map((function(e){return e-t[0]+1})),r=(n[n.length-1]-1)/(2*e.length+10),i=1/r;return e.map((function(t,a){return function(t){if(0===t)return 0;var a=Math.min(Math.max(1,t),e.length-1);return i*(r+(e[a]*n[a-1]-e[a-1]*n[a])/(e[a]-e[a-1]))+4}(a)}))}function pt(e,t){var n=ft(t);return O.Z.debug("ABR: Steps for buffer based chooser.",n.map((function(e,n){return{bufferLevel:e,bitrate:t[n]}}))),e.pipe((0,v.U)((function(e){return function(e,t,n){var r=e.bufferGap,i=e.currentBitrate,a=e.currentScore,o=e.speed;if(null==i)return t[0];var s,u=(0,Ce.Z)(t,(function(e){return e===i}));if(u<0||t.length!==n.length)return O.Z.error("ABR: Current Bitrate not found in the calculated levels"),t[0];if(null!=a&&(s=0===o?a:a/o),null!=s&&s>1){var l=n[u],d=function(){for(var e=u+1;el)return e}();if(null!=d&&r>=n[d])return t[d]}if((null==s||s<1.15)&&r=0;c--)if(t[c]t&&t-e.time>-1.2}));if(n<0)return[];for(var r=e[n],i=r.time,a=[r],o=n+1;o0?l.progress[l.progress.length-1]:void 0,p=Et(l);if(void 0!==f&&void 0!==p){var h=wt(f,p);if((c-f.timestamp)/1e3<=h)if(h-s/a>2e3)return p}var v=(c-l.requestTimestamp)/1e3;if(null!=n&&!(v<=(1.5*d+2)/a)){var m=d/v,g=n.bitrate*Math.min(.7,m);return void 0===r||g=s.outOfStarvationGap&&(O.Z.info("ABR: exit starvation mode."),this._inStarvationMode=!1):this._inStarvationMode&&(O.Z.info("ABR: exit starvation mode."),this._inStarvationMode=!1),this._inStarvationMode&&null!=(o=St(r,e,n,i))&&(O.Z.info("ABR: starvation mode emergency estimate:",o),t.reset(),a=null==n?o:Math.min(o,n.bitrate)),null==a&&(a=null!=(o=t.getEstimate())?o*(this._inStarvationMode?s.starvationBitrateFactor:s.regularBitrateFactor):null!=i?i*(this._inStarvationMode?s.starvationBitrateFactor:s.regularBitrateFactor):this._initialBitrate),e.speed>1&&(a/=e.speed),{bandwidthEstimate:o,bitrateChosen:a}},t.isUrgent=function(e,t,n,r){return null===t||e!==t.bitrate&&(e>t.bitrate?!this._inStarvationMode:function(e,t){var n=isFinite(e.bufferGap)?e.bufferGap:0,r=e.position+n,i=(0,mt.Z)(t,(function(e){return e.duration>0&&e.time+e.duration>r}));if(void 0===i)return!0;var a=performance.now(),o=i.progress.length>0?i.progress[i.progress.length-1]:void 0,s=Et(i);if(void 0===o||void 0===s)return!0;var u=wt(o,s);return(a-o.timestamp)/1e3>1.2*u||u-n/e.speed>-1.5}(r,n))},e}(),At=n(1679),xt=function(){function e(){this._currentRequests={}}var t=e.prototype;return t.add=function(e){var t=e.id,n=e.time,r=e.duration,i=e.requestTimestamp;this._currentRequests[t]={time:n,duration:r,requestTimestamp:i,progress:[]}},t.addProgress=function(e){var t=this._currentRequests[e.id];null!=t?t.progress.push(e):O.Z.warn("ABR: progress for a request not added")},t.remove=function(e){null==this._currentRequests[e]&&O.Z.warn("ABR: can't remove unknown request"),delete this._currentRequests[e]},t.getRequests=function(){return(0,At.Z)(this._currentRequests).filter((function(e){return null!=e})).sort((function(e,t){return e.time-t.time}))},e}(),It=function(){function e(){this._currentRepresentationData=null,this._lastRepresentationWithGoodScore=null}var t=e.prototype;return t.addSample=function(e,t,n){var r,i=n/t,a=this._getEWMA(e);null!=a?(r=a,a.addSample(t,i)):((r=new tt(5)).addSample(t,i),this._currentRepresentationData={representation:e,ewma:r}),r.getEstimate()>1&&this._lastRepresentationWithGoodScore!==e&&(O.Z.debug("ABR: New last stable representation",e),this._lastRepresentationWithGoodScore=e)},t.getEstimate=function(e){var t=this._getEWMA(e);if(null!=t)return t.getEstimate()},t.getLastStableRepresentation=function(){return this._lastRepresentationWithGoodScore},t._getEWMA=function(e){return null!=this._currentRepresentationData&&this._currentRepresentationData.representation.id===e.id?this._currentRepresentationData.ewma:null},e}();function Zt(e,t,n,r){var i=t<=n?n:t>=r?r:t,a=(0,Ce.Z)(e,(function(e){return e.bitrate>i}));return-1===a?e[e.length-1]:0===a?e[0]:e[a-1]}function Rt(e,t){var n=e;return null!=t.bitrate&&(n=function(e,t){if(0===e.length)return[];e.sort((function(e,t){return e.bitrate-t.bitrate}));var n=e[0].bitrate,r=Math.max(t,n),i=(0,Ce.Z)(e,(function(e){return e.bitrate>r}));return-1===i?e:e.slice(0,i)}(n,t.bitrate)),null!=t.width&&(n=function(e,t){var n=e.slice().sort((function(e,t){return(0,et.Z)(e.width,0)-(0,et.Z)(t.width,0)})),r=(0,mt.Z)(n,(function(e){return"number"==typeof e.width&&e.width>=t}));if(void 0===r)return e;var i="number"==typeof r.width?r.width:0;return e.filter((function(e){return"number"!=typeof e.width||e.width<=i}))}(n,t.width)),n}function Mt(e){var t=e.bandwidthEstimator,n=e.clock$,r=e.filters$,i=e.initialBitrate,a=e.lowLatencyMode,o=e.manualBitrate$,s=e.minAutoBitrate$,u=e.maxAutoBitrate$,c=e.representations,p=e.streamEvents$,h=new It,m=new kt(null==i?0:i,a),g=new xt,y=vt();var _=p.pipe((0,T.h)((function(e){return"metrics"===e.type})),(0,Pe.b)((function(e){return function(e){var n=e.duration,r=e.size,i=e.content;if(!y(i,n)){t.addSample(n,r);var a=n/1e3,o=i.segment.duration,s=i.representation;h.addSample(s,a,o)}}(e.value)})),(0,ie.l)()),b=p.pipe((0,Pe.b)((function(e){switch(e.type){case"requestBegin":g.add(e.value);break;case"requestEnd":g.remove(e.value.id);break;case"progress":g.addProgress(e.value)}})),(0,ie.l)()),E=p.pipe((0,T.h)((function(e){return"representationChange"===e.type})),(0,v.U)((function(e){return e.value.representation})),(0,w.O)(null)),S=(0,J.P)((function(){if(0===c.length)throw new Error("ABRManager: no representation choice given");return 1===c.length?(0,l.of)({bitrate:void 0,representation:c[0],manual:!1,urgent:!0,knownStableBitrate:void 0}):o.pipe((0,Qe.w)((function(e){if(e>=0){var i=Zt(c,e,0,1/0);return(0,l.of)({representation:i,bitrate:void 0,knownStableBitrate:void 0,manual:!0,urgent:!0})}var a,o=!0,f=pt(p.pipe((0,T.h)((function(e){return"added-segment"===e.type})),lt(n),(0,v.U)((function(e){var t=e[0].value,n=e[1],r=n.speed,i=n.position,a=t.buffered,o=(0,X.L7)(a,i),s=t.content.representation,u=h.getEstimate(s);return{bufferGap:o,currentBitrate:s.bitrate,currentScore:u,speed:r}}))),c.map((function(e){return e.bitrate}))).pipe((0,w.O)(void 0));return(0,d.aj)([n,s,u,r,f]).pipe(lt(E),(0,v.U)((function(e){var n=e[0],r=n[0],i=n[1],s=n[2],u=n[3],l=n[4],d=e[1],f=Rt(c,u),p=g.getRequests(),v=m.getBandwidthEstimate(r,t,d,p,a),y=v.bandwidthEstimate,_=v.bitrateChosen;a=y;var b=h.getLastStableRepresentation(),T=null==b?void 0:b.bitrate/(r.speed>0?r.speed:1),E=r.bufferGap;!o&&E<=5?o=!0:o&&isFinite(E)&&E>10&&(o=!1);var w=Zt(f,_,i,s);if(o)return O.Z.debug("ABR: Choosing representation with bandwidth estimation.",w),{bitrate:y,representation:w,urgent:m.isUrgent(w.bitrate,d,p,r),manual:!1,knownStableBitrate:T};if(null==l||w.bitrate>=l)return O.Z.debug("ABR: Choosing representation with bandwidth estimation.",w),{bitrate:y,representation:w,urgent:m.isUrgent(w.bitrate,d,p,r),manual:!1,knownStableBitrate:T};var S=Zt(f,l,i,s);return l<=s&&O.Z.debug("ABR: Choosing representation with buffer based bitrate ceiling.",S),{bitrate:y,representation:S,urgent:m.isUrgent(l,d,p,r),manual:!1,knownStableBitrate:T}})))})))}));return(0,f.T)(_,b,S)}const Ct=function(){function e(e){this._manualBitrates=e.manualBitrates,this._minAutoBitrates=e.minAutoBitrates,this._maxAutoBitrates=e.maxAutoBitrates,this._initialBitrates=e.initialBitrates,this._throttlers=e.throttlers,this._bandwidthEstimators={},this._lowLatencyMode=e.lowLatencyMode}var t=e.prototype;return t.get$=function(e,t,n,r){var i,a,o,s,u=this._getBandwidthEstimator(e),c=(0,et.Z)(this._manualBitrates[e],(0,l.of)(-1)),f=(0,et.Z)(this._minAutoBitrates[e],(0,l.of)(0)),p=(0,et.Z)(this._maxAutoBitrates[e],(0,l.of)(1/0)),h=(0,et.Z)(this._initialBitrates[e],0);return Mt({bandwidthEstimator:u,streamEvents$:r,clock$:n,filters$:(i=this._throttlers.limitWidth[e],a=this._throttlers.throttleBitrate[e],o=this._throttlers.throttle[e],s=[],null!=i&&s.push(i.pipe((0,v.U)((function(e){return{width:e}})))),null!=o&&s.push(o.pipe((0,v.U)((function(e){return{bitrate:e}})))),null!=a&&s.push(a.pipe((0,v.U)((function(e){return{bitrate:e}})))),s.length>0?(0,d.aj)(s).pipe((0,v.U)((function(e){return Y.Z.apply(void 0,[{}].concat(e))}))):(0,l.of)({})),initialBitrate:h,manualBitrate$:c,minAutoBitrate$:f,maxAutoBitrate$:p,representations:t,lowLatencyMode:this._lowLatencyMode})},t._getBandwidthEstimator=function(e){var t=this._bandwidthEstimators[e];if(null==t){O.Z.debug("ABR: Creating new BandwidthEstimator for ",e);var n=new ot;return this._bandwidthEstimators[e]=n,n}return t},e}();var Nt=n(4507),Pt=n(5767),Ot=n(3774),Dt=n(6923),Lt=M.ym;function Bt(e,t,n){if(null!==t&&"closed"!==t.readyState){for(var r=t.readyState,i=t.sourceBuffers,a=i.length-1;a>=0;a--){var o=i[a];try{"open"===r&&(O.Z.info("Init: Removing SourceBuffer from mediaSource",o),o.abort()),t.removeSourceBuffer(o)}catch(e){O.Z.warn("Init: Error while disposing SourceBuffer",e)}}i.length>0&&O.Z.warn("Init: Not all SourceBuffers could have been removed.")}if((0,Pt.Z)(e),null!==n)try{O.Z.debug("Init: Revoking previous URL"),URL.revokeObjectURL(n)}catch(e){O.Z.warn("Init: Error while revoking the media source URL",e)}}function Ut(e){return function(e){return new Me.y((function(t){if(null==Ot.JJ)throw new B.Z("MEDIA_SOURCE_NOT_SUPPORTED","No MediaSource Object was found in the current browser.");var n=(0,Dt.Z)(e.src)?e.src:null;Bt(e,null,n),O.Z.info("Init: Creating MediaSource");var r=new Ot.JJ,i=URL.createObjectURL(r);return O.Z.info("Init: Attaching MediaSource URL to the media element",i),e.src=i,t.next(r),function(){Bt(e,r,i)}}))}(e).pipe((0,g.zg)((function(e){return Lt(e).pipe((0,S.q)(1),(0,k.h)(e))})))}var Ft=n(8343),zt=L.Z.DEFAULT_LIVE_GAP;var Kt=n(4944),Vt=n(6564),Wt=n(7027);var Gt=n(6968),Ht=n(2870),$t=n(4123),jt=L.Z.SOURCE_BUFFER_FLUSHING_INTERVAL;const Yt=function(e){function n(t,n,r){var a;a=e.call(this)||this;var o=r.addSourceBuffer(n);return a._destroy$=new i.xQ,a.bufferType=t,a._mediaSource=r,a._sourceBuffer=o,a._queue=[],a._pendingTask=null,a._lastInitSegment=null,a.codec=n,(0,Vt.F)(jt).pipe((0,Pe.b)((function(){return a._flush()})),(0,h.R)(a._destroy$)).subscribe(),(0,Wt.R)(a._sourceBuffer,"error").pipe((0,Pe.b)((function(e){return a._onPendingTaskError(e)})),(0,h.R)(a._destroy$)).subscribe(),(0,Wt.R)(a._sourceBuffer,"updateend").pipe((0,Pe.b)((function(){return a._flush()})),(0,h.R)(a._destroy$)).subscribe(),a}(0,t.Z)(n,e);var r=n.prototype;return r.pushChunk=function(e){return O.Z.debug("AVSB: receiving order to push data to the SourceBuffer",this.bufferType,e),this._addToQueue({type:$t.f.Push,value:e})},r.removeBuffer=function(e,t){return O.Z.debug("AVSB: receiving order to remove data from the SourceBuffer",this.bufferType,e,t),this._addToQueue({type:$t.f.Remove,value:{start:e,end:t}})},r.endOfSegment=function(e){return O.Z.debug("AVSB: receiving order for validating end of segment",this.bufferType,e.segment),this._addToQueue({type:$t.f.EndOfSegment,value:e})},r.getBufferedRanges=function(){return this._sourceBuffer.buffered},r.getPendingOperations=function(){var e=function(e){switch(e.type){case $t.f.Push:case $t.f.Remove:case $t.f.EndOfSegment:return{type:e.type,value:e.value}}},t=this._queue.map(e);return null===this._pendingTask?t:[e(this._pendingTask)].concat(t)},r.dispose=function(){for(this._destroy$.next(),this._destroy$.complete(),null!==this._pendingTask&&(this._pendingTask.subject.complete(),this._pendingTask=null);this._queue.length>0;){var e=this._queue.shift();void 0!==e&&e.subject.complete()}if("open"===this._mediaSource.readyState)try{this._sourceBuffer.abort()}catch(e){O.Z.warn("AVSB: Failed to abort a "+this.bufferType+" SourceBuffer:",e)}},r._onPendingTaskError=function(e){if(this._lastInitSegment=null,null!==this._pendingTask){var t=e instanceof Error?e:new Error("An unknown error occured when doing operations on the SourceBuffer");this._pendingTask.subject.error(t)}},r._addToQueue=function(e){var t=this;return new Me.y((function(n){var r=0===t._queue.length&&null===t._pendingTask,a=new i.xQ,o=(0,Y.Z)({subject:a},e);t._queue.push(o);var s=a.subscribe(n);return r&&t._flush(),function(){s.unsubscribe();var e=t._queue.indexOf(o);e>=0&&t._queue.splice(e,1)}}))},r._flush=function(){if(!this._sourceBuffer.updating){if(null!==this._pendingTask){var e=this._pendingTask;if(e.type!==$t.f.Push||0===e.data.length){switch(e.type){case $t.f.Push:null!==e.inventoryData&&this._segmentInventory.insertChunk(e.inventoryData);break;case $t.f.EndOfSegment:this._segmentInventory.completeSegment(e.value);break;case $t.f.Remove:this.synchronizeInventory();break;default:(0,De.Z)(e)}var t=e.subject;return this._pendingTask=null,t.next(),t.complete(),void this._flush()}}else{var n=this._queue.shift();if(void 0===n)return;if(n.type!==$t.f.Push)this._pendingTask=n;else{var r,i=n.value;try{r=this._preparePushOperation(i.data)}catch(e){this._pendingTask=(0,Y.Z)({data:[],inventoryData:i.inventoryInfos},n);var a=e instanceof Error?e:new Error("An unknown error occured when preparing a push operation");return this._lastInitSegment=null,void n.subject.error(a)}this._pendingTask=(0,Y.Z)({data:r,inventoryData:i.inventoryInfos},n)}}try{switch(this._pendingTask.type){case $t.f.EndOfSegment:return O.Z.debug("AVSB: Acknowledging complete segment",this._pendingTask.value),void this._flush();case $t.f.Push:var o=this._pendingTask.data.shift();if(void 0===o)return void this._flush();this._sourceBuffer.appendBuffer(o);break;case $t.f.Remove:var s=this._pendingTask.value,u=s.start,l=s.end;O.Z.debug("AVSB: removing data from SourceBuffer",this.bufferType,u,l),this._sourceBuffer.remove(u,l);break;default:(0,De.Z)(this._pendingTask)}}catch(e){this._onPendingTaskError(e)}}},r._preparePushOperation=function(e){var t=[],n=e.codec,r=e.timestampOffset,i=e.appendWindow,a=!1;if(n!==this.codec&&(O.Z.debug("AVSB: updating codec",n),(a=function(e,t){if("function"==typeof e.changeType){try{e.changeType(t)}catch(e){return O.Z.warn("Could not call 'changeType' on the given SourceBuffer:",e),!1}return!0}return!1}(this._sourceBuffer,n))?this.codec=n:O.Z.debug("AVSB: could not update codec",n,this.codec)),this._sourceBuffer.timestampOffset!==r){var o=r;O.Z.debug("AVSB: updating timestampOffset",this.bufferType,this._sourceBuffer.timestampOffset,o),this._sourceBuffer.timestampOffset=o}if(void 0===i[0]?this._sourceBuffer.appendWindowStart>0&&(this._sourceBuffer.appendWindowStart=0):i[0]!==this._sourceBuffer.appendWindowStart&&(i[0]>=this._sourceBuffer.appendWindowEnd&&(this._sourceBuffer.appendWindowEnd=i[0]+1),this._sourceBuffer.appendWindowStart=i[0]),void 0===i[1]?this._sourceBuffer.appendWindowEnd!==1/0&&(this._sourceBuffer.appendWindowEnd=1/0):i[1]!==this._sourceBuffer.appendWindowEnd&&(this._sourceBuffer.appendWindowEnd=i[1]),null!==e.initSegment&&(a||!this._isLastInitSegment(e.initSegment))){var s=e.initSegment;t.push(s);var u=(0,Gt._f)(s);this._lastInitSegment={data:u,hash:(0,Ht.Z)(u)}}return null!==e.chunk&&t.push(e.chunk),t},r._isLastInitSegment=function(e){if(null===this._lastInitSegment)return!1;if(this._lastInitSegment.data===e)return!0;var t=this._lastInitSegment.data;if(t.byteLength===e.byteLength){var n=(0,Gt._f)(e);if((0,Ht.Z)(n)===this._lastInitSegment.hash&&(0,G.Z)(t,n))return!0}return!1},n}($t.C);var qt=["audio","video","text","image"];function Xt(e){return"audio"===e||"video"===e}const Qt=function(){function e(e,t){this._mediaElement=e,this._mediaSource=t,this._initializedSegmentBuffers={},this._onNativeBufferAddedOrDisabled=[]}e.isNative=function(e){return Xt(e)};var t=e.prototype;return t.getBufferTypes=function(){var e=this.getNativeBufferTypes();return null==V.Z.nativeTextTracksBuffer&&null==V.Z.htmlTextTracksBuffer||e.push("text"),null!=V.Z.imageBuffer&&e.push("image"),e},t.getNativeBufferTypes=function(){return"AUDIO"===this._mediaElement.nodeName?["audio"]:["video","audio"]},t.getStatus=function(e){var t=this._initializedSegmentBuffers[e];return void 0===t?{type:"uninitialized"}:null===t?{type:"disabled"}:{type:"initialized",value:t}},t.waitForUsableBuffers=function(){var e=this;return this._areNativeBuffersUsable()?(0,l.of)(void 0):new Me.y((function(t){e._onNativeBufferAddedOrDisabled.push((function(){e._areNativeBuffersUsable()&&(t.next(void 0),t.complete())}))}))},t.disableSegmentBuffer=function(t){var n=this._initializedSegmentBuffers[t];if(null!==n){if(void 0!==n)throw new Error("Cannot disable an active SegmentBuffer.");this._initializedSegmentBuffers[t]=null,e.isNative(t)&&this._onNativeBufferAddedOrDisabled.forEach((function(e){return e()}))}else O.Z.warn("SBS: The "+t+" SegmentBuffer was already disabled.")},t.createSegmentBuffer=function(e,t,n){void 0===n&&(n={});var r,i=this._initializedSegmentBuffers[e];if(Xt(e)){if(null!=i)return i instanceof Yt&&i.codec!==t?O.Z.warn("SB: Reusing native SegmentBuffer with codec",i.codec,"for codec",t):O.Z.info("SB: Reusing native SegmentBuffer with codec",t),i;O.Z.info("SB: Adding native SegmentBuffer with codec",t);var a=new Yt(e,t,this._mediaSource);return this._initializedSegmentBuffers[e]=a,this._onNativeBufferAddedOrDisabled.forEach((function(e){return e()})),a}if(null!=i)return O.Z.info("SB: Reusing a previous custom SegmentBuffer for the type",e),i;if("text"===e){if(O.Z.info("SB: Creating a new text SegmentBuffer"),"html"===n.textTrackMode){if(null==V.Z.htmlTextTracksBuffer)throw new Error("HTML Text track feature not activated");r=new V.Z.htmlTextTracksBuffer(this._mediaElement,n.textTrackElement)}else{if(null==V.Z.nativeTextTracksBuffer)throw new Error("Native Text track feature not activated");r=new V.Z.nativeTextTracksBuffer(this._mediaElement,!0===n.hideNativeSubtitle)}return this._initializedSegmentBuffers.text=r,r}if("image"===e){if(null==V.Z.imageBuffer)throw new Error("Image buffer feature not activated");return O.Z.info("SB: Creating a new image SegmentBuffer"),r=new V.Z.imageBuffer,this._initializedSegmentBuffers.image=r,r}throw O.Z.error("SB: Unknown buffer type:",e),new B.Z("BUFFER_TYPE_UNKNOWN","The player wants to create a SegmentBuffer of an unknown type.")},t.disposeSegmentBuffer=function(e){var t=this._initializedSegmentBuffers[e];null!=t?(O.Z.info("SB: Aborting SegmentBuffer",e),t.dispose(),delete this._initializedSegmentBuffers[e]):O.Z.warn("SB: Trying to dispose a SegmentBuffer that does not exist")},t.disposeAll=function(){var e=this;qt.forEach((function(t){"initialized"===e.getStatus(t).type&&e.disposeSegmentBuffer(t)}))},t._areNativeBuffersUsable=function(){var e=this,t=this.getNativeBufferTypes();return!t.some((function(t){return void 0===e._initializedSegmentBuffers[t]}))&&!t.every((function(t){return null===e._initializedSegmentBuffers[t]}))},e}();var Jt=function(){function e(e){this._array=[],this._sortingFn=e}var t=e.prototype;return t.add=function(){for(var e=arguments.length,t=new Array(e),n=0;n=this._array.length)throw new Error("Invalid index.");return this._array[e]},t.findFirst=function(e){return(0,mt.Z)(this._array,e)},t.has=function(e){return(0,Oe.Z)(this._array,e)},t.removeElement=function(e){var t=this._array.indexOf(e);if(t>=0)return this._array.splice(t,1),t},t.head=function(){return this._array[0]},t.last=function(){return this._array[this._array.length-1]},t.shift=function(){return this._array.shift()},t.pop=function(){return this._array.pop()},e}(),en=function(){function e(e){this._weakMap=new WeakMap,this._fn=e}var t=e.prototype;return t.get=function(e){var t=this._weakMap.get(e);if(void 0===t){var n=this._fn(e);return this._weakMap.set(e,n),n}return t},t.destroy=function(e){this._weakMap.delete(e)},e}(),tn=n(2257);function nn(e){var t=e.segmentBuffer,n=e.clock$,r=e.maxBufferBehind$,i=e.maxBufferAhead$;return(0,d.aj)([n,r,i]).pipe((0,g.zg)((function(e){var n=e[0],r=e[1],i=e[2];return function(e,t,n,r){if(!isFinite(n)&&!isFinite(r))return p.E;var i=[],a=(0,X.F_)(e.getBufferedRanges(),t),o=a.innerRange,s=a.outerRanges,u=function(){if(isFinite(r)){for(var e=0;en.start&&i.push({start:t+r,end:n.end})}null!=o&&t+r=r.end?i.push(r):t>=r.end&&t-n>r.start&&t-no.start&&i.push({start:o.start,end:t-n})}}(),u(),(0,je.D)(i.map((function(t){return O.Z.debug("GC: cleaning range from SegmentBuffer",t),e.removeBuffer(t.start,t.end)}))).pipe((0,tn.u)(),(0,ie.l)())}(t,n,r,i)})))}const rn={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,n){return{type:"needs-media-source-reload",value:{position:t,autoPlay:n,period:e}}},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){return{type:"encryption-data-encountered",value: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}}};var an=n(7473),on=n.n(an);var sn=function(){function e(e,t){this.predicate=e,this.inclusive=t}return e.prototype.call=function(e,t){return t.subscribe(new un(e,this.predicate,this.inclusive))},e}(),un=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.predicate=n,i.inclusive=r,i.index=0,i}return o.ZT(t,e),t.prototype._next=function(e){var t,n=this.destination;try{t=this.predicate(e,this.index++)}catch(e){return void n.error(e)}this.nextOrComplete(e,t)},t.prototype.nextOrComplete=function(e,t){var n=this.destination;Boolean(t)?n.next(e):(this.inclusive&&n.next(e),n.complete())},t}(A.L);function ln(e,t,n,r,i){var a=e.period,o=e.adaptation,s=e.representation,u=function(e,t){for(var n=0;n=t.end)return null;if(r.bufferedEnd>t.start)return n}return null}(i,t);if(null===u){if(null===n){if(r&&void 0!==a.end&&t.end>=a.end)return{start:void 0,end:null};var l=s.index.checkDiscontinuity(t.start);if(null!==l)return{start:void 0,end:l}}return null}var d=i[u];if(void 0!==d.bufferedStart&&d.bufferedStart>t.start&&(null===n||d.infos.segment.end<=n))return O.Z.debug("RS: current discontinuity encountered",o.type,d.bufferedStart),{start:void 0,end:d.bufferedStart};var c=function(e,t,n){if(n<=0)return O.Z.error("RS: Asked to check a discontinuity before the first chunk."),null;for(var r=n;r=t.end)return null;if(i.bufferedStart-a.bufferedEnd>0)return r}return null}(i,t,u+1);if(null!==c&&(null===n||i[c].infos.segment.end<=n)){var f=i[c-1].bufferedEnd,p=i[c].bufferedStart;return O.Z.debug("RS: future discontinuity encountered",o.type,f,p),{start:f,end:p}}if(null===n){if(r&&void 0!==a.end){if(t.end=0;n--){var r=e[n];if(void 0===r.bufferedStart)return null;if(r.bufferedStart=a.end)return null;for(var m=i.length-1;m>=0;m--){var g=i[m];if(void 0===g.bufferedStart)break;if(g.bufferedStart=n.length-1?null:n[t+1];return!function(e,t,n){if(void 0===e.bufferedStart)return O.Z.warn("Stream: Start of a segment unknown. Assuming it is garbage collected by default.",e),!0;if(null!==t&&void 0!==t.bufferedEnd&&e.bufferedStart-t.bufferedEnd<.1)return!1;if(npn)return O.Z.info("Stream: The start of the wanted segment has been garbage collected",e),!0;return!1}(e,r,i.start)&&!function(e,t,n){if(void 0===e.bufferedEnd)return O.Z.warn("Stream: End of a segment unknown. Assuming it is garbage collected by default.",e),!0;if(null!==t&&void 0!==t.bufferedStart&&t.bufferedStart-e.bufferedEnd<.1)return!1;if(n>e.bufferedEnd&&e.end-e.bufferedEnd>pn)return O.Z.info("Stream: The end of the wanted segment has been garbage collected",e),!0;return!1}(e,a,i.end)}));return s.filter((function(e){var i=(0,Y.Z)({segment:e},t);if(a.length>0&&a.some((function(e){return(0,dn.Z)(i,e)})))return!1;var o=e.duration,s=e.time,l=e.end;if(e.isInit)return!0;if(o0&&a.some((function(e){if(e.period.id!==t.period.id||e.adaptation.id!==t.adaptation.id)return!1;var a=e.segment;return!(a.time-vn>s)&&(!(a.end+vn-vn&&f.end-l>-vn)return!1}}for(var p=0;ps)return h.start>s+vn||gn(u,p).ende[n].start;)n++;return e[--n]}function yn(e,t,n,r){return e.period.id===t.period.id&&(!(e.segment.timei}return rr}(e.representation,t.representation,r)))}var _n=L.Z.SEGMENT_PRIORITIES_STEPS;function bn(e,t){for(var n=e-(t.position+t.wantedTimeOffset),r=0;r<_n.length;r++)if(n<_n[r])return r;return _n.length}var Tn=L.Z.MINIMUM_SEGMENT_SIZE;function En(e,t,n,r,i){var a,o=e.period,s=e.representation;i.synchronizeInventory();var u,l,d=t.position+t.wantedTimeOffset,c=d+r,f={start:Math.max(d,o.start),end:Math.min(c,null!==(a=o.end)&&void 0!==a?a:1/0)},p=s.index.shouldRefresh(d,c),h=i.getPendingOperations().filter((function(e){return e.type===$t.f.EndOfSegment})).map((function(e){return e.value})),v=function(e,t){for(var n=Math.max(1/60,Tn),r=e.start+n,i=e.end-n,a=[],o=t.length-1;o>=0;o--){var s=t[o],u=s.infos.representation;if(!s.partiallyPushed&&!1!==u.decipherable&&u.isSupported){var l=s.infos.segment,d=l.time/l.timescale;((null==l.duration?s.end:d+l.duration/l.timescale)>r&&dr&&s.start0)u=!1;else if(void 0===g)u=f.end>=o.end&&s.index.isFinished();else if(null===g)u=s.index.isFinished();else{var y=void 0!==o.end?Math.min(o.end,g):g;u=f.end>=y&&s.index.isFinished()}if(s.index.isInitialized()&&(s.index.areSegmentsChronologicallyGenerated()||u)){var _=null;h.length>0&&(_=Math.min.apply(Math,h.map((function(e){return e.segment.time})))),m.length>0&&(_=null!==_?Math.min(_,m[0].segment.time):m[0].segment.time),l=ln(e,f,_,u,v)}else l=null;return{imminentDiscontinuity:l,hasFinishedLoading:u,neededSegments:m,shouldRefreshManifest:p}}var wn=L.Z.BUFFER_GC_GAPS.CALM,Sn=L.Z.BUFFER_GC_GAPS.BEEFY;function kn(e,t,n){for(var r=(0,X.F_)(t,e),i=r.innerRange,a=r.outerRanges,o=[],s=0;su.start)&&o.push(u)}return null!=i&&(O.Z.debug("Stream: GC removing part of inner range",o),e-n>i.start&&o.push({start:i.start,end:e-n}),e+n0&&null!==Z&&null===R){var p=f[0].priority;f.unshift({segment:Z,priority:p})}}else null===Z?O.Z.warn("Stream: Uninitialized index without an initialization segment"):null!==R?O.Z.warn("Stream: Uninitialized index with an already loaded initialization segment"):f.unshift({segment:Z,priority:bn(_.start,n)});var h=f[0];if(null!==i){if(M=[],i.urgent)return O.Z.debug("Stream: urgent termination request, terminate.",I),C.next(),C.complete(),(0,l.of)(rn.streamTerminating());if(null===P||void 0===h||P.segment.id!==h.segment.id)return O.Z.debug("Stream: cancel request and terminate.",null===P,I),C.next(),C.complete(),(0,l.of)(rn.streamTerminating());if(P.priority!==h.priority){var v=P.request$;P.priority=h.priority,u.updatePriority(v,h.priority)}O.Z.debug("Stream: terminate after request.",I)}else if(void 0===h)null!==P&&O.Z.debug("Stream: interrupt segment request.",I),M=[],C.next();else if(null===P)O.Z.debug("Stream: start downloading queue.",I),M=f,C.next();else if(P.segment.id!==h.segment.id)O.Z.debug("Stream: restart download queue.",I),M=f,C.next();else if(P.priority!==h.priority){O.Z.debug("Stream: update request priority.",I);var m=P.request$;P.priority=h.priority,u.updatePriority(m,h.priority)}else O.Z.debug("Stream: update downloading queue",I),M=f.slice().splice(1,f.length);var g=(0,l.of)({type:"stream-status",value:{period:_,position:n.position,bufferType:I,imminentDiscontinuity:d.imminentDiscontinuity,hasFinishedLoading:d.hasFinishedLoading,neededSegments:d.neededSegments}});return d.shouldRefreshManifest?(0,c.z)((0,l.of)(rn.needsManifestRefresh()),g):g})),(t=function(e){return"stream-terminating"!==e.type},void 0===(n=!0)&&(n=!1),function(e){return e.lift(new sn(t,n))})),L=!1,B=p.E;if(void 0!==A){var U=T.getEncryptionData(A);U.length>0&&(B=l.of.apply(void 0,U.map((function(e){return rn.encryptionDataEncountered(e)}))),L=!0)}var F=C.pipe((0,Qe.w)((function(){return M.length>0?(e=(0,J.P)((function(){var t=M.shift();if(void 0===t)return on()((function(){N.next()})),p.E;var n=t.segment,r=t.priority,i={manifest:y,period:_,adaptation:b,representation:T,segment:n},a=u.createRequest(i,r);return P={segment:n,priority:r,request$:a},a.pipe((0,g.zg)((function(t){switch(t.type){case"warning":return(0,l.of)({type:"retry",value:{segment:n,error:t.value}});case"chunk-complete":return P=null,(0,l.of)({type:"end-of-segment",value:{segment:n}});case"interrupted":return O.Z.info("Stream: segment request interrupted temporarly.",n),p.E;case"chunk":var r=null==R?void 0:R.initTimescale;return t.parse(r).pipe((0,v.U)((function(e){return(0,Y.Z)({segment:n},e)})));case"ended":return e;default:(0,De.Z)(t)}})))}))).pipe(ue((function(){P=null}))):p.E;var e})),(0,g.zg)((function(e){var t;switch(e.type){case"retry":return(0,c.z)((0,l.of)({type:"warning",value:e.value.error}),(0,J.P)((function(){var t=e.value.segment,n=T.index;if(!1===n.isSegmentStillAvailable(t))N.next();else if(n.canBeOutOfSyncError(e.value.error,t))return(0,l.of)(rn.manifestMightBeOufOfSync());return p.E})));case"parsed-init-segment":R=e.value;var n=T.getAllEncryptionData(),i=!L&&n.length>0?l.of.apply(void 0,n.map((function(e){return rn.encryptionDataEncountered(e)}))):p.E,a=function(e){var t=e.clock$,n=e.content,r=e.segment,i=e.segmentData,a=e.segmentBuffer;return(0,J.P)((function(){if(null===i)return p.E;var e=n.representation.getMimeTypeString();return An(t,a,{data:{initSegment:i,chunk:null,timestampOffset:0,appendWindow:[void 0,void 0],codec:e},inventoryInfos:null}).pipe((0,v.U)((function(){var e=a.getBufferedRanges();return rn.addedSegment(n,r,e,i)})))}))}({clock$:r,content:o,segment:e.segment,segmentData:e.value.initializationData,segmentBuffer:s});return(0,f.T)(i,a);case"parsed-segment":var u=null!==(t=null==R?void 0:R.initializationData)&&void 0!==t?t:null,d=e.value,h=d.inbandEvents,m=!0===d.needsManifestRefresh?(0,l.of)(rn.needsManifestRefresh()):p.E,g=void 0!==h&&h.length>0?(0,l.of)({type:"inband-events",value:h}):p.E;return(0,c.z)(m,g,function(e){var t=e.clock$,n=e.content,r=e.initSegmentData,i=e.parsedSegment,a=e.segment,o=e.segmentBuffer;return(0,J.P)((function(){var e,s;if(null===i.chunkData)return p.E;var u=i.chunkData,l=i.chunkInfos,d=i.chunkOffset,c=i.appendWindow,f=n.representation.getMimeTypeString(),h=[void 0!==c[0]?Math.max(0,c[0]-xn.START):void 0,void 0!==c[1]?c[1]+xn.END:void 0],m={initSegment:r,chunk:u,timestampOffset:d,appendWindow:h,codec:f},g=null!==(e=null==l?void 0:l.time)&&void 0!==e?e:a.time,y=g+(null!==(s=null==l?void 0:l.duration)&&void 0!==s?s:a.duration);void 0!==h[0]&&(g=Math.max(g,h[0])),void 0!==h[1]&&(y=Math.min(y,h[1]));var _=(0,Y.Z)({segment:a,start:g,end:y},n);return An(t,o,{data:m,inventoryInfos:_}).pipe((0,v.U)((function(){var e=o.getBufferedRanges();return rn.addedSegment(n,a,e,u)})))}))}({clock$:r,content:o,initSegmentData:u,parsedSegment:e.value,segment:e.segment,segmentBuffer:s}));case"end-of-segment":var y=e.value.segment;return s.endOfSegment((0,Y.Z)({segment:y},o)).pipe((0,ie.l)());default:(0,De.Z)(e)}})));return(0,c.z)(B,(0,f.T)(D,F).pipe((0,E.B)()))};function Zn(e,t,n){return t.pipe((0,S.q)(1),(0,g.zg)((function(r){var i;if(e.start<=r.position&&(void 0===e.end||e.end>r.position)){var a=r.getCurrentTime()+n,o=Math.min(Math.max(e.start,a),null!==(i=e.end)&&void 0!==i?i:1/0);return(0,l.of)(rn.needsMediaSourceReload(e,o,!r.isPaused))}return t.pipe((0,v.U)((function(t){return rn.needsMediaSourceReload(e,t.getCurrentTime(),!t.isPaused)})))})))}var Rn=L.Z.DELTA_POSITION_AFTER_RELOAD;const Mn=function(e){var t=e.abrManager,n=e.clock$,r=e.content,a=e.options,o=e.segmentBuffer,s=e.segmentFetcherCreator,d=e.wantedBufferAhead$,h="direct"===a.manualBitrateSwitchingMode,y=r.manifest,_=r.period,b=r.adaptation,w={},k=function(e,t,n){var r=e.manifest,a=e.adaptation,o=new i.xQ,s=new i.xQ,u=(0,f.T)(o,s);return{estimator$:(0,c.z)((0,l.of)(null),(0,H.R)(r,"decipherabilityUpdate")).pipe((0,v.U)((function(){var e=a.getPlayableRepresentations();if(e.length<=0)throw new B.Z("NO_PLAYABLE_REPRESENTATION","No Representation in the chosen Adaptation can be played");return e})),(0,m.x)((function(e,t){if(e.length!==t.length)return!1;for(var n=0;n=i.end&&(O.Z.debug('Stream: full "empty" AdaptationStream',n),a=!0),(0,l.of)({type:"stream-status",value:{period:i,bufferType:n,position:t.position,imminentDiscontinuity:null,hasFinishedLoading:a,neededSegments:[],shouldRefreshManifest:!1}})})))}var Nn=n(9252);const Pn=function(e,t){var n=e.split(";"),r=n[0],i=n.slice(1),a=t.split(";"),o=a[0],s=a.slice(1);if(r!==o)return!1;var u=(0,mt.Z)(i,(function(e){return(0,Nn.Z)(e,"codecs=")})),l=(0,mt.Z)(s,(function(e){return(0,Nn.Z)(e,"codecs=")}));if(void 0===u||void 0===l)return!1;var d=u.substring(7),c=l.substring(7);return d.split(".")[0]===c.split(".")[0]};var On=L.Z.ADAPTATION_SWITCH_BUFFER_PADDINGS;function Dn(e,t,n,r,i){if(void 0!==e.codec&&"reload"===i.onCodecSwitch&&!Ln(n,e.codec))return{type:"needs-reload",value:void 0};var a=e.getBufferedRanges();if(0===a.length)return{type:"continue",value:void 0};var o=(0,X.JN)(a),s=t.start,u=null==t.end?1/0:t.end,l=(0,X.tn)(o,[{start:s,end:u}]);if(0===l.length)return{type:"continue",value:void 0};e.synchronizeInventory();var d=e.getInventory();if(!d.some((function(e){return e.infos.period.id===t.id&&e.infos.adaptation.id!==n.id})))return{type:"continue",value:void 0};var c=function(e,t,n){return e.reduce((function(e,r){if(r.infos.period.id!==t.id||r.infos.adaptation.id!==n.id)return e;var i=r.bufferedStart,a=r.bufferedEnd;return void 0===i||void 0===a||e.push({start:i,end:a}),e}),[])}(d,t,n),f=(0,X.uH)(l,c);if(0===f.length)return{type:"continue",value:void 0};var p=r.currentTime;if("video"===n.type&&(0,X.Ti)({start:s,end:u},p)&&(r.readyState>1||!n.getPlayableRepresentations().some((function(t){var n;return Pn(t.getMimeTypeString(),null!==(n=e.codec)&&void 0!==n?n:"")})))&&!(0,X.A1)(c,p))return{type:"needs-reload",value:void 0};if("audio"===n.type&&void 0!==e.codec&&"direct"===i.audioTrackSwitchingMode&&(0,X.Ti)({start:s,end:u},p)&&(r.readyState>1||!Ln(n,e.codec))&&!(0,X.A1)(c,p))return{type:"needs-reload",value:void 0};var h=[],v=function(e,t){for(var n=0;n=t.start)return n>0?e[n-1]:null;return e.length>0?e[e.length-1]:null}(d,t);null!==v&&(void 0===v.bufferedEnd||t.start-v.bufferedEnd<1)&&h.push({start:0,end:t.start+1});var m=n.type,g=On[m].before;null==g&&(g=0);var y=On[m].after;if(null==y&&(y=0),h.push({start:p-g,end:p+y}),void 0!==t.end){var _=function(e,t){for(var n=0;nt.start)return e[n];return null}(d,t);null!==_&&(void 0===_.bufferedStart||_.bufferedStart-t.end<1)&&h.push({start:t.end-1,end:Number.MAX_VALUE})}var b=(0,X.uH)(f,h);return b.length>0?{type:"clean-buffer",value:b}:{type:"continue",value:void 0}}function Ln(e,t){return e.getPlayableRepresentations().some((function(e){return Pn(e.getMimeTypeString(),t)}))}var Bn=L.Z.DELTA_POSITION_AFTER_RELOAD;const Un=function(e){var t=e.abrManager,n=e.bufferType,r=e.clock$,i=e.content,o=e.garbageCollectors,s=e.segmentFetcherCreator,u=e.segmentBuffersStore,d=e.options,h=e.wantedBufferAhead$,m=i.period,y=new a.t(1);return y.pipe((0,Qe.w)((function(e,a){var y=0===a?0:"audio"===n?Bn.trackSwitch.audio:"video"===n?Bn.trackSwitch.video:Bn.trackSwitch.other;if(null===e){O.Z.info("Stream: Set no "+n+" Adaptation",m);var _,b=u.getStatus(n);if("initialized"===b.type){if(O.Z.info("Stream: Clearing previous "+n+" SegmentBuffer"),Qt.isNative(n))return Zn(m,r,y);_=b.value.removeBuffer(m.start,null==m.end?1/0:m.end)}else"uninitialized"===b.type&&u.disableSegmentBuffer(n),_=(0,l.of)(null);return(0,c.z)(_.pipe((0,k.h)(rn.adaptationChange(n,null,m))),Cn(r,h,n,{period:m}))}if(Qt.isNative(n)&&"disabled"===u.getStatus(n).type)return Zn(m,r,y);O.Z.info("Stream: Updating "+n+" adaptation",e,m);var T=r.pipe((0,S.q)(1),(0,g.zg)((function(a){var _=function(e,t,n,r){var i=e.getStatus(t);if("initialized"===i.type)return O.Z.info("Stream: Reusing a previous SegmentBuffer for the type",t),i.value;var a=function(e){var t=e.representations;if(null==t[0])return"";return t[0].getMimeTypeString()}(n),o="text"===t?r.textTrackOptions:void 0;return e.createSegmentBuffer(t,a,o)}(u,n,e,d),b={currentTime:a.getCurrentTime(),readyState:a.readyState},T=Dn(_,m,e,b,d);if("needs-reload"===T.type)return Zn(m,r,y);var E="clean-buffer"===T.type?c.z.apply(void 0,T.value.map((function(e){var t=e.start,n=e.end;return _.removeBuffer(t,n)}))).pipe((0,ie.l)()):p.E,w=o.get(_),S=function(e,a){var o=i.manifest,f=r.pipe((0,v.U)((function(e){var t=a.getBufferedRanges();return(0,Y.Z)({},e,{bufferGap:(0,X.L7)(t,e.position)})})));return Mn({abrManager:t,clock$:f,content:{manifest:o,period:m,adaptation:e},options:d,segmentBuffer:a,segmentFetcherCreator:s,wantedBufferAhead$:h}).pipe((0,oe.K)((function(e){if(!Qt.isNative(n)){O.Z.error("Stream: "+n+" Stream crashed. Aborting it.",e),u.disposeSegmentBuffer(n);var t=z(e,{defaultCode:"NONE",defaultReason:"Unknown `AdaptationStream` error"});return(0,c.z)((0,l.of)(rn.warning(t)),Cn(r,h,n,{period:m}))}throw O.Z.error("Stream: "+n+" Stream crashed. Stopping playback.",e),e})))}(e,_);return u.waitForUsableBuffers().pipe((0,g.zg)((function(){return(0,c.z)(E,(0,f.T)(S,w))})))})));return(0,c.z)((0,l.of)(rn.adaptationChange(n,e,m)),T)})),(0,w.O)(rn.periodStreamReady(n,m,y)))};var Fn=n(2807);function zn(){for(var e=arguments.length,t=new Array(e),n=0;nd.getMaximumPosition()){var i=new B.Z("MEDIA_TIME_AFTER_MANIFEST","The current position is after the latest time announced in the Manifest.");return rn.warning(i)}return null}),null)),x=r.getBufferTypes().map((function(e){return function(e,n){var a=new Jt((function(e,t){return e.start-t.start})),o=new i.xQ,s=!1;function u(t){return R(e,t,o).pipe((0,fe.Z)((function(e){switch(e.type){case"needs-media-source-reload":var t=a.head();if(void 0===t||t.id!==e.value.period.id)return null;break;case"periodStreamReady":s=!0,a.add(e.value.period);break;case"periodStreamCleared":a.removeElement(e.value.period)}return e}),null),(0,E.B)())}function h(e){var t=a.head(),n=a.last();return null==t||null==n||(t.start>e||(null==n.end?1/0:n.end)=s.end}))),y=p.pipe(Ye((function(t){return R(e,t,v)}))),_=u.pipe((0,S.q)(1),(0,Pe.b)((function(){p.complete(),v.next(),v.complete()})),(0,E.B)()),b=(0,f.T)(m,_),A=Un({abrManager:n,bufferType:e,clock$:t,content:{manifest:d,period:s},garbageCollectors:k,segmentFetcherCreator:a,segmentBuffersStore:r,options:o,wantedBufferAhead$:w}).pipe((0,g.zg)((function(t){if("stream-status"===t.type)if(t.value.hasFinishedLoading){var n=d.getPeriodAfter(s);if(null===n)return(0,c.z)((0,l.of)(t),(0,l.of)(rn.streamComplete(e)));p.next(n)}else v.next();return(0,l.of)(t)})),(0,E.B)()),x=(0,c.z)(A.pipe((0,h.R)(b)),(0,l.of)(rn.periodStreamCleared(e,s)).pipe((0,Pe.b)((function(){O.Z.info("SO: Destroying Stream for",e,s)}))));return(0,f.T)(x,y,_.pipe((0,ie.l)()))}};var Gn=n(8821),Hn=n(6565);var $n=function(){function e(e){if(this.total=e,this.total<0)throw new Hn.W}return e.prototype.call=function(e,t){return t.subscribe(new jn(e,this.total))},e}(),jn=function(e){function t(t,n){var r=e.call(this,t)||this;return r.total=n,r.ring=new Array,r.count=0,r}return o.ZT(t,e),t.prototype._next=function(e){var t=this.ring,n=this.total,r=this.count++;t.length0)for(var n=this.count>=this.total?this.total:this.count,r=this.ring,i=0;i0&&void 0!==e[0].period.end&&e[0].period.end+10r.start)return ar(t)&&e.splice(a,0,t),e;ar(t)&&e.push(t);return e}(e,t[0],t[1])}),[])),o=null,s=null;return e.pipe(lt(a),(0,v.U)((function(e){var r=e[0],a=e[1],u=r.buffered,l=r.currentRange,d=r.position,c=r.event,f=r.stalled;if(null===f)return{type:"unstalled",value:null};if(r.seeking)o=r.position;else if(null!==o){var p=performance.now();if(null===s&&(s=p),er&&r.positionn)return r;var o=void 0;if(void 0===a.end||a.end>n){var s=e[i],u=s.discontinuity,l=s.position,d=u.start,c=u.end;if(n>=(null!=d?d:l)-rr)if(null===c){var f=t.getPeriodAfter(a);null!==f?o=f.start+rr:O.Z.warn("Init: discontinuity at Period's end but no next Period")}else no?r:o)}}return r}(a,n,h);if(null!==v){var m=v+.001;if(!(m<=t.currentTime))return O.Z.warn("SA: skippable discontinuity found in the stream",d,m),i(m),rn.warning(or(h,m));O.Z.info("Init: position to seek already reached, no seeking",t.currentTime,m)}}if(function(e,t,n,r){return P.vU&&r&&"timeupdate"===n&&null!=t&&t.end-e>10}(d,l,c,null!==f))return O.Z.warn("Init: After freeze seek",d,l),i(d),rn.warning(or(d,d));var g=null!=h?h:d,y=(0,X.XS)(u,g);if(y=0;b--){var T=n.periods[b];if(void 0!==T.end&&T.end<=g){if(n.periods[b+1].start>g&&n.periods[b+1].start>t.currentTime){var E=n.periods[b+1];return i(E.start),rn.warning(or(g,E.start))}break}}return{type:"stalled",value:f}})))}function ar(e){return null!==e.discontinuity}function or(e,t){return new B.Z("DISCONTINUITY_ENCOUNTERED","A discontinuity has been encountered at position "+String(e)+", seeked at position "+String(t))}var sr=function(){function e(){}return e.prototype.call=function(e,t){return t.subscribe(new ur(e))},e}(),ur=function(e){function t(t){var n=e.call(this,t)||this;return n.hasPrev=!1,n}return o.ZT(t,e),t.prototype._next=function(e){var t;this.hasPrev?t=[this.prev,e]:this.hasPrev=!0,this.prev=e,t&&this.destination.next(t)},t}(A.L);const lr=function(e,t){return e.id===t.id&&e.start===t.start&&e.end===t.end};const dr=function(e,t){for(var n=[],r=t.periods,i=0;i0})),(0,m.x)(),(0,Qe.w)((function(e){return e?(0,d.aj)([(0,Vt.F)(cr).pipe((0,w.O)(null)),n]).pipe((0,v.U)((function(e){e[0];return{isSeeking:e[1].seeking,currentTime:t.currentTime}})),(function(e){return e.lift(new sr)}),(0,g.zg)((function(e){var t=e[0],n=e[1];return function(e,t,n){for(var i=t.currentTime,a=n.isSeeking,o=n.currentTime,s=[],u=[],d=0;do||void 0!==v&&o>=v)&&(fr(f)&&u.push(f.publicEvent),r.delete(f)):h<=o&&void 0!==v&&o=(null!=v?v:h)&&(a?s.push({type:"stream-event-skip",value:f.publicEvent}):(s.push({type:"stream-event",value:f.publicEvent}),fr(f)&&u.push(f.publicEvent)))}return(0,c.z)(s.length>0?l.of.apply(void 0,s):p.E,u.length>0?l.of.apply(void 0,u).pipe((0,Pe.b)((function(e){"function"==typeof e.onExit&&e.onExit()})),(0,ie.l)()):p.E)}(i,t,n)}))):p.E})))};var hr=n(2983);function vr(e){var t=e.mediaElement,n=e.manifest,r=e.clock$,o=e.speed$,s=e.bufferOptions,u=e.abrManager,c=e.segmentFetcherCreator,m=e.setCurrentTime;return function(e,_,b){var E,S=function(e,t){return(0,H.R)(e,"manifestUpdate").pipe((0,w.O)(null),(0,Pe.b)((function(){var n=e.getMaximumPosition(),r=e.isLive?Math.max(Math.pow(2,32),n+31536e3):n;(isNaN(t.duration)||!isFinite(t.duration)||Math.abs(t.duration-r)>.01)&&(O.Z.info("Init: Updating duration",r),t.duration=r)})),(0,ie.l)())}(n,e),k=null!==(E=n.getPeriodForTime(_))&&void 0!==E?E:n.getNextPeriod(_);if(void 0===k){var A=new B.Z("MEDIA_STARTING_TIME_NOT_FOUND","Wanted starting time not found in the Manifest.");return(0,Kt._)(A)}var x=new Qt(t,e),I=function(e,t,n){var r=n.autoPlay,i=n.manifest,o=n.speed$,s=n.startTime,u=n.setCurrentTime,l=!1,c=!1,p=new a.t(1),h=(0,Jn.Z)(t,e,r,!1).pipe((0,Pe.b)((function(e){l=!0,p.next(e)})),(0,ie.l)()),m=(0,d.aj)([t,o]).pipe((0,v.U)((function(t){var n=t[0],a=t[1],o=c;!c&&(n.readyState>0||"loadedmetadata"===n.event)&&(e.currentTime!==s&&(O.Z.info("Init: Set initial time",s),u(s)),c=!0);var d=i.isLive?o?i.getMaximumPosition()-n.position:i.getMaximumPosition()-s:1/0;return{position:n.position,getCurrentTime:n.getCurrentTime,duration:n.duration,isPaused:l?n.paused:!r,liveGap:d,readyState:n.readyState,speed:a,stalled:n.stalled,wantedTimeOffset:o?0:s}})));return{loaded$:p,clock$:(0,f.T)(h,m).pipe((0,y.d)({bufferSize:1,refCount:!0}))}}(t,r,{autoPlay:b,manifest:n,setCurrentTime:m,speed$:o,startTime:_}),Z=I.loaded$,R=I.clock$,M=Z.pipe((0,T.h)((function(e){return"not-loaded-metadata"!==e}))).pipe((0,g.zg)((function(){return pr(n,t,r)}))),C=new i.xQ,N=new i.xQ,P=Wn({manifest:n,initialPeriod:k},R,u,x,c,s).pipe((0,g.zg)((function(t){switch(t.type){case"end-of-stream":return O.Z.debug("Init: end-of-stream order received."),function(e){return qn(e).pipe((0,w.O)(null),(0,Qe.w)((function(){return Qn(e)})))}(e).pipe((0,ie.l)(),(0,h.R)(C));case"resume-stream":return O.Z.debug("Init: resume-stream order received."),C.next(null),p.E;case"stream-status":var n=t.value,r=n.period,i=n.bufferType,a=n.imminentDiscontinuity,o=n.position;return N.next({period:r,bufferType:i,discontinuity:a,position:o}),p.E;default:return(0,l.of)(t)}}))),D=(0,hr.Z)(t,o,r,{pauseWhenStalled:!0}).pipe((0,ie.l)()),L=ir(r,t,n,N,m),U=Z.pipe((0,g.zg)((function(e){if("autoplay-blocked"===e){var t=new B.Z("MEDIA_ERR_BLOCKED_AUTOPLAY","Cannot trigger auto-play automatically: your browser does not allow it.");return(0,l.of)(Ft.Z.warning(t),Ft.Z.loaded(x))}if("not-loaded-metadata"===e){var n=new B.Z("MEDIA_ERR_NOT_LOADED_METADATA","Cannot load automatically: your browser falsely announced having loaded the content.");return(0,l.of)(Ft.Z.warning(n))}return O.Z.debug("Init: The current content is loaded."),(0,l.of)(Ft.Z.loaded(x))})));return(0,f.T)(S,U,D,L,P,M).pipe(ue((function(){x.disposeAll()})))}}var mr=L.Z.FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY,gr=L.Z.MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE,yr=L.Z.MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE;function _r(e){var t,n,r=e.initialManifest,i=e.manifestFetcher,a=e.minimumManifestUpdateInterval,o=e.scheduleRefresh$,s=(t=function(e,t){return i.fetch(e).pipe((0,g.zg)((function(e){return"warning"===e.type?(0,l.of)(e):e.parse(t)})),(0,E.B)())},n=!1,function(){for(var e=arguments.length,r=new Array(e),i=0;i0?d=yr,m=o.pipe((0,g.zg)((function(e){var t=e.completeRefresh,r=e.delay,i=e.canUseUnsafeMode&&v;return br(null!=r?r:0,a,n).pipe((0,k.h)({completeRefresh:t,unsafeMode:i}))}))),y=void 0===n?0:performance.now()-n,_=Math.max(a-y,0);if(void 0===u.lifetime||u.lifetime<0)t=p.E;else{var b=1e3*u.lifetime-y;if(void 0!==s)if(u.lifetime<3&&s>=100){var T=1e3*(3-u.lifetime)+b,E=Math.max(T,Math.max(b,0)+s);O.Z.info("MUS: Manifest update rythm is too frequent. Postponing next request.",b,E),b=E}else if(s>=1e3*u.lifetime/10){var w=Math.max(b,0)+s;O.Z.info("MUS: Manifest took too long to parse. Postponing next request",b,w),b=w}t=(0,me.H)(Math.max(b,_)).pipe((0,k.h)({completeRefresh:!1,unsafeMode:v}))}var A=null===u.expired?p.E:(0,me.H)(_).pipe((0,R.j)((0,je.D)(u.expired)),(0,k.h)({completeRefresh:!0,unsafeMode:v}));return(0,f.T)(t,m,A).pipe((0,S.q)(1),(0,g.zg)((function(e){return h({completeRefresh:e.completeRefresh,unsafeMode:e.unsafeMode})})),(0,g.zg)((function(e){return"warning"===e.type?(0,l.of)(e):c(e)})))}return(0,J.P)((function(){return c(r)}));function h(e){var t=e.completeRefresh,n=e.unsafeMode,r=u.updateUrl,i=t||void 0===r,o=i?u.getUrl():r,c=u.clockOffset;return n?(d+=1,O.Z.info('Init: Refreshing the Manifest in "unsafeMode" for the '+String(d)+" consecutive time.")):d>0&&(O.Z.info('Init: Not parsing the Manifest in "unsafeMode" anymore after '+String(d)+" consecutive times."),d=0),s(o,{externalClockOffset:c,previousManifest:u,unsafeMode:n}).pipe((0,g.zg)((function(e){if("warning"===e.type)return(0,l.of)(e);var t=e.manifest,n=e.sendingTime,r=e.receivedTime,o=e.parsingTime,s=performance.now();if(i)u.replace(t);else try{u.update(t)}catch(e){var d=e instanceof Error?e.message:"unknown error";return O.Z.warn("MUS: Attempt to update Manifest failed: "+d,"Re-downloading the Manifest fully"),br(mr,a,n).pipe((0,g.zg)((function(){return h({completeRefresh:!0,unsafeMode:!1})})))}return(0,l.of)({type:"parsed",manifest:u,sendingTime:n,receivedTime:r,parsingTime:o,updatingTime:performance.now()-s})})))}}function br(e,t,n){return(0,J.P)((function(){var r=void 0===n?0:performance.now()-n,i=Math.max(t-r,0);return(0,me.H)(Math.max(e-r,i))}))}var Tr=n(2447),Er=L.Z.OUT_OF_SYNC_MANIFEST_REFRESH_DELAY;const wr=function(e){var t,n,r,a=e.adaptiveOptions,o=e.autoPlay,s=e.bufferOptions,u=e.clock$,c=e.keySystems,m=e.lowLatencyMode,_=e.manifest$,b=e.manifestFetcher,A=e.mediaElement,x=e.minimumManifestUpdateInterval,I=e.segmentFetcherCreator,Z=e.setCurrentTime,R=e.speed$,M=e.startAt,C=e.textTrackOptions,N=new Ct(a),P=Ut(A).pipe((0,y.d)({refCount:!0})),D=new i.xQ,L=(0,Nt.Z)(A,c,D).pipe((0,Je.Z)(),(0,E.B)()),B=(0,Tr.Z)(A),U=L.pipe((t=function(e,t){switch(t.type){case"eme-disabled":case"attached-media-keys":return(0,l.of)({isEmeReady:!0,drmSystemId:e.drmSystemId});case"created-media-keys":var n=t.value.initializationDataSystemId;return P.pipe((0,g.zg)((function(){return t.value.attachMediaKeys$.next(),!0===t.value.options.disableMediaKeysAttachmentLock?(0,l.of)({isEmeReady:!0,drmSystemId:n}):p.E})),(0,w.O)({isEmeReady:!1,drmSystemId:n}));default:return p.E}},n={isEmeReady:!1,drmSystemId:void 0},void 0===r&&(r=Number.POSITIVE_INFINITY),function(e){return e.lift(new He(t,n,r))}),(0,T.h)((function(e){return e.isEmeReady})),(0,S.q)(1),Ye((function(e){var t=e.drmSystemId;return P.pipe((0,v.U)((function(e){return{mediaSource:e,drmSystemId:t}})))}))),F=(0,d.aj)([_,U]).pipe((0,g.zg)((function(e){var t=e[0],n=e[1];if("warning"===t.type)return(0,l.of)(t);var r=t.manifest,a=n.mediaSource,d=n.drmSystemId;O.Z.debug("Init: Calculating initial time");var c=function(e,t,n){if(O.Z.debug("Init: calculating initial time"),null!=n){var r=e.getMinimumPosition(),i=e.getMaximumPosition();if(null!=n.position)return O.Z.debug("Init: using startAt.minimumPosition"),Math.max(Math.min(n.position,i),r);if(null!=n.wallClockTime){O.Z.debug("Init: using startAt.wallClockTime");var a=null==e.availabilityStartTime?0:e.availabilityStartTime,o=n.wallClockTime-a;return Math.max(Math.min(o,i),r)}if(null!=n.fromFirstPosition){O.Z.debug("Init: using startAt.fromFirstPosition");var s=n.fromFirstPosition;return s<=0?r:Math.min(i,r+s)}if(null!=n.fromLastPosition){O.Z.debug("Init: using startAt.fromLastPosition");var u=n.fromLastPosition;return u>=0?i:Math.max(r,i+u)}if(null!=n.percentage){O.Z.debug("Init: using startAt.percentage");var l=n.percentage;return l>100?i:l<0?r:r+ +l/100*(i-r)}}var d=e.getMinimumPosition();if(e.isLive){var c,f=e.suggestedPresentationDelay,p=e.clockOffset,h=e.getMaximumPosition();if(null==p)O.Z.info("Init: no clock offset found for a live content, starting close to maximum available position"),c=h;else{O.Z.info("Init: clock offset found for a live content, checking if we can start close to it");var v=null==e.availabilityStartTime?0:e.availabilityStartTime,m=(performance.now()+p)/1e3-v;c=Math.min(h,m)}var g=void 0!==f?f:t?zt.LOW_LATENCY:zt.DEFAULT;return O.Z.debug("Init: "+c+" defined as the live time, applying a live gap of "+g),Math.max(c-g,d)}return O.Z.info("Init: starting at the minimum available position:",d),d}(r,m,M);O.Z.debug("Init: Initial time calculated:",c);var p=vr({abrManager:N,bufferOptions:(0,Y.Z)({textTrackOptions:C,drmSystemId:d},s),clock$:u,manifest:r,mediaElement:A,segmentFetcherCreator:I,speed$:R,setCurrentTime:Z}),y=function e(t,n,r){var a=new i.xQ,o=p(t,n,r).pipe((0,fe.Z)((function(e){switch(e.type){case"needs-manifest-refresh":return _.next({completeRefresh:!1,canUseUnsafeMode:!0}),null;case"manifest-might-be-out-of-sync":return _.next({completeRefresh:!0,canUseUnsafeMode:!1,delay:Er}),null;case"needs-media-source-reload":return a.next(e.value),null;case"needs-decipherability-flush":var t=re(A);if(null===(r=t)||r.indexOf("widevine")<0)return a.next(e.value),null;var n=e.value.position;return n+.001=1&&"loadedmetadata"!==u&&null===m&&!(_||v),T=null,E=s?Mr.LOW_LATENCY:Mr.DEFAULT;if(o){if(b)d<=E?(r=!0,T=l+d):d===1/0?(r=!0,T=l):1===h&&(r=!0);else if(null!==m){var w=Nr(m,s);!0!==r&&null!==m&&h>1&&(_||v||d<1/0&&d>w)?i=!0:(d===1/0||d<=w)&&(T=d===1/0?l:l+d)}}else b&&(!p&&"timeupdate"===u&&"timeupdate"===g&&l===y||"seeking"===u&&d===1/0)?r=!0:null!==m&&("seeking"!==u&&l!==y||"canplay"===u||d<1/0&&(d>Nr(m,s)||_||v))&&(i=!0);return!0===i?null:!0===r||null!==m?(a="seeking"===u||null!==m&&"seeking"===m.reason?"seeking":t.seeking&&("internal-seeking"===u||null!==m&&"internal-seek"===m.reason)?"internal-seek":t.seeking?"seeking":1===h?"not-ready":"buffering",null!==m&&m.reason===a?{reason:m.reason,timestamp:m.timestamp,position:T}:{reason:a,timestamp:performance.now(),position:T}):null}const Dr=function(e,t){var n=0;return{clock$:(0,J.P)((function(){var r=(0,Y.Z)(Pr(e,"init"),{stalled:null,getCurrentTime:function(){return e.currentTime}});var i=Cr.map((function(t){return(0,Wt.R)(e,t).pipe((0,k.h)(t))})),a=t.lowLatencyMode?Ar:t.withMediaSource?kr:xr,o=(0,Vt.F)(a).pipe((0,k.h)("timeupdate"));return f.T.apply(void 0,[o].concat(i)).pipe((0,v.U)((function(i){return r=function(i){var a=i;"seeking"===a&&n>0&&(a="internal-seeking",n-=1);var o=Pr(e,a),s=Or(r,o,t),u=(0,Y.Z)({},{stalled:s,getCurrentTime:function(){return e.currentTime}},o);return O.Z.debug("API: current media element state",u),u}(i),"DEBUG"===O.Z.getLevel()&&O.Z.debug("API: current playback timeline:\n"+function(e,t){for(var n="",r="",i=0;it){var d=n.length-Math.floor(l.length/2);r=" ".repeat(d)+"^"+t}if(i=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.")}return(n=e[Symbol.iterator]()).next.bind(n)}function Yr(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0;)this._periods.pop()},t.update=function(){this._resetChosenAudioTracks(),this._resetChosenTextTracks(),this._resetChosenVideoTracks()},t.setInitialAudioTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.audio:null;if(null==n||null==t)throw new Error("TrackChoiceManager: Given Period not found.");var r=e.getPlayableAdaptations("audio"),i=this._audioChoiceMemory.get(e);if(null===i)n.adaptation$.next(null);else if(void 0!==i&&(0,Oe.Z)(r,i))n.adaptation$.next(i);else{var a=yi(r,hi(this._preferredAudioTracks));this._audioChoiceMemory.set(e,a),n.adaptation$.next(a)}},t.setInitialTextTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.text:null;if(null==n||null==t)throw new Error("TrackChoiceManager: Given Period not found.");var r=e.getPlayableAdaptations("text"),i=this._textChoiceMemory.get(e);if(null===i)n.adaptation$.next(null);else if(void 0!==i&&(0,Oe.Z)(r,i))n.adaptation$.next(i);else{var a=bi(r,vi(this._preferredTextTracks));this._textChoiceMemory.set(e,a),n.adaptation$.next(a)}},t.setInitialVideoTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.video:null;if(null==n||null==t)throw new Error("TrackChoiceManager: Given Period not found.");var r=e.getPlayableAdaptations("video"),i=this._videoChoiceMemory.get(e);if(null===i)n.adaptation$.next(null);else if(void 0!==i&&(0,Oe.Z)(r,i))n.adaptation$.next(i);else{var a=Ei(r,this._preferredVideoTracks);this._videoChoiceMemory.set(e,a),n.adaptation$.next(a)}},t.setAudioTrackByID=function(e,t){var n=wi(this._periods,e),r=null!=n?n.audio:null;if(null==r)throw new Error("TrackChoiceManager: Given Period not found.");var i=(0,mt.Z)(r.adaptations,(function(e){return e.id===t}));if(void 0===i)throw new Error("Audio Track not found.");this._audioChoiceMemory.get(e)!==i&&(this._audioChoiceMemory.set(e,i),r.adaptation$.next(i))},t.setTextTrackByID=function(e,t){var n=wi(this._periods,e),r=null!=n?n.text:null;if(null==r)throw new Error("TrackChoiceManager: Given Period not found.");var i=(0,mt.Z)(r.adaptations,(function(e){return e.id===t}));if(void 0===i)throw new Error("Text Track not found.");this._textChoiceMemory.get(e)!==i&&(this._textChoiceMemory.set(e,i),r.adaptation$.next(i))},t.setVideoTrackByID=function(e,t){var n=wi(this._periods,e),r=null!=n?n.video:null;if(null==r)throw new Error("LanguageManager: Given Period not found.");var i=(0,mt.Z)(r.adaptations,(function(e){return e.id===t}));if(void 0===i)throw new Error("Video Track not found.");this._videoChoiceMemory.get(e)!==i&&(this._videoChoiceMemory.set(e,i),r.adaptation$.next(i))},t.disableTextTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.text:null;if(null==n)throw new Error("TrackChoiceManager: Given Period not found.");null!==this._textChoiceMemory.get(e)&&(this._textChoiceMemory.set(e,null),n.adaptation$.next(null))},t.disableVideoTrack=function(e){var t=wi(this._periods,e),n=null==t?void 0:t.video;if(void 0===n)throw new Error("TrackManager: Given Period not found.");null!==this._videoChoiceMemory.get(e)&&(this._videoChoiceMemory.set(e,null),n.adaptation$.next(null))},t.getChosenAudioTrack=function(e){var t=wi(this._periods,e);if(null==(null!=t?t.audio:null))return null;var n=this._audioChoiceMemory.get(e);if(null==n)return null;var r={language:(0,et.Z)(n.language,""),normalized:(0,et.Z)(n.normalizedLanguage,""),audioDescription:!0===n.isAudioDescription,id:n.id,representations:n.representations.map(ki)};return!0===n.isDub&&(r.dub=!0),r},t.getChosenTextTrack=function(e){var t=wi(this._periods,e);if(null==(null!=t?t.text:null))return null;var n=this._textChoiceMemory.get(e);return null==n?null:{language:(0,et.Z)(n.language,""),normalized:(0,et.Z)(n.normalizedLanguage,""),closedCaption:!0===n.isClosedCaption,id:n.id}},t.getChosenVideoTrack=function(e){var t=wi(this._periods,e);if(null==(null!=t?t.video:null))return null;var n=this._videoChoiceMemory.get(e);if(null==n)return null;var r={id:n.id,representations:n.representations.map(Si)};return!0===n.isSignInterpreted&&(r.signInterpreted=!0),r},t.getAvailableAudioTracks=function(e){var t=wi(this._periods,e),n=null!=t?t.audio:null;if(null==n)return[];var r=this._audioChoiceMemory.get(e),i=null!=r?r.id:null;return n.adaptations.map((function(e){var t={language:(0,et.Z)(e.language,""),normalized:(0,et.Z)(e.normalizedLanguage,""),audioDescription:!0===e.isAudioDescription,id:e.id,active:null!=i&&i===e.id,representations:e.representations.map(ki)};return!0===e.isDub&&(t.dub=!0),t}))},t.getAvailableTextTracks=function(e){var t=wi(this._periods,e),n=null!=t?t.text:null;if(null==n)return[];var r=this._textChoiceMemory.get(e),i=null!=r?r.id:null;return n.adaptations.map((function(e){return{language:(0,et.Z)(e.language,""),normalized:(0,et.Z)(e.normalizedLanguage,""),closedCaption:!0===e.isClosedCaption,id:e.id,active:null!=i&&i===e.id}}))},t.getAvailableVideoTracks=function(e){var t=wi(this._periods,e),n=null!=t?t.video:null;if(null==n)return[];var r=this._videoChoiceMemory.get(e),i=null!=r?r.id:null;return n.adaptations.map((function(e){var t={id:e.id,active:null!==i&&i===e.id,representations:e.representations.map(Si)};return!0===e.isSignInterpreted&&(t.signInterpreted=!0),t}))},t._applyAudioPreferences=function(){this._audioChoiceMemory=new WeakMap,this._resetChosenAudioTracks()},t._applyTextPreferences=function(){this._textChoiceMemory=new WeakMap,this._resetChosenTextTracks()},t._applyVideoPreferences=function(){this._videoChoiceMemory=new WeakMap,this._resetChosenVideoTracks()},t._resetChosenAudioTracks=function(){var e=this,t=hi(this._preferredAudioTracks);!function n(r){if(!(r>=e._periods.length())){var i=e._periods.get(r);if(null!=i.audio){var a=i.period,o=i.audio,s=a.getPlayableAdaptations("audio"),u=e._audioChoiceMemory.get(a);if(null===u||void 0!==u&&(0,Oe.Z)(s,u))n(r+1);else{var l=yi(s,t);e._audioChoiceMemory.set(a,l),o.adaptation$.next(l),n(0)}}else n(r+1)}}(0)},t._resetChosenTextTracks=function(){var e=this,t=vi(this._preferredTextTracks);!function n(r){if(!(r>=e._periods.length())){var i=e._periods.get(r);if(null!=i.text){var a=i.period,o=i.text,s=a.getPlayableAdaptations("text"),u=e._textChoiceMemory.get(a);if(null===u||void 0!==u&&(0,Oe.Z)(s,u))n(r+1);else{var l=bi(s,t);e._textChoiceMemory.set(a,l),o.adaptation$.next(l),n(0)}}else n(r+1)}}(0)},t._resetChosenVideoTracks=function(){var e=this,t=this._preferredVideoTracks;!function n(r){if(!(r>=e._periods.length())){var i=e._periods.get(r);if(null!=i.video){var a=i.period,o=i.video,s=a.getPlayableAdaptations("video"),u=e._videoChoiceMemory.get(a);if(null===u||void 0!==u&&(0,Oe.Z)(s,u))n(r+1);else{var l=Ei(s,t);e._videoChoiceMemory.set(a,l),o.adaptation$.next(l),n(0)}}else n(r+1)}}(0)},e}();function gi(e){return function(t){var n;if(void 0!==e.normalized&&(null!==(n=t.normalizedLanguage)&&void 0!==n?n:"")!==e.normalized)return!1;if(void 0!==e.audioDescription)if(e.audioDescription){if(!0!==t.isAudioDescription)return!1}else if(!0===t.isAudioDescription)return!1;if(void 0===e.codec)return!0;var r=e.codec.test,i=function(e){return void 0!==e.codec&&r.test(e.codec)};return e.codec.all?t.representations.every(i):t.representations.some(i)}}function yi(e,t){if(0===e.length)return null;for(var n=0;nv)throw new Error('Invalid maxVideoBitrate parameter. Its value, "'+v+'", is inferior to the set minVideoBitrate, "'+p+'"')}if((0,$.Z)(e.maxAudioBitrate))h=ii.audio;else{if(h=Number(e.maxAudioBitrate),isNaN(h))throw new Error("Invalid maxAudioBitrate parameter. Should be a number.");if(f>h)throw new Error('Invalid maxAudioBitrate parameter. Its value, "'+h+'", is inferior to the set minAudioBitrate, "'+f+'"')}return{maxBufferAhead:t,maxBufferBehind:n,limitVideoWidth:m,videoElement:l,wantedBufferAhead:r,throttleWhenHidden:i,throttleVideoBitrateWhenHidden:a,preferredAudioTracks:o,preferredTextTracks:s,preferredVideoTracks:u,initialAudioBitrate:c,initialVideoBitrate:d,minAudioBitrate:f,minVideoBitrate:p,maxAudioBitrate:h,maxVideoBitrate:v,stopAtEnd:(0,$.Z)(e.stopAtEnd)?ui:!!e.stopAtEnd}}(e),o=r.initialAudioBitrate,s=r.initialVideoBitrate,l=r.limitVideoWidth,d=r.minAudioBitrate,c=r.minVideoBitrate,f=r.maxAudioBitrate,p=r.maxBufferAhead,g=r.maxBufferBehind,y=r.maxVideoBitrate,_=r.preferredAudioTracks,b=r.preferredTextTracks,T=r.preferredVideoTracks,E=r.throttleWhenHidden,w=r.throttleVideoBitrateWhenHidden,S=r.videoElement,k=r.wantedBufferAhead,A=r.stopAtEnd;return S.preload="auto",t.version="3.24.0",t.log=O.Z,t.state="STOPPED",t.videoElement=S,t._priv_destroy$=new i.xQ,t._priv_pictureInPictureEvent$=new a.t(1),Ci(S).pipe((0,h.R)(t._priv_destroy$)).subscribe(t._priv_pictureInPictureEvent$),Ri(S).pipe((0,h.R)(t._priv_destroy$)).subscribe((function(){return t.trigger("fullscreenChange",t.isFullscreen())})),Pi(S.textTracks).pipe((0,h.R)(t._priv_destroy$),(0,v.U)((function(e){for(var t=e.target,n=[],r=0;r0?e.textTracks[0]:null},o.getPlayerState=function(){return this.state},o.isLive=function(){if(null===this._priv_contentInfos)return!1;var e=this._priv_contentInfos,t=e.isDirectFile,n=e.manifest;return!t&&null!==n&&n.isLive},o.getUrl=function(){if(null!==this._priv_contentInfos){var e=this._priv_contentInfos,t=e.isDirectFile,n=e.manifest,r=e.url;return t?r:null!==n?n.getUrl():void 0}},o.getVideoDuration=function(){if(null===this.videoElement)throw new Error("Disposed player");return this.videoElement.duration},o.getVideoBufferGap=function(){if(null===this.videoElement)throw new Error("Disposed player");var e=this.videoElement;return(0,X.L7)(e.buffered,e.currentTime)},o.getVideoLoadedTime=function(){if(null===this.videoElement)throw new Error("Disposed player");var e=this.videoElement;return(0,X.at)(e.buffered,e.currentTime)},o.getVideoPlayedTime=function(){if(null===this.videoElement)throw new Error("Disposed player");var e=this.videoElement;return(0,X.DD)(e.buffered,e.currentTime)},o.getWallClockTime=function(){if(null===this.videoElement)throw new Error("Disposed player");if(null===this._priv_contentInfos)return this.videoElement.currentTime;var e=this._priv_contentInfos,t=e.isDirectFile,n=e.manifest;return t?this.videoElement.currentTime:null!==n?this.videoElement.currentTime+(void 0!==n.availabilityStartTime?n.availabilityStartTime:0):0},o.getPosition=function(){if(null===this.videoElement)throw new Error("Disposed player");return this.videoElement.currentTime},o.getPlaybackRate=function(){return this._priv_speed$.getValue()},o.setPlaybackRate=function(e){this._priv_speed$.next(e)},o.getAvailableVideoBitrates=function(){if(null===this._priv_contentInfos)return[];var e=this._priv_contentInfos,t=e.currentPeriod,n=e.activeAdaptations;if(null===t||null===n)return[];var r=n[t.id];return void 0===r||(0,$.Z)(r.video)?[]:r.video.getAvailableBitrates()},o.getAvailableAudioBitrates=function(){if(null===this._priv_contentInfos)return[];var e=this._priv_contentInfos,t=e.currentPeriod,n=e.activeAdaptations;if(null===t||null===n)return[];var r=n[t.id];return void 0===r||(0,$.Z)(r.audio)?[]:r.audio.getAvailableBitrates()},o.getManualAudioBitrate=function(){return this._priv_bitrateInfos.manualBitrates.audio.getValue()},o.getManualVideoBitrate=function(){return this._priv_bitrateInfos.manualBitrates.video.getValue()},o.getVideoBitrate=function(){var e=this._priv_getCurrentRepresentations();if(null!==e&&!(0,$.Z)(e.video))return e.video.bitrate},o.getAudioBitrate=function(){var e=this._priv_getCurrentRepresentations();if(null!==e&&!(0,$.Z)(e.audio))return e.audio.bitrate},o.getMinVideoBitrate=function(){return this._priv_bitrateInfos.minAutoBitrates.video.getValue()},o.getMinAudioBitrate=function(){return this._priv_bitrateInfos.minAutoBitrates.audio.getValue()},o.getMaxVideoBitrate=function(){return this._priv_bitrateInfos.maxAutoBitrates.video.getValue()},o.getMaxAudioBitrate=function(){return this._priv_bitrateInfos.maxAutoBitrates.audio.getValue()},o.play=function(){var e=this;if(null===this.videoElement)throw new Error("Disposed player");var t=this.videoElement.play();return(0,$.Z)(t)||"function"!=typeof t.catch?q.Z.resolve():t.catch((function(t){if("NotAllowedError"===t.name){var n=new B.Z("MEDIA_ERR_PLAY_NOT_ALLOWED",t.toString());e.trigger("warning",n)}throw t}))},o.pause=function(){if(null===this.videoElement)throw new Error("Disposed player");this.videoElement.pause()},o.seekTo=function(e){if(null===this.videoElement)throw new Error("Disposed player");if(null===this._priv_contentInfos)throw new Error("player: no content loaded");var t,n=this._priv_contentInfos,r=n.isDirectFile,i=n.manifest;if(!r&&null===i)throw new Error("player: the content did not load yet");if("number"==typeof e)t=e;else if("object"==typeof e){var a=e,o=this.videoElement.currentTime;if((0,$.Z)(a.relative))if((0,$.Z)(a.position)){if((0,$.Z)(a.wallClockTime))throw new Error('invalid time object. You must set one of the following properties: "relative", "position" or "wallClockTime"');t=r||null===i?a.wallClockTime:a.wallClockTime-(void 0!==i.availabilityStartTime?i.availabilityStartTime:0)}else t=a.position;else t=o+a.relative}if(void 0===t)throw new Error("invalid time given");return this.videoElement.currentTime=t,t},o.isFullscreen=function(){return(0,Q.Z)("isFullscreen is deprecated. Fullscreen management should now be managed by the application"),N()},o.setFullscreen=function(e){if(void 0===e&&(e=!0),(0,Q.Z)("setFullscreen is deprecated. Fullscreen management should now be managed by the application"),null===this.videoElement)throw new Error("Disposed player");e?function(e){if(!N()){var t=e;"function"==typeof t.requestFullscreen?t.requestFullscreen():"function"==typeof t.msRequestFullscreen?t.msRequestFullscreen():"function"==typeof t.mozRequestFullScreen?t.mozRequestFullScreen():"function"==typeof t.webkitRequestFullscreen&&t.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}}(this.videoElement):C()},o.exitFullscreen=function(){(0,Q.Z)("exitFullscreen is deprecated. Fullscreen management should now be managed by the application"),C()},o.getVolume=function(){if(null===this.videoElement)throw new Error("Disposed player");return this.videoElement.volume},o.setVolume=function(e){if(null===this.videoElement)throw new Error("Disposed player");var t=this.videoElement;e!==t.volume&&(t.volume=e,this.trigger("volumeChange",e))},o.isMute=function(){return 0===this.getVolume()},o.mute=function(){this._priv_mutedMemory=this.getVolume(),this.setVolume(0)},o.unMute=function(){0===this.getVolume()&&this.setVolume(0===this._priv_mutedMemory?Ai:this._priv_mutedMemory)},o.setVideoBitrate=function(e){this._priv_bitrateInfos.manualBitrates.video.next(e)},o.setAudioBitrate=function(e){this._priv_bitrateInfos.manualBitrates.audio.next(e)},o.setMinVideoBitrate=function(e){var t=this._priv_bitrateInfos.maxAutoBitrates.video.getValue();if(e>t)throw new Error('Invalid minimum video bitrate given. Its value, "'+e+'" is superior the current maximum video birate, "'+t+'".');this._priv_bitrateInfos.minAutoBitrates.video.next(e)},o.setMinAudioBitrate=function(e){var t=this._priv_bitrateInfos.maxAutoBitrates.audio.getValue();if(e>t)throw new Error('Invalid minimum audio bitrate given. Its value, "'+e+'" is superior the current maximum audio birate, "'+t+'".');this._priv_bitrateInfos.minAutoBitrates.audio.next(e)},o.setMaxVideoBitrate=function(e){var t=this._priv_bitrateInfos.minAutoBitrates.video.getValue();if(e0?r.next(i[0]):r.next(null)}},o._priv_onPeriodStreamCleared=function(e){var t=e.type,n=e.period;switch(t){case"audio":case"text":case"video":null!==this._priv_trackChoiceManager&&this._priv_trackChoiceManager.removePeriod(t,n)}if(null!==this._priv_contentInfos){var r=this._priv_contentInfos,i=r.activeAdaptations,a=r.activeRepresentations;if(!(0,$.Z)(i)&&!(0,$.Z)(i[n.id])){var o=i[n.id];delete o[t],0===Object.keys(o).length&&delete i[n.id]}if(!(0,$.Z)(a)&&!(0,$.Z)(a[n.id])){var s=a[n.id];delete s[t],0===Object.keys(s).length&&delete a[n.id]}}},o._priv_onReloadingMediaSource=function(){null!==this._priv_contentInfos&&(this._priv_contentInfos.segmentBuffersStore=null),null!==this._priv_trackChoiceManager&&this._priv_trackChoiceManager.resetPeriods()},o._priv_onAdaptationChange=function(e){var t=e.type,n=e.adaptation,r=e.period;if(null!==this._priv_contentInfos){null===this._priv_contentInfos.activeAdaptations&&(this._priv_contentInfos.activeAdaptations={});var i,a=this._priv_contentInfos,o=a.activeAdaptations,s=a.currentPeriod,u=o[r.id];if((0,$.Z)(u))o[r.id]=((i={})[t]=n,i);else u[t]=n;if(null!==this._priv_trackChoiceManager&&null!==s&&!(0,$.Z)(r)&&r.id===s.id)switch(t){case"audio":var l=this._priv_trackChoiceManager.getChosenAudioTrack(s);this.trigger("audioTrackChange",l);var d=this.getAvailableAudioBitrates();this._priv_triggerAvailableBitratesChangeEvent("availableAudioBitratesChange",d);break;case"text":var c=this._priv_trackChoiceManager.getChosenTextTrack(s);this.trigger("textTrackChange",c);break;case"video":var f=this._priv_trackChoiceManager.getChosenVideoTrack(s);this.trigger("videoTrackChange",f);var p=this.getAvailableVideoBitrates();this._priv_triggerAvailableBitratesChangeEvent("availableVideoBitratesChange",p)}}else O.Z.error("API: The adaptations changed but no content is loaded")},o._priv_onRepresentationChange=function(e){var t,n=e.type,r=e.period,i=e.representation;if(null!==this._priv_contentInfos){null===this._priv_contentInfos.activeRepresentations&&(this._priv_contentInfos.activeRepresentations={});var a,o=this._priv_contentInfos,s=o.activeRepresentations,u=o.currentPeriod,l=s[r.id];if((0,$.Z)(l))s[r.id]=((a={})[n]=i,a);else l[n]=i;var d=null!==(t=null==i?void 0:i.bitrate)&&void 0!==t?t:-1;(0,$.Z)(r)||null===u||u.id!==r.id||("video"===n?this._priv_triggerCurrentBitrateChangeEvent("videoBitrateChange",d):"audio"===n&&this._priv_triggerCurrentBitrateChangeEvent("audioBitrateChange",d))}else O.Z.error("API: The representations changed but no content is loaded")},o._priv_onBitrateEstimationChange=function(e){var t=e.type,n=e.bitrate;void 0!==n&&(this._priv_bitrateInfos.lastBitrates[t]=n),this.trigger("bitrateEstimationChange",{type:t,bitrate:n})},o._priv_onPlayPauseNext=function(e){if(null===this.videoElement)throw new Error("Disposed player");this._priv_playing$.next(e)},o._priv_onNativeTextTracksNext=function(e){this.trigger("nativeTextTracksChange",e)},o._priv_setPlayerState=function(e){this.state!==e&&(this.state=e,O.Z.info("API: playerStateChange event",e),this.trigger("playerStateChange",e))},o._priv_triggerPositionUpdate=function(e){var t;if(null!==this._priv_contentInfos){if(this.state!==Hr){var n=this._priv_contentInfos,r=n.isDirectFile,i=n.manifest;if((r||null!==i)&&!(0,$.Z)(e)){this._priv_lastContentPlaybackInfos.lastPlaybackPosition=e.position;var a=null!==i?i.getMaximumPosition():void 0,o={position:e.position,duration:e.duration,playbackRate:e.playbackRate,maximumBufferTime:a,bufferGap:isFinite(e.bufferGap)?e.bufferGap:0};if(null!==i&&void 0!==a&&i.isLive&&e.position>0){var s=null!==(t=i.availabilityStartTime)&&void 0!==t?t:0;o.wallClockTime=e.position+s,o.liveGap=a-e.position}this.trigger("positionUpdate",o)}}}else O.Z.warn("API: Cannot perform time update: no content loaded.")},o._priv_triggerAvailableBitratesChangeEvent=function(e,t){var n=this._priv_contentEventsMemory[e];(void 0===n||(0,G.Z)(t,n))&&(this._priv_contentEventsMemory[e]=t,this.trigger(e,t))},o._priv_triggerCurrentBitrateChangeEvent=function(e,t){t!==this._priv_contentEventsMemory[e]&&(this._priv_contentEventsMemory[e]=t,this.trigger(e,t))},o._priv_getCurrentRepresentations=function(){if(null===this._priv_contentInfos)return null;var e=this._priv_contentInfos,t=e.currentPeriod,n=e.activeRepresentations;return null===t||null===n||(0,$.Z)(n[t.id])?null:n[t.id]},(0,e.Z)(r,null,[{key:"ErrorTypes",get:function(){return K.ZB}},{key:"ErrorCodes",get:function(){return K.SM}},{key:"LogLevel",get:function(){return O.Z.getLevel()},set:function(e){O.Z.setLevel(e)}}]),r}(H.Z);Di.version="3.24.0";const Li=Di;var Bi=n(7273);!function(){Bi.Z.emeManager=n(1603).ZP,Bi.Z.imageBuffer=n(7127).Z,Bi.Z.imageParser=n(3203).Z,Bi.Z.transports.smooth=n(2339).Z,Bi.Z.transports.dash=n(1923).Z,Bi.Z.nativeTextTracksBuffer=n(9059).Z,Bi.Z.nativeTextTracksParsers.vtt=n(9405).Z,Bi.Z.nativeTextTracksParsers.ttml=n(1570).Z,Bi.Z.nativeTextTracksParsers.sami=n(1812).Z,Bi.Z.nativeTextTracksParsers.srt=n(8057).Z,Bi.Z.htmlTextTracksBuffer=n(5192).Z,Bi.Z.htmlTextTracksParsers.sami=n(5734).Z,Bi.Z.htmlTextTracksParsers.ttml=n(7439).Z,Bi.Z.htmlTextTracksParsers.srt=n(8675).Z,Bi.Z.htmlTextTracksParsers.vtt=n(4099).Z;var e=n(8969).Z,t=n(7794).Z;Bi.Z.directfile={initDirectFile:e,mediaElementTrackChoiceManager:t}}();const Ui=Li})(),r=r.default})()})); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 324d292cfa..d2beed7b62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "rx-player", - "version": "3.23.1", + "version": "3.24.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "3.23.1", + "version": "3.24.0", "license": "Apache-2.0", "dependencies": { "next-tick": "1.1.0", diff --git a/package.json b/package.json index a8e86266fc..6e2354766c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "rx-player", "author": "Canal+", - "version": "3.23.1", + "version": "3.24.0", "description": "Canal+ HTML5 Video Player", "main": "./dist/rx-player.js", "keywords": [ diff --git a/sonar-project.properties b/sonar-project.properties index c5277922ab..7c2a4a4fe3 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,6 +1,6 @@ sonar.projectKey=rx-player sonar.projectName=rx-player -sonar.projectVersion=3.23.1 +sonar.projectVersion=3.24.0 sonar.sources=./src,./demo,./tests sonar.exclusions=demo/full/bundle.js,demo/standalone/lib.js,demo/bundle.js sonar.host.url=https://sonarcloud.io diff --git a/src/core/api/public_api.ts b/src/core/api/public_api.ts index 602fb30667..0a74be2791 100644 --- a/src/core/api/public_api.ts +++ b/src/core/api/public_api.ts @@ -493,7 +493,7 @@ class Player extends EventEmitter { // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624 videoElement.preload = "auto"; - this.version = /* PLAYER_VERSION */"3.23.1"; + this.version = /* PLAYER_VERSION */"3.24.0"; this.log = log; this.state = "STOPPED"; this.videoElement = videoElement; @@ -2875,7 +2875,7 @@ class Player extends EventEmitter { return activeRepresentations[currentPeriod.id]; } } -Player.version = /* PLAYER_VERSION */"3.23.1"; +Player.version = /* PLAYER_VERSION */"3.24.0"; export default Player; export { IStreamEventData }; From c15ef2f99efb7cf0b839f785385fddb6a239955b Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Tue, 30 Mar 2021 18:51:37 +0200 Subject: [PATCH 51/75] Revert "rename tryBeginningPlayback into emitLoadedEventWhenReady" This reverts commit 1ca6dcc8cc49301bdc11f6870bb062a9d0e8547e. --- src/core/init/initial_seek_and_play.ts | 6 +++--- src/core/init/initialize_directfile.ts | 4 ++-- .../{emit_loaded_event.ts => try_beginning_playback.ts} | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/core/init/{emit_loaded_event.ts => try_beginning_playback.ts} (98%) diff --git a/src/core/init/initial_seek_and_play.ts b/src/core/init/initial_seek_and_play.ts index d13af2fbb2..22e62f4208 100644 --- a/src/core/init/initial_seek_and_play.ts +++ b/src/core/init/initial_seek_and_play.ts @@ -29,9 +29,9 @@ import { import log from "../../log"; import Manifest from "../../manifest"; import { IStreamOrchestratorClockTick } from "../stream"; -import emitLoadedEventWhenReady, { +import tryBeginningPlayback, { ILoadEvents, -} from "./emit_loaded_event"; +} from "./try_beginning_playback"; import { IInitClockTick } from "./types"; /** Arguments for the `initialSeekAndPlay` function. */ @@ -104,7 +104,7 @@ export default function initialSeekAndPlay( * needed and which emits through `loaded$` the current loading status. * Completes when done. */ - const load$ = emitLoadedEventWhenReady(initClock$, mediaElement, autoPlay, false).pipe( + const load$ = tryBeginningPlayback(initClock$, mediaElement, autoPlay, false).pipe( tap((evt) => { isLoaded = true; loaded$.next(evt); diff --git a/src/core/init/initialize_directfile.ts b/src/core/init/initialize_directfile.ts index 144abc800b..b1874e3ed4 100644 --- a/src/core/init/initialize_directfile.ts +++ b/src/core/init/initialize_directfile.ts @@ -39,10 +39,10 @@ import log from "../../log"; import deferSubscriptions from "../../utils/defer_subscriptions"; import { IKeySystemOption } from "../eme"; import createEMEManager from "./create_eme_manager"; -import emitLoadedEventWhenReady from "./emit_loaded_event"; import EVENTS from "./events_generators"; import { IInitialTimeOptions } from "./get_initial_time"; import throwOnMediaError from "./throw_on_media_error"; +import tryBeginningPlayback from "./try_beginning_playback"; import { IDirectfileEvent, IInitClockTick, @@ -167,7 +167,7 @@ export default function initializeDirectfileContent({ return evt.type === "eme-disabled" || evt.type === "attached-media-keys"; }), take(1), - mergeMapTo(emitLoadedEventWhenReady(clock$, mediaElement, autoPlay, true)), + mergeMapTo(tryBeginningPlayback(clock$, mediaElement, autoPlay, true)), mergeMap((evt) => { if (evt === "autoplay-blocked") { const error = new MediaError("MEDIA_ERR_BLOCKED_AUTOPLAY", diff --git a/src/core/init/emit_loaded_event.ts b/src/core/init/try_beginning_playback.ts similarity index 98% rename from src/core/init/emit_loaded_event.ts rename to src/core/init/try_beginning_playback.ts index f6a6598d5b..429490cfa3 100644 --- a/src/core/init/emit_loaded_event.ts +++ b/src/core/init/try_beginning_playback.ts @@ -78,7 +78,7 @@ function tryToPlay$( * @param {boolean} isDirectfile * @returns {Observable} */ -export default function emitLoadedEventWhenReady( +export default function tryBeginningPlayback( initClock$ : Observable, mediaElement : HTMLMediaElement, autoPlay : boolean, From 12e9ee298e388ddf62498441a0d272cfefd73991 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Tue, 30 Mar 2021 18:54:22 +0200 Subject: [PATCH 52/75] Revert "stop forcing initial seek as better fix has been found" This reverts commit 505e62840c83b628acac67d1ef003f18e4542fc0. --- .../__tests__/when_loaded_metadata.test.ts | 110 ++++++++++++++++++ src/compat/index.ts | 2 + src/compat/when_loaded_metadata.ts | 40 +++++++ src/core/init/initial_seek_and_play.ts | 35 ++---- src/core/init/initialize_directfile.ts | 11 +- .../integration/scenarios/dash_multi-track.js | 3 + 6 files changed, 168 insertions(+), 33 deletions(-) create mode 100644 src/compat/__tests__/when_loaded_metadata.test.ts create mode 100644 src/compat/when_loaded_metadata.ts diff --git a/src/compat/__tests__/when_loaded_metadata.test.ts b/src/compat/__tests__/when_loaded_metadata.test.ts new file mode 100644 index 0000000000..e8d457fff9 --- /dev/null +++ b/src/compat/__tests__/when_loaded_metadata.test.ts @@ -0,0 +1,110 @@ +/** + * 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. + */ + +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-var-requires */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ + +import { + interval as observableInterval, + timer as observableTimer, +} from "rxjs"; +import { + finalize, + mapTo, + tap, +} from "rxjs/operators"; + +describe("compat - whenLoadedMetadata$", () => { + beforeEach(() => { + jest.resetModules(); + }); + + it("should wait for loaded metadata if they are not yet loaded", (done) => { + const fakeMediaElement = { + readyState: 0, + }; + + const mockOnLoadedMetadata$ = jest.fn(() => { + return observableTimer(500).pipe( + tap(() => fakeMediaElement.readyState = 1), + mapTo(null) + ); + }); + + jest.mock("../event_listeners", () => ({ + __esModule: true as const, + onLoadedMetadata$: mockOnLoadedMetadata$, + })); + + const whenLoadedMetadata$ = require("../when_loaded_metadata").default; + whenLoadedMetadata$(fakeMediaElement).subscribe(() => { + expect(fakeMediaElement.readyState).toBe(1); + expect(mockOnLoadedMetadata$).toHaveBeenCalledTimes(1); + done(); + }); + }); + + it("should emit once when metadata is loaded several times", (done) => { + const fakeMediaElement = { + readyState: 0, + }; + + const mockOnLoadedMetadata$ = jest.fn(() => { + return observableInterval(500).pipe( + tap(() => fakeMediaElement.readyState++), + mapTo(null) + ); + }); + + jest.mock("../event_listeners", () => ({ + __esModule: true as const, + onLoadedMetadata$: mockOnLoadedMetadata$, + })); + + const whenLoadedMetadata$ = require("../when_loaded_metadata").default; + whenLoadedMetadata$(fakeMediaElement).pipe( + finalize(() => { + expect(fakeMediaElement.readyState).toBe(1); + expect(mockOnLoadedMetadata$).toHaveBeenCalledTimes(1); + done(); + }) + ).subscribe(); + }); + + it("should emit if metadata is already loaded", (done) => { + const fakeMediaElement = { + readyState: 1, + }; + + const mockOnLoadedMetadata$ = jest.fn(() => null); + + jest.mock("../event_listeners", () => ({ + __esModule: true as const, + onLoadedMetadata$: mockOnLoadedMetadata$, + })); + + const whenLoadedMetadata$ = require("../when_loaded_metadata").default; + whenLoadedMetadata$(fakeMediaElement).subscribe(() => { + expect(fakeMediaElement.readyState).toBe(1); + expect(mockOnLoadedMetadata$).not.toHaveBeenCalled(); + done(); + }); + }); +}); diff --git a/src/compat/index.ts b/src/compat/index.ts index 37baba9c48..417e5e457a 100644 --- a/src/compat/index.ts +++ b/src/compat/index.ts @@ -63,6 +63,7 @@ import shouldUnsetMediaKeys from "./should_unset_media_keys"; import shouldValidateMetadata from "./should_validate_metadata"; import shouldWaitForDataBeforeLoaded from "./should_wait_for_data_before_loaded"; import shouldWaitForSeekValidation from "./should_wait_for_seek_validation"; +import whenLoadedMetadata$ from "./when_loaded_metadata"; import whenMediaSourceOpen$ from "./when_media_source_open"; // TODO To remove. This seems to be the only side-effect done on import, which @@ -111,5 +112,6 @@ export { shouldWaitForSeekValidation, tryToChangeSourceBufferType, VTTCue_, + whenLoadedMetadata$, whenMediaSourceOpen$, }; diff --git a/src/compat/when_loaded_metadata.ts b/src/compat/when_loaded_metadata.ts new file mode 100644 index 0000000000..ad7a9f35de --- /dev/null +++ b/src/compat/when_loaded_metadata.ts @@ -0,0 +1,40 @@ +/** + * 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. + */ + +import { + Observable, + of as observableOf, +} from "rxjs"; +import { take } from "rxjs/operators"; +import { READY_STATES } from "./browser_compatibility_types"; +import { onLoadedMetadata$ } from "./event_listeners"; + +/** + * Returns an observable emitting a single time, as soon as a seek is possible + * (the metadata are loaded). + * @param {HTMLMediaElement} mediaElement + * @returns {Observable} + */ +export default function whenLoadedMetadata$( + mediaElement : HTMLMediaElement +) : Observable { + if (mediaElement.readyState >= READY_STATES.HAVE_METADATA) { + return observableOf(null); + } else { + return onLoadedMetadata$(mediaElement) + .pipe(take(1)); + } +} diff --git a/src/core/init/initial_seek_and_play.ts b/src/core/init/initial_seek_and_play.ts index 22e62f4208..77cf813132 100644 --- a/src/core/init/initial_seek_and_play.ts +++ b/src/core/init/initial_seek_and_play.ts @@ -26,12 +26,12 @@ import { tap, shareReplay, } from "rxjs/operators"; -import log from "../../log"; import Manifest from "../../manifest"; import { IStreamOrchestratorClockTick } from "../stream"; import tryBeginningPlayback, { ILoadEvents, } from "./try_beginning_playback"; +import tryInitialSeek from "./try_initial_seek"; import { IInitClockTick } from "./types"; /** Arguments for the `initialSeekAndPlay` function. */ @@ -95,8 +95,7 @@ export default function initialSeekAndPlay( /** * Emit loading-related events. * As its own ReplaySubject to avoid polluting the more general clock$ - * Observable. - */ + * Observable. */ const loaded$ = new ReplaySubject(1); /** @@ -117,26 +116,14 @@ export default function initialSeekAndPlay( */ const clock$ = observableCombineLatest([initClock$, speed$]).pipe( map(([tick, speed]) => { - /** - * When this value is `false`, the `startTime` should be considered as - * the current position instead of the clock tick's `position` property. - * This is because that clock tick was triggered before the initial seek - * was done. - */ - const isTickPositionRight = isSeekDone; - - // perform initial seek, if ready and not already done - if (!isSeekDone && (tick.readyState > 0 || tick.event === "loadedmetadata")) { - if (mediaElement.currentTime !== startTime) { - log.info("Init: Set initial time", startTime); - setCurrentTime(startTime); - } - isSeekDone = true; + /** True if the tick's position is at the right value */ + let isRightPosition = true; + if (!isSeekDone) { + isRightPosition = tick.position === startTime; + isSeekDone = tryInitialSeek(tick, mediaElement, startTime); } - const liveGap = !manifest.isLive ? Infinity : - isTickPositionRight ? - manifest.getMaximumPosition() - tick.position : - manifest.getMaximumPosition() - startTime; + const liveGap = manifest.isLive ? manifest.getMaximumPosition() - tick.position : + Infinity; return { position: tick.position, getCurrentTime: tick.getCurrentTime, @@ -154,8 +141,8 @@ export default function initialSeekAndPlay( // initial position, the currentTime will most probably be 0 where the // effective starting position will be _startTime_. // Thus we initially set a wantedTimeOffset equal to startTime. - wantedTimeOffset: isTickPositionRight ? 0 : - startTime, + wantedTimeOffset: isRightPosition ? 0 : + startTime - tick.position, }; })); diff --git a/src/core/init/initialize_directfile.ts b/src/core/init/initialize_directfile.ts index b1874e3ed4..5ca3e0a154 100644 --- a/src/core/init/initialize_directfile.ts +++ b/src/core/init/initialize_directfile.ts @@ -28,7 +28,6 @@ import { mergeMapTo, share, take, - tap, } from "rxjs/operators"; import { clearElementSrc, @@ -43,6 +42,7 @@ import EVENTS from "./events_generators"; import { IInitialTimeOptions } from "./get_initial_time"; import throwOnMediaError from "./throw_on_media_error"; import tryBeginningPlayback from "./try_beginning_playback"; +import tryInitialSeek from "./try_initial_seek"; import { IDirectfileEvent, IInitClockTick, @@ -184,15 +184,8 @@ export default function initializeDirectfileContent({ })); const initialSeek$ = clock$.pipe( - filter((tick) => tick.readyState > 0 || tick.event === "loadedmetadata"), + filter((tick) => tryInitialSeek(tick, mediaElement, initialTime)), take(1), - tap(() => { - const startTime = initialTime(); - if (mediaElement.currentTime !== startTime) { - log.info("Init: Set initial time", startTime); - setCurrentTime(startTime); - } - }), ignoreElements()); return observableMerge(loadedEvent$, diff --git a/tests/integration/scenarios/dash_multi-track.js b/tests/integration/scenarios/dash_multi-track.js index f26740dfae..4c88b58f94 100644 --- a/tests/integration/scenarios/dash_multi-track.js +++ b/tests/integration/scenarios/dash_multi-track.js @@ -156,6 +156,9 @@ describe("DASH multi-track content (SegmentTimeline)", function () { await sleep(10); + if (xhrMock.getLockedXHR().length > 1) { + console.log("!!!!!!!!!", JSON.stringify(xhrMock.getLockedXHR())); + } expect(xhrMock.getLockedXHR().length).to.equal(1); // Manifest request await xhrMock.flush(); await sleep(10); From fcacd68655b63c9b8d44dfe33bebb04bd0af98ae Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Tue, 30 Mar 2021 18:55:52 +0200 Subject: [PATCH 53/75] Revert "Refacto initial seek and play logic to support Tizen" This reverts commit 5d0980d177b8c784ded8545e156ecb2f1a41635c. --- src/compat/browser_detection.ts | 4 - src/compat/index.ts | 2 - src/compat/should_wait_for_seek_validation.ts | 27 -- src/core/init/create_stream_clock.ts | 94 +++++++ src/core/init/initial_seek_and_play.ts | 248 ++++++++++-------- src/core/init/initialize_directfile.ts | 21 +- src/core/init/load_on_media_source.ts | 32 ++- src/core/init/try_beginning_playback.ts | 133 ---------- src/core/init/try_initial_seek.ts | 58 ---- src/core/init/update_playback_rate.ts | 6 +- 10 files changed, 263 insertions(+), 362 deletions(-) delete mode 100644 src/compat/should_wait_for_seek_validation.ts create mode 100644 src/core/init/create_stream_clock.ts delete mode 100644 src/core/init/try_beginning_playback.ts delete mode 100644 src/core/init/try_initial_seek.ts diff --git a/src/compat/browser_detection.ts b/src/compat/browser_detection.ts index beeb3936ae..1c4bcda8e3 100644 --- a/src/compat/browser_detection.ts +++ b/src/compat/browser_detection.ts @@ -42,9 +42,6 @@ const isFirefox : boolean = !isNode && const isSamsungBrowser : boolean = !isNode && /SamsungBrowser/.test(navigator.userAgent); -const isTizen : boolean = !isNode && - /Tizen/.test(navigator.userAgent); - /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-call */ const isSafari : boolean = @@ -68,5 +65,4 @@ export { isSafari, isSafariMobile, isSamsungBrowser, - isTizen, }; diff --git a/src/compat/index.ts b/src/compat/index.ts index 417e5e457a..23af18f10f 100644 --- a/src/compat/index.ts +++ b/src/compat/index.ts @@ -62,7 +62,6 @@ import shouldRenewMediaKeys from "./should_renew_media_keys"; import shouldUnsetMediaKeys from "./should_unset_media_keys"; import shouldValidateMetadata from "./should_validate_metadata"; import shouldWaitForDataBeforeLoaded from "./should_wait_for_data_before_loaded"; -import shouldWaitForSeekValidation from "./should_wait_for_seek_validation"; import whenLoadedMetadata$ from "./when_loaded_metadata"; import whenMediaSourceOpen$ from "./when_media_source_open"; @@ -109,7 +108,6 @@ export { shouldUnsetMediaKeys, shouldValidateMetadata, shouldWaitForDataBeforeLoaded, - shouldWaitForSeekValidation, tryToChangeSourceBufferType, VTTCue_, whenLoadedMetadata$, diff --git a/src/compat/should_wait_for_seek_validation.ts b/src/compat/should_wait_for_seek_validation.ts deleted file mode 100644 index 4acdd94932..0000000000 --- a/src/compat/should_wait_for_seek_validation.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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. - */ - -import { isTizen } from "./browser_detection"; - -/** - * Returns true if an initial seek, performed normally after a "loadedmetadata" - * event, might not be taken into account by the browser. - * In that condition, we might want to try to seek later. - * @returns {boolean} - */ -export default function shouldWaitForSeekValidation() : boolean { - return isTizen; -} diff --git a/src/core/init/create_stream_clock.ts b/src/core/init/create_stream_clock.ts new file mode 100644 index 0000000000..98590e19fb --- /dev/null +++ b/src/core/init/create_stream_clock.ts @@ -0,0 +1,94 @@ +/** + * 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. + */ + +import { + combineLatest as observableCombineLatest, + merge as observableMerge, + Observable, +} from "rxjs"; +import { + ignoreElements, + map, + tap, +} from "rxjs/operators"; +import Manifest from "../../manifest"; +import { IStreamOrchestratorClockTick } from "../stream"; +import { IInitClockTick } from "./types"; + +export interface IStreamClockArguments { + autoPlay : boolean; // If true, the player will auto-play when initialPlay$ emits + initialPlay$ : Observable; // The initial play has been done + initialSeek$ : Observable; // The initial seek has been done + manifest : Manifest; + speed$ : Observable; // The last speed requested by the user + startTime : number; // The time the player will seek when initialSeek$ emits +} + +/** + * Create clock Observable for the `Stream` part of the code. + * @param {Observable} initClock$ + * @param {Object} streamClockArgument + * @returns {Observable} + */ +export default function createStreamClock( + initClock$ : Observable, + { autoPlay, + initialPlay$, + initialSeek$, + manifest, + speed$, + startTime } : IStreamClockArguments +) : Observable { + let initialPlayPerformed = false; + let initialSeekPerformed = false; + + const updateIsPaused$ = initialPlay$.pipe( + tap(() => { initialPlayPerformed = true; }), + ignoreElements()); + + const updateTimeOffset$ = initialSeek$.pipe( + tap(() => { initialSeekPerformed = true; }), + ignoreElements()); + + const clock$ : Observable = + observableCombineLatest([initClock$, speed$]) + .pipe(map(([tick, speed]) => { + const { isLive } = manifest; + return { + position: tick.position, + getCurrentTime: tick.getCurrentTime, + duration: tick.duration, + isPaused: initialPlayPerformed ? tick.paused : + !autoPlay, + liveGap: isLive ? manifest.getMaximumPosition() - tick.position : + Infinity, + readyState: tick.readyState, + speed, + stalled: tick.stalled, + + // wantedTimeOffset is an offset to add to the timing's current time to have + // the "real" wanted position. + // For now, this is seen when the media element has not yet seeked to its + // initial position, the currentTime will most probably be 0 where the + // effective starting position will be _startTime_. + // Thus we initially set a wantedTimeOffset equal to startTime. + wantedTimeOffset: initialSeekPerformed ? 0 : + startTime - tick.position, + }; + })); + + return observableMerge(updateIsPaused$, updateTimeOffset$, clock$); +} diff --git a/src/core/init/initial_seek_and_play.ts b/src/core/init/initial_seek_and_play.ts index 77cf813132..158f9a64a1 100644 --- a/src/core/init/initial_seek_and_play.ts +++ b/src/core/init/initial_seek_and_play.ts @@ -15,138 +15,158 @@ */ import { - combineLatest as observableCombineLatest, - merge as observableMerge, + concat as observableConcat, Observable, - ReplaySubject, + of as observableOf, } from "rxjs"; import { - ignoreElements, - map, - tap, + catchError, + filter, + mapTo, + mergeMap, shareReplay, + take, + tap, } from "rxjs/operators"; -import Manifest from "../../manifest"; -import { IStreamOrchestratorClockTick } from "../stream"; -import tryBeginningPlayback, { - ILoadEvents, -} from "./try_beginning_playback"; -import tryInitialSeek from "./try_initial_seek"; +import { + play$, + shouldValidateMetadata, + shouldWaitForDataBeforeLoaded, + whenLoadedMetadata$, +} from "../../compat"; +import log from "../../log"; import { IInitClockTick } from "./types"; -/** Arguments for the `initialSeekAndPlay` function. */ -export interface IInitialSeekAndPlayArguments { - /** `true` if you want to play automatically when possible. */ - autoPlay : boolean; - /** Manifest linked to that content. */ - manifest : Manifest; - /** Always emits the last speed requested by the user. */ - speed$ : Observable; - /** The initial time you want to seek to. */ - startTime : number; - /** Perform an internal seek. */ - setCurrentTime: (nb: number) => void; -} +export type ILoadEvents = + "not-loaded-metadata" | // metadata are not loaded. Manual action required + "autoplay-blocked" | // loaded but autoplay is blocked by the browser + "autoplay" | // loaded and autoplayed succesfully + "loaded"; // loaded without autoplay enabled /** - * When the HTMLMediaElement is ready, perform if needed: - * - the initial seek - * - the initial autoplay operation - * - * Returns the following Observables: - * - * - `clock$`: The central observable performing both the seek and autoPlay. - * Also returns an updated clock's tick (which includes information such as - * the position offset until the seek is taken into account or the last - * wanted playback speed). - * - * - `loaded$`: An observable emitting events specifically related to the - * loading status. Will always emit its last value on subscription. - * - * @see ILoadEvents for more information. + * Emit once a "can-play" message as soon as the clock$ announce that the content + * can begin to be played. * - * @param {HTMLMediaElement} mediaElement - * @param {Observable} initClock$ - * @param {Object} streamClockArgument + * Warn you if the metadata is not yet loaded metadata by emitting a + * "not-loaded-metadata" message first. + * @param {Observable} clock$ * @returns {Observable} */ -export default function initialSeekAndPlay( +function canPlay( + clock$ : Observable, mediaElement : HTMLMediaElement, - initClock$ : Observable, - { autoPlay, - manifest, - speed$, - startTime, - setCurrentTime } : IInitialSeekAndPlayArguments -) : { - clock$: Observable; - loaded$ : Observable; + isDirectfile : boolean +) : Observable<"can-play"|"not-loaded-metadata"> { + const isLoaded$ = clock$.pipe( + filter((tick) => { + const { seeking, stalled, readyState, currentRange } = tick; + if (seeking || stalled !== null) { + return false; + } + if (!shouldWaitForDataBeforeLoaded( + isDirectfile, + mediaElement.hasAttribute("playsinline"))) { + return readyState >= 1 && mediaElement.duration > 0; + } + if (readyState >= 4 || (readyState === 3 && currentRange !== null)) { + return shouldValidateMetadata() ? mediaElement.duration > 0 : + true; + } + return false; + }), + take(1), + mapTo("can-play" as const) + ); + + if (shouldValidateMetadata() && mediaElement.duration === 0) { + return observableConcat( + observableOf("not-loaded-metadata" as const), + isLoaded$ + ); } -{ - /** - * `true` once the content is considered "loaded". - * This means it can begin to play. - */ - let isLoaded = false; - /** `true` once the seek to a protential initial position has been performed. */ - let isSeekDone = false; + return isLoaded$; +} - /** - * Emit loading-related events. - * As its own ReplaySubject to avoid polluting the more general clock$ - * Observable. */ - const loaded$ = new ReplaySubject(1); +/** + * Try to play content then handle autoplay errors. + * @param {HTMLMediaElement} - mediaElement + * @returns {Observable} + */ +function autoPlay$( + mediaElement: HTMLMediaElement +): Observable<"autoplay"|"autoplay-blocked"> { + return play$(mediaElement).pipe( + mapTo("autoplay" as const), + catchError((error : unknown) => { + if (error instanceof Error && error.name === "NotAllowedError") { + // auto-play was probably prevented. + log.warn("Init: Media element can't play." + + " It may be due to browser auto-play policies."); + return observableOf("autoplay-blocked" as const); + } else { + throw error; + } + }) + ); +} - /** - * Silent Observable (does not emit anything) which performs autoPlay if - * needed and which emits through `loaded$` the current loading status. - * Completes when done. - */ - const load$ = tryBeginningPlayback(initClock$, mediaElement, autoPlay, false).pipe( - tap((evt) => { - isLoaded = true; - loaded$.next(evt); +/** + * Returns two Observables: + * + * - seek$: when subscribed, will seek to the wanted started time as soon as + * it can. Emit and complete when done. + * + * - load$: when subscribed, will play if and only if the `mustAutoPlay` + * option is set as soon as it can. Emit and complete when done. + * When this observable emits, it also means that the content is `loaded` + * and can begin to play the current content. + * + * @param {Object} args + * @returns {Object} + */ +export default function seekAndLoadOnMediaEvents( + { clock$, + mediaElement, + startTime, + mustAutoPlay, + isDirectfile } : { clock$ : Observable; + isDirectfile : boolean; + mediaElement : HTMLMediaElement; + mustAutoPlay : boolean; + startTime : number|(() => number); } +) : { seek$ : Observable; load$ : Observable } { + const seek$ = whenLoadedMetadata$(mediaElement).pipe( + take(1), + tap(() => { + log.info("Init: Set initial time", startTime); + mediaElement.currentTime = typeof startTime === "function" ? startTime() : + startTime; }), - ignoreElements()); + shareReplay({ refCount: true }) + ); - /** - * Observable trying to perform the initial seek and emitting updated clock - * ticks. - */ - const clock$ = observableCombineLatest([initClock$, speed$]).pipe( - map(([tick, speed]) => { - /** True if the tick's position is at the right value */ - let isRightPosition = true; - if (!isSeekDone) { - isRightPosition = tick.position === startTime; - isSeekDone = tryInitialSeek(tick, mediaElement, startTime); - } - const liveGap = manifest.isLive ? manifest.getMaximumPosition() - tick.position : - Infinity; - return { - position: tick.position, - getCurrentTime: tick.getCurrentTime, - duration: tick.duration, - isPaused: isLoaded ? tick.paused : - !autoPlay, - liveGap, - readyState: tick.readyState, - speed, - stalled: tick.stalled, - - // wantedTimeOffset is an offset to add to the timing's current time to have - // the "real" wanted position. - // For now, this is seen when the media element has not yet seeked to its - // initial position, the currentTime will most probably be 0 where the - // effective starting position will be _startTime_. - // Thus we initially set a wantedTimeOffset equal to startTime. - wantedTimeOffset: isRightPosition ? 0 : - startTime - tick.position, - }; - })); + const load$ : Observable = seek$.pipe( + mergeMap(() => { + return canPlay(clock$, mediaElement, isDirectfile).pipe( + tap(() => log.info("Init: Can begin to play content")), + mergeMap((evt) => { + if (evt === "can-play") { + if (!mustAutoPlay) { + if (mediaElement.autoplay) { + log.warn("Init: autoplay is enabled on HTML media element. " + + "Media will play as soon as possible."); + } + return observableOf("loaded" as const); + } + return autoPlay$(mediaElement); + } + return observableOf(evt); + }) + ); + }), + shareReplay({ refCount: true }) + ); - return { loaded$, - clock$: observableMerge(load$, clock$).pipe( - shareReplay({ bufferSize: 1, refCount: true })) }; + return { seek$, load$ }; } diff --git a/src/core/init/initialize_directfile.ts b/src/core/init/initialize_directfile.ts index 5ca3e0a154..cca83fdf26 100644 --- a/src/core/init/initialize_directfile.ts +++ b/src/core/init/initialize_directfile.ts @@ -14,6 +14,11 @@ * limitations under the License. */ +/** + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. + */ + import { EMPTY, merge as observableMerge, @@ -40,9 +45,8 @@ import { IKeySystemOption } from "../eme"; import createEMEManager from "./create_eme_manager"; import EVENTS from "./events_generators"; import { IInitialTimeOptions } from "./get_initial_time"; +import seekAndLoadOnMediaEvents from "./initial_seek_and_play"; import throwOnMediaError from "./throw_on_media_error"; -import tryBeginningPlayback from "./try_beginning_playback"; -import tryInitialSeek from "./try_initial_seek"; import { IDirectfileEvent, IInitClockTick, @@ -133,6 +137,12 @@ export default function initializeDirectfileContent({ const initialTime = () => getDirectFileInitialTime(mediaElement, startAt); log.debug("Init: Initial time calculated:", initialTime); + const { seek$, load$ } = seekAndLoadOnMediaEvents({ clock$, + mediaElement, + startTime: initialTime, + mustAutoPlay: autoPlay, + isDirectfile: true }); + // Create EME Manager, an observable which will manage every EME-related // issue. const emeManager$ = linkURL$.pipe( @@ -167,7 +177,7 @@ export default function initializeDirectfileContent({ return evt.type === "eme-disabled" || evt.type === "attached-media-keys"; }), take(1), - mergeMapTo(tryBeginningPlayback(clock$, mediaElement, autoPlay, true)), + mergeMapTo(load$), mergeMap((evt) => { if (evt === "autoplay-blocked") { const error = new MediaError("MEDIA_ERR_BLOCKED_AUTOPLAY", @@ -183,10 +193,7 @@ export default function initializeDirectfileContent({ return observableOf(EVENTS.loaded(null)); })); - const initialSeek$ = clock$.pipe( - filter((tick) => tryInitialSeek(tick, mediaElement, initialTime)), - take(1), - ignoreElements()); + const initialSeek$ = seek$.pipe(ignoreElements()); return observableMerge(loadedEvent$, initialSeek$, diff --git a/src/core/init/load_on_media_source.ts b/src/core/init/load_on_media_source.ts index a51ed3a8ee..d323eedc87 100644 --- a/src/core/init/load_on_media_source.ts +++ b/src/core/init/load_on_media_source.ts @@ -38,10 +38,11 @@ import SegmentBuffersStore from "../segment_buffers"; import StreamOrchestrator, { IStreamOrchestratorOptions, } from "../stream"; +import createStreamClock from "./create_stream_clock"; import DurationUpdater from "./duration_updater"; import { maintainEndOfStream } from "./end_of_stream"; import EVENTS from "./events_generators"; -import initialSeekAndPlay from "./initial_seek_and_play"; +import seekAndLoadOnMediaEvents from "./initial_seek_and_play"; import StallAvoider, { IDiscontinuityEvent, } from "./stall_avoider"; @@ -117,22 +118,25 @@ export default function createMediaSourceLoader( /** Interface to create media buffers for loaded segments. */ const segmentBuffersStore = new SegmentBuffersStore(mediaElement, mediaSource); + const { seek$, load$ } = seekAndLoadOnMediaEvents({ clock$, + mediaElement, + startTime: initialTime, + mustAutoPlay: autoPlay, + isDirectfile: false }); - const { loaded$, - clock$: updatedClock$ } = initialSeekAndPlay(mediaElement, - clock$, - { autoPlay, - manifest, - setCurrentTime, - speed$, - startTime: initialTime }); + const initialPlay$ = load$.pipe(filter((evt) => evt !== "not-loaded-metadata")); - const isLoaded$ = loaded$.pipe(filter((evt) => evt !== "not-loaded-metadata")); - - const streamEvents$ = isLoaded$.pipe( + const streamEvents$ = initialPlay$.pipe( mergeMap(() => streamEventsEmitter(manifest, mediaElement, clock$)) ); + const streamClock$ = createStreamClock(clock$, { autoPlay, + initialPlay$, + initialSeek$: seek$, + manifest, + speed$, + startTime: initialTime }); + /** Cancel endOfStream calls when streams become active again. */ const cancelEndOfStream$ = new Subject(); @@ -141,7 +145,7 @@ export default function createMediaSourceLoader( // Creates Observable which will manage every Stream for the given Content. const streams$ = StreamOrchestrator({ manifest, initialPeriod }, - updatedClock$, + streamClock$, abrManager, segmentBuffersStore, segmentFetcherCreator, @@ -190,7 +194,7 @@ export default function createMediaSourceLoader( discontinuityUpdate$, setCurrentTime); - const loadedEvent$ = loaded$ + const loadedEvent$ = load$ .pipe(mergeMap((evt) => { if (evt === "autoplay-blocked") { const error = new MediaError("MEDIA_ERR_BLOCKED_AUTOPLAY", diff --git a/src/core/init/try_beginning_playback.ts b/src/core/init/try_beginning_playback.ts deleted file mode 100644 index 429490cfa3..0000000000 --- a/src/core/init/try_beginning_playback.ts +++ /dev/null @@ -1,133 +0,0 @@ -/** - * 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. - */ - -import { - concat as observableConcat, - Observable, - of as observableOf, -} from "rxjs"; -import { - catchError, - filter, - mapTo, - mergeMap, - take, -} from "rxjs/operators"; -import { - play$, - shouldValidateMetadata, - shouldWaitForDataBeforeLoaded, -} from "../../compat"; -import log from "../../log"; -import { IInitClockTick } from "./types"; - -export type ILoadEvents = - "not-loaded-metadata" | // metadata are not loaded. Manual action required - "autoplay-blocked" | // loaded but autoplay is blocked by the browser - "autoplay" | // loaded and autoplayed succesfully - "loaded"; // loaded without autoplay enabled - - -/** - * Try to play content then handle autoplay errors. - * @param {HTMLMediaElement} - mediaElement - * @returns {Observable} - */ -function tryToPlay$( - mediaElement: HTMLMediaElement -): Observable<"autoplay"|"autoplay-blocked"> { - return play$(mediaElement).pipe( - mapTo("autoplay" as const), - catchError((error : unknown) => { - if (error instanceof Error && error.name === "NotAllowedError") { - // auto-play was probably prevented. - log.warn("Init: Media element can't play." + - " It may be due to browser auto-play policies."); - return observableOf("autoplay-blocked" as const); - } else { - throw error; - } - }) - ); -} - -/** - * Listen to the `initClock$` to know when the autoPlay action can be triggered. - * Emit either one of these values: - * - "autoplay": The content is loaded and autoplay has been performed - * - "loaded": The constent is loaded without autoplay, as asked - * - "autoplay-blocked": The content is loaded but autoplay could not be - * performed due to browser restrictions. - * - "not-loaded-metadata" - * @param {Observable} initClock$ - * @param {HTMLMediaElement} mediaElement - * @param {boolean} autoPlay - * @param {boolean} isDirectfile - * @returns {Observable} - */ -export default function tryBeginningPlayback( - initClock$ : Observable, - mediaElement : HTMLMediaElement, - autoPlay : boolean, - isDirectfile : boolean -) : Observable { - /** - * Observable which will try to apply the autoplay setting then announced the - * content as loaded (or as "autoplay-blocked"). - */ - const beginPlayback$ = initClock$.pipe( - filter((tick) => { - const { seeking, stalled, readyState, currentRange } = tick; - if (seeking || stalled !== null) { - return false; - } - if (!shouldWaitForDataBeforeLoaded( - isDirectfile, - mediaElement.hasAttribute("playsinline"))) { - return readyState >= 1 && mediaElement.duration > 0; - } - if (readyState >= 4 || (readyState === 3 && currentRange !== null)) { - return shouldValidateMetadata() ? mediaElement.duration > 0 : - true; - } - return false; - }), - take(1), - mergeMap(() => { - if (!autoPlay) { - if (mediaElement.autoplay) { - log.warn("Init: autoplay is enabled on HTML media element. " + - "Media will play as soon as possible."); - } - return observableOf("loaded" as const); - } - return tryToPlay$(mediaElement); - })); - - if (!shouldValidateMetadata()) { - return beginPlayback$; - } - - return initClock$.pipe( - filter((tick) => tick.readyState >= 1), - mergeMap(() => { - if (mediaElement.duration === 0) { - return observableConcat(observableOf("not-loaded-metadata" as const), - beginPlayback$); - } - return beginPlayback$; - })); -} diff --git a/src/core/init/try_initial_seek.ts b/src/core/init/try_initial_seek.ts deleted file mode 100644 index eea88accf5..0000000000 --- a/src/core/init/try_initial_seek.ts +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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. - */ - -import { shouldWaitForSeekValidation } from "../../compat"; -import log from "../../log"; -import { IInitClockTick } from "./types"; - -/** - * Only if it's possible currently on the HTMLMediaElement, try to seek at the - * position indicated by `startTime`. - * - * Returns a boolean set to `true` if we're sure the seek has been taken into - * account, `false` if either we didn't seek or if we did but we are not yet - * sure it has been taken into account. - * @param {Object} tick - The currently Observed clock tick. - * @param {HTMLMediaElement} mediaElement - The HTMLMediaElement we want to seek - * on. - * @param {Number} startTime - The wanted starting position. - * @returns {boolean} - */ -export default function tryInitialSeek( - tick : IInitClockTick, - mediaElement : HTMLMediaElement, - startTime : number | (() => number) -) : boolean { - const initialTime = typeof startTime === "function" ? startTime() : - startTime; - const hasAlreadySeeked = mediaElement.currentTime > 0 || initialTime === 0; - if (tick.readyState >= 3 && hasAlreadySeeked) { - return true; - } else if (tick.event === "seeking" || tick.event === "seeked") { - return true; - } else if (tick.readyState === 0 && tick.event !== "loadedmetadata") { - return false; - } else { - if (mediaElement.currentTime === 0 && initialTime !== 0) { - // Perform initial seek if necessary - log.info("Init: Set initial time", initialTime); - mediaElement.currentTime = initialTime; - } - return !shouldWaitForSeekValidation() || - (tick.readyState >= 3 && - (initialTime === 0 || mediaElement.currentTime !== 0)); - } -} diff --git a/src/core/init/update_playback_rate.ts b/src/core/init/update_playback_rate.ts index daa6d81e78..f1edfeb538 100644 --- a/src/core/init/update_playback_rate.ts +++ b/src/core/init/update_playback_rate.ts @@ -27,7 +27,7 @@ import { tap, } from "rxjs/operators"; import log from "../../log"; -import { IStalledStatus } from "../api"; +import { IInitClockTick } from "./types"; export interface IPlaybackRateOptions { pauseWhenStalled? : boolean } @@ -38,7 +38,7 @@ export interface IPlaybackRateOptions { pauseWhenStalled? : boolean } * * @param {HTMLMediaElement} mediaElement * @param {Observable} speed$ - emit speed set by the user - * @param {Observable} clock$ - Emit current stalled status. + * @param {Observable} clock$ - Current playback conditions * @param {Object} options - Contains the following properties: * - pauseWhenStalled {Boolean|undefined} - true if the player * stalling should lead to a pause until it un-stalls. True by default. @@ -47,7 +47,7 @@ export interface IPlaybackRateOptions { pauseWhenStalled? : boolean } export default function updatePlaybackRate( mediaElement : HTMLMediaElement, speed$ : Observable, - clock$ : Observable<{ stalled : IStalledStatus | null }>, + clock$ : Observable, { pauseWhenStalled = true } : IPlaybackRateOptions ) : Observable { let forcePause$ : Observable; From 20aa29bab29e99d10edeeb9f612177241feef9ce Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Tue, 30 Mar 2021 19:05:10 +0200 Subject: [PATCH 54/75] init/compat: fix remaining errors after reverting what was done by the tizen branch --- src/compat/browser_detection.ts | 4 ++++ src/core/init/initial_seek_and_play.ts | 8 ++++++-- src/core/init/initialize_directfile.ts | 1 + src/core/init/load_on_media_source.ts | 1 + tests/integration/scenarios/dash_multi-track.js | 3 --- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/compat/browser_detection.ts b/src/compat/browser_detection.ts index 1c4bcda8e3..beeb3936ae 100644 --- a/src/compat/browser_detection.ts +++ b/src/compat/browser_detection.ts @@ -42,6 +42,9 @@ const isFirefox : boolean = !isNode && const isSamsungBrowser : boolean = !isNode && /SamsungBrowser/.test(navigator.userAgent); +const isTizen : boolean = !isNode && + /Tizen/.test(navigator.userAgent); + /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-call */ const isSafari : boolean = @@ -65,4 +68,5 @@ export { isSafari, isSafariMobile, isSamsungBrowser, + isTizen, }; diff --git a/src/core/init/initial_seek_and_play.ts b/src/core/init/initial_seek_and_play.ts index 158f9a64a1..466bc7167b 100644 --- a/src/core/init/initial_seek_and_play.ts +++ b/src/core/init/initial_seek_and_play.ts @@ -130,18 +130,22 @@ export default function seekAndLoadOnMediaEvents( mediaElement, startTime, mustAutoPlay, + setCurrentTime, isDirectfile } : { clock$ : Observable; isDirectfile : boolean; mediaElement : HTMLMediaElement; mustAutoPlay : boolean; + /** Perform an internal seek. */ + setCurrentTime: (nb: number) => void; startTime : number|(() => number); } ) : { seek$ : Observable; load$ : Observable } { const seek$ = whenLoadedMetadata$(mediaElement).pipe( take(1), tap(() => { log.info("Init: Set initial time", startTime); - mediaElement.currentTime = typeof startTime === "function" ? startTime() : - startTime; + const initialTime = typeof startTime === "function" ? startTime() : + startTime; + setCurrentTime(initialTime); }), shareReplay({ refCount: true }) ); diff --git a/src/core/init/initialize_directfile.ts b/src/core/init/initialize_directfile.ts index cca83fdf26..9be1badbe9 100644 --- a/src/core/init/initialize_directfile.ts +++ b/src/core/init/initialize_directfile.ts @@ -141,6 +141,7 @@ export default function initializeDirectfileContent({ mediaElement, startTime: initialTime, mustAutoPlay: autoPlay, + setCurrentTime, isDirectfile: true }); // Create EME Manager, an observable which will manage every EME-related diff --git a/src/core/init/load_on_media_source.ts b/src/core/init/load_on_media_source.ts index d323eedc87..293019c621 100644 --- a/src/core/init/load_on_media_source.ts +++ b/src/core/init/load_on_media_source.ts @@ -122,6 +122,7 @@ export default function createMediaSourceLoader( mediaElement, startTime: initialTime, mustAutoPlay: autoPlay, + setCurrentTime, isDirectfile: false }); const initialPlay$ = load$.pipe(filter((evt) => evt !== "not-loaded-metadata")); diff --git a/tests/integration/scenarios/dash_multi-track.js b/tests/integration/scenarios/dash_multi-track.js index 4c88b58f94..f26740dfae 100644 --- a/tests/integration/scenarios/dash_multi-track.js +++ b/tests/integration/scenarios/dash_multi-track.js @@ -156,9 +156,6 @@ describe("DASH multi-track content (SegmentTimeline)", function () { await sleep(10); - if (xhrMock.getLockedXHR().length > 1) { - console.log("!!!!!!!!!", JSON.stringify(xhrMock.getLockedXHR())); - } expect(xhrMock.getLockedXHR().length).to.equal(1); // Manifest request await xhrMock.flush(); await sleep(10); From 58f7e2ad8389ac6edeea3a4f7dccca0a14b2c97c Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Wed, 31 Mar 2021 10:17:58 +0200 Subject: [PATCH 55/75] update builds for v3.24.0 --- dist/rx-player.js | 806 ++++++++++++++++++++++-------------------- dist/rx-player.min.js | 2 +- 2 files changed, 416 insertions(+), 392 deletions(-) diff --git a/dist/rx-player.js b/dist/rx-player.js index b2769fa3ac..868d546a05 100644 --- a/dist/rx-player.js +++ b/dist/rx-player.js @@ -199,9 +199,9 @@ module.exports = __webpack_require__(5666); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "DQ": () => (/* binding */ HTMLElement_), /* harmony export */ "JJ": () => (/* binding */ MediaSource_), +/* harmony export */ "cX": () => (/* binding */ READY_STATES), /* harmony export */ "w": () => (/* binding */ VTTCue_) /* harmony export */ }); -/* unused harmony export READY_STATES */ /* harmony import */ var _utils_is_null_or_undefined__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1946); /* harmony import */ var _is_node__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2203); /** @@ -1671,6 +1671,7 @@ __webpack_require__.d(__webpack_exports__, { "Xe": () => (/* binding */ onKeyError$), "GJ": () => (/* binding */ onKeyMessage$), "eX": () => (/* binding */ onKeyStatusesChange$), + "K4": () => (/* binding */ onLoadedMetadata$), "yj": () => (/* binding */ onPictureInPictureEvent$), "Qt": () => (/* binding */ onPlayPause$), "gg": () => (/* binding */ onRemoveSourceBuffers$), @@ -1682,7 +1683,7 @@ __webpack_require__.d(__webpack_exports__, { "$x": () => (/* binding */ videoWidth$) }); -// UNUSED EXPORTS: onLoadedMetadata$, onTimeUpdate$ +// UNUSED EXPORTS: onTimeUpdate$ // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules var Observable = __webpack_require__(4379); @@ -8746,37 +8747,13 @@ function createEMEManager(mediaElement, keySystems, contentProtections$) { /***/ }), -/***/ 7247: +/***/ 8343: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; - -// EXPORTS -__webpack_require__.d(__webpack_exports__, { - "Z": () => (/* binding */ emitLoadedEventWhenReady) -}); - -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js -var of = __webpack_require__(8170); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/concat.js -var concat = __webpack_require__(9795); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mapTo.js -var mapTo = __webpack_require__(5602); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/catchError.js -var catchError = __webpack_require__(486); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/filter.js -var filter = __webpack_require__(6008); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/take.js -var take = __webpack_require__(1015); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMap.js -var mergeMap = __webpack_require__(7746); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/defer.js -var defer = __webpack_require__(1410); -// EXTERNAL MODULE: ./src/utils/cast_to_observable.ts -var cast_to_observable = __webpack_require__(8117); -// EXTERNAL MODULE: ./src/utils/rx-try_catch.ts -var rx_try_catch = __webpack_require__(5561); -;// CONCATENATED MODULE: ./src/compat/play.ts +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); /** * Copyright 2015 CANAL+ Group * @@ -8793,26 +8770,171 @@ var rx_try_catch = __webpack_require__(5561); * limitations under the License. */ +/** + * Construct a "loaded" event. + * @returns {Object} + */ +function loaded(segmentBuffersStore) { + return { + type: "loaded", + value: { + segmentBuffersStore: segmentBuffersStore + } + }; +} +/** + * Construct a "stalled" event. + * @param {Object|null} stalling + * @returns {Object} + */ +function stalled(stalling) { + return { + type: "stalled", + value: stalling + }; +} /** - * Call play on the media element on subscription and return the response as an - * observable. - * @param {HTMLMediaElement} mediaElement - * @returns {Observable} + * Construct a "stalled" event. + * @param {Object|null} stalling + * @returns {Object} */ -function play$(mediaElement) { - return (0,defer/* defer */.P)(function () { - return (// mediaElement.play is not always a Promise. In the improbable case it - // throws, I prefer still to catch to return the error wrapped in an - // Observable - (0,rx_try_catch/* default */.Z)(function () { - return (0,cast_to_observable/* default */.Z)(mediaElement.play()); - }, undefined) - ); - }); + +function unstalled() { + return { + type: "unstalled", + value: null + }; } +/** + * Construct a "decipherabilityUpdate" event. + * @param {Array.} arg + * @returns {Object} + */ + + +function decipherabilityUpdate(arg) { + return { + type: "decipherabilityUpdate", + value: arg + }; +} +/** + * Construct a "manifestReady" event. + * @param {Object} manifest + * @returns {Object} + */ + + +function manifestReady(manifest) { + return { + type: "manifestReady", + value: { + manifest: manifest + } + }; +} +/** + * Construct a "manifestUpdate" event. + * @returns {Object} + */ + + +function manifestUpdate() { + return { + type: "manifestUpdate", + value: null + }; +} +/** + * Construct a "representationChange" event. + * @param {string} type + * @param {Object} period + * @returns {Object} + */ + + +function nullRepresentation(type, period) { + return { + type: "representationChange", + value: { + type: type, + representation: null, + period: period + } + }; +} +/** + * construct a "warning" event. + * @param {error} value + * @returns {object} + */ + + +function warning(value) { + return { + type: "warning", + value: value + }; +} +/** + * construct a "reloading-media-source" event. + * @returns {object} + */ + + +function reloadingMediaSource() { + return { + type: "reloading-media-source", + value: undefined + }; +} + +var INIT_EVENTS = { + loaded: loaded, + decipherabilityUpdate: decipherabilityUpdate, + manifestReady: manifestReady, + manifestUpdate: manifestUpdate, + nullRepresentation: nullRepresentation, + reloadingMediaSource: reloadingMediaSource, + stalled: stalled, + unstalled: unstalled, + warning: warning +}; +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (INIT_EVENTS); + +/***/ }), + +/***/ 2795: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "Z": () => (/* binding */ seekAndLoadOnMediaEvents) +}); + +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/concat.js +var concat = __webpack_require__(9795); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/of.js +var of = __webpack_require__(8170); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/filter.js +var filter = __webpack_require__(6008); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/take.js +var take = __webpack_require__(1015); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mapTo.js +var mapTo = __webpack_require__(5602); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/catchError.js +var catchError = __webpack_require__(486); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/tap.js +var tap = __webpack_require__(3068); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/shareReplay.js +var shareReplay = __webpack_require__(7006); +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMap.js +var mergeMap = __webpack_require__(7746); // EXTERNAL MODULE: ./src/compat/browser_detection.ts var browser_detection = __webpack_require__(3666); ;// CONCATENATED MODULE: ./src/compat/should_wait_for_data_before_loaded.ts @@ -8875,9 +8997,13 @@ function shouldWaitForDataBeforeLoaded(isDirectfile, mustPlayInline) { function shouldValidateMetadata() { return browser_detection/* isSamsungBrowser */.op; } -// EXTERNAL MODULE: ./src/log.ts + 1 modules -var log = __webpack_require__(3887); -;// CONCATENATED MODULE: ./src/core/init/emit_loaded_event.ts +// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/observable/defer.js +var defer = __webpack_require__(1410); +// EXTERNAL MODULE: ./src/utils/cast_to_observable.ts +var cast_to_observable = __webpack_require__(8117); +// EXTERNAL MODULE: ./src/utils/rx-try_catch.ts +var rx_try_catch = __webpack_require__(5561); +;// CONCATENATED MODULE: ./src/compat/play.ts /** * Copyright 2015 CANAL+ Group * @@ -8896,100 +9022,65 @@ var log = __webpack_require__(3887); - /** - * Try to play content then handle autoplay errors. - * @param {HTMLMediaElement} - mediaElement + * Call play on the media element on subscription and return the response as an + * observable. + * @param {HTMLMediaElement} mediaElement * @returns {Observable} */ -function tryToPlay$(mediaElement) { - return play$(mediaElement).pipe((0,mapTo/* mapTo */.h)("autoplay"), (0,catchError/* catchError */.K)(function (error) { - if (error instanceof Error && error.name === "NotAllowedError") { - // auto-play was probably prevented. - log/* default.warn */.Z.warn("Init: Media element can't play." + " It may be due to browser auto-play policies."); - return (0,of.of)("autoplay-blocked"); - } else { - throw error; - } - })); +function play$(mediaElement) { + return (0,defer/* defer */.P)(function () { + return (// mediaElement.play is not always a Promise. In the improbable case it + // throws, I prefer still to catch to return the error wrapped in an + // Observable + (0,rx_try_catch/* default */.Z)(function () { + return (0,cast_to_observable/* default */.Z)(mediaElement.play()); + }, undefined) + ); + }); } +// EXTERNAL MODULE: ./src/compat/browser_compatibility_types.ts +var browser_compatibility_types = __webpack_require__(3774); +// EXTERNAL MODULE: ./src/compat/event_listeners.ts + 4 modules +var event_listeners = __webpack_require__(1473); +;// CONCATENATED MODULE: ./src/compat/when_loaded_metadata.ts /** - * Listen to the `initClock$` to know when the autoPlay action can be triggered. - * Emit either one of these values: - * - "autoplay": The content is loaded and autoplay has been performed - * - "loaded": The constent is loaded without autoplay, as asked - * - "autoplay-blocked": The content is loaded but autoplay could not be - * performed due to browser restrictions. - * - "not-loaded-metadata" - * @param {Observable} initClock$ - * @param {HTMLMediaElement} mediaElement - * @param {boolean} autoPlay - * @param {boolean} isDirectfile - * @returns {Observable} + * 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 emitLoadedEventWhenReady(initClock$, mediaElement, autoPlay, isDirectfile) { - /** - * Observable which will try to apply the autoplay setting then announced the - * content as loaded (or as "autoplay-blocked"). - */ - var beginPlayback$ = initClock$.pipe((0,filter/* filter */.h)(function (tick) { - var seeking = tick.seeking, - stalled = tick.stalled, - readyState = tick.readyState, - currentRange = tick.currentRange; - - if (seeking || stalled !== null) { - return false; - } - - if (!shouldWaitForDataBeforeLoaded(isDirectfile, mediaElement.hasAttribute("playsinline"))) { - return readyState >= 1 && mediaElement.duration > 0; - } - - if (readyState >= 4 || readyState === 3 && currentRange !== null) { - return shouldValidateMetadata() ? mediaElement.duration > 0 : true; - } - - return false; - }), (0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.zg)(function () { - if (!autoPlay) { - if (mediaElement.autoplay) { - log/* default.warn */.Z.warn("Init: autoplay is enabled on HTML media element. " + "Media will play as soon as possible."); - } - return (0,of.of)("loaded"); - } - return tryToPlay$(mediaElement); - })); +/** + * Returns an observable emitting a single time, as soon as a seek is possible + * (the metadata are loaded). + * @param {HTMLMediaElement} mediaElement + * @returns {Observable} + */ - if (!shouldValidateMetadata()) { - return beginPlayback$; +function whenLoadedMetadata$(mediaElement) { + if (mediaElement.readyState >= browser_compatibility_types/* READY_STATES.HAVE_METADATA */.cX.HAVE_METADATA) { + return (0,of.of)(null); + } else { + return (0,event_listeners/* onLoadedMetadata$ */.K4)(mediaElement).pipe((0,take/* take */.q)(1)); } - - return initClock$.pipe((0,filter/* filter */.h)(function (tick) { - return tick.readyState >= 1; - }), (0,mergeMap/* mergeMap */.zg)(function () { - if (mediaElement.duration === 0) { - return (0,concat/* concat */.z)((0,of.of)("not-loaded-metadata"), beginPlayback$); - } - - return beginPlayback$; - })); } - -/***/ }), - -/***/ 8343: -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -/* harmony export */ __webpack_require__.d(__webpack_exports__, { -/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) -/* harmony export */ }); +// EXTERNAL MODULE: ./src/log.ts + 1 modules +var log = __webpack_require__(3887); +;// CONCATENATED MODULE: ./src/core/init/initial_seek_and_play.ts /** * Copyright 2015 CANAL+ Group * @@ -9006,141 +9097,122 @@ function emitLoadedEventWhenReady(initClock$, mediaElement, autoPlay, isDirectfi * limitations under the License. */ -/** - * Construct a "loaded" event. - * @returns {Object} - */ -function loaded(segmentBuffersStore) { - return { - type: "loaded", - value: { - segmentBuffersStore: segmentBuffersStore - } - }; -} -/** - * Construct a "stalled" event. - * @param {Object|null} stalling - * @returns {Object} - */ -function stalled(stalling) { - return { - type: "stalled", - value: stalling - }; -} -/** - * Construct a "stalled" event. - * @param {Object|null} stalling - * @returns {Object} - */ - -function unstalled() { - return { - type: "unstalled", - value: null - }; -} /** - * Construct a "decipherabilityUpdate" event. - * @param {Array.} arg - * @returns {Object} + * Emit once a "can-play" message as soon as the clock$ announce that the content + * can begin to be played. + * + * Warn you if the metadata is not yet loaded metadata by emitting a + * "not-loaded-metadata" message first. + * @param {Observable} clock$ + * @returns {Observable} */ +function canPlay(clock$, mediaElement, isDirectfile) { + var isLoaded$ = clock$.pipe((0,filter/* filter */.h)(function (tick) { + var seeking = tick.seeking, + stalled = tick.stalled, + readyState = tick.readyState, + currentRange = tick.currentRange; -function decipherabilityUpdate(arg) { - return { - type: "decipherabilityUpdate", - value: arg - }; -} -/** - * Construct a "manifestReady" event. - * @param {Object} manifest - * @returns {Object} - */ + if (seeking || stalled !== null) { + return false; + } + if (!shouldWaitForDataBeforeLoaded(isDirectfile, mediaElement.hasAttribute("playsinline"))) { + return readyState >= 1 && mediaElement.duration > 0; + } -function manifestReady(manifest) { - return { - type: "manifestReady", - value: { - manifest: manifest + if (readyState >= 4 || readyState === 3 && currentRange !== null) { + return shouldValidateMetadata() ? mediaElement.duration > 0 : true; } - }; -} -/** - * Construct a "manifestUpdate" event. - * @returns {Object} - */ + return false; + }), (0,take/* take */.q)(1), (0,mapTo/* mapTo */.h)("can-play")); -function manifestUpdate() { - return { - type: "manifestUpdate", - value: null - }; + if (shouldValidateMetadata() && mediaElement.duration === 0) { + return (0,concat/* concat */.z)((0,of.of)("not-loaded-metadata"), isLoaded$); + } + + return isLoaded$; } /** - * Construct a "representationChange" event. - * @param {string} type - * @param {Object} period - * @returns {Object} + * Try to play content then handle autoplay errors. + * @param {HTMLMediaElement} - mediaElement + * @returns {Observable} */ -function nullRepresentation(type, period) { - return { - type: "representationChange", - value: { - type: type, - representation: null, - period: period +function autoPlay$(mediaElement) { + return play$(mediaElement).pipe((0,mapTo/* mapTo */.h)("autoplay"), (0,catchError/* catchError */.K)(function (error) { + if (error instanceof Error && error.name === "NotAllowedError") { + // auto-play was probably prevented. + log/* default.warn */.Z.warn("Init: Media element can't play." + " It may be due to browser auto-play policies."); + return (0,of.of)("autoplay-blocked"); + } else { + throw error; } - }; + })); } /** - * construct a "warning" event. - * @param {error} value - * @returns {object} + * Returns two Observables: + * + * - seek$: when subscribed, will seek to the wanted started time as soon as + * it can. Emit and complete when done. + * + * - load$: when subscribed, will play if and only if the `mustAutoPlay` + * option is set as soon as it can. Emit and complete when done. + * When this observable emits, it also means that the content is `loaded` + * and can begin to play the current content. + * + * @param {Object} args + * @returns {Object} */ -function warning(value) { - return { - type: "warning", - value: value - }; -} -/** - * construct a "reloading-media-source" event. - * @returns {object} - */ +function seekAndLoadOnMediaEvents(_ref) { + var clock$ = _ref.clock$, + mediaElement = _ref.mediaElement, + startTime = _ref.startTime, + mustAutoPlay = _ref.mustAutoPlay, + setCurrentTime = _ref.setCurrentTime, + isDirectfile = _ref.isDirectfile; + var seek$ = whenLoadedMetadata$(mediaElement).pipe((0,take/* take */.q)(1), (0,tap/* tap */.b)(function () { + log/* default.info */.Z.info("Init: Set initial time", startTime); + var initialTime = typeof startTime === "function" ? startTime() : startTime; + setCurrentTime(initialTime); + }), (0,shareReplay/* shareReplay */.d)({ + refCount: true + })); + var load$ = seek$.pipe((0,mergeMap/* mergeMap */.zg)(function () { + return canPlay(clock$, mediaElement, isDirectfile).pipe((0,tap/* tap */.b)(function () { + return log/* default.info */.Z.info("Init: Can begin to play content"); + }), (0,mergeMap/* mergeMap */.zg)(function (evt) { + if (evt === "can-play") { + if (!mustAutoPlay) { + if (mediaElement.autoplay) { + log/* default.warn */.Z.warn("Init: autoplay is enabled on HTML media element. " + "Media will play as soon as possible."); + } + return (0,of.of)("loaded"); + } -function reloadingMediaSource() { + return autoPlay$(mediaElement); + } + + return (0,of.of)(evt); + })); + }), (0,shareReplay/* shareReplay */.d)({ + refCount: true + })); return { - type: "reloading-media-source", - value: undefined + seek$: seek$, + load$: load$ }; } -var INIT_EVENTS = { - loaded: loaded, - decipherabilityUpdate: decipherabilityUpdate, - manifestReady: manifestReady, - manifestUpdate: manifestUpdate, - nullRepresentation: nullRepresentation, - reloadingMediaSource: reloadingMediaSource, - stalled: stalled, - unstalled: unstalled, - warning: warning -}; -/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (INIT_EVENTS); - /***/ }), /***/ 8969: @@ -9173,8 +9245,6 @@ var filter = __webpack_require__(6008); var take = __webpack_require__(1015); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/mergeMapTo.js var mergeMapTo = __webpack_require__(3756); -// EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/operators/tap.js -var tap = __webpack_require__(3068); // EXTERNAL MODULE: ./node_modules/rxjs/_esm5/internal/Observable.js + 3 modules var Observable = __webpack_require__(4379); // EXTERNAL MODULE: ./src/log.ts + 1 modules @@ -9226,10 +9296,10 @@ var media_error = __webpack_require__(3714); var defer_subscriptions = __webpack_require__(8025); // EXTERNAL MODULE: ./src/core/init/create_eme_manager.ts + 1 modules var create_eme_manager = __webpack_require__(4507); -// EXTERNAL MODULE: ./src/core/init/emit_loaded_event.ts + 3 modules -var emit_loaded_event = __webpack_require__(7247); // EXTERNAL MODULE: ./src/core/init/events_generators.ts var events_generators = __webpack_require__(8343); +// EXTERNAL MODULE: ./src/core/init/initial_seek_and_play.ts + 4 modules +var initial_seek_and_play = __webpack_require__(2795); // EXTERNAL MODULE: ./src/core/init/throw_on_media_error.ts var throw_on_media_error = __webpack_require__(2447); // EXTERNAL MODULE: ./src/core/init/update_playback_rate.ts @@ -9251,6 +9321,11 @@ var update_playback_rate = __webpack_require__(2983); * limitations under the License. */ +/** + * /!\ This file is feature-switchable. + * It always should be imported through the `features` object. + */ + @@ -9335,9 +9410,21 @@ function initializeDirectfileContent(_ref) { return getDirectFileInitialTime(mediaElement, startAt); }; - log/* default.debug */.Z.debug("Init: Initial time calculated:", initialTime); // Create EME Manager, an observable which will manage every EME-related + log/* default.debug */.Z.debug("Init: Initial time calculated:", initialTime); + + var _seekAndLoadOnMediaEv = (0,initial_seek_and_play/* default */.Z)({ + clock$: clock$, + mediaElement: mediaElement, + startTime: initialTime, + mustAutoPlay: autoPlay, + setCurrentTime: setCurrentTime, + isDirectfile: true + }), + seek$ = _seekAndLoadOnMediaEv.seek$, + load$ = _seekAndLoadOnMediaEv.load$; // Create EME Manager, an observable which will manage every EME-related // issue. + var emeManager$ = linkURL$.pipe((0,mergeMap/* mergeMap */.zg)(function () { return (0,create_eme_manager/* default */.Z)(mediaElement, keySystems, empty/* EMPTY */.E); }), (0,defer_subscriptions/* default */.Z)(), (0,share/* share */.B)()); // Translate errors coming from the media element into RxPlayer errors @@ -9362,7 +9449,7 @@ function initializeDirectfileContent(_ref) { } return evt.type === "eme-disabled" || evt.type === "attached-media-keys"; - }), (0,take/* take */.q)(1), (0,mergeMapTo/* mergeMapTo */.j)((0,emit_loaded_event/* default */.Z)(clock$, mediaElement, autoPlay, true)), (0,mergeMap/* mergeMap */.zg)(function (evt) { + }), (0,take/* take */.q)(1), (0,mergeMapTo/* mergeMapTo */.j)(load$), (0,mergeMap/* mergeMap */.zg)(function (evt) { if (evt === "autoplay-blocked") { var error = new media_error/* default */.Z("MEDIA_ERR_BLOCKED_AUTOPLAY", "Cannot trigger auto-play automatically: " + "your browser does not allow it."); return (0,of.of)(events_generators/* default.warning */.Z.warning(error), events_generators/* default.loaded */.Z.loaded(null)); @@ -9374,16 +9461,7 @@ function initializeDirectfileContent(_ref) { return (0,of.of)(events_generators/* default.loaded */.Z.loaded(null)); })); - var initialSeek$ = clock$.pipe((0,filter/* filter */.h)(function (tick) { - return tick.readyState > 0 || tick.event === "loadedmetadata"; - }), (0,take/* take */.q)(1), (0,tap/* tap */.b)(function () { - var startTime = initialTime(); - - if (mediaElement.currentTime !== startTime) { - log/* default.info */.Z.info("Init: Set initial time", startTime); - setCurrentTime(startTime); - } - }), (0,ignoreElements/* ignoreElements */.l)()); + var initialSeek$ = seek$.pipe((0,ignoreElements/* ignoreElements */.l)()); return (0,merge/* merge */.T)(loadedEvent$, initialSeek$, emeManager$, mediaError$, playbackRate$, stalled$); } @@ -9489,7 +9567,7 @@ function throwOnMediaError(mediaElement) { * * @param {HTMLMediaElement} mediaElement * @param {Observable} speed$ - emit speed set by the user - * @param {Observable} clock$ - Emit current stalled status. + * @param {Observable} clock$ - Current playback conditions * @param {Object} options - Contains the following properties: * - pauseWhenStalled {Boolean|undefined} - true if the player * stalling should lead to a pause until it un-stalls. True by default. @@ -52740,6 +52818,70 @@ function StreamOrchestrator(content, clock$, abrManager, segmentBuffersStore, se /* harmony default export */ const stream = (orchestrator); +;// CONCATENATED MODULE: ./src/core/init/create_stream_clock.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 clock Observable for the `Stream` part of the code. + * @param {Observable} initClock$ + * @param {Object} streamClockArgument + * @returns {Observable} + */ + +function createStreamClock(initClock$, _ref) { + var autoPlay = _ref.autoPlay, + initialPlay$ = _ref.initialPlay$, + initialSeek$ = _ref.initialSeek$, + manifest = _ref.manifest, + speed$ = _ref.speed$, + startTime = _ref.startTime; + var initialPlayPerformed = false; + var initialSeekPerformed = false; + var updateIsPaused$ = initialPlay$.pipe((0,tap/* tap */.b)(function () { + initialPlayPerformed = true; + }), (0,ignoreElements/* ignoreElements */.l)()); + var updateTimeOffset$ = initialSeek$.pipe((0,tap/* tap */.b)(function () { + initialSeekPerformed = true; + }), (0,ignoreElements/* ignoreElements */.l)()); + var clock$ = (0,combineLatest/* combineLatest */.aj)([initClock$, speed$]).pipe((0,map/* map */.U)(function (_ref2) { + var tick = _ref2[0], + speed = _ref2[1]; + var isLive = manifest.isLive; + return { + position: tick.position, + getCurrentTime: tick.getCurrentTime, + duration: tick.duration, + isPaused: initialPlayPerformed ? tick.paused : !autoPlay, + liveGap: isLive ? manifest.getMaximumPosition() - tick.position : Infinity, + readyState: tick.readyState, + speed: speed, + stalled: tick.stalled, + // wantedTimeOffset is an offset to add to the timing's current time to have + // the "real" wanted position. + // For now, this is seen when the media element has not yet seeked to its + // initial position, the currentTime will most probably be 0 where the + // effective starting position will be _startTime_. + // Thus we initially set a wantedTimeOffset equal to startTime. + wantedTimeOffset: initialSeekPerformed ? 0 : startTime - tick.position + }; + })); + return (0,merge/* merge */.T)(updateIsPaused$, updateTimeOffset$, clock$); +} ;// CONCATENATED MODULE: ./src/core/init/duration_updater.ts /** * Copyright 2015 CANAL+ Group @@ -52951,136 +53093,8 @@ function maintainEndOfStream(mediaSource) { return triggerEndOfStream(mediaSource); })); } -// EXTERNAL MODULE: ./src/core/init/emit_loaded_event.ts + 3 modules -var emit_loaded_event = __webpack_require__(7247); -;// CONCATENATED MODULE: ./src/core/init/initial_seek_and_play.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. - */ - - - - -/** - * When the HTMLMediaElement is ready, perform if needed: - * - the initial seek - * - the initial autoplay operation - * - * Returns the following Observables: - * - * - `clock$`: The central observable performing both the seek and autoPlay. - * Also returns an updated clock's tick (which includes information such as - * the position offset until the seek is taken into account or the last - * wanted playback speed). - * - * - `loaded$`: An observable emitting events specifically related to the - * loading status. Will always emit its last value on subscription. - * - * @see ILoadEvents for more information. - * - * @param {HTMLMediaElement} mediaElement - * @param {Observable} initClock$ - * @param {Object} streamClockArgument - * @returns {Observable} - */ - -function initialSeekAndPlay(mediaElement, initClock$, _ref) { - var autoPlay = _ref.autoPlay, - manifest = _ref.manifest, - speed$ = _ref.speed$, - startTime = _ref.startTime, - setCurrentTime = _ref.setCurrentTime; - - /** - * `true` once the content is considered "loaded". - * This means it can begin to play. - */ - var isLoaded = false; - /** `true` once the seek to a protential initial position has been performed. */ - - var isSeekDone = false; - /** - * Emit loading-related events. - * As its own ReplaySubject to avoid polluting the more general clock$ - * Observable. - */ - - var loaded$ = new ReplaySubject/* ReplaySubject */.t(1); - /** - * Silent Observable (does not emit anything) which performs autoPlay if - * needed and which emits through `loaded$` the current loading status. - * Completes when done. - */ - - var load$ = (0,emit_loaded_event/* default */.Z)(initClock$, mediaElement, autoPlay, false).pipe((0,tap/* tap */.b)(function (evt) { - isLoaded = true; - loaded$.next(evt); - }), (0,ignoreElements/* ignoreElements */.l)()); - /** - * Observable trying to perform the initial seek and emitting updated clock - * ticks. - */ - - var clock$ = (0,combineLatest/* combineLatest */.aj)([initClock$, speed$]).pipe((0,map/* map */.U)(function (_ref2) { - var tick = _ref2[0], - speed = _ref2[1]; - - /** - * When this value is `false`, the `startTime` should be considered as - * the current position instead of the clock tick's `position` property. - * This is because that clock tick was triggered before the initial seek - * was done. - */ - var isTickPositionRight = isSeekDone; // perform initial seek, if ready and not already done - - if (!isSeekDone && (tick.readyState > 0 || tick.event === "loadedmetadata")) { - if (mediaElement.currentTime !== startTime) { - log/* default.info */.Z.info("Init: Set initial time", startTime); - setCurrentTime(startTime); - } - - isSeekDone = true; - } - - var liveGap = !manifest.isLive ? Infinity : isTickPositionRight ? manifest.getMaximumPosition() - tick.position : manifest.getMaximumPosition() - startTime; - return { - position: tick.position, - getCurrentTime: tick.getCurrentTime, - duration: tick.duration, - isPaused: isLoaded ? tick.paused : !autoPlay, - liveGap: liveGap, - readyState: tick.readyState, - speed: speed, - stalled: tick.stalled, - // wantedTimeOffset is an offset to add to the timing's current time to have - // the "real" wanted position. - // For now, this is seen when the media element has not yet seeked to its - // initial position, the currentTime will most probably be 0 where the - // effective starting position will be _startTime_. - // Thus we initially set a wantedTimeOffset equal to startTime. - wantedTimeOffset: isTickPositionRight ? 0 : startTime - }; - })); - return { - loaded$: loaded$, - clock$: (0,merge/* merge */.T)(load$, clock$).pipe((0,shareReplay/* shareReplay */.d)({ - bufferSize: 1, - refCount: true - })) - }; -} +// EXTERNAL MODULE: ./src/core/init/initial_seek_and_play.ts + 4 modules +var initial_seek_and_play = __webpack_require__(2795); ;// CONCATENATED MODULE: ./src/compat/is_playback_stuck.ts /** * Copyright 2015 CANAL+ Group @@ -53810,6 +53824,7 @@ var update_playback_rate = __webpack_require__(2983); + /** * Returns a function allowing to load or reload the content in arguments into * a single or multiple MediaSources. @@ -53850,22 +53865,31 @@ function createMediaSourceLoader(_ref) { var segmentBuffersStore = new segment_buffers(mediaElement, mediaSource); - var _initialSeekAndPlay = initialSeekAndPlay(mediaElement, clock$, { - autoPlay: autoPlay, - manifest: manifest, + var _seekAndLoadOnMediaEv = (0,initial_seek_and_play/* default */.Z)({ + clock$: clock$, + mediaElement: mediaElement, + startTime: initialTime, + mustAutoPlay: autoPlay, setCurrentTime: setCurrentTime, - speed$: speed$, - startTime: initialTime + isDirectfile: false }), - loaded$ = _initialSeekAndPlay.loaded$, - updatedClock$ = _initialSeekAndPlay.clock$; + seek$ = _seekAndLoadOnMediaEv.seek$, + load$ = _seekAndLoadOnMediaEv.load$; - var isLoaded$ = loaded$.pipe((0,filter/* filter */.h)(function (evt) { + var initialPlay$ = load$.pipe((0,filter/* filter */.h)(function (evt) { return evt !== "not-loaded-metadata"; })); - var streamEvents$ = isLoaded$.pipe((0,mergeMap/* mergeMap */.zg)(function () { + var streamEvents$ = initialPlay$.pipe((0,mergeMap/* mergeMap */.zg)(function () { return init_stream_events_emitter(manifest, mediaElement, clock$); })); + var streamClock$ = createStreamClock(clock$, { + autoPlay: autoPlay, + initialPlay$: initialPlay$, + initialSeek$: seek$, + manifest: manifest, + speed$: speed$, + startTime: initialTime + }); /** Cancel endOfStream calls when streams become active again. */ var cancelEndOfStream$ = new Subject/* Subject */.xQ(); @@ -53876,7 +53900,7 @@ function createMediaSourceLoader(_ref) { var streams$ = stream({ manifest: manifest, initialPeriod: initialPeriod - }, updatedClock$, abrManager, segmentBuffersStore, segmentFetcherCreator, bufferOptions).pipe((0,mergeMap/* mergeMap */.zg)(function (evt) { + }, streamClock$, abrManager, segmentBuffersStore, segmentFetcherCreator, bufferOptions).pipe((0,mergeMap/* mergeMap */.zg)(function (evt) { switch (evt.type) { case "end-of-stream": log/* default.debug */.Z.debug("Init: end-of-stream order received."); @@ -53920,7 +53944,7 @@ function createMediaSourceLoader(_ref) { */ var stallAvoider$ = StallAvoider(clock$, mediaElement, manifest, discontinuityUpdate$, setCurrentTime); - var loadedEvent$ = loaded$.pipe((0,mergeMap/* mergeMap */.zg)(function (evt) { + var loadedEvent$ = load$.pipe((0,mergeMap/* mergeMap */.zg)(function (evt) { if (evt === "autoplay-blocked") { var _error = new media_error/* default */.Z("MEDIA_ERR_BLOCKED_AUTOPLAY", "Cannot trigger auto-play automatically: " + "your browser does not allow it."); diff --git a/dist/rx-player.min.js b/dist/rx-player.min.js index 745d54fe7b..9f324b34c6 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(()=>{var e={3349:(e,t,n)=>{"use strict";function r(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}n.d(t,{Z:()=>r})},5991:(e,t,n)=>{"use strict";function r(e,t){for(var n=0;ni})},1788:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(4665);function i(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,(0,r.Z)(e,t)}},4665:(e,t,n)=>{"use strict";function r(e,t){return(r=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{Z:()=>r})},3786:(e,t,n)=>{"use strict";function r(e){return(r=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}n.d(t,{Z:()=>s});var i=n(4665);function a(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var a=new(Function.bind.apply(e,r));return n&&(0,i.Z)(a,n.prototype),a}).apply(null,arguments)}function s(e){var t="function"==typeof Map?new Map:void 0;return(s=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,a)}function a(){return o(e,arguments,r(this).constructor)}return a.prototype=Object.create(e.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),(0,i.Z)(a,e)})(e)}},7757:(e,t,n)=>{e.exports=n(5666)},3774:(e,t,n)=>{"use strict";n.d(t,{DQ:()=>a,JJ:()=>s,w:()=>o});var r=n(1946),i=n(2203).Z?{}:window,a=i.HTMLElement,o=(0,r.Z)(i.VTTCue)?i.TextTrackCue:i.VTTCue,s=(0,r.Z)(i.MediaSource)?(0,r.Z)(i.MozMediaSource)?(0,r.Z)(i.WebKitMediaSource)?i.MSMediaSource:i.WebKitMediaSource:i.MozMediaSource:i.MediaSource},3666:(e,t,n)=>{"use strict";n.d(t,{kD:()=>s,fq:()=>a,YM:()=>o,vU:()=>u,G6:()=>c,SB:()=>f,op:()=>l,yS:()=>d});var r,i=n(2203),a=!i.Z&&!!window.MSInputMethodContext&&!!document.documentMode,o=!i.Z&&("Microsoft Internet Explorer"===navigator.appName||"Netscape"===navigator.appName&&/(Trident|Edge)\//.test(navigator.userAgent)),s=!i.Z&&-1!==navigator.userAgent.toLowerCase().indexOf("edg/"),u=!i.Z&&-1!==navigator.userAgent.toLowerCase().indexOf("firefox"),l=!i.Z&&/SamsungBrowser/.test(navigator.userAgent),d=!i.Z&&/Tizen/.test(navigator.userAgent),c=!i.Z&&(Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>=0||"[object SafariRemoteNotification]"===(null===(r=window.safari)||void 0===r?void 0:r.pushNotification.toString())),f=!i.Z&&"string"==typeof navigator.platform&&/iPad|iPhone|iPod/.test(navigator.platform)},5767:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3887),i=n(3666);function a(e){if(i.vU){for(var t=e.textTracks,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:(e,t,n)=>{"use strict";n.d(t,{N:()=>D,Y:()=>H});var r,i=n(4944),a=n(8170),o=n(1410),s=n(3714),u=n(8117),l=n(3666),d=n(2203),c=n(5059),f=n(5991),p=n(9589),h=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 p.Z((function(t){return t(e._mediaKeys)}))},t.getConfiguration=function(){return this._configuration},(0,f.Z)(e,[{key:"keySystem",get:function(){return this._keyType}}]),e}(),v=n(1788),m=n(211),g=n(4370),y=n(1558),_=n(1959),b=n(1473);if(!d.Z){var T=window.MSMediaKeys;void 0!==T&&void 0!==T.prototype&&"function"==typeof T.isTypeSupported&&"function"==typeof T.prototype.createSession&&(r=T)}var E,w=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 m.xQ,n.closed=new p.Z((function(e){n._closeSession$.subscribe(e)})),n.update=function(e){return new p.Z((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 p.Z((function(e){n._ss=n._mk.createSession("video/mp4",t),(0,g.T)(b.GJ(n._ss),b.GV(n._ss),b.Xe(n._ss)).pipe((0,y.R)(n._closeSession$)).subscribe((function(e){return n.trigger(e.type,e)})),e()}))},n.close=function(){var e=this;return new p.Z((function(t){null!=e._ss&&(e._ss.close(),e._ss=void 0),e._closeSession$.next(),e._closeSession$.complete(),t()}))},n.load=function(){return p.Z.resolve(!1)},n.remove=function(){return p.Z.resolve()},(0,f.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}(_.Z),S=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 w(this._mediaKeys)},t.setServerCertificate=function(){throw new Error("Server certificate is not implemented in your browser")},e}();if(!d.Z){var k=window.MozMediaKeys;void 0!==k&&void 0!==k.prototype&&"function"==typeof k.isTypeSupported&&"function"==typeof k.prototype.createSession&&(E=k)}var A=n(9689),x=n(3635);function I(e){return"function"==typeof e.webkitGenerateKeyRequest}var Z=function(e){function t(t,n){var r;return(r=e.call(this)||this)._closeSession$=new m.xQ,r._vid=t,r._key=n,r.sessionId="",r.closed=new p.Z((function(e){r._closeSession$.subscribe(e)})),r.keyStatuses=new Map,r.expiration=NaN,(0,g.T)(b.GJ(t),b.GV(t),b.Xe(t)).pipe((0,y.R)(r._closeSession$)).subscribe((function(e){return r.trigger(e.type,e)})),r.update=function(e){return new p.Z((function(t,n){try{if(r._key.indexOf("clearkey")>=0){var i=e instanceof ArrayBuffer?new Uint8Array(e):e,a=JSON.parse((0,x.uR)(i)),o=(0,A.K)(a.keys[0].k),s=(0,A.K)(a.keys[0].kid);t(r._vid.webkitAddKey(r._key,o,s,""))}else t(r._vid.webkitAddKey(r._key,e,null,""))}catch(e){n(e)}}))},r}(0,v.Z)(t,e);var n=t.prototype;return n.generateRequest=function(e,t){var n=this;return new p.Z((function(e){n._vid.webkitGenerateKeyRequest(n._key,t),e()}))},n.close=function(){var e=this;return new p.Z((function(t){e._closeSession$.next(),e._closeSession$.complete(),t()}))},n.load=function(){return p.Z.resolve(!1)},n.remove=function(){return p.Z.resolve()},t}(_.Z),R=function(){function e(e){this._keySystem=e}var t=e.prototype;return t._setVideo=function(e){if(!I(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 Z(this._videoElement,this._keySystem)},t.setServerCertificate=function(){throw new Error("Server certificate is not implemented in your browser")},e}();var M=n(6968);var C=n(158);function N(e,t){if(void 0===e.webkitSetMediaKeys)throw new Error("No webKitMediaKeys API.");return e.webkitSetMediaKeys(t)}var P=function(e){function t(t,n,r){var i;return(i=e.call(this)||this)._serverCertificate=r,i._closeSession$=new m.xQ,i._videoElement=t,i._keyType=n,i.closed=new p.Z((function(e){i._closeSession$.subscribe(e)})),i.keyStatuses=new Map,i.expiration=NaN,i.update=function(e){return new p.Z((function(t,n){if(void 0===i._nativeSession||void 0===i._nativeSession.update||"function"!=typeof i._nativeSession.update)return n("Unavailable WebKit key session.");try{t(i._nativeSession.update(e))}catch(e){n(e)}}))},i}(0,v.Z)(t,e);var n=t.prototype;return n.listenEvent=function(e){var t=this;(0,g.T)(b.GJ(e),b.GV(e),b.Xe(e)).pipe((0,y.R)(this._closeSession$)).subscribe((function(e){t.trigger(e.type,e)}))},n.generateRequest=function(e,t){var n=this;return new p.Z((function(e){if(void 0===n._videoElement.webkitKeys||void 0===n._videoElement.webkitKeys.createSession)throw new Error("No WebKitMediaKeys API.");var r,i;if("com.apple.fps.1_0"===(i=n._keyType)||"com.apple.fps.2_0"===i){if(void 0===n._serverCertificate)throw new Error("A server certificate is needed for creating fairplay session.");r=function(e,t){var n=e instanceof Uint8Array?e:new Uint8Array(e),r=t instanceof Uint8Array?t:new Uint8Array(t);if((0,M.dN)(n,0)+4!==n.length)throw new Error("Unsupported WebKit initData.");var i=(0,x.wV)(n),a=i.indexOf("skd://"),o=a>-1?i.substring(a+6):i,s=(0,x.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,M.O_)(s.byteLength),u),u+=4,l.set(s,u),u+=s.byteLength,l.set((0,M.O_)(r.byteLength),u),u+=4,l.set(r,u),l}(t,n._serverCertificate)}else r=t;var a=n._videoElement.webkitKeys.createSession("video/mp4",r);if(null==a)throw new Error("Impossible to get the key sessions");n.listenEvent(a),n._nativeSession=a,e()}))},n.close=function(){var e=this;return new p.Z((function(t,n){e._closeSession$.next(),e._closeSession$.complete(),void 0===e._nativeSession&&n("No session to close."),e._nativeSession.close(),t()}))},n.load=function(){return p.Z.resolve(!1)},n.remove=function(){return p.Z.resolve()},(0,f.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}(_.Z),O=function(){function e(e){if(void 0===C.t)throw new Error("No WebKitMediaKeys API.");this._keyType=e,this._mediaKeys=new C.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 N(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 P(this._videoElement,this._keyType,this._serverCertificate)},t.setServerCertificate=function(e){return this._serverCertificate=e,p.Z.resolve()},e}();var D=null,L=function(e,t){return"function"==typeof e.setMediaKeys?e.setMediaKeys(t):e.webkitSetMediaKeys?e.webkitSetMediaKeys(t):e.mozSetMediaKeys?e.mozSetMediaKeys(t):e.msSetMediaKeys&&null!==t?e.msSetMediaKeys(t):void 0};if(d.Z||null!=navigator.requestMediaKeySystemAccess&&!(0,c.Z)())D=function(e,t){return(0,u.Z)(navigator.requestMediaKeySystemAccess(e,t))};else{var B,U;if(I(HTMLVideoElement.prototype)){var F={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 R(e)},setMediaKeys:function(e,t){if(null!==t){if(!(t instanceof R))throw new Error("Custom setMediaKeys is supposed to be called with old webkit custom MediaKeys.");return t._setVideo(e)}}};B=F.isTypeSupported,U=F.createCustomMediaKeys,L=F.setMediaKeys}else if(void 0!==C.t){var z=function(){if(void 0===C.t)throw new Error("No WebKitMediaKeys API.");return{isTypeSupported:C.t.isTypeSupported,createCustomMediaKeys:function(e){return new O(e)},setMediaKeys:function(e,t){if(null===t)return N(e,t);if(!(t instanceof O))throw new Error("Custom setMediaKeys is supposed to be called with webkit custom MediaKeys.");return t._setVideo(e)}}}();B=z.isTypeSupported,U=z.createCustomMediaKeys,L=z.setMediaKeys}else if(l.fq&&void 0!==r){var K={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 S(e)},setMediaKeys:function(e,t){if(null!==t){if(!(t instanceof S))throw new Error("Custom setMediaKeys is supposed to be called with IE11 custom MediaKeys.");return t._setVideo(e)}}};B=K.isTypeSupported,U=K.createCustomMediaKeys,L=K.setMediaKeys}else if(void 0!==E){var V={isTypeSupported:function(e,t){if(void 0===E)throw new Error("No MozMediaKeys API.");return void 0!==t?E.isTypeSupported(e,t):E.isTypeSupported(e)},createCustomMediaKeys:function(e){if(void 0===E)throw new Error("No MozMediaKeys API.");return new E(e)},setMediaKeys:function(e,t){if(void 0===e.mozSetMediaKeys||"function"!=typeof e.mozSetMediaKeys)throw new Error("Can't set video on MozMediaKeys.");return e.mozSetMediaKeys(t)}};B=V.isTypeSupported,U=V.createCustomMediaKeys,L=V.setMediaKeys}else{var W=window.MediaKeys,G=function(){if(void 0===W)throw new s.Z("MEDIA_KEYS_NOT_SUPPORTED","No `MediaKeys` implementation found in the current browser.");if(void 0===W.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.")}};B=function(e){return G(),W.isTypeSupported(e)},U=function(e){return G(),new W(e)}}D=function(e,t){if(!B(e))return(0,i._)(void 0);for(var n=0;n{"use strict";var r;if(n.d(t,{t:()=>r}),!n(2203).Z){var i=window.WebKitMediaKeys;void 0!==i&&"function"==typeof i.isTypeSupported&&"function"==typeof i.prototype.createSession&&"function"==typeof HTMLMediaElement.prototype.webkitSetMediaKeys&&(r=i)}},1473:(e,t,n)=>{"use strict";n.d(t,{zh:()=>V,_K:()=>H,Oh:()=>re,C1:()=>q,Q1:()=>X,GV:()=>ae,Xe:()=>oe,GJ:()=>ie,eX:()=>se,yj:()=>G,Qt:()=>Q,gg:()=>ne,ik:()=>Y,d5:()=>j,ym:()=>ee,UA:()=>J,_E:()=>te,$x:()=>$});var r=n(4379),i=n(3306),a=new r.y(i.Z);var o=n(7027),s=n(4370),u=n(1410),l=n(8170),d=n(5142),c=n(6564),f=n(655),p=n(964),h=n(9914),v=n(979),m=n(2632);function g(e,t){void 0===t&&(t=p.P);var n=(0,h.J)(e)?+e-t.now():Math.abs(e);return function(e){return e.lift(new y(n,t))}}var y=function(){function e(e,t){this.delay=e,this.scheduler=t}return e.prototype.call=function(e,t){return t.subscribe(new _(e,this.delay,this.scheduler))},e}(),_=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.delay=n,i.scheduler=r,i.queue=[],i.active=!1,i.errored=!1,i}return f.ZT(t,e),t.dispatch=function(e){for(var t=e.source,n=t.queue,r=e.scheduler,i=e.destination;n.length>0&&n[0].time-r.now()<=0;)n.shift().notification.observe(i);if(n.length>0){var a=Math.max(0,n[0].time-r.now());this.schedule(e,a)}else this.unsubscribe(),t.active=!1},t.prototype._schedule=function(e){this.active=!0,this.destination.add(e.schedule(t.dispatch,this.delay,{source:this,destination:this.destination,scheduler:e}))},t.prototype.scheduleNotification=function(e){if(!0!==this.errored){var t=this.scheduler,n=new b(t.now()+this.delay,e);this.queue.push(n),!1===this.active&&this._schedule(t)}},t.prototype._next=function(e){this.scheduleNotification(m.P.createNext(e))},t.prototype._error=function(e){this.errored=!0,this.queue=[],this.destination.error(e),this.unsubscribe()},t.prototype._complete=function(){this.scheduleNotification(m.P.createComplete()),this.unsubscribe()},t}(v.L),b=function(){return function(e,t){this.time=e,this.notification=t}}(),T=n(7604),E={leading:!0,trailing:!1};T.Ds;function w(e,t,n){return void 0===t&&(t=p.P),void 0===n&&(n=E),function(r){return r.lift(new S(e,t,n.leading,n.trailing))}}var S=function(){function e(e,t,n,r){this.duration=e,this.scheduler=t,this.leading=n,this.trailing=r}return e.prototype.call=function(e,t){return t.subscribe(new k(e,this.duration,this.scheduler,this.leading,this.trailing))},e}(),k=function(e){function t(t,n,r,i,a){var o=e.call(this,t)||this;return o.duration=n,o.scheduler=r,o.leading=i,o.trailing=a,o._hasTrailingValue=!1,o._trailingValue=null,o}return f.ZT(t,e),t.prototype._next=function(e){this.throttled?this.trailing&&(this._trailingValue=e,this._hasTrailingValue=!0):(this.add(this.throttled=this.scheduler.schedule(A,this.duration,{subscriber:this})),this.leading?this.destination.next(e):this.trailing&&(this._trailingValue=e,this._hasTrailingValue=!0))},t.prototype._complete=function(){this._hasTrailingValue?(this.destination.next(this._trailingValue),this.destination.complete()):this.destination.complete()},t.prototype.clearThrottle=function(){var e=this.throttled;e&&(this.trailing&&this._hasTrailingValue&&(this.destination.next(this._trailingValue),this._trailingValue=null,this._hasTrailingValue=!1),e.unsubscribe(),this.remove(e),this.throttled=null)},t}(v.L);function A(e){e.subscriber.clearThrottle()}var x=n(5709),I=n(3485),Z=n(1931),R=n(6381),M=n(5602),C=n(944),N=n(6923),P=n(3774),O=n(2203),D=n(5059),L=["","webkit","moz","ms"],B=C.Z.INACTIVITY_DELAY,U=O.Z||null==window.devicePixelRatio||0===window.devicePixelRatio?1:window.devicePixelRatio;function F(e,t){return t.filter((function(t){return function(e,t){var n=document.createElement(e.tagName),r="on"+t;return r in n||(n.setAttribute(r,"return;"),"function"==typeof n[r])}(e,t)}))[0]}function z(e,t){var n,r=function(e,t){return e.reduce((function(e,n){return e.concat((null==t?L:t).map((function(e){return e+n})))}),[])}(e,t);return function(e){return e instanceof P.DQ?(void 0===n&&(n=F(e,r)),(0,N.Z)(n)?(0,o.R)(e,n):a):s.T.apply(void 0,r.map((function(t){return(0,o.R)(e,t)})))}}function K(){var e,t=document;null!=t.hidden?e="":null!=t.mozHidden?e="moz":null!=t.msHidden?e="ms":null!=t.webkitHidden&&(e="webkit");var n=(0,N.Z)(e)?e+"Hidden":"hidden",r=(0,N.Z)(e)?e+"visibilitychange":"visibilitychange";return(0,u.P)((function(){var e=document[n];return(0,o.R)(document,r).pipe((0,x.U)((function(){return!document[n]})),(0,I.O)(!e),(0,Z.x)())}))}function V(){return K().pipe((0,R.w)((function(e){return e?(0,l.of)(e):(0,l.of)(e).pipe(g(B))})))}function W(e,t){var n=t.width,r=t.height/(e.clientHeight/e.clientWidth);return Math.min(n,r)}function G(e){return(0,u.P)((function(){if(e.webkitSupportsPresentationMode&&"function"==typeof e.webkitSetPresentationMode){var t="picture-in-picture"===e.webkitPresentationMode;return(0,o.R)(e,"webkitpresentationmodechanged").pipe((0,x.U)((function(){return{isEnabled:"picture-in-picture"===e.webkitPresentationMode,pipWindow:null}})),(0,I.O)({isEnabled:t,pipWindow:null}))}var n={isEnabled:document.pictureInPictureElement&&document.pictureInPictureElement===e,pipWindow:null};return(0,s.T)((0,o.R)(e,"enterpictureinpicture").pipe((0,x.U)((function(e){return{isEnabled:!0,pipWindow:e.pictureInPictureWindow}}))),(0,o.R)(e,"leavepictureinpicture").pipe((0,M.h)({isEnabled:!1,pipWindow:null}))).pipe((0,I.O)(n))}))}function H(e){return(0,d.aj)([K(),e]).pipe((0,R.w)((function(e){var t=e[0];return e[1].isEnabled||t?(0,l.of)(!0):(0,l.of)(!1).pipe(g(B))})),(0,Z.x)())}function $(e,t){return(0,d.aj)([t,(0,c.F)(2e4).pipe((0,I.O)(null)),(0,o.R)(window,"resize").pipe(w(500),(0,I.O)(null))]).pipe((0,R.w)((function(t){var n=t[0];if(n.isEnabled){if(null!=n.pipWindow){var r=n.pipWindow,i=W(e,r);return(0,o.R)(r,"resize").pipe((0,I.O)(i*U),(0,x.U)((function(){return W(e,r)*U})))}return(0,l.of)(1/0)}return(0,l.of)(e.clientWidth*U)})),(0,Z.x)())}z(["loadedmetadata"]);var j=z(["seeking"]),Y=z(["seeked"]),q=z(["ended"]),X=(z(["timeupdate"]),z(["fullscreenchange","FullscreenChange"],L.concat("MS"))),Q=function(e){return(0,s.T)(z(["play"])(e),z(["pause"])(e))},J=function(e){return(0,s.T)(z(["addtrack"])(e),z(["removetrack"])(e))},ee=z(["sourceopen","webkitsourceopen"]),te=z(["update"]),ne=z(["onremovesourcebuffer"]),re=z((0,D.Z)()?["needkey"]:["encrypted","needkey"]),ie=z(["keymessage","message"]),ae=z(["keyadded","ready"]),oe=z(["keyerror","error"]),se=z(["keystatuseschange"])},2203:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r="undefined"==typeof window},1988:(e,t,n)=>{"use strict";function r(e){return"function"==typeof window.VTTCue&&e instanceof window.VTTCue}n.d(t,{Z:()=>r})},7253:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3887),i=n(3774);function a(e,t,n){if(null==i.w)throw new Error("VTT cues not supported in your target");return e>=t?(r.Z.warn("Compat: Invalid cue times: "+e+" - "+t),null):new i.w(e,t,n)}},5059:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3666),i=n(158);function a(){return r.G6&&void 0!==i.t}},944:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const 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,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},BUFFER_DISCONTINUITY_THRESHOLD:.2,FORCE_DISCONTINUITY_SEEK_DELAY:2e3,BITRATE_REBUFFERING_RATIO:1.5,BUFFER_GC_GAPS:{CALM:240,BEEFY:30},DEFAULT_MAX_MANIFEST_REQUEST_RETRY:4,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},STALL_GAP:{DEFAULT:.5,LOW_LATENCY:.2},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_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS:50,EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION:1e3,EME_SESSION_CLOSING_MAX_RETRY:5,EME_SESSION_CLOSING_INITIAL_DELAY:100,EME_SESSION_CLOSING_MAX_DELAY:1e3,EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES:100,FORCED_ENDED_THRESHOLD:.001,ADAPTATION_SWITCH_BUFFER_PADDINGS:{video:{before:2,after:2.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}},7794:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(1788),i=n(1959),a=n(7829);function o(e,t){var n;if(t.length!==e.length)return!0;for(var r=0;r{"use strict";n.d(t,{ZP:()=>Qe});var r=n(8170),i=n(9795),a=n(4370),o=n(4944),s=n(2135),u=n(5631),l=n(7746),d=n(7006),c=n(6008),f=n(1015),p=n(3068),h=n(5709),v=n(486),m=n(6738),g=n(1473),y=n(3887),_=n(6490),b=n(4791),T=n(6968),E=n(3635),w=(0,T.pX)((0,E.tG)("pssh"),0);function S(e,t){for(var n=0;ne.length)return y.Z.warn("Compat: Unrecognized initialization data. Use as is."),[{systemId:void 0,data:e}];var i=e.subarray(n,n+r),a={systemId:(0,_.Y)(i,8),data:i};S(t,a)?y.Z.warn("Compat: Duplicated PSSH found in initialization data, removing it."):t.push(a),n+=r}return n!==e.length?(y.Z.warn("Compat: Unrecognized initialization data. Use as is."),[{systemId:void 0,data:e}]):t}(new Uint8Array(t))}}var A=n(1410),x=n(2297),I=n(8117);function Z(e,t,n){return(0,A.P)((function(){var r;y.Z.debug("Compat: Calling generateRequest on the MediaKeySession");try{r=function(e){y.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 y.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,x.Xj)(o),u=null===s?void 0:o[s[1]];y.Z.info("Compat: CENC PSSH found with version",u),void 0===u?y.Z.warn("Compat: could not read version of CENC PSSH"):t===(1===u)?n=(0,T.zo)(n,o):1===u?(y.Z.warn("Compat: cenc version 1 encountered, removing every other cenc pssh box."),n=o,t=!0):y.Z.warn("Compat: filtering out cenc pssh box with wrong version",u)}else r=(0,T.zo)(r,o);i+=a}if(i!==e.length)throw y.Z.warn("Compat: unrecognized initialization data. Cannot patch it."),new Error("Compat: unrecognized initialization data. Cannot patch it.");return(0,T.zo)(r,n)}(n)}catch(e){r=n}var i=null!=t?t:"";return(0,I.Z)(e.generateRequest(i,r)).pipe((0,v.K)((function(t){if(""!==i||!(t instanceof TypeError))throw t;return y.Z.warn('Compat: error while calling `generateRequest` with an empty initialization data type. Retrying with a default "cenc" value.',t),(0,I.Z)(e.generateRequest("cenc",r))})))}))}var R=n(944),M=n(5157),C=n(7714),N=n(8418),P=n(2793),O=n(1946);var D=n(5602),L=n(3485);var B=n(8821),U=n(9604),F=n(5561);function z(e){if(""===e.sessionId)return!1;var t=e.keyStatuses,n=[];return t.forEach((function(e){n.push(e)})),n.length<=0?(y.Z.debug("EME: isSessionUsable: MediaKeySession given has an empty keyStatuses",e),!1):(0,C.Z)(n,"expired")?(y.Z.debug("EME: isSessionUsable: MediaKeySession given has an expired key",e.sessionId),!1):(0,C.Z)(n,"internal-error")?(y.Z.debug("EME: isSessionUsable: MediaKeySession given has a key with an internal-error",e.sessionId),!1):(y.Z.debug("EME: isSessionUsable: MediaKeySession is usable",e.sessionId),!0)}function K(e,t,n){return(0,A.P)((function(){var i=e.loadedSessionsStore,a=e.persistentSessionsStore;return"temporary"===n?V(i,t):null===a?(y.Z.warn("EME: Cannot create persistent MediaKeySession, PersistentSessionsStore not created."),V(i,t)):function(e,t,n){return(0,A.P)((function(){y.Z.info("EME: Creating persistent MediaKeySession");var i=e.createSession(n,"persistent-license"),a=t.getAndReuse(n);if(null===a)return(0,r.of)({type:"created-session",value:{mediaKeySession:i,sessionType:"persistent-license"}});var o=function(){return y.Z.info("EME: Removing previous persistent session."),null!==t.get(n)&&t.delete(n),e.closeSession(n).pipe((0,h.U)((function(){return{type:"created-session",value:{mediaKeySession:e.createSession(n,"persistent-license"),sessionType:"persistent-license"}}})))};return function(e,t){return(0,A.P)((function(){return y.Z.info("Compat/EME: Load persisted session",t),(0,F.Z)((function(){return(0,I.Z)(e.load(t))}),void 0)})).pipe((0,l.zg)((function(t){return!t||e.keyStatuses.size>0?(0,r.of)(t):(0,B.S3)((0,U.H)(100),(0,g.eX)(e)).pipe((0,f.q)(1),(0,D.h)(t))})))}(i,a.sessionId).pipe((0,l.zg)((function(e){return e?e&&z(i)?(t.add(n,i),y.Z.info("EME: Succeeded to load persistent session."),(0,r.of)({type:"loaded-persistent-session",value:{mediaKeySession:i,sessionType:"persistent-license"}})):(y.Z.warn("EME: Previous persistent session not usable anymore."),o()):(y.Z.warn("EME: No data stored for the loaded session"),t.delete(n),(0,r.of)({type:"created-session",value:{mediaKeySession:i,sessionType:"persistent-license"}}))})),(0,v.K)((function(e){return y.Z.warn("EME: Unable to load persistent session: "+(e instanceof Error?e.toString():"Unknown Error")),o()})))}))}(i,a,t)}))}function V(e,t){return(0,A.P)((function(){y.Z.info("EME: Creating a new temporary session");var n=e.createSession(t,"temporary");return(0,r.of)({type:"created-session",value:{mediaKeySession:n,sessionType:"temporary"}})}))}var W=R.Z.EME_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS;function G(e,t,n){return(0,A.P)((function(){var o=null,s=t.loadedSessionsStore,d=t.persistentSessionsStore,c=s.getAndReuse(e);if(null!==c){if(z(o=c.mediaKeySession))return y.Z.info("EME: Reuse loaded session",o.sessionId),(0,r.of)({type:"loaded-open-session",value:{mediaKeySession:o,sessionType:c.sessionType,initializationData:e}});null!==d&&d.delete(e)}return(null!=o?s.closeSession(e):(0,r.of)(null)).pipe((0,l.zg)((function(){return(0,i.z)(function(e,t){if(t<0||t>=e.getLength())return u.E;for(var n=[],r=e.getAll().slice(),i=r.length-t,o=0;o=a.length){var n=new M.Z("INCOMPATIBLE_KEYSYSTEMS","No key system compatible with your wanted configuration has been found in the current browser.");return(0,o._)(n)}if(null==H.N){var r=Error("requestMediaKeySystemAccess is not implemented in your browser.");return(0,o._)(r)}var i=a[t],s=i.keyName,u=i.keyType,l=i.keySystemOptions,d=function(e,t){var n=["temporary"],r="optional",i="optional";!0===t.persistentLicense&&(r="required",n.push("persistent-license")),!0===t.persistentStateRequired&&(r="required"),!0===t.distinctiveIdentifierRequired&&(i="required");var a=null!=t.videoRobustnesses?t.videoRobustnesses:"widevine"===e?X:[],o=null!=t.audioRobustnesses?t.audioRobustnesses:"widevine"===e?X:[];return 0===a.length&&a.push(void 0),0===o.length&&o.push(void 0),[{initDataTypes:["cenc"],videoCapabilities:(0,q.Z)(a,(function(e){return[{contentType:'video/mp4;codecs="avc1.4d401e"',robustness:e},{contentType:'video/mp4;codecs="avc1.42e01e"',robustness:e},{contentType:'video/webm;codecs="vp8"',robustness:e}]})),audioCapabilities:(0,q.Z)(o,(function(e){return[{contentType:'audio/mp4;codecs="mp4a.40.2"',robustness:e},{contentType:"audio/webm;codecs=opus",robustness:e}]})),distinctiveIdentifier:i,persistentState:r,sessionTypes:n}]}(s,l);return y.Z.debug("EME: Request keysystem access "+u+","+(t+1)+" of "+a.length,d),(0,H.N)(u,d).pipe((0,h.U)((function(e){return y.Z.info("EME: Found compatible keysystem",u,d),{type:"create-media-key-system-access",value:{options:l,mediaKeySystemAccess:e}}})),(0,v.K)((function(){return y.Z.debug("EME: Rejected access to keysystem",u,d),e(t+1)})))}(0)}))}var te=n(2870),ne=new WeakMap;const re=function(e){ne.set(e,null)},ie=function(e,t){var n=t instanceof Uint8Array?t:new Uint8Array(t instanceof ArrayBuffer?t:t.buffer),r=(0,te.Z)(n);ne.set(e,{hash:r,serverCertificate:n})},ae=function(e){var t=ne.get(e);return void 0!==t&&(null!==t||void 0)},oe=function(e,t){var n=ne.get(e);if(null==n)return!1;var r=n.hash,i=n.serverCertificate,a=t instanceof Uint8Array?t:new Uint8Array(t instanceof ArrayBuffer?t:t.buffer);if((0,te.Z)(a)!==r||i.length!==a.length)return!1;for(var o=0;ose)return t(r);var o=Math.min(Math.pow(2,i)*ue,le);return y.Z.warn("EME: attempt to close a mediaKeySession failed, scheduling retry...",o),(0,B.S3)([(0,U.H)(o),(0,g.eX)(e),(0,g.GJ)(e)]).pipe((0,f.q)(1),(0,l.zg)((function(){return n(a)})))})))}(0);function t(e){return y.Z.error("EME: Could not close MediaKeySession: "+(e instanceof Error?e.toString():"Unknown error")),(0,r.of)(null)}}var ce=n(9689),fe=function(){function e(e){this.initData=e}return e.prototype.toJSON=function(){return(0,ce.J)(this.initData)},e.decode=function(e){return(0,ce.K)(e)},e}();function pe(e,t){var n,r;return null!==(r=null!==(n=he(e,t))&&void 0!==n?n:he(t,e))&&void 0!==r&&r}function he(e,t){if(0===e.length)return!1;if(t.length=0?this._storage[t].payload:void 0},t.getAndReuse=function(e){var t=this._findIndex(e);if(-1!==t){var n=this._storage.splice(t,1)[0];return this._storage.push(n),n.payload}},t.store=function(e,t){var n=this._findIndex(e);n>=0&&this._storage.splice(n,1);var r=this._formatValuesForStore(e.values);this._storage.push({type:e.type,values:r,payload:t})},t.storeIfNone=function(e,t){if(this._findIndex(e)>=0)return!1;var n=this._formatValuesForStore(e.values);return this._storage.push({type:e.type,values:n,payload:t}),!0},t.remove=function(e){var t=this._findIndex(e);if(-1!==t)return this._storage.splice(t,1)[0].payload},t._findIndex=function(e){for(var t=this._formatValuesForStore(e.values),n=this._storage.length-1;n>=0;n--){var r=this._storage[n];if(r.type===e.type&&pe(r.values,t))return n}return-1},t._formatValuesForStore=function(e){return e.slice().sort((function(e,t){return e.systemId===t.systemId?0:void 0===e.systemId?1:void 0===t.systemId||e.systemId=0?Oe(n):xe.y)})),T=function(e,t){return{totalRetry:null!=t?t:2,baseDelay:200,maxDelay:3e3,shouldRetry:function(e){return e instanceof Ie||(0,O.Z)(e)||!0!==e.noRetry},onRetry:function(t){return e.next({type:"warning",value:je(t)})}}}(d,f.retry);return(o=b,s=T,u=s.baseDelay,c=s.maxDelay,p=s.totalRetry,m=s.shouldRetry,g=s.onRetry,_=0,o.pipe((0,v.K)((function(e,t){if(!(0,O.Z)(m)&&!m(e)||_++>=p)throw e;"function"==typeof g&&g(e,_);var n=Math.min(u*Math.pow(2,_-1),c),r=(0,Le.Z)(n);return(0,U.H)(r).pipe((0,l.zg)((function(){return t})))})))).pipe((0,h.U)((function(t){return{type:"key-message-handled",value:{session:e,license:t}}})),(0,v.K)((function(e){var t=je(e);if(!(0,O.Z)(e)&&!0===e.fallbackOnLastTry)throw y.Z.warn("EME: Last `getLicense` attempt failed. Blacklisting the current session."),new Ge(t);throw t})),(0,L.O)({type:"session-message",value:{messageType:a,initializationData:i}}))}))),b=(0,a.T)(_,g).pipe((o=function(t){switch(t.type){case"key-message-handled":case"key-status-change-handled":return function(e,t,n){return(0,O.Z)(t)?(y.Z.info("EME: No message given, skipping session.update"),(0,r.of)({type:"no-update",value:{initializationData:n}})):(y.Z.info("EME: Updating MediaKeySession with message"),(0,I.Z)(e.update(t)).pipe((0,v.K)((function(e){var t=e instanceof Error?e.toString():"`session.update` failed";throw new M.Z("KEY_UPDATE_ERROR",t)})),(0,p.b)((function(){y.Z.info("EME: MediaKeySession update succeeded.")})),(0,D.h)({type:"session-updated",value:{session:e,license:t,initializationData:n}})))}(e,t.value.license,i);default:return(0,r.of)(t)}},(0,l.zg)(o,s,1))),T=(0,a.T)($e(e,t,n),b,m,d);return(0,O.Z)(e.closed)?T:T.pipe((0,De.R)((0,I.Z)(e.closed)))}function $e(e,t,n){return(0,A.P)((function(){if(0===e.keyStatuses.size)return u.E;var a=ze(e,t,n),o=a.warnings,s=a.blacklistedKeyIDs,l=a.whitelistedKeyIds,d=o.length>0?r.of.apply(void 0,o):u.E,c=(0,r.of)({type:"keys-update",value:{whitelistedKeyIds:l,blacklistedKeyIDs:s}});return(0,i.z)(d,c)}))}function je(e){if(e instanceof Ie)return new M.Z("KEY_LOAD_TIMEOUT","The license server took too much time to respond.");var t=new M.Z("KEY_LOAD_ERROR","An error occured when calling `getLicense`.");return!(0,O.Z)(e)&&(0,ye.Z)(e.message)&&(t.message=e.message),t}function Ye(e,t){return(0,A.P)((function(){return"function"!=typeof e.setServerCertificate?(y.Z.warn("EME: Could not set the server certificate. mediaKeys.setServerCertificate is not a function"),u.E):!0===ae(e)?(y.Z.info("EME: The MediaKeys already has a server certificate, skipping..."),u.E):(y.Z.info("EME: Setting server certificate on the MediaKeys"),re(e),function(e,t){return(0,A.P)((function(){return(0,F.Z)((function(){return(0,I.Z)(e.setServerCertificate(t))}),void 0).pipe((0,v.K)((function(e){y.Z.warn("EME: mediaKeys.setServerCertificate returned an error",e);var t=e instanceof Error?e.toString():"`setServerCertificate` error";throw new M.Z("LICENSE_SERVER_CERTIFICATE_ERROR",t)})))}))}(e,t).pipe((0,p.b)((function(){ie(e,t)})),(0,m.l)(),(0,v.K)((function(e){return(0,r.of)({type:"warning",value:e})}))))}))}var qe=R.Z.EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION,Xe=g.Oh;const Qe=function(e,t,n){y.Z.debug("EME: Starting EMEManager logic.");var g=new ve,_=new ve,E=Ee(e,t).pipe((0,l.zg)((function(e){if("attached-media-keys"!==e.type)return(0,r.of)(e);var t=e.value,n=t.mediaKeys,a=t.options.serverCertificate;return(0,O.Z)(a)?(0,r.of)(e):(0,i.z)(Ye(n,a),(0,r.of)(e))})),(0,d.d)()),w=E.pipe((0,c.h)((function(e){return"attached-media-keys"===e.type})),(0,f.q)(1)),S=Xe(e).pipe((0,p.b)((function(e){y.Z.debug("EME: Encrypted event received from media element.",e)})),(0,P.Z)((function(e){return k(e)}),null),(0,d.d)({refCount:!0})),A=n.pipe((0,p.b)((function(e){y.Z.debug("EME: Encrypted event received from Player",e)}))),x=(0,a.T)(A,S).pipe((0,l.zg)((function(e){return w.pipe((0,h.U)((function(t){return[e,t]})))})),(0,l.zg)((function(e){var t=e[0],n=e[1],i=n.value,d=i.mediaKeySystemAccess,c=i.stores,f=i.options,h=_.get(t);if(void 0!==h){if(void 0===t.type){y.Z.error("EME: The current session has already been blacklisted but the current content is not known. Throwing.");var E=h.sessionError;return E.fatal=!0,(0,o._)(E)}return y.Z.warn("EME: The current session has already been blacklisted. Blacklisting content."),(0,r.of)({type:"blacklist-protection-data",value:t})}var w,S=new s.t(1);if("content"===f.singleLicensePer&&!g.isEmpty()){var k=t.keyIds;if(void 0===k)return y.Z.warn("EME: Initialization data linked to unknown key id, we'll not able to fallback from it."),(0,r.of)({type:"init-data-ignored",value:{initializationData:t}});var A=g.getAll()[0];return A.lastKeyUpdate$.pipe((0,l.zg)((function(e){return k.every((function(t){for(var n=0;n=e.getLength())){var n=e.getLength(),r=n-t;y.Z.info("EME: Too many stored persistent sessions, removing some.",n,r),e.deleteOldSessions(r)}}(n,qe-1),n.add(t,i),s=!0}})),(0,v.K)((function(e){if(!(e instanceof Ge))throw e;_.store(t,e);var n=e.sessionError;if(void 0===t.type)throw y.Z.error("EME: Current session blacklisted and content not known. Throwing."),n.fatal=!0,n;return y.Z.warn("EME: Current session blacklisted. Blacklisting content."),(0,r.of)({type:"warning",value:n},{type:"blacklist-protection-data",value:t})})))})))):(y.Z.debug("EME: Init data already received. Skipping it."),(0,r.of)({type:"init-data-ignored",value:{initializationData:t}}))})));return(0,a.T)(E,S.pipe((0,h.U)((function(e){return{type:"encrypted-event-received",value:e}}))),x)}},6033:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=new WeakMap;const i={setState:function(e,t){r.set(e,t)},getState:function(e){var t=r.get(e);return void 0===t?null:t},clearState:function(e){r.set(e,null)}}},4507:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(4370),i=n(8170),a=n(5709),o=n(6139);var s=n(1473),u=n(5157),l=n(7874),d=n(3887),c=s.Oh;function f(e,t,n){var s=(0,r.T)(c(e),n);return null==l.Z.emeManager?(0,r.T)(s.pipe((0,a.U)((function(){throw d.Z.error("Init: Encrypted event but EME feature not activated"),new u.Z("MEDIA_IS_ENCRYPTED_ERROR","EME feature not activated.")}))),(0,i.of)({type:"eme-disabled"})):0===t.length?(0,r.T)(s.pipe((0,a.U)((function(){throw d.Z.error("Init: Ciphered media and no keySystem passed"),new u.Z("MEDIA_IS_ENCRYPTED_ERROR","Media is encrypted and no `keySystems` given")}))),(0,i.of)({type:"eme-disabled"})):"function"!=typeof o.N?(0,r.T)(s.pipe((0,a.U)((function(){throw d.Z.error("Init: Encrypted event but no EME API available"),new u.Z("MEDIA_IS_ENCRYPTED_ERROR","Encryption APIs not found.")}))),(0,i.of)({type:"eme-disabled"})):(d.Z.debug("Init: Creating EMEManager"),l.Z.emeManager(e,t,n))}},7247:(e,t,n)=>{"use strict";n.d(t,{Z:()=>g});var r=n(8170),i=n(9795),a=n(5602),o=n(486),s=n(6008),u=n(1015),l=n(7746),d=n(1410),c=n(8117),f=n(5561);var p=n(3666);function h(){return p.op}var v=n(3887);function m(e){return function(e){return(0,d.P)((function(){return(0,f.Z)((function(){return(0,c.Z)(e.play())}),void 0)}))}(e).pipe((0,a.h)("autoplay"),(0,o.K)((function(e){if(e instanceof Error&&"NotAllowedError"===e.name)return v.Z.warn("Init: Media element can't play. It may be due to browser auto-play policies."),(0,r.of)("autoplay-blocked");throw e})))}function g(e,t,n,a){var o=e.pipe((0,s.h)((function(e){var n=e.seeking,r=e.stalled,i=e.readyState,o=e.currentRange;return!n&&null===r&&(function(e,t){return!e||!p.SB||t}(a,t.hasAttribute("playsinline"))?(i>=4||3===i&&null!==o)&&(!h()||t.duration>0):i>=1&&t.duration>0)})),(0,u.q)(1),(0,l.zg)((function(){return n?m(t):(t.autoplay&&v.Z.warn("Init: autoplay is enabled on HTML media element. Media will play as soon as possible."),(0,r.of)("loaded"))})));return h()?e.pipe((0,s.h)((function(e){return e.readyState>=1})),(0,l.zg)((function(){return 0===t.duration?(0,i.z)((0,r.of)("not-loaded-metadata"),o):o}))):o}},8343:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r={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}}}},8969:(e,t,n)=>{"use strict";n.d(t,{Z:()=>S});var r=n(5631),i=n(8170),a=n(4370),o=n(7746),s=n(9095),u=n(6738),l=n(5709),d=n(6008),c=n(1015),f=n(3756),p=n(3068),h=n(4379),v=n(3887),m=n(5767);var g=n(3714),y=n(8025),_=n(4507),b=n(7247),T=n(8343),E=n(2447),w=n(2983);function S(e){var t=e.autoPlay,n=e.clock$,S=e.keySystems,k=e.mediaElement,A=e.speed$,x=e.setCurrentTime,I=e.startAt,Z=e.url;if((0,m.Z)(k),null==Z)throw new Error("No URL for a DirectFile content");var R=function(e,t){return new h.y((function(n){return v.Z.info("Setting URL to Element",t,e),e.src=t,n.next(void 0),function(){(0,m.Z)(e)}}))}(k,Z);v.Z.debug("Init: Calculating initial time");var M=function(){return 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 v.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}(k,I)};v.Z.debug("Init: Initial time calculated:",M);var C=R.pipe((0,o.zg)((function(){return(0,_.Z)(k,S,r.E)})),(0,y.Z)(),(0,s.B)()),N=(0,E.Z)(k),P=(0,w.Z)(k,A,n,{pauseWhenStalled:!0}).pipe((0,u.l)()),O=n.pipe((0,l.U)((function(e){return null===e.stalled?T.Z.unstalled():T.Z.stalled(e.stalled)}))),D=C.pipe((0,d.h)((function(e){return"created-media-keys"===e.type?(e.value.attachMediaKeys$.next(),!0):"eme-disabled"===e.type||"attached-media-keys"===e.type})),(0,c.q)(1),(0,f.j)((0,b.Z)(n,k,t,!0)),(0,o.zg)((function(e){if("autoplay-blocked"===e){var t=new g.Z("MEDIA_ERR_BLOCKED_AUTOPLAY","Cannot trigger auto-play automatically: your browser does not allow it.");return(0,i.of)(T.Z.warning(t),T.Z.loaded(null))}if("not-loaded-metadata"===e){var n=new g.Z("MEDIA_ERR_NOT_LOADED_METADATA","Cannot load automatically: your browser falsely announced having loaded the content.");return(0,i.of)(T.Z.warning(n))}return(0,i.of)(T.Z.loaded(null))}))),L=n.pipe((0,d.h)((function(e){return e.readyState>0||"loadedmetadata"===e.event})),(0,c.q)(1),(0,p.b)((function(){var e=M();k.currentTime!==e&&(v.Z.info("Init: Set initial time",e),x(e))})),(0,u.l)());return(0,a.T)(D,L,C,N,P,O)}},2447:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7027),i=n(7746),a=n(3714);function o(e){return(0,r.R)(e,"error").pipe((0,i.zg)((function(){switch(null==e.error?0:e.error.code){case 1:throw new a.Z("MEDIA_ERR_ABORTED","The fetching of the associated resource was aborted by the user's request.");case 2:throw new a.Z("MEDIA_ERR_NETWORK","A network error occurred which prevented the media from being successfully fetched");case 3:throw new a.Z("MEDIA_ERR_DECODE","An error occurred while trying to decode the media resource");case 4:throw new a.Z("MEDIA_ERR_SRC_NOT_SUPPORTED","The media resource has been found to be unsuitable.");default:throw new a.Z("MEDIA_ERR_UNKNOWN","The HTMLMediaElement errored due to an unknown reason.")}})))}},2983:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(8170),i=n(1410),a=n(5709),o=n(3485),s=n(1931),u=n(6381),l=n(3068),d=n(3887);function c(e,t,n,c){var f=c.pauseWhenStalled;return(void 0===f||f?n.pipe((0,a.U)((function(e){return null!==e.stalled})),(0,o.O)(!1),(0,s.x)()):(0,r.of)(!1)).pipe((0,u.w)((function(n){return n?(0,i.P)((function(){return d.Z.info("Init: Pause playback to build buffer"),e.playbackRate=0,(0,r.of)(0)})):t.pipe((0,l.b)((function(t){d.Z.info("Init: Resume playback speed",t),e.playbackRate=t})))})))}},7127:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l});var r=n(1788),i=n(1410),a=n(8170),o=n(3887),s=n(4123),u=n(4309);const l=function(e){function t(){var t;return o.Z.debug("ISB: Creating ImageSegmentBuffer"),(t=e.call(this)||this).bufferType="image",t._buffered=new u.Z,t}(0,r.Z)(t,e);var n=t.prototype;return n.pushChunk=function(e){var t=this;return(0,i.P)((function(){var n,r;if(o.Z.debug("ISB: appending new data."),null===e.data.chunk)return(0,a.of)(void 0);var i=e.data,s=i.appendWindow,u=i.chunk,l=u.start,d=u.end,c=u.timescale,f=null!==(n=s[0])&&void 0!==n?n:0,p=null!==(r=s[1])&&void 0!==r?r:1/0,h=l/c,v=d/c,m=Math.max(f,h),g=Math.min(p,v);return t._buffered.insert(m,g),null!==e.inventoryInfos&&t._segmentInventory.insertChunk(e.inventoryInfos),(0,a.of)(void 0)}))},n.removeBuffer=function(e,t){return(0,i.P)((function(){return o.Z.info("ISB: ignored image data remove order",e,t),(0,a.of)(void 0)}))},n.endOfSegment=function(e){var t=this;return(0,i.P)((function(){return t._segmentInventory.completeSegment(e),(0,a.of)(void 0)}))},n.getBufferedRanges=function(){return this._buffered},n.dispose=function(){o.Z.debug("ISB: disposing image SegmentBuffer"),this._buffered.remove(0,1/0)},t}(s.C)},5192:(e,t,n)=>{"use strict";n.d(t,{Z:()=>L});var r=n(1788),i=n(4370),a=n(6564),o=n(9795),s=n(8170),u=n(211),l=n(1410),d=n(3485),c=n(1198),f=n(5602),p=n(1558),h=n(1473),v=n(4379),m=n(5709),g=n(1931),y=n(3887),_=n(2203).Z?void 0:window.ResizeObserver;var b=n(944),T=n(4123),E=n(4309),w=n(7874);function S(e,t){return Math.abs(e-t)<=.2}function k(e,t){for(var n=e.length-1;n>=0;n--){if(e[n].startt)return e.slice(n,e.length)}return[]}function x(e,t,n){var r=Math.max(e.start,t),i=k(e.cues,t),a={start:e.start,end:r,cues:i},o=Math.min(n,e.end),s=A(e.cues,n);return[a,{start:o,end:e.end,cues:s}]}var I=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=A(a.cues,n),a.start=n;else{var o=x(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=k(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||S(i.end,t.end)?r[e]=i:(t.start>=i.end||(t.cues=A(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(S(s.end,n))return s.cues=k(s.cues,t),s.end=t,void r.splice(o+1,0,i);if(s.end>n){var u=x(s,t,n),l=u[0],d=u[1];return this._cuesBuffer[o]=l,r.splice(o+1,0,i),void r.splice(o+2,0,d)}for(s.cues=k(s.cues,t),s.end=t,s=r[o+1];void 0!==s&&n>s.end;)r.splice(o,1),s=r[o];return void a(o)}}r.push(i)},e}();function Z(e,t,n,r){for(var i=[t/n.columns,e/n.rows],a=r.getElementsByClassName("proportional-style"),o=0;o0}var R=h.C1,M=h.ik,C=h.d5,N=b.Z.MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL,P=b.Z.TEXT_TRACK_SIZE_CHECKS_INTERVAL;function O(e,t){try{e.removeChild(t)}catch(e){y.Z.warn("HTSB: Can't remove text track: not in the element.")}}function D(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}}const L=function(e){function t(t,n){var r;return y.Z.debug("HTSB: Creating HTMLTextSegmentBuffer"),(r=e.call(this)||this).bufferType="text",r._buffered=new E.Z,r._videoElement=t,r._textTrackElement=n,r._clearSizeUpdates$=new u.xQ,r._destroy$=new u.xQ,r._buffer=new I,r._currentCues=[],function(e){var t=C(e),n=M(e),r=R(e),u=(0,i.T)(n,r),l=(0,a.F)(N).pipe((0,d.O)(null));return u.pipe((0,d.O)(null),(0,c.c)((0,o.z)(l.pipe((0,f.h)(!0),(0,p.R)(t)),(0,s.of)(!1))))}(r._videoElement).pipe((0,p.R)(r._destroy$)).subscribe((function(e){if(e){var t=Math.max(r._videoElement.currentTime+N/1e3/2,0),n=r._buffer.get(t);0===n.length?r._disableCurrentCues():r._displayCues(n)}else r._disableCurrentCues()})),r}(0,r.Z)(t,e);var n=t.prototype;return n.pushChunk=function(e){var t=this;return(0,l.P)((function(){return t.pushChunkSync(e),(0,s.of)(void 0)}))},n.removeBuffer=function(e,t){var n=this;return(0,l.P)((function(){return n.removeBufferSync(e,t),(0,s.of)(void 0)}))},n.endOfSegment=function(e){var t=this;return(0,l.P)((function(){return t._segmentInventory.completeSegment(e),(0,s.of)(void 0)}))},n.getBufferedRanges=function(){return this._buffered},n.dispose=function(){y.Z.debug("HTSB: Disposing HTMLTextSegmentBuffer"),this._disableCurrentCues(),this._buffer.remove(0,1/0),this._buffered.remove(0,1/0),this._destroy$.next(),this._destroy$.complete()},n.pushChunkSync=function(e){var t,n;y.Z.debug("HTSB: Appending new html text tracks");var r=e.data,i=r.timestampOffset,a=r.appendWindow,o=r.chunk;if(null!==o){var s,u,l=o.start,d=o.end,c=o.data,f=o.type,p=o.language,h=null!==(t=a[0])&&void 0!==t?t:0,v=null!==(n=a[1])&&void 0!==n?n:1/0,m=function(e,t,n,r){y.Z.debug("HTSB: Finding parser for html text tracks:",e);var i=w.Z.htmlTextTracksParsers[e];if("function"!=typeof i)throw new Error("no parser found for the given text track");y.Z.debug("HTSB: Parser found, parsing...");var a=i(t,n,r);return y.Z.debug("HTTB: Parsed successfully!",a),a}(f,c,i,p);if(0!==h&&v!==1/0){for(var g=0;g=0&&m[g].start>=v;)g--;for(m.splice(g,m.length),g=m.length-1;g>=0&&m[g].end>v;)m[g].end=v,g--}if(void 0!==l)s=Math.max(h,l);else{if(m.length<=0)return void y.Z.warn("HTSB: Current text tracks have no cues nor start time. Aborting");y.Z.warn("HTSB: No start time given. Guessing from cues."),s=m[0].start}if(void 0!==d)u=Math.min(v,d);else{if(m.length<=0)return void y.Z.warn("HTSB: Current text tracks have no cues nor end time. Aborting");y.Z.warn("HTSB: No end time given. Guessing from cues."),u=m[m.length-1].end}u<=s?y.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(m,s,u),this._buffered.insert(s,u))}},n.removeBufferSync=function(e,t){y.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._clearSizeUpdates$.next(),this._currentCues.length>0){for(var e=0;e0&&function(e,t){return(0,l.P)((function(){if(void 0!==_){var n=-1,r=-1;return new v.y((function(t){var i=new _((function(e){if(0!==e.length){var i=e[0].contentRect,a=i.height,o=i.width;a===n&&o===r||(n=a,r=o,t.next({height:a,width:o}))}else y.Z.error("Compat: Resized but no observed element.")}));return i.observe(e),function(){i.disconnect()}}))}return(0,a.F)(t).pipe((0,d.O)(null),(0,m.U)((function(){var t=e.getBoundingClientRect();return{height:t.height,width:t.width}})),(0,g.x)((function(e,t){return e.height===t.height&&e.width===t.width})))}))}(this._textTrackElement,P).pipe((0,p.R)(this._clearSizeUpdates$),(0,p.R)(this._destroy$)).subscribe((function(e){for(var t=e.height,n=e.width,r=0;r{"use strict";n.d(t,{Z:()=>f});var r=n(1788),i=n(1410),a=n(8170),o=n(3666);var s=n(3887);function u(e,t){if(o.vU&&function(e,t){var n=e.activeCues;if(null===n)return!1;for(var r=0;r0?e.textTracks[u-1]:e.addTextTrack(s)).mode=t?null!==(n=i.HIDDEN)&&void 0!==n?n:"hidden":null!==(r=i.SHOWING)&&void 0!==r?r:"showing"}else a=document.createElement("track"),e.appendChild(a),i=a.track,a.kind=s,i.mode=t?"hidden":"showing";return{track:i,trackElement:a}}(t,n),a=i.track,u=i.trackElement;return r.bufferType="text",r._buffered=new d.Z,r._videoElement=t,r._track=a,r._trackElement=u,r}(0,r.Z)(t,e);var n=t.prototype;return n.pushChunk=function(e){var t=this;return(0,i.P)((function(){var n,r;if(s.Z.debug("NTSB: Appending new native text tracks"),null===e.data.chunk)return(0,a.of)(void 0);var i,o,u=e.data,l=u.timestampOffset,d=u.appendWindow,f=u.chunk,p=f.start,h=f.end,v=f.data,m=f.type,g=f.language,y=null!==(n=d[0])&&void 0!==n?n:0,_=null!==(r=d[1])&&void 0!==r?r:1/0,b=function(e,t,n,r){s.Z.debug("NTSB: Finding parser for native text tracks:",e);var i=c.Z.nativeTextTracksParsers[e];if("function"!=typeof i)throw new Error("no parser found for the given text track");s.Z.debug("NTSB: Parser found, parsing...");var a=i(t,n,r);return s.Z.debug("NTSB: Parsed successfully!",a),a}(m,v,l,g);if(0!==y&&_!==1/0){for(var T=0;T=0&&b[T].startTime>=_;)T--;for(b.splice(T,b.length),T=b.length-1;T>=0&&b[T].endTime>_;)b[T].endTime=_,T--}if(void 0!==p)i=Math.max(y,p);else{if(b.length<=0)return s.Z.warn("NTSB: Current text tracks have no cues nor start time. Aborting"),(0,a.of)(void 0);s.Z.warn("NTSB: No start time given. Guessing from cues."),i=b[0].startTime}if(void 0!==h)o=Math.min(_,h);else{if(b.length<=0)return s.Z.warn("NTSB: Current text tracks have no cues nor end time. Aborting"),(0,a.of)(void 0);s.Z.warn("NTSB: No end time given. Guessing from cues."),o=b[b.length-1].endTime}if(o<=i)return s.Z.warn("NTSB: Invalid text track appended: ","the start time is inferior or equal to the end time."),(0,a.of)(void 0);if(b.length>0){var E=b[0],w=t._track.cues;null!==w&&w.length>0&&E.startTime=0;i--){var a=r[i],o=a.startTime,l=a.endTime;o>=e&&o<=t&&l<=t&&u(n,a)}this._buffered.remove(e,t)},t}(l.C)},4123:(e,t,n)=>{"use strict";n.d(t,{C:()=>m,f:()=>v});var r=n(944),i=n(3887),a=n(5952),o=n(5278),s=r.Z.MAX_MANIFEST_BUFFERED_START_END_DIFFERENCE,u=r.Z.MAX_MANIFEST_BUFFERED_DURATION_DIFFERENCE,l=r.Z.MINIMUM_SEGMENT_SIZE,d=function(){function e(){this._inventory=[]}var t=e.prototype;return t.reset=function(){this._inventory.length=0},t.synchronizeBuffered=function(e){for(var t=this._inventory,n=0,r=t[0],a=null==r?void 0:r.infos.adaptation.type,s=e.length,u=0;u0){var g=t[f+m-1];v={end:(0,o.Z)(g.bufferedEnd,g.end),precizeEnd:g.precizeEnd},i.Z.debug("SI: "+m+" segments GCed.",a),t.splice(f,m),n=f}if(void 0===r)return;if(c-(0,o.Z)(r.bufferedStart,r.start)>=l){if(p(r,d,v,a),n===t.length-1)return void h(r,c,a);r=t[++n];for(var y=(0,o.Z)(r.bufferedStart,r.start),_=(0,o.Z)(r.bufferedEnd,r.end),b=u=l&&(void 0===b||c-y>=_-b);){var T=t[n-1];void 0===T.bufferedEnd&&(T.bufferedEnd=r.precizeStart?r.start:T.end,i.Z.debug("SI: calculating buffered end of contiguous segment",a,T.bufferedEnd,T.end)),r.bufferedStart=T.bufferedEnd,void 0!==(r=t[++n])&&(y=(0,o.Z)(r.bufferedStart,r.start),_=(0,o.Z)(r.bufferedEnd,r.end))}}var E=t[n-1];void 0!==E&&h(E,c,a)}}null!=r&&(i.Z.debug("SI: last segments have been GCed",a,n,t.length),t.splice(n,t.length-n)),void 0!==a&&"DEBUG"===i.Z.getLevel()&&i.Z.debug("SI: current "+a+" 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=s)i.Z.warn("SI: Invalid chunked inserted: starts before it ends",u,o,s);else{for(var l=this._inventory,d={partiallyPushed:!0,estimatedStart:o,start:o,end:s,precizeStart:!1,precizeEnd:!1,bufferedStart:void 0,bufferedEnd:void 0,infos:{segment:a,period:t,adaptation:n,representation:r}},c=l.length-1;c>=0;c--){var f=l[c];if(f.start<=o){if(f.end<=o){for(i.Z.debug("SI: Pushing segment strictly after previous one.",u,o,f.end),this._inventory.splice(c+1,0,d),c+=2;cd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,d.end,l[c].start),l[c].start=d.end,l[c].bufferedStart=void 0,void(l[c].precizeStart=l[c].precizeStart&&d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[c].start,l[c].end),l.splice(c,1)}return}if(f.start===o){if(f.end<=s){for(i.Z.debug("SI: Segment pushed replace another one",u,o,s,f.end),this._inventory.splice(c,1,d),c+=1;cd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,d.end,l[c].start),l[c].start=d.end,l[c].bufferedStart=void 0,void(l[c].precizeStart=l[c].precizeStart&&d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[c].start,l[c].end),l.splice(c,1)}return}return i.Z.debug("SI: Segment pushed ends before another with the same start",u,o,s,f.end),l.splice(c,0,d),f.start=d.end,f.bufferedStart=void 0,void(f.precizeStart=f.precizeStart&&d.precizeEnd)}if(f.end<=d.end){for(i.Z.debug("SI: Segment pushed updates end of previous one",u,o,s,f.start,f.end),this._inventory.splice(c+1,0,d),f.end=d.start,f.bufferedEnd=void 0,f.precizeEnd=f.precizeEnd&&d.precizeStart,c+=2;cd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,d.end,l[c].start),l[c].start=d.end,l[c].bufferedStart=void 0,void(l[c].precizeStart=l[c].precizeStart&&d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[c].start,l[c].end),l.splice(c,1)}return}i.Z.debug("SI: Segment pushed is contained in a previous one",u,o,s,f.start,f.end);var p={partiallyPushed:f.partiallyPushed,start:d.end,end:f.end,precizeStart:f.precizeStart&&f.precizeEnd&&d.precizeEnd,precizeEnd:f.precizeEnd,bufferedStart:void 0,bufferedEnd:f.end,infos:f.infos};return f.end=d.start,f.bufferedEnd=void 0,f.precizeEnd=f.precizeEnd&&d.precizeStart,l.splice(c+1,0,d),void l.splice(c+2,0,p)}}var h=this._inventory[0];if(void 0===h)return i.Z.debug("SI: first segment pushed",u,o,s),void this._inventory.push(d);if(!(h.start>=s)){if(h.end<=s){for(i.Z.debug("SI: Segment pushed starts before and completely recovers the previous first one",u,o,s,h.start,h.end),this._inventory.splice(0,1,d);l.length>1&&l[1].startd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,d.end,l[1].start),l[1].start=d.end,l[1].bufferedStart=void 0,void(l[1].precizeStart=d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[1].start,l[1].end),l.splice(1,1)}return}return i.Z.debug("SI: Segment pushed start of the next one",u,o,s,h.start,h.end),h.start=s,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",u,o,s,h.start),this._inventory.splice(0,0,d)}}},t.completeSegment=function(e){if(!e.segment.isInit){for(var t=this._inventory,n=!1,r=0;r0&&(this._inventory.splice(o+1,u),r-=u),this._inventory[o].partiallyPushed=!1,this._inventory[o].end=l,this._inventory[o].bufferedEnd=d}n||i.Z.warn("SI: Completed Segment not found",e)}},t.getInventory=function(){return this._inventory},e}();function c(e){if(void 0===e.bufferedStart||e.partiallyPushed)return!1;var t=e.start,n=e.end-t;return Math.abs(t-e.bufferedStart)<=s&&(void 0===e.bufferedEnd||e.bufferedEnd>e.bufferedStart&&Math.abs(e.bufferedEnd-e.bufferedStart-n)<=Math.min(u,n/3))}function f(e){if(void 0===e.bufferedEnd||e.partiallyPushed)return!1;var t=e.start,n=e.end,r=n-t;return Math.abs(n-e.bufferedEnd)<=s&&null!=e.bufferedStart&&e.bufferedEnd>e.bufferedStart&&Math.abs(e.bufferedEnd-e.bufferedStart-r)<=Math.min(u,r/3)}function p(e,t,n,r){void 0!==e.bufferedStart?(e.bufferedStartt&&(n.precizeEnd||e.start-n.end<=s)?(i.Z.debug("SI: buffered start is end of previous segment",r,t,e.start,n.end),e.bufferedStart=n.end,c(e)&&(e.start=n.end,e.precizeStart=!0)):e.start-t<=s?(i.Z.debug("SI: found true buffered start",r,t,e.start),e.bufferedStart=t,c(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<=s&&f(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<=s?(i.Z.debug("SI: found true buffered end",n,t,e.end),e.bufferedEnd=t,f(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 v,m=function(){function e(){this._segmentInventory=new d}var t=e.prototype;return t.synchronizeInventory=function(){this._segmentInventory.synchronizeBuffered(this.getBufferedRanges())},t.getInventory=function(){return this._segmentInventory.getInventory()},t.getPendingOperations=function(){return[]},e}();!function(e){e[e.Push=0]="Push",e[e.Remove=1]="Remove",e[e.EndOfSegment=2]="EndOfSegment"}(v||(v={}))},4309:(e,t,n)=>{"use strict";n.d(t,{Z:()=>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}()},3801:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3349),i=n(1788),a=function(e){function t(n){var i;return i=e.call(this)||this,Object.setPrototypeOf((0,r.Z)(i),t.prototype),i.name="AssertionError",i.message=n,i}return(0,i.Z)(t,e),t}((0,n(3786).Z)(Error))},5157:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(3349),i=n(1788),a=n(3786),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="EncryptedMediaError",a.type=o.ZB.ENCRYPTED_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))},5992:(e,t,n)=>{"use strict";n.d(t,{ZB:()=>r,br:()=>i,SM:()=>a});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:(e,t,n)=>{"use strict";function r(e,t,n){return e+" ("+t+") "+n}n.d(t,{Z:()=>r})},9822:(e,t,n)=>{"use strict";n.d(t,{Z:()=>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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(3349),i=n(1788),a=n(3786),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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(3349),i=n(1788),a=n(3786),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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(3349),i=n(1788),a=n(3786),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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3349),i=n(1788),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,s.xhr=o,s.status=i,s.type=a,s.message=a,s}return(0,i.Z)(t,e),t}((0,n(3786).Z)(Error))},7273:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r={directfile:null,emeManager:null,htmlTextTracksBuffer:null,htmlTextTracksParsers:{},imageBuffer:null,imageParser:null,nativeTextTracksBuffer:null,nativeTextTracksParsers:{},transports:{}}},7874:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=n(7273).Z},3887:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(8894);const 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},e}())},5952:(e,t,n)=>{"use strict";function r(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}n.d(t,{Z:()=>r})},1966:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>Z});var r=n(1788),i=n(4791),a=n(3274),o=n(1959),s=n(908),u=n(8806),l=n(3714),d=n(3887),c=n(7714),f=n(1946),p=n(7829);const h="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}))};var v=n(3774);const m=function(){function e(e,t){var n;this.id=e.id,this.bitrate=e.bitrate,this.codec=e.codecs,null!=e.height&&(this.height=e.height),null!=e.width&&(this.width=e.width),null!=e.mimeType&&(this.mimeType=e.mimeType),void 0!==e.contentProtections&&(this.contentProtections=e.contentProtections),null!=e.frameRate&&(this.frameRate=e.frameRate),this.index=e.index,this.isSupported="audio"!==t.type&&"video"!==t.type||(n=this.getMimeTypeString(),null!=v.JJ&&("function"!=typeof v.JJ.isTypeSupported||v.JJ.isTypeSupported(n)))}var t=e.prototype;return t.getMimeTypeString=function(){var e,t;return(null!==(e=this.mimeType)&&void 0!==e?e:"")+';codecs="'+(null!==(t=this.codec)&&void 0!==t?t:"")+'"'},t.getEncryptionData=function(e){for(var t,n=this.getAllEncryptionData(),r=[],i=0;i0&&!u){d.Z.warn("Incompatible codecs for adaptation",e);var y=new l.Z("MANIFEST_INCOMPATIBLE_CODECS_ERROR","An Adaptation contains only incompatible codecs.");this.parsingErrors.push(y)}}var t=e.prototype;return t.getAvailableBitrates=function(){for(var e=[],t=0;t0}));if(o.every((function(e){return!e.isSupported}))&&a.length>0&&("video"===i||"audio"===i))throw new l.Z("MANIFEST_PARSE_ERROR","No supported "+i+" adaptations");return o.length>0&&(r[i]=o),r}),{}),!Array.isArray(this.adaptations.video)&&!Array.isArray(this.adaptations.audio))throw new l.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,T.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,a.Z)(this.getAdaptations(),(function(t){var n=t.id;return e===n}))},t.getPlayableAdaptations=function(e){if(void 0===e)return this.getAdaptations().filter((function(e){return e.getPlayableRepresentations().length>0}));var t=this.adaptations[e];return void 0===t?[]:t.filter((function(e){return e.getPlayableRepresentations().length>0}))},e}(),w=function(){function e(e){this._mediaURLs=e.media}var t=e.prototype;return t.getInitSegment=function(){return null},t.getSegments=function(){return[{id:"0",isInit:!1,number:0,mediaURLs:[this._mediaURLs],time:0,end:Number.MAX_VALUE,duration:Number.MAX_VALUE,timescale:1}]},t.getFirstPosition=function(){},t.getLastPosition=function(){},t.shouldRefresh=function(){return!1},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},t.isSegmentStillAvailable=function(){return!0},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){return!0},t.isInitialized=function(){return!0},t._replace=function(){d.Z.warn("Tried to replace a static RepresentationIndex")},t._update=function(){d.Z.warn("Tried to update a static RepresentationIndex")},e}();!function(e){e[e.Full=0]="Full",e[e.Partial=1]="Partial"}(y||(y={}));var S=n(5138);function k(e,t,n){e.start=t.start,e.end=t.end,e.duration=t.duration;for(var r=e.getAdaptations(),i=t.getAdaptations(),o=function(e){var t=r[e],o=(0,a.Z)(i,(function(e){return e.id===t.id}));if(void 0===o)d.Z.warn('Manifest: Adaptation "'+r[e].id+'" not found when merging.');else for(var s=r[e].representations,u=o.representations,l=function(e){var t=s[e],r=(0,a.Z)(u,(function(e){return e.id===t.id}));void 0===r?d.Z.warn('Manifest: Representation "'+s[e].id+'" not found when merging.'):n===y.Full?t.index._replace(r.index):t.index._update(r.index)},c=0;c0&&r._addSupplementaryImageAdaptations(u),o.length>0&&r._addSupplementaryTextAdaptations(o),r}(0,r.Z)(t,e);var n=t.prototype;return n.getPeriod=function(e){return(0,a.Z)(this.periods,(function(t){return e===t.id}))},n.getPeriodForTime=function(e){return(0,a.Z)(this.periods,(function(t){return e>=t.start&&(void 0===t.end||t.end>e)}))},n.getNextPeriod=function(e){return(0,a.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,a.Z)(this.periods,(function(e){return void 0===e.end||t0&&this.trigger("decipherabilityUpdate",r)},n.addUndecipherableProtectionData=function(e){var t=I(this,(function(t){var n,r;if(!1===t.decipherable)return!1;for(var a=null!==(r=null===(n=t.contentProtections)||void 0===n?void 0:n.initData)&&void 0!==r?r:[],o=function(t){if((void 0===e.type||a[t].type===e.type)&&e.values.every((function(e){return a[t].values.some((function(t){return(void 0===e.systemId||t.systemId===e.systemId)&&(0,i.Z)(t.data,e.data)}))})))return{v:!1}},s=0;s0&&this.trigger("decipherabilityUpdate",t)},n.getAdaptations=function(){(0,u.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,u.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,u.Z)("manifest.getAdaptation(id) is deprecated. Please use manifest.period[].getAdaptation(id) instead"),(0,a.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,r=e.mimeType,i=e.url,a="gen-image-ada-"+A(),o="gen-image-rep-"+A(),s=new _({id:a,type:"image",representations:[{bitrate:0,id:o,mimeType:r,index:new w({media:i})}]},{isManuallyAdded:!0});return(n=t.parsingErrors).push.apply(n,s.parsingErrors),s}));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,a=n.url,o=n.language,s=n.languages,u=n.closedCaption,l=null!=o?[o]:null!=s?s:[];return e.concat(l.map((function(e){var n,o="gen-text-ada-"+A(),s="gen-text-rep-"+A(),l=new _({id:o,type:"text",language:e,closedCaption:u,representations:[{bitrate:0,id:s,mimeType:r,codecs:i,index:new w({media:a})}]},{isManuallyAdded:!0});return(n=t.parsingErrors).push.apply(n,l.parsingErrors),l})))}),[]);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.lifetime=e.lifetime,this.parsingErrors=e.parsingErrors,this.suggestedPresentationDelay=e.suggestedPresentationDelay,this.transport=e.transport,this.publishTime=e.publishTime,t===y.Full)this._timeBounds=e._timeBounds,this.uris=e.uris,function(e,t){for(var n=0,r=0;re.length)d.Z.error("Manifest: error when updating Periods");else{n0&&e.push.apply(e,l)}}(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.starti&&(e.splice(i,s-i),s=i),k(e[s],o,y.Full),i++}i0;){var r=this.periods[0];if(void 0===r.end||r.end>n)break;this.periods.shift()}}this.adaptations=void 0===this.periods[0]?{}:this.periods[0].adaptations,this.trigger("manifestUpdate",null)},t}(o.Z)},2689:(e,t,n)=>{"use strict";n.d(t,{s:()=>r});var r=Math.pow(2,32)-1},2297:(e,t,n)=>{"use strict";n.d(t,{iz:()=>o,t_:()=>a,Qy:()=>s,Xj:()=>l,nR:()=>u});var r=n(3887),i=n(6968);function a(e,t){var n=s(e,t);return null!==n?e.subarray(n[1],n[2]):null}function o(e,t){var n=s(e,t);return null!==n?e.subarray(n[0],n[2]):null}function s(e,t){for(var n,r,a=e.length,o=0,s=0;o+8<=a;){if(r=o,s=(0,i.pX)(e,r),r+=4,n=(0,i.pX)(e,r),r+=4,0===s)s=a-o;else if(1===s){if(r+8>a)return null;s=(0,i.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 u(e,t,n,r,a){for(var o,s=e.length,u=0;us)return;o=(0,i.pV)(e,l),l+=8}if(1970628964===d&&l+16<=s&&(0,i.pX)(e,l)===t&&(0,i.pX)(e,l+4)===n&&(0,i.pX)(e,l+8)===r&&(0,i.pX)(e,l+12)===a)return l+=16,e.subarray(l,u+o)}}function l(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,a=(0,i.pX)(e,n);n+=4;var o=(0,i.pX)(e,n);if(n+=4,0===a)a=t;else if(1===a){if(n+8>t)return r.Z.warn("ISOBMFF: box too short, cannot find offsets"),null;a=(0,i.pV)(e,n),n+=8}if(a<0)throw new Error("ISOBMFF: Size out of range");return 1970628964===o&&(n+=16),[0,n,a]}},6807:(e,t,n)=>{"use strict";n.d(t,{XA:()=>i,Le:()=>a,fs:()=>o,E3:()=>s});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.t_)(e,1835295092)}function o(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 s(e,t){return void 0===t&&(t=0),(0,r.t_)(e.subarray(t),1701671783)}},6490:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s,Y:()=>u});var r=n(3887);const 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))};var 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:(e,t,n)=>{"use strict";n.d(t,{LD:()=>c,Qx:()=>l,MM:()=>d,Wf:()=>u,J6:()=>f,s9:()=>p});var r=n(6968),i=n(3635),a=n(2689),o=n(2297),s=n(6807);function u(e,t){var n=(0,o.Qy)(e,1936286840);if(null===n)return null;var i=t,a=n[2]-n[0],s=n[1],u=e[s];s+=8;var l,d=(0,r.pX)(e,s);if(s+=4,0===u)l=(0,r.pX)(e,s),s+=4,i+=(0,r.pX)(e,s)+a,s+=4;else{if(1!==u)return null;l=(0,r.pV)(e,s),s+=8,i+=(0,r.pV)(e,s)+a,s+=8}var c=[];s+=2;var f=(0,r.zK)(e,s);for(s+=2;--f>=0;){var p=(0,r.pX)(e,s);s+=4;var h=2147483647&p;if(1===(2147483648&p)>>>31)throw new Error("sidx with reference_type `1` not yet implemented");var v=(0,r.pX)(e,s);s+=4,s+=4,c.push({time:l,duration:v,count:0,timescale:d,range:[i,i+h-1]}),l+=v,i+=h}return c}function l(e){var t=(0,s.XA)(e);if(null!==t){var n=(0,o.t_)(t,1952867444);if(null!==n){var i=n[0];return 1===i?(0,r.pV)(n,4):0===i?(0,r.pX)(n,4):void 0}}}function d(e){var t=(0,s.XA)(e);if(null!==t){var n=(0,o.t_)(t,1953658222);if(null!==n){var i=0,a=n[i];if(i+=1,!(a>1)){var u=(0,r.QI)(n,i);i+=3;var l=(256&u)>0,d=0;if(l||void 0!==(d=function(e){var t=(0,o.t_)(e,1952868452);if(null!==t){var n=1,i=(0,r.QI)(t,n);if(n+=3,(8&i)>0)return n+=4,(1&i)>0&&(n+=8),(2&i)>0&&(n+=4),(0,r.pX)(t,n)}}(t))){var c=(1&u)>0,f=(4&u)>0,p=(512&u)>0,h=(1024&u)>0,v=(2048&u)>0,m=(0,r.pX)(n,i);i+=4,c&&(i+=4),f&&(i+=4);for(var g=m,y=0;g-- >0;)l?(y+=(0,r.pX)(n,i),i+=4):y+=d,p&&(i+=4),h&&(i+=4),v&&(i+=4);return y}}}}}function c(e){var t=(0,s.fs)(e);if(null!==t){var n=(0,o.t_)(t,1835296868);if(null!==n){var i=0,a=n[i];return i+=4,1===a?(0,r.pX)(n,i+16):0===a?(0,r.pX)(n,i+8):void 0}}}function f(e){var t=e.length;if(t<4)throw new Error("Cannot update box length: box too short");var n=(0,r.pX)(e,0);if(0===n){if(t>a.s){var i=new Uint8Array(t+8);return i.set((0,r.kh)(1),0),i.set(e.subarray(4,8),4),i.set((0,r.el)(t+8),8),i.set(e.subarray(8,t),16),i}return e.set((0,r.kh)(t),0),e}if(1===n){if(t<16)throw new Error("Cannot update box length: box too short");return e.set((0,r.el)(t),8),e}if(t<=a.s)return e.set((0,r.kh)(t),0),e;var o=new Uint8Array(t+8);return o.set((0,r.kh)(1),0),o.set(e.subarray(4,8),4),o.set((0,r.el)(t+8),8),o.set(e.subarray(8,t),16),o}function p(e){for(var t=[],n=0;n{"use strict";n.d(t,{Z:()=>a});var r=n(6968),i=n(3635);const a=function(e){var t=0,n=e.length,a=(0,i.uR)(e.subarray(t+1,t+8));if(t+=8,137!==e[0]||"BIF\r\n\n"!==a)throw new Error("Invalid BIF file");var o=e[t],s=e[t+=1],u=e[t+=1],l=e[t+=1];t+=1;var d=[o,s,u,l].join(".");if(s>0)throw new Error("Unhandled version: "+s);var c=(0,r.dN)(e,t);t+=4;var f=(0,r.dN)(e,t);t+=4;var p=(0,i.uR)(e.subarray(t,t+4));t+=4;var h=(0,r.qb)(e,t);t+=2;var v=(0,r.qb)(e,t),m=[e[t+=2],e[t+1]].join(":"),g=1===e[t+=2];t=64;var y=[];if(0===c)throw new Error("bif: no images to parse");for(var _=0,b=null;t{"use strict";function r(e,t){for(;e.length>0;){var n=e[0];if(n.start>=t)return;if(n.repeatCount<=0)e.shift();else{var r=e[1];if(null!=r&&r.start<=t)e.shift();else{if(n.duration<=0)return;for(var i=n.start+n.duration,a=1;in.repeatCount)){var o=n.repeatCount-a;return n.start=i,void(n.repeatCount=o)}e.shift()}}}}n.d(t,{Z:()=>r})},3911:(e,t,n)=>{"use strict";function r(e,t,n){var r,i=e.repeatCount;return i>=0?i:(r=null!=t?t.start:null!=n?n:Number.MAX_VALUE,Math.ceil((r-e.start)/e.duration)-1)}function i(e,t,n){var i=e.start,a=e.duration;return a<=0?i:i+(r(e,t,n)+1)*a}function a(e,t){var n;return e*t.timescale+(null!==(n=t.indexTimeOffset)&&void 0!==n?n:0)}function o(e,t){var n;return(e-(null!==(n=t.indexTimeOffset)&&void 0!==n?n:0))/t.timescale}function s(e,t,n){return[e*n,(e+t)*n]}function u(e,t,n){var r=e.timeline,s=a(t,e);if(s<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,s);if(u<0||u>=r.length-1)return null;var l=r[u];if(l.duration<=0)return null;var d=r[u+1];if(void 0===d)return null;var c=d.start;return s>=i(l,d,n)&&sr,jH:()=>i,gT:()=>a,zG:()=>o,PZ:()=>s,_j:()=>u})},1091:(e,t,n)=>{"use strict";function r(e,t,n,r){for(var i=0;ie.time)return!1;if(o===e.time)return a.duration/n===e.duration&&(null==a.range?null==e.range:null!=e.range&&a.range[0]===e.range[0]&&a.range[1]===e.range[1]);if(a.repeatCount>=0&&null!=a.duration){var s=(o-a.start)/a.duration-1;return s%1==0&&s<=a.repeatCount}}return!1}n.d(t,{Z:()=>r})},5505:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(3714),i=n(3887),a=n(3911);function o(e,t){var n=e.length;if(0!==e.length){if(0!==t.length){var 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)return void e.splice.apply(e,[u,n-u].concat(t));if(lo)return i.Z.warn("RepresentationIndex: Manifest update removed previous segments"),void e.splice.apply(e,[u,n-u].concat(t));if(void 0===d.repeatCount||d.repeatCount<=0)return d.repeatCount<0&&(d.repeatCount=Math.floor((o-d.start)/d.duration)-1),void e.splice.apply(e,[u+1,n-(u+1)].concat(t));if(d.start+d.duration*(d.repeatCount+1)<=o)return void e.splice.apply(e,[u+1,n-(u+1)].concat(t));var c=(o-d.start)/d.duration-1;if(c%1==0&&d.duration===t[0].duration){var f=t[0].repeatCount<0?-1:t[0].repeatCount+c+1;return e.splice.apply(e,[u,n-u].concat(t)),e[u].start=d.start,void(e[u].repeatCount=f)}return i.Z.warn("RepresentationIndex: Manifest update removed previous segments"),e[u].repeatCount=Math.floor(c),void e.splice.apply(e,[u+1,n-(u+1)].concat(t))}}var p=e[e.length-1],h=t[t.length-1];if(void 0!==p.repeatCount&&p.repeatCount<0)return p.start>h.start?void i.Z.warn("RepresentationIndex: The new index is older than the previous one"):(i.Z.warn('RepresentationIndex: The new index is "bigger" than the previous one'),void e.splice.apply(e,[0,n].concat(t)));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"):(i.Z.warn('RepresentationIndex: The new index is "bigger" than the previous one'),e.splice.apply(e,[0,n].concat(t)))}}else e.splice.apply(e,[0,n].concat(t))}},5734:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(6923),i=/&#([0-9]+);/g,a=/
/gi,o=/]*>([\s\S]*?)<\/style[^>]*>/i,s=/\s*

]+))?>(.*)/i,u=/]+?start="?([0-9]*)"?[^0-9]/i;function l(e,t){var n=new RegExp("\\s*"+t+":\\s*(\\S+);","i").exec(e);return Array.isArray(n)?n[1]:null}const d=function(e,t,n){var d,c,f=/]/gi,p=/]|<\/body>/gi,h=[],v=o.exec(e),m=Array.isArray(v)?v[1]:"";p.exec(e);var g,y=function(e){for(var t=/\.(\S+)\s*{([^}]*)}/gi,n={},r=t.exec(e);null!==r;){var i=r[1],a=l(r[2],"lang");null!=i&&null!=a&&(n[a]=i),r=t.exec(e)}return n}(m),_=function(e){var t=/p\s*{([^}]*)}/gi.exec(e);return null===t?"":t[1]}(m);if((0,r.Z)(n)&&void 0===(g=y[n]))throw new Error("sami: could not find lang "+n+" in CSS");for(;d=f.exec(e),c=p.exec(e),null!==d||null!==c;){if(null===d||null===c||d.index>=c.index)throw new Error("parse error");var b=e.slice(d.index,c.index),T=u.exec(b);if(!Array.isArray(T))throw new Error("parse error (sync time attribute)");var E=+T[1];if(isNaN(E))throw new Error("parse error (sync time attribute NaN)");w(b.split("\n"),E/1e3)}return h;function w(e,n){for(var o=e.length;--o>=0;){var u=s.exec(e[o]);if(Array.isArray(u)){var l=u[1],d=u[2];if(g===l)if(" "===d)h[h.length-1].end=n;else{var c=document.createElement("DIV");c.className="rxp-texttrack-region";var f=document.createElement("DIV");f.className="rxp-texttrack-div",f.style.position="absolute",f.style.bottom="0",f.style.width="100%",f.style.color="#fff",f.style.textShadow="-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000";var p=document.createElement("div");p.className="rxp-texttrack-p",(0,r.Z)(_)&&(p.style.cssText=_);for(var v=d.split(a),m=0;m{"use strict";n.d(t,{Z:()=>c});var r=n(7253),i=n(6923),a=/&#([0-9]+);/g,o=/
/gi,s=/]*>([\s\S]*?)<\/style[^>]*>/i,u=/\s*

]+))?>(.*)/i,l=/]+?start="?([0-9]*)"?[^0-9]/i;function d(e,t){var n=new RegExp("\\s*"+t+":\\s*(\\S+);","i").exec(e);return Array.isArray(n)?n[1]:null}const c=function(e,t,n){var c,f,p=/]/gi,h=/]|<\/body>/gi,v=[],m=s.exec(e),g=null!==m?m[1]:"";h.exec(e);var y,_=function(e){for(var t=/\.(\S+)\s*{([^}]*)}/gi,n={},r=t.exec(e);Array.isArray(r);){var i=r[1],a=d(r[2],"lang");null!=i&&null!=a&&(n[a]=i),r=t.exec(e)}return n}(g);if((0,i.Z)(n)&&void 0===(y=_[n]))throw new Error("sami: could not find lang "+n+" in CSS");for(;c=p.exec(e),f=h.exec(e),null!==c||null!==f;){if(null===c||null===f||c.index>=f.index)throw new Error("parse error");var b=e.slice(c.index,f.index),T=l.exec(b);if(null===T)throw new Error("parse error (sync time attribute)");var E=+T[1];if(isNaN(E))throw new Error("parse error (sync time attribute NaN)");w(b.split("\n"),E/1e3)}return function(e){for(var t=[],n=0;n=0;)if(null!==(r=u.exec(e[s]))){var l=r,d=l[1],c=l[2];y===d&&(" "===c?v[v.length-1].end=n:v.push({text:(i=c,i.replace(o,"\n").replace(a,(function(e,t){return String.fromCharCode(t)}))),start:n+t}))}}}},2061:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(6923);function i(e,t){for(var n=t+1;(0,r.Z)(e[n]);)n++;return n}function a(e){for(var t=[],n=0;n0&&(1===o.length?o[0].indexOf("--\x3e")>=0&&t.push(o):(o[1].indexOf("--\x3e")>=0||o[0].indexOf("--\x3e")>=0)&&t.push(o)),n=a}return t}},8675:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(2061),i=n(788);function a(e,t){for(var n=e.split(/\r\n|\n|\r/),a=(0,r.Z)(n),s=[],u=0;u0){var u=document.createTextNode(o[s]);r.appendChild(u)}}else if("B"===a.nodeName){var l=e(a);l.style.fontWeight="bold",r.appendChild(l)}else if("I"===a.nodeName){var d=e(a);d.style.fontStyle="italic",r.appendChild(d)}else if("U"===a.nodeName){var c=e(a);c.style.textDecoration="underline",r.appendChild(c)}else if("FONT"===a.nodeName&&null!=a.color){var f=e(a);f.style.color=a.color,r.appendChild(f)}else{var p=e(a);r.appendChild(p)}}return r}(t)}},8057:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7253),i=n(2061),a=n(788);function o(e,t){for(var n,o,s,u,l,d=e.split(/\r\n|\n|\r/),c=(0,i.Z)(d),f=[],p=0;p{"use strict";n.d(t,{Z:()=>a});var r=n(6923);function i(e){var t=e.split(":");if((0,r.Z)(t[2])){var n=parseInt(t[0],10),i=parseInt(t[1],10),a=parseFloat(t[2].replace(",","."));if(isNaN(n)||isNaN(i)||isNaN(a))return;return 60*n*60+60*i+a}}function a(e,t){if(0===e.length)return null;var n,a,o=[];if((0,r.Z)(e[1])&&-1!==e[1].indexOf("--\x3e")){var s=e[1].split("--\x3e").map((function(e){return e.trim()}));n=s[0],a=s[1],o=e.slice(2,e.length)}if(!(0,r.Z)(n)||!(0,r.Z)(a)){var u=e[0].split("--\x3e").map((function(e){return e.trim()}));n=u[0],a=u[1],o=e.slice(1,e.length)}if(!(0,r.Z)(n)||!(0,r.Z)(a))return null;var l=i(n),d=i(a);return void 0===l||void 0===d?null:{start:l+t,end:d+t,payload:o}}},2967:(e,t,n)=>{"use strict";function r(e,t){if(!(e.parentNode instanceof Element))return[];return function e(n){var r=[];n.tagName.toLowerCase()===t.toLowerCase()&&r.push(n);var i=n.parentNode;return i instanceof Element&&r.push.apply(r,e(i)),r}(e.parentNode)}n.d(t,{Z:()=>r})},3791:(e,t,n)=>{"use strict";n.d(t,{U:()=>s,b:()=>u});var r=n(3274),i=n(7714),a=n(6923),o=n(9252);function s(e,t,n,o){for(var s={},u=e.slice(),l=0;l<=t.length-1;l++){var d=t[l];if(void 0!==d){var c=function(){var e=void 0,t=void 0;if(d.nodeType===Node.ELEMENT_NODE)for(var l=d,c=0;c<=l.attributes.length-1;c++){var f=l.attributes[c],p=f.name;if("style"===p)e=f.value;else if("region"===p)t=f.value;else{var h=p.substring(4);if((0,i.Z)(u,h)&&(s[h]=f.value,u.splice(c,1),0===u.length))return{v:s}}}if((0,a.Z)(e)){var v=(0,r.Z)(n,(function(t){return t.id===e}));if(void 0!==v)for(var m=0;m<=u.length-1;m++){var g=u[m];if(!(0,a.Z)(s[g])&&(0,a.Z)(v.style[g])){if(s[g]=v.style[g],u.splice(m,1),0===u.length)return{v:s};m--}}}if((0,a.Z)(t)){var y=(0,r.Z)(o,(function(e){return e.id===t}));if(void 0!==y)for(var _=0;_<=u.length-1;_++){var b=u[_];if(!(0,a.Z)(s[b])&&(0,a.Z)(y.style[b])){if(s[b]=y.style[b],u.splice(_,1),0===u.length)return{v:s};_--}}}}();if("object"==typeof c)return c.v}}return s}function u(e){if(e.nodeType!==Node.ELEMENT_NODE)return{};for(var t=e,n={},r=0;r<=t.attributes.length-1;r++){var i=t.attributes[r];if((0,o.Z)(i.name,"tts"))n[i.name.substring(4)]=i.value}return n}},6177:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(6923),i=n(5336);function a(e,t){var n=e.exec(t);if(null===n||""===n[0])return null;var r=Number(n[1]);isNaN(r)&&(r=0);var i=Number(n[2]);isNaN(i)&&(i=0);var a=Number(n[3]);isNaN(a)&&(a=0);var o=Number(n[4]);return isNaN(o)&&(o=0),o/1e3+a+60*i+3600*r}const o=function(e,t){return i.gu.test(e)?function(e,t){var n=i.gu.exec(t),r=Number(n[1]),a=Number(n[2]),o=Number(n[3]),s=Number(n[4]),u=Number(n[5]);isNaN(u)&&(u=0);return s+=u/e.subFrameRate,(o+=s/e.frameRate)+60*a+3600*r}(t,e):i.KO.test(e)?a(i.KO,e):i.wf.test(e)?a(i.wf,e):i.jb.test(e)?function(e,t){var n=i.jb.exec(t);return Number(n[1])/e.frameRate}(t,e):i.Du.test(e)?function(e,t){var n=i.Du.exec(t);return Number(n[1])/e.tickRate}(t,e):i.te.test(e)?a(i.te,e):void 0};function s(e,t){var n=e.getAttribute("begin"),i=e.getAttribute("dur"),a=e.getAttribute("end"),s=(0,r.Z)(n)?o(n,t):null,u=(0,r.Z)(i)?o(i,t):null,l=(0,r.Z)(a)?o(a,t):null;if(null==s||null==l&&null==u)throw new Error("Invalid text cue");return{start:s,end:null==l?s+u:l}}},7439:(e,t,n)=>{"use strict";n.d(t,{Z:()=>S});var r=n(5403);function i(e){return void 0===e.extent&&void 0===e.origin&&void 0===e.displayAlign&&void 0===e.display&&void 0===e.textAlign&&void 0===e.fontSize}function a(e){e.extent="70% 20%",e.fontSize="1c",e.origin="15% 80%",e.displayAlign="before",e.textAlign="center"}var o,s=n(6177);function u(e,t){(void 0===o&&(o=void 0!==e.classList&&"function"==typeof e.classList.add),o)?e.classList.add(t):(" "+e.className+" ").indexOf(" "+t+" ")<0&&(e.className+=" "+t)}var l=n(6923),d=n(8026),c=n(2967),f=n(3791),p=n(3887),h=n(5336);function v(e,t){return"-1px -1px "+t+" "+e+",1px -1px "+t+" "+e+",-1px 1px "+t+" "+e+",1px 1px "+t+" "+e}function m(e){var t;return null!=(t=h.Dq.exec(e))?"rgba("+String(parseInt(t[1],16))+","+String(parseInt(t[2],16))+","+String(parseInt(t[3],16))+","+String(parseInt(t[4],16)/255)+")":null!=(t=h.YU.exec(e))?"rgba("+String(parseInt(t[1]+t[1],16))+","+String(parseInt(t[2]+t[2],16))+","+String(parseInt(t[3]+t[3],16))+","+String(parseInt(t[4]+t[4],16)/255)+")":null!=(t=h.GK.exec(e))?"rgb("+String(+t[1])+","+String(+t[2])+","+String(+t[3])+")":null!=(t=h.ev.exec(e))?"rgba("+String(+t[1])+","+String(+t[2])+","+String(+t[3])+","+String(+t[4]/255)+")":e}var g=["color","direction","display","fontFamily","fontSize","fontStyle","fontWeight","textDecoration","textOutline","unicodeBidi","visibility","wrapOption"];function y(e,t,n){var r=t.color;(0,l.Z)(r)&&(e.style.color=m(r));var i=t.backgroundColor;(0,l.Z)(i)&&(e.style.backgroundColor=m(i));var a=t.textOutline;if((0,l.Z)(a)){var o=a.trim().replace(/\s+/g," ").split(" "),s=o.length;if(3===s){var d=m(o[0]),c=o[1];e.style.textShadow=v(d,c)}else if((0,l.Z)(r)&&1===s){var f=o[0];e.style.textShadow=v(r,f)}else if(2===s){var g=/^[#A-Z]/i.test(o[0]);if(g!==/^[0-9]/.test(o[0]))if(g){var y=m(o[0]),_=o[1];e.style.textShadow=v(y,_)}else if((0,l.Z)(r)){var b=o[0];e.style.textShadow=v(r,b)}}}var T=t.textDecoration;if((0,l.Z)(T))switch(T){case"noUnderline":case"noLineThrough":case"noOverline":e.style.textDecoration="none";break;case"lineThrough":e.style.textDecoration="line-through";break;default:e.style.textDecoration=T}var E=t.fontFamily;if((0,l.Z)(E))switch(E){case"proportionalSansSerif":e.style.fontFamily="Arial, Helvetica, Liberation Sans, sans-serif";break;case"monospaceSansSerif":case"sansSerif":e.style.fontFamily="sans-serif";break;case"monospaceSerif":case"default":e.style.fontFamily="Courier New, Liberation Mono, monospace";break;case"proportionalSerif":e.style.fontFamily="serif";break;default:e.style.fontFamily=E}var w=t.fontStyle;(0,l.Z)(w)&&(e.style.fontStyle=w);var S=t.fontWeight;(0,l.Z)(S)&&(e.style.fontWeight=S);var k=t.fontSize;(0,l.Z)(k)?function(e,t){var n=t.trim().split(" ");if(0!==n.length){var r=h.eT.exec(n[0]);null!==r&&("px"===r[2]||"%"===r[2]||"em"===r[2]?e.style.fontSize=r[1]+r[2]:"c"===r[2]?(e.style.position="relative",u(e,"proportional-style"),e.setAttribute("data-proportional-font-size",r[1])):p.Z.warn("TTML Parser: unhandled fontSize unit:",r[2]))}}(e,k):(u(e,"proportional-style"),e.setAttribute("data-proportional-font-size","1"));var A=t.direction;(0,l.Z)(A)&&(e.style.direction=A);var x=t.unicodeBidi;if((0,l.Z)(x))switch(x){case"bidiOverride":e.style.unicodeBidi="bidi-override";break;case"embed":e.style.unicodeBidi="embed";break;default:e.style.unicodeBidi="normal"}var I=t.visibility;(0,l.Z)(I)&&(e.style.visibility=I),"none"===t.display&&(e.style.display="none");var Z=t.wrapOption;e.style.whiteSpace="noWrap"===Z?n?"nowrap":"pre":n?"normal":"pre-wrap"}function _(e,t){e.style.color="white",e.style.position="absolute";var n=t.extent;(0,l.Z)(n)&&function(e,t){var n=t.trim();if("auto"!==n){var r=n.split(" ");if(2===r.length){var i=h.eT.exec(r[0]),a=h.eT.exec(r[1]);null!==i&&null!==a&&("px"===i[2]||"%"===i[2]||"em"===i[2]?e.style.width=i[1]+i[2]:"c"===i[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-width",i[1])):p.Z.warn("TTML Parser: unhandled extent unit:",i[2]),"px"===a[2]||"%"===a[2]||"em"===a[2]?e.style.height=a[1]+a[2]:"c"===a[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-height",a[1])):p.Z.warn("TTML Parser: unhandled extent unit:",a[2]))}}}(e,n);var r=t.writingMode;(0,l.Z)(r);var i=t.overflow;e.style.overflow=(0,l.Z)(i)?i:"hidden";var a=t.padding;(0,l.Z)(a)&&function(e,t){var n=t.trim().split(" ");if(!(n.length<1)){var r=h.eT.exec(n[0]);if(null!==r){if("px"===r[2]||"%"===r[2]||"em"===r[2]){var i=r[1]+r[2];1===n.length?e.style.padding=i:2===n.length?(e.style.paddingTop=i,e.style.paddingBottom=i):e.style.paddingTop=i}else"c"===r[2]?(u(e,"proportional-style"),1===n.length?(e.setAttribute("data-proportional-padding-top",r[1]),e.setAttribute("data-proportional-padding-bottom",r[1]),e.setAttribute("data-proportional-padding-left",r[1]),e.setAttribute("data-proportional-padding-right",r[1])):2===n.length?(e.setAttribute("data-proportional-padding-top",r[1]),e.setAttribute("data-proportional-padding-bottom",r[1])):e.setAttribute("data-proportional-padding-top",r[1])):p.Z.warn("TTML Parser: unhandled padding unit:",r[2]);if(1!==n.length){var a=h.eT.exec(n[1]);if(null!==a){if("px"===a[2]||"%"===a[2]||"em"===a[2]){var o=a[1]+a[2];n.length<4?(e.style.paddingLeft=o,e.style.paddingRight=o):e.style.paddingRight=o}else"c"===a[2]?(u(e,"proportional-style"),n.length<4?(e.setAttribute("data-proportional-padding-left",a[1]),e.setAttribute("data-proportional-padding-right",a[1])):e.setAttribute("data-proportional-padding-right",a[1])):p.Z.warn("TTML Parser: unhandled padding unit:",a[2]);if(2!==n.length){var s=h.eT.exec(n[2]);if(null!==s){if("px"===s[2]||"%"===s[2]||"em"===s[2]){var l=s[1]+s[2];e.style.paddingBottom=l}else"c"===s[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-padding-bottom",s[1])):p.Z.warn("TTML Parser: unhandled padding unit:",s[2]);if(3!==n.length){var d=h.eT.exec(n[3]);if(null!==d)if("px"===d[2]||"%"===d[2]||"em"===d[2]){var c=d[1]+d[2];e.style.paddingLeft=c}else"c"===d[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-padding-left",d[1])):p.Z.warn("TTML Parser: unhandled padding unit:",d[2])}}}}}}}}(e,a);var o=t.origin;(0,l.Z)(o)&&function(e,t){var n=t.trim();if("auto"!==n){var r=n.split(" ");if(2===r.length){var i=h.eT.exec(r[0]),a=h.eT.exec(r[1]);null!==i&&null!==a&&("px"===i[2]||"%"===i[2]||"em"===i[2]?e.style.left=i[1]+i[2]:"c"===i[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-left",i[1])):p.Z.warn("TTML Parser: unhandled origin unit:",i[2]),"px"===a[2]||"%"===a[2]||"em"===a[2]?e.style.top=a[1]+a[2]:"c"===a[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-top",a[1])):p.Z.warn("TTML Parser: unhandled origin unit:",a[2]))}}}(e,o);var s=t.displayAlign;if((0,l.Z)(s))switch(e.style.display="flex",e.style.flexDirection="column",s){case"before":e.style.justifyContent="flex-start";break;case"center":e.style.justifyContent="center";break;case"after":e.style.justifyContent="flex-end"}var d=t.opacity;(0,l.Z)(d)&&(e.style.opacity=d);var c=t.visibility;(0,l.Z)(c)&&(e.style.visibility=c),"none"===t.display&&(e.style.display="none")}function b(e,t){e.style.margin="0px";var n=t.backgroundColor;(0,l.Z)(n)&&(e.style.backgroundColor=m(n));var r=t.lineHeight;(0,l.Z)(r)&&function(e,t){var n=t.trim();if("auto"!==n){var r=h.eT.exec(n[0]);null!==r&&("px"===r[2]||"%"===r[2]||"em"===r[2]?e.style.lineHeight=r[1]+r[2]:"c"===r[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-line-height",r[1])):p.Z.warn("TTML Parser: unhandled lineHeight unit:",r[2]))}}(e,r);var i=t.textAlign;if((0,l.Z)(i))switch(i){case"center":e.style.textAlign="center";break;case"left":case"start":e.style.textAlign="left";break;case"right":case"end":e.style.textAlign="right"}}function T(e,t,n){var r=document.createElement("span"),i=null===e.textContent?"":e.textContent;if(n){var a=i.trim();i=a=a.replace(/\s+/g," ")}return r.innerHTML=i,r.className="rxp-texttrack-span",y(r,t,n),r}function E(e,t,n,r,i,a){var o=a.cellResolution,s=a.shouldTrimWhiteSpace,u=(0,c.Z)(e,"div"),p=document.createElement("DIV");if(p.className="rxp-texttrack-region",p.setAttribute("data-resolution-columns",String(o.columns)),p.setAttribute("data-resolution-rows",String(o.rows)),_(p,i),null!==t){var h=(0,f.U)(["backgroundColor"],[].concat(u,[t]),r,n).bodyBackgroundColor;(0,l.Z)(h)&&(p.style.backgroundColor=m(h))}var v=document.createElement("p");v.className="rxp-texttrack-p",b(v,i);for(var y=function(e,t,n,r,i){return function e(r,i,a,o){for(var s=r.childNodes,u=[],c=0;c0){var y=p.getAttribute("xml:space"),_=(0,l.Z)(y)?"default"===y:o,b=(0,d.Z)({},i,(0,f.U)(g,[p],n,t));u.push.apply(u,e(p,b,[p].concat(a),_))}}return u}(e,(0,d.Z)({},r),[],i)}(e,n,r,i,s),E=0;E{"use strict";n.d(t,{Z:()=>f});var r=n(5403),i=n(7253),a=n(1988),o=n(6923),s=n(6177),u=n(5336),l={left:"start",center:"center",right:"end",start:"start",end:"end"},d={left:"line-left",center:"center",right:"line-right"};function c(e){var t=e.paragraph,n=e.timeOffset,r=e.paragraphStyle,c=e.ttParams,f=e.shouldTrimWhiteSpace;if(!t.hasAttribute("begin")&&!t.hasAttribute("end")&&/^\s*$/.test(null===t.textContent?"":t.textContent))return null;var p=(0,s.Z)(t,c),h=p.start,v=p.end,m=function(e,t){function n(e,t){for(var r=e.childNodes,i="",a=0;a|\u2265/g,">").replace(/\u200E/g,"‎").replace(/\u200F/g,"‏").replace(/\u00A0/g," ")}else if("br"===s.nodeName)i+="\n";else if("span"===s.nodeName&&s.nodeType===Node.ELEMENT_NODE&&s.childNodes.length>0){var d=s.getAttribute("xml:space");i+=n(s,(0,o.Z)(d)?"default"===d:t)}}return i}return n(e,t)}(t,f),g=(0,i.Z)(h+n,v+n,m);return null===g?null:((0,a.Z)(g)&&function(e,t){var n=t.extent;if((0,o.Z)(n)){var r=u._0.exec(n);null!=r&&(e.size=Number(r[1]))}switch(t.writingMode){case"tb":case"tblr":e.vertical="lr";break;case"tbrl":e.vertical="rl"}var i=t.origin;if((0,o.Z)(i))u._0.exec(i);var a=t.align;if((0,o.Z)(a)){e.align=a,"center"===a&&("center"!==e.align&&(e.align="middle"),e.position="auto");var s=d[a];e.positionAlign=void 0===s?"":s;var c=l[a];e.lineAlign=void 0===c?"":c}}(g,r),g)}const f=function(e,t){for(var n=(0,r.Z)(e,t),i=[],a=0;a{"use strict";n.d(t,{Z:()=>p});var r=n(3274),i=n(6923),a=n(8026),o=n(3887),s=/(\d+) (\d+)/;var u=n(2967),l=n(3791);var d=n(5138),c=n(7714);var f=["align","backgroundColor","color","direction","display","displayAlign","extent","fontFamily","fontSize","fontStyle","fontWeight","lineHeight","opacity","origin","overflow","padding","textAlign","textDecoration","textOutline","unicodeBidi","visibility","wrapOption","writingMode"];function p(e,t){var n=[],p=(new DOMParser).parseFromString(e,"text/xml");if(null!=p){var h=p.getElementsByTagName("tt")[0];if(void 0===h)throw new Error("invalid XML");for(var v=function(e){return e.getElementsByTagName("body")[0]}(h),m=function(e){return e.getElementsByTagName("style")}(h),g=function(e){return e.getElementsByTagName("region")}(h),y=function(e){return e.getElementsByTagName("p")}(h),_=function(e){var t=e.getAttribute("ttp:frameRate"),n=e.getAttribute("ttp:subFramRate"),r=e.getAttribute("ttp:tickRate"),a=e.getAttribute("ttp:frameRateMultiplier"),u=e.getAttribute("xml:space"),l=e.getAttribute("ttp:cellResolution"),d={columns:32,rows:15};if(null!==l){var c=s.exec(l);if(null===c||c.length<3)o.Z.warn("TTML Parser: Invalid cellResolution");else{var f=parseInt(c[1],10),p=parseInt(c[2],10);isNaN(f)||isNaN(p)?o.Z.warn("TTML Parser: Invalid cellResolution"):d={columns:f,rows:p}}}if((0,i.Z)(u)&&"default"!==u&&"preserve"!==u)throw new Error("Invalid spacing style");var h=Number(t);(isNaN(h)||h<=0)&&(h=30);var v=Number(n);(isNaN(v)||v<=0)&&(v=1);var m=Number(r);(isNaN(m)||m<=0)&&(m=void 0);var g=h,y=null!=v?v:1,_=null!==u?u:"default",b=void 0!==m?m:h*v;if(null!==a){var T=/^(\d+) (\d+)$/g.exec(a);null!==T&&(g=h*(Number(T[1])/Number(T[2])))}return{cellResolution:d,tickRate:b,frameRate:g,subFrameRate:y,spaceStyle:_}}(h),b=[],T=0;T<=m.length-1;T++){var E=m[T];if(E instanceof Element){var w=E.getAttribute("xml:id");if(null!==w){var S=E.getAttribute("style"),k=null===S?[]:S.split(" ");b.push({id:w,style:(0,l.b)(E),extendsStyles:k})}}}!function(e){var t=[];function n(r,i){t.push(i);for(var s=function(i){var s=r.extendsStyles[i],u=(0,d.Z)(e,(function(e){return e.id===s}));if(u<0)o.Z.warn("TTML Parser: unknown style inheritance: "+s);else{var l=e[u];(0,c.Z)(t,u)?o.Z.warn("TTML Parser: infinite style inheritance loop avoided"):n(l,u),r.style=(0,a.Z)({},l.style,r.style)}},u=0;u{"use strict";n.d(t,{YU:()=>f,Dq:()=>c,GK:()=>p,ev:()=>h,eT:()=>d,_0:()=>l,KO:()=>i,gu:()=>r,wf:()=>a,jb:()=>o,te:()=>u,Du:()=>s});var r=/^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/,i=/^(?:(\d{2,}):)?(\d{2}):(\d{2})$/,a=/^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{2,})$/,o=/^(\d*\.?\d*)f$/,s=/^(\d*\.?\d*)t$/,u=/^(?:(\d*\.?\d*)h)?(?:(\d*\.?\d*)m)?(?:(\d*\.?\d*)s)?(?:(\d*\.?\d*)ms)?$/,l=/^(\d{1,2}|100)% (\d{1,2}|100)%$/,d=/^((?:\+|\-)?\d*(?:\.\d+)?)(px|em|c|%|rh|rw)$/,c=/^#([0-9A-f]{2})([0-9A-f]{2})([0-9A-f]{2})([0-9A-f]{2})$/,f=/^#([0-9A-f])([0-9A-f])([0-9A-f])([0-9A-f])$/,p=/^rgb\( *(\d+) *, *(\d+) *, *(\d+) *\)/,h=/^rgba\( *(\d+) *, *(\d+) *, *(\d+) *, *(\d+) *\)/},1138:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(6923),i=n(360);function a(e,t){for(var n=[],a=t;a{"use strict";n.d(t,{Z:()=>x});var r=n(1138),i=n(6923),a=n(360);var o=n(9525),s={white:"#ffffff",lime:"#00ff00",cyan:"#00ffff",red:"#ff0000",yellow:"#ffff00",magenta:"#ff00ff",blue:"#0000ff",black:"#000000"};function u(e){var t=Object.keys(s).reduce((function(e,t){return e[t]="color: "+s[t]+";",e["bg_"+t]="background-color: "+s[t]+";",e}),{}),n="";return e.forEach((function(e){if(e.length>=2)for(var r=1;r0&&n.appendChild(document.createElement("br")),o[s].length>0){var u=document.createTextNode(o[s]);n.appendChild(u)}}else{var c=e.nodeName.toLowerCase().split("."),f=[];if(c.forEach((function(e){(0,i.Z)(t[e])&&f.push(t[e])})),0!==f.length){var p=document.createAttribute("style");f.forEach((function(e){p.value+=e}));var h=(0,l.Z)(r,a)?a:"span";(n=document.createElement(h)).setAttributeNode(p)}else{var v=(0,l.Z)(r,a)?a:"span";n=document.createElement(v)}for(var m=0;m/,"").replace(/<([u,i,b,c])(\..*?)?(?: .*?)?>(.*?)<\/\1>/g,"<$1$2>$3"),r=(new DOMParser).parseFromString(n,"text/html").body.childNodes,i=[],a=0;a{"use strict";n.d(t,{Z:()=>c});var r=n(1988),i=n(1138),a=n(9525),o=n(360),s=n(7714),u=n(6923);function l(e,t){if(!(0,u.Z)(e.vertical)||"rl"!==e.vertical&&"lr"!==e.vertical||(t.vertical=e.vertical),(0,u.Z)(e.line)){var n=/^(\d+(\.\d+)?)%(,([a-z]+))?/.exec(e.line);if(Array.isArray(n))t.line=Number(n[1]),t.snapToLines=!1,(0,s.Z)(["start","center","end"],n[4])&&(t.lineAlign=n[4]);else{var r=/^(-?\d+)(,([a-z]+))?/.exec(e.line);Array.isArray(r)&&(t.line=Number(r[1]),t.snapToLines=!0,(0,s.Z)(["start","center","end"],r[3])&&(t.lineAlign=r[3]))}}if((0,u.Z)(e.position)){var i=/^([\d\.]+)%(?:,(line-left|line-right|center))?$/.exec(e.position);if(Array.isArray(i)&&i.length>=2){var a=parseInt(i[1],10);isNaN(a)||(t.position=a,void 0!==i[2]&&(t.positionAlign=i[2]))}}(0,u.Z)(e.size)&&(t.size=e.size),"string"==typeof e.align&&(0,s.Z)(["start","center","end","left"],e.align)&&(t.align=e.align)}var d=n(7253);const c=function(e,t){var n=e.split(/\r\n|\n|\r/);if(!/^WEBVTT($| |\t)/.test(n[0]))throw new Error("Can't parse WebVTT: Invalid file.");for(var s,u,c,f,p=(0,o.yE)(n),h=(0,i.Z)(n,p),v=[],m=0;m{"use strict";n.d(t,{Z:()=>a});var r=n(6923);function i(e){var t=e.split(":").reverse();if((0,r.Z)(t[2])||(0,r.Z)(t[1])){var n=(0,r.Z)(t[2])?parseInt(t[2],10):0,i=parseInt(t[1],10),a=parseFloat(t[0].replace(",","."));if(isNaN(n)||isNaN(i)||isNaN(a))return;return 60*n*60+60*i+a}}function a(e,t){var n,r,a,o=/-->/;if(o.test(e[0]))n=e[0],r=e.slice(1,e.length);else{if(!o.test(e[1]))return null;a=e[0],n=e[1],r=e.slice(2,e.length)}var s=function(e){var t=/^([\d:.]+)[ |\t]+-->[ |\t]+([\d:.]+)[ |\t]*(.*)$/.exec(e);if(null===t)return null;var n=i(t[1]),r=i(t[2]);return null==n||null==r?null:{start:n,end:r,settings:t[3].split(/ |\t/).reduce((function(e,t){var n=t.split(":");return 2===n.length&&(e[n[0]]=n[1]),e}),{})}}(n);return null===s?null:{start:s.start+t,end:s.end+t,settings:s.settings,payload:r,header:a}}},360:(e,t,n)=>{"use strict";n.d(t,{yE:()=>i,tq:()=>o,JF:()=>a,$4:()=>s});var r=n(6923);function i(e){for(var t=0;t=0)return!0;var r=e[t+1];return void 0!==r&&r.indexOf("--\x3e")>=0}function s(e,t){for(var n=t+1;(0,r.Z)(e[n]);)n++;return n}},1923:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Wt});var r=n(7278),i=n(8170),a=n(7874),o=n(4597),s=n(5278);function u(e){var t=e.segment,n=e.url;return t.isInit||null===n?(0,i.of)({type:"data-created",value:{responseData:null}}):(0,o.ZP)({url:n,responseType:"arraybuffer",sendProgressEvents:!0})}function l(e){var t=e.response,n=e.content,r=n.segment,o=n.period,u=t.data,l=t.isChunked;if(n.segment.isInit)return(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}});if(l)throw new Error("Image data should not be downloaded in chunks");var d=(0,s.Z)(r.timestampOffset,0);if(null===u||null===a.Z.imageParser)return(0,i.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:{duration:r.duration,time:r.time},chunkOffset:d,appendWindow:[o.start,o.end]}});var c=a.Z.imageParser(new Uint8Array(u)),f=c.thumbs;return(0,i.of)({type:"parsed-segment",value:{chunkData:{data:f,start:0,end:Number.MAX_VALUE,timescale:1,type:"bif"},chunkInfos:{time:0,duration:Number.MAX_VALUE,timescale:c.timescale},chunkOffset:d,appendWindow:[o.start,o.end]}})}var d=n(9795),c=n(5142),f=n(6008),p=n(5709),h=n(7746),v=n(1966),m=n(944),g=n(3887),y=n(3274),_=n(9829);function b(e){return 0===e.length?0:e.reduce((function(e,t){var n;return Math.min(null!==(n=t.attributes.availabilityTimeOffset)&&void 0!==n?n:0,e)}),1/0)}function T(e){var t=Date.parse(e)-performance.now();if(!isNaN(t))return t;g.Z.warn("DASH Parser: Invalid clock received: ",e)}function E(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,o=null;if(void 0!==r){var s=E(r);if(void 0===s)return;a=s}if(void 0!==i){var u=E(i);if(void 0===u)return;o=u}if(void 0!==r&&null===a||void 0!==i&&null===o)return void g.Z.info("Parser utils: found Period with no segment. ","Going to previous one to calculate last position");if(null!==o)return null!==a?Math.min(a,o):o;if(null!==a)return a}}}function S(e){for(var t=e.representations,n=null,r=0;r0){var o=F(a,"cenc:pssh"),s=o[0],u=o[1];null!==u&&(g.Z.warn(u.message),t.push(u)),null!==s&&n.push(s)}}}return[{cencPssh:n},t]}(e.childNodes),n=t[0],r=t[1];return[{children:n,attributes:function(e){for(var t={},n=0;n0&&(n=n.concat(d));break;case"SegmentList":var c=Q(i),f=c[0],p=c[1];n=n.concat(p),t.segmentList=f;break;case"SegmentTemplate":var h=ee(i),v=h[0],m=h[1];n=n.concat(m),t.segmentTemplate=v}}return[t,n]}(e.childNodes),n=t[0],r=t[1],i=function(e){for(var t={},n=[],r=K(t,n),i=0;i0&&(r=r.concat(u));break;case"ContentComponent":t.contentComponent=G(a);break;case"EssentialProperty":null==t.essentialProperties?t.essentialProperties=[z(a)]:t.essentialProperties.push(z(a));break;case"InbandEventStream":void 0===t.inbandEventStreams&&(t.inbandEventStreams=[]),t.inbandEventStreams.push(z(a));break;case"Representation":var l=te(a),d=l[0],c=l[1];t.representations.push(d),c.length>0&&(r=r.concat(c));break;case"Role":null==t.roles?t.roles=[z(a)]:t.roles.push(z(a));break;case"SupplementalProperty":null==t.supplementalProperties?t.supplementalProperties=[z(a)]:t.supplementalProperties.push(z(a));break;case"SegmentBase":var f=Y(a),p=f[0],h=f[1];t.segmentBase=p,h.length>0&&(r=r.concat(h));break;case"SegmentList":var v=Q(a),m=v[0],g=v[1];t.segmentList=m,g.length>0&&(r=r.concat(g));break;case"SegmentTemplate":var y=ee(a),_=y[0],b=y[1];t.segmentTemplate=_,b.length>0&&(r=r.concat(b));break;case"ContentProtection":var T=$(a),E=T[0],w=T[1];w.length>0&&(r=r.concat(w)),void 0!==E&&n.push(E)}}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=K(t,n),i=0;i0&&(i=i.concat(_))}}return[{baseURLs:n,adaptations:r,streamEvents:a,segmentTemplate:t},i]}(e.childNodes),n=t[0],r=t[1],i=function(e){for(var t={},n=[],r=K(t,n),i=0;i=a?o:(new Array(a+1).join("0")+o).slice(-a)}}function ge(e,t,n,r){return 0===e.length?void 0!==t?[ye(t,n,r)]:null:e.map((function(e){return ye((0,_.Z)(e,t),n,r)}))}function ye(e,t,n){return-1===e.indexOf("$")?e:e.replace(/\$\$/g,"$").replace(/\$RepresentationID\$/g,String(t)).replace(/\$Bandwidth(|\%0(\d+)d)\$/g,me(void 0===n?0:n))}function _e(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 me(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 me(e)(t,n,r)}))}}function be(e,t,n,r,i){for(var a,o,s=(0,he.gT)(t,e),u=(0,he.gT)(t+n,e),l=e.timeline,d=e.timescale,c=e.mediaURLs,f=e.startNumber,p=null!=f?f:void 0,h=[],v=l.length,m=l.length>0&&null!=l[0].duration?l[0].duration:0,g=0;g0?Math.floor(o/a):0),S=b+w*_;S=u)return h;null!=p&&(p+=E+1)}return h}function Te(e,t){if(t.timescale!==e.timescale){var n=e.timescale;e.timeline.push({start:t.time/t.timescale*n,duration:t.duration/t.timescale*n,repeatCount:void 0===t.count?0:t.count,range:t.range})}else e.timeline.push({start:t.time,duration:t.duration,repeatCount:void 0===t.count?0:t.count,range:t.range});return!0}var Ee=function(){function e(e,t){var n,r,i=t.periodStart,a=t.periodEnd,o=t.representationBaseURLs,s=t.representationId,u=t.representationBitrate,l=t.isEMSGWhitelisted,d=null!==(n=e.timescale)&&void 0!==n?n:1,c=(null!=e.presentationTimeOffset?e.presentationTimeOffset:0)-i*d,f=ge(o,void 0!==e.initialization?e.initialization.media:void 0,s,u),p=void 0!==e.initialization?e.initialization.range:void 0!==e.indexRange?[0,e.indexRange[0]-1]:void 0;this._index={indexRange:e.indexRange,indexTimeOffset:c,initialization:{mediaURLs:f,range:p},mediaURLs:ge(o,e.media,s,u),startNumber:e.startNumber,timeline:null!==(r=e.timeline)&&void 0!==r?r:[],timescale:d},this._scaledPeriodEnd=null==a?void 0:(0,he.gT)(a,this._index),this._isInitialized=this._index.timeline.length>0,this._isEMSGWhitelisted=l}var t=e.prototype;return t.getInitSegment=function(){return ve(this._index,this._isEMSGWhitelisted)},t.getSegments=function(e,t){return be(this._index,e,t,this._isEMSGWhitelisted,this._scaledPeriodEnd)},t.shouldRefresh=function(){return!1},t.getFirstPosition=function(){var e=this._index;return 0===e.timeline.length?null:(0,he.zG)(e.timeline[0].start,e)},t.getLastPosition=function(){var e=this._index.timeline;if(0===e.length)return null;var t=e[e.length-1],n=(0,he.jH)(t,null,this._scaledPeriodEnd);return(0,he.zG)(n,this._index)},t.isSegmentStillAvailable=function(){return!0},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},t._addSegments=function(e){for(var t=0;t0&&(this._isInitialized=!0)},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){return!0},t.isInitialized=function(){return this._isInitialized},t._replace=function(e){this._index=e._index},t._update=function(){g.Z.error("Base RepresentationIndex: Cannot update a SegmentList")},e}(),we=function(){function e(e,t){var n,r=t.periodStart,i=t.representationBaseURLs,a=t.representationId,o=t.representationBitrate,s=t.isEMSGWhitelisted;this._isEMSGWhitelisted=s,this._periodStart=r;var u=null!=e.presentationTimeOffset?e.presentationTimeOffset:0,l=null!==(n=e.timescale)&&void 0!==n?n:1,d=u-r*l,c=e.list.map((function(e){return{mediaURLs:ge(i,e.media,a,o),mediaRange:e.mediaRange}}));this._index={list:c,timescale:l,duration:e.duration,indexTimeOffset:d,indexRange:e.indexRange,initialization:null==e.initialization?void 0:{mediaURLs:ge(i,e.initialization.media,a,o),range:e.initialization.range}}}var t=e.prototype;return t.getInitSegment=function(){var e=ve(this._index);return void 0===e.privateInfos&&(e.privateInfos={}),e.privateInfos.isEMSGWhitelisted=this._isEMSGWhitelisted,e},t.getSegments=function(e,t){for(var n=this._index,r=n.duration,i=n.list,a=n.timescale,o=r/a,s=e-this._periodStart,u=(0,he.PZ)(s,t,a),l=u[0],d=u[1],c=Math.min(i.length-1,Math.floor(d/r)),f=[],p=Math.floor(l/r);p<=c;){var h=i[p].mediaRange,v=i[p].mediaURLs,m=p*o+this._periodStart,g={id:String(p),time:m,isInit:!1,range:h,duration:o,timescale:1,end:m+o,mediaURLs:v,timestampOffset:-n.indexTimeOffset/a,privateInfos:{isEMSGWhitelisted:this._isEMSGWhitelisted}};f.push(g),p++}return f},t.shouldRefresh=function(e,t){var n=this._index,r=n.timescale,i=n.duration,a=n.list,o=t*r,s=Math.floor(o/i);return s<0||s>=a.length},t.getFirstPosition=function(){return this._periodStart},t.getLastPosition=function(){var e=this._index,t=e.duration;return e.list.length*t/e.timescale+this._periodStart},t.isSegmentStillAvailable=function(){return!0},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){return!0},t.isInitialized=function(){return!0},t._replace=function(e){this._index=e._index},t._update=function(){g.Z.error("List RepresentationIndex: Cannot update a SegmentList")},e}(),Se=n(9362),ke=n(8232),Ae=n(1091),xe=n(5505),Ie=m.Z.DEFAULT_MAXIMUM_TIME_ROUNDING_ERROR;function Ze(e,t,n){return t+Ie*e>=n}function Re(e,t,n,r){var i=e.start,a=e.duration,o=e.repeatCount;return null==i&&(null==t?i=r:null!=t.duration&&(i=t.start+t.duration*(t.repeatCount+1))),null!=a&&!isNaN(a)||null==n||null==n.start||isNaN(n.start)||null==i||isNaN(i)||(a=n.start-i),null==i||isNaN(i)||null==a||isNaN(a)||null!=o&&isNaN(o)?(g.Z.warn('DASH: A "S" Element could not have been parsed.'),null):{start:i,duration:a,repeatCount:void 0===o?0:o}}function Me(e){for(var t={},n=0;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],d=i;;){var c=l.getAttribute("d"),f=null===c?null:parseInt(c,10);if(null===f||Number.isNaN(f))return null;var p=l.getAttribute("r"),h=null===p?null:parseInt(p,10);if(null!==h){if(Number.isNaN(h)||h<0)return null;if(h>0){var v=n-d;if(v%f==0&&v/f<=h)return{repeatNumberInPrevSegments:0,repeatNumberInNewElements:v/f,prevSegmentsIdx:0,newElementsIdx:u}}d+=f*(h+1)}else d+=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;d=g}if(d===n)return{newElementsIdx:u,prevSegmentsIdx:0,repeatNumberInPrevSegments:0,repeatNumberInNewElements:0};if(d>i)return null}}(t,e);if(null===i)return g.Z.warn('DASH: Cannot perform "based" update. Common segment not found.'),Ce(e,n);var a=i.prevSegmentsIdx,o=i.newElementsIdx,s=i.repeatNumberInPrevSegments,u=i.repeatNumberInNewElements,l=t.length-a+o-1;if(l>=e.length)return g.Z.info('DASH: Cannot perform "based" update. New timeline too short'),Ce(e,n);var d=t.slice(a);if(s>0){var c=d[0];c.start+=c.duration*s,d[0].repeatCount-=s}if(u>0&&0!==o)return g.Z.info('DASH: Cannot perform "based" update. The new timeline has a different form.'),Ce(e,n);var f=d[d.length-1],p=Me(e[l]),h=(null!==(r=p.repeatCount)&&void 0!==r?r:0)-u;if(p.duration!==f.duration||f.repeatCount>h)return g.Z.info('DASH: Cannot perform "based" update. The new timeline has a different form at the beginning.'),Ce(e,n);void 0!==p.repeatCount&&p.repeatCount>f.repeatCount&&(f.repeatCount=p.repeatCount);for(var v=[],m=[],y=l+1;yu?u-y:r,T=y+s,E=y+this._index.presentationTimeOffset,w=null===o?null:o.map(_e(E,_)),S={id:String(_),number:_,time:T/a,end:(T+b)/a,duration:b/a,timescale:1,isInit:!1,scaledDuration:b/a,mediaURLs:w,timestampOffset:-n.indexTimeOffset/a,privateInfos:{isEMSGWhitelisted:this._isEMSGWhitelisted}};v.push(S),g++}return v},t.getFirstPosition=function(){var e=this._getFirstSegmentStart();return null==e?e:e/this._index.timescale+this._periodStart},t.getLastPosition=function(){var e=this._getLastSegmentStart();return null==e?e:(e+this._index.duration)/this._index.timescale+this._periodStart},t.shouldRefresh=function(){return!1},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},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._scaledPeriodEnd)return!1;var e=this._index.timescale,t=this._getLastSegmentStart();return null!=t&&Ze(e,t+this._index.duration,this._scaledPeriodEnd)},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._scaledPeriodEnd=e._scaledPeriodEnd,this._manifestBoundsCalculator=e._manifestBoundsCalculator},t._update=function(e){this._replace(e)},t._getFirstSegmentStart=function(){if(!this._isDynamic)return 0;if(0===this._scaledPeriodEnd||void 0===this._scaledPeriodEnd){var e=this._manifestBoundsCalculator.estimateMaximumBound();if(void 0!==e&&ethis._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 a=this._aggressiveMode?n/r:0;if(null!=this._scaledPeriodEnd&&this._scaledPeriodEnd<(i+a-this._periodStart)*this._index.timescale)return this._scaledPeriodEndDe*r||0===d?c:(d-1)*n},e}();function Be(e,t){var n=[];if(0===t.length)return e;if(0===e.length){for(var r=0;r0){var _=t.parentSegmentTemplates.slice(),T=e.children.segmentTemplate;void 0!==T&&_.push(T);var E=q.Z.apply(void 0,[{}].concat(_));m.availabilityTimeOffset=t.availabilityTimeOffset+b(e.children.baseURLs)+(null!==(r=E.availabilityTimeOffset)&&void 0!==r?r:0);var w=E.timelineParser;i=void 0!==w?new Oe(E,w,m):new Le(E,m)}else{var S=t.adaptation.children;if(void 0!==S.segmentBase){var k=S.segmentBase;i=new Ee(k,m)}else if(void 0!==S.segmentList){var A=S.segmentList;i=new we(A,m)}else i=new Le({duration:Number.MAX_VALUE,timescale:1,startNumber:0,initialization:{media:""},media:""},m)}return i}(s,(0,q.Z)({},n,{unsafelyBaseOnPreviousRepresentation:l,adaptation:t,inbandEventStreams:d})),f=void 0;null==s.attributes.bitrate?(g.Z.warn("DASH: No usable bitrate found in the Representation."),f=0):f=s.attributes.bitrate;var p={bitrate:f,index:c,id:u},h=void 0;if(null!=s.attributes.codecs?h=s.attributes.codecs:null!=t.attributes.codecs&&(h=t.attributes.codecs),null!=h&&(h="mp4a.40.02"===h?"mp4a.40.2":h,p.codecs=h),null!=s.attributes.frameRate?p.frameRate=s.attributes.frameRate:null!=t.attributes.frameRate&&(p.frameRate=t.attributes.frameRate),null!=s.attributes.height?p.height=s.attributes.height:null!=t.attributes.height&&(p.height=t.attributes.height),null!=s.attributes.mimeType?p.mimeType=s.attributes.mimeType:null!=t.attributes.mimeType&&(p.mimeType=t.attributes.mimeType),null!=s.attributes.width?p.width=s.attributes.width:null!=t.attributes.width&&(p.width=t.attributes.width),null!=t.children.contentProtections){var v=t.children.contentProtections.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&&e.keyIds.push({keyId:t.attributes.keyId,systemId:n}),void 0!==n){for(var r=t.children.cencPssh,i=[],a=0;a0){var s,u=(0,y.Z)(e.initData,(function(e){return"cenc"===e.type}));if(void 0===u)e.initData.push({type:"cenc",values:i});else(s=u.values).push.apply(s,i)}}return e}),{keyIds:[],initData:[]});(Object.keys(v.initData).length>0||v.keyIds.length>0)&&(p.contentProtections=v)}a.push(p)},s=0;s0&&void 0!==l.video){var Z,M=o.video[l.video];I.unsafelyBaseOnPreviousAdaptation=null!==(r=null===(n=t.unsafelyBaseOnPreviousPeriod)||void 0===n?void 0:n.getAdaptation(M.id))&&void 0!==r?r:null;var C=Ue(m,c,I);(Z=M.representations).push.apply(Z,C),k=M.id}else{var N=f.accessibilities,P=void 0;void 0!==h&&h.some((function(e){return"dub"===e.value}))&&(P=!0);var O=void 0;"text"!==w?O=!1:void 0!==N&&(O=N.some(ze));var D=void 0;"audio"!==w?D=!1:void 0!==N&&(D=N.some(Fe));var L=void 0;"video"!==w?L=!1:void 0!==N&&(L=N.some(Ke));for(var B=Ve(c,{isAudioDescription:D,isClosedCaption:O,isSignInterpreted:L,type:w});(0,de.Z)(u,B);)B+="-dup";k=B,u.push(B),I.unsafelyBaseOnPreviousAdaptation=null!==(a=null===(i=t.unsafelyBaseOnPreviousPeriod)||void 0===i?void 0:i.getAdaptation(B))&&void 0!==a?a:null;var U={id:B,representations:Ue(m,c,I),type:w};null!=c.attributes.language&&(U.language=c.attributes.language),null!=O&&(U.closedCaption=O),null!=D&&(U.audioDescription=D),!0===P&&(U.isDub=!0),!0===L&&(U.isSignInterpreted=!0);var F=o[w];if(void 0===F)o[w]=[U],v&&(l[w]=0);else{for(var z=null,K=function(e){var t=A[e],n=s[t];if(null!=n&&n.newID!==k&&(0,de.Z)(n.adaptationSetSwitchingIDs,S)){var r,i=(0,y.Z)(F,(function(e){return e.id===t}));null!=i&&i.audioDescription===U.audioDescription&&i.closedCaption===U.closedCaption&&i.language===U.language&&(g.Z.info('DASH Parser: merging "switchable" AdaptationSets',S,t),(r=i.representations).push.apply(r,U.representations),z=i)}},V=0;VW)&&(F.splice(H,1),F.splice(G,0,z),l[w]=G)}}else null===z&&F.push(U)}}null!=S&&null==s[S]&&(s[S]={newID:k,adaptationSetSwitchingIDs:A})}}}return o}(c.children.adaptations,k),x=null===(i=c.children.streamEvents)||void 0===i?void 0:i.map((function(e){var t,n=(null!==(t=e.eventPresentationTime)&&void 0!==t?t:0)/e.timescale+v;return{start:n,end:void 0!==e.duration?n+e.duration/e.timescale:void 0,data:e.data,id:e.id}})),I={id:T,start:v,end:_,duration:m,adaptations:A,streamEvents:x};if(a.unshift(I),!l.lastPositionIsKnown()){var Z=function(e){for(var t=null,n=!0,r=(0,ue.Z)(e).filter((function(e){return null!=e})),i=(0,oe.Z)(r,(function(e){return e})),a=0;a=0;c--)d(c);if(t.isDynamic&&!l.lastPositionIsKnown()){var f=$e(t,0);if(void 0!==f){var p=f[0],h=f[1];l.setLastPosition(p,h)}}return function(e){if(0===e.length)return[];for(var t=[e[0]],n=1;nr.start;)g.Z.warn("DASH: Updating overlapping Periods.",i,r),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}(a)}function $e(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 g.Z.warn("DASH Parser: no clock synchronization mechanism found. Using the system clock instead."),[a-e.availabilityStartTime,performance.now()/1e3]}}var je=m.Z.DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0;function Ye(e,t){var n=ae(e);return qe(n[0],t,n[1])}function qe(e,t,n,r){var i=e.children,a=e.attributes,o=new WeakMap;if(null==t.externalClockOffset){var s="dynamic"===a.type,u=(0,y.Z)(i.utcTimings,(function(e){return"urn:mpeg:dash:utc:direct:2014"===e.schemeIdUri&&null!=e.value})),l=null!=u&&null!=u.value?T(u.value):void 0,d=null==l||isNaN(l)?void 0:l;if(null!=d)t.externalClockOffset=d;else if(s&&!0!==r){var c=function(e){var t=e.children.utcTimings.filter((function(e){return"urn:mpeg:dash:utc:http-iso:2014"===e.schemeIdUri&&void 0!==e.value}));return t.length>0?t[0].value:void 0}(e);if(null!=c&&c.length>0)return{type:"needs-ressources",value:{ressources:[c],continue:function(r){if(1!==r.length)throw new Error("DASH parser: wrong number of loaded ressources.");return d=T(r[0].responseData),t.externalClockOffset=d,qe(e,t,n,!0)}}}}}for(var f=[],p=0;p=0&&(o=0===d.minimumUpdatePeriod?je:d.minimumUpdatePeriod);var x=function(e){if(0===e.length)throw new Error("DASH Parser: no period available for a dynamic content");return[k(e),w(e)]}(E),I=x[0],Z=x[1],R=performance.now();if(c){var M;if(s=I,A=null!=h?h:null,void 0!==Z)M=Z;else{var C=null!=p?p:0,N=t.externalClockOffset;if(void 0===N)g.Z.warn("DASH Parser: use system clock to define maximum position"),M=Date.now()/1e3-C;else M=(performance.now()+N)/1e3-C}u={isLinear:!0,value:M,time:R},null!==A&&void 0!==s&&M-s>A&&(A=M-s)}else{var P;if(s=void 0!==I?I:void 0!==(null===(i=E[0])||void 0===i?void 0:i.start)?E[0].start:0,void 0!==Z)P=Z;else if(void 0!==S)P=S;else if(void 0!==E[E.length-1]){var O=E[E.length-1];P=null!==(a=O.end)&&void 0!==a?a:void 0!==O.duration?O.start+O.duration:void 0}u={isLinear:!1,value:null!=P?P:1/0,time:R}}return{type:"done",value:{parsed:{availabilityStartTime:p,clockOffset:t.externalClockOffset,isDynamic:c,isLive:c,periods:E,publishTime:d.publishTime,suggestedPresentationDelay:d.suggestedPresentationDelay,transportType:"dash",timeBounds:{absoluteMinimumTime:s,timeshiftDepth:A,maximumTimeData:u},lifetime:o,uris:null==t.url?l.locations:[t.url].concat(l.locations)},warnings:n}}}(e,t,n,o):{type:"needs-ressources",value:{ressources:f.map((function(e){return e.ressource})),continue:function(r){if(r.length!==f.length)throw new Error("DASH parser: wrong number of loaded ressources.");for(var a=r.length-1;a>=0;a--){var s,u=f[a].index,l=r[a],d=l.responseData,c=l.receivedTime,p=l.sendingTime,h=l.url,v=""+d+"",m=(new DOMParser).parseFromString(v,"text/xml");if(null==m||0===m.children.length)throw new Error("DASH parser: Invalid external ressources");for(var g=m.children[0].children,y=[],_=0;_0&&n.push.apply(n,E)}(s=i.periods).splice.apply(s,[u,1].concat(y))}return qe(e,t,n)}}}}const Xe=function(e,t){var n=e.documentElement;if(null==n||"MPD"!==n.nodeName)throw new Error("DASH Parser: document root should be MPD");return Ye(n,t)};var Qe=n(7445);function Je(e){var t=e.aggressiveMode,n=e.referenceDateTime,r=void 0!==e.serverSyncInfos?e.serverSyncInfos.serverTimestamp-e.serverSyncInfos.clientTime:void 0;return function(a){var s,u=a.response,l=a.scheduleRequest,m=a.externalClockOffset,g=a.url,y=null!==(s=u.url)&&void 0!==s?s:g,_="string"==typeof u.responseData?(new DOMParser).parseFromString(u.responseData,"text/xml"):u.responseData,b=null!=r?r:m,T=a.unsafeMode?a.previousManifest:null;return function t(n){if("done"===n.type){var r=n.value,a=r.warnings,s=r.parsed,u=a.map((function(e){return{type:"warning",value:e}})),m=new v.ZP(s,e);return(0,d.z)(i.of.apply(void 0,u),(0,Qe.Z)(m,y))}var g=n.value,_=g.ressources,b=g.continue,T=_.map((function(e){return l((function(){return function(e){return(0,o.ZP)({url:e,responseType:"text"}).pipe((0,f.h)((function(e){return"data-loaded"===e.type})),(0,p.U)((function(e){return e.value})))}(e)}))}));return(0,c.aj)(T).pipe((0,h.zg)((function(e){for(var n=[],r=0;r=300)return g.Z.warn("Fetch: Request HTTP Error",e),void n.error(new at.Z(e.url,e.status,ot.br.ERROR_HTTP_CODE));if(!(0,st.Z)(e.body)){var t=e.headers.get("Content-Length"),r=(0,st.Z)(t)||isNaN(+t)?void 0:+t,i=e.body.getReader(),s=0;return u()}function u(){return l.apply(this,arguments)}function l(){return(l=nt(it().mark((function t(){var l,d,c,f,p;return it().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,i.read();case 2:if((l=t.sent).done||(0,st.Z)(l.value)){t.next=11;break}return s+=l.value.byteLength,d=performance.now(),c={type:"data-chunk",value:{url:e.url,currentTime:d,duration:d-o,sendingTime:o,chunkSize:l.value.byteLength,chunk:l.value.buffer,size:s,totalSize:r}},n.next(c),t.abrupt("return",u());case 11:l.done&&(f=performance.now(),p=f-o,a=!0,n.next({type:"data-complete",value:{duration:p,receivedTime:f,sendingTime:o,size:s,status:e.status,url:e.url}}),n.complete());case 12:case"end":return t.stop()}}),t)})))).apply(this,arguments)}n.error(new at.Z(e.url,e.status,ot.br.PARSE_ERROR))})).catch((function(t){if(r)g.Z.debug("Fetch: Request aborted.");else{if(i)return g.Z.warn("Fetch: Request timeouted."),void n.error(new at.Z(e.url,0,ot.br.TIMEOUT));g.Z.warn("Fetch: Request Error",t instanceof Error?t.toString():""),n.error(new at.Z(e.url,0,ot.br.ERROR_EVENT))}})),function(){r=!0,u()}}))};var pt=n(8806),ht=n(281);function vt(e){return"video/webm"===e.mimeType||"audio/webm"===e.mimeType}var mt=n(3068),gt=n(4460);function yt(e){return function(t){return e(t).pipe((0,mt.b)((function(e){"data-loaded"!==e.type&&"data-chunk"!==e.type||null===e.value.responseData||"string"==typeof e.value.responseData||vt(t.representation)||(0,gt.Z)(new Uint8Array(e.value.responseData),t.segment.isInit)})))}}var _t=n(6968);function bt(e,t){var n=t.segment;if(void 0===n.range)return(0,o.ZP)({url:e,responseType:"arraybuffer",sendProgressEvents:!0});if(void 0===n.indexRange)return(0,o.ZP)({url:e,headers:{Range:(0,ht.Z)(n.range)},responseType:"arraybuffer",sendProgressEvents:!0});if(n.range[1]+1===n.indexRange[0])return(0,o.ZP)({url:e,headers:{Range:(0,ht.Z)([n.range[0],n.indexRange[1]])},responseType:"arraybuffer",sendProgressEvents:!0});var r=(0,o.ZP)({url:e,headers:{Range:(0,ht.Z)(n.range)},responseType:"arraybuffer",sendProgressEvents:!1}),i=(0,o.ZP)({url:e,headers:{Range:(0,ht.Z)(n.indexRange)},responseType:"arraybuffer",sendProgressEvents:!1});return(0,c.aj)([r,i]).pipe((0,p.U)((function(t){var n=t[0],r=t[1],i=(0,_t.zo)(new Uint8Array(n.value.responseData),new Uint8Array(r.value.responseData)),a=Math.min(n.value.sendingTime,r.value.sendingTime),o=Math.max(n.value.receivedTime,r.value.receivedTime);return{type:"data-loaded",value:{url:e,responseData:i,size:n.value.size+r.value.size,duration:o-a,sendingTime:a,receivedTime:o}}})))}var Tt=n(2807),Et=n(8766);function wt(e,t){var n=t.segment,r=void 0!==n.range?{Range:(0,ht.Z)(n.range)}:void 0;return ft({url:e,headers:r}).pipe((0,Tt.R)((function(e,t){if("data-complete"===t.type)return null!==e.partialChunk&&g.Z.warn("DASH Pipelines: remaining chunk does not belong to any segment"),{event:t,completeChunks:[],partialChunk:null};var n=new Uint8Array(t.value.chunk),r=function(e){for(var t=0,n=[];te.length)return[n,r];var o=(0,Et.Z)(r,1835295092);if(o<0)return[n,r];var s=t+o+(0,_t.pX)(e,o+t);if(s>e.length)return[n,r];var u=Math.max(a,s),l=e.subarray(t,u);n.push(l),t=u}return[n,null]}(null!==e.partialChunk?(0,_t.zo)(e.partialChunk,n):n);return{event:t,completeChunks:r[0],partialChunk:r[1]}}),{event:null,completeChunks:[],partialChunk:null}),(0,h.zg)((function(e){for(var t=[],n=0;n0)for(var p=0;p=Math.pow(2,8-n))return n}function Nt(e,t){var n=Ct(e,t);if(null==n)return g.Z.warn("webm: unrepresentable length"),null;if(t+n>e.length)return g.Z.warn("webm: impossible length"),null;for(var r=0,i=0;ie.length)return g.Z.warn("webm: impossible length"),null;for(var r=(e[t]&(1<<8-n)-1)*Math.pow(2,8*(n-1)),i=1;i=i)return!0}return!1}(r,t)}}}function Bt(e){var t=e.__priv_patchLastSegmentInSidx;return function(e){var n=e.content,r=e.response,a=e.initTimescale,o=n.period,u=n.representation,l=n.segment,d=n.manifest,c=r.data,f=r.isChunked,p=[o.start,o.end];if(null===c)return l.isInit?(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}}):(0,i.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:p}});var h=c instanceof Uint8Array?c:new Uint8Array(c),v=vt(u);if(!l.isInit){var m=v?null:Dt(h,f,l,a),g=(0,s.Z)(l.timestampOffset,0);if(!v){var y=(0,kt.s9)(h);if(void 0!==y){var _=Lt(y.filter((function(e){return void 0!==l.privateInfos&&void 0!==l.privateInfos.isEMSGWhitelisted&&l.privateInfos.isEMSGWhitelisted(e)})),d.publishTime);if(void 0!==_){var b=_.needsManifestRefresh,T=_.inbandEvents;return(0,i.of)({type:"parsed-segment",value:{chunkData:h,chunkInfos:m,chunkOffset:g,appendWindow:p,inbandEvents:T,needsManifestRefresh:b}})}}}return(0,i.of)({type:"parsed-segment",value:{chunkData:h,chunkInfos:m,chunkOffset:g,appendWindow:p}})}var E,w=l.indexRange;if(v)E=function(e,t){var n=Zt(xt,[],e,[t,e.length]);if(null==n)return null;var r=n[0],i=n[1],a=Rt(e,r);if(null==a)return null;var o=Mt(e,r);if(null==o)return null;var s=Zt(475249515,[],e,[r,i]);if(null==s)return null;for(var u=[],l=s[0];l0){var S=E[E.length-1];Array.isArray(S.range)&&(S.range[1]=1/0)}u.index instanceof Ee&&null!==E&&E.length>0&&u.index._addSegments(E);var k=v?Rt(h,0):(0,kt.LD)(h),A=(0,st.Z)(k)?void 0:k,x=!1;if(!v){var I=(0,At.Z)(h);I.length>0&&(x=u._addProtectionData("cenc",I))}return(0,i.of)({type:"parsed-init-segment",value:{initializationData:h,protectionDataUpdate:x,initTimescale:A}})}}function Ut(e){return"application/mp4"===e.mimeType}var Ft=n(6807);function zt(e,t,n,r){var i,a,o=e.segment,s=e.adaptation,u=e.representation;if(o.isInit)return null;null===n?r?(i=o.time,a=o.end):g.Z.warn("Transport: Unavailable time data for current text track."):(i=n.time,void 0!==n.duration?a=i+n.duration:r||(a=i+o.duration));var l=function(e){var t=e.codec;if(void 0===t)throw new Error("Cannot parse subtitles: unknown format");switch(t.toLowerCase()){case"stpp":case"stpp.ttml.im1t":return"ttml";case"wvtt":return"vtt"}throw new Error('The codec used for the subtitles "'+t+'" is not managed yet.')}(u);return{data:function(e){var t=(0,Ft.Le)(e);return null===t?"":(0,H.uR)(t)}(t),type:l,language:s.language,start:i,end:a}}function Kt(e,t,n){var r=e.segment,i=e.adaptation,a=e.representation;return r.isInit?null:(n&&g.Z.warn("Transport: Unavailable time data for current text track."),{data:t,type:function(e){var t=e.mimeType,n=void 0===t?"":t;switch(e.mimeType){case"application/ttml+xml":return"ttml";case"application/x-sami":case"application/smil":return"sami";case"text/vtt":return"vtt"}var r=e.codec;if("srt"===(void 0===r?"":r).toLowerCase())return"srt";throw new Error("could not find a text-track parser for the type "+n)}(a),language:i.language})}function Vt(e){var t=e.__priv_patchLastSegmentInSidx;return function(e){var n=e.response,r=e.content,a=e.initTimescale,o=r.period,u=r.representation,l=r.segment,d=l.timestampOffset,c=void 0===d?0:d,f=n.data,p=n.isChunked;return null===f?l.isInit?(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}}):(0,i.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:c,appendWindow:[o.start,o.end]}}):Ut(u)?function(e,t){var n=e.response,r=e.content,a=e.initTimescale,o=r.period,u=r.representation,l=r.segment,d=l.isInit,c=l.indexRange,f=n.data,p=n.isChunked,h="string"==typeof f?(0,H.tG)(f):f instanceof Uint8Array?f:new Uint8Array(f);if(d){var v=(0,kt.Wf)(h,Array.isArray(c)?c[0]:0);if(!0===t&&null!==v&&v.length>0){var m=v[v.length-1];Array.isArray(m.range)&&(m.range[1]=1/0)}var g=(0,kt.LD)(h);return u.index instanceof Ee&&null!==v&&v.length>0&&u.index._addSegments(v),(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:g}})}var y=Dt(h,p,l,a),_=zt(r,h,y,p),b=(0,s.Z)(l.timestampOffset,0);return(0,i.of)({type:"parsed-segment",value:{chunkData:_,chunkInfos:y,chunkOffset:b,appendWindow:[o.start,o.end]}})}({response:{data:f,isChunked:p},content:r,initTimescale:a},t):function(e){var t=e.response,n=e.content,r=n.period,a=n.segment,o=a.timestampOffset,s=void 0===o?0:o;if(a.isInit)return(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}});var u,l=t.data,d=t.isChunked;if("string"!=typeof l){var c=l instanceof Uint8Array?l:new Uint8Array(l);u=(0,H.uR)(c)}else u=l;var f=Kt(n,u,d);return(0,i.of)({type:"parsed-segment",value:{chunkData:f,chunkInfos:null,chunkOffset:s,appendWindow:[r.start,r.end]}})}({response:{data:f,isChunked:p},content:r})}}const Wt=function(e){var t=(0,r.Z)({customManifestLoader:e.manifestLoader}),n=Je(e),a=function(e){var t=e.lowLatencyMode,n=e.segmentLoader;return!0!==e.checkMediaSegmentIntegrity?r:yt(r);function r(e){var r=e.url;if(null==r)return(0,i.of)({type:"data-created",value:{responseData:null}});if(t||void 0===n)return St(r,e,t);var a={adaptation:e.adaptation,manifest:e.manifest,period:e.period,representation:e.representation,segment:e.segment,transport:"dash",url:r};return new et.y((function(i){var o=!1,s=!1,u=n(a,{reject:function(e){void 0===e&&(e={}),s||(o=!0,i.error(e))},resolve:function(e){s||(o=!0,i.next({type:"data-loaded",value:{responseData:e.data,size:e.size,duration:e.duration}}),i.complete())},progress:function(e){s||i.next({type:"progress",value:{duration:e.duration,size:e.size,totalSize:e.totalSize}})},fallback:function(){s=!0,St(r,e,t).subscribe(i)}});return function(){o||s||"function"!=typeof u||u()}}))}}(e),s=Bt(e);return{manifest:{loader:t,parser:n},audio:{loader:a,parser:s},video:{loader:a,parser:s},text:{loader:function(e){var t=e.lowLatencyMode;return!0!==e.checkMediaSegmentIntegrity?n:yt(n);function n(e){var n=e.segment.range,r=e.url;if(null===r)return(0,i.of)({type:"data-created",value:{responseData:null}});if(e.segment.isInit)return bt(r,e);var a=Ut(e.representation);if(t&&a){if(ct())return wt(r,e);(0,pt.Z)("DASH: Your browser does not have the fetch API. You will have a higher chance of rebuffering when playing close to the live edge")}var s=a?"arraybuffer":"text";return(0,o.ZP)({url:r,responseType:s,headers:Array.isArray(n)?{Range:(0,ht.Z)(n)}:null,sendProgressEvents:!0})}}(e),parser:Vt(e)},image:{loader:u,parser:l}}}},2339:(e,t,n)=>{"use strict";n.d(t,{Z:()=>ye});var r=n(8170),i=n(5709),a=n(3068),o=n(7874),s=n(3887),u=n(1966),l=n(6807),d=n(7714),c=n(811),f=n(6968),p=n(6923),h=n(8026),v=n(9829),m=n(3635),g=n(5278),y=n(2689),_={};function b(e){if(null!=_[e])return _[e];var t=(0,m.tG)(e);return _[e]=t,t}function T(e,t){var n=t.length+8;return n<=y.s?(0,f.zo)((0,f.kh)(n),b(e),t):(0,f.zo)((0,f.kh)(1),b(e),(0,f.el)(n+8),t)}function E(e,t){return T(e,f.zo.apply(void 0,t))}function w(e){var t=[];e.periods.forEach((function(n){var r=n.id;if((0,d.Z)(t,r)){s.Z.warn("Two periods with the same ID found. Updating.");var i=r+"-dup";n.id=i,w(e),t.push(i)}else t.push(r);var a=n.adaptations,o=[];Object.keys(a).forEach((function(t){var n=a[t];void 0!==n&&n.forEach((function(t){var n=t.id;if((0,d.Z)(o,n)){s.Z.warn("Two adaptations with the same ID found. Updating.",n);var r=n+"-dup";t.id=r,w(e),o.push(r)}else o.push(n);var i=[];t.representations.forEach((function(t){var n=t.id;if((0,d.Z)(i,n)){s.Z.warn("Two representations with the same ID found. Updating.",n);var r=n+"-dup";t.id=r,w(e),i.push(r)}else i.push(n)}))}))}))}))}var S=n(9689);function k(e){return[{systemId:"edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",privateData:(0,f.zo)([8,1,18,16],e)}]}function A(e,t){if(void 0===t&&(t=k),null===e.firstElementChild||"ProtectionHeader"!==e.firstElementChild.nodeName)throw new Error("Protection should have ProtectionHeader child");var n=e.firstElementChild,r=(0,S.K)(null===n.textContent?"":n.textContent),i=function(e){var t=(0,f.qb)(e,8),n=(0,m.wV)(e.subarray(10,t+10)),r=(new DOMParser).parseFromString(n,"application/xml").querySelector("KID");if(null===r)throw new Error("Cannot parse PlayReady private data: invalid XML");var i=null===r.textContent?"":r.textContent,a=(0,m.wO)((0,S.K)(i));return(0,m.ci)(a).toLowerCase()}(r),a=(0,m.nr)(i),o=n.getAttribute("SystemID");return{keyId:a,keySystems:[{systemId:(null!==o?o:"").toLowerCase().replace(/\{|\}/g,""),privateData:r}].concat(t(a))}}var x=n(9362),I=n(8232),Z=n(3911),R=n(1091),M=n(5505);function C(e,t,n){var r=e.timeline,i=e.timescale,a=r[r.length-1],o=t.timescale===i?{time:t.time,duration:t.duration}:{time:t.time/t.timescale*i,duration:t.duration/t.timescale*i};return!(n.time===o.time)&&(o.time>=(0,Z.jH)(a,null)&&(a.duration===o.duration?a.repeatCount++:e.timeline.push({duration:o.duration,start:o.time,repeatCount:0}),!0))}function N(e,t){return e.replace(/\{start time\}/g,String(t))}function P(e,t,n){var r=t-e;return r>0?Math.floor(r/n):0}function O(e,t){var n=e.repeatCount;if(null!=e.duration&&n<0){var r=void 0!==t?t.start:1/0;n=Math.ceil((r-e.start)/e.duration)-1}return n}var D=function(){function e(e,t){var n=t.aggressiveMode,r=t.isLive,i=t.segmentPrivateInfos,a=null==e.manifestReceivedTime?performance.now():e.manifestReceivedTime;if(this._index=e,this._indexValidityTime=a,this._initSegmentInfos={bitsPerSample:i.bitsPerSample,channels:i.channels,codecPrivateData:i.codecPrivateData,packetSize:i.packetSize,samplingRate:i.samplingRate,timescale:e.timescale,protection:i.protection},this._isAggressiveMode=n,this._isLive=r,0!==e.timeline.length){var o=e.timeline[e.timeline.length-1],s=(0,Z.jH)(o,null);if(this._initialScaledLastPosition=s,e.isLive){var u=a/1e3*e.timescale;this._scaledLiveGap=u-s}}}var t=e.prototype;return t.getInitSegment=function(){return{id:"init",isInit:!0,privateInfos:{smoothInitSegment:this._initSegmentInfos},mediaURLs:null,time:0,end:0,duration:0,timescale:1}},t.getSegments=function(e,t){this._refreshTimeline();for(var n,r=function(e,t,n){var r=void 0===e.timescale||0===e.timescale?1:e.timescale;return{up:t*r,to:(t+n)*r}}(this._index,e,t),i=r.up,a=r.to,o=this._index,s=o.timeline,u=o.timescale,l=o.media,d=this._isAggressiveMode,c=[],f=s.length,p=null==this._scaledLiveGap?void 0:performance.now()/1e3*u-this._scaledLiveGap,h=0;h=a)return c;null!=n&&(n+=y+1)}return c},t.shouldRefresh=function(e,t){if(this._refreshTimeline(),!this._index.isLive)return!1;var n=this._index,r=n.timeline,i=n.timescale,a=r[r.length-1];if(void 0===a)return!1;var o=a.repeatCount,s=a.start+(o+1)*a.duration;return!(t*i=s||e*i>a.start+o*a.duration)},t.getFirstPosition=function(){this._refreshTimeline();var e=this._index;return 0===e.timeline.length?null:e.timeline[0].start/e.timescale},t.getLastPosition=function(){this._refreshTimeline();var e=this._index;if(null==this._scaledLiveGap){var t=e.timeline[e.timeline.length-1];return(0,Z.jH)(t,null)/e.timescale}for(var n=e.timeline.length-1;n>=0;n--)for(var r=e.timeline[n],i=performance.now()/1e3*e.timescale,a=r.start,o=r.duration,s=r.repeatCount;s>=0;s--){var u=a+o*(s+1);if((this._isAggressiveMode?u-o:u)<=i-this._scaledLiveGap)return u/e.timescale}},t.checkDiscontinuity=function(e){return this._refreshTimeline(),(0,Z._j)(this._index,e,void 0)},t.areSegmentsChronologicallyGenerated=function(){return!0},t.isSegmentStillAvailable=function(e){if(e.isInit)return!0;this._refreshTimeline();var t=this._index,n=t.timeline,r=t.timescale;return(0,R.Z)(e,n,r,0)},t.canBeOutOfSyncError=function(e){return!!this._isLive&&(e instanceof x.Z&&(e.isHttpError(404)||e.isHttpError(412)))},t._replace=function(e){var t=this._index.timeline,n=e._index.timeline,r=this._index.timescale,i=e._index.timescale;if(this._index=e._index,this._initialScaledLastPosition=e._initialScaledLastPosition,this._indexValidityTime=e._indexValidityTime,this._scaledLiveGap=e._scaledLiveGap,0!==t.length&&0!==n.length&&r===i){var a=t[t.length-1],o=n[n.length-1],u=(0,Z.jH)(o,null);if(!((0,Z.jH)(a,null)<=u))for(var l=0;lu){if(d.duration!==o.duration)return;var f=u-d.start;if(0===f)return s.Z.warn("Smooth Parser: a discontinuity detected in the previous manifest has been resolved."),void(this._index.timeline=this._index.timeline.concat(t.slice(l)));if(f<0||f%d.duration!=0)return;var p=f/d.duration-1,h=d.repeatCount-p;if(h<0)return;o.repeatCount+=h;var v=t.slice(l+1);return void(this._index.timeline=this._index.timeline.concat(v))}}}},t._update=function(e){(0,M.Z)(this._index.timeline,e._index.timeline),this._initialScaledLastPosition=e._initialScaledLastPosition,this._indexValidityTime=e._indexValidityTime,this._scaledLiveGap=e._scaledLiveGap},t.isFinished=function(){return!this._isLive},t.isInitialized=function(){return!0},t._addSegments=function(e,t){this._refreshTimeline();for(var n=0;n>3:2)?"mp4a.40.2":"mp4a.40."+n}(u,l);return{audiotag:void 0!==i?parseInt(i,10):i,bitrate:h,bitsPerSample:void 0!==a?parseInt(a,10):a,channels:void 0!==o?parseInt(o,10):o,codecPrivateData:u,codecs:v,customAttributes:n,mimeType:void 0!==l?F[l]:l,packetSize:void 0!==d?parseInt(d,10):d,samplingRate:void 0!==c?parseInt(c,10):c};case"video":var m=r("CodecPrivateData"),y=r("FourCC"),_=r("MaxWidth"),b=r("MaxHeight"),T=r("Bitrate"),E=void 0===T||isNaN(parseInt(T,10))?0:parseInt(T,10);if(void 0!==y&&void 0===F[y]||void 0===m)return s.Z.warn("Smooth parser: Unsupported video codec. Ignoring quality level."),null;var w=function(e){var t=/00000001\d7([0-9a-fA-F]{6})/.exec(e);return null!==t&&(0,p.Z)(t[1])?"avc1."+t[1]:"avc1.4D401E"}(m);return{bitrate:E,customAttributes:n,mimeType:void 0!==y?F[y]:y,codecPrivateData:m,codecs:w,width:void 0!==_?parseInt(_,10):void 0,height:void 0!==b?parseInt(b,10):void 0};case"text":var S=r("CodecPrivateData"),k=r("FourCC"),A=r("Bitrate");return{bitrate:void 0===A||isNaN(parseInt(A,10))?0:parseInt(A,10),customAttributes:n,mimeType:void 0!==k?F[k]:k,codecPrivateData:(0,g.Z)(S,"")};default:return s.Z.error("Smooth Parser: Unrecognized StreamIndex type: "+t),null}}function o(t){var r=t.root,i=t.timescale,o=t.rootURL,u=t.protections,l=t.timeShiftBufferDepth,g=t.manifestReceivedTime,y=t.isLive,_=r.getAttribute("Timescale"),b=null===_||isNaN(+_)?i:+_,E=r.getAttribute("Type");if(null===E)throw new Error("StreamIndex without type.");(0,d.Z)(B,E)||s.Z.warn("Smooth Parser: Unrecognized adaptation type:",E);var w=E,S=r.getAttribute("Subtype"),k=r.getAttribute("Language"),A=r.getAttribute("Url"),x=null===A?"":A;var I,Z=L(r,(function(e,t,r){switch(t){case"QualityLevel":var i=a(r,w);if(null===i)return e;("video"!==w||i.bitrate>n)&&e.qualityLevels.push(i);break;case"c":e.cNodes.push(r)}return e}),{qualityLevels:[],cNodes:[]}),R=Z.qualityLevels,M=Z.cNodes,C={timeline:(I=M,I.reduce((function(e,t,n){var r=t.getAttribute("d"),i=t.getAttribute("t"),a=t.getAttribute("r"),o=null!==a?+a-1:0,s=null!==i?+i:void 0,u=null!==r?+r:void 0;if(0===n)s=void 0===s||isNaN(s)?0:s;else{var l=e[n-1];if(null==s||isNaN(s)){if(null==l.duration||isNaN(l.duration))throw new Error("Smooth: Invalid CNodes. Missing timestamp.");s=l.start+l.duration*(l.repeatCount+1)}}if(null==u||isNaN(u)){var d=I[n+1];if(void 0===d)return e;var c=d.getAttribute("t"),f=(0,p.Z)(c)?+c:null;if(null===f)throw new Error("Can't build index timeline from Smooth Manifest.");u=f-s}return e.push({duration:u,start:s,repeatCount:o}),e}),[])),timescale:b};(0,c.Z)(0!==R.length,"Adaptation should have at least one playable representation.");var N=w+((0,p.Z)(k)?"_"+k:""),P=R.map((function(t){var n,r,i,a,s=(0,v.Z)(o,x),d={timeline:C.timeline,timescale:C.timescale,media:(n=s,r=t.bitrate,i=t.customAttributes,n.replace(/\{bitrate\}/g,String(r)).replace(/{CustomAttributes}/g,i.length>0?i[0]:"")),isLive:y,timeShiftBufferDepth:l,manifestReceivedTime:g},c=(0,p.Z)(t.mimeType)?t.mimeType:U[w],_=t.codecs,b=N+"_"+(null!=w?w+"-":"")+(null!=c?c+"-":"")+(null!=_?_+"-":"")+String(t.bitrate),E=[];u.length>0&&(a=u[0],u.forEach((function(e){var t=e.keyId;e.keySystems.forEach((function(e){E.push({keyId:t,systemId:e.systemId})}))})));var S={bitsPerSample:t.bitsPerSample,channels:t.channels,codecPrivateData:t.codecPrivateData,packetSize:t.packetSize,samplingRate:t.samplingRate,protection:null!=a?{keyId:a.keyId}:void 0},k=null!=e.aggressiveMode&&e.aggressiveMode,A=new D(d,{aggressiveMode:k,isLive:y,segmentPrivateInfos:S}),I=(0,h.Z)({},t,{index:A,mimeType:c,codecs:_,id:b});if(E.length>0||void 0!==a){var Z=void 0===a?[]:a.keySystems.map((function(e){var t=e.systemId,n=e.privateData,r=t.replace(/-/g,"");return{systemId:r,data:function(e,t){if(32!==e.length)throw new Error("HSS: wrong system id length");var n=0;return T("pssh",(0,f.zo)([n,0,0,0],(0,m.nr)(e),(0,f.kh)(t.length),t))}(r,n)}}));if(Z.length>0){var R=[{type:"cenc",values:Z}];I.contentProtections={keyIds:E,initData:R}}else I.contentProtections={keyIds:E,initData:[]}}return I}));if("ADVT"===S)return null;var O={id:N,type:w,representations:P,language:null==k?void 0:k};return"text"===w&&"DESC"===S&&(O.closedCaption=!0),O}return function(n,r,a){var s=(0,v.f)(null==r?"":r),u=n.documentElement;if(null==u||"SmoothStreamingMedia"!==u.nodeName)throw new Error("document root should be SmoothStreamingMedia");var l=u.getAttribute("MajorVersion"),d=u.getAttribute("MinorVersion");if(null===l||null===d||!/^[2]-[0-2]$/.test(l+"-"+d))throw new Error("Version should be 2.0, 2.1 or 2.2");var c,f,h=u.getAttribute("Timescale"),m=(0,p.Z)(h)?isNaN(+h)?1e7:+h:1e7,g=L(u,(function(t,n,r){switch(n){case"Protection":t.protections.push(A(r,e.keySystems));break;case"StreamIndex":t.adaptationNodes.push(r)}return t}),{adaptationNodes:[],protections:[]}),y=g.protections,_=g.adaptationNodes,b="boolean"==typeof(c=u.getAttribute("IsLive"))?c:"string"==typeof c&&"TRUE"===c.toUpperCase();if(b){var T=u.getAttribute("DVRWindowLength");null==T||isNaN(+T)||0==+T||(f=+T/m)}var E,S,k,x,I,Z,R=_.reduce((function(e,t){var n=o({root:t,rootURL:s,timescale:m,protections:y,isLive:b,timeShiftBufferDepth:f,manifestReceivedTime:a});if(null===n)return e;var r=n.type,i=e[r];return void 0===i?e[r]=[n]:i.push(n),e}),{}),M=null,C=void 0!==R.video?R.video[0]:void 0,N=void 0!==R.audio?R.audio[0]:void 0;if(void 0!==C||void 0!==N){var P=[],O=[];if(void 0!==C){var D=C.representations[0];if(void 0!==D){var B=D.index.getFirstPosition(),U=D.index.getLastPosition();null!=B&&P.push(B),null!=U&&O.push(U)}}if(void 0!==N){var F=N.representations[0];if(void 0!==F){var z=F.index.getFirstPosition(),K=F.index.getLastPosition();null!=z&&P.push(z),null!=K&&O.push(K)}}P.length>0&&(I=Math.max.apply(Math,P)),O.length>0&&(Z=Math.min.apply(Math,O))}var V=u.getAttribute("Duration"),W=null!=V&&0!=+V?+V/m:void 0;b?(E=e.suggestedPresentationDelay,S=t,k=null!=I?I:S,x={isLinear:!0,value:null!=Z?Z:Date.now()/1e3-S,time:performance.now()},M=null!=f?f:null):(k=null!=I?I:0,x={isLinear:!1,value:void 0!==Z?Z:void 0!==W?k+W:1/0,time:performance.now()});var G=b?0:k,H=b?void 0:x.value,$={availabilityStartTime:void 0===S?0:S,clockOffset:i,isLive:b,isDynamic:b,timeBounds:{absoluteMinimumTime:k,timeshiftDepth:M,maximumTimeData:x},periods:[{adaptations:R,duration:void 0!==H?H-G:W,end:H,id:"gen-smooth-period-0",start:G}],suggestedPresentationDelay:E,transportType:"smooth",uris:null==r?[]:[r]};return w($),$}};var K=n(4597),V=n(8806),W=n(4460),G=n(7445),H=n(7278),$=n(4644),j=n(2297);function Y(e,t,n,r,i){var a,o,u,d=[];if(i){var c=(0,l.XA)(e);null!==c?(u=function(e){var t=(0,j.nR)(e,3565190898,3392751253,2387879627,2655430559);if(void 0===t)return[];for(var n=[],r=t[0],i=t[4],a=0;a0)return e;var n=new Uint8Array(e.length+4);return n.set(e.subarray(0,t+8),0),n[t+3]=1|n[t+3],n.set([0,0,0,0],t+8),n.set(e.subarray(t+8,e.length),t+12),(0,$.J6)(n)}(l,s[1]-s[0]),p=te(u,d,c,i,(0,j.nR)(a,2721664850,1520127764,2722393154,2086964724)),h=E("moof",[i,p]),v=(0,j.Qy)(h,1836019558),m=(0,j.Qy)(p,1953653094),g=(0,j.Qy)(c,1953658222);if(null===v||null===m||null===g)throw new Error("Smooth: Invalid moof, trun or traf generation");var y=v[1]-v[0]+i.length+(m[1]-m[0])+u.length+d.length+(g[1]-g[0])+8,_=n[2]-n[0],b=h.length-_,w=(0,j.Qy)(e,1835295092);if(null===w)throw new Error("Smooth: Invalid ISOBMFF given");if(!q.YM&&(0===b||b<=-8)){var S=w[1];return h.set((0,f.kh)(S),y),e.set(h,n[0]),b<=-8&&e.set(T("free",new Uint8Array(-b-8)),h.length),e}var k=w[1]+b;h.set((0,f.kh)(k),y);var A=new Uint8Array(e.length+b),x=e.subarray(0,n[0]),I=e.subarray(n[2],e.length);return A.set(x,0),A.set(h,x.length),A.set(I,x.length+h.length),A}var re=n(4379),ie=n(281);function ae(e,t,n,r,i,a){var o,s,u,l=E("stbl",[n,T("stts",new Uint8Array(8)),T("stsc",new Uint8Array(8)),T("stsz",new Uint8Array(12)),T("stco",new Uint8Array(8))]),d=E("dinf",[function(e){return T("dref",(0,f.zo)(7,[1],e))}(T("url ",new Uint8Array([0,0,0,1])))]),c=E("minf",[r,d,l]),p=function(e){var t,n;switch(e){case"video":t="vide",n="VideoHandler";break;case"audio":t="soun",n="SoundHandler";break;default:t="hint",n=""}return T("hdlr",(0,f.zo)(8,(0,m.tG)(t),12,(0,m.tG)(n),1))}(t),h=E("mdia",[function(e){return T("mdhd",(0,f.zo)(12,(0,f.kh)(e),8))}(e),p,c]),v=E("trak",[function(e,t,n){return T("tkhd",(0,f.zo)((0,f.kh)(7),8,(0,f.kh)(n),20,[1,0,0,0],[0,1,0,0],12,[0,1,0,0],12,[64,0,0,0],(0,f.XT)(e),2,(0,f.XT)(t),2))}(i,a,1),h]),g=E("mvex",[(o=1,T("trex",(0,f.zo)(4,(0,f.kh)(o),[0,0,0,1],12)))]),y=function(e,t,n){return E("moov",[e,t,n])}(function(e,t){return T("mvhd",(0,f.zo)(12,(0,f.kh)(e),4,[0,1],2,[1,0],10,[0,1],14,[0,1],14,[64,0,0,0],26,(0,f.XT)(t+1)))}(e,1),g,v),_=(s="isom",u=["isom","iso2","iso6","avc1","dash"],T("ftyp",f.zo.apply(void 0,[(0,m.tG)(s),[0,0,0,1]].concat(u.map(m.tG)))));return(0,f.zo)(_,y)}function oe(e,t,n,r,i,a,o,s){var u=o.split("00000001"),l=u[1],d=u[2];if(void 0===l||void 0===d)throw new Error("Smooth: unsupported codec private data.");var c,p,h=function(e,t,n){var r=2===n?1:4===n?3:0,i=e[1],a=e[2],o=e[3];return T("avcC",(0,f.zo)([1,i,a,o,252|r,225],(0,f.XT)(e.length),e,[1],(0,f.XT)(t.length),t))}((0,m.nr)(l),(0,m.nr)(d),a);if(void 0===s){c=J([function(e,t,n,r,i,a,o){return T("avc1",(0,f.zo)(6,(0,f.XT)(1),16,(0,f.XT)(e),(0,f.XT)(t),(0,f.XT)(n),2,(0,f.XT)(r),6,[0,1,i.length],(0,m.tG)(i),31-i.length,(0,f.XT)(a),[255,255],o))}(t,n,r,i,"AVC Coding",24,h)])}else{var v=E("schi",[ee(1,8,s)]),g=X("cenc",65536);c=J([function(e,t,n,r,i,a,o,s){return T("encv",(0,f.zo)(6,(0,f.XT)(1),16,(0,f.XT)(e),(0,f.XT)(t),(0,f.XT)(n),2,(0,f.XT)(r),6,[0,1,i.length],(0,m.tG)(i),31-i.length,(0,f.XT)(a),[255,255],o,s))}(t,n,r,i,"AVC Coding",24,h,E("sinf",[Q("avc1"),g,v]))])}return ae(e,"video",c,((p=new Uint8Array(12))[3]=1,T("vmhd",p)),t,n)}var se=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];function ue(e,t,n,r,i,a,o){var s,u,l,d=function(e,t){return T("esds",(0,f.zo)(4,[3,25],(0,f.XT)(e),[0,4,17,64,21],11,[5,2],(0,m.nr)(t),[6,1,2]))}(1,0===a.length?(s=i,u=t,l=((l=((l=(63&2)<<4)|31&se.indexOf(s))<<4)|31&u)<<3,(0,m.ci)((0,f.XT)(l))):a);return ae(e,"audio",function(){if(void 0===o)return J([function(e,t,n,r,i,a){return T("mp4a",(0,f.zo)(6,(0,f.XT)(e),8,(0,f.XT)(t),(0,f.XT)(n),2,(0,f.XT)(r),(0,f.XT)(i),2,a))}(1,t,n,r,i,d)]);var e=E("schi",[ee(1,8,o)]),a=X("cenc",65536),s=E("sinf",[Q("mp4a"),a,e]);return J([function(e,t,n,r,i,a,o){return T("enca",(0,f.zo)(6,(0,f.XT)(e),8,(0,f.XT)(t),(0,f.XT)(n),2,(0,f.XT)(r),(0,f.XT)(i),2,a,o))}(1,t,n,r,i,d,s)])}(),T("smhd",new Uint8Array(8)),0,0)}function le(e){var t,n=e.url,r=e.segment.range;return Array.isArray(r)&&(t={Range:(0,ie.Z)(r)}),(0,K.ZP)({url:n,responseType:"arraybuffer",headers:t,sendProgressEvents:!0})}const de=function(e){return function(t){var n=t.segment,i=t.representation,a=t.adaptation,o=t.period,s=t.manifest,u=t.url;if(n.isInit){if(void 0===n.privateInfos||void 0===n.privateInfos.smoothInitSegment)throw new Error("Smooth: Invalid segment format");var l,d=n.privateInfos.smoothInitSegment,c=d.codecPrivateData,f=d.timescale,p=d.protection,h=void 0===p?{keyId:void 0,keySystems:void 0}:p;if(void 0===c)throw new Error("Smooth: no codec private data.");switch(a.type){case"video":var v=i.width,m=void 0===v?0:v,g=i.height;l=oe(f,m,void 0===g?0:g,72,72,4,c,h.keyId);break;case"audio":var y=d.channels,_=void 0===y?0:y,b=d.bitsPerSample,T=void 0===b?0:b,E=d.packetSize,w=void 0===E?0:E,S=d.samplingRate;l=ue(f,_,T,w,void 0===S?0:S,c,h.keyId);break;default:0,l=new Uint8Array(0)}return(0,r.of)({type:"data-created",value:{responseData:l}})}if(null===u)return(0,r.of)({type:"data-created",value:{responseData:null}});var k={adaptation:a,manifest:s,period:o,representation:i,segment:n,transport:"smooth",url:u};return"function"!=typeof e?le(k):new re.y((function(t){var n=!1,r=!1,i=e(k,{reject:function(e){void 0===e&&(e={}),r||(n=!0,t.error(e))},resolve:function(e){r||(n=!0,t.next({type:"data-loaded",value:{responseData:e.data,size:e.size,duration:e.duration}}),t.complete())},fallback:function(){r=!0,le(k).subscribe(t)},progress:function(e){r||t.next({type:"progress",value:{duration:e.duration,size:e.size,totalSize:e.totalSize}})}});return function(){n||r||"function"!=typeof i||i()}}))}};var ce=/(\.isml?)(\?token=\S+)?$/,fe=/\?token=(\S+)/;function pe(e,t){return(0,p.Z)(t)?e.replace(fe,"?token="+t):e.replace(fe,"")}function he(e){return ce.test(e)?((0,V.Z)("Giving a isml URL to loadVideo is deprecated. Please give the Manifest URL directly"),e.replace(ce,"$1/manifest$2")):e}var ve=/\.wsx?(\?token=\S+)?/;function me(e,t,n){var r;s.Z.debug("Smooth Parser: update segments information.");for(var i=e.representations,a=0;a=0}const ye=function(e){var t=z(e),n=de(e.segmentLoader),d={customManifestLoader:e.manifestLoader},c={loader:function(t){return t.segment.isInit||!0!==e.checkMediaSegmentIntegrity?n(t):n(t).pipe((0,a.b)((function(e){"data-loaded"!==e.type&&"data-chunk"!==e.type||null===e.value.responseData||(0,W.Z)(new Uint8Array(e.value.responseData),t.segment.isInit)})))},parser:function(e){var t,n,i=e.content,a=e.response,o=e.initTimescale,s=i.segment,u=i.adaptation,l=i.manifest,d=a.data,c=a.isChunked;if(null===d)return s.isInit?(0,r.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}}):(0,r.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:[void 0,void 0]}});var f=d instanceof Uint8Array?d:new Uint8Array(d);if(s.isInit){var p=null===(n=null===(t=s.privateInfos)||void 0===t?void 0:t.smoothInitSegment)||void 0===n?void 0:n.timescale;return(0,r.of)({type:"parsed-init-segment",value:{initializationData:d,initTimescale:p,protectionDataUpdate:!1}})}var h=void 0!==o?Y(f,c,o,s,l.isLive):null;if(null===h||null===h.chunkInfos||void 0===h.scaledSegmentTime)throw new Error("Smooth Segment without time information");var v=h.nextSegments,m=h.chunkInfos,g=ne(f,h.scaledSegmentTime);return v.length>0&&me(u,v,s),(0,r.of)({type:"parsed-segment",value:{chunkData:g,chunkInfos:m,chunkOffset:0,appendWindow:[void 0,void 0]}})}};return{manifest:{resolver:function(e){var t,n=e.url;if(void 0===n)return(0,r.of)({url:void 0});ve.test(n)?((0,V.Z)("Giving WSX URL to loadVideo is deprecated. You should only give Manifest URLs."),t=(0,K.ZP)({url:pe(n,""),responseType:"document"}).pipe((0,i.U)((function(e){var t=e.value,n=t.responseData.getElementsByTagName("media")[0].getAttribute("src");if(null===n||0===n.length)throw new Error("Invalid ISML");return n})))):t=(0,r.of)(n);var a=function(e){var t=fe.exec(e);if(null!==t){var n=t[1];if(void 0!==n)return n}return""}(n);return t.pipe((0,i.U)((function(e){return{url:pe(he(e),a)}})))},loader:(0,H.Z)(d),parser:function(n){var r=n.response,i=n.url,a=void 0===r.url?i:r.url,o="string"==typeof r.responseData?(new DOMParser).parseFromString(r.responseData,"text/xml"):r.responseData,s=r.receivedTime,l=t(o,a,s),d=new u.ZP(l,{representationFilter:e.representationFilter,supplementaryImageTracks:e.supplementaryImageTracks,supplementaryTextTracks:e.supplementaryTextTracks});return(0,G.Z)(d,a)}},audio:c,video:c,text:{loader:function(t){var n=t.segment,i=t.representation,o=t.url;if(n.isInit||null===o)return(0,r.of)({type:"data-created",value:{responseData:null}});var s=ge(i);return s&&!0===e.checkMediaSegmentIntegrity?(0,K.ZP)({url:o,responseType:"arraybuffer",sendProgressEvents:!0}).pipe((0,a.b)((function(e){"data-loaded"===e.type&&(0,W.Z)(new Uint8Array(e.value.responseData),n.isInit)}))):(0,K.ZP)({url:o,responseType:s?"arraybuffer":"text",sendProgressEvents:!0})},parser:function(e){var t,n,i=e.content,a=e.response,o=e.initTimescale,u=i.manifest,d=i.adaptation,c=i.representation,f=i.segment,p=d.language,h=ge(c),v=c.mimeType,g=void 0===v?"":v,y=c.codec,_=void 0===y?"":y,b=a.data,T=a.isChunked;if(f.isInit)return(0,r.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}});if(null===b)return(0,r.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:[void 0,void 0]}});var E,w,S,k,A=null;if(h){var x;x="string"==typeof b?(0,m.tG)(b):b instanceof Uint8Array?b:new Uint8Array(b);var I=void 0!==o?Y(x,T,o,f,u.isLive):null;n=null==I?void 0:I.nextSegments,null===(A=null!==(t=null==I?void 0:I.chunkInfos)&&void 0!==t?t:null)?T?s.Z.warn("Smooth: Unavailable time data for current text track."):(E=f.time,w=f.end):(E=A.time,w=void 0!==A.duration?A.time+A.duration:f.end);var Z=_.toLowerCase();if("application/ttml+xml+mp4"===g||"stpp"===Z||"stpp.ttml.im1t"===Z)k="ttml";else{if("wvtt"!==Z)throw new Error("could not find a text-track parser for the type "+g);k="vtt"}var R=(0,l.Le)(x);S=null===R?"":(0,m.uR)(R)}else{var M;if(E=f.time,w=f.end,"string"!=typeof b){var C=b instanceof Uint8Array?b:new Uint8Array(b);M=(0,m.uR)(C)}else M=b;switch(g){case"application/x-sami":case"application/smil":k="sami";break;case"application/ttml+xml":k="ttml";break;case"text/vtt":k="vtt"}if(void 0===k){if("srt"!==_.toLowerCase())throw new Error("could not find a text-track parser for the type "+g);k="srt"}S=M}null!==A&&Array.isArray(n)&&n.length>0&&me(d,n,f);var N=null!=E?E:0;return(0,r.of)({type:"parsed-segment",value:{chunkData:{type:k,data:S,start:E,end:w,language:p},chunkInfos:A,chunkOffset:N,appendWindow:[void 0,void 0]}})}},image:{loader:function(e){var t=e.segment,n=e.url;return t.isInit||null===n?(0,r.of)({type:"data-created",value:{responseData:null}}):(0,K.ZP)({url:n,responseType:"arraybuffer",sendProgressEvents:!0})},parser:function(e){var t=e.response,n=e.content,i=t.data,a=t.isChunked;if(n.segment.isInit)return(0,r.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}});if(a)throw new Error("Image data should not be downloaded in chunks");if(null===i||null===o.Z.imageParser)return(0,r.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:[void 0,void 0]}});var s=o.Z.imageParser(new Uint8Array(i)),u=s.thumbs;return(0,r.of)({type:"parsed-segment",value:{chunkData:{data:u,start:0,end:Number.MAX_VALUE,timescale:1,type:"bif"},chunkInfos:{time:0,duration:Number.MAX_VALUE,timescale:s.timescale},chunkOffset:0,protectionDataUpdate:!1,appendWindow:[void 0,void 0]}})}}}}},281:(e,t,n)=>{"use strict";function r(e){var t=e[0],n=e[1];return n===1/0?"bytes="+t+"-":"bytes="+t+"-"+n}n.d(t,{Z:()=>r})},4460:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(5389),i=n(8766);function a(e,t){if(t){if((0,i.Z)(e,1718909296)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `ftyp` box");if((0,i.Z)(e,1836019574)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `moov` box")}else{if((0,i.Z)(e,1836019558)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `moof` box");if((0,i.Z)(e,1835295092)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `mdat` box")}}},8766:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(6968);function i(e,t){for(var n=e.length,i=0;i+8<=n;){var a=(0,r.pX)(e,i);if(0===a)a=n-i;else if(1===a){if(i+16>n)return-1;a=(0,r.pV)(e,i+8)}if(isNaN(a)||a<=0)return-1;if((0,r.pX)(e,i+4)===t)return i+a<=n?i:-1;i+=a}return-1}},7445:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(8170),i=n(9795);function a(e,t){var n=r.of.apply(void 0,e.parsingErrors.map((function(e){return{type:"warning",value:e}})));return(0,i.z)(n,(0,r.of)({type:"parsed",value:{manifest:e,url:t}}))}},7278:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(1946),i=n(4597),a=n(4379);function o(e){var t=e.url;if(void 0===t)throw new Error("Cannot perform HTTP(s) request. URL not known");return(0,i.ZP)({url:t,responseType:"text"})}function s(e){var t=e.customManifestLoader;return(0,r.Z)(t)?o:function(e,t){return function(n){return new a.y((function(r){var i=n.url,a=Date.now()-performance.now(),o=!1,s=!1,u=e(i,{reject:function(e){s||(o=!0,r.error(e))},resolve:function(e){if(!s){o=!0;var t=void 0!==e.receivingTime?e.receivingTime-a:void 0,n=void 0!==e.sendingTime?e.sendingTime-a:void 0;r.next({type:"data-loaded",value:{responseData:e.data,size:e.size,duration:e.duration,url:e.url,receivedTime:t,sendingTime:n}}),r.complete()}},fallback:function(){s=!0,t(n).subscribe(r)}});return function(){o||s||"function"!=typeof u||u()}}))}}(t,o)}},4791:(e,t,n)=>{"use strict";function r(e,t){if(e.length!==t.length)return!1;for(var n=e.length-1;n>=0;n--)if(e[n]!==t[n])return!1;return!0}n.d(t,{Z:()=>r})},3274:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof Array.prototype.find)return e.find(t,n);for(var r=e.length>>>0,i=0;ir})},5138:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof Array.prototype.findIndex)return e.findIndex(t,n);for(var r=e.length>>>0,i=0;ir})},7714:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof Array.prototype.includes)return e.includes(t,n);var r=e.length>>>0;if(0===r)return!1;for(var i,a,o=0|n,s=o>=0?Math.min(o,r-1):Math.max(r+o,0);sr})},811:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a,u:()=>o});var r=n(3801),i=n(1946);function a(e,t){if(!e)throw new r.Z(void 0===t?"invalid assertion":t)}function o(e,t,n){for(var r in void 0===n&&(n="object"),a(!(0,i.Z)(e),n+" should be an object"),t)t.hasOwnProperty(r)&&a(typeof e[r]===t[r],n+" should have property "+r+" as a "+t[r])}},8418:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(3801);function i(e){throw new r.Z("Unreachable path taken")}},9689:(e,t,n)=>{"use strict";n.d(t,{J:()=>s,K:()=>u});var r=n(3887),i=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/"],a=[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,62,255,255,255,63,52,53,54,55,56,57,58,59,60,61,255,255,255,0,255,255,255,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,255,255,255,255,255,255,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];function o(e){if(e>=a.length)throw new Error("Unable to parse base64 string.");var t=a[e];if(255===t)throw new Error("Unable to parse base64 string.");return t}function s(e){var t,n="",r=e.length;for(t=2;t>2],n+=i[(3&e[t-2])<<4|e[t-1]>>4],n+=i[(15&e[t-1])<<2|e[t]>>6],n+=i[63&e[t]];return t===r+1&&(n+=i[e[t-2]>>2],n+=i[(3&e[t-2])<<4],n+="=="),t===r&&(n+=i[e[t-2]>>2],n+=i[(3&e[t-2])<<4|e[t-1]>>4],n+=i[(15&e[t-1])<<2],n+="="),n}function u(e){var t=e.length%4,n=e;0!==t&&(r.Z.warn("base64ToBytes: base64 given miss padding"),n+=3===t?"=":2===t?"==":"===");var i=n.indexOf("=");if(-1!==i&&i>16,l[c+1]=a>>8&255,l[c+2]=255&a;return l.subarray(0,l.length-s)}},6968:(e,t,n)=>{"use strict";function r(){for(var e,t=arguments.length,n=-1,r=0;++n0&&(i.set(e,a),a+=e.length);return i}function i(e,t){return(e[t+0]<<8)+(e[t+1]<<0)}function a(e,t){return 65536*e[t+0]+256*e[t+1]+e[t+2]}function o(e,t){return 16777216*e[t+0]+65536*e[t+1]+256*e[t+2]+e[t+3]}function s(e,t){return 4294967296*(16777216*e[t+0]+65536*e[t+1]+256*e[t+2]+e[t+3])+16777216*e[t+4]+65536*e[t+5]+256*e[t+6]+e[t+7]}function u(e){return new Uint8Array([e>>>8&255,255&e])}function l(e){return new Uint8Array([e>>>24&255,e>>>16&255,e>>>8&255,255&e])}function d(e){var t=e%4294967296,n=(e-t)/4294967296;return new Uint8Array([n>>>24&255,n>>>16&255,n>>>8&255,255&n,t>>>24&255,t>>>16&255,t>>>8&255,255&t])}function c(e,t){return(e[t+0]<<0)+(e[t+1]<<8)}function f(e,t){return e[t+0]+256*e[t+1]+65536*e[t+2]+16777216*e[t+3]}function p(e){return new Uint8Array([255&e,e>>>8&255,e>>>16&255,e>>>24&255])}function h(e){return e instanceof Uint8Array?e:e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer)}n.d(t,{zo:()=>r,zK:()=>i,QI:()=>a,pX:()=>o,pV:()=>s,qb:()=>c,dN:()=>f,XT:()=>u,kh:()=>l,el:()=>d,O_:()=>p,_f:()=>h})},8117:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(4379),i=n(4072),a=n(8170),o=n(1946);const s=function(e){if(e instanceof r.y)return e;if(!(0,o.Z)(e)&&"function"==typeof e.subscribe){var t=e;return new r.y((function(e){var n=t.subscribe((function(t){e.next(t)}),(function(t){e.error(t)}),(function(){e.complete()}));return function(){(0,o.Z)(n)||"function"!=typeof n.dispose?(0,o.Z)(n)||"function"!=typeof n.unsubscribe||n.unsubscribe():n.dispose()}}))}return(0,o.Z)(e)||"function"!=typeof e.then?(0,a.of)(e):(0,i.D)(e)}},8025:(e,t,n)=>{"use strict";n.d(t,{Z:()=>g});var r=n(655),i=1,a=function(){return Promise.resolve()}(),o={};function s(e){return e in o&&(delete o[e],!0)}var u=function(e){var t=i++;return o[t]=!0,a.then((function(){return s(t)&&e()})),t},l=function(e){s(e)},d=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.scheduler=t,r.work=n,r}return r.ZT(t,e),t.prototype.requestAsyncId=function(t,n,r){return void 0===r&&(r=0),null!==r&&r>0?e.prototype.requestAsyncId.call(this,t,n,r):(t.actions.push(this),t.scheduled||(t.scheduled=u(t.flush.bind(t,null))))},t.prototype.recycleAsyncId=function(t,n,r){if(void 0===r&&(r=0),null!==r&&r>0||null===r&&this.delay>0)return e.prototype.recycleAsyncId.call(this,t,n,r);0===t.actions.length&&(l(n),t.scheduled=void 0)},t}(n(6114).o),c=new(function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype.flush=function(e){this.active=!0,this.scheduled=void 0;var t,n=this.actions,r=-1,i=n.length;e=e||n.shift();do{if(t=e.execute(e.state,e.delay))break}while(++r{"use strict";n.d(t,{Z:()=>o,R:()=>s});var r=n(4379),i=n(3887),a=n(1946),o=function(){function e(){this._listeners={}}var t=e.prototype;return t.addEventListener=function(e,t){var n=this._listeners[e];Array.isArray(n)?n.push(t):this._listeners[e]=[t]},t.removeEventListener=function(e,t){if((0,a.Z)(e))this._listeners={};else{var n=this._listeners[e];if(Array.isArray(n))if((0,a.Z)(t))delete this._listeners[e];else{var r=n.indexOf(t);-1!==r&&n.splice(r,1),0===n.length&&delete this._listeners[e]}}},t.trigger=function(e,t){var n=this._listeners[e];Array.isArray(n)&&n.slice().forEach((function(e){try{e(t)}catch(e){i.Z.error(e,e instanceof Error?e.stack:null)}}))},e}();function s(e,t){return new r.y((function(n){function r(e){n.next(e)}return e.addEventListener(t,r),function(){e.removeEventListener(t,r)}}))}},2793:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(1410),i=n(5709),a=n(6008);function o(e,t){return function(n){return(0,r.P)((function(){return n.pipe((0,i.U)(e),(0,a.h)((function(e){return e!==t})))}))}}},9592:(e,t,n)=>{"use strict";function r(e,t){return"function"==typeof Array.prototype.flatMap?e.flatMap(t):e.reduce((function(e,n){var r=t(n);return Array.isArray(r)?(e.push.apply(e,r),e):(e.push(r),e)}),[])}n.d(t,{Z:()=>r})},2572:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});function r(e){return e*(.3*(2*Math.random()-1)+1)}},2870:(e,t,n)=>{"use strict";function r(e){for(var t=0,n=0;nr})},908:(e,t,n)=>{"use strict";function r(){var e="",t=-1;return function(){return++t>=Number.MAX_SAFE_INTEGER&&(e+="0",t=0),e+String(t)}}n.d(t,{Z:()=>r})},6923:(e,t,n)=>{"use strict";function r(e){return"string"==typeof e&&e.length>0}n.d(t,{Z:()=>r})},1946:(e,t,n)=>{"use strict";function r(e){return null==e}n.d(t,{Z:()=>r})},7829:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>r});const r=n(5553).ZP},5553:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>d,iH:()=>l,Y1:()=>u});var r=n(6923),i=n(1946);const a={aa:"aar",ab:"abk",ae:"ave",af:"afr",ak:"aka",am:"amh",an:"arg",ar:"ara",as:"asm",av:"ava",ay:"aym",az:"aze",ba:"bak",be:"bel",bg:"bul",bi:"bis",bm:"bam",bn:"ben",bo:"bod",br:"bre",bs:"bos",ca:"cat",ce:"che",ch:"cha",co:"cos",cr:"cre",cs:"ces",cu:"chu",cv:"chv",cy:"cym",da:"dan",de:"deu",dv:"div",dz:"dzo",ee:"ewe",el:"ell",en:"eng",eo:"epo",es:"spa",et:"est",eu:"eus",fa:"fas",ff:"ful",fi:"fin",fj:"fij",fo:"fao",fr:"fra",fy:"fry",ga:"gle",gd:"gla",gl:"glg",gn:"grn",gu:"guj",gv:"glv",ha:"hau",he:"heb",hi:"hin",ho:"hmo",hr:"hrv",ht:"hat",hu:"hun",hy:"hye",hz:"her",ia:"ina",id:"ind",ie:"ile",ig:"ibo",ii:"iii",ik:"ipk",io:"ido",is:"isl",it:"ita",iu:"iku",ja:"jpn",jv:"jav",ka:"kat",kg:"kon",ki:"kik",kj:"kua",kk:"kaz",kl:"kal",km:"khm",kn:"kan",ko:"kor",kr:"kau",ks:"kas",ku:"kur",kv:"kom",kw:"cor",ky:"kir",la:"lat",lb:"ltz",lg:"lug",li:"lim",ln:"lin",lo:"lao",lt:"lit",lu:"lub",lv:"lav",mg:"mlg",mh:"mah",mi:"mri",mk:"mkd",ml:"mal",mn:"mon",mr:"mar",ms:"msa",mt:"mlt",my:"mya",na:"nau",nb:"nob",nd:"nde",ne:"nep",ng:"ndo",nl:"nld",nn:"nno",no:"nor",nr:"nbl",nv:"nav",ny:"nya",oc:"oci",oj:"oji",om:"orm",or:"ori",os:"oss",pa:"pan",pi:"pli",pl:"pol",ps:"pus",pt:"por",qu:"que",rm:"roh",rn:"run",ro:"ron",ru:"rus",rw:"kin",sa:"san",sc:"srd",sd:"snd",se:"sme",sg:"sag",si:"sin",sk:"slk",sl:"slv",sm:"smo",sn:"sna",so:"som",sq:"sqi",sr:"srp",ss:"ssw",st:"sot",su:"sun",sv:"swe",sw:"swa",ta:"tam",te:"tel",tg:"tgk",th:"tha",ti:"tir",tk:"tuk",tl:"tgl",tn:"tsn",to:"ton",tr:"tur",ts:"tso",tt:"tat",tw:"twi",ty:"tah",ug:"uig",uk:"ukr",ur:"urd",uz:"uzb",ve:"ven",vi:"vie",vo:"vol",wa:"wln",wo:"wol",xh:"xho",yi:"yid",yo:"yor",za:"zha",zh:"zho",zu:"zul"};const o={alb:"sqi",arm:"hye",baq:"eus",bur:"mya",chi:"zho",cze:"ces",dut:"nld",fre:"fra",geo:"kat",ger:"deu",gre:"ell",ice:"isl",mac:"mkd",mao:"mri",may:"msa",per:"fas",slo:"slk",rum:"ron",tib:"bod",wel:"cym"};function s(e){if((0,i.Z)(e)||""===e)return"";var t=function(e){var t;switch(e.length){case 2:t=a[e];break;case 3:t=o[e]}return t}((""+e).toLowerCase().split("-")[0]);return(0,r.Z)(t)?t:e}function u(e){if(!(0,i.Z)(e)){var t,n=!1;return"string"==typeof e?t=e:(t=e.language,!0===e.closedCaption&&(n=!0)),{language:t,closedCaption:n,normalized:s(t)}}return e}function l(e){if((0,i.Z)(e))return e;if("string"==typeof e)return{language:e,audioDescription:!1,normalized:s(e)};var t={language:e.language,audioDescription:!0===e.audioDescription,normalized:s(s(e.language))};return!0===e.isDub&&(t.isDub=!0),t}const d=s},8894:(e,t,n)=>{"use strict";function r(){}n.d(t,{Z:()=>r})},8026:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r="function"==typeof Object.assign?Object.assign:function(e){if(null==e)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(e),n=0;n<(arguments.length<=1?0:arguments.length-1);n++){var r=n+1<1||arguments.length<=n+1?void 0:arguments[n+1];for(var i in r)Object.prototype.hasOwnProperty.call(r,i)&&(t[i]=r[i])}return t}},1679:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r="function"==typeof Object.values?Object.values:function(e){return Object.keys(e).map((function(t){return e[t]}))}},9589:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(8555);const i="function"==typeof Promise?Promise:n.n(r)()},2829:(e,t,n)=>{"use strict";n.d(t,{JN:()=>d,uH:()=>b,F_:()=>p,L7:()=>m,XS:()=>f,DD:()=>v,rx:()=>c,at:()=>h,kR:()=>g,Ti:()=>s,A1:()=>o,tn:()=>_});function r(e,t){return Math.abs(e-t)<.016666666666666666}function i(e,t){return{start:Math.min(e.start,t.start),end:Math.max(e.end,t.end)}}function a(e,t){return e.end<=t.start}function o(e,t){for(var n=0;n=0;n--){var r=e.start(n);if(t>=r){var i=e.end(n);if(t=o?r.push({start:a,end:o}):n={start:a,end:o}}return{outerRanges:r,innerRange:n}}function h(e,t){var n=c(e,t);return null!==n?n.end-n.start:0}function v(e,t){var n=c(e,t);return null!==n?t-n.start:0}function m(e,t){var n=c(e,t);return null!==n?n.end-t:1/0}function g(e,t){if(t.start===t.end)return e;for(var n=t,r=0;r0)for(var o=0;o0)for(var s=0;sl&&n.push({start:l,end:a[d].start}),l=a[d].end;l{"use strict";n.d(t,{ZP:()=>l});var r=n(4379),i=n(944),a=n(9105),o=n(6923),s=n(1946),u=i.Z.DEFAULT_REQUEST_TIMEOUT;const l=function(e){var t={url:e.url,headers:e.headers,responseType:(0,s.Z)(e.responseType)?"json":e.responseType,timeout:(0,s.Z)(e.timeout)?u:e.timeout};return new r.y((function(n){var r=t.url,i=t.headers,u=t.responseType,l=t.timeout,d=new XMLHttpRequest;if(d.open("GET",r,!0),l>=0&&(d.timeout=l),d.responseType=u,"document"===d.responseType&&d.overrideMimeType("text/xml"),!(0,s.Z)(i)){var c=i;for(var f in c)c.hasOwnProperty(f)&&d.setRequestHeader(f,c[f])}var p=performance.now();return d.onerror=function(){n.error(new a.Z(r,d.status,"ERROR_EVENT",d))},d.ontimeout=function(){n.error(new a.Z(r,d.status,"TIMEOUT",d))},!0===e.sendProgressEvents&&(d.onprogress=function(e){var t=performance.now();n.next({type:"progress",value:{url:r,duration:t-p,sendingTime:p,currentTime:t,size:e.loaded,totalSize:e.total}})}),d.onload=function(e){if(4===d.readyState)if(d.status>=200&&d.status<300){var t,i=performance.now(),u=d.response instanceof ArrayBuffer?d.response.byteLength:e.total,l=d.status,c=d.responseType,f=(0,o.Z)(d.responseURL)?d.responseURL:r;if(t="json"===c?"object"==typeof d.response?d.response:function(e){try{return JSON.parse(e)}catch(e){return null}}(d.responseText):d.response,(0,s.Z)(t))return void n.error(new a.Z(r,d.status,"PARSE_ERROR",d));n.next({type:"data-loaded",value:{status:l,url:f,responseType:c,sendingTime:p,receivedTime:i,duration:i-p,size:u,responseData:t}}),n.complete()}else n.error(new a.Z(r,d.status,"ERROR_HTTP_CODE",d))},d.send(),function(){(0,s.Z)(d)||4===d.readyState||d.abort()}}))}},9829:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o,f:()=>s});var r=/^(?:[a-z]+:)?\/\//i,i=/\/\.{1,2}\//;function a(e){if(!i.test(e))return e;for(var t=[],n=e.split("/"),r=0,a=n.length;r=0&&t===n+1)return e}var i=e.indexOf("?");return i>=0&&i{"use strict";n.d(t,{Z:()=>i});var r=n(4944);function i(e,t){try{return e(t)}catch(e){return(0,r._)(e)}}},9252:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof String.prototype.startsWith)return e.startsWith(t,n);var r="number"==typeof n?Math.max(n,0):0;return e.substring(r,r+t.length)===t}n.d(t,{Z:()=>r})},3635:(e,t,n)=>{"use strict";n.d(t,{ci:()=>p,nr:()=>f,tG:()=>l,uR:()=>c,TZ:()=>s,wV:()=>u,wO:()=>h,DM:()=>v});var r=n(3887),i=n(811),a="object"==typeof window&&"function"==typeof window.TextDecoder,o="object"==typeof window&&"function"==typeof window.TextEncoder;function s(e){for(var t=new ArrayBuffer(2*e.length),n=new Uint8Array(t),r=0;r>8&255}return n}function u(e){if(a)try{return new TextDecoder("utf-16le").decode(e)}catch(e){r.Z.warn("Utils: could not use TextDecoder to parse UTF-16LE, fallbacking to another implementation",e)}for(var t="",n=0;n=t?n:new Array(t-n.length+1).join("0")+n}function c(e){if(a)try{return(new TextDecoder).decode(e)}catch(e){r.Z.warn("Utils: could not use TextDecoder to parse UTF-8, fallbacking to another implementation",e)}var t=e;239===t[0]&&187===t[1]&&191===t[2]&&(t=t.subarray(3));var n,i=function(e){for(var t="",n=0;n=256?"%u"+d(u,4):"%"+d(u,2)}}return decodeURIComponent(n)}function f(e){for(var t=e.length,n=new Uint8Array(t/2),r=0,i=0;r>>4).toString(16),n+=(15&e[r]).toString(16),t.length>0&&r{"use strict";n.d(t,{Z:()=>i});var r=n(1946);function i(){for(var e=0,t=arguments.length,n=new Array(t),i=0;i{"use strict";n.d(t,{Z:()=>a});var r=n(7714),i=[];function a(e){(0,r.Z)(i,e)||(console.warn(e),i.push(e))}},7473:e=>{"use strict";var t=function(e){if("function"!=typeof e)throw new TypeError(e+" is not a function");return e},n=function(e){var n,r,i=document.createTextNode(""),a=0;return new e((function(){var e;if(n)r&&(n=r.concat(n));else{if(!r)return;n=r}if(r=n,n=null,"function"==typeof r)return e=r,r=null,void e();for(i.data=a=++a%2;r;)e=r.shift(),r.length||(r=null),e()})).observe(i,{characterData:!0}),function(e){t(e),n?"function"==typeof n?n=[n,e]:n.push(e):(n=e,i.data=a=++a%2)}};e.exports=function(){if("object"==typeof process&&process&&"function"==typeof process.nextTick)return process.nextTick;if("function"==typeof queueMicrotask)return function(e){queueMicrotask(t(e))};if("object"==typeof document&&document){if("function"==typeof MutationObserver)return n(MutationObserver);if("function"==typeof WebKitMutationObserver)return n(WebKitMutationObserver)}return"function"==typeof setImmediate?function(e){setImmediate(t(e))}:"function"==typeof setTimeout||"object"==typeof setTimeout?function(e){setTimeout(t(e),0)}:null}()},8555:(e,t,n)=>{"use strict";var r,i="pending",a="settled",o="fulfilled",s="rejected",u=function(){},l=void 0!==n.g&&void 0!==n.g.process&&"function"==typeof n.g.process.emit,d="undefined"==typeof setImmediate?setTimeout:setImmediate,c=[];function f(){for(var e=0;e{var t=function(e){"use strict";var t,n=Object.prototype,r=n.hasOwnProperty,i="function"==typeof Symbol?Symbol:{},a=i.iterator||"@@iterator",o=i.asyncIterator||"@@asyncIterator",s=i.toStringTag||"@@toStringTag";function u(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{u({},"")}catch(e){u=function(e,t,n){return e[t]=n}}function l(e,t,n,r){var i=t&&t.prototype instanceof m?t:m,a=Object.create(i.prototype),o=new I(r||[]);return a._invoke=function(e,t,n){var r=c;return function(i,a){if(r===p)throw new Error("Generator is already running");if(r===h){if("throw"===i)throw a;return R()}for(n.method=i,n.arg=a;;){var o=n.delegate;if(o){var s=k(o,n);if(s){if(s===v)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(r===c)throw r=h,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r=p;var u=d(e,t,n);if("normal"===u.type){if(r=n.done?h:f,u.arg===v)continue;return{value:u.arg,done:n.done}}"throw"===u.type&&(r=h,n.method="throw",n.arg=u.arg)}}}(e,n,o),a}function d(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}e.wrap=l;var c="suspendedStart",f="suspendedYield",p="executing",h="completed",v={};function m(){}function g(){}function y(){}var _={};_[a]=function(){return this};var b=Object.getPrototypeOf,T=b&&b(b(Z([])));T&&T!==n&&r.call(T,a)&&(_=T);var E=y.prototype=m.prototype=Object.create(_);function w(e){["next","throw","return"].forEach((function(t){u(e,t,(function(e){return this._invoke(t,e)}))}))}function S(e,t){function n(i,a,o,s){var u=d(e[i],e,a);if("throw"!==u.type){var l=u.arg,c=l.value;return c&&"object"==typeof c&&r.call(c,"__await")?t.resolve(c.__await).then((function(e){n("next",e,o,s)}),(function(e){n("throw",e,o,s)})):t.resolve(c).then((function(e){l.value=e,o(l)}),(function(e){return n("throw",e,o,s)}))}s(u.arg)}var i;this._invoke=function(e,r){function a(){return new t((function(t,i){n(e,r,t,i)}))}return i=i?i.then(a,a):a()}}function k(e,n){var r=e.iterator[n.method];if(r===t){if(n.delegate=null,"throw"===n.method){if(e.iterator.return&&(n.method="return",n.arg=t,k(e,n),"throw"===n.method))return v;n.method="throw",n.arg=new TypeError("The iterator does not provide a 'throw' method")}return v}var i=d(r,e.iterator,n.arg);if("throw"===i.type)return n.method="throw",n.arg=i.arg,n.delegate=null,v;var a=i.arg;return a?a.done?(n[e.resultName]=a.value,n.next=e.nextLoc,"return"!==n.method&&(n.method="next",n.arg=t),n.delegate=null,v):a:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,v)}function A(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function x(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function I(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(A,this),this.reset(!0)}function Z(e){if(e){var n=e[a];if(n)return n.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var i=-1,o=function n(){for(;++i=0;--a){var o=this.tryEntries[a],s=o.completion;if("root"===o.tryLoc)return i("end");if(o.tryLoc<=this.prev){var u=r.call(o,"catchLoc"),l=r.call(o,"finallyLoc");if(u&&l){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),x(n),v}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var i=r.arg;x(n)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,n,r){return this.delegate={iterator:Z(e),resultName:n,nextLoc:r},"next"===this.method&&(this.arg=t),v}},e}(e.exports);try{regeneratorRuntime=t}catch(e){Function("r","regeneratorRuntime = r")(t)}},2632:(e,t,n)=>{"use strict";n.d(t,{P:()=>s});var r,i=n(5631),a=n(8170),o=n(4944);r||(r={});var s=function(){function e(e,t,n){this.kind=e,this.value=t,this.error=n,this.hasValue="N"===e}return e.prototype.observe=function(e){switch(this.kind){case"N":return e.next&&e.next(this.value);case"E":return e.error&&e.error(this.error);case"C":return e.complete&&e.complete()}},e.prototype.do=function(e,t,n){switch(this.kind){case"N":return e&&e(this.value);case"E":return t&&t(this.error);case"C":return n&&n()}},e.prototype.accept=function(e,t,n){return e&&"function"==typeof e.next?this.observe(e):this.do(e,t,n)},e.prototype.toObservable=function(){switch(this.kind){case"N":return(0,a.of)(this.value);case"E":return(0,o._)(this.error);case"C":return(0,i.c)()}throw new Error("unexpected notification kind value")},e.createNext=function(t){return void 0!==t?new e("N",t):e.undefinedValueNotification},e.createError=function(t){return new e("E",void 0,t)},e.createComplete=function(){return e.completeNotification},e.completeNotification=new e("C"),e.undefinedValueNotification=new e("N",void 0),e}()},4379:(e,t,n)=>{"use strict";n.d(t,{y:()=>d});var r=n(979);var i=n(3142),a=n(2174);var o=n(5050),s=n(3608);function u(e){return 0===e.length?s.y:1===e.length?e[0]:function(t){return e.reduce((function(e,t){return t(e)}),t)}}var l=n(150),d=function(){function e(e){this._isScalar=!1,e&&(this._subscribe=e)}return e.prototype.lift=function(t){var n=new e;return n.source=this,n.operator=t,n},e.prototype.subscribe=function(e,t,n){var o=this.operator,s=function(e,t,n){if(e){if(e instanceof r.L)return e;if(e[i.b])return e[i.b]()}return e||t||n?new r.L(e,t,n):new r.L(a.c)}(e,t,n);if(o?s.add(o.call(s,this.source)):s.add(this.source||l.v.useDeprecatedSynchronousErrorHandling&&!s.syncErrorThrowable?this._subscribe(s):this._trySubscribe(s)),l.v.useDeprecatedSynchronousErrorHandling&&s.syncErrorThrowable&&(s.syncErrorThrowable=!1,s.syncErrorThrown))throw s.syncErrorValue;return s},e.prototype._trySubscribe=function(e){try{return this._subscribe(e)}catch(t){l.v.useDeprecatedSynchronousErrorHandling&&(e.syncErrorThrown=!0,e.syncErrorValue=t),!function(e){for(;e;){var t=e,n=t.closed,i=t.destination,a=t.isStopped;if(n||a)return!1;e=i&&i instanceof r.L?i:null}return!0}(e)?console.warn(t):e.error(t)}},e.prototype.forEach=function(e,t){var n=this;return new(t=c(t))((function(t,r){var i;i=n.subscribe((function(t){try{e(t)}catch(e){r(e),i&&i.unsubscribe()}}),r,t)}))},e.prototype._subscribe=function(e){var t=this.source;return t&&t.subscribe(e)},e.prototype[o.L]=function(){return this},e.prototype.pipe=function(){for(var e=[],t=0;t{"use strict";n.d(t,{c:()=>a});var r=n(150),i=n(1644),a={closed:!0,next:function(e){},error:function(e){if(r.v.useDeprecatedSynchronousErrorHandling)throw e;(0,i.z)(e)},complete:function(){}}},2039:(e,t,n)=>{"use strict";n.d(t,{L:()=>i});var r=n(655),i=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype.notifyNext=function(e,t,n,r,i){this.destination.next(t)},t.prototype.notifyError=function(e,t){this.destination.error(e)},t.prototype.notifyComplete=function(e){this.destination.complete()},t}(n(979).L)},2135:(e,t,n)=>{"use strict";n.d(t,{t:()=>h});var r=n(655),i=n(211),a=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.scheduler=t,r.work=n,r}return r.ZT(t,e),t.prototype.schedule=function(t,n){return void 0===n&&(n=0),n>0?e.prototype.schedule.call(this,t,n):(this.delay=n,this.state=t,this.scheduler.flush(this),this)},t.prototype.execute=function(t,n){return n>0||this.closed?e.prototype.execute.call(this,t,n):this._execute(t,n)},t.prototype.requestAsyncId=function(t,n,r){return void 0===r&&(r=0),null!==r&&r>0||null===r&&this.delay>0?e.prototype.requestAsyncId.call(this,t,n,r):t.flush(this)},t}(n(6114).o),o=new(function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t}(n(2980).v))(a),s=n(3884),u=n(979),l=n(2632);var d=function(e){function t(t,n,r){void 0===r&&(r=0);var i=e.call(this,t)||this;return i.scheduler=n,i.delay=r,i}return r.ZT(t,e),t.dispatch=function(e){var t=e.notification,n=e.destination;t.observe(n),this.unsubscribe()},t.prototype.scheduleMessage=function(e){this.destination.add(this.scheduler.schedule(t.dispatch,this.delay,new c(e,this.destination)))},t.prototype._next=function(e){this.scheduleMessage(l.P.createNext(e))},t.prototype._error=function(e){this.scheduleMessage(l.P.createError(e)),this.unsubscribe()},t.prototype._complete=function(){this.scheduleMessage(l.P.createComplete()),this.unsubscribe()},t}(u.L),c=function(){return function(e,t){this.notification=e,this.destination=t}}(),f=n(1016),p=n(8253),h=function(e){function t(t,n,r){void 0===t&&(t=Number.POSITIVE_INFINITY),void 0===n&&(n=Number.POSITIVE_INFINITY);var i=e.call(this)||this;return i.scheduler=r,i._events=[],i._infiniteTimeWindow=!1,i._bufferSize=t<1?1:t,i._windowTime=n<1?1:n,n===Number.POSITIVE_INFINITY?(i._infiniteTimeWindow=!0,i.next=i.nextInfiniteTimeWindow):i.next=i.nextTimeWindow,i}return r.ZT(t,e),t.prototype.nextInfiniteTimeWindow=function(t){if(!this.isStopped){var n=this._events;n.push(t),n.length>this._bufferSize&&n.shift()}e.prototype.next.call(this,t)},t.prototype.nextTimeWindow=function(t){this.isStopped||(this._events.push(new v(this._getNow(),t)),this._trimBufferThenGetEvents()),e.prototype.next.call(this,t)},t.prototype._subscribe=function(e){var t,n=this._infiniteTimeWindow,r=n?this._events:this._trimBufferThenGetEvents(),i=this.scheduler,a=r.length;if(this.closed)throw new f.N;if(this.isStopped||this.hasError?t=s.w.EMPTY:(this.observers.push(e),t=new p.W(this,e)),i&&e.add(e=new d(e,i)),n)for(var o=0;ot&&(a=Math.max(a,i-t)),a>0&&r.splice(0,a),r},t}(i.xQ),v=function(){return function(e,t){this.time=e,this.value=t}}()},211:(e,t,n)=>{"use strict";n.d(t,{Yc:()=>d,xQ:()=>c});var r=n(655),i=n(4379),a=n(979),o=n(3884),s=n(1016),u=n(8253),l=n(3142),d=function(e){function t(t){var n=e.call(this,t)||this;return n.destination=t,n}return r.ZT(t,e),t}(a.L),c=function(e){function t(){var t=e.call(this)||this;return t.observers=[],t.closed=!1,t.isStopped=!1,t.hasError=!1,t.thrownError=null,t}return r.ZT(t,e),t.prototype[l.b]=function(){return new d(this)},t.prototype.lift=function(e){var t=new f(this,this);return t.operator=e,t},t.prototype.next=function(e){if(this.closed)throw new s.N;if(!this.isStopped)for(var t=this.observers,n=t.length,r=t.slice(),i=0;i{"use strict";n.d(t,{W:()=>i});var r=n(655),i=function(e){function t(t,n){var r=e.call(this)||this;return r.subject=t,r.subscriber=n,r.closed=!1,r}return r.ZT(t,e),t.prototype.unsubscribe=function(){if(!this.closed){this.closed=!0;var e=this.subject,t=e.observers;if(this.subject=null,t&&0!==t.length&&!e.isStopped&&!e.closed){var n=t.indexOf(this.subscriber);-1!==n&&t.splice(n,1)}}},t}(n(3884).w)},979:(e,t,n)=>{"use strict";n.d(t,{L:()=>d});var r=n(655),i=n(4156),a=n(2174),o=n(3884),s=n(3142),u=n(150),l=n(1644),d=function(e){function t(n,r,i){var o=e.call(this)||this;switch(o.syncErrorValue=null,o.syncErrorThrown=!1,o.syncErrorThrowable=!1,o.isStopped=!1,arguments.length){case 0:o.destination=a.c;break;case 1:if(!n){o.destination=a.c;break}if("object"==typeof n){n instanceof t?(o.syncErrorThrowable=n.syncErrorThrowable,o.destination=n,n.add(o)):(o.syncErrorThrowable=!0,o.destination=new c(o,n));break}default:o.syncErrorThrowable=!0,o.destination=new c(o,n,r,i)}return o}return r.ZT(t,e),t.prototype[s.b]=function(){return this},t.create=function(e,n,r){var i=new t(e,n,r);return i.syncErrorThrowable=!1,i},t.prototype.next=function(e){this.isStopped||this._next(e)},t.prototype.error=function(e){this.isStopped||(this.isStopped=!0,this._error(e))},t.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},t.prototype.unsubscribe=function(){this.closed||(this.isStopped=!0,e.prototype.unsubscribe.call(this))},t.prototype._next=function(e){this.destination.next(e)},t.prototype._error=function(e){this.destination.error(e),this.unsubscribe()},t.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},t.prototype._unsubscribeAndRecycle=function(){var e=this._parentOrParents;return this._parentOrParents=null,this.unsubscribe(),this.closed=!1,this.isStopped=!1,this._parentOrParents=e,this},t}(o.w),c=function(e){function t(t,n,r,o){var s,u=e.call(this)||this;u._parentSubscriber=t;var l=u;return(0,i.m)(n)?s=n:n&&(s=n.next,r=n.error,o=n.complete,n!==a.c&&(l=Object.create(n),(0,i.m)(l.unsubscribe)&&u.add(l.unsubscribe.bind(l)),l.unsubscribe=u.unsubscribe.bind(u))),u._context=l,u._next=s,u._error=r,u._complete=o,u}return r.ZT(t,e),t.prototype.next=function(e){if(!this.isStopped&&this._next){var t=this._parentSubscriber;u.v.useDeprecatedSynchronousErrorHandling&&t.syncErrorThrowable?this.__tryOrSetError(t,this._next,e)&&this.unsubscribe():this.__tryOrUnsub(this._next,e)}},t.prototype.error=function(e){if(!this.isStopped){var t=this._parentSubscriber,n=u.v.useDeprecatedSynchronousErrorHandling;if(this._error)n&&t.syncErrorThrowable?(this.__tryOrSetError(t,this._error,e),this.unsubscribe()):(this.__tryOrUnsub(this._error,e),this.unsubscribe());else if(t.syncErrorThrowable)n?(t.syncErrorValue=e,t.syncErrorThrown=!0):(0,l.z)(e),this.unsubscribe();else{if(this.unsubscribe(),n)throw e;(0,l.z)(e)}}},t.prototype.complete=function(){var e=this;if(!this.isStopped){var t=this._parentSubscriber;if(this._complete){var n=function(){return e._complete.call(e._context)};u.v.useDeprecatedSynchronousErrorHandling&&t.syncErrorThrowable?(this.__tryOrSetError(t,n),this.unsubscribe()):(this.__tryOrUnsub(n),this.unsubscribe())}else this.unsubscribe()}},t.prototype.__tryOrUnsub=function(e,t){try{e.call(this._context,t)}catch(e){if(this.unsubscribe(),u.v.useDeprecatedSynchronousErrorHandling)throw e;(0,l.z)(e)}},t.prototype.__tryOrSetError=function(e,t,n){if(!u.v.useDeprecatedSynchronousErrorHandling)throw new Error("bad call");try{t.call(this._context,n)}catch(t){return u.v.useDeprecatedSynchronousErrorHandling?(e.syncErrorValue=t,e.syncErrorThrown=!0,!0):((0,l.z)(t),!0)}return!1},t.prototype._unsubscribe=function(){var e=this._parentSubscriber;this._context=null,this._parentSubscriber=null,e.unsubscribe()},t}(d)},3884:(e,t,n)=>{"use strict";n.d(t,{w:()=>s});var r=n(9026),i=n(2009),a=n(4156),o=function(){function e(e){return Error.call(this),this.message=e?e.length+" errors occurred during unsubscription:\n"+e.map((function(e,t){return t+1+") "+e.toString()})).join("\n "):"",this.name="UnsubscriptionError",this.errors=e,this}return e.prototype=Object.create(Error.prototype),e}(),s=function(){function e(e){this.closed=!1,this._parentOrParents=null,this._subscriptions=null,e&&(this._ctorUnsubscribe=!0,this._unsubscribe=e)}var t;return e.prototype.unsubscribe=function(){var t;if(!this.closed){var n=this,s=n._parentOrParents,l=n._ctorUnsubscribe,d=n._unsubscribe,c=n._subscriptions;if(this.closed=!0,this._parentOrParents=null,this._subscriptions=null,s instanceof e)s.remove(this);else if(null!==s)for(var f=0;f{"use strict";n.d(t,{v:()=>i});var r=!1,i={Promise:void 0,set useDeprecatedSynchronousErrorHandling(e){e&&(new Error).stack;r=e},get useDeprecatedSynchronousErrorHandling(){return r}}},7604:(e,t,n)=>{"use strict";n.d(t,{IY:()=>s,Ds:()=>u,ft:()=>l});var r=n(655),i=n(979),a=n(4379),o=n(7843),s=function(e){function t(t){var n=e.call(this)||this;return n.parent=t,n}return r.ZT(t,e),t.prototype._next=function(e){this.parent.notifyNext(e)},t.prototype._error=function(e){this.parent.notifyError(e),this.unsubscribe()},t.prototype._complete=function(){this.parent.notifyComplete(),this.unsubscribe()},t}(i.L),u=(i.L,function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype.notifyNext=function(e){this.destination.next(e)},t.prototype.notifyError=function(e){this.destination.error(e)},t.prototype.notifyComplete=function(){this.destination.complete()},t}(i.L));i.L;function l(e,t){if(!t.closed){if(e instanceof a.y)return e.subscribe(t);var n;try{n=(0,o.s)(e)(t)}catch(e){t.error(e)}return n}}},5142:(e,t,n)=>{"use strict";n.d(t,{aj:()=>d});var r=n(655),i=n(7507),a=n(9026),o=n(2039),s=n(2080),u=n(3375),l={};function d(){for(var e=[],t=0;t{"use strict";n.d(t,{z:()=>a});var r=n(8170),i=n(2257);function a(){for(var e=[],t=0;t{"use strict";n.d(t,{P:()=>o});var r=n(4379),i=n(4072),a=n(5631);function o(e){return new r.y((function(t){var n;try{n=e()}catch(e){return void t.error(e)}return(n?(0,i.D)(n):(0,a.c)()).subscribe(t)}))}},5631:(e,t,n)=>{"use strict";n.d(t,{E:()=>i,c:()=>a});var r=n(4379),i=new r.y((function(e){return e.complete()}));function a(e){return e?function(e){return new r.y((function(t){return e.schedule((function(){return t.complete()}))}))}(e):i}},4072:(e,t,n)=>{"use strict";n.d(t,{D:()=>f});var r=n(4379),i=n(7843),a=n(3884),o=n(5050);var s=n(3109),u=n(999);var l=n(336),d=n(9217);function c(e,t){if(null!=e){if(function(e){return e&&"function"==typeof e[o.L]}(e))return function(e,t){return new r.y((function(n){var r=new a.w;return r.add(t.schedule((function(){var i=e[o.L]();r.add(i.subscribe({next:function(e){r.add(t.schedule((function(){return n.next(e)})))},error:function(e){r.add(t.schedule((function(){return n.error(e)})))},complete:function(){r.add(t.schedule((function(){return n.complete()})))}}))}))),r}))}(e,t);if((0,l.t)(e))return function(e,t){return new r.y((function(n){var r=new a.w;return r.add(t.schedule((function(){return e.then((function(e){r.add(t.schedule((function(){n.next(e),r.add(t.schedule((function(){return n.complete()})))})))}),(function(e){r.add(t.schedule((function(){return n.error(e)})))}))}))),r}))}(e,t);if((0,d.z)(e))return(0,s.r)(e,t);if(function(e){return e&&"function"==typeof e[u.hZ]}(e)||"string"==typeof e)return function(e,t){if(!e)throw new Error("Iterable cannot be null");return new r.y((function(n){var r,i=new a.w;return i.add((function(){r&&"function"==typeof r.return&&r.return()})),i.add(t.schedule((function(){r=e[u.hZ](),i.add(t.schedule((function(){if(!n.closed){var e,t;try{var i=r.next();e=i.value,t=i.done}catch(e){return void n.error(e)}t?n.complete():(n.next(e),this.schedule())}})))}))),i}))}(e,t)}throw new TypeError((null!==e&&typeof e||e)+" is not observable")}function f(e,t){return t?c(e,t):e instanceof r.y?e:new r.y((0,i.s)(e))}},3375:(e,t,n)=>{"use strict";n.d(t,{n:()=>o});var r=n(4379),i=n(6900),a=n(3109);function o(e,t){return t?(0,a.r)(e,t):new r.y((0,i.V)(e))}},7027:(e,t,n)=>{"use strict";n.d(t,{R:()=>s});var r=n(4379),i=n(9026),a=n(4156),o=n(5709);function s(e,t,n,l){return(0,a.m)(n)&&(l=n,n=void 0),l?s(e,t,n).pipe((0,o.U)((function(e){return(0,i.k)(e)?l.apply(void 0,e):l(e)}))):new r.y((function(r){u(e,t,(function(e){arguments.length>1?r.next(Array.prototype.slice.call(arguments)):r.next(e)}),r,n)}))}function u(e,t,n,r,i){var a;if(function(e){return e&&"function"==typeof e.addEventListener&&"function"==typeof e.removeEventListener}(e)){var o=e;e.addEventListener(t,n,i),a=function(){return o.removeEventListener(t,n,i)}}else if(function(e){return e&&"function"==typeof e.on&&"function"==typeof e.off}(e)){var s=e;e.on(t,n),a=function(){return s.off(t,n)}}else if(function(e){return e&&"function"==typeof e.addListener&&"function"==typeof e.removeListener}(e)){var l=e;e.addListener(t,n),a=function(){return l.removeListener(t,n)}}else{if(!e||!e.length)throw new TypeError("Invalid event target");for(var d=0,c=e.length;d{"use strict";n.d(t,{F:()=>o});var r=n(4379),i=n(964),a=n(5812);function o(e,t){return void 0===e&&(e=0),void 0===t&&(t=i.P),(!(0,a.k)(e)||e<0)&&(e=0),t&&"function"==typeof t.schedule||(t=i.P),new r.y((function(n){return n.add(t.schedule(s,e,{subscriber:n,counter:0,period:e})),n}))}function s(e){var t=e.subscriber,n=e.counter,r=e.period;t.next(n),this.schedule({subscriber:t,counter:n+1,period:r},r)}},4370:(e,t,n)=>{"use strict";n.d(t,{T:()=>s});var r=n(4379),i=n(7507),a=n(2556),o=n(3375);function s(){for(var e=[],t=0;t1&&"number"==typeof e[e.length-1]&&(n=e.pop())):"number"==typeof u&&(n=e.pop()),null===s&&1===e.length&&e[0]instanceof r.y?e[0]:(0,a.J)(n)((0,o.n)(e,s))}},8170:(e,t,n)=>{"use strict";n.d(t,{of:()=>o});var r=n(7507),i=n(3375),a=n(3109);function o(){for(var e=[],t=0;t{"use strict";n.d(t,{S3:()=>u});var r=n(655),i=n(9026),a=n(3375),o=n(2039),s=n(2080);function u(){for(var e=[],t=0;t{"use strict";n.d(t,{_:()=>i});var r=n(4379);function i(e,t){return t?new r.y((function(n){return t.schedule(a,0,{error:e,subscriber:n})})):new r.y((function(t){return t.error(e)}))}function a(e){var t=e.error;e.subscriber.error(t)}},9604:(e,t,n)=>{"use strict";n.d(t,{H:()=>s});var r=n(4379),i=n(964),a=n(5812),o=n(7507);function s(e,t,n){void 0===e&&(e=0);var s=-1;return(0,a.k)(t)?s=Number(t)<1?1:Number(t):(0,o.K)(t)&&(n=t),(0,o.K)(n)||(n=i.P),new r.y((function(t){var r=(0,a.k)(e)?e:+e-n.now();return n.schedule(u,r,{index:0,period:s,subscriber:t})}))}function u(e){var t=e.index,n=e.period,r=e.subscriber;if(r.next(t),!r.closed){if(-1===n)return r.complete();e.index=t+1,this.schedule(e,n)}}},486:(e,t,n)=>{"use strict";n.d(t,{K:()=>a});var r=n(655),i=n(7604);function a(e){return function(t){var n=new o(e),r=t.lift(n);return n.caught=r}}var o=function(){function e(e){this.selector=e}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.selector,this.caught))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.selector=n,i.caught=r,i}return r.ZT(t,e),t.prototype.error=function(t){if(!this.isStopped){var n=void 0;try{n=this.selector(t,this.caught)}catch(t){return void e.prototype.error.call(this,t)}this._unsubscribeAndRecycle();var r=new i.IY(this);this.add(r);var a=(0,i.ft)(n,r);a!==r&&this.add(a)}},t}(i.Ds)},2257:(e,t,n)=>{"use strict";n.d(t,{u:()=>i});var r=n(2556);function i(){return(0,r.J)(1)}},1931:(e,t,n)=>{"use strict";n.d(t,{x:()=>a});var r=n(655),i=n(979);function a(e,t){return function(n){return n.lift(new o(e,t))}}var o=function(){function e(e,t){this.compare=e,this.keySelector=t}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.compare,this.keySelector))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.keySelector=r,i.hasKey=!1,"function"==typeof n&&(i.compare=n),i}return r.ZT(t,e),t.prototype.compare=function(e,t){return e===t},t.prototype._next=function(e){var t;try{var n=this.keySelector;t=n?n(e):e}catch(e){return this.destination.error(e)}var r=!1;if(this.hasKey)try{r=(0,this.compare)(this.key,t)}catch(e){return this.destination.error(e)}else this.hasKey=!0;r||(this.key=t,this.destination.next(e))},t}(i.L)},6008:(e,t,n)=>{"use strict";n.d(t,{h:()=>a});var r=n(655),i=n(979);function a(e,t){return function(n){return n.lift(new o(e,t))}}var o=function(){function e(e,t){this.predicate=e,this.thisArg=t}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.predicate,this.thisArg))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.predicate=n,i.thisArg=r,i.count=0,i}return r.ZT(t,e),t.prototype._next=function(e){var t;try{t=this.predicate.call(this.thisArg,e,this.count++)}catch(e){return void this.destination.error(e)}t&&this.destination.next(e)},t}(i.L)},6738:(e,t,n)=>{"use strict";n.d(t,{l:()=>a});var r=n(655),i=n(979);function a(){return function(e){return e.lift(new o)}}var o=function(){function e(){}return e.prototype.call=function(e,t){return t.subscribe(new s(e))},e}(),s=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype._next=function(e){},t}(i.L)},5709:(e,t,n)=>{"use strict";n.d(t,{U:()=>a});var r=n(655),i=n(979);function a(e,t){return function(n){if("function"!=typeof e)throw new TypeError("argument is not a function. Are you looking for `mapTo()`?");return n.lift(new o(e,t))}}var o=function(){function e(e,t){this.project=e,this.thisArg=t}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.project,this.thisArg))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.project=n,i.count=0,i.thisArg=r||i,i}return r.ZT(t,e),t.prototype._next=function(e){var t;try{t=this.project.call(this.thisArg,e,this.count++)}catch(e){return void this.destination.error(e)}this.destination.next(t)},t}(i.L)},5602:(e,t,n)=>{"use strict";n.d(t,{h:()=>a});var r=n(655),i=n(979);function a(e){return function(t){return t.lift(new o(e))}}var o=function(){function e(e){this.value=e}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.value))},e}(),s=function(e){function t(t,n){var r=e.call(this,t)||this;return r.value=n,r}return r.ZT(t,e),t.prototype._next=function(e){this.destination.next(this.value)},t}(i.L)},2556:(e,t,n)=>{"use strict";n.d(t,{J:()=>a});var r=n(7746),i=n(3608);function a(e){return void 0===e&&(e=Number.POSITIVE_INFINITY),(0,r.zg)(i.y,e)}},7746:(e,t,n)=>{"use strict";n.d(t,{zg:()=>s});var r=n(655),i=n(5709),a=n(4072),o=n(7604);function s(e,t,n){return void 0===n&&(n=Number.POSITIVE_INFINITY),"function"==typeof t?function(r){return r.pipe(s((function(n,r){return(0,a.D)(e(n,r)).pipe((0,i.U)((function(e,i){return t(n,e,r,i)})))}),n))}:("number"==typeof t&&(n=t),function(t){return t.lift(new u(e,n))})}var u=function(){function e(e,t){void 0===t&&(t=Number.POSITIVE_INFINITY),this.project=e,this.concurrent=t}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.project,this.concurrent))},e}(),l=function(e){function t(t,n,r){void 0===r&&(r=Number.POSITIVE_INFINITY);var i=e.call(this,t)||this;return i.project=n,i.concurrent=r,i.hasCompleted=!1,i.buffer=[],i.active=0,i.index=0,i}return r.ZT(t,e),t.prototype._next=function(e){this.active0?this._next(e.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()},t}(o.Ds)},3756:(e,t,n)=>{"use strict";n.d(t,{j:()=>i});var r=n(7746);function i(e,t,n){return void 0===n&&(n=Number.POSITIVE_INFINITY),"function"==typeof t?(0,r.zg)((function(){return e}),t,n):("number"==typeof t&&(n=t),(0,r.zg)((function(){return e}),n))}},1421:(e,t,n)=>{"use strict";n.d(t,{O:()=>f});var r=n(655),i=n(211),a=n(4379),o=n(979),s=n(3884),u=n(3018),l=function(e){function t(t,n){var r=e.call(this)||this;return r.source=t,r.subjectFactory=n,r._refCount=0,r._isComplete=!1,r}return r.ZT(t,e),t.prototype._subscribe=function(e){return this.getSubject().subscribe(e)},t.prototype.getSubject=function(){var e=this._subject;return e&&!e.isStopped||(this._subject=this.subjectFactory()),this._subject},t.prototype.connect=function(){var e=this._connection;return e||(this._isComplete=!1,(e=this._connection=new s.w).add(this.source.subscribe(new c(this.getSubject(),this))),e.closed&&(this._connection=null,e=s.w.EMPTY)),e},t.prototype.refCount=function(){return(0,u.x)()(this)},t}(a.y),d=function(){var e=l.prototype;return{operator:{value:null},_refCount:{value:0,writable:!0},_subject:{value:null,writable:!0},_connection:{value:null,writable:!0},_subscribe:{value:e._subscribe},_isComplete:{value:e._isComplete,writable:!0},getSubject:{value:e.getSubject},connect:{value:e.connect},refCount:{value:e.refCount}}}(),c=function(e){function t(t,n){var r=e.call(this,t)||this;return r.connectable=n,r}return r.ZT(t,e),t.prototype._error=function(t){this._unsubscribe(),e.prototype._error.call(this,t)},t.prototype._complete=function(){this.connectable._isComplete=!0,this._unsubscribe(),e.prototype._complete.call(this)},t.prototype._unsubscribe=function(){var e=this.connectable;if(e){this.connectable=null;var t=e._connection;e._refCount=0,e._subject=null,e._connection=null,t&&t.unsubscribe()}},t}(i.Yc);o.L;function f(e,t){return function(n){var r;if(r="function"==typeof e?e:function(){return e},"function"==typeof t)return n.lift(new p(r,t));var i=Object.create(n,d);return i.source=n,i.subjectFactory=r,i}}var p=function(){function e(e,t){this.subjectFactory=e,this.selector=t}return e.prototype.call=function(e,t){var n=this.selector,r=this.subjectFactory(),i=n(r).subscribe(e);return i.add(t.subscribe(r)),i},e}()},3018:(e,t,n)=>{"use strict";n.d(t,{x:()=>a});var r=n(655),i=n(979);function a(){return function(e){return e.lift(new o(e))}}var o=function(){function e(e){this.connectable=e}return e.prototype.call=function(e,t){var n=this.connectable;n._refCount++;var r=new s(e,n),i=t.subscribe(r);return r.closed||(r.connection=n.connect()),i},e}(),s=function(e){function t(t,n){var r=e.call(this,t)||this;return r.connectable=n,r}return r.ZT(t,e),t.prototype._unsubscribe=function(){var e=this.connectable;if(e){this.connectable=null;var t=e._refCount;if(t<=0)this.connection=null;else if(e._refCount=t-1,t>1)this.connection=null;else{var n=this.connection,r=e._connection;this.connection=null,!r||n&&r!==n||r.unsubscribe()}}else this.connection=null},t}(i.L)},2807:(e,t,n)=>{"use strict";n.d(t,{R:()=>a});var r=n(655),i=n(979);function a(e,t){var n=!1;return arguments.length>=2&&(n=!0),function(r){return r.lift(new o(e,t,n))}}var o=function(){function e(e,t,n){void 0===n&&(n=!1),this.accumulator=e,this.seed=t,this.hasSeed=n}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.accumulator,this.seed,this.hasSeed))},e}(),s=function(e){function t(t,n,r,i){var a=e.call(this,t)||this;return a.accumulator=n,a._seed=r,a.hasSeed=i,a.index=0,a}return r.ZT(t,e),Object.defineProperty(t.prototype,"seed",{get:function(){return this._seed},set:function(e){this.hasSeed=!0,this._seed=e},enumerable:!0,configurable:!0}),t.prototype._next=function(e){if(this.hasSeed)return this._tryNext(e);this.seed=e,this.destination.next(e)},t.prototype._tryNext=function(e){var t,n=this.index++;try{t=this.accumulator(this.seed,e,n)}catch(e){this.destination.error(e)}this.seed=t,this.destination.next(t)},t}(i.L)},9095:(e,t,n)=>{"use strict";n.d(t,{B:()=>s});var r=n(1421),i=n(3018),a=n(211);function o(){return new a.xQ}function s(){return function(e){return(0,i.x)()((0,r.O)(o)(e))}}},7006:(e,t,n)=>{"use strict";n.d(t,{d:()=>i});var r=n(2135);function i(e,t,n){var i;return i=e&&"object"==typeof e?e:{bufferSize:e,windowTime:t,refCount:!1,scheduler:n},function(e){return e.lift(function(e){var t,n,i=e.bufferSize,a=void 0===i?Number.POSITIVE_INFINITY:i,o=e.windowTime,s=void 0===o?Number.POSITIVE_INFINITY:o,u=e.refCount,l=e.scheduler,d=0,c=!1,f=!1;return function(e){var i;d++,!t||c?(c=!1,t=new r.t(a,s,l),i=t.subscribe(this),n=e.subscribe({next:function(e){t.next(e)},error:function(e){c=!0,t.error(e)},complete:function(){f=!0,n=void 0,t.complete()}}),f&&(n=void 0)):i=t.subscribe(this),this.add((function(){d--,i.unsubscribe(),i=void 0,n&&!f&&u&&0===d&&(n.unsubscribe(),n=void 0,t=void 0)}))}}(i))}}},3485:(e,t,n)=>{"use strict";n.d(t,{O:()=>a});var r=n(9795),i=n(7507);function a(){for(var e=[],t=0;t{"use strict";n.d(t,{w:()=>s});var r=n(655),i=n(5709),a=n(4072),o=n(7604);function s(e,t){return"function"==typeof t?function(n){return n.pipe(s((function(n,r){return(0,a.D)(e(n,r)).pipe((0,i.U)((function(e,i){return t(n,e,r,i)})))})))}:function(t){return t.lift(new u(e))}}var u=function(){function e(e){this.project=e}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.project))},e}(),l=function(e){function t(t,n){var r=e.call(this,t)||this;return r.project=n,r.index=0,r}return r.ZT(t,e),t.prototype._next=function(e){var t,n=this.index++;try{t=this.project(e,n)}catch(e){return void this.destination.error(e)}this._innerSub(t)},t.prototype._innerSub=function(e){var t=this.innerSubscription;t&&t.unsubscribe();var n=new o.IY(this),r=this.destination;r.add(n),this.innerSubscription=(0,o.ft)(e,n),this.innerSubscription!==n&&r.add(this.innerSubscription)},t.prototype._complete=function(){var t=this.innerSubscription;t&&!t.closed||e.prototype._complete.call(this),this.unsubscribe()},t.prototype._unsubscribe=function(){this.innerSubscription=void 0},t.prototype.notifyComplete=function(){this.innerSubscription=void 0,this.isStopped&&e.prototype._complete.call(this)},t.prototype.notifyNext=function(e){this.destination.next(e)},t}(o.Ds)},1198:(e,t,n)=>{"use strict";n.d(t,{c:()=>i});var r=n(6381);function i(e,t){return t?(0,r.w)((function(){return e}),t):(0,r.w)((function(){return e}))}},1015:(e,t,n)=>{"use strict";n.d(t,{q:()=>s});var r=n(655),i=n(979),a=n(6565),o=n(5631);function s(e){return function(t){return 0===e?(0,o.c)():t.lift(new u(e))}}var u=function(){function e(e){if(this.total=e,this.total<0)throw new a.W}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.total))},e}(),l=function(e){function t(t,n){var r=e.call(this,t)||this;return r.total=n,r.count=0,r}return r.ZT(t,e),t.prototype._next=function(e){var t=this.total,n=++this.count;n<=t&&(this.destination.next(e),n===t&&(this.destination.complete(),this.unsubscribe()))},t}(i.L)},1558:(e,t,n)=>{"use strict";n.d(t,{R:()=>a});var r=n(655),i=n(7604);function a(e){return function(t){return t.lift(new o(e))}}var o=function(){function e(e){this.notifier=e}return e.prototype.call=function(e,t){var n=new s(e),r=(0,i.ft)(this.notifier,new i.IY(n));return r&&!n.seenValue?(n.add(r),t.subscribe(n)):n},e}(),s=function(e){function t(t){var n=e.call(this,t)||this;return n.seenValue=!1,n}return r.ZT(t,e),t.prototype.notifyNext=function(){this.seenValue=!0,this.complete()},t.prototype.notifyComplete=function(){},t}(i.Ds)},3068:(e,t,n)=>{"use strict";n.d(t,{b:()=>s});var r=n(655),i=n(979),a=n(3306),o=n(4156);function s(e,t,n){return function(r){return r.lift(new u(e,t,n))}}var u=function(){function e(e,t,n){this.nextOrObserver=e,this.error=t,this.complete=n}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.nextOrObserver,this.error,this.complete))},e}(),l=function(e){function t(t,n,r,i){var s=e.call(this,t)||this;return s._tapNext=a.Z,s._tapError=a.Z,s._tapComplete=a.Z,s._tapError=r||a.Z,s._tapComplete=i||a.Z,(0,o.m)(n)?(s._context=s,s._tapNext=n):n&&(s._context=n,s._tapNext=n.next||a.Z,s._tapError=n.error||a.Z,s._tapComplete=n.complete||a.Z),s}return r.ZT(t,e),t.prototype._next=function(e){try{this._tapNext.call(this._context,e)}catch(e){return void this.destination.error(e)}this.destination.next(e)},t.prototype._error=function(e){try{this._tapError.call(this._context,e)}catch(e){return void this.destination.error(e)}this.destination.error(e)},t.prototype._complete=function(){try{this._tapComplete.call(this._context)}catch(e){return void this.destination.error(e)}return this.destination.complete()},t}(i.L)},3109:(e,t,n)=>{"use strict";n.d(t,{r:()=>a});var r=n(4379),i=n(3884);function a(e,t){return new r.y((function(n){var r=new i.w,a=0;return r.add(t.schedule((function(){a!==e.length?(n.next(e[a++]),n.closed||r.add(this.schedule())):n.complete()}))),r}))}},6114:(e,t,n)=>{"use strict";n.d(t,{o:()=>i});var r=n(655),i=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.scheduler=t,r.work=n,r.pending=!1,r}return r.ZT(t,e),t.prototype.schedule=function(e,t){if(void 0===t&&(t=0),this.closed)return this;this.state=e;var n=this.id,r=this.scheduler;return null!=n&&(this.id=this.recycleAsyncId(r,n,t)),this.pending=!0,this.delay=t,this.id=this.id||this.requestAsyncId(r,this.id,t),this},t.prototype.requestAsyncId=function(e,t,n){return void 0===n&&(n=0),setInterval(e.flush.bind(e,this),n)},t.prototype.recycleAsyncId=function(e,t,n){if(void 0===n&&(n=0),null!==n&&this.delay===n&&!1===this.pending)return t;clearInterval(t)},t.prototype.execute=function(e,t){if(this.closed)return new Error("executing a cancelled action");this.pending=!1;var n=this._execute(e,t);if(n)return n;!1===this.pending&&null!=this.id&&(this.id=this.recycleAsyncId(this.scheduler,this.id,null))},t.prototype._execute=function(e,t){var n=!1,r=void 0;try{this.work(e)}catch(e){n=!0,r=!!e&&e||new Error(e)}if(n)return this.unsubscribe(),r},t.prototype._unsubscribe=function(){var e=this.id,t=this.scheduler,n=t.actions,r=n.indexOf(this);this.work=null,this.state=null,this.pending=!1,this.scheduler=null,-1!==r&&n.splice(r,1),null!=e&&(this.id=this.recycleAsyncId(t,e,null)),this.delay=null},t}(function(e){function t(t,n){return e.call(this)||this}return r.ZT(t,e),t.prototype.schedule=function(e,t){return void 0===t&&(t=0),this},t}(n(3884).w))},2980:(e,t,n)=>{"use strict";n.d(t,{v:()=>a});var r=n(655),i=function(){function e(t,n){void 0===n&&(n=e.now),this.SchedulerAction=t,this.now=n}return e.prototype.schedule=function(e,t,n){return void 0===t&&(t=0),new this.SchedulerAction(this,e).schedule(n,t)},e.now=function(){return Date.now()},e}(),a=function(e){function t(n,r){void 0===r&&(r=i.now);var a=e.call(this,n,(function(){return t.delegate&&t.delegate!==a?t.delegate.now():r()}))||this;return a.actions=[],a.active=!1,a.scheduled=void 0,a}return r.ZT(t,e),t.prototype.schedule=function(n,r,i){return void 0===r&&(r=0),t.delegate&&t.delegate!==this?t.delegate.schedule(n,r,i):e.prototype.schedule.call(this,n,r,i)},t.prototype.flush=function(e){var t=this.actions;if(this.active)t.push(e);else{var n;this.active=!0;do{if(n=e.execute(e.state,e.delay))break}while(e=t.shift());if(this.active=!1,n){for(;e=t.shift();)e.unsubscribe();throw n}}},t}(i)},964:(e,t,n)=>{"use strict";n.d(t,{P:()=>i});var r=n(6114),i=new(n(2980).v)(r.o)},999:(e,t,n)=>{"use strict";function r(){return"function"==typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator"}n.d(t,{hZ:()=>i});var i=r()},5050:(e,t,n)=>{"use strict";n.d(t,{L:()=>r});var r=function(){return"function"==typeof Symbol&&Symbol.observable||"@@observable"}()},3142:(e,t,n)=>{"use strict";n.d(t,{b:()=>r});var r=function(){return"function"==typeof Symbol?Symbol("rxSubscriber"):"@@rxSubscriber_"+Math.random()}()},6565:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});var r=function(){function e(){return Error.call(this),this.message="argument out of range",this.name="ArgumentOutOfRangeError",this}return e.prototype=Object.create(Error.prototype),e}()},1016:(e,t,n)=>{"use strict";n.d(t,{N:()=>r});var r=function(){function e(){return Error.call(this),this.message="object unsubscribed",this.name="ObjectUnsubscribedError",this}return e.prototype=Object.create(Error.prototype),e}()},1644:(e,t,n)=>{"use strict";function r(e){setTimeout((function(){throw e}),0)}n.d(t,{z:()=>r})},3608:(e,t,n)=>{"use strict";function r(e){return e}n.d(t,{y:()=>r})},9026:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});var r=function(){return Array.isArray||function(e){return e&&"number"==typeof e.length}}()},9217:(e,t,n)=>{"use strict";n.d(t,{z:()=>r});var r=function(e){return e&&"number"==typeof e.length&&"function"!=typeof e}},9914:(e,t,n)=>{"use strict";function r(e){return e instanceof Date&&!isNaN(+e)}n.d(t,{J:()=>r})},4156:(e,t,n)=>{"use strict";function r(e){return"function"==typeof e}n.d(t,{m:()=>r})},5812:(e,t,n)=>{"use strict";n.d(t,{k:()=>i});var r=n(9026);function i(e){return!(0,r.k)(e)&&e-parseFloat(e)+1>=0}},2009:(e,t,n)=>{"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{K:()=>r})},336:(e,t,n)=>{"use strict";function r(e){return!!e&&"function"!=typeof e.subscribe&&"function"==typeof e.then}n.d(t,{t:()=>r})},7507:(e,t,n)=>{"use strict";function r(e){return e&&"function"==typeof e.schedule}n.d(t,{K:()=>r})},3306:(e,t,n)=>{"use strict";function r(){}n.d(t,{Z:()=>r})},7843:(e,t,n)=>{"use strict";n.d(t,{s:()=>d});var r=n(6900),i=n(1644),a=n(999),o=n(5050),s=n(9217),u=n(336),l=n(2009),d=function(e){if(e&&"function"==typeof e[o.L])return d=e,function(e){var t=d[o.L]();if("function"!=typeof t.subscribe)throw new TypeError("Provided object does not correctly implement Symbol.observable");return t.subscribe(e)};if((0,s.z)(e))return(0,r.V)(e);if((0,u.t)(e))return n=e,function(e){return n.then((function(t){e.closed||(e.next(t),e.complete())}),(function(t){return e.error(t)})).then(null,i.z),e};if(e&&"function"==typeof e[a.hZ])return t=e,function(e){for(var n=t[a.hZ]();;){var r=void 0;try{r=n.next()}catch(t){return e.error(t),e}if(r.done){e.complete();break}if(e.next(r.value),e.closed)break}return"function"==typeof n.return&&e.add((function(){n.return&&n.return()})),e};var t,n,d,c=(0,l.K)(e)?"an invalid object":"'"+e+"'";throw new TypeError("You provided "+c+" where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.")}},6900:(e,t,n)=>{"use strict";n.d(t,{V:()=>r});var r=function(e){return function(t){for(var n=0,r=e.length;n{"use strict";n.d(t,{D:()=>s});var r=n(655),i=function(e){function t(t,n,r){var i=e.call(this)||this;return i.parent=t,i.outerValue=n,i.outerIndex=r,i.index=0,i}return r.ZT(t,e),t.prototype._next=function(e){this.parent.notifyNext(this.outerValue,e,this.outerIndex,this.index++,this)},t.prototype._error=function(e){this.parent.notifyError(e,this),this.unsubscribe()},t.prototype._complete=function(){this.parent.notifyComplete(this),this.unsubscribe()},t}(n(979).L),a=n(7843),o=n(4379);function s(e,t,n,r,s){if(void 0===s&&(s=new i(e,n,r)),!s.closed)return t instanceof o.y?t.subscribe(s):(0,a.s)(t)(s)}},655:(e,t,n)=>{"use strict";n.d(t,{ZT:()=>i});var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function i(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var a=t[r]={exports:{}};return e[r](a,a.exports,n),a.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var r={};return(()=>{"use strict";n.d(r,{default:()=>Ui});var e=n(5991),t=n(1788),i=n(211),a=n(2135),o=n(655),s=n(1016),u=function(e){function t(t){var n=e.call(this)||this;return n._value=t,n}return o.ZT(t,e),Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!0,configurable:!0}),t.prototype._subscribe=function(t){var n=e.prototype._subscribe.call(this,t);return n&&!n.closed&&t.next(this._value),n},t.prototype.getValue=function(){if(this.hasError)throw this.thrownError;if(this.closed)throw new s.N;return this._value},t.prototype.next=function(t){e.prototype.next.call(this,this._value=t)},t}(i.xQ),l=n(8170),d=n(5142),c=n(9795),f=n(4370),p=n(5631),h=n(1558),v=n(5709),m=n(1931),g=n(7746),y=n(7006),_=n(1421);function b(e){return e?(0,_.O)((function(){return new i.xQ}),e):(0,_.O)(new i.xQ)}var T=n(6008),E=n(9095),w=n(3485),S=n(1015),k=n(5602),A=n(979);var x=function(){function e(e){this.predicate=e}return e.prototype.call=function(e,t){return t.subscribe(new I(e,this.predicate))},e}(),I=function(e){function t(t,n){var r=e.call(this,t)||this;return r.predicate=n,r.skipping=!0,r.index=0,r}return o.ZT(t,e),t.prototype._next=function(e){var t=this.destination;this.skipping&&this.tryCallPredicate(e),this.skipping||t.next(e)},t.prototype.tryCallPredicate=function(e){try{var t=this.predicate(e,this.index++);this.skipping=Boolean(t)}catch(e){this.destination.error(e)}},t}(A.L),Z=n(1198),R=n(3756),M=n(1473);function C(){if(N()){var e=document;"function"==typeof e.exitFullscreen?e.exitFullscreen():"function"==typeof e.msExitFullscreen?e.msExitFullscreen():"function"==typeof e.mozCancelFullScreen?e.mozCancelFullScreen():"function"==typeof e.webkitExitFullscreen&&e.webkitExitFullscreen()}}function N(){var e=document;return null!=e.fullscreenElement||null!=e.mozFullScreenElement||null!=e.webkitFullscreenElement||null!=e.msFullscreenElement}var P=n(3666),O=n(3887);function D(){var e,t;if(!P.vU)return!0;var n=function(){if(!P.vU)return O.Z.warn("Compat: Can't access Firefox version on no firefox browser."),null;var e=navigator.userAgent,t=/Firefox\/([0-9]+)\./.exec(e);if(null===t)return-1;var n=parseInt(t[1],10);return isNaN(n)?-1:n}();return null===n||n<67||void 0!==(null===(t=null===(e=HTMLVideoElement)||void 0===e?void 0:e.prototype)||void 0===t?void 0:t.requirePictureInPicture)}var L=n(944),B=n(3714),U=n(9822),F=n(5389);function z(e,t){var n=t.defaultCode,r=t.defaultReason;if((0,U.Z)(e))return e;var i=e instanceof Error?e.toString():r;return new F.Z(n,i)}var K=n(5992),V=n(7874),W=n(1966),G=n(4791),H=n(1959),$=n(1946),j=n(8894),Y=n(8026),q=n(9589),X=n(2829),Q=n(8806),J=n(1410),ee=n(6139),te=n(6033);function ne(e){return(0,J.P)((function(){var t=te.Z.getState(e);if(null===t)return(0,l.of)(null);O.Z.info("EME: Disposing of the current MediaKeys");var n=t.loadedSessionsStore;return te.Z.clearState(e),n.closeAllSessions().pipe((0,R.j)((0,ee.Y)(e,null)))}))}function re(e){var t=te.Z.getState(e);return null==t?null:t.keySystemOptions.type}var ie=n(6738);function ae(e){return(0,J.P)((function(){if(O.Z.info("EME: Clearing-up EME session."),P.fq)return O.Z.info("EME: disposing current MediaKeys."),ne(e).pipe((0,ie.l)());var t=te.Z.getState(e);return null!==t&&!0===t.keySystemOptions.closeSessionsOnStop?(O.Z.info("EME: closing all current sessions."),t.loadedSessionsStore.closeAllSessions().pipe((0,ie.l)())):(O.Z.info("EME: Nothing to clear. Returning right away. No state =",null===t),p.E)}))}var oe=n(486),se=n(3884);function ue(e){return function(t){return t.lift(new le(e))}}var le=function(){function e(e){this.callback=e}return e.prototype.call=function(e,t){return t.subscribe(new de(e,this.callback))},e}(),de=function(e){function t(t,n){var r=e.call(this,t)||this;return r.add(new se.w(n)),r}return o.ZT(t,e),t}(A.L),ce=n(5561),fe=n(2793),pe=n(9105),he=n(9362);function ve(e){return e instanceof pe.Z?new he.Z("PIPELINE_LOAD_ERROR",e):z(e,{defaultCode:"PIPELINE_LOAD_ERROR",defaultReason:"Unknown error when fetching the Manifest"})}var me=n(9604);var ge,ye=n(2572);function _e(e){return e.type===K.br.ERROR_EVENT&&!1===navigator.onLine}function be(e,t,n){var r=n.baseDelay,i=n.maxDelay,a=n.maxRetryRegular,o=n.maxRetryOffline,s=0,u=ge.None,l=e.slice();return 0===l.length?(O.Z.warn("Fetchers: no URL given to `tryURLsWithBackoff`."),p.E):function e(n,d){return t(n).pipe((0,v.U)((function(e){return{type:"response",value:e}})),(0,oe.K)((function(t){if(!function(e){return e instanceof pe.Z?e.type===K.br.ERROR_HTTP_CODE?e.status>=500||404===e.status||415===e.status||412===e.status:e.type===K.br.TIMEOUT||e.type===K.br.ERROR_EVENT:(0,U.Z)(e)&&"INTEGRITY_ERROR"===e.code}(t)){if(l.length<=1)throw t;l.splice(d,1);var n=d>=l.length-1?0:d;return e(l[n],n).pipe((0,w.O)({type:"retry",value:t}))}var c=function(e){return e instanceof pe.Z&&_e(e)?ge.Offline:ge.Regular}(t),f=c===ge.Offline?o:a;if(c!==u&&(s=0,u=c),df)throw t;var h=Math.min(r*Math.pow(2,s-1),i),v=(0,ye.Z)(h),m=l[0];return(0,me.H)(v).pipe((0,g.zg)((function(){return e(m,0)})),(0,w.O)({type:"retry",value:t}))})))}(l[0],0)}function Te(e,t){return be([null],(function(){return e}),t)}!function(e){e[e.None=0]="None",e[e.Regular=1]="Regular",e[e.Offline=2]="Offline"}(ge||(ge={}));var Ee=L.Z.DEFAULT_MAX_MANIFEST_REQUEST_RETRY,we=L.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE,Se=L.Z.INITIAL_BACKOFF_DELAY_BASE,ke=L.Z.MAX_BACKOFF_DELAY_BASE;const Ae=function(){function e(e,t,n){var r,i,a,o;this._manifestUrl=e,this._pipelines=t.manifest,this._backoffOptions=(i=(r=n).maxRetryRegular,a=r.maxRetryOffline,{baseDelay:(o=r.lowLatencyMode)?Se.LOW_LATENCY:Se.REGULAR,maxDelay:o?ke.LOW_LATENCY:ke.REGULAR,maxRetryRegular:void 0!==i?i:Ee,maxRetryOffline:void 0!==a?a:we})}var t=e.prototype;return t.fetch=function(e){var t,n=this,r=null!=e?e:this._manifestUrl,i=null!==(t=this._pipelines.resolver)&&void 0!==t?t:l.of,a=this._pipelines.loader;return(0,ce.Z)(i,{url:r}).pipe((0,oe.K)((function(e){throw ve(e)})),(0,g.zg)((function(e){return Te((0,ce.Z)(a,e),n._backoffOptions).pipe((0,oe.K)((function(e){throw ve(e)})),(0,v.U)((function(e){return"retry"===e.type?{type:"warning",value:ve(e.value)}:{type:"response",parse:function(t){return n._parseLoadedManifest(e.value.value,t)}}})))})))},t.parse=function(e,t){return this._parseLoadedManifest({responseData:e,size:void 0,duration:void 0},t)},t._parseLoadedManifest=function(e,t){var n,r,a=e.sendingTime,o=e.receivedTime,s=performance.now(),u=new i.xQ,l=(n=this._backoffOptions,r=u,function(e){return Te((0,ce.Z)(e,void 0),n).pipe((0,fe.Z)((function(e){return"retry"===e.type?(r.next(ve(e.value)),null):e.value}),null),(0,oe.K)((function(e){throw ve(e)})))});return(0,f.T)(u.pipe((0,v.U)((function(e){return{type:"warning",value:e}}))),this._pipelines.parser({response:e,url:this._manifestUrl,externalClockOffset:t.externalClockOffset,previousManifest:t.previousManifest,scheduleRequest:l,unsafeMode:t.unsafeMode}).pipe((0,oe.K)((function(e){throw z(e,{defaultCode:"PIPELINE_PARSE_ERROR",defaultReason:"Unknown error when parsing the Manifest"})})),(0,v.U)((function(e){if("warning"===e.type)return{type:"warning",value:z(e.value,{defaultCode:"PIPELINE_PARSE_ERROR",defaultReason:"Unknown error when parsing the Manifest"})};var t=performance.now()-s;return{type:"parsed",manifest:e.value.manifest,sendingTime:a,receivedTime:o,parsingTime:t}})),ue((function(){u.complete()}))))},e}();var xe=L.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR,Ie=L.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE,Ze=L.Z.INITIAL_BACKOFF_DELAY_BASE,Re=L.Z.MAX_BACKOFF_DELAY_BASE;var Me=n(4379),Ce=n(5138),Ne=function(){function e(e){var t=e.prioritySteps;if(this._minPendingPriority=null,this._waitingQueue=[],this._pendingTasks=[],this._prioritySteps=t,this._prioritySteps.high>=this._prioritySteps.low)throw new Error("FP Error: the max high level priority should be given a lowerpriority number than the min low priority.")}var t=e.prototype;return t.create=function(e,t){var n=this,r=new Me.y((function(i){var a,o=!0;return a={observable:r,priority:t,trigger:function(t){null!==a.subscription&&(a.subscription.unsubscribe(),a.subscription=null,o&&i.next({type:"interrupted"})),t&&(n._minPendingPriority=null===n._minPendingPriority?a.priority:Math.min(n._minPendingPriority,a.priority),n._pendingTasks.push(a),a.subscription=e.subscribe((function(e){return i.next({type:"data",value:e})}),(function(e){i.error(e),a.subscription=null,a.finished=!0,n._onTaskEnd(a)}),(function(){i.next({type:"ended"}),o&&i.complete(),a.subscription=null,a.finished=!0,n._onTaskEnd(a)})))},subscription:null,finished:!1},n._canBeStartedNow(a)?(a.trigger(!0),n._isRunningHighPriorityTasks()&&n._interruptCancellableTasks()):n._waitingQueue.push(a),function(){if(o=!1,null!==a.subscription&&(a.subscription.unsubscribe(),a.subscription=null),!a.finished){var e=(0,Ce.Z)(n._waitingQueue,(function(e){return e.observable===r}));if(e>=0)n._waitingQueue.splice(e,1);else{var t=(0,Ce.Z)(n._pendingTasks,(function(e){return e.observable===r}));if(t<0)return void O.Z.warn("FP: unsubscribing non-existent task");var i=n._pendingTasks.splice(t,1)[0];0===n._pendingTasks.length?(n._minPendingPriority=null,n._loopThroughWaitingQueue()):n._minPendingPriority===i.priority&&(n._minPendingPriority=Math.min.apply(Math,n._pendingTasks.map((function(e){return e.priority}))),n._loopThroughWaitingQueue())}}}}));return r},t.updatePriority=function(e,t){var n=(0,Ce.Z)(this._waitingQueue,(function(t){return t.observable===e}));if(n>=0){var r=this._waitingQueue[n];if(r.priority===t)return;if(r.priority=t,!this._canBeStartedNow(r))return;return this._startWaitingQueueTask(n),void(this._isRunningHighPriorityTasks()&&this._interruptCancellableTasks())}var i=(0,Ce.Z)(this._pendingTasks,(function(t){return t.observable===e}));if(i<0)O.Z.warn("FP: request to update the priority of a non-existent task");else{var a=this._pendingTasks[i];if(a.priority!==t){var o=a.priority;if(a.priority=t,null===this._minPendingPriority||tt.priority?t.priority:e}),null);if(!(null===e||null!==this._minPendingPriority&&this._minPendingPriority=this._prioritySteps.low)return this._interruptPendingTask(t),this._interruptCancellableTasks()}},t._startWaitingQueueTask=function(e){this._waitingQueue.splice(e,1)[0].trigger(!0)},t._interruptPendingTask=function(e){var t=(0,Ce.Z)(this._pendingTasks,(function(t){return t.observable===e.observable}));t<0?O.Z.warn("FP: Interrupting a non-existent pending task. Aborting..."):(this._pendingTasks.splice(t,1),this._waitingQueue.push(e),0===this._pendingTasks.length?this._minPendingPriority=null:this._minPendingPriority===e.priority&&(this._minPendingPriority=Math.min.apply(Math,this._pendingTasks.map((function(e){return e.priority})))),e.trigger(!1))},t._onTaskEnd=function(e){var t=(0,Ce.Z)(this._pendingTasks,(function(t){return t.observable===e.observable}));t<0||(this._pendingTasks.splice(t,1),this._pendingTasks.length>0?this._minPendingPriority===e.priority&&(this._minPendingPriority=Math.min.apply(Math,this._pendingTasks.map((function(e){return e.priority})))):(this._minPendingPriority=null,this._loopThroughWaitingQueue()))},t._canBeStartedNow=function(e){return null===this._minPendingPriority||e.priority<=this._minPendingPriority},t._isRunningHighPriorityTasks=function(){return null!==this._minPendingPriority&&this._minPendingPriority<=this._prioritySteps.high},e}(),Pe=n(3068),Oe=n(7714),De=n(8418),Le=n(908);const Be=function(){function e(){this._cache=new WeakMap}var t=e.prototype;return t.add=function(e,t){var n=e.representation;e.segment.isInit&&this._cache.set(n,t)},t.get=function(e){var t=e.representation;if(e.segment.isInit){var n=this._cache.get(t);if(void 0!==n)return n}return null},e}();var Ue=n(8117);function Fe(e,t,n){return function(r){return function(r){function i(){var i;return be(null!==(i=r.segment.mediaURLs)&&void 0!==i?i:[null],(function(t){var n=(0,Y.Z)({url:t},r);return(0,c.z)((0,l.of)({type:"request",value:n}),(0,ce.Z)(e,n))}),n).pipe((0,oe.K)((function(e){throw ve(e)})),(0,v.U)((function(e){if("retry"===e.type)return{type:"warning",value:ve(e.value)};if("request"===e.value.type)return e.value;var n=e.value;return"data-loaded"===n.type&&null!=t&&t.add(r,n.value),e.value})))}var a=null!=t?t.get(r):null;return null!=a?(0,Ue.Z)(a).pipe((0,v.U)((function(e){return{type:"cache",value:e}})),(0,oe.K)(i)):i()}(r).pipe((0,g.zg)((function(e){var t;switch(t="data-chunk-complete"!==e.type&&"data-loaded"!==e.type||void 0===e.value.size||void 0===e.value.duration?p.E:(0,l.of)({type:"metrics",value:{size:e.value.size,duration:e.value.duration,content:r}}),e.type){case"warning":case"request":case"progress":return(0,l.of)(e);case"cache":case"data-created":case"data-loaded":return(0,c.z)((0,l.of)({type:"data",value:e.value}),t);case"data-chunk":return(0,l.of)({type:"chunk",value:e.value});case"data-chunk-complete":return(0,c.z)((0,l.of)({type:"chunk-complete",value:null}),t);default:(0,De.Z)(e)}})))}}var ze=(0,Le.Z)();var Ke=L.Z.MIN_CANCELABLE_PRIORITY,Ve=L.Z.MAX_HIGH_PRIORITY_LEVEL;const We=function(){function e(e,t){this._transport=e,this._prioritizer=new Ne({prioritySteps:{high:Ve,low:Ke}}),this._backoffOptions=t}return e.prototype.createSegmentFetcher=function(e,t){var n,r,i,a=function(e,t){var n=t.maxRetryRegular,r=t.maxRetryOffline,i=t.lowLatencyMode;return{maxRetryRegular:"image"===e?0:null!=n?n:xe,maxRetryOffline:null!=r?r:Ie,baseDelay:i?Ze.LOW_LATENCY:Ze.REGULAR,maxDelay:i?Re.LOW_LATENCY:Re.REGULAR}}(e,this._backoffOptions),o=function(e,t,n,r){var i=(0,Oe.Z)(["audio","video"],e)?new Be:void 0,a=Fe(t[e].loader,i,r),o=t[e].parser;return function(e){var t=ze(),r=!1;return a(e).pipe((0,Pe.b)((function(e){switch(e.type){case"metrics":n.next(e);break;case"request":var i=e.value.segment;if(void 0===i)return;r=!0,n.next({type:"requestBegin",value:{duration:i.duration,time:i.time,requestTimestamp:performance.now(),id:t}});break;case"progress":var a=e.value;null!=a.totalSize&&a.size0?this._next(e.shift()):0===this.active&&this.hasCompleted&&(!1===this.hasValue&&this.destination.next(this.acc),this.destination.complete())},t}(Ge.Ds),je=n(4072);function Ye(e,t){return t?function(n){return n.pipe(Ye((function(n,r){return(0,je.D)(e(n,r)).pipe((0,v.U)((function(e,i){return t(n,e,r,i)})))})))}:function(t){return t.lift(new qe(e))}}var qe=function(){function e(e){this.project=e}return e.prototype.call=function(e,t){return t.subscribe(new Xe(e,this.project))},e}(),Xe=function(e){function t(t,n){var r=e.call(this,t)||this;return r.project=n,r.hasSubscription=!1,r.hasCompleted=!1,r.index=0,r}return o.ZT(t,e),t.prototype._next=function(e){this.hasSubscription||this.tryNext(e)},t.prototype.tryNext=function(e){var t,n=this.index++;try{t=this.project(e,n)}catch(e){return void this.destination.error(e)}this.hasSubscription=!0,this._innerSub(t)},t.prototype._innerSub=function(e){var t=new Ge.IY(this),n=this.destination;n.add(t);var r=(0,Ge.ft)(e,t);r!==t&&n.add(r)},t.prototype._complete=function(){this.hasCompleted=!0,this.hasSubscription||this.destination.complete(),this.unsubscribe()},t.prototype.notifyNext=function(e){this.destination.next(e)},t.prototype.notifyError=function(e){this.destination.error(e)},t.prototype.notifyComplete=function(){this.hasSubscription=!1,this.hasCompleted&&this.destination.complete()},t}(Ge.Ds),Qe=n(6381);var Je=n(8025),et=n(5278),tt=function(){function e(e){this._alpha=Math.exp(Math.log(.5)/e),this._lastEstimate=0,this._totalWeight=0}var t=e.prototype;return t.addSample=function(e,t){var n=Math.pow(this._alpha,e),r=t*(1-n)+n*this._lastEstimate;isNaN(r)||(this._lastEstimate=r,this._totalWeight+=e)},t.getEstimate=function(){var e=1-Math.pow(this._alpha,this._totalWeight);return this._lastEstimate/e},e}(),nt=L.Z.ABR_MINIMUM_TOTAL_BYTES,rt=L.Z.ABR_MINIMUM_CHUNK_SIZE,it=L.Z.ABR_FAST_EMA,at=L.Z.ABR_SLOW_EMA,ot=function(){function e(){this._fastEWMA=new tt(it),this._slowEWMA=new tt(at),this._bytesSampled=0}var t=e.prototype;return t.addSample=function(e,t){if(!(t0){var i=r.indexOf(n);-1!==i&&r.splice(i,1)}},t.prototype.notifyComplete=function(){},t.prototype._next=function(e){if(0===this.toRespond.length){var t=[e].concat(this.values);this.project?this._tryProject(t):this.destination.next(t)}},t.prototype._tryProject=function(e){var t;try{t=this.project.apply(this,e)}catch(e){return void this.destination.error(e)}this.destination.next(t)},t}(st.L);function ft(e){var t=e.map((function(t){return Math.log(t/e[0])})),n=t.map((function(e){return e-t[0]+1})),r=(n[n.length-1]-1)/(2*e.length+10),i=1/r;return e.map((function(t,a){return function(t){if(0===t)return 0;var a=Math.min(Math.max(1,t),e.length-1);return i*(r+(e[a]*n[a-1]-e[a-1]*n[a])/(e[a]-e[a-1]))+4}(a)}))}function pt(e,t){var n=ft(t);return O.Z.debug("ABR: Steps for buffer based chooser.",n.map((function(e,n){return{bufferLevel:e,bitrate:t[n]}}))),e.pipe((0,v.U)((function(e){return function(e,t,n){var r=e.bufferGap,i=e.currentBitrate,a=e.currentScore,o=e.speed;if(null==i)return t[0];var s,u=(0,Ce.Z)(t,(function(e){return e===i}));if(u<0||t.length!==n.length)return O.Z.error("ABR: Current Bitrate not found in the calculated levels"),t[0];if(null!=a&&(s=0===o?a:a/o),null!=s&&s>1){var l=n[u],d=function(){for(var e=u+1;el)return e}();if(null!=d&&r>=n[d])return t[d]}if((null==s||s<1.15)&&r=0;c--)if(t[c]t&&t-e.time>-1.2}));if(n<0)return[];for(var r=e[n],i=r.time,a=[r],o=n+1;o0?l.progress[l.progress.length-1]:void 0,p=Et(l);if(void 0!==f&&void 0!==p){var h=wt(f,p);if((c-f.timestamp)/1e3<=h)if(h-s/a>2e3)return p}var v=(c-l.requestTimestamp)/1e3;if(null!=n&&!(v<=(1.5*d+2)/a)){var m=d/v,g=n.bitrate*Math.min(.7,m);return void 0===r||g=s.outOfStarvationGap&&(O.Z.info("ABR: exit starvation mode."),this._inStarvationMode=!1):this._inStarvationMode&&(O.Z.info("ABR: exit starvation mode."),this._inStarvationMode=!1),this._inStarvationMode&&null!=(o=St(r,e,n,i))&&(O.Z.info("ABR: starvation mode emergency estimate:",o),t.reset(),a=null==n?o:Math.min(o,n.bitrate)),null==a&&(a=null!=(o=t.getEstimate())?o*(this._inStarvationMode?s.starvationBitrateFactor:s.regularBitrateFactor):null!=i?i*(this._inStarvationMode?s.starvationBitrateFactor:s.regularBitrateFactor):this._initialBitrate),e.speed>1&&(a/=e.speed),{bandwidthEstimate:o,bitrateChosen:a}},t.isUrgent=function(e,t,n,r){return null===t||e!==t.bitrate&&(e>t.bitrate?!this._inStarvationMode:function(e,t){var n=isFinite(e.bufferGap)?e.bufferGap:0,r=e.position+n,i=(0,mt.Z)(t,(function(e){return e.duration>0&&e.time+e.duration>r}));if(void 0===i)return!0;var a=performance.now(),o=i.progress.length>0?i.progress[i.progress.length-1]:void 0,s=Et(i);if(void 0===o||void 0===s)return!0;var u=wt(o,s);return(a-o.timestamp)/1e3>1.2*u||u-n/e.speed>-1.5}(r,n))},e}(),At=n(1679),xt=function(){function e(){this._currentRequests={}}var t=e.prototype;return t.add=function(e){var t=e.id,n=e.time,r=e.duration,i=e.requestTimestamp;this._currentRequests[t]={time:n,duration:r,requestTimestamp:i,progress:[]}},t.addProgress=function(e){var t=this._currentRequests[e.id];null!=t?t.progress.push(e):O.Z.warn("ABR: progress for a request not added")},t.remove=function(e){null==this._currentRequests[e]&&O.Z.warn("ABR: can't remove unknown request"),delete this._currentRequests[e]},t.getRequests=function(){return(0,At.Z)(this._currentRequests).filter((function(e){return null!=e})).sort((function(e,t){return e.time-t.time}))},e}(),It=function(){function e(){this._currentRepresentationData=null,this._lastRepresentationWithGoodScore=null}var t=e.prototype;return t.addSample=function(e,t,n){var r,i=n/t,a=this._getEWMA(e);null!=a?(r=a,a.addSample(t,i)):((r=new tt(5)).addSample(t,i),this._currentRepresentationData={representation:e,ewma:r}),r.getEstimate()>1&&this._lastRepresentationWithGoodScore!==e&&(O.Z.debug("ABR: New last stable representation",e),this._lastRepresentationWithGoodScore=e)},t.getEstimate=function(e){var t=this._getEWMA(e);if(null!=t)return t.getEstimate()},t.getLastStableRepresentation=function(){return this._lastRepresentationWithGoodScore},t._getEWMA=function(e){return null!=this._currentRepresentationData&&this._currentRepresentationData.representation.id===e.id?this._currentRepresentationData.ewma:null},e}();function Zt(e,t,n,r){var i=t<=n?n:t>=r?r:t,a=(0,Ce.Z)(e,(function(e){return e.bitrate>i}));return-1===a?e[e.length-1]:0===a?e[0]:e[a-1]}function Rt(e,t){var n=e;return null!=t.bitrate&&(n=function(e,t){if(0===e.length)return[];e.sort((function(e,t){return e.bitrate-t.bitrate}));var n=e[0].bitrate,r=Math.max(t,n),i=(0,Ce.Z)(e,(function(e){return e.bitrate>r}));return-1===i?e:e.slice(0,i)}(n,t.bitrate)),null!=t.width&&(n=function(e,t){var n=e.slice().sort((function(e,t){return(0,et.Z)(e.width,0)-(0,et.Z)(t.width,0)})),r=(0,mt.Z)(n,(function(e){return"number"==typeof e.width&&e.width>=t}));if(void 0===r)return e;var i="number"==typeof r.width?r.width:0;return e.filter((function(e){return"number"!=typeof e.width||e.width<=i}))}(n,t.width)),n}function Mt(e){var t=e.bandwidthEstimator,n=e.clock$,r=e.filters$,i=e.initialBitrate,a=e.lowLatencyMode,o=e.manualBitrate$,s=e.minAutoBitrate$,u=e.maxAutoBitrate$,c=e.representations,p=e.streamEvents$,h=new It,m=new kt(null==i?0:i,a),g=new xt,y=vt();var _=p.pipe((0,T.h)((function(e){return"metrics"===e.type})),(0,Pe.b)((function(e){return function(e){var n=e.duration,r=e.size,i=e.content;if(!y(i,n)){t.addSample(n,r);var a=n/1e3,o=i.segment.duration,s=i.representation;h.addSample(s,a,o)}}(e.value)})),(0,ie.l)()),b=p.pipe((0,Pe.b)((function(e){switch(e.type){case"requestBegin":g.add(e.value);break;case"requestEnd":g.remove(e.value.id);break;case"progress":g.addProgress(e.value)}})),(0,ie.l)()),E=p.pipe((0,T.h)((function(e){return"representationChange"===e.type})),(0,v.U)((function(e){return e.value.representation})),(0,w.O)(null)),S=(0,J.P)((function(){if(0===c.length)throw new Error("ABRManager: no representation choice given");return 1===c.length?(0,l.of)({bitrate:void 0,representation:c[0],manual:!1,urgent:!0,knownStableBitrate:void 0}):o.pipe((0,Qe.w)((function(e){if(e>=0){var i=Zt(c,e,0,1/0);return(0,l.of)({representation:i,bitrate:void 0,knownStableBitrate:void 0,manual:!0,urgent:!0})}var a,o=!0,f=pt(p.pipe((0,T.h)((function(e){return"added-segment"===e.type})),lt(n),(0,v.U)((function(e){var t=e[0].value,n=e[1],r=n.speed,i=n.position,a=t.buffered,o=(0,X.L7)(a,i),s=t.content.representation,u=h.getEstimate(s);return{bufferGap:o,currentBitrate:s.bitrate,currentScore:u,speed:r}}))),c.map((function(e){return e.bitrate}))).pipe((0,w.O)(void 0));return(0,d.aj)([n,s,u,r,f]).pipe(lt(E),(0,v.U)((function(e){var n=e[0],r=n[0],i=n[1],s=n[2],u=n[3],l=n[4],d=e[1],f=Rt(c,u),p=g.getRequests(),v=m.getBandwidthEstimate(r,t,d,p,a),y=v.bandwidthEstimate,_=v.bitrateChosen;a=y;var b=h.getLastStableRepresentation(),T=null==b?void 0:b.bitrate/(r.speed>0?r.speed:1),E=r.bufferGap;!o&&E<=5?o=!0:o&&isFinite(E)&&E>10&&(o=!1);var w=Zt(f,_,i,s);if(o)return O.Z.debug("ABR: Choosing representation with bandwidth estimation.",w),{bitrate:y,representation:w,urgent:m.isUrgent(w.bitrate,d,p,r),manual:!1,knownStableBitrate:T};if(null==l||w.bitrate>=l)return O.Z.debug("ABR: Choosing representation with bandwidth estimation.",w),{bitrate:y,representation:w,urgent:m.isUrgent(w.bitrate,d,p,r),manual:!1,knownStableBitrate:T};var S=Zt(f,l,i,s);return l<=s&&O.Z.debug("ABR: Choosing representation with buffer based bitrate ceiling.",S),{bitrate:y,representation:S,urgent:m.isUrgent(l,d,p,r),manual:!1,knownStableBitrate:T}})))})))}));return(0,f.T)(_,b,S)}const Ct=function(){function e(e){this._manualBitrates=e.manualBitrates,this._minAutoBitrates=e.minAutoBitrates,this._maxAutoBitrates=e.maxAutoBitrates,this._initialBitrates=e.initialBitrates,this._throttlers=e.throttlers,this._bandwidthEstimators={},this._lowLatencyMode=e.lowLatencyMode}var t=e.prototype;return t.get$=function(e,t,n,r){var i,a,o,s,u=this._getBandwidthEstimator(e),c=(0,et.Z)(this._manualBitrates[e],(0,l.of)(-1)),f=(0,et.Z)(this._minAutoBitrates[e],(0,l.of)(0)),p=(0,et.Z)(this._maxAutoBitrates[e],(0,l.of)(1/0)),h=(0,et.Z)(this._initialBitrates[e],0);return Mt({bandwidthEstimator:u,streamEvents$:r,clock$:n,filters$:(i=this._throttlers.limitWidth[e],a=this._throttlers.throttleBitrate[e],o=this._throttlers.throttle[e],s=[],null!=i&&s.push(i.pipe((0,v.U)((function(e){return{width:e}})))),null!=o&&s.push(o.pipe((0,v.U)((function(e){return{bitrate:e}})))),null!=a&&s.push(a.pipe((0,v.U)((function(e){return{bitrate:e}})))),s.length>0?(0,d.aj)(s).pipe((0,v.U)((function(e){return Y.Z.apply(void 0,[{}].concat(e))}))):(0,l.of)({})),initialBitrate:h,manualBitrate$:c,minAutoBitrate$:f,maxAutoBitrate$:p,representations:t,lowLatencyMode:this._lowLatencyMode})},t._getBandwidthEstimator=function(e){var t=this._bandwidthEstimators[e];if(null==t){O.Z.debug("ABR: Creating new BandwidthEstimator for ",e);var n=new ot;return this._bandwidthEstimators[e]=n,n}return t},e}();var Nt=n(4507),Pt=n(5767),Ot=n(3774),Dt=n(6923),Lt=M.ym;function Bt(e,t,n){if(null!==t&&"closed"!==t.readyState){for(var r=t.readyState,i=t.sourceBuffers,a=i.length-1;a>=0;a--){var o=i[a];try{"open"===r&&(O.Z.info("Init: Removing SourceBuffer from mediaSource",o),o.abort()),t.removeSourceBuffer(o)}catch(e){O.Z.warn("Init: Error while disposing SourceBuffer",e)}}i.length>0&&O.Z.warn("Init: Not all SourceBuffers could have been removed.")}if((0,Pt.Z)(e),null!==n)try{O.Z.debug("Init: Revoking previous URL"),URL.revokeObjectURL(n)}catch(e){O.Z.warn("Init: Error while revoking the media source URL",e)}}function Ut(e){return function(e){return new Me.y((function(t){if(null==Ot.JJ)throw new B.Z("MEDIA_SOURCE_NOT_SUPPORTED","No MediaSource Object was found in the current browser.");var n=(0,Dt.Z)(e.src)?e.src:null;Bt(e,null,n),O.Z.info("Init: Creating MediaSource");var r=new Ot.JJ,i=URL.createObjectURL(r);return O.Z.info("Init: Attaching MediaSource URL to the media element",i),e.src=i,t.next(r),function(){Bt(e,r,i)}}))}(e).pipe((0,g.zg)((function(e){return Lt(e).pipe((0,S.q)(1),(0,k.h)(e))})))}var Ft=n(8343),zt=L.Z.DEFAULT_LIVE_GAP;var Kt=n(4944),Vt=n(6564),Wt=n(7027);var Gt=n(6968),Ht=n(2870),$t=n(4123),jt=L.Z.SOURCE_BUFFER_FLUSHING_INTERVAL;const Yt=function(e){function n(t,n,r){var a;a=e.call(this)||this;var o=r.addSourceBuffer(n);return a._destroy$=new i.xQ,a.bufferType=t,a._mediaSource=r,a._sourceBuffer=o,a._queue=[],a._pendingTask=null,a._lastInitSegment=null,a.codec=n,(0,Vt.F)(jt).pipe((0,Pe.b)((function(){return a._flush()})),(0,h.R)(a._destroy$)).subscribe(),(0,Wt.R)(a._sourceBuffer,"error").pipe((0,Pe.b)((function(e){return a._onPendingTaskError(e)})),(0,h.R)(a._destroy$)).subscribe(),(0,Wt.R)(a._sourceBuffer,"updateend").pipe((0,Pe.b)((function(){return a._flush()})),(0,h.R)(a._destroy$)).subscribe(),a}(0,t.Z)(n,e);var r=n.prototype;return r.pushChunk=function(e){return O.Z.debug("AVSB: receiving order to push data to the SourceBuffer",this.bufferType,e),this._addToQueue({type:$t.f.Push,value:e})},r.removeBuffer=function(e,t){return O.Z.debug("AVSB: receiving order to remove data from the SourceBuffer",this.bufferType,e,t),this._addToQueue({type:$t.f.Remove,value:{start:e,end:t}})},r.endOfSegment=function(e){return O.Z.debug("AVSB: receiving order for validating end of segment",this.bufferType,e.segment),this._addToQueue({type:$t.f.EndOfSegment,value:e})},r.getBufferedRanges=function(){return this._sourceBuffer.buffered},r.getPendingOperations=function(){var e=function(e){switch(e.type){case $t.f.Push:case $t.f.Remove:case $t.f.EndOfSegment:return{type:e.type,value:e.value}}},t=this._queue.map(e);return null===this._pendingTask?t:[e(this._pendingTask)].concat(t)},r.dispose=function(){for(this._destroy$.next(),this._destroy$.complete(),null!==this._pendingTask&&(this._pendingTask.subject.complete(),this._pendingTask=null);this._queue.length>0;){var e=this._queue.shift();void 0!==e&&e.subject.complete()}if("open"===this._mediaSource.readyState)try{this._sourceBuffer.abort()}catch(e){O.Z.warn("AVSB: Failed to abort a "+this.bufferType+" SourceBuffer:",e)}},r._onPendingTaskError=function(e){if(this._lastInitSegment=null,null!==this._pendingTask){var t=e instanceof Error?e:new Error("An unknown error occured when doing operations on the SourceBuffer");this._pendingTask.subject.error(t)}},r._addToQueue=function(e){var t=this;return new Me.y((function(n){var r=0===t._queue.length&&null===t._pendingTask,a=new i.xQ,o=(0,Y.Z)({subject:a},e);t._queue.push(o);var s=a.subscribe(n);return r&&t._flush(),function(){s.unsubscribe();var e=t._queue.indexOf(o);e>=0&&t._queue.splice(e,1)}}))},r._flush=function(){if(!this._sourceBuffer.updating){if(null!==this._pendingTask){var e=this._pendingTask;if(e.type!==$t.f.Push||0===e.data.length){switch(e.type){case $t.f.Push:null!==e.inventoryData&&this._segmentInventory.insertChunk(e.inventoryData);break;case $t.f.EndOfSegment:this._segmentInventory.completeSegment(e.value);break;case $t.f.Remove:this.synchronizeInventory();break;default:(0,De.Z)(e)}var t=e.subject;return this._pendingTask=null,t.next(),t.complete(),void this._flush()}}else{var n=this._queue.shift();if(void 0===n)return;if(n.type!==$t.f.Push)this._pendingTask=n;else{var r,i=n.value;try{r=this._preparePushOperation(i.data)}catch(e){this._pendingTask=(0,Y.Z)({data:[],inventoryData:i.inventoryInfos},n);var a=e instanceof Error?e:new Error("An unknown error occured when preparing a push operation");return this._lastInitSegment=null,void n.subject.error(a)}this._pendingTask=(0,Y.Z)({data:r,inventoryData:i.inventoryInfos},n)}}try{switch(this._pendingTask.type){case $t.f.EndOfSegment:return O.Z.debug("AVSB: Acknowledging complete segment",this._pendingTask.value),void this._flush();case $t.f.Push:var o=this._pendingTask.data.shift();if(void 0===o)return void this._flush();this._sourceBuffer.appendBuffer(o);break;case $t.f.Remove:var s=this._pendingTask.value,u=s.start,l=s.end;O.Z.debug("AVSB: removing data from SourceBuffer",this.bufferType,u,l),this._sourceBuffer.remove(u,l);break;default:(0,De.Z)(this._pendingTask)}}catch(e){this._onPendingTaskError(e)}}},r._preparePushOperation=function(e){var t=[],n=e.codec,r=e.timestampOffset,i=e.appendWindow,a=!1;if(n!==this.codec&&(O.Z.debug("AVSB: updating codec",n),(a=function(e,t){if("function"==typeof e.changeType){try{e.changeType(t)}catch(e){return O.Z.warn("Could not call 'changeType' on the given SourceBuffer:",e),!1}return!0}return!1}(this._sourceBuffer,n))?this.codec=n:O.Z.debug("AVSB: could not update codec",n,this.codec)),this._sourceBuffer.timestampOffset!==r){var o=r;O.Z.debug("AVSB: updating timestampOffset",this.bufferType,this._sourceBuffer.timestampOffset,o),this._sourceBuffer.timestampOffset=o}if(void 0===i[0]?this._sourceBuffer.appendWindowStart>0&&(this._sourceBuffer.appendWindowStart=0):i[0]!==this._sourceBuffer.appendWindowStart&&(i[0]>=this._sourceBuffer.appendWindowEnd&&(this._sourceBuffer.appendWindowEnd=i[0]+1),this._sourceBuffer.appendWindowStart=i[0]),void 0===i[1]?this._sourceBuffer.appendWindowEnd!==1/0&&(this._sourceBuffer.appendWindowEnd=1/0):i[1]!==this._sourceBuffer.appendWindowEnd&&(this._sourceBuffer.appendWindowEnd=i[1]),null!==e.initSegment&&(a||!this._isLastInitSegment(e.initSegment))){var s=e.initSegment;t.push(s);var u=(0,Gt._f)(s);this._lastInitSegment={data:u,hash:(0,Ht.Z)(u)}}return null!==e.chunk&&t.push(e.chunk),t},r._isLastInitSegment=function(e){if(null===this._lastInitSegment)return!1;if(this._lastInitSegment.data===e)return!0;var t=this._lastInitSegment.data;if(t.byteLength===e.byteLength){var n=(0,Gt._f)(e);if((0,Ht.Z)(n)===this._lastInitSegment.hash&&(0,G.Z)(t,n))return!0}return!1},n}($t.C);var qt=["audio","video","text","image"];function Xt(e){return"audio"===e||"video"===e}const Qt=function(){function e(e,t){this._mediaElement=e,this._mediaSource=t,this._initializedSegmentBuffers={},this._onNativeBufferAddedOrDisabled=[]}e.isNative=function(e){return Xt(e)};var t=e.prototype;return t.getBufferTypes=function(){var e=this.getNativeBufferTypes();return null==V.Z.nativeTextTracksBuffer&&null==V.Z.htmlTextTracksBuffer||e.push("text"),null!=V.Z.imageBuffer&&e.push("image"),e},t.getNativeBufferTypes=function(){return"AUDIO"===this._mediaElement.nodeName?["audio"]:["video","audio"]},t.getStatus=function(e){var t=this._initializedSegmentBuffers[e];return void 0===t?{type:"uninitialized"}:null===t?{type:"disabled"}:{type:"initialized",value:t}},t.waitForUsableBuffers=function(){var e=this;return this._areNativeBuffersUsable()?(0,l.of)(void 0):new Me.y((function(t){e._onNativeBufferAddedOrDisabled.push((function(){e._areNativeBuffersUsable()&&(t.next(void 0),t.complete())}))}))},t.disableSegmentBuffer=function(t){var n=this._initializedSegmentBuffers[t];if(null!==n){if(void 0!==n)throw new Error("Cannot disable an active SegmentBuffer.");this._initializedSegmentBuffers[t]=null,e.isNative(t)&&this._onNativeBufferAddedOrDisabled.forEach((function(e){return e()}))}else O.Z.warn("SBS: The "+t+" SegmentBuffer was already disabled.")},t.createSegmentBuffer=function(e,t,n){void 0===n&&(n={});var r,i=this._initializedSegmentBuffers[e];if(Xt(e)){if(null!=i)return i instanceof Yt&&i.codec!==t?O.Z.warn("SB: Reusing native SegmentBuffer with codec",i.codec,"for codec",t):O.Z.info("SB: Reusing native SegmentBuffer with codec",t),i;O.Z.info("SB: Adding native SegmentBuffer with codec",t);var a=new Yt(e,t,this._mediaSource);return this._initializedSegmentBuffers[e]=a,this._onNativeBufferAddedOrDisabled.forEach((function(e){return e()})),a}if(null!=i)return O.Z.info("SB: Reusing a previous custom SegmentBuffer for the type",e),i;if("text"===e){if(O.Z.info("SB: Creating a new text SegmentBuffer"),"html"===n.textTrackMode){if(null==V.Z.htmlTextTracksBuffer)throw new Error("HTML Text track feature not activated");r=new V.Z.htmlTextTracksBuffer(this._mediaElement,n.textTrackElement)}else{if(null==V.Z.nativeTextTracksBuffer)throw new Error("Native Text track feature not activated");r=new V.Z.nativeTextTracksBuffer(this._mediaElement,!0===n.hideNativeSubtitle)}return this._initializedSegmentBuffers.text=r,r}if("image"===e){if(null==V.Z.imageBuffer)throw new Error("Image buffer feature not activated");return O.Z.info("SB: Creating a new image SegmentBuffer"),r=new V.Z.imageBuffer,this._initializedSegmentBuffers.image=r,r}throw O.Z.error("SB: Unknown buffer type:",e),new B.Z("BUFFER_TYPE_UNKNOWN","The player wants to create a SegmentBuffer of an unknown type.")},t.disposeSegmentBuffer=function(e){var t=this._initializedSegmentBuffers[e];null!=t?(O.Z.info("SB: Aborting SegmentBuffer",e),t.dispose(),delete this._initializedSegmentBuffers[e]):O.Z.warn("SB: Trying to dispose a SegmentBuffer that does not exist")},t.disposeAll=function(){var e=this;qt.forEach((function(t){"initialized"===e.getStatus(t).type&&e.disposeSegmentBuffer(t)}))},t._areNativeBuffersUsable=function(){var e=this,t=this.getNativeBufferTypes();return!t.some((function(t){return void 0===e._initializedSegmentBuffers[t]}))&&!t.every((function(t){return null===e._initializedSegmentBuffers[t]}))},e}();var Jt=function(){function e(e){this._array=[],this._sortingFn=e}var t=e.prototype;return t.add=function(){for(var e=arguments.length,t=new Array(e),n=0;n=this._array.length)throw new Error("Invalid index.");return this._array[e]},t.findFirst=function(e){return(0,mt.Z)(this._array,e)},t.has=function(e){return(0,Oe.Z)(this._array,e)},t.removeElement=function(e){var t=this._array.indexOf(e);if(t>=0)return this._array.splice(t,1),t},t.head=function(){return this._array[0]},t.last=function(){return this._array[this._array.length-1]},t.shift=function(){return this._array.shift()},t.pop=function(){return this._array.pop()},e}(),en=function(){function e(e){this._weakMap=new WeakMap,this._fn=e}var t=e.prototype;return t.get=function(e){var t=this._weakMap.get(e);if(void 0===t){var n=this._fn(e);return this._weakMap.set(e,n),n}return t},t.destroy=function(e){this._weakMap.delete(e)},e}(),tn=n(2257);function nn(e){var t=e.segmentBuffer,n=e.clock$,r=e.maxBufferBehind$,i=e.maxBufferAhead$;return(0,d.aj)([n,r,i]).pipe((0,g.zg)((function(e){var n=e[0],r=e[1],i=e[2];return function(e,t,n,r){if(!isFinite(n)&&!isFinite(r))return p.E;var i=[],a=(0,X.F_)(e.getBufferedRanges(),t),o=a.innerRange,s=a.outerRanges,u=function(){if(isFinite(r)){for(var e=0;en.start&&i.push({start:t+r,end:n.end})}null!=o&&t+r=r.end?i.push(r):t>=r.end&&t-n>r.start&&t-no.start&&i.push({start:o.start,end:t-n})}}(),u(),(0,je.D)(i.map((function(t){return O.Z.debug("GC: cleaning range from SegmentBuffer",t),e.removeBuffer(t.start,t.end)}))).pipe((0,tn.u)(),(0,ie.l)())}(t,n,r,i)})))}const rn={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,n){return{type:"needs-media-source-reload",value:{position:t,autoPlay:n,period:e}}},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){return{type:"encryption-data-encountered",value: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}}};var an=n(7473),on=n.n(an);var sn=function(){function e(e,t){this.predicate=e,this.inclusive=t}return e.prototype.call=function(e,t){return t.subscribe(new un(e,this.predicate,this.inclusive))},e}(),un=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.predicate=n,i.inclusive=r,i.index=0,i}return o.ZT(t,e),t.prototype._next=function(e){var t,n=this.destination;try{t=this.predicate(e,this.index++)}catch(e){return void n.error(e)}this.nextOrComplete(e,t)},t.prototype.nextOrComplete=function(e,t){var n=this.destination;Boolean(t)?n.next(e):(this.inclusive&&n.next(e),n.complete())},t}(A.L);function ln(e,t,n,r,i){var a=e.period,o=e.adaptation,s=e.representation,u=function(e,t){for(var n=0;n=t.end)return null;if(r.bufferedEnd>t.start)return n}return null}(i,t);if(null===u){if(null===n){if(r&&void 0!==a.end&&t.end>=a.end)return{start:void 0,end:null};var l=s.index.checkDiscontinuity(t.start);if(null!==l)return{start:void 0,end:l}}return null}var d=i[u];if(void 0!==d.bufferedStart&&d.bufferedStart>t.start&&(null===n||d.infos.segment.end<=n))return O.Z.debug("RS: current discontinuity encountered",o.type,d.bufferedStart),{start:void 0,end:d.bufferedStart};var c=function(e,t,n){if(n<=0)return O.Z.error("RS: Asked to check a discontinuity before the first chunk."),null;for(var r=n;r=t.end)return null;if(i.bufferedStart-a.bufferedEnd>0)return r}return null}(i,t,u+1);if(null!==c&&(null===n||i[c].infos.segment.end<=n)){var f=i[c-1].bufferedEnd,p=i[c].bufferedStart;return O.Z.debug("RS: future discontinuity encountered",o.type,f,p),{start:f,end:p}}if(null===n){if(r&&void 0!==a.end){if(t.end=0;n--){var r=e[n];if(void 0===r.bufferedStart)return null;if(r.bufferedStart=a.end)return null;for(var m=i.length-1;m>=0;m--){var g=i[m];if(void 0===g.bufferedStart)break;if(g.bufferedStart=n.length-1?null:n[t+1];return!function(e,t,n){if(void 0===e.bufferedStart)return O.Z.warn("Stream: Start of a segment unknown. Assuming it is garbage collected by default.",e),!0;if(null!==t&&void 0!==t.bufferedEnd&&e.bufferedStart-t.bufferedEnd<.1)return!1;if(npn)return O.Z.info("Stream: The start of the wanted segment has been garbage collected",e),!0;return!1}(e,r,i.start)&&!function(e,t,n){if(void 0===e.bufferedEnd)return O.Z.warn("Stream: End of a segment unknown. Assuming it is garbage collected by default.",e),!0;if(null!==t&&void 0!==t.bufferedStart&&t.bufferedStart-e.bufferedEnd<.1)return!1;if(n>e.bufferedEnd&&e.end-e.bufferedEnd>pn)return O.Z.info("Stream: The end of the wanted segment has been garbage collected",e),!0;return!1}(e,a,i.end)}));return s.filter((function(e){var i=(0,Y.Z)({segment:e},t);if(a.length>0&&a.some((function(e){return(0,dn.Z)(i,e)})))return!1;var o=e.duration,s=e.time,l=e.end;if(e.isInit)return!0;if(o0&&a.some((function(e){if(e.period.id!==t.period.id||e.adaptation.id!==t.adaptation.id)return!1;var a=e.segment;return!(a.time-vn>s)&&(!(a.end+vn-vn&&f.end-l>-vn)return!1}}for(var p=0;ps)return h.start>s+vn||gn(u,p).ende[n].start;)n++;return e[--n]}function yn(e,t,n,r){return e.period.id===t.period.id&&(!(e.segment.timei}return rr}(e.representation,t.representation,r)))}var _n=L.Z.SEGMENT_PRIORITIES_STEPS;function bn(e,t){for(var n=e-(t.position+t.wantedTimeOffset),r=0;r<_n.length;r++)if(n<_n[r])return r;return _n.length}var Tn=L.Z.MINIMUM_SEGMENT_SIZE;function En(e,t,n,r,i){var a,o=e.period,s=e.representation;i.synchronizeInventory();var u,l,d=t.position+t.wantedTimeOffset,c=d+r,f={start:Math.max(d,o.start),end:Math.min(c,null!==(a=o.end)&&void 0!==a?a:1/0)},p=s.index.shouldRefresh(d,c),h=i.getPendingOperations().filter((function(e){return e.type===$t.f.EndOfSegment})).map((function(e){return e.value})),v=function(e,t){for(var n=Math.max(1/60,Tn),r=e.start+n,i=e.end-n,a=[],o=t.length-1;o>=0;o--){var s=t[o],u=s.infos.representation;if(!s.partiallyPushed&&!1!==u.decipherable&&u.isSupported){var l=s.infos.segment,d=l.time/l.timescale;((null==l.duration?s.end:d+l.duration/l.timescale)>r&&dr&&s.start0)u=!1;else if(void 0===g)u=f.end>=o.end&&s.index.isFinished();else if(null===g)u=s.index.isFinished();else{var y=void 0!==o.end?Math.min(o.end,g):g;u=f.end>=y&&s.index.isFinished()}if(s.index.isInitialized()&&(s.index.areSegmentsChronologicallyGenerated()||u)){var _=null;h.length>0&&(_=Math.min.apply(Math,h.map((function(e){return e.segment.time})))),m.length>0&&(_=null!==_?Math.min(_,m[0].segment.time):m[0].segment.time),l=ln(e,f,_,u,v)}else l=null;return{imminentDiscontinuity:l,hasFinishedLoading:u,neededSegments:m,shouldRefreshManifest:p}}var wn=L.Z.BUFFER_GC_GAPS.CALM,Sn=L.Z.BUFFER_GC_GAPS.BEEFY;function kn(e,t,n){for(var r=(0,X.F_)(t,e),i=r.innerRange,a=r.outerRanges,o=[],s=0;su.start)&&o.push(u)}return null!=i&&(O.Z.debug("Stream: GC removing part of inner range",o),e-n>i.start&&o.push({start:i.start,end:e-n}),e+n0&&null!==Z&&null===R){var p=f[0].priority;f.unshift({segment:Z,priority:p})}}else null===Z?O.Z.warn("Stream: Uninitialized index without an initialization segment"):null!==R?O.Z.warn("Stream: Uninitialized index with an already loaded initialization segment"):f.unshift({segment:Z,priority:bn(_.start,n)});var h=f[0];if(null!==i){if(M=[],i.urgent)return O.Z.debug("Stream: urgent termination request, terminate.",I),C.next(),C.complete(),(0,l.of)(rn.streamTerminating());if(null===P||void 0===h||P.segment.id!==h.segment.id)return O.Z.debug("Stream: cancel request and terminate.",null===P,I),C.next(),C.complete(),(0,l.of)(rn.streamTerminating());if(P.priority!==h.priority){var v=P.request$;P.priority=h.priority,u.updatePriority(v,h.priority)}O.Z.debug("Stream: terminate after request.",I)}else if(void 0===h)null!==P&&O.Z.debug("Stream: interrupt segment request.",I),M=[],C.next();else if(null===P)O.Z.debug("Stream: start downloading queue.",I),M=f,C.next();else if(P.segment.id!==h.segment.id)O.Z.debug("Stream: restart download queue.",I),M=f,C.next();else if(P.priority!==h.priority){O.Z.debug("Stream: update request priority.",I);var m=P.request$;P.priority=h.priority,u.updatePriority(m,h.priority)}else O.Z.debug("Stream: update downloading queue",I),M=f.slice().splice(1,f.length);var g=(0,l.of)({type:"stream-status",value:{period:_,position:n.position,bufferType:I,imminentDiscontinuity:d.imminentDiscontinuity,hasFinishedLoading:d.hasFinishedLoading,neededSegments:d.neededSegments}});return d.shouldRefreshManifest?(0,c.z)((0,l.of)(rn.needsManifestRefresh()),g):g})),(t=function(e){return"stream-terminating"!==e.type},void 0===(n=!0)&&(n=!1),function(e){return e.lift(new sn(t,n))})),L=!1,B=p.E;if(void 0!==A){var U=T.getEncryptionData(A);U.length>0&&(B=l.of.apply(void 0,U.map((function(e){return rn.encryptionDataEncountered(e)}))),L=!0)}var F=C.pipe((0,Qe.w)((function(){return M.length>0?(e=(0,J.P)((function(){var t=M.shift();if(void 0===t)return on()((function(){N.next()})),p.E;var n=t.segment,r=t.priority,i={manifest:y,period:_,adaptation:b,representation:T,segment:n},a=u.createRequest(i,r);return P={segment:n,priority:r,request$:a},a.pipe((0,g.zg)((function(t){switch(t.type){case"warning":return(0,l.of)({type:"retry",value:{segment:n,error:t.value}});case"chunk-complete":return P=null,(0,l.of)({type:"end-of-segment",value:{segment:n}});case"interrupted":return O.Z.info("Stream: segment request interrupted temporarly.",n),p.E;case"chunk":var r=null==R?void 0:R.initTimescale;return t.parse(r).pipe((0,v.U)((function(e){return(0,Y.Z)({segment:n},e)})));case"ended":return e;default:(0,De.Z)(t)}})))}))).pipe(ue((function(){P=null}))):p.E;var e})),(0,g.zg)((function(e){var t;switch(e.type){case"retry":return(0,c.z)((0,l.of)({type:"warning",value:e.value.error}),(0,J.P)((function(){var t=e.value.segment,n=T.index;if(!1===n.isSegmentStillAvailable(t))N.next();else if(n.canBeOutOfSyncError(e.value.error,t))return(0,l.of)(rn.manifestMightBeOufOfSync());return p.E})));case"parsed-init-segment":R=e.value;var n=T.getAllEncryptionData(),i=!L&&n.length>0?l.of.apply(void 0,n.map((function(e){return rn.encryptionDataEncountered(e)}))):p.E,a=function(e){var t=e.clock$,n=e.content,r=e.segment,i=e.segmentData,a=e.segmentBuffer;return(0,J.P)((function(){if(null===i)return p.E;var e=n.representation.getMimeTypeString();return An(t,a,{data:{initSegment:i,chunk:null,timestampOffset:0,appendWindow:[void 0,void 0],codec:e},inventoryInfos:null}).pipe((0,v.U)((function(){var e=a.getBufferedRanges();return rn.addedSegment(n,r,e,i)})))}))}({clock$:r,content:o,segment:e.segment,segmentData:e.value.initializationData,segmentBuffer:s});return(0,f.T)(i,a);case"parsed-segment":var u=null!==(t=null==R?void 0:R.initializationData)&&void 0!==t?t:null,d=e.value,h=d.inbandEvents,m=!0===d.needsManifestRefresh?(0,l.of)(rn.needsManifestRefresh()):p.E,g=void 0!==h&&h.length>0?(0,l.of)({type:"inband-events",value:h}):p.E;return(0,c.z)(m,g,function(e){var t=e.clock$,n=e.content,r=e.initSegmentData,i=e.parsedSegment,a=e.segment,o=e.segmentBuffer;return(0,J.P)((function(){var e,s;if(null===i.chunkData)return p.E;var u=i.chunkData,l=i.chunkInfos,d=i.chunkOffset,c=i.appendWindow,f=n.representation.getMimeTypeString(),h=[void 0!==c[0]?Math.max(0,c[0]-xn.START):void 0,void 0!==c[1]?c[1]+xn.END:void 0],m={initSegment:r,chunk:u,timestampOffset:d,appendWindow:h,codec:f},g=null!==(e=null==l?void 0:l.time)&&void 0!==e?e:a.time,y=g+(null!==(s=null==l?void 0:l.duration)&&void 0!==s?s:a.duration);void 0!==h[0]&&(g=Math.max(g,h[0])),void 0!==h[1]&&(y=Math.min(y,h[1]));var _=(0,Y.Z)({segment:a,start:g,end:y},n);return An(t,o,{data:m,inventoryInfos:_}).pipe((0,v.U)((function(){var e=o.getBufferedRanges();return rn.addedSegment(n,a,e,u)})))}))}({clock$:r,content:o,initSegmentData:u,parsedSegment:e.value,segment:e.segment,segmentBuffer:s}));case"end-of-segment":var y=e.value.segment;return s.endOfSegment((0,Y.Z)({segment:y},o)).pipe((0,ie.l)());default:(0,De.Z)(e)}})));return(0,c.z)(B,(0,f.T)(D,F).pipe((0,E.B)()))};function Zn(e,t,n){return t.pipe((0,S.q)(1),(0,g.zg)((function(r){var i;if(e.start<=r.position&&(void 0===e.end||e.end>r.position)){var a=r.getCurrentTime()+n,o=Math.min(Math.max(e.start,a),null!==(i=e.end)&&void 0!==i?i:1/0);return(0,l.of)(rn.needsMediaSourceReload(e,o,!r.isPaused))}return t.pipe((0,v.U)((function(t){return rn.needsMediaSourceReload(e,t.getCurrentTime(),!t.isPaused)})))})))}var Rn=L.Z.DELTA_POSITION_AFTER_RELOAD;const Mn=function(e){var t=e.abrManager,n=e.clock$,r=e.content,a=e.options,o=e.segmentBuffer,s=e.segmentFetcherCreator,d=e.wantedBufferAhead$,h="direct"===a.manualBitrateSwitchingMode,y=r.manifest,_=r.period,b=r.adaptation,w={},k=function(e,t,n){var r=e.manifest,a=e.adaptation,o=new i.xQ,s=new i.xQ,u=(0,f.T)(o,s);return{estimator$:(0,c.z)((0,l.of)(null),(0,H.R)(r,"decipherabilityUpdate")).pipe((0,v.U)((function(){var e=a.getPlayableRepresentations();if(e.length<=0)throw new B.Z("NO_PLAYABLE_REPRESENTATION","No Representation in the chosen Adaptation can be played");return e})),(0,m.x)((function(e,t){if(e.length!==t.length)return!1;for(var n=0;n=i.end&&(O.Z.debug('Stream: full "empty" AdaptationStream',n),a=!0),(0,l.of)({type:"stream-status",value:{period:i,bufferType:n,position:t.position,imminentDiscontinuity:null,hasFinishedLoading:a,neededSegments:[],shouldRefreshManifest:!1}})})))}var Nn=n(9252);const Pn=function(e,t){var n=e.split(";"),r=n[0],i=n.slice(1),a=t.split(";"),o=a[0],s=a.slice(1);if(r!==o)return!1;var u=(0,mt.Z)(i,(function(e){return(0,Nn.Z)(e,"codecs=")})),l=(0,mt.Z)(s,(function(e){return(0,Nn.Z)(e,"codecs=")}));if(void 0===u||void 0===l)return!1;var d=u.substring(7),c=l.substring(7);return d.split(".")[0]===c.split(".")[0]};var On=L.Z.ADAPTATION_SWITCH_BUFFER_PADDINGS;function Dn(e,t,n,r,i){if(void 0!==e.codec&&"reload"===i.onCodecSwitch&&!Ln(n,e.codec))return{type:"needs-reload",value:void 0};var a=e.getBufferedRanges();if(0===a.length)return{type:"continue",value:void 0};var o=(0,X.JN)(a),s=t.start,u=null==t.end?1/0:t.end,l=(0,X.tn)(o,[{start:s,end:u}]);if(0===l.length)return{type:"continue",value:void 0};e.synchronizeInventory();var d=e.getInventory();if(!d.some((function(e){return e.infos.period.id===t.id&&e.infos.adaptation.id!==n.id})))return{type:"continue",value:void 0};var c=function(e,t,n){return e.reduce((function(e,r){if(r.infos.period.id!==t.id||r.infos.adaptation.id!==n.id)return e;var i=r.bufferedStart,a=r.bufferedEnd;return void 0===i||void 0===a||e.push({start:i,end:a}),e}),[])}(d,t,n),f=(0,X.uH)(l,c);if(0===f.length)return{type:"continue",value:void 0};var p=r.currentTime;if("video"===n.type&&(0,X.Ti)({start:s,end:u},p)&&(r.readyState>1||!n.getPlayableRepresentations().some((function(t){var n;return Pn(t.getMimeTypeString(),null!==(n=e.codec)&&void 0!==n?n:"")})))&&!(0,X.A1)(c,p))return{type:"needs-reload",value:void 0};if("audio"===n.type&&void 0!==e.codec&&"direct"===i.audioTrackSwitchingMode&&(0,X.Ti)({start:s,end:u},p)&&(r.readyState>1||!Ln(n,e.codec))&&!(0,X.A1)(c,p))return{type:"needs-reload",value:void 0};var h=[],v=function(e,t){for(var n=0;n=t.start)return n>0?e[n-1]:null;return e.length>0?e[e.length-1]:null}(d,t);null!==v&&(void 0===v.bufferedEnd||t.start-v.bufferedEnd<1)&&h.push({start:0,end:t.start+1});var m=n.type,g=On[m].before;null==g&&(g=0);var y=On[m].after;if(null==y&&(y=0),h.push({start:p-g,end:p+y}),void 0!==t.end){var _=function(e,t){for(var n=0;nt.start)return e[n];return null}(d,t);null!==_&&(void 0===_.bufferedStart||_.bufferedStart-t.end<1)&&h.push({start:t.end-1,end:Number.MAX_VALUE})}var b=(0,X.uH)(f,h);return b.length>0?{type:"clean-buffer",value:b}:{type:"continue",value:void 0}}function Ln(e,t){return e.getPlayableRepresentations().some((function(e){return Pn(e.getMimeTypeString(),t)}))}var Bn=L.Z.DELTA_POSITION_AFTER_RELOAD;const Un=function(e){var t=e.abrManager,n=e.bufferType,r=e.clock$,i=e.content,o=e.garbageCollectors,s=e.segmentFetcherCreator,u=e.segmentBuffersStore,d=e.options,h=e.wantedBufferAhead$,m=i.period,y=new a.t(1);return y.pipe((0,Qe.w)((function(e,a){var y=0===a?0:"audio"===n?Bn.trackSwitch.audio:"video"===n?Bn.trackSwitch.video:Bn.trackSwitch.other;if(null===e){O.Z.info("Stream: Set no "+n+" Adaptation",m);var _,b=u.getStatus(n);if("initialized"===b.type){if(O.Z.info("Stream: Clearing previous "+n+" SegmentBuffer"),Qt.isNative(n))return Zn(m,r,y);_=b.value.removeBuffer(m.start,null==m.end?1/0:m.end)}else"uninitialized"===b.type&&u.disableSegmentBuffer(n),_=(0,l.of)(null);return(0,c.z)(_.pipe((0,k.h)(rn.adaptationChange(n,null,m))),Cn(r,h,n,{period:m}))}if(Qt.isNative(n)&&"disabled"===u.getStatus(n).type)return Zn(m,r,y);O.Z.info("Stream: Updating "+n+" adaptation",e,m);var T=r.pipe((0,S.q)(1),(0,g.zg)((function(a){var _=function(e,t,n,r){var i=e.getStatus(t);if("initialized"===i.type)return O.Z.info("Stream: Reusing a previous SegmentBuffer for the type",t),i.value;var a=function(e){var t=e.representations;if(null==t[0])return"";return t[0].getMimeTypeString()}(n),o="text"===t?r.textTrackOptions:void 0;return e.createSegmentBuffer(t,a,o)}(u,n,e,d),b={currentTime:a.getCurrentTime(),readyState:a.readyState},T=Dn(_,m,e,b,d);if("needs-reload"===T.type)return Zn(m,r,y);var E="clean-buffer"===T.type?c.z.apply(void 0,T.value.map((function(e){var t=e.start,n=e.end;return _.removeBuffer(t,n)}))).pipe((0,ie.l)()):p.E,w=o.get(_),S=function(e,a){var o=i.manifest,f=r.pipe((0,v.U)((function(e){var t=a.getBufferedRanges();return(0,Y.Z)({},e,{bufferGap:(0,X.L7)(t,e.position)})})));return Mn({abrManager:t,clock$:f,content:{manifest:o,period:m,adaptation:e},options:d,segmentBuffer:a,segmentFetcherCreator:s,wantedBufferAhead$:h}).pipe((0,oe.K)((function(e){if(!Qt.isNative(n)){O.Z.error("Stream: "+n+" Stream crashed. Aborting it.",e),u.disposeSegmentBuffer(n);var t=z(e,{defaultCode:"NONE",defaultReason:"Unknown `AdaptationStream` error"});return(0,c.z)((0,l.of)(rn.warning(t)),Cn(r,h,n,{period:m}))}throw O.Z.error("Stream: "+n+" Stream crashed. Stopping playback.",e),e})))}(e,_);return u.waitForUsableBuffers().pipe((0,g.zg)((function(){return(0,c.z)(E,(0,f.T)(S,w))})))})));return(0,c.z)((0,l.of)(rn.adaptationChange(n,e,m)),T)})),(0,w.O)(rn.periodStreamReady(n,m,y)))};var Fn=n(2807);function zn(){for(var e=arguments.length,t=new Array(e),n=0;nd.getMaximumPosition()){var i=new B.Z("MEDIA_TIME_AFTER_MANIFEST","The current position is after the latest time announced in the Manifest.");return rn.warning(i)}return null}),null)),x=r.getBufferTypes().map((function(e){return function(e,n){var a=new Jt((function(e,t){return e.start-t.start})),o=new i.xQ,s=!1;function u(t){return R(e,t,o).pipe((0,fe.Z)((function(e){switch(e.type){case"needs-media-source-reload":var t=a.head();if(void 0===t||t.id!==e.value.period.id)return null;break;case"periodStreamReady":s=!0,a.add(e.value.period);break;case"periodStreamCleared":a.removeElement(e.value.period)}return e}),null),(0,E.B)())}function h(e){var t=a.head(),n=a.last();return null==t||null==n||(t.start>e||(null==n.end?1/0:n.end)=s.end}))),y=p.pipe(Ye((function(t){return R(e,t,v)}))),_=u.pipe((0,S.q)(1),(0,Pe.b)((function(){p.complete(),v.next(),v.complete()})),(0,E.B)()),b=(0,f.T)(m,_),A=Un({abrManager:n,bufferType:e,clock$:t,content:{manifest:d,period:s},garbageCollectors:k,segmentFetcherCreator:a,segmentBuffersStore:r,options:o,wantedBufferAhead$:w}).pipe((0,g.zg)((function(t){if("stream-status"===t.type)if(t.value.hasFinishedLoading){var n=d.getPeriodAfter(s);if(null===n)return(0,c.z)((0,l.of)(t),(0,l.of)(rn.streamComplete(e)));p.next(n)}else v.next();return(0,l.of)(t)})),(0,E.B)()),x=(0,c.z)(A.pipe((0,h.R)(b)),(0,l.of)(rn.periodStreamCleared(e,s)).pipe((0,Pe.b)((function(){O.Z.info("SO: Destroying Stream for",e,s)}))));return(0,f.T)(x,y,_.pipe((0,ie.l)()))}};var Gn=n(8821),Hn=n(6565);var $n=function(){function e(e){if(this.total=e,this.total<0)throw new Hn.W}return e.prototype.call=function(e,t){return t.subscribe(new jn(e,this.total))},e}(),jn=function(e){function t(t,n){var r=e.call(this,t)||this;return r.total=n,r.ring=new Array,r.count=0,r}return o.ZT(t,e),t.prototype._next=function(e){var t=this.ring,n=this.total,r=this.count++;t.length0)for(var n=this.count>=this.total?this.total:this.count,r=this.ring,i=0;i0&&void 0!==e[0].period.end&&e[0].period.end+10r.start)return ar(t)&&e.splice(a,0,t),e;ar(t)&&e.push(t);return e}(e,t[0],t[1])}),[])),o=null,s=null;return e.pipe(lt(a),(0,v.U)((function(e){var r=e[0],a=e[1],u=r.buffered,l=r.currentRange,d=r.position,c=r.event,f=r.stalled;if(null===f)return{type:"unstalled",value:null};if(r.seeking)o=r.position;else if(null!==o){var p=performance.now();if(null===s&&(s=p),er&&r.positionn)return r;var o=void 0;if(void 0===a.end||a.end>n){var s=e[i],u=s.discontinuity,l=s.position,d=u.start,c=u.end;if(n>=(null!=d?d:l)-rr)if(null===c){var f=t.getPeriodAfter(a);null!==f?o=f.start+rr:O.Z.warn("Init: discontinuity at Period's end but no next Period")}else no?r:o)}}return r}(a,n,h);if(null!==v){var m=v+.001;if(!(m<=t.currentTime))return O.Z.warn("SA: skippable discontinuity found in the stream",d,m),i(m),rn.warning(or(h,m));O.Z.info("Init: position to seek already reached, no seeking",t.currentTime,m)}}if(function(e,t,n,r){return P.vU&&r&&"timeupdate"===n&&null!=t&&t.end-e>10}(d,l,c,null!==f))return O.Z.warn("Init: After freeze seek",d,l),i(d),rn.warning(or(d,d));var g=null!=h?h:d,y=(0,X.XS)(u,g);if(y=0;b--){var T=n.periods[b];if(void 0!==T.end&&T.end<=g){if(n.periods[b+1].start>g&&n.periods[b+1].start>t.currentTime){var E=n.periods[b+1];return i(E.start),rn.warning(or(g,E.start))}break}}return{type:"stalled",value:f}})))}function ar(e){return null!==e.discontinuity}function or(e,t){return new B.Z("DISCONTINUITY_ENCOUNTERED","A discontinuity has been encountered at position "+String(e)+", seeked at position "+String(t))}var sr=function(){function e(){}return e.prototype.call=function(e,t){return t.subscribe(new ur(e))},e}(),ur=function(e){function t(t){var n=e.call(this,t)||this;return n.hasPrev=!1,n}return o.ZT(t,e),t.prototype._next=function(e){var t;this.hasPrev?t=[this.prev,e]:this.hasPrev=!0,this.prev=e,t&&this.destination.next(t)},t}(A.L);const lr=function(e,t){return e.id===t.id&&e.start===t.start&&e.end===t.end};const dr=function(e,t){for(var n=[],r=t.periods,i=0;i0})),(0,m.x)(),(0,Qe.w)((function(e){return e?(0,d.aj)([(0,Vt.F)(cr).pipe((0,w.O)(null)),n]).pipe((0,v.U)((function(e){e[0];return{isSeeking:e[1].seeking,currentTime:t.currentTime}})),(function(e){return e.lift(new sr)}),(0,g.zg)((function(e){var t=e[0],n=e[1];return function(e,t,n){for(var i=t.currentTime,a=n.isSeeking,o=n.currentTime,s=[],u=[],d=0;do||void 0!==v&&o>=v)&&(fr(f)&&u.push(f.publicEvent),r.delete(f)):h<=o&&void 0!==v&&o=(null!=v?v:h)&&(a?s.push({type:"stream-event-skip",value:f.publicEvent}):(s.push({type:"stream-event",value:f.publicEvent}),fr(f)&&u.push(f.publicEvent)))}return(0,c.z)(s.length>0?l.of.apply(void 0,s):p.E,u.length>0?l.of.apply(void 0,u).pipe((0,Pe.b)((function(e){"function"==typeof e.onExit&&e.onExit()})),(0,ie.l)()):p.E)}(i,t,n)}))):p.E})))};var hr=n(2983);function vr(e){var t=e.mediaElement,n=e.manifest,r=e.clock$,o=e.speed$,s=e.bufferOptions,u=e.abrManager,c=e.segmentFetcherCreator,m=e.setCurrentTime;return function(e,_,b){var E,S=function(e,t){return(0,H.R)(e,"manifestUpdate").pipe((0,w.O)(null),(0,Pe.b)((function(){var n=e.getMaximumPosition(),r=e.isLive?Math.max(Math.pow(2,32),n+31536e3):n;(isNaN(t.duration)||!isFinite(t.duration)||Math.abs(t.duration-r)>.01)&&(O.Z.info("Init: Updating duration",r),t.duration=r)})),(0,ie.l)())}(n,e),k=null!==(E=n.getPeriodForTime(_))&&void 0!==E?E:n.getNextPeriod(_);if(void 0===k){var A=new B.Z("MEDIA_STARTING_TIME_NOT_FOUND","Wanted starting time not found in the Manifest.");return(0,Kt._)(A)}var x=new Qt(t,e),I=function(e,t,n){var r=n.autoPlay,i=n.manifest,o=n.speed$,s=n.startTime,u=n.setCurrentTime,l=!1,c=!1,p=new a.t(1),h=(0,Jn.Z)(t,e,r,!1).pipe((0,Pe.b)((function(e){l=!0,p.next(e)})),(0,ie.l)()),m=(0,d.aj)([t,o]).pipe((0,v.U)((function(t){var n=t[0],a=t[1],o=c;!c&&(n.readyState>0||"loadedmetadata"===n.event)&&(e.currentTime!==s&&(O.Z.info("Init: Set initial time",s),u(s)),c=!0);var d=i.isLive?o?i.getMaximumPosition()-n.position:i.getMaximumPosition()-s:1/0;return{position:n.position,getCurrentTime:n.getCurrentTime,duration:n.duration,isPaused:l?n.paused:!r,liveGap:d,readyState:n.readyState,speed:a,stalled:n.stalled,wantedTimeOffset:o?0:s}})));return{loaded$:p,clock$:(0,f.T)(h,m).pipe((0,y.d)({bufferSize:1,refCount:!0}))}}(t,r,{autoPlay:b,manifest:n,setCurrentTime:m,speed$:o,startTime:_}),Z=I.loaded$,R=I.clock$,M=Z.pipe((0,T.h)((function(e){return"not-loaded-metadata"!==e}))).pipe((0,g.zg)((function(){return pr(n,t,r)}))),C=new i.xQ,N=new i.xQ,P=Wn({manifest:n,initialPeriod:k},R,u,x,c,s).pipe((0,g.zg)((function(t){switch(t.type){case"end-of-stream":return O.Z.debug("Init: end-of-stream order received."),function(e){return qn(e).pipe((0,w.O)(null),(0,Qe.w)((function(){return Qn(e)})))}(e).pipe((0,ie.l)(),(0,h.R)(C));case"resume-stream":return O.Z.debug("Init: resume-stream order received."),C.next(null),p.E;case"stream-status":var n=t.value,r=n.period,i=n.bufferType,a=n.imminentDiscontinuity,o=n.position;return N.next({period:r,bufferType:i,discontinuity:a,position:o}),p.E;default:return(0,l.of)(t)}}))),D=(0,hr.Z)(t,o,r,{pauseWhenStalled:!0}).pipe((0,ie.l)()),L=ir(r,t,n,N,m),U=Z.pipe((0,g.zg)((function(e){if("autoplay-blocked"===e){var t=new B.Z("MEDIA_ERR_BLOCKED_AUTOPLAY","Cannot trigger auto-play automatically: your browser does not allow it.");return(0,l.of)(Ft.Z.warning(t),Ft.Z.loaded(x))}if("not-loaded-metadata"===e){var n=new B.Z("MEDIA_ERR_NOT_LOADED_METADATA","Cannot load automatically: your browser falsely announced having loaded the content.");return(0,l.of)(Ft.Z.warning(n))}return O.Z.debug("Init: The current content is loaded."),(0,l.of)(Ft.Z.loaded(x))})));return(0,f.T)(S,U,D,L,P,M).pipe(ue((function(){x.disposeAll()})))}}var mr=L.Z.FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY,gr=L.Z.MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE,yr=L.Z.MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE;function _r(e){var t,n,r=e.initialManifest,i=e.manifestFetcher,a=e.minimumManifestUpdateInterval,o=e.scheduleRefresh$,s=(t=function(e,t){return i.fetch(e).pipe((0,g.zg)((function(e){return"warning"===e.type?(0,l.of)(e):e.parse(t)})),(0,E.B)())},n=!1,function(){for(var e=arguments.length,r=new Array(e),i=0;i0?d=yr,m=o.pipe((0,g.zg)((function(e){var t=e.completeRefresh,r=e.delay,i=e.canUseUnsafeMode&&v;return br(null!=r?r:0,a,n).pipe((0,k.h)({completeRefresh:t,unsafeMode:i}))}))),y=void 0===n?0:performance.now()-n,_=Math.max(a-y,0);if(void 0===u.lifetime||u.lifetime<0)t=p.E;else{var b=1e3*u.lifetime-y;if(void 0!==s)if(u.lifetime<3&&s>=100){var T=1e3*(3-u.lifetime)+b,E=Math.max(T,Math.max(b,0)+s);O.Z.info("MUS: Manifest update rythm is too frequent. Postponing next request.",b,E),b=E}else if(s>=1e3*u.lifetime/10){var w=Math.max(b,0)+s;O.Z.info("MUS: Manifest took too long to parse. Postponing next request",b,w),b=w}t=(0,me.H)(Math.max(b,_)).pipe((0,k.h)({completeRefresh:!1,unsafeMode:v}))}var A=null===u.expired?p.E:(0,me.H)(_).pipe((0,R.j)((0,je.D)(u.expired)),(0,k.h)({completeRefresh:!0,unsafeMode:v}));return(0,f.T)(t,m,A).pipe((0,S.q)(1),(0,g.zg)((function(e){return h({completeRefresh:e.completeRefresh,unsafeMode:e.unsafeMode})})),(0,g.zg)((function(e){return"warning"===e.type?(0,l.of)(e):c(e)})))}return(0,J.P)((function(){return c(r)}));function h(e){var t=e.completeRefresh,n=e.unsafeMode,r=u.updateUrl,i=t||void 0===r,o=i?u.getUrl():r,c=u.clockOffset;return n?(d+=1,O.Z.info('Init: Refreshing the Manifest in "unsafeMode" for the '+String(d)+" consecutive time.")):d>0&&(O.Z.info('Init: Not parsing the Manifest in "unsafeMode" anymore after '+String(d)+" consecutive times."),d=0),s(o,{externalClockOffset:c,previousManifest:u,unsafeMode:n}).pipe((0,g.zg)((function(e){if("warning"===e.type)return(0,l.of)(e);var t=e.manifest,n=e.sendingTime,r=e.receivedTime,o=e.parsingTime,s=performance.now();if(i)u.replace(t);else try{u.update(t)}catch(e){var d=e instanceof Error?e.message:"unknown error";return O.Z.warn("MUS: Attempt to update Manifest failed: "+d,"Re-downloading the Manifest fully"),br(mr,a,n).pipe((0,g.zg)((function(){return h({completeRefresh:!0,unsafeMode:!1})})))}return(0,l.of)({type:"parsed",manifest:u,sendingTime:n,receivedTime:r,parsingTime:o,updatingTime:performance.now()-s})})))}}function br(e,t,n){return(0,J.P)((function(){var r=void 0===n?0:performance.now()-n,i=Math.max(t-r,0);return(0,me.H)(Math.max(e-r,i))}))}var Tr=n(2447),Er=L.Z.OUT_OF_SYNC_MANIFEST_REFRESH_DELAY;const wr=function(e){var t,n,r,a=e.adaptiveOptions,o=e.autoPlay,s=e.bufferOptions,u=e.clock$,c=e.keySystems,m=e.lowLatencyMode,_=e.manifest$,b=e.manifestFetcher,A=e.mediaElement,x=e.minimumManifestUpdateInterval,I=e.segmentFetcherCreator,Z=e.setCurrentTime,R=e.speed$,M=e.startAt,C=e.textTrackOptions,N=new Ct(a),P=Ut(A).pipe((0,y.d)({refCount:!0})),D=new i.xQ,L=(0,Nt.Z)(A,c,D).pipe((0,Je.Z)(),(0,E.B)()),B=(0,Tr.Z)(A),U=L.pipe((t=function(e,t){switch(t.type){case"eme-disabled":case"attached-media-keys":return(0,l.of)({isEmeReady:!0,drmSystemId:e.drmSystemId});case"created-media-keys":var n=t.value.initializationDataSystemId;return P.pipe((0,g.zg)((function(){return t.value.attachMediaKeys$.next(),!0===t.value.options.disableMediaKeysAttachmentLock?(0,l.of)({isEmeReady:!0,drmSystemId:n}):p.E})),(0,w.O)({isEmeReady:!1,drmSystemId:n}));default:return p.E}},n={isEmeReady:!1,drmSystemId:void 0},void 0===r&&(r=Number.POSITIVE_INFINITY),function(e){return e.lift(new He(t,n,r))}),(0,T.h)((function(e){return e.isEmeReady})),(0,S.q)(1),Ye((function(e){var t=e.drmSystemId;return P.pipe((0,v.U)((function(e){return{mediaSource:e,drmSystemId:t}})))}))),F=(0,d.aj)([_,U]).pipe((0,g.zg)((function(e){var t=e[0],n=e[1];if("warning"===t.type)return(0,l.of)(t);var r=t.manifest,a=n.mediaSource,d=n.drmSystemId;O.Z.debug("Init: Calculating initial time");var c=function(e,t,n){if(O.Z.debug("Init: calculating initial time"),null!=n){var r=e.getMinimumPosition(),i=e.getMaximumPosition();if(null!=n.position)return O.Z.debug("Init: using startAt.minimumPosition"),Math.max(Math.min(n.position,i),r);if(null!=n.wallClockTime){O.Z.debug("Init: using startAt.wallClockTime");var a=null==e.availabilityStartTime?0:e.availabilityStartTime,o=n.wallClockTime-a;return Math.max(Math.min(o,i),r)}if(null!=n.fromFirstPosition){O.Z.debug("Init: using startAt.fromFirstPosition");var s=n.fromFirstPosition;return s<=0?r:Math.min(i,r+s)}if(null!=n.fromLastPosition){O.Z.debug("Init: using startAt.fromLastPosition");var u=n.fromLastPosition;return u>=0?i:Math.max(r,i+u)}if(null!=n.percentage){O.Z.debug("Init: using startAt.percentage");var l=n.percentage;return l>100?i:l<0?r:r+ +l/100*(i-r)}}var d=e.getMinimumPosition();if(e.isLive){var c,f=e.suggestedPresentationDelay,p=e.clockOffset,h=e.getMaximumPosition();if(null==p)O.Z.info("Init: no clock offset found for a live content, starting close to maximum available position"),c=h;else{O.Z.info("Init: clock offset found for a live content, checking if we can start close to it");var v=null==e.availabilityStartTime?0:e.availabilityStartTime,m=(performance.now()+p)/1e3-v;c=Math.min(h,m)}var g=void 0!==f?f:t?zt.LOW_LATENCY:zt.DEFAULT;return O.Z.debug("Init: "+c+" defined as the live time, applying a live gap of "+g),Math.max(c-g,d)}return O.Z.info("Init: starting at the minimum available position:",d),d}(r,m,M);O.Z.debug("Init: Initial time calculated:",c);var p=vr({abrManager:N,bufferOptions:(0,Y.Z)({textTrackOptions:C,drmSystemId:d},s),clock$:u,manifest:r,mediaElement:A,segmentFetcherCreator:I,speed$:R,setCurrentTime:Z}),y=function e(t,n,r){var a=new i.xQ,o=p(t,n,r).pipe((0,fe.Z)((function(e){switch(e.type){case"needs-manifest-refresh":return _.next({completeRefresh:!1,canUseUnsafeMode:!0}),null;case"manifest-might-be-out-of-sync":return _.next({completeRefresh:!0,canUseUnsafeMode:!1,delay:Er}),null;case"needs-media-source-reload":return a.next(e.value),null;case"needs-decipherability-flush":var t=re(A);if(null===(r=t)||r.indexOf("widevine")<0)return a.next(e.value),null;var n=e.value.position;return n+.001=1&&"loadedmetadata"!==u&&null===m&&!(_||v),T=null,E=s?Mr.LOW_LATENCY:Mr.DEFAULT;if(o){if(b)d<=E?(r=!0,T=l+d):d===1/0?(r=!0,T=l):1===h&&(r=!0);else if(null!==m){var w=Nr(m,s);!0!==r&&null!==m&&h>1&&(_||v||d<1/0&&d>w)?i=!0:(d===1/0||d<=w)&&(T=d===1/0?l:l+d)}}else b&&(!p&&"timeupdate"===u&&"timeupdate"===g&&l===y||"seeking"===u&&d===1/0)?r=!0:null!==m&&("seeking"!==u&&l!==y||"canplay"===u||d<1/0&&(d>Nr(m,s)||_||v))&&(i=!0);return!0===i?null:!0===r||null!==m?(a="seeking"===u||null!==m&&"seeking"===m.reason?"seeking":t.seeking&&("internal-seeking"===u||null!==m&&"internal-seek"===m.reason)?"internal-seek":t.seeking?"seeking":1===h?"not-ready":"buffering",null!==m&&m.reason===a?{reason:m.reason,timestamp:m.timestamp,position:T}:{reason:a,timestamp:performance.now(),position:T}):null}const Dr=function(e,t){var n=0;return{clock$:(0,J.P)((function(){var r=(0,Y.Z)(Pr(e,"init"),{stalled:null,getCurrentTime:function(){return e.currentTime}});var i=Cr.map((function(t){return(0,Wt.R)(e,t).pipe((0,k.h)(t))})),a=t.lowLatencyMode?Ar:t.withMediaSource?kr:xr,o=(0,Vt.F)(a).pipe((0,k.h)("timeupdate"));return f.T.apply(void 0,[o].concat(i)).pipe((0,v.U)((function(i){return r=function(i){var a=i;"seeking"===a&&n>0&&(a="internal-seeking",n-=1);var o=Pr(e,a),s=Or(r,o,t),u=(0,Y.Z)({},{stalled:s,getCurrentTime:function(){return e.currentTime}},o);return O.Z.debug("API: current media element state",u),u}(i),"DEBUG"===O.Z.getLevel()&&O.Z.debug("API: current playback timeline:\n"+function(e,t){for(var n="",r="",i=0;it){var d=n.length-Math.floor(l.length/2);r=" ".repeat(d)+"^"+t}if(i=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.")}return(n=e[Symbol.iterator]()).next.bind(n)}function Yr(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0;)this._periods.pop()},t.update=function(){this._resetChosenAudioTracks(),this._resetChosenTextTracks(),this._resetChosenVideoTracks()},t.setInitialAudioTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.audio:null;if(null==n||null==t)throw new Error("TrackChoiceManager: Given Period not found.");var r=e.getPlayableAdaptations("audio"),i=this._audioChoiceMemory.get(e);if(null===i)n.adaptation$.next(null);else if(void 0!==i&&(0,Oe.Z)(r,i))n.adaptation$.next(i);else{var a=yi(r,hi(this._preferredAudioTracks));this._audioChoiceMemory.set(e,a),n.adaptation$.next(a)}},t.setInitialTextTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.text:null;if(null==n||null==t)throw new Error("TrackChoiceManager: Given Period not found.");var r=e.getPlayableAdaptations("text"),i=this._textChoiceMemory.get(e);if(null===i)n.adaptation$.next(null);else if(void 0!==i&&(0,Oe.Z)(r,i))n.adaptation$.next(i);else{var a=bi(r,vi(this._preferredTextTracks));this._textChoiceMemory.set(e,a),n.adaptation$.next(a)}},t.setInitialVideoTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.video:null;if(null==n||null==t)throw new Error("TrackChoiceManager: Given Period not found.");var r=e.getPlayableAdaptations("video"),i=this._videoChoiceMemory.get(e);if(null===i)n.adaptation$.next(null);else if(void 0!==i&&(0,Oe.Z)(r,i))n.adaptation$.next(i);else{var a=Ei(r,this._preferredVideoTracks);this._videoChoiceMemory.set(e,a),n.adaptation$.next(a)}},t.setAudioTrackByID=function(e,t){var n=wi(this._periods,e),r=null!=n?n.audio:null;if(null==r)throw new Error("TrackChoiceManager: Given Period not found.");var i=(0,mt.Z)(r.adaptations,(function(e){return e.id===t}));if(void 0===i)throw new Error("Audio Track not found.");this._audioChoiceMemory.get(e)!==i&&(this._audioChoiceMemory.set(e,i),r.adaptation$.next(i))},t.setTextTrackByID=function(e,t){var n=wi(this._periods,e),r=null!=n?n.text:null;if(null==r)throw new Error("TrackChoiceManager: Given Period not found.");var i=(0,mt.Z)(r.adaptations,(function(e){return e.id===t}));if(void 0===i)throw new Error("Text Track not found.");this._textChoiceMemory.get(e)!==i&&(this._textChoiceMemory.set(e,i),r.adaptation$.next(i))},t.setVideoTrackByID=function(e,t){var n=wi(this._periods,e),r=null!=n?n.video:null;if(null==r)throw new Error("LanguageManager: Given Period not found.");var i=(0,mt.Z)(r.adaptations,(function(e){return e.id===t}));if(void 0===i)throw new Error("Video Track not found.");this._videoChoiceMemory.get(e)!==i&&(this._videoChoiceMemory.set(e,i),r.adaptation$.next(i))},t.disableTextTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.text:null;if(null==n)throw new Error("TrackChoiceManager: Given Period not found.");null!==this._textChoiceMemory.get(e)&&(this._textChoiceMemory.set(e,null),n.adaptation$.next(null))},t.disableVideoTrack=function(e){var t=wi(this._periods,e),n=null==t?void 0:t.video;if(void 0===n)throw new Error("TrackManager: Given Period not found.");null!==this._videoChoiceMemory.get(e)&&(this._videoChoiceMemory.set(e,null),n.adaptation$.next(null))},t.getChosenAudioTrack=function(e){var t=wi(this._periods,e);if(null==(null!=t?t.audio:null))return null;var n=this._audioChoiceMemory.get(e);if(null==n)return null;var r={language:(0,et.Z)(n.language,""),normalized:(0,et.Z)(n.normalizedLanguage,""),audioDescription:!0===n.isAudioDescription,id:n.id,representations:n.representations.map(ki)};return!0===n.isDub&&(r.dub=!0),r},t.getChosenTextTrack=function(e){var t=wi(this._periods,e);if(null==(null!=t?t.text:null))return null;var n=this._textChoiceMemory.get(e);return null==n?null:{language:(0,et.Z)(n.language,""),normalized:(0,et.Z)(n.normalizedLanguage,""),closedCaption:!0===n.isClosedCaption,id:n.id}},t.getChosenVideoTrack=function(e){var t=wi(this._periods,e);if(null==(null!=t?t.video:null))return null;var n=this._videoChoiceMemory.get(e);if(null==n)return null;var r={id:n.id,representations:n.representations.map(Si)};return!0===n.isSignInterpreted&&(r.signInterpreted=!0),r},t.getAvailableAudioTracks=function(e){var t=wi(this._periods,e),n=null!=t?t.audio:null;if(null==n)return[];var r=this._audioChoiceMemory.get(e),i=null!=r?r.id:null;return n.adaptations.map((function(e){var t={language:(0,et.Z)(e.language,""),normalized:(0,et.Z)(e.normalizedLanguage,""),audioDescription:!0===e.isAudioDescription,id:e.id,active:null!=i&&i===e.id,representations:e.representations.map(ki)};return!0===e.isDub&&(t.dub=!0),t}))},t.getAvailableTextTracks=function(e){var t=wi(this._periods,e),n=null!=t?t.text:null;if(null==n)return[];var r=this._textChoiceMemory.get(e),i=null!=r?r.id:null;return n.adaptations.map((function(e){return{language:(0,et.Z)(e.language,""),normalized:(0,et.Z)(e.normalizedLanguage,""),closedCaption:!0===e.isClosedCaption,id:e.id,active:null!=i&&i===e.id}}))},t.getAvailableVideoTracks=function(e){var t=wi(this._periods,e),n=null!=t?t.video:null;if(null==n)return[];var r=this._videoChoiceMemory.get(e),i=null!=r?r.id:null;return n.adaptations.map((function(e){var t={id:e.id,active:null!==i&&i===e.id,representations:e.representations.map(Si)};return!0===e.isSignInterpreted&&(t.signInterpreted=!0),t}))},t._applyAudioPreferences=function(){this._audioChoiceMemory=new WeakMap,this._resetChosenAudioTracks()},t._applyTextPreferences=function(){this._textChoiceMemory=new WeakMap,this._resetChosenTextTracks()},t._applyVideoPreferences=function(){this._videoChoiceMemory=new WeakMap,this._resetChosenVideoTracks()},t._resetChosenAudioTracks=function(){var e=this,t=hi(this._preferredAudioTracks);!function n(r){if(!(r>=e._periods.length())){var i=e._periods.get(r);if(null!=i.audio){var a=i.period,o=i.audio,s=a.getPlayableAdaptations("audio"),u=e._audioChoiceMemory.get(a);if(null===u||void 0!==u&&(0,Oe.Z)(s,u))n(r+1);else{var l=yi(s,t);e._audioChoiceMemory.set(a,l),o.adaptation$.next(l),n(0)}}else n(r+1)}}(0)},t._resetChosenTextTracks=function(){var e=this,t=vi(this._preferredTextTracks);!function n(r){if(!(r>=e._periods.length())){var i=e._periods.get(r);if(null!=i.text){var a=i.period,o=i.text,s=a.getPlayableAdaptations("text"),u=e._textChoiceMemory.get(a);if(null===u||void 0!==u&&(0,Oe.Z)(s,u))n(r+1);else{var l=bi(s,t);e._textChoiceMemory.set(a,l),o.adaptation$.next(l),n(0)}}else n(r+1)}}(0)},t._resetChosenVideoTracks=function(){var e=this,t=this._preferredVideoTracks;!function n(r){if(!(r>=e._periods.length())){var i=e._periods.get(r);if(null!=i.video){var a=i.period,o=i.video,s=a.getPlayableAdaptations("video"),u=e._videoChoiceMemory.get(a);if(null===u||void 0!==u&&(0,Oe.Z)(s,u))n(r+1);else{var l=Ei(s,t);e._videoChoiceMemory.set(a,l),o.adaptation$.next(l),n(0)}}else n(r+1)}}(0)},e}();function gi(e){return function(t){var n;if(void 0!==e.normalized&&(null!==(n=t.normalizedLanguage)&&void 0!==n?n:"")!==e.normalized)return!1;if(void 0!==e.audioDescription)if(e.audioDescription){if(!0!==t.isAudioDescription)return!1}else if(!0===t.isAudioDescription)return!1;if(void 0===e.codec)return!0;var r=e.codec.test,i=function(e){return void 0!==e.codec&&r.test(e.codec)};return e.codec.all?t.representations.every(i):t.representations.some(i)}}function yi(e,t){if(0===e.length)return null;for(var n=0;nv)throw new Error('Invalid maxVideoBitrate parameter. Its value, "'+v+'", is inferior to the set minVideoBitrate, "'+p+'"')}if((0,$.Z)(e.maxAudioBitrate))h=ii.audio;else{if(h=Number(e.maxAudioBitrate),isNaN(h))throw new Error("Invalid maxAudioBitrate parameter. Should be a number.");if(f>h)throw new Error('Invalid maxAudioBitrate parameter. Its value, "'+h+'", is inferior to the set minAudioBitrate, "'+f+'"')}return{maxBufferAhead:t,maxBufferBehind:n,limitVideoWidth:m,videoElement:l,wantedBufferAhead:r,throttleWhenHidden:i,throttleVideoBitrateWhenHidden:a,preferredAudioTracks:o,preferredTextTracks:s,preferredVideoTracks:u,initialAudioBitrate:c,initialVideoBitrate:d,minAudioBitrate:f,minVideoBitrate:p,maxAudioBitrate:h,maxVideoBitrate:v,stopAtEnd:(0,$.Z)(e.stopAtEnd)?ui:!!e.stopAtEnd}}(e),o=r.initialAudioBitrate,s=r.initialVideoBitrate,l=r.limitVideoWidth,d=r.minAudioBitrate,c=r.minVideoBitrate,f=r.maxAudioBitrate,p=r.maxBufferAhead,g=r.maxBufferBehind,y=r.maxVideoBitrate,_=r.preferredAudioTracks,b=r.preferredTextTracks,T=r.preferredVideoTracks,E=r.throttleWhenHidden,w=r.throttleVideoBitrateWhenHidden,S=r.videoElement,k=r.wantedBufferAhead,A=r.stopAtEnd;return S.preload="auto",t.version="3.24.0",t.log=O.Z,t.state="STOPPED",t.videoElement=S,t._priv_destroy$=new i.xQ,t._priv_pictureInPictureEvent$=new a.t(1),Ci(S).pipe((0,h.R)(t._priv_destroy$)).subscribe(t._priv_pictureInPictureEvent$),Ri(S).pipe((0,h.R)(t._priv_destroy$)).subscribe((function(){return t.trigger("fullscreenChange",t.isFullscreen())})),Pi(S.textTracks).pipe((0,h.R)(t._priv_destroy$),(0,v.U)((function(e){for(var t=e.target,n=[],r=0;r0?e.textTracks[0]:null},o.getPlayerState=function(){return this.state},o.isLive=function(){if(null===this._priv_contentInfos)return!1;var e=this._priv_contentInfos,t=e.isDirectFile,n=e.manifest;return!t&&null!==n&&n.isLive},o.getUrl=function(){if(null!==this._priv_contentInfos){var e=this._priv_contentInfos,t=e.isDirectFile,n=e.manifest,r=e.url;return t?r:null!==n?n.getUrl():void 0}},o.getVideoDuration=function(){if(null===this.videoElement)throw new Error("Disposed player");return this.videoElement.duration},o.getVideoBufferGap=function(){if(null===this.videoElement)throw new Error("Disposed player");var e=this.videoElement;return(0,X.L7)(e.buffered,e.currentTime)},o.getVideoLoadedTime=function(){if(null===this.videoElement)throw new Error("Disposed player");var e=this.videoElement;return(0,X.at)(e.buffered,e.currentTime)},o.getVideoPlayedTime=function(){if(null===this.videoElement)throw new Error("Disposed player");var e=this.videoElement;return(0,X.DD)(e.buffered,e.currentTime)},o.getWallClockTime=function(){if(null===this.videoElement)throw new Error("Disposed player");if(null===this._priv_contentInfos)return this.videoElement.currentTime;var e=this._priv_contentInfos,t=e.isDirectFile,n=e.manifest;return t?this.videoElement.currentTime:null!==n?this.videoElement.currentTime+(void 0!==n.availabilityStartTime?n.availabilityStartTime:0):0},o.getPosition=function(){if(null===this.videoElement)throw new Error("Disposed player");return this.videoElement.currentTime},o.getPlaybackRate=function(){return this._priv_speed$.getValue()},o.setPlaybackRate=function(e){this._priv_speed$.next(e)},o.getAvailableVideoBitrates=function(){if(null===this._priv_contentInfos)return[];var e=this._priv_contentInfos,t=e.currentPeriod,n=e.activeAdaptations;if(null===t||null===n)return[];var r=n[t.id];return void 0===r||(0,$.Z)(r.video)?[]:r.video.getAvailableBitrates()},o.getAvailableAudioBitrates=function(){if(null===this._priv_contentInfos)return[];var e=this._priv_contentInfos,t=e.currentPeriod,n=e.activeAdaptations;if(null===t||null===n)return[];var r=n[t.id];return void 0===r||(0,$.Z)(r.audio)?[]:r.audio.getAvailableBitrates()},o.getManualAudioBitrate=function(){return this._priv_bitrateInfos.manualBitrates.audio.getValue()},o.getManualVideoBitrate=function(){return this._priv_bitrateInfos.manualBitrates.video.getValue()},o.getVideoBitrate=function(){var e=this._priv_getCurrentRepresentations();if(null!==e&&!(0,$.Z)(e.video))return e.video.bitrate},o.getAudioBitrate=function(){var e=this._priv_getCurrentRepresentations();if(null!==e&&!(0,$.Z)(e.audio))return e.audio.bitrate},o.getMinVideoBitrate=function(){return this._priv_bitrateInfos.minAutoBitrates.video.getValue()},o.getMinAudioBitrate=function(){return this._priv_bitrateInfos.minAutoBitrates.audio.getValue()},o.getMaxVideoBitrate=function(){return this._priv_bitrateInfos.maxAutoBitrates.video.getValue()},o.getMaxAudioBitrate=function(){return this._priv_bitrateInfos.maxAutoBitrates.audio.getValue()},o.play=function(){var e=this;if(null===this.videoElement)throw new Error("Disposed player");var t=this.videoElement.play();return(0,$.Z)(t)||"function"!=typeof t.catch?q.Z.resolve():t.catch((function(t){if("NotAllowedError"===t.name){var n=new B.Z("MEDIA_ERR_PLAY_NOT_ALLOWED",t.toString());e.trigger("warning",n)}throw t}))},o.pause=function(){if(null===this.videoElement)throw new Error("Disposed player");this.videoElement.pause()},o.seekTo=function(e){if(null===this.videoElement)throw new Error("Disposed player");if(null===this._priv_contentInfos)throw new Error("player: no content loaded");var t,n=this._priv_contentInfos,r=n.isDirectFile,i=n.manifest;if(!r&&null===i)throw new Error("player: the content did not load yet");if("number"==typeof e)t=e;else if("object"==typeof e){var a=e,o=this.videoElement.currentTime;if((0,$.Z)(a.relative))if((0,$.Z)(a.position)){if((0,$.Z)(a.wallClockTime))throw new Error('invalid time object. You must set one of the following properties: "relative", "position" or "wallClockTime"');t=r||null===i?a.wallClockTime:a.wallClockTime-(void 0!==i.availabilityStartTime?i.availabilityStartTime:0)}else t=a.position;else t=o+a.relative}if(void 0===t)throw new Error("invalid time given");return this.videoElement.currentTime=t,t},o.isFullscreen=function(){return(0,Q.Z)("isFullscreen is deprecated. Fullscreen management should now be managed by the application"),N()},o.setFullscreen=function(e){if(void 0===e&&(e=!0),(0,Q.Z)("setFullscreen is deprecated. Fullscreen management should now be managed by the application"),null===this.videoElement)throw new Error("Disposed player");e?function(e){if(!N()){var t=e;"function"==typeof t.requestFullscreen?t.requestFullscreen():"function"==typeof t.msRequestFullscreen?t.msRequestFullscreen():"function"==typeof t.mozRequestFullScreen?t.mozRequestFullScreen():"function"==typeof t.webkitRequestFullscreen&&t.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}}(this.videoElement):C()},o.exitFullscreen=function(){(0,Q.Z)("exitFullscreen is deprecated. Fullscreen management should now be managed by the application"),C()},o.getVolume=function(){if(null===this.videoElement)throw new Error("Disposed player");return this.videoElement.volume},o.setVolume=function(e){if(null===this.videoElement)throw new Error("Disposed player");var t=this.videoElement;e!==t.volume&&(t.volume=e,this.trigger("volumeChange",e))},o.isMute=function(){return 0===this.getVolume()},o.mute=function(){this._priv_mutedMemory=this.getVolume(),this.setVolume(0)},o.unMute=function(){0===this.getVolume()&&this.setVolume(0===this._priv_mutedMemory?Ai:this._priv_mutedMemory)},o.setVideoBitrate=function(e){this._priv_bitrateInfos.manualBitrates.video.next(e)},o.setAudioBitrate=function(e){this._priv_bitrateInfos.manualBitrates.audio.next(e)},o.setMinVideoBitrate=function(e){var t=this._priv_bitrateInfos.maxAutoBitrates.video.getValue();if(e>t)throw new Error('Invalid minimum video bitrate given. Its value, "'+e+'" is superior the current maximum video birate, "'+t+'".');this._priv_bitrateInfos.minAutoBitrates.video.next(e)},o.setMinAudioBitrate=function(e){var t=this._priv_bitrateInfos.maxAutoBitrates.audio.getValue();if(e>t)throw new Error('Invalid minimum audio bitrate given. Its value, "'+e+'" is superior the current maximum audio birate, "'+t+'".');this._priv_bitrateInfos.minAutoBitrates.audio.next(e)},o.setMaxVideoBitrate=function(e){var t=this._priv_bitrateInfos.minAutoBitrates.video.getValue();if(e0?r.next(i[0]):r.next(null)}},o._priv_onPeriodStreamCleared=function(e){var t=e.type,n=e.period;switch(t){case"audio":case"text":case"video":null!==this._priv_trackChoiceManager&&this._priv_trackChoiceManager.removePeriod(t,n)}if(null!==this._priv_contentInfos){var r=this._priv_contentInfos,i=r.activeAdaptations,a=r.activeRepresentations;if(!(0,$.Z)(i)&&!(0,$.Z)(i[n.id])){var o=i[n.id];delete o[t],0===Object.keys(o).length&&delete i[n.id]}if(!(0,$.Z)(a)&&!(0,$.Z)(a[n.id])){var s=a[n.id];delete s[t],0===Object.keys(s).length&&delete a[n.id]}}},o._priv_onReloadingMediaSource=function(){null!==this._priv_contentInfos&&(this._priv_contentInfos.segmentBuffersStore=null),null!==this._priv_trackChoiceManager&&this._priv_trackChoiceManager.resetPeriods()},o._priv_onAdaptationChange=function(e){var t=e.type,n=e.adaptation,r=e.period;if(null!==this._priv_contentInfos){null===this._priv_contentInfos.activeAdaptations&&(this._priv_contentInfos.activeAdaptations={});var i,a=this._priv_contentInfos,o=a.activeAdaptations,s=a.currentPeriod,u=o[r.id];if((0,$.Z)(u))o[r.id]=((i={})[t]=n,i);else u[t]=n;if(null!==this._priv_trackChoiceManager&&null!==s&&!(0,$.Z)(r)&&r.id===s.id)switch(t){case"audio":var l=this._priv_trackChoiceManager.getChosenAudioTrack(s);this.trigger("audioTrackChange",l);var d=this.getAvailableAudioBitrates();this._priv_triggerAvailableBitratesChangeEvent("availableAudioBitratesChange",d);break;case"text":var c=this._priv_trackChoiceManager.getChosenTextTrack(s);this.trigger("textTrackChange",c);break;case"video":var f=this._priv_trackChoiceManager.getChosenVideoTrack(s);this.trigger("videoTrackChange",f);var p=this.getAvailableVideoBitrates();this._priv_triggerAvailableBitratesChangeEvent("availableVideoBitratesChange",p)}}else O.Z.error("API: The adaptations changed but no content is loaded")},o._priv_onRepresentationChange=function(e){var t,n=e.type,r=e.period,i=e.representation;if(null!==this._priv_contentInfos){null===this._priv_contentInfos.activeRepresentations&&(this._priv_contentInfos.activeRepresentations={});var a,o=this._priv_contentInfos,s=o.activeRepresentations,u=o.currentPeriod,l=s[r.id];if((0,$.Z)(l))s[r.id]=((a={})[n]=i,a);else l[n]=i;var d=null!==(t=null==i?void 0:i.bitrate)&&void 0!==t?t:-1;(0,$.Z)(r)||null===u||u.id!==r.id||("video"===n?this._priv_triggerCurrentBitrateChangeEvent("videoBitrateChange",d):"audio"===n&&this._priv_triggerCurrentBitrateChangeEvent("audioBitrateChange",d))}else O.Z.error("API: The representations changed but no content is loaded")},o._priv_onBitrateEstimationChange=function(e){var t=e.type,n=e.bitrate;void 0!==n&&(this._priv_bitrateInfos.lastBitrates[t]=n),this.trigger("bitrateEstimationChange",{type:t,bitrate:n})},o._priv_onPlayPauseNext=function(e){if(null===this.videoElement)throw new Error("Disposed player");this._priv_playing$.next(e)},o._priv_onNativeTextTracksNext=function(e){this.trigger("nativeTextTracksChange",e)},o._priv_setPlayerState=function(e){this.state!==e&&(this.state=e,O.Z.info("API: playerStateChange event",e),this.trigger("playerStateChange",e))},o._priv_triggerPositionUpdate=function(e){var t;if(null!==this._priv_contentInfos){if(this.state!==Hr){var n=this._priv_contentInfos,r=n.isDirectFile,i=n.manifest;if((r||null!==i)&&!(0,$.Z)(e)){this._priv_lastContentPlaybackInfos.lastPlaybackPosition=e.position;var a=null!==i?i.getMaximumPosition():void 0,o={position:e.position,duration:e.duration,playbackRate:e.playbackRate,maximumBufferTime:a,bufferGap:isFinite(e.bufferGap)?e.bufferGap:0};if(null!==i&&void 0!==a&&i.isLive&&e.position>0){var s=null!==(t=i.availabilityStartTime)&&void 0!==t?t:0;o.wallClockTime=e.position+s,o.liveGap=a-e.position}this.trigger("positionUpdate",o)}}}else O.Z.warn("API: Cannot perform time update: no content loaded.")},o._priv_triggerAvailableBitratesChangeEvent=function(e,t){var n=this._priv_contentEventsMemory[e];(void 0===n||(0,G.Z)(t,n))&&(this._priv_contentEventsMemory[e]=t,this.trigger(e,t))},o._priv_triggerCurrentBitrateChangeEvent=function(e,t){t!==this._priv_contentEventsMemory[e]&&(this._priv_contentEventsMemory[e]=t,this.trigger(e,t))},o._priv_getCurrentRepresentations=function(){if(null===this._priv_contentInfos)return null;var e=this._priv_contentInfos,t=e.currentPeriod,n=e.activeRepresentations;return null===t||null===n||(0,$.Z)(n[t.id])?null:n[t.id]},(0,e.Z)(r,null,[{key:"ErrorTypes",get:function(){return K.ZB}},{key:"ErrorCodes",get:function(){return K.SM}},{key:"LogLevel",get:function(){return O.Z.getLevel()},set:function(e){O.Z.setLevel(e)}}]),r}(H.Z);Di.version="3.24.0";const Li=Di;var Bi=n(7273);!function(){Bi.Z.emeManager=n(1603).ZP,Bi.Z.imageBuffer=n(7127).Z,Bi.Z.imageParser=n(3203).Z,Bi.Z.transports.smooth=n(2339).Z,Bi.Z.transports.dash=n(1923).Z,Bi.Z.nativeTextTracksBuffer=n(9059).Z,Bi.Z.nativeTextTracksParsers.vtt=n(9405).Z,Bi.Z.nativeTextTracksParsers.ttml=n(1570).Z,Bi.Z.nativeTextTracksParsers.sami=n(1812).Z,Bi.Z.nativeTextTracksParsers.srt=n(8057).Z,Bi.Z.htmlTextTracksBuffer=n(5192).Z,Bi.Z.htmlTextTracksParsers.sami=n(5734).Z,Bi.Z.htmlTextTracksParsers.ttml=n(7439).Z,Bi.Z.htmlTextTracksParsers.srt=n(8675).Z,Bi.Z.htmlTextTracksParsers.vtt=n(4099).Z;var e=n(8969).Z,t=n(7794).Z;Bi.Z.directfile={initDirectFile:e,mediaElementTrackChoiceManager:t}}();const Ui=Li})(),r=r.default})()})); \ No newline at end of file +!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(()=>{var e={3349:(e,t,n)=>{"use strict";function r(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}n.d(t,{Z:()=>r})},5991:(e,t,n)=>{"use strict";function r(e,t){for(var n=0;ni})},1788:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(4665);function i(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,(0,r.Z)(e,t)}},4665:(e,t,n)=>{"use strict";function r(e,t){return(r=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}n.d(t,{Z:()=>r})},3786:(e,t,n)=>{"use strict";function r(e){return(r=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}n.d(t,{Z:()=>s});var i=n(4665);function a(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function o(e,t,n){return(o=a()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var a=new(Function.bind.apply(e,r));return n&&(0,i.Z)(a,n.prototype),a}).apply(null,arguments)}function s(e){var t="function"==typeof Map?new Map:void 0;return(s=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,a)}function a(){return o(e,arguments,r(this).constructor)}return a.prototype=Object.create(e.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),(0,i.Z)(a,e)})(e)}},7757:(e,t,n)=>{e.exports=n(5666)},3774:(e,t,n)=>{"use strict";n.d(t,{DQ:()=>a,JJ:()=>s,cX:()=>u,w:()=>o});var r=n(1946),i=n(2203).Z?{}:window,a=i.HTMLElement,o=(0,r.Z)(i.VTTCue)?i.TextTrackCue:i.VTTCue,s=(0,r.Z)(i.MediaSource)?(0,r.Z)(i.MozMediaSource)?(0,r.Z)(i.WebKitMediaSource)?i.MSMediaSource:i.WebKitMediaSource:i.MozMediaSource:i.MediaSource,u={HAVE_NOTHING:0,HAVE_METADATA:1,HAVE_CURRENT_DATA:2,HAVE_FUTURE_DATA:3,HAVE_ENOUGH_DATA:4}},3666:(e,t,n)=>{"use strict";n.d(t,{kD:()=>s,fq:()=>a,YM:()=>o,vU:()=>u,G6:()=>c,SB:()=>f,op:()=>l,yS:()=>d});var r,i=n(2203),a=!i.Z&&!!window.MSInputMethodContext&&!!document.documentMode,o=!i.Z&&("Microsoft Internet Explorer"===navigator.appName||"Netscape"===navigator.appName&&/(Trident|Edge)\//.test(navigator.userAgent)),s=!i.Z&&-1!==navigator.userAgent.toLowerCase().indexOf("edg/"),u=!i.Z&&-1!==navigator.userAgent.toLowerCase().indexOf("firefox"),l=!i.Z&&/SamsungBrowser/.test(navigator.userAgent),d=!i.Z&&/Tizen/.test(navigator.userAgent),c=!i.Z&&(Object.prototype.toString.call(window.HTMLElement).indexOf("Constructor")>=0||"[object SafariRemoteNotification]"===(null===(r=window.safari)||void 0===r?void 0:r.pushNotification.toString())),f=!i.Z&&"string"==typeof navigator.platform&&/iPad|iPhone|iPod/.test(navigator.platform)},5767:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3887),i=n(3666);function a(e){if(i.vU){for(var t=e.textTracks,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:(e,t,n)=>{"use strict";n.d(t,{N:()=>D,Y:()=>H});var r,i=n(4944),a=n(8170),o=n(1410),s=n(3714),u=n(8117),l=n(3666),d=n(2203),c=n(5059),f=n(5991),p=n(9589),h=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 p.Z((function(t){return t(e._mediaKeys)}))},t.getConfiguration=function(){return this._configuration},(0,f.Z)(e,[{key:"keySystem",get:function(){return this._keyType}}]),e}(),v=n(1788),m=n(211),g=n(4370),y=n(1558),_=n(1959),b=n(1473);if(!d.Z){var T=window.MSMediaKeys;void 0!==T&&void 0!==T.prototype&&"function"==typeof T.isTypeSupported&&"function"==typeof T.prototype.createSession&&(r=T)}var E,w=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 m.xQ,n.closed=new p.Z((function(e){n._closeSession$.subscribe(e)})),n.update=function(e){return new p.Z((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 p.Z((function(e){n._ss=n._mk.createSession("video/mp4",t),(0,g.T)(b.GJ(n._ss),b.GV(n._ss),b.Xe(n._ss)).pipe((0,y.R)(n._closeSession$)).subscribe((function(e){return n.trigger(e.type,e)})),e()}))},n.close=function(){var e=this;return new p.Z((function(t){null!=e._ss&&(e._ss.close(),e._ss=void 0),e._closeSession$.next(),e._closeSession$.complete(),t()}))},n.load=function(){return p.Z.resolve(!1)},n.remove=function(){return p.Z.resolve()},(0,f.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}(_.Z),S=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 w(this._mediaKeys)},t.setServerCertificate=function(){throw new Error("Server certificate is not implemented in your browser")},e}();if(!d.Z){var k=window.MozMediaKeys;void 0!==k&&void 0!==k.prototype&&"function"==typeof k.isTypeSupported&&"function"==typeof k.prototype.createSession&&(E=k)}var A=n(9689),x=n(3635);function I(e){return"function"==typeof e.webkitGenerateKeyRequest}var Z=function(e){function t(t,n){var r;return(r=e.call(this)||this)._closeSession$=new m.xQ,r._vid=t,r._key=n,r.sessionId="",r.closed=new p.Z((function(e){r._closeSession$.subscribe(e)})),r.keyStatuses=new Map,r.expiration=NaN,(0,g.T)(b.GJ(t),b.GV(t),b.Xe(t)).pipe((0,y.R)(r._closeSession$)).subscribe((function(e){return r.trigger(e.type,e)})),r.update=function(e){return new p.Z((function(t,n){try{if(r._key.indexOf("clearkey")>=0){var i=e instanceof ArrayBuffer?new Uint8Array(e):e,a=JSON.parse((0,x.uR)(i)),o=(0,A.K)(a.keys[0].k),s=(0,A.K)(a.keys[0].kid);t(r._vid.webkitAddKey(r._key,o,s,""))}else t(r._vid.webkitAddKey(r._key,e,null,""))}catch(e){n(e)}}))},r}(0,v.Z)(t,e);var n=t.prototype;return n.generateRequest=function(e,t){var n=this;return new p.Z((function(e){n._vid.webkitGenerateKeyRequest(n._key,t),e()}))},n.close=function(){var e=this;return new p.Z((function(t){e._closeSession$.next(),e._closeSession$.complete(),t()}))},n.load=function(){return p.Z.resolve(!1)},n.remove=function(){return p.Z.resolve()},t}(_.Z),R=function(){function e(e){this._keySystem=e}var t=e.prototype;return t._setVideo=function(e){if(!I(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 Z(this._videoElement,this._keySystem)},t.setServerCertificate=function(){throw new Error("Server certificate is not implemented in your browser")},e}();var M=n(6968);var C=n(158);function N(e,t){if(void 0===e.webkitSetMediaKeys)throw new Error("No webKitMediaKeys API.");return e.webkitSetMediaKeys(t)}var P=function(e){function t(t,n,r){var i;return(i=e.call(this)||this)._serverCertificate=r,i._closeSession$=new m.xQ,i._videoElement=t,i._keyType=n,i.closed=new p.Z((function(e){i._closeSession$.subscribe(e)})),i.keyStatuses=new Map,i.expiration=NaN,i.update=function(e){return new p.Z((function(t,n){if(void 0===i._nativeSession||void 0===i._nativeSession.update||"function"!=typeof i._nativeSession.update)return n("Unavailable WebKit key session.");try{t(i._nativeSession.update(e))}catch(e){n(e)}}))},i}(0,v.Z)(t,e);var n=t.prototype;return n.listenEvent=function(e){var t=this;(0,g.T)(b.GJ(e),b.GV(e),b.Xe(e)).pipe((0,y.R)(this._closeSession$)).subscribe((function(e){t.trigger(e.type,e)}))},n.generateRequest=function(e,t){var n=this;return new p.Z((function(e){if(void 0===n._videoElement.webkitKeys||void 0===n._videoElement.webkitKeys.createSession)throw new Error("No WebKitMediaKeys API.");var r,i;if("com.apple.fps.1_0"===(i=n._keyType)||"com.apple.fps.2_0"===i){if(void 0===n._serverCertificate)throw new Error("A server certificate is needed for creating fairplay session.");r=function(e,t){var n=e instanceof Uint8Array?e:new Uint8Array(e),r=t instanceof Uint8Array?t:new Uint8Array(t);if((0,M.dN)(n,0)+4!==n.length)throw new Error("Unsupported WebKit initData.");var i=(0,x.wV)(n),a=i.indexOf("skd://"),o=a>-1?i.substring(a+6):i,s=(0,x.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,M.O_)(s.byteLength),u),u+=4,l.set(s,u),u+=s.byteLength,l.set((0,M.O_)(r.byteLength),u),u+=4,l.set(r,u),l}(t,n._serverCertificate)}else r=t;var a=n._videoElement.webkitKeys.createSession("video/mp4",r);if(null==a)throw new Error("Impossible to get the key sessions");n.listenEvent(a),n._nativeSession=a,e()}))},n.close=function(){var e=this;return new p.Z((function(t,n){e._closeSession$.next(),e._closeSession$.complete(),void 0===e._nativeSession&&n("No session to close."),e._nativeSession.close(),t()}))},n.load=function(){return p.Z.resolve(!1)},n.remove=function(){return p.Z.resolve()},(0,f.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}(_.Z),O=function(){function e(e){if(void 0===C.t)throw new Error("No WebKitMediaKeys API.");this._keyType=e,this._mediaKeys=new C.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 N(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 P(this._videoElement,this._keyType,this._serverCertificate)},t.setServerCertificate=function(e){return this._serverCertificate=e,p.Z.resolve()},e}();var D=null,L=function(e,t){return"function"==typeof e.setMediaKeys?e.setMediaKeys(t):e.webkitSetMediaKeys?e.webkitSetMediaKeys(t):e.mozSetMediaKeys?e.mozSetMediaKeys(t):e.msSetMediaKeys&&null!==t?e.msSetMediaKeys(t):void 0};if(d.Z||null!=navigator.requestMediaKeySystemAccess&&!(0,c.Z)())D=function(e,t){return(0,u.Z)(navigator.requestMediaKeySystemAccess(e,t))};else{var B,U;if(I(HTMLVideoElement.prototype)){var F={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 R(e)},setMediaKeys:function(e,t){if(null!==t){if(!(t instanceof R))throw new Error("Custom setMediaKeys is supposed to be called with old webkit custom MediaKeys.");return t._setVideo(e)}}};B=F.isTypeSupported,U=F.createCustomMediaKeys,L=F.setMediaKeys}else if(void 0!==C.t){var z=function(){if(void 0===C.t)throw new Error("No WebKitMediaKeys API.");return{isTypeSupported:C.t.isTypeSupported,createCustomMediaKeys:function(e){return new O(e)},setMediaKeys:function(e,t){if(null===t)return N(e,t);if(!(t instanceof O))throw new Error("Custom setMediaKeys is supposed to be called with webkit custom MediaKeys.");return t._setVideo(e)}}}();B=z.isTypeSupported,U=z.createCustomMediaKeys,L=z.setMediaKeys}else if(l.fq&&void 0!==r){var K={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 S(e)},setMediaKeys:function(e,t){if(null!==t){if(!(t instanceof S))throw new Error("Custom setMediaKeys is supposed to be called with IE11 custom MediaKeys.");return t._setVideo(e)}}};B=K.isTypeSupported,U=K.createCustomMediaKeys,L=K.setMediaKeys}else if(void 0!==E){var V={isTypeSupported:function(e,t){if(void 0===E)throw new Error("No MozMediaKeys API.");return void 0!==t?E.isTypeSupported(e,t):E.isTypeSupported(e)},createCustomMediaKeys:function(e){if(void 0===E)throw new Error("No MozMediaKeys API.");return new E(e)},setMediaKeys:function(e,t){if(void 0===e.mozSetMediaKeys||"function"!=typeof e.mozSetMediaKeys)throw new Error("Can't set video on MozMediaKeys.");return e.mozSetMediaKeys(t)}};B=V.isTypeSupported,U=V.createCustomMediaKeys,L=V.setMediaKeys}else{var W=window.MediaKeys,G=function(){if(void 0===W)throw new s.Z("MEDIA_KEYS_NOT_SUPPORTED","No `MediaKeys` implementation found in the current browser.");if(void 0===W.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.")}};B=function(e){return G(),W.isTypeSupported(e)},U=function(e){return G(),new W(e)}}D=function(e,t){if(!B(e))return(0,i._)(void 0);for(var n=0;n{"use strict";var r;if(n.d(t,{t:()=>r}),!n(2203).Z){var i=window.WebKitMediaKeys;void 0!==i&&"function"==typeof i.isTypeSupported&&"function"==typeof i.prototype.createSession&&"function"==typeof HTMLMediaElement.prototype.webkitSetMediaKeys&&(r=i)}},1473:(e,t,n)=>{"use strict";n.d(t,{zh:()=>V,_K:()=>H,Oh:()=>ie,C1:()=>X,Q1:()=>Q,GV:()=>oe,Xe:()=>se,GJ:()=>ae,eX:()=>ue,K4:()=>j,yj:()=>G,Qt:()=>J,gg:()=>re,ik:()=>q,d5:()=>Y,ym:()=>te,UA:()=>ee,_E:()=>ne,$x:()=>$});var r=n(4379),i=n(3306),a=new r.y(i.Z);var o=n(7027),s=n(4370),u=n(1410),l=n(8170),d=n(5142),c=n(6564),f=n(655),p=n(964),h=n(9914),v=n(979),m=n(2632);function g(e,t){void 0===t&&(t=p.P);var n=(0,h.J)(e)?+e-t.now():Math.abs(e);return function(e){return e.lift(new y(n,t))}}var y=function(){function e(e,t){this.delay=e,this.scheduler=t}return e.prototype.call=function(e,t){return t.subscribe(new _(e,this.delay,this.scheduler))},e}(),_=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.delay=n,i.scheduler=r,i.queue=[],i.active=!1,i.errored=!1,i}return f.ZT(t,e),t.dispatch=function(e){for(var t=e.source,n=t.queue,r=e.scheduler,i=e.destination;n.length>0&&n[0].time-r.now()<=0;)n.shift().notification.observe(i);if(n.length>0){var a=Math.max(0,n[0].time-r.now());this.schedule(e,a)}else this.unsubscribe(),t.active=!1},t.prototype._schedule=function(e){this.active=!0,this.destination.add(e.schedule(t.dispatch,this.delay,{source:this,destination:this.destination,scheduler:e}))},t.prototype.scheduleNotification=function(e){if(!0!==this.errored){var t=this.scheduler,n=new b(t.now()+this.delay,e);this.queue.push(n),!1===this.active&&this._schedule(t)}},t.prototype._next=function(e){this.scheduleNotification(m.P.createNext(e))},t.prototype._error=function(e){this.errored=!0,this.queue=[],this.destination.error(e),this.unsubscribe()},t.prototype._complete=function(){this.scheduleNotification(m.P.createComplete()),this.unsubscribe()},t}(v.L),b=function(){return function(e,t){this.time=e,this.notification=t}}(),T=n(7604),E={leading:!0,trailing:!1};T.Ds;function w(e,t,n){return void 0===t&&(t=p.P),void 0===n&&(n=E),function(r){return r.lift(new S(e,t,n.leading,n.trailing))}}var S=function(){function e(e,t,n,r){this.duration=e,this.scheduler=t,this.leading=n,this.trailing=r}return e.prototype.call=function(e,t){return t.subscribe(new k(e,this.duration,this.scheduler,this.leading,this.trailing))},e}(),k=function(e){function t(t,n,r,i,a){var o=e.call(this,t)||this;return o.duration=n,o.scheduler=r,o.leading=i,o.trailing=a,o._hasTrailingValue=!1,o._trailingValue=null,o}return f.ZT(t,e),t.prototype._next=function(e){this.throttled?this.trailing&&(this._trailingValue=e,this._hasTrailingValue=!0):(this.add(this.throttled=this.scheduler.schedule(A,this.duration,{subscriber:this})),this.leading?this.destination.next(e):this.trailing&&(this._trailingValue=e,this._hasTrailingValue=!0))},t.prototype._complete=function(){this._hasTrailingValue?(this.destination.next(this._trailingValue),this.destination.complete()):this.destination.complete()},t.prototype.clearThrottle=function(){var e=this.throttled;e&&(this.trailing&&this._hasTrailingValue&&(this.destination.next(this._trailingValue),this._trailingValue=null,this._hasTrailingValue=!1),e.unsubscribe(),this.remove(e),this.throttled=null)},t}(v.L);function A(e){e.subscriber.clearThrottle()}var x=n(5709),I=n(3485),Z=n(1931),R=n(6381),M=n(5602),C=n(944),N=n(6923),P=n(3774),O=n(2203),D=n(5059),L=["","webkit","moz","ms"],B=C.Z.INACTIVITY_DELAY,U=O.Z||null==window.devicePixelRatio||0===window.devicePixelRatio?1:window.devicePixelRatio;function F(e,t){return t.filter((function(t){return function(e,t){var n=document.createElement(e.tagName),r="on"+t;return r in n||(n.setAttribute(r,"return;"),"function"==typeof n[r])}(e,t)}))[0]}function z(e,t){var n,r=function(e,t){return e.reduce((function(e,n){return e.concat((null==t?L:t).map((function(e){return e+n})))}),[])}(e,t);return function(e){return e instanceof P.DQ?(void 0===n&&(n=F(e,r)),(0,N.Z)(n)?(0,o.R)(e,n):a):s.T.apply(void 0,r.map((function(t){return(0,o.R)(e,t)})))}}function K(){var e,t=document;null!=t.hidden?e="":null!=t.mozHidden?e="moz":null!=t.msHidden?e="ms":null!=t.webkitHidden&&(e="webkit");var n=(0,N.Z)(e)?e+"Hidden":"hidden",r=(0,N.Z)(e)?e+"visibilitychange":"visibilitychange";return(0,u.P)((function(){var e=document[n];return(0,o.R)(document,r).pipe((0,x.U)((function(){return!document[n]})),(0,I.O)(!e),(0,Z.x)())}))}function V(){return K().pipe((0,R.w)((function(e){return e?(0,l.of)(e):(0,l.of)(e).pipe(g(B))})))}function W(e,t){var n=t.width,r=t.height/(e.clientHeight/e.clientWidth);return Math.min(n,r)}function G(e){return(0,u.P)((function(){if(e.webkitSupportsPresentationMode&&"function"==typeof e.webkitSetPresentationMode){var t="picture-in-picture"===e.webkitPresentationMode;return(0,o.R)(e,"webkitpresentationmodechanged").pipe((0,x.U)((function(){return{isEnabled:"picture-in-picture"===e.webkitPresentationMode,pipWindow:null}})),(0,I.O)({isEnabled:t,pipWindow:null}))}var n={isEnabled:document.pictureInPictureElement&&document.pictureInPictureElement===e,pipWindow:null};return(0,s.T)((0,o.R)(e,"enterpictureinpicture").pipe((0,x.U)((function(e){return{isEnabled:!0,pipWindow:e.pictureInPictureWindow}}))),(0,o.R)(e,"leavepictureinpicture").pipe((0,M.h)({isEnabled:!1,pipWindow:null}))).pipe((0,I.O)(n))}))}function H(e){return(0,d.aj)([K(),e]).pipe((0,R.w)((function(e){var t=e[0];return e[1].isEnabled||t?(0,l.of)(!0):(0,l.of)(!1).pipe(g(B))})),(0,Z.x)())}function $(e,t){return(0,d.aj)([t,(0,c.F)(2e4).pipe((0,I.O)(null)),(0,o.R)(window,"resize").pipe(w(500),(0,I.O)(null))]).pipe((0,R.w)((function(t){var n=t[0];if(n.isEnabled){if(null!=n.pipWindow){var r=n.pipWindow,i=W(e,r);return(0,o.R)(r,"resize").pipe((0,I.O)(i*U),(0,x.U)((function(){return W(e,r)*U})))}return(0,l.of)(1/0)}return(0,l.of)(e.clientWidth*U)})),(0,Z.x)())}var j=z(["loadedmetadata"]),Y=z(["seeking"]),q=z(["seeked"]),X=z(["ended"]),Q=(z(["timeupdate"]),z(["fullscreenchange","FullscreenChange"],L.concat("MS"))),J=function(e){return(0,s.T)(z(["play"])(e),z(["pause"])(e))},ee=function(e){return(0,s.T)(z(["addtrack"])(e),z(["removetrack"])(e))},te=z(["sourceopen","webkitsourceopen"]),ne=z(["update"]),re=z(["onremovesourcebuffer"]),ie=z((0,D.Z)()?["needkey"]:["encrypted","needkey"]),ae=z(["keymessage","message"]),oe=z(["keyadded","ready"]),se=z(["keyerror","error"]),ue=z(["keystatuseschange"])},2203:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r="undefined"==typeof window},1988:(e,t,n)=>{"use strict";function r(e){return"function"==typeof window.VTTCue&&e instanceof window.VTTCue}n.d(t,{Z:()=>r})},7253:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3887),i=n(3774);function a(e,t,n){if(null==i.w)throw new Error("VTT cues not supported in your target");return e>=t?(r.Z.warn("Compat: Invalid cue times: "+e+" - "+t),null):new i.w(e,t,n)}},5059:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3666),i=n(158);function a(){return r.G6&&void 0!==i.t}},944:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const 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,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},BUFFER_DISCONTINUITY_THRESHOLD:.2,FORCE_DISCONTINUITY_SEEK_DELAY:2e3,BITRATE_REBUFFERING_RATIO:1.5,BUFFER_GC_GAPS:{CALM:240,BEEFY:30},DEFAULT_MAX_MANIFEST_REQUEST_RETRY:4,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},STALL_GAP:{DEFAULT:.5,LOW_LATENCY:.2},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_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS:50,EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION:1e3,EME_SESSION_CLOSING_MAX_RETRY:5,EME_SESSION_CLOSING_INITIAL_DELAY:100,EME_SESSION_CLOSING_MAX_DELAY:1e3,EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES:100,FORCED_ENDED_THRESHOLD:.001,ADAPTATION_SWITCH_BUFFER_PADDINGS:{video:{before:2,after:2.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}},7794:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(1788),i=n(1959),a=n(7829);function o(e,t){var n;if(t.length!==e.length)return!0;for(var r=0;r{"use strict";n.d(t,{ZP:()=>Qe});var r=n(8170),i=n(9795),a=n(4370),o=n(4944),s=n(2135),u=n(5631),l=n(7746),d=n(7006),c=n(6008),f=n(1015),p=n(3068),h=n(5709),v=n(486),m=n(6738),g=n(1473),y=n(3887),_=n(6490),b=n(4791),T=n(6968),E=n(3635),w=(0,T.pX)((0,E.tG)("pssh"),0);function S(e,t){for(var n=0;ne.length)return y.Z.warn("Compat: Unrecognized initialization data. Use as is."),[{systemId:void 0,data:e}];var i=e.subarray(n,n+r),a={systemId:(0,_.Y)(i,8),data:i};S(t,a)?y.Z.warn("Compat: Duplicated PSSH found in initialization data, removing it."):t.push(a),n+=r}return n!==e.length?(y.Z.warn("Compat: Unrecognized initialization data. Use as is."),[{systemId:void 0,data:e}]):t}(new Uint8Array(t))}}var A=n(1410),x=n(2297),I=n(8117);function Z(e,t,n){return(0,A.P)((function(){var r;y.Z.debug("Compat: Calling generateRequest on the MediaKeySession");try{r=function(e){y.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 y.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,x.Xj)(o),u=null===s?void 0:o[s[1]];y.Z.info("Compat: CENC PSSH found with version",u),void 0===u?y.Z.warn("Compat: could not read version of CENC PSSH"):t===(1===u)?n=(0,T.zo)(n,o):1===u?(y.Z.warn("Compat: cenc version 1 encountered, removing every other cenc pssh box."),n=o,t=!0):y.Z.warn("Compat: filtering out cenc pssh box with wrong version",u)}else r=(0,T.zo)(r,o);i+=a}if(i!==e.length)throw y.Z.warn("Compat: unrecognized initialization data. Cannot patch it."),new Error("Compat: unrecognized initialization data. Cannot patch it.");return(0,T.zo)(r,n)}(n)}catch(e){r=n}var i=null!=t?t:"";return(0,I.Z)(e.generateRequest(i,r)).pipe((0,v.K)((function(t){if(""!==i||!(t instanceof TypeError))throw t;return y.Z.warn('Compat: error while calling `generateRequest` with an empty initialization data type. Retrying with a default "cenc" value.',t),(0,I.Z)(e.generateRequest("cenc",r))})))}))}var R=n(944),M=n(5157),C=n(7714),N=n(8418),P=n(2793),O=n(1946);var D=n(5602),L=n(3485);var B=n(8821),U=n(9604),F=n(5561);function z(e){if(""===e.sessionId)return!1;var t=e.keyStatuses,n=[];return t.forEach((function(e){n.push(e)})),n.length<=0?(y.Z.debug("EME: isSessionUsable: MediaKeySession given has an empty keyStatuses",e),!1):(0,C.Z)(n,"expired")?(y.Z.debug("EME: isSessionUsable: MediaKeySession given has an expired key",e.sessionId),!1):(0,C.Z)(n,"internal-error")?(y.Z.debug("EME: isSessionUsable: MediaKeySession given has a key with an internal-error",e.sessionId),!1):(y.Z.debug("EME: isSessionUsable: MediaKeySession is usable",e.sessionId),!0)}function K(e,t,n){return(0,A.P)((function(){var i=e.loadedSessionsStore,a=e.persistentSessionsStore;return"temporary"===n?V(i,t):null===a?(y.Z.warn("EME: Cannot create persistent MediaKeySession, PersistentSessionsStore not created."),V(i,t)):function(e,t,n){return(0,A.P)((function(){y.Z.info("EME: Creating persistent MediaKeySession");var i=e.createSession(n,"persistent-license"),a=t.getAndReuse(n);if(null===a)return(0,r.of)({type:"created-session",value:{mediaKeySession:i,sessionType:"persistent-license"}});var o=function(){return y.Z.info("EME: Removing previous persistent session."),null!==t.get(n)&&t.delete(n),e.closeSession(n).pipe((0,h.U)((function(){return{type:"created-session",value:{mediaKeySession:e.createSession(n,"persistent-license"),sessionType:"persistent-license"}}})))};return function(e,t){return(0,A.P)((function(){return y.Z.info("Compat/EME: Load persisted session",t),(0,F.Z)((function(){return(0,I.Z)(e.load(t))}),void 0)})).pipe((0,l.zg)((function(t){return!t||e.keyStatuses.size>0?(0,r.of)(t):(0,B.S3)((0,U.H)(100),(0,g.eX)(e)).pipe((0,f.q)(1),(0,D.h)(t))})))}(i,a.sessionId).pipe((0,l.zg)((function(e){return e?e&&z(i)?(t.add(n,i),y.Z.info("EME: Succeeded to load persistent session."),(0,r.of)({type:"loaded-persistent-session",value:{mediaKeySession:i,sessionType:"persistent-license"}})):(y.Z.warn("EME: Previous persistent session not usable anymore."),o()):(y.Z.warn("EME: No data stored for the loaded session"),t.delete(n),(0,r.of)({type:"created-session",value:{mediaKeySession:i,sessionType:"persistent-license"}}))})),(0,v.K)((function(e){return y.Z.warn("EME: Unable to load persistent session: "+(e instanceof Error?e.toString():"Unknown Error")),o()})))}))}(i,a,t)}))}function V(e,t){return(0,A.P)((function(){y.Z.info("EME: Creating a new temporary session");var n=e.createSession(t,"temporary");return(0,r.of)({type:"created-session",value:{mediaKeySession:n,sessionType:"temporary"}})}))}var W=R.Z.EME_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS;function G(e,t,n){return(0,A.P)((function(){var o=null,s=t.loadedSessionsStore,d=t.persistentSessionsStore,c=s.getAndReuse(e);if(null!==c){if(z(o=c.mediaKeySession))return y.Z.info("EME: Reuse loaded session",o.sessionId),(0,r.of)({type:"loaded-open-session",value:{mediaKeySession:o,sessionType:c.sessionType,initializationData:e}});null!==d&&d.delete(e)}return(null!=o?s.closeSession(e):(0,r.of)(null)).pipe((0,l.zg)((function(){return(0,i.z)(function(e,t){if(t<0||t>=e.getLength())return u.E;for(var n=[],r=e.getAll().slice(),i=r.length-t,o=0;o=a.length){var n=new M.Z("INCOMPATIBLE_KEYSYSTEMS","No key system compatible with your wanted configuration has been found in the current browser.");return(0,o._)(n)}if(null==H.N){var r=Error("requestMediaKeySystemAccess is not implemented in your browser.");return(0,o._)(r)}var i=a[t],s=i.keyName,u=i.keyType,l=i.keySystemOptions,d=function(e,t){var n=["temporary"],r="optional",i="optional";!0===t.persistentLicense&&(r="required",n.push("persistent-license")),!0===t.persistentStateRequired&&(r="required"),!0===t.distinctiveIdentifierRequired&&(i="required");var a=null!=t.videoRobustnesses?t.videoRobustnesses:"widevine"===e?X:[],o=null!=t.audioRobustnesses?t.audioRobustnesses:"widevine"===e?X:[];return 0===a.length&&a.push(void 0),0===o.length&&o.push(void 0),[{initDataTypes:["cenc"],videoCapabilities:(0,q.Z)(a,(function(e){return[{contentType:'video/mp4;codecs="avc1.4d401e"',robustness:e},{contentType:'video/mp4;codecs="avc1.42e01e"',robustness:e},{contentType:'video/webm;codecs="vp8"',robustness:e}]})),audioCapabilities:(0,q.Z)(o,(function(e){return[{contentType:'audio/mp4;codecs="mp4a.40.2"',robustness:e},{contentType:"audio/webm;codecs=opus",robustness:e}]})),distinctiveIdentifier:i,persistentState:r,sessionTypes:n}]}(s,l);return y.Z.debug("EME: Request keysystem access "+u+","+(t+1)+" of "+a.length,d),(0,H.N)(u,d).pipe((0,h.U)((function(e){return y.Z.info("EME: Found compatible keysystem",u,d),{type:"create-media-key-system-access",value:{options:l,mediaKeySystemAccess:e}}})),(0,v.K)((function(){return y.Z.debug("EME: Rejected access to keysystem",u,d),e(t+1)})))}(0)}))}var te=n(2870),ne=new WeakMap;const re=function(e){ne.set(e,null)},ie=function(e,t){var n=t instanceof Uint8Array?t:new Uint8Array(t instanceof ArrayBuffer?t:t.buffer),r=(0,te.Z)(n);ne.set(e,{hash:r,serverCertificate:n})},ae=function(e){var t=ne.get(e);return void 0!==t&&(null!==t||void 0)},oe=function(e,t){var n=ne.get(e);if(null==n)return!1;var r=n.hash,i=n.serverCertificate,a=t instanceof Uint8Array?t:new Uint8Array(t instanceof ArrayBuffer?t:t.buffer);if((0,te.Z)(a)!==r||i.length!==a.length)return!1;for(var o=0;ose)return t(r);var o=Math.min(Math.pow(2,i)*ue,le);return y.Z.warn("EME: attempt to close a mediaKeySession failed, scheduling retry...",o),(0,B.S3)([(0,U.H)(o),(0,g.eX)(e),(0,g.GJ)(e)]).pipe((0,f.q)(1),(0,l.zg)((function(){return n(a)})))})))}(0);function t(e){return y.Z.error("EME: Could not close MediaKeySession: "+(e instanceof Error?e.toString():"Unknown error")),(0,r.of)(null)}}var ce=n(9689),fe=function(){function e(e){this.initData=e}return e.prototype.toJSON=function(){return(0,ce.J)(this.initData)},e.decode=function(e){return(0,ce.K)(e)},e}();function pe(e,t){var n,r;return null!==(r=null!==(n=he(e,t))&&void 0!==n?n:he(t,e))&&void 0!==r&&r}function he(e,t){if(0===e.length)return!1;if(t.length=0?this._storage[t].payload:void 0},t.getAndReuse=function(e){var t=this._findIndex(e);if(-1!==t){var n=this._storage.splice(t,1)[0];return this._storage.push(n),n.payload}},t.store=function(e,t){var n=this._findIndex(e);n>=0&&this._storage.splice(n,1);var r=this._formatValuesForStore(e.values);this._storage.push({type:e.type,values:r,payload:t})},t.storeIfNone=function(e,t){if(this._findIndex(e)>=0)return!1;var n=this._formatValuesForStore(e.values);return this._storage.push({type:e.type,values:n,payload:t}),!0},t.remove=function(e){var t=this._findIndex(e);if(-1!==t)return this._storage.splice(t,1)[0].payload},t._findIndex=function(e){for(var t=this._formatValuesForStore(e.values),n=this._storage.length-1;n>=0;n--){var r=this._storage[n];if(r.type===e.type&&pe(r.values,t))return n}return-1},t._formatValuesForStore=function(e){return e.slice().sort((function(e,t){return e.systemId===t.systemId?0:void 0===e.systemId?1:void 0===t.systemId||e.systemId=0?Oe(n):xe.y)})),T=function(e,t){return{totalRetry:null!=t?t:2,baseDelay:200,maxDelay:3e3,shouldRetry:function(e){return e instanceof Ie||(0,O.Z)(e)||!0!==e.noRetry},onRetry:function(t){return e.next({type:"warning",value:je(t)})}}}(d,f.retry);return(o=b,s=T,u=s.baseDelay,c=s.maxDelay,p=s.totalRetry,m=s.shouldRetry,g=s.onRetry,_=0,o.pipe((0,v.K)((function(e,t){if(!(0,O.Z)(m)&&!m(e)||_++>=p)throw e;"function"==typeof g&&g(e,_);var n=Math.min(u*Math.pow(2,_-1),c),r=(0,Le.Z)(n);return(0,U.H)(r).pipe((0,l.zg)((function(){return t})))})))).pipe((0,h.U)((function(t){return{type:"key-message-handled",value:{session:e,license:t}}})),(0,v.K)((function(e){var t=je(e);if(!(0,O.Z)(e)&&!0===e.fallbackOnLastTry)throw y.Z.warn("EME: Last `getLicense` attempt failed. Blacklisting the current session."),new Ge(t);throw t})),(0,L.O)({type:"session-message",value:{messageType:a,initializationData:i}}))}))),b=(0,a.T)(_,g).pipe((o=function(t){switch(t.type){case"key-message-handled":case"key-status-change-handled":return function(e,t,n){return(0,O.Z)(t)?(y.Z.info("EME: No message given, skipping session.update"),(0,r.of)({type:"no-update",value:{initializationData:n}})):(y.Z.info("EME: Updating MediaKeySession with message"),(0,I.Z)(e.update(t)).pipe((0,v.K)((function(e){var t=e instanceof Error?e.toString():"`session.update` failed";throw new M.Z("KEY_UPDATE_ERROR",t)})),(0,p.b)((function(){y.Z.info("EME: MediaKeySession update succeeded.")})),(0,D.h)({type:"session-updated",value:{session:e,license:t,initializationData:n}})))}(e,t.value.license,i);default:return(0,r.of)(t)}},(0,l.zg)(o,s,1))),T=(0,a.T)($e(e,t,n),b,m,d);return(0,O.Z)(e.closed)?T:T.pipe((0,De.R)((0,I.Z)(e.closed)))}function $e(e,t,n){return(0,A.P)((function(){if(0===e.keyStatuses.size)return u.E;var a=ze(e,t,n),o=a.warnings,s=a.blacklistedKeyIDs,l=a.whitelistedKeyIds,d=o.length>0?r.of.apply(void 0,o):u.E,c=(0,r.of)({type:"keys-update",value:{whitelistedKeyIds:l,blacklistedKeyIDs:s}});return(0,i.z)(d,c)}))}function je(e){if(e instanceof Ie)return new M.Z("KEY_LOAD_TIMEOUT","The license server took too much time to respond.");var t=new M.Z("KEY_LOAD_ERROR","An error occured when calling `getLicense`.");return!(0,O.Z)(e)&&(0,ye.Z)(e.message)&&(t.message=e.message),t}function Ye(e,t){return(0,A.P)((function(){return"function"!=typeof e.setServerCertificate?(y.Z.warn("EME: Could not set the server certificate. mediaKeys.setServerCertificate is not a function"),u.E):!0===ae(e)?(y.Z.info("EME: The MediaKeys already has a server certificate, skipping..."),u.E):(y.Z.info("EME: Setting server certificate on the MediaKeys"),re(e),function(e,t){return(0,A.P)((function(){return(0,F.Z)((function(){return(0,I.Z)(e.setServerCertificate(t))}),void 0).pipe((0,v.K)((function(e){y.Z.warn("EME: mediaKeys.setServerCertificate returned an error",e);var t=e instanceof Error?e.toString():"`setServerCertificate` error";throw new M.Z("LICENSE_SERVER_CERTIFICATE_ERROR",t)})))}))}(e,t).pipe((0,p.b)((function(){ie(e,t)})),(0,m.l)(),(0,v.K)((function(e){return(0,r.of)({type:"warning",value:e})}))))}))}var qe=R.Z.EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION,Xe=g.Oh;const Qe=function(e,t,n){y.Z.debug("EME: Starting EMEManager logic.");var g=new ve,_=new ve,E=Ee(e,t).pipe((0,l.zg)((function(e){if("attached-media-keys"!==e.type)return(0,r.of)(e);var t=e.value,n=t.mediaKeys,a=t.options.serverCertificate;return(0,O.Z)(a)?(0,r.of)(e):(0,i.z)(Ye(n,a),(0,r.of)(e))})),(0,d.d)()),w=E.pipe((0,c.h)((function(e){return"attached-media-keys"===e.type})),(0,f.q)(1)),S=Xe(e).pipe((0,p.b)((function(e){y.Z.debug("EME: Encrypted event received from media element.",e)})),(0,P.Z)((function(e){return k(e)}),null),(0,d.d)({refCount:!0})),A=n.pipe((0,p.b)((function(e){y.Z.debug("EME: Encrypted event received from Player",e)}))),x=(0,a.T)(A,S).pipe((0,l.zg)((function(e){return w.pipe((0,h.U)((function(t){return[e,t]})))})),(0,l.zg)((function(e){var t=e[0],n=e[1],i=n.value,d=i.mediaKeySystemAccess,c=i.stores,f=i.options,h=_.get(t);if(void 0!==h){if(void 0===t.type){y.Z.error("EME: The current session has already been blacklisted but the current content is not known. Throwing.");var E=h.sessionError;return E.fatal=!0,(0,o._)(E)}return y.Z.warn("EME: The current session has already been blacklisted. Blacklisting content."),(0,r.of)({type:"blacklist-protection-data",value:t})}var w,S=new s.t(1);if("content"===f.singleLicensePer&&!g.isEmpty()){var k=t.keyIds;if(void 0===k)return y.Z.warn("EME: Initialization data linked to unknown key id, we'll not able to fallback from it."),(0,r.of)({type:"init-data-ignored",value:{initializationData:t}});var A=g.getAll()[0];return A.lastKeyUpdate$.pipe((0,l.zg)((function(e){return k.every((function(t){for(var n=0;n=e.getLength())){var n=e.getLength(),r=n-t;y.Z.info("EME: Too many stored persistent sessions, removing some.",n,r),e.deleteOldSessions(r)}}(n,qe-1),n.add(t,i),s=!0}})),(0,v.K)((function(e){if(!(e instanceof Ge))throw e;_.store(t,e);var n=e.sessionError;if(void 0===t.type)throw y.Z.error("EME: Current session blacklisted and content not known. Throwing."),n.fatal=!0,n;return y.Z.warn("EME: Current session blacklisted. Blacklisting content."),(0,r.of)({type:"warning",value:n},{type:"blacklist-protection-data",value:t})})))})))):(y.Z.debug("EME: Init data already received. Skipping it."),(0,r.of)({type:"init-data-ignored",value:{initializationData:t}}))})));return(0,a.T)(E,S.pipe((0,h.U)((function(e){return{type:"encrypted-event-received",value:e}}))),x)}},6033:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=new WeakMap;const i={setState:function(e,t){r.set(e,t)},getState:function(e){var t=r.get(e);return void 0===t?null:t},clearState:function(e){r.set(e,null)}}},4507:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(4370),i=n(8170),a=n(5709),o=n(6139);var s=n(1473),u=n(5157),l=n(7874),d=n(3887),c=s.Oh;function f(e,t,n){var s=(0,r.T)(c(e),n);return null==l.Z.emeManager?(0,r.T)(s.pipe((0,a.U)((function(){throw d.Z.error("Init: Encrypted event but EME feature not activated"),new u.Z("MEDIA_IS_ENCRYPTED_ERROR","EME feature not activated.")}))),(0,i.of)({type:"eme-disabled"})):0===t.length?(0,r.T)(s.pipe((0,a.U)((function(){throw d.Z.error("Init: Ciphered media and no keySystem passed"),new u.Z("MEDIA_IS_ENCRYPTED_ERROR","Media is encrypted and no `keySystems` given")}))),(0,i.of)({type:"eme-disabled"})):"function"!=typeof o.N?(0,r.T)(s.pipe((0,a.U)((function(){throw d.Z.error("Init: Encrypted event but no EME API available"),new u.Z("MEDIA_IS_ENCRYPTED_ERROR","Encryption APIs not found.")}))),(0,i.of)({type:"eme-disabled"})):(d.Z.debug("Init: Creating EMEManager"),l.Z.emeManager(e,t,n))}},8343:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r={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}}}},2795:(e,t,n)=>{"use strict";n.d(t,{Z:()=>E});var r=n(9795),i=n(8170),a=n(6008),o=n(1015),s=n(5602),u=n(486),l=n(3068),d=n(7006),c=n(7746),f=n(3666);function p(){return f.op}var h=n(1410),v=n(8117),m=n(5561);var g=n(3774),y=n(1473);var _=n(3887);function b(e,t,n){var u=e.pipe((0,a.h)((function(e){var r=e.seeking,i=e.stalled,a=e.readyState,o=e.currentRange;return!r&&null===i&&(function(e,t){return!e||!f.SB||t}(n,t.hasAttribute("playsinline"))?(a>=4||3===a&&null!==o)&&(!p()||t.duration>0):a>=1&&t.duration>0)})),(0,o.q)(1),(0,s.h)("can-play"));return p()&&0===t.duration?(0,r.z)((0,i.of)("not-loaded-metadata"),u):u}function T(e){return function(e){return(0,h.P)((function(){return(0,m.Z)((function(){return(0,v.Z)(e.play())}),void 0)}))}(e).pipe((0,s.h)("autoplay"),(0,u.K)((function(e){if(e instanceof Error&&"NotAllowedError"===e.name)return _.Z.warn("Init: Media element can't play. It may be due to browser auto-play policies."),(0,i.of)("autoplay-blocked");throw e})))}function E(e){var t=e.clock$,n=e.mediaElement,r=e.startTime,a=e.mustAutoPlay,s=e.setCurrentTime,u=e.isDirectfile,f=function(e){return e.readyState>=g.cX.HAVE_METADATA?(0,i.of)(null):(0,y.K4)(e).pipe((0,o.q)(1))}(n).pipe((0,o.q)(1),(0,l.b)((function(){_.Z.info("Init: Set initial time",r);var e="function"==typeof r?r():r;s(e)})),(0,d.d)({refCount:!0})),p=f.pipe((0,c.zg)((function(){return b(t,n,u).pipe((0,l.b)((function(){return _.Z.info("Init: Can begin to play content")})),(0,c.zg)((function(e){return"can-play"===e?a?T(n):(n.autoplay&&_.Z.warn("Init: autoplay is enabled on HTML media element. Media will play as soon as possible."),(0,i.of)("loaded")):(0,i.of)(e)})))})),(0,d.d)({refCount:!0}));return{seek$:f,load$:p}}},8969:(e,t,n)=>{"use strict";n.d(t,{Z:()=>w});var r=n(5631),i=n(8170),a=n(4370),o=n(7746),s=n(9095),u=n(6738),l=n(5709),d=n(6008),c=n(1015),f=n(3756),p=n(4379),h=n(3887),v=n(5767);var m=n(3714),g=n(8025),y=n(4507),_=n(8343),b=n(2795),T=n(2447),E=n(2983);function w(e){var t=e.autoPlay,n=e.clock$,w=e.keySystems,S=e.mediaElement,k=e.speed$,A=e.setCurrentTime,x=e.startAt,I=e.url;if((0,v.Z)(S),null==I)throw new Error("No URL for a DirectFile content");var Z=function(e,t){return new p.y((function(n){return h.Z.info("Setting URL to Element",t,e),e.src=t,n.next(void 0),function(){(0,v.Z)(e)}}))}(S,I);h.Z.debug("Init: Calculating initial time");var R=function(){return 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 h.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}(S,x)};h.Z.debug("Init: Initial time calculated:",R);var M=(0,b.Z)({clock$:n,mediaElement:S,startTime:R,mustAutoPlay:t,setCurrentTime:A,isDirectfile:!0}),C=M.seek$,N=M.load$,P=Z.pipe((0,o.zg)((function(){return(0,y.Z)(S,w,r.E)})),(0,g.Z)(),(0,s.B)()),O=(0,T.Z)(S),D=(0,E.Z)(S,k,n,{pauseWhenStalled:!0}).pipe((0,u.l)()),L=n.pipe((0,l.U)((function(e){return null===e.stalled?_.Z.unstalled():_.Z.stalled(e.stalled)}))),B=P.pipe((0,d.h)((function(e){return"created-media-keys"===e.type?(e.value.attachMediaKeys$.next(),!0):"eme-disabled"===e.type||"attached-media-keys"===e.type})),(0,c.q)(1),(0,f.j)(N),(0,o.zg)((function(e){if("autoplay-blocked"===e){var t=new m.Z("MEDIA_ERR_BLOCKED_AUTOPLAY","Cannot trigger auto-play automatically: your browser does not allow it.");return(0,i.of)(_.Z.warning(t),_.Z.loaded(null))}if("not-loaded-metadata"===e){var n=new m.Z("MEDIA_ERR_NOT_LOADED_METADATA","Cannot load automatically: your browser falsely announced having loaded the content.");return(0,i.of)(_.Z.warning(n))}return(0,i.of)(_.Z.loaded(null))}))),U=C.pipe((0,u.l)());return(0,a.T)(B,U,P,O,D,L)}},2447:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7027),i=n(7746),a=n(3714);function o(e){return(0,r.R)(e,"error").pipe((0,i.zg)((function(){switch(null==e.error?0:e.error.code){case 1:throw new a.Z("MEDIA_ERR_ABORTED","The fetching of the associated resource was aborted by the user's request.");case 2:throw new a.Z("MEDIA_ERR_NETWORK","A network error occurred which prevented the media from being successfully fetched");case 3:throw new a.Z("MEDIA_ERR_DECODE","An error occurred while trying to decode the media resource");case 4:throw new a.Z("MEDIA_ERR_SRC_NOT_SUPPORTED","The media resource has been found to be unsuitable.");default:throw new a.Z("MEDIA_ERR_UNKNOWN","The HTMLMediaElement errored due to an unknown reason.")}})))}},2983:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(8170),i=n(1410),a=n(5709),o=n(3485),s=n(1931),u=n(6381),l=n(3068),d=n(3887);function c(e,t,n,c){var f=c.pauseWhenStalled;return(void 0===f||f?n.pipe((0,a.U)((function(e){return null!==e.stalled})),(0,o.O)(!1),(0,s.x)()):(0,r.of)(!1)).pipe((0,u.w)((function(n){return n?(0,i.P)((function(){return d.Z.info("Init: Pause playback to build buffer"),e.playbackRate=0,(0,r.of)(0)})):t.pipe((0,l.b)((function(t){d.Z.info("Init: Resume playback speed",t),e.playbackRate=t})))})))}},7127:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l});var r=n(1788),i=n(1410),a=n(8170),o=n(3887),s=n(4123),u=n(4309);const l=function(e){function t(){var t;return o.Z.debug("ISB: Creating ImageSegmentBuffer"),(t=e.call(this)||this).bufferType="image",t._buffered=new u.Z,t}(0,r.Z)(t,e);var n=t.prototype;return n.pushChunk=function(e){var t=this;return(0,i.P)((function(){var n,r;if(o.Z.debug("ISB: appending new data."),null===e.data.chunk)return(0,a.of)(void 0);var i=e.data,s=i.appendWindow,u=i.chunk,l=u.start,d=u.end,c=u.timescale,f=null!==(n=s[0])&&void 0!==n?n:0,p=null!==(r=s[1])&&void 0!==r?r:1/0,h=l/c,v=d/c,m=Math.max(f,h),g=Math.min(p,v);return t._buffered.insert(m,g),null!==e.inventoryInfos&&t._segmentInventory.insertChunk(e.inventoryInfos),(0,a.of)(void 0)}))},n.removeBuffer=function(e,t){return(0,i.P)((function(){return o.Z.info("ISB: ignored image data remove order",e,t),(0,a.of)(void 0)}))},n.endOfSegment=function(e){var t=this;return(0,i.P)((function(){return t._segmentInventory.completeSegment(e),(0,a.of)(void 0)}))},n.getBufferedRanges=function(){return this._buffered},n.dispose=function(){o.Z.debug("ISB: disposing image SegmentBuffer"),this._buffered.remove(0,1/0)},t}(s.C)},5192:(e,t,n)=>{"use strict";n.d(t,{Z:()=>L});var r=n(1788),i=n(4370),a=n(6564),o=n(9795),s=n(8170),u=n(211),l=n(1410),d=n(3485),c=n(1198),f=n(5602),p=n(1558),h=n(1473),v=n(4379),m=n(5709),g=n(1931),y=n(3887),_=n(2203).Z?void 0:window.ResizeObserver;var b=n(944),T=n(4123),E=n(4309),w=n(7874);function S(e,t){return Math.abs(e-t)<=.2}function k(e,t){for(var n=e.length-1;n>=0;n--){if(e[n].startt)return e.slice(n,e.length)}return[]}function x(e,t,n){var r=Math.max(e.start,t),i=k(e.cues,t),a={start:e.start,end:r,cues:i},o=Math.min(n,e.end),s=A(e.cues,n);return[a,{start:o,end:e.end,cues:s}]}var I=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=A(a.cues,n),a.start=n;else{var o=x(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=k(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||S(i.end,t.end)?r[e]=i:(t.start>=i.end||(t.cues=A(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(S(s.end,n))return s.cues=k(s.cues,t),s.end=t,void r.splice(o+1,0,i);if(s.end>n){var u=x(s,t,n),l=u[0],d=u[1];return this._cuesBuffer[o]=l,r.splice(o+1,0,i),void r.splice(o+2,0,d)}for(s.cues=k(s.cues,t),s.end=t,s=r[o+1];void 0!==s&&n>s.end;)r.splice(o,1),s=r[o];return void a(o)}}r.push(i)},e}();function Z(e,t,n,r){for(var i=[t/n.columns,e/n.rows],a=r.getElementsByClassName("proportional-style"),o=0;o0}var R=h.C1,M=h.ik,C=h.d5,N=b.Z.MAXIMUM_HTML_TEXT_TRACK_UPDATE_INTERVAL,P=b.Z.TEXT_TRACK_SIZE_CHECKS_INTERVAL;function O(e,t){try{e.removeChild(t)}catch(e){y.Z.warn("HTSB: Can't remove text track: not in the element.")}}function D(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}}const L=function(e){function t(t,n){var r;return y.Z.debug("HTSB: Creating HTMLTextSegmentBuffer"),(r=e.call(this)||this).bufferType="text",r._buffered=new E.Z,r._videoElement=t,r._textTrackElement=n,r._clearSizeUpdates$=new u.xQ,r._destroy$=new u.xQ,r._buffer=new I,r._currentCues=[],function(e){var t=C(e),n=M(e),r=R(e),u=(0,i.T)(n,r),l=(0,a.F)(N).pipe((0,d.O)(null));return u.pipe((0,d.O)(null),(0,c.c)((0,o.z)(l.pipe((0,f.h)(!0),(0,p.R)(t)),(0,s.of)(!1))))}(r._videoElement).pipe((0,p.R)(r._destroy$)).subscribe((function(e){if(e){var t=Math.max(r._videoElement.currentTime+N/1e3/2,0),n=r._buffer.get(t);0===n.length?r._disableCurrentCues():r._displayCues(n)}else r._disableCurrentCues()})),r}(0,r.Z)(t,e);var n=t.prototype;return n.pushChunk=function(e){var t=this;return(0,l.P)((function(){return t.pushChunkSync(e),(0,s.of)(void 0)}))},n.removeBuffer=function(e,t){var n=this;return(0,l.P)((function(){return n.removeBufferSync(e,t),(0,s.of)(void 0)}))},n.endOfSegment=function(e){var t=this;return(0,l.P)((function(){return t._segmentInventory.completeSegment(e),(0,s.of)(void 0)}))},n.getBufferedRanges=function(){return this._buffered},n.dispose=function(){y.Z.debug("HTSB: Disposing HTMLTextSegmentBuffer"),this._disableCurrentCues(),this._buffer.remove(0,1/0),this._buffered.remove(0,1/0),this._destroy$.next(),this._destroy$.complete()},n.pushChunkSync=function(e){var t,n;y.Z.debug("HTSB: Appending new html text tracks");var r=e.data,i=r.timestampOffset,a=r.appendWindow,o=r.chunk;if(null!==o){var s,u,l=o.start,d=o.end,c=o.data,f=o.type,p=o.language,h=null!==(t=a[0])&&void 0!==t?t:0,v=null!==(n=a[1])&&void 0!==n?n:1/0,m=function(e,t,n,r){y.Z.debug("HTSB: Finding parser for html text tracks:",e);var i=w.Z.htmlTextTracksParsers[e];if("function"!=typeof i)throw new Error("no parser found for the given text track");y.Z.debug("HTSB: Parser found, parsing...");var a=i(t,n,r);return y.Z.debug("HTTB: Parsed successfully!",a),a}(f,c,i,p);if(0!==h&&v!==1/0){for(var g=0;g=0&&m[g].start>=v;)g--;for(m.splice(g,m.length),g=m.length-1;g>=0&&m[g].end>v;)m[g].end=v,g--}if(void 0!==l)s=Math.max(h,l);else{if(m.length<=0)return void y.Z.warn("HTSB: Current text tracks have no cues nor start time. Aborting");y.Z.warn("HTSB: No start time given. Guessing from cues."),s=m[0].start}if(void 0!==d)u=Math.min(v,d);else{if(m.length<=0)return void y.Z.warn("HTSB: Current text tracks have no cues nor end time. Aborting");y.Z.warn("HTSB: No end time given. Guessing from cues."),u=m[m.length-1].end}u<=s?y.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(m,s,u),this._buffered.insert(s,u))}},n.removeBufferSync=function(e,t){y.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._clearSizeUpdates$.next(),this._currentCues.length>0){for(var e=0;e0&&function(e,t){return(0,l.P)((function(){if(void 0!==_){var n=-1,r=-1;return new v.y((function(t){var i=new _((function(e){if(0!==e.length){var i=e[0].contentRect,a=i.height,o=i.width;a===n&&o===r||(n=a,r=o,t.next({height:a,width:o}))}else y.Z.error("Compat: Resized but no observed element.")}));return i.observe(e),function(){i.disconnect()}}))}return(0,a.F)(t).pipe((0,d.O)(null),(0,m.U)((function(){var t=e.getBoundingClientRect();return{height:t.height,width:t.width}})),(0,g.x)((function(e,t){return e.height===t.height&&e.width===t.width})))}))}(this._textTrackElement,P).pipe((0,p.R)(this._clearSizeUpdates$),(0,p.R)(this._destroy$)).subscribe((function(e){for(var t=e.height,n=e.width,r=0;r{"use strict";n.d(t,{Z:()=>f});var r=n(1788),i=n(1410),a=n(8170),o=n(3666);var s=n(3887);function u(e,t){if(o.vU&&function(e,t){var n=e.activeCues;if(null===n)return!1;for(var r=0;r0?e.textTracks[u-1]:e.addTextTrack(s)).mode=t?null!==(n=i.HIDDEN)&&void 0!==n?n:"hidden":null!==(r=i.SHOWING)&&void 0!==r?r:"showing"}else a=document.createElement("track"),e.appendChild(a),i=a.track,a.kind=s,i.mode=t?"hidden":"showing";return{track:i,trackElement:a}}(t,n),a=i.track,u=i.trackElement;return r.bufferType="text",r._buffered=new d.Z,r._videoElement=t,r._track=a,r._trackElement=u,r}(0,r.Z)(t,e);var n=t.prototype;return n.pushChunk=function(e){var t=this;return(0,i.P)((function(){var n,r;if(s.Z.debug("NTSB: Appending new native text tracks"),null===e.data.chunk)return(0,a.of)(void 0);var i,o,u=e.data,l=u.timestampOffset,d=u.appendWindow,f=u.chunk,p=f.start,h=f.end,v=f.data,m=f.type,g=f.language,y=null!==(n=d[0])&&void 0!==n?n:0,_=null!==(r=d[1])&&void 0!==r?r:1/0,b=function(e,t,n,r){s.Z.debug("NTSB: Finding parser for native text tracks:",e);var i=c.Z.nativeTextTracksParsers[e];if("function"!=typeof i)throw new Error("no parser found for the given text track");s.Z.debug("NTSB: Parser found, parsing...");var a=i(t,n,r);return s.Z.debug("NTSB: Parsed successfully!",a),a}(m,v,l,g);if(0!==y&&_!==1/0){for(var T=0;T=0&&b[T].startTime>=_;)T--;for(b.splice(T,b.length),T=b.length-1;T>=0&&b[T].endTime>_;)b[T].endTime=_,T--}if(void 0!==p)i=Math.max(y,p);else{if(b.length<=0)return s.Z.warn("NTSB: Current text tracks have no cues nor start time. Aborting"),(0,a.of)(void 0);s.Z.warn("NTSB: No start time given. Guessing from cues."),i=b[0].startTime}if(void 0!==h)o=Math.min(_,h);else{if(b.length<=0)return s.Z.warn("NTSB: Current text tracks have no cues nor end time. Aborting"),(0,a.of)(void 0);s.Z.warn("NTSB: No end time given. Guessing from cues."),o=b[b.length-1].endTime}if(o<=i)return s.Z.warn("NTSB: Invalid text track appended: ","the start time is inferior or equal to the end time."),(0,a.of)(void 0);if(b.length>0){var E=b[0],w=t._track.cues;null!==w&&w.length>0&&E.startTime=0;i--){var a=r[i],o=a.startTime,l=a.endTime;o>=e&&o<=t&&l<=t&&u(n,a)}this._buffered.remove(e,t)},t}(l.C)},4123:(e,t,n)=>{"use strict";n.d(t,{C:()=>m,f:()=>v});var r=n(944),i=n(3887),a=n(5952),o=n(5278),s=r.Z.MAX_MANIFEST_BUFFERED_START_END_DIFFERENCE,u=r.Z.MAX_MANIFEST_BUFFERED_DURATION_DIFFERENCE,l=r.Z.MINIMUM_SEGMENT_SIZE,d=function(){function e(){this._inventory=[]}var t=e.prototype;return t.reset=function(){this._inventory.length=0},t.synchronizeBuffered=function(e){for(var t=this._inventory,n=0,r=t[0],a=null==r?void 0:r.infos.adaptation.type,s=e.length,u=0;u0){var g=t[f+m-1];v={end:(0,o.Z)(g.bufferedEnd,g.end),precizeEnd:g.precizeEnd},i.Z.debug("SI: "+m+" segments GCed.",a),t.splice(f,m),n=f}if(void 0===r)return;if(c-(0,o.Z)(r.bufferedStart,r.start)>=l){if(p(r,d,v,a),n===t.length-1)return void h(r,c,a);r=t[++n];for(var y=(0,o.Z)(r.bufferedStart,r.start),_=(0,o.Z)(r.bufferedEnd,r.end),b=u=l&&(void 0===b||c-y>=_-b);){var T=t[n-1];void 0===T.bufferedEnd&&(T.bufferedEnd=r.precizeStart?r.start:T.end,i.Z.debug("SI: calculating buffered end of contiguous segment",a,T.bufferedEnd,T.end)),r.bufferedStart=T.bufferedEnd,void 0!==(r=t[++n])&&(y=(0,o.Z)(r.bufferedStart,r.start),_=(0,o.Z)(r.bufferedEnd,r.end))}}var E=t[n-1];void 0!==E&&h(E,c,a)}}null!=r&&(i.Z.debug("SI: last segments have been GCed",a,n,t.length),t.splice(n,t.length-n)),void 0!==a&&"DEBUG"===i.Z.getLevel()&&i.Z.debug("SI: current "+a+" 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=s)i.Z.warn("SI: Invalid chunked inserted: starts before it ends",u,o,s);else{for(var l=this._inventory,d={partiallyPushed:!0,estimatedStart:o,start:o,end:s,precizeStart:!1,precizeEnd:!1,bufferedStart:void 0,bufferedEnd:void 0,infos:{segment:a,period:t,adaptation:n,representation:r}},c=l.length-1;c>=0;c--){var f=l[c];if(f.start<=o){if(f.end<=o){for(i.Z.debug("SI: Pushing segment strictly after previous one.",u,o,f.end),this._inventory.splice(c+1,0,d),c+=2;cd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,d.end,l[c].start),l[c].start=d.end,l[c].bufferedStart=void 0,void(l[c].precizeStart=l[c].precizeStart&&d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[c].start,l[c].end),l.splice(c,1)}return}if(f.start===o){if(f.end<=s){for(i.Z.debug("SI: Segment pushed replace another one",u,o,s,f.end),this._inventory.splice(c,1,d),c+=1;cd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,d.end,l[c].start),l[c].start=d.end,l[c].bufferedStart=void 0,void(l[c].precizeStart=l[c].precizeStart&&d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[c].start,l[c].end),l.splice(c,1)}return}return i.Z.debug("SI: Segment pushed ends before another with the same start",u,o,s,f.end),l.splice(c,0,d),f.start=d.end,f.bufferedStart=void 0,void(f.precizeStart=f.precizeStart&&d.precizeEnd)}if(f.end<=d.end){for(i.Z.debug("SI: Segment pushed updates end of previous one",u,o,s,f.start,f.end),this._inventory.splice(c+1,0,d),f.end=d.start,f.bufferedEnd=void 0,f.precizeEnd=f.precizeEnd&&d.precizeStart,c+=2;cd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,d.end,l[c].start),l[c].start=d.end,l[c].bufferedStart=void 0,void(l[c].precizeStart=l[c].precizeStart&&d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[c].start,l[c].end),l.splice(c,1)}return}i.Z.debug("SI: Segment pushed is contained in a previous one",u,o,s,f.start,f.end);var p={partiallyPushed:f.partiallyPushed,start:d.end,end:f.end,precizeStart:f.precizeStart&&f.precizeEnd&&d.precizeEnd,precizeEnd:f.precizeEnd,bufferedStart:void 0,bufferedEnd:f.end,infos:f.infos};return f.end=d.start,f.bufferedEnd=void 0,f.precizeEnd=f.precizeEnd&&d.precizeStart,l.splice(c+1,0,d),void l.splice(c+2,0,p)}}var h=this._inventory[0];if(void 0===h)return i.Z.debug("SI: first segment pushed",u,o,s),void this._inventory.push(d);if(!(h.start>=s)){if(h.end<=s){for(i.Z.debug("SI: Segment pushed starts before and completely recovers the previous first one",u,o,s,h.start,h.end),this._inventory.splice(0,1,d);l.length>1&&l[1].startd.end)return i.Z.debug("SI: Segment pushed updates the start of the next one",u,d.end,l[1].start),l[1].start=d.end,l[1].bufferedStart=void 0,void(l[1].precizeStart=d.precizeEnd);i.Z.debug("SI: Segment pushed removes the next one",u,o,s,l[1].start,l[1].end),l.splice(1,1)}return}return i.Z.debug("SI: Segment pushed start of the next one",u,o,s,h.start,h.end),h.start=s,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",u,o,s,h.start),this._inventory.splice(0,0,d)}}},t.completeSegment=function(e){if(!e.segment.isInit){for(var t=this._inventory,n=!1,r=0;r0&&(this._inventory.splice(o+1,u),r-=u),this._inventory[o].partiallyPushed=!1,this._inventory[o].end=l,this._inventory[o].bufferedEnd=d}n||i.Z.warn("SI: Completed Segment not found",e)}},t.getInventory=function(){return this._inventory},e}();function c(e){if(void 0===e.bufferedStart||e.partiallyPushed)return!1;var t=e.start,n=e.end-t;return Math.abs(t-e.bufferedStart)<=s&&(void 0===e.bufferedEnd||e.bufferedEnd>e.bufferedStart&&Math.abs(e.bufferedEnd-e.bufferedStart-n)<=Math.min(u,n/3))}function f(e){if(void 0===e.bufferedEnd||e.partiallyPushed)return!1;var t=e.start,n=e.end,r=n-t;return Math.abs(n-e.bufferedEnd)<=s&&null!=e.bufferedStart&&e.bufferedEnd>e.bufferedStart&&Math.abs(e.bufferedEnd-e.bufferedStart-r)<=Math.min(u,r/3)}function p(e,t,n,r){void 0!==e.bufferedStart?(e.bufferedStartt&&(n.precizeEnd||e.start-n.end<=s)?(i.Z.debug("SI: buffered start is end of previous segment",r,t,e.start,n.end),e.bufferedStart=n.end,c(e)&&(e.start=n.end,e.precizeStart=!0)):e.start-t<=s?(i.Z.debug("SI: found true buffered start",r,t,e.start),e.bufferedStart=t,c(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<=s&&f(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<=s?(i.Z.debug("SI: found true buffered end",n,t,e.end),e.bufferedEnd=t,f(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 v,m=function(){function e(){this._segmentInventory=new d}var t=e.prototype;return t.synchronizeInventory=function(){this._segmentInventory.synchronizeBuffered(this.getBufferedRanges())},t.getInventory=function(){return this._segmentInventory.getInventory()},t.getPendingOperations=function(){return[]},e}();!function(e){e[e.Push=0]="Push",e[e.Remove=1]="Remove",e[e.EndOfSegment=2]="EndOfSegment"}(v||(v={}))},4309:(e,t,n)=>{"use strict";n.d(t,{Z:()=>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}()},3801:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3349),i=n(1788),a=function(e){function t(n){var i;return i=e.call(this)||this,Object.setPrototypeOf((0,r.Z)(i),t.prototype),i.name="AssertionError",i.message=n,i}return(0,i.Z)(t,e),t}((0,n(3786).Z)(Error))},5157:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(3349),i=n(1788),a=n(3786),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="EncryptedMediaError",a.type=o.ZB.ENCRYPTED_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))},5992:(e,t,n)=>{"use strict";n.d(t,{ZB:()=>r,br:()=>i,SM:()=>a});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:(e,t,n)=>{"use strict";function r(e,t,n){return e+" ("+t+") "+n}n.d(t,{Z:()=>r})},9822:(e,t,n)=>{"use strict";n.d(t,{Z:()=>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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(3349),i=n(1788),a=n(3786),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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(3349),i=n(1788),a=n(3786),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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(3349),i=n(1788),a=n(3786),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:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3349),i=n(1788),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,s.xhr=o,s.status=i,s.type=a,s.message=a,s}return(0,i.Z)(t,e),t}((0,n(3786).Z)(Error))},7273:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r={directfile:null,emeManager:null,htmlTextTracksBuffer:null,htmlTextTracksParsers:{},imageBuffer:null,imageParser:null,nativeTextTracksBuffer:null,nativeTextTracksParsers:{},transports:{}}},7874:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=n(7273).Z},3887:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(8894);const 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},e}())},5952:(e,t,n)=>{"use strict";function r(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}n.d(t,{Z:()=>r})},1966:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>Z});var r=n(1788),i=n(4791),a=n(3274),o=n(1959),s=n(908),u=n(8806),l=n(3714),d=n(3887),c=n(7714),f=n(1946),p=n(7829);const h="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}))};var v=n(3774);const m=function(){function e(e,t){var n;this.id=e.id,this.bitrate=e.bitrate,this.codec=e.codecs,null!=e.height&&(this.height=e.height),null!=e.width&&(this.width=e.width),null!=e.mimeType&&(this.mimeType=e.mimeType),void 0!==e.contentProtections&&(this.contentProtections=e.contentProtections),null!=e.frameRate&&(this.frameRate=e.frameRate),this.index=e.index,this.isSupported="audio"!==t.type&&"video"!==t.type||(n=this.getMimeTypeString(),null!=v.JJ&&("function"!=typeof v.JJ.isTypeSupported||v.JJ.isTypeSupported(n)))}var t=e.prototype;return t.getMimeTypeString=function(){var e,t;return(null!==(e=this.mimeType)&&void 0!==e?e:"")+';codecs="'+(null!==(t=this.codec)&&void 0!==t?t:"")+'"'},t.getEncryptionData=function(e){for(var t,n=this.getAllEncryptionData(),r=[],i=0;i0&&!u){d.Z.warn("Incompatible codecs for adaptation",e);var y=new l.Z("MANIFEST_INCOMPATIBLE_CODECS_ERROR","An Adaptation contains only incompatible codecs.");this.parsingErrors.push(y)}}var t=e.prototype;return t.getAvailableBitrates=function(){for(var e=[],t=0;t0}));if(o.every((function(e){return!e.isSupported}))&&a.length>0&&("video"===i||"audio"===i))throw new l.Z("MANIFEST_PARSE_ERROR","No supported "+i+" adaptations");return o.length>0&&(r[i]=o),r}),{}),!Array.isArray(this.adaptations.video)&&!Array.isArray(this.adaptations.audio))throw new l.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,T.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,a.Z)(this.getAdaptations(),(function(t){var n=t.id;return e===n}))},t.getPlayableAdaptations=function(e){if(void 0===e)return this.getAdaptations().filter((function(e){return e.getPlayableRepresentations().length>0}));var t=this.adaptations[e];return void 0===t?[]:t.filter((function(e){return e.getPlayableRepresentations().length>0}))},e}(),w=function(){function e(e){this._mediaURLs=e.media}var t=e.prototype;return t.getInitSegment=function(){return null},t.getSegments=function(){return[{id:"0",isInit:!1,number:0,mediaURLs:[this._mediaURLs],time:0,end:Number.MAX_VALUE,duration:Number.MAX_VALUE,timescale:1}]},t.getFirstPosition=function(){},t.getLastPosition=function(){},t.shouldRefresh=function(){return!1},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},t.isSegmentStillAvailable=function(){return!0},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){return!0},t.isInitialized=function(){return!0},t._replace=function(){d.Z.warn("Tried to replace a static RepresentationIndex")},t._update=function(){d.Z.warn("Tried to update a static RepresentationIndex")},e}();!function(e){e[e.Full=0]="Full",e[e.Partial=1]="Partial"}(y||(y={}));var S=n(5138);function k(e,t,n){e.start=t.start,e.end=t.end,e.duration=t.duration;for(var r=e.getAdaptations(),i=t.getAdaptations(),o=function(e){var t=r[e],o=(0,a.Z)(i,(function(e){return e.id===t.id}));if(void 0===o)d.Z.warn('Manifest: Adaptation "'+r[e].id+'" not found when merging.');else for(var s=r[e].representations,u=o.representations,l=function(e){var t=s[e],r=(0,a.Z)(u,(function(e){return e.id===t.id}));void 0===r?d.Z.warn('Manifest: Representation "'+s[e].id+'" not found when merging.'):n===y.Full?t.index._replace(r.index):t.index._update(r.index)},c=0;c0&&r._addSupplementaryImageAdaptations(u),o.length>0&&r._addSupplementaryTextAdaptations(o),r}(0,r.Z)(t,e);var n=t.prototype;return n.getPeriod=function(e){return(0,a.Z)(this.periods,(function(t){return e===t.id}))},n.getPeriodForTime=function(e){return(0,a.Z)(this.periods,(function(t){return e>=t.start&&(void 0===t.end||t.end>e)}))},n.getNextPeriod=function(e){return(0,a.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,a.Z)(this.periods,(function(e){return void 0===e.end||t0&&this.trigger("decipherabilityUpdate",r)},n.addUndecipherableProtectionData=function(e){var t=I(this,(function(t){var n,r;if(!1===t.decipherable)return!1;for(var a=null!==(r=null===(n=t.contentProtections)||void 0===n?void 0:n.initData)&&void 0!==r?r:[],o=function(t){if((void 0===e.type||a[t].type===e.type)&&e.values.every((function(e){return a[t].values.some((function(t){return(void 0===e.systemId||t.systemId===e.systemId)&&(0,i.Z)(t.data,e.data)}))})))return{v:!1}},s=0;s0&&this.trigger("decipherabilityUpdate",t)},n.getAdaptations=function(){(0,u.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,u.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,u.Z)("manifest.getAdaptation(id) is deprecated. Please use manifest.period[].getAdaptation(id) instead"),(0,a.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,r=e.mimeType,i=e.url,a="gen-image-ada-"+A(),o="gen-image-rep-"+A(),s=new _({id:a,type:"image",representations:[{bitrate:0,id:o,mimeType:r,index:new w({media:i})}]},{isManuallyAdded:!0});return(n=t.parsingErrors).push.apply(n,s.parsingErrors),s}));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,a=n.url,o=n.language,s=n.languages,u=n.closedCaption,l=null!=o?[o]:null!=s?s:[];return e.concat(l.map((function(e){var n,o="gen-text-ada-"+A(),s="gen-text-rep-"+A(),l=new _({id:o,type:"text",language:e,closedCaption:u,representations:[{bitrate:0,id:s,mimeType:r,codecs:i,index:new w({media:a})}]},{isManuallyAdded:!0});return(n=t.parsingErrors).push.apply(n,l.parsingErrors),l})))}),[]);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.lifetime=e.lifetime,this.parsingErrors=e.parsingErrors,this.suggestedPresentationDelay=e.suggestedPresentationDelay,this.transport=e.transport,this.publishTime=e.publishTime,t===y.Full)this._timeBounds=e._timeBounds,this.uris=e.uris,function(e,t){for(var n=0,r=0;re.length)d.Z.error("Manifest: error when updating Periods");else{n0&&e.push.apply(e,l)}}(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.starti&&(e.splice(i,s-i),s=i),k(e[s],o,y.Full),i++}i0;){var r=this.periods[0];if(void 0===r.end||r.end>n)break;this.periods.shift()}}this.adaptations=void 0===this.periods[0]?{}:this.periods[0].adaptations,this.trigger("manifestUpdate",null)},t}(o.Z)},2689:(e,t,n)=>{"use strict";n.d(t,{s:()=>r});var r=Math.pow(2,32)-1},2297:(e,t,n)=>{"use strict";n.d(t,{iz:()=>o,t_:()=>a,Qy:()=>s,Xj:()=>l,nR:()=>u});var r=n(3887),i=n(6968);function a(e,t){var n=s(e,t);return null!==n?e.subarray(n[1],n[2]):null}function o(e,t){var n=s(e,t);return null!==n?e.subarray(n[0],n[2]):null}function s(e,t){for(var n,r,a=e.length,o=0,s=0;o+8<=a;){if(r=o,s=(0,i.pX)(e,r),r+=4,n=(0,i.pX)(e,r),r+=4,0===s)s=a-o;else if(1===s){if(r+8>a)return null;s=(0,i.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 u(e,t,n,r,a){for(var o,s=e.length,u=0;us)return;o=(0,i.pV)(e,l),l+=8}if(1970628964===d&&l+16<=s&&(0,i.pX)(e,l)===t&&(0,i.pX)(e,l+4)===n&&(0,i.pX)(e,l+8)===r&&(0,i.pX)(e,l+12)===a)return l+=16,e.subarray(l,u+o)}}function l(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,a=(0,i.pX)(e,n);n+=4;var o=(0,i.pX)(e,n);if(n+=4,0===a)a=t;else if(1===a){if(n+8>t)return r.Z.warn("ISOBMFF: box too short, cannot find offsets"),null;a=(0,i.pV)(e,n),n+=8}if(a<0)throw new Error("ISOBMFF: Size out of range");return 1970628964===o&&(n+=16),[0,n,a]}},6807:(e,t,n)=>{"use strict";n.d(t,{XA:()=>i,Le:()=>a,fs:()=>o,E3:()=>s});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.t_)(e,1835295092)}function o(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 s(e,t){return void 0===t&&(t=0),(0,r.t_)(e.subarray(t),1701671783)}},6490:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s,Y:()=>u});var r=n(3887);const 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))};var 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:(e,t,n)=>{"use strict";n.d(t,{LD:()=>c,Qx:()=>l,MM:()=>d,Wf:()=>u,J6:()=>f,s9:()=>p});var r=n(6968),i=n(3635),a=n(2689),o=n(2297),s=n(6807);function u(e,t){var n=(0,o.Qy)(e,1936286840);if(null===n)return null;var i=t,a=n[2]-n[0],s=n[1],u=e[s];s+=8;var l,d=(0,r.pX)(e,s);if(s+=4,0===u)l=(0,r.pX)(e,s),s+=4,i+=(0,r.pX)(e,s)+a,s+=4;else{if(1!==u)return null;l=(0,r.pV)(e,s),s+=8,i+=(0,r.pV)(e,s)+a,s+=8}var c=[];s+=2;var f=(0,r.zK)(e,s);for(s+=2;--f>=0;){var p=(0,r.pX)(e,s);s+=4;var h=2147483647&p;if(1===(2147483648&p)>>>31)throw new Error("sidx with reference_type `1` not yet implemented");var v=(0,r.pX)(e,s);s+=4,s+=4,c.push({time:l,duration:v,count:0,timescale:d,range:[i,i+h-1]}),l+=v,i+=h}return c}function l(e){var t=(0,s.XA)(e);if(null!==t){var n=(0,o.t_)(t,1952867444);if(null!==n){var i=n[0];return 1===i?(0,r.pV)(n,4):0===i?(0,r.pX)(n,4):void 0}}}function d(e){var t=(0,s.XA)(e);if(null!==t){var n=(0,o.t_)(t,1953658222);if(null!==n){var i=0,a=n[i];if(i+=1,!(a>1)){var u=(0,r.QI)(n,i);i+=3;var l=(256&u)>0,d=0;if(l||void 0!==(d=function(e){var t=(0,o.t_)(e,1952868452);if(null!==t){var n=1,i=(0,r.QI)(t,n);if(n+=3,(8&i)>0)return n+=4,(1&i)>0&&(n+=8),(2&i)>0&&(n+=4),(0,r.pX)(t,n)}}(t))){var c=(1&u)>0,f=(4&u)>0,p=(512&u)>0,h=(1024&u)>0,v=(2048&u)>0,m=(0,r.pX)(n,i);i+=4,c&&(i+=4),f&&(i+=4);for(var g=m,y=0;g-- >0;)l?(y+=(0,r.pX)(n,i),i+=4):y+=d,p&&(i+=4),h&&(i+=4),v&&(i+=4);return y}}}}}function c(e){var t=(0,s.fs)(e);if(null!==t){var n=(0,o.t_)(t,1835296868);if(null!==n){var i=0,a=n[i];return i+=4,1===a?(0,r.pX)(n,i+16):0===a?(0,r.pX)(n,i+8):void 0}}}function f(e){var t=e.length;if(t<4)throw new Error("Cannot update box length: box too short");var n=(0,r.pX)(e,0);if(0===n){if(t>a.s){var i=new Uint8Array(t+8);return i.set((0,r.kh)(1),0),i.set(e.subarray(4,8),4),i.set((0,r.el)(t+8),8),i.set(e.subarray(8,t),16),i}return e.set((0,r.kh)(t),0),e}if(1===n){if(t<16)throw new Error("Cannot update box length: box too short");return e.set((0,r.el)(t),8),e}if(t<=a.s)return e.set((0,r.kh)(t),0),e;var o=new Uint8Array(t+8);return o.set((0,r.kh)(1),0),o.set(e.subarray(4,8),4),o.set((0,r.el)(t+8),8),o.set(e.subarray(8,t),16),o}function p(e){for(var t=[],n=0;n{"use strict";n.d(t,{Z:()=>a});var r=n(6968),i=n(3635);const a=function(e){var t=0,n=e.length,a=(0,i.uR)(e.subarray(t+1,t+8));if(t+=8,137!==e[0]||"BIF\r\n\n"!==a)throw new Error("Invalid BIF file");var o=e[t],s=e[t+=1],u=e[t+=1],l=e[t+=1];t+=1;var d=[o,s,u,l].join(".");if(s>0)throw new Error("Unhandled version: "+s);var c=(0,r.dN)(e,t);t+=4;var f=(0,r.dN)(e,t);t+=4;var p=(0,i.uR)(e.subarray(t,t+4));t+=4;var h=(0,r.qb)(e,t);t+=2;var v=(0,r.qb)(e,t),m=[e[t+=2],e[t+1]].join(":"),g=1===e[t+=2];t=64;var y=[];if(0===c)throw new Error("bif: no images to parse");for(var _=0,b=null;t{"use strict";function r(e,t){for(;e.length>0;){var n=e[0];if(n.start>=t)return;if(n.repeatCount<=0)e.shift();else{var r=e[1];if(null!=r&&r.start<=t)e.shift();else{if(n.duration<=0)return;for(var i=n.start+n.duration,a=1;in.repeatCount)){var o=n.repeatCount-a;return n.start=i,void(n.repeatCount=o)}e.shift()}}}}n.d(t,{Z:()=>r})},3911:(e,t,n)=>{"use strict";function r(e,t,n){var r,i=e.repeatCount;return i>=0?i:(r=null!=t?t.start:null!=n?n:Number.MAX_VALUE,Math.ceil((r-e.start)/e.duration)-1)}function i(e,t,n){var i=e.start,a=e.duration;return a<=0?i:i+(r(e,t,n)+1)*a}function a(e,t){var n;return e*t.timescale+(null!==(n=t.indexTimeOffset)&&void 0!==n?n:0)}function o(e,t){var n;return(e-(null!==(n=t.indexTimeOffset)&&void 0!==n?n:0))/t.timescale}function s(e,t,n){return[e*n,(e+t)*n]}function u(e,t,n){var r=e.timeline,s=a(t,e);if(s<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,s);if(u<0||u>=r.length-1)return null;var l=r[u];if(l.duration<=0)return null;var d=r[u+1];if(void 0===d)return null;var c=d.start;return s>=i(l,d,n)&&sr,jH:()=>i,gT:()=>a,zG:()=>o,PZ:()=>s,_j:()=>u})},1091:(e,t,n)=>{"use strict";function r(e,t,n,r){for(var i=0;ie.time)return!1;if(o===e.time)return a.duration/n===e.duration&&(null==a.range?null==e.range:null!=e.range&&a.range[0]===e.range[0]&&a.range[1]===e.range[1]);if(a.repeatCount>=0&&null!=a.duration){var s=(o-a.start)/a.duration-1;return s%1==0&&s<=a.repeatCount}}return!1}n.d(t,{Z:()=>r})},5505:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(3714),i=n(3887),a=n(3911);function o(e,t){var n=e.length;if(0!==e.length){if(0!==t.length){var 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)return void e.splice.apply(e,[u,n-u].concat(t));if(lo)return i.Z.warn("RepresentationIndex: Manifest update removed previous segments"),void e.splice.apply(e,[u,n-u].concat(t));if(void 0===d.repeatCount||d.repeatCount<=0)return d.repeatCount<0&&(d.repeatCount=Math.floor((o-d.start)/d.duration)-1),void e.splice.apply(e,[u+1,n-(u+1)].concat(t));if(d.start+d.duration*(d.repeatCount+1)<=o)return void e.splice.apply(e,[u+1,n-(u+1)].concat(t));var c=(o-d.start)/d.duration-1;if(c%1==0&&d.duration===t[0].duration){var f=t[0].repeatCount<0?-1:t[0].repeatCount+c+1;return e.splice.apply(e,[u,n-u].concat(t)),e[u].start=d.start,void(e[u].repeatCount=f)}return i.Z.warn("RepresentationIndex: Manifest update removed previous segments"),e[u].repeatCount=Math.floor(c),void e.splice.apply(e,[u+1,n-(u+1)].concat(t))}}var p=e[e.length-1],h=t[t.length-1];if(void 0!==p.repeatCount&&p.repeatCount<0)return p.start>h.start?void i.Z.warn("RepresentationIndex: The new index is older than the previous one"):(i.Z.warn('RepresentationIndex: The new index is "bigger" than the previous one'),void e.splice.apply(e,[0,n].concat(t)));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"):(i.Z.warn('RepresentationIndex: The new index is "bigger" than the previous one'),e.splice.apply(e,[0,n].concat(t)))}}else e.splice.apply(e,[0,n].concat(t))}},5734:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(6923),i=/&#([0-9]+);/g,a=/
/gi,o=/]*>([\s\S]*?)<\/style[^>]*>/i,s=/\s*

]+))?>(.*)/i,u=/]+?start="?([0-9]*)"?[^0-9]/i;function l(e,t){var n=new RegExp("\\s*"+t+":\\s*(\\S+);","i").exec(e);return Array.isArray(n)?n[1]:null}const d=function(e,t,n){var d,c,f=/]/gi,p=/]|<\/body>/gi,h=[],v=o.exec(e),m=Array.isArray(v)?v[1]:"";p.exec(e);var g,y=function(e){for(var t=/\.(\S+)\s*{([^}]*)}/gi,n={},r=t.exec(e);null!==r;){var i=r[1],a=l(r[2],"lang");null!=i&&null!=a&&(n[a]=i),r=t.exec(e)}return n}(m),_=function(e){var t=/p\s*{([^}]*)}/gi.exec(e);return null===t?"":t[1]}(m);if((0,r.Z)(n)&&void 0===(g=y[n]))throw new Error("sami: could not find lang "+n+" in CSS");for(;d=f.exec(e),c=p.exec(e),null!==d||null!==c;){if(null===d||null===c||d.index>=c.index)throw new Error("parse error");var b=e.slice(d.index,c.index),T=u.exec(b);if(!Array.isArray(T))throw new Error("parse error (sync time attribute)");var E=+T[1];if(isNaN(E))throw new Error("parse error (sync time attribute NaN)");w(b.split("\n"),E/1e3)}return h;function w(e,n){for(var o=e.length;--o>=0;){var u=s.exec(e[o]);if(Array.isArray(u)){var l=u[1],d=u[2];if(g===l)if(" "===d)h[h.length-1].end=n;else{var c=document.createElement("DIV");c.className="rxp-texttrack-region";var f=document.createElement("DIV");f.className="rxp-texttrack-div",f.style.position="absolute",f.style.bottom="0",f.style.width="100%",f.style.color="#fff",f.style.textShadow="-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000";var p=document.createElement("div");p.className="rxp-texttrack-p",(0,r.Z)(_)&&(p.style.cssText=_);for(var v=d.split(a),m=0;m{"use strict";n.d(t,{Z:()=>c});var r=n(7253),i=n(6923),a=/&#([0-9]+);/g,o=/
/gi,s=/]*>([\s\S]*?)<\/style[^>]*>/i,u=/\s*

]+))?>(.*)/i,l=/]+?start="?([0-9]*)"?[^0-9]/i;function d(e,t){var n=new RegExp("\\s*"+t+":\\s*(\\S+);","i").exec(e);return Array.isArray(n)?n[1]:null}const c=function(e,t,n){var c,f,p=/]/gi,h=/]|<\/body>/gi,v=[],m=s.exec(e),g=null!==m?m[1]:"";h.exec(e);var y,_=function(e){for(var t=/\.(\S+)\s*{([^}]*)}/gi,n={},r=t.exec(e);Array.isArray(r);){var i=r[1],a=d(r[2],"lang");null!=i&&null!=a&&(n[a]=i),r=t.exec(e)}return n}(g);if((0,i.Z)(n)&&void 0===(y=_[n]))throw new Error("sami: could not find lang "+n+" in CSS");for(;c=p.exec(e),f=h.exec(e),null!==c||null!==f;){if(null===c||null===f||c.index>=f.index)throw new Error("parse error");var b=e.slice(c.index,f.index),T=l.exec(b);if(null===T)throw new Error("parse error (sync time attribute)");var E=+T[1];if(isNaN(E))throw new Error("parse error (sync time attribute NaN)");w(b.split("\n"),E/1e3)}return function(e){for(var t=[],n=0;n=0;)if(null!==(r=u.exec(e[s]))){var l=r,d=l[1],c=l[2];y===d&&(" "===c?v[v.length-1].end=n:v.push({text:(i=c,i.replace(o,"\n").replace(a,(function(e,t){return String.fromCharCode(t)}))),start:n+t}))}}}},2061:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(6923);function i(e,t){for(var n=t+1;(0,r.Z)(e[n]);)n++;return n}function a(e){for(var t=[],n=0;n0&&(1===o.length?o[0].indexOf("--\x3e")>=0&&t.push(o):(o[1].indexOf("--\x3e")>=0||o[0].indexOf("--\x3e")>=0)&&t.push(o)),n=a}return t}},8675:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(2061),i=n(788);function a(e,t){for(var n=e.split(/\r\n|\n|\r/),a=(0,r.Z)(n),s=[],u=0;u0){var u=document.createTextNode(o[s]);r.appendChild(u)}}else if("B"===a.nodeName){var l=e(a);l.style.fontWeight="bold",r.appendChild(l)}else if("I"===a.nodeName){var d=e(a);d.style.fontStyle="italic",r.appendChild(d)}else if("U"===a.nodeName){var c=e(a);c.style.textDecoration="underline",r.appendChild(c)}else if("FONT"===a.nodeName&&null!=a.color){var f=e(a);f.style.color=a.color,r.appendChild(f)}else{var p=e(a);r.appendChild(p)}}return r}(t)}},8057:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7253),i=n(2061),a=n(788);function o(e,t){for(var n,o,s,u,l,d=e.split(/\r\n|\n|\r/),c=(0,i.Z)(d),f=[],p=0;p{"use strict";n.d(t,{Z:()=>a});var r=n(6923);function i(e){var t=e.split(":");if((0,r.Z)(t[2])){var n=parseInt(t[0],10),i=parseInt(t[1],10),a=parseFloat(t[2].replace(",","."));if(isNaN(n)||isNaN(i)||isNaN(a))return;return 60*n*60+60*i+a}}function a(e,t){if(0===e.length)return null;var n,a,o=[];if((0,r.Z)(e[1])&&-1!==e[1].indexOf("--\x3e")){var s=e[1].split("--\x3e").map((function(e){return e.trim()}));n=s[0],a=s[1],o=e.slice(2,e.length)}if(!(0,r.Z)(n)||!(0,r.Z)(a)){var u=e[0].split("--\x3e").map((function(e){return e.trim()}));n=u[0],a=u[1],o=e.slice(1,e.length)}if(!(0,r.Z)(n)||!(0,r.Z)(a))return null;var l=i(n),d=i(a);return void 0===l||void 0===d?null:{start:l+t,end:d+t,payload:o}}},2967:(e,t,n)=>{"use strict";function r(e,t){if(!(e.parentNode instanceof Element))return[];return function e(n){var r=[];n.tagName.toLowerCase()===t.toLowerCase()&&r.push(n);var i=n.parentNode;return i instanceof Element&&r.push.apply(r,e(i)),r}(e.parentNode)}n.d(t,{Z:()=>r})},3791:(e,t,n)=>{"use strict";n.d(t,{U:()=>s,b:()=>u});var r=n(3274),i=n(7714),a=n(6923),o=n(9252);function s(e,t,n,o){for(var s={},u=e.slice(),l=0;l<=t.length-1;l++){var d=t[l];if(void 0!==d){var c=function(){var e=void 0,t=void 0;if(d.nodeType===Node.ELEMENT_NODE)for(var l=d,c=0;c<=l.attributes.length-1;c++){var f=l.attributes[c],p=f.name;if("style"===p)e=f.value;else if("region"===p)t=f.value;else{var h=p.substring(4);if((0,i.Z)(u,h)&&(s[h]=f.value,u.splice(c,1),0===u.length))return{v:s}}}if((0,a.Z)(e)){var v=(0,r.Z)(n,(function(t){return t.id===e}));if(void 0!==v)for(var m=0;m<=u.length-1;m++){var g=u[m];if(!(0,a.Z)(s[g])&&(0,a.Z)(v.style[g])){if(s[g]=v.style[g],u.splice(m,1),0===u.length)return{v:s};m--}}}if((0,a.Z)(t)){var y=(0,r.Z)(o,(function(e){return e.id===t}));if(void 0!==y)for(var _=0;_<=u.length-1;_++){var b=u[_];if(!(0,a.Z)(s[b])&&(0,a.Z)(y.style[b])){if(s[b]=y.style[b],u.splice(_,1),0===u.length)return{v:s};_--}}}}();if("object"==typeof c)return c.v}}return s}function u(e){if(e.nodeType!==Node.ELEMENT_NODE)return{};for(var t=e,n={},r=0;r<=t.attributes.length-1;r++){var i=t.attributes[r];if((0,o.Z)(i.name,"tts"))n[i.name.substring(4)]=i.value}return n}},6177:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(6923),i=n(5336);function a(e,t){var n=e.exec(t);if(null===n||""===n[0])return null;var r=Number(n[1]);isNaN(r)&&(r=0);var i=Number(n[2]);isNaN(i)&&(i=0);var a=Number(n[3]);isNaN(a)&&(a=0);var o=Number(n[4]);return isNaN(o)&&(o=0),o/1e3+a+60*i+3600*r}const o=function(e,t){return i.gu.test(e)?function(e,t){var n=i.gu.exec(t),r=Number(n[1]),a=Number(n[2]),o=Number(n[3]),s=Number(n[4]),u=Number(n[5]);isNaN(u)&&(u=0);return s+=u/e.subFrameRate,(o+=s/e.frameRate)+60*a+3600*r}(t,e):i.KO.test(e)?a(i.KO,e):i.wf.test(e)?a(i.wf,e):i.jb.test(e)?function(e,t){var n=i.jb.exec(t);return Number(n[1])/e.frameRate}(t,e):i.Du.test(e)?function(e,t){var n=i.Du.exec(t);return Number(n[1])/e.tickRate}(t,e):i.te.test(e)?a(i.te,e):void 0};function s(e,t){var n=e.getAttribute("begin"),i=e.getAttribute("dur"),a=e.getAttribute("end"),s=(0,r.Z)(n)?o(n,t):null,u=(0,r.Z)(i)?o(i,t):null,l=(0,r.Z)(a)?o(a,t):null;if(null==s||null==l&&null==u)throw new Error("Invalid text cue");return{start:s,end:null==l?s+u:l}}},7439:(e,t,n)=>{"use strict";n.d(t,{Z:()=>S});var r=n(5403);function i(e){return void 0===e.extent&&void 0===e.origin&&void 0===e.displayAlign&&void 0===e.display&&void 0===e.textAlign&&void 0===e.fontSize}function a(e){e.extent="70% 20%",e.fontSize="1c",e.origin="15% 80%",e.displayAlign="before",e.textAlign="center"}var o,s=n(6177);function u(e,t){(void 0===o&&(o=void 0!==e.classList&&"function"==typeof e.classList.add),o)?e.classList.add(t):(" "+e.className+" ").indexOf(" "+t+" ")<0&&(e.className+=" "+t)}var l=n(6923),d=n(8026),c=n(2967),f=n(3791),p=n(3887),h=n(5336);function v(e,t){return"-1px -1px "+t+" "+e+",1px -1px "+t+" "+e+",-1px 1px "+t+" "+e+",1px 1px "+t+" "+e}function m(e){var t;return null!=(t=h.Dq.exec(e))?"rgba("+String(parseInt(t[1],16))+","+String(parseInt(t[2],16))+","+String(parseInt(t[3],16))+","+String(parseInt(t[4],16)/255)+")":null!=(t=h.YU.exec(e))?"rgba("+String(parseInt(t[1]+t[1],16))+","+String(parseInt(t[2]+t[2],16))+","+String(parseInt(t[3]+t[3],16))+","+String(parseInt(t[4]+t[4],16)/255)+")":null!=(t=h.GK.exec(e))?"rgb("+String(+t[1])+","+String(+t[2])+","+String(+t[3])+")":null!=(t=h.ev.exec(e))?"rgba("+String(+t[1])+","+String(+t[2])+","+String(+t[3])+","+String(+t[4]/255)+")":e}var g=["color","direction","display","fontFamily","fontSize","fontStyle","fontWeight","textDecoration","textOutline","unicodeBidi","visibility","wrapOption"];function y(e,t,n){var r=t.color;(0,l.Z)(r)&&(e.style.color=m(r));var i=t.backgroundColor;(0,l.Z)(i)&&(e.style.backgroundColor=m(i));var a=t.textOutline;if((0,l.Z)(a)){var o=a.trim().replace(/\s+/g," ").split(" "),s=o.length;if(3===s){var d=m(o[0]),c=o[1];e.style.textShadow=v(d,c)}else if((0,l.Z)(r)&&1===s){var f=o[0];e.style.textShadow=v(r,f)}else if(2===s){var g=/^[#A-Z]/i.test(o[0]);if(g!==/^[0-9]/.test(o[0]))if(g){var y=m(o[0]),_=o[1];e.style.textShadow=v(y,_)}else if((0,l.Z)(r)){var b=o[0];e.style.textShadow=v(r,b)}}}var T=t.textDecoration;if((0,l.Z)(T))switch(T){case"noUnderline":case"noLineThrough":case"noOverline":e.style.textDecoration="none";break;case"lineThrough":e.style.textDecoration="line-through";break;default:e.style.textDecoration=T}var E=t.fontFamily;if((0,l.Z)(E))switch(E){case"proportionalSansSerif":e.style.fontFamily="Arial, Helvetica, Liberation Sans, sans-serif";break;case"monospaceSansSerif":case"sansSerif":e.style.fontFamily="sans-serif";break;case"monospaceSerif":case"default":e.style.fontFamily="Courier New, Liberation Mono, monospace";break;case"proportionalSerif":e.style.fontFamily="serif";break;default:e.style.fontFamily=E}var w=t.fontStyle;(0,l.Z)(w)&&(e.style.fontStyle=w);var S=t.fontWeight;(0,l.Z)(S)&&(e.style.fontWeight=S);var k=t.fontSize;(0,l.Z)(k)?function(e,t){var n=t.trim().split(" ");if(0!==n.length){var r=h.eT.exec(n[0]);null!==r&&("px"===r[2]||"%"===r[2]||"em"===r[2]?e.style.fontSize=r[1]+r[2]:"c"===r[2]?(e.style.position="relative",u(e,"proportional-style"),e.setAttribute("data-proportional-font-size",r[1])):p.Z.warn("TTML Parser: unhandled fontSize unit:",r[2]))}}(e,k):(u(e,"proportional-style"),e.setAttribute("data-proportional-font-size","1"));var A=t.direction;(0,l.Z)(A)&&(e.style.direction=A);var x=t.unicodeBidi;if((0,l.Z)(x))switch(x){case"bidiOverride":e.style.unicodeBidi="bidi-override";break;case"embed":e.style.unicodeBidi="embed";break;default:e.style.unicodeBidi="normal"}var I=t.visibility;(0,l.Z)(I)&&(e.style.visibility=I),"none"===t.display&&(e.style.display="none");var Z=t.wrapOption;e.style.whiteSpace="noWrap"===Z?n?"nowrap":"pre":n?"normal":"pre-wrap"}function _(e,t){e.style.color="white",e.style.position="absolute";var n=t.extent;(0,l.Z)(n)&&function(e,t){var n=t.trim();if("auto"!==n){var r=n.split(" ");if(2===r.length){var i=h.eT.exec(r[0]),a=h.eT.exec(r[1]);null!==i&&null!==a&&("px"===i[2]||"%"===i[2]||"em"===i[2]?e.style.width=i[1]+i[2]:"c"===i[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-width",i[1])):p.Z.warn("TTML Parser: unhandled extent unit:",i[2]),"px"===a[2]||"%"===a[2]||"em"===a[2]?e.style.height=a[1]+a[2]:"c"===a[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-height",a[1])):p.Z.warn("TTML Parser: unhandled extent unit:",a[2]))}}}(e,n);var r=t.writingMode;(0,l.Z)(r);var i=t.overflow;e.style.overflow=(0,l.Z)(i)?i:"hidden";var a=t.padding;(0,l.Z)(a)&&function(e,t){var n=t.trim().split(" ");if(!(n.length<1)){var r=h.eT.exec(n[0]);if(null!==r){if("px"===r[2]||"%"===r[2]||"em"===r[2]){var i=r[1]+r[2];1===n.length?e.style.padding=i:2===n.length?(e.style.paddingTop=i,e.style.paddingBottom=i):e.style.paddingTop=i}else"c"===r[2]?(u(e,"proportional-style"),1===n.length?(e.setAttribute("data-proportional-padding-top",r[1]),e.setAttribute("data-proportional-padding-bottom",r[1]),e.setAttribute("data-proportional-padding-left",r[1]),e.setAttribute("data-proportional-padding-right",r[1])):2===n.length?(e.setAttribute("data-proportional-padding-top",r[1]),e.setAttribute("data-proportional-padding-bottom",r[1])):e.setAttribute("data-proportional-padding-top",r[1])):p.Z.warn("TTML Parser: unhandled padding unit:",r[2]);if(1!==n.length){var a=h.eT.exec(n[1]);if(null!==a){if("px"===a[2]||"%"===a[2]||"em"===a[2]){var o=a[1]+a[2];n.length<4?(e.style.paddingLeft=o,e.style.paddingRight=o):e.style.paddingRight=o}else"c"===a[2]?(u(e,"proportional-style"),n.length<4?(e.setAttribute("data-proportional-padding-left",a[1]),e.setAttribute("data-proportional-padding-right",a[1])):e.setAttribute("data-proportional-padding-right",a[1])):p.Z.warn("TTML Parser: unhandled padding unit:",a[2]);if(2!==n.length){var s=h.eT.exec(n[2]);if(null!==s){if("px"===s[2]||"%"===s[2]||"em"===s[2]){var l=s[1]+s[2];e.style.paddingBottom=l}else"c"===s[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-padding-bottom",s[1])):p.Z.warn("TTML Parser: unhandled padding unit:",s[2]);if(3!==n.length){var d=h.eT.exec(n[3]);if(null!==d)if("px"===d[2]||"%"===d[2]||"em"===d[2]){var c=d[1]+d[2];e.style.paddingLeft=c}else"c"===d[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-padding-left",d[1])):p.Z.warn("TTML Parser: unhandled padding unit:",d[2])}}}}}}}}(e,a);var o=t.origin;(0,l.Z)(o)&&function(e,t){var n=t.trim();if("auto"!==n){var r=n.split(" ");if(2===r.length){var i=h.eT.exec(r[0]),a=h.eT.exec(r[1]);null!==i&&null!==a&&("px"===i[2]||"%"===i[2]||"em"===i[2]?e.style.left=i[1]+i[2]:"c"===i[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-left",i[1])):p.Z.warn("TTML Parser: unhandled origin unit:",i[2]),"px"===a[2]||"%"===a[2]||"em"===a[2]?e.style.top=a[1]+a[2]:"c"===a[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-top",a[1])):p.Z.warn("TTML Parser: unhandled origin unit:",a[2]))}}}(e,o);var s=t.displayAlign;if((0,l.Z)(s))switch(e.style.display="flex",e.style.flexDirection="column",s){case"before":e.style.justifyContent="flex-start";break;case"center":e.style.justifyContent="center";break;case"after":e.style.justifyContent="flex-end"}var d=t.opacity;(0,l.Z)(d)&&(e.style.opacity=d);var c=t.visibility;(0,l.Z)(c)&&(e.style.visibility=c),"none"===t.display&&(e.style.display="none")}function b(e,t){e.style.margin="0px";var n=t.backgroundColor;(0,l.Z)(n)&&(e.style.backgroundColor=m(n));var r=t.lineHeight;(0,l.Z)(r)&&function(e,t){var n=t.trim();if("auto"!==n){var r=h.eT.exec(n[0]);null!==r&&("px"===r[2]||"%"===r[2]||"em"===r[2]?e.style.lineHeight=r[1]+r[2]:"c"===r[2]?(u(e,"proportional-style"),e.setAttribute("data-proportional-line-height",r[1])):p.Z.warn("TTML Parser: unhandled lineHeight unit:",r[2]))}}(e,r);var i=t.textAlign;if((0,l.Z)(i))switch(i){case"center":e.style.textAlign="center";break;case"left":case"start":e.style.textAlign="left";break;case"right":case"end":e.style.textAlign="right"}}function T(e,t,n){var r=document.createElement("span"),i=null===e.textContent?"":e.textContent;if(n){var a=i.trim();i=a=a.replace(/\s+/g," ")}return r.innerHTML=i,r.className="rxp-texttrack-span",y(r,t,n),r}function E(e,t,n,r,i,a){var o=a.cellResolution,s=a.shouldTrimWhiteSpace,u=(0,c.Z)(e,"div"),p=document.createElement("DIV");if(p.className="rxp-texttrack-region",p.setAttribute("data-resolution-columns",String(o.columns)),p.setAttribute("data-resolution-rows",String(o.rows)),_(p,i),null!==t){var h=(0,f.U)(["backgroundColor"],[].concat(u,[t]),r,n).bodyBackgroundColor;(0,l.Z)(h)&&(p.style.backgroundColor=m(h))}var v=document.createElement("p");v.className="rxp-texttrack-p",b(v,i);for(var y=function(e,t,n,r,i){return function e(r,i,a,o){for(var s=r.childNodes,u=[],c=0;c0){var y=p.getAttribute("xml:space"),_=(0,l.Z)(y)?"default"===y:o,b=(0,d.Z)({},i,(0,f.U)(g,[p],n,t));u.push.apply(u,e(p,b,[p].concat(a),_))}}return u}(e,(0,d.Z)({},r),[],i)}(e,n,r,i,s),E=0;E{"use strict";n.d(t,{Z:()=>f});var r=n(5403),i=n(7253),a=n(1988),o=n(6923),s=n(6177),u=n(5336),l={left:"start",center:"center",right:"end",start:"start",end:"end"},d={left:"line-left",center:"center",right:"line-right"};function c(e){var t=e.paragraph,n=e.timeOffset,r=e.paragraphStyle,c=e.ttParams,f=e.shouldTrimWhiteSpace;if(!t.hasAttribute("begin")&&!t.hasAttribute("end")&&/^\s*$/.test(null===t.textContent?"":t.textContent))return null;var p=(0,s.Z)(t,c),h=p.start,v=p.end,m=function(e,t){function n(e,t){for(var r=e.childNodes,i="",a=0;a|\u2265/g,">").replace(/\u200E/g,"‎").replace(/\u200F/g,"‏").replace(/\u00A0/g," ")}else if("br"===s.nodeName)i+="\n";else if("span"===s.nodeName&&s.nodeType===Node.ELEMENT_NODE&&s.childNodes.length>0){var d=s.getAttribute("xml:space");i+=n(s,(0,o.Z)(d)?"default"===d:t)}}return i}return n(e,t)}(t,f),g=(0,i.Z)(h+n,v+n,m);return null===g?null:((0,a.Z)(g)&&function(e,t){var n=t.extent;if((0,o.Z)(n)){var r=u._0.exec(n);null!=r&&(e.size=Number(r[1]))}switch(t.writingMode){case"tb":case"tblr":e.vertical="lr";break;case"tbrl":e.vertical="rl"}var i=t.origin;if((0,o.Z)(i))u._0.exec(i);var a=t.align;if((0,o.Z)(a)){e.align=a,"center"===a&&("center"!==e.align&&(e.align="middle"),e.position="auto");var s=d[a];e.positionAlign=void 0===s?"":s;var c=l[a];e.lineAlign=void 0===c?"":c}}(g,r),g)}const f=function(e,t){for(var n=(0,r.Z)(e,t),i=[],a=0;a{"use strict";n.d(t,{Z:()=>p});var r=n(3274),i=n(6923),a=n(8026),o=n(3887),s=/(\d+) (\d+)/;var u=n(2967),l=n(3791);var d=n(5138),c=n(7714);var f=["align","backgroundColor","color","direction","display","displayAlign","extent","fontFamily","fontSize","fontStyle","fontWeight","lineHeight","opacity","origin","overflow","padding","textAlign","textDecoration","textOutline","unicodeBidi","visibility","wrapOption","writingMode"];function p(e,t){var n=[],p=(new DOMParser).parseFromString(e,"text/xml");if(null!=p){var h=p.getElementsByTagName("tt")[0];if(void 0===h)throw new Error("invalid XML");for(var v=function(e){return e.getElementsByTagName("body")[0]}(h),m=function(e){return e.getElementsByTagName("style")}(h),g=function(e){return e.getElementsByTagName("region")}(h),y=function(e){return e.getElementsByTagName("p")}(h),_=function(e){var t=e.getAttribute("ttp:frameRate"),n=e.getAttribute("ttp:subFramRate"),r=e.getAttribute("ttp:tickRate"),a=e.getAttribute("ttp:frameRateMultiplier"),u=e.getAttribute("xml:space"),l=e.getAttribute("ttp:cellResolution"),d={columns:32,rows:15};if(null!==l){var c=s.exec(l);if(null===c||c.length<3)o.Z.warn("TTML Parser: Invalid cellResolution");else{var f=parseInt(c[1],10),p=parseInt(c[2],10);isNaN(f)||isNaN(p)?o.Z.warn("TTML Parser: Invalid cellResolution"):d={columns:f,rows:p}}}if((0,i.Z)(u)&&"default"!==u&&"preserve"!==u)throw new Error("Invalid spacing style");var h=Number(t);(isNaN(h)||h<=0)&&(h=30);var v=Number(n);(isNaN(v)||v<=0)&&(v=1);var m=Number(r);(isNaN(m)||m<=0)&&(m=void 0);var g=h,y=null!=v?v:1,_=null!==u?u:"default",b=void 0!==m?m:h*v;if(null!==a){var T=/^(\d+) (\d+)$/g.exec(a);null!==T&&(g=h*(Number(T[1])/Number(T[2])))}return{cellResolution:d,tickRate:b,frameRate:g,subFrameRate:y,spaceStyle:_}}(h),b=[],T=0;T<=m.length-1;T++){var E=m[T];if(E instanceof Element){var w=E.getAttribute("xml:id");if(null!==w){var S=E.getAttribute("style"),k=null===S?[]:S.split(" ");b.push({id:w,style:(0,l.b)(E),extendsStyles:k})}}}!function(e){var t=[];function n(r,i){t.push(i);for(var s=function(i){var s=r.extendsStyles[i],u=(0,d.Z)(e,(function(e){return e.id===s}));if(u<0)o.Z.warn("TTML Parser: unknown style inheritance: "+s);else{var l=e[u];(0,c.Z)(t,u)?o.Z.warn("TTML Parser: infinite style inheritance loop avoided"):n(l,u),r.style=(0,a.Z)({},l.style,r.style)}},u=0;u{"use strict";n.d(t,{YU:()=>f,Dq:()=>c,GK:()=>p,ev:()=>h,eT:()=>d,_0:()=>l,KO:()=>i,gu:()=>r,wf:()=>a,jb:()=>o,te:()=>u,Du:()=>s});var r=/^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/,i=/^(?:(\d{2,}):)?(\d{2}):(\d{2})$/,a=/^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{2,})$/,o=/^(\d*\.?\d*)f$/,s=/^(\d*\.?\d*)t$/,u=/^(?:(\d*\.?\d*)h)?(?:(\d*\.?\d*)m)?(?:(\d*\.?\d*)s)?(?:(\d*\.?\d*)ms)?$/,l=/^(\d{1,2}|100)% (\d{1,2}|100)%$/,d=/^((?:\+|\-)?\d*(?:\.\d+)?)(px|em|c|%|rh|rw)$/,c=/^#([0-9A-f]{2})([0-9A-f]{2})([0-9A-f]{2})([0-9A-f]{2})$/,f=/^#([0-9A-f])([0-9A-f])([0-9A-f])([0-9A-f])$/,p=/^rgb\( *(\d+) *, *(\d+) *, *(\d+) *\)/,h=/^rgba\( *(\d+) *, *(\d+) *, *(\d+) *, *(\d+) *\)/},1138:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(6923),i=n(360);function a(e,t){for(var n=[],a=t;a{"use strict";n.d(t,{Z:()=>x});var r=n(1138),i=n(6923),a=n(360);var o=n(9525),s={white:"#ffffff",lime:"#00ff00",cyan:"#00ffff",red:"#ff0000",yellow:"#ffff00",magenta:"#ff00ff",blue:"#0000ff",black:"#000000"};function u(e){var t=Object.keys(s).reduce((function(e,t){return e[t]="color: "+s[t]+";",e["bg_"+t]="background-color: "+s[t]+";",e}),{}),n="";return e.forEach((function(e){if(e.length>=2)for(var r=1;r0&&n.appendChild(document.createElement("br")),o[s].length>0){var u=document.createTextNode(o[s]);n.appendChild(u)}}else{var c=e.nodeName.toLowerCase().split("."),f=[];if(c.forEach((function(e){(0,i.Z)(t[e])&&f.push(t[e])})),0!==f.length){var p=document.createAttribute("style");f.forEach((function(e){p.value+=e}));var h=(0,l.Z)(r,a)?a:"span";(n=document.createElement(h)).setAttributeNode(p)}else{var v=(0,l.Z)(r,a)?a:"span";n=document.createElement(v)}for(var m=0;m/,"").replace(/<([u,i,b,c])(\..*?)?(?: .*?)?>(.*?)<\/\1>/g,"<$1$2>$3"),r=(new DOMParser).parseFromString(n,"text/html").body.childNodes,i=[],a=0;a{"use strict";n.d(t,{Z:()=>c});var r=n(1988),i=n(1138),a=n(9525),o=n(360),s=n(7714),u=n(6923);function l(e,t){if(!(0,u.Z)(e.vertical)||"rl"!==e.vertical&&"lr"!==e.vertical||(t.vertical=e.vertical),(0,u.Z)(e.line)){var n=/^(\d+(\.\d+)?)%(,([a-z]+))?/.exec(e.line);if(Array.isArray(n))t.line=Number(n[1]),t.snapToLines=!1,(0,s.Z)(["start","center","end"],n[4])&&(t.lineAlign=n[4]);else{var r=/^(-?\d+)(,([a-z]+))?/.exec(e.line);Array.isArray(r)&&(t.line=Number(r[1]),t.snapToLines=!0,(0,s.Z)(["start","center","end"],r[3])&&(t.lineAlign=r[3]))}}if((0,u.Z)(e.position)){var i=/^([\d\.]+)%(?:,(line-left|line-right|center))?$/.exec(e.position);if(Array.isArray(i)&&i.length>=2){var a=parseInt(i[1],10);isNaN(a)||(t.position=a,void 0!==i[2]&&(t.positionAlign=i[2]))}}(0,u.Z)(e.size)&&(t.size=e.size),"string"==typeof e.align&&(0,s.Z)(["start","center","end","left"],e.align)&&(t.align=e.align)}var d=n(7253);const c=function(e,t){var n=e.split(/\r\n|\n|\r/);if(!/^WEBVTT($| |\t)/.test(n[0]))throw new Error("Can't parse WebVTT: Invalid file.");for(var s,u,c,f,p=(0,o.yE)(n),h=(0,i.Z)(n,p),v=[],m=0;m{"use strict";n.d(t,{Z:()=>a});var r=n(6923);function i(e){var t=e.split(":").reverse();if((0,r.Z)(t[2])||(0,r.Z)(t[1])){var n=(0,r.Z)(t[2])?parseInt(t[2],10):0,i=parseInt(t[1],10),a=parseFloat(t[0].replace(",","."));if(isNaN(n)||isNaN(i)||isNaN(a))return;return 60*n*60+60*i+a}}function a(e,t){var n,r,a,o=/-->/;if(o.test(e[0]))n=e[0],r=e.slice(1,e.length);else{if(!o.test(e[1]))return null;a=e[0],n=e[1],r=e.slice(2,e.length)}var s=function(e){var t=/^([\d:.]+)[ |\t]+-->[ |\t]+([\d:.]+)[ |\t]*(.*)$/.exec(e);if(null===t)return null;var n=i(t[1]),r=i(t[2]);return null==n||null==r?null:{start:n,end:r,settings:t[3].split(/ |\t/).reduce((function(e,t){var n=t.split(":");return 2===n.length&&(e[n[0]]=n[1]),e}),{})}}(n);return null===s?null:{start:s.start+t,end:s.end+t,settings:s.settings,payload:r,header:a}}},360:(e,t,n)=>{"use strict";n.d(t,{yE:()=>i,tq:()=>o,JF:()=>a,$4:()=>s});var r=n(6923);function i(e){for(var t=0;t=0)return!0;var r=e[t+1];return void 0!==r&&r.indexOf("--\x3e")>=0}function s(e,t){for(var n=t+1;(0,r.Z)(e[n]);)n++;return n}},1923:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Wt});var r=n(7278),i=n(8170),a=n(7874),o=n(4597),s=n(5278);function u(e){var t=e.segment,n=e.url;return t.isInit||null===n?(0,i.of)({type:"data-created",value:{responseData:null}}):(0,o.ZP)({url:n,responseType:"arraybuffer",sendProgressEvents:!0})}function l(e){var t=e.response,n=e.content,r=n.segment,o=n.period,u=t.data,l=t.isChunked;if(n.segment.isInit)return(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}});if(l)throw new Error("Image data should not be downloaded in chunks");var d=(0,s.Z)(r.timestampOffset,0);if(null===u||null===a.Z.imageParser)return(0,i.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:{duration:r.duration,time:r.time},chunkOffset:d,appendWindow:[o.start,o.end]}});var c=a.Z.imageParser(new Uint8Array(u)),f=c.thumbs;return(0,i.of)({type:"parsed-segment",value:{chunkData:{data:f,start:0,end:Number.MAX_VALUE,timescale:1,type:"bif"},chunkInfos:{time:0,duration:Number.MAX_VALUE,timescale:c.timescale},chunkOffset:d,appendWindow:[o.start,o.end]}})}var d=n(9795),c=n(5142),f=n(6008),p=n(5709),h=n(7746),v=n(1966),m=n(944),g=n(3887),y=n(3274),_=n(9829);function b(e){return 0===e.length?0:e.reduce((function(e,t){var n;return Math.min(null!==(n=t.attributes.availabilityTimeOffset)&&void 0!==n?n:0,e)}),1/0)}function T(e){var t=Date.parse(e)-performance.now();if(!isNaN(t))return t;g.Z.warn("DASH Parser: Invalid clock received: ",e)}function E(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,o=null;if(void 0!==r){var s=E(r);if(void 0===s)return;a=s}if(void 0!==i){var u=E(i);if(void 0===u)return;o=u}if(void 0!==r&&null===a||void 0!==i&&null===o)return void g.Z.info("Parser utils: found Period with no segment. ","Going to previous one to calculate last position");if(null!==o)return null!==a?Math.min(a,o):o;if(null!==a)return a}}}function S(e){for(var t=e.representations,n=null,r=0;r0){var o=F(a,"cenc:pssh"),s=o[0],u=o[1];null!==u&&(g.Z.warn(u.message),t.push(u)),null!==s&&n.push(s)}}}return[{cencPssh:n},t]}(e.childNodes),n=t[0],r=t[1];return[{children:n,attributes:function(e){for(var t={},n=0;n0&&(n=n.concat(d));break;case"SegmentList":var c=Q(i),f=c[0],p=c[1];n=n.concat(p),t.segmentList=f;break;case"SegmentTemplate":var h=ee(i),v=h[0],m=h[1];n=n.concat(m),t.segmentTemplate=v}}return[t,n]}(e.childNodes),n=t[0],r=t[1],i=function(e){for(var t={},n=[],r=K(t,n),i=0;i0&&(r=r.concat(u));break;case"ContentComponent":t.contentComponent=G(a);break;case"EssentialProperty":null==t.essentialProperties?t.essentialProperties=[z(a)]:t.essentialProperties.push(z(a));break;case"InbandEventStream":void 0===t.inbandEventStreams&&(t.inbandEventStreams=[]),t.inbandEventStreams.push(z(a));break;case"Representation":var l=te(a),d=l[0],c=l[1];t.representations.push(d),c.length>0&&(r=r.concat(c));break;case"Role":null==t.roles?t.roles=[z(a)]:t.roles.push(z(a));break;case"SupplementalProperty":null==t.supplementalProperties?t.supplementalProperties=[z(a)]:t.supplementalProperties.push(z(a));break;case"SegmentBase":var f=Y(a),p=f[0],h=f[1];t.segmentBase=p,h.length>0&&(r=r.concat(h));break;case"SegmentList":var v=Q(a),m=v[0],g=v[1];t.segmentList=m,g.length>0&&(r=r.concat(g));break;case"SegmentTemplate":var y=ee(a),_=y[0],b=y[1];t.segmentTemplate=_,b.length>0&&(r=r.concat(b));break;case"ContentProtection":var T=$(a),E=T[0],w=T[1];w.length>0&&(r=r.concat(w)),void 0!==E&&n.push(E)}}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=K(t,n),i=0;i0&&(i=i.concat(_))}}return[{baseURLs:n,adaptations:r,streamEvents:a,segmentTemplate:t},i]}(e.childNodes),n=t[0],r=t[1],i=function(e){for(var t={},n=[],r=K(t,n),i=0;i=a?o:(new Array(a+1).join("0")+o).slice(-a)}}function ge(e,t,n,r){return 0===e.length?void 0!==t?[ye(t,n,r)]:null:e.map((function(e){return ye((0,_.Z)(e,t),n,r)}))}function ye(e,t,n){return-1===e.indexOf("$")?e:e.replace(/\$\$/g,"$").replace(/\$RepresentationID\$/g,String(t)).replace(/\$Bandwidth(|\%0(\d+)d)\$/g,me(void 0===n?0:n))}function _e(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 me(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 me(e)(t,n,r)}))}}function be(e,t,n,r,i){for(var a,o,s=(0,he.gT)(t,e),u=(0,he.gT)(t+n,e),l=e.timeline,d=e.timescale,c=e.mediaURLs,f=e.startNumber,p=null!=f?f:void 0,h=[],v=l.length,m=l.length>0&&null!=l[0].duration?l[0].duration:0,g=0;g0?Math.floor(o/a):0),S=b+w*_;S=u)return h;null!=p&&(p+=E+1)}return h}function Te(e,t){if(t.timescale!==e.timescale){var n=e.timescale;e.timeline.push({start:t.time/t.timescale*n,duration:t.duration/t.timescale*n,repeatCount:void 0===t.count?0:t.count,range:t.range})}else e.timeline.push({start:t.time,duration:t.duration,repeatCount:void 0===t.count?0:t.count,range:t.range});return!0}var Ee=function(){function e(e,t){var n,r,i=t.periodStart,a=t.periodEnd,o=t.representationBaseURLs,s=t.representationId,u=t.representationBitrate,l=t.isEMSGWhitelisted,d=null!==(n=e.timescale)&&void 0!==n?n:1,c=(null!=e.presentationTimeOffset?e.presentationTimeOffset:0)-i*d,f=ge(o,void 0!==e.initialization?e.initialization.media:void 0,s,u),p=void 0!==e.initialization?e.initialization.range:void 0!==e.indexRange?[0,e.indexRange[0]-1]:void 0;this._index={indexRange:e.indexRange,indexTimeOffset:c,initialization:{mediaURLs:f,range:p},mediaURLs:ge(o,e.media,s,u),startNumber:e.startNumber,timeline:null!==(r=e.timeline)&&void 0!==r?r:[],timescale:d},this._scaledPeriodEnd=null==a?void 0:(0,he.gT)(a,this._index),this._isInitialized=this._index.timeline.length>0,this._isEMSGWhitelisted=l}var t=e.prototype;return t.getInitSegment=function(){return ve(this._index,this._isEMSGWhitelisted)},t.getSegments=function(e,t){return be(this._index,e,t,this._isEMSGWhitelisted,this._scaledPeriodEnd)},t.shouldRefresh=function(){return!1},t.getFirstPosition=function(){var e=this._index;return 0===e.timeline.length?null:(0,he.zG)(e.timeline[0].start,e)},t.getLastPosition=function(){var e=this._index.timeline;if(0===e.length)return null;var t=e[e.length-1],n=(0,he.jH)(t,null,this._scaledPeriodEnd);return(0,he.zG)(n,this._index)},t.isSegmentStillAvailable=function(){return!0},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},t._addSegments=function(e){for(var t=0;t0&&(this._isInitialized=!0)},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){return!0},t.isInitialized=function(){return this._isInitialized},t._replace=function(e){this._index=e._index},t._update=function(){g.Z.error("Base RepresentationIndex: Cannot update a SegmentList")},e}(),we=function(){function e(e,t){var n,r=t.periodStart,i=t.representationBaseURLs,a=t.representationId,o=t.representationBitrate,s=t.isEMSGWhitelisted;this._isEMSGWhitelisted=s,this._periodStart=r;var u=null!=e.presentationTimeOffset?e.presentationTimeOffset:0,l=null!==(n=e.timescale)&&void 0!==n?n:1,d=u-r*l,c=e.list.map((function(e){return{mediaURLs:ge(i,e.media,a,o),mediaRange:e.mediaRange}}));this._index={list:c,timescale:l,duration:e.duration,indexTimeOffset:d,indexRange:e.indexRange,initialization:null==e.initialization?void 0:{mediaURLs:ge(i,e.initialization.media,a,o),range:e.initialization.range}}}var t=e.prototype;return t.getInitSegment=function(){var e=ve(this._index);return void 0===e.privateInfos&&(e.privateInfos={}),e.privateInfos.isEMSGWhitelisted=this._isEMSGWhitelisted,e},t.getSegments=function(e,t){for(var n=this._index,r=n.duration,i=n.list,a=n.timescale,o=r/a,s=e-this._periodStart,u=(0,he.PZ)(s,t,a),l=u[0],d=u[1],c=Math.min(i.length-1,Math.floor(d/r)),f=[],p=Math.floor(l/r);p<=c;){var h=i[p].mediaRange,v=i[p].mediaURLs,m=p*o+this._periodStart,g={id:String(p),time:m,isInit:!1,range:h,duration:o,timescale:1,end:m+o,mediaURLs:v,timestampOffset:-n.indexTimeOffset/a,privateInfos:{isEMSGWhitelisted:this._isEMSGWhitelisted}};f.push(g),p++}return f},t.shouldRefresh=function(e,t){var n=this._index,r=n.timescale,i=n.duration,a=n.list,o=t*r,s=Math.floor(o/i);return s<0||s>=a.length},t.getFirstPosition=function(){return this._periodStart},t.getLastPosition=function(){var e=this._index,t=e.duration;return e.list.length*t/e.timescale+this._periodStart},t.isSegmentStillAvailable=function(){return!0},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},t.canBeOutOfSyncError=function(){return!1},t.isFinished=function(){return!0},t.isInitialized=function(){return!0},t._replace=function(e){this._index=e._index},t._update=function(){g.Z.error("List RepresentationIndex: Cannot update a SegmentList")},e}(),Se=n(9362),ke=n(8232),Ae=n(1091),xe=n(5505),Ie=m.Z.DEFAULT_MAXIMUM_TIME_ROUNDING_ERROR;function Ze(e,t,n){return t+Ie*e>=n}function Re(e,t,n,r){var i=e.start,a=e.duration,o=e.repeatCount;return null==i&&(null==t?i=r:null!=t.duration&&(i=t.start+t.duration*(t.repeatCount+1))),null!=a&&!isNaN(a)||null==n||null==n.start||isNaN(n.start)||null==i||isNaN(i)||(a=n.start-i),null==i||isNaN(i)||null==a||isNaN(a)||null!=o&&isNaN(o)?(g.Z.warn('DASH: A "S" Element could not have been parsed.'),null):{start:i,duration:a,repeatCount:void 0===o?0:o}}function Me(e){for(var t={},n=0;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],d=i;;){var c=l.getAttribute("d"),f=null===c?null:parseInt(c,10);if(null===f||Number.isNaN(f))return null;var p=l.getAttribute("r"),h=null===p?null:parseInt(p,10);if(null!==h){if(Number.isNaN(h)||h<0)return null;if(h>0){var v=n-d;if(v%f==0&&v/f<=h)return{repeatNumberInPrevSegments:0,repeatNumberInNewElements:v/f,prevSegmentsIdx:0,newElementsIdx:u}}d+=f*(h+1)}else d+=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;d=g}if(d===n)return{newElementsIdx:u,prevSegmentsIdx:0,repeatNumberInPrevSegments:0,repeatNumberInNewElements:0};if(d>i)return null}}(t,e);if(null===i)return g.Z.warn('DASH: Cannot perform "based" update. Common segment not found.'),Ce(e,n);var a=i.prevSegmentsIdx,o=i.newElementsIdx,s=i.repeatNumberInPrevSegments,u=i.repeatNumberInNewElements,l=t.length-a+o-1;if(l>=e.length)return g.Z.info('DASH: Cannot perform "based" update. New timeline too short'),Ce(e,n);var d=t.slice(a);if(s>0){var c=d[0];c.start+=c.duration*s,d[0].repeatCount-=s}if(u>0&&0!==o)return g.Z.info('DASH: Cannot perform "based" update. The new timeline has a different form.'),Ce(e,n);var f=d[d.length-1],p=Me(e[l]),h=(null!==(r=p.repeatCount)&&void 0!==r?r:0)-u;if(p.duration!==f.duration||f.repeatCount>h)return g.Z.info('DASH: Cannot perform "based" update. The new timeline has a different form at the beginning.'),Ce(e,n);void 0!==p.repeatCount&&p.repeatCount>f.repeatCount&&(f.repeatCount=p.repeatCount);for(var v=[],m=[],y=l+1;yu?u-y:r,T=y+s,E=y+this._index.presentationTimeOffset,w=null===o?null:o.map(_e(E,_)),S={id:String(_),number:_,time:T/a,end:(T+b)/a,duration:b/a,timescale:1,isInit:!1,scaledDuration:b/a,mediaURLs:w,timestampOffset:-n.indexTimeOffset/a,privateInfos:{isEMSGWhitelisted:this._isEMSGWhitelisted}};v.push(S),g++}return v},t.getFirstPosition=function(){var e=this._getFirstSegmentStart();return null==e?e:e/this._index.timescale+this._periodStart},t.getLastPosition=function(){var e=this._getLastSegmentStart();return null==e?e:(e+this._index.duration)/this._index.timescale+this._periodStart},t.shouldRefresh=function(){return!1},t.checkDiscontinuity=function(){return null},t.areSegmentsChronologicallyGenerated=function(){return!0},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._scaledPeriodEnd)return!1;var e=this._index.timescale,t=this._getLastSegmentStart();return null!=t&&Ze(e,t+this._index.duration,this._scaledPeriodEnd)},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._scaledPeriodEnd=e._scaledPeriodEnd,this._manifestBoundsCalculator=e._manifestBoundsCalculator},t._update=function(e){this._replace(e)},t._getFirstSegmentStart=function(){if(!this._isDynamic)return 0;if(0===this._scaledPeriodEnd||void 0===this._scaledPeriodEnd){var e=this._manifestBoundsCalculator.estimateMaximumBound();if(void 0!==e&&ethis._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 a=this._aggressiveMode?n/r:0;if(null!=this._scaledPeriodEnd&&this._scaledPeriodEnd<(i+a-this._periodStart)*this._index.timescale)return this._scaledPeriodEndDe*r||0===d?c:(d-1)*n},e}();function Be(e,t){var n=[];if(0===t.length)return e;if(0===e.length){for(var r=0;r0){var _=t.parentSegmentTemplates.slice(),T=e.children.segmentTemplate;void 0!==T&&_.push(T);var E=q.Z.apply(void 0,[{}].concat(_));m.availabilityTimeOffset=t.availabilityTimeOffset+b(e.children.baseURLs)+(null!==(r=E.availabilityTimeOffset)&&void 0!==r?r:0);var w=E.timelineParser;i=void 0!==w?new Oe(E,w,m):new Le(E,m)}else{var S=t.adaptation.children;if(void 0!==S.segmentBase){var k=S.segmentBase;i=new Ee(k,m)}else if(void 0!==S.segmentList){var A=S.segmentList;i=new we(A,m)}else i=new Le({duration:Number.MAX_VALUE,timescale:1,startNumber:0,initialization:{media:""},media:""},m)}return i}(s,(0,q.Z)({},n,{unsafelyBaseOnPreviousRepresentation:l,adaptation:t,inbandEventStreams:d})),f=void 0;null==s.attributes.bitrate?(g.Z.warn("DASH: No usable bitrate found in the Representation."),f=0):f=s.attributes.bitrate;var p={bitrate:f,index:c,id:u},h=void 0;if(null!=s.attributes.codecs?h=s.attributes.codecs:null!=t.attributes.codecs&&(h=t.attributes.codecs),null!=h&&(h="mp4a.40.02"===h?"mp4a.40.2":h,p.codecs=h),null!=s.attributes.frameRate?p.frameRate=s.attributes.frameRate:null!=t.attributes.frameRate&&(p.frameRate=t.attributes.frameRate),null!=s.attributes.height?p.height=s.attributes.height:null!=t.attributes.height&&(p.height=t.attributes.height),null!=s.attributes.mimeType?p.mimeType=s.attributes.mimeType:null!=t.attributes.mimeType&&(p.mimeType=t.attributes.mimeType),null!=s.attributes.width?p.width=s.attributes.width:null!=t.attributes.width&&(p.width=t.attributes.width),null!=t.children.contentProtections){var v=t.children.contentProtections.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&&e.keyIds.push({keyId:t.attributes.keyId,systemId:n}),void 0!==n){for(var r=t.children.cencPssh,i=[],a=0;a0){var s,u=(0,y.Z)(e.initData,(function(e){return"cenc"===e.type}));if(void 0===u)e.initData.push({type:"cenc",values:i});else(s=u.values).push.apply(s,i)}}return e}),{keyIds:[],initData:[]});(Object.keys(v.initData).length>0||v.keyIds.length>0)&&(p.contentProtections=v)}a.push(p)},s=0;s0&&void 0!==l.video){var Z,M=o.video[l.video];I.unsafelyBaseOnPreviousAdaptation=null!==(r=null===(n=t.unsafelyBaseOnPreviousPeriod)||void 0===n?void 0:n.getAdaptation(M.id))&&void 0!==r?r:null;var C=Ue(m,c,I);(Z=M.representations).push.apply(Z,C),k=M.id}else{var N=f.accessibilities,P=void 0;void 0!==h&&h.some((function(e){return"dub"===e.value}))&&(P=!0);var O=void 0;"text"!==w?O=!1:void 0!==N&&(O=N.some(ze));var D=void 0;"audio"!==w?D=!1:void 0!==N&&(D=N.some(Fe));var L=void 0;"video"!==w?L=!1:void 0!==N&&(L=N.some(Ke));for(var B=Ve(c,{isAudioDescription:D,isClosedCaption:O,isSignInterpreted:L,type:w});(0,de.Z)(u,B);)B+="-dup";k=B,u.push(B),I.unsafelyBaseOnPreviousAdaptation=null!==(a=null===(i=t.unsafelyBaseOnPreviousPeriod)||void 0===i?void 0:i.getAdaptation(B))&&void 0!==a?a:null;var U={id:B,representations:Ue(m,c,I),type:w};null!=c.attributes.language&&(U.language=c.attributes.language),null!=O&&(U.closedCaption=O),null!=D&&(U.audioDescription=D),!0===P&&(U.isDub=!0),!0===L&&(U.isSignInterpreted=!0);var F=o[w];if(void 0===F)o[w]=[U],v&&(l[w]=0);else{for(var z=null,K=function(e){var t=A[e],n=s[t];if(null!=n&&n.newID!==k&&(0,de.Z)(n.adaptationSetSwitchingIDs,S)){var r,i=(0,y.Z)(F,(function(e){return e.id===t}));null!=i&&i.audioDescription===U.audioDescription&&i.closedCaption===U.closedCaption&&i.language===U.language&&(g.Z.info('DASH Parser: merging "switchable" AdaptationSets',S,t),(r=i.representations).push.apply(r,U.representations),z=i)}},V=0;VW)&&(F.splice(H,1),F.splice(G,0,z),l[w]=G)}}else null===z&&F.push(U)}}null!=S&&null==s[S]&&(s[S]={newID:k,adaptationSetSwitchingIDs:A})}}}return o}(c.children.adaptations,k),x=null===(i=c.children.streamEvents)||void 0===i?void 0:i.map((function(e){var t,n=(null!==(t=e.eventPresentationTime)&&void 0!==t?t:0)/e.timescale+v;return{start:n,end:void 0!==e.duration?n+e.duration/e.timescale:void 0,data:e.data,id:e.id}})),I={id:T,start:v,end:_,duration:m,adaptations:A,streamEvents:x};if(a.unshift(I),!l.lastPositionIsKnown()){var Z=function(e){for(var t=null,n=!0,r=(0,ue.Z)(e).filter((function(e){return null!=e})),i=(0,oe.Z)(r,(function(e){return e})),a=0;a=0;c--)d(c);if(t.isDynamic&&!l.lastPositionIsKnown()){var f=$e(t,0);if(void 0!==f){var p=f[0],h=f[1];l.setLastPosition(p,h)}}return function(e){if(0===e.length)return[];for(var t=[e[0]],n=1;nr.start;)g.Z.warn("DASH: Updating overlapping Periods.",i,r),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}(a)}function $e(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 g.Z.warn("DASH Parser: no clock synchronization mechanism found. Using the system clock instead."),[a-e.availabilityStartTime,performance.now()/1e3]}}var je=m.Z.DASH_FALLBACK_LIFETIME_WHEN_MINIMUM_UPDATE_PERIOD_EQUAL_0;function Ye(e,t){var n=ae(e);return qe(n[0],t,n[1])}function qe(e,t,n,r){var i=e.children,a=e.attributes,o=new WeakMap;if(null==t.externalClockOffset){var s="dynamic"===a.type,u=(0,y.Z)(i.utcTimings,(function(e){return"urn:mpeg:dash:utc:direct:2014"===e.schemeIdUri&&null!=e.value})),l=null!=u&&null!=u.value?T(u.value):void 0,d=null==l||isNaN(l)?void 0:l;if(null!=d)t.externalClockOffset=d;else if(s&&!0!==r){var c=function(e){var t=e.children.utcTimings.filter((function(e){return"urn:mpeg:dash:utc:http-iso:2014"===e.schemeIdUri&&void 0!==e.value}));return t.length>0?t[0].value:void 0}(e);if(null!=c&&c.length>0)return{type:"needs-ressources",value:{ressources:[c],continue:function(r){if(1!==r.length)throw new Error("DASH parser: wrong number of loaded ressources.");return d=T(r[0].responseData),t.externalClockOffset=d,qe(e,t,n,!0)}}}}}for(var f=[],p=0;p=0&&(o=0===d.minimumUpdatePeriod?je:d.minimumUpdatePeriod);var x=function(e){if(0===e.length)throw new Error("DASH Parser: no period available for a dynamic content");return[k(e),w(e)]}(E),I=x[0],Z=x[1],R=performance.now();if(c){var M;if(s=I,A=null!=h?h:null,void 0!==Z)M=Z;else{var C=null!=p?p:0,N=t.externalClockOffset;if(void 0===N)g.Z.warn("DASH Parser: use system clock to define maximum position"),M=Date.now()/1e3-C;else M=(performance.now()+N)/1e3-C}u={isLinear:!0,value:M,time:R},null!==A&&void 0!==s&&M-s>A&&(A=M-s)}else{var P;if(s=void 0!==I?I:void 0!==(null===(i=E[0])||void 0===i?void 0:i.start)?E[0].start:0,void 0!==Z)P=Z;else if(void 0!==S)P=S;else if(void 0!==E[E.length-1]){var O=E[E.length-1];P=null!==(a=O.end)&&void 0!==a?a:void 0!==O.duration?O.start+O.duration:void 0}u={isLinear:!1,value:null!=P?P:1/0,time:R}}return{type:"done",value:{parsed:{availabilityStartTime:p,clockOffset:t.externalClockOffset,isDynamic:c,isLive:c,periods:E,publishTime:d.publishTime,suggestedPresentationDelay:d.suggestedPresentationDelay,transportType:"dash",timeBounds:{absoluteMinimumTime:s,timeshiftDepth:A,maximumTimeData:u},lifetime:o,uris:null==t.url?l.locations:[t.url].concat(l.locations)},warnings:n}}}(e,t,n,o):{type:"needs-ressources",value:{ressources:f.map((function(e){return e.ressource})),continue:function(r){if(r.length!==f.length)throw new Error("DASH parser: wrong number of loaded ressources.");for(var a=r.length-1;a>=0;a--){var s,u=f[a].index,l=r[a],d=l.responseData,c=l.receivedTime,p=l.sendingTime,h=l.url,v=""+d+"",m=(new DOMParser).parseFromString(v,"text/xml");if(null==m||0===m.children.length)throw new Error("DASH parser: Invalid external ressources");for(var g=m.children[0].children,y=[],_=0;_0&&n.push.apply(n,E)}(s=i.periods).splice.apply(s,[u,1].concat(y))}return qe(e,t,n)}}}}const Xe=function(e,t){var n=e.documentElement;if(null==n||"MPD"!==n.nodeName)throw new Error("DASH Parser: document root should be MPD");return Ye(n,t)};var Qe=n(7445);function Je(e){var t=e.aggressiveMode,n=e.referenceDateTime,r=void 0!==e.serverSyncInfos?e.serverSyncInfos.serverTimestamp-e.serverSyncInfos.clientTime:void 0;return function(a){var s,u=a.response,l=a.scheduleRequest,m=a.externalClockOffset,g=a.url,y=null!==(s=u.url)&&void 0!==s?s:g,_="string"==typeof u.responseData?(new DOMParser).parseFromString(u.responseData,"text/xml"):u.responseData,b=null!=r?r:m,T=a.unsafeMode?a.previousManifest:null;return function t(n){if("done"===n.type){var r=n.value,a=r.warnings,s=r.parsed,u=a.map((function(e){return{type:"warning",value:e}})),m=new v.ZP(s,e);return(0,d.z)(i.of.apply(void 0,u),(0,Qe.Z)(m,y))}var g=n.value,_=g.ressources,b=g.continue,T=_.map((function(e){return l((function(){return function(e){return(0,o.ZP)({url:e,responseType:"text"}).pipe((0,f.h)((function(e){return"data-loaded"===e.type})),(0,p.U)((function(e){return e.value})))}(e)}))}));return(0,c.aj)(T).pipe((0,h.zg)((function(e){for(var n=[],r=0;r=300)return g.Z.warn("Fetch: Request HTTP Error",e),void n.error(new at.Z(e.url,e.status,ot.br.ERROR_HTTP_CODE));if(!(0,st.Z)(e.body)){var t=e.headers.get("Content-Length"),r=(0,st.Z)(t)||isNaN(+t)?void 0:+t,i=e.body.getReader(),s=0;return u()}function u(){return l.apply(this,arguments)}function l(){return(l=nt(it().mark((function t(){var l,d,c,f,p;return it().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,i.read();case 2:if((l=t.sent).done||(0,st.Z)(l.value)){t.next=11;break}return s+=l.value.byteLength,d=performance.now(),c={type:"data-chunk",value:{url:e.url,currentTime:d,duration:d-o,sendingTime:o,chunkSize:l.value.byteLength,chunk:l.value.buffer,size:s,totalSize:r}},n.next(c),t.abrupt("return",u());case 11:l.done&&(f=performance.now(),p=f-o,a=!0,n.next({type:"data-complete",value:{duration:p,receivedTime:f,sendingTime:o,size:s,status:e.status,url:e.url}}),n.complete());case 12:case"end":return t.stop()}}),t)})))).apply(this,arguments)}n.error(new at.Z(e.url,e.status,ot.br.PARSE_ERROR))})).catch((function(t){if(r)g.Z.debug("Fetch: Request aborted.");else{if(i)return g.Z.warn("Fetch: Request timeouted."),void n.error(new at.Z(e.url,0,ot.br.TIMEOUT));g.Z.warn("Fetch: Request Error",t instanceof Error?t.toString():""),n.error(new at.Z(e.url,0,ot.br.ERROR_EVENT))}})),function(){r=!0,u()}}))};var pt=n(8806),ht=n(281);function vt(e){return"video/webm"===e.mimeType||"audio/webm"===e.mimeType}var mt=n(3068),gt=n(4460);function yt(e){return function(t){return e(t).pipe((0,mt.b)((function(e){"data-loaded"!==e.type&&"data-chunk"!==e.type||null===e.value.responseData||"string"==typeof e.value.responseData||vt(t.representation)||(0,gt.Z)(new Uint8Array(e.value.responseData),t.segment.isInit)})))}}var _t=n(6968);function bt(e,t){var n=t.segment;if(void 0===n.range)return(0,o.ZP)({url:e,responseType:"arraybuffer",sendProgressEvents:!0});if(void 0===n.indexRange)return(0,o.ZP)({url:e,headers:{Range:(0,ht.Z)(n.range)},responseType:"arraybuffer",sendProgressEvents:!0});if(n.range[1]+1===n.indexRange[0])return(0,o.ZP)({url:e,headers:{Range:(0,ht.Z)([n.range[0],n.indexRange[1]])},responseType:"arraybuffer",sendProgressEvents:!0});var r=(0,o.ZP)({url:e,headers:{Range:(0,ht.Z)(n.range)},responseType:"arraybuffer",sendProgressEvents:!1}),i=(0,o.ZP)({url:e,headers:{Range:(0,ht.Z)(n.indexRange)},responseType:"arraybuffer",sendProgressEvents:!1});return(0,c.aj)([r,i]).pipe((0,p.U)((function(t){var n=t[0],r=t[1],i=(0,_t.zo)(new Uint8Array(n.value.responseData),new Uint8Array(r.value.responseData)),a=Math.min(n.value.sendingTime,r.value.sendingTime),o=Math.max(n.value.receivedTime,r.value.receivedTime);return{type:"data-loaded",value:{url:e,responseData:i,size:n.value.size+r.value.size,duration:o-a,sendingTime:a,receivedTime:o}}})))}var Tt=n(2807),Et=n(8766);function wt(e,t){var n=t.segment,r=void 0!==n.range?{Range:(0,ht.Z)(n.range)}:void 0;return ft({url:e,headers:r}).pipe((0,Tt.R)((function(e,t){if("data-complete"===t.type)return null!==e.partialChunk&&g.Z.warn("DASH Pipelines: remaining chunk does not belong to any segment"),{event:t,completeChunks:[],partialChunk:null};var n=new Uint8Array(t.value.chunk),r=function(e){for(var t=0,n=[];te.length)return[n,r];var o=(0,Et.Z)(r,1835295092);if(o<0)return[n,r];var s=t+o+(0,_t.pX)(e,o+t);if(s>e.length)return[n,r];var u=Math.max(a,s),l=e.subarray(t,u);n.push(l),t=u}return[n,null]}(null!==e.partialChunk?(0,_t.zo)(e.partialChunk,n):n);return{event:t,completeChunks:r[0],partialChunk:r[1]}}),{event:null,completeChunks:[],partialChunk:null}),(0,h.zg)((function(e){for(var t=[],n=0;n0)for(var p=0;p=Math.pow(2,8-n))return n}function Nt(e,t){var n=Ct(e,t);if(null==n)return g.Z.warn("webm: unrepresentable length"),null;if(t+n>e.length)return g.Z.warn("webm: impossible length"),null;for(var r=0,i=0;ie.length)return g.Z.warn("webm: impossible length"),null;for(var r=(e[t]&(1<<8-n)-1)*Math.pow(2,8*(n-1)),i=1;i=i)return!0}return!1}(r,t)}}}function Bt(e){var t=e.__priv_patchLastSegmentInSidx;return function(e){var n=e.content,r=e.response,a=e.initTimescale,o=n.period,u=n.representation,l=n.segment,d=n.manifest,c=r.data,f=r.isChunked,p=[o.start,o.end];if(null===c)return l.isInit?(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}}):(0,i.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:p}});var h=c instanceof Uint8Array?c:new Uint8Array(c),v=vt(u);if(!l.isInit){var m=v?null:Dt(h,f,l,a),g=(0,s.Z)(l.timestampOffset,0);if(!v){var y=(0,kt.s9)(h);if(void 0!==y){var _=Lt(y.filter((function(e){return void 0!==l.privateInfos&&void 0!==l.privateInfos.isEMSGWhitelisted&&l.privateInfos.isEMSGWhitelisted(e)})),d.publishTime);if(void 0!==_){var b=_.needsManifestRefresh,T=_.inbandEvents;return(0,i.of)({type:"parsed-segment",value:{chunkData:h,chunkInfos:m,chunkOffset:g,appendWindow:p,inbandEvents:T,needsManifestRefresh:b}})}}}return(0,i.of)({type:"parsed-segment",value:{chunkData:h,chunkInfos:m,chunkOffset:g,appendWindow:p}})}var E,w=l.indexRange;if(v)E=function(e,t){var n=Zt(xt,[],e,[t,e.length]);if(null==n)return null;var r=n[0],i=n[1],a=Rt(e,r);if(null==a)return null;var o=Mt(e,r);if(null==o)return null;var s=Zt(475249515,[],e,[r,i]);if(null==s)return null;for(var u=[],l=s[0];l0){var S=E[E.length-1];Array.isArray(S.range)&&(S.range[1]=1/0)}u.index instanceof Ee&&null!==E&&E.length>0&&u.index._addSegments(E);var k=v?Rt(h,0):(0,kt.LD)(h),A=(0,st.Z)(k)?void 0:k,x=!1;if(!v){var I=(0,At.Z)(h);I.length>0&&(x=u._addProtectionData("cenc",I))}return(0,i.of)({type:"parsed-init-segment",value:{initializationData:h,protectionDataUpdate:x,initTimescale:A}})}}function Ut(e){return"application/mp4"===e.mimeType}var Ft=n(6807);function zt(e,t,n,r){var i,a,o=e.segment,s=e.adaptation,u=e.representation;if(o.isInit)return null;null===n?r?(i=o.time,a=o.end):g.Z.warn("Transport: Unavailable time data for current text track."):(i=n.time,void 0!==n.duration?a=i+n.duration:r||(a=i+o.duration));var l=function(e){var t=e.codec;if(void 0===t)throw new Error("Cannot parse subtitles: unknown format");switch(t.toLowerCase()){case"stpp":case"stpp.ttml.im1t":return"ttml";case"wvtt":return"vtt"}throw new Error('The codec used for the subtitles "'+t+'" is not managed yet.')}(u);return{data:function(e){var t=(0,Ft.Le)(e);return null===t?"":(0,H.uR)(t)}(t),type:l,language:s.language,start:i,end:a}}function Kt(e,t,n){var r=e.segment,i=e.adaptation,a=e.representation;return r.isInit?null:(n&&g.Z.warn("Transport: Unavailable time data for current text track."),{data:t,type:function(e){var t=e.mimeType,n=void 0===t?"":t;switch(e.mimeType){case"application/ttml+xml":return"ttml";case"application/x-sami":case"application/smil":return"sami";case"text/vtt":return"vtt"}var r=e.codec;if("srt"===(void 0===r?"":r).toLowerCase())return"srt";throw new Error("could not find a text-track parser for the type "+n)}(a),language:i.language})}function Vt(e){var t=e.__priv_patchLastSegmentInSidx;return function(e){var n=e.response,r=e.content,a=e.initTimescale,o=r.period,u=r.representation,l=r.segment,d=l.timestampOffset,c=void 0===d?0:d,f=n.data,p=n.isChunked;return null===f?l.isInit?(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}}):(0,i.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:c,appendWindow:[o.start,o.end]}}):Ut(u)?function(e,t){var n=e.response,r=e.content,a=e.initTimescale,o=r.period,u=r.representation,l=r.segment,d=l.isInit,c=l.indexRange,f=n.data,p=n.isChunked,h="string"==typeof f?(0,H.tG)(f):f instanceof Uint8Array?f:new Uint8Array(f);if(d){var v=(0,kt.Wf)(h,Array.isArray(c)?c[0]:0);if(!0===t&&null!==v&&v.length>0){var m=v[v.length-1];Array.isArray(m.range)&&(m.range[1]=1/0)}var g=(0,kt.LD)(h);return u.index instanceof Ee&&null!==v&&v.length>0&&u.index._addSegments(v),(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:g}})}var y=Dt(h,p,l,a),_=zt(r,h,y,p),b=(0,s.Z)(l.timestampOffset,0);return(0,i.of)({type:"parsed-segment",value:{chunkData:_,chunkInfos:y,chunkOffset:b,appendWindow:[o.start,o.end]}})}({response:{data:f,isChunked:p},content:r,initTimescale:a},t):function(e){var t=e.response,n=e.content,r=n.period,a=n.segment,o=a.timestampOffset,s=void 0===o?0:o;if(a.isInit)return(0,i.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}});var u,l=t.data,d=t.isChunked;if("string"!=typeof l){var c=l instanceof Uint8Array?l:new Uint8Array(l);u=(0,H.uR)(c)}else u=l;var f=Kt(n,u,d);return(0,i.of)({type:"parsed-segment",value:{chunkData:f,chunkInfos:null,chunkOffset:s,appendWindow:[r.start,r.end]}})}({response:{data:f,isChunked:p},content:r})}}const Wt=function(e){var t=(0,r.Z)({customManifestLoader:e.manifestLoader}),n=Je(e),a=function(e){var t=e.lowLatencyMode,n=e.segmentLoader;return!0!==e.checkMediaSegmentIntegrity?r:yt(r);function r(e){var r=e.url;if(null==r)return(0,i.of)({type:"data-created",value:{responseData:null}});if(t||void 0===n)return St(r,e,t);var a={adaptation:e.adaptation,manifest:e.manifest,period:e.period,representation:e.representation,segment:e.segment,transport:"dash",url:r};return new et.y((function(i){var o=!1,s=!1,u=n(a,{reject:function(e){void 0===e&&(e={}),s||(o=!0,i.error(e))},resolve:function(e){s||(o=!0,i.next({type:"data-loaded",value:{responseData:e.data,size:e.size,duration:e.duration}}),i.complete())},progress:function(e){s||i.next({type:"progress",value:{duration:e.duration,size:e.size,totalSize:e.totalSize}})},fallback:function(){s=!0,St(r,e,t).subscribe(i)}});return function(){o||s||"function"!=typeof u||u()}}))}}(e),s=Bt(e);return{manifest:{loader:t,parser:n},audio:{loader:a,parser:s},video:{loader:a,parser:s},text:{loader:function(e){var t=e.lowLatencyMode;return!0!==e.checkMediaSegmentIntegrity?n:yt(n);function n(e){var n=e.segment.range,r=e.url;if(null===r)return(0,i.of)({type:"data-created",value:{responseData:null}});if(e.segment.isInit)return bt(r,e);var a=Ut(e.representation);if(t&&a){if(ct())return wt(r,e);(0,pt.Z)("DASH: Your browser does not have the fetch API. You will have a higher chance of rebuffering when playing close to the live edge")}var s=a?"arraybuffer":"text";return(0,o.ZP)({url:r,responseType:s,headers:Array.isArray(n)?{Range:(0,ht.Z)(n)}:null,sendProgressEvents:!0})}}(e),parser:Vt(e)},image:{loader:u,parser:l}}}},2339:(e,t,n)=>{"use strict";n.d(t,{Z:()=>ye});var r=n(8170),i=n(5709),a=n(3068),o=n(7874),s=n(3887),u=n(1966),l=n(6807),d=n(7714),c=n(811),f=n(6968),p=n(6923),h=n(8026),v=n(9829),m=n(3635),g=n(5278),y=n(2689),_={};function b(e){if(null!=_[e])return _[e];var t=(0,m.tG)(e);return _[e]=t,t}function T(e,t){var n=t.length+8;return n<=y.s?(0,f.zo)((0,f.kh)(n),b(e),t):(0,f.zo)((0,f.kh)(1),b(e),(0,f.el)(n+8),t)}function E(e,t){return T(e,f.zo.apply(void 0,t))}function w(e){var t=[];e.periods.forEach((function(n){var r=n.id;if((0,d.Z)(t,r)){s.Z.warn("Two periods with the same ID found. Updating.");var i=r+"-dup";n.id=i,w(e),t.push(i)}else t.push(r);var a=n.adaptations,o=[];Object.keys(a).forEach((function(t){var n=a[t];void 0!==n&&n.forEach((function(t){var n=t.id;if((0,d.Z)(o,n)){s.Z.warn("Two adaptations with the same ID found. Updating.",n);var r=n+"-dup";t.id=r,w(e),o.push(r)}else o.push(n);var i=[];t.representations.forEach((function(t){var n=t.id;if((0,d.Z)(i,n)){s.Z.warn("Two representations with the same ID found. Updating.",n);var r=n+"-dup";t.id=r,w(e),i.push(r)}else i.push(n)}))}))}))}))}var S=n(9689);function k(e){return[{systemId:"edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",privateData:(0,f.zo)([8,1,18,16],e)}]}function A(e,t){if(void 0===t&&(t=k),null===e.firstElementChild||"ProtectionHeader"!==e.firstElementChild.nodeName)throw new Error("Protection should have ProtectionHeader child");var n=e.firstElementChild,r=(0,S.K)(null===n.textContent?"":n.textContent),i=function(e){var t=(0,f.qb)(e,8),n=(0,m.wV)(e.subarray(10,t+10)),r=(new DOMParser).parseFromString(n,"application/xml").querySelector("KID");if(null===r)throw new Error("Cannot parse PlayReady private data: invalid XML");var i=null===r.textContent?"":r.textContent,a=(0,m.wO)((0,S.K)(i));return(0,m.ci)(a).toLowerCase()}(r),a=(0,m.nr)(i),o=n.getAttribute("SystemID");return{keyId:a,keySystems:[{systemId:(null!==o?o:"").toLowerCase().replace(/\{|\}/g,""),privateData:r}].concat(t(a))}}var x=n(9362),I=n(8232),Z=n(3911),R=n(1091),M=n(5505);function C(e,t,n){var r=e.timeline,i=e.timescale,a=r[r.length-1],o=t.timescale===i?{time:t.time,duration:t.duration}:{time:t.time/t.timescale*i,duration:t.duration/t.timescale*i};return!(n.time===o.time)&&(o.time>=(0,Z.jH)(a,null)&&(a.duration===o.duration?a.repeatCount++:e.timeline.push({duration:o.duration,start:o.time,repeatCount:0}),!0))}function N(e,t){return e.replace(/\{start time\}/g,String(t))}function P(e,t,n){var r=t-e;return r>0?Math.floor(r/n):0}function O(e,t){var n=e.repeatCount;if(null!=e.duration&&n<0){var r=void 0!==t?t.start:1/0;n=Math.ceil((r-e.start)/e.duration)-1}return n}var D=function(){function e(e,t){var n=t.aggressiveMode,r=t.isLive,i=t.segmentPrivateInfos,a=null==e.manifestReceivedTime?performance.now():e.manifestReceivedTime;if(this._index=e,this._indexValidityTime=a,this._initSegmentInfos={bitsPerSample:i.bitsPerSample,channels:i.channels,codecPrivateData:i.codecPrivateData,packetSize:i.packetSize,samplingRate:i.samplingRate,timescale:e.timescale,protection:i.protection},this._isAggressiveMode=n,this._isLive=r,0!==e.timeline.length){var o=e.timeline[e.timeline.length-1],s=(0,Z.jH)(o,null);if(this._initialScaledLastPosition=s,e.isLive){var u=a/1e3*e.timescale;this._scaledLiveGap=u-s}}}var t=e.prototype;return t.getInitSegment=function(){return{id:"init",isInit:!0,privateInfos:{smoothInitSegment:this._initSegmentInfos},mediaURLs:null,time:0,end:0,duration:0,timescale:1}},t.getSegments=function(e,t){this._refreshTimeline();for(var n,r=function(e,t,n){var r=void 0===e.timescale||0===e.timescale?1:e.timescale;return{up:t*r,to:(t+n)*r}}(this._index,e,t),i=r.up,a=r.to,o=this._index,s=o.timeline,u=o.timescale,l=o.media,d=this._isAggressiveMode,c=[],f=s.length,p=null==this._scaledLiveGap?void 0:performance.now()/1e3*u-this._scaledLiveGap,h=0;h=a)return c;null!=n&&(n+=y+1)}return c},t.shouldRefresh=function(e,t){if(this._refreshTimeline(),!this._index.isLive)return!1;var n=this._index,r=n.timeline,i=n.timescale,a=r[r.length-1];if(void 0===a)return!1;var o=a.repeatCount,s=a.start+(o+1)*a.duration;return!(t*i=s||e*i>a.start+o*a.duration)},t.getFirstPosition=function(){this._refreshTimeline();var e=this._index;return 0===e.timeline.length?null:e.timeline[0].start/e.timescale},t.getLastPosition=function(){this._refreshTimeline();var e=this._index;if(null==this._scaledLiveGap){var t=e.timeline[e.timeline.length-1];return(0,Z.jH)(t,null)/e.timescale}for(var n=e.timeline.length-1;n>=0;n--)for(var r=e.timeline[n],i=performance.now()/1e3*e.timescale,a=r.start,o=r.duration,s=r.repeatCount;s>=0;s--){var u=a+o*(s+1);if((this._isAggressiveMode?u-o:u)<=i-this._scaledLiveGap)return u/e.timescale}},t.checkDiscontinuity=function(e){return this._refreshTimeline(),(0,Z._j)(this._index,e,void 0)},t.areSegmentsChronologicallyGenerated=function(){return!0},t.isSegmentStillAvailable=function(e){if(e.isInit)return!0;this._refreshTimeline();var t=this._index,n=t.timeline,r=t.timescale;return(0,R.Z)(e,n,r,0)},t.canBeOutOfSyncError=function(e){return!!this._isLive&&(e instanceof x.Z&&(e.isHttpError(404)||e.isHttpError(412)))},t._replace=function(e){var t=this._index.timeline,n=e._index.timeline,r=this._index.timescale,i=e._index.timescale;if(this._index=e._index,this._initialScaledLastPosition=e._initialScaledLastPosition,this._indexValidityTime=e._indexValidityTime,this._scaledLiveGap=e._scaledLiveGap,0!==t.length&&0!==n.length&&r===i){var a=t[t.length-1],o=n[n.length-1],u=(0,Z.jH)(o,null);if(!((0,Z.jH)(a,null)<=u))for(var l=0;lu){if(d.duration!==o.duration)return;var f=u-d.start;if(0===f)return s.Z.warn("Smooth Parser: a discontinuity detected in the previous manifest has been resolved."),void(this._index.timeline=this._index.timeline.concat(t.slice(l)));if(f<0||f%d.duration!=0)return;var p=f/d.duration-1,h=d.repeatCount-p;if(h<0)return;o.repeatCount+=h;var v=t.slice(l+1);return void(this._index.timeline=this._index.timeline.concat(v))}}}},t._update=function(e){(0,M.Z)(this._index.timeline,e._index.timeline),this._initialScaledLastPosition=e._initialScaledLastPosition,this._indexValidityTime=e._indexValidityTime,this._scaledLiveGap=e._scaledLiveGap},t.isFinished=function(){return!this._isLive},t.isInitialized=function(){return!0},t._addSegments=function(e,t){this._refreshTimeline();for(var n=0;n>3:2)?"mp4a.40.2":"mp4a.40."+n}(u,l);return{audiotag:void 0!==i?parseInt(i,10):i,bitrate:h,bitsPerSample:void 0!==a?parseInt(a,10):a,channels:void 0!==o?parseInt(o,10):o,codecPrivateData:u,codecs:v,customAttributes:n,mimeType:void 0!==l?F[l]:l,packetSize:void 0!==d?parseInt(d,10):d,samplingRate:void 0!==c?parseInt(c,10):c};case"video":var m=r("CodecPrivateData"),y=r("FourCC"),_=r("MaxWidth"),b=r("MaxHeight"),T=r("Bitrate"),E=void 0===T||isNaN(parseInt(T,10))?0:parseInt(T,10);if(void 0!==y&&void 0===F[y]||void 0===m)return s.Z.warn("Smooth parser: Unsupported video codec. Ignoring quality level."),null;var w=function(e){var t=/00000001\d7([0-9a-fA-F]{6})/.exec(e);return null!==t&&(0,p.Z)(t[1])?"avc1."+t[1]:"avc1.4D401E"}(m);return{bitrate:E,customAttributes:n,mimeType:void 0!==y?F[y]:y,codecPrivateData:m,codecs:w,width:void 0!==_?parseInt(_,10):void 0,height:void 0!==b?parseInt(b,10):void 0};case"text":var S=r("CodecPrivateData"),k=r("FourCC"),A=r("Bitrate");return{bitrate:void 0===A||isNaN(parseInt(A,10))?0:parseInt(A,10),customAttributes:n,mimeType:void 0!==k?F[k]:k,codecPrivateData:(0,g.Z)(S,"")};default:return s.Z.error("Smooth Parser: Unrecognized StreamIndex type: "+t),null}}function o(t){var r=t.root,i=t.timescale,o=t.rootURL,u=t.protections,l=t.timeShiftBufferDepth,g=t.manifestReceivedTime,y=t.isLive,_=r.getAttribute("Timescale"),b=null===_||isNaN(+_)?i:+_,E=r.getAttribute("Type");if(null===E)throw new Error("StreamIndex without type.");(0,d.Z)(B,E)||s.Z.warn("Smooth Parser: Unrecognized adaptation type:",E);var w=E,S=r.getAttribute("Subtype"),k=r.getAttribute("Language"),A=r.getAttribute("Url"),x=null===A?"":A;var I,Z=L(r,(function(e,t,r){switch(t){case"QualityLevel":var i=a(r,w);if(null===i)return e;("video"!==w||i.bitrate>n)&&e.qualityLevels.push(i);break;case"c":e.cNodes.push(r)}return e}),{qualityLevels:[],cNodes:[]}),R=Z.qualityLevels,M=Z.cNodes,C={timeline:(I=M,I.reduce((function(e,t,n){var r=t.getAttribute("d"),i=t.getAttribute("t"),a=t.getAttribute("r"),o=null!==a?+a-1:0,s=null!==i?+i:void 0,u=null!==r?+r:void 0;if(0===n)s=void 0===s||isNaN(s)?0:s;else{var l=e[n-1];if(null==s||isNaN(s)){if(null==l.duration||isNaN(l.duration))throw new Error("Smooth: Invalid CNodes. Missing timestamp.");s=l.start+l.duration*(l.repeatCount+1)}}if(null==u||isNaN(u)){var d=I[n+1];if(void 0===d)return e;var c=d.getAttribute("t"),f=(0,p.Z)(c)?+c:null;if(null===f)throw new Error("Can't build index timeline from Smooth Manifest.");u=f-s}return e.push({duration:u,start:s,repeatCount:o}),e}),[])),timescale:b};(0,c.Z)(0!==R.length,"Adaptation should have at least one playable representation.");var N=w+((0,p.Z)(k)?"_"+k:""),P=R.map((function(t){var n,r,i,a,s=(0,v.Z)(o,x),d={timeline:C.timeline,timescale:C.timescale,media:(n=s,r=t.bitrate,i=t.customAttributes,n.replace(/\{bitrate\}/g,String(r)).replace(/{CustomAttributes}/g,i.length>0?i[0]:"")),isLive:y,timeShiftBufferDepth:l,manifestReceivedTime:g},c=(0,p.Z)(t.mimeType)?t.mimeType:U[w],_=t.codecs,b=N+"_"+(null!=w?w+"-":"")+(null!=c?c+"-":"")+(null!=_?_+"-":"")+String(t.bitrate),E=[];u.length>0&&(a=u[0],u.forEach((function(e){var t=e.keyId;e.keySystems.forEach((function(e){E.push({keyId:t,systemId:e.systemId})}))})));var S={bitsPerSample:t.bitsPerSample,channels:t.channels,codecPrivateData:t.codecPrivateData,packetSize:t.packetSize,samplingRate:t.samplingRate,protection:null!=a?{keyId:a.keyId}:void 0},k=null!=e.aggressiveMode&&e.aggressiveMode,A=new D(d,{aggressiveMode:k,isLive:y,segmentPrivateInfos:S}),I=(0,h.Z)({},t,{index:A,mimeType:c,codecs:_,id:b});if(E.length>0||void 0!==a){var Z=void 0===a?[]:a.keySystems.map((function(e){var t=e.systemId,n=e.privateData,r=t.replace(/-/g,"");return{systemId:r,data:function(e,t){if(32!==e.length)throw new Error("HSS: wrong system id length");var n=0;return T("pssh",(0,f.zo)([n,0,0,0],(0,m.nr)(e),(0,f.kh)(t.length),t))}(r,n)}}));if(Z.length>0){var R=[{type:"cenc",values:Z}];I.contentProtections={keyIds:E,initData:R}}else I.contentProtections={keyIds:E,initData:[]}}return I}));if("ADVT"===S)return null;var O={id:N,type:w,representations:P,language:null==k?void 0:k};return"text"===w&&"DESC"===S&&(O.closedCaption=!0),O}return function(n,r,a){var s=(0,v.f)(null==r?"":r),u=n.documentElement;if(null==u||"SmoothStreamingMedia"!==u.nodeName)throw new Error("document root should be SmoothStreamingMedia");var l=u.getAttribute("MajorVersion"),d=u.getAttribute("MinorVersion");if(null===l||null===d||!/^[2]-[0-2]$/.test(l+"-"+d))throw new Error("Version should be 2.0, 2.1 or 2.2");var c,f,h=u.getAttribute("Timescale"),m=(0,p.Z)(h)?isNaN(+h)?1e7:+h:1e7,g=L(u,(function(t,n,r){switch(n){case"Protection":t.protections.push(A(r,e.keySystems));break;case"StreamIndex":t.adaptationNodes.push(r)}return t}),{adaptationNodes:[],protections:[]}),y=g.protections,_=g.adaptationNodes,b="boolean"==typeof(c=u.getAttribute("IsLive"))?c:"string"==typeof c&&"TRUE"===c.toUpperCase();if(b){var T=u.getAttribute("DVRWindowLength");null==T||isNaN(+T)||0==+T||(f=+T/m)}var E,S,k,x,I,Z,R=_.reduce((function(e,t){var n=o({root:t,rootURL:s,timescale:m,protections:y,isLive:b,timeShiftBufferDepth:f,manifestReceivedTime:a});if(null===n)return e;var r=n.type,i=e[r];return void 0===i?e[r]=[n]:i.push(n),e}),{}),M=null,C=void 0!==R.video?R.video[0]:void 0,N=void 0!==R.audio?R.audio[0]:void 0;if(void 0!==C||void 0!==N){var P=[],O=[];if(void 0!==C){var D=C.representations[0];if(void 0!==D){var B=D.index.getFirstPosition(),U=D.index.getLastPosition();null!=B&&P.push(B),null!=U&&O.push(U)}}if(void 0!==N){var F=N.representations[0];if(void 0!==F){var z=F.index.getFirstPosition(),K=F.index.getLastPosition();null!=z&&P.push(z),null!=K&&O.push(K)}}P.length>0&&(I=Math.max.apply(Math,P)),O.length>0&&(Z=Math.min.apply(Math,O))}var V=u.getAttribute("Duration"),W=null!=V&&0!=+V?+V/m:void 0;b?(E=e.suggestedPresentationDelay,S=t,k=null!=I?I:S,x={isLinear:!0,value:null!=Z?Z:Date.now()/1e3-S,time:performance.now()},M=null!=f?f:null):(k=null!=I?I:0,x={isLinear:!1,value:void 0!==Z?Z:void 0!==W?k+W:1/0,time:performance.now()});var G=b?0:k,H=b?void 0:x.value,$={availabilityStartTime:void 0===S?0:S,clockOffset:i,isLive:b,isDynamic:b,timeBounds:{absoluteMinimumTime:k,timeshiftDepth:M,maximumTimeData:x},periods:[{adaptations:R,duration:void 0!==H?H-G:W,end:H,id:"gen-smooth-period-0",start:G}],suggestedPresentationDelay:E,transportType:"smooth",uris:null==r?[]:[r]};return w($),$}};var K=n(4597),V=n(8806),W=n(4460),G=n(7445),H=n(7278),$=n(4644),j=n(2297);function Y(e,t,n,r,i){var a,o,u,d=[];if(i){var c=(0,l.XA)(e);null!==c?(u=function(e){var t=(0,j.nR)(e,3565190898,3392751253,2387879627,2655430559);if(void 0===t)return[];for(var n=[],r=t[0],i=t[4],a=0;a0)return e;var n=new Uint8Array(e.length+4);return n.set(e.subarray(0,t+8),0),n[t+3]=1|n[t+3],n.set([0,0,0,0],t+8),n.set(e.subarray(t+8,e.length),t+12),(0,$.J6)(n)}(l,s[1]-s[0]),p=te(u,d,c,i,(0,j.nR)(a,2721664850,1520127764,2722393154,2086964724)),h=E("moof",[i,p]),v=(0,j.Qy)(h,1836019558),m=(0,j.Qy)(p,1953653094),g=(0,j.Qy)(c,1953658222);if(null===v||null===m||null===g)throw new Error("Smooth: Invalid moof, trun or traf generation");var y=v[1]-v[0]+i.length+(m[1]-m[0])+u.length+d.length+(g[1]-g[0])+8,_=n[2]-n[0],b=h.length-_,w=(0,j.Qy)(e,1835295092);if(null===w)throw new Error("Smooth: Invalid ISOBMFF given");if(!q.YM&&(0===b||b<=-8)){var S=w[1];return h.set((0,f.kh)(S),y),e.set(h,n[0]),b<=-8&&e.set(T("free",new Uint8Array(-b-8)),h.length),e}var k=w[1]+b;h.set((0,f.kh)(k),y);var A=new Uint8Array(e.length+b),x=e.subarray(0,n[0]),I=e.subarray(n[2],e.length);return A.set(x,0),A.set(h,x.length),A.set(I,x.length+h.length),A}var re=n(4379),ie=n(281);function ae(e,t,n,r,i,a){var o,s,u,l=E("stbl",[n,T("stts",new Uint8Array(8)),T("stsc",new Uint8Array(8)),T("stsz",new Uint8Array(12)),T("stco",new Uint8Array(8))]),d=E("dinf",[function(e){return T("dref",(0,f.zo)(7,[1],e))}(T("url ",new Uint8Array([0,0,0,1])))]),c=E("minf",[r,d,l]),p=function(e){var t,n;switch(e){case"video":t="vide",n="VideoHandler";break;case"audio":t="soun",n="SoundHandler";break;default:t="hint",n=""}return T("hdlr",(0,f.zo)(8,(0,m.tG)(t),12,(0,m.tG)(n),1))}(t),h=E("mdia",[function(e){return T("mdhd",(0,f.zo)(12,(0,f.kh)(e),8))}(e),p,c]),v=E("trak",[function(e,t,n){return T("tkhd",(0,f.zo)((0,f.kh)(7),8,(0,f.kh)(n),20,[1,0,0,0],[0,1,0,0],12,[0,1,0,0],12,[64,0,0,0],(0,f.XT)(e),2,(0,f.XT)(t),2))}(i,a,1),h]),g=E("mvex",[(o=1,T("trex",(0,f.zo)(4,(0,f.kh)(o),[0,0,0,1],12)))]),y=function(e,t,n){return E("moov",[e,t,n])}(function(e,t){return T("mvhd",(0,f.zo)(12,(0,f.kh)(e),4,[0,1],2,[1,0],10,[0,1],14,[0,1],14,[64,0,0,0],26,(0,f.XT)(t+1)))}(e,1),g,v),_=(s="isom",u=["isom","iso2","iso6","avc1","dash"],T("ftyp",f.zo.apply(void 0,[(0,m.tG)(s),[0,0,0,1]].concat(u.map(m.tG)))));return(0,f.zo)(_,y)}function oe(e,t,n,r,i,a,o,s){var u=o.split("00000001"),l=u[1],d=u[2];if(void 0===l||void 0===d)throw new Error("Smooth: unsupported codec private data.");var c,p,h=function(e,t,n){var r=2===n?1:4===n?3:0,i=e[1],a=e[2],o=e[3];return T("avcC",(0,f.zo)([1,i,a,o,252|r,225],(0,f.XT)(e.length),e,[1],(0,f.XT)(t.length),t))}((0,m.nr)(l),(0,m.nr)(d),a);if(void 0===s){c=J([function(e,t,n,r,i,a,o){return T("avc1",(0,f.zo)(6,(0,f.XT)(1),16,(0,f.XT)(e),(0,f.XT)(t),(0,f.XT)(n),2,(0,f.XT)(r),6,[0,1,i.length],(0,m.tG)(i),31-i.length,(0,f.XT)(a),[255,255],o))}(t,n,r,i,"AVC Coding",24,h)])}else{var v=E("schi",[ee(1,8,s)]),g=X("cenc",65536);c=J([function(e,t,n,r,i,a,o,s){return T("encv",(0,f.zo)(6,(0,f.XT)(1),16,(0,f.XT)(e),(0,f.XT)(t),(0,f.XT)(n),2,(0,f.XT)(r),6,[0,1,i.length],(0,m.tG)(i),31-i.length,(0,f.XT)(a),[255,255],o,s))}(t,n,r,i,"AVC Coding",24,h,E("sinf",[Q("avc1"),g,v]))])}return ae(e,"video",c,((p=new Uint8Array(12))[3]=1,T("vmhd",p)),t,n)}var se=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];function ue(e,t,n,r,i,a,o){var s,u,l,d=function(e,t){return T("esds",(0,f.zo)(4,[3,25],(0,f.XT)(e),[0,4,17,64,21],11,[5,2],(0,m.nr)(t),[6,1,2]))}(1,0===a.length?(s=i,u=t,l=((l=((l=(63&2)<<4)|31&se.indexOf(s))<<4)|31&u)<<3,(0,m.ci)((0,f.XT)(l))):a);return ae(e,"audio",function(){if(void 0===o)return J([function(e,t,n,r,i,a){return T("mp4a",(0,f.zo)(6,(0,f.XT)(e),8,(0,f.XT)(t),(0,f.XT)(n),2,(0,f.XT)(r),(0,f.XT)(i),2,a))}(1,t,n,r,i,d)]);var e=E("schi",[ee(1,8,o)]),a=X("cenc",65536),s=E("sinf",[Q("mp4a"),a,e]);return J([function(e,t,n,r,i,a,o){return T("enca",(0,f.zo)(6,(0,f.XT)(e),8,(0,f.XT)(t),(0,f.XT)(n),2,(0,f.XT)(r),(0,f.XT)(i),2,a,o))}(1,t,n,r,i,d,s)])}(),T("smhd",new Uint8Array(8)),0,0)}function le(e){var t,n=e.url,r=e.segment.range;return Array.isArray(r)&&(t={Range:(0,ie.Z)(r)}),(0,K.ZP)({url:n,responseType:"arraybuffer",headers:t,sendProgressEvents:!0})}const de=function(e){return function(t){var n=t.segment,i=t.representation,a=t.adaptation,o=t.period,s=t.manifest,u=t.url;if(n.isInit){if(void 0===n.privateInfos||void 0===n.privateInfos.smoothInitSegment)throw new Error("Smooth: Invalid segment format");var l,d=n.privateInfos.smoothInitSegment,c=d.codecPrivateData,f=d.timescale,p=d.protection,h=void 0===p?{keyId:void 0,keySystems:void 0}:p;if(void 0===c)throw new Error("Smooth: no codec private data.");switch(a.type){case"video":var v=i.width,m=void 0===v?0:v,g=i.height;l=oe(f,m,void 0===g?0:g,72,72,4,c,h.keyId);break;case"audio":var y=d.channels,_=void 0===y?0:y,b=d.bitsPerSample,T=void 0===b?0:b,E=d.packetSize,w=void 0===E?0:E,S=d.samplingRate;l=ue(f,_,T,w,void 0===S?0:S,c,h.keyId);break;default:0,l=new Uint8Array(0)}return(0,r.of)({type:"data-created",value:{responseData:l}})}if(null===u)return(0,r.of)({type:"data-created",value:{responseData:null}});var k={adaptation:a,manifest:s,period:o,representation:i,segment:n,transport:"smooth",url:u};return"function"!=typeof e?le(k):new re.y((function(t){var n=!1,r=!1,i=e(k,{reject:function(e){void 0===e&&(e={}),r||(n=!0,t.error(e))},resolve:function(e){r||(n=!0,t.next({type:"data-loaded",value:{responseData:e.data,size:e.size,duration:e.duration}}),t.complete())},fallback:function(){r=!0,le(k).subscribe(t)},progress:function(e){r||t.next({type:"progress",value:{duration:e.duration,size:e.size,totalSize:e.totalSize}})}});return function(){n||r||"function"!=typeof i||i()}}))}};var ce=/(\.isml?)(\?token=\S+)?$/,fe=/\?token=(\S+)/;function pe(e,t){return(0,p.Z)(t)?e.replace(fe,"?token="+t):e.replace(fe,"")}function he(e){return ce.test(e)?((0,V.Z)("Giving a isml URL to loadVideo is deprecated. Please give the Manifest URL directly"),e.replace(ce,"$1/manifest$2")):e}var ve=/\.wsx?(\?token=\S+)?/;function me(e,t,n){var r;s.Z.debug("Smooth Parser: update segments information.");for(var i=e.representations,a=0;a=0}const ye=function(e){var t=z(e),n=de(e.segmentLoader),d={customManifestLoader:e.manifestLoader},c={loader:function(t){return t.segment.isInit||!0!==e.checkMediaSegmentIntegrity?n(t):n(t).pipe((0,a.b)((function(e){"data-loaded"!==e.type&&"data-chunk"!==e.type||null===e.value.responseData||(0,W.Z)(new Uint8Array(e.value.responseData),t.segment.isInit)})))},parser:function(e){var t,n,i=e.content,a=e.response,o=e.initTimescale,s=i.segment,u=i.adaptation,l=i.manifest,d=a.data,c=a.isChunked;if(null===d)return s.isInit?(0,r.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}}):(0,r.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:[void 0,void 0]}});var f=d instanceof Uint8Array?d:new Uint8Array(d);if(s.isInit){var p=null===(n=null===(t=s.privateInfos)||void 0===t?void 0:t.smoothInitSegment)||void 0===n?void 0:n.timescale;return(0,r.of)({type:"parsed-init-segment",value:{initializationData:d,initTimescale:p,protectionDataUpdate:!1}})}var h=void 0!==o?Y(f,c,o,s,l.isLive):null;if(null===h||null===h.chunkInfos||void 0===h.scaledSegmentTime)throw new Error("Smooth Segment without time information");var v=h.nextSegments,m=h.chunkInfos,g=ne(f,h.scaledSegmentTime);return v.length>0&&me(u,v,s),(0,r.of)({type:"parsed-segment",value:{chunkData:g,chunkInfos:m,chunkOffset:0,appendWindow:[void 0,void 0]}})}};return{manifest:{resolver:function(e){var t,n=e.url;if(void 0===n)return(0,r.of)({url:void 0});ve.test(n)?((0,V.Z)("Giving WSX URL to loadVideo is deprecated. You should only give Manifest URLs."),t=(0,K.ZP)({url:pe(n,""),responseType:"document"}).pipe((0,i.U)((function(e){var t=e.value,n=t.responseData.getElementsByTagName("media")[0].getAttribute("src");if(null===n||0===n.length)throw new Error("Invalid ISML");return n})))):t=(0,r.of)(n);var a=function(e){var t=fe.exec(e);if(null!==t){var n=t[1];if(void 0!==n)return n}return""}(n);return t.pipe((0,i.U)((function(e){return{url:pe(he(e),a)}})))},loader:(0,H.Z)(d),parser:function(n){var r=n.response,i=n.url,a=void 0===r.url?i:r.url,o="string"==typeof r.responseData?(new DOMParser).parseFromString(r.responseData,"text/xml"):r.responseData,s=r.receivedTime,l=t(o,a,s),d=new u.ZP(l,{representationFilter:e.representationFilter,supplementaryImageTracks:e.supplementaryImageTracks,supplementaryTextTracks:e.supplementaryTextTracks});return(0,G.Z)(d,a)}},audio:c,video:c,text:{loader:function(t){var n=t.segment,i=t.representation,o=t.url;if(n.isInit||null===o)return(0,r.of)({type:"data-created",value:{responseData:null}});var s=ge(i);return s&&!0===e.checkMediaSegmentIntegrity?(0,K.ZP)({url:o,responseType:"arraybuffer",sendProgressEvents:!0}).pipe((0,a.b)((function(e){"data-loaded"===e.type&&(0,W.Z)(new Uint8Array(e.value.responseData),n.isInit)}))):(0,K.ZP)({url:o,responseType:s?"arraybuffer":"text",sendProgressEvents:!0})},parser:function(e){var t,n,i=e.content,a=e.response,o=e.initTimescale,u=i.manifest,d=i.adaptation,c=i.representation,f=i.segment,p=d.language,h=ge(c),v=c.mimeType,g=void 0===v?"":v,y=c.codec,_=void 0===y?"":y,b=a.data,T=a.isChunked;if(f.isInit)return(0,r.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}});if(null===b)return(0,r.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:[void 0,void 0]}});var E,w,S,k,A=null;if(h){var x;x="string"==typeof b?(0,m.tG)(b):b instanceof Uint8Array?b:new Uint8Array(b);var I=void 0!==o?Y(x,T,o,f,u.isLive):null;n=null==I?void 0:I.nextSegments,null===(A=null!==(t=null==I?void 0:I.chunkInfos)&&void 0!==t?t:null)?T?s.Z.warn("Smooth: Unavailable time data for current text track."):(E=f.time,w=f.end):(E=A.time,w=void 0!==A.duration?A.time+A.duration:f.end);var Z=_.toLowerCase();if("application/ttml+xml+mp4"===g||"stpp"===Z||"stpp.ttml.im1t"===Z)k="ttml";else{if("wvtt"!==Z)throw new Error("could not find a text-track parser for the type "+g);k="vtt"}var R=(0,l.Le)(x);S=null===R?"":(0,m.uR)(R)}else{var M;if(E=f.time,w=f.end,"string"!=typeof b){var C=b instanceof Uint8Array?b:new Uint8Array(b);M=(0,m.uR)(C)}else M=b;switch(g){case"application/x-sami":case"application/smil":k="sami";break;case"application/ttml+xml":k="ttml";break;case"text/vtt":k="vtt"}if(void 0===k){if("srt"!==_.toLowerCase())throw new Error("could not find a text-track parser for the type "+g);k="srt"}S=M}null!==A&&Array.isArray(n)&&n.length>0&&me(d,n,f);var N=null!=E?E:0;return(0,r.of)({type:"parsed-segment",value:{chunkData:{type:k,data:S,start:E,end:w,language:p},chunkInfos:A,chunkOffset:N,appendWindow:[void 0,void 0]}})}},image:{loader:function(e){var t=e.segment,n=e.url;return t.isInit||null===n?(0,r.of)({type:"data-created",value:{responseData:null}}):(0,K.ZP)({url:n,responseType:"arraybuffer",sendProgressEvents:!0})},parser:function(e){var t=e.response,n=e.content,i=t.data,a=t.isChunked;if(n.segment.isInit)return(0,r.of)({type:"parsed-init-segment",value:{initializationData:null,protectionDataUpdate:!1,initTimescale:void 0}});if(a)throw new Error("Image data should not be downloaded in chunks");if(null===i||null===o.Z.imageParser)return(0,r.of)({type:"parsed-segment",value:{chunkData:null,chunkInfos:null,chunkOffset:0,appendWindow:[void 0,void 0]}});var s=o.Z.imageParser(new Uint8Array(i)),u=s.thumbs;return(0,r.of)({type:"parsed-segment",value:{chunkData:{data:u,start:0,end:Number.MAX_VALUE,timescale:1,type:"bif"},chunkInfos:{time:0,duration:Number.MAX_VALUE,timescale:s.timescale},chunkOffset:0,protectionDataUpdate:!1,appendWindow:[void 0,void 0]}})}}}}},281:(e,t,n)=>{"use strict";function r(e){var t=e[0],n=e[1];return n===1/0?"bytes="+t+"-":"bytes="+t+"-"+n}n.d(t,{Z:()=>r})},4460:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(5389),i=n(8766);function a(e,t){if(t){if((0,i.Z)(e,1718909296)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `ftyp` box");if((0,i.Z)(e,1836019574)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `moov` box")}else{if((0,i.Z)(e,1836019558)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `moof` box");if((0,i.Z)(e,1835295092)<0)throw new r.Z("INTEGRITY_ERROR","Incomplete `mdat` box")}}},8766:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(6968);function i(e,t){for(var n=e.length,i=0;i+8<=n;){var a=(0,r.pX)(e,i);if(0===a)a=n-i;else if(1===a){if(i+16>n)return-1;a=(0,r.pV)(e,i+8)}if(isNaN(a)||a<=0)return-1;if((0,r.pX)(e,i+4)===t)return i+a<=n?i:-1;i+=a}return-1}},7445:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(8170),i=n(9795);function a(e,t){var n=r.of.apply(void 0,e.parsingErrors.map((function(e){return{type:"warning",value:e}})));return(0,i.z)(n,(0,r.of)({type:"parsed",value:{manifest:e,url:t}}))}},7278:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(1946),i=n(4597),a=n(4379);function o(e){var t=e.url;if(void 0===t)throw new Error("Cannot perform HTTP(s) request. URL not known");return(0,i.ZP)({url:t,responseType:"text"})}function s(e){var t=e.customManifestLoader;return(0,r.Z)(t)?o:function(e,t){return function(n){return new a.y((function(r){var i=n.url,a=Date.now()-performance.now(),o=!1,s=!1,u=e(i,{reject:function(e){s||(o=!0,r.error(e))},resolve:function(e){if(!s){o=!0;var t=void 0!==e.receivingTime?e.receivingTime-a:void 0,n=void 0!==e.sendingTime?e.sendingTime-a:void 0;r.next({type:"data-loaded",value:{responseData:e.data,size:e.size,duration:e.duration,url:e.url,receivedTime:t,sendingTime:n}}),r.complete()}},fallback:function(){s=!0,t(n).subscribe(r)}});return function(){o||s||"function"!=typeof u||u()}}))}}(t,o)}},4791:(e,t,n)=>{"use strict";function r(e,t){if(e.length!==t.length)return!1;for(var n=e.length-1;n>=0;n--)if(e[n]!==t[n])return!1;return!0}n.d(t,{Z:()=>r})},3274:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof Array.prototype.find)return e.find(t,n);for(var r=e.length>>>0,i=0;ir})},5138:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof Array.prototype.findIndex)return e.findIndex(t,n);for(var r=e.length>>>0,i=0;ir})},7714:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof Array.prototype.includes)return e.includes(t,n);var r=e.length>>>0;if(0===r)return!1;for(var i,a,o=0|n,s=o>=0?Math.min(o,r-1):Math.max(r+o,0);sr})},811:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a,u:()=>o});var r=n(3801),i=n(1946);function a(e,t){if(!e)throw new r.Z(void 0===t?"invalid assertion":t)}function o(e,t,n){for(var r in void 0===n&&(n="object"),a(!(0,i.Z)(e),n+" should be an object"),t)t.hasOwnProperty(r)&&a(typeof e[r]===t[r],n+" should have property "+r+" as a "+t[r])}},8418:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(3801);function i(e){throw new r.Z("Unreachable path taken")}},9689:(e,t,n)=>{"use strict";n.d(t,{J:()=>s,K:()=>u});var r=n(3887),i=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/"],a=[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,62,255,255,255,63,52,53,54,55,56,57,58,59,60,61,255,255,255,0,255,255,255,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,255,255,255,255,255,255,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];function o(e){if(e>=a.length)throw new Error("Unable to parse base64 string.");var t=a[e];if(255===t)throw new Error("Unable to parse base64 string.");return t}function s(e){var t,n="",r=e.length;for(t=2;t>2],n+=i[(3&e[t-2])<<4|e[t-1]>>4],n+=i[(15&e[t-1])<<2|e[t]>>6],n+=i[63&e[t]];return t===r+1&&(n+=i[e[t-2]>>2],n+=i[(3&e[t-2])<<4],n+="=="),t===r&&(n+=i[e[t-2]>>2],n+=i[(3&e[t-2])<<4|e[t-1]>>4],n+=i[(15&e[t-1])<<2],n+="="),n}function u(e){var t=e.length%4,n=e;0!==t&&(r.Z.warn("base64ToBytes: base64 given miss padding"),n+=3===t?"=":2===t?"==":"===");var i=n.indexOf("=");if(-1!==i&&i>16,l[c+1]=a>>8&255,l[c+2]=255&a;return l.subarray(0,l.length-s)}},6968:(e,t,n)=>{"use strict";function r(){for(var e,t=arguments.length,n=-1,r=0;++n0&&(i.set(e,a),a+=e.length);return i}function i(e,t){return(e[t+0]<<8)+(e[t+1]<<0)}function a(e,t){return 65536*e[t+0]+256*e[t+1]+e[t+2]}function o(e,t){return 16777216*e[t+0]+65536*e[t+1]+256*e[t+2]+e[t+3]}function s(e,t){return 4294967296*(16777216*e[t+0]+65536*e[t+1]+256*e[t+2]+e[t+3])+16777216*e[t+4]+65536*e[t+5]+256*e[t+6]+e[t+7]}function u(e){return new Uint8Array([e>>>8&255,255&e])}function l(e){return new Uint8Array([e>>>24&255,e>>>16&255,e>>>8&255,255&e])}function d(e){var t=e%4294967296,n=(e-t)/4294967296;return new Uint8Array([n>>>24&255,n>>>16&255,n>>>8&255,255&n,t>>>24&255,t>>>16&255,t>>>8&255,255&t])}function c(e,t){return(e[t+0]<<0)+(e[t+1]<<8)}function f(e,t){return e[t+0]+256*e[t+1]+65536*e[t+2]+16777216*e[t+3]}function p(e){return new Uint8Array([255&e,e>>>8&255,e>>>16&255,e>>>24&255])}function h(e){return e instanceof Uint8Array?e:e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer)}n.d(t,{zo:()=>r,zK:()=>i,QI:()=>a,pX:()=>o,pV:()=>s,qb:()=>c,dN:()=>f,XT:()=>u,kh:()=>l,el:()=>d,O_:()=>p,_f:()=>h})},8117:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(4379),i=n(4072),a=n(8170),o=n(1946);const s=function(e){if(e instanceof r.y)return e;if(!(0,o.Z)(e)&&"function"==typeof e.subscribe){var t=e;return new r.y((function(e){var n=t.subscribe((function(t){e.next(t)}),(function(t){e.error(t)}),(function(){e.complete()}));return function(){(0,o.Z)(n)||"function"!=typeof n.dispose?(0,o.Z)(n)||"function"!=typeof n.unsubscribe||n.unsubscribe():n.dispose()}}))}return(0,o.Z)(e)||"function"!=typeof e.then?(0,a.of)(e):(0,i.D)(e)}},8025:(e,t,n)=>{"use strict";n.d(t,{Z:()=>g});var r=n(655),i=1,a=function(){return Promise.resolve()}(),o={};function s(e){return e in o&&(delete o[e],!0)}var u=function(e){var t=i++;return o[t]=!0,a.then((function(){return s(t)&&e()})),t},l=function(e){s(e)},d=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.scheduler=t,r.work=n,r}return r.ZT(t,e),t.prototype.requestAsyncId=function(t,n,r){return void 0===r&&(r=0),null!==r&&r>0?e.prototype.requestAsyncId.call(this,t,n,r):(t.actions.push(this),t.scheduled||(t.scheduled=u(t.flush.bind(t,null))))},t.prototype.recycleAsyncId=function(t,n,r){if(void 0===r&&(r=0),null!==r&&r>0||null===r&&this.delay>0)return e.prototype.recycleAsyncId.call(this,t,n,r);0===t.actions.length&&(l(n),t.scheduled=void 0)},t}(n(6114).o),c=new(function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype.flush=function(e){this.active=!0,this.scheduled=void 0;var t,n=this.actions,r=-1,i=n.length;e=e||n.shift();do{if(t=e.execute(e.state,e.delay))break}while(++r{"use strict";n.d(t,{Z:()=>o,R:()=>s});var r=n(4379),i=n(3887),a=n(1946),o=function(){function e(){this._listeners={}}var t=e.prototype;return t.addEventListener=function(e,t){var n=this._listeners[e];Array.isArray(n)?n.push(t):this._listeners[e]=[t]},t.removeEventListener=function(e,t){if((0,a.Z)(e))this._listeners={};else{var n=this._listeners[e];if(Array.isArray(n))if((0,a.Z)(t))delete this._listeners[e];else{var r=n.indexOf(t);-1!==r&&n.splice(r,1),0===n.length&&delete this._listeners[e]}}},t.trigger=function(e,t){var n=this._listeners[e];Array.isArray(n)&&n.slice().forEach((function(e){try{e(t)}catch(e){i.Z.error(e,e instanceof Error?e.stack:null)}}))},e}();function s(e,t){return new r.y((function(n){function r(e){n.next(e)}return e.addEventListener(t,r),function(){e.removeEventListener(t,r)}}))}},2793:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(1410),i=n(5709),a=n(6008);function o(e,t){return function(n){return(0,r.P)((function(){return n.pipe((0,i.U)(e),(0,a.h)((function(e){return e!==t})))}))}}},9592:(e,t,n)=>{"use strict";function r(e,t){return"function"==typeof Array.prototype.flatMap?e.flatMap(t):e.reduce((function(e,n){var r=t(n);return Array.isArray(r)?(e.push.apply(e,r),e):(e.push(r),e)}),[])}n.d(t,{Z:()=>r})},2572:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});function r(e){return e*(.3*(2*Math.random()-1)+1)}},2870:(e,t,n)=>{"use strict";function r(e){for(var t=0,n=0;nr})},908:(e,t,n)=>{"use strict";function r(){var e="",t=-1;return function(){return++t>=Number.MAX_SAFE_INTEGER&&(e+="0",t=0),e+String(t)}}n.d(t,{Z:()=>r})},6923:(e,t,n)=>{"use strict";function r(e){return"string"==typeof e&&e.length>0}n.d(t,{Z:()=>r})},1946:(e,t,n)=>{"use strict";function r(e){return null==e}n.d(t,{Z:()=>r})},7829:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>r});const r=n(5553).ZP},5553:(e,t,n)=>{"use strict";n.d(t,{ZP:()=>d,iH:()=>l,Y1:()=>u});var r=n(6923),i=n(1946);const a={aa:"aar",ab:"abk",ae:"ave",af:"afr",ak:"aka",am:"amh",an:"arg",ar:"ara",as:"asm",av:"ava",ay:"aym",az:"aze",ba:"bak",be:"bel",bg:"bul",bi:"bis",bm:"bam",bn:"ben",bo:"bod",br:"bre",bs:"bos",ca:"cat",ce:"che",ch:"cha",co:"cos",cr:"cre",cs:"ces",cu:"chu",cv:"chv",cy:"cym",da:"dan",de:"deu",dv:"div",dz:"dzo",ee:"ewe",el:"ell",en:"eng",eo:"epo",es:"spa",et:"est",eu:"eus",fa:"fas",ff:"ful",fi:"fin",fj:"fij",fo:"fao",fr:"fra",fy:"fry",ga:"gle",gd:"gla",gl:"glg",gn:"grn",gu:"guj",gv:"glv",ha:"hau",he:"heb",hi:"hin",ho:"hmo",hr:"hrv",ht:"hat",hu:"hun",hy:"hye",hz:"her",ia:"ina",id:"ind",ie:"ile",ig:"ibo",ii:"iii",ik:"ipk",io:"ido",is:"isl",it:"ita",iu:"iku",ja:"jpn",jv:"jav",ka:"kat",kg:"kon",ki:"kik",kj:"kua",kk:"kaz",kl:"kal",km:"khm",kn:"kan",ko:"kor",kr:"kau",ks:"kas",ku:"kur",kv:"kom",kw:"cor",ky:"kir",la:"lat",lb:"ltz",lg:"lug",li:"lim",ln:"lin",lo:"lao",lt:"lit",lu:"lub",lv:"lav",mg:"mlg",mh:"mah",mi:"mri",mk:"mkd",ml:"mal",mn:"mon",mr:"mar",ms:"msa",mt:"mlt",my:"mya",na:"nau",nb:"nob",nd:"nde",ne:"nep",ng:"ndo",nl:"nld",nn:"nno",no:"nor",nr:"nbl",nv:"nav",ny:"nya",oc:"oci",oj:"oji",om:"orm",or:"ori",os:"oss",pa:"pan",pi:"pli",pl:"pol",ps:"pus",pt:"por",qu:"que",rm:"roh",rn:"run",ro:"ron",ru:"rus",rw:"kin",sa:"san",sc:"srd",sd:"snd",se:"sme",sg:"sag",si:"sin",sk:"slk",sl:"slv",sm:"smo",sn:"sna",so:"som",sq:"sqi",sr:"srp",ss:"ssw",st:"sot",su:"sun",sv:"swe",sw:"swa",ta:"tam",te:"tel",tg:"tgk",th:"tha",ti:"tir",tk:"tuk",tl:"tgl",tn:"tsn",to:"ton",tr:"tur",ts:"tso",tt:"tat",tw:"twi",ty:"tah",ug:"uig",uk:"ukr",ur:"urd",uz:"uzb",ve:"ven",vi:"vie",vo:"vol",wa:"wln",wo:"wol",xh:"xho",yi:"yid",yo:"yor",za:"zha",zh:"zho",zu:"zul"};const o={alb:"sqi",arm:"hye",baq:"eus",bur:"mya",chi:"zho",cze:"ces",dut:"nld",fre:"fra",geo:"kat",ger:"deu",gre:"ell",ice:"isl",mac:"mkd",mao:"mri",may:"msa",per:"fas",slo:"slk",rum:"ron",tib:"bod",wel:"cym"};function s(e){if((0,i.Z)(e)||""===e)return"";var t=function(e){var t;switch(e.length){case 2:t=a[e];break;case 3:t=o[e]}return t}((""+e).toLowerCase().split("-")[0]);return(0,r.Z)(t)?t:e}function u(e){if(!(0,i.Z)(e)){var t,n=!1;return"string"==typeof e?t=e:(t=e.language,!0===e.closedCaption&&(n=!0)),{language:t,closedCaption:n,normalized:s(t)}}return e}function l(e){if((0,i.Z)(e))return e;if("string"==typeof e)return{language:e,audioDescription:!1,normalized:s(e)};var t={language:e.language,audioDescription:!0===e.audioDescription,normalized:s(s(e.language))};return!0===e.isDub&&(t.isDub=!0),t}const d=s},8894:(e,t,n)=>{"use strict";function r(){}n.d(t,{Z:()=>r})},8026:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r="function"==typeof Object.assign?Object.assign:function(e){if(null==e)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(e),n=0;n<(arguments.length<=1?0:arguments.length-1);n++){var r=n+1<1||arguments.length<=n+1?void 0:arguments[n+1];for(var i in r)Object.prototype.hasOwnProperty.call(r,i)&&(t[i]=r[i])}return t}},1679:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r="function"==typeof Object.values?Object.values:function(e){return Object.keys(e).map((function(t){return e[t]}))}},9589:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(8555);const i="function"==typeof Promise?Promise:n.n(r)()},2829:(e,t,n)=>{"use strict";n.d(t,{JN:()=>d,uH:()=>b,F_:()=>p,L7:()=>m,XS:()=>f,DD:()=>v,rx:()=>c,at:()=>h,kR:()=>g,Ti:()=>s,A1:()=>o,tn:()=>_});function r(e,t){return Math.abs(e-t)<.016666666666666666}function i(e,t){return{start:Math.min(e.start,t.start),end:Math.max(e.end,t.end)}}function a(e,t){return e.end<=t.start}function o(e,t){for(var n=0;n=0;n--){var r=e.start(n);if(t>=r){var i=e.end(n);if(t=o?r.push({start:a,end:o}):n={start:a,end:o}}return{outerRanges:r,innerRange:n}}function h(e,t){var n=c(e,t);return null!==n?n.end-n.start:0}function v(e,t){var n=c(e,t);return null!==n?t-n.start:0}function m(e,t){var n=c(e,t);return null!==n?n.end-t:1/0}function g(e,t){if(t.start===t.end)return e;for(var n=t,r=0;r0)for(var o=0;o0)for(var s=0;sl&&n.push({start:l,end:a[d].start}),l=a[d].end;l{"use strict";n.d(t,{ZP:()=>l});var r=n(4379),i=n(944),a=n(9105),o=n(6923),s=n(1946),u=i.Z.DEFAULT_REQUEST_TIMEOUT;const l=function(e){var t={url:e.url,headers:e.headers,responseType:(0,s.Z)(e.responseType)?"json":e.responseType,timeout:(0,s.Z)(e.timeout)?u:e.timeout};return new r.y((function(n){var r=t.url,i=t.headers,u=t.responseType,l=t.timeout,d=new XMLHttpRequest;if(d.open("GET",r,!0),l>=0&&(d.timeout=l),d.responseType=u,"document"===d.responseType&&d.overrideMimeType("text/xml"),!(0,s.Z)(i)){var c=i;for(var f in c)c.hasOwnProperty(f)&&d.setRequestHeader(f,c[f])}var p=performance.now();return d.onerror=function(){n.error(new a.Z(r,d.status,"ERROR_EVENT",d))},d.ontimeout=function(){n.error(new a.Z(r,d.status,"TIMEOUT",d))},!0===e.sendProgressEvents&&(d.onprogress=function(e){var t=performance.now();n.next({type:"progress",value:{url:r,duration:t-p,sendingTime:p,currentTime:t,size:e.loaded,totalSize:e.total}})}),d.onload=function(e){if(4===d.readyState)if(d.status>=200&&d.status<300){var t,i=performance.now(),u=d.response instanceof ArrayBuffer?d.response.byteLength:e.total,l=d.status,c=d.responseType,f=(0,o.Z)(d.responseURL)?d.responseURL:r;if(t="json"===c?"object"==typeof d.response?d.response:function(e){try{return JSON.parse(e)}catch(e){return null}}(d.responseText):d.response,(0,s.Z)(t))return void n.error(new a.Z(r,d.status,"PARSE_ERROR",d));n.next({type:"data-loaded",value:{status:l,url:f,responseType:c,sendingTime:p,receivedTime:i,duration:i-p,size:u,responseData:t}}),n.complete()}else n.error(new a.Z(r,d.status,"ERROR_HTTP_CODE",d))},d.send(),function(){(0,s.Z)(d)||4===d.readyState||d.abort()}}))}},9829:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o,f:()=>s});var r=/^(?:[a-z]+:)?\/\//i,i=/\/\.{1,2}\//;function a(e){if(!i.test(e))return e;for(var t=[],n=e.split("/"),r=0,a=n.length;r=0&&t===n+1)return e}var i=e.indexOf("?");return i>=0&&i{"use strict";n.d(t,{Z:()=>i});var r=n(4944);function i(e,t){try{return e(t)}catch(e){return(0,r._)(e)}}},9252:(e,t,n)=>{"use strict";function r(e,t,n){if("function"==typeof String.prototype.startsWith)return e.startsWith(t,n);var r="number"==typeof n?Math.max(n,0):0;return e.substring(r,r+t.length)===t}n.d(t,{Z:()=>r})},3635:(e,t,n)=>{"use strict";n.d(t,{ci:()=>p,nr:()=>f,tG:()=>l,uR:()=>c,TZ:()=>s,wV:()=>u,wO:()=>h,DM:()=>v});var r=n(3887),i=n(811),a="object"==typeof window&&"function"==typeof window.TextDecoder,o="object"==typeof window&&"function"==typeof window.TextEncoder;function s(e){for(var t=new ArrayBuffer(2*e.length),n=new Uint8Array(t),r=0;r>8&255}return n}function u(e){if(a)try{return new TextDecoder("utf-16le").decode(e)}catch(e){r.Z.warn("Utils: could not use TextDecoder to parse UTF-16LE, fallbacking to another implementation",e)}for(var t="",n=0;n=t?n:new Array(t-n.length+1).join("0")+n}function c(e){if(a)try{return(new TextDecoder).decode(e)}catch(e){r.Z.warn("Utils: could not use TextDecoder to parse UTF-8, fallbacking to another implementation",e)}var t=e;239===t[0]&&187===t[1]&&191===t[2]&&(t=t.subarray(3));var n,i=function(e){for(var t="",n=0;n=256?"%u"+d(u,4):"%"+d(u,2)}}return decodeURIComponent(n)}function f(e){for(var t=e.length,n=new Uint8Array(t/2),r=0,i=0;r>>4).toString(16),n+=(15&e[r]).toString(16),t.length>0&&r{"use strict";n.d(t,{Z:()=>i});var r=n(1946);function i(){for(var e=0,t=arguments.length,n=new Array(t),i=0;i{"use strict";n.d(t,{Z:()=>a});var r=n(7714),i=[];function a(e){(0,r.Z)(i,e)||(console.warn(e),i.push(e))}},7473:e=>{"use strict";var t=function(e){if("function"!=typeof e)throw new TypeError(e+" is not a function");return e},n=function(e){var n,r,i=document.createTextNode(""),a=0;return new e((function(){var e;if(n)r&&(n=r.concat(n));else{if(!r)return;n=r}if(r=n,n=null,"function"==typeof r)return e=r,r=null,void e();for(i.data=a=++a%2;r;)e=r.shift(),r.length||(r=null),e()})).observe(i,{characterData:!0}),function(e){t(e),n?"function"==typeof n?n=[n,e]:n.push(e):(n=e,i.data=a=++a%2)}};e.exports=function(){if("object"==typeof process&&process&&"function"==typeof process.nextTick)return process.nextTick;if("function"==typeof queueMicrotask)return function(e){queueMicrotask(t(e))};if("object"==typeof document&&document){if("function"==typeof MutationObserver)return n(MutationObserver);if("function"==typeof WebKitMutationObserver)return n(WebKitMutationObserver)}return"function"==typeof setImmediate?function(e){setImmediate(t(e))}:"function"==typeof setTimeout||"object"==typeof setTimeout?function(e){setTimeout(t(e),0)}:null}()},8555:(e,t,n)=>{"use strict";var r,i="pending",a="settled",o="fulfilled",s="rejected",u=function(){},l=void 0!==n.g&&void 0!==n.g.process&&"function"==typeof n.g.process.emit,d="undefined"==typeof setImmediate?setTimeout:setImmediate,c=[];function f(){for(var e=0;e{var t=function(e){"use strict";var t,n=Object.prototype,r=n.hasOwnProperty,i="function"==typeof Symbol?Symbol:{},a=i.iterator||"@@iterator",o=i.asyncIterator||"@@asyncIterator",s=i.toStringTag||"@@toStringTag";function u(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{u({},"")}catch(e){u=function(e,t,n){return e[t]=n}}function l(e,t,n,r){var i=t&&t.prototype instanceof m?t:m,a=Object.create(i.prototype),o=new I(r||[]);return a._invoke=function(e,t,n){var r=c;return function(i,a){if(r===p)throw new Error("Generator is already running");if(r===h){if("throw"===i)throw a;return R()}for(n.method=i,n.arg=a;;){var o=n.delegate;if(o){var s=k(o,n);if(s){if(s===v)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(r===c)throw r=h,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r=p;var u=d(e,t,n);if("normal"===u.type){if(r=n.done?h:f,u.arg===v)continue;return{value:u.arg,done:n.done}}"throw"===u.type&&(r=h,n.method="throw",n.arg=u.arg)}}}(e,n,o),a}function d(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}e.wrap=l;var c="suspendedStart",f="suspendedYield",p="executing",h="completed",v={};function m(){}function g(){}function y(){}var _={};_[a]=function(){return this};var b=Object.getPrototypeOf,T=b&&b(b(Z([])));T&&T!==n&&r.call(T,a)&&(_=T);var E=y.prototype=m.prototype=Object.create(_);function w(e){["next","throw","return"].forEach((function(t){u(e,t,(function(e){return this._invoke(t,e)}))}))}function S(e,t){function n(i,a,o,s){var u=d(e[i],e,a);if("throw"!==u.type){var l=u.arg,c=l.value;return c&&"object"==typeof c&&r.call(c,"__await")?t.resolve(c.__await).then((function(e){n("next",e,o,s)}),(function(e){n("throw",e,o,s)})):t.resolve(c).then((function(e){l.value=e,o(l)}),(function(e){return n("throw",e,o,s)}))}s(u.arg)}var i;this._invoke=function(e,r){function a(){return new t((function(t,i){n(e,r,t,i)}))}return i=i?i.then(a,a):a()}}function k(e,n){var r=e.iterator[n.method];if(r===t){if(n.delegate=null,"throw"===n.method){if(e.iterator.return&&(n.method="return",n.arg=t,k(e,n),"throw"===n.method))return v;n.method="throw",n.arg=new TypeError("The iterator does not provide a 'throw' method")}return v}var i=d(r,e.iterator,n.arg);if("throw"===i.type)return n.method="throw",n.arg=i.arg,n.delegate=null,v;var a=i.arg;return a?a.done?(n[e.resultName]=a.value,n.next=e.nextLoc,"return"!==n.method&&(n.method="next",n.arg=t),n.delegate=null,v):a:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,v)}function A(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function x(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function I(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(A,this),this.reset(!0)}function Z(e){if(e){var n=e[a];if(n)return n.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var i=-1,o=function n(){for(;++i=0;--a){var o=this.tryEntries[a],s=o.completion;if("root"===o.tryLoc)return i("end");if(o.tryLoc<=this.prev){var u=r.call(o,"catchLoc"),l=r.call(o,"finallyLoc");if(u&&l){if(this.prev=0;--n){var i=this.tryEntries[n];if(i.tryLoc<=this.prev&&r.call(i,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),x(n),v}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var i=r.arg;x(n)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,n,r){return this.delegate={iterator:Z(e),resultName:n,nextLoc:r},"next"===this.method&&(this.arg=t),v}},e}(e.exports);try{regeneratorRuntime=t}catch(e){Function("r","regeneratorRuntime = r")(t)}},2632:(e,t,n)=>{"use strict";n.d(t,{P:()=>s});var r,i=n(5631),a=n(8170),o=n(4944);r||(r={});var s=function(){function e(e,t,n){this.kind=e,this.value=t,this.error=n,this.hasValue="N"===e}return e.prototype.observe=function(e){switch(this.kind){case"N":return e.next&&e.next(this.value);case"E":return e.error&&e.error(this.error);case"C":return e.complete&&e.complete()}},e.prototype.do=function(e,t,n){switch(this.kind){case"N":return e&&e(this.value);case"E":return t&&t(this.error);case"C":return n&&n()}},e.prototype.accept=function(e,t,n){return e&&"function"==typeof e.next?this.observe(e):this.do(e,t,n)},e.prototype.toObservable=function(){switch(this.kind){case"N":return(0,a.of)(this.value);case"E":return(0,o._)(this.error);case"C":return(0,i.c)()}throw new Error("unexpected notification kind value")},e.createNext=function(t){return void 0!==t?new e("N",t):e.undefinedValueNotification},e.createError=function(t){return new e("E",void 0,t)},e.createComplete=function(){return e.completeNotification},e.completeNotification=new e("C"),e.undefinedValueNotification=new e("N",void 0),e}()},4379:(e,t,n)=>{"use strict";n.d(t,{y:()=>d});var r=n(979);var i=n(3142),a=n(2174);var o=n(5050),s=n(3608);function u(e){return 0===e.length?s.y:1===e.length?e[0]:function(t){return e.reduce((function(e,t){return t(e)}),t)}}var l=n(150),d=function(){function e(e){this._isScalar=!1,e&&(this._subscribe=e)}return e.prototype.lift=function(t){var n=new e;return n.source=this,n.operator=t,n},e.prototype.subscribe=function(e,t,n){var o=this.operator,s=function(e,t,n){if(e){if(e instanceof r.L)return e;if(e[i.b])return e[i.b]()}return e||t||n?new r.L(e,t,n):new r.L(a.c)}(e,t,n);if(o?s.add(o.call(s,this.source)):s.add(this.source||l.v.useDeprecatedSynchronousErrorHandling&&!s.syncErrorThrowable?this._subscribe(s):this._trySubscribe(s)),l.v.useDeprecatedSynchronousErrorHandling&&s.syncErrorThrowable&&(s.syncErrorThrowable=!1,s.syncErrorThrown))throw s.syncErrorValue;return s},e.prototype._trySubscribe=function(e){try{return this._subscribe(e)}catch(t){l.v.useDeprecatedSynchronousErrorHandling&&(e.syncErrorThrown=!0,e.syncErrorValue=t),!function(e){for(;e;){var t=e,n=t.closed,i=t.destination,a=t.isStopped;if(n||a)return!1;e=i&&i instanceof r.L?i:null}return!0}(e)?console.warn(t):e.error(t)}},e.prototype.forEach=function(e,t){var n=this;return new(t=c(t))((function(t,r){var i;i=n.subscribe((function(t){try{e(t)}catch(e){r(e),i&&i.unsubscribe()}}),r,t)}))},e.prototype._subscribe=function(e){var t=this.source;return t&&t.subscribe(e)},e.prototype[o.L]=function(){return this},e.prototype.pipe=function(){for(var e=[],t=0;t{"use strict";n.d(t,{c:()=>a});var r=n(150),i=n(1644),a={closed:!0,next:function(e){},error:function(e){if(r.v.useDeprecatedSynchronousErrorHandling)throw e;(0,i.z)(e)},complete:function(){}}},2039:(e,t,n)=>{"use strict";n.d(t,{L:()=>i});var r=n(655),i=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype.notifyNext=function(e,t,n,r,i){this.destination.next(t)},t.prototype.notifyError=function(e,t){this.destination.error(e)},t.prototype.notifyComplete=function(e){this.destination.complete()},t}(n(979).L)},2135:(e,t,n)=>{"use strict";n.d(t,{t:()=>h});var r=n(655),i=n(211),a=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.scheduler=t,r.work=n,r}return r.ZT(t,e),t.prototype.schedule=function(t,n){return void 0===n&&(n=0),n>0?e.prototype.schedule.call(this,t,n):(this.delay=n,this.state=t,this.scheduler.flush(this),this)},t.prototype.execute=function(t,n){return n>0||this.closed?e.prototype.execute.call(this,t,n):this._execute(t,n)},t.prototype.requestAsyncId=function(t,n,r){return void 0===r&&(r=0),null!==r&&r>0||null===r&&this.delay>0?e.prototype.requestAsyncId.call(this,t,n,r):t.flush(this)},t}(n(6114).o),o=new(function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t}(n(2980).v))(a),s=n(3884),u=n(979),l=n(2632);var d=function(e){function t(t,n,r){void 0===r&&(r=0);var i=e.call(this,t)||this;return i.scheduler=n,i.delay=r,i}return r.ZT(t,e),t.dispatch=function(e){var t=e.notification,n=e.destination;t.observe(n),this.unsubscribe()},t.prototype.scheduleMessage=function(e){this.destination.add(this.scheduler.schedule(t.dispatch,this.delay,new c(e,this.destination)))},t.prototype._next=function(e){this.scheduleMessage(l.P.createNext(e))},t.prototype._error=function(e){this.scheduleMessage(l.P.createError(e)),this.unsubscribe()},t.prototype._complete=function(){this.scheduleMessage(l.P.createComplete()),this.unsubscribe()},t}(u.L),c=function(){return function(e,t){this.notification=e,this.destination=t}}(),f=n(1016),p=n(8253),h=function(e){function t(t,n,r){void 0===t&&(t=Number.POSITIVE_INFINITY),void 0===n&&(n=Number.POSITIVE_INFINITY);var i=e.call(this)||this;return i.scheduler=r,i._events=[],i._infiniteTimeWindow=!1,i._bufferSize=t<1?1:t,i._windowTime=n<1?1:n,n===Number.POSITIVE_INFINITY?(i._infiniteTimeWindow=!0,i.next=i.nextInfiniteTimeWindow):i.next=i.nextTimeWindow,i}return r.ZT(t,e),t.prototype.nextInfiniteTimeWindow=function(t){if(!this.isStopped){var n=this._events;n.push(t),n.length>this._bufferSize&&n.shift()}e.prototype.next.call(this,t)},t.prototype.nextTimeWindow=function(t){this.isStopped||(this._events.push(new v(this._getNow(),t)),this._trimBufferThenGetEvents()),e.prototype.next.call(this,t)},t.prototype._subscribe=function(e){var t,n=this._infiniteTimeWindow,r=n?this._events:this._trimBufferThenGetEvents(),i=this.scheduler,a=r.length;if(this.closed)throw new f.N;if(this.isStopped||this.hasError?t=s.w.EMPTY:(this.observers.push(e),t=new p.W(this,e)),i&&e.add(e=new d(e,i)),n)for(var o=0;ot&&(a=Math.max(a,i-t)),a>0&&r.splice(0,a),r},t}(i.xQ),v=function(){return function(e,t){this.time=e,this.value=t}}()},211:(e,t,n)=>{"use strict";n.d(t,{Yc:()=>d,xQ:()=>c});var r=n(655),i=n(4379),a=n(979),o=n(3884),s=n(1016),u=n(8253),l=n(3142),d=function(e){function t(t){var n=e.call(this,t)||this;return n.destination=t,n}return r.ZT(t,e),t}(a.L),c=function(e){function t(){var t=e.call(this)||this;return t.observers=[],t.closed=!1,t.isStopped=!1,t.hasError=!1,t.thrownError=null,t}return r.ZT(t,e),t.prototype[l.b]=function(){return new d(this)},t.prototype.lift=function(e){var t=new f(this,this);return t.operator=e,t},t.prototype.next=function(e){if(this.closed)throw new s.N;if(!this.isStopped)for(var t=this.observers,n=t.length,r=t.slice(),i=0;i{"use strict";n.d(t,{W:()=>i});var r=n(655),i=function(e){function t(t,n){var r=e.call(this)||this;return r.subject=t,r.subscriber=n,r.closed=!1,r}return r.ZT(t,e),t.prototype.unsubscribe=function(){if(!this.closed){this.closed=!0;var e=this.subject,t=e.observers;if(this.subject=null,t&&0!==t.length&&!e.isStopped&&!e.closed){var n=t.indexOf(this.subscriber);-1!==n&&t.splice(n,1)}}},t}(n(3884).w)},979:(e,t,n)=>{"use strict";n.d(t,{L:()=>d});var r=n(655),i=n(4156),a=n(2174),o=n(3884),s=n(3142),u=n(150),l=n(1644),d=function(e){function t(n,r,i){var o=e.call(this)||this;switch(o.syncErrorValue=null,o.syncErrorThrown=!1,o.syncErrorThrowable=!1,o.isStopped=!1,arguments.length){case 0:o.destination=a.c;break;case 1:if(!n){o.destination=a.c;break}if("object"==typeof n){n instanceof t?(o.syncErrorThrowable=n.syncErrorThrowable,o.destination=n,n.add(o)):(o.syncErrorThrowable=!0,o.destination=new c(o,n));break}default:o.syncErrorThrowable=!0,o.destination=new c(o,n,r,i)}return o}return r.ZT(t,e),t.prototype[s.b]=function(){return this},t.create=function(e,n,r){var i=new t(e,n,r);return i.syncErrorThrowable=!1,i},t.prototype.next=function(e){this.isStopped||this._next(e)},t.prototype.error=function(e){this.isStopped||(this.isStopped=!0,this._error(e))},t.prototype.complete=function(){this.isStopped||(this.isStopped=!0,this._complete())},t.prototype.unsubscribe=function(){this.closed||(this.isStopped=!0,e.prototype.unsubscribe.call(this))},t.prototype._next=function(e){this.destination.next(e)},t.prototype._error=function(e){this.destination.error(e),this.unsubscribe()},t.prototype._complete=function(){this.destination.complete(),this.unsubscribe()},t.prototype._unsubscribeAndRecycle=function(){var e=this._parentOrParents;return this._parentOrParents=null,this.unsubscribe(),this.closed=!1,this.isStopped=!1,this._parentOrParents=e,this},t}(o.w),c=function(e){function t(t,n,r,o){var s,u=e.call(this)||this;u._parentSubscriber=t;var l=u;return(0,i.m)(n)?s=n:n&&(s=n.next,r=n.error,o=n.complete,n!==a.c&&(l=Object.create(n),(0,i.m)(l.unsubscribe)&&u.add(l.unsubscribe.bind(l)),l.unsubscribe=u.unsubscribe.bind(u))),u._context=l,u._next=s,u._error=r,u._complete=o,u}return r.ZT(t,e),t.prototype.next=function(e){if(!this.isStopped&&this._next){var t=this._parentSubscriber;u.v.useDeprecatedSynchronousErrorHandling&&t.syncErrorThrowable?this.__tryOrSetError(t,this._next,e)&&this.unsubscribe():this.__tryOrUnsub(this._next,e)}},t.prototype.error=function(e){if(!this.isStopped){var t=this._parentSubscriber,n=u.v.useDeprecatedSynchronousErrorHandling;if(this._error)n&&t.syncErrorThrowable?(this.__tryOrSetError(t,this._error,e),this.unsubscribe()):(this.__tryOrUnsub(this._error,e),this.unsubscribe());else if(t.syncErrorThrowable)n?(t.syncErrorValue=e,t.syncErrorThrown=!0):(0,l.z)(e),this.unsubscribe();else{if(this.unsubscribe(),n)throw e;(0,l.z)(e)}}},t.prototype.complete=function(){var e=this;if(!this.isStopped){var t=this._parentSubscriber;if(this._complete){var n=function(){return e._complete.call(e._context)};u.v.useDeprecatedSynchronousErrorHandling&&t.syncErrorThrowable?(this.__tryOrSetError(t,n),this.unsubscribe()):(this.__tryOrUnsub(n),this.unsubscribe())}else this.unsubscribe()}},t.prototype.__tryOrUnsub=function(e,t){try{e.call(this._context,t)}catch(e){if(this.unsubscribe(),u.v.useDeprecatedSynchronousErrorHandling)throw e;(0,l.z)(e)}},t.prototype.__tryOrSetError=function(e,t,n){if(!u.v.useDeprecatedSynchronousErrorHandling)throw new Error("bad call");try{t.call(this._context,n)}catch(t){return u.v.useDeprecatedSynchronousErrorHandling?(e.syncErrorValue=t,e.syncErrorThrown=!0,!0):((0,l.z)(t),!0)}return!1},t.prototype._unsubscribe=function(){var e=this._parentSubscriber;this._context=null,this._parentSubscriber=null,e.unsubscribe()},t}(d)},3884:(e,t,n)=>{"use strict";n.d(t,{w:()=>s});var r=n(9026),i=n(2009),a=n(4156),o=function(){function e(e){return Error.call(this),this.message=e?e.length+" errors occurred during unsubscription:\n"+e.map((function(e,t){return t+1+") "+e.toString()})).join("\n "):"",this.name="UnsubscriptionError",this.errors=e,this}return e.prototype=Object.create(Error.prototype),e}(),s=function(){function e(e){this.closed=!1,this._parentOrParents=null,this._subscriptions=null,e&&(this._ctorUnsubscribe=!0,this._unsubscribe=e)}var t;return e.prototype.unsubscribe=function(){var t;if(!this.closed){var n=this,s=n._parentOrParents,l=n._ctorUnsubscribe,d=n._unsubscribe,c=n._subscriptions;if(this.closed=!0,this._parentOrParents=null,this._subscriptions=null,s instanceof e)s.remove(this);else if(null!==s)for(var f=0;f{"use strict";n.d(t,{v:()=>i});var r=!1,i={Promise:void 0,set useDeprecatedSynchronousErrorHandling(e){e&&(new Error).stack;r=e},get useDeprecatedSynchronousErrorHandling(){return r}}},7604:(e,t,n)=>{"use strict";n.d(t,{IY:()=>s,Ds:()=>u,ft:()=>l});var r=n(655),i=n(979),a=n(4379),o=n(7843),s=function(e){function t(t){var n=e.call(this)||this;return n.parent=t,n}return r.ZT(t,e),t.prototype._next=function(e){this.parent.notifyNext(e)},t.prototype._error=function(e){this.parent.notifyError(e),this.unsubscribe()},t.prototype._complete=function(){this.parent.notifyComplete(),this.unsubscribe()},t}(i.L),u=(i.L,function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype.notifyNext=function(e){this.destination.next(e)},t.prototype.notifyError=function(e){this.destination.error(e)},t.prototype.notifyComplete=function(){this.destination.complete()},t}(i.L));i.L;function l(e,t){if(!t.closed){if(e instanceof a.y)return e.subscribe(t);var n;try{n=(0,o.s)(e)(t)}catch(e){t.error(e)}return n}}},5142:(e,t,n)=>{"use strict";n.d(t,{aj:()=>d});var r=n(655),i=n(7507),a=n(9026),o=n(2039),s=n(2080),u=n(3375),l={};function d(){for(var e=[],t=0;t{"use strict";n.d(t,{z:()=>a});var r=n(8170),i=n(2257);function a(){for(var e=[],t=0;t{"use strict";n.d(t,{P:()=>o});var r=n(4379),i=n(4072),a=n(5631);function o(e){return new r.y((function(t){var n;try{n=e()}catch(e){return void t.error(e)}return(n?(0,i.D)(n):(0,a.c)()).subscribe(t)}))}},5631:(e,t,n)=>{"use strict";n.d(t,{E:()=>i,c:()=>a});var r=n(4379),i=new r.y((function(e){return e.complete()}));function a(e){return e?function(e){return new r.y((function(t){return e.schedule((function(){return t.complete()}))}))}(e):i}},4072:(e,t,n)=>{"use strict";n.d(t,{D:()=>f});var r=n(4379),i=n(7843),a=n(3884),o=n(5050);var s=n(3109),u=n(999);var l=n(336),d=n(9217);function c(e,t){if(null!=e){if(function(e){return e&&"function"==typeof e[o.L]}(e))return function(e,t){return new r.y((function(n){var r=new a.w;return r.add(t.schedule((function(){var i=e[o.L]();r.add(i.subscribe({next:function(e){r.add(t.schedule((function(){return n.next(e)})))},error:function(e){r.add(t.schedule((function(){return n.error(e)})))},complete:function(){r.add(t.schedule((function(){return n.complete()})))}}))}))),r}))}(e,t);if((0,l.t)(e))return function(e,t){return new r.y((function(n){var r=new a.w;return r.add(t.schedule((function(){return e.then((function(e){r.add(t.schedule((function(){n.next(e),r.add(t.schedule((function(){return n.complete()})))})))}),(function(e){r.add(t.schedule((function(){return n.error(e)})))}))}))),r}))}(e,t);if((0,d.z)(e))return(0,s.r)(e,t);if(function(e){return e&&"function"==typeof e[u.hZ]}(e)||"string"==typeof e)return function(e,t){if(!e)throw new Error("Iterable cannot be null");return new r.y((function(n){var r,i=new a.w;return i.add((function(){r&&"function"==typeof r.return&&r.return()})),i.add(t.schedule((function(){r=e[u.hZ](),i.add(t.schedule((function(){if(!n.closed){var e,t;try{var i=r.next();e=i.value,t=i.done}catch(e){return void n.error(e)}t?n.complete():(n.next(e),this.schedule())}})))}))),i}))}(e,t)}throw new TypeError((null!==e&&typeof e||e)+" is not observable")}function f(e,t){return t?c(e,t):e instanceof r.y?e:new r.y((0,i.s)(e))}},3375:(e,t,n)=>{"use strict";n.d(t,{n:()=>o});var r=n(4379),i=n(6900),a=n(3109);function o(e,t){return t?(0,a.r)(e,t):new r.y((0,i.V)(e))}},7027:(e,t,n)=>{"use strict";n.d(t,{R:()=>s});var r=n(4379),i=n(9026),a=n(4156),o=n(5709);function s(e,t,n,l){return(0,a.m)(n)&&(l=n,n=void 0),l?s(e,t,n).pipe((0,o.U)((function(e){return(0,i.k)(e)?l.apply(void 0,e):l(e)}))):new r.y((function(r){u(e,t,(function(e){arguments.length>1?r.next(Array.prototype.slice.call(arguments)):r.next(e)}),r,n)}))}function u(e,t,n,r,i){var a;if(function(e){return e&&"function"==typeof e.addEventListener&&"function"==typeof e.removeEventListener}(e)){var o=e;e.addEventListener(t,n,i),a=function(){return o.removeEventListener(t,n,i)}}else if(function(e){return e&&"function"==typeof e.on&&"function"==typeof e.off}(e)){var s=e;e.on(t,n),a=function(){return s.off(t,n)}}else if(function(e){return e&&"function"==typeof e.addListener&&"function"==typeof e.removeListener}(e)){var l=e;e.addListener(t,n),a=function(){return l.removeListener(t,n)}}else{if(!e||!e.length)throw new TypeError("Invalid event target");for(var d=0,c=e.length;d{"use strict";n.d(t,{F:()=>o});var r=n(4379),i=n(964),a=n(5812);function o(e,t){return void 0===e&&(e=0),void 0===t&&(t=i.P),(!(0,a.k)(e)||e<0)&&(e=0),t&&"function"==typeof t.schedule||(t=i.P),new r.y((function(n){return n.add(t.schedule(s,e,{subscriber:n,counter:0,period:e})),n}))}function s(e){var t=e.subscriber,n=e.counter,r=e.period;t.next(n),this.schedule({subscriber:t,counter:n+1,period:r},r)}},4370:(e,t,n)=>{"use strict";n.d(t,{T:()=>s});var r=n(4379),i=n(7507),a=n(2556),o=n(3375);function s(){for(var e=[],t=0;t1&&"number"==typeof e[e.length-1]&&(n=e.pop())):"number"==typeof u&&(n=e.pop()),null===s&&1===e.length&&e[0]instanceof r.y?e[0]:(0,a.J)(n)((0,o.n)(e,s))}},8170:(e,t,n)=>{"use strict";n.d(t,{of:()=>o});var r=n(7507),i=n(3375),a=n(3109);function o(){for(var e=[],t=0;t{"use strict";n.d(t,{S3:()=>u});var r=n(655),i=n(9026),a=n(3375),o=n(2039),s=n(2080);function u(){for(var e=[],t=0;t{"use strict";n.d(t,{_:()=>i});var r=n(4379);function i(e,t){return t?new r.y((function(n){return t.schedule(a,0,{error:e,subscriber:n})})):new r.y((function(t){return t.error(e)}))}function a(e){var t=e.error;e.subscriber.error(t)}},9604:(e,t,n)=>{"use strict";n.d(t,{H:()=>s});var r=n(4379),i=n(964),a=n(5812),o=n(7507);function s(e,t,n){void 0===e&&(e=0);var s=-1;return(0,a.k)(t)?s=Number(t)<1?1:Number(t):(0,o.K)(t)&&(n=t),(0,o.K)(n)||(n=i.P),new r.y((function(t){var r=(0,a.k)(e)?e:+e-n.now();return n.schedule(u,r,{index:0,period:s,subscriber:t})}))}function u(e){var t=e.index,n=e.period,r=e.subscriber;if(r.next(t),!r.closed){if(-1===n)return r.complete();e.index=t+1,this.schedule(e,n)}}},486:(e,t,n)=>{"use strict";n.d(t,{K:()=>a});var r=n(655),i=n(7604);function a(e){return function(t){var n=new o(e),r=t.lift(n);return n.caught=r}}var o=function(){function e(e){this.selector=e}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.selector,this.caught))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.selector=n,i.caught=r,i}return r.ZT(t,e),t.prototype.error=function(t){if(!this.isStopped){var n=void 0;try{n=this.selector(t,this.caught)}catch(t){return void e.prototype.error.call(this,t)}this._unsubscribeAndRecycle();var r=new i.IY(this);this.add(r);var a=(0,i.ft)(n,r);a!==r&&this.add(a)}},t}(i.Ds)},2257:(e,t,n)=>{"use strict";n.d(t,{u:()=>i});var r=n(2556);function i(){return(0,r.J)(1)}},1931:(e,t,n)=>{"use strict";n.d(t,{x:()=>a});var r=n(655),i=n(979);function a(e,t){return function(n){return n.lift(new o(e,t))}}var o=function(){function e(e,t){this.compare=e,this.keySelector=t}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.compare,this.keySelector))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.keySelector=r,i.hasKey=!1,"function"==typeof n&&(i.compare=n),i}return r.ZT(t,e),t.prototype.compare=function(e,t){return e===t},t.prototype._next=function(e){var t;try{var n=this.keySelector;t=n?n(e):e}catch(e){return this.destination.error(e)}var r=!1;if(this.hasKey)try{r=(0,this.compare)(this.key,t)}catch(e){return this.destination.error(e)}else this.hasKey=!0;r||(this.key=t,this.destination.next(e))},t}(i.L)},6008:(e,t,n)=>{"use strict";n.d(t,{h:()=>a});var r=n(655),i=n(979);function a(e,t){return function(n){return n.lift(new o(e,t))}}var o=function(){function e(e,t){this.predicate=e,this.thisArg=t}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.predicate,this.thisArg))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.predicate=n,i.thisArg=r,i.count=0,i}return r.ZT(t,e),t.prototype._next=function(e){var t;try{t=this.predicate.call(this.thisArg,e,this.count++)}catch(e){return void this.destination.error(e)}t&&this.destination.next(e)},t}(i.L)},6738:(e,t,n)=>{"use strict";n.d(t,{l:()=>a});var r=n(655),i=n(979);function a(){return function(e){return e.lift(new o)}}var o=function(){function e(){}return e.prototype.call=function(e,t){return t.subscribe(new s(e))},e}(),s=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return r.ZT(t,e),t.prototype._next=function(e){},t}(i.L)},5709:(e,t,n)=>{"use strict";n.d(t,{U:()=>a});var r=n(655),i=n(979);function a(e,t){return function(n){if("function"!=typeof e)throw new TypeError("argument is not a function. Are you looking for `mapTo()`?");return n.lift(new o(e,t))}}var o=function(){function e(e,t){this.project=e,this.thisArg=t}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.project,this.thisArg))},e}(),s=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.project=n,i.count=0,i.thisArg=r||i,i}return r.ZT(t,e),t.prototype._next=function(e){var t;try{t=this.project.call(this.thisArg,e,this.count++)}catch(e){return void this.destination.error(e)}this.destination.next(t)},t}(i.L)},5602:(e,t,n)=>{"use strict";n.d(t,{h:()=>a});var r=n(655),i=n(979);function a(e){return function(t){return t.lift(new o(e))}}var o=function(){function e(e){this.value=e}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.value))},e}(),s=function(e){function t(t,n){var r=e.call(this,t)||this;return r.value=n,r}return r.ZT(t,e),t.prototype._next=function(e){this.destination.next(this.value)},t}(i.L)},2556:(e,t,n)=>{"use strict";n.d(t,{J:()=>a});var r=n(7746),i=n(3608);function a(e){return void 0===e&&(e=Number.POSITIVE_INFINITY),(0,r.zg)(i.y,e)}},7746:(e,t,n)=>{"use strict";n.d(t,{zg:()=>s});var r=n(655),i=n(5709),a=n(4072),o=n(7604);function s(e,t,n){return void 0===n&&(n=Number.POSITIVE_INFINITY),"function"==typeof t?function(r){return r.pipe(s((function(n,r){return(0,a.D)(e(n,r)).pipe((0,i.U)((function(e,i){return t(n,e,r,i)})))}),n))}:("number"==typeof t&&(n=t),function(t){return t.lift(new u(e,n))})}var u=function(){function e(e,t){void 0===t&&(t=Number.POSITIVE_INFINITY),this.project=e,this.concurrent=t}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.project,this.concurrent))},e}(),l=function(e){function t(t,n,r){void 0===r&&(r=Number.POSITIVE_INFINITY);var i=e.call(this,t)||this;return i.project=n,i.concurrent=r,i.hasCompleted=!1,i.buffer=[],i.active=0,i.index=0,i}return r.ZT(t,e),t.prototype._next=function(e){this.active0?this._next(e.shift()):0===this.active&&this.hasCompleted&&this.destination.complete()},t}(o.Ds)},3756:(e,t,n)=>{"use strict";n.d(t,{j:()=>i});var r=n(7746);function i(e,t,n){return void 0===n&&(n=Number.POSITIVE_INFINITY),"function"==typeof t?(0,r.zg)((function(){return e}),t,n):("number"==typeof t&&(n=t),(0,r.zg)((function(){return e}),n))}},1421:(e,t,n)=>{"use strict";n.d(t,{O:()=>f});var r=n(655),i=n(211),a=n(4379),o=n(979),s=n(3884),u=n(3018),l=function(e){function t(t,n){var r=e.call(this)||this;return r.source=t,r.subjectFactory=n,r._refCount=0,r._isComplete=!1,r}return r.ZT(t,e),t.prototype._subscribe=function(e){return this.getSubject().subscribe(e)},t.prototype.getSubject=function(){var e=this._subject;return e&&!e.isStopped||(this._subject=this.subjectFactory()),this._subject},t.prototype.connect=function(){var e=this._connection;return e||(this._isComplete=!1,(e=this._connection=new s.w).add(this.source.subscribe(new c(this.getSubject(),this))),e.closed&&(this._connection=null,e=s.w.EMPTY)),e},t.prototype.refCount=function(){return(0,u.x)()(this)},t}(a.y),d=function(){var e=l.prototype;return{operator:{value:null},_refCount:{value:0,writable:!0},_subject:{value:null,writable:!0},_connection:{value:null,writable:!0},_subscribe:{value:e._subscribe},_isComplete:{value:e._isComplete,writable:!0},getSubject:{value:e.getSubject},connect:{value:e.connect},refCount:{value:e.refCount}}}(),c=function(e){function t(t,n){var r=e.call(this,t)||this;return r.connectable=n,r}return r.ZT(t,e),t.prototype._error=function(t){this._unsubscribe(),e.prototype._error.call(this,t)},t.prototype._complete=function(){this.connectable._isComplete=!0,this._unsubscribe(),e.prototype._complete.call(this)},t.prototype._unsubscribe=function(){var e=this.connectable;if(e){this.connectable=null;var t=e._connection;e._refCount=0,e._subject=null,e._connection=null,t&&t.unsubscribe()}},t}(i.Yc);o.L;function f(e,t){return function(n){var r;if(r="function"==typeof e?e:function(){return e},"function"==typeof t)return n.lift(new p(r,t));var i=Object.create(n,d);return i.source=n,i.subjectFactory=r,i}}var p=function(){function e(e,t){this.subjectFactory=e,this.selector=t}return e.prototype.call=function(e,t){var n=this.selector,r=this.subjectFactory(),i=n(r).subscribe(e);return i.add(t.subscribe(r)),i},e}()},3018:(e,t,n)=>{"use strict";n.d(t,{x:()=>a});var r=n(655),i=n(979);function a(){return function(e){return e.lift(new o(e))}}var o=function(){function e(e){this.connectable=e}return e.prototype.call=function(e,t){var n=this.connectable;n._refCount++;var r=new s(e,n),i=t.subscribe(r);return r.closed||(r.connection=n.connect()),i},e}(),s=function(e){function t(t,n){var r=e.call(this,t)||this;return r.connectable=n,r}return r.ZT(t,e),t.prototype._unsubscribe=function(){var e=this.connectable;if(e){this.connectable=null;var t=e._refCount;if(t<=0)this.connection=null;else if(e._refCount=t-1,t>1)this.connection=null;else{var n=this.connection,r=e._connection;this.connection=null,!r||n&&r!==n||r.unsubscribe()}}else this.connection=null},t}(i.L)},2807:(e,t,n)=>{"use strict";n.d(t,{R:()=>a});var r=n(655),i=n(979);function a(e,t){var n=!1;return arguments.length>=2&&(n=!0),function(r){return r.lift(new o(e,t,n))}}var o=function(){function e(e,t,n){void 0===n&&(n=!1),this.accumulator=e,this.seed=t,this.hasSeed=n}return e.prototype.call=function(e,t){return t.subscribe(new s(e,this.accumulator,this.seed,this.hasSeed))},e}(),s=function(e){function t(t,n,r,i){var a=e.call(this,t)||this;return a.accumulator=n,a._seed=r,a.hasSeed=i,a.index=0,a}return r.ZT(t,e),Object.defineProperty(t.prototype,"seed",{get:function(){return this._seed},set:function(e){this.hasSeed=!0,this._seed=e},enumerable:!0,configurable:!0}),t.prototype._next=function(e){if(this.hasSeed)return this._tryNext(e);this.seed=e,this.destination.next(e)},t.prototype._tryNext=function(e){var t,n=this.index++;try{t=this.accumulator(this.seed,e,n)}catch(e){this.destination.error(e)}this.seed=t,this.destination.next(t)},t}(i.L)},9095:(e,t,n)=>{"use strict";n.d(t,{B:()=>s});var r=n(1421),i=n(3018),a=n(211);function o(){return new a.xQ}function s(){return function(e){return(0,i.x)()((0,r.O)(o)(e))}}},7006:(e,t,n)=>{"use strict";n.d(t,{d:()=>i});var r=n(2135);function i(e,t,n){var i;return i=e&&"object"==typeof e?e:{bufferSize:e,windowTime:t,refCount:!1,scheduler:n},function(e){return e.lift(function(e){var t,n,i=e.bufferSize,a=void 0===i?Number.POSITIVE_INFINITY:i,o=e.windowTime,s=void 0===o?Number.POSITIVE_INFINITY:o,u=e.refCount,l=e.scheduler,d=0,c=!1,f=!1;return function(e){var i;d++,!t||c?(c=!1,t=new r.t(a,s,l),i=t.subscribe(this),n=e.subscribe({next:function(e){t.next(e)},error:function(e){c=!0,t.error(e)},complete:function(){f=!0,n=void 0,t.complete()}}),f&&(n=void 0)):i=t.subscribe(this),this.add((function(){d--,i.unsubscribe(),i=void 0,n&&!f&&u&&0===d&&(n.unsubscribe(),n=void 0,t=void 0)}))}}(i))}}},3485:(e,t,n)=>{"use strict";n.d(t,{O:()=>a});var r=n(9795),i=n(7507);function a(){for(var e=[],t=0;t{"use strict";n.d(t,{w:()=>s});var r=n(655),i=n(5709),a=n(4072),o=n(7604);function s(e,t){return"function"==typeof t?function(n){return n.pipe(s((function(n,r){return(0,a.D)(e(n,r)).pipe((0,i.U)((function(e,i){return t(n,e,r,i)})))})))}:function(t){return t.lift(new u(e))}}var u=function(){function e(e){this.project=e}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.project))},e}(),l=function(e){function t(t,n){var r=e.call(this,t)||this;return r.project=n,r.index=0,r}return r.ZT(t,e),t.prototype._next=function(e){var t,n=this.index++;try{t=this.project(e,n)}catch(e){return void this.destination.error(e)}this._innerSub(t)},t.prototype._innerSub=function(e){var t=this.innerSubscription;t&&t.unsubscribe();var n=new o.IY(this),r=this.destination;r.add(n),this.innerSubscription=(0,o.ft)(e,n),this.innerSubscription!==n&&r.add(this.innerSubscription)},t.prototype._complete=function(){var t=this.innerSubscription;t&&!t.closed||e.prototype._complete.call(this),this.unsubscribe()},t.prototype._unsubscribe=function(){this.innerSubscription=void 0},t.prototype.notifyComplete=function(){this.innerSubscription=void 0,this.isStopped&&e.prototype._complete.call(this)},t.prototype.notifyNext=function(e){this.destination.next(e)},t}(o.Ds)},1198:(e,t,n)=>{"use strict";n.d(t,{c:()=>i});var r=n(6381);function i(e,t){return t?(0,r.w)((function(){return e}),t):(0,r.w)((function(){return e}))}},1015:(e,t,n)=>{"use strict";n.d(t,{q:()=>s});var r=n(655),i=n(979),a=n(6565),o=n(5631);function s(e){return function(t){return 0===e?(0,o.c)():t.lift(new u(e))}}var u=function(){function e(e){if(this.total=e,this.total<0)throw new a.W}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.total))},e}(),l=function(e){function t(t,n){var r=e.call(this,t)||this;return r.total=n,r.count=0,r}return r.ZT(t,e),t.prototype._next=function(e){var t=this.total,n=++this.count;n<=t&&(this.destination.next(e),n===t&&(this.destination.complete(),this.unsubscribe()))},t}(i.L)},1558:(e,t,n)=>{"use strict";n.d(t,{R:()=>a});var r=n(655),i=n(7604);function a(e){return function(t){return t.lift(new o(e))}}var o=function(){function e(e){this.notifier=e}return e.prototype.call=function(e,t){var n=new s(e),r=(0,i.ft)(this.notifier,new i.IY(n));return r&&!n.seenValue?(n.add(r),t.subscribe(n)):n},e}(),s=function(e){function t(t){var n=e.call(this,t)||this;return n.seenValue=!1,n}return r.ZT(t,e),t.prototype.notifyNext=function(){this.seenValue=!0,this.complete()},t.prototype.notifyComplete=function(){},t}(i.Ds)},3068:(e,t,n)=>{"use strict";n.d(t,{b:()=>s});var r=n(655),i=n(979),a=n(3306),o=n(4156);function s(e,t,n){return function(r){return r.lift(new u(e,t,n))}}var u=function(){function e(e,t,n){this.nextOrObserver=e,this.error=t,this.complete=n}return e.prototype.call=function(e,t){return t.subscribe(new l(e,this.nextOrObserver,this.error,this.complete))},e}(),l=function(e){function t(t,n,r,i){var s=e.call(this,t)||this;return s._tapNext=a.Z,s._tapError=a.Z,s._tapComplete=a.Z,s._tapError=r||a.Z,s._tapComplete=i||a.Z,(0,o.m)(n)?(s._context=s,s._tapNext=n):n&&(s._context=n,s._tapNext=n.next||a.Z,s._tapError=n.error||a.Z,s._tapComplete=n.complete||a.Z),s}return r.ZT(t,e),t.prototype._next=function(e){try{this._tapNext.call(this._context,e)}catch(e){return void this.destination.error(e)}this.destination.next(e)},t.prototype._error=function(e){try{this._tapError.call(this._context,e)}catch(e){return void this.destination.error(e)}this.destination.error(e)},t.prototype._complete=function(){try{this._tapComplete.call(this._context)}catch(e){return void this.destination.error(e)}return this.destination.complete()},t}(i.L)},3109:(e,t,n)=>{"use strict";n.d(t,{r:()=>a});var r=n(4379),i=n(3884);function a(e,t){return new r.y((function(n){var r=new i.w,a=0;return r.add(t.schedule((function(){a!==e.length?(n.next(e[a++]),n.closed||r.add(this.schedule())):n.complete()}))),r}))}},6114:(e,t,n)=>{"use strict";n.d(t,{o:()=>i});var r=n(655),i=function(e){function t(t,n){var r=e.call(this,t,n)||this;return r.scheduler=t,r.work=n,r.pending=!1,r}return r.ZT(t,e),t.prototype.schedule=function(e,t){if(void 0===t&&(t=0),this.closed)return this;this.state=e;var n=this.id,r=this.scheduler;return null!=n&&(this.id=this.recycleAsyncId(r,n,t)),this.pending=!0,this.delay=t,this.id=this.id||this.requestAsyncId(r,this.id,t),this},t.prototype.requestAsyncId=function(e,t,n){return void 0===n&&(n=0),setInterval(e.flush.bind(e,this),n)},t.prototype.recycleAsyncId=function(e,t,n){if(void 0===n&&(n=0),null!==n&&this.delay===n&&!1===this.pending)return t;clearInterval(t)},t.prototype.execute=function(e,t){if(this.closed)return new Error("executing a cancelled action");this.pending=!1;var n=this._execute(e,t);if(n)return n;!1===this.pending&&null!=this.id&&(this.id=this.recycleAsyncId(this.scheduler,this.id,null))},t.prototype._execute=function(e,t){var n=!1,r=void 0;try{this.work(e)}catch(e){n=!0,r=!!e&&e||new Error(e)}if(n)return this.unsubscribe(),r},t.prototype._unsubscribe=function(){var e=this.id,t=this.scheduler,n=t.actions,r=n.indexOf(this);this.work=null,this.state=null,this.pending=!1,this.scheduler=null,-1!==r&&n.splice(r,1),null!=e&&(this.id=this.recycleAsyncId(t,e,null)),this.delay=null},t}(function(e){function t(t,n){return e.call(this)||this}return r.ZT(t,e),t.prototype.schedule=function(e,t){return void 0===t&&(t=0),this},t}(n(3884).w))},2980:(e,t,n)=>{"use strict";n.d(t,{v:()=>a});var r=n(655),i=function(){function e(t,n){void 0===n&&(n=e.now),this.SchedulerAction=t,this.now=n}return e.prototype.schedule=function(e,t,n){return void 0===t&&(t=0),new this.SchedulerAction(this,e).schedule(n,t)},e.now=function(){return Date.now()},e}(),a=function(e){function t(n,r){void 0===r&&(r=i.now);var a=e.call(this,n,(function(){return t.delegate&&t.delegate!==a?t.delegate.now():r()}))||this;return a.actions=[],a.active=!1,a.scheduled=void 0,a}return r.ZT(t,e),t.prototype.schedule=function(n,r,i){return void 0===r&&(r=0),t.delegate&&t.delegate!==this?t.delegate.schedule(n,r,i):e.prototype.schedule.call(this,n,r,i)},t.prototype.flush=function(e){var t=this.actions;if(this.active)t.push(e);else{var n;this.active=!0;do{if(n=e.execute(e.state,e.delay))break}while(e=t.shift());if(this.active=!1,n){for(;e=t.shift();)e.unsubscribe();throw n}}},t}(i)},964:(e,t,n)=>{"use strict";n.d(t,{P:()=>i});var r=n(6114),i=new(n(2980).v)(r.o)},999:(e,t,n)=>{"use strict";function r(){return"function"==typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator"}n.d(t,{hZ:()=>i});var i=r()},5050:(e,t,n)=>{"use strict";n.d(t,{L:()=>r});var r=function(){return"function"==typeof Symbol&&Symbol.observable||"@@observable"}()},3142:(e,t,n)=>{"use strict";n.d(t,{b:()=>r});var r=function(){return"function"==typeof Symbol?Symbol("rxSubscriber"):"@@rxSubscriber_"+Math.random()}()},6565:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});var r=function(){function e(){return Error.call(this),this.message="argument out of range",this.name="ArgumentOutOfRangeError",this}return e.prototype=Object.create(Error.prototype),e}()},1016:(e,t,n)=>{"use strict";n.d(t,{N:()=>r});var r=function(){function e(){return Error.call(this),this.message="object unsubscribed",this.name="ObjectUnsubscribedError",this}return e.prototype=Object.create(Error.prototype),e}()},1644:(e,t,n)=>{"use strict";function r(e){setTimeout((function(){throw e}),0)}n.d(t,{z:()=>r})},3608:(e,t,n)=>{"use strict";function r(e){return e}n.d(t,{y:()=>r})},9026:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});var r=function(){return Array.isArray||function(e){return e&&"number"==typeof e.length}}()},9217:(e,t,n)=>{"use strict";n.d(t,{z:()=>r});var r=function(e){return e&&"number"==typeof e.length&&"function"!=typeof e}},9914:(e,t,n)=>{"use strict";function r(e){return e instanceof Date&&!isNaN(+e)}n.d(t,{J:()=>r})},4156:(e,t,n)=>{"use strict";function r(e){return"function"==typeof e}n.d(t,{m:()=>r})},5812:(e,t,n)=>{"use strict";n.d(t,{k:()=>i});var r=n(9026);function i(e){return!(0,r.k)(e)&&e-parseFloat(e)+1>=0}},2009:(e,t,n)=>{"use strict";function r(e){return null!==e&&"object"==typeof e}n.d(t,{K:()=>r})},336:(e,t,n)=>{"use strict";function r(e){return!!e&&"function"!=typeof e.subscribe&&"function"==typeof e.then}n.d(t,{t:()=>r})},7507:(e,t,n)=>{"use strict";function r(e){return e&&"function"==typeof e.schedule}n.d(t,{K:()=>r})},3306:(e,t,n)=>{"use strict";function r(){}n.d(t,{Z:()=>r})},7843:(e,t,n)=>{"use strict";n.d(t,{s:()=>d});var r=n(6900),i=n(1644),a=n(999),o=n(5050),s=n(9217),u=n(336),l=n(2009),d=function(e){if(e&&"function"==typeof e[o.L])return d=e,function(e){var t=d[o.L]();if("function"!=typeof t.subscribe)throw new TypeError("Provided object does not correctly implement Symbol.observable");return t.subscribe(e)};if((0,s.z)(e))return(0,r.V)(e);if((0,u.t)(e))return n=e,function(e){return n.then((function(t){e.closed||(e.next(t),e.complete())}),(function(t){return e.error(t)})).then(null,i.z),e};if(e&&"function"==typeof e[a.hZ])return t=e,function(e){for(var n=t[a.hZ]();;){var r=void 0;try{r=n.next()}catch(t){return e.error(t),e}if(r.done){e.complete();break}if(e.next(r.value),e.closed)break}return"function"==typeof n.return&&e.add((function(){n.return&&n.return()})),e};var t,n,d,c=(0,l.K)(e)?"an invalid object":"'"+e+"'";throw new TypeError("You provided "+c+" where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.")}},6900:(e,t,n)=>{"use strict";n.d(t,{V:()=>r});var r=function(e){return function(t){for(var n=0,r=e.length;n{"use strict";n.d(t,{D:()=>s});var r=n(655),i=function(e){function t(t,n,r){var i=e.call(this)||this;return i.parent=t,i.outerValue=n,i.outerIndex=r,i.index=0,i}return r.ZT(t,e),t.prototype._next=function(e){this.parent.notifyNext(this.outerValue,e,this.outerIndex,this.index++,this)},t.prototype._error=function(e){this.parent.notifyError(e,this),this.unsubscribe()},t.prototype._complete=function(){this.parent.notifyComplete(this),this.unsubscribe()},t}(n(979).L),a=n(7843),o=n(4379);function s(e,t,n,r,s){if(void 0===s&&(s=new i(e,n,r)),!s.closed)return t instanceof o.y?t.subscribe(s):(0,a.s)(t)(s)}},655:(e,t,n)=>{"use strict";n.d(t,{ZT:()=>i});var r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function i(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var a=t[r]={exports:{}};return e[r](a,a.exports,n),a.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var r={};return(()=>{"use strict";n.d(r,{default:()=>Ui});var e=n(5991),t=n(1788),i=n(211),a=n(2135),o=n(655),s=n(1016),u=function(e){function t(t){var n=e.call(this)||this;return n._value=t,n}return o.ZT(t,e),Object.defineProperty(t.prototype,"value",{get:function(){return this.getValue()},enumerable:!0,configurable:!0}),t.prototype._subscribe=function(t){var n=e.prototype._subscribe.call(this,t);return n&&!n.closed&&t.next(this._value),n},t.prototype.getValue=function(){if(this.hasError)throw this.thrownError;if(this.closed)throw new s.N;return this._value},t.prototype.next=function(t){e.prototype.next.call(this,this._value=t)},t}(i.xQ),l=n(8170),d=n(5142),c=n(9795),f=n(4370),p=n(5631),h=n(1558),v=n(5709),m=n(1931),g=n(7746),y=n(7006),_=n(1421);function b(e){return e?(0,_.O)((function(){return new i.xQ}),e):(0,_.O)(new i.xQ)}var T=n(6008),E=n(9095),w=n(3485),S=n(1015),k=n(5602),A=n(979);var x=function(){function e(e){this.predicate=e}return e.prototype.call=function(e,t){return t.subscribe(new I(e,this.predicate))},e}(),I=function(e){function t(t,n){var r=e.call(this,t)||this;return r.predicate=n,r.skipping=!0,r.index=0,r}return o.ZT(t,e),t.prototype._next=function(e){var t=this.destination;this.skipping&&this.tryCallPredicate(e),this.skipping||t.next(e)},t.prototype.tryCallPredicate=function(e){try{var t=this.predicate(e,this.index++);this.skipping=Boolean(t)}catch(e){this.destination.error(e)}},t}(A.L),Z=n(1198),R=n(3756),M=n(1473);function C(){if(N()){var e=document;"function"==typeof e.exitFullscreen?e.exitFullscreen():"function"==typeof e.msExitFullscreen?e.msExitFullscreen():"function"==typeof e.mozCancelFullScreen?e.mozCancelFullScreen():"function"==typeof e.webkitExitFullscreen&&e.webkitExitFullscreen()}}function N(){var e=document;return null!=e.fullscreenElement||null!=e.mozFullScreenElement||null!=e.webkitFullscreenElement||null!=e.msFullscreenElement}var P=n(3666),O=n(3887);function D(){var e,t;if(!P.vU)return!0;var n=function(){if(!P.vU)return O.Z.warn("Compat: Can't access Firefox version on no firefox browser."),null;var e=navigator.userAgent,t=/Firefox\/([0-9]+)\./.exec(e);if(null===t)return-1;var n=parseInt(t[1],10);return isNaN(n)?-1:n}();return null===n||n<67||void 0!==(null===(t=null===(e=HTMLVideoElement)||void 0===e?void 0:e.prototype)||void 0===t?void 0:t.requirePictureInPicture)}var L=n(944),B=n(3714),U=n(9822),F=n(5389);function z(e,t){var n=t.defaultCode,r=t.defaultReason;if((0,U.Z)(e))return e;var i=e instanceof Error?e.toString():r;return new F.Z(n,i)}var K=n(5992),V=n(7874),W=n(1966),G=n(4791),H=n(1959),$=n(1946),j=n(8894),Y=n(8026),q=n(9589),X=n(2829),Q=n(8806),J=n(1410),ee=n(6139),te=n(6033);function ne(e){return(0,J.P)((function(){var t=te.Z.getState(e);if(null===t)return(0,l.of)(null);O.Z.info("EME: Disposing of the current MediaKeys");var n=t.loadedSessionsStore;return te.Z.clearState(e),n.closeAllSessions().pipe((0,R.j)((0,ee.Y)(e,null)))}))}function re(e){var t=te.Z.getState(e);return null==t?null:t.keySystemOptions.type}var ie=n(6738);function ae(e){return(0,J.P)((function(){if(O.Z.info("EME: Clearing-up EME session."),P.fq)return O.Z.info("EME: disposing current MediaKeys."),ne(e).pipe((0,ie.l)());var t=te.Z.getState(e);return null!==t&&!0===t.keySystemOptions.closeSessionsOnStop?(O.Z.info("EME: closing all current sessions."),t.loadedSessionsStore.closeAllSessions().pipe((0,ie.l)())):(O.Z.info("EME: Nothing to clear. Returning right away. No state =",null===t),p.E)}))}var oe=n(486),se=n(3884);function ue(e){return function(t){return t.lift(new le(e))}}var le=function(){function e(e){this.callback=e}return e.prototype.call=function(e,t){return t.subscribe(new de(e,this.callback))},e}(),de=function(e){function t(t,n){var r=e.call(this,t)||this;return r.add(new se.w(n)),r}return o.ZT(t,e),t}(A.L),ce=n(5561),fe=n(2793),pe=n(9105),he=n(9362);function ve(e){return e instanceof pe.Z?new he.Z("PIPELINE_LOAD_ERROR",e):z(e,{defaultCode:"PIPELINE_LOAD_ERROR",defaultReason:"Unknown error when fetching the Manifest"})}var me=n(9604);var ge,ye=n(2572);function _e(e){return e.type===K.br.ERROR_EVENT&&!1===navigator.onLine}function be(e,t,n){var r=n.baseDelay,i=n.maxDelay,a=n.maxRetryRegular,o=n.maxRetryOffline,s=0,u=ge.None,l=e.slice();return 0===l.length?(O.Z.warn("Fetchers: no URL given to `tryURLsWithBackoff`."),p.E):function e(n,d){return t(n).pipe((0,v.U)((function(e){return{type:"response",value:e}})),(0,oe.K)((function(t){if(!function(e){return e instanceof pe.Z?e.type===K.br.ERROR_HTTP_CODE?e.status>=500||404===e.status||415===e.status||412===e.status:e.type===K.br.TIMEOUT||e.type===K.br.ERROR_EVENT:(0,U.Z)(e)&&"INTEGRITY_ERROR"===e.code}(t)){if(l.length<=1)throw t;l.splice(d,1);var n=d>=l.length-1?0:d;return e(l[n],n).pipe((0,w.O)({type:"retry",value:t}))}var c=function(e){return e instanceof pe.Z&&_e(e)?ge.Offline:ge.Regular}(t),f=c===ge.Offline?o:a;if(c!==u&&(s=0,u=c),df)throw t;var h=Math.min(r*Math.pow(2,s-1),i),v=(0,ye.Z)(h),m=l[0];return(0,me.H)(v).pipe((0,g.zg)((function(){return e(m,0)})),(0,w.O)({type:"retry",value:t}))})))}(l[0],0)}function Te(e,t){return be([null],(function(){return e}),t)}!function(e){e[e.None=0]="None",e[e.Regular=1]="Regular",e[e.Offline=2]="Offline"}(ge||(ge={}));var Ee=L.Z.DEFAULT_MAX_MANIFEST_REQUEST_RETRY,we=L.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE,Se=L.Z.INITIAL_BACKOFF_DELAY_BASE,ke=L.Z.MAX_BACKOFF_DELAY_BASE;const Ae=function(){function e(e,t,n){var r,i,a,o;this._manifestUrl=e,this._pipelines=t.manifest,this._backoffOptions=(i=(r=n).maxRetryRegular,a=r.maxRetryOffline,{baseDelay:(o=r.lowLatencyMode)?Se.LOW_LATENCY:Se.REGULAR,maxDelay:o?ke.LOW_LATENCY:ke.REGULAR,maxRetryRegular:void 0!==i?i:Ee,maxRetryOffline:void 0!==a?a:we})}var t=e.prototype;return t.fetch=function(e){var t,n=this,r=null!=e?e:this._manifestUrl,i=null!==(t=this._pipelines.resolver)&&void 0!==t?t:l.of,a=this._pipelines.loader;return(0,ce.Z)(i,{url:r}).pipe((0,oe.K)((function(e){throw ve(e)})),(0,g.zg)((function(e){return Te((0,ce.Z)(a,e),n._backoffOptions).pipe((0,oe.K)((function(e){throw ve(e)})),(0,v.U)((function(e){return"retry"===e.type?{type:"warning",value:ve(e.value)}:{type:"response",parse:function(t){return n._parseLoadedManifest(e.value.value,t)}}})))})))},t.parse=function(e,t){return this._parseLoadedManifest({responseData:e,size:void 0,duration:void 0},t)},t._parseLoadedManifest=function(e,t){var n,r,a=e.sendingTime,o=e.receivedTime,s=performance.now(),u=new i.xQ,l=(n=this._backoffOptions,r=u,function(e){return Te((0,ce.Z)(e,void 0),n).pipe((0,fe.Z)((function(e){return"retry"===e.type?(r.next(ve(e.value)),null):e.value}),null),(0,oe.K)((function(e){throw ve(e)})))});return(0,f.T)(u.pipe((0,v.U)((function(e){return{type:"warning",value:e}}))),this._pipelines.parser({response:e,url:this._manifestUrl,externalClockOffset:t.externalClockOffset,previousManifest:t.previousManifest,scheduleRequest:l,unsafeMode:t.unsafeMode}).pipe((0,oe.K)((function(e){throw z(e,{defaultCode:"PIPELINE_PARSE_ERROR",defaultReason:"Unknown error when parsing the Manifest"})})),(0,v.U)((function(e){if("warning"===e.type)return{type:"warning",value:z(e.value,{defaultCode:"PIPELINE_PARSE_ERROR",defaultReason:"Unknown error when parsing the Manifest"})};var t=performance.now()-s;return{type:"parsed",manifest:e.value.manifest,sendingTime:a,receivedTime:o,parsingTime:t}})),ue((function(){u.complete()}))))},e}();var xe=L.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_ERROR,Ie=L.Z.DEFAULT_MAX_REQUESTS_RETRY_ON_OFFLINE,Ze=L.Z.INITIAL_BACKOFF_DELAY_BASE,Re=L.Z.MAX_BACKOFF_DELAY_BASE;var Me=n(4379),Ce=n(5138),Ne=function(){function e(e){var t=e.prioritySteps;if(this._minPendingPriority=null,this._waitingQueue=[],this._pendingTasks=[],this._prioritySteps=t,this._prioritySteps.high>=this._prioritySteps.low)throw new Error("FP Error: the max high level priority should be given a lowerpriority number than the min low priority.")}var t=e.prototype;return t.create=function(e,t){var n=this,r=new Me.y((function(i){var a,o=!0;return a={observable:r,priority:t,trigger:function(t){null!==a.subscription&&(a.subscription.unsubscribe(),a.subscription=null,o&&i.next({type:"interrupted"})),t&&(n._minPendingPriority=null===n._minPendingPriority?a.priority:Math.min(n._minPendingPriority,a.priority),n._pendingTasks.push(a),a.subscription=e.subscribe((function(e){return i.next({type:"data",value:e})}),(function(e){i.error(e),a.subscription=null,a.finished=!0,n._onTaskEnd(a)}),(function(){i.next({type:"ended"}),o&&i.complete(),a.subscription=null,a.finished=!0,n._onTaskEnd(a)})))},subscription:null,finished:!1},n._canBeStartedNow(a)?(a.trigger(!0),n._isRunningHighPriorityTasks()&&n._interruptCancellableTasks()):n._waitingQueue.push(a),function(){if(o=!1,null!==a.subscription&&(a.subscription.unsubscribe(),a.subscription=null),!a.finished){var e=(0,Ce.Z)(n._waitingQueue,(function(e){return e.observable===r}));if(e>=0)n._waitingQueue.splice(e,1);else{var t=(0,Ce.Z)(n._pendingTasks,(function(e){return e.observable===r}));if(t<0)return void O.Z.warn("FP: unsubscribing non-existent task");var i=n._pendingTasks.splice(t,1)[0];0===n._pendingTasks.length?(n._minPendingPriority=null,n._loopThroughWaitingQueue()):n._minPendingPriority===i.priority&&(n._minPendingPriority=Math.min.apply(Math,n._pendingTasks.map((function(e){return e.priority}))),n._loopThroughWaitingQueue())}}}}));return r},t.updatePriority=function(e,t){var n=(0,Ce.Z)(this._waitingQueue,(function(t){return t.observable===e}));if(n>=0){var r=this._waitingQueue[n];if(r.priority===t)return;if(r.priority=t,!this._canBeStartedNow(r))return;return this._startWaitingQueueTask(n),void(this._isRunningHighPriorityTasks()&&this._interruptCancellableTasks())}var i=(0,Ce.Z)(this._pendingTasks,(function(t){return t.observable===e}));if(i<0)O.Z.warn("FP: request to update the priority of a non-existent task");else{var a=this._pendingTasks[i];if(a.priority!==t){var o=a.priority;if(a.priority=t,null===this._minPendingPriority||tt.priority?t.priority:e}),null);if(!(null===e||null!==this._minPendingPriority&&this._minPendingPriority=this._prioritySteps.low)return this._interruptPendingTask(t),this._interruptCancellableTasks()}},t._startWaitingQueueTask=function(e){this._waitingQueue.splice(e,1)[0].trigger(!0)},t._interruptPendingTask=function(e){var t=(0,Ce.Z)(this._pendingTasks,(function(t){return t.observable===e.observable}));t<0?O.Z.warn("FP: Interrupting a non-existent pending task. Aborting..."):(this._pendingTasks.splice(t,1),this._waitingQueue.push(e),0===this._pendingTasks.length?this._minPendingPriority=null:this._minPendingPriority===e.priority&&(this._minPendingPriority=Math.min.apply(Math,this._pendingTasks.map((function(e){return e.priority})))),e.trigger(!1))},t._onTaskEnd=function(e){var t=(0,Ce.Z)(this._pendingTasks,(function(t){return t.observable===e.observable}));t<0||(this._pendingTasks.splice(t,1),this._pendingTasks.length>0?this._minPendingPriority===e.priority&&(this._minPendingPriority=Math.min.apply(Math,this._pendingTasks.map((function(e){return e.priority})))):(this._minPendingPriority=null,this._loopThroughWaitingQueue()))},t._canBeStartedNow=function(e){return null===this._minPendingPriority||e.priority<=this._minPendingPriority},t._isRunningHighPriorityTasks=function(){return null!==this._minPendingPriority&&this._minPendingPriority<=this._prioritySteps.high},e}(),Pe=n(3068),Oe=n(7714),De=n(8418),Le=n(908);const Be=function(){function e(){this._cache=new WeakMap}var t=e.prototype;return t.add=function(e,t){var n=e.representation;e.segment.isInit&&this._cache.set(n,t)},t.get=function(e){var t=e.representation;if(e.segment.isInit){var n=this._cache.get(t);if(void 0!==n)return n}return null},e}();var Ue=n(8117);function Fe(e,t,n){return function(r){return function(r){function i(){var i;return be(null!==(i=r.segment.mediaURLs)&&void 0!==i?i:[null],(function(t){var n=(0,Y.Z)({url:t},r);return(0,c.z)((0,l.of)({type:"request",value:n}),(0,ce.Z)(e,n))}),n).pipe((0,oe.K)((function(e){throw ve(e)})),(0,v.U)((function(e){if("retry"===e.type)return{type:"warning",value:ve(e.value)};if("request"===e.value.type)return e.value;var n=e.value;return"data-loaded"===n.type&&null!=t&&t.add(r,n.value),e.value})))}var a=null!=t?t.get(r):null;return null!=a?(0,Ue.Z)(a).pipe((0,v.U)((function(e){return{type:"cache",value:e}})),(0,oe.K)(i)):i()}(r).pipe((0,g.zg)((function(e){var t;switch(t="data-chunk-complete"!==e.type&&"data-loaded"!==e.type||void 0===e.value.size||void 0===e.value.duration?p.E:(0,l.of)({type:"metrics",value:{size:e.value.size,duration:e.value.duration,content:r}}),e.type){case"warning":case"request":case"progress":return(0,l.of)(e);case"cache":case"data-created":case"data-loaded":return(0,c.z)((0,l.of)({type:"data",value:e.value}),t);case"data-chunk":return(0,l.of)({type:"chunk",value:e.value});case"data-chunk-complete":return(0,c.z)((0,l.of)({type:"chunk-complete",value:null}),t);default:(0,De.Z)(e)}})))}}var ze=(0,Le.Z)();var Ke=L.Z.MIN_CANCELABLE_PRIORITY,Ve=L.Z.MAX_HIGH_PRIORITY_LEVEL;const We=function(){function e(e,t){this._transport=e,this._prioritizer=new Ne({prioritySteps:{high:Ve,low:Ke}}),this._backoffOptions=t}return e.prototype.createSegmentFetcher=function(e,t){var n,r,i,a=function(e,t){var n=t.maxRetryRegular,r=t.maxRetryOffline,i=t.lowLatencyMode;return{maxRetryRegular:"image"===e?0:null!=n?n:xe,maxRetryOffline:null!=r?r:Ie,baseDelay:i?Ze.LOW_LATENCY:Ze.REGULAR,maxDelay:i?Re.LOW_LATENCY:Re.REGULAR}}(e,this._backoffOptions),o=function(e,t,n,r){var i=(0,Oe.Z)(["audio","video"],e)?new Be:void 0,a=Fe(t[e].loader,i,r),o=t[e].parser;return function(e){var t=ze(),r=!1;return a(e).pipe((0,Pe.b)((function(e){switch(e.type){case"metrics":n.next(e);break;case"request":var i=e.value.segment;if(void 0===i)return;r=!0,n.next({type:"requestBegin",value:{duration:i.duration,time:i.time,requestTimestamp:performance.now(),id:t}});break;case"progress":var a=e.value;null!=a.totalSize&&a.size0?this._next(e.shift()):0===this.active&&this.hasCompleted&&(!1===this.hasValue&&this.destination.next(this.acc),this.destination.complete())},t}(Ge.Ds),je=n(4072);function Ye(e,t){return t?function(n){return n.pipe(Ye((function(n,r){return(0,je.D)(e(n,r)).pipe((0,v.U)((function(e,i){return t(n,e,r,i)})))})))}:function(t){return t.lift(new qe(e))}}var qe=function(){function e(e){this.project=e}return e.prototype.call=function(e,t){return t.subscribe(new Xe(e,this.project))},e}(),Xe=function(e){function t(t,n){var r=e.call(this,t)||this;return r.project=n,r.hasSubscription=!1,r.hasCompleted=!1,r.index=0,r}return o.ZT(t,e),t.prototype._next=function(e){this.hasSubscription||this.tryNext(e)},t.prototype.tryNext=function(e){var t,n=this.index++;try{t=this.project(e,n)}catch(e){return void this.destination.error(e)}this.hasSubscription=!0,this._innerSub(t)},t.prototype._innerSub=function(e){var t=new Ge.IY(this),n=this.destination;n.add(t);var r=(0,Ge.ft)(e,t);r!==t&&n.add(r)},t.prototype._complete=function(){this.hasCompleted=!0,this.hasSubscription||this.destination.complete(),this.unsubscribe()},t.prototype.notifyNext=function(e){this.destination.next(e)},t.prototype.notifyError=function(e){this.destination.error(e)},t.prototype.notifyComplete=function(){this.hasSubscription=!1,this.hasCompleted&&this.destination.complete()},t}(Ge.Ds),Qe=n(6381);var Je=n(8025),et=n(5278),tt=function(){function e(e){this._alpha=Math.exp(Math.log(.5)/e),this._lastEstimate=0,this._totalWeight=0}var t=e.prototype;return t.addSample=function(e,t){var n=Math.pow(this._alpha,e),r=t*(1-n)+n*this._lastEstimate;isNaN(r)||(this._lastEstimate=r,this._totalWeight+=e)},t.getEstimate=function(){var e=1-Math.pow(this._alpha,this._totalWeight);return this._lastEstimate/e},e}(),nt=L.Z.ABR_MINIMUM_TOTAL_BYTES,rt=L.Z.ABR_MINIMUM_CHUNK_SIZE,it=L.Z.ABR_FAST_EMA,at=L.Z.ABR_SLOW_EMA,ot=function(){function e(){this._fastEWMA=new tt(it),this._slowEWMA=new tt(at),this._bytesSampled=0}var t=e.prototype;return t.addSample=function(e,t){if(!(t0){var i=r.indexOf(n);-1!==i&&r.splice(i,1)}},t.prototype.notifyComplete=function(){},t.prototype._next=function(e){if(0===this.toRespond.length){var t=[e].concat(this.values);this.project?this._tryProject(t):this.destination.next(t)}},t.prototype._tryProject=function(e){var t;try{t=this.project.apply(this,e)}catch(e){return void this.destination.error(e)}this.destination.next(t)},t}(st.L);function ft(e){var t=e.map((function(t){return Math.log(t/e[0])})),n=t.map((function(e){return e-t[0]+1})),r=(n[n.length-1]-1)/(2*e.length+10),i=1/r;return e.map((function(t,a){return function(t){if(0===t)return 0;var a=Math.min(Math.max(1,t),e.length-1);return i*(r+(e[a]*n[a-1]-e[a-1]*n[a])/(e[a]-e[a-1]))+4}(a)}))}function pt(e,t){var n=ft(t);return O.Z.debug("ABR: Steps for buffer based chooser.",n.map((function(e,n){return{bufferLevel:e,bitrate:t[n]}}))),e.pipe((0,v.U)((function(e){return function(e,t,n){var r=e.bufferGap,i=e.currentBitrate,a=e.currentScore,o=e.speed;if(null==i)return t[0];var s,u=(0,Ce.Z)(t,(function(e){return e===i}));if(u<0||t.length!==n.length)return O.Z.error("ABR: Current Bitrate not found in the calculated levels"),t[0];if(null!=a&&(s=0===o?a:a/o),null!=s&&s>1){var l=n[u],d=function(){for(var e=u+1;el)return e}();if(null!=d&&r>=n[d])return t[d]}if((null==s||s<1.15)&&r=0;c--)if(t[c]t&&t-e.time>-1.2}));if(n<0)return[];for(var r=e[n],i=r.time,a=[r],o=n+1;o0?l.progress[l.progress.length-1]:void 0,p=Et(l);if(void 0!==f&&void 0!==p){var h=wt(f,p);if((c-f.timestamp)/1e3<=h)if(h-s/a>2e3)return p}var v=(c-l.requestTimestamp)/1e3;if(null!=n&&!(v<=(1.5*d+2)/a)){var m=d/v,g=n.bitrate*Math.min(.7,m);return void 0===r||g=s.outOfStarvationGap&&(O.Z.info("ABR: exit starvation mode."),this._inStarvationMode=!1):this._inStarvationMode&&(O.Z.info("ABR: exit starvation mode."),this._inStarvationMode=!1),this._inStarvationMode&&null!=(o=St(r,e,n,i))&&(O.Z.info("ABR: starvation mode emergency estimate:",o),t.reset(),a=null==n?o:Math.min(o,n.bitrate)),null==a&&(a=null!=(o=t.getEstimate())?o*(this._inStarvationMode?s.starvationBitrateFactor:s.regularBitrateFactor):null!=i?i*(this._inStarvationMode?s.starvationBitrateFactor:s.regularBitrateFactor):this._initialBitrate),e.speed>1&&(a/=e.speed),{bandwidthEstimate:o,bitrateChosen:a}},t.isUrgent=function(e,t,n,r){return null===t||e!==t.bitrate&&(e>t.bitrate?!this._inStarvationMode:function(e,t){var n=isFinite(e.bufferGap)?e.bufferGap:0,r=e.position+n,i=(0,mt.Z)(t,(function(e){return e.duration>0&&e.time+e.duration>r}));if(void 0===i)return!0;var a=performance.now(),o=i.progress.length>0?i.progress[i.progress.length-1]:void 0,s=Et(i);if(void 0===o||void 0===s)return!0;var u=wt(o,s);return(a-o.timestamp)/1e3>1.2*u||u-n/e.speed>-1.5}(r,n))},e}(),At=n(1679),xt=function(){function e(){this._currentRequests={}}var t=e.prototype;return t.add=function(e){var t=e.id,n=e.time,r=e.duration,i=e.requestTimestamp;this._currentRequests[t]={time:n,duration:r,requestTimestamp:i,progress:[]}},t.addProgress=function(e){var t=this._currentRequests[e.id];null!=t?t.progress.push(e):O.Z.warn("ABR: progress for a request not added")},t.remove=function(e){null==this._currentRequests[e]&&O.Z.warn("ABR: can't remove unknown request"),delete this._currentRequests[e]},t.getRequests=function(){return(0,At.Z)(this._currentRequests).filter((function(e){return null!=e})).sort((function(e,t){return e.time-t.time}))},e}(),It=function(){function e(){this._currentRepresentationData=null,this._lastRepresentationWithGoodScore=null}var t=e.prototype;return t.addSample=function(e,t,n){var r,i=n/t,a=this._getEWMA(e);null!=a?(r=a,a.addSample(t,i)):((r=new tt(5)).addSample(t,i),this._currentRepresentationData={representation:e,ewma:r}),r.getEstimate()>1&&this._lastRepresentationWithGoodScore!==e&&(O.Z.debug("ABR: New last stable representation",e),this._lastRepresentationWithGoodScore=e)},t.getEstimate=function(e){var t=this._getEWMA(e);if(null!=t)return t.getEstimate()},t.getLastStableRepresentation=function(){return this._lastRepresentationWithGoodScore},t._getEWMA=function(e){return null!=this._currentRepresentationData&&this._currentRepresentationData.representation.id===e.id?this._currentRepresentationData.ewma:null},e}();function Zt(e,t,n,r){var i=t<=n?n:t>=r?r:t,a=(0,Ce.Z)(e,(function(e){return e.bitrate>i}));return-1===a?e[e.length-1]:0===a?e[0]:e[a-1]}function Rt(e,t){var n=e;return null!=t.bitrate&&(n=function(e,t){if(0===e.length)return[];e.sort((function(e,t){return e.bitrate-t.bitrate}));var n=e[0].bitrate,r=Math.max(t,n),i=(0,Ce.Z)(e,(function(e){return e.bitrate>r}));return-1===i?e:e.slice(0,i)}(n,t.bitrate)),null!=t.width&&(n=function(e,t){var n=e.slice().sort((function(e,t){return(0,et.Z)(e.width,0)-(0,et.Z)(t.width,0)})),r=(0,mt.Z)(n,(function(e){return"number"==typeof e.width&&e.width>=t}));if(void 0===r)return e;var i="number"==typeof r.width?r.width:0;return e.filter((function(e){return"number"!=typeof e.width||e.width<=i}))}(n,t.width)),n}function Mt(e){var t=e.bandwidthEstimator,n=e.clock$,r=e.filters$,i=e.initialBitrate,a=e.lowLatencyMode,o=e.manualBitrate$,s=e.minAutoBitrate$,u=e.maxAutoBitrate$,c=e.representations,p=e.streamEvents$,h=new It,m=new kt(null==i?0:i,a),g=new xt,y=vt();var _=p.pipe((0,T.h)((function(e){return"metrics"===e.type})),(0,Pe.b)((function(e){return function(e){var n=e.duration,r=e.size,i=e.content;if(!y(i,n)){t.addSample(n,r);var a=n/1e3,o=i.segment.duration,s=i.representation;h.addSample(s,a,o)}}(e.value)})),(0,ie.l)()),b=p.pipe((0,Pe.b)((function(e){switch(e.type){case"requestBegin":g.add(e.value);break;case"requestEnd":g.remove(e.value.id);break;case"progress":g.addProgress(e.value)}})),(0,ie.l)()),E=p.pipe((0,T.h)((function(e){return"representationChange"===e.type})),(0,v.U)((function(e){return e.value.representation})),(0,w.O)(null)),S=(0,J.P)((function(){if(0===c.length)throw new Error("ABRManager: no representation choice given");return 1===c.length?(0,l.of)({bitrate:void 0,representation:c[0],manual:!1,urgent:!0,knownStableBitrate:void 0}):o.pipe((0,Qe.w)((function(e){if(e>=0){var i=Zt(c,e,0,1/0);return(0,l.of)({representation:i,bitrate:void 0,knownStableBitrate:void 0,manual:!0,urgent:!0})}var a,o=!0,f=pt(p.pipe((0,T.h)((function(e){return"added-segment"===e.type})),lt(n),(0,v.U)((function(e){var t=e[0].value,n=e[1],r=n.speed,i=n.position,a=t.buffered,o=(0,X.L7)(a,i),s=t.content.representation,u=h.getEstimate(s);return{bufferGap:o,currentBitrate:s.bitrate,currentScore:u,speed:r}}))),c.map((function(e){return e.bitrate}))).pipe((0,w.O)(void 0));return(0,d.aj)([n,s,u,r,f]).pipe(lt(E),(0,v.U)((function(e){var n=e[0],r=n[0],i=n[1],s=n[2],u=n[3],l=n[4],d=e[1],f=Rt(c,u),p=g.getRequests(),v=m.getBandwidthEstimate(r,t,d,p,a),y=v.bandwidthEstimate,_=v.bitrateChosen;a=y;var b=h.getLastStableRepresentation(),T=null==b?void 0:b.bitrate/(r.speed>0?r.speed:1),E=r.bufferGap;!o&&E<=5?o=!0:o&&isFinite(E)&&E>10&&(o=!1);var w=Zt(f,_,i,s);if(o)return O.Z.debug("ABR: Choosing representation with bandwidth estimation.",w),{bitrate:y,representation:w,urgent:m.isUrgent(w.bitrate,d,p,r),manual:!1,knownStableBitrate:T};if(null==l||w.bitrate>=l)return O.Z.debug("ABR: Choosing representation with bandwidth estimation.",w),{bitrate:y,representation:w,urgent:m.isUrgent(w.bitrate,d,p,r),manual:!1,knownStableBitrate:T};var S=Zt(f,l,i,s);return l<=s&&O.Z.debug("ABR: Choosing representation with buffer based bitrate ceiling.",S),{bitrate:y,representation:S,urgent:m.isUrgent(l,d,p,r),manual:!1,knownStableBitrate:T}})))})))}));return(0,f.T)(_,b,S)}const Ct=function(){function e(e){this._manualBitrates=e.manualBitrates,this._minAutoBitrates=e.minAutoBitrates,this._maxAutoBitrates=e.maxAutoBitrates,this._initialBitrates=e.initialBitrates,this._throttlers=e.throttlers,this._bandwidthEstimators={},this._lowLatencyMode=e.lowLatencyMode}var t=e.prototype;return t.get$=function(e,t,n,r){var i,a,o,s,u=this._getBandwidthEstimator(e),c=(0,et.Z)(this._manualBitrates[e],(0,l.of)(-1)),f=(0,et.Z)(this._minAutoBitrates[e],(0,l.of)(0)),p=(0,et.Z)(this._maxAutoBitrates[e],(0,l.of)(1/0)),h=(0,et.Z)(this._initialBitrates[e],0);return Mt({bandwidthEstimator:u,streamEvents$:r,clock$:n,filters$:(i=this._throttlers.limitWidth[e],a=this._throttlers.throttleBitrate[e],o=this._throttlers.throttle[e],s=[],null!=i&&s.push(i.pipe((0,v.U)((function(e){return{width:e}})))),null!=o&&s.push(o.pipe((0,v.U)((function(e){return{bitrate:e}})))),null!=a&&s.push(a.pipe((0,v.U)((function(e){return{bitrate:e}})))),s.length>0?(0,d.aj)(s).pipe((0,v.U)((function(e){return Y.Z.apply(void 0,[{}].concat(e))}))):(0,l.of)({})),initialBitrate:h,manualBitrate$:c,minAutoBitrate$:f,maxAutoBitrate$:p,representations:t,lowLatencyMode:this._lowLatencyMode})},t._getBandwidthEstimator=function(e){var t=this._bandwidthEstimators[e];if(null==t){O.Z.debug("ABR: Creating new BandwidthEstimator for ",e);var n=new ot;return this._bandwidthEstimators[e]=n,n}return t},e}();var Nt=n(4507),Pt=n(5767),Ot=n(3774),Dt=n(6923),Lt=M.ym;function Bt(e,t,n){if(null!==t&&"closed"!==t.readyState){for(var r=t.readyState,i=t.sourceBuffers,a=i.length-1;a>=0;a--){var o=i[a];try{"open"===r&&(O.Z.info("Init: Removing SourceBuffer from mediaSource",o),o.abort()),t.removeSourceBuffer(o)}catch(e){O.Z.warn("Init: Error while disposing SourceBuffer",e)}}i.length>0&&O.Z.warn("Init: Not all SourceBuffers could have been removed.")}if((0,Pt.Z)(e),null!==n)try{O.Z.debug("Init: Revoking previous URL"),URL.revokeObjectURL(n)}catch(e){O.Z.warn("Init: Error while revoking the media source URL",e)}}function Ut(e){return function(e){return new Me.y((function(t){if(null==Ot.JJ)throw new B.Z("MEDIA_SOURCE_NOT_SUPPORTED","No MediaSource Object was found in the current browser.");var n=(0,Dt.Z)(e.src)?e.src:null;Bt(e,null,n),O.Z.info("Init: Creating MediaSource");var r=new Ot.JJ,i=URL.createObjectURL(r);return O.Z.info("Init: Attaching MediaSource URL to the media element",i),e.src=i,t.next(r),function(){Bt(e,r,i)}}))}(e).pipe((0,g.zg)((function(e){return Lt(e).pipe((0,S.q)(1),(0,k.h)(e))})))}var Ft=n(8343),zt=L.Z.DEFAULT_LIVE_GAP;var Kt=n(4944),Vt=n(6564),Wt=n(7027);var Gt=n(6968),Ht=n(2870),$t=n(4123),jt=L.Z.SOURCE_BUFFER_FLUSHING_INTERVAL;const Yt=function(e){function n(t,n,r){var a;a=e.call(this)||this;var o=r.addSourceBuffer(n);return a._destroy$=new i.xQ,a.bufferType=t,a._mediaSource=r,a._sourceBuffer=o,a._queue=[],a._pendingTask=null,a._lastInitSegment=null,a.codec=n,(0,Vt.F)(jt).pipe((0,Pe.b)((function(){return a._flush()})),(0,h.R)(a._destroy$)).subscribe(),(0,Wt.R)(a._sourceBuffer,"error").pipe((0,Pe.b)((function(e){return a._onPendingTaskError(e)})),(0,h.R)(a._destroy$)).subscribe(),(0,Wt.R)(a._sourceBuffer,"updateend").pipe((0,Pe.b)((function(){return a._flush()})),(0,h.R)(a._destroy$)).subscribe(),a}(0,t.Z)(n,e);var r=n.prototype;return r.pushChunk=function(e){return O.Z.debug("AVSB: receiving order to push data to the SourceBuffer",this.bufferType,e),this._addToQueue({type:$t.f.Push,value:e})},r.removeBuffer=function(e,t){return O.Z.debug("AVSB: receiving order to remove data from the SourceBuffer",this.bufferType,e,t),this._addToQueue({type:$t.f.Remove,value:{start:e,end:t}})},r.endOfSegment=function(e){return O.Z.debug("AVSB: receiving order for validating end of segment",this.bufferType,e.segment),this._addToQueue({type:$t.f.EndOfSegment,value:e})},r.getBufferedRanges=function(){return this._sourceBuffer.buffered},r.getPendingOperations=function(){var e=function(e){switch(e.type){case $t.f.Push:case $t.f.Remove:case $t.f.EndOfSegment:return{type:e.type,value:e.value}}},t=this._queue.map(e);return null===this._pendingTask?t:[e(this._pendingTask)].concat(t)},r.dispose=function(){for(this._destroy$.next(),this._destroy$.complete(),null!==this._pendingTask&&(this._pendingTask.subject.complete(),this._pendingTask=null);this._queue.length>0;){var e=this._queue.shift();void 0!==e&&e.subject.complete()}if("open"===this._mediaSource.readyState)try{this._sourceBuffer.abort()}catch(e){O.Z.warn("AVSB: Failed to abort a "+this.bufferType+" SourceBuffer:",e)}},r._onPendingTaskError=function(e){if(this._lastInitSegment=null,null!==this._pendingTask){var t=e instanceof Error?e:new Error("An unknown error occured when doing operations on the SourceBuffer");this._pendingTask.subject.error(t)}},r._addToQueue=function(e){var t=this;return new Me.y((function(n){var r=0===t._queue.length&&null===t._pendingTask,a=new i.xQ,o=(0,Y.Z)({subject:a},e);t._queue.push(o);var s=a.subscribe(n);return r&&t._flush(),function(){s.unsubscribe();var e=t._queue.indexOf(o);e>=0&&t._queue.splice(e,1)}}))},r._flush=function(){if(!this._sourceBuffer.updating){if(null!==this._pendingTask){var e=this._pendingTask;if(e.type!==$t.f.Push||0===e.data.length){switch(e.type){case $t.f.Push:null!==e.inventoryData&&this._segmentInventory.insertChunk(e.inventoryData);break;case $t.f.EndOfSegment:this._segmentInventory.completeSegment(e.value);break;case $t.f.Remove:this.synchronizeInventory();break;default:(0,De.Z)(e)}var t=e.subject;return this._pendingTask=null,t.next(),t.complete(),void this._flush()}}else{var n=this._queue.shift();if(void 0===n)return;if(n.type!==$t.f.Push)this._pendingTask=n;else{var r,i=n.value;try{r=this._preparePushOperation(i.data)}catch(e){this._pendingTask=(0,Y.Z)({data:[],inventoryData:i.inventoryInfos},n);var a=e instanceof Error?e:new Error("An unknown error occured when preparing a push operation");return this._lastInitSegment=null,void n.subject.error(a)}this._pendingTask=(0,Y.Z)({data:r,inventoryData:i.inventoryInfos},n)}}try{switch(this._pendingTask.type){case $t.f.EndOfSegment:return O.Z.debug("AVSB: Acknowledging complete segment",this._pendingTask.value),void this._flush();case $t.f.Push:var o=this._pendingTask.data.shift();if(void 0===o)return void this._flush();this._sourceBuffer.appendBuffer(o);break;case $t.f.Remove:var s=this._pendingTask.value,u=s.start,l=s.end;O.Z.debug("AVSB: removing data from SourceBuffer",this.bufferType,u,l),this._sourceBuffer.remove(u,l);break;default:(0,De.Z)(this._pendingTask)}}catch(e){this._onPendingTaskError(e)}}},r._preparePushOperation=function(e){var t=[],n=e.codec,r=e.timestampOffset,i=e.appendWindow,a=!1;if(n!==this.codec&&(O.Z.debug("AVSB: updating codec",n),(a=function(e,t){if("function"==typeof e.changeType){try{e.changeType(t)}catch(e){return O.Z.warn("Could not call 'changeType' on the given SourceBuffer:",e),!1}return!0}return!1}(this._sourceBuffer,n))?this.codec=n:O.Z.debug("AVSB: could not update codec",n,this.codec)),this._sourceBuffer.timestampOffset!==r){var o=r;O.Z.debug("AVSB: updating timestampOffset",this.bufferType,this._sourceBuffer.timestampOffset,o),this._sourceBuffer.timestampOffset=o}if(void 0===i[0]?this._sourceBuffer.appendWindowStart>0&&(this._sourceBuffer.appendWindowStart=0):i[0]!==this._sourceBuffer.appendWindowStart&&(i[0]>=this._sourceBuffer.appendWindowEnd&&(this._sourceBuffer.appendWindowEnd=i[0]+1),this._sourceBuffer.appendWindowStart=i[0]),void 0===i[1]?this._sourceBuffer.appendWindowEnd!==1/0&&(this._sourceBuffer.appendWindowEnd=1/0):i[1]!==this._sourceBuffer.appendWindowEnd&&(this._sourceBuffer.appendWindowEnd=i[1]),null!==e.initSegment&&(a||!this._isLastInitSegment(e.initSegment))){var s=e.initSegment;t.push(s);var u=(0,Gt._f)(s);this._lastInitSegment={data:u,hash:(0,Ht.Z)(u)}}return null!==e.chunk&&t.push(e.chunk),t},r._isLastInitSegment=function(e){if(null===this._lastInitSegment)return!1;if(this._lastInitSegment.data===e)return!0;var t=this._lastInitSegment.data;if(t.byteLength===e.byteLength){var n=(0,Gt._f)(e);if((0,Ht.Z)(n)===this._lastInitSegment.hash&&(0,G.Z)(t,n))return!0}return!1},n}($t.C);var qt=["audio","video","text","image"];function Xt(e){return"audio"===e||"video"===e}const Qt=function(){function e(e,t){this._mediaElement=e,this._mediaSource=t,this._initializedSegmentBuffers={},this._onNativeBufferAddedOrDisabled=[]}e.isNative=function(e){return Xt(e)};var t=e.prototype;return t.getBufferTypes=function(){var e=this.getNativeBufferTypes();return null==V.Z.nativeTextTracksBuffer&&null==V.Z.htmlTextTracksBuffer||e.push("text"),null!=V.Z.imageBuffer&&e.push("image"),e},t.getNativeBufferTypes=function(){return"AUDIO"===this._mediaElement.nodeName?["audio"]:["video","audio"]},t.getStatus=function(e){var t=this._initializedSegmentBuffers[e];return void 0===t?{type:"uninitialized"}:null===t?{type:"disabled"}:{type:"initialized",value:t}},t.waitForUsableBuffers=function(){var e=this;return this._areNativeBuffersUsable()?(0,l.of)(void 0):new Me.y((function(t){e._onNativeBufferAddedOrDisabled.push((function(){e._areNativeBuffersUsable()&&(t.next(void 0),t.complete())}))}))},t.disableSegmentBuffer=function(t){var n=this._initializedSegmentBuffers[t];if(null!==n){if(void 0!==n)throw new Error("Cannot disable an active SegmentBuffer.");this._initializedSegmentBuffers[t]=null,e.isNative(t)&&this._onNativeBufferAddedOrDisabled.forEach((function(e){return e()}))}else O.Z.warn("SBS: The "+t+" SegmentBuffer was already disabled.")},t.createSegmentBuffer=function(e,t,n){void 0===n&&(n={});var r,i=this._initializedSegmentBuffers[e];if(Xt(e)){if(null!=i)return i instanceof Yt&&i.codec!==t?O.Z.warn("SB: Reusing native SegmentBuffer with codec",i.codec,"for codec",t):O.Z.info("SB: Reusing native SegmentBuffer with codec",t),i;O.Z.info("SB: Adding native SegmentBuffer with codec",t);var a=new Yt(e,t,this._mediaSource);return this._initializedSegmentBuffers[e]=a,this._onNativeBufferAddedOrDisabled.forEach((function(e){return e()})),a}if(null!=i)return O.Z.info("SB: Reusing a previous custom SegmentBuffer for the type",e),i;if("text"===e){if(O.Z.info("SB: Creating a new text SegmentBuffer"),"html"===n.textTrackMode){if(null==V.Z.htmlTextTracksBuffer)throw new Error("HTML Text track feature not activated");r=new V.Z.htmlTextTracksBuffer(this._mediaElement,n.textTrackElement)}else{if(null==V.Z.nativeTextTracksBuffer)throw new Error("Native Text track feature not activated");r=new V.Z.nativeTextTracksBuffer(this._mediaElement,!0===n.hideNativeSubtitle)}return this._initializedSegmentBuffers.text=r,r}if("image"===e){if(null==V.Z.imageBuffer)throw new Error("Image buffer feature not activated");return O.Z.info("SB: Creating a new image SegmentBuffer"),r=new V.Z.imageBuffer,this._initializedSegmentBuffers.image=r,r}throw O.Z.error("SB: Unknown buffer type:",e),new B.Z("BUFFER_TYPE_UNKNOWN","The player wants to create a SegmentBuffer of an unknown type.")},t.disposeSegmentBuffer=function(e){var t=this._initializedSegmentBuffers[e];null!=t?(O.Z.info("SB: Aborting SegmentBuffer",e),t.dispose(),delete this._initializedSegmentBuffers[e]):O.Z.warn("SB: Trying to dispose a SegmentBuffer that does not exist")},t.disposeAll=function(){var e=this;qt.forEach((function(t){"initialized"===e.getStatus(t).type&&e.disposeSegmentBuffer(t)}))},t._areNativeBuffersUsable=function(){var e=this,t=this.getNativeBufferTypes();return!t.some((function(t){return void 0===e._initializedSegmentBuffers[t]}))&&!t.every((function(t){return null===e._initializedSegmentBuffers[t]}))},e}();var Jt=function(){function e(e){this._array=[],this._sortingFn=e}var t=e.prototype;return t.add=function(){for(var e=arguments.length,t=new Array(e),n=0;n=this._array.length)throw new Error("Invalid index.");return this._array[e]},t.findFirst=function(e){return(0,mt.Z)(this._array,e)},t.has=function(e){return(0,Oe.Z)(this._array,e)},t.removeElement=function(e){var t=this._array.indexOf(e);if(t>=0)return this._array.splice(t,1),t},t.head=function(){return this._array[0]},t.last=function(){return this._array[this._array.length-1]},t.shift=function(){return this._array.shift()},t.pop=function(){return this._array.pop()},e}(),en=function(){function e(e){this._weakMap=new WeakMap,this._fn=e}var t=e.prototype;return t.get=function(e){var t=this._weakMap.get(e);if(void 0===t){var n=this._fn(e);return this._weakMap.set(e,n),n}return t},t.destroy=function(e){this._weakMap.delete(e)},e}(),tn=n(2257);function nn(e){var t=e.segmentBuffer,n=e.clock$,r=e.maxBufferBehind$,i=e.maxBufferAhead$;return(0,d.aj)([n,r,i]).pipe((0,g.zg)((function(e){var n=e[0],r=e[1],i=e[2];return function(e,t,n,r){if(!isFinite(n)&&!isFinite(r))return p.E;var i=[],a=(0,X.F_)(e.getBufferedRanges(),t),o=a.innerRange,s=a.outerRanges,u=function(){if(isFinite(r)){for(var e=0;en.start&&i.push({start:t+r,end:n.end})}null!=o&&t+r=r.end?i.push(r):t>=r.end&&t-n>r.start&&t-no.start&&i.push({start:o.start,end:t-n})}}(),u(),(0,je.D)(i.map((function(t){return O.Z.debug("GC: cleaning range from SegmentBuffer",t),e.removeBuffer(t.start,t.end)}))).pipe((0,tn.u)(),(0,ie.l)())}(t,n,r,i)})))}const rn={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,n){return{type:"needs-media-source-reload",value:{position:t,autoPlay:n,period:e}}},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){return{type:"encryption-data-encountered",value: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}}};var an=n(7473),on=n.n(an);var sn=function(){function e(e,t){this.predicate=e,this.inclusive=t}return e.prototype.call=function(e,t){return t.subscribe(new un(e,this.predicate,this.inclusive))},e}(),un=function(e){function t(t,n,r){var i=e.call(this,t)||this;return i.predicate=n,i.inclusive=r,i.index=0,i}return o.ZT(t,e),t.prototype._next=function(e){var t,n=this.destination;try{t=this.predicate(e,this.index++)}catch(e){return void n.error(e)}this.nextOrComplete(e,t)},t.prototype.nextOrComplete=function(e,t){var n=this.destination;Boolean(t)?n.next(e):(this.inclusive&&n.next(e),n.complete())},t}(A.L);function ln(e,t,n,r,i){var a=e.period,o=e.adaptation,s=e.representation,u=function(e,t){for(var n=0;n=t.end)return null;if(r.bufferedEnd>t.start)return n}return null}(i,t);if(null===u){if(null===n){if(r&&void 0!==a.end&&t.end>=a.end)return{start:void 0,end:null};var l=s.index.checkDiscontinuity(t.start);if(null!==l)return{start:void 0,end:l}}return null}var d=i[u];if(void 0!==d.bufferedStart&&d.bufferedStart>t.start&&(null===n||d.infos.segment.end<=n))return O.Z.debug("RS: current discontinuity encountered",o.type,d.bufferedStart),{start:void 0,end:d.bufferedStart};var c=function(e,t,n){if(n<=0)return O.Z.error("RS: Asked to check a discontinuity before the first chunk."),null;for(var r=n;r=t.end)return null;if(i.bufferedStart-a.bufferedEnd>0)return r}return null}(i,t,u+1);if(null!==c&&(null===n||i[c].infos.segment.end<=n)){var f=i[c-1].bufferedEnd,p=i[c].bufferedStart;return O.Z.debug("RS: future discontinuity encountered",o.type,f,p),{start:f,end:p}}if(null===n){if(r&&void 0!==a.end){if(t.end=0;n--){var r=e[n];if(void 0===r.bufferedStart)return null;if(r.bufferedStart=a.end)return null;for(var m=i.length-1;m>=0;m--){var g=i[m];if(void 0===g.bufferedStart)break;if(g.bufferedStart=n.length-1?null:n[t+1];return!function(e,t,n){if(void 0===e.bufferedStart)return O.Z.warn("Stream: Start of a segment unknown. Assuming it is garbage collected by default.",e),!0;if(null!==t&&void 0!==t.bufferedEnd&&e.bufferedStart-t.bufferedEnd<.1)return!1;if(npn)return O.Z.info("Stream: The start of the wanted segment has been garbage collected",e),!0;return!1}(e,r,i.start)&&!function(e,t,n){if(void 0===e.bufferedEnd)return O.Z.warn("Stream: End of a segment unknown. Assuming it is garbage collected by default.",e),!0;if(null!==t&&void 0!==t.bufferedStart&&t.bufferedStart-e.bufferedEnd<.1)return!1;if(n>e.bufferedEnd&&e.end-e.bufferedEnd>pn)return O.Z.info("Stream: The end of the wanted segment has been garbage collected",e),!0;return!1}(e,a,i.end)}));return s.filter((function(e){var i=(0,Y.Z)({segment:e},t);if(a.length>0&&a.some((function(e){return(0,dn.Z)(i,e)})))return!1;var o=e.duration,s=e.time,l=e.end;if(e.isInit)return!0;if(o0&&a.some((function(e){if(e.period.id!==t.period.id||e.adaptation.id!==t.adaptation.id)return!1;var a=e.segment;return!(a.time-vn>s)&&(!(a.end+vn-vn&&f.end-l>-vn)return!1}}for(var p=0;ps)return h.start>s+vn||gn(u,p).ende[n].start;)n++;return e[--n]}function yn(e,t,n,r){return e.period.id===t.period.id&&(!(e.segment.timei}return rr}(e.representation,t.representation,r)))}var _n=L.Z.SEGMENT_PRIORITIES_STEPS;function bn(e,t){for(var n=e-(t.position+t.wantedTimeOffset),r=0;r<_n.length;r++)if(n<_n[r])return r;return _n.length}var Tn=L.Z.MINIMUM_SEGMENT_SIZE;function En(e,t,n,r,i){var a,o=e.period,s=e.representation;i.synchronizeInventory();var u,l,d=t.position+t.wantedTimeOffset,c=d+r,f={start:Math.max(d,o.start),end:Math.min(c,null!==(a=o.end)&&void 0!==a?a:1/0)},p=s.index.shouldRefresh(d,c),h=i.getPendingOperations().filter((function(e){return e.type===$t.f.EndOfSegment})).map((function(e){return e.value})),v=function(e,t){for(var n=Math.max(1/60,Tn),r=e.start+n,i=e.end-n,a=[],o=t.length-1;o>=0;o--){var s=t[o],u=s.infos.representation;if(!s.partiallyPushed&&!1!==u.decipherable&&u.isSupported){var l=s.infos.segment,d=l.time/l.timescale;((null==l.duration?s.end:d+l.duration/l.timescale)>r&&dr&&s.start0)u=!1;else if(void 0===g)u=f.end>=o.end&&s.index.isFinished();else if(null===g)u=s.index.isFinished();else{var y=void 0!==o.end?Math.min(o.end,g):g;u=f.end>=y&&s.index.isFinished()}if(s.index.isInitialized()&&(s.index.areSegmentsChronologicallyGenerated()||u)){var _=null;h.length>0&&(_=Math.min.apply(Math,h.map((function(e){return e.segment.time})))),m.length>0&&(_=null!==_?Math.min(_,m[0].segment.time):m[0].segment.time),l=ln(e,f,_,u,v)}else l=null;return{imminentDiscontinuity:l,hasFinishedLoading:u,neededSegments:m,shouldRefreshManifest:p}}var wn=L.Z.BUFFER_GC_GAPS.CALM,Sn=L.Z.BUFFER_GC_GAPS.BEEFY;function kn(e,t,n){for(var r=(0,X.F_)(t,e),i=r.innerRange,a=r.outerRanges,o=[],s=0;su.start)&&o.push(u)}return null!=i&&(O.Z.debug("Stream: GC removing part of inner range",o),e-n>i.start&&o.push({start:i.start,end:e-n}),e+n0&&null!==Z&&null===R){var p=f[0].priority;f.unshift({segment:Z,priority:p})}}else null===Z?O.Z.warn("Stream: Uninitialized index without an initialization segment"):null!==R?O.Z.warn("Stream: Uninitialized index with an already loaded initialization segment"):f.unshift({segment:Z,priority:bn(_.start,n)});var h=f[0];if(null!==i){if(M=[],i.urgent)return O.Z.debug("Stream: urgent termination request, terminate.",I),C.next(),C.complete(),(0,l.of)(rn.streamTerminating());if(null===P||void 0===h||P.segment.id!==h.segment.id)return O.Z.debug("Stream: cancel request and terminate.",null===P,I),C.next(),C.complete(),(0,l.of)(rn.streamTerminating());if(P.priority!==h.priority){var v=P.request$;P.priority=h.priority,u.updatePriority(v,h.priority)}O.Z.debug("Stream: terminate after request.",I)}else if(void 0===h)null!==P&&O.Z.debug("Stream: interrupt segment request.",I),M=[],C.next();else if(null===P)O.Z.debug("Stream: start downloading queue.",I),M=f,C.next();else if(P.segment.id!==h.segment.id)O.Z.debug("Stream: restart download queue.",I),M=f,C.next();else if(P.priority!==h.priority){O.Z.debug("Stream: update request priority.",I);var m=P.request$;P.priority=h.priority,u.updatePriority(m,h.priority)}else O.Z.debug("Stream: update downloading queue",I),M=f.slice().splice(1,f.length);var g=(0,l.of)({type:"stream-status",value:{period:_,position:n.position,bufferType:I,imminentDiscontinuity:d.imminentDiscontinuity,hasFinishedLoading:d.hasFinishedLoading,neededSegments:d.neededSegments}});return d.shouldRefreshManifest?(0,c.z)((0,l.of)(rn.needsManifestRefresh()),g):g})),(t=function(e){return"stream-terminating"!==e.type},void 0===(n=!0)&&(n=!1),function(e){return e.lift(new sn(t,n))})),L=!1,B=p.E;if(void 0!==A){var U=T.getEncryptionData(A);U.length>0&&(B=l.of.apply(void 0,U.map((function(e){return rn.encryptionDataEncountered(e)}))),L=!0)}var F=C.pipe((0,Qe.w)((function(){return M.length>0?(e=(0,J.P)((function(){var t=M.shift();if(void 0===t)return on()((function(){N.next()})),p.E;var n=t.segment,r=t.priority,i={manifest:y,period:_,adaptation:b,representation:T,segment:n},a=u.createRequest(i,r);return P={segment:n,priority:r,request$:a},a.pipe((0,g.zg)((function(t){switch(t.type){case"warning":return(0,l.of)({type:"retry",value:{segment:n,error:t.value}});case"chunk-complete":return P=null,(0,l.of)({type:"end-of-segment",value:{segment:n}});case"interrupted":return O.Z.info("Stream: segment request interrupted temporarly.",n),p.E;case"chunk":var r=null==R?void 0:R.initTimescale;return t.parse(r).pipe((0,v.U)((function(e){return(0,Y.Z)({segment:n},e)})));case"ended":return e;default:(0,De.Z)(t)}})))}))).pipe(ue((function(){P=null}))):p.E;var e})),(0,g.zg)((function(e){var t;switch(e.type){case"retry":return(0,c.z)((0,l.of)({type:"warning",value:e.value.error}),(0,J.P)((function(){var t=e.value.segment,n=T.index;if(!1===n.isSegmentStillAvailable(t))N.next();else if(n.canBeOutOfSyncError(e.value.error,t))return(0,l.of)(rn.manifestMightBeOufOfSync());return p.E})));case"parsed-init-segment":R=e.value;var n=T.getAllEncryptionData(),i=!L&&n.length>0?l.of.apply(void 0,n.map((function(e){return rn.encryptionDataEncountered(e)}))):p.E,a=function(e){var t=e.clock$,n=e.content,r=e.segment,i=e.segmentData,a=e.segmentBuffer;return(0,J.P)((function(){if(null===i)return p.E;var e=n.representation.getMimeTypeString();return An(t,a,{data:{initSegment:i,chunk:null,timestampOffset:0,appendWindow:[void 0,void 0],codec:e},inventoryInfos:null}).pipe((0,v.U)((function(){var e=a.getBufferedRanges();return rn.addedSegment(n,r,e,i)})))}))}({clock$:r,content:o,segment:e.segment,segmentData:e.value.initializationData,segmentBuffer:s});return(0,f.T)(i,a);case"parsed-segment":var u=null!==(t=null==R?void 0:R.initializationData)&&void 0!==t?t:null,d=e.value,h=d.inbandEvents,m=!0===d.needsManifestRefresh?(0,l.of)(rn.needsManifestRefresh()):p.E,g=void 0!==h&&h.length>0?(0,l.of)({type:"inband-events",value:h}):p.E;return(0,c.z)(m,g,function(e){var t=e.clock$,n=e.content,r=e.initSegmentData,i=e.parsedSegment,a=e.segment,o=e.segmentBuffer;return(0,J.P)((function(){var e,s;if(null===i.chunkData)return p.E;var u=i.chunkData,l=i.chunkInfos,d=i.chunkOffset,c=i.appendWindow,f=n.representation.getMimeTypeString(),h=[void 0!==c[0]?Math.max(0,c[0]-xn.START):void 0,void 0!==c[1]?c[1]+xn.END:void 0],m={initSegment:r,chunk:u,timestampOffset:d,appendWindow:h,codec:f},g=null!==(e=null==l?void 0:l.time)&&void 0!==e?e:a.time,y=g+(null!==(s=null==l?void 0:l.duration)&&void 0!==s?s:a.duration);void 0!==h[0]&&(g=Math.max(g,h[0])),void 0!==h[1]&&(y=Math.min(y,h[1]));var _=(0,Y.Z)({segment:a,start:g,end:y},n);return An(t,o,{data:m,inventoryInfos:_}).pipe((0,v.U)((function(){var e=o.getBufferedRanges();return rn.addedSegment(n,a,e,u)})))}))}({clock$:r,content:o,initSegmentData:u,parsedSegment:e.value,segment:e.segment,segmentBuffer:s}));case"end-of-segment":var y=e.value.segment;return s.endOfSegment((0,Y.Z)({segment:y},o)).pipe((0,ie.l)());default:(0,De.Z)(e)}})));return(0,c.z)(B,(0,f.T)(D,F).pipe((0,E.B)()))};function Zn(e,t,n){return t.pipe((0,S.q)(1),(0,g.zg)((function(r){var i;if(e.start<=r.position&&(void 0===e.end||e.end>r.position)){var a=r.getCurrentTime()+n,o=Math.min(Math.max(e.start,a),null!==(i=e.end)&&void 0!==i?i:1/0);return(0,l.of)(rn.needsMediaSourceReload(e,o,!r.isPaused))}return t.pipe((0,v.U)((function(t){return rn.needsMediaSourceReload(e,t.getCurrentTime(),!t.isPaused)})))})))}var Rn=L.Z.DELTA_POSITION_AFTER_RELOAD;const Mn=function(e){var t=e.abrManager,n=e.clock$,r=e.content,a=e.options,o=e.segmentBuffer,s=e.segmentFetcherCreator,d=e.wantedBufferAhead$,h="direct"===a.manualBitrateSwitchingMode,y=r.manifest,_=r.period,b=r.adaptation,w={},k=function(e,t,n){var r=e.manifest,a=e.adaptation,o=new i.xQ,s=new i.xQ,u=(0,f.T)(o,s);return{estimator$:(0,c.z)((0,l.of)(null),(0,H.R)(r,"decipherabilityUpdate")).pipe((0,v.U)((function(){var e=a.getPlayableRepresentations();if(e.length<=0)throw new B.Z("NO_PLAYABLE_REPRESENTATION","No Representation in the chosen Adaptation can be played");return e})),(0,m.x)((function(e,t){if(e.length!==t.length)return!1;for(var n=0;n=i.end&&(O.Z.debug('Stream: full "empty" AdaptationStream',n),a=!0),(0,l.of)({type:"stream-status",value:{period:i,bufferType:n,position:t.position,imminentDiscontinuity:null,hasFinishedLoading:a,neededSegments:[],shouldRefreshManifest:!1}})})))}var Nn=n(9252);const Pn=function(e,t){var n=e.split(";"),r=n[0],i=n.slice(1),a=t.split(";"),o=a[0],s=a.slice(1);if(r!==o)return!1;var u=(0,mt.Z)(i,(function(e){return(0,Nn.Z)(e,"codecs=")})),l=(0,mt.Z)(s,(function(e){return(0,Nn.Z)(e,"codecs=")}));if(void 0===u||void 0===l)return!1;var d=u.substring(7),c=l.substring(7);return d.split(".")[0]===c.split(".")[0]};var On=L.Z.ADAPTATION_SWITCH_BUFFER_PADDINGS;function Dn(e,t,n,r,i){if(void 0!==e.codec&&"reload"===i.onCodecSwitch&&!Ln(n,e.codec))return{type:"needs-reload",value:void 0};var a=e.getBufferedRanges();if(0===a.length)return{type:"continue",value:void 0};var o=(0,X.JN)(a),s=t.start,u=null==t.end?1/0:t.end,l=(0,X.tn)(o,[{start:s,end:u}]);if(0===l.length)return{type:"continue",value:void 0};e.synchronizeInventory();var d=e.getInventory();if(!d.some((function(e){return e.infos.period.id===t.id&&e.infos.adaptation.id!==n.id})))return{type:"continue",value:void 0};var c=function(e,t,n){return e.reduce((function(e,r){if(r.infos.period.id!==t.id||r.infos.adaptation.id!==n.id)return e;var i=r.bufferedStart,a=r.bufferedEnd;return void 0===i||void 0===a||e.push({start:i,end:a}),e}),[])}(d,t,n),f=(0,X.uH)(l,c);if(0===f.length)return{type:"continue",value:void 0};var p=r.currentTime;if("video"===n.type&&(0,X.Ti)({start:s,end:u},p)&&(r.readyState>1||!n.getPlayableRepresentations().some((function(t){var n;return Pn(t.getMimeTypeString(),null!==(n=e.codec)&&void 0!==n?n:"")})))&&!(0,X.A1)(c,p))return{type:"needs-reload",value:void 0};if("audio"===n.type&&void 0!==e.codec&&"direct"===i.audioTrackSwitchingMode&&(0,X.Ti)({start:s,end:u},p)&&(r.readyState>1||!Ln(n,e.codec))&&!(0,X.A1)(c,p))return{type:"needs-reload",value:void 0};var h=[],v=function(e,t){for(var n=0;n=t.start)return n>0?e[n-1]:null;return e.length>0?e[e.length-1]:null}(d,t);null!==v&&(void 0===v.bufferedEnd||t.start-v.bufferedEnd<1)&&h.push({start:0,end:t.start+1});var m=n.type,g=On[m].before;null==g&&(g=0);var y=On[m].after;if(null==y&&(y=0),h.push({start:p-g,end:p+y}),void 0!==t.end){var _=function(e,t){for(var n=0;nt.start)return e[n];return null}(d,t);null!==_&&(void 0===_.bufferedStart||_.bufferedStart-t.end<1)&&h.push({start:t.end-1,end:Number.MAX_VALUE})}var b=(0,X.uH)(f,h);return b.length>0?{type:"clean-buffer",value:b}:{type:"continue",value:void 0}}function Ln(e,t){return e.getPlayableRepresentations().some((function(e){return Pn(e.getMimeTypeString(),t)}))}var Bn=L.Z.DELTA_POSITION_AFTER_RELOAD;const Un=function(e){var t=e.abrManager,n=e.bufferType,r=e.clock$,i=e.content,o=e.garbageCollectors,s=e.segmentFetcherCreator,u=e.segmentBuffersStore,d=e.options,h=e.wantedBufferAhead$,m=i.period,y=new a.t(1);return y.pipe((0,Qe.w)((function(e,a){var y=0===a?0:"audio"===n?Bn.trackSwitch.audio:"video"===n?Bn.trackSwitch.video:Bn.trackSwitch.other;if(null===e){O.Z.info("Stream: Set no "+n+" Adaptation",m);var _,b=u.getStatus(n);if("initialized"===b.type){if(O.Z.info("Stream: Clearing previous "+n+" SegmentBuffer"),Qt.isNative(n))return Zn(m,r,y);_=b.value.removeBuffer(m.start,null==m.end?1/0:m.end)}else"uninitialized"===b.type&&u.disableSegmentBuffer(n),_=(0,l.of)(null);return(0,c.z)(_.pipe((0,k.h)(rn.adaptationChange(n,null,m))),Cn(r,h,n,{period:m}))}if(Qt.isNative(n)&&"disabled"===u.getStatus(n).type)return Zn(m,r,y);O.Z.info("Stream: Updating "+n+" adaptation",e,m);var T=r.pipe((0,S.q)(1),(0,g.zg)((function(a){var _=function(e,t,n,r){var i=e.getStatus(t);if("initialized"===i.type)return O.Z.info("Stream: Reusing a previous SegmentBuffer for the type",t),i.value;var a=function(e){var t=e.representations;if(null==t[0])return"";return t[0].getMimeTypeString()}(n),o="text"===t?r.textTrackOptions:void 0;return e.createSegmentBuffer(t,a,o)}(u,n,e,d),b={currentTime:a.getCurrentTime(),readyState:a.readyState},T=Dn(_,m,e,b,d);if("needs-reload"===T.type)return Zn(m,r,y);var E="clean-buffer"===T.type?c.z.apply(void 0,T.value.map((function(e){var t=e.start,n=e.end;return _.removeBuffer(t,n)}))).pipe((0,ie.l)()):p.E,w=o.get(_),S=function(e,a){var o=i.manifest,f=r.pipe((0,v.U)((function(e){var t=a.getBufferedRanges();return(0,Y.Z)({},e,{bufferGap:(0,X.L7)(t,e.position)})})));return Mn({abrManager:t,clock$:f,content:{manifest:o,period:m,adaptation:e},options:d,segmentBuffer:a,segmentFetcherCreator:s,wantedBufferAhead$:h}).pipe((0,oe.K)((function(e){if(!Qt.isNative(n)){O.Z.error("Stream: "+n+" Stream crashed. Aborting it.",e),u.disposeSegmentBuffer(n);var t=z(e,{defaultCode:"NONE",defaultReason:"Unknown `AdaptationStream` error"});return(0,c.z)((0,l.of)(rn.warning(t)),Cn(r,h,n,{period:m}))}throw O.Z.error("Stream: "+n+" Stream crashed. Stopping playback.",e),e})))}(e,_);return u.waitForUsableBuffers().pipe((0,g.zg)((function(){return(0,c.z)(E,(0,f.T)(S,w))})))})));return(0,c.z)((0,l.of)(rn.adaptationChange(n,e,m)),T)})),(0,w.O)(rn.periodStreamReady(n,m,y)))};var Fn=n(2807);function zn(){for(var e=arguments.length,t=new Array(e),n=0;nd.getMaximumPosition()){var i=new B.Z("MEDIA_TIME_AFTER_MANIFEST","The current position is after the latest time announced in the Manifest.");return rn.warning(i)}return null}),null)),x=r.getBufferTypes().map((function(e){return function(e,n){var a=new Jt((function(e,t){return e.start-t.start})),o=new i.xQ,s=!1;function u(t){return R(e,t,o).pipe((0,fe.Z)((function(e){switch(e.type){case"needs-media-source-reload":var t=a.head();if(void 0===t||t.id!==e.value.period.id)return null;break;case"periodStreamReady":s=!0,a.add(e.value.period);break;case"periodStreamCleared":a.removeElement(e.value.period)}return e}),null),(0,E.B)())}function h(e){var t=a.head(),n=a.last();return null==t||null==n||(t.start>e||(null==n.end?1/0:n.end)=s.end}))),y=p.pipe(Ye((function(t){return R(e,t,v)}))),_=u.pipe((0,S.q)(1),(0,Pe.b)((function(){p.complete(),v.next(),v.complete()})),(0,E.B)()),b=(0,f.T)(m,_),A=Un({abrManager:n,bufferType:e,clock$:t,content:{manifest:d,period:s},garbageCollectors:k,segmentFetcherCreator:a,segmentBuffersStore:r,options:o,wantedBufferAhead$:w}).pipe((0,g.zg)((function(t){if("stream-status"===t.type)if(t.value.hasFinishedLoading){var n=d.getPeriodAfter(s);if(null===n)return(0,c.z)((0,l.of)(t),(0,l.of)(rn.streamComplete(e)));p.next(n)}else v.next();return(0,l.of)(t)})),(0,E.B)()),x=(0,c.z)(A.pipe((0,h.R)(b)),(0,l.of)(rn.periodStreamCleared(e,s)).pipe((0,Pe.b)((function(){O.Z.info("SO: Destroying Stream for",e,s)}))));return(0,f.T)(x,y,_.pipe((0,ie.l)()))}};var Gn=n(8821),Hn=n(6565);var $n=function(){function e(e){if(this.total=e,this.total<0)throw new Hn.W}return e.prototype.call=function(e,t){return t.subscribe(new jn(e,this.total))},e}(),jn=function(e){function t(t,n){var r=e.call(this,t)||this;return r.total=n,r.ring=new Array,r.count=0,r}return o.ZT(t,e),t.prototype._next=function(e){var t=this.ring,n=this.total,r=this.count++;t.length0)for(var n=this.count>=this.total?this.total:this.count,r=this.ring,i=0;i0&&void 0!==e[0].period.end&&e[0].period.end+10r.start)return ar(t)&&e.splice(a,0,t),e;ar(t)&&e.push(t);return e}(e,t[0],t[1])}),[])),o=null,s=null;return e.pipe(lt(a),(0,v.U)((function(e){var r=e[0],a=e[1],u=r.buffered,l=r.currentRange,d=r.position,c=r.event,f=r.stalled;if(null===f)return{type:"unstalled",value:null};if(r.seeking)o=r.position;else if(null!==o){var p=performance.now();if(null===s&&(s=p),er&&r.positionn)return r;var o=void 0;if(void 0===a.end||a.end>n){var s=e[i],u=s.discontinuity,l=s.position,d=u.start,c=u.end;if(n>=(null!=d?d:l)-rr)if(null===c){var f=t.getPeriodAfter(a);null!==f?o=f.start+rr:O.Z.warn("Init: discontinuity at Period's end but no next Period")}else no?r:o)}}return r}(a,n,h);if(null!==v){var m=v+.001;if(!(m<=t.currentTime))return O.Z.warn("SA: skippable discontinuity found in the stream",d,m),i(m),rn.warning(or(h,m));O.Z.info("Init: position to seek already reached, no seeking",t.currentTime,m)}}if(function(e,t,n,r){return P.vU&&r&&"timeupdate"===n&&null!=t&&t.end-e>10}(d,l,c,null!==f))return O.Z.warn("Init: After freeze seek",d,l),i(d),rn.warning(or(d,d));var g=null!=h?h:d,y=(0,X.XS)(u,g);if(y=0;b--){var T=n.periods[b];if(void 0!==T.end&&T.end<=g){if(n.periods[b+1].start>g&&n.periods[b+1].start>t.currentTime){var E=n.periods[b+1];return i(E.start),rn.warning(or(g,E.start))}break}}return{type:"stalled",value:f}})))}function ar(e){return null!==e.discontinuity}function or(e,t){return new B.Z("DISCONTINUITY_ENCOUNTERED","A discontinuity has been encountered at position "+String(e)+", seeked at position "+String(t))}var sr=function(){function e(){}return e.prototype.call=function(e,t){return t.subscribe(new ur(e))},e}(),ur=function(e){function t(t){var n=e.call(this,t)||this;return n.hasPrev=!1,n}return o.ZT(t,e),t.prototype._next=function(e){var t;this.hasPrev?t=[this.prev,e]:this.hasPrev=!0,this.prev=e,t&&this.destination.next(t)},t}(A.L);const lr=function(e,t){return e.id===t.id&&e.start===t.start&&e.end===t.end};const dr=function(e,t){for(var n=[],r=t.periods,i=0;i0})),(0,m.x)(),(0,Qe.w)((function(e){return e?(0,d.aj)([(0,Vt.F)(cr).pipe((0,w.O)(null)),n]).pipe((0,v.U)((function(e){e[0];return{isSeeking:e[1].seeking,currentTime:t.currentTime}})),(function(e){return e.lift(new sr)}),(0,g.zg)((function(e){var t=e[0],n=e[1];return function(e,t,n){for(var i=t.currentTime,a=n.isSeeking,o=n.currentTime,s=[],u=[],d=0;do||void 0!==v&&o>=v)&&(fr(f)&&u.push(f.publicEvent),r.delete(f)):h<=o&&void 0!==v&&o=(null!=v?v:h)&&(a?s.push({type:"stream-event-skip",value:f.publicEvent}):(s.push({type:"stream-event",value:f.publicEvent}),fr(f)&&u.push(f.publicEvent)))}return(0,c.z)(s.length>0?l.of.apply(void 0,s):p.E,u.length>0?l.of.apply(void 0,u).pipe((0,Pe.b)((function(e){"function"==typeof e.onExit&&e.onExit()})),(0,ie.l)()):p.E)}(i,t,n)}))):p.E})))};var hr=n(2983);function vr(e){var t=e.mediaElement,n=e.manifest,r=e.clock$,a=e.speed$,o=e.bufferOptions,s=e.abrManager,u=e.segmentFetcherCreator,c=e.setCurrentTime;return function(e,m,y){var _,b=function(e,t){return(0,H.R)(e,"manifestUpdate").pipe((0,w.O)(null),(0,Pe.b)((function(){var n=e.getMaximumPosition(),r=e.isLive?Math.max(Math.pow(2,32),n+31536e3):n;(isNaN(t.duration)||!isFinite(t.duration)||Math.abs(t.duration-r)>.01)&&(O.Z.info("Init: Updating duration",r),t.duration=r)})),(0,ie.l)())}(n,e),E=null!==(_=n.getPeriodForTime(m))&&void 0!==_?_:n.getNextPeriod(m);if(void 0===E){var S=new B.Z("MEDIA_STARTING_TIME_NOT_FOUND","Wanted starting time not found in the Manifest.");return(0,Kt._)(S)}var k=new Qt(t,e),A=(0,Jn.Z)({clock$:r,mediaElement:t,startTime:m,mustAutoPlay:y,setCurrentTime:c,isDirectfile:!1}),x=A.seek$,I=A.load$,Z=I.pipe((0,T.h)((function(e){return"not-loaded-metadata"!==e}))),R=Z.pipe((0,g.zg)((function(){return pr(n,t,r)}))),M=function(e,t){var n=t.autoPlay,r=t.initialPlay$,i=t.initialSeek$,a=t.manifest,o=t.speed$,s=t.startTime,u=!1,l=!1,c=r.pipe((0,Pe.b)((function(){u=!0})),(0,ie.l)()),p=i.pipe((0,Pe.b)((function(){l=!0})),(0,ie.l)()),h=(0,d.aj)([e,o]).pipe((0,v.U)((function(e){var t=e[0],r=e[1],i=a.isLive;return{position:t.position,getCurrentTime:t.getCurrentTime,duration:t.duration,isPaused:u?t.paused:!n,liveGap:i?a.getMaximumPosition()-t.position:1/0,readyState:t.readyState,speed:r,stalled:t.stalled,wantedTimeOffset:l?0:s-t.position}})));return(0,f.T)(c,p,h)}(r,{autoPlay:y,initialPlay$:Z,initialSeek$:x,manifest:n,speed$:a,startTime:m}),C=new i.xQ,N=new i.xQ,P=Wn({manifest:n,initialPeriod:E},M,s,k,u,o).pipe((0,g.zg)((function(t){switch(t.type){case"end-of-stream":return O.Z.debug("Init: end-of-stream order received."),function(e){return qn(e).pipe((0,w.O)(null),(0,Qe.w)((function(){return Qn(e)})))}(e).pipe((0,ie.l)(),(0,h.R)(C));case"resume-stream":return O.Z.debug("Init: resume-stream order received."),C.next(null),p.E;case"stream-status":var n=t.value,r=n.period,i=n.bufferType,a=n.imminentDiscontinuity,o=n.position;return N.next({period:r,bufferType:i,discontinuity:a,position:o}),p.E;default:return(0,l.of)(t)}}))),D=(0,hr.Z)(t,a,r,{pauseWhenStalled:!0}).pipe((0,ie.l)()),L=ir(r,t,n,N,c),U=I.pipe((0,g.zg)((function(e){if("autoplay-blocked"===e){var t=new B.Z("MEDIA_ERR_BLOCKED_AUTOPLAY","Cannot trigger auto-play automatically: your browser does not allow it.");return(0,l.of)(Ft.Z.warning(t),Ft.Z.loaded(k))}if("not-loaded-metadata"===e){var n=new B.Z("MEDIA_ERR_NOT_LOADED_METADATA","Cannot load automatically: your browser falsely announced having loaded the content.");return(0,l.of)(Ft.Z.warning(n))}return O.Z.debug("Init: The current content is loaded."),(0,l.of)(Ft.Z.loaded(k))})));return(0,f.T)(b,U,D,L,P,R).pipe(ue((function(){k.disposeAll()})))}}var mr=L.Z.FAILED_PARTIAL_UPDATE_MANIFEST_REFRESH_DELAY,gr=L.Z.MAX_CONSECUTIVE_MANIFEST_PARSING_IN_UNSAFE_MODE,yr=L.Z.MIN_MANIFEST_PARSING_TIME_TO_ENTER_UNSAFE_MODE;function _r(e){var t,n,r=e.initialManifest,i=e.manifestFetcher,a=e.minimumManifestUpdateInterval,o=e.scheduleRefresh$,s=(t=function(e,t){return i.fetch(e).pipe((0,g.zg)((function(e){return"warning"===e.type?(0,l.of)(e):e.parse(t)})),(0,E.B)())},n=!1,function(){for(var e=arguments.length,r=new Array(e),i=0;i0?d=yr,m=o.pipe((0,g.zg)((function(e){var t=e.completeRefresh,r=e.delay,i=e.canUseUnsafeMode&&v;return br(null!=r?r:0,a,n).pipe((0,k.h)({completeRefresh:t,unsafeMode:i}))}))),y=void 0===n?0:performance.now()-n,_=Math.max(a-y,0);if(void 0===u.lifetime||u.lifetime<0)t=p.E;else{var b=1e3*u.lifetime-y;if(void 0!==s)if(u.lifetime<3&&s>=100){var T=1e3*(3-u.lifetime)+b,E=Math.max(T,Math.max(b,0)+s);O.Z.info("MUS: Manifest update rythm is too frequent. Postponing next request.",b,E),b=E}else if(s>=1e3*u.lifetime/10){var w=Math.max(b,0)+s;O.Z.info("MUS: Manifest took too long to parse. Postponing next request",b,w),b=w}t=(0,me.H)(Math.max(b,_)).pipe((0,k.h)({completeRefresh:!1,unsafeMode:v}))}var A=null===u.expired?p.E:(0,me.H)(_).pipe((0,R.j)((0,je.D)(u.expired)),(0,k.h)({completeRefresh:!0,unsafeMode:v}));return(0,f.T)(t,m,A).pipe((0,S.q)(1),(0,g.zg)((function(e){return h({completeRefresh:e.completeRefresh,unsafeMode:e.unsafeMode})})),(0,g.zg)((function(e){return"warning"===e.type?(0,l.of)(e):c(e)})))}return(0,J.P)((function(){return c(r)}));function h(e){var t=e.completeRefresh,n=e.unsafeMode,r=u.updateUrl,i=t||void 0===r,o=i?u.getUrl():r,c=u.clockOffset;return n?(d+=1,O.Z.info('Init: Refreshing the Manifest in "unsafeMode" for the '+String(d)+" consecutive time.")):d>0&&(O.Z.info('Init: Not parsing the Manifest in "unsafeMode" anymore after '+String(d)+" consecutive times."),d=0),s(o,{externalClockOffset:c,previousManifest:u,unsafeMode:n}).pipe((0,g.zg)((function(e){if("warning"===e.type)return(0,l.of)(e);var t=e.manifest,n=e.sendingTime,r=e.receivedTime,o=e.parsingTime,s=performance.now();if(i)u.replace(t);else try{u.update(t)}catch(e){var d=e instanceof Error?e.message:"unknown error";return O.Z.warn("MUS: Attempt to update Manifest failed: "+d,"Re-downloading the Manifest fully"),br(mr,a,n).pipe((0,g.zg)((function(){return h({completeRefresh:!0,unsafeMode:!1})})))}return(0,l.of)({type:"parsed",manifest:u,sendingTime:n,receivedTime:r,parsingTime:o,updatingTime:performance.now()-s})})))}}function br(e,t,n){return(0,J.P)((function(){var r=void 0===n?0:performance.now()-n,i=Math.max(t-r,0);return(0,me.H)(Math.max(e-r,i))}))}var Tr=n(2447),Er=L.Z.OUT_OF_SYNC_MANIFEST_REFRESH_DELAY;const wr=function(e){var t,n,r,a=e.adaptiveOptions,o=e.autoPlay,s=e.bufferOptions,u=e.clock$,c=e.keySystems,m=e.lowLatencyMode,_=e.manifest$,b=e.manifestFetcher,A=e.mediaElement,x=e.minimumManifestUpdateInterval,I=e.segmentFetcherCreator,Z=e.setCurrentTime,R=e.speed$,M=e.startAt,C=e.textTrackOptions,N=new Ct(a),P=Ut(A).pipe((0,y.d)({refCount:!0})),D=new i.xQ,L=(0,Nt.Z)(A,c,D).pipe((0,Je.Z)(),(0,E.B)()),B=(0,Tr.Z)(A),U=L.pipe((t=function(e,t){switch(t.type){case"eme-disabled":case"attached-media-keys":return(0,l.of)({isEmeReady:!0,drmSystemId:e.drmSystemId});case"created-media-keys":var n=t.value.initializationDataSystemId;return P.pipe((0,g.zg)((function(){return t.value.attachMediaKeys$.next(),!0===t.value.options.disableMediaKeysAttachmentLock?(0,l.of)({isEmeReady:!0,drmSystemId:n}):p.E})),(0,w.O)({isEmeReady:!1,drmSystemId:n}));default:return p.E}},n={isEmeReady:!1,drmSystemId:void 0},void 0===r&&(r=Number.POSITIVE_INFINITY),function(e){return e.lift(new He(t,n,r))}),(0,T.h)((function(e){return e.isEmeReady})),(0,S.q)(1),Ye((function(e){var t=e.drmSystemId;return P.pipe((0,v.U)((function(e){return{mediaSource:e,drmSystemId:t}})))}))),F=(0,d.aj)([_,U]).pipe((0,g.zg)((function(e){var t=e[0],n=e[1];if("warning"===t.type)return(0,l.of)(t);var r=t.manifest,a=n.mediaSource,d=n.drmSystemId;O.Z.debug("Init: Calculating initial time");var c=function(e,t,n){if(O.Z.debug("Init: calculating initial time"),null!=n){var r=e.getMinimumPosition(),i=e.getMaximumPosition();if(null!=n.position)return O.Z.debug("Init: using startAt.minimumPosition"),Math.max(Math.min(n.position,i),r);if(null!=n.wallClockTime){O.Z.debug("Init: using startAt.wallClockTime");var a=null==e.availabilityStartTime?0:e.availabilityStartTime,o=n.wallClockTime-a;return Math.max(Math.min(o,i),r)}if(null!=n.fromFirstPosition){O.Z.debug("Init: using startAt.fromFirstPosition");var s=n.fromFirstPosition;return s<=0?r:Math.min(i,r+s)}if(null!=n.fromLastPosition){O.Z.debug("Init: using startAt.fromLastPosition");var u=n.fromLastPosition;return u>=0?i:Math.max(r,i+u)}if(null!=n.percentage){O.Z.debug("Init: using startAt.percentage");var l=n.percentage;return l>100?i:l<0?r:r+ +l/100*(i-r)}}var d=e.getMinimumPosition();if(e.isLive){var c,f=e.suggestedPresentationDelay,p=e.clockOffset,h=e.getMaximumPosition();if(null==p)O.Z.info("Init: no clock offset found for a live content, starting close to maximum available position"),c=h;else{O.Z.info("Init: clock offset found for a live content, checking if we can start close to it");var v=null==e.availabilityStartTime?0:e.availabilityStartTime,m=(performance.now()+p)/1e3-v;c=Math.min(h,m)}var g=void 0!==f?f:t?zt.LOW_LATENCY:zt.DEFAULT;return O.Z.debug("Init: "+c+" defined as the live time, applying a live gap of "+g),Math.max(c-g,d)}return O.Z.info("Init: starting at the minimum available position:",d),d}(r,m,M);O.Z.debug("Init: Initial time calculated:",c);var p=vr({abrManager:N,bufferOptions:(0,Y.Z)({textTrackOptions:C,drmSystemId:d},s),clock$:u,manifest:r,mediaElement:A,segmentFetcherCreator:I,speed$:R,setCurrentTime:Z}),y=function e(t,n,r){var a=new i.xQ,o=p(t,n,r).pipe((0,fe.Z)((function(e){switch(e.type){case"needs-manifest-refresh":return _.next({completeRefresh:!1,canUseUnsafeMode:!0}),null;case"manifest-might-be-out-of-sync":return _.next({completeRefresh:!0,canUseUnsafeMode:!1,delay:Er}),null;case"needs-media-source-reload":return a.next(e.value),null;case"needs-decipherability-flush":var t=re(A);if(null===(r=t)||r.indexOf("widevine")<0)return a.next(e.value),null;var n=e.value.position;return n+.001=1&&"loadedmetadata"!==u&&null===m&&!(_||v),T=null,E=s?Mr.LOW_LATENCY:Mr.DEFAULT;if(o){if(b)d<=E?(r=!0,T=l+d):d===1/0?(r=!0,T=l):1===h&&(r=!0);else if(null!==m){var w=Nr(m,s);!0!==r&&null!==m&&h>1&&(_||v||d<1/0&&d>w)?i=!0:(d===1/0||d<=w)&&(T=d===1/0?l:l+d)}}else b&&(!p&&"timeupdate"===u&&"timeupdate"===g&&l===y||"seeking"===u&&d===1/0)?r=!0:null!==m&&("seeking"!==u&&l!==y||"canplay"===u||d<1/0&&(d>Nr(m,s)||_||v))&&(i=!0);return!0===i?null:!0===r||null!==m?(a="seeking"===u||null!==m&&"seeking"===m.reason?"seeking":t.seeking&&("internal-seeking"===u||null!==m&&"internal-seek"===m.reason)?"internal-seek":t.seeking?"seeking":1===h?"not-ready":"buffering",null!==m&&m.reason===a?{reason:m.reason,timestamp:m.timestamp,position:T}:{reason:a,timestamp:performance.now(),position:T}):null}const Dr=function(e,t){var n=0;return{clock$:(0,J.P)((function(){var r=(0,Y.Z)(Pr(e,"init"),{stalled:null,getCurrentTime:function(){return e.currentTime}});var i=Cr.map((function(t){return(0,Wt.R)(e,t).pipe((0,k.h)(t))})),a=t.lowLatencyMode?Ar:t.withMediaSource?kr:xr,o=(0,Vt.F)(a).pipe((0,k.h)("timeupdate"));return f.T.apply(void 0,[o].concat(i)).pipe((0,v.U)((function(i){return r=function(i){var a=i;"seeking"===a&&n>0&&(a="internal-seeking",n-=1);var o=Pr(e,a),s=Or(r,o,t),u=(0,Y.Z)({},{stalled:s,getCurrentTime:function(){return e.currentTime}},o);return O.Z.debug("API: current media element state",u),u}(i),"DEBUG"===O.Z.getLevel()&&O.Z.debug("API: current playback timeline:\n"+function(e,t){for(var n="",r="",i=0;it){var d=n.length-Math.floor(l.length/2);r=" ".repeat(d)+"^"+t}if(i=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.")}return(n=e[Symbol.iterator]()).next.bind(n)}function Yr(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0;)this._periods.pop()},t.update=function(){this._resetChosenAudioTracks(),this._resetChosenTextTracks(),this._resetChosenVideoTracks()},t.setInitialAudioTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.audio:null;if(null==n||null==t)throw new Error("TrackChoiceManager: Given Period not found.");var r=e.getPlayableAdaptations("audio"),i=this._audioChoiceMemory.get(e);if(null===i)n.adaptation$.next(null);else if(void 0!==i&&(0,Oe.Z)(r,i))n.adaptation$.next(i);else{var a=yi(r,hi(this._preferredAudioTracks));this._audioChoiceMemory.set(e,a),n.adaptation$.next(a)}},t.setInitialTextTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.text:null;if(null==n||null==t)throw new Error("TrackChoiceManager: Given Period not found.");var r=e.getPlayableAdaptations("text"),i=this._textChoiceMemory.get(e);if(null===i)n.adaptation$.next(null);else if(void 0!==i&&(0,Oe.Z)(r,i))n.adaptation$.next(i);else{var a=bi(r,vi(this._preferredTextTracks));this._textChoiceMemory.set(e,a),n.adaptation$.next(a)}},t.setInitialVideoTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.video:null;if(null==n||null==t)throw new Error("TrackChoiceManager: Given Period not found.");var r=e.getPlayableAdaptations("video"),i=this._videoChoiceMemory.get(e);if(null===i)n.adaptation$.next(null);else if(void 0!==i&&(0,Oe.Z)(r,i))n.adaptation$.next(i);else{var a=Ei(r,this._preferredVideoTracks);this._videoChoiceMemory.set(e,a),n.adaptation$.next(a)}},t.setAudioTrackByID=function(e,t){var n=wi(this._periods,e),r=null!=n?n.audio:null;if(null==r)throw new Error("TrackChoiceManager: Given Period not found.");var i=(0,mt.Z)(r.adaptations,(function(e){return e.id===t}));if(void 0===i)throw new Error("Audio Track not found.");this._audioChoiceMemory.get(e)!==i&&(this._audioChoiceMemory.set(e,i),r.adaptation$.next(i))},t.setTextTrackByID=function(e,t){var n=wi(this._periods,e),r=null!=n?n.text:null;if(null==r)throw new Error("TrackChoiceManager: Given Period not found.");var i=(0,mt.Z)(r.adaptations,(function(e){return e.id===t}));if(void 0===i)throw new Error("Text Track not found.");this._textChoiceMemory.get(e)!==i&&(this._textChoiceMemory.set(e,i),r.adaptation$.next(i))},t.setVideoTrackByID=function(e,t){var n=wi(this._periods,e),r=null!=n?n.video:null;if(null==r)throw new Error("LanguageManager: Given Period not found.");var i=(0,mt.Z)(r.adaptations,(function(e){return e.id===t}));if(void 0===i)throw new Error("Video Track not found.");this._videoChoiceMemory.get(e)!==i&&(this._videoChoiceMemory.set(e,i),r.adaptation$.next(i))},t.disableTextTrack=function(e){var t=wi(this._periods,e),n=null!=t?t.text:null;if(null==n)throw new Error("TrackChoiceManager: Given Period not found.");null!==this._textChoiceMemory.get(e)&&(this._textChoiceMemory.set(e,null),n.adaptation$.next(null))},t.disableVideoTrack=function(e){var t=wi(this._periods,e),n=null==t?void 0:t.video;if(void 0===n)throw new Error("TrackManager: Given Period not found.");null!==this._videoChoiceMemory.get(e)&&(this._videoChoiceMemory.set(e,null),n.adaptation$.next(null))},t.getChosenAudioTrack=function(e){var t=wi(this._periods,e);if(null==(null!=t?t.audio:null))return null;var n=this._audioChoiceMemory.get(e);if(null==n)return null;var r={language:(0,et.Z)(n.language,""),normalized:(0,et.Z)(n.normalizedLanguage,""),audioDescription:!0===n.isAudioDescription,id:n.id,representations:n.representations.map(ki)};return!0===n.isDub&&(r.dub=!0),r},t.getChosenTextTrack=function(e){var t=wi(this._periods,e);if(null==(null!=t?t.text:null))return null;var n=this._textChoiceMemory.get(e);return null==n?null:{language:(0,et.Z)(n.language,""),normalized:(0,et.Z)(n.normalizedLanguage,""),closedCaption:!0===n.isClosedCaption,id:n.id}},t.getChosenVideoTrack=function(e){var t=wi(this._periods,e);if(null==(null!=t?t.video:null))return null;var n=this._videoChoiceMemory.get(e);if(null==n)return null;var r={id:n.id,representations:n.representations.map(Si)};return!0===n.isSignInterpreted&&(r.signInterpreted=!0),r},t.getAvailableAudioTracks=function(e){var t=wi(this._periods,e),n=null!=t?t.audio:null;if(null==n)return[];var r=this._audioChoiceMemory.get(e),i=null!=r?r.id:null;return n.adaptations.map((function(e){var t={language:(0,et.Z)(e.language,""),normalized:(0,et.Z)(e.normalizedLanguage,""),audioDescription:!0===e.isAudioDescription,id:e.id,active:null!=i&&i===e.id,representations:e.representations.map(ki)};return!0===e.isDub&&(t.dub=!0),t}))},t.getAvailableTextTracks=function(e){var t=wi(this._periods,e),n=null!=t?t.text:null;if(null==n)return[];var r=this._textChoiceMemory.get(e),i=null!=r?r.id:null;return n.adaptations.map((function(e){return{language:(0,et.Z)(e.language,""),normalized:(0,et.Z)(e.normalizedLanguage,""),closedCaption:!0===e.isClosedCaption,id:e.id,active:null!=i&&i===e.id}}))},t.getAvailableVideoTracks=function(e){var t=wi(this._periods,e),n=null!=t?t.video:null;if(null==n)return[];var r=this._videoChoiceMemory.get(e),i=null!=r?r.id:null;return n.adaptations.map((function(e){var t={id:e.id,active:null!==i&&i===e.id,representations:e.representations.map(Si)};return!0===e.isSignInterpreted&&(t.signInterpreted=!0),t}))},t._applyAudioPreferences=function(){this._audioChoiceMemory=new WeakMap,this._resetChosenAudioTracks()},t._applyTextPreferences=function(){this._textChoiceMemory=new WeakMap,this._resetChosenTextTracks()},t._applyVideoPreferences=function(){this._videoChoiceMemory=new WeakMap,this._resetChosenVideoTracks()},t._resetChosenAudioTracks=function(){var e=this,t=hi(this._preferredAudioTracks);!function n(r){if(!(r>=e._periods.length())){var i=e._periods.get(r);if(null!=i.audio){var a=i.period,o=i.audio,s=a.getPlayableAdaptations("audio"),u=e._audioChoiceMemory.get(a);if(null===u||void 0!==u&&(0,Oe.Z)(s,u))n(r+1);else{var l=yi(s,t);e._audioChoiceMemory.set(a,l),o.adaptation$.next(l),n(0)}}else n(r+1)}}(0)},t._resetChosenTextTracks=function(){var e=this,t=vi(this._preferredTextTracks);!function n(r){if(!(r>=e._periods.length())){var i=e._periods.get(r);if(null!=i.text){var a=i.period,o=i.text,s=a.getPlayableAdaptations("text"),u=e._textChoiceMemory.get(a);if(null===u||void 0!==u&&(0,Oe.Z)(s,u))n(r+1);else{var l=bi(s,t);e._textChoiceMemory.set(a,l),o.adaptation$.next(l),n(0)}}else n(r+1)}}(0)},t._resetChosenVideoTracks=function(){var e=this,t=this._preferredVideoTracks;!function n(r){if(!(r>=e._periods.length())){var i=e._periods.get(r);if(null!=i.video){var a=i.period,o=i.video,s=a.getPlayableAdaptations("video"),u=e._videoChoiceMemory.get(a);if(null===u||void 0!==u&&(0,Oe.Z)(s,u))n(r+1);else{var l=Ei(s,t);e._videoChoiceMemory.set(a,l),o.adaptation$.next(l),n(0)}}else n(r+1)}}(0)},e}();function gi(e){return function(t){var n;if(void 0!==e.normalized&&(null!==(n=t.normalizedLanguage)&&void 0!==n?n:"")!==e.normalized)return!1;if(void 0!==e.audioDescription)if(e.audioDescription){if(!0!==t.isAudioDescription)return!1}else if(!0===t.isAudioDescription)return!1;if(void 0===e.codec)return!0;var r=e.codec.test,i=function(e){return void 0!==e.codec&&r.test(e.codec)};return e.codec.all?t.representations.every(i):t.representations.some(i)}}function yi(e,t){if(0===e.length)return null;for(var n=0;nv)throw new Error('Invalid maxVideoBitrate parameter. Its value, "'+v+'", is inferior to the set minVideoBitrate, "'+p+'"')}if((0,$.Z)(e.maxAudioBitrate))h=ii.audio;else{if(h=Number(e.maxAudioBitrate),isNaN(h))throw new Error("Invalid maxAudioBitrate parameter. Should be a number.");if(f>h)throw new Error('Invalid maxAudioBitrate parameter. Its value, "'+h+'", is inferior to the set minAudioBitrate, "'+f+'"')}return{maxBufferAhead:t,maxBufferBehind:n,limitVideoWidth:m,videoElement:l,wantedBufferAhead:r,throttleWhenHidden:i,throttleVideoBitrateWhenHidden:a,preferredAudioTracks:o,preferredTextTracks:s,preferredVideoTracks:u,initialAudioBitrate:c,initialVideoBitrate:d,minAudioBitrate:f,minVideoBitrate:p,maxAudioBitrate:h,maxVideoBitrate:v,stopAtEnd:(0,$.Z)(e.stopAtEnd)?ui:!!e.stopAtEnd}}(e),o=r.initialAudioBitrate,s=r.initialVideoBitrate,l=r.limitVideoWidth,d=r.minAudioBitrate,c=r.minVideoBitrate,f=r.maxAudioBitrate,p=r.maxBufferAhead,g=r.maxBufferBehind,y=r.maxVideoBitrate,_=r.preferredAudioTracks,b=r.preferredTextTracks,T=r.preferredVideoTracks,E=r.throttleWhenHidden,w=r.throttleVideoBitrateWhenHidden,S=r.videoElement,k=r.wantedBufferAhead,A=r.stopAtEnd;return S.preload="auto",t.version="3.24.0",t.log=O.Z,t.state="STOPPED",t.videoElement=S,t._priv_destroy$=new i.xQ,t._priv_pictureInPictureEvent$=new a.t(1),Ci(S).pipe((0,h.R)(t._priv_destroy$)).subscribe(t._priv_pictureInPictureEvent$),Ri(S).pipe((0,h.R)(t._priv_destroy$)).subscribe((function(){return t.trigger("fullscreenChange",t.isFullscreen())})),Pi(S.textTracks).pipe((0,h.R)(t._priv_destroy$),(0,v.U)((function(e){for(var t=e.target,n=[],r=0;r0?e.textTracks[0]:null},o.getPlayerState=function(){return this.state},o.isLive=function(){if(null===this._priv_contentInfos)return!1;var e=this._priv_contentInfos,t=e.isDirectFile,n=e.manifest;return!t&&null!==n&&n.isLive},o.getUrl=function(){if(null!==this._priv_contentInfos){var e=this._priv_contentInfos,t=e.isDirectFile,n=e.manifest,r=e.url;return t?r:null!==n?n.getUrl():void 0}},o.getVideoDuration=function(){if(null===this.videoElement)throw new Error("Disposed player");return this.videoElement.duration},o.getVideoBufferGap=function(){if(null===this.videoElement)throw new Error("Disposed player");var e=this.videoElement;return(0,X.L7)(e.buffered,e.currentTime)},o.getVideoLoadedTime=function(){if(null===this.videoElement)throw new Error("Disposed player");var e=this.videoElement;return(0,X.at)(e.buffered,e.currentTime)},o.getVideoPlayedTime=function(){if(null===this.videoElement)throw new Error("Disposed player");var e=this.videoElement;return(0,X.DD)(e.buffered,e.currentTime)},o.getWallClockTime=function(){if(null===this.videoElement)throw new Error("Disposed player");if(null===this._priv_contentInfos)return this.videoElement.currentTime;var e=this._priv_contentInfos,t=e.isDirectFile,n=e.manifest;return t?this.videoElement.currentTime:null!==n?this.videoElement.currentTime+(void 0!==n.availabilityStartTime?n.availabilityStartTime:0):0},o.getPosition=function(){if(null===this.videoElement)throw new Error("Disposed player");return this.videoElement.currentTime},o.getPlaybackRate=function(){return this._priv_speed$.getValue()},o.setPlaybackRate=function(e){this._priv_speed$.next(e)},o.getAvailableVideoBitrates=function(){if(null===this._priv_contentInfos)return[];var e=this._priv_contentInfos,t=e.currentPeriod,n=e.activeAdaptations;if(null===t||null===n)return[];var r=n[t.id];return void 0===r||(0,$.Z)(r.video)?[]:r.video.getAvailableBitrates()},o.getAvailableAudioBitrates=function(){if(null===this._priv_contentInfos)return[];var e=this._priv_contentInfos,t=e.currentPeriod,n=e.activeAdaptations;if(null===t||null===n)return[];var r=n[t.id];return void 0===r||(0,$.Z)(r.audio)?[]:r.audio.getAvailableBitrates()},o.getManualAudioBitrate=function(){return this._priv_bitrateInfos.manualBitrates.audio.getValue()},o.getManualVideoBitrate=function(){return this._priv_bitrateInfos.manualBitrates.video.getValue()},o.getVideoBitrate=function(){var e=this._priv_getCurrentRepresentations();if(null!==e&&!(0,$.Z)(e.video))return e.video.bitrate},o.getAudioBitrate=function(){var e=this._priv_getCurrentRepresentations();if(null!==e&&!(0,$.Z)(e.audio))return e.audio.bitrate},o.getMinVideoBitrate=function(){return this._priv_bitrateInfos.minAutoBitrates.video.getValue()},o.getMinAudioBitrate=function(){return this._priv_bitrateInfos.minAutoBitrates.audio.getValue()},o.getMaxVideoBitrate=function(){return this._priv_bitrateInfos.maxAutoBitrates.video.getValue()},o.getMaxAudioBitrate=function(){return this._priv_bitrateInfos.maxAutoBitrates.audio.getValue()},o.play=function(){var e=this;if(null===this.videoElement)throw new Error("Disposed player");var t=this.videoElement.play();return(0,$.Z)(t)||"function"!=typeof t.catch?q.Z.resolve():t.catch((function(t){if("NotAllowedError"===t.name){var n=new B.Z("MEDIA_ERR_PLAY_NOT_ALLOWED",t.toString());e.trigger("warning",n)}throw t}))},o.pause=function(){if(null===this.videoElement)throw new Error("Disposed player");this.videoElement.pause()},o.seekTo=function(e){if(null===this.videoElement)throw new Error("Disposed player");if(null===this._priv_contentInfos)throw new Error("player: no content loaded");var t,n=this._priv_contentInfos,r=n.isDirectFile,i=n.manifest;if(!r&&null===i)throw new Error("player: the content did not load yet");if("number"==typeof e)t=e;else if("object"==typeof e){var a=e,o=this.videoElement.currentTime;if((0,$.Z)(a.relative))if((0,$.Z)(a.position)){if((0,$.Z)(a.wallClockTime))throw new Error('invalid time object. You must set one of the following properties: "relative", "position" or "wallClockTime"');t=r||null===i?a.wallClockTime:a.wallClockTime-(void 0!==i.availabilityStartTime?i.availabilityStartTime:0)}else t=a.position;else t=o+a.relative}if(void 0===t)throw new Error("invalid time given");return this.videoElement.currentTime=t,t},o.isFullscreen=function(){return(0,Q.Z)("isFullscreen is deprecated. Fullscreen management should now be managed by the application"),N()},o.setFullscreen=function(e){if(void 0===e&&(e=!0),(0,Q.Z)("setFullscreen is deprecated. Fullscreen management should now be managed by the application"),null===this.videoElement)throw new Error("Disposed player");e?function(e){if(!N()){var t=e;"function"==typeof t.requestFullscreen?t.requestFullscreen():"function"==typeof t.msRequestFullscreen?t.msRequestFullscreen():"function"==typeof t.mozRequestFullScreen?t.mozRequestFullScreen():"function"==typeof t.webkitRequestFullscreen&&t.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}}(this.videoElement):C()},o.exitFullscreen=function(){(0,Q.Z)("exitFullscreen is deprecated. Fullscreen management should now be managed by the application"),C()},o.getVolume=function(){if(null===this.videoElement)throw new Error("Disposed player");return this.videoElement.volume},o.setVolume=function(e){if(null===this.videoElement)throw new Error("Disposed player");var t=this.videoElement;e!==t.volume&&(t.volume=e,this.trigger("volumeChange",e))},o.isMute=function(){return 0===this.getVolume()},o.mute=function(){this._priv_mutedMemory=this.getVolume(),this.setVolume(0)},o.unMute=function(){0===this.getVolume()&&this.setVolume(0===this._priv_mutedMemory?Ai:this._priv_mutedMemory)},o.setVideoBitrate=function(e){this._priv_bitrateInfos.manualBitrates.video.next(e)},o.setAudioBitrate=function(e){this._priv_bitrateInfos.manualBitrates.audio.next(e)},o.setMinVideoBitrate=function(e){var t=this._priv_bitrateInfos.maxAutoBitrates.video.getValue();if(e>t)throw new Error('Invalid minimum video bitrate given. Its value, "'+e+'" is superior the current maximum video birate, "'+t+'".');this._priv_bitrateInfos.minAutoBitrates.video.next(e)},o.setMinAudioBitrate=function(e){var t=this._priv_bitrateInfos.maxAutoBitrates.audio.getValue();if(e>t)throw new Error('Invalid minimum audio bitrate given. Its value, "'+e+'" is superior the current maximum audio birate, "'+t+'".');this._priv_bitrateInfos.minAutoBitrates.audio.next(e)},o.setMaxVideoBitrate=function(e){var t=this._priv_bitrateInfos.minAutoBitrates.video.getValue();if(e0?r.next(i[0]):r.next(null)}},o._priv_onPeriodStreamCleared=function(e){var t=e.type,n=e.period;switch(t){case"audio":case"text":case"video":null!==this._priv_trackChoiceManager&&this._priv_trackChoiceManager.removePeriod(t,n)}if(null!==this._priv_contentInfos){var r=this._priv_contentInfos,i=r.activeAdaptations,a=r.activeRepresentations;if(!(0,$.Z)(i)&&!(0,$.Z)(i[n.id])){var o=i[n.id];delete o[t],0===Object.keys(o).length&&delete i[n.id]}if(!(0,$.Z)(a)&&!(0,$.Z)(a[n.id])){var s=a[n.id];delete s[t],0===Object.keys(s).length&&delete a[n.id]}}},o._priv_onReloadingMediaSource=function(){null!==this._priv_contentInfos&&(this._priv_contentInfos.segmentBuffersStore=null),null!==this._priv_trackChoiceManager&&this._priv_trackChoiceManager.resetPeriods()},o._priv_onAdaptationChange=function(e){var t=e.type,n=e.adaptation,r=e.period;if(null!==this._priv_contentInfos){null===this._priv_contentInfos.activeAdaptations&&(this._priv_contentInfos.activeAdaptations={});var i,a=this._priv_contentInfos,o=a.activeAdaptations,s=a.currentPeriod,u=o[r.id];if((0,$.Z)(u))o[r.id]=((i={})[t]=n,i);else u[t]=n;if(null!==this._priv_trackChoiceManager&&null!==s&&!(0,$.Z)(r)&&r.id===s.id)switch(t){case"audio":var l=this._priv_trackChoiceManager.getChosenAudioTrack(s);this.trigger("audioTrackChange",l);var d=this.getAvailableAudioBitrates();this._priv_triggerAvailableBitratesChangeEvent("availableAudioBitratesChange",d);break;case"text":var c=this._priv_trackChoiceManager.getChosenTextTrack(s);this.trigger("textTrackChange",c);break;case"video":var f=this._priv_trackChoiceManager.getChosenVideoTrack(s);this.trigger("videoTrackChange",f);var p=this.getAvailableVideoBitrates();this._priv_triggerAvailableBitratesChangeEvent("availableVideoBitratesChange",p)}}else O.Z.error("API: The adaptations changed but no content is loaded")},o._priv_onRepresentationChange=function(e){var t,n=e.type,r=e.period,i=e.representation;if(null!==this._priv_contentInfos){null===this._priv_contentInfos.activeRepresentations&&(this._priv_contentInfos.activeRepresentations={});var a,o=this._priv_contentInfos,s=o.activeRepresentations,u=o.currentPeriod,l=s[r.id];if((0,$.Z)(l))s[r.id]=((a={})[n]=i,a);else l[n]=i;var d=null!==(t=null==i?void 0:i.bitrate)&&void 0!==t?t:-1;(0,$.Z)(r)||null===u||u.id!==r.id||("video"===n?this._priv_triggerCurrentBitrateChangeEvent("videoBitrateChange",d):"audio"===n&&this._priv_triggerCurrentBitrateChangeEvent("audioBitrateChange",d))}else O.Z.error("API: The representations changed but no content is loaded")},o._priv_onBitrateEstimationChange=function(e){var t=e.type,n=e.bitrate;void 0!==n&&(this._priv_bitrateInfos.lastBitrates[t]=n),this.trigger("bitrateEstimationChange",{type:t,bitrate:n})},o._priv_onPlayPauseNext=function(e){if(null===this.videoElement)throw new Error("Disposed player");this._priv_playing$.next(e)},o._priv_onNativeTextTracksNext=function(e){this.trigger("nativeTextTracksChange",e)},o._priv_setPlayerState=function(e){this.state!==e&&(this.state=e,O.Z.info("API: playerStateChange event",e),this.trigger("playerStateChange",e))},o._priv_triggerPositionUpdate=function(e){var t;if(null!==this._priv_contentInfos){if(this.state!==Hr){var n=this._priv_contentInfos,r=n.isDirectFile,i=n.manifest;if((r||null!==i)&&!(0,$.Z)(e)){this._priv_lastContentPlaybackInfos.lastPlaybackPosition=e.position;var a=null!==i?i.getMaximumPosition():void 0,o={position:e.position,duration:e.duration,playbackRate:e.playbackRate,maximumBufferTime:a,bufferGap:isFinite(e.bufferGap)?e.bufferGap:0};if(null!==i&&void 0!==a&&i.isLive&&e.position>0){var s=null!==(t=i.availabilityStartTime)&&void 0!==t?t:0;o.wallClockTime=e.position+s,o.liveGap=a-e.position}this.trigger("positionUpdate",o)}}}else O.Z.warn("API: Cannot perform time update: no content loaded.")},o._priv_triggerAvailableBitratesChangeEvent=function(e,t){var n=this._priv_contentEventsMemory[e];(void 0===n||(0,G.Z)(t,n))&&(this._priv_contentEventsMemory[e]=t,this.trigger(e,t))},o._priv_triggerCurrentBitrateChangeEvent=function(e,t){t!==this._priv_contentEventsMemory[e]&&(this._priv_contentEventsMemory[e]=t,this.trigger(e,t))},o._priv_getCurrentRepresentations=function(){if(null===this._priv_contentInfos)return null;var e=this._priv_contentInfos,t=e.currentPeriod,n=e.activeRepresentations;return null===t||null===n||(0,$.Z)(n[t.id])?null:n[t.id]},(0,e.Z)(r,null,[{key:"ErrorTypes",get:function(){return K.ZB}},{key:"ErrorCodes",get:function(){return K.SM}},{key:"LogLevel",get:function(){return O.Z.getLevel()},set:function(e){O.Z.setLevel(e)}}]),r}(H.Z);Di.version="3.24.0";const Li=Di;var Bi=n(7273);!function(){Bi.Z.emeManager=n(1603).ZP,Bi.Z.imageBuffer=n(7127).Z,Bi.Z.imageParser=n(3203).Z,Bi.Z.transports.smooth=n(2339).Z,Bi.Z.transports.dash=n(1923).Z,Bi.Z.nativeTextTracksBuffer=n(9059).Z,Bi.Z.nativeTextTracksParsers.vtt=n(9405).Z,Bi.Z.nativeTextTracksParsers.ttml=n(1570).Z,Bi.Z.nativeTextTracksParsers.sami=n(1812).Z,Bi.Z.nativeTextTracksParsers.srt=n(8057).Z,Bi.Z.htmlTextTracksBuffer=n(5192).Z,Bi.Z.htmlTextTracksParsers.sami=n(5734).Z,Bi.Z.htmlTextTracksParsers.ttml=n(7439).Z,Bi.Z.htmlTextTracksParsers.srt=n(8675).Z,Bi.Z.htmlTextTracksParsers.vtt=n(4099).Z;var e=n(8969).Z,t=n(7794).Z;Bi.Z.directfile={initDirectFile:e,mediaElementTrackChoiceManager:t}}();const Ui=Li})(),r=r.default})()})); \ No newline at end of file From b19a447d3c40070a722ff997ab5d83bc9785f8ae Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Wed, 31 Mar 2021 10:51:25 +0200 Subject: [PATCH 56/75] demo: update NODE_ENV to development on webpack conf for the demo page Previous "production" value emitted warnings I think because the `mode` webpack property was set to development. I did not take the time to dive all the consequences but this is not too bas as we're only speaking about the demo page. --- webpack-demo.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webpack-demo.config.js b/webpack-demo.config.js index e788f54978..2a21061d09 100644 --- a/webpack-demo.config.js +++ b/webpack-demo.config.js @@ -79,7 +79,7 @@ module.exports = { "__DEV__": true, "__LOGGER_LEVEL__": "\"INFO\"", "process.env": { - NODE_ENV: JSON.stringify("production"), + NODE_ENV: JSON.stringify(isDevMode ? "development" : "production"), }, "__FEATURES__": { BIF_PARSER: true, From 18f6601b1aa889d278a24743644f424ad88b439d Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Wed, 31 Mar 2021 11:08:13 +0200 Subject: [PATCH 57/75] build: disable size warning by rising authorized size --- webpack.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webpack.config.js b/webpack.config.js index 5fb4337c34..dce3d48298 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -123,8 +123,8 @@ module.exports = { minimizer: shouldMinify ? [new TerserPlugin()] : [], }, performance: { - maxEntrypointSize: shouldMinify ? 450000 : 2000000, - maxAssetSize: shouldMinify ? 450000 : 2000000, + maxEntrypointSize: shouldMinify ? 500000 : 2500000, + maxAssetSize: shouldMinify ? 500000 : 2500000, }, resolve: { extensions: [".ts", ".tsx", ".js", ".jsx", ".json"], From 2aed98f816cfe89aa74503f8e4ca7c113b2008c2 Mon Sep 17 00:00:00 2001 From: Paul Berberian Date: Wed, 31 Mar 2021 11:24:43 +0200 Subject: [PATCH 58/75] demo: minor updates responding to react warnings --- demo/full/scripts/controllers/ContentList.jsx | 14 ++++++++------ demo/full/scripts/controllers/Main.jsx | 2 +- demo/full/scripts/controllers/charts/index.jsx | 8 ++++---- demo/full/scripts/lib/withModulesState.jsx | 2 +- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/demo/full/scripts/controllers/ContentList.jsx b/demo/full/scripts/controllers/ContentList.jsx index 9d9b94f05a..8216332585 100644 --- a/demo/full/scripts/controllers/ContentList.jsx +++ b/demo/full/scripts/controllers/ContentList.jsx @@ -598,12 +598,14 @@ class ContentList extends React.Component { const generateDRMButtons = () => { return DRM_TYPES.map(type => -

li-QrdP6b! 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