26175 lines
1.1 MiB
26175 lines
1.1 MiB
!function e(t) {
|
|
var r, i;
|
|
r = this,
|
|
i = function() {
|
|
"use strict";
|
|
function r(e, t) {
|
|
for (var r = 0; r < t.length; r++) {
|
|
var i = t[r];
|
|
i.enumerable = i.enumerable || !1,
|
|
i.configurable = !0,
|
|
"value"in i && (i.writable = !0),
|
|
Object.defineProperty(e, f(i.key), i)
|
|
}
|
|
}
|
|
function i(e, t, i) {
|
|
return t && r(e.prototype, t),
|
|
i && r(e, i),
|
|
Object.defineProperty(e, "prototype", {
|
|
writable: !1
|
|
}),
|
|
e
|
|
}
|
|
function n(e, t, r) {
|
|
return (t = f(t))in e ? Object.defineProperty(e, t, {
|
|
value: r,
|
|
enumerable: !0,
|
|
configurable: !0,
|
|
writable: !0
|
|
}) : e[t] = r,
|
|
e
|
|
}
|
|
function a() {
|
|
return a = Object.assign ? Object.assign.bind() : function(e) {
|
|
for (var t = 1; t < arguments.length; t++) {
|
|
var r = arguments[t];
|
|
for (var i in r)
|
|
({}).hasOwnProperty.call(r, i) && (e[i] = r[i])
|
|
}
|
|
return e
|
|
}
|
|
,
|
|
a.apply(null, arguments)
|
|
}
|
|
function s(e) {
|
|
return s = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function(e) {
|
|
return e.__proto__ || Object.getPrototypeOf(e)
|
|
}
|
|
,
|
|
s(e)
|
|
}
|
|
function o(e, t) {
|
|
e.prototype = Object.create(t.prototype),
|
|
e.prototype.constructor = e,
|
|
h(e, t)
|
|
}
|
|
function l() {
|
|
try {
|
|
var e = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], (function() {}
|
|
)))
|
|
} catch (e) {}
|
|
return (l = function() {
|
|
return !!e
|
|
}
|
|
)()
|
|
}
|
|
function u(e, t) {
|
|
var r = Object.keys(e);
|
|
if (Object.getOwnPropertySymbols) {
|
|
var i = Object.getOwnPropertySymbols(e);
|
|
t && (i = i.filter((function(t) {
|
|
return Object.getOwnPropertyDescriptor(e, t).enumerable
|
|
}
|
|
))),
|
|
r.push.apply(r, i)
|
|
}
|
|
return r
|
|
}
|
|
function d(e) {
|
|
for (var t = 1; t < arguments.length; t++) {
|
|
var r = null != arguments[t] ? arguments[t] : {};
|
|
t % 2 ? u(Object(r), !0).forEach((function(t) {
|
|
n(e, t, r[t])
|
|
}
|
|
)) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(r)) : u(Object(r)).forEach((function(t) {
|
|
Object.defineProperty(e, t, Object.getOwnPropertyDescriptor(r, t))
|
|
}
|
|
))
|
|
}
|
|
return e
|
|
}
|
|
function h(e, t) {
|
|
return h = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(e, t) {
|
|
return e.__proto__ = t,
|
|
e
|
|
}
|
|
,
|
|
h(e, t)
|
|
}
|
|
function f(e) {
|
|
var t = function(e, t) {
|
|
if ("object" != typeof e || !e)
|
|
return e;
|
|
var r = e[Symbol.toPrimitive];
|
|
if (void 0 !== r) {
|
|
var i = r.call(e, t);
|
|
if ("object" != typeof i)
|
|
return i;
|
|
throw new TypeError("@@toPrimitive must return a primitive value.")
|
|
}
|
|
return ("string" === t ? String : Number)(e)
|
|
}(e, "string");
|
|
return "symbol" == typeof t ? t : t + ""
|
|
}
|
|
function c(e) {
|
|
var t = "function" == typeof Map ? new Map : void 0;
|
|
return c = function(e) {
|
|
if (null === e || !function(e) {
|
|
try {
|
|
return -1 !== Function.toString.call(e).indexOf("[native code]")
|
|
} catch (t) {
|
|
return "function" == typeof e
|
|
}
|
|
}(e))
|
|
return e;
|
|
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, r)
|
|
}
|
|
function r() {
|
|
return function(e, t, r) {
|
|
if (l())
|
|
return Reflect.construct.apply(null, arguments);
|
|
var i = [null];
|
|
i.push.apply(i, t);
|
|
var n = new (e.bind.apply(e, i));
|
|
return r && h(n, r.prototype),
|
|
n
|
|
}(e, arguments, s(this).constructor)
|
|
}
|
|
return r.prototype = Object.create(e.prototype, {
|
|
constructor: {
|
|
value: r,
|
|
enumerable: !1,
|
|
writable: !0,
|
|
configurable: !0
|
|
}
|
|
}),
|
|
h(r, e)
|
|
}
|
|
,
|
|
c(e)
|
|
}
|
|
function g(e) {
|
|
return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e
|
|
}
|
|
var v, m, p = {
|
|
exports: {}
|
|
}, y = (v || (v = 1,
|
|
function(e) {
|
|
var t = Object.prototype.hasOwnProperty
|
|
, r = "~";
|
|
function i() {}
|
|
function n(e, t, r) {
|
|
this.fn = e,
|
|
this.context = t,
|
|
this.once = r || !1
|
|
}
|
|
function a(e, t, i, a, s) {
|
|
if ("function" != typeof i)
|
|
throw new TypeError("The listener must be a function");
|
|
var o = new n(i,a || e,s)
|
|
, l = r ? r + t : t;
|
|
return e._events[l] ? e._events[l].fn ? e._events[l] = [e._events[l], o] : e._events[l].push(o) : (e._events[l] = o,
|
|
e._eventsCount++),
|
|
e
|
|
}
|
|
function s(e, t) {
|
|
0 == --e._eventsCount ? e._events = new i : delete e._events[t]
|
|
}
|
|
function o() {
|
|
this._events = new i,
|
|
this._eventsCount = 0
|
|
}
|
|
Object.create && (i.prototype = Object.create(null),
|
|
(new i).__proto__ || (r = !1)),
|
|
o.prototype.eventNames = function() {
|
|
var e, i, n = [];
|
|
if (0 === this._eventsCount)
|
|
return n;
|
|
for (i in e = this._events)
|
|
t.call(e, i) && n.push(r ? i.slice(1) : i);
|
|
return Object.getOwnPropertySymbols ? n.concat(Object.getOwnPropertySymbols(e)) : n
|
|
}
|
|
,
|
|
o.prototype.listeners = function(e) {
|
|
var t = r ? r + e : e
|
|
, i = this._events[t];
|
|
if (!i)
|
|
return [];
|
|
if (i.fn)
|
|
return [i.fn];
|
|
for (var n = 0, a = i.length, s = new Array(a); n < a; n++)
|
|
s[n] = i[n].fn;
|
|
return s
|
|
}
|
|
,
|
|
o.prototype.listenerCount = function(e) {
|
|
var t = r ? r + e : e
|
|
, i = this._events[t];
|
|
return i ? i.fn ? 1 : i.length : 0
|
|
}
|
|
,
|
|
o.prototype.emit = function(e, t, i, n, a, s) {
|
|
var o = r ? r + e : e;
|
|
if (!this._events[o])
|
|
return !1;
|
|
var l, u, d = this._events[o], h = arguments.length;
|
|
if (d.fn) {
|
|
switch (d.once && this.removeListener(e, d.fn, void 0, !0),
|
|
h) {
|
|
case 1:
|
|
return d.fn.call(d.context),
|
|
!0;
|
|
case 2:
|
|
return d.fn.call(d.context, t),
|
|
!0;
|
|
case 3:
|
|
return d.fn.call(d.context, t, i),
|
|
!0;
|
|
case 4:
|
|
return d.fn.call(d.context, t, i, n),
|
|
!0;
|
|
case 5:
|
|
return d.fn.call(d.context, t, i, n, a),
|
|
!0;
|
|
case 6:
|
|
return d.fn.call(d.context, t, i, n, a, s),
|
|
!0
|
|
}
|
|
for (u = 1,
|
|
l = new Array(h - 1); u < h; u++)
|
|
l[u - 1] = arguments[u];
|
|
d.fn.apply(d.context, l)
|
|
} else {
|
|
var f, c = d.length;
|
|
for (u = 0; u < c; u++)
|
|
switch (d[u].once && this.removeListener(e, d[u].fn, void 0, !0),
|
|
h) {
|
|
case 1:
|
|
d[u].fn.call(d[u].context);
|
|
break;
|
|
case 2:
|
|
d[u].fn.call(d[u].context, t);
|
|
break;
|
|
case 3:
|
|
d[u].fn.call(d[u].context, t, i);
|
|
break;
|
|
case 4:
|
|
d[u].fn.call(d[u].context, t, i, n);
|
|
break;
|
|
default:
|
|
if (!l)
|
|
for (f = 1,
|
|
l = new Array(h - 1); f < h; f++)
|
|
l[f - 1] = arguments[f];
|
|
d[u].fn.apply(d[u].context, l)
|
|
}
|
|
}
|
|
return !0
|
|
}
|
|
,
|
|
o.prototype.on = function(e, t, r) {
|
|
return a(this, e, t, r, !1)
|
|
}
|
|
,
|
|
o.prototype.once = function(e, t, r) {
|
|
return a(this, e, t, r, !0)
|
|
}
|
|
,
|
|
o.prototype.removeListener = function(e, t, i, n) {
|
|
var a = r ? r + e : e;
|
|
if (!this._events[a])
|
|
return this;
|
|
if (!t)
|
|
return s(this, a),
|
|
this;
|
|
var o = this._events[a];
|
|
if (o.fn)
|
|
o.fn !== t || n && !o.once || i && o.context !== i || s(this, a);
|
|
else {
|
|
for (var l = 0, u = [], d = o.length; l < d; l++)
|
|
(o[l].fn !== t || n && !o[l].once || i && o[l].context !== i) && u.push(o[l]);
|
|
u.length ? this._events[a] = 1 === u.length ? u[0] : u : s(this, a)
|
|
}
|
|
return this
|
|
}
|
|
,
|
|
o.prototype.removeAllListeners = function(e) {
|
|
var t;
|
|
return e ? (t = r ? r + e : e,
|
|
this._events[t] && s(this, t)) : (this._events = new i,
|
|
this._eventsCount = 0),
|
|
this
|
|
}
|
|
,
|
|
o.prototype.off = o.prototype.removeListener,
|
|
o.prototype.addListener = o.prototype.on,
|
|
o.prefixed = r,
|
|
o.EventEmitter = o,
|
|
e.exports = o
|
|
}(p)),
|
|
p.exports), E = g(y), T = {
|
|
exports: {}
|
|
}, S = (m || (m = 1,
|
|
function(e, t) {
|
|
var r, i, n, a, s;
|
|
r = /^(?=((?:[a-zA-Z0-9+\-.]+:)?))\1(?=((?:\/\/[^\/?#]*)?))\2(?=((?:(?:[^?#\/]*\/)*[^;?#\/]*)?))\3((?:;[^?#]*)?)(\?[^#]*)?(#[^]*)?$/,
|
|
i = /^(?=([^\/?#]*))\1([^]*)$/,
|
|
n = /(?:\/|^)\.(?=\/)/g,
|
|
a = /(?:\/|^)\.\.\/(?!\.\.\/)[^\/]*(?=\/)/g,
|
|
s = {
|
|
buildAbsoluteURL: function(e, t, r) {
|
|
if (r = r || {},
|
|
e = e.trim(),
|
|
!(t = t.trim())) {
|
|
if (!r.alwaysNormalize)
|
|
return e;
|
|
var n = s.parseURL(e);
|
|
if (!n)
|
|
throw new Error("Error trying to parse base URL.");
|
|
return n.path = s.normalizePath(n.path),
|
|
s.buildURLFromParts(n)
|
|
}
|
|
var a = s.parseURL(t);
|
|
if (!a)
|
|
throw new Error("Error trying to parse relative URL.");
|
|
if (a.scheme)
|
|
return r.alwaysNormalize ? (a.path = s.normalizePath(a.path),
|
|
s.buildURLFromParts(a)) : t;
|
|
var o = s.parseURL(e);
|
|
if (!o)
|
|
throw new Error("Error trying to parse base URL.");
|
|
if (!o.netLoc && o.path && "/" !== o.path[0]) {
|
|
var l = i.exec(o.path);
|
|
o.netLoc = l[1],
|
|
o.path = l[2]
|
|
}
|
|
o.netLoc && !o.path && (o.path = "/");
|
|
var u = {
|
|
scheme: o.scheme,
|
|
netLoc: a.netLoc,
|
|
path: null,
|
|
params: a.params,
|
|
query: a.query,
|
|
fragment: a.fragment
|
|
};
|
|
if (!a.netLoc && (u.netLoc = o.netLoc,
|
|
"/" !== a.path[0]))
|
|
if (a.path) {
|
|
var d = o.path
|
|
, h = d.substring(0, d.lastIndexOf("/") + 1) + a.path;
|
|
u.path = s.normalizePath(h)
|
|
} else
|
|
u.path = o.path,
|
|
a.params || (u.params = o.params,
|
|
a.query || (u.query = o.query));
|
|
return null === u.path && (u.path = r.alwaysNormalize ? s.normalizePath(a.path) : a.path),
|
|
s.buildURLFromParts(u)
|
|
},
|
|
parseURL: function(e) {
|
|
var t = r.exec(e);
|
|
return t ? {
|
|
scheme: t[1] || "",
|
|
netLoc: t[2] || "",
|
|
path: t[3] || "",
|
|
params: t[4] || "",
|
|
query: t[5] || "",
|
|
fragment: t[6] || ""
|
|
} : null
|
|
},
|
|
normalizePath: function(e) {
|
|
for (e = e.split("").reverse().join("").replace(n, ""); e.length !== (e = e.replace(a, "")).length; )
|
|
;
|
|
return e.split("").reverse().join("")
|
|
},
|
|
buildURLFromParts: function(e) {
|
|
return e.scheme + e.netLoc + e.path + e.params + e.query + e.fragment
|
|
}
|
|
},
|
|
e.exports = s
|
|
}(T)),
|
|
T.exports), A = Number.isFinite || function(e) {
|
|
return "number" == typeof e && isFinite(e)
|
|
}
|
|
, L = Number.isSafeInteger || function(e) {
|
|
return "number" == typeof e && Math.abs(e) <= I
|
|
}
|
|
, I = Number.MAX_SAFE_INTEGER || 9007199254740991, R = function(e) {
|
|
return e.NETWORK_ERROR = "networkError",
|
|
e.MEDIA_ERROR = "mediaError",
|
|
e.KEY_SYSTEM_ERROR = "keySystemError",
|
|
e.MUX_ERROR = "muxError",
|
|
e.OTHER_ERROR = "otherError",
|
|
e
|
|
}({}), k = function(e) {
|
|
return e.KEY_SYSTEM_NO_KEYS = "keySystemNoKeys",
|
|
e.KEY_SYSTEM_NO_ACCESS = "keySystemNoAccess",
|
|
e.KEY_SYSTEM_NO_SESSION = "keySystemNoSession",
|
|
e.KEY_SYSTEM_NO_CONFIGURED_LICENSE = "keySystemNoConfiguredLicense",
|
|
e.KEY_SYSTEM_LICENSE_REQUEST_FAILED = "keySystemLicenseRequestFailed",
|
|
e.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED = "keySystemServerCertificateRequestFailed",
|
|
e.KEY_SYSTEM_SERVER_CERTIFICATE_UPDATE_FAILED = "keySystemServerCertificateUpdateFailed",
|
|
e.KEY_SYSTEM_SESSION_UPDATE_FAILED = "keySystemSessionUpdateFailed",
|
|
e.KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED = "keySystemStatusOutputRestricted",
|
|
e.KEY_SYSTEM_STATUS_INTERNAL_ERROR = "keySystemStatusInternalError",
|
|
e.KEY_SYSTEM_DESTROY_MEDIA_KEYS_ERROR = "keySystemDestroyMediaKeysError",
|
|
e.KEY_SYSTEM_DESTROY_CLOSE_SESSION_ERROR = "keySystemDestroyCloseSessionError",
|
|
e.KEY_SYSTEM_DESTROY_REMOVE_SESSION_ERROR = "keySystemDestroyRemoveSessionError",
|
|
e.MANIFEST_LOAD_ERROR = "manifestLoadError",
|
|
e.MANIFEST_LOAD_TIMEOUT = "manifestLoadTimeOut",
|
|
e.MANIFEST_PARSING_ERROR = "manifestParsingError",
|
|
e.MANIFEST_INCOMPATIBLE_CODECS_ERROR = "manifestIncompatibleCodecsError",
|
|
e.LEVEL_EMPTY_ERROR = "levelEmptyError",
|
|
e.LEVEL_LOAD_ERROR = "levelLoadError",
|
|
e.LEVEL_LOAD_TIMEOUT = "levelLoadTimeOut",
|
|
e.LEVEL_PARSING_ERROR = "levelParsingError",
|
|
e.LEVEL_SWITCH_ERROR = "levelSwitchError",
|
|
e.AUDIO_TRACK_LOAD_ERROR = "audioTrackLoadError",
|
|
e.AUDIO_TRACK_LOAD_TIMEOUT = "audioTrackLoadTimeOut",
|
|
e.SUBTITLE_LOAD_ERROR = "subtitleTrackLoadError",
|
|
e.SUBTITLE_TRACK_LOAD_TIMEOUT = "subtitleTrackLoadTimeOut",
|
|
e.FRAG_LOAD_ERROR = "fragLoadError",
|
|
e.FRAG_LOAD_TIMEOUT = "fragLoadTimeOut",
|
|
e.FRAG_DECRYPT_ERROR = "fragDecryptError",
|
|
e.FRAG_PARSING_ERROR = "fragParsingError",
|
|
e.FRAG_GAP = "fragGap",
|
|
e.REMUX_ALLOC_ERROR = "remuxAllocError",
|
|
e.KEY_LOAD_ERROR = "keyLoadError",
|
|
e.KEY_LOAD_TIMEOUT = "keyLoadTimeOut",
|
|
e.BUFFER_ADD_CODEC_ERROR = "bufferAddCodecError",
|
|
e.BUFFER_INCOMPATIBLE_CODECS_ERROR = "bufferIncompatibleCodecsError",
|
|
e.BUFFER_APPEND_ERROR = "bufferAppendError",
|
|
e.BUFFER_APPENDING_ERROR = "bufferAppendingError",
|
|
e.BUFFER_STALLED_ERROR = "bufferStalledError",
|
|
e.BUFFER_FULL_ERROR = "bufferFullError",
|
|
e.BUFFER_SEEK_OVER_HOLE = "bufferSeekOverHole",
|
|
e.BUFFER_NUDGE_ON_STALL = "bufferNudgeOnStall",
|
|
e.ASSET_LIST_LOAD_ERROR = "assetListLoadError",
|
|
e.ASSET_LIST_LOAD_TIMEOUT = "assetListLoadTimeout",
|
|
e.ASSET_LIST_PARSING_ERROR = "assetListParsingError",
|
|
e.INTERSTITIAL_ASSET_ITEM_ERROR = "interstitialAssetItemError",
|
|
e.INTERNAL_EXCEPTION = "internalException",
|
|
e.INTERNAL_ABORTED = "aborted",
|
|
e.ATTACH_MEDIA_ERROR = "attachMediaError",
|
|
e.UNKNOWN = "unknown",
|
|
e
|
|
}({}), b = function(e) {
|
|
return e.MEDIA_ATTACHING = "hlsMediaAttaching",
|
|
e.MEDIA_ATTACHED = "hlsMediaAttached",
|
|
e.MEDIA_DETACHING = "hlsMediaDetaching",
|
|
e.MEDIA_DETACHED = "hlsMediaDetached",
|
|
e.MEDIA_ENDED = "hlsMediaEnded",
|
|
e.STALL_RESOLVED = "hlsStallResolved",
|
|
e.BUFFER_RESET = "hlsBufferReset",
|
|
e.BUFFER_CODECS = "hlsBufferCodecs",
|
|
e.BUFFER_CREATED = "hlsBufferCreated",
|
|
e.BUFFER_APPENDING = "hlsBufferAppending",
|
|
e.BUFFER_APPENDED = "hlsBufferAppended",
|
|
e.BUFFER_EOS = "hlsBufferEos",
|
|
e.BUFFERED_TO_END = "hlsBufferedToEnd",
|
|
e.BUFFER_FLUSHING = "hlsBufferFlushing",
|
|
e.BUFFER_FLUSHED = "hlsBufferFlushed",
|
|
e.MANIFEST_LOADING = "hlsManifestLoading",
|
|
e.MANIFEST_LOADED = "hlsManifestLoaded",
|
|
e.MANIFEST_PARSED = "hlsManifestParsed",
|
|
e.LEVEL_SWITCHING = "hlsLevelSwitching",
|
|
e.LEVEL_SWITCHED = "hlsLevelSwitched",
|
|
e.LEVEL_LOADING = "hlsLevelLoading",
|
|
e.LEVEL_LOADED = "hlsLevelLoaded",
|
|
e.LEVEL_UPDATED = "hlsLevelUpdated",
|
|
e.LEVEL_PTS_UPDATED = "hlsLevelPtsUpdated",
|
|
e.LEVELS_UPDATED = "hlsLevelsUpdated",
|
|
e.AUDIO_TRACKS_UPDATED = "hlsAudioTracksUpdated",
|
|
e.AUDIO_TRACK_SWITCHING = "hlsAudioTrackSwitching",
|
|
e.AUDIO_TRACK_SWITCHED = "hlsAudioTrackSwitched",
|
|
e.AUDIO_TRACK_LOADING = "hlsAudioTrackLoading",
|
|
e.AUDIO_TRACK_LOADED = "hlsAudioTrackLoaded",
|
|
e.AUDIO_TRACK_UPDATED = "hlsAudioTrackUpdated",
|
|
e.SUBTITLE_TRACKS_UPDATED = "hlsSubtitleTracksUpdated",
|
|
e.SUBTITLE_TRACKS_CLEARED = "hlsSubtitleTracksCleared",
|
|
e.SUBTITLE_TRACK_SWITCH = "hlsSubtitleTrackSwitch",
|
|
e.SUBTITLE_TRACK_LOADING = "hlsSubtitleTrackLoading",
|
|
e.SUBTITLE_TRACK_LOADED = "hlsSubtitleTrackLoaded",
|
|
e.SUBTITLE_TRACK_UPDATED = "hlsSubtitleTrackUpdated",
|
|
e.SUBTITLE_FRAG_PROCESSED = "hlsSubtitleFragProcessed",
|
|
e.CUES_PARSED = "hlsCuesParsed",
|
|
e.NON_NATIVE_TEXT_TRACKS_FOUND = "hlsNonNativeTextTracksFound",
|
|
e.INIT_PTS_FOUND = "hlsInitPtsFound",
|
|
e.FRAG_LOADING = "hlsFragLoading",
|
|
e.FRAG_LOAD_EMERGENCY_ABORTED = "hlsFragLoadEmergencyAborted",
|
|
e.FRAG_LOADED = "hlsFragLoaded",
|
|
e.FRAG_DECRYPTED = "hlsFragDecrypted",
|
|
e.FRAG_PARSING_INIT_SEGMENT = "hlsFragParsingInitSegment",
|
|
e.FRAG_PARSING_USERDATA = "hlsFragParsingUserdata",
|
|
e.FRAG_PARSING_METADATA = "hlsFragParsingMetadata",
|
|
e.FRAG_PARSED = "hlsFragParsed",
|
|
e.FRAG_BUFFERED = "hlsFragBuffered",
|
|
e.FRAG_CHANGED = "hlsFragChanged",
|
|
e.FPS_DROP = "hlsFpsDrop",
|
|
e.FPS_DROP_LEVEL_CAPPING = "hlsFpsDropLevelCapping",
|
|
e.MAX_AUTO_LEVEL_UPDATED = "hlsMaxAutoLevelUpdated",
|
|
e.ERROR = "hlsError",
|
|
e.DESTROYING = "hlsDestroying",
|
|
e.KEY_LOADING = "hlsKeyLoading",
|
|
e.KEY_LOADED = "hlsKeyLoaded",
|
|
e.LIVE_BACK_BUFFER_REACHED = "hlsLiveBackBufferReached",
|
|
e.BACK_BUFFER_REACHED = "hlsBackBufferReached",
|
|
e.STEERING_MANIFEST_LOADED = "hlsSteeringManifestLoaded",
|
|
e.ASSET_LIST_LOADING = "hlsAssetListLoading",
|
|
e.ASSET_LIST_LOADED = "hlsAssetListLoaded",
|
|
e.INTERSTITIALS_UPDATED = "hlsInterstitialsUpdated",
|
|
e.INTERSTITIALS_BUFFERED_TO_BOUNDARY = "hlsInterstitialsBufferedToBoundary",
|
|
e.INTERSTITIAL_ASSET_PLAYER_CREATED = "hlsInterstitialAssetPlayerCreated",
|
|
e.INTERSTITIAL_STARTED = "hlsInterstitialStarted",
|
|
e.INTERSTITIAL_ASSET_STARTED = "hlsInterstitialAssetStarted",
|
|
e.INTERSTITIAL_ASSET_ENDED = "hlsInterstitialAssetEnded",
|
|
e.INTERSTITIAL_ASSET_ERROR = "hlsInterstitialAssetError",
|
|
e.INTERSTITIAL_ENDED = "hlsInterstitialEnded",
|
|
e.INTERSTITIALS_PRIMARY_RESUMED = "hlsInterstitialsPrimaryResumed",
|
|
e.PLAYOUT_LIMIT_REACHED = "hlsPlayoutLimitReached",
|
|
e.EVENT_CUE_ENTER = "hlsEventCueEnter",
|
|
e
|
|
}({}), D = "manifest", _ = "level", P = "audioTrack", C = "subtitleTrack", w = "main", O = "audio", x = "subtitle", M = function() {
|
|
function e(e, t, r) {
|
|
void 0 === t && (t = 0),
|
|
void 0 === r && (r = 0),
|
|
this.halfLife = void 0,
|
|
this.alpha_ = void 0,
|
|
this.estimate_ = void 0,
|
|
this.totalWeight_ = void 0,
|
|
this.halfLife = e,
|
|
this.alpha_ = e ? Math.exp(Math.log(.5) / e) : 0,
|
|
this.estimate_ = t,
|
|
this.totalWeight_ = r
|
|
}
|
|
var t = e.prototype;
|
|
return t.sample = function(e, t) {
|
|
var r = Math.pow(this.alpha_, e);
|
|
this.estimate_ = t * (1 - r) + r * this.estimate_,
|
|
this.totalWeight_ += e
|
|
}
|
|
,
|
|
t.getTotalWeight = function() {
|
|
return this.totalWeight_
|
|
}
|
|
,
|
|
t.getEstimate = function() {
|
|
if (this.alpha_) {
|
|
var e = 1 - Math.pow(this.alpha_, this.totalWeight_);
|
|
if (e)
|
|
return this.estimate_ / e
|
|
}
|
|
return this.estimate_
|
|
}
|
|
,
|
|
e
|
|
}(), F = function() {
|
|
function e(e, t, r, i) {
|
|
void 0 === i && (i = 100),
|
|
this.defaultEstimate_ = void 0,
|
|
this.minWeight_ = void 0,
|
|
this.minDelayMs_ = void 0,
|
|
this.slow_ = void 0,
|
|
this.fast_ = void 0,
|
|
this.defaultTTFB_ = void 0,
|
|
this.ttfb_ = void 0,
|
|
this.defaultEstimate_ = r,
|
|
this.minWeight_ = .001,
|
|
this.minDelayMs_ = 50,
|
|
this.slow_ = new M(e),
|
|
this.fast_ = new M(t),
|
|
this.defaultTTFB_ = i,
|
|
this.ttfb_ = new M(e)
|
|
}
|
|
var t = e.prototype;
|
|
return t.update = function(e, t) {
|
|
var r = this.slow_
|
|
, i = this.fast_
|
|
, n = this.ttfb_;
|
|
r.halfLife !== e && (this.slow_ = new M(e,r.getEstimate(),r.getTotalWeight())),
|
|
i.halfLife !== t && (this.fast_ = new M(t,i.getEstimate(),i.getTotalWeight())),
|
|
n.halfLife !== e && (this.ttfb_ = new M(e,n.getEstimate(),n.getTotalWeight()))
|
|
}
|
|
,
|
|
t.sample = function(e, t) {
|
|
var r = (e = Math.max(e, this.minDelayMs_)) / 1e3
|
|
, i = 8 * t / r;
|
|
this.fast_.sample(r, i),
|
|
this.slow_.sample(r, i)
|
|
}
|
|
,
|
|
t.sampleTTFB = function(e) {
|
|
var t = e / 1e3
|
|
, r = Math.sqrt(2) * Math.exp(-Math.pow(t, 2) / 2);
|
|
this.ttfb_.sample(r, Math.max(e, 5))
|
|
}
|
|
,
|
|
t.canEstimate = function() {
|
|
return this.fast_.getTotalWeight() >= this.minWeight_
|
|
}
|
|
,
|
|
t.getEstimate = function() {
|
|
return this.canEstimate() ? Math.min(this.fast_.getEstimate(), this.slow_.getEstimate()) : this.defaultEstimate_
|
|
}
|
|
,
|
|
t.getEstimateTTFB = function() {
|
|
return this.ttfb_.getTotalWeight() >= this.minWeight_ ? this.ttfb_.getEstimate() : this.defaultTTFB_
|
|
}
|
|
,
|
|
t.destroy = function() {}
|
|
,
|
|
i(e, [{
|
|
key: "defaultEstimate",
|
|
get: function() {
|
|
return this.defaultEstimate_
|
|
}
|
|
}])
|
|
}(), N = function(e, t) {
|
|
this.trace = void 0,
|
|
this.debug = void 0,
|
|
this.log = void 0,
|
|
this.warn = void 0,
|
|
this.info = void 0,
|
|
this.error = void 0;
|
|
var r = "[" + e + "]:";
|
|
this.trace = U,
|
|
this.debug = t.debug.bind(null, r),
|
|
this.log = t.log.bind(null, r),
|
|
this.warn = t.warn.bind(null, r),
|
|
this.info = t.info.bind(null, r),
|
|
this.error = t.error.bind(null, r)
|
|
}, U = function() {}, B = {
|
|
trace: U,
|
|
debug: U,
|
|
log: U,
|
|
warn: U,
|
|
info: U,
|
|
error: U
|
|
};
|
|
function G() {
|
|
return a({}, B)
|
|
}
|
|
function K(e, t, r) {
|
|
return t[e] ? t[e].bind(t) : function(e, t) {
|
|
var r = self.console[e];
|
|
return r ? r.bind(self.console, (t ? "[" + t + "] " : "") + "[" + e + "] >") : U
|
|
}(e, r)
|
|
}
|
|
var V = G();
|
|
function H(e, t, r) {
|
|
var i = G();
|
|
if ("object" == typeof console && !0 === e || "object" == typeof e) {
|
|
var n = ["debug", "log", "info", "warn", "error"];
|
|
n.forEach((function(t) {
|
|
i[t] = K(t, e, r)
|
|
}
|
|
));
|
|
try {
|
|
i.log('Debug logs enabled for "' + t + '" in hls.js version 1.6.12')
|
|
} catch (e) {
|
|
return G()
|
|
}
|
|
n.forEach((function(t) {
|
|
V[t] = K(t, e)
|
|
}
|
|
))
|
|
} else
|
|
a(V, i);
|
|
return i
|
|
}
|
|
var Y = V;
|
|
function W(e) {
|
|
if (void 0 === e && (e = !0),
|
|
"undefined" != typeof self)
|
|
return (e || !self.MediaSource) && self.ManagedMediaSource || self.MediaSource || self.WebKitMediaSource
|
|
}
|
|
function j(e, t) {
|
|
var r = Object.keys(e)
|
|
, i = Object.keys(t)
|
|
, n = r.length
|
|
, a = i.length;
|
|
return !n || !a || n === a && !r.some((function(e) {
|
|
return -1 === i.indexOf(e)
|
|
}
|
|
))
|
|
}
|
|
function q(e, t) {
|
|
if (void 0 === t && (t = !1),
|
|
"undefined" != typeof TextDecoder) {
|
|
var r = new TextDecoder("utf-8").decode(e);
|
|
if (t) {
|
|
var i = r.indexOf("\0");
|
|
return -1 !== i ? r.substring(0, i) : r
|
|
}
|
|
return r.replace(/\0/g, "")
|
|
}
|
|
for (var n, a, s, o = e.length, l = "", u = 0; u < o; ) {
|
|
if (0 === (n = e[u++]) && t)
|
|
return l;
|
|
if (0 !== n && 3 !== n)
|
|
switch (n >> 4) {
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
case 6:
|
|
case 7:
|
|
l += String.fromCharCode(n);
|
|
break;
|
|
case 12:
|
|
case 13:
|
|
a = e[u++],
|
|
l += String.fromCharCode((31 & n) << 6 | 63 & a);
|
|
break;
|
|
case 14:
|
|
a = e[u++],
|
|
s = e[u++],
|
|
l += String.fromCharCode((15 & n) << 12 | (63 & a) << 6 | (63 & s) << 0)
|
|
}
|
|
}
|
|
return l
|
|
}
|
|
function X(e) {
|
|
for (var t = "", r = 0; r < e.length; r++) {
|
|
var i = e[r].toString(16);
|
|
i.length < 2 && (i = "0" + i),
|
|
t += i
|
|
}
|
|
return t
|
|
}
|
|
function Q(e) {
|
|
return Uint8Array.from(e.replace(/^0x/, "").replace(/([\da-fA-F]{2}) ?/g, "0x$1 ").replace(/ +$/, "").split(" ")).buffer
|
|
}
|
|
var z = function() {
|
|
this.aborted = !1,
|
|
this.loaded = 0,
|
|
this.retry = 0,
|
|
this.total = 0,
|
|
this.chunkCount = 0,
|
|
this.bwEstimate = 0,
|
|
this.loading = {
|
|
start: 0,
|
|
first: 0,
|
|
end: 0
|
|
},
|
|
this.parsing = {
|
|
start: 0,
|
|
end: 0
|
|
},
|
|
this.buffering = {
|
|
start: 0,
|
|
first: 0,
|
|
end: 0
|
|
}
|
|
}
|
|
, $ = "audio"
|
|
, Z = "video"
|
|
, J = "audiovideo"
|
|
, ee = function() {
|
|
function e(e) {
|
|
var t, r, i;
|
|
this._byteRange = null,
|
|
this._url = null,
|
|
this._stats = null,
|
|
this._streams = null,
|
|
this.base = void 0,
|
|
this.relurl = void 0,
|
|
"string" == typeof e && (e = {
|
|
url: e
|
|
}),
|
|
this.base = e,
|
|
(i = ne(t = this, r = "stats")) && (i.enumerable = !0,
|
|
Object.defineProperty(t, r, i))
|
|
}
|
|
var t = e.prototype;
|
|
return t.setByteRange = function(e, t) {
|
|
var r, i = e.split("@", 2);
|
|
r = 1 === i.length ? (null == t ? void 0 : t.byteRangeEndOffset) || 0 : parseInt(i[1]),
|
|
this._byteRange = [r, parseInt(i[0]) + r]
|
|
}
|
|
,
|
|
t.clearElementaryStreamInfo = function() {
|
|
var e = this.elementaryStreams;
|
|
e[$] = null,
|
|
e[Z] = null,
|
|
e[J] = null
|
|
}
|
|
,
|
|
i(e, [{
|
|
key: "baseurl",
|
|
get: function() {
|
|
return this.base.url
|
|
}
|
|
}, {
|
|
key: "byteRange",
|
|
get: function() {
|
|
return null === this._byteRange ? [] : this._byteRange
|
|
}
|
|
}, {
|
|
key: "byteRangeStartOffset",
|
|
get: function() {
|
|
return this.byteRange[0]
|
|
}
|
|
}, {
|
|
key: "byteRangeEndOffset",
|
|
get: function() {
|
|
return this.byteRange[1]
|
|
}
|
|
}, {
|
|
key: "elementaryStreams",
|
|
get: function() {
|
|
var e;
|
|
return null === this._streams && (this._streams = ((e = {})[$] = null,
|
|
e[Z] = null,
|
|
e[J] = null,
|
|
e)),
|
|
this._streams
|
|
},
|
|
set: function(e) {
|
|
this._streams = e
|
|
}
|
|
}, {
|
|
key: "hasStats",
|
|
get: function() {
|
|
return null !== this._stats
|
|
}
|
|
}, {
|
|
key: "hasStreams",
|
|
get: function() {
|
|
return null !== this._streams
|
|
}
|
|
}, {
|
|
key: "stats",
|
|
get: function() {
|
|
return null === this._stats && (this._stats = new z),
|
|
this._stats
|
|
},
|
|
set: function(e) {
|
|
this._stats = e
|
|
}
|
|
}, {
|
|
key: "url",
|
|
get: function() {
|
|
return !this._url && this.baseurl && this.relurl && (this._url = S.buildAbsoluteURL(this.baseurl, this.relurl, {
|
|
alwaysNormalize: !0
|
|
})),
|
|
this._url || ""
|
|
},
|
|
set: function(e) {
|
|
this._url = e
|
|
}
|
|
}])
|
|
}();
|
|
function te(e) {
|
|
return "initSegment" !== e.sn
|
|
}
|
|
var re = function(e) {
|
|
function t(t, r) {
|
|
var i;
|
|
return (i = e.call(this, r) || this)._decryptdata = null,
|
|
i._programDateTime = null,
|
|
i._ref = null,
|
|
i._bitrate = void 0,
|
|
i.rawProgramDateTime = null,
|
|
i.tagList = [],
|
|
i.duration = 0,
|
|
i.sn = 0,
|
|
i.levelkeys = void 0,
|
|
i.type = void 0,
|
|
i.loader = null,
|
|
i.keyLoader = null,
|
|
i.level = -1,
|
|
i.cc = 0,
|
|
i.startPTS = void 0,
|
|
i.endPTS = void 0,
|
|
i.startDTS = void 0,
|
|
i.endDTS = void 0,
|
|
i.start = 0,
|
|
i.playlistOffset = 0,
|
|
i.deltaPTS = void 0,
|
|
i.maxStartPTS = void 0,
|
|
i.minEndPTS = void 0,
|
|
i.data = void 0,
|
|
i.bitrateTest = !1,
|
|
i.title = null,
|
|
i.initSegment = null,
|
|
i.endList = void 0,
|
|
i.gap = void 0,
|
|
i.urlId = 0,
|
|
i.type = t,
|
|
i
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.addStart = function(e) {
|
|
this.setStart(this.start + e)
|
|
}
|
|
,
|
|
r.setStart = function(e) {
|
|
this.start = e,
|
|
this._ref && (this._ref.start = e)
|
|
}
|
|
,
|
|
r.setDuration = function(e) {
|
|
this.duration = e,
|
|
this._ref && (this._ref.duration = e)
|
|
}
|
|
,
|
|
r.setKeyFormat = function(e) {
|
|
if (this.levelkeys) {
|
|
var t = this.levelkeys[e];
|
|
t && !this._decryptdata && (this._decryptdata = t.getDecryptData(this.sn))
|
|
}
|
|
}
|
|
,
|
|
r.abortRequests = function() {
|
|
var e, t;
|
|
null == (e = this.loader) || e.abort(),
|
|
null == (t = this.keyLoader) || t.abort()
|
|
}
|
|
,
|
|
r.setElementaryStreamInfo = function(e, t, r, i, n, a) {
|
|
void 0 === a && (a = !1);
|
|
var s = this.elementaryStreams
|
|
, o = s[e];
|
|
o ? (o.startPTS = Math.min(o.startPTS, t),
|
|
o.endPTS = Math.max(o.endPTS, r),
|
|
o.startDTS = Math.min(o.startDTS, i),
|
|
o.endDTS = Math.max(o.endDTS, n)) : s[e] = {
|
|
startPTS: t,
|
|
endPTS: r,
|
|
startDTS: i,
|
|
endDTS: n,
|
|
partial: a
|
|
}
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "byteLength",
|
|
get: function() {
|
|
if (this.hasStats) {
|
|
var e = this.stats.total;
|
|
if (e)
|
|
return e
|
|
}
|
|
if (this.byteRange.length) {
|
|
var t = this.byteRange[0]
|
|
, r = this.byteRange[1];
|
|
if (A(t) && A(r))
|
|
return r - t
|
|
}
|
|
return null
|
|
}
|
|
}, {
|
|
key: "bitrate",
|
|
get: function() {
|
|
return this.byteLength ? 8 * this.byteLength / this.duration : this._bitrate ? this._bitrate : null
|
|
},
|
|
set: function(e) {
|
|
this._bitrate = e
|
|
}
|
|
}, {
|
|
key: "decryptdata",
|
|
get: function() {
|
|
if (!this.levelkeys && !this._decryptdata)
|
|
return null;
|
|
if (!this._decryptdata && this.levelkeys && !this.levelkeys.NONE) {
|
|
var e = this.levelkeys.identity;
|
|
if (e)
|
|
this._decryptdata = e.getDecryptData(this.sn);
|
|
else {
|
|
var t = Object.keys(this.levelkeys);
|
|
if (1 === t.length) {
|
|
var r = this._decryptdata = this.levelkeys[t[0]] || null;
|
|
if (r)
|
|
return r.getDecryptData(this.sn)
|
|
}
|
|
}
|
|
}
|
|
return this._decryptdata
|
|
}
|
|
}, {
|
|
key: "end",
|
|
get: function() {
|
|
return this.start + this.duration
|
|
}
|
|
}, {
|
|
key: "endProgramDateTime",
|
|
get: function() {
|
|
if (null === this.programDateTime)
|
|
return null;
|
|
var e = A(this.duration) ? this.duration : 0;
|
|
return this.programDateTime + 1e3 * e
|
|
}
|
|
}, {
|
|
key: "encrypted",
|
|
get: function() {
|
|
var e;
|
|
if (null != (e = this._decryptdata) && e.encrypted)
|
|
return !0;
|
|
if (this.levelkeys) {
|
|
var t, r = Object.keys(this.levelkeys), i = r.length;
|
|
if (i > 1 || 1 === i && null != (t = this.levelkeys[r[0]]) && t.encrypted)
|
|
return !0
|
|
}
|
|
return !1
|
|
}
|
|
}, {
|
|
key: "programDateTime",
|
|
get: function() {
|
|
return null === this._programDateTime && this.rawProgramDateTime && (this.programDateTime = Date.parse(this.rawProgramDateTime)),
|
|
this._programDateTime
|
|
},
|
|
set: function(e) {
|
|
A(e) ? this._programDateTime = e : this._programDateTime = this.rawProgramDateTime = null
|
|
}
|
|
}, {
|
|
key: "ref",
|
|
get: function() {
|
|
return te(this) ? (this._ref || (this._ref = {
|
|
base: this.base,
|
|
start: this.start,
|
|
duration: this.duration,
|
|
sn: this.sn,
|
|
programDateTime: this.programDateTime
|
|
}),
|
|
this._ref) : null
|
|
}
|
|
}])
|
|
}(ee)
|
|
, ie = function(e) {
|
|
function t(t, r, i, n, a) {
|
|
var s;
|
|
(s = e.call(this, i) || this).fragOffset = 0,
|
|
s.duration = 0,
|
|
s.gap = !1,
|
|
s.independent = !1,
|
|
s.relurl = void 0,
|
|
s.fragment = void 0,
|
|
s.index = void 0,
|
|
s.duration = t.decimalFloatingPoint("DURATION"),
|
|
s.gap = t.bool("GAP"),
|
|
s.independent = t.bool("INDEPENDENT"),
|
|
s.relurl = t.enumeratedString("URI"),
|
|
s.fragment = r,
|
|
s.index = n;
|
|
var o = t.enumeratedString("BYTERANGE");
|
|
return o && s.setByteRange(o, a),
|
|
a && (s.fragOffset = a.fragOffset + a.duration),
|
|
s
|
|
}
|
|
return o(t, e),
|
|
i(t, [{
|
|
key: "start",
|
|
get: function() {
|
|
return this.fragment.start + this.fragOffset
|
|
}
|
|
}, {
|
|
key: "end",
|
|
get: function() {
|
|
return this.start + this.duration
|
|
}
|
|
}, {
|
|
key: "loaded",
|
|
get: function() {
|
|
var e = this.elementaryStreams;
|
|
return !!(e.audio || e.video || e.audiovideo)
|
|
}
|
|
}])
|
|
}(ee);
|
|
function ne(e, t) {
|
|
var r = Object.getPrototypeOf(e);
|
|
if (r) {
|
|
var i = Object.getOwnPropertyDescriptor(r, t);
|
|
return i || ne(r, t)
|
|
}
|
|
}
|
|
var ae = Math.pow(2, 32) - 1
|
|
, se = [].push
|
|
, oe = {
|
|
video: 1,
|
|
audio: 2,
|
|
id3: 3,
|
|
text: 4
|
|
};
|
|
function le(e) {
|
|
return String.fromCharCode.apply(null, e)
|
|
}
|
|
function ue(e, t) {
|
|
var r = e[t] << 8 | e[t + 1];
|
|
return r < 0 ? 65536 + r : r
|
|
}
|
|
function de(e, t) {
|
|
var r = fe(e, t);
|
|
return r < 0 ? 4294967296 + r : r
|
|
}
|
|
function he(e, t) {
|
|
var r = de(e, t);
|
|
return r *= Math.pow(2, 32),
|
|
r += de(e, t + 4)
|
|
}
|
|
function fe(e, t) {
|
|
return e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3]
|
|
}
|
|
function ce(e, t) {
|
|
var r = [];
|
|
if (!t.length)
|
|
return r;
|
|
for (var i = e.byteLength, n = 0; n < i; ) {
|
|
var a = de(e, n)
|
|
, s = a > 1 ? n + a : i;
|
|
if (le(e.subarray(n + 4, n + 8)) === t[0])
|
|
if (1 === t.length)
|
|
r.push(e.subarray(n + 8, s));
|
|
else {
|
|
var o = ce(e.subarray(n + 8, s), t.slice(1));
|
|
o.length && se.apply(r, o)
|
|
}
|
|
n = s
|
|
}
|
|
return r
|
|
}
|
|
function ge(e) {
|
|
var t = []
|
|
, r = e[0]
|
|
, i = 8
|
|
, n = de(e, i);
|
|
i += 4;
|
|
var a = 0
|
|
, s = 0;
|
|
0 === r ? (a = de(e, i),
|
|
s = de(e, i + 4),
|
|
i += 8) : (a = he(e, i),
|
|
s = he(e, i + 8),
|
|
i += 16),
|
|
i += 2;
|
|
var o = e.length + s
|
|
, l = ue(e, i);
|
|
i += 2;
|
|
for (var u = 0; u < l; u++) {
|
|
var d = i
|
|
, h = de(e, d);
|
|
d += 4;
|
|
var f = 2147483647 & h;
|
|
if (1 == (2147483648 & h) >>> 31)
|
|
return Y.warn("SIDX has hierarchical references (not supported)"),
|
|
null;
|
|
var c = de(e, d);
|
|
d += 4,
|
|
t.push({
|
|
referenceSize: f,
|
|
subsegmentDuration: c,
|
|
info: {
|
|
duration: c / n,
|
|
start: o,
|
|
end: o + f - 1
|
|
}
|
|
}),
|
|
o += f,
|
|
i = d += 4
|
|
}
|
|
return {
|
|
earliestPresentationTime: a,
|
|
timescale: n,
|
|
version: r,
|
|
referencesCount: l,
|
|
references: t
|
|
}
|
|
}
|
|
function ve(e) {
|
|
for (var t = [], r = ce(e, ["moov", "trak"]), i = 0; i < r.length; i++) {
|
|
var n = r[i]
|
|
, a = ce(n, ["tkhd"])[0];
|
|
if (a) {
|
|
var s = a[0]
|
|
, o = de(a, 0 === s ? 12 : 20)
|
|
, l = ce(n, ["mdia", "mdhd"])[0];
|
|
if (l) {
|
|
var u = de(l, 0 === (s = l[0]) ? 12 : 20)
|
|
, h = ce(n, ["mdia", "hdlr"])[0];
|
|
if (h) {
|
|
var f = le(h.subarray(8, 12))
|
|
, c = {
|
|
soun: $,
|
|
vide: Z
|
|
}[f]
|
|
, g = me(ce(n, ["mdia", "minf", "stbl", "stsd"])[0]);
|
|
c ? (t[o] = {
|
|
timescale: u,
|
|
type: c,
|
|
stsd: g
|
|
},
|
|
t[c] = d({
|
|
timescale: u,
|
|
id: o
|
|
}, g)) : t[o] = {
|
|
timescale: u,
|
|
type: f,
|
|
stsd: g
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ce(e, ["moov", "mvex", "trex"]).forEach((function(e) {
|
|
var r = de(e, 4)
|
|
, i = t[r];
|
|
i && (i.default = {
|
|
duration: de(e, 12),
|
|
flags: de(e, 20)
|
|
})
|
|
}
|
|
)),
|
|
t
|
|
}
|
|
function me(e) {
|
|
var t, r = e.subarray(8), i = r.subarray(86), n = le(r.subarray(4, 8)), a = n, s = "enca" === n || "encv" === n;
|
|
if (s) {
|
|
var o = ce(r, [n])[0];
|
|
ce(o.subarray("enca" === n ? 28 : 78), ["sinf"]).forEach((function(e) {
|
|
var t = ce(e, ["schm"])[0];
|
|
if (t) {
|
|
var r = le(t.subarray(4, 8));
|
|
if ("cbcs" === r || "cenc" === r) {
|
|
var i = ce(e, ["frma"])[0];
|
|
i && (a = le(i))
|
|
}
|
|
}
|
|
}
|
|
))
|
|
}
|
|
var l = a;
|
|
switch (a) {
|
|
case "avc1":
|
|
case "avc2":
|
|
case "avc3":
|
|
case "avc4":
|
|
var u = ce(i, ["avcC"])[0];
|
|
u && u.length > 3 && (a += "." + Ee(u[1]) + Ee(u[2]) + Ee(u[3]),
|
|
t = pe("avc1" === l ? "dva1" : "dvav", i));
|
|
break;
|
|
case "mp4a":
|
|
var d = ce(r, [n])[0]
|
|
, h = ce(d.subarray(28), ["esds"])[0];
|
|
if (h && h.length > 7) {
|
|
var f = 4;
|
|
if (3 !== h[f++])
|
|
break;
|
|
f = ye(h, f),
|
|
f += 2;
|
|
var c = h[f++];
|
|
if (128 & c && (f += 2),
|
|
64 & c && (f += h[f++]),
|
|
4 !== h[f++])
|
|
break;
|
|
f = ye(h, f);
|
|
var g = h[f++];
|
|
if (64 !== g)
|
|
break;
|
|
if (a += "." + Ee(g),
|
|
f += 12,
|
|
5 !== h[f++])
|
|
break;
|
|
f = ye(h, f);
|
|
var v = h[f++]
|
|
, m = (248 & v) >> 3;
|
|
31 === m && (m += 1 + ((7 & v) << 3) + ((224 & h[f]) >> 5)),
|
|
a += "." + m
|
|
}
|
|
break;
|
|
case "hvc1":
|
|
case "hev1":
|
|
var p = ce(i, ["hvcC"])[0];
|
|
if (p && p.length > 12) {
|
|
var y = p[1]
|
|
, E = ["", "A", "B", "C"][y >> 6]
|
|
, T = 31 & y
|
|
, S = de(p, 2)
|
|
, A = (32 & y) >> 5 ? "H" : "L"
|
|
, L = p[12]
|
|
, I = p.subarray(6, 12);
|
|
a += "." + E + T,
|
|
a += "." + function(e) {
|
|
for (var t = 0, r = 0; r < 32; r++)
|
|
t |= (e >> r & 1) << 31 - r;
|
|
return t >>> 0
|
|
}(S).toString(16).toUpperCase(),
|
|
a += "." + A + L;
|
|
for (var R = "", k = I.length; k--; ) {
|
|
var b = I[k];
|
|
(b || R) && (R = "." + b.toString(16).toUpperCase() + R)
|
|
}
|
|
a += R
|
|
}
|
|
t = pe("hev1" == l ? "dvhe" : "dvh1", i);
|
|
break;
|
|
case "dvh1":
|
|
case "dvhe":
|
|
case "dvav":
|
|
case "dva1":
|
|
case "dav1":
|
|
a = pe(a, i) || a;
|
|
break;
|
|
case "vp09":
|
|
var D = ce(i, ["vpcC"])[0];
|
|
if (D && D.length > 6) {
|
|
var _ = D[4]
|
|
, P = D[5]
|
|
, C = D[6] >> 4 & 15;
|
|
a += "." + Te(_) + "." + Te(P) + "." + Te(C)
|
|
}
|
|
break;
|
|
case "av01":
|
|
var w = ce(i, ["av1C"])[0];
|
|
if (w && w.length > 2) {
|
|
var O = w[1] >>> 5
|
|
, x = 31 & w[1]
|
|
, M = w[2] >>> 7 ? "H" : "M"
|
|
, F = (64 & w[2]) >> 6
|
|
, N = (32 & w[2]) >> 5
|
|
, U = 2 === O && F ? N ? 12 : 10 : F ? 10 : 8
|
|
, B = (16 & w[2]) >> 4
|
|
, G = (8 & w[2]) >> 3
|
|
, K = (4 & w[2]) >> 2
|
|
, V = 3 & w[2];
|
|
a += "." + O + "." + Te(x) + M + "." + Te(U) + "." + B + "." + G + K + V + "." + Te(1) + "." + Te(1) + "." + Te(1) + ".0",
|
|
t = pe("dav1", i)
|
|
}
|
|
}
|
|
return {
|
|
codec: a,
|
|
encrypted: s,
|
|
supplemental: t
|
|
}
|
|
}
|
|
function pe(e, t) {
|
|
var r = ce(t, ["dvvC"])
|
|
, i = r.length ? r[0] : ce(t, ["dvcC"])[0];
|
|
if (i) {
|
|
var n = i[2] >> 1 & 127
|
|
, a = i[2] << 5 & 32 | i[3] >> 3 & 31;
|
|
return e + "." + Te(n) + "." + Te(a)
|
|
}
|
|
}
|
|
function ye(e, t) {
|
|
for (var r = t + 5; 128 & e[t++] && t < r; )
|
|
;
|
|
return t
|
|
}
|
|
function Ee(e) {
|
|
return ("0" + e.toString(16).toUpperCase()).slice(-2)
|
|
}
|
|
function Te(e) {
|
|
return (e < 10 ? "0" : "") + e
|
|
}
|
|
function Se(e) {
|
|
var t = ce(e, ["schm"])[0];
|
|
if (t) {
|
|
var r = le(t.subarray(4, 8));
|
|
if ("cbcs" === r || "cenc" === r)
|
|
return ce(e, ["schi", "tenc"])[0]
|
|
}
|
|
return null
|
|
}
|
|
function Ae(e, t) {
|
|
var r = new Uint8Array(e.length + t.length);
|
|
return r.set(e),
|
|
r.set(t, e.length),
|
|
r
|
|
}
|
|
function Le(e, t) {
|
|
var r = []
|
|
, i = t.samples
|
|
, n = t.timescale
|
|
, a = t.id
|
|
, s = !1;
|
|
return ce(i, ["moof"]).map((function(o) {
|
|
var l = o.byteOffset - 8;
|
|
ce(o, ["traf"]).map((function(o) {
|
|
var u = ce(o, ["tfdt"]).map((function(e) {
|
|
var t = e[0]
|
|
, r = de(e, 4);
|
|
return 1 === t && (r *= Math.pow(2, 32),
|
|
r += de(e, 8)),
|
|
r / n
|
|
}
|
|
))[0];
|
|
return void 0 !== u && (e = u),
|
|
ce(o, ["tfhd"]).map((function(u) {
|
|
var d = de(u, 4)
|
|
, h = 16777215 & de(u, 0)
|
|
, f = 0
|
|
, c = 0 != (16 & h)
|
|
, g = 0
|
|
, v = 0 != (32 & h)
|
|
, m = 8;
|
|
d === a && (0 != (1 & h) && (m += 8),
|
|
0 != (2 & h) && (m += 4),
|
|
0 != (8 & h) && (f = de(u, m),
|
|
m += 4),
|
|
c && (g = de(u, m),
|
|
m += 4),
|
|
v && (m += 4),
|
|
"video" === t.type && (s = Ie(t.codec)),
|
|
ce(o, ["trun"]).map((function(a) {
|
|
var o = a[0]
|
|
, u = 16777215 & de(a, 0)
|
|
, d = 0 != (1 & u)
|
|
, h = 0
|
|
, c = 0 != (4 & u)
|
|
, v = 0 != (256 & u)
|
|
, m = 0
|
|
, p = 0 != (512 & u)
|
|
, y = 0
|
|
, E = 0 != (1024 & u)
|
|
, T = 0 != (2048 & u)
|
|
, S = 0
|
|
, A = de(a, 4)
|
|
, L = 8;
|
|
d && (h = de(a, L),
|
|
L += 4),
|
|
c && (L += 4);
|
|
for (var I = h + l, R = 0; R < A; R++) {
|
|
if (v ? (m = de(a, L),
|
|
L += 4) : m = f,
|
|
p ? (y = de(a, L),
|
|
L += 4) : y = g,
|
|
E && (L += 4),
|
|
T && (S = 0 === o ? de(a, L) : fe(a, L),
|
|
L += 4),
|
|
t.type === Z)
|
|
for (var k = 0; k < y; ) {
|
|
var b = de(i, I);
|
|
Re(s, i[I += 4]) && ke(i.subarray(I, I + b), s ? 2 : 1, e + S / n, r),
|
|
I += b,
|
|
k += b + 4
|
|
}
|
|
e += m / n
|
|
}
|
|
}
|
|
)))
|
|
}
|
|
))
|
|
}
|
|
))
|
|
}
|
|
)),
|
|
r
|
|
}
|
|
function Ie(e) {
|
|
if (!e)
|
|
return !1;
|
|
var t = e.substring(0, 4);
|
|
return "hvc1" === t || "hev1" === t || "dvh1" === t || "dvhe" === t
|
|
}
|
|
function Re(e, t) {
|
|
if (e) {
|
|
var r = t >> 1 & 63;
|
|
return 39 === r || 40 === r
|
|
}
|
|
return 6 == (31 & t)
|
|
}
|
|
function ke(e, t, r, i) {
|
|
var n = be(e)
|
|
, a = 0;
|
|
a += t;
|
|
for (var s = 0, o = 0, l = 0; a < n.length; ) {
|
|
s = 0;
|
|
do {
|
|
if (a >= n.length)
|
|
break;
|
|
s += l = n[a++]
|
|
} while (255 === l);
|
|
o = 0;
|
|
do {
|
|
if (a >= n.length)
|
|
break;
|
|
o += l = n[a++]
|
|
} while (255 === l);
|
|
var u = n.length - a
|
|
, d = a;
|
|
if (o < u)
|
|
a += o;
|
|
else if (o > u) {
|
|
Y.error("Malformed SEI payload. " + o + " is too small, only " + u + " bytes left to parse.");
|
|
break
|
|
}
|
|
if (4 === s) {
|
|
if (181 === n[d++]) {
|
|
var h = ue(n, d);
|
|
if (d += 2,
|
|
49 === h) {
|
|
var f = de(n, d);
|
|
if (d += 4,
|
|
1195456820 === f) {
|
|
var c = n[d++];
|
|
if (3 === c) {
|
|
var g = n[d++]
|
|
, v = 64 & g
|
|
, m = v ? 2 + 3 * (31 & g) : 0
|
|
, p = new Uint8Array(m);
|
|
if (v) {
|
|
p[0] = g;
|
|
for (var y = 1; y < m; y++)
|
|
p[y] = n[d++]
|
|
}
|
|
i.push({
|
|
type: c,
|
|
payloadType: s,
|
|
pts: r,
|
|
bytes: p
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if (5 === s && o > 16) {
|
|
for (var E = [], T = 0; T < 16; T++) {
|
|
var S = n[d++].toString(16);
|
|
E.push(1 == S.length ? "0" + S : S),
|
|
3 !== T && 5 !== T && 7 !== T && 9 !== T || E.push("-")
|
|
}
|
|
for (var A = o - 16, L = new Uint8Array(A), I = 0; I < A; I++)
|
|
L[I] = n[d++];
|
|
i.push({
|
|
payloadType: s,
|
|
pts: r,
|
|
uuid: E.join(""),
|
|
userData: q(L),
|
|
userDataBytes: L
|
|
})
|
|
}
|
|
}
|
|
}
|
|
function be(e) {
|
|
for (var t = e.byteLength, r = [], i = 1; i < t - 2; )
|
|
0 === e[i] && 0 === e[i + 1] && 3 === e[i + 2] ? (r.push(i + 2),
|
|
i += 2) : i++;
|
|
if (0 === r.length)
|
|
return e;
|
|
var n = t - r.length
|
|
, a = new Uint8Array(n)
|
|
, s = 0;
|
|
for (i = 0; i < n; s++,
|
|
i++)
|
|
s === r[0] && (s++,
|
|
r.shift()),
|
|
a[i] = e[s];
|
|
return a
|
|
}
|
|
function De(e, t, r) {
|
|
if (16 !== e.byteLength)
|
|
throw new RangeError("Invalid system id");
|
|
var i, n;
|
|
i = new Uint8Array,
|
|
n = new Uint8Array;
|
|
var a = new Uint8Array(4);
|
|
return r.byteLength > 0 && new DataView(a.buffer).setUint32(0, r.byteLength, !1),
|
|
function(e) {
|
|
for (var t = arguments.length, r = new Array(t > 1 ? t - 1 : 0), i = 1; i < t; i++)
|
|
r[i - 1] = arguments[i];
|
|
for (var n = r.length, a = 8, s = n; s--; )
|
|
a += r[s].byteLength;
|
|
var o = new Uint8Array(a);
|
|
for (o[0] = a >> 24 & 255,
|
|
o[1] = a >> 16 & 255,
|
|
o[2] = a >> 8 & 255,
|
|
o[3] = 255 & a,
|
|
o.set(e, 4),
|
|
s = 0,
|
|
a = 8; s < n; s++)
|
|
o.set(r[s], a),
|
|
a += r[s].byteLength;
|
|
return o
|
|
}([112, 115, 115, 104], new Uint8Array([0, 0, 0, 0]), e, n, i, a, r)
|
|
}
|
|
function _e(e) {
|
|
var t = e.getUint32(0)
|
|
, r = e.byteOffset
|
|
, i = e.byteLength;
|
|
if (i < t)
|
|
return {
|
|
offset: r,
|
|
size: i
|
|
};
|
|
if (1886614376 !== e.getUint32(4))
|
|
return {
|
|
offset: r,
|
|
size: t
|
|
};
|
|
var n = e.getUint32(8) >>> 24;
|
|
if (0 !== n && 1 !== n)
|
|
return {
|
|
offset: r,
|
|
size: t
|
|
};
|
|
var a = e.buffer
|
|
, s = X(new Uint8Array(a,r + 12,16))
|
|
, o = null
|
|
, l = 0;
|
|
if (0 === n)
|
|
l = 28;
|
|
else {
|
|
var u = e.getUint32(28);
|
|
if (!u || i < 32 + 16 * u)
|
|
return {
|
|
offset: r,
|
|
size: t
|
|
};
|
|
o = [];
|
|
for (var d = 0; d < u; d++)
|
|
o.push(new Uint8Array(a,r + 32 + 16 * d,16));
|
|
l = 32 + 16 * u
|
|
}
|
|
if (!l)
|
|
return {
|
|
offset: r,
|
|
size: t
|
|
};
|
|
var h = e.getUint32(l);
|
|
return t - 32 < h ? {
|
|
offset: r,
|
|
size: t
|
|
} : {
|
|
version: n,
|
|
systemId: s,
|
|
kids: o,
|
|
data: new Uint8Array(a,r + l + 4,h),
|
|
offset: r,
|
|
size: t
|
|
}
|
|
}
|
|
var Pe = function() {
|
|
return /\(Windows.+Firefox\//i.test(navigator.userAgent)
|
|
}
|
|
, Ce = {
|
|
audio: {
|
|
a3ds: 1,
|
|
"ac-3": .95,
|
|
"ac-4": 1,
|
|
alac: .9,
|
|
alaw: 1,
|
|
dra1: 1,
|
|
"dts+": 1,
|
|
"dts-": 1,
|
|
dtsc: 1,
|
|
dtse: 1,
|
|
dtsh: 1,
|
|
"ec-3": .9,
|
|
enca: 1,
|
|
fLaC: .9,
|
|
flac: .9,
|
|
FLAC: .9,
|
|
g719: 1,
|
|
g726: 1,
|
|
m4ae: 1,
|
|
mha1: 1,
|
|
mha2: 1,
|
|
mhm1: 1,
|
|
mhm2: 1,
|
|
mlpa: 1,
|
|
mp4a: 1,
|
|
"raw ": 1,
|
|
Opus: 1,
|
|
opus: 1,
|
|
samr: 1,
|
|
sawb: 1,
|
|
sawp: 1,
|
|
sevc: 1,
|
|
sqcp: 1,
|
|
ssmv: 1,
|
|
twos: 1,
|
|
ulaw: 1
|
|
},
|
|
video: {
|
|
avc1: 1,
|
|
avc2: 1,
|
|
avc3: 1,
|
|
avc4: 1,
|
|
avcp: 1,
|
|
av01: .8,
|
|
dav1: .8,
|
|
drac: 1,
|
|
dva1: 1,
|
|
dvav: 1,
|
|
dvh1: .7,
|
|
dvhe: .7,
|
|
encv: 1,
|
|
hev1: .75,
|
|
hvc1: .75,
|
|
mjp2: 1,
|
|
mp4v: 1,
|
|
mvc1: 1,
|
|
mvc2: 1,
|
|
mvc3: 1,
|
|
mvc4: 1,
|
|
resv: 1,
|
|
rv60: 1,
|
|
s263: 1,
|
|
svc1: 1,
|
|
svc2: 1,
|
|
"vc-1": 1,
|
|
vp08: 1,
|
|
vp09: .9
|
|
},
|
|
text: {
|
|
stpp: 1,
|
|
wvtt: 1
|
|
}
|
|
};
|
|
function we(e, t) {
|
|
var r = Ce[t];
|
|
return !!r && !!r[e.slice(0, 4)]
|
|
}
|
|
function Oe(e, t, r) {
|
|
return void 0 === r && (r = !0),
|
|
!e.split(",").some((function(e) {
|
|
return !xe(e, t, r)
|
|
}
|
|
))
|
|
}
|
|
function xe(e, t, r) {
|
|
var i;
|
|
void 0 === r && (r = !0);
|
|
var n = W(r);
|
|
return null != (i = null == n ? void 0 : n.isTypeSupported(Me(e, t))) && i
|
|
}
|
|
function Me(e, t) {
|
|
return t + "/mp4;codecs=" + e
|
|
}
|
|
function Fe(e) {
|
|
if (e) {
|
|
var t = e.substring(0, 4);
|
|
return Ce.video[t]
|
|
}
|
|
return 2
|
|
}
|
|
function Ne(e) {
|
|
var t = Pe();
|
|
return e.split(",").reduce((function(e, r) {
|
|
var i = t && Ie(r) ? 9 : Ce.video[r];
|
|
return i ? (2 * i + e) / (e ? 3 : 2) : (Ce.audio[r] + e) / (e ? 2 : 1)
|
|
}
|
|
), 0)
|
|
}
|
|
var Ue = {}
|
|
, Be = /flac|opus|mp4a\.40\.34/i;
|
|
function Ge(e, t) {
|
|
return void 0 === t && (t = !0),
|
|
e.replace(Be, (function(e) {
|
|
return function(e, t) {
|
|
if (void 0 === t && (t = !0),
|
|
Ue[e])
|
|
return Ue[e];
|
|
for (var r = {
|
|
flac: ["flac", "fLaC", "FLAC"],
|
|
opus: ["opus", "Opus"],
|
|
"mp4a.40.34": ["mp3"]
|
|
}[e], i = 0; i < r.length; i++) {
|
|
var n;
|
|
if (xe(r[i], "audio", t))
|
|
return Ue[e] = r[i],
|
|
r[i];
|
|
if ("mp3" === r[i] && null != (n = W(t)) && n.isTypeSupported("audio/mpeg"))
|
|
return ""
|
|
}
|
|
return e
|
|
}(e.toLowerCase(), t)
|
|
}
|
|
))
|
|
}
|
|
function Ke(e, t) {
|
|
if (e && (e.length > 4 || -1 !== ["ac-3", "ec-3", "alac", "fLaC", "Opus"].indexOf(e)) && (Ve(e, "audio") || Ve(e, "video")))
|
|
return e;
|
|
if (t) {
|
|
var r = t.split(",");
|
|
if (r.length > 1) {
|
|
if (e)
|
|
for (var i = r.length; i--; )
|
|
if (r[i].substring(0, 4) === e.substring(0, 4))
|
|
return r[i];
|
|
return r[0]
|
|
}
|
|
}
|
|
return t || e
|
|
}
|
|
function Ve(e, t) {
|
|
return we(e, t) && xe(e, t)
|
|
}
|
|
function He(e) {
|
|
if (e.startsWith("av01.")) {
|
|
for (var t = e.split("."), r = ["0", "111", "01", "01", "01", "0"], i = t.length; i > 4 && i < 10; i++)
|
|
t[i] = r[i - 4];
|
|
return t.join(".")
|
|
}
|
|
return e
|
|
}
|
|
function Ye(e) {
|
|
var t = W(e) || {
|
|
isTypeSupported: function() {
|
|
return !1
|
|
}
|
|
};
|
|
return {
|
|
mpeg: t.isTypeSupported("audio/mpeg"),
|
|
mp3: t.isTypeSupported('audio/mp4; codecs="mp3"'),
|
|
ac3: t.isTypeSupported('audio/mp4; codecs="ac-3"')
|
|
}
|
|
}
|
|
function We(e) {
|
|
return e.replace(/^.+codecs=["']?([^"']+).*$/, "$1")
|
|
}
|
|
var je = {
|
|
supported: !1,
|
|
smooth: !1,
|
|
powerEfficient: !1
|
|
}
|
|
, qe = {
|
|
supported: !0,
|
|
configurations: [],
|
|
decodingInfoResults: [{
|
|
supported: !0,
|
|
powerEfficient: !0,
|
|
smooth: !0
|
|
}]
|
|
};
|
|
function Xe(e, t) {
|
|
return {
|
|
supported: !1,
|
|
configurations: t,
|
|
decodingInfoResults: [je],
|
|
error: e
|
|
}
|
|
}
|
|
function Qe(e, t, r, i) {
|
|
void 0 === i && (i = {});
|
|
var n = e.videoCodec;
|
|
if (!n && !e.audioCodec || !r)
|
|
return Promise.resolve(qe);
|
|
for (var a = [], s = function(e) {
|
|
var t, r = null == (t = e.videoCodec) ? void 0 : t.split(","), i = $e(e), n = e.width || 640, a = e.height || 480, s = e.frameRate || 30, o = e.videoRange.toLowerCase();
|
|
return r ? r.map((function(e) {
|
|
var t = {
|
|
contentType: Me(He(e), "video"),
|
|
width: n,
|
|
height: a,
|
|
bitrate: i,
|
|
framerate: s
|
|
};
|
|
return "sdr" !== o && (t.transferFunction = o),
|
|
t
|
|
}
|
|
)) : []
|
|
}(e), o = s.length, l = function(e, t, r) {
|
|
var i, n = null == (i = e.audioCodec) ? void 0 : i.split(","), a = $e(e);
|
|
return n && e.audioGroups ? e.audioGroups.reduce((function(e, i) {
|
|
var s, o = i ? null == (s = t.groups[i]) ? void 0 : s.tracks : null;
|
|
return o ? o.reduce((function(e, t) {
|
|
if (t.groupId === i) {
|
|
var s = parseFloat(t.channels || "");
|
|
n.forEach((function(t) {
|
|
var i = {
|
|
contentType: Me(t, "audio"),
|
|
bitrate: r ? ze(t, a) : a
|
|
};
|
|
s && (i.channels = "" + s),
|
|
e.push(i)
|
|
}
|
|
))
|
|
}
|
|
return e
|
|
}
|
|
), e) : e
|
|
}
|
|
), []) : []
|
|
}(e, t, o > 0), u = l.length, d = o || 1 * u || 1; d--; ) {
|
|
var h = {
|
|
type: "media-source"
|
|
};
|
|
if (o && (h.video = s[d % o]),
|
|
u) {
|
|
h.audio = l[d % u];
|
|
var f = h.audio.bitrate;
|
|
h.video && f && (h.video.bitrate -= f)
|
|
}
|
|
a.push(h)
|
|
}
|
|
if (n) {
|
|
var c = navigator.userAgent;
|
|
if (n.split(",").some((function(e) {
|
|
return Ie(e)
|
|
}
|
|
)) && Pe())
|
|
return Promise.resolve(Xe(new Error("Overriding Windows Firefox HEVC MediaCapabilities result based on user-agent string: (" + c + ")"), a))
|
|
}
|
|
return Promise.all(a.map((function(e) {
|
|
var t, n, a, s, o = (n = "",
|
|
a = (t = e).audio,
|
|
(s = t.video) && (n += We(s.contentType) + "_r" + s.height + "x" + s.width + "f" + Math.ceil(s.framerate) + (s.transferFunction || "sd") + "_" + Math.ceil(s.bitrate / 1e5)),
|
|
a && (n += (s ? "_" : "") + We(a.contentType) + "_c" + a.channels),
|
|
n);
|
|
return i[o] || (i[o] = r.decodingInfo(e))
|
|
}
|
|
))).then((function(e) {
|
|
return {
|
|
supported: !e.some((function(e) {
|
|
return !e.supported
|
|
}
|
|
)),
|
|
configurations: a,
|
|
decodingInfoResults: e
|
|
}
|
|
}
|
|
)).catch((function(e) {
|
|
return {
|
|
supported: !1,
|
|
configurations: a,
|
|
decodingInfoResults: [],
|
|
error: e
|
|
}
|
|
}
|
|
))
|
|
}
|
|
function ze(e, t) {
|
|
if (t <= 1)
|
|
return 1;
|
|
var r = 128e3;
|
|
return "ec-3" === e ? r = 768e3 : "ac-3" === e && (r = 64e4),
|
|
Math.min(t / 2, r)
|
|
}
|
|
function $e(e) {
|
|
return 1e3 * Math.ceil(Math.max(.9 * e.bitrate, e.averageBitrate) / 1e3) || 1
|
|
}
|
|
var Ze = ["NONE", "TYPE-0", "TYPE-1", null]
|
|
, Je = ["SDR", "PQ", "HLG"]
|
|
, et = ""
|
|
, tt = "YES"
|
|
, rt = "v2";
|
|
function it(e) {
|
|
var t = e.canSkipUntil
|
|
, r = e.canSkipDateRanges
|
|
, i = e.age;
|
|
return t && i < t / 2 ? r ? rt : tt : et
|
|
}
|
|
var nt = function() {
|
|
function e(e, t, r) {
|
|
this.msn = void 0,
|
|
this.part = void 0,
|
|
this.skip = void 0,
|
|
this.msn = e,
|
|
this.part = t,
|
|
this.skip = r
|
|
}
|
|
return e.prototype.addDirectives = function(e) {
|
|
var t = new self.URL(e);
|
|
return void 0 !== this.msn && t.searchParams.set("_HLS_msn", this.msn.toString()),
|
|
void 0 !== this.part && t.searchParams.set("_HLS_part", this.part.toString()),
|
|
this.skip && t.searchParams.set("_HLS_skip", this.skip),
|
|
t.href
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, at = function() {
|
|
function e(e) {
|
|
if (this._attrs = void 0,
|
|
this.audioCodec = void 0,
|
|
this.bitrate = void 0,
|
|
this.codecSet = void 0,
|
|
this.url = void 0,
|
|
this.frameRate = void 0,
|
|
this.height = void 0,
|
|
this.id = void 0,
|
|
this.name = void 0,
|
|
this.supplemental = void 0,
|
|
this.videoCodec = void 0,
|
|
this.width = void 0,
|
|
this.details = void 0,
|
|
this.fragmentError = 0,
|
|
this.loadError = 0,
|
|
this.loaded = void 0,
|
|
this.realBitrate = 0,
|
|
this.supportedPromise = void 0,
|
|
this.supportedResult = void 0,
|
|
this._avgBitrate = 0,
|
|
this._audioGroups = void 0,
|
|
this._subtitleGroups = void 0,
|
|
this._urlId = 0,
|
|
this.url = [e.url],
|
|
this._attrs = [e.attrs],
|
|
this.bitrate = e.bitrate,
|
|
e.details && (this.details = e.details),
|
|
this.id = e.id || 0,
|
|
this.name = e.name,
|
|
this.width = e.width || 0,
|
|
this.height = e.height || 0,
|
|
this.frameRate = e.attrs.optionalFloat("FRAME-RATE", 0),
|
|
this._avgBitrate = e.attrs.decimalInteger("AVERAGE-BANDWIDTH"),
|
|
this.audioCodec = e.audioCodec,
|
|
this.videoCodec = e.videoCodec,
|
|
this.codecSet = [e.videoCodec, e.audioCodec].filter((function(e) {
|
|
return !!e
|
|
}
|
|
)).map((function(e) {
|
|
return e.substring(0, 4)
|
|
}
|
|
)).join(","),
|
|
"supplemental"in e) {
|
|
var t;
|
|
this.supplemental = e.supplemental;
|
|
var r = null == (t = e.supplemental) ? void 0 : t.videoCodec;
|
|
r && r !== e.videoCodec && (this.codecSet += "," + r.substring(0, 4))
|
|
}
|
|
this.addGroupId("audio", e.attrs.AUDIO),
|
|
this.addGroupId("text", e.attrs.SUBTITLES)
|
|
}
|
|
var t = e.prototype;
|
|
return t.hasAudioGroup = function(e) {
|
|
return st(this._audioGroups, e)
|
|
}
|
|
,
|
|
t.hasSubtitleGroup = function(e) {
|
|
return st(this._subtitleGroups, e)
|
|
}
|
|
,
|
|
t.addGroupId = function(e, t) {
|
|
if (t)
|
|
if ("audio" === e) {
|
|
var r = this._audioGroups;
|
|
r || (r = this._audioGroups = []),
|
|
-1 === r.indexOf(t) && r.push(t)
|
|
} else if ("text" === e) {
|
|
var i = this._subtitleGroups;
|
|
i || (i = this._subtitleGroups = []),
|
|
-1 === i.indexOf(t) && i.push(t)
|
|
}
|
|
}
|
|
,
|
|
t.addFallback = function() {}
|
|
,
|
|
i(e, [{
|
|
key: "maxBitrate",
|
|
get: function() {
|
|
return Math.max(this.realBitrate, this.bitrate)
|
|
}
|
|
}, {
|
|
key: "averageBitrate",
|
|
get: function() {
|
|
return this._avgBitrate || this.realBitrate || this.bitrate
|
|
}
|
|
}, {
|
|
key: "attrs",
|
|
get: function() {
|
|
return this._attrs[0]
|
|
}
|
|
}, {
|
|
key: "codecs",
|
|
get: function() {
|
|
return this.attrs.CODECS || ""
|
|
}
|
|
}, {
|
|
key: "pathwayId",
|
|
get: function() {
|
|
return this.attrs["PATHWAY-ID"] || "."
|
|
}
|
|
}, {
|
|
key: "videoRange",
|
|
get: function() {
|
|
return this.attrs["VIDEO-RANGE"] || "SDR"
|
|
}
|
|
}, {
|
|
key: "score",
|
|
get: function() {
|
|
return this.attrs.optionalFloat("SCORE", 0)
|
|
}
|
|
}, {
|
|
key: "uri",
|
|
get: function() {
|
|
return this.url[0] || ""
|
|
}
|
|
}, {
|
|
key: "audioGroups",
|
|
get: function() {
|
|
return this._audioGroups
|
|
}
|
|
}, {
|
|
key: "subtitleGroups",
|
|
get: function() {
|
|
return this._subtitleGroups
|
|
}
|
|
}, {
|
|
key: "urlId",
|
|
get: function() {
|
|
return 0
|
|
},
|
|
set: function(e) {}
|
|
}, {
|
|
key: "audioGroupIds",
|
|
get: function() {
|
|
return this.audioGroups ? [this.audioGroupId] : void 0
|
|
}
|
|
}, {
|
|
key: "textGroupIds",
|
|
get: function() {
|
|
return this.subtitleGroups ? [this.textGroupId] : void 0
|
|
}
|
|
}, {
|
|
key: "audioGroupId",
|
|
get: function() {
|
|
var e;
|
|
return null == (e = this.audioGroups) ? void 0 : e[0]
|
|
}
|
|
}, {
|
|
key: "textGroupId",
|
|
get: function() {
|
|
var e;
|
|
return null == (e = this.subtitleGroups) ? void 0 : e[0]
|
|
}
|
|
}])
|
|
}();
|
|
function st(e, t) {
|
|
return !(!t || !e) && -1 !== e.indexOf(t)
|
|
}
|
|
function ot(e, t) {
|
|
var r = !1
|
|
, i = [];
|
|
if (e && (r = "SDR" !== e,
|
|
i = [e]),
|
|
t) {
|
|
var n = "SDR" !== (i = t.allowedVideoRanges || Je.slice(0)).join("") && !t.videoCodec;
|
|
(r = void 0 !== t.preferHDR ? t.preferHDR : n && function() {
|
|
if ("function" == typeof matchMedia) {
|
|
var e = matchMedia("(dynamic-range: high)")
|
|
, t = matchMedia("bad query");
|
|
if (e.media !== t.media)
|
|
return !0 === e.matches
|
|
}
|
|
return !1
|
|
}()) || (i = ["SDR"])
|
|
}
|
|
return {
|
|
preferHDR: r,
|
|
allowedVideoRanges: i
|
|
}
|
|
}
|
|
var lt = function(e, t) {
|
|
return JSON.stringify(e, function(e) {
|
|
var t = new WeakSet;
|
|
return function(r, i) {
|
|
if (e && (i = e(r, i)),
|
|
"object" == typeof i && null !== i) {
|
|
if (t.has(i))
|
|
return;
|
|
t.add(i)
|
|
}
|
|
return i
|
|
}
|
|
}(t))
|
|
};
|
|
function ut(e, t) {
|
|
Y.log('[abr] start candidates with "' + e + '" ignored because ' + t)
|
|
}
|
|
function dt(e) {
|
|
return e.reduce((function(e, t) {
|
|
var r = e.groups[t.groupId];
|
|
r || (r = e.groups[t.groupId] = {
|
|
tracks: [],
|
|
channels: {
|
|
2: 0
|
|
},
|
|
hasDefault: !1,
|
|
hasAutoSelect: !1
|
|
}),
|
|
r.tracks.push(t);
|
|
var i = t.channels || "2";
|
|
return r.channels[i] = (r.channels[i] || 0) + 1,
|
|
r.hasDefault = r.hasDefault || t.default,
|
|
r.hasAutoSelect = r.hasAutoSelect || t.autoselect,
|
|
r.hasDefault && (e.hasDefaultAudio = !0),
|
|
r.hasAutoSelect && (e.hasAutoSelectAudio = !0),
|
|
e
|
|
}
|
|
), {
|
|
hasDefaultAudio: !1,
|
|
hasAutoSelectAudio: !1,
|
|
groups: {}
|
|
})
|
|
}
|
|
function ht(e) {
|
|
if (!e)
|
|
return e;
|
|
var t = e;
|
|
return {
|
|
lang: t.lang,
|
|
assocLang: t.assocLang,
|
|
characteristics: t.characteristics,
|
|
channels: t.channels,
|
|
audioCodec: t.audioCodec
|
|
}
|
|
}
|
|
function ft(e, t, r) {
|
|
if ("attrs"in e) {
|
|
var i = t.indexOf(e);
|
|
if (-1 !== i)
|
|
return i
|
|
}
|
|
for (var n = 0; n < t.length; n++)
|
|
if (ct(e, t[n], r))
|
|
return n;
|
|
return -1
|
|
}
|
|
function ct(e, t, r) {
|
|
var i, n, a = e.groupId, s = e.name, o = e.lang, l = e.assocLang, u = e.default, d = e.forced;
|
|
return (void 0 === a || t.groupId === a) && (void 0 === s || t.name === s) && (void 0 === o || (i = o,
|
|
void 0 === (n = t.lang) && (n = "--"),
|
|
i.length === n.length ? i === n : i.startsWith(n) || n.startsWith(i))) && (void 0 === o || t.assocLang === l) && (void 0 === u || t.default === u) && (void 0 === d || t.forced === d) && (!("characteristics"in e) || function(e, t) {
|
|
void 0 === t && (t = "");
|
|
var r = e.split(",")
|
|
, i = t.split(",");
|
|
return r.length === i.length && !r.some((function(e) {
|
|
return -1 === i.indexOf(e)
|
|
}
|
|
))
|
|
}(e.characteristics || "", t.characteristics)) && (void 0 === r || r(e, t))
|
|
}
|
|
function gt(e, t) {
|
|
var r = e.audioCodec
|
|
, i = e.channels;
|
|
return !(void 0 !== r && (t.audioCodec || "").substring(0, 4) !== r.substring(0, 4) || void 0 !== i && i !== (t.channels || "2"))
|
|
}
|
|
function vt(e, t, r) {
|
|
for (var i = t; i > -1; i--)
|
|
if (r(e[i]))
|
|
return i;
|
|
for (var n = t + 1; n < e.length; n++)
|
|
if (r(e[n]))
|
|
return n;
|
|
return -1
|
|
}
|
|
function mt(e, t) {
|
|
var r;
|
|
return !!e && e !== (null == (r = t.loadLevelObj) ? void 0 : r.uri)
|
|
}
|
|
var pt = function(e) {
|
|
function t(t) {
|
|
var r;
|
|
return (r = e.call(this, "abr", t.logger) || this).hls = void 0,
|
|
r.lastLevelLoadSec = 0,
|
|
r.lastLoadedFragLevel = -1,
|
|
r.firstSelection = -1,
|
|
r._nextAutoLevel = -1,
|
|
r.nextAutoLevelKey = "",
|
|
r.audioTracksByGroup = null,
|
|
r.codecTiers = null,
|
|
r.timer = -1,
|
|
r.fragCurrent = null,
|
|
r.partCurrent = null,
|
|
r.bitrateTestDelay = 0,
|
|
r.rebufferNotice = -1,
|
|
r.supportedCache = {},
|
|
r.bwEstimator = void 0,
|
|
r._abandonRulesCheck = function(e) {
|
|
var t, i = r, n = i.fragCurrent, a = i.partCurrent, s = i.hls, o = s.autoLevelEnabled, l = s.media;
|
|
if (n && l) {
|
|
var u = performance.now()
|
|
, d = a ? a.stats : n.stats
|
|
, h = a ? a.duration : n.duration
|
|
, f = u - d.loading.start
|
|
, c = s.minAutoLevel
|
|
, g = n.level
|
|
, v = r._nextAutoLevel;
|
|
if (d.aborted || d.loaded && d.loaded === d.total || g <= c)
|
|
return r.clearTimer(),
|
|
void (r._nextAutoLevel = -1);
|
|
if (o) {
|
|
var m = v > -1 && v !== g
|
|
, p = !!e || m;
|
|
if (p || !l.paused && l.playbackRate && l.readyState) {
|
|
var y = s.mainForwardBufferInfo;
|
|
if (p || null !== y) {
|
|
var E = r.bwEstimator.getEstimateTTFB()
|
|
, T = Math.abs(l.playbackRate);
|
|
if (!(f <= Math.max(E, h / (2 * T) * 1e3))) {
|
|
var S = y ? y.len / T : 0
|
|
, L = d.loading.first ? d.loading.first - d.loading.start : -1
|
|
, I = d.loaded && L > -1
|
|
, R = r.getBwEstimate()
|
|
, k = s.levels
|
|
, D = k[g]
|
|
, _ = Math.max(d.loaded, Math.round(h * (n.bitrate || D.averageBitrate) / 8))
|
|
, P = I ? f - L : f;
|
|
P < 1 && I && (P = Math.min(f, 8 * d.loaded / R));
|
|
var C = I ? 1e3 * d.loaded / P : 0
|
|
, w = E / 1e3
|
|
, O = C ? (_ - d.loaded) / C : 8 * _ / R + w;
|
|
if (!(O <= S)) {
|
|
var x, M = C ? 8 * C : R, F = !0 === (null == (t = (null == e ? void 0 : e.details) || r.hls.latestLevelDetails) ? void 0 : t.live), N = r.hls.config.abrBandWidthUpFactor, U = Number.POSITIVE_INFINITY;
|
|
for (x = g - 1; x > c; x--) {
|
|
var B = k[x].maxBitrate
|
|
, G = !k[x].details || F;
|
|
if ((U = r.getTimeToLoadFrag(w, M, h * B, G)) < Math.min(S, h + w))
|
|
break
|
|
}
|
|
if (!(U >= O || U > 10 * h)) {
|
|
I ? r.bwEstimator.sample(f - Math.min(E, L), d.loaded) : r.bwEstimator.sampleTTFB(f);
|
|
var K = k[x].maxBitrate;
|
|
r.getBwEstimate() * N > K && r.resetEstimator(K);
|
|
var V = r.findBestLevel(K, c, x, 0, S, 1, 1);
|
|
V > -1 && (x = V),
|
|
r.warn("Fragment " + n.sn + (a ? " part " + a.index : "") + " of level " + g + " is loading too slowly;\n Fragment duration: " + n.duration.toFixed(3) + "\n Time to underbuffer: " + S.toFixed(3) + " s\n Estimated load time for current fragment: " + O.toFixed(3) + " s\n Estimated load time for down switch fragment: " + U.toFixed(3) + " s\n TTFB estimate: " + (0 | L) + " ms\n Current BW estimate: " + (A(R) ? 0 | R : "Unknown") + " bps\n New BW estimate: " + (0 | r.getBwEstimate()) + " bps\n Switching to level " + x + " @ " + (0 | K) + " bps"),
|
|
s.nextLoadLevel = s.nextAutoLevel = x,
|
|
r.clearTimer();
|
|
var H = function() {
|
|
if (r.clearTimer(),
|
|
r.fragCurrent === n && r.hls.loadLevel === x && x > 0) {
|
|
var e = r.getStarvationDelay();
|
|
if (r.warn("Aborting inflight request " + (x > 0 ? "and switching down" : "") + "\n Fragment duration: " + n.duration.toFixed(3) + " s\n Time to underbuffer: " + e.toFixed(3) + " s"),
|
|
n.abortRequests(),
|
|
r.fragCurrent = r.partCurrent = null,
|
|
x > c) {
|
|
var t = r.findBestLevel(r.hls.levels[c].bitrate, c, x, 0, e, 1, 1);
|
|
-1 === t && (t = c),
|
|
r.hls.nextLoadLevel = r.hls.nextAutoLevel = t,
|
|
r.resetEstimator(r.hls.levels[t].bitrate)
|
|
}
|
|
}
|
|
};
|
|
m || O > 2 * U ? H() : r.timer = self.setInterval(H, 1e3 * U),
|
|
s.trigger(b.FRAG_LOAD_EMERGENCY_ABORTED, {
|
|
frag: n,
|
|
part: a,
|
|
stats: d
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.hls = t,
|
|
r.bwEstimator = r.initEstimator(),
|
|
r.registerListeners(),
|
|
r
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.resetEstimator = function(e) {
|
|
e && (this.log("setting initial bwe to " + e),
|
|
this.hls.config.abrEwmaDefaultEstimate = e),
|
|
this.firstSelection = -1,
|
|
this.bwEstimator = this.initEstimator()
|
|
}
|
|
,
|
|
r.initEstimator = function() {
|
|
var e = this.hls.config;
|
|
return new F(e.abrEwmaSlowVoD,e.abrEwmaFastVoD,e.abrEwmaDefaultEstimate)
|
|
}
|
|
,
|
|
r.registerListeners = function() {
|
|
var e = this.hls;
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.FRAG_LOADING, this.onFragLoading, this),
|
|
e.on(b.FRAG_LOADED, this.onFragLoaded, this),
|
|
e.on(b.FRAG_BUFFERED, this.onFragBuffered, this),
|
|
e.on(b.LEVEL_SWITCHING, this.onLevelSwitching, this),
|
|
e.on(b.LEVEL_LOADED, this.onLevelLoaded, this),
|
|
e.on(b.LEVELS_UPDATED, this.onLevelsUpdated, this),
|
|
e.on(b.MAX_AUTO_LEVEL_UPDATED, this.onMaxAutoLevelUpdated, this),
|
|
e.on(b.ERROR, this.onError, this)
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.FRAG_LOADING, this.onFragLoading, this),
|
|
e.off(b.FRAG_LOADED, this.onFragLoaded, this),
|
|
e.off(b.FRAG_BUFFERED, this.onFragBuffered, this),
|
|
e.off(b.LEVEL_SWITCHING, this.onLevelSwitching, this),
|
|
e.off(b.LEVEL_LOADED, this.onLevelLoaded, this),
|
|
e.off(b.LEVELS_UPDATED, this.onLevelsUpdated, this),
|
|
e.off(b.MAX_AUTO_LEVEL_UPDATED, this.onMaxAutoLevelUpdated, this),
|
|
e.off(b.ERROR, this.onError, this))
|
|
}
|
|
,
|
|
r.destroy = function() {
|
|
this.unregisterListeners(),
|
|
this.clearTimer(),
|
|
this.hls = this._abandonRulesCheck = this.supportedCache = null,
|
|
this.fragCurrent = this.partCurrent = null
|
|
}
|
|
,
|
|
r.onManifestLoading = function(e, t) {
|
|
this.lastLoadedFragLevel = -1,
|
|
this.firstSelection = -1,
|
|
this.lastLevelLoadSec = 0,
|
|
this.supportedCache = {},
|
|
this.fragCurrent = this.partCurrent = null,
|
|
this.onLevelsUpdated(),
|
|
this.clearTimer()
|
|
}
|
|
,
|
|
r.onLevelsUpdated = function() {
|
|
this.lastLoadedFragLevel > -1 && this.fragCurrent && (this.lastLoadedFragLevel = this.fragCurrent.level),
|
|
this._nextAutoLevel = -1,
|
|
this.onMaxAutoLevelUpdated(),
|
|
this.codecTiers = null,
|
|
this.audioTracksByGroup = null
|
|
}
|
|
,
|
|
r.onMaxAutoLevelUpdated = function() {
|
|
this.firstSelection = -1,
|
|
this.nextAutoLevelKey = ""
|
|
}
|
|
,
|
|
r.onFragLoading = function(e, t) {
|
|
var r, i = t.frag;
|
|
this.ignoreFragment(i) || (i.bitrateTest || (this.fragCurrent = i,
|
|
this.partCurrent = null != (r = t.part) ? r : null),
|
|
this.clearTimer(),
|
|
this.timer = self.setInterval(this._abandonRulesCheck, 100))
|
|
}
|
|
,
|
|
r.onLevelSwitching = function(e, t) {
|
|
this.clearTimer()
|
|
}
|
|
,
|
|
r.onError = function(e, t) {
|
|
if (!t.fatal)
|
|
switch (t.details) {
|
|
case k.BUFFER_ADD_CODEC_ERROR:
|
|
case k.BUFFER_APPEND_ERROR:
|
|
this.lastLoadedFragLevel = -1,
|
|
this.firstSelection = -1;
|
|
break;
|
|
case k.FRAG_LOAD_TIMEOUT:
|
|
var r = t.frag
|
|
, i = this.fragCurrent
|
|
, n = this.partCurrent;
|
|
if (r && i && r.sn === i.sn && r.level === i.level) {
|
|
var a = performance.now()
|
|
, s = n ? n.stats : r.stats
|
|
, o = a - s.loading.start
|
|
, l = s.loading.first ? s.loading.first - s.loading.start : -1;
|
|
if (s.loaded && l > -1) {
|
|
var u = this.bwEstimator.getEstimateTTFB();
|
|
this.bwEstimator.sample(o - Math.min(u, l), s.loaded)
|
|
} else
|
|
this.bwEstimator.sampleTTFB(o)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.getTimeToLoadFrag = function(e, t, r, i) {
|
|
return e + r / t + (i ? e + this.lastLevelLoadSec : 0)
|
|
}
|
|
,
|
|
r.onLevelLoaded = function(e, t) {
|
|
var r = this.hls.config
|
|
, i = t.stats.loading
|
|
, n = i.end - i.first;
|
|
A(n) && (this.lastLevelLoadSec = n / 1e3),
|
|
t.details.live ? this.bwEstimator.update(r.abrEwmaSlowLive, r.abrEwmaFastLive) : this.bwEstimator.update(r.abrEwmaSlowVoD, r.abrEwmaFastVoD),
|
|
this.timer > -1 && this._abandonRulesCheck(t.levelInfo)
|
|
}
|
|
,
|
|
r.onFragLoaded = function(e, t) {
|
|
var r = t.frag
|
|
, i = t.part
|
|
, n = i ? i.stats : r.stats;
|
|
if (r.type === w && this.bwEstimator.sampleTTFB(n.loading.first - n.loading.start),
|
|
!this.ignoreFragment(r)) {
|
|
if (this.clearTimer(),
|
|
r.level === this._nextAutoLevel && (this._nextAutoLevel = -1),
|
|
this.firstSelection = -1,
|
|
this.hls.config.abrMaxWithRealBitrate) {
|
|
var a = i ? i.duration : r.duration
|
|
, s = this.hls.levels[r.level]
|
|
, o = (s.loaded ? s.loaded.bytes : 0) + n.loaded
|
|
, l = (s.loaded ? s.loaded.duration : 0) + a;
|
|
s.loaded = {
|
|
bytes: o,
|
|
duration: l
|
|
},
|
|
s.realBitrate = Math.round(8 * o / l)
|
|
}
|
|
if (r.bitrateTest) {
|
|
var u = {
|
|
stats: n,
|
|
frag: r,
|
|
part: i,
|
|
id: r.type
|
|
};
|
|
this.onFragBuffered(b.FRAG_BUFFERED, u),
|
|
r.bitrateTest = !1
|
|
} else
|
|
this.lastLoadedFragLevel = r.level
|
|
}
|
|
}
|
|
,
|
|
r.onFragBuffered = function(e, t) {
|
|
var r = t.frag
|
|
, i = t.part
|
|
, n = null != i && i.stats.loaded ? i.stats : r.stats;
|
|
if (!n.aborted && !this.ignoreFragment(r)) {
|
|
var a = n.parsing.end - n.loading.start - Math.min(n.loading.first - n.loading.start, this.bwEstimator.getEstimateTTFB());
|
|
this.bwEstimator.sample(a, n.loaded),
|
|
n.bwEstimate = this.getBwEstimate(),
|
|
r.bitrateTest ? this.bitrateTestDelay = a / 1e3 : this.bitrateTestDelay = 0
|
|
}
|
|
}
|
|
,
|
|
r.ignoreFragment = function(e) {
|
|
return e.type !== w || "initSegment" === e.sn
|
|
}
|
|
,
|
|
r.clearTimer = function() {
|
|
this.timer > -1 && (self.clearInterval(this.timer),
|
|
this.timer = -1)
|
|
}
|
|
,
|
|
r.getAutoLevelKey = function() {
|
|
return this.getBwEstimate() + "_" + this.getStarvationDelay().toFixed(2)
|
|
}
|
|
,
|
|
r.getNextABRAutoLevel = function() {
|
|
var e = this.fragCurrent
|
|
, t = this.partCurrent
|
|
, r = this.hls;
|
|
if (r.levels.length <= 1)
|
|
return r.loadLevel;
|
|
var i = r.maxAutoLevel
|
|
, n = r.config
|
|
, a = r.minAutoLevel
|
|
, s = t ? t.duration : e ? e.duration : 0
|
|
, o = this.getBwEstimate()
|
|
, l = this.getStarvationDelay()
|
|
, u = n.abrBandWidthFactor
|
|
, d = n.abrBandWidthUpFactor;
|
|
if (l) {
|
|
var h = this.findBestLevel(o, a, i, l, 0, u, d);
|
|
if (h >= 0)
|
|
return this.rebufferNotice = -1,
|
|
h
|
|
}
|
|
var f = s ? Math.min(s, n.maxStarvationDelay) : n.maxStarvationDelay;
|
|
if (!l) {
|
|
var c = this.bitrateTestDelay;
|
|
c && (f = (s ? Math.min(s, n.maxLoadingDelay) : n.maxLoadingDelay) - c,
|
|
this.info("bitrate test took " + Math.round(1e3 * c) + "ms, set first fragment max fetchDuration to " + Math.round(1e3 * f) + " ms"),
|
|
u = d = 1)
|
|
}
|
|
var g = this.findBestLevel(o, a, i, l, f, u, d);
|
|
if (this.rebufferNotice !== g && (this.rebufferNotice = g,
|
|
this.info((l ? "rebuffering expected" : "buffer is empty") + ", optimal quality level " + g)),
|
|
g > -1)
|
|
return g;
|
|
var v = r.levels[a]
|
|
, m = r.loadLevelObj;
|
|
return m && (null == v ? void 0 : v.bitrate) < m.bitrate ? a : r.loadLevel
|
|
}
|
|
,
|
|
r.getStarvationDelay = function() {
|
|
var e = this.hls
|
|
, t = e.media;
|
|
if (!t)
|
|
return 1 / 0;
|
|
var r = t && 0 !== t.playbackRate ? Math.abs(t.playbackRate) : 1
|
|
, i = e.mainForwardBufferInfo;
|
|
return (i ? i.len : 0) / r
|
|
}
|
|
,
|
|
r.getBwEstimate = function() {
|
|
return this.bwEstimator.canEstimate() ? this.bwEstimator.getEstimate() : this.hls.config.abrEwmaDefaultEstimate
|
|
}
|
|
,
|
|
r.findBestLevel = function(e, t, r, i, n, a, s) {
|
|
var o, l = this, u = i + n, d = this.lastLoadedFragLevel, h = -1 === d ? this.hls.firstLevel : d, f = this.fragCurrent, c = this.partCurrent, g = this.hls, v = g.levels, m = g.allAudioTracks, p = g.loadLevel, y = g.config;
|
|
if (1 === v.length)
|
|
return 0;
|
|
var E, T = v[h], S = !(null == (o = this.hls.latestLevelDetails) || !o.live), L = -1 === p || -1 === d, I = "SDR", R = (null == T ? void 0 : T.frameRate) || 0, k = y.audioPreference, b = y.videoPreference, D = this.audioTracksByGroup || (this.audioTracksByGroup = dt(m)), _ = -1;
|
|
if (L) {
|
|
if (-1 !== this.firstSelection)
|
|
return this.firstSelection;
|
|
var P = this.codecTiers || (this.codecTiers = function(e, t, r, i) {
|
|
return e.slice(r, i + 1).reduce((function(e, r, i) {
|
|
if (!r.codecSet)
|
|
return e;
|
|
var n = r.audioGroups
|
|
, a = e[r.codecSet];
|
|
a || (e[r.codecSet] = a = {
|
|
minBitrate: 1 / 0,
|
|
minHeight: 1 / 0,
|
|
minFramerate: 1 / 0,
|
|
minIndex: i,
|
|
maxScore: 0,
|
|
videoRanges: {
|
|
SDR: 0
|
|
},
|
|
channels: {
|
|
2: 0
|
|
},
|
|
hasDefaultAudio: !n,
|
|
fragmentError: 0
|
|
}),
|
|
a.minBitrate = Math.min(a.minBitrate, r.bitrate);
|
|
var s = Math.min(r.height, r.width);
|
|
return a.minHeight = Math.min(a.minHeight, s),
|
|
a.minFramerate = Math.min(a.minFramerate, r.frameRate),
|
|
a.minIndex = Math.min(a.minIndex, i),
|
|
a.maxScore = Math.max(a.maxScore, r.score),
|
|
a.fragmentError += r.fragmentError,
|
|
a.videoRanges[r.videoRange] = (a.videoRanges[r.videoRange] || 0) + 1,
|
|
n && n.forEach((function(e) {
|
|
if (e) {
|
|
var r = t.groups[e];
|
|
r && (a.hasDefaultAudio = a.hasDefaultAudio || t.hasDefaultAudio ? r.hasDefault : r.hasAutoSelect || !t.hasDefaultAudio && !t.hasAutoSelectAudio,
|
|
Object.keys(r.channels).forEach((function(e) {
|
|
a.channels[e] = (a.channels[e] || 0) + r.channels[e]
|
|
}
|
|
)))
|
|
}
|
|
}
|
|
)),
|
|
e
|
|
}
|
|
), {})
|
|
}(v, D, t, r))
|
|
, C = function(e, t, r, i, n) {
|
|
for (var a = Object.keys(e), s = null == i ? void 0 : i.channels, o = null == i ? void 0 : i.audioCodec, l = null == n ? void 0 : n.videoCodec, u = s && 2 === parseInt(s), d = !1, h = !1, f = 1 / 0, c = 1 / 0, g = 1 / 0, v = 1 / 0, m = 0, p = [], y = ot(t, n), E = y.preferHDR, T = y.allowedVideoRanges, S = function() {
|
|
var t = e[a[L]];
|
|
d || (d = t.channels[2] > 0),
|
|
f = Math.min(f, t.minHeight),
|
|
c = Math.min(c, t.minFramerate),
|
|
g = Math.min(g, t.minBitrate),
|
|
T.filter((function(e) {
|
|
return t.videoRanges[e] > 0
|
|
}
|
|
)).length > 0 && (h = !0)
|
|
}, L = a.length; L--; )
|
|
S();
|
|
f = A(f) ? f : 0,
|
|
c = A(c) ? c : 0;
|
|
var I = Math.max(1080, f)
|
|
, R = Math.max(30, c);
|
|
g = A(g) ? g : r,
|
|
r = Math.max(g, r),
|
|
h || (t = void 0);
|
|
var k = a.length > 1;
|
|
return {
|
|
codecSet: a.reduce((function(t, i) {
|
|
var n = e[i];
|
|
if (i === t)
|
|
return t;
|
|
if (p = h ? T.filter((function(e) {
|
|
return n.videoRanges[e] > 0
|
|
}
|
|
)) : [],
|
|
k) {
|
|
if (n.minBitrate > r)
|
|
return ut(i, "min bitrate of " + n.minBitrate + " > current estimate of " + r),
|
|
t;
|
|
if (!n.hasDefaultAudio)
|
|
return ut(i, "no renditions with default or auto-select sound found"),
|
|
t;
|
|
if (o && i.indexOf(o.substring(0, 4)) % 5 != 0)
|
|
return ut(i, 'audio codec preference "' + o + '" not found'),
|
|
t;
|
|
if (s && !u) {
|
|
if (!n.channels[s])
|
|
return ut(i, "no renditions with " + s + " channel sound found (channels options: " + Object.keys(n.channels) + ")"),
|
|
t
|
|
} else if ((!o || u) && d && 0 === n.channels[2])
|
|
return ut(i, "no renditions with stereo sound found"),
|
|
t;
|
|
if (n.minHeight > I)
|
|
return ut(i, "min resolution of " + n.minHeight + " > maximum of " + I),
|
|
t;
|
|
if (n.minFramerate > R)
|
|
return ut(i, "min framerate of " + n.minFramerate + " > maximum of " + R),
|
|
t;
|
|
if (!p.some((function(e) {
|
|
return n.videoRanges[e] > 0
|
|
}
|
|
)))
|
|
return ut(i, "no variants with VIDEO-RANGE of " + lt(p) + " found"),
|
|
t;
|
|
if (l && i.indexOf(l.substring(0, 4)) % 5 != 0)
|
|
return ut(i, 'video codec preference "' + l + '" not found'),
|
|
t;
|
|
if (n.maxScore < m)
|
|
return ut(i, "max score of " + n.maxScore + " < selected max of " + m),
|
|
t
|
|
}
|
|
return t && (Ne(i) >= Ne(t) || n.fragmentError > e[t].fragmentError) ? t : (v = n.minIndex,
|
|
m = n.maxScore,
|
|
i)
|
|
}
|
|
), void 0),
|
|
videoRanges: p,
|
|
preferHDR: E,
|
|
minFramerate: c,
|
|
minBitrate: g,
|
|
minIndex: v
|
|
}
|
|
}(P, I, e, k, b)
|
|
, w = C.codecSet
|
|
, O = C.videoRanges
|
|
, x = C.minFramerate
|
|
, M = C.minBitrate
|
|
, F = C.minIndex
|
|
, N = C.preferHDR;
|
|
_ = F,
|
|
E = w,
|
|
I = N ? O[O.length - 1] : O[0],
|
|
R = x,
|
|
e = Math.max(e, M),
|
|
this.log("picked start tier " + lt(C))
|
|
} else
|
|
E = null == T ? void 0 : T.codecSet,
|
|
I = null == T ? void 0 : T.videoRange;
|
|
for (var U, B = c ? c.duration : f ? f.duration : 0, G = this.bwEstimator.getEstimateTTFB() / 1e3, K = [], V = function() {
|
|
var t, o = v[H], f = H > h;
|
|
if (!o)
|
|
return 0;
|
|
if (y.useMediaCapabilities && !o.supportedResult && !o.supportedPromise) {
|
|
var g = navigator.mediaCapabilities;
|
|
"function" == typeof (null == g ? void 0 : g.decodingInfo) && function(e, t, r, i, n, a) {
|
|
var s = e.videoCodec
|
|
, o = e.audioCodec ? e.audioGroups : null
|
|
, l = null == a ? void 0 : a.audioCodec
|
|
, u = null == a ? void 0 : a.channels
|
|
, d = u ? parseInt(u) : l ? 1 / 0 : 2
|
|
, h = null;
|
|
if (null != o && o.length)
|
|
try {
|
|
h = 1 === o.length && o[0] ? t.groups[o[0]].channels : o.reduce((function(e, r) {
|
|
if (r) {
|
|
var i = t.groups[r];
|
|
if (!i)
|
|
throw new Error("Audio track group " + r + " not found");
|
|
Object.keys(i.channels).forEach((function(t) {
|
|
e[t] = (e[t] || 0) + i.channels[t]
|
|
}
|
|
))
|
|
}
|
|
return e
|
|
}
|
|
), {
|
|
2: 0
|
|
})
|
|
} catch (e) {
|
|
return !0
|
|
}
|
|
return void 0 !== s && (s.split(",").some((function(e) {
|
|
return Ie(e)
|
|
}
|
|
)) || e.width > 1920 && e.height > 1088 || e.height > 1920 && e.width > 1088 || e.frameRate > Math.max(i, 30) || "SDR" !== e.videoRange && e.videoRange !== r || e.bitrate > Math.max(n, 8e6)) || !!h && A(d) && Object.keys(h).some((function(e) {
|
|
return parseInt(e) > d
|
|
}
|
|
))
|
|
}(o, D, I, R, e, k) ? (o.supportedPromise = Qe(o, D, g, l.supportedCache),
|
|
o.supportedPromise.then((function(e) {
|
|
if (l.hls) {
|
|
o.supportedResult = e;
|
|
var t = l.hls.levels
|
|
, r = t.indexOf(o);
|
|
e.error ? l.warn('MediaCapabilities decodingInfo error: "' + e.error + '" for level ' + r + " " + lt(e)) : e.supported ? e.decodingInfoResults.some((function(e) {
|
|
return !1 === e.smooth || !1 === e.powerEfficient
|
|
}
|
|
)) && l.log("MediaCapabilities decodingInfo for level " + r + " not smooth or powerEfficient: " + lt(e)) : (l.warn("Unsupported MediaCapabilities decodingInfo result for level " + r + " " + lt(e)),
|
|
r > -1 && t.length > 1 && (l.log("Removing unsupported level " + r),
|
|
l.hls.removeLevel(r),
|
|
-1 === l.hls.loadLevel && (l.hls.nextLoadLevel = 0)))
|
|
}
|
|
}
|
|
)).catch((function(e) {
|
|
l.warn("Error handling MediaCapabilities decodingInfo: " + e)
|
|
}
|
|
))) : o.supportedResult = qe
|
|
}
|
|
if ((E && o.codecSet !== E || I && o.videoRange !== I || f && R > o.frameRate || !f && R > 0 && R < o.frameRate || null != (t = o.supportedResult) && null != (t = t.decodingInfoResults) && t.some((function(e) {
|
|
return !1 === e.smooth
|
|
}
|
|
))) && (!L || H !== _))
|
|
return K.push(H),
|
|
0;
|
|
var m, T = o.details, b = (c ? null == T ? void 0 : T.partTarget : null == T ? void 0 : T.averagetargetduration) || B;
|
|
m = f ? s * e : a * e;
|
|
var P = B && i >= 2 * B && 0 === n ? o.averageBitrate : o.maxBitrate
|
|
, C = l.getTimeToLoadFrag(G, m, P * b, void 0 === T);
|
|
if (m >= P && (H === d || 0 === o.loadError && 0 === o.fragmentError) && (C <= G || !A(C) || S && !l.bitrateTestDelay || C < u)) {
|
|
var w = l.forcedAutoLevel;
|
|
return H === p || -1 !== w && w === p || (K.length && l.trace("Skipped level(s) " + K.join(",") + " of " + r + ' max with CODECS and VIDEO-RANGE:"' + v[K[0]].codecs + '" ' + v[K[0]].videoRange + '; not compatible with "' + E + '" ' + I),
|
|
l.info("switch candidate:" + h + "->" + H + " adjustedbw(" + Math.round(m) + ")-bitrate=" + Math.round(m - P) + " ttfb:" + G.toFixed(1) + " avgDuration:" + b.toFixed(1) + " maxFetchDuration:" + u.toFixed(1) + " fetchDuration:" + C.toFixed(1) + " firstSelection:" + L + " codecSet:" + o.codecSet + " videoRange:" + o.videoRange + " hls.loadLevel:" + p)),
|
|
L && (l.firstSelection = H),
|
|
{
|
|
v: H
|
|
}
|
|
}
|
|
}, H = r; H >= t; H--)
|
|
if (0 !== (U = V()) && U)
|
|
return U.v;
|
|
return -1
|
|
}
|
|
,
|
|
r.deriveNextAutoLevel = function(e) {
|
|
var t = this.hls
|
|
, r = t.maxAutoLevel
|
|
, i = t.minAutoLevel;
|
|
return Math.min(Math.max(e, i), r)
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "firstAutoLevel",
|
|
get: function() {
|
|
var e = this.hls
|
|
, t = e.maxAutoLevel
|
|
, r = e.minAutoLevel
|
|
, i = this.getBwEstimate()
|
|
, n = this.hls.config.maxStarvationDelay
|
|
, a = this.findBestLevel(i, r, t, 0, n, 1, 1);
|
|
if (a > -1)
|
|
return a;
|
|
var s = this.hls.firstLevel
|
|
, o = Math.min(Math.max(s, r), t);
|
|
return this.warn("Could not find best starting auto level. Defaulting to first in playlist " + s + " clamped to " + o),
|
|
o
|
|
}
|
|
}, {
|
|
key: "forcedAutoLevel",
|
|
get: function() {
|
|
return this.nextAutoLevelKey ? -1 : this._nextAutoLevel
|
|
}
|
|
}, {
|
|
key: "nextAutoLevel",
|
|
get: function() {
|
|
var e = this.forcedAutoLevel
|
|
, t = this.bwEstimator.canEstimate()
|
|
, r = this.lastLoadedFragLevel > -1;
|
|
if (!(-1 === e || t && r && this.nextAutoLevelKey !== this.getAutoLevelKey()))
|
|
return e;
|
|
var i = t && r ? this.getNextABRAutoLevel() : this.firstAutoLevel;
|
|
if (-1 !== e) {
|
|
var n = this.hls.levels;
|
|
if (n.length > Math.max(e, i) && n[e].loadError <= n[i].loadError)
|
|
return e
|
|
}
|
|
return this._nextAutoLevel = i,
|
|
this.nextAutoLevelKey = this.getAutoLevelKey(),
|
|
i
|
|
},
|
|
set: function(e) {
|
|
var t = this.deriveNextAutoLevel(e);
|
|
this._nextAutoLevel !== t && (this.nextAutoLevelKey = "",
|
|
this._nextAutoLevel = t)
|
|
}
|
|
}])
|
|
}(N)
|
|
, yt = function(e, t) {
|
|
for (var r = 0, i = e.length - 1, n = null, a = null; r <= i; ) {
|
|
var s = t(a = e[n = (r + i) / 2 | 0]);
|
|
if (s > 0)
|
|
r = n + 1;
|
|
else {
|
|
if (!(s < 0))
|
|
return a;
|
|
i = n - 1
|
|
}
|
|
}
|
|
return null
|
|
};
|
|
function Et(e, t, r, i, n) {
|
|
void 0 === r && (r = 0),
|
|
void 0 === i && (i = 0),
|
|
void 0 === n && (n = .005);
|
|
var a = null;
|
|
if (e) {
|
|
a = t[1 + e.sn - t[0].sn] || null;
|
|
var s = e.endDTS - r;
|
|
s > 0 && s < 15e-7 && (r += 15e-7),
|
|
a && e.level !== a.level && a.end <= e.end && (a = t[2 + e.sn - t[0].sn] || null)
|
|
} else
|
|
0 === r && 0 === t[0].start && (a = t[0]);
|
|
if (a && ((!e || e.level === a.level) && 0 === Tt(r, i, a) || function(e, t, r) {
|
|
if (t && 0 === t.start && t.level < e.level && (t.endPTS || 0) > 0) {
|
|
var i = t.tagList.reduce((function(e, t) {
|
|
return "INF" === t[0] && (e += parseFloat(t[1])),
|
|
e
|
|
}
|
|
), r);
|
|
return e.start <= i
|
|
}
|
|
return !1
|
|
}(a, e, Math.min(n, i))))
|
|
return a;
|
|
var o = yt(t, Tt.bind(null, r, i));
|
|
return !o || o === e && a ? a : o
|
|
}
|
|
function Tt(e, t, r) {
|
|
if (void 0 === e && (e = 0),
|
|
void 0 === t && (t = 0),
|
|
r.start <= e && r.start + r.duration > e)
|
|
return 0;
|
|
var i = Math.min(t, r.duration + (r.deltaPTS ? r.deltaPTS : 0));
|
|
return r.start + r.duration - i <= e ? 1 : r.start - i > e && r.start ? -1 : 0
|
|
}
|
|
function St(e, t, r) {
|
|
var i = 1e3 * Math.min(t, r.duration + (r.deltaPTS ? r.deltaPTS : 0));
|
|
return (r.endProgramDateTime || 0) - i > e
|
|
}
|
|
function At(e, t, r) {
|
|
if (e && e.startCC <= t && e.endCC >= t) {
|
|
var i, n = e.fragments, a = e.fragmentHint;
|
|
return a && (n = n.concat(a)),
|
|
yt(n, (function(e) {
|
|
return e.cc < t ? 1 : e.cc > t ? -1 : (i = e,
|
|
e.end <= r ? 1 : e.start > r ? -1 : 0)
|
|
}
|
|
)),
|
|
i || null
|
|
}
|
|
return null
|
|
}
|
|
function Lt(e) {
|
|
switch (e.details) {
|
|
case k.FRAG_LOAD_TIMEOUT:
|
|
case k.KEY_LOAD_TIMEOUT:
|
|
case k.LEVEL_LOAD_TIMEOUT:
|
|
case k.MANIFEST_LOAD_TIMEOUT:
|
|
return !0
|
|
}
|
|
return !1
|
|
}
|
|
function It(e) {
|
|
return e.details.startsWith("key")
|
|
}
|
|
function Rt(e) {
|
|
return It(e) && !!e.frag && !e.frag.decryptdata
|
|
}
|
|
function kt(e, t) {
|
|
var r = Lt(t);
|
|
return e.default[(r ? "timeout" : "error") + "Retry"]
|
|
}
|
|
function bt(e, t) {
|
|
var r = "linear" === e.backoff ? 1 : Math.pow(2, t);
|
|
return Math.min(r * e.retryDelayMs, e.maxRetryDelayMs)
|
|
}
|
|
function Dt(e) {
|
|
return d(d({}, e), {
|
|
errorRetry: null,
|
|
timeoutRetry: null
|
|
})
|
|
}
|
|
function _t(e, t, r, i) {
|
|
if (!e)
|
|
return !1;
|
|
var n = null == i ? void 0 : i.code
|
|
, a = t < e.maxNumRetry && (function(e) {
|
|
return Pt(e) || !!e && (e < 400 || e > 499)
|
|
}(n) || !!r);
|
|
return e.shouldRetry ? e.shouldRetry(e, t, r, i, a) : a
|
|
}
|
|
function Pt(e) {
|
|
return 0 === e && !1 === navigator.onLine
|
|
}
|
|
var Ct = 0
|
|
, wt = 2
|
|
, Ot = 3
|
|
, xt = 5
|
|
, Mt = 0
|
|
, Ft = 1
|
|
, Nt = 2
|
|
, Ut = 4
|
|
, Bt = function(e) {
|
|
function t(t) {
|
|
var r;
|
|
return (r = e.call(this, "error-controller", t.logger) || this).hls = void 0,
|
|
r.playlistError = 0,
|
|
r.hls = t,
|
|
r.registerListeners(),
|
|
r
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.registerListeners = function() {
|
|
var e = this.hls;
|
|
e.on(b.ERROR, this.onError, this),
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.LEVEL_UPDATED, this.onLevelUpdated, this)
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.off(b.ERROR, this.onError, this),
|
|
e.off(b.ERROR, this.onErrorOut, this),
|
|
e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.LEVEL_UPDATED, this.onLevelUpdated, this))
|
|
}
|
|
,
|
|
r.destroy = function() {
|
|
this.unregisterListeners(),
|
|
this.hls = null
|
|
}
|
|
,
|
|
r.startLoad = function(e) {}
|
|
,
|
|
r.stopLoad = function() {
|
|
this.playlistError = 0
|
|
}
|
|
,
|
|
r.getVariantLevelIndex = function(e) {
|
|
return (null == e ? void 0 : e.type) === w ? e.level : this.getVariantIndex()
|
|
}
|
|
,
|
|
r.getVariantIndex = function() {
|
|
var e, t = this.hls, r = t.currentLevel;
|
|
return null != (e = t.loadLevelObj) && e.details || -1 === r ? t.loadLevel : r
|
|
}
|
|
,
|
|
r.variantHasKey = function(e, t) {
|
|
if (e) {
|
|
var r;
|
|
if (null != (r = e.details) && r.hasKey(t))
|
|
return !0;
|
|
var i = e.audioGroups;
|
|
if (i)
|
|
return this.hls.allAudioTracks.filter((function(e) {
|
|
return i.indexOf(e.groupId) >= 0
|
|
}
|
|
)).some((function(e) {
|
|
var r;
|
|
return null == (r = e.details) ? void 0 : r.hasKey(t)
|
|
}
|
|
))
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
r.onManifestLoading = function() {
|
|
this.playlistError = 0
|
|
}
|
|
,
|
|
r.onLevelUpdated = function() {
|
|
this.playlistError = 0
|
|
}
|
|
,
|
|
r.onError = function(e, t) {
|
|
var r;
|
|
if (!t.fatal) {
|
|
var i = this.hls
|
|
, n = t.context;
|
|
switch (t.details) {
|
|
case k.FRAG_LOAD_ERROR:
|
|
case k.FRAG_LOAD_TIMEOUT:
|
|
case k.KEY_LOAD_ERROR:
|
|
case k.KEY_LOAD_TIMEOUT:
|
|
return void (t.errorAction = this.getFragRetryOrSwitchAction(t));
|
|
case k.FRAG_PARSING_ERROR:
|
|
if (null != (r = t.frag) && r.gap)
|
|
return void (t.errorAction = Gt());
|
|
case k.FRAG_GAP:
|
|
case k.FRAG_DECRYPT_ERROR:
|
|
return t.errorAction = this.getFragRetryOrSwitchAction(t),
|
|
void (t.errorAction.action = wt);
|
|
case k.LEVEL_EMPTY_ERROR:
|
|
case k.LEVEL_PARSING_ERROR:
|
|
var a, s = t.parent === w ? t.level : i.loadLevel;
|
|
return void (t.details === k.LEVEL_EMPTY_ERROR && null != (a = t.context) && null != (a = a.levelDetails) && a.live ? t.errorAction = this.getPlaylistRetryOrSwitchAction(t, s) : (t.levelRetry = !1,
|
|
t.errorAction = this.getLevelSwitchAction(t, s)));
|
|
case k.LEVEL_LOAD_ERROR:
|
|
case k.LEVEL_LOAD_TIMEOUT:
|
|
return void ("number" == typeof (null == n ? void 0 : n.level) && (t.errorAction = this.getPlaylistRetryOrSwitchAction(t, n.level)));
|
|
case k.AUDIO_TRACK_LOAD_ERROR:
|
|
case k.AUDIO_TRACK_LOAD_TIMEOUT:
|
|
case k.SUBTITLE_LOAD_ERROR:
|
|
case k.SUBTITLE_TRACK_LOAD_TIMEOUT:
|
|
if (n) {
|
|
var o = i.loadLevelObj;
|
|
if (o && (n.type === P && o.hasAudioGroup(n.groupId) || n.type === C && o.hasSubtitleGroup(n.groupId)))
|
|
return t.errorAction = this.getPlaylistRetryOrSwitchAction(t, i.loadLevel),
|
|
t.errorAction.action = wt,
|
|
void (t.errorAction.flags = Ft)
|
|
}
|
|
return;
|
|
case k.KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED:
|
|
return void (t.errorAction = {
|
|
action: wt,
|
|
flags: Nt
|
|
});
|
|
case k.KEY_SYSTEM_SESSION_UPDATE_FAILED:
|
|
case k.KEY_SYSTEM_STATUS_INTERNAL_ERROR:
|
|
case k.KEY_SYSTEM_NO_SESSION:
|
|
return void (t.errorAction = {
|
|
action: wt,
|
|
flags: Ut
|
|
});
|
|
case k.BUFFER_ADD_CODEC_ERROR:
|
|
case k.REMUX_ALLOC_ERROR:
|
|
case k.BUFFER_APPEND_ERROR:
|
|
var l;
|
|
return void (t.errorAction || (t.errorAction = this.getLevelSwitchAction(t, null != (l = t.level) ? l : i.loadLevel)));
|
|
case k.INTERNAL_EXCEPTION:
|
|
case k.BUFFER_APPENDING_ERROR:
|
|
case k.BUFFER_FULL_ERROR:
|
|
case k.LEVEL_SWITCH_ERROR:
|
|
case k.BUFFER_STALLED_ERROR:
|
|
case k.BUFFER_SEEK_OVER_HOLE:
|
|
case k.BUFFER_NUDGE_ON_STALL:
|
|
return void (t.errorAction = Gt())
|
|
}
|
|
t.type === R.KEY_SYSTEM_ERROR && (t.levelRetry = !1,
|
|
t.errorAction = Gt())
|
|
}
|
|
}
|
|
,
|
|
r.getPlaylistRetryOrSwitchAction = function(e, t) {
|
|
var r = kt(this.hls.config.playlistLoadPolicy, e)
|
|
, i = this.playlistError++;
|
|
if (_t(r, i, Lt(e), e.response))
|
|
return {
|
|
action: xt,
|
|
flags: Mt,
|
|
retryConfig: r,
|
|
retryCount: i
|
|
};
|
|
var n = this.getLevelSwitchAction(e, t);
|
|
return r && (n.retryConfig = r,
|
|
n.retryCount = i),
|
|
n
|
|
}
|
|
,
|
|
r.getFragRetryOrSwitchAction = function(e) {
|
|
var t = this.hls
|
|
, r = this.getVariantLevelIndex(e.frag)
|
|
, i = t.levels[r]
|
|
, n = t.config
|
|
, a = n.fragLoadPolicy
|
|
, s = n.keyLoadPolicy
|
|
, o = kt(It(e) ? s : a, e)
|
|
, l = t.levels.reduce((function(e, t) {
|
|
return e + t.fragmentError
|
|
}
|
|
), 0);
|
|
if (i && (e.details !== k.FRAG_GAP && i.fragmentError++,
|
|
!Rt(e) && _t(o, l, Lt(e), e.response)))
|
|
return {
|
|
action: xt,
|
|
flags: Mt,
|
|
retryConfig: o,
|
|
retryCount: l
|
|
};
|
|
var u = this.getLevelSwitchAction(e, r);
|
|
return o && (u.retryConfig = o,
|
|
u.retryCount = l),
|
|
u
|
|
}
|
|
,
|
|
r.getLevelSwitchAction = function(e, t) {
|
|
var r = this.hls;
|
|
null == t && (t = r.loadLevel);
|
|
var i = this.hls.levels[t];
|
|
if (i) {
|
|
var n, a, s = e.details;
|
|
i.loadError++,
|
|
s === k.BUFFER_APPEND_ERROR && i.fragmentError++;
|
|
var o = -1
|
|
, l = r.levels
|
|
, u = r.loadLevel
|
|
, d = r.minAutoLevel
|
|
, h = r.maxAutoLevel;
|
|
r.autoLevelEnabled || r.config.preserveManualLevelOnError || (r.loadLevel = -1);
|
|
for (var f, c = null == (n = e.frag) ? void 0 : n.type, g = (c === O && s === k.FRAG_PARSING_ERROR || "audio" === e.sourceBufferName && (s === k.BUFFER_ADD_CODEC_ERROR || s === k.BUFFER_APPEND_ERROR)) && l.some((function(e) {
|
|
var t = e.audioCodec;
|
|
return i.audioCodec !== t
|
|
}
|
|
)), v = "video" === e.sourceBufferName && (s === k.BUFFER_ADD_CODEC_ERROR || s === k.BUFFER_APPEND_ERROR) && l.some((function(e) {
|
|
var t = e.codecSet
|
|
, r = e.audioCodec;
|
|
return i.codecSet !== t && i.audioCodec === r
|
|
}
|
|
)), m = null != (a = e.context) ? a : {}, p = m.type, y = m.groupId, E = function() {
|
|
var t = (T + u) % l.length;
|
|
if (t !== u && t >= d && t <= h && 0 === l[t].loadError) {
|
|
var r, n, a = l[t];
|
|
if (s === k.FRAG_GAP && c === w && e.frag) {
|
|
var f = l[t].details;
|
|
if (f) {
|
|
var m = Et(e.frag, f.fragments, e.frag.start);
|
|
if (null != m && m.gap)
|
|
return 0
|
|
}
|
|
} else {
|
|
if (p === P && a.hasAudioGroup(y) || p === C && a.hasSubtitleGroup(y))
|
|
return 0;
|
|
if (c === O && null != (r = i.audioGroups) && r.some((function(e) {
|
|
return a.hasAudioGroup(e)
|
|
}
|
|
)) || c === x && null != (n = i.subtitleGroups) && n.some((function(e) {
|
|
return a.hasSubtitleGroup(e)
|
|
}
|
|
)) || g && i.audioCodec === a.audioCodec || v && i.codecSet === a.codecSet || !g && i.codecSet !== a.codecSet)
|
|
return 0
|
|
}
|
|
return o = t,
|
|
1
|
|
}
|
|
}, T = l.length; T-- && (0 === (f = E()) || 1 !== f); )
|
|
;
|
|
if (o > -1 && r.loadLevel !== o)
|
|
return e.levelRetry = !0,
|
|
this.playlistError = 0,
|
|
{
|
|
action: wt,
|
|
flags: Mt,
|
|
nextAutoLevel: o
|
|
}
|
|
}
|
|
return {
|
|
action: wt,
|
|
flags: Ft
|
|
}
|
|
}
|
|
,
|
|
r.onErrorOut = function(e, t) {
|
|
var r;
|
|
switch (null == (r = t.errorAction) ? void 0 : r.action) {
|
|
case Ct:
|
|
break;
|
|
case wt:
|
|
this.sendAlternateToPenaltyBox(t),
|
|
t.errorAction.resolved || t.details === k.FRAG_GAP ? /MediaSource readyState: ended/.test(t.error.message) && (this.warn('MediaSource ended after "' + t.sourceBufferName + '" sourceBuffer append error. Attempting to recover from media error.'),
|
|
this.hls.recoverMediaError()) : t.fatal = !0
|
|
}
|
|
t.fatal && this.hls.stopLoad()
|
|
}
|
|
,
|
|
r.sendAlternateToPenaltyBox = function(e) {
|
|
var t = this.hls
|
|
, r = e.errorAction;
|
|
if (r) {
|
|
var i = r.flags
|
|
, n = r.nextAutoLevel;
|
|
switch (i) {
|
|
case Mt:
|
|
this.switchLevel(e, n);
|
|
break;
|
|
case Nt:
|
|
var a = this.getVariantLevelIndex(e.frag)
|
|
, s = t.levels[a]
|
|
, o = null == s ? void 0 : s.attrs["HDCP-LEVEL"];
|
|
if (r.hdcpLevel = o,
|
|
"NONE" === o)
|
|
this.warn("HDCP policy resticted output with HDCP-LEVEL=NONE");
|
|
else if (o) {
|
|
t.maxHdcpLevel = Ze[Ze.indexOf(o) - 1],
|
|
r.resolved = !0,
|
|
this.warn('Restricting playback to HDCP-LEVEL of "' + t.maxHdcpLevel + '" or lower');
|
|
break
|
|
}
|
|
case Ut:
|
|
var l = e.decryptdata;
|
|
if (l) {
|
|
for (var u = this.hls.levels, d = u.length, h = d; h--; ) {
|
|
var f, c;
|
|
this.variantHasKey(u[h], l) && (this.log("Banned key found in level " + h + " (" + u[h].bitrate + 'bps) or audio group "' + (null == (f = u[h].audioGroups) ? void 0 : f.join(",")) + '" (' + (null == (c = e.frag) ? void 0 : c.type) + " fragment) " + X(l.keyId || [])),
|
|
u[h].fragmentError++,
|
|
u[h].loadError++,
|
|
this.log("Removing level " + h + " with key error (" + e.error + ")"),
|
|
this.hls.removeLevel(h))
|
|
}
|
|
var g = e.frag;
|
|
if (this.hls.levels.length < d)
|
|
r.resolved = !0;
|
|
else if (g && g.type !== w) {
|
|
var v = g.decryptdata;
|
|
v && !l.matches(v) && (r.resolved = !0)
|
|
}
|
|
}
|
|
}
|
|
r.resolved || this.switchLevel(e, n)
|
|
}
|
|
}
|
|
,
|
|
r.switchLevel = function(e, t) {
|
|
if (void 0 !== t && e.errorAction && (this.warn("switching to level " + t + " after " + e.details),
|
|
this.hls.nextAutoLevel = t,
|
|
e.errorAction.resolved = !0,
|
|
this.hls.nextLoadLevel = this.hls.nextAutoLevel,
|
|
e.details === k.BUFFER_ADD_CODEC_ERROR && e.mimeType && "audiovideo" !== e.sourceBufferName))
|
|
for (var r = We(e.mimeType), i = this.hls.levels, n = i.length; n--; )
|
|
i[n][e.sourceBufferName + "Codec"] === r && (this.log("Removing level " + n + " for " + e.details + ' ("' + r + '" not supported)'),
|
|
this.hls.removeLevel(n))
|
|
}
|
|
,
|
|
t
|
|
}(N);
|
|
function Gt(e) {
|
|
var t = {
|
|
action: Ct,
|
|
flags: Mt
|
|
};
|
|
return e && (t.resolved = !0),
|
|
t
|
|
}
|
|
var Kt = "NOT_LOADED"
|
|
, Vt = "APPENDING"
|
|
, Ht = "PARTIAL"
|
|
, Yt = "OK"
|
|
, Wt = function() {
|
|
function e(e) {
|
|
this.activePartLists = Object.create(null),
|
|
this.endListFragments = Object.create(null),
|
|
this.fragments = Object.create(null),
|
|
this.timeRanges = Object.create(null),
|
|
this.bufferPadding = .2,
|
|
this.hls = void 0,
|
|
this.hasGaps = !1,
|
|
this.hls = e,
|
|
this._registerListeners()
|
|
}
|
|
var t = e.prototype;
|
|
return t._registerListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.BUFFER_APPENDED, this.onBufferAppended, this),
|
|
e.on(b.FRAG_BUFFERED, this.onFragBuffered, this),
|
|
e.on(b.FRAG_LOADED, this.onFragLoaded, this))
|
|
}
|
|
,
|
|
t._unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.BUFFER_APPENDED, this.onBufferAppended, this),
|
|
e.off(b.FRAG_BUFFERED, this.onFragBuffered, this),
|
|
e.off(b.FRAG_LOADED, this.onFragLoaded, this))
|
|
}
|
|
,
|
|
t.destroy = function() {
|
|
this._unregisterListeners(),
|
|
this.hls = this.fragments = this.activePartLists = this.endListFragments = this.timeRanges = null
|
|
}
|
|
,
|
|
t.getAppendedFrag = function(e, t) {
|
|
var r = this.activePartLists[t];
|
|
if (r)
|
|
for (var i = r.length; i--; ) {
|
|
var n = r[i];
|
|
if (!n)
|
|
break;
|
|
if (n.start <= e && e <= n.end && n.loaded)
|
|
return n
|
|
}
|
|
return this.getBufferedFrag(e, t)
|
|
}
|
|
,
|
|
t.getBufferedFrag = function(e, t) {
|
|
return this.getFragAtPos(e, t, !0)
|
|
}
|
|
,
|
|
t.getFragAtPos = function(e, t, r) {
|
|
for (var i = this.fragments, n = Object.keys(i), a = n.length; a--; ) {
|
|
var s = i[n[a]];
|
|
if ((null == s ? void 0 : s.body.type) === t && (!r || s.buffered)) {
|
|
var o = s.body;
|
|
if (o.start <= e && e <= o.end)
|
|
return o
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
,
|
|
t.detectEvictedFragments = function(e, t, r, i, n) {
|
|
var a = this;
|
|
this.timeRanges && (this.timeRanges[e] = t);
|
|
var s = (null == i ? void 0 : i.fragment.sn) || -1;
|
|
Object.keys(this.fragments).forEach((function(i) {
|
|
var o = a.fragments[i];
|
|
if (o && !(s >= o.body.sn))
|
|
if (o.buffered || o.loaded && !n) {
|
|
var l = o.range[e];
|
|
l && (0 !== l.time.length ? l.time.some((function(e) {
|
|
var r = !a.isTimeBuffered(e.startPTS, e.endPTS, t);
|
|
return r && a.removeFragment(o.body),
|
|
r
|
|
}
|
|
)) : a.removeFragment(o.body))
|
|
} else
|
|
o.body.type === r && a.removeFragment(o.body)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t.detectPartialFragments = function(e) {
|
|
var t = this
|
|
, r = this.timeRanges;
|
|
if (r && "initSegment" !== e.frag.sn) {
|
|
var i = e.frag
|
|
, n = qt(i)
|
|
, a = this.fragments[n];
|
|
if (!(!a || a.buffered && i.gap)) {
|
|
var s = !i.relurl;
|
|
Object.keys(r).forEach((function(n) {
|
|
var o = i.elementaryStreams[n];
|
|
if (o) {
|
|
var l = r[n]
|
|
, u = s || !0 === o.partial;
|
|
a.range[n] = t.getBufferedTimes(i, e.part, u, l)
|
|
}
|
|
}
|
|
)),
|
|
a.loaded = null,
|
|
Object.keys(a.range).length ? (a.buffered = !0,
|
|
(a.body.endList = i.endList || a.body.endList) && (this.endListFragments[a.body.type] = a),
|
|
jt(a) || this.removeParts(i.sn - 1, i.type)) : this.removeFragment(a.body)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
t.removeParts = function(e, t) {
|
|
var r = this.activePartLists[t];
|
|
r && (this.activePartLists[t] = Xt(r, (function(t) {
|
|
return t.fragment.sn >= e
|
|
}
|
|
)))
|
|
}
|
|
,
|
|
t.fragBuffered = function(e, t) {
|
|
var r = qt(e)
|
|
, i = this.fragments[r];
|
|
!i && t && (i = this.fragments[r] = {
|
|
body: e,
|
|
appendedPTS: null,
|
|
loaded: null,
|
|
buffered: !1,
|
|
range: Object.create(null)
|
|
},
|
|
e.gap && (this.hasGaps = !0)),
|
|
i && (i.loaded = null,
|
|
i.buffered = !0)
|
|
}
|
|
,
|
|
t.getBufferedTimes = function(e, t, r, i) {
|
|
for (var n = {
|
|
time: [],
|
|
partial: r
|
|
}, a = e.start, s = e.end, o = e.minEndPTS || s, l = e.maxStartPTS || a, u = 0; u < i.length; u++) {
|
|
var d = i.start(u) - this.bufferPadding
|
|
, h = i.end(u) + this.bufferPadding;
|
|
if (l >= d && o <= h) {
|
|
n.time.push({
|
|
startPTS: Math.max(a, i.start(u)),
|
|
endPTS: Math.min(s, i.end(u))
|
|
});
|
|
break
|
|
}
|
|
if (a < h && s > d) {
|
|
var f = Math.max(a, i.start(u))
|
|
, c = Math.min(s, i.end(u));
|
|
c > f && (n.partial = !0,
|
|
n.time.push({
|
|
startPTS: f,
|
|
endPTS: c
|
|
}))
|
|
} else if (s <= d)
|
|
break
|
|
}
|
|
return n
|
|
}
|
|
,
|
|
t.getPartialFragment = function(e) {
|
|
var t, r, i, n = null, a = 0, s = this.bufferPadding, o = this.fragments;
|
|
return Object.keys(o).forEach((function(l) {
|
|
var u = o[l];
|
|
u && jt(u) && (r = u.body.start - s,
|
|
i = u.body.end + s,
|
|
e >= r && e <= i && (t = Math.min(e - r, i - e),
|
|
a <= t && (n = u.body,
|
|
a = t)))
|
|
}
|
|
)),
|
|
n
|
|
}
|
|
,
|
|
t.isEndListAppended = function(e) {
|
|
var t = this.endListFragments[e];
|
|
return void 0 !== t && (t.buffered || jt(t))
|
|
}
|
|
,
|
|
t.getState = function(e) {
|
|
var t = qt(e)
|
|
, r = this.fragments[t];
|
|
return r ? r.buffered ? jt(r) ? Ht : Yt : Vt : Kt
|
|
}
|
|
,
|
|
t.isTimeBuffered = function(e, t, r) {
|
|
for (var i, n, a = 0; a < r.length; a++) {
|
|
if (i = r.start(a) - this.bufferPadding,
|
|
n = r.end(a) + this.bufferPadding,
|
|
e >= i && t <= n)
|
|
return !0;
|
|
if (t <= i)
|
|
return !1
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
t.onManifestLoading = function() {
|
|
this.removeAllFragments()
|
|
}
|
|
,
|
|
t.onFragLoaded = function(e, t) {
|
|
if ("initSegment" !== t.frag.sn && !t.frag.bitrateTest) {
|
|
var r = t.frag
|
|
, i = t.part ? null : t
|
|
, n = qt(r);
|
|
this.fragments[n] = {
|
|
body: r,
|
|
appendedPTS: null,
|
|
loaded: i,
|
|
buffered: !1,
|
|
range: Object.create(null)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
t.onBufferAppended = function(e, t) {
|
|
var r = t.frag
|
|
, i = t.part
|
|
, n = t.timeRanges
|
|
, a = t.type;
|
|
if ("initSegment" !== r.sn) {
|
|
var s = r.type;
|
|
if (i) {
|
|
var o = this.activePartLists[s];
|
|
o || (this.activePartLists[s] = o = []),
|
|
o.push(i)
|
|
}
|
|
this.timeRanges = n;
|
|
var l = n[a];
|
|
this.detectEvictedFragments(a, l, s, i)
|
|
}
|
|
}
|
|
,
|
|
t.onFragBuffered = function(e, t) {
|
|
this.detectPartialFragments(t)
|
|
}
|
|
,
|
|
t.hasFragment = function(e) {
|
|
var t = qt(e);
|
|
return !!this.fragments[t]
|
|
}
|
|
,
|
|
t.hasFragments = function(e) {
|
|
var t = this.fragments
|
|
, r = Object.keys(t);
|
|
if (!e)
|
|
return r.length > 0;
|
|
for (var i = r.length; i--; ) {
|
|
var n = t[r[i]];
|
|
if ((null == n ? void 0 : n.body.type) === e)
|
|
return !0
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
t.hasParts = function(e) {
|
|
var t;
|
|
return !(null == (t = this.activePartLists[e]) || !t.length)
|
|
}
|
|
,
|
|
t.removeFragmentsInRange = function(e, t, r, i, n) {
|
|
var a = this;
|
|
i && !this.hasGaps || Object.keys(this.fragments).forEach((function(s) {
|
|
var o = a.fragments[s];
|
|
if (o) {
|
|
var l = o.body;
|
|
l.type !== r || i && !l.gap || l.start < t && l.end > e && (o.buffered || n) && a.removeFragment(l)
|
|
}
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t.removeFragment = function(e) {
|
|
var t = qt(e);
|
|
e.clearElementaryStreamInfo();
|
|
var r = this.activePartLists[e.type];
|
|
if (r) {
|
|
var i = e.sn;
|
|
this.activePartLists[e.type] = Xt(r, (function(e) {
|
|
return e.fragment.sn !== i
|
|
}
|
|
))
|
|
}
|
|
delete this.fragments[t],
|
|
e.endList && delete this.endListFragments[e.type]
|
|
}
|
|
,
|
|
t.removeAllFragments = function() {
|
|
var e;
|
|
this.fragments = Object.create(null),
|
|
this.endListFragments = Object.create(null),
|
|
this.activePartLists = Object.create(null),
|
|
this.hasGaps = !1;
|
|
var t = null == (e = this.hls) || null == (e = e.latestLevelDetails) ? void 0 : e.partList;
|
|
t && t.forEach((function(e) {
|
|
return e.clearElementaryStreamInfo()
|
|
}
|
|
))
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function jt(e) {
|
|
var t, r, i;
|
|
return e.buffered && !!(e.body.gap || null != (t = e.range.video) && t.partial || null != (r = e.range.audio) && r.partial || null != (i = e.range.audiovideo) && i.partial)
|
|
}
|
|
function qt(e) {
|
|
return e.type + "_" + e.level + "_" + e.sn
|
|
}
|
|
function Xt(e, t) {
|
|
return e.filter((function(e) {
|
|
var r = t(e);
|
|
return r || e.clearElementaryStreamInfo(),
|
|
r
|
|
}
|
|
))
|
|
}
|
|
var Qt = 0
|
|
, zt = 1
|
|
, $t = function() {
|
|
function e(e, t, r) {
|
|
this.subtle = void 0,
|
|
this.aesIV = void 0,
|
|
this.aesMode = void 0,
|
|
this.subtle = e,
|
|
this.aesIV = t,
|
|
this.aesMode = r
|
|
}
|
|
return e.prototype.decrypt = function(e, t) {
|
|
switch (this.aesMode) {
|
|
case Qt:
|
|
return this.subtle.decrypt({
|
|
name: "AES-CBC",
|
|
iv: this.aesIV
|
|
}, t, e);
|
|
case zt:
|
|
return this.subtle.decrypt({
|
|
name: "AES-CTR",
|
|
counter: this.aesIV,
|
|
length: 64
|
|
}, t, e);
|
|
default:
|
|
throw new Error("[AESCrypto] invalid aes mode " + this.aesMode)
|
|
}
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, Zt = function() {
|
|
function e() {
|
|
this.rcon = [0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54],
|
|
this.subMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)],
|
|
this.invSubMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)],
|
|
this.sBox = new Uint32Array(256),
|
|
this.invSBox = new Uint32Array(256),
|
|
this.key = new Uint32Array(0),
|
|
this.ksRows = 0,
|
|
this.keySize = 0,
|
|
this.keySchedule = void 0,
|
|
this.invKeySchedule = void 0,
|
|
this.initTable()
|
|
}
|
|
var t = e.prototype;
|
|
return t.uint8ArrayToUint32Array_ = function(e) {
|
|
for (var t = new DataView(e), r = new Uint32Array(4), i = 0; i < 4; i++)
|
|
r[i] = t.getUint32(4 * i);
|
|
return r
|
|
}
|
|
,
|
|
t.initTable = function() {
|
|
var e = this.sBox
|
|
, t = this.invSBox
|
|
, r = this.subMix
|
|
, i = r[0]
|
|
, n = r[1]
|
|
, a = r[2]
|
|
, s = r[3]
|
|
, o = this.invSubMix
|
|
, l = o[0]
|
|
, u = o[1]
|
|
, d = o[2]
|
|
, h = o[3]
|
|
, f = new Uint32Array(256)
|
|
, c = 0
|
|
, g = 0
|
|
, v = 0;
|
|
for (v = 0; v < 256; v++)
|
|
f[v] = v < 128 ? v << 1 : v << 1 ^ 283;
|
|
for (v = 0; v < 256; v++) {
|
|
var m = g ^ g << 1 ^ g << 2 ^ g << 3 ^ g << 4;
|
|
m = m >>> 8 ^ 255 & m ^ 99,
|
|
e[c] = m,
|
|
t[m] = c;
|
|
var p = f[c]
|
|
, y = f[p]
|
|
, E = f[y]
|
|
, T = 257 * f[m] ^ 16843008 * m;
|
|
i[c] = T << 24 | T >>> 8,
|
|
n[c] = T << 16 | T >>> 16,
|
|
a[c] = T << 8 | T >>> 24,
|
|
s[c] = T,
|
|
T = 16843009 * E ^ 65537 * y ^ 257 * p ^ 16843008 * c,
|
|
l[m] = T << 24 | T >>> 8,
|
|
u[m] = T << 16 | T >>> 16,
|
|
d[m] = T << 8 | T >>> 24,
|
|
h[m] = T,
|
|
c ? (c = p ^ f[f[f[E ^ p]]],
|
|
g ^= f[f[g]]) : c = g = 1
|
|
}
|
|
}
|
|
,
|
|
t.expandKey = function(e) {
|
|
for (var t = this.uint8ArrayToUint32Array_(e), r = !0, i = 0; i < t.length && r; )
|
|
r = t[i] === this.key[i],
|
|
i++;
|
|
if (!r) {
|
|
this.key = t;
|
|
var n = this.keySize = t.length;
|
|
if (4 !== n && 6 !== n && 8 !== n)
|
|
throw new Error("Invalid aes key size=" + n);
|
|
var a, s, o, l, u = this.ksRows = 4 * (n + 6 + 1), d = this.keySchedule = new Uint32Array(u), h = this.invKeySchedule = new Uint32Array(u), f = this.sBox, c = this.rcon, g = this.invSubMix, v = g[0], m = g[1], p = g[2], y = g[3];
|
|
for (a = 0; a < u; a++)
|
|
a < n ? o = d[a] = t[a] : (l = o,
|
|
a % n == 0 ? (l = f[(l = l << 8 | l >>> 24) >>> 24] << 24 | f[l >>> 16 & 255] << 16 | f[l >>> 8 & 255] << 8 | f[255 & l],
|
|
l ^= c[a / n | 0] << 24) : n > 6 && a % n == 4 && (l = f[l >>> 24] << 24 | f[l >>> 16 & 255] << 16 | f[l >>> 8 & 255] << 8 | f[255 & l]),
|
|
d[a] = o = (d[a - n] ^ l) >>> 0);
|
|
for (s = 0; s < u; s++)
|
|
a = u - s,
|
|
l = 3 & s ? d[a] : d[a - 4],
|
|
h[s] = s < 4 || a <= 4 ? l : v[f[l >>> 24]] ^ m[f[l >>> 16 & 255]] ^ p[f[l >>> 8 & 255]] ^ y[f[255 & l]],
|
|
h[s] = h[s] >>> 0
|
|
}
|
|
}
|
|
,
|
|
t.networkToHostOrderSwap = function(e) {
|
|
return e << 24 | (65280 & e) << 8 | (16711680 & e) >> 8 | e >>> 24
|
|
}
|
|
,
|
|
t.decrypt = function(e, t, r) {
|
|
for (var i, n, a, s, o, l, u, d, h, f, c, g, v, m, p = this.keySize + 6, y = this.invKeySchedule, E = this.invSBox, T = this.invSubMix, S = T[0], A = T[1], L = T[2], I = T[3], R = this.uint8ArrayToUint32Array_(r), k = R[0], b = R[1], D = R[2], _ = R[3], P = new Int32Array(e), C = new Int32Array(P.length), w = this.networkToHostOrderSwap; t < P.length; ) {
|
|
for (h = w(P[t]),
|
|
f = w(P[t + 1]),
|
|
c = w(P[t + 2]),
|
|
g = w(P[t + 3]),
|
|
o = h ^ y[0],
|
|
l = g ^ y[1],
|
|
u = c ^ y[2],
|
|
d = f ^ y[3],
|
|
v = 4,
|
|
m = 1; m < p; m++)
|
|
i = S[o >>> 24] ^ A[l >> 16 & 255] ^ L[u >> 8 & 255] ^ I[255 & d] ^ y[v],
|
|
n = S[l >>> 24] ^ A[u >> 16 & 255] ^ L[d >> 8 & 255] ^ I[255 & o] ^ y[v + 1],
|
|
a = S[u >>> 24] ^ A[d >> 16 & 255] ^ L[o >> 8 & 255] ^ I[255 & l] ^ y[v + 2],
|
|
s = S[d >>> 24] ^ A[o >> 16 & 255] ^ L[l >> 8 & 255] ^ I[255 & u] ^ y[v + 3],
|
|
o = i,
|
|
l = n,
|
|
u = a,
|
|
d = s,
|
|
v += 4;
|
|
i = E[o >>> 24] << 24 ^ E[l >> 16 & 255] << 16 ^ E[u >> 8 & 255] << 8 ^ E[255 & d] ^ y[v],
|
|
n = E[l >>> 24] << 24 ^ E[u >> 16 & 255] << 16 ^ E[d >> 8 & 255] << 8 ^ E[255 & o] ^ y[v + 1],
|
|
a = E[u >>> 24] << 24 ^ E[d >> 16 & 255] << 16 ^ E[o >> 8 & 255] << 8 ^ E[255 & l] ^ y[v + 2],
|
|
s = E[d >>> 24] << 24 ^ E[o >> 16 & 255] << 16 ^ E[l >> 8 & 255] << 8 ^ E[255 & u] ^ y[v + 3],
|
|
C[t] = w(i ^ k),
|
|
C[t + 1] = w(s ^ b),
|
|
C[t + 2] = w(a ^ D),
|
|
C[t + 3] = w(n ^ _),
|
|
k = h,
|
|
b = f,
|
|
D = c,
|
|
_ = g,
|
|
t += 4
|
|
}
|
|
return C.buffer
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, Jt = function() {
|
|
function e(e, t, r) {
|
|
this.subtle = void 0,
|
|
this.key = void 0,
|
|
this.aesMode = void 0,
|
|
this.subtle = e,
|
|
this.key = t,
|
|
this.aesMode = r
|
|
}
|
|
return e.prototype.expandKey = function() {
|
|
var e = function(e) {
|
|
switch (e) {
|
|
case Qt:
|
|
return "AES-CBC";
|
|
case zt:
|
|
return "AES-CTR";
|
|
default:
|
|
throw new Error("[FastAESKey] invalid aes mode " + e)
|
|
}
|
|
}(this.aesMode);
|
|
return this.subtle.importKey("raw", this.key, {
|
|
name: e
|
|
}, !1, ["encrypt", "decrypt"])
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, er = function() {
|
|
function e(e, t) {
|
|
var r = (void 0 === t ? {} : t).removePKCS7Padding
|
|
, i = void 0 === r || r;
|
|
if (this.logEnabled = !0,
|
|
this.removePKCS7Padding = void 0,
|
|
this.subtle = null,
|
|
this.softwareDecrypter = null,
|
|
this.key = null,
|
|
this.fastAesKey = null,
|
|
this.remainderData = null,
|
|
this.currentIV = null,
|
|
this.currentResult = null,
|
|
this.useSoftware = void 0,
|
|
this.enableSoftwareAES = void 0,
|
|
this.enableSoftwareAES = e.enableSoftwareAES,
|
|
this.removePKCS7Padding = i,
|
|
i)
|
|
try {
|
|
var n = self.crypto;
|
|
n && (this.subtle = n.subtle || n.webkitSubtle)
|
|
} catch (e) {}
|
|
this.useSoftware = !this.subtle
|
|
}
|
|
var t = e.prototype;
|
|
return t.destroy = function() {
|
|
this.subtle = null,
|
|
this.softwareDecrypter = null,
|
|
this.key = null,
|
|
this.fastAesKey = null,
|
|
this.remainderData = null,
|
|
this.currentIV = null,
|
|
this.currentResult = null
|
|
}
|
|
,
|
|
t.isSync = function() {
|
|
return this.useSoftware
|
|
}
|
|
,
|
|
t.flush = function() {
|
|
var e = this.currentResult
|
|
, t = this.remainderData;
|
|
if (!e || t)
|
|
return this.reset(),
|
|
null;
|
|
var r, i, n, a = new Uint8Array(e);
|
|
return this.reset(),
|
|
this.removePKCS7Padding ? (i = (r = a).byteLength,
|
|
(n = i && new DataView(r.buffer).getUint8(i - 1)) ? r.slice(0, i - n) : r) : a
|
|
}
|
|
,
|
|
t.reset = function() {
|
|
this.currentResult = null,
|
|
this.currentIV = null,
|
|
this.remainderData = null,
|
|
this.softwareDecrypter && (this.softwareDecrypter = null)
|
|
}
|
|
,
|
|
t.decrypt = function(e, t, r, i) {
|
|
var n = this;
|
|
return this.useSoftware ? new Promise((function(a, s) {
|
|
var o = ArrayBuffer.isView(e) ? e : new Uint8Array(e);
|
|
n.softwareDecrypt(o, t, r, i);
|
|
var l = n.flush();
|
|
l ? a(l.buffer) : s(new Error("[softwareDecrypt] Failed to decrypt data"))
|
|
}
|
|
)) : this.webCryptoDecrypt(new Uint8Array(e), t, r, i)
|
|
}
|
|
,
|
|
t.softwareDecrypt = function(e, t, r, i) {
|
|
var n = this.currentIV
|
|
, a = this.currentResult
|
|
, s = this.remainderData;
|
|
if (i !== Qt || 16 !== t.byteLength)
|
|
return Y.warn("SoftwareDecrypt: can only handle AES-128-CBC"),
|
|
null;
|
|
this.logOnce("JS AES decrypt"),
|
|
s && (e = Ae(s, e),
|
|
this.remainderData = null);
|
|
var o = this.getValidChunk(e);
|
|
if (!o.length)
|
|
return null;
|
|
n && (r = n);
|
|
var l = this.softwareDecrypter;
|
|
l || (l = this.softwareDecrypter = new Zt),
|
|
l.expandKey(t);
|
|
var u = a;
|
|
return this.currentResult = l.decrypt(o.buffer, 0, r),
|
|
this.currentIV = o.slice(-16).buffer,
|
|
u || null
|
|
}
|
|
,
|
|
t.webCryptoDecrypt = function(e, t, r, i) {
|
|
var n = this;
|
|
if (this.key !== t || !this.fastAesKey) {
|
|
if (!this.subtle)
|
|
return Promise.resolve(this.onWebCryptoError(e, t, r, i));
|
|
this.key = t,
|
|
this.fastAesKey = new Jt(this.subtle,t,i)
|
|
}
|
|
return this.fastAesKey.expandKey().then((function(t) {
|
|
return n.subtle ? (n.logOnce("WebCrypto AES decrypt"),
|
|
new $t(n.subtle,new Uint8Array(r),i).decrypt(e.buffer, t)) : Promise.reject(new Error("web crypto not initialized"))
|
|
}
|
|
)).catch((function(a) {
|
|
return Y.warn("[decrypter]: WebCrypto Error, disable WebCrypto API, " + a.name + ": " + a.message),
|
|
n.onWebCryptoError(e, t, r, i)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t.onWebCryptoError = function(e, t, r, i) {
|
|
var n = this.enableSoftwareAES;
|
|
if (n) {
|
|
this.useSoftware = !0,
|
|
this.logEnabled = !0,
|
|
this.softwareDecrypt(e, t, r, i);
|
|
var a = this.flush();
|
|
if (a)
|
|
return a.buffer
|
|
}
|
|
throw new Error("WebCrypto" + (n ? " and softwareDecrypt" : "") + ": failed to decrypt data")
|
|
}
|
|
,
|
|
t.getValidChunk = function(e) {
|
|
var t = e
|
|
, r = e.length - e.length % 16;
|
|
return r !== e.length && (t = e.slice(0, r),
|
|
this.remainderData = e.slice(r)),
|
|
t
|
|
}
|
|
,
|
|
t.logOnce = function(e) {
|
|
this.logEnabled && (Y.log("[decrypter]: " + e),
|
|
this.logEnabled = !1)
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, tr = Math.pow(2, 17)
|
|
, rr = function() {
|
|
function e(e) {
|
|
this.config = void 0,
|
|
this.loader = null,
|
|
this.partLoadTimeout = -1,
|
|
this.config = e
|
|
}
|
|
var t = e.prototype;
|
|
return t.destroy = function() {
|
|
this.loader && (this.loader.destroy(),
|
|
this.loader = null)
|
|
}
|
|
,
|
|
t.abort = function() {
|
|
this.loader && this.loader.abort()
|
|
}
|
|
,
|
|
t.load = function(e, t) {
|
|
var r = this
|
|
, i = e.url;
|
|
if (!i)
|
|
return Promise.reject(new ar({
|
|
type: R.NETWORK_ERROR,
|
|
details: k.FRAG_LOAD_ERROR,
|
|
fatal: !1,
|
|
frag: e,
|
|
error: new Error("Fragment does not have a " + (i ? "part list" : "url")),
|
|
networkDetails: null
|
|
}));
|
|
this.abort();
|
|
var n = this.config
|
|
, a = n.fLoader
|
|
, s = n.loader;
|
|
return new Promise((function(o, l) {
|
|
if (r.loader && r.loader.destroy(),
|
|
e.gap) {
|
|
if (e.tagList.some((function(e) {
|
|
return "GAP" === e[0]
|
|
}
|
|
)))
|
|
return void l(nr(e));
|
|
e.gap = !1
|
|
}
|
|
var u = r.loader = a ? new a(n) : new s(n)
|
|
, h = ir(e);
|
|
e.loader = u;
|
|
var f = Dt(n.fragLoadPolicy.default)
|
|
, c = {
|
|
loadPolicy: f,
|
|
timeout: f.maxLoadTimeMs,
|
|
maxRetry: 0,
|
|
retryDelay: 0,
|
|
maxRetryDelay: 0,
|
|
highWaterMark: "initSegment" === e.sn ? 1 / 0 : tr
|
|
};
|
|
e.stats = u.stats;
|
|
var g = {
|
|
onSuccess: function(t, i, n, a) {
|
|
r.resetLoader(e, u);
|
|
var s = t.data;
|
|
n.resetIV && e.decryptdata && (e.decryptdata.iv = new Uint8Array(s.slice(0, 16)),
|
|
s = s.slice(16)),
|
|
o({
|
|
frag: e,
|
|
part: null,
|
|
payload: s,
|
|
networkDetails: a
|
|
})
|
|
},
|
|
onError: function(t, n, a, s) {
|
|
r.resetLoader(e, u),
|
|
l(new ar({
|
|
type: R.NETWORK_ERROR,
|
|
details: k.FRAG_LOAD_ERROR,
|
|
fatal: !1,
|
|
frag: e,
|
|
response: d({
|
|
url: i,
|
|
data: void 0
|
|
}, t),
|
|
error: new Error("HTTP Error " + t.code + " " + t.text),
|
|
networkDetails: a,
|
|
stats: s
|
|
}))
|
|
},
|
|
onAbort: function(t, i, n) {
|
|
r.resetLoader(e, u),
|
|
l(new ar({
|
|
type: R.NETWORK_ERROR,
|
|
details: k.INTERNAL_ABORTED,
|
|
fatal: !1,
|
|
frag: e,
|
|
error: new Error("Aborted"),
|
|
networkDetails: n,
|
|
stats: t
|
|
}))
|
|
},
|
|
onTimeout: function(t, i, n) {
|
|
r.resetLoader(e, u),
|
|
l(new ar({
|
|
type: R.NETWORK_ERROR,
|
|
details: k.FRAG_LOAD_TIMEOUT,
|
|
fatal: !1,
|
|
frag: e,
|
|
error: new Error("Timeout after " + c.timeout + "ms"),
|
|
networkDetails: n,
|
|
stats: t
|
|
}))
|
|
}
|
|
};
|
|
t && (g.onProgress = function(r, i, n, a) {
|
|
return t({
|
|
frag: e,
|
|
part: null,
|
|
payload: n,
|
|
networkDetails: a
|
|
})
|
|
}
|
|
),
|
|
u.load(h, c, g)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t.loadPart = function(e, t, r) {
|
|
var i = this;
|
|
this.abort();
|
|
var n = this.config
|
|
, a = n.fLoader
|
|
, s = n.loader;
|
|
return new Promise((function(o, l) {
|
|
if (i.loader && i.loader.destroy(),
|
|
e.gap || t.gap)
|
|
l(nr(e, t));
|
|
else {
|
|
var u = i.loader = a ? new a(n) : new s(n)
|
|
, h = ir(e, t);
|
|
e.loader = u;
|
|
var f = Dt(n.fragLoadPolicy.default)
|
|
, c = {
|
|
loadPolicy: f,
|
|
timeout: f.maxLoadTimeMs,
|
|
maxRetry: 0,
|
|
retryDelay: 0,
|
|
maxRetryDelay: 0,
|
|
highWaterMark: tr
|
|
};
|
|
t.stats = u.stats,
|
|
u.load(h, c, {
|
|
onSuccess: function(n, a, s, l) {
|
|
i.resetLoader(e, u),
|
|
i.updateStatsFromPart(e, t);
|
|
var d = {
|
|
frag: e,
|
|
part: t,
|
|
payload: n.data,
|
|
networkDetails: l
|
|
};
|
|
r(d),
|
|
o(d)
|
|
},
|
|
onError: function(r, n, a, s) {
|
|
i.resetLoader(e, u),
|
|
l(new ar({
|
|
type: R.NETWORK_ERROR,
|
|
details: k.FRAG_LOAD_ERROR,
|
|
fatal: !1,
|
|
frag: e,
|
|
part: t,
|
|
response: d({
|
|
url: h.url,
|
|
data: void 0
|
|
}, r),
|
|
error: new Error("HTTP Error " + r.code + " " + r.text),
|
|
networkDetails: a,
|
|
stats: s
|
|
}))
|
|
},
|
|
onAbort: function(r, n, a) {
|
|
e.stats.aborted = t.stats.aborted,
|
|
i.resetLoader(e, u),
|
|
l(new ar({
|
|
type: R.NETWORK_ERROR,
|
|
details: k.INTERNAL_ABORTED,
|
|
fatal: !1,
|
|
frag: e,
|
|
part: t,
|
|
error: new Error("Aborted"),
|
|
networkDetails: a,
|
|
stats: r
|
|
}))
|
|
},
|
|
onTimeout: function(r, n, a) {
|
|
i.resetLoader(e, u),
|
|
l(new ar({
|
|
type: R.NETWORK_ERROR,
|
|
details: k.FRAG_LOAD_TIMEOUT,
|
|
fatal: !1,
|
|
frag: e,
|
|
part: t,
|
|
error: new Error("Timeout after " + c.timeout + "ms"),
|
|
networkDetails: a,
|
|
stats: r
|
|
}))
|
|
}
|
|
})
|
|
}
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t.updateStatsFromPart = function(e, t) {
|
|
var r = e.stats
|
|
, i = t.stats
|
|
, n = i.total;
|
|
if (r.loaded += i.loaded,
|
|
n) {
|
|
var a = Math.round(e.duration / t.duration)
|
|
, s = Math.min(Math.round(r.loaded / n), a)
|
|
, o = (a - s) * Math.round(r.loaded / s);
|
|
r.total = r.loaded + o
|
|
} else
|
|
r.total = Math.max(r.loaded, r.total);
|
|
var l = r.loading
|
|
, u = i.loading;
|
|
l.start ? l.first += u.first - u.start : (l.start = u.start,
|
|
l.first = u.first),
|
|
l.end = u.end
|
|
}
|
|
,
|
|
t.resetLoader = function(e, t) {
|
|
e.loader = null,
|
|
this.loader === t && (self.clearTimeout(this.partLoadTimeout),
|
|
this.loader = null),
|
|
t.destroy()
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function ir(e, t) {
|
|
void 0 === t && (t = null);
|
|
var r, i = t || e, n = {
|
|
frag: e,
|
|
part: t,
|
|
responseType: "arraybuffer",
|
|
url: i.url,
|
|
headers: {},
|
|
rangeStart: 0,
|
|
rangeEnd: 0
|
|
}, a = i.byteRangeStartOffset, s = i.byteRangeEndOffset;
|
|
if (A(a) && A(s)) {
|
|
var o, l = a, u = s;
|
|
if ("initSegment" === e.sn && ("AES-128" === (r = null == (o = e.decryptdata) ? void 0 : o.method) || "AES-256" === r)) {
|
|
var d = s - a;
|
|
d % 16 && (u = s + (16 - d % 16)),
|
|
0 !== a && (n.resetIV = !0,
|
|
l = a - 16)
|
|
}
|
|
n.rangeStart = l,
|
|
n.rangeEnd = u
|
|
}
|
|
return n
|
|
}
|
|
function nr(e, t) {
|
|
var r = new Error("GAP " + (e.gap ? "tag" : "attribute") + " found")
|
|
, i = {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.FRAG_GAP,
|
|
fatal: !1,
|
|
frag: e,
|
|
error: r,
|
|
networkDetails: null
|
|
};
|
|
return t && (i.part = t),
|
|
(t || e).stats.aborted = !0,
|
|
new ar(i)
|
|
}
|
|
var ar = function(e) {
|
|
function t(t) {
|
|
var r;
|
|
return (r = e.call(this, t.error.message) || this).data = void 0,
|
|
r.data = t,
|
|
r
|
|
}
|
|
return o(t, e),
|
|
t
|
|
}(c(Error))
|
|
, sr = function(e) {
|
|
function t(t, r) {
|
|
var i;
|
|
return (i = e.call(this, t, r) || this)._boundTick = void 0,
|
|
i._tickTimer = null,
|
|
i._tickInterval = null,
|
|
i._tickCallCount = 0,
|
|
i._boundTick = i.tick.bind(i),
|
|
i
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.destroy = function() {
|
|
this.onHandlerDestroying(),
|
|
this.onHandlerDestroyed()
|
|
}
|
|
,
|
|
r.onHandlerDestroying = function() {
|
|
this.clearNextTick(),
|
|
this.clearInterval()
|
|
}
|
|
,
|
|
r.onHandlerDestroyed = function() {}
|
|
,
|
|
r.hasInterval = function() {
|
|
return !!this._tickInterval
|
|
}
|
|
,
|
|
r.hasNextTick = function() {
|
|
return !!this._tickTimer
|
|
}
|
|
,
|
|
r.setInterval = function(e) {
|
|
return !this._tickInterval && (this._tickCallCount = 0,
|
|
this._tickInterval = self.setInterval(this._boundTick, e),
|
|
!0)
|
|
}
|
|
,
|
|
r.clearInterval = function() {
|
|
return !!this._tickInterval && (self.clearInterval(this._tickInterval),
|
|
this._tickInterval = null,
|
|
!0)
|
|
}
|
|
,
|
|
r.clearNextTick = function() {
|
|
return !!this._tickTimer && (self.clearTimeout(this._tickTimer),
|
|
this._tickTimer = null,
|
|
!0)
|
|
}
|
|
,
|
|
r.tick = function() {
|
|
this._tickCallCount++,
|
|
1 === this._tickCallCount && (this.doTick(),
|
|
this._tickCallCount > 1 && this.tickImmediate(),
|
|
this._tickCallCount = 0)
|
|
}
|
|
,
|
|
r.tickImmediate = function() {
|
|
this.clearNextTick(),
|
|
this._tickTimer = self.setTimeout(this._boundTick, 0)
|
|
}
|
|
,
|
|
r.doTick = function() {}
|
|
,
|
|
t
|
|
}(N)
|
|
, or = function(e, t, r, i, n, a) {
|
|
void 0 === i && (i = 0),
|
|
void 0 === n && (n = -1),
|
|
void 0 === a && (a = !1),
|
|
this.level = void 0,
|
|
this.sn = void 0,
|
|
this.part = void 0,
|
|
this.id = void 0,
|
|
this.size = void 0,
|
|
this.partial = void 0,
|
|
this.transmuxing = {
|
|
start: 0,
|
|
executeStart: 0,
|
|
executeEnd: 0,
|
|
end: 0
|
|
},
|
|
this.buffering = {
|
|
audio: {
|
|
start: 0,
|
|
executeStart: 0,
|
|
executeEnd: 0,
|
|
end: 0
|
|
},
|
|
video: {
|
|
start: 0,
|
|
executeStart: 0,
|
|
executeEnd: 0,
|
|
end: 0
|
|
},
|
|
audiovideo: {
|
|
start: 0,
|
|
executeStart: 0,
|
|
executeEnd: 0,
|
|
end: 0
|
|
}
|
|
},
|
|
this.level = e,
|
|
this.sn = t,
|
|
this.id = r,
|
|
this.size = i,
|
|
this.part = n,
|
|
this.partial = a
|
|
}
|
|
, lr = {
|
|
length: 0,
|
|
start: function() {
|
|
return 0
|
|
},
|
|
end: function() {
|
|
return 0
|
|
}
|
|
}
|
|
, ur = function() {
|
|
function e() {}
|
|
return e.isBuffered = function(t, r) {
|
|
if (t)
|
|
for (var i = e.getBuffered(t), n = i.length; n--; )
|
|
if (r >= i.start(n) && r <= i.end(n))
|
|
return !0;
|
|
return !1
|
|
}
|
|
,
|
|
e.bufferedRanges = function(t) {
|
|
if (t) {
|
|
var r = e.getBuffered(t);
|
|
return e.timeRangesToArray(r)
|
|
}
|
|
return []
|
|
}
|
|
,
|
|
e.timeRangesToArray = function(e) {
|
|
for (var t = [], r = 0; r < e.length; r++)
|
|
t.push({
|
|
start: e.start(r),
|
|
end: e.end(r)
|
|
});
|
|
return t
|
|
}
|
|
,
|
|
e.bufferInfo = function(t, r, i) {
|
|
if (t) {
|
|
var n = e.bufferedRanges(t);
|
|
if (n.length)
|
|
return e.bufferedInfo(n, r, i)
|
|
}
|
|
return {
|
|
len: 0,
|
|
start: r,
|
|
end: r,
|
|
bufferedIndex: -1
|
|
}
|
|
}
|
|
,
|
|
e.bufferedInfo = function(e, t, r) {
|
|
t = Math.max(0, t),
|
|
e.length > 1 && e.sort((function(e, t) {
|
|
return e.start - t.start || t.end - e.end
|
|
}
|
|
));
|
|
var i = -1
|
|
, n = [];
|
|
if (r)
|
|
for (var a = 0; a < e.length; a++) {
|
|
t >= e[a].start && t <= e[a].end && (i = a);
|
|
var s = n.length;
|
|
if (s) {
|
|
var o = n[s - 1].end;
|
|
e[a].start - o < r ? e[a].end > o && (n[s - 1].end = e[a].end) : n.push(e[a])
|
|
} else
|
|
n.push(e[a])
|
|
}
|
|
else
|
|
n = e;
|
|
for (var l, u = 0, d = t, h = t, f = 0; f < n.length; f++) {
|
|
var c = n[f].start
|
|
, g = n[f].end;
|
|
if (-1 === i && t >= c && t <= g && (i = f),
|
|
t + r >= c && t < g)
|
|
d = c,
|
|
u = (h = g) - t;
|
|
else if (t + r < c) {
|
|
l = c;
|
|
break
|
|
}
|
|
}
|
|
return {
|
|
len: u,
|
|
start: d || 0,
|
|
end: h || 0,
|
|
nextStart: l,
|
|
buffered: e,
|
|
bufferedIndex: i
|
|
}
|
|
}
|
|
,
|
|
e.getBuffered = function(e) {
|
|
try {
|
|
return e.buffered || lr
|
|
} catch (e) {
|
|
return Y.log("failed to get media.buffered", e),
|
|
lr
|
|
}
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, dr = /\{\$([a-zA-Z0-9-_]+)\}/g;
|
|
function hr(e) {
|
|
return dr.test(e)
|
|
}
|
|
function fr(e, t) {
|
|
if (null !== e.variableList || e.hasVariableRefs) {
|
|
var r = e.variableList;
|
|
return t.replace(dr, (function(t) {
|
|
var i = t.substring(2, t.length - 1)
|
|
, n = null == r ? void 0 : r[i];
|
|
return void 0 === n ? (e.playlistParsingError || (e.playlistParsingError = new Error('Missing preceding EXT-X-DEFINE tag for Variable Reference: "' + i + '"')),
|
|
t) : n
|
|
}
|
|
))
|
|
}
|
|
return t
|
|
}
|
|
function cr(e, t, r) {
|
|
var i, n, a = e.variableList;
|
|
if (a || (e.variableList = a = {}),
|
|
"QUERYPARAM"in t) {
|
|
i = t.QUERYPARAM;
|
|
try {
|
|
var s = new self.URL(r).searchParams;
|
|
if (!s.has(i))
|
|
throw new Error('"' + i + '" does not match any query parameter in URI: "' + r + '"');
|
|
n = s.get(i)
|
|
} catch (t) {
|
|
e.playlistParsingError || (e.playlistParsingError = new Error("EXT-X-DEFINE QUERYPARAM: " + t.message))
|
|
}
|
|
} else
|
|
i = t.NAME,
|
|
n = t.VALUE;
|
|
i in a ? e.playlistParsingError || (e.playlistParsingError = new Error('EXT-X-DEFINE duplicate Variable Name declarations: "' + i + '"')) : a[i] = n || ""
|
|
}
|
|
function gr(e, t, r) {
|
|
var i = t.IMPORT;
|
|
if (r && i in r) {
|
|
var n = e.variableList;
|
|
n || (e.variableList = n = {}),
|
|
n[i] = r[i]
|
|
} else
|
|
e.playlistParsingError || (e.playlistParsingError = new Error('EXT-X-DEFINE IMPORT attribute not found in Multivariant Playlist: "' + i + '"'))
|
|
}
|
|
var vr = /^(\d+)x(\d+)$/
|
|
, mr = /(.+?)=(".*?"|.*?)(?:,|$)/g
|
|
, pr = function() {
|
|
function e(t, r) {
|
|
"string" == typeof t && (t = e.parseAttrList(t, r)),
|
|
a(this, t)
|
|
}
|
|
var t = e.prototype;
|
|
return t.decimalInteger = function(e) {
|
|
var t = parseInt(this[e], 10);
|
|
return t > Number.MAX_SAFE_INTEGER ? 1 / 0 : t
|
|
}
|
|
,
|
|
t.hexadecimalInteger = function(e) {
|
|
if (this[e]) {
|
|
var t = (this[e] || "0x").slice(2);
|
|
t = (1 & t.length ? "0" : "") + t;
|
|
for (var r = new Uint8Array(t.length / 2), i = 0; i < t.length / 2; i++)
|
|
r[i] = parseInt(t.slice(2 * i, 2 * i + 2), 16);
|
|
return r
|
|
}
|
|
return null
|
|
}
|
|
,
|
|
t.hexadecimalIntegerAsNumber = function(e) {
|
|
var t = parseInt(this[e], 16);
|
|
return t > Number.MAX_SAFE_INTEGER ? 1 / 0 : t
|
|
}
|
|
,
|
|
t.decimalFloatingPoint = function(e) {
|
|
return parseFloat(this[e])
|
|
}
|
|
,
|
|
t.optionalFloat = function(e, t) {
|
|
var r = this[e];
|
|
return r ? parseFloat(r) : t
|
|
}
|
|
,
|
|
t.enumeratedString = function(e) {
|
|
return this[e]
|
|
}
|
|
,
|
|
t.enumeratedStringList = function(e, t) {
|
|
var r = this[e];
|
|
return (r ? r.split(/[ ,]+/) : []).reduce((function(e, t) {
|
|
return e[t.toLowerCase()] = !0,
|
|
e
|
|
}
|
|
), t)
|
|
}
|
|
,
|
|
t.bool = function(e) {
|
|
return "YES" === this[e]
|
|
}
|
|
,
|
|
t.decimalResolution = function(e) {
|
|
var t = vr.exec(this[e]);
|
|
if (null !== t)
|
|
return {
|
|
width: parseInt(t[1], 10),
|
|
height: parseInt(t[2], 10)
|
|
}
|
|
}
|
|
,
|
|
e.parseAttrList = function(e, t) {
|
|
var r, i = {};
|
|
for (mr.lastIndex = 0; null !== (r = mr.exec(e)); ) {
|
|
var n = r[1].trim()
|
|
, a = r[2]
|
|
, s = 0 === a.indexOf('"') && a.lastIndexOf('"') === a.length - 1
|
|
, o = !1;
|
|
if (s)
|
|
a = a.slice(1, -1);
|
|
else
|
|
switch (n) {
|
|
case "IV":
|
|
case "SCTE35-CMD":
|
|
case "SCTE35-IN":
|
|
case "SCTE35-OUT":
|
|
o = !0
|
|
}
|
|
if (t && (s || o))
|
|
a = fr(t, a);
|
|
else if (!o && !s)
|
|
switch (n) {
|
|
case "CLOSED-CAPTIONS":
|
|
if ("NONE" === a)
|
|
break;
|
|
case "ALLOWED-CPC":
|
|
case "CLASS":
|
|
case "ASSOC-LANGUAGE":
|
|
case "AUDIO":
|
|
case "BYTERANGE":
|
|
case "CHANNELS":
|
|
case "CHARACTERISTICS":
|
|
case "CODECS":
|
|
case "DATA-ID":
|
|
case "END-DATE":
|
|
case "GROUP-ID":
|
|
case "ID":
|
|
case "IMPORT":
|
|
case "INSTREAM-ID":
|
|
case "KEYFORMAT":
|
|
case "KEYFORMATVERSIONS":
|
|
case "LANGUAGE":
|
|
case "NAME":
|
|
case "PATHWAY-ID":
|
|
case "QUERYPARAM":
|
|
case "RECENTLY-REMOVED-DATERANGES":
|
|
case "SERVER-URI":
|
|
case "STABLE-RENDITION-ID":
|
|
case "STABLE-VARIANT-ID":
|
|
case "START-DATE":
|
|
case "SUBTITLES":
|
|
case "SUPPLEMENTAL-CODECS":
|
|
case "URI":
|
|
case "VALUE":
|
|
case "VIDEO":
|
|
case "X-ASSET-LIST":
|
|
case "X-ASSET-URI":
|
|
Y.warn(e + ": attribute " + n + " is missing quotes")
|
|
}
|
|
i[n] = a
|
|
}
|
|
return i
|
|
}
|
|
,
|
|
i(e, [{
|
|
key: "clientAttrs",
|
|
get: function() {
|
|
return Object.keys(this).filter((function(e) {
|
|
return "X-" === e.substring(0, 2)
|
|
}
|
|
))
|
|
}
|
|
}])
|
|
}();
|
|
function yr(e) {
|
|
return "SCTE35-OUT" === e || "SCTE35-IN" === e || "SCTE35-CMD" === e
|
|
}
|
|
var Er = function() {
|
|
return i((function(e, t, r) {
|
|
var i;
|
|
if (void 0 === r && (r = 0),
|
|
this.attr = void 0,
|
|
this.tagAnchor = void 0,
|
|
this.tagOrder = void 0,
|
|
this._startDate = void 0,
|
|
this._endDate = void 0,
|
|
this._dateAtEnd = void 0,
|
|
this._cue = void 0,
|
|
this._badValueForSameId = void 0,
|
|
this.tagAnchor = (null == t ? void 0 : t.tagAnchor) || null,
|
|
this.tagOrder = null != (i = null == t ? void 0 : t.tagOrder) ? i : r,
|
|
t) {
|
|
var n = t.attr;
|
|
for (var s in n)
|
|
if (Object.prototype.hasOwnProperty.call(e, s) && e[s] !== n[s]) {
|
|
Y.warn('DATERANGE tag attribute: "' + s + '" does not match for tags with ID: "' + e.ID + '"'),
|
|
this._badValueForSameId = s;
|
|
break
|
|
}
|
|
e = a(new pr({}), n, e)
|
|
}
|
|
if (this.attr = e,
|
|
t ? (this._startDate = t._startDate,
|
|
this._cue = t._cue,
|
|
this._endDate = t._endDate,
|
|
this._dateAtEnd = t._dateAtEnd) : this._startDate = new Date(e["START-DATE"]),
|
|
"END-DATE"in this.attr) {
|
|
var o = (null == t ? void 0 : t.endDate) || new Date(this.attr["END-DATE"]);
|
|
A(o.getTime()) && (this._endDate = o)
|
|
}
|
|
}
|
|
), [{
|
|
key: "id",
|
|
get: function() {
|
|
return this.attr.ID
|
|
}
|
|
}, {
|
|
key: "class",
|
|
get: function() {
|
|
return this.attr.CLASS
|
|
}
|
|
}, {
|
|
key: "cue",
|
|
get: function() {
|
|
var e = this._cue;
|
|
return void 0 === e ? this._cue = this.attr.enumeratedStringList(this.attr.CUE ? "CUE" : "X-CUE", {
|
|
pre: !1,
|
|
post: !1,
|
|
once: !1
|
|
}) : e
|
|
}
|
|
}, {
|
|
key: "startTime",
|
|
get: function() {
|
|
var e = this.tagAnchor;
|
|
return null === e || null === e.programDateTime ? (Y.warn('Expected tagAnchor Fragment with PDT set for DateRange "' + this.id + '": ' + e),
|
|
NaN) : e.start + (this.startDate.getTime() - e.programDateTime) / 1e3
|
|
}
|
|
}, {
|
|
key: "startDate",
|
|
get: function() {
|
|
return this._startDate
|
|
}
|
|
}, {
|
|
key: "endDate",
|
|
get: function() {
|
|
var e = this._endDate || this._dateAtEnd;
|
|
if (e)
|
|
return e;
|
|
var t = this.duration;
|
|
return null !== t ? this._dateAtEnd = new Date(this._startDate.getTime() + 1e3 * t) : null
|
|
}
|
|
}, {
|
|
key: "duration",
|
|
get: function() {
|
|
if ("DURATION"in this.attr) {
|
|
var e = this.attr.decimalFloatingPoint("DURATION");
|
|
if (A(e))
|
|
return e
|
|
} else if (this._endDate)
|
|
return (this._endDate.getTime() - this._startDate.getTime()) / 1e3;
|
|
return null
|
|
}
|
|
}, {
|
|
key: "plannedDuration",
|
|
get: function() {
|
|
return "PLANNED-DURATION"in this.attr ? this.attr.decimalFloatingPoint("PLANNED-DURATION") : null
|
|
}
|
|
}, {
|
|
key: "endOnNext",
|
|
get: function() {
|
|
return this.attr.bool("END-ON-NEXT")
|
|
}
|
|
}, {
|
|
key: "isInterstitial",
|
|
get: function() {
|
|
return "com.apple.hls.interstitial" === this.class
|
|
}
|
|
}, {
|
|
key: "isValid",
|
|
get: function() {
|
|
return !!this.id && !this._badValueForSameId && A(this.startDate.getTime()) && (null === this.duration || this.duration >= 0) && (!this.endOnNext || !!this.class) && (!this.attr.CUE || !this.cue.pre && !this.cue.post || this.cue.pre !== this.cue.post) && (!this.isInterstitial || "X-ASSET-URI"in this.attr || "X-ASSET-LIST"in this.attr)
|
|
}
|
|
}])
|
|
}()
|
|
, Tr = function() {
|
|
function e(e) {
|
|
this.PTSKnown = !1,
|
|
this.alignedSliding = !1,
|
|
this.averagetargetduration = void 0,
|
|
this.endCC = 0,
|
|
this.endSN = 0,
|
|
this.fragments = void 0,
|
|
this.fragmentHint = void 0,
|
|
this.partList = null,
|
|
this.dateRanges = void 0,
|
|
this.dateRangeTagCount = 0,
|
|
this.live = !0,
|
|
this.requestScheduled = -1,
|
|
this.ageHeader = 0,
|
|
this.advancedDateTime = void 0,
|
|
this.updated = !0,
|
|
this.advanced = !0,
|
|
this.misses = 0,
|
|
this.startCC = 0,
|
|
this.startSN = 0,
|
|
this.startTimeOffset = null,
|
|
this.targetduration = 0,
|
|
this.totalduration = 0,
|
|
this.type = null,
|
|
this.url = void 0,
|
|
this.m3u8 = "",
|
|
this.version = null,
|
|
this.canBlockReload = !1,
|
|
this.canSkipUntil = 0,
|
|
this.canSkipDateRanges = !1,
|
|
this.skippedSegments = 0,
|
|
this.recentlyRemovedDateranges = void 0,
|
|
this.partHoldBack = 0,
|
|
this.holdBack = 0,
|
|
this.partTarget = 0,
|
|
this.preloadHint = void 0,
|
|
this.renditionReports = void 0,
|
|
this.tuneInGoal = 0,
|
|
this.deltaUpdateFailed = void 0,
|
|
this.driftStartTime = 0,
|
|
this.driftEndTime = 0,
|
|
this.driftStart = 0,
|
|
this.driftEnd = 0,
|
|
this.encryptedFragments = void 0,
|
|
this.playlistParsingError = null,
|
|
this.variableList = null,
|
|
this.hasVariableRefs = !1,
|
|
this.appliedTimelineOffset = void 0,
|
|
this.fragments = [],
|
|
this.encryptedFragments = [],
|
|
this.dateRanges = {},
|
|
this.url = e
|
|
}
|
|
var t = e.prototype;
|
|
return t.reloaded = function(e) {
|
|
if (!e)
|
|
return this.advanced = !0,
|
|
void (this.updated = !0);
|
|
var t = this.lastPartSn - e.lastPartSn
|
|
, r = this.lastPartIndex - e.lastPartIndex;
|
|
this.updated = this.endSN !== e.endSN || !!r || !!t || !this.live,
|
|
this.advanced = this.endSN > e.endSN || t > 0 || 0 === t && r > 0,
|
|
this.updated || this.advanced ? this.misses = Math.floor(.6 * e.misses) : this.misses = e.misses + 1
|
|
}
|
|
,
|
|
t.hasKey = function(e) {
|
|
return this.encryptedFragments.some((function(t) {
|
|
var r = t.decryptdata;
|
|
return r || (t.setKeyFormat(e.keyFormat),
|
|
r = t.decryptdata),
|
|
!!r && e.matches(r)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
i(e, [{
|
|
key: "hasProgramDateTime",
|
|
get: function() {
|
|
return !!this.fragments.length && A(this.fragments[this.fragments.length - 1].programDateTime)
|
|
}
|
|
}, {
|
|
key: "levelTargetDuration",
|
|
get: function() {
|
|
return this.averagetargetduration || this.targetduration || 10
|
|
}
|
|
}, {
|
|
key: "drift",
|
|
get: function() {
|
|
var e = this.driftEndTime - this.driftStartTime;
|
|
return e > 0 ? 1e3 * (this.driftEnd - this.driftStart) / e : 1
|
|
}
|
|
}, {
|
|
key: "edge",
|
|
get: function() {
|
|
return this.partEnd || this.fragmentEnd
|
|
}
|
|
}, {
|
|
key: "partEnd",
|
|
get: function() {
|
|
var e;
|
|
return null != (e = this.partList) && e.length ? this.partList[this.partList.length - 1].end : this.fragmentEnd
|
|
}
|
|
}, {
|
|
key: "fragmentEnd",
|
|
get: function() {
|
|
return this.fragments.length ? this.fragments[this.fragments.length - 1].end : 0
|
|
}
|
|
}, {
|
|
key: "fragmentStart",
|
|
get: function() {
|
|
return this.fragments.length ? this.fragments[0].start : 0
|
|
}
|
|
}, {
|
|
key: "age",
|
|
get: function() {
|
|
return this.advancedDateTime ? Math.max(Date.now() - this.advancedDateTime, 0) / 1e3 : 0
|
|
}
|
|
}, {
|
|
key: "lastPartIndex",
|
|
get: function() {
|
|
var e;
|
|
return null != (e = this.partList) && e.length ? this.partList[this.partList.length - 1].index : -1
|
|
}
|
|
}, {
|
|
key: "maxPartIndex",
|
|
get: function() {
|
|
var e = this.partList;
|
|
if (e) {
|
|
var t = this.lastPartIndex;
|
|
if (-1 !== t) {
|
|
for (var r = e.length; r--; )
|
|
if (e[r].index > t)
|
|
return e[r].index;
|
|
return t
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
}, {
|
|
key: "lastPartSn",
|
|
get: function() {
|
|
var e;
|
|
return null != (e = this.partList) && e.length ? this.partList[this.partList.length - 1].fragment.sn : this.endSN
|
|
}
|
|
}, {
|
|
key: "expired",
|
|
get: function() {
|
|
if (this.live && this.age && this.misses < 3) {
|
|
var e = this.partEnd - this.fragmentStart;
|
|
return this.age > Math.max(e, this.totalduration) + this.levelTargetDuration
|
|
}
|
|
return !1
|
|
}
|
|
}])
|
|
}();
|
|
function Sr(e, t) {
|
|
return e.length === t.length && !e.some((function(e, r) {
|
|
return e !== t[r]
|
|
}
|
|
))
|
|
}
|
|
function Ar(e, t) {
|
|
return !e && !t || !(!e || !t) && Sr(e, t)
|
|
}
|
|
function Lr(e) {
|
|
return "AES-128" === e || "AES-256" === e || "AES-256-CTR" === e
|
|
}
|
|
function Ir(e) {
|
|
switch (e) {
|
|
case "AES-128":
|
|
case "AES-256":
|
|
return Qt;
|
|
case "AES-256-CTR":
|
|
return zt;
|
|
default:
|
|
throw new Error("invalid full segment method " + e)
|
|
}
|
|
}
|
|
function Rr(e) {
|
|
return Uint8Array.from(atob(e), (function(e) {
|
|
return e.charCodeAt(0)
|
|
}
|
|
))
|
|
}
|
|
function kr(e) {
|
|
return Uint8Array.from(unescape(encodeURIComponent(e)), (function(e) {
|
|
return e.charCodeAt(0)
|
|
}
|
|
))
|
|
}
|
|
function br(e) {
|
|
var t = function(e, t, r) {
|
|
var i = e[t];
|
|
e[t] = e[r],
|
|
e[r] = i
|
|
};
|
|
t(e, 0, 3),
|
|
t(e, 1, 2),
|
|
t(e, 4, 5),
|
|
t(e, 6, 7)
|
|
}
|
|
function Dr(e) {
|
|
var t, r, i = e.split(":"), n = null;
|
|
if ("data" === i[0] && 2 === i.length) {
|
|
var a = i[1].split(";")
|
|
, s = a[a.length - 1].split(",");
|
|
if (2 === s.length) {
|
|
var o = "base64" === s[0]
|
|
, l = s[1];
|
|
o ? (a.splice(-1, 1),
|
|
n = Rr(l)) : (t = kr(l).subarray(0, 16),
|
|
(r = new Uint8Array(16)).set(t, 16 - t.length),
|
|
n = r)
|
|
}
|
|
}
|
|
return n
|
|
}
|
|
var _r = "undefined" != typeof self ? self : void 0
|
|
, Pr = {
|
|
CLEARKEY: "org.w3.clearkey",
|
|
FAIRPLAY: "com.apple.fps",
|
|
PLAYREADY: "com.microsoft.playready",
|
|
WIDEVINE: "com.widevine.alpha"
|
|
}
|
|
, Cr = "org.w3.clearkey"
|
|
, wr = "com.apple.streamingkeydelivery"
|
|
, Or = "com.microsoft.playready"
|
|
, xr = "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed";
|
|
function Mr(e) {
|
|
switch (e) {
|
|
case wr:
|
|
return Pr.FAIRPLAY;
|
|
case Or:
|
|
return Pr.PLAYREADY;
|
|
case xr:
|
|
return Pr.WIDEVINE;
|
|
case Cr:
|
|
return Pr.CLEARKEY
|
|
}
|
|
}
|
|
function Fr(e) {
|
|
switch (e) {
|
|
case Pr.FAIRPLAY:
|
|
return wr;
|
|
case Pr.PLAYREADY:
|
|
return Or;
|
|
case Pr.WIDEVINE:
|
|
return xr;
|
|
case Pr.CLEARKEY:
|
|
return Cr
|
|
}
|
|
}
|
|
function Nr(e) {
|
|
var t = e.drmSystems
|
|
, r = e.widevineLicenseUrl
|
|
, i = t ? [Pr.FAIRPLAY, Pr.WIDEVINE, Pr.PLAYREADY, Pr.CLEARKEY].filter((function(e) {
|
|
return !!t[e]
|
|
}
|
|
)) : [];
|
|
return !i[Pr.WIDEVINE] && r && i.push(Pr.WIDEVINE),
|
|
i
|
|
}
|
|
var Ur, Br = null != _r && null != (Ur = _r.navigator) && Ur.requestMediaKeySystemAccess ? self.navigator.requestMediaKeySystemAccess.bind(self.navigator) : null, Gr = {}, Kr = function() {
|
|
function e(e, t, r, i, n, a) {
|
|
void 0 === i && (i = [1]),
|
|
void 0 === n && (n = null),
|
|
this.uri = void 0,
|
|
this.method = void 0,
|
|
this.keyFormat = void 0,
|
|
this.keyFormatVersions = void 0,
|
|
this.encrypted = void 0,
|
|
this.isCommonEncryption = void 0,
|
|
this.iv = null,
|
|
this.key = null,
|
|
this.keyId = null,
|
|
this.pssh = null,
|
|
this.method = e,
|
|
this.uri = t,
|
|
this.keyFormat = r,
|
|
this.keyFormatVersions = i,
|
|
this.iv = n,
|
|
this.encrypted = !!e && "NONE" !== e,
|
|
this.isCommonEncryption = this.encrypted && !Lr(e),
|
|
null != a && a.startsWith("0x") && (this.keyId = new Uint8Array(Q(a)))
|
|
}
|
|
e.clearKeyUriToKeyIdMap = function() {
|
|
Gr = {}
|
|
}
|
|
,
|
|
e.setKeyIdForUri = function(e, t) {
|
|
Gr[e] = t
|
|
}
|
|
;
|
|
var t = e.prototype;
|
|
return t.matches = function(e) {
|
|
return e.uri === this.uri && e.method === this.method && e.encrypted === this.encrypted && e.keyFormat === this.keyFormat && Sr(e.keyFormatVersions, this.keyFormatVersions) && Ar(e.iv, this.iv) && Ar(e.keyId, this.keyId)
|
|
}
|
|
,
|
|
t.isSupported = function() {
|
|
if (this.method) {
|
|
if (Lr(this.method) || "NONE" === this.method)
|
|
return !0;
|
|
if ("identity" === this.keyFormat)
|
|
return "SAMPLE-AES" === this.method;
|
|
switch (this.keyFormat) {
|
|
case wr:
|
|
case xr:
|
|
case Or:
|
|
case Cr:
|
|
return -1 !== ["SAMPLE-AES", "SAMPLE-AES-CENC", "SAMPLE-AES-CTR"].indexOf(this.method)
|
|
}
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
t.getDecryptData = function(t) {
|
|
if (!this.encrypted || !this.uri)
|
|
return null;
|
|
if (Lr(this.method)) {
|
|
var r = this.iv;
|
|
return r || ("number" != typeof t && (Y.warn('missing IV for initialization segment with method="' + this.method + '" - compliance issue'),
|
|
t = 0),
|
|
r = function(e) {
|
|
for (var t = new Uint8Array(16), r = 12; r < 16; r++)
|
|
t[r] = e >> 8 * (15 - r) & 255;
|
|
return t
|
|
}(t)),
|
|
new e(this.method,this.uri,"identity",this.keyFormatVersions,r)
|
|
}
|
|
if (this.pssh && this.keyId)
|
|
return this;
|
|
var i = Dr(this.uri);
|
|
if (i)
|
|
switch (this.keyFormat) {
|
|
case xr:
|
|
if (this.pssh = i,
|
|
!this.keyId) {
|
|
var n = function(e) {
|
|
var t = [];
|
|
if (e instanceof ArrayBuffer)
|
|
for (var r = e.byteLength, i = 0; i + 32 < r; ) {
|
|
var n = _e(new DataView(e,i));
|
|
t.push(n),
|
|
i += n.size
|
|
}
|
|
return t
|
|
}(i.buffer);
|
|
if (n.length) {
|
|
var a, s = n[0];
|
|
this.keyId = null != (a = s.kids) && a.length ? s.kids[0] : null
|
|
}
|
|
}
|
|
if (!this.keyId) {
|
|
var o = i.length - 22;
|
|
this.keyId = i.subarray(o, o + 16)
|
|
}
|
|
break;
|
|
case Or:
|
|
var l = new Uint8Array([154, 4, 240, 121, 152, 64, 66, 134, 171, 146, 230, 91, 224, 136, 95, 149]);
|
|
this.pssh = De(l, 0, i),
|
|
this.keyId = function(e) {
|
|
var t = new Uint16Array(e.buffer,e.byteOffset,e.byteLength / 2)
|
|
, r = String.fromCharCode.apply(null, Array.from(t))
|
|
, i = r.substring(r.indexOf("<"), r.length)
|
|
, n = (new DOMParser).parseFromString(i, "text/xml").getElementsByTagName("KID")[0];
|
|
if (n) {
|
|
var a = n.childNodes[0] ? n.childNodes[0].nodeValue : n.getAttribute("VALUE");
|
|
if (a) {
|
|
var s = Rr(a).subarray(0, 16);
|
|
return br(s),
|
|
s
|
|
}
|
|
}
|
|
return null
|
|
}(i);
|
|
break;
|
|
default:
|
|
var u = i.subarray(0, 16);
|
|
if (16 !== u.length) {
|
|
var d = new Uint8Array(16);
|
|
d.set(u, 16 - u.length),
|
|
u = d
|
|
}
|
|
this.keyId = u
|
|
}
|
|
if (!this.keyId || 16 !== this.keyId.byteLength) {
|
|
var h = Gr[this.uri];
|
|
if (!h) {
|
|
var f = Object.keys(Gr).length % Number.MAX_SAFE_INTEGER;
|
|
h = new Uint8Array(16),
|
|
new DataView(h.buffer,12,4).setUint32(0, f),
|
|
e.setKeyIdForUri(this.uri, h)
|
|
}
|
|
this.keyId = h
|
|
}
|
|
return this
|
|
}
|
|
,
|
|
e
|
|
}(), Vr = /#EXT-X-STREAM-INF:([^\r\n]*)(?:[\r\n](?:#[^\r\n]*)?)*([^\r\n]+)|#EXT-X-(SESSION-DATA|SESSION-KEY|DEFINE|CONTENT-STEERING|START):([^\r\n]*)[\r\n]+/g, Hr = /#EXT-X-MEDIA:(.*)/g, Yr = /^#EXT(?:INF|-X-TARGETDURATION):/m, Wr = new RegExp([/#EXTINF:\s*(\d*(?:\.\d+)?)(?:,(.*)\s+)?/.source, /(?!#) *(\S[^\r\n]*)/.source, /#.*/.source].join("|"),"g"), jr = new RegExp([/#EXT-X-(PROGRAM-DATE-TIME|BYTERANGE|DATERANGE|DEFINE|KEY|MAP|PART|PART-INF|PLAYLIST-TYPE|PRELOAD-HINT|RENDITION-REPORT|SERVER-CONTROL|SKIP|START):(.+)/.source, /#EXT-X-(BITRATE|DISCONTINUITY-SEQUENCE|MEDIA-SEQUENCE|TARGETDURATION|VERSION): *(\d+)/.source, /#EXT-X-(DISCONTINUITY|ENDLIST|GAP|INDEPENDENT-SEGMENTS)/.source, /(#)([^:]*):(.*)/.source, /(#)(.*)(?:.*)\r?\n?/.source].join("|")), qr = function() {
|
|
function e() {}
|
|
return e.findGroup = function(e, t) {
|
|
for (var r = 0; r < e.length; r++) {
|
|
var i = e[r];
|
|
if (i.id === t)
|
|
return i
|
|
}
|
|
}
|
|
,
|
|
e.resolve = function(e, t) {
|
|
return S.buildAbsoluteURL(t, e, {
|
|
alwaysNormalize: !0
|
|
})
|
|
}
|
|
,
|
|
e.isMediaPlaylist = function(e) {
|
|
return Yr.test(e)
|
|
}
|
|
,
|
|
e.parseMasterPlaylist = function(t, r) {
|
|
var i, n = {
|
|
contentSteering: null,
|
|
levels: [],
|
|
playlistParsingError: null,
|
|
sessionData: null,
|
|
sessionKeys: null,
|
|
startTimeOffset: null,
|
|
variableList: null,
|
|
hasVariableRefs: hr(t)
|
|
}, a = [];
|
|
if (Vr.lastIndex = 0,
|
|
!t.startsWith("#EXTM3U"))
|
|
return n.playlistParsingError = new Error("no EXTM3U delimiter"),
|
|
n;
|
|
for (; null != (i = Vr.exec(t)); )
|
|
if (i[1]) {
|
|
var s, o = new pr(i[1],n), l = fr(n, i[2]), u = {
|
|
attrs: o,
|
|
bitrate: o.decimalInteger("BANDWIDTH") || o.decimalInteger("AVERAGE-BANDWIDTH"),
|
|
name: o.NAME,
|
|
url: e.resolve(l, r)
|
|
}, d = o.decimalResolution("RESOLUTION");
|
|
d && (u.width = d.width,
|
|
u.height = d.height),
|
|
Zr(o.CODECS, u);
|
|
var h = o["SUPPLEMENTAL-CODECS"];
|
|
h && (u.supplemental = {},
|
|
Zr(h, u.supplemental)),
|
|
null != (s = u.unknownCodecs) && s.length || a.push(u),
|
|
n.levels.push(u)
|
|
} else if (i[3]) {
|
|
var f = i[3]
|
|
, c = i[4];
|
|
switch (f) {
|
|
case "SESSION-DATA":
|
|
var g = new pr(c,n)
|
|
, v = g["DATA-ID"];
|
|
v && (null === n.sessionData && (n.sessionData = {}),
|
|
n.sessionData[v] = g);
|
|
break;
|
|
case "SESSION-KEY":
|
|
var m = zr(c, r, n);
|
|
m.encrypted && m.isSupported() ? (null === n.sessionKeys && (n.sessionKeys = []),
|
|
n.sessionKeys.push(m)) : Y.warn('[Keys] Ignoring invalid EXT-X-SESSION-KEY tag: "' + c + '"');
|
|
break;
|
|
case "DEFINE":
|
|
cr(n, new pr(c,n), r);
|
|
break;
|
|
case "CONTENT-STEERING":
|
|
var p = new pr(c,n);
|
|
n.contentSteering = {
|
|
uri: e.resolve(p["SERVER-URI"], r),
|
|
pathwayId: p["PATHWAY-ID"] || "."
|
|
};
|
|
break;
|
|
case "START":
|
|
n.startTimeOffset = $r(c)
|
|
}
|
|
}
|
|
var y = a.length > 0 && a.length < n.levels.length;
|
|
return n.levels = y ? a : n.levels,
|
|
0 === n.levels.length && (n.playlistParsingError = new Error("no levels found in manifest")),
|
|
n
|
|
}
|
|
,
|
|
e.parseMasterPlaylistMedia = function(t, r, i) {
|
|
var n, a = {}, s = i.levels, o = {
|
|
AUDIO: s.map((function(e) {
|
|
return {
|
|
id: e.attrs.AUDIO,
|
|
audioCodec: e.audioCodec
|
|
}
|
|
}
|
|
)),
|
|
SUBTITLES: s.map((function(e) {
|
|
return {
|
|
id: e.attrs.SUBTITLES,
|
|
textCodec: e.textCodec
|
|
}
|
|
}
|
|
)),
|
|
"CLOSED-CAPTIONS": []
|
|
}, l = 0;
|
|
for (Hr.lastIndex = 0; null !== (n = Hr.exec(t)); ) {
|
|
var u = new pr(n[1],i)
|
|
, d = u.TYPE;
|
|
if (d) {
|
|
var h = o[d]
|
|
, f = a[d] || [];
|
|
a[d] = f;
|
|
var c = u.LANGUAGE
|
|
, g = u["ASSOC-LANGUAGE"]
|
|
, v = u.CHANNELS
|
|
, m = u.CHARACTERISTICS
|
|
, p = u["INSTREAM-ID"]
|
|
, y = {
|
|
attrs: u,
|
|
bitrate: 0,
|
|
id: l++,
|
|
groupId: u["GROUP-ID"] || "",
|
|
name: u.NAME || c || "",
|
|
type: d,
|
|
default: u.bool("DEFAULT"),
|
|
autoselect: u.bool("AUTOSELECT"),
|
|
forced: u.bool("FORCED"),
|
|
lang: c,
|
|
url: u.URI ? e.resolve(u.URI, r) : ""
|
|
};
|
|
if (g && (y.assocLang = g),
|
|
v && (y.channels = v),
|
|
m && (y.characteristics = m),
|
|
p && (y.instreamId = p),
|
|
null != h && h.length) {
|
|
var E = e.findGroup(h, y.groupId) || h[0];
|
|
Jr(y, E, "audioCodec"),
|
|
Jr(y, E, "textCodec")
|
|
}
|
|
f.push(y)
|
|
}
|
|
}
|
|
return a
|
|
}
|
|
,
|
|
e.parseLevelPlaylist = function(e, t, r, i, n, s) {
|
|
var o, l, u, d, h, f = {
|
|
url: t
|
|
}, c = new Tr(t), g = c.fragments, v = [], m = null, p = 0, y = 0, E = 0, T = 0, S = 0, L = null, I = new re(i,f), R = -1, k = !1, b = null;
|
|
if (Wr.lastIndex = 0,
|
|
c.m3u8 = e,
|
|
c.hasVariableRefs = hr(e),
|
|
"#EXTM3U" !== (null == (o = Wr.exec(e)) ? void 0 : o[0]))
|
|
return c.playlistParsingError = new Error("Missing format identifier #EXTM3U"),
|
|
c;
|
|
for (; null !== (l = Wr.exec(e)); ) {
|
|
k && (k = !1,
|
|
(I = new re(i,f)).playlistOffset = E,
|
|
I.setStart(E),
|
|
I.sn = p,
|
|
I.cc = T,
|
|
S && (I.bitrate = S),
|
|
I.level = r,
|
|
m && (I.initSegment = m,
|
|
m.rawProgramDateTime && (I.rawProgramDateTime = m.rawProgramDateTime,
|
|
m.rawProgramDateTime = null),
|
|
b && (I.setByteRange(b),
|
|
b = null)));
|
|
var D = l[1];
|
|
if (D) {
|
|
I.duration = parseFloat(D);
|
|
var _ = (" " + l[2]).slice(1);
|
|
I.title = _ || null,
|
|
I.tagList.push(_ ? ["INF", D, _] : ["INF", D])
|
|
} else if (l[3]) {
|
|
if (A(I.duration)) {
|
|
I.playlistOffset = E,
|
|
I.setStart(E),
|
|
d && ri(I, d, c),
|
|
I.sn = p,
|
|
I.level = r,
|
|
I.cc = T,
|
|
g.push(I);
|
|
var P = (" " + l[3]).slice(1);
|
|
I.relurl = fr(c, P),
|
|
ei(I, L, v),
|
|
L = I,
|
|
E += I.duration,
|
|
p++,
|
|
y = 0,
|
|
k = !0
|
|
}
|
|
} else {
|
|
if (!(l = l[0].match(jr))) {
|
|
Y.warn("No matches on slow regex match for level playlist!");
|
|
continue
|
|
}
|
|
for (u = 1; u < l.length && void 0 === l[u]; u++)
|
|
;
|
|
var C = (" " + l[u]).slice(1)
|
|
, w = (" " + l[u + 1]).slice(1)
|
|
, O = l[u + 2] ? (" " + l[u + 2]).slice(1) : null;
|
|
switch (C) {
|
|
case "BYTERANGE":
|
|
L ? I.setByteRange(w, L) : I.setByteRange(w);
|
|
break;
|
|
case "PROGRAM-DATE-TIME":
|
|
I.rawProgramDateTime = w,
|
|
I.tagList.push(["PROGRAM-DATE-TIME", w]),
|
|
-1 === R && (R = g.length);
|
|
break;
|
|
case "PLAYLIST-TYPE":
|
|
c.type && ii(c, C, l),
|
|
c.type = w.toUpperCase();
|
|
break;
|
|
case "MEDIA-SEQUENCE":
|
|
0 !== c.startSN ? ii(c, C, l) : g.length > 0 && ni(c, C, l),
|
|
p = c.startSN = parseInt(w);
|
|
break;
|
|
case "SKIP":
|
|
c.skippedSegments && ii(c, C, l);
|
|
var x = new pr(w,c)
|
|
, M = x.decimalInteger("SKIPPED-SEGMENTS");
|
|
if (A(M)) {
|
|
c.skippedSegments += M;
|
|
for (var F = M; F--; )
|
|
g.push(null);
|
|
p += M
|
|
}
|
|
var N = x.enumeratedString("RECENTLY-REMOVED-DATERANGES");
|
|
N && (c.recentlyRemovedDateranges = (c.recentlyRemovedDateranges || []).concat(N.split("\t")));
|
|
break;
|
|
case "TARGETDURATION":
|
|
0 !== c.targetduration && ii(c, C, l),
|
|
c.targetduration = Math.max(parseInt(w), 1);
|
|
break;
|
|
case "VERSION":
|
|
null !== c.version && ii(c, C, l),
|
|
c.version = parseInt(w);
|
|
break;
|
|
case "INDEPENDENT-SEGMENTS":
|
|
break;
|
|
case "ENDLIST":
|
|
c.live || ii(c, C, l),
|
|
c.live = !1;
|
|
break;
|
|
case "#":
|
|
(w || O) && I.tagList.push(O ? [w, O] : [w]);
|
|
break;
|
|
case "DISCONTINUITY":
|
|
T++,
|
|
I.tagList.push(["DIS"]);
|
|
break;
|
|
case "GAP":
|
|
I.gap = !0,
|
|
I.tagList.push([C]);
|
|
break;
|
|
case "BITRATE":
|
|
I.tagList.push([C, w]),
|
|
S = 1e3 * parseInt(w),
|
|
A(S) ? I.bitrate = S : S = 0;
|
|
break;
|
|
case "DATERANGE":
|
|
var U = new pr(w,c)
|
|
, B = new Er(U,c.dateRanges[U.ID],c.dateRangeTagCount);
|
|
c.dateRangeTagCount++,
|
|
B.isValid || c.skippedSegments ? c.dateRanges[B.id] = B : Y.warn('Ignoring invalid DATERANGE tag: "' + w + '"'),
|
|
I.tagList.push(["EXT-X-DATERANGE", w]);
|
|
break;
|
|
case "DEFINE":
|
|
var G = new pr(w,c);
|
|
"IMPORT"in G ? gr(c, G, s) : cr(c, G, t);
|
|
break;
|
|
case "DISCONTINUITY-SEQUENCE":
|
|
0 !== c.startCC ? ii(c, C, l) : g.length > 0 && ni(c, C, l),
|
|
c.startCC = T = parseInt(w);
|
|
break;
|
|
case "KEY":
|
|
var K = zr(w, t, c);
|
|
if (K.isSupported()) {
|
|
if ("NONE" === K.method) {
|
|
d = void 0;
|
|
break
|
|
}
|
|
d || (d = {});
|
|
var V = d[K.keyFormat];
|
|
null != V && V.matches(K) || (V && (d = a({}, d)),
|
|
d[K.keyFormat] = K)
|
|
} else
|
|
Y.warn('[Keys] Ignoring unsupported EXT-X-KEY tag: "' + w + '"');
|
|
break;
|
|
case "START":
|
|
c.startTimeOffset = $r(w);
|
|
break;
|
|
case "MAP":
|
|
var H = new pr(w,c);
|
|
if (I.duration) {
|
|
var W = new re(i,f);
|
|
ti(W, H, r, d),
|
|
m = W,
|
|
I.initSegment = m,
|
|
m.rawProgramDateTime && !I.rawProgramDateTime && (I.rawProgramDateTime = m.rawProgramDateTime)
|
|
} else {
|
|
var j = I.byteRangeEndOffset;
|
|
if (j) {
|
|
var q = I.byteRangeStartOffset;
|
|
b = j - q + "@" + q
|
|
} else
|
|
b = null;
|
|
ti(I, H, r, d),
|
|
m = I,
|
|
k = !0
|
|
}
|
|
m.cc = T;
|
|
break;
|
|
case "SERVER-CONTROL":
|
|
h && ii(c, C, l),
|
|
h = new pr(w),
|
|
c.canBlockReload = h.bool("CAN-BLOCK-RELOAD"),
|
|
c.canSkipUntil = h.optionalFloat("CAN-SKIP-UNTIL", 0),
|
|
c.canSkipDateRanges = c.canSkipUntil > 0 && h.bool("CAN-SKIP-DATERANGES"),
|
|
c.partHoldBack = h.optionalFloat("PART-HOLD-BACK", 0),
|
|
c.holdBack = h.optionalFloat("HOLD-BACK", 0);
|
|
break;
|
|
case "PART-INF":
|
|
c.partTarget && ii(c, C, l);
|
|
var X = new pr(w);
|
|
c.partTarget = X.decimalFloatingPoint("PART-TARGET");
|
|
break;
|
|
case "PART":
|
|
var Q = c.partList;
|
|
Q || (Q = c.partList = []);
|
|
var z = y > 0 ? Q[Q.length - 1] : void 0
|
|
, $ = y++
|
|
, Z = new pr(w,c)
|
|
, J = new ie(Z,I,f,$,z);
|
|
Q.push(J),
|
|
I.duration += J.duration;
|
|
break;
|
|
case "PRELOAD-HINT":
|
|
var ee = new pr(w,c);
|
|
c.preloadHint = ee;
|
|
break;
|
|
case "RENDITION-REPORT":
|
|
var te = new pr(w,c);
|
|
c.renditionReports = c.renditionReports || [],
|
|
c.renditionReports.push(te);
|
|
break;
|
|
default:
|
|
Y.warn("line parsed but not handled: " + l)
|
|
}
|
|
}
|
|
}
|
|
L && !L.relurl ? (g.pop(),
|
|
E -= L.duration,
|
|
c.partList && (c.fragmentHint = L)) : c.partList && (ei(I, L, v),
|
|
I.cc = T,
|
|
c.fragmentHint = I,
|
|
d && ri(I, d, c)),
|
|
c.targetduration || (c.playlistParsingError = new Error("Missing Target Duration"));
|
|
var ne = g.length
|
|
, ae = g[0]
|
|
, se = g[ne - 1];
|
|
if ((E += c.skippedSegments * c.targetduration) > 0 && ne && se) {
|
|
c.averagetargetduration = E / ne;
|
|
var oe = se.sn;
|
|
c.endSN = "initSegment" !== oe ? oe : 0,
|
|
c.live || (se.endList = !0),
|
|
R > 0 && (function(e, t) {
|
|
for (var r = e[t], i = t; i--; ) {
|
|
var n = e[i];
|
|
if (!n)
|
|
return;
|
|
n.programDateTime = r.programDateTime - 1e3 * n.duration,
|
|
r = n
|
|
}
|
|
}(g, R),
|
|
ae && v.unshift(ae))
|
|
}
|
|
return c.fragmentHint && (E += c.fragmentHint.duration),
|
|
c.totalduration = E,
|
|
v.length && c.dateRangeTagCount && ae && Xr(v, c),
|
|
c.endCC = T,
|
|
c
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function Xr(e, t) {
|
|
var r = e.length;
|
|
if (!r) {
|
|
if (!t.hasProgramDateTime)
|
|
return;
|
|
var i = t.fragments[t.fragments.length - 1];
|
|
e.push(i),
|
|
r++
|
|
}
|
|
for (var n = e[r - 1], a = t.live ? 1 / 0 : t.totalduration, s = Object.keys(t.dateRanges), o = s.length; o--; ) {
|
|
var l = t.dateRanges[s[o]]
|
|
, u = l.startDate.getTime();
|
|
l.tagAnchor = n.ref;
|
|
for (var d = r; d--; ) {
|
|
var h;
|
|
if ((null == (h = e[d]) ? void 0 : h.sn) < t.startSN)
|
|
break;
|
|
var f = Qr(t, u, e, d, a);
|
|
if (-1 !== f) {
|
|
l.tagAnchor = t.fragments[f].ref;
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function Qr(e, t, r, i, n) {
|
|
var a = r[i];
|
|
if (a) {
|
|
var s, o = a.programDateTime;
|
|
if ((t >= o || 0 === i) && t <= o + 1e3 * (((null == (s = r[i + 1]) ? void 0 : s.start) || n) - a.start)) {
|
|
var l = r[i].sn - e.startSN;
|
|
if (l < 0)
|
|
return -1;
|
|
var u = e.fragments;
|
|
if (u.length > r.length)
|
|
for (var d = (r[i + 1] || u[u.length - 1]).sn - e.startSN; d > l; d--) {
|
|
var h = u[d].programDateTime;
|
|
if (t >= h && t < h + 1e3 * u[d].duration)
|
|
return d
|
|
}
|
|
return l
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
function zr(e, t, r) {
|
|
var i, n, a = new pr(e,r), s = null != (i = a.METHOD) ? i : "", o = a.URI, l = a.hexadecimalInteger("IV"), u = a.KEYFORMATVERSIONS, d = null != (n = a.KEYFORMAT) ? n : "identity";
|
|
o && a.IV && !l && Y.error("Invalid IV: " + a.IV);
|
|
var h = o ? qr.resolve(o, t) : ""
|
|
, f = (u || "1").split("/").map(Number).filter(Number.isFinite);
|
|
return new Kr(s,h,d,f,l,a.KEYID)
|
|
}
|
|
function $r(e) {
|
|
var t = new pr(e).decimalFloatingPoint("TIME-OFFSET");
|
|
return A(t) ? t : null
|
|
}
|
|
function Zr(e, t) {
|
|
var r = (e || "").split(/[ ,]+/).filter((function(e) {
|
|
return e
|
|
}
|
|
));
|
|
["video", "audio", "text"].forEach((function(e) {
|
|
var i = r.filter((function(t) {
|
|
return we(t, e)
|
|
}
|
|
));
|
|
i.length && (t[e + "Codec"] = i.map((function(e) {
|
|
return e.split("/")[0]
|
|
}
|
|
)).join(","),
|
|
r = r.filter((function(e) {
|
|
return -1 === i.indexOf(e)
|
|
}
|
|
)))
|
|
}
|
|
)),
|
|
t.unknownCodecs = r
|
|
}
|
|
function Jr(e, t, r) {
|
|
var i = t[r];
|
|
i && (e[r] = i)
|
|
}
|
|
function ei(e, t, r) {
|
|
e.rawProgramDateTime ? r.push(e) : null != t && t.programDateTime && (e.programDateTime = t.endProgramDateTime)
|
|
}
|
|
function ti(e, t, r, i) {
|
|
e.relurl = t.URI,
|
|
t.BYTERANGE && e.setByteRange(t.BYTERANGE),
|
|
e.level = r,
|
|
e.sn = "initSegment",
|
|
i && (e.levelkeys = i),
|
|
e.initSegment = null
|
|
}
|
|
function ri(e, t, r) {
|
|
e.levelkeys = t;
|
|
var i = r.encryptedFragments;
|
|
i.length && i[i.length - 1].levelkeys === t || !Object.keys(t).some((function(e) {
|
|
return t[e].isCommonEncryption
|
|
}
|
|
)) || i.push(e)
|
|
}
|
|
function ii(e, t, r) {
|
|
e.playlistParsingError = new Error("#EXT-X-" + t + " must not appear more than once (" + r[0] + ")")
|
|
}
|
|
function ni(e, t, r) {
|
|
e.playlistParsingError = new Error("#EXT-X-" + t + " must appear before the first Media Segment (" + r[0] + ")")
|
|
}
|
|
function ai(e, t) {
|
|
var r = t.startPTS;
|
|
if (A(r)) {
|
|
var i, n = 0;
|
|
t.sn > e.sn ? (n = r - e.start,
|
|
i = e) : (n = e.start - r,
|
|
i = t),
|
|
i.duration !== n && i.setDuration(n)
|
|
} else
|
|
t.sn > e.sn ? e.cc === t.cc && e.minEndPTS ? t.setStart(e.start + (e.minEndPTS - e.start)) : t.setStart(e.start + e.duration) : t.setStart(Math.max(e.start - t.duration, 0))
|
|
}
|
|
function si(e, t, r, i, n, a, s) {
|
|
i - r <= 0 && (s.warn("Fragment should have a positive duration", t),
|
|
i = r + t.duration,
|
|
a = n + t.duration);
|
|
var o = r
|
|
, l = i
|
|
, u = t.startPTS
|
|
, d = t.endPTS;
|
|
if (A(u)) {
|
|
var h = Math.abs(u - r);
|
|
e && h > e.totalduration ? s.warn("media timestamps and playlist times differ by " + h + "s for level " + t.level + " " + e.url) : A(t.deltaPTS) ? t.deltaPTS = Math.max(h, t.deltaPTS) : t.deltaPTS = h,
|
|
o = Math.max(r, u),
|
|
r = Math.min(r, u),
|
|
n = void 0 !== t.startDTS ? Math.min(n, t.startDTS) : n,
|
|
l = Math.min(i, d),
|
|
i = Math.max(i, d),
|
|
a = void 0 !== t.endDTS ? Math.max(a, t.endDTS) : a
|
|
}
|
|
var f = r - t.start;
|
|
0 !== t.start && t.setStart(r),
|
|
t.setDuration(i - t.start),
|
|
t.startPTS = r,
|
|
t.maxStartPTS = o,
|
|
t.startDTS = n,
|
|
t.endPTS = i,
|
|
t.minEndPTS = l,
|
|
t.endDTS = a;
|
|
var c, g = t.sn;
|
|
if (!e || g < e.startSN || g > e.endSN)
|
|
return 0;
|
|
var v = g - e.startSN
|
|
, m = e.fragments;
|
|
for (m[v] = t,
|
|
c = v; c > 0; c--)
|
|
ai(m[c], m[c - 1]);
|
|
for (c = v; c < m.length - 1; c++)
|
|
ai(m[c], m[c + 1]);
|
|
return e.fragmentHint && ai(m[m.length - 1], e.fragmentHint),
|
|
e.PTSKnown = e.alignedSliding = !0,
|
|
f
|
|
}
|
|
function oi(e, t, r) {
|
|
if (e !== t) {
|
|
for (var i, n = null, s = e.fragments, o = s.length - 1; o >= 0; o--) {
|
|
var l = s[o].initSegment;
|
|
if (l) {
|
|
n = l;
|
|
break
|
|
}
|
|
}
|
|
e.fragmentHint && delete e.fragmentHint.endPTS,
|
|
function(e, t, r) {
|
|
for (var i = t.skippedSegments, n = Math.max(e.startSN, t.startSN) - t.startSN, a = (e.fragmentHint ? 1 : 0) + (i ? t.endSN : Math.min(e.endSN, t.endSN)) - t.startSN, s = t.startSN - e.startSN, o = t.fragmentHint ? t.fragments.concat(t.fragmentHint) : t.fragments, l = e.fragmentHint ? e.fragments.concat(e.fragmentHint) : e.fragments, u = n; u <= a; u++) {
|
|
var d = l[s + u]
|
|
, h = o[u];
|
|
if (i && !h && d && (h = t.fragments[u] = d),
|
|
d && h) {
|
|
r(d, h, u, o);
|
|
var f = d.relurl
|
|
, c = h.relurl;
|
|
if (f && mi(f, c))
|
|
return void (t.playlistParsingError = li("media sequence mismatch " + h.sn + ":", e, t, 0, h));
|
|
if (d.cc !== h.cc)
|
|
return void (t.playlistParsingError = li("discontinuity sequence mismatch (" + d.cc + "!=" + h.cc + ")", e, t, 0, h))
|
|
}
|
|
}
|
|
}(e, t, (function(e, r, a, s) {
|
|
if ((!t.startCC || t.skippedSegments) && r.cc !== e.cc) {
|
|
for (var o = e.cc - r.cc, l = a; l < s.length; l++)
|
|
s[l].cc += o;
|
|
t.endCC = s[s.length - 1].cc
|
|
}
|
|
A(e.startPTS) && A(e.endPTS) && (r.setStart(r.startPTS = e.startPTS),
|
|
r.startDTS = e.startDTS,
|
|
r.maxStartPTS = e.maxStartPTS,
|
|
r.endPTS = e.endPTS,
|
|
r.endDTS = e.endDTS,
|
|
r.minEndPTS = e.minEndPTS,
|
|
r.setDuration(e.endPTS - e.startPTS),
|
|
r.duration && (i = r),
|
|
t.PTSKnown = t.alignedSliding = !0),
|
|
e.hasStreams && (r.elementaryStreams = e.elementaryStreams),
|
|
r.loader = e.loader,
|
|
e.hasStats && (r.stats = e.stats),
|
|
e.initSegment && (r.initSegment = e.initSegment,
|
|
n = e.initSegment)
|
|
}
|
|
));
|
|
var u = t.fragments
|
|
, d = t.fragmentHint ? u.concat(t.fragmentHint) : u;
|
|
if (n && d.forEach((function(e) {
|
|
var t;
|
|
!e || e.initSegment && e.initSegment.relurl !== (null == (t = n) ? void 0 : t.relurl) || (e.initSegment = n)
|
|
}
|
|
)),
|
|
t.skippedSegments) {
|
|
if (t.deltaUpdateFailed = u.some((function(e) {
|
|
return !e
|
|
}
|
|
)),
|
|
t.deltaUpdateFailed) {
|
|
r.warn("[level-helper] Previous playlist missing segments skipped in delta playlist");
|
|
for (var h = t.skippedSegments; h--; )
|
|
u.shift();
|
|
t.startSN = u[0].sn
|
|
} else {
|
|
t.canSkipDateRanges && (t.dateRanges = function(e, t, r) {
|
|
var i = t.dateRanges
|
|
, n = t.recentlyRemovedDateranges
|
|
, s = a({}, e);
|
|
n && n.forEach((function(e) {
|
|
delete s[e]
|
|
}
|
|
));
|
|
var o = Object.keys(s).length;
|
|
return o ? (Object.keys(i).forEach((function(e) {
|
|
var t = s[e]
|
|
, n = new Er(i[e].attr,t);
|
|
n.isValid ? (s[e] = n,
|
|
t || (n.tagOrder += o)) : r.warn('Ignoring invalid Playlist Delta Update DATERANGE tag: "' + lt(i[e].attr) + '"')
|
|
}
|
|
)),
|
|
s) : i
|
|
}(e.dateRanges, t, r));
|
|
var f = e.fragments.filter((function(e) {
|
|
return e.rawProgramDateTime
|
|
}
|
|
));
|
|
if (e.hasProgramDateTime && !t.hasProgramDateTime)
|
|
for (var c = 1; c < d.length; c++)
|
|
null === d[c].programDateTime && ei(d[c], d[c - 1], f);
|
|
Xr(f, t)
|
|
}
|
|
t.endCC = u[u.length - 1].cc
|
|
}
|
|
if (!t.startCC) {
|
|
var g, v = fi(e, t.startSN - 1);
|
|
t.startCC = null != (g = null == v ? void 0 : v.cc) ? g : u[0].cc
|
|
}
|
|
!function(e, t, r) {
|
|
if (e && t)
|
|
for (var i = 0, n = 0, a = e.length; n <= a; n++) {
|
|
var s = e[n]
|
|
, o = t[n + i];
|
|
s && o && s.index === o.index && s.fragment.sn === o.fragment.sn ? r(s, o) : i--
|
|
}
|
|
}(e.partList, t.partList, (function(e, t) {
|
|
t.elementaryStreams = e.elementaryStreams,
|
|
t.stats = e.stats
|
|
}
|
|
)),
|
|
i ? si(t, i, i.startPTS, i.endPTS, i.startDTS, i.endDTS, r) : ui(e, t),
|
|
u.length && (t.totalduration = t.edge - u[0].start),
|
|
t.driftStartTime = e.driftStartTime,
|
|
t.driftStart = e.driftStart;
|
|
var m = t.advancedDateTime;
|
|
if (t.advanced && m) {
|
|
var p = t.edge;
|
|
t.driftStart || (t.driftStartTime = m,
|
|
t.driftStart = p),
|
|
t.driftEndTime = m,
|
|
t.driftEnd = p
|
|
} else
|
|
t.driftEndTime = e.driftEndTime,
|
|
t.driftEnd = e.driftEnd,
|
|
t.advancedDateTime = e.advancedDateTime;
|
|
-1 === t.requestScheduled && (t.requestScheduled = e.requestScheduled)
|
|
}
|
|
}
|
|
function li(e, t, r, i, n) {
|
|
return new Error(e + " " + n.url + "\nPlaylist starting @" + t.startSN + "\n" + t.m3u8 + "\n\nPlaylist starting @" + r.startSN + "\n" + r.m3u8)
|
|
}
|
|
function ui(e, t, r) {
|
|
void 0 === r && (r = !0);
|
|
var i = t.startSN + t.skippedSegments - e.startSN
|
|
, n = e.fragments
|
|
, a = i >= 0
|
|
, s = 0;
|
|
if (a && i < n.length)
|
|
s = n[i].start;
|
|
else if (a && t.startSN === e.endSN + 1)
|
|
s = e.fragmentEnd;
|
|
else if (a && r)
|
|
s = e.fragmentStart + i * t.levelTargetDuration;
|
|
else {
|
|
if (t.skippedSegments || 0 !== t.fragmentStart)
|
|
return;
|
|
s = e.fragmentStart
|
|
}
|
|
di(t, s)
|
|
}
|
|
function di(e, t) {
|
|
if (t) {
|
|
for (var r = e.fragments, i = e.skippedSegments; i < r.length; i++)
|
|
r[i].addStart(t);
|
|
e.fragmentHint && e.fragmentHint.addStart(t)
|
|
}
|
|
}
|
|
function hi(e, t) {
|
|
void 0 === t && (t = 1 / 0);
|
|
var r = 1e3 * e.targetduration;
|
|
if (e.updated) {
|
|
var i = e.fragments;
|
|
if (i.length && 4 * r > t) {
|
|
var n = 1e3 * i[i.length - 1].duration;
|
|
n < r && (r = n)
|
|
}
|
|
} else
|
|
r /= 2;
|
|
return Math.round(r)
|
|
}
|
|
function fi(e, t, r) {
|
|
if (!e)
|
|
return null;
|
|
var i = e.fragments[t - e.startSN];
|
|
return i || ((i = e.fragmentHint) && i.sn === t ? i : t < e.startSN && r && r.sn === t ? r : null)
|
|
}
|
|
function ci(e, t, r) {
|
|
return e ? gi(e.partList, t, r) : null
|
|
}
|
|
function gi(e, t, r) {
|
|
if (e)
|
|
for (var i = e.length; i--; ) {
|
|
var n = e[i];
|
|
if (n.index === r && n.fragment.sn === t)
|
|
return n
|
|
}
|
|
return null
|
|
}
|
|
function vi(e) {
|
|
e.forEach((function(e, t) {
|
|
var r;
|
|
null == (r = e.details) || r.fragments.forEach((function(e) {
|
|
e.level = t,
|
|
e.initSegment && (e.initSegment.level = t)
|
|
}
|
|
))
|
|
}
|
|
))
|
|
}
|
|
function mi(e, t) {
|
|
return !(e === t || !t) && pi(e) !== pi(t)
|
|
}
|
|
function pi(e) {
|
|
return e.replace(/\?[^?]*$/, "")
|
|
}
|
|
function yi(e, t) {
|
|
for (var r = 0, i = e.length; r < i; r++) {
|
|
var n;
|
|
if ((null == (n = e[r]) ? void 0 : n.cc) === t)
|
|
return e[r]
|
|
}
|
|
return null
|
|
}
|
|
function Ei(e, t) {
|
|
var r = e.start + t;
|
|
e.startPTS = r,
|
|
e.setStart(r),
|
|
e.endPTS = r + e.duration
|
|
}
|
|
function Ti(e, t) {
|
|
for (var r = t.fragments, i = 0, n = r.length; i < n; i++)
|
|
Ei(r[i], e);
|
|
t.fragmentHint && Ei(t.fragmentHint, e),
|
|
t.alignedSliding = !0
|
|
}
|
|
function Si(e, t) {
|
|
if (function(e, t) {
|
|
return !!(e && t.startCC < e.endCC && t.endCC > e.startCC)
|
|
}(t, e)) {
|
|
var r = Math.min(t.endCC, e.endCC)
|
|
, i = yi(t.fragments, r)
|
|
, n = yi(e.fragments, r);
|
|
i && n && (Y.log("Aligning playlist at start of dicontinuity sequence " + r),
|
|
Ti(i.start - n.start, e))
|
|
}
|
|
}
|
|
function Ai(e, t) {
|
|
if (e.hasProgramDateTime && t.hasProgramDateTime) {
|
|
var r = e.fragments
|
|
, i = t.fragments;
|
|
if (r.length && i.length) {
|
|
var n, a, s = Math.min(t.endCC, e.endCC);
|
|
t.startCC < s && e.startCC < s && (n = yi(i, s),
|
|
a = yi(r, s)),
|
|
n && a || (a = yi(r, (n = i[Math.floor(i.length / 2)]).cc) || r[Math.floor(r.length / 2)]);
|
|
var o = n.programDateTime
|
|
, l = a.programDateTime;
|
|
o && l && Ti((l - o) / 1e3 - (a.start - n.start), e)
|
|
}
|
|
}
|
|
}
|
|
function Li(e, t, r) {
|
|
Ii(e, t, r),
|
|
e.addEventListener(t, r)
|
|
}
|
|
function Ii(e, t, r) {
|
|
e.removeEventListener(t, r)
|
|
}
|
|
var Ri = function(e) {
|
|
for (var t = "", r = e.length, i = 0; i < r; i++)
|
|
t += "[" + e.start(i).toFixed(3) + "-" + e.end(i).toFixed(3) + "]";
|
|
return t
|
|
}
|
|
, ki = {
|
|
STOPPED: "STOPPED",
|
|
IDLE: "IDLE",
|
|
KEY_LOADING: "KEY_LOADING",
|
|
FRAG_LOADING: "FRAG_LOADING",
|
|
FRAG_LOADING_WAITING_RETRY: "FRAG_LOADING_WAITING_RETRY",
|
|
WAITING_TRACK: "WAITING_TRACK",
|
|
PARSING: "PARSING",
|
|
PARSED: "PARSED",
|
|
ENDED: "ENDED",
|
|
ERROR: "ERROR",
|
|
WAITING_INIT_PTS: "WAITING_INIT_PTS",
|
|
WAITING_LEVEL: "WAITING_LEVEL"
|
|
}
|
|
, bi = function(e) {
|
|
function t(t, r, i, n, a) {
|
|
var s;
|
|
return (s = e.call(this, n, t.logger) || this).hls = void 0,
|
|
s.fragPrevious = null,
|
|
s.fragCurrent = null,
|
|
s.fragmentTracker = void 0,
|
|
s.transmuxer = null,
|
|
s._state = ki.STOPPED,
|
|
s.playlistType = void 0,
|
|
s.media = null,
|
|
s.mediaBuffer = null,
|
|
s.config = void 0,
|
|
s.bitrateTest = !1,
|
|
s.lastCurrentTime = 0,
|
|
s.nextLoadPosition = 0,
|
|
s.startPosition = 0,
|
|
s.startTimeOffset = null,
|
|
s.retryDate = 0,
|
|
s.levels = null,
|
|
s.fragmentLoader = void 0,
|
|
s.keyLoader = void 0,
|
|
s.levelLastLoaded = null,
|
|
s.startFragRequested = !1,
|
|
s.decrypter = void 0,
|
|
s.initPTS = [],
|
|
s.buffering = !0,
|
|
s.loadingParts = !1,
|
|
s.loopSn = void 0,
|
|
s.onMediaSeeking = function() {
|
|
var e = s
|
|
, t = e.config
|
|
, r = e.fragCurrent
|
|
, i = e.media
|
|
, n = e.mediaBuffer
|
|
, a = e.state
|
|
, o = i ? i.currentTime : 0
|
|
, l = ur.bufferInfo(n || i, o, t.maxBufferHole)
|
|
, u = !l.len;
|
|
if (s.log("Media seeking to " + (A(o) ? o.toFixed(3) : o) + ", state: " + a + ", " + (u ? "out of" : "in") + " buffer"),
|
|
s.state === ki.ENDED)
|
|
s.resetLoadingState();
|
|
else if (r) {
|
|
var d = t.maxFragLookUpTolerance
|
|
, h = r.start - d
|
|
, f = r.start + r.duration + d;
|
|
if (u || f < l.start || h > l.end) {
|
|
var c = o > f;
|
|
(o < h || c) && (c && r.loader && (s.log("Cancelling fragment load for seek (sn: " + r.sn + ")"),
|
|
r.abortRequests(),
|
|
s.resetLoadingState()),
|
|
s.fragPrevious = null)
|
|
}
|
|
}
|
|
if (i && (s.fragmentTracker.removeFragmentsInRange(o, 1 / 0, s.playlistType, !0),
|
|
o > s.lastCurrentTime && (s.lastCurrentTime = o),
|
|
!s.loadingParts)) {
|
|
var g = Math.max(l.end, o)
|
|
, v = s.shouldLoadParts(s.getLevelDetails(), g);
|
|
v && (s.log("LL-Part loading ON after seeking to " + o.toFixed(2) + " with buffer @" + g.toFixed(2)),
|
|
s.loadingParts = v)
|
|
}
|
|
s.hls.hasEnoughToStart || (s.log("Setting " + (u ? "startPosition" : "nextLoadPosition") + " to " + o + " for seek without enough to start"),
|
|
s.nextLoadPosition = o,
|
|
u && (s.startPosition = o)),
|
|
u && s.state === ki.IDLE && s.tickImmediate()
|
|
}
|
|
,
|
|
s.onMediaEnded = function() {
|
|
s.log("setting startPosition to 0 because media ended"),
|
|
s.startPosition = s.lastCurrentTime = 0
|
|
}
|
|
,
|
|
s.playlistType = a,
|
|
s.hls = t,
|
|
s.fragmentLoader = new rr(t.config),
|
|
s.keyLoader = i,
|
|
s.fragmentTracker = r,
|
|
s.config = t.config,
|
|
s.decrypter = new er(t.config),
|
|
s
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.registerListeners = function() {
|
|
var e = this.hls;
|
|
e.on(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.on(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.MANIFEST_LOADED, this.onManifestLoaded, this),
|
|
e.on(b.ERROR, this.onError, this)
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e.off(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.off(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.MANIFEST_LOADED, this.onManifestLoaded, this),
|
|
e.off(b.ERROR, this.onError, this)
|
|
}
|
|
,
|
|
r.doTick = function() {
|
|
this.onTickEnd()
|
|
}
|
|
,
|
|
r.onTickEnd = function() {}
|
|
,
|
|
r.startLoad = function(e) {}
|
|
,
|
|
r.stopLoad = function() {
|
|
if (this.state !== ki.STOPPED) {
|
|
this.fragmentLoader.abort(),
|
|
this.keyLoader.abort(this.playlistType);
|
|
var e = this.fragCurrent;
|
|
null != e && e.loader && (e.abortRequests(),
|
|
this.fragmentTracker.removeFragment(e)),
|
|
this.resetTransmuxer(),
|
|
this.fragCurrent = null,
|
|
this.fragPrevious = null,
|
|
this.clearInterval(),
|
|
this.clearNextTick(),
|
|
this.state = ki.STOPPED
|
|
}
|
|
}
|
|
,
|
|
r.pauseBuffering = function() {
|
|
this.buffering = !1
|
|
}
|
|
,
|
|
r.resumeBuffering = function() {
|
|
this.buffering = !0
|
|
}
|
|
,
|
|
r._streamEnded = function(e, t) {
|
|
if (t.live || !this.media)
|
|
return !1;
|
|
var r = e.end || 0
|
|
, i = this.config.timelineOffset || 0;
|
|
if (r <= i)
|
|
return !1;
|
|
var n = e.buffered;
|
|
this.config.maxBufferHole && n && n.length > 1 && (e = ur.bufferedInfo(n, e.start, 0));
|
|
var a = e.nextStart;
|
|
if (a && a > i && a < t.edge)
|
|
return !1;
|
|
if (this.media.currentTime < e.start)
|
|
return !1;
|
|
var s = t.partList;
|
|
if (null != s && s.length) {
|
|
var o = s[s.length - 1];
|
|
return ur.isBuffered(this.media, o.start + o.duration / 2)
|
|
}
|
|
var l = t.fragments[t.fragments.length - 1].type;
|
|
return this.fragmentTracker.isEndListAppended(l)
|
|
}
|
|
,
|
|
r.getLevelDetails = function() {
|
|
if (this.levels && null !== this.levelLastLoaded)
|
|
return this.levelLastLoaded.details
|
|
}
|
|
,
|
|
r.onMediaAttached = function(e, t) {
|
|
var r = this.media = this.mediaBuffer = t.media;
|
|
Li(r, "seeking", this.onMediaSeeking),
|
|
Li(r, "ended", this.onMediaEnded);
|
|
var i = this.config;
|
|
this.levels && i.autoStartLoad && this.state === ki.STOPPED && this.startLoad(i.startPosition)
|
|
}
|
|
,
|
|
r.onMediaDetaching = function(e, t) {
|
|
var r = !!t.transferMedia
|
|
, i = this.media;
|
|
if (null !== i) {
|
|
if (i.ended && (this.log("MSE detaching and video ended, reset startPosition"),
|
|
this.startPosition = this.lastCurrentTime = 0),
|
|
Ii(i, "seeking", this.onMediaSeeking),
|
|
Ii(i, "ended", this.onMediaEnded),
|
|
this.keyLoader && !r && this.keyLoader.detach(),
|
|
this.media = this.mediaBuffer = null,
|
|
this.loopSn = void 0,
|
|
r)
|
|
return this.resetLoadingState(),
|
|
void this.resetTransmuxer();
|
|
this.loadingParts = !1,
|
|
this.fragmentTracker.removeAllFragments(),
|
|
this.stopLoad()
|
|
}
|
|
}
|
|
,
|
|
r.onManifestLoading = function() {
|
|
this.initPTS = [],
|
|
this.levels = this.levelLastLoaded = this.fragCurrent = null,
|
|
this.lastCurrentTime = this.startPosition = 0,
|
|
this.startFragRequested = !1
|
|
}
|
|
,
|
|
r.onError = function(e, t) {}
|
|
,
|
|
r.onManifestLoaded = function(e, t) {
|
|
this.startTimeOffset = t.startTimeOffset
|
|
}
|
|
,
|
|
r.onHandlerDestroying = function() {
|
|
this.stopLoad(),
|
|
this.transmuxer && (this.transmuxer.destroy(),
|
|
this.transmuxer = null),
|
|
e.prototype.onHandlerDestroying.call(this),
|
|
this.hls = this.onMediaSeeking = this.onMediaEnded = null
|
|
}
|
|
,
|
|
r.onHandlerDestroyed = function() {
|
|
this.state = ki.STOPPED,
|
|
this.fragmentLoader && this.fragmentLoader.destroy(),
|
|
this.keyLoader && this.keyLoader.destroy(),
|
|
this.decrypter && this.decrypter.destroy(),
|
|
this.hls = this.log = this.warn = this.decrypter = this.keyLoader = this.fragmentLoader = this.fragmentTracker = null,
|
|
e.prototype.onHandlerDestroyed.call(this)
|
|
}
|
|
,
|
|
r.loadFragment = function(e, t, r) {
|
|
this.startFragRequested = !0,
|
|
this._loadFragForPlayback(e, t, r)
|
|
}
|
|
,
|
|
r._loadFragForPlayback = function(e, t, r) {
|
|
var i = this;
|
|
this._doFragLoad(e, t, r, (function(e) {
|
|
var t = e.frag;
|
|
if (i.fragContextChanged(t))
|
|
return i.warn(t.type + " sn: " + t.sn + (e.part ? " part: " + e.part.index : "") + " of " + i.fragInfo(t, !1, e.part) + ") was dropped during download."),
|
|
void i.fragmentTracker.removeFragment(t);
|
|
t.stats.chunkCount++,
|
|
i._handleFragmentLoadProgress(e)
|
|
}
|
|
)).then((function(e) {
|
|
if (e) {
|
|
var t = i.state
|
|
, r = e.frag;
|
|
i.fragContextChanged(r) ? (t === ki.FRAG_LOADING || !i.fragCurrent && t === ki.PARSING) && (i.fragmentTracker.removeFragment(r),
|
|
i.state = ki.IDLE) : ("payload"in e && (i.log("Loaded " + r.type + " sn: " + r.sn + " of " + i.playlistLabel() + " " + r.level),
|
|
i.hls.trigger(b.FRAG_LOADED, e)),
|
|
i._handleFragmentLoadComplete(e))
|
|
}
|
|
}
|
|
)).catch((function(t) {
|
|
i.state !== ki.STOPPED && i.state !== ki.ERROR && (i.warn("Frag error: " + ((null == t ? void 0 : t.message) || t)),
|
|
i.resetFragmentLoading(e))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.clearTrackerIfNeeded = function(e) {
|
|
var t, r = this.fragmentTracker;
|
|
if (r.getState(e) === Vt) {
|
|
var i = e.type
|
|
, n = this.getFwdBufferInfo(this.mediaBuffer, i)
|
|
, a = Math.max(e.duration, n ? n.len : this.config.maxBufferLength)
|
|
, s = this.backtrackFragment;
|
|
(1 == (s ? e.sn - s.sn : 0) || this.reduceMaxBufferLength(a, e.duration)) && r.removeFragment(e)
|
|
} else
|
|
0 === (null == (t = this.mediaBuffer) ? void 0 : t.buffered.length) ? r.removeAllFragments() : r.hasParts(e.type) && (r.detectPartialFragments({
|
|
frag: e,
|
|
part: null,
|
|
stats: e.stats,
|
|
id: e.type
|
|
}),
|
|
r.getState(e) === Ht && r.removeFragment(e))
|
|
}
|
|
,
|
|
r.checkLiveUpdate = function(e) {
|
|
if (e.updated && !e.live) {
|
|
var t = e.fragments[e.fragments.length - 1];
|
|
this.fragmentTracker.detectPartialFragments({
|
|
frag: t,
|
|
part: null,
|
|
stats: t.stats,
|
|
id: t.type
|
|
})
|
|
}
|
|
e.fragments[0] || (e.deltaUpdateFailed = !0)
|
|
}
|
|
,
|
|
r.waitForLive = function(e) {
|
|
var t = e.details;
|
|
return (null == t ? void 0 : t.live) && "EVENT" !== t.type && (this.levelLastLoaded !== e || t.expired)
|
|
}
|
|
,
|
|
r.flushMainBuffer = function(e, t, r) {
|
|
if (void 0 === r && (r = null),
|
|
e - t) {
|
|
var i = {
|
|
startOffset: e,
|
|
endOffset: t,
|
|
type: r
|
|
};
|
|
this.hls.trigger(b.BUFFER_FLUSHING, i)
|
|
}
|
|
}
|
|
,
|
|
r._loadInitSegment = function(e, t) {
|
|
var r = this;
|
|
this._doFragLoad(e, t).then((function(e) {
|
|
var t = null == e ? void 0 : e.frag;
|
|
if (!t || r.fragContextChanged(t) || !r.levels)
|
|
throw new Error("init load aborted");
|
|
return e
|
|
}
|
|
)).then((function(e) {
|
|
var t = r.hls
|
|
, i = e.frag
|
|
, n = e.payload
|
|
, a = i.decryptdata;
|
|
if (n && n.byteLength > 0 && null != a && a.key && a.iv && Lr(a.method)) {
|
|
var s = self.performance.now();
|
|
return r.decrypter.decrypt(new Uint8Array(n), a.key.buffer, a.iv.buffer, Ir(a.method)).catch((function(e) {
|
|
throw t.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.FRAG_DECRYPT_ERROR,
|
|
fatal: !1,
|
|
error: e,
|
|
reason: e.message,
|
|
frag: i
|
|
}),
|
|
e
|
|
}
|
|
)).then((function(n) {
|
|
var a = self.performance.now();
|
|
return t.trigger(b.FRAG_DECRYPTED, {
|
|
frag: i,
|
|
payload: n,
|
|
stats: {
|
|
tstart: s,
|
|
tdecrypt: a
|
|
}
|
|
}),
|
|
e.payload = n,
|
|
r.completeInitSegmentLoad(e)
|
|
}
|
|
))
|
|
}
|
|
return r.completeInitSegmentLoad(e)
|
|
}
|
|
)).catch((function(t) {
|
|
r.state !== ki.STOPPED && r.state !== ki.ERROR && (r.warn(t),
|
|
r.resetFragmentLoading(e))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.completeInitSegmentLoad = function(e) {
|
|
if (!this.levels)
|
|
throw new Error("init load aborted, missing levels");
|
|
var t = e.frag.stats;
|
|
this.state !== ki.STOPPED && (this.state = ki.IDLE),
|
|
e.frag.data = new Uint8Array(e.payload),
|
|
t.parsing.start = t.buffering.start = self.performance.now(),
|
|
t.parsing.end = t.buffering.end = self.performance.now(),
|
|
this.tick()
|
|
}
|
|
,
|
|
r.unhandledEncryptionError = function(e, t) {
|
|
var r, i, n = e.tracks;
|
|
if (n && !t.encrypted && (null != (r = n.audio) && r.encrypted || null != (i = n.video) && i.encrypted) && (!this.config.emeEnabled || !this.keyLoader.emeController)) {
|
|
var a = this.media
|
|
, s = new Error("Encrypted track with no key in " + this.fragInfo(t) + " (media " + (a ? "attached mediaKeys: " + a.mediaKeys : "detached") + ")");
|
|
return this.warn(s.message),
|
|
!(!a || a.mediaKeys) && (this.hls.trigger(b.ERROR, {
|
|
type: R.KEY_SYSTEM_ERROR,
|
|
details: k.KEY_SYSTEM_NO_KEYS,
|
|
fatal: !1,
|
|
error: s,
|
|
frag: t
|
|
}),
|
|
this.resetTransmuxer(),
|
|
!0)
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
r.fragContextChanged = function(e) {
|
|
var t = this.fragCurrent;
|
|
return !e || !t || e.sn !== t.sn || e.level !== t.level
|
|
}
|
|
,
|
|
r.fragBufferedComplete = function(e, t) {
|
|
var r = this.mediaBuffer ? this.mediaBuffer : this.media;
|
|
if (this.log("Buffered " + e.type + " sn: " + e.sn + (t ? " part: " + t.index : "") + " of " + this.fragInfo(e, !1, t) + " > buffer:" + (r ? Ri(ur.getBuffered(r)) : "(detached)") + ")"),
|
|
te(e)) {
|
|
var i;
|
|
if (e.type !== x) {
|
|
var n = e.elementaryStreams;
|
|
if (!Object.keys(n).some((function(e) {
|
|
return !!n[e]
|
|
}
|
|
)))
|
|
return void (this.state = ki.IDLE)
|
|
}
|
|
var a = null == (i = this.levels) ? void 0 : i[e.level];
|
|
null != a && a.fragmentError && (this.log("Resetting level fragment error count of " + a.fragmentError + " on frag buffered"),
|
|
a.fragmentError = 0)
|
|
}
|
|
this.state = ki.IDLE
|
|
}
|
|
,
|
|
r._handleFragmentLoadComplete = function(e) {
|
|
var t = this.transmuxer;
|
|
if (t) {
|
|
var r = e.frag
|
|
, i = e.part
|
|
, n = e.partsLoaded
|
|
, a = !n || 0 === n.length || n.some((function(e) {
|
|
return !e
|
|
}
|
|
))
|
|
, s = new or(r.level,r.sn,r.stats.chunkCount + 1,0,i ? i.index : -1,!a);
|
|
t.flush(s)
|
|
}
|
|
}
|
|
,
|
|
r._handleFragmentLoadProgress = function(e) {}
|
|
,
|
|
r._doFragLoad = function(e, t, r, i) {
|
|
var n, a = this;
|
|
void 0 === r && (r = null),
|
|
this.fragCurrent = e;
|
|
var s = t.details;
|
|
if (!this.levels || !s)
|
|
throw new Error("frag load aborted, missing level" + (s ? "" : " detail") + "s");
|
|
var o = null;
|
|
if (!e.encrypted || null != (n = e.decryptdata) && n.key)
|
|
e.encrypted || (o = this.keyLoader.loadClear(e, s.encryptedFragments, this.startFragRequested)) && this.log("[eme] blocking frag load until media-keys acquired");
|
|
else if (this.log("Loading key for " + e.sn + " of [" + s.startSN + "-" + s.endSN + "], " + this.playlistLabel() + " " + e.level),
|
|
this.state = ki.KEY_LOADING,
|
|
this.fragCurrent = e,
|
|
o = this.keyLoader.load(e).then((function(e) {
|
|
if (!a.fragContextChanged(e.frag))
|
|
return a.hls.trigger(b.KEY_LOADED, e),
|
|
a.state === ki.KEY_LOADING && (a.state = ki.IDLE),
|
|
e
|
|
}
|
|
)),
|
|
this.hls.trigger(b.KEY_LOADING, {
|
|
frag: e
|
|
}),
|
|
null === this.fragCurrent)
|
|
return this.log("context changed in KEY_LOADING"),
|
|
Promise.resolve(null);
|
|
var l, u = this.fragPrevious;
|
|
if (te(e) && (!u || e.sn !== u.sn)) {
|
|
var d = this.shouldLoadParts(t.details, e.end);
|
|
d !== this.loadingParts && (this.log("LL-Part loading " + (d ? "ON" : "OFF") + " loading sn " + (null == u ? void 0 : u.sn) + "->" + e.sn),
|
|
this.loadingParts = d)
|
|
}
|
|
if (r = Math.max(e.start, r || 0),
|
|
this.loadingParts && te(e)) {
|
|
var h = s.partList;
|
|
if (h && i) {
|
|
r > s.fragmentEnd && s.fragmentHint && (e = s.fragmentHint);
|
|
var f = this.getNextPart(h, e, r);
|
|
if (f > -1) {
|
|
var c, g = h[f];
|
|
return e = this.fragCurrent = g.fragment,
|
|
this.log("Loading " + e.type + " sn: " + e.sn + " part: " + g.index + " (" + f + "/" + (h.length - 1) + ") of " + this.fragInfo(e, !1, g) + ") cc: " + e.cc + " [" + s.startSN + "-" + s.endSN + "], target: " + parseFloat(r.toFixed(3))),
|
|
this.nextLoadPosition = g.start + g.duration,
|
|
this.state = ki.FRAG_LOADING,
|
|
c = o ? o.then((function(r) {
|
|
return !r || a.fragContextChanged(r.frag) ? null : a.doFragPartsLoad(e, g, t, i)
|
|
}
|
|
)).catch((function(e) {
|
|
return a.handleFragLoadError(e)
|
|
}
|
|
)) : this.doFragPartsLoad(e, g, t, i).catch((function(e) {
|
|
return a.handleFragLoadError(e)
|
|
}
|
|
)),
|
|
this.hls.trigger(b.FRAG_LOADING, {
|
|
frag: e,
|
|
part: g,
|
|
targetBufferTime: r
|
|
}),
|
|
null === this.fragCurrent ? Promise.reject(new Error("frag load aborted, context changed in FRAG_LOADING parts")) : c
|
|
}
|
|
if (!e.url || this.loadedEndOfParts(h, r))
|
|
return Promise.resolve(null)
|
|
}
|
|
}
|
|
if (te(e) && this.loadingParts)
|
|
this.log("LL-Part loading OFF after next part miss @" + r.toFixed(2) + " Check buffer at sn: " + e.sn + " loaded parts: " + (null == (l = s.partList) ? void 0 : l.filter((function(e) {
|
|
return e.loaded
|
|
}
|
|
)).map((function(e) {
|
|
return "[" + e.start + "-" + e.end + "]"
|
|
}
|
|
)))),
|
|
this.loadingParts = !1;
|
|
else if (!e.url)
|
|
return Promise.resolve(null);
|
|
this.log("Loading " + e.type + " sn: " + e.sn + " of " + this.fragInfo(e, !1) + ") cc: " + e.cc + " [" + s.startSN + "-" + s.endSN + "], target: " + parseFloat(r.toFixed(3))),
|
|
A(e.sn) && !this.bitrateTest && (this.nextLoadPosition = e.start + e.duration),
|
|
this.state = ki.FRAG_LOADING;
|
|
var v, m = this.config.progressive;
|
|
return v = m && o ? o.then((function(t) {
|
|
return !t || a.fragContextChanged(t.frag) ? null : a.fragmentLoader.load(e, i)
|
|
}
|
|
)).catch((function(e) {
|
|
return a.handleFragLoadError(e)
|
|
}
|
|
)) : Promise.all([this.fragmentLoader.load(e, m ? i : void 0), o]).then((function(e) {
|
|
var t = e[0];
|
|
return !m && i && i(t),
|
|
t
|
|
}
|
|
)).catch((function(e) {
|
|
return a.handleFragLoadError(e)
|
|
}
|
|
)),
|
|
this.hls.trigger(b.FRAG_LOADING, {
|
|
frag: e,
|
|
targetBufferTime: r
|
|
}),
|
|
null === this.fragCurrent ? Promise.reject(new Error("frag load aborted, context changed in FRAG_LOADING")) : v
|
|
}
|
|
,
|
|
r.doFragPartsLoad = function(e, t, r, i) {
|
|
var n = this;
|
|
return new Promise((function(a, s) {
|
|
var o, l = [], u = null == (o = r.details) ? void 0 : o.partList, d = function(t) {
|
|
n.fragmentLoader.loadPart(e, t, i).then((function(i) {
|
|
l[t.index] = i;
|
|
var s = i.part;
|
|
n.hls.trigger(b.FRAG_LOADED, i);
|
|
var o = ci(r.details, e.sn, t.index + 1) || gi(u, e.sn, t.index + 1);
|
|
if (!o)
|
|
return a({
|
|
frag: e,
|
|
part: s,
|
|
partsLoaded: l
|
|
});
|
|
d(o)
|
|
}
|
|
)).catch(s)
|
|
};
|
|
d(t)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.handleFragLoadError = function(e) {
|
|
if ("data"in e) {
|
|
var t = e.data;
|
|
t.frag && t.details === k.INTERNAL_ABORTED ? this.handleFragLoadAborted(t.frag, t.part) : t.frag && t.type === R.KEY_SYSTEM_ERROR ? (t.frag.abortRequests(),
|
|
this.resetStartWhenNotLoaded(),
|
|
this.resetFragmentLoading(t.frag)) : this.hls.trigger(b.ERROR, t)
|
|
} else
|
|
this.hls.trigger(b.ERROR, {
|
|
type: R.OTHER_ERROR,
|
|
details: k.INTERNAL_EXCEPTION,
|
|
err: e,
|
|
error: e,
|
|
fatal: !0
|
|
});
|
|
return null
|
|
}
|
|
,
|
|
r._handleTransmuxerFlush = function(e) {
|
|
var t = this.getCurrentContext(e);
|
|
if (t && this.state === ki.PARSING) {
|
|
var r = t.frag
|
|
, i = t.part
|
|
, n = t.level
|
|
, a = self.performance.now();
|
|
r.stats.parsing.end = a,
|
|
i && (i.stats.parsing.end = a);
|
|
var s = this.getLevelDetails()
|
|
, o = s && r.sn > s.endSN || this.shouldLoadParts(s, r.end);
|
|
o !== this.loadingParts && (this.log("LL-Part loading " + (o ? "ON" : "OFF") + " after parsing segment ending @" + r.end.toFixed(2)),
|
|
this.loadingParts = o),
|
|
this.updateLevelTiming(r, i, n, e.partial)
|
|
} else
|
|
this.fragCurrent || this.state === ki.STOPPED || this.state === ki.ERROR || (this.state = ki.IDLE)
|
|
}
|
|
,
|
|
r.shouldLoadParts = function(e, t) {
|
|
if (this.config.lowLatencyMode) {
|
|
if (!e)
|
|
return this.loadingParts;
|
|
if (e.partList) {
|
|
var r, i, n = e.partList[0];
|
|
if (n.fragment.type === x)
|
|
return !1;
|
|
if (t >= n.end + ((null == (r = e.fragmentHint) ? void 0 : r.duration) || 0) && (this.hls.hasEnoughToStart ? (null == (i = this.media) ? void 0 : i.currentTime) || this.lastCurrentTime : this.getLoadPosition()) > n.start - n.fragment.duration)
|
|
return !0
|
|
}
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
r.getCurrentContext = function(e) {
|
|
var t = this.levels
|
|
, r = this.fragCurrent
|
|
, i = e.level
|
|
, n = e.sn
|
|
, a = e.part;
|
|
if (null == t || !t[i])
|
|
return this.warn("Levels object was unset while buffering fragment " + n + " of " + this.playlistLabel() + " " + i + ". The current chunk will not be buffered."),
|
|
null;
|
|
var s = t[i]
|
|
, o = s.details
|
|
, l = a > -1 ? ci(o, n, a) : null
|
|
, u = l ? l.fragment : fi(o, n, r);
|
|
return u ? (r && r !== u && (u.stats = r.stats),
|
|
{
|
|
frag: u,
|
|
part: l,
|
|
level: s
|
|
}) : null
|
|
}
|
|
,
|
|
r.bufferFragmentData = function(e, t, r, i, n) {
|
|
if (this.state === ki.PARSING) {
|
|
var a = e.data1
|
|
, s = e.data2
|
|
, o = a;
|
|
if (s && (o = Ae(a, s)),
|
|
o.length) {
|
|
var l = this.initPTS[t.cc]
|
|
, u = l ? -l.baseTime / l.timescale : void 0
|
|
, d = {
|
|
type: e.type,
|
|
frag: t,
|
|
part: r,
|
|
chunkMeta: i,
|
|
offset: u,
|
|
parent: t.type,
|
|
data: o
|
|
};
|
|
if (this.hls.trigger(b.BUFFER_APPENDING, d),
|
|
e.dropped && e.independent && !r) {
|
|
if (n)
|
|
return;
|
|
this.flushBufferGap(t)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.flushBufferGap = function(e) {
|
|
var t = this.media;
|
|
if (t)
|
|
if (ur.isBuffered(t, t.currentTime)) {
|
|
var r = t.currentTime
|
|
, i = ur.bufferInfo(t, r, 0)
|
|
, n = e.duration
|
|
, a = Math.min(2 * this.config.maxFragLookUpTolerance, .25 * n)
|
|
, s = Math.max(Math.min(e.start - a, i.end - a), r + a);
|
|
e.start - s > a && this.flushMainBuffer(s, e.start)
|
|
} else
|
|
this.flushMainBuffer(0, e.start)
|
|
}
|
|
,
|
|
r.getFwdBufferInfo = function(e, t) {
|
|
var r, i = this.getLoadPosition();
|
|
if (!A(i))
|
|
return null;
|
|
var n = this.lastCurrentTime > i || null != (r = this.media) && r.paused ? 0 : this.config.maxBufferHole;
|
|
return this.getFwdBufferInfoAtPos(e, i, t, n)
|
|
}
|
|
,
|
|
r.getFwdBufferInfoAtPos = function(e, t, r, i) {
|
|
var n = ur.bufferInfo(e, t, i);
|
|
if (0 === n.len && void 0 !== n.nextStart) {
|
|
var a = this.fragmentTracker.getBufferedFrag(t, r);
|
|
if (a && (n.nextStart <= a.end || a.gap)) {
|
|
var s = Math.max(Math.min(n.nextStart, a.end) - t, i);
|
|
return ur.bufferInfo(e, t, s)
|
|
}
|
|
}
|
|
return n
|
|
}
|
|
,
|
|
r.getMaxBufferLength = function(e) {
|
|
var t, r = this.config;
|
|
return t = e ? Math.max(8 * r.maxBufferSize / e, r.maxBufferLength) : r.maxBufferLength,
|
|
Math.min(t, r.maxMaxBufferLength)
|
|
}
|
|
,
|
|
r.reduceMaxBufferLength = function(e, t) {
|
|
var r = this.config
|
|
, i = Math.max(Math.min(e - t, r.maxBufferLength), t)
|
|
, n = Math.max(e - 3 * t, r.maxMaxBufferLength / 2, i);
|
|
return n >= i && (r.maxMaxBufferLength = n,
|
|
this.warn("Reduce max buffer length to " + n + "s"),
|
|
!0)
|
|
}
|
|
,
|
|
r.getAppendedFrag = function(e, t) {
|
|
void 0 === t && (t = w);
|
|
var r = this.fragmentTracker ? this.fragmentTracker.getAppendedFrag(e, t) : null;
|
|
return r && "fragment"in r ? r.fragment : r
|
|
}
|
|
,
|
|
r.getNextFragment = function(e, t) {
|
|
var r = t.fragments
|
|
, i = r.length;
|
|
if (!i)
|
|
return null;
|
|
var n = this.config
|
|
, a = r[0].start
|
|
, s = n.lowLatencyMode && !!t.partList
|
|
, o = null;
|
|
if (t.live) {
|
|
var l = n.initialLiveManifestSize;
|
|
if (i < l)
|
|
return this.warn("Not enough fragments to start playback (have: " + i + ", need: " + l + ")"),
|
|
null;
|
|
if (!t.PTSKnown && !this.startFragRequested && -1 === this.startPosition || e < a) {
|
|
var u;
|
|
s && !this.loadingParts && (this.log("LL-Part loading ON for initial live fragment"),
|
|
this.loadingParts = !0),
|
|
o = this.getInitialLiveFragment(t);
|
|
var d = this.hls.startPosition
|
|
, h = this.hls.liveSyncPosition
|
|
, f = o ? (-1 !== d && d >= a ? d : h) || o.start : e;
|
|
this.log("Setting startPosition to " + f + " to match start frag at live edge. mainStart: " + d + " liveSyncPosition: " + h + " frag.start: " + (null == (u = o) ? void 0 : u.start)),
|
|
this.startPosition = this.nextLoadPosition = f
|
|
}
|
|
} else
|
|
e <= a && (o = r[0]);
|
|
if (!o) {
|
|
var c = this.loadingParts ? t.partEnd : t.fragmentEnd;
|
|
o = this.getFragmentAtPosition(e, c, t)
|
|
}
|
|
var g = this.filterReplacedPrimary(o, t);
|
|
if (!g && o) {
|
|
var v = o.sn - t.startSN;
|
|
g = this.filterReplacedPrimary(r[v + 1] || null, t)
|
|
}
|
|
return this.mapToInitFragWhenRequired(g)
|
|
}
|
|
,
|
|
r.isLoopLoading = function(e, t) {
|
|
var r = this.fragmentTracker.getState(e);
|
|
return (r === Yt || r === Ht && !!e.gap) && this.nextLoadPosition > t
|
|
}
|
|
,
|
|
r.getNextFragmentLoopLoading = function(e, t, r, i, n) {
|
|
var a = null;
|
|
if (e.gap && (a = this.getNextFragment(this.nextLoadPosition, t)) && !a.gap && r.nextStart) {
|
|
var s = this.getFwdBufferInfoAtPos(this.mediaBuffer ? this.mediaBuffer : this.media, r.nextStart, i, 0);
|
|
if (null !== s && r.len + s.len >= n) {
|
|
var o = a.sn;
|
|
return this.loopSn !== o && (this.log('buffer full after gaps in "' + i + '" playlist starting at sn: ' + o),
|
|
this.loopSn = o),
|
|
null
|
|
}
|
|
}
|
|
return this.loopSn = void 0,
|
|
a
|
|
}
|
|
,
|
|
r.filterReplacedPrimary = function(e, t) {
|
|
if (!e)
|
|
return e;
|
|
if (Di(this.config) && e.type !== x) {
|
|
var r = this.hls.interstitialsManager
|
|
, i = null == r ? void 0 : r.bufferingItem;
|
|
if (i) {
|
|
var n = i.event;
|
|
if (n) {
|
|
if (n.appendInPlace || Math.abs(e.start - i.start) > 1 || 0 === i.start)
|
|
return null
|
|
} else {
|
|
if (e.end <= i.start && !1 === (null == t ? void 0 : t.live))
|
|
return null;
|
|
if (e.start > i.end && i.nextEvent && (i.nextEvent.appendInPlace || e.start - i.end > 1))
|
|
return null
|
|
}
|
|
}
|
|
var a = null == r ? void 0 : r.playerQueue;
|
|
if (a)
|
|
for (var s = a.length; s--; ) {
|
|
var o = a[s].interstitial;
|
|
if (o.appendInPlace && e.start >= o.startTime && e.end <= o.resumeTime)
|
|
return null
|
|
}
|
|
}
|
|
return e
|
|
}
|
|
,
|
|
r.mapToInitFragWhenRequired = function(e) {
|
|
return null == e || !e.initSegment || e.initSegment.data || this.bitrateTest ? e : e.initSegment
|
|
}
|
|
,
|
|
r.getNextPart = function(e, t, r) {
|
|
for (var i = -1, n = !1, a = !0, s = 0, o = e.length; s < o; s++) {
|
|
var l = e[s];
|
|
if (a = a && !l.independent,
|
|
i > -1 && r < l.start)
|
|
break;
|
|
var u = l.loaded;
|
|
u ? i = -1 : (n || (l.independent || a) && l.fragment === t) && (l.fragment !== t && this.warn("Need buffer at " + r + " but next unloaded part starts at " + l.start),
|
|
i = s),
|
|
n = u
|
|
}
|
|
return i
|
|
}
|
|
,
|
|
r.loadedEndOfParts = function(e, t) {
|
|
for (var r, i = e.length; i--; ) {
|
|
if (!(r = e[i]).loaded)
|
|
return !1;
|
|
if (t > r.start)
|
|
return !0
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
r.getInitialLiveFragment = function(e) {
|
|
var t = e.fragments
|
|
, r = this.fragPrevious
|
|
, i = null;
|
|
if (r) {
|
|
if (e.hasProgramDateTime && (this.log("Live playlist, switching playlist, load frag with same PDT: " + r.programDateTime),
|
|
i = function(e, t, r) {
|
|
if (null === t || !Array.isArray(e) || !e.length || !A(t))
|
|
return null;
|
|
if (t < (e[0].programDateTime || 0))
|
|
return null;
|
|
if (t >= (e[e.length - 1].endProgramDateTime || 0))
|
|
return null;
|
|
for (var i = 0; i < e.length; ++i) {
|
|
var n = e[i];
|
|
if (St(t, r, n))
|
|
return n
|
|
}
|
|
return null
|
|
}(t, r.endProgramDateTime, this.config.maxFragLookUpTolerance)),
|
|
!i) {
|
|
var n = r.sn + 1;
|
|
if (n >= e.startSN && n <= e.endSN) {
|
|
var a = t[n - e.startSN];
|
|
r.cc === a.cc && (i = a,
|
|
this.log("Live playlist, switching playlist, load frag with next SN: " + i.sn))
|
|
}
|
|
i || (i = At(e, r.cc, r.end)) && this.log("Live playlist, switching playlist, load frag with same CC: " + i.sn)
|
|
}
|
|
} else {
|
|
var s = this.hls.liveSyncPosition;
|
|
null !== s && (i = this.getFragmentAtPosition(s, this.bitrateTest ? e.fragmentEnd : e.edge, e))
|
|
}
|
|
return i
|
|
}
|
|
,
|
|
r.getFragmentAtPosition = function(e, t, r) {
|
|
var i, n, a = this.config, s = this.fragPrevious, o = r.fragments, l = r.endSN, u = r.fragmentHint, d = a.maxFragLookUpTolerance, h = r.partList, f = !!(this.loadingParts && null != h && h.length && u);
|
|
if (f && !this.bitrateTest && h[h.length - 1].fragment.sn === u.sn && (o = o.concat(u),
|
|
l = u.sn),
|
|
i = e < t ? Et(s, o, e, e < this.lastCurrentTime || e > t - d || null != (n = this.media) && n.paused || !this.startFragRequested ? 0 : d) : o[o.length - 1]) {
|
|
var c = i.sn - r.startSN
|
|
, g = this.fragmentTracker.getState(i);
|
|
if ((g === Yt || g === Ht && i.gap) && (s = i),
|
|
s && i.sn === s.sn && (!f || h[0].fragment.sn > i.sn || !r.live) && i.level === s.level) {
|
|
var v = o[c + 1];
|
|
i = i.sn < l && this.fragmentTracker.getState(v) !== Yt ? v : null
|
|
}
|
|
}
|
|
return i
|
|
}
|
|
,
|
|
r.alignPlaylists = function(e, t, r) {
|
|
var i = e.fragments.length;
|
|
if (!i)
|
|
return this.warn("No fragments in live playlist"),
|
|
0;
|
|
var n = e.fragmentStart
|
|
, a = !t
|
|
, s = e.alignedSliding && A(n);
|
|
if (a || !s && !n) {
|
|
!function(e, t) {
|
|
e && (Si(t, e),
|
|
t.alignedSliding || Ai(t, e),
|
|
t.alignedSliding || t.skippedSegments || ui(e, t, !1))
|
|
}(r, e);
|
|
var o = e.fragmentStart;
|
|
return this.log("Live playlist sliding: " + o.toFixed(2) + " start-sn: " + (t ? t.startSN : "na") + "->" + e.startSN + " fragments: " + i),
|
|
o
|
|
}
|
|
return n
|
|
}
|
|
,
|
|
r.waitForCdnTuneIn = function(e) {
|
|
return e.live && e.canBlockReload && e.partTarget && e.tuneInGoal > Math.max(e.partHoldBack, 3 * e.partTarget)
|
|
}
|
|
,
|
|
r.setStartPosition = function(e, t) {
|
|
var r = this.startPosition;
|
|
r < t && (r = -1);
|
|
var i = this.timelineOffset;
|
|
if (-1 === r) {
|
|
var n = null !== this.startTimeOffset
|
|
, a = n ? this.startTimeOffset : e.startTimeOffset;
|
|
null !== a && A(a) ? (r = t + a,
|
|
a < 0 && (r += e.edge),
|
|
r = Math.min(Math.max(t, r), t + e.totalduration),
|
|
this.log("Setting startPosition to " + r + " for start time offset " + a + " found in " + (n ? "multivariant" : "media") + " playlist"),
|
|
this.startPosition = r) : e.live ? (r = this.hls.liveSyncPosition || t,
|
|
this.log("Setting startPosition to -1 to start at live edge " + r),
|
|
this.startPosition = -1) : (this.log("setting startPosition to 0 by default"),
|
|
this.startPosition = r = 0),
|
|
this.lastCurrentTime = r + i
|
|
}
|
|
this.nextLoadPosition = r + i
|
|
}
|
|
,
|
|
r.getLoadPosition = function() {
|
|
var e, t = this.media, r = 0;
|
|
return null != (e = this.hls) && e.hasEnoughToStart && t ? r = t.currentTime : this.nextLoadPosition >= 0 && (r = this.nextLoadPosition),
|
|
r
|
|
}
|
|
,
|
|
r.handleFragLoadAborted = function(e, t) {
|
|
this.transmuxer && e.type === this.playlistType && te(e) && e.stats.aborted && (this.log("Fragment " + e.sn + (t ? " part " + t.index : "") + " of " + this.playlistLabel() + " " + e.level + " was aborted"),
|
|
this.resetFragmentLoading(e))
|
|
}
|
|
,
|
|
r.resetFragmentLoading = function(e) {
|
|
this.fragCurrent && (this.fragContextChanged(e) || this.state === ki.FRAG_LOADING_WAITING_RETRY) || (this.state = ki.IDLE)
|
|
}
|
|
,
|
|
r.onFragmentOrKeyLoadError = function(e, t) {
|
|
var r;
|
|
if (t.chunkMeta && !t.frag) {
|
|
var i = this.getCurrentContext(t.chunkMeta);
|
|
i && (t.frag = i.frag)
|
|
}
|
|
var n = t.frag;
|
|
if (n && n.type === e && this.levels)
|
|
if (this.fragContextChanged(n)) {
|
|
var a;
|
|
this.warn("Frag load error must match current frag to retry " + n.url + " > " + (null == (a = this.fragCurrent) ? void 0 : a.url))
|
|
} else {
|
|
var s = t.details === k.FRAG_GAP;
|
|
s && this.fragmentTracker.fragBuffered(n, !0);
|
|
var o = t.errorAction;
|
|
if (o) {
|
|
var l = o.action
|
|
, u = o.flags
|
|
, d = o.retryCount
|
|
, h = void 0 === d ? 0 : d
|
|
, f = o.retryConfig
|
|
, c = !!f
|
|
, g = c && l === xt
|
|
, v = c && !o.resolved && u === Ft
|
|
, m = null == (r = this.hls.latestLevelDetails) ? void 0 : r.live;
|
|
if (!g && v && te(n) && !n.endList && m && !Rt(t))
|
|
this.resetFragmentErrors(e),
|
|
this.treatAsGap(n),
|
|
o.resolved = !0;
|
|
else if ((g || v) && h < f.maxNumRetry) {
|
|
var p, y = Pt(null == (p = t.response) ? void 0 : p.code), E = bt(f, h);
|
|
if (this.resetStartWhenNotLoaded(),
|
|
this.retryDate = self.performance.now() + E,
|
|
this.state = ki.FRAG_LOADING_WAITING_RETRY,
|
|
o.resolved = !0,
|
|
y)
|
|
return this.log("Waiting for connection (offline)"),
|
|
this.retryDate = 1 / 0,
|
|
void (t.reason = "offline");
|
|
this.warn("Fragment " + n.sn + " of " + e + " " + n.level + " errored with " + t.details + ", retrying loading " + (h + 1) + "/" + f.maxNumRetry + " in " + E + "ms")
|
|
} else if (f) {
|
|
if (this.resetFragmentErrors(e),
|
|
!(h < f.maxNumRetry))
|
|
return void this.warn(t.details + " reached or exceeded max retry (" + h + ")");
|
|
s || l === Ot || (o.resolved = !0)
|
|
} else
|
|
this.state = l === wt ? ki.WAITING_LEVEL : ki.ERROR;
|
|
this.tickImmediate()
|
|
} else
|
|
this.state = ki.ERROR
|
|
}
|
|
}
|
|
,
|
|
r.checkRetryDate = function() {
|
|
var e = self.performance.now()
|
|
, t = this.retryDate
|
|
, r = t === 1 / 0;
|
|
(!t || e >= t || r && !Pt(0)) && (r && this.log("Connection restored (online)"),
|
|
this.resetStartWhenNotLoaded(),
|
|
this.state = ki.IDLE)
|
|
}
|
|
,
|
|
r.reduceLengthAndFlushBuffer = function(e) {
|
|
if (this.state === ki.PARSING || this.state === ki.PARSED) {
|
|
var t = e.frag
|
|
, r = e.parent
|
|
, i = this.getFwdBufferInfo(this.mediaBuffer, r)
|
|
, n = i && i.len > .5;
|
|
n && this.reduceMaxBufferLength(i.len, (null == t ? void 0 : t.duration) || 10);
|
|
var a = !n;
|
|
return a && this.warn("Buffer full error while media.currentTime (" + this.getLoadPosition() + ") is not buffered, flush " + r + " buffer"),
|
|
t && (this.fragmentTracker.removeFragment(t),
|
|
this.nextLoadPosition = t.start),
|
|
this.resetLoadingState(),
|
|
a
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
r.resetFragmentErrors = function(e) {
|
|
e === O && (this.fragCurrent = null),
|
|
this.hls.hasEnoughToStart || (this.startFragRequested = !1),
|
|
this.state !== ki.STOPPED && (this.state = ki.IDLE)
|
|
}
|
|
,
|
|
r.afterBufferFlushed = function(e, t, r) {
|
|
if (e) {
|
|
var i = ur.getBuffered(e);
|
|
this.fragmentTracker.detectEvictedFragments(t, i, r),
|
|
this.state === ki.ENDED && this.resetLoadingState()
|
|
}
|
|
}
|
|
,
|
|
r.resetLoadingState = function() {
|
|
this.log("Reset loading state"),
|
|
this.fragCurrent = null,
|
|
this.fragPrevious = null,
|
|
this.state !== ki.STOPPED && (this.state = ki.IDLE)
|
|
}
|
|
,
|
|
r.resetStartWhenNotLoaded = function() {
|
|
if (!this.hls.hasEnoughToStart) {
|
|
this.startFragRequested = !1;
|
|
var e = this.levelLastLoaded
|
|
, t = e ? e.details : null;
|
|
null != t && t.live ? (this.log("resetting startPosition for live start"),
|
|
this.startPosition = -1,
|
|
this.setStartPosition(t, t.fragmentStart),
|
|
this.resetLoadingState()) : this.nextLoadPosition = this.startPosition
|
|
}
|
|
}
|
|
,
|
|
r.resetWhenMissingContext = function(e) {
|
|
this.log("Loading context changed while buffering sn " + e.sn + " of " + this.playlistLabel() + " " + (-1 === e.level ? "<removed>" : e.level) + ". This chunk will not be buffered."),
|
|
this.removeUnbufferedFrags(),
|
|
this.resetStartWhenNotLoaded(),
|
|
this.resetLoadingState()
|
|
}
|
|
,
|
|
r.removeUnbufferedFrags = function(e) {
|
|
void 0 === e && (e = 0),
|
|
this.fragmentTracker.removeFragmentsInRange(e, 1 / 0, this.playlistType, !1, !0)
|
|
}
|
|
,
|
|
r.updateLevelTiming = function(e, t, r, i) {
|
|
var n = this
|
|
, a = r.details;
|
|
if (a) {
|
|
var s;
|
|
if (!Object.keys(e.elementaryStreams).reduce((function(t, s) {
|
|
var o = e.elementaryStreams[s];
|
|
if (o) {
|
|
var l = o.endPTS - o.startPTS;
|
|
if (l <= 0)
|
|
return n.warn("Could not parse fragment " + e.sn + " " + s + " duration reliably (" + l + ")"),
|
|
t || !1;
|
|
var u = i ? 0 : si(a, e, o.startPTS, o.endPTS, o.startDTS, o.endDTS, n);
|
|
return n.hls.trigger(b.LEVEL_PTS_UPDATED, {
|
|
details: a,
|
|
level: r,
|
|
drift: u,
|
|
type: s,
|
|
frag: e,
|
|
start: o.startPTS,
|
|
end: o.endPTS
|
|
}),
|
|
!0
|
|
}
|
|
return t
|
|
}
|
|
), !1) && (0 === r.fragmentError && this.treatAsGap(e, r),
|
|
null === (null == (s = this.transmuxer) ? void 0 : s.error))) {
|
|
var o = new Error("Found no media in fragment " + e.sn + " of " + this.playlistLabel() + " " + e.level + " resetting transmuxer to fallback to playlist timing");
|
|
if (this.warn(o.message),
|
|
this.hls.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.FRAG_PARSING_ERROR,
|
|
fatal: !1,
|
|
error: o,
|
|
frag: e,
|
|
reason: "Found no media in msn " + e.sn + " of " + this.playlistLabel() + ' "' + r.url + '"'
|
|
}),
|
|
!this.hls)
|
|
return;
|
|
this.resetTransmuxer()
|
|
}
|
|
this.state = ki.PARSED,
|
|
this.log("Parsed " + e.type + " sn: " + e.sn + (t ? " part: " + t.index : "") + " of " + this.fragInfo(e, !1, t) + ")"),
|
|
this.hls.trigger(b.FRAG_PARSED, {
|
|
frag: e,
|
|
part: t
|
|
})
|
|
} else
|
|
this.warn("level.details undefined")
|
|
}
|
|
,
|
|
r.playlistLabel = function() {
|
|
return this.playlistType === w ? "level" : "track"
|
|
}
|
|
,
|
|
r.fragInfo = function(e, t, r) {
|
|
var i, n;
|
|
return void 0 === t && (t = !0),
|
|
this.playlistLabel() + " " + e.level + " (" + (r ? "part" : "frag") + ":[" + (null != (i = t && !r ? e.startPTS : (r || e).start) ? i : NaN).toFixed(3) + "-" + (null != (n = t && !r ? e.endPTS : (r || e).end) ? n : NaN).toFixed(3) + "]" + (r && "main" === e.type ? "INDEPENDENT=" + (r.independent ? "YES" : "NO") : "")
|
|
}
|
|
,
|
|
r.treatAsGap = function(e, t) {
|
|
t && t.fragmentError++,
|
|
e.gap = !0,
|
|
this.fragmentTracker.removeFragment(e),
|
|
this.fragmentTracker.fragBuffered(e, !0)
|
|
}
|
|
,
|
|
r.resetTransmuxer = function() {
|
|
var e;
|
|
null == (e = this.transmuxer) || e.reset()
|
|
}
|
|
,
|
|
r.recoverWorkerError = function(e) {
|
|
"demuxerWorker" === e.event && (this.fragmentTracker.removeAllFragments(),
|
|
this.transmuxer && (this.transmuxer.destroy(),
|
|
this.transmuxer = null),
|
|
this.resetStartWhenNotLoaded(),
|
|
this.resetLoadingState())
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "startPositionValue",
|
|
get: function() {
|
|
var e = this.nextLoadPosition
|
|
, t = this.startPosition;
|
|
return -1 === t && e ? e : t
|
|
}
|
|
}, {
|
|
key: "bufferingEnabled",
|
|
get: function() {
|
|
return this.buffering
|
|
}
|
|
}, {
|
|
key: "inFlightFrag",
|
|
get: function() {
|
|
return {
|
|
frag: this.fragCurrent,
|
|
state: this.state
|
|
}
|
|
}
|
|
}, {
|
|
key: "timelineOffset",
|
|
get: function() {
|
|
var e, t = this.config.timelineOffset;
|
|
return t ? (null == (e = this.getLevelDetails()) ? void 0 : e.appliedTimelineOffset) || t : 0
|
|
}
|
|
}, {
|
|
key: "primaryPrefetch",
|
|
get: function() {
|
|
var e;
|
|
return !(!Di(this.config) || !(null == (e = this.hls.interstitialsManager) || null == (e = e.playingItem) ? void 0 : e.event))
|
|
}
|
|
}, {
|
|
key: "state",
|
|
get: function() {
|
|
return this._state
|
|
},
|
|
set: function(e) {
|
|
var t = this._state;
|
|
t !== e && (this._state = e,
|
|
this.log(t + "->" + e))
|
|
}
|
|
}])
|
|
}(sr);
|
|
function Di(e) {
|
|
return !!e.interstitialsController && !1 !== e.enableInterstitialPlayback
|
|
}
|
|
var _i = function() {
|
|
function e() {
|
|
this.chunks = [],
|
|
this.dataLength = 0
|
|
}
|
|
var t = e.prototype;
|
|
return t.push = function(e) {
|
|
this.chunks.push(e),
|
|
this.dataLength += e.length
|
|
}
|
|
,
|
|
t.flush = function() {
|
|
var e, t = this.chunks, r = this.dataLength;
|
|
return t.length ? (e = 1 === t.length ? t[0] : function(e, t) {
|
|
for (var r = new Uint8Array(t), i = 0, n = 0; n < e.length; n++) {
|
|
var a = e[n];
|
|
r.set(a, i),
|
|
i += a.length
|
|
}
|
|
return r
|
|
}(t, r),
|
|
this.reset(),
|
|
e) : new Uint8Array(0)
|
|
}
|
|
,
|
|
t.reset = function() {
|
|
this.chunks.length = 0,
|
|
this.dataLength = 0
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function Pi(e, t) {
|
|
return t + 10 <= e.length && 51 === e[t] && 68 === e[t + 1] && 73 === e[t + 2] && e[t + 3] < 255 && e[t + 4] < 255 && e[t + 6] < 128 && e[t + 7] < 128 && e[t + 8] < 128 && e[t + 9] < 128
|
|
}
|
|
function Ci(e, t) {
|
|
return t + 10 <= e.length && 73 === e[t] && 68 === e[t + 1] && 51 === e[t + 2] && e[t + 3] < 255 && e[t + 4] < 255 && e[t + 6] < 128 && e[t + 7] < 128 && e[t + 8] < 128 && e[t + 9] < 128
|
|
}
|
|
function wi(e, t) {
|
|
var r = 0;
|
|
return r = (127 & e[t]) << 21,
|
|
r |= (127 & e[t + 1]) << 14,
|
|
r |= (127 & e[t + 2]) << 7,
|
|
r |= 127 & e[t + 3]
|
|
}
|
|
function Oi(e, t) {
|
|
for (var r = t, i = 0; Ci(e, t); )
|
|
i += 10,
|
|
i += wi(e, t + 6),
|
|
Pi(e, t + 10) && (i += 10),
|
|
t += i;
|
|
if (i > 0)
|
|
return e.subarray(r, r + i)
|
|
}
|
|
function xi(e, t) {
|
|
return 255 === e[t] && 240 == (246 & e[t + 1])
|
|
}
|
|
function Mi(e, t) {
|
|
return 1 & e[t + 1] ? 7 : 9
|
|
}
|
|
function Fi(e, t) {
|
|
return (3 & e[t + 3]) << 11 | e[t + 4] << 3 | (224 & e[t + 5]) >>> 5
|
|
}
|
|
function Ni(e, t) {
|
|
return t + 1 < e.length && xi(e, t)
|
|
}
|
|
function Ui(e, t) {
|
|
if (Ni(e, t)) {
|
|
var r = Mi(e, t);
|
|
if (t + r >= e.length)
|
|
return !1;
|
|
var i = Fi(e, t);
|
|
if (i <= r)
|
|
return !1;
|
|
var n = t + i;
|
|
return n === e.length || Ni(e, n)
|
|
}
|
|
return !1
|
|
}
|
|
function Bi(e, t, r, i, n) {
|
|
if (!e.samplerate) {
|
|
var s = function(e, t, r, i) {
|
|
var n = t[r + 2]
|
|
, a = n >> 2 & 15;
|
|
if (!(a > 12)) {
|
|
var s = 1 + (n >> 6 & 3)
|
|
, o = t[r + 3] >> 6 & 3 | (1 & n) << 2
|
|
, l = "mp4a.40." + s
|
|
, u = [96e3, 88200, 64e3, 48e3, 44100, 32e3, 24e3, 22050, 16e3, 12e3, 11025, 8e3, 7350][a]
|
|
, d = a;
|
|
5 !== s && 29 !== s || (d -= 3);
|
|
var h = [s << 3 | (14 & d) >> 1, (1 & d) << 7 | o << 3];
|
|
return Y.log("manifest codec:" + i + ", parsed codec:" + l + ", channels:" + o + ", rate:" + u + " (ADTS object type:" + s + " sampling index:" + a + ")"),
|
|
{
|
|
config: h,
|
|
samplerate: u,
|
|
channelCount: o,
|
|
codec: l,
|
|
parsedCodec: l,
|
|
manifestCodec: i
|
|
}
|
|
}
|
|
var f = new Error("invalid ADTS sampling index:" + a);
|
|
e.emit(b.ERROR, b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.FRAG_PARSING_ERROR,
|
|
fatal: !0,
|
|
error: f,
|
|
reason: f.message
|
|
})
|
|
}(t, r, i, n);
|
|
if (!s)
|
|
return;
|
|
a(e, s)
|
|
}
|
|
}
|
|
function Gi(e) {
|
|
return 9216e4 / e
|
|
}
|
|
function Ki(e, t, r, i, n) {
|
|
var a, s = i + n * Gi(e.samplerate), o = function(e, t) {
|
|
var r = Mi(e, t);
|
|
if (t + r <= e.length) {
|
|
var i = Fi(e, t) - r;
|
|
if (i > 0)
|
|
return {
|
|
headerLength: r,
|
|
frameLength: i
|
|
}
|
|
}
|
|
}(t, r);
|
|
if (o) {
|
|
var l = o.frameLength
|
|
, u = o.headerLength
|
|
, d = u + l
|
|
, h = Math.max(0, r + d - t.length);
|
|
h ? (a = new Uint8Array(d - u)).set(t.subarray(r + u, t.length), 0) : a = t.subarray(r + u, r + d);
|
|
var f = {
|
|
unit: a,
|
|
pts: s
|
|
};
|
|
return h || e.samples.push(f),
|
|
{
|
|
sample: f,
|
|
length: d,
|
|
missing: h
|
|
}
|
|
}
|
|
var c = t.length - r;
|
|
return (a = new Uint8Array(c)).set(t.subarray(r, t.length), 0),
|
|
{
|
|
sample: {
|
|
unit: a,
|
|
pts: s
|
|
},
|
|
length: c,
|
|
missing: -1
|
|
}
|
|
}
|
|
function Vi(e, t) {
|
|
return Ci(e, t) && wi(e, t + 6) + 10 <= e.length - t
|
|
}
|
|
function Hi(e, t, r) {
|
|
return void 0 === t && (t = 0),
|
|
void 0 === r && (r = 1 / 0),
|
|
function(e, t, r, i) {
|
|
var n = function(e) {
|
|
return e instanceof ArrayBuffer ? e : e.buffer
|
|
}(e)
|
|
, a = 1;
|
|
"BYTES_PER_ELEMENT"in i && (a = i.BYTES_PER_ELEMENT);
|
|
var s, o = (s = e) && s.buffer instanceof ArrayBuffer && void 0 !== s.byteLength && void 0 !== s.byteOffset ? e.byteOffset : 0, l = (o + e.byteLength) / a, u = (o + t) / a, d = Math.floor(Math.max(0, Math.min(u, l))), h = Math.floor(Math.min(d + Math.max(r, 0), l));
|
|
return new i(n,d,h - d)
|
|
}(e, t, r, Uint8Array)
|
|
}
|
|
function Yi(e) {
|
|
var t = {
|
|
key: e.type,
|
|
description: "",
|
|
data: "",
|
|
mimeType: null,
|
|
pictureType: null
|
|
};
|
|
if (!(e.size < 2))
|
|
if (3 === e.data[0]) {
|
|
var r = e.data.subarray(1).indexOf(0);
|
|
if (-1 !== r) {
|
|
var i = q(Hi(e.data, 1, r))
|
|
, n = e.data[2 + r]
|
|
, a = e.data.subarray(3 + r).indexOf(0);
|
|
if (-1 !== a) {
|
|
var s, o = q(Hi(e.data, 3 + r, a));
|
|
return s = "--\x3e" === i ? q(Hi(e.data, 4 + r + a)) : function(e) {
|
|
return e instanceof ArrayBuffer ? e : 0 == e.byteOffset && e.byteLength == e.buffer.byteLength ? e.buffer : new Uint8Array(e).buffer
|
|
}(e.data.subarray(4 + r + a)),
|
|
t.mimeType = i,
|
|
t.pictureType = n,
|
|
t.description = o,
|
|
t.data = s,
|
|
t
|
|
}
|
|
}
|
|
} else
|
|
console.log("Ignore frame with unrecognized character encoding")
|
|
}
|
|
function Wi(e) {
|
|
return "PRIV" === e.type ? function(e) {
|
|
if (!(e.size < 2)) {
|
|
var t = q(e.data, !0)
|
|
, r = new Uint8Array(e.data.subarray(t.length + 1));
|
|
return {
|
|
key: e.type,
|
|
info: t,
|
|
data: r.buffer
|
|
}
|
|
}
|
|
}(e) : "W" === e.type[0] ? function(e) {
|
|
if ("WXXX" === e.type) {
|
|
if (e.size < 2)
|
|
return;
|
|
var t = 1
|
|
, r = q(e.data.subarray(t), !0);
|
|
t += r.length + 1;
|
|
var i = q(e.data.subarray(t));
|
|
return {
|
|
key: e.type,
|
|
info: r,
|
|
data: i
|
|
}
|
|
}
|
|
var n = q(e.data);
|
|
return {
|
|
key: e.type,
|
|
info: "",
|
|
data: n
|
|
}
|
|
}(e) : "APIC" === e.type ? Yi(e) : function(e) {
|
|
if (!(e.size < 2)) {
|
|
if ("TXXX" === e.type) {
|
|
var t = 1
|
|
, r = q(e.data.subarray(t), !0);
|
|
t += r.length + 1;
|
|
var i = q(e.data.subarray(t));
|
|
return {
|
|
key: e.type,
|
|
info: r,
|
|
data: i
|
|
}
|
|
}
|
|
var n = q(e.data.subarray(1));
|
|
return {
|
|
key: e.type,
|
|
info: "",
|
|
data: n
|
|
}
|
|
}
|
|
}(e)
|
|
}
|
|
function ji(e) {
|
|
var t = String.fromCharCode(e[0], e[1], e[2], e[3])
|
|
, r = wi(e, 4);
|
|
return {
|
|
type: t,
|
|
size: r,
|
|
data: e.subarray(10, 10 + r)
|
|
}
|
|
}
|
|
var qi = 10
|
|
, Xi = 10;
|
|
function Qi(e) {
|
|
for (var t = 0, r = []; Ci(e, t); ) {
|
|
var i = wi(e, t + 6);
|
|
e[t + 5] >> 6 & 1 && (t += qi);
|
|
for (var n = (t += qi) + i; t + Xi < n; ) {
|
|
var a = ji(e.subarray(t))
|
|
, s = Wi(a);
|
|
s && r.push(s),
|
|
t += a.size + qi
|
|
}
|
|
Pi(e, t) && (t += qi)
|
|
}
|
|
return r
|
|
}
|
|
function zi(e) {
|
|
return e && "PRIV" === e.key && "com.apple.streaming.transportStreamTimestamp" === e.info
|
|
}
|
|
function $i(e) {
|
|
if (8 === e.data.byteLength) {
|
|
var t = new Uint8Array(e.data)
|
|
, r = 1 & t[3]
|
|
, i = (t[4] << 23) + (t[5] << 15) + (t[6] << 7) + t[7];
|
|
return i /= 45,
|
|
r && (i += 47721858.84),
|
|
Math.round(i)
|
|
}
|
|
}
|
|
function Zi(e) {
|
|
for (var t = Qi(e), r = 0; r < t.length; r++) {
|
|
var i = t[r];
|
|
if (zi(i))
|
|
return $i(i)
|
|
}
|
|
}
|
|
var Ji = function(e) {
|
|
return e.audioId3 = "org.id3",
|
|
e.dateRange = "com.apple.quicktime.HLS",
|
|
e.emsg = "https://aomedia.org/emsg/ID3",
|
|
e.misbklv = "urn:misb:KLV:bin:1910.1",
|
|
e
|
|
}({});
|
|
function en(e, t) {
|
|
return void 0 === e && (e = ""),
|
|
void 0 === t && (t = 9e4),
|
|
{
|
|
type: e,
|
|
id: -1,
|
|
pid: -1,
|
|
inputTimeScale: t,
|
|
sequenceNumber: -1,
|
|
samples: [],
|
|
dropped: 0
|
|
}
|
|
}
|
|
var tn = function() {
|
|
function e() {
|
|
this._audioTrack = void 0,
|
|
this._id3Track = void 0,
|
|
this.frameIndex = 0,
|
|
this.cachedData = null,
|
|
this.basePTS = null,
|
|
this.initPTS = null,
|
|
this.lastPTS = null
|
|
}
|
|
var t = e.prototype;
|
|
return t.resetInitSegment = function(e, t, r, i) {
|
|
this._id3Track = {
|
|
type: "id3",
|
|
id: 3,
|
|
pid: -1,
|
|
inputTimeScale: 9e4,
|
|
sequenceNumber: 0,
|
|
samples: [],
|
|
dropped: 0
|
|
}
|
|
}
|
|
,
|
|
t.resetTimeStamp = function(e) {
|
|
this.initPTS = e,
|
|
this.resetContiguity()
|
|
}
|
|
,
|
|
t.resetContiguity = function() {
|
|
this.basePTS = null,
|
|
this.lastPTS = null,
|
|
this.frameIndex = 0
|
|
}
|
|
,
|
|
t.canParse = function(e, t) {
|
|
return !1
|
|
}
|
|
,
|
|
t.appendFrame = function(e, t, r) {}
|
|
,
|
|
t.demux = function(e, t) {
|
|
this.cachedData && (e = Ae(this.cachedData, e),
|
|
this.cachedData = null);
|
|
var r, i = Oi(e, 0), n = i ? i.length : 0, a = this._audioTrack, s = this._id3Track, o = i ? Zi(i) : void 0, l = e.length;
|
|
for ((null === this.basePTS || 0 === this.frameIndex && A(o)) && (this.basePTS = rn(o, t, this.initPTS),
|
|
this.lastPTS = this.basePTS),
|
|
null === this.lastPTS && (this.lastPTS = this.basePTS),
|
|
i && i.length > 0 && s.samples.push({
|
|
pts: this.lastPTS,
|
|
dts: this.lastPTS,
|
|
data: i,
|
|
type: Ji.audioId3,
|
|
duration: Number.POSITIVE_INFINITY
|
|
}); n < l; ) {
|
|
if (this.canParse(e, n)) {
|
|
var u = this.appendFrame(a, e, n);
|
|
u ? (this.frameIndex++,
|
|
this.lastPTS = u.sample.pts,
|
|
r = n += u.length) : n = l
|
|
} else
|
|
Vi(e, n) ? (i = Oi(e, n),
|
|
s.samples.push({
|
|
pts: this.lastPTS,
|
|
dts: this.lastPTS,
|
|
data: i,
|
|
type: Ji.audioId3,
|
|
duration: Number.POSITIVE_INFINITY
|
|
}),
|
|
r = n += i.length) : n++;
|
|
if (n === l && r !== l) {
|
|
var d = e.slice(r);
|
|
this.cachedData ? this.cachedData = Ae(this.cachedData, d) : this.cachedData = d
|
|
}
|
|
}
|
|
return {
|
|
audioTrack: a,
|
|
videoTrack: en(),
|
|
id3Track: s,
|
|
textTrack: en()
|
|
}
|
|
}
|
|
,
|
|
t.demuxSampleAes = function(e, t, r) {
|
|
return Promise.reject(new Error("[" + this + "] This demuxer does not support Sample-AES decryption"))
|
|
}
|
|
,
|
|
t.flush = function(e) {
|
|
var t = this.cachedData;
|
|
return t && (this.cachedData = null,
|
|
this.demux(t, 0)),
|
|
{
|
|
audioTrack: this._audioTrack,
|
|
videoTrack: en(),
|
|
id3Track: this._id3Track,
|
|
textTrack: en()
|
|
}
|
|
}
|
|
,
|
|
t.destroy = function() {
|
|
this.cachedData = null,
|
|
this._audioTrack = this._id3Track = void 0
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, rn = function(e, t, r) {
|
|
return A(e) ? 90 * e : 9e4 * t + (r ? 9e4 * r.baseTime / r.timescale : 0)
|
|
}
|
|
, nn = null
|
|
, an = [32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160]
|
|
, sn = [44100, 48e3, 32e3, 22050, 24e3, 16e3, 11025, 12e3, 8e3]
|
|
, on = [[0, 72, 144, 12], [0, 0, 0, 0], [0, 72, 144, 12], [0, 144, 144, 12]]
|
|
, ln = [0, 1, 1, 4];
|
|
function un(e, t, r, i, n) {
|
|
if (!(r + 24 > t.length)) {
|
|
var a = dn(t, r);
|
|
if (a && r + a.frameLength <= t.length) {
|
|
var s = i + n * (9e4 * a.samplesPerFrame / a.sampleRate)
|
|
, o = {
|
|
unit: t.subarray(r, r + a.frameLength),
|
|
pts: s,
|
|
dts: s
|
|
};
|
|
return e.config = [],
|
|
e.channelCount = a.channelCount,
|
|
e.samplerate = a.sampleRate,
|
|
e.samples.push(o),
|
|
{
|
|
sample: o,
|
|
length: a.frameLength,
|
|
missing: 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function dn(e, t) {
|
|
var r = e[t + 1] >> 3 & 3
|
|
, i = e[t + 1] >> 1 & 3
|
|
, n = e[t + 2] >> 4 & 15
|
|
, a = e[t + 2] >> 2 & 3;
|
|
if (1 !== r && 0 !== n && 15 !== n && 3 !== a) {
|
|
var s = e[t + 2] >> 1 & 1
|
|
, o = e[t + 3] >> 6
|
|
, l = 1e3 * an[14 * (3 === r ? 3 - i : 3 === i ? 3 : 4) + n - 1]
|
|
, u = sn[3 * (3 === r ? 0 : 2 === r ? 1 : 2) + a]
|
|
, d = 3 === o ? 1 : 2
|
|
, h = on[r][i]
|
|
, f = ln[i]
|
|
, c = 8 * h * f
|
|
, g = Math.floor(h * l / u + s) * f;
|
|
if (null === nn) {
|
|
var v = (navigator.userAgent || "").match(/Chrome\/(\d+)/i);
|
|
nn = v ? parseInt(v[1]) : 0
|
|
}
|
|
return !!nn && nn <= 87 && 2 === i && l >= 224e3 && 0 === o && (e[t + 3] = 128 | e[t + 3]),
|
|
{
|
|
sampleRate: u,
|
|
channelCount: d,
|
|
frameLength: g,
|
|
samplesPerFrame: c
|
|
}
|
|
}
|
|
}
|
|
function hn(e, t) {
|
|
return 255 === e[t] && 224 == (224 & e[t + 1]) && 0 != (6 & e[t + 1])
|
|
}
|
|
function fn(e, t) {
|
|
return t + 1 < e.length && hn(e, t)
|
|
}
|
|
function cn(e, t) {
|
|
if (t + 1 < e.length && hn(e, t)) {
|
|
var r = dn(e, t)
|
|
, i = 4;
|
|
null != r && r.frameLength && (i = r.frameLength);
|
|
var n = t + i;
|
|
return n === e.length || fn(e, n)
|
|
}
|
|
return !1
|
|
}
|
|
var gn = function(e) {
|
|
function t(t, r) {
|
|
var i;
|
|
return (i = e.call(this) || this).observer = void 0,
|
|
i.config = void 0,
|
|
i.observer = t,
|
|
i.config = r,
|
|
i
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.resetInitSegment = function(t, r, i, n) {
|
|
e.prototype.resetInitSegment.call(this, t, r, i, n),
|
|
this._audioTrack = {
|
|
container: "audio/adts",
|
|
type: "audio",
|
|
id: 2,
|
|
pid: -1,
|
|
sequenceNumber: 0,
|
|
segmentCodec: "aac",
|
|
samples: [],
|
|
manifestCodec: r,
|
|
duration: n,
|
|
inputTimeScale: 9e4,
|
|
dropped: 0
|
|
}
|
|
}
|
|
,
|
|
t.probe = function(e, t) {
|
|
if (!e)
|
|
return !1;
|
|
var r = Oi(e, 0)
|
|
, i = (null == r ? void 0 : r.length) || 0;
|
|
if (cn(e, i))
|
|
return !1;
|
|
for (var n = e.length; i < n; i++)
|
|
if (Ui(e, i))
|
|
return t.log("ADTS sync word found !"),
|
|
!0;
|
|
return !1
|
|
}
|
|
,
|
|
r.canParse = function(e, t) {
|
|
return function(e, t) {
|
|
return function(e, t) {
|
|
return t + 5 < e.length
|
|
}(e, t) && xi(e, t) && Fi(e, t) <= e.length - t
|
|
}(e, t)
|
|
}
|
|
,
|
|
r.appendFrame = function(e, t, r) {
|
|
Bi(e, this.observer, t, r, e.manifestCodec);
|
|
var i = Ki(e, t, r, this.basePTS, this.frameIndex);
|
|
if (i && 0 === i.missing)
|
|
return i
|
|
}
|
|
,
|
|
t
|
|
}(tn)
|
|
, vn = function(e, t) {
|
|
var r = 0
|
|
, i = 5;
|
|
t += i;
|
|
for (var n = new Uint32Array(1), a = new Uint32Array(1), s = new Uint8Array(1); i > 0; ) {
|
|
s[0] = e[t];
|
|
var o = Math.min(i, 8)
|
|
, l = 8 - o;
|
|
a[0] = 4278190080 >>> 24 + l << l,
|
|
n[0] = (s[0] & a[0]) >> l,
|
|
r = r ? r << o | n[0] : n[0],
|
|
t += 1,
|
|
i -= o
|
|
}
|
|
return r
|
|
}
|
|
, mn = function(e) {
|
|
function t(t) {
|
|
var r;
|
|
return (r = e.call(this) || this).observer = void 0,
|
|
r.observer = t,
|
|
r
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.resetInitSegment = function(t, r, i, n) {
|
|
e.prototype.resetInitSegment.call(this, t, r, i, n),
|
|
this._audioTrack = {
|
|
container: "audio/ac-3",
|
|
type: "audio",
|
|
id: 2,
|
|
pid: -1,
|
|
sequenceNumber: 0,
|
|
segmentCodec: "ac3",
|
|
samples: [],
|
|
manifestCodec: r,
|
|
duration: n,
|
|
inputTimeScale: 9e4,
|
|
dropped: 0
|
|
}
|
|
}
|
|
,
|
|
r.canParse = function(e, t) {
|
|
return t + 64 < e.length
|
|
}
|
|
,
|
|
r.appendFrame = function(e, t, r) {
|
|
var i = pn(e, t, r, this.basePTS, this.frameIndex);
|
|
if (-1 !== i)
|
|
return {
|
|
sample: e.samples[e.samples.length - 1],
|
|
length: i,
|
|
missing: 0
|
|
}
|
|
}
|
|
,
|
|
t.probe = function(e) {
|
|
if (!e)
|
|
return !1;
|
|
var t = Oi(e, 0);
|
|
if (!t)
|
|
return !1;
|
|
var r = t.length;
|
|
return 11 === e[r] && 119 === e[r + 1] && void 0 !== Zi(t) && vn(e, r) < 16
|
|
}
|
|
,
|
|
t
|
|
}(tn);
|
|
function pn(e, t, r, i, n) {
|
|
if (r + 8 > t.length)
|
|
return -1;
|
|
if (11 !== t[r] || 119 !== t[r + 1])
|
|
return -1;
|
|
var a = t[r + 4] >> 6;
|
|
if (a >= 3)
|
|
return -1;
|
|
var s = [48e3, 44100, 32e3][a]
|
|
, o = 63 & t[r + 4]
|
|
, l = 2 * [64, 69, 96, 64, 70, 96, 80, 87, 120, 80, 88, 120, 96, 104, 144, 96, 105, 144, 112, 121, 168, 112, 122, 168, 128, 139, 192, 128, 140, 192, 160, 174, 240, 160, 175, 240, 192, 208, 288, 192, 209, 288, 224, 243, 336, 224, 244, 336, 256, 278, 384, 256, 279, 384, 320, 348, 480, 320, 349, 480, 384, 417, 576, 384, 418, 576, 448, 487, 672, 448, 488, 672, 512, 557, 768, 512, 558, 768, 640, 696, 960, 640, 697, 960, 768, 835, 1152, 768, 836, 1152, 896, 975, 1344, 896, 976, 1344, 1024, 1114, 1536, 1024, 1115, 1536, 1152, 1253, 1728, 1152, 1254, 1728, 1280, 1393, 1920, 1280, 1394, 1920][3 * o + a];
|
|
if (r + l > t.length)
|
|
return -1;
|
|
var u = t[r + 6] >> 5
|
|
, d = 0;
|
|
2 === u ? d += 2 : (1 & u && 1 !== u && (d += 2),
|
|
4 & u && (d += 2));
|
|
var h = (t[r + 6] << 8 | t[r + 7]) >> 12 - d & 1
|
|
, f = [2, 1, 2, 3, 3, 4, 4, 5][u] + h
|
|
, c = t[r + 5] >> 3
|
|
, g = 7 & t[r + 5]
|
|
, v = new Uint8Array([a << 6 | c << 1 | g >> 2, (3 & g) << 6 | u << 3 | h << 2 | o >> 4, o << 4 & 224])
|
|
, m = i + n * (1536 / s * 9e4)
|
|
, p = t.subarray(r, r + l);
|
|
return e.config = v,
|
|
e.channelCount = f,
|
|
e.samplerate = s,
|
|
e.samples.push({
|
|
unit: p,
|
|
pts: m
|
|
}),
|
|
l
|
|
}
|
|
var yn = function(e) {
|
|
function t() {
|
|
return e.apply(this, arguments) || this
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.resetInitSegment = function(t, r, i, n) {
|
|
e.prototype.resetInitSegment.call(this, t, r, i, n),
|
|
this._audioTrack = {
|
|
container: "audio/mpeg",
|
|
type: "audio",
|
|
id: 2,
|
|
pid: -1,
|
|
sequenceNumber: 0,
|
|
segmentCodec: "mp3",
|
|
samples: [],
|
|
manifestCodec: r,
|
|
duration: n,
|
|
inputTimeScale: 9e4,
|
|
dropped: 0
|
|
}
|
|
}
|
|
,
|
|
t.probe = function(e) {
|
|
if (!e)
|
|
return !1;
|
|
var t = Oi(e, 0)
|
|
, r = (null == t ? void 0 : t.length) || 0;
|
|
if (t && 11 === e[r] && 119 === e[r + 1] && void 0 !== Zi(t) && vn(e, r) <= 16)
|
|
return !1;
|
|
for (var i = e.length; r < i; r++)
|
|
if (cn(e, r))
|
|
return Y.log("MPEG Audio sync word found !"),
|
|
!0;
|
|
return !1
|
|
}
|
|
,
|
|
r.canParse = function(e, t) {
|
|
return function(e, t) {
|
|
return hn(e, t) && 4 <= e.length - t
|
|
}(e, t)
|
|
}
|
|
,
|
|
r.appendFrame = function(e, t, r) {
|
|
if (null !== this.basePTS)
|
|
return un(e, t, r, this.basePTS, this.frameIndex)
|
|
}
|
|
,
|
|
t
|
|
}(tn)
|
|
, En = /\/emsg[-/]ID3/i
|
|
, Tn = function() {
|
|
function e(e, t) {
|
|
this.remainderData = null,
|
|
this.timeOffset = 0,
|
|
this.config = void 0,
|
|
this.videoTrack = void 0,
|
|
this.audioTrack = void 0,
|
|
this.id3Track = void 0,
|
|
this.txtTrack = void 0,
|
|
this.config = t
|
|
}
|
|
var t = e.prototype;
|
|
return t.resetTimeStamp = function() {}
|
|
,
|
|
t.resetInitSegment = function(e, t, r, i) {
|
|
var n = this.videoTrack = en("video", 1)
|
|
, a = this.audioTrack = en("audio", 1)
|
|
, s = this.txtTrack = en("text", 1);
|
|
if (this.id3Track = en("id3", 1),
|
|
this.timeOffset = 0,
|
|
null != e && e.byteLength) {
|
|
var o = ve(e);
|
|
if (o.video) {
|
|
var l = o.video
|
|
, u = l.id
|
|
, d = l.timescale
|
|
, h = l.codec
|
|
, f = l.supplemental;
|
|
n.id = u,
|
|
n.timescale = s.timescale = d,
|
|
n.codec = h,
|
|
n.supplemental = f
|
|
}
|
|
if (o.audio) {
|
|
var c = o.audio
|
|
, g = c.id
|
|
, v = c.timescale
|
|
, m = c.codec;
|
|
a.id = g,
|
|
a.timescale = v,
|
|
a.codec = m
|
|
}
|
|
s.id = oe.text,
|
|
n.sampleDuration = 0,
|
|
n.duration = a.duration = i
|
|
}
|
|
}
|
|
,
|
|
t.resetContiguity = function() {
|
|
this.remainderData = null
|
|
}
|
|
,
|
|
e.probe = function(e) {
|
|
return function(e) {
|
|
for (var t = e.byteLength, r = 0; r < t; ) {
|
|
var i = de(e, r);
|
|
if (i > 8 && 109 === e[r + 4] && 111 === e[r + 5] && 111 === e[r + 6] && 102 === e[r + 7])
|
|
return !0;
|
|
r = i > 1 ? r + i : t
|
|
}
|
|
return !1
|
|
}(e)
|
|
}
|
|
,
|
|
t.demux = function(e, t) {
|
|
this.timeOffset = t;
|
|
var r = e
|
|
, i = this.videoTrack
|
|
, n = this.txtTrack;
|
|
if (this.config.progressive) {
|
|
this.remainderData && (r = Ae(this.remainderData, e));
|
|
var a = function(e) {
|
|
var t = {
|
|
valid: null,
|
|
remainder: null
|
|
}
|
|
, r = ce(e, ["moof"]);
|
|
if (r.length < 2)
|
|
return t.remainder = e,
|
|
t;
|
|
var i = r[r.length - 1];
|
|
return t.valid = e.slice(0, i.byteOffset - 8),
|
|
t.remainder = e.slice(i.byteOffset - 8),
|
|
t
|
|
}(r);
|
|
this.remainderData = a.remainder,
|
|
i.samples = a.valid || new Uint8Array
|
|
} else
|
|
i.samples = r;
|
|
var s = this.extractID3Track(i, t);
|
|
return n.samples = Le(t, i),
|
|
{
|
|
videoTrack: i,
|
|
audioTrack: this.audioTrack,
|
|
id3Track: s,
|
|
textTrack: this.txtTrack
|
|
}
|
|
}
|
|
,
|
|
t.flush = function() {
|
|
var e = this.timeOffset
|
|
, t = this.videoTrack
|
|
, r = this.txtTrack;
|
|
t.samples = this.remainderData || new Uint8Array,
|
|
this.remainderData = null;
|
|
var i = this.extractID3Track(t, this.timeOffset);
|
|
return r.samples = Le(e, t),
|
|
{
|
|
videoTrack: t,
|
|
audioTrack: en(),
|
|
id3Track: i,
|
|
textTrack: en()
|
|
}
|
|
}
|
|
,
|
|
t.extractID3Track = function(e, t) {
|
|
var r = this
|
|
, i = this.id3Track;
|
|
if (e.samples.length) {
|
|
var n = ce(e.samples, ["emsg"]);
|
|
n && n.forEach((function(e) {
|
|
var n = function(e) {
|
|
var t = e[0]
|
|
, r = ""
|
|
, i = ""
|
|
, n = 0
|
|
, a = 0
|
|
, s = 0
|
|
, o = 0
|
|
, l = 0
|
|
, u = 0;
|
|
if (0 === t) {
|
|
for (; "\0" !== le(e.subarray(u, u + 1)); )
|
|
r += le(e.subarray(u, u + 1)),
|
|
u += 1;
|
|
for (r += le(e.subarray(u, u + 1)),
|
|
u += 1; "\0" !== le(e.subarray(u, u + 1)); )
|
|
i += le(e.subarray(u, u + 1)),
|
|
u += 1;
|
|
i += le(e.subarray(u, u + 1)),
|
|
u += 1,
|
|
n = de(e, 12),
|
|
a = de(e, 16),
|
|
o = de(e, 20),
|
|
l = de(e, 24),
|
|
u = 28
|
|
} else if (1 === t) {
|
|
n = de(e, u += 4);
|
|
var d = de(e, u += 4)
|
|
, h = de(e, u += 4);
|
|
for (u += 4,
|
|
s = Math.pow(2, 32) * d + h,
|
|
L(s) || (s = Number.MAX_SAFE_INTEGER,
|
|
Y.warn("Presentation time exceeds safe integer limit and wrapped to max safe integer in parsing emsg box")),
|
|
o = de(e, u),
|
|
l = de(e, u += 4),
|
|
u += 4; "\0" !== le(e.subarray(u, u + 1)); )
|
|
r += le(e.subarray(u, u + 1)),
|
|
u += 1;
|
|
for (r += le(e.subarray(u, u + 1)),
|
|
u += 1; "\0" !== le(e.subarray(u, u + 1)); )
|
|
i += le(e.subarray(u, u + 1)),
|
|
u += 1;
|
|
i += le(e.subarray(u, u + 1)),
|
|
u += 1
|
|
}
|
|
return {
|
|
schemeIdUri: r,
|
|
value: i,
|
|
timeScale: n,
|
|
presentationTime: s,
|
|
presentationTimeDelta: a,
|
|
eventDuration: o,
|
|
id: l,
|
|
payload: e.subarray(u, e.byteLength)
|
|
}
|
|
}(e);
|
|
if (En.test(n.schemeIdUri)) {
|
|
var a = Sn(n, t)
|
|
, s = 4294967295 === n.eventDuration ? Number.POSITIVE_INFINITY : n.eventDuration / n.timeScale;
|
|
s <= .001 && (s = Number.POSITIVE_INFINITY);
|
|
var o = n.payload;
|
|
i.samples.push({
|
|
data: o,
|
|
len: o.byteLength,
|
|
dts: a,
|
|
pts: a,
|
|
type: Ji.emsg,
|
|
duration: s
|
|
})
|
|
} else if (r.config.enableEmsgKLVMetadata && n.schemeIdUri.startsWith("urn:misb:KLV:bin:1910.1")) {
|
|
var l = Sn(n, t);
|
|
i.samples.push({
|
|
data: n.payload,
|
|
len: n.payload.byteLength,
|
|
dts: l,
|
|
pts: l,
|
|
type: Ji.misbklv,
|
|
duration: Number.POSITIVE_INFINITY
|
|
})
|
|
}
|
|
}
|
|
))
|
|
}
|
|
return i
|
|
}
|
|
,
|
|
t.demuxSampleAes = function(e, t, r) {
|
|
return Promise.reject(new Error("The MP4 demuxer does not support SAMPLE-AES decryption"))
|
|
}
|
|
,
|
|
t.destroy = function() {
|
|
this.config = null,
|
|
this.remainderData = null,
|
|
this.videoTrack = this.audioTrack = this.id3Track = this.txtTrack = void 0
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function Sn(e, t) {
|
|
return A(e.presentationTime) ? e.presentationTime / e.timeScale : t + e.presentationTimeDelta / e.timeScale
|
|
}
|
|
var An = function() {
|
|
function e(e, t, r) {
|
|
this.keyData = void 0,
|
|
this.decrypter = void 0,
|
|
this.keyData = r,
|
|
this.decrypter = new er(t,{
|
|
removePKCS7Padding: !1
|
|
})
|
|
}
|
|
var t = e.prototype;
|
|
return t.decryptBuffer = function(e) {
|
|
return this.decrypter.decrypt(e, this.keyData.key.buffer, this.keyData.iv.buffer, Qt)
|
|
}
|
|
,
|
|
t.decryptAacSample = function(e, t, r) {
|
|
var i = this
|
|
, n = e[t].unit;
|
|
if (!(n.length <= 16)) {
|
|
var a = n.subarray(16, n.length - n.length % 16)
|
|
, s = a.buffer.slice(a.byteOffset, a.byteOffset + a.length);
|
|
this.decryptBuffer(s).then((function(a) {
|
|
var s = new Uint8Array(a);
|
|
n.set(s, 16),
|
|
i.decrypter.isSync() || i.decryptAacSamples(e, t + 1, r)
|
|
}
|
|
)).catch(r)
|
|
}
|
|
}
|
|
,
|
|
t.decryptAacSamples = function(e, t, r) {
|
|
for (; ; t++) {
|
|
if (t >= e.length)
|
|
return void r();
|
|
if (!(e[t].unit.length < 32 || (this.decryptAacSample(e, t, r),
|
|
this.decrypter.isSync())))
|
|
return
|
|
}
|
|
}
|
|
,
|
|
t.getAvcEncryptedData = function(e) {
|
|
for (var t = 16 * Math.floor((e.length - 48) / 160) + 16, r = new Int8Array(t), i = 0, n = 32; n < e.length - 16; n += 160,
|
|
i += 16)
|
|
r.set(e.subarray(n, n + 16), i);
|
|
return r
|
|
}
|
|
,
|
|
t.getAvcDecryptedUnit = function(e, t) {
|
|
for (var r = new Uint8Array(t), i = 0, n = 32; n < e.length - 16; n += 160,
|
|
i += 16)
|
|
e.set(r.subarray(i, i + 16), n);
|
|
return e
|
|
}
|
|
,
|
|
t.decryptAvcSample = function(e, t, r, i, n) {
|
|
var a = this
|
|
, s = be(n.data)
|
|
, o = this.getAvcEncryptedData(s);
|
|
this.decryptBuffer(o.buffer).then((function(o) {
|
|
n.data = a.getAvcDecryptedUnit(s, o),
|
|
a.decrypter.isSync() || a.decryptAvcSamples(e, t, r + 1, i)
|
|
}
|
|
)).catch(i)
|
|
}
|
|
,
|
|
t.decryptAvcSamples = function(e, t, r, i) {
|
|
if (e instanceof Uint8Array)
|
|
throw new Error("Cannot decrypt samples of type Uint8Array");
|
|
for (; ; t++,
|
|
r = 0) {
|
|
if (t >= e.length)
|
|
return void i();
|
|
for (var n = e[t].units; !(r >= n.length); r++) {
|
|
var a = n[r];
|
|
if (!(a.data.length <= 48 || 1 !== a.type && 5 !== a.type || (this.decryptAvcSample(e, t, r, i, a),
|
|
this.decrypter.isSync())))
|
|
return
|
|
}
|
|
}
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, Ln = function() {
|
|
function e() {
|
|
this.VideoSample = null
|
|
}
|
|
var t = e.prototype;
|
|
return t.createVideoSample = function(e, t, r) {
|
|
return {
|
|
key: e,
|
|
frame: !1,
|
|
pts: t,
|
|
dts: r,
|
|
units: [],
|
|
length: 0
|
|
}
|
|
}
|
|
,
|
|
t.getLastNalUnit = function(e) {
|
|
var t, r, i = this.VideoSample;
|
|
if (i && 0 !== i.units.length || (i = e[e.length - 1]),
|
|
null != (t = i) && t.units) {
|
|
var n = i.units;
|
|
r = n[n.length - 1]
|
|
}
|
|
return r
|
|
}
|
|
,
|
|
t.pushAccessUnit = function(e, t) {
|
|
if (e.units.length && e.frame) {
|
|
if (void 0 === e.pts) {
|
|
var r = t.samples
|
|
, i = r.length;
|
|
if (!i)
|
|
return void t.dropped++;
|
|
var n = r[i - 1];
|
|
e.pts = n.pts,
|
|
e.dts = n.dts
|
|
}
|
|
t.samples.push(e)
|
|
}
|
|
}
|
|
,
|
|
t.parseNALu = function(e, t, r) {
|
|
var i, n, a = t.byteLength, s = e.naluState || 0, o = s, l = [], u = 0, d = -1, h = 0;
|
|
for (-1 === s && (d = 0,
|
|
h = this.getNALuType(t, 0),
|
|
s = 0,
|
|
u = 1); u < a; )
|
|
if (i = t[u++],
|
|
s)
|
|
if (1 !== s)
|
|
if (i)
|
|
if (1 === i) {
|
|
if (n = u - s - 1,
|
|
d >= 0) {
|
|
var f = {
|
|
data: t.subarray(d, n),
|
|
type: h
|
|
};
|
|
l.push(f)
|
|
} else {
|
|
var c = this.getLastNalUnit(e.samples);
|
|
c && (o && u <= 4 - o && c.state && (c.data = c.data.subarray(0, c.data.byteLength - o)),
|
|
n > 0 && (c.data = Ae(c.data, t.subarray(0, n)),
|
|
c.state = 0))
|
|
}
|
|
u < a ? (d = u,
|
|
h = this.getNALuType(t, u),
|
|
s = 0) : s = -1
|
|
} else
|
|
s = 0;
|
|
else
|
|
s = 3;
|
|
else
|
|
s = i ? 0 : 2;
|
|
else
|
|
s = i ? 0 : 1;
|
|
if (d >= 0 && s >= 0) {
|
|
var g = {
|
|
data: t.subarray(d, a),
|
|
type: h,
|
|
state: s
|
|
};
|
|
l.push(g)
|
|
}
|
|
if (0 === l.length) {
|
|
var v = this.getLastNalUnit(e.samples);
|
|
v && (v.data = Ae(v.data, t))
|
|
}
|
|
return e.naluState = s,
|
|
l
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, In = function() {
|
|
function e(e) {
|
|
this.data = void 0,
|
|
this.bytesAvailable = void 0,
|
|
this.word = void 0,
|
|
this.bitsAvailable = void 0,
|
|
this.data = e,
|
|
this.bytesAvailable = e.byteLength,
|
|
this.word = 0,
|
|
this.bitsAvailable = 0
|
|
}
|
|
var t = e.prototype;
|
|
return t.loadWord = function() {
|
|
var e = this.data
|
|
, t = this.bytesAvailable
|
|
, r = e.byteLength - t
|
|
, i = new Uint8Array(4)
|
|
, n = Math.min(4, t);
|
|
if (0 === n)
|
|
throw new Error("no bytes available");
|
|
i.set(e.subarray(r, r + n)),
|
|
this.word = new DataView(i.buffer).getUint32(0),
|
|
this.bitsAvailable = 8 * n,
|
|
this.bytesAvailable -= n
|
|
}
|
|
,
|
|
t.skipBits = function(e) {
|
|
var t;
|
|
e = Math.min(e, 8 * this.bytesAvailable + this.bitsAvailable),
|
|
this.bitsAvailable > e ? (this.word <<= e,
|
|
this.bitsAvailable -= e) : (e -= this.bitsAvailable,
|
|
e -= (t = e >> 3) << 3,
|
|
this.bytesAvailable -= t,
|
|
this.loadWord(),
|
|
this.word <<= e,
|
|
this.bitsAvailable -= e)
|
|
}
|
|
,
|
|
t.readBits = function(e) {
|
|
var t = Math.min(this.bitsAvailable, e)
|
|
, r = this.word >>> 32 - t;
|
|
if (e > 32 && Y.error("Cannot read more than 32 bits at a time"),
|
|
this.bitsAvailable -= t,
|
|
this.bitsAvailable > 0)
|
|
this.word <<= t;
|
|
else {
|
|
if (!(this.bytesAvailable > 0))
|
|
throw new Error("no bits available");
|
|
this.loadWord()
|
|
}
|
|
return (t = e - t) > 0 && this.bitsAvailable ? r << t | this.readBits(t) : r
|
|
}
|
|
,
|
|
t.skipLZ = function() {
|
|
var e;
|
|
for (e = 0; e < this.bitsAvailable; ++e)
|
|
if (0 != (this.word & 2147483648 >>> e))
|
|
return this.word <<= e,
|
|
this.bitsAvailable -= e,
|
|
e;
|
|
return this.loadWord(),
|
|
e + this.skipLZ()
|
|
}
|
|
,
|
|
t.skipUEG = function() {
|
|
this.skipBits(1 + this.skipLZ())
|
|
}
|
|
,
|
|
t.skipEG = function() {
|
|
this.skipBits(1 + this.skipLZ())
|
|
}
|
|
,
|
|
t.readUEG = function() {
|
|
var e = this.skipLZ();
|
|
return this.readBits(e + 1) - 1
|
|
}
|
|
,
|
|
t.readEG = function() {
|
|
var e = this.readUEG();
|
|
return 1 & e ? 1 + e >>> 1 : -1 * (e >>> 1)
|
|
}
|
|
,
|
|
t.readBoolean = function() {
|
|
return 1 === this.readBits(1)
|
|
}
|
|
,
|
|
t.readUByte = function() {
|
|
return this.readBits(8)
|
|
}
|
|
,
|
|
t.readUShort = function() {
|
|
return this.readBits(16)
|
|
}
|
|
,
|
|
t.readUInt = function() {
|
|
return this.readBits(32)
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, Rn = function(e) {
|
|
function t() {
|
|
return e.apply(this, arguments) || this
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.parsePES = function(e, t, r, i) {
|
|
var n, a = this, s = this.parseNALu(e, r.data, i), o = this.VideoSample, l = !1;
|
|
r.data = null,
|
|
o && s.length && !e.audFound && (this.pushAccessUnit(o, e),
|
|
o = this.VideoSample = this.createVideoSample(!1, r.pts, r.dts)),
|
|
s.forEach((function(i) {
|
|
var s, u;
|
|
switch (i.type) {
|
|
case 1:
|
|
var d = !1;
|
|
n = !0;
|
|
var h, f = i.data;
|
|
if (l && f.length > 4) {
|
|
var c = a.readSliceType(f);
|
|
2 !== c && 4 !== c && 7 !== c && 9 !== c || (d = !0)
|
|
}
|
|
d && null != (h = o) && h.frame && !o.key && (a.pushAccessUnit(o, e),
|
|
o = a.VideoSample = null),
|
|
o || (o = a.VideoSample = a.createVideoSample(!0, r.pts, r.dts)),
|
|
o.frame = !0,
|
|
o.key = d;
|
|
break;
|
|
case 5:
|
|
n = !0,
|
|
null != (s = o) && s.frame && !o.key && (a.pushAccessUnit(o, e),
|
|
o = a.VideoSample = null),
|
|
o || (o = a.VideoSample = a.createVideoSample(!0, r.pts, r.dts)),
|
|
o.key = !0,
|
|
o.frame = !0;
|
|
break;
|
|
case 6:
|
|
n = !0,
|
|
ke(i.data, 1, r.pts, t.samples);
|
|
break;
|
|
case 7:
|
|
var g, v;
|
|
n = !0,
|
|
l = !0;
|
|
var m = i.data
|
|
, p = a.readSPS(m);
|
|
if (!e.sps || e.width !== p.width || e.height !== p.height || (null == (g = e.pixelRatio) ? void 0 : g[0]) !== p.pixelRatio[0] || (null == (v = e.pixelRatio) ? void 0 : v[1]) !== p.pixelRatio[1]) {
|
|
e.width = p.width,
|
|
e.height = p.height,
|
|
e.pixelRatio = p.pixelRatio,
|
|
e.sps = [m];
|
|
for (var y = m.subarray(1, 4), E = "avc1.", T = 0; T < 3; T++) {
|
|
var S = y[T].toString(16);
|
|
S.length < 2 && (S = "0" + S),
|
|
E += S
|
|
}
|
|
e.codec = E
|
|
}
|
|
break;
|
|
case 8:
|
|
n = !0,
|
|
e.pps = [i.data];
|
|
break;
|
|
case 9:
|
|
n = !0,
|
|
e.audFound = !0,
|
|
null != (u = o) && u.frame && (a.pushAccessUnit(o, e),
|
|
o = null),
|
|
o || (o = a.VideoSample = a.createVideoSample(!1, r.pts, r.dts));
|
|
break;
|
|
case 12:
|
|
n = !0;
|
|
break;
|
|
default:
|
|
n = !1
|
|
}
|
|
o && n && o.units.push(i)
|
|
}
|
|
)),
|
|
i && o && (this.pushAccessUnit(o, e),
|
|
this.VideoSample = null)
|
|
}
|
|
,
|
|
r.getNALuType = function(e, t) {
|
|
return 31 & e[t]
|
|
}
|
|
,
|
|
r.readSliceType = function(e) {
|
|
var t = new In(e);
|
|
return t.readUByte(),
|
|
t.readUEG(),
|
|
t.readUEG()
|
|
}
|
|
,
|
|
r.skipScalingList = function(e, t) {
|
|
for (var r = 8, i = 8, n = 0; n < e; n++)
|
|
0 !== i && (i = (r + t.readEG() + 256) % 256),
|
|
r = 0 === i ? r : i
|
|
}
|
|
,
|
|
r.readSPS = function(e) {
|
|
var t, r, i, n = new In(e), a = 0, s = 0, o = 0, l = 0, u = n.readUByte.bind(n), d = n.readBits.bind(n), h = n.readUEG.bind(n), f = n.readBoolean.bind(n), c = n.skipBits.bind(n), g = n.skipEG.bind(n), v = n.skipUEG.bind(n), m = this.skipScalingList.bind(this);
|
|
u();
|
|
var p = u();
|
|
if (d(5),
|
|
c(3),
|
|
u(),
|
|
v(),
|
|
100 === p || 110 === p || 122 === p || 244 === p || 44 === p || 83 === p || 86 === p || 118 === p || 128 === p) {
|
|
var y = h();
|
|
if (3 === y && c(1),
|
|
v(),
|
|
v(),
|
|
c(1),
|
|
f())
|
|
for (r = 3 !== y ? 8 : 12,
|
|
i = 0; i < r; i++)
|
|
f() && m(i < 6 ? 16 : 64, n)
|
|
}
|
|
v();
|
|
var E = h();
|
|
if (0 === E)
|
|
h();
|
|
else if (1 === E)
|
|
for (c(1),
|
|
g(),
|
|
g(),
|
|
t = h(),
|
|
i = 0; i < t; i++)
|
|
g();
|
|
v(),
|
|
c(1);
|
|
var T = h()
|
|
, S = h()
|
|
, A = d(1);
|
|
0 === A && c(1),
|
|
c(1),
|
|
f() && (a = h(),
|
|
s = h(),
|
|
o = h(),
|
|
l = h());
|
|
var L = [1, 1];
|
|
if (f() && f())
|
|
switch (u()) {
|
|
case 1:
|
|
L = [1, 1];
|
|
break;
|
|
case 2:
|
|
L = [12, 11];
|
|
break;
|
|
case 3:
|
|
L = [10, 11];
|
|
break;
|
|
case 4:
|
|
L = [16, 11];
|
|
break;
|
|
case 5:
|
|
L = [40, 33];
|
|
break;
|
|
case 6:
|
|
L = [24, 11];
|
|
break;
|
|
case 7:
|
|
L = [20, 11];
|
|
break;
|
|
case 8:
|
|
L = [32, 11];
|
|
break;
|
|
case 9:
|
|
L = [80, 33];
|
|
break;
|
|
case 10:
|
|
L = [18, 11];
|
|
break;
|
|
case 11:
|
|
L = [15, 11];
|
|
break;
|
|
case 12:
|
|
L = [64, 33];
|
|
break;
|
|
case 13:
|
|
L = [160, 99];
|
|
break;
|
|
case 14:
|
|
L = [4, 3];
|
|
break;
|
|
case 15:
|
|
L = [3, 2];
|
|
break;
|
|
case 16:
|
|
L = [2, 1];
|
|
break;
|
|
case 255:
|
|
L = [u() << 8 | u(), u() << 8 | u()]
|
|
}
|
|
return {
|
|
width: Math.ceil(16 * (T + 1) - 2 * a - 2 * s),
|
|
height: (2 - A) * (S + 1) * 16 - (A ? 2 : 4) * (o + l),
|
|
pixelRatio: L
|
|
}
|
|
}
|
|
,
|
|
t
|
|
}(Ln)
|
|
, kn = function(e) {
|
|
function t() {
|
|
for (var t, r = arguments.length, i = new Array(r), n = 0; n < r; n++)
|
|
i[n] = arguments[n];
|
|
return (t = e.call.apply(e, [this].concat(i)) || this).initVPS = null,
|
|
t
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.parsePES = function(e, t, r, i) {
|
|
var n, s = this, o = this.parseNALu(e, r.data, i), l = this.VideoSample, u = !1;
|
|
r.data = null,
|
|
l && o.length && !e.audFound && (this.pushAccessUnit(l, e),
|
|
l = this.VideoSample = this.createVideoSample(!1, r.pts, r.dts)),
|
|
o.forEach((function(i) {
|
|
var o, d;
|
|
switch (i.type) {
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
case 6:
|
|
case 7:
|
|
case 8:
|
|
case 9:
|
|
l || (l = s.VideoSample = s.createVideoSample(!1, r.pts, r.dts)),
|
|
l.frame = !0,
|
|
n = !0;
|
|
break;
|
|
case 16:
|
|
case 17:
|
|
case 18:
|
|
case 21:
|
|
var h;
|
|
n = !0,
|
|
u && null != (h = l) && h.frame && !l.key && (s.pushAccessUnit(l, e),
|
|
l = s.VideoSample = null),
|
|
l || (l = s.VideoSample = s.createVideoSample(!0, r.pts, r.dts)),
|
|
l.key = !0,
|
|
l.frame = !0;
|
|
break;
|
|
case 19:
|
|
case 20:
|
|
n = !0,
|
|
null != (o = l) && o.frame && !l.key && (s.pushAccessUnit(l, e),
|
|
l = s.VideoSample = null),
|
|
l || (l = s.VideoSample = s.createVideoSample(!0, r.pts, r.dts)),
|
|
l.key = !0,
|
|
l.frame = !0;
|
|
break;
|
|
case 39:
|
|
n = !0,
|
|
ke(i.data, 2, r.pts, t.samples);
|
|
break;
|
|
case 32:
|
|
n = !0,
|
|
e.vps || ("object" != typeof e.params && (e.params = {}),
|
|
e.params = a(e.params, s.readVPS(i.data)),
|
|
s.initVPS = i.data),
|
|
e.vps = [i.data];
|
|
break;
|
|
case 33:
|
|
if (n = !0,
|
|
u = !0,
|
|
void 0 === e.vps || e.vps[0] === s.initVPS || void 0 === e.sps || s.matchSPS(e.sps[0], i.data) || (s.initVPS = e.vps[0],
|
|
e.sps = e.pps = void 0),
|
|
!e.sps) {
|
|
var f = s.readSPS(i.data);
|
|
for (var c in e.width = f.width,
|
|
e.height = f.height,
|
|
e.pixelRatio = f.pixelRatio,
|
|
e.codec = f.codecString,
|
|
e.sps = [],
|
|
"object" != typeof e.params && (e.params = {}),
|
|
f.params)
|
|
e.params[c] = f.params[c]
|
|
}
|
|
s.pushParameterSet(e.sps, i.data, e.vps),
|
|
l || (l = s.VideoSample = s.createVideoSample(!0, r.pts, r.dts)),
|
|
l.key = !0;
|
|
break;
|
|
case 34:
|
|
if (n = !0,
|
|
"object" == typeof e.params) {
|
|
if (!e.pps) {
|
|
e.pps = [];
|
|
var g = s.readPPS(i.data);
|
|
for (var v in g)
|
|
e.params[v] = g[v]
|
|
}
|
|
s.pushParameterSet(e.pps, i.data, e.vps)
|
|
}
|
|
break;
|
|
case 35:
|
|
n = !0,
|
|
e.audFound = !0,
|
|
null != (d = l) && d.frame && (s.pushAccessUnit(l, e),
|
|
l = null),
|
|
l || (l = s.VideoSample = s.createVideoSample(!1, r.pts, r.dts));
|
|
break;
|
|
default:
|
|
n = !1
|
|
}
|
|
l && n && l.units.push(i)
|
|
}
|
|
)),
|
|
i && l && (this.pushAccessUnit(l, e),
|
|
this.VideoSample = null)
|
|
}
|
|
,
|
|
r.pushParameterSet = function(e, t, r) {
|
|
(r && r[0] === this.initVPS || !r && !e.length) && e.push(t)
|
|
}
|
|
,
|
|
r.getNALuType = function(e, t) {
|
|
return (126 & e[t]) >>> 1
|
|
}
|
|
,
|
|
r.ebsp2rbsp = function(e) {
|
|
for (var t = new Uint8Array(e.byteLength), r = 0, i = 0; i < e.byteLength; i++)
|
|
i >= 2 && 3 === e[i] && 0 === e[i - 1] && 0 === e[i - 2] || (t[r] = e[i],
|
|
r++);
|
|
return new Uint8Array(t.buffer,0,r)
|
|
}
|
|
,
|
|
r.pushAccessUnit = function(t, r) {
|
|
e.prototype.pushAccessUnit.call(this, t, r),
|
|
this.initVPS && (this.initVPS = null)
|
|
}
|
|
,
|
|
r.readVPS = function(e) {
|
|
var t = new In(e);
|
|
return t.readUByte(),
|
|
t.readUByte(),
|
|
t.readBits(4),
|
|
t.skipBits(2),
|
|
t.readBits(6),
|
|
{
|
|
numTemporalLayers: t.readBits(3) + 1,
|
|
temporalIdNested: t.readBoolean()
|
|
}
|
|
}
|
|
,
|
|
r.readSPS = function(e) {
|
|
var t = new In(this.ebsp2rbsp(e));
|
|
t.readUByte(),
|
|
t.readUByte(),
|
|
t.readBits(4);
|
|
var r = t.readBits(3);
|
|
t.readBoolean();
|
|
for (var i = t.readBits(2), n = t.readBoolean(), a = t.readBits(5), s = t.readUByte(), o = t.readUByte(), l = t.readUByte(), u = t.readUByte(), d = t.readUByte(), h = t.readUByte(), f = t.readUByte(), c = t.readUByte(), g = t.readUByte(), v = t.readUByte(), m = t.readUByte(), p = [], y = [], E = 0; E < r; E++)
|
|
p.push(t.readBoolean()),
|
|
y.push(t.readBoolean());
|
|
if (r > 0)
|
|
for (var T = r; T < 8; T++)
|
|
t.readBits(2);
|
|
for (var S = 0; S < r; S++)
|
|
p[S] && (t.readUByte(),
|
|
t.readUByte(),
|
|
t.readUByte(),
|
|
t.readUByte(),
|
|
t.readUByte(),
|
|
t.readUByte(),
|
|
t.readUByte(),
|
|
t.readUByte(),
|
|
t.readUByte(),
|
|
t.readUByte(),
|
|
t.readUByte()),
|
|
y[S] && t.readUByte();
|
|
t.readUEG();
|
|
var A = t.readUEG();
|
|
3 == A && t.skipBits(1);
|
|
var L = t.readUEG()
|
|
, I = t.readUEG()
|
|
, R = t.readBoolean()
|
|
, k = 0
|
|
, b = 0
|
|
, D = 0
|
|
, _ = 0;
|
|
R && (k += t.readUEG(),
|
|
b += t.readUEG(),
|
|
D += t.readUEG(),
|
|
_ += t.readUEG());
|
|
for (var P = t.readUEG(), C = t.readUEG(), w = t.readUEG(), O = t.readBoolean() ? 0 : r; O <= r; O++)
|
|
t.skipUEG(),
|
|
t.skipUEG(),
|
|
t.skipUEG();
|
|
if (t.skipUEG(),
|
|
t.skipUEG(),
|
|
t.skipUEG(),
|
|
t.skipUEG(),
|
|
t.skipUEG(),
|
|
t.skipUEG(),
|
|
t.readBoolean() && t.readBoolean())
|
|
for (var x = 0; x < 4; x++)
|
|
for (var M = 0; M < (3 === x ? 2 : 6); M++)
|
|
if (t.readBoolean()) {
|
|
var F = Math.min(64, 1 << 4 + (x << 1));
|
|
x > 1 && t.readEG();
|
|
for (var N = 0; N < F; N++)
|
|
t.readEG()
|
|
} else
|
|
t.readUEG();
|
|
t.readBoolean(),
|
|
t.readBoolean(),
|
|
t.readBoolean() && (t.readUByte(),
|
|
t.skipUEG(),
|
|
t.skipUEG(),
|
|
t.readBoolean());
|
|
for (var U = t.readUEG(), B = 0, G = 0; G < U; G++) {
|
|
var K = !1;
|
|
if (0 !== G && (K = t.readBoolean()),
|
|
K) {
|
|
G === U && t.readUEG(),
|
|
t.readBoolean(),
|
|
t.readUEG();
|
|
for (var V = 0, H = 0; H <= B; H++) {
|
|
var Y = t.readBoolean()
|
|
, W = !1;
|
|
Y || (W = t.readBoolean()),
|
|
(Y || W) && V++
|
|
}
|
|
B = V
|
|
} else {
|
|
var j = t.readUEG()
|
|
, q = t.readUEG();
|
|
B = j + q;
|
|
for (var X = 0; X < j; X++)
|
|
t.readUEG(),
|
|
t.readBoolean();
|
|
for (var Q = 0; Q < q; Q++)
|
|
t.readUEG(),
|
|
t.readBoolean()
|
|
}
|
|
}
|
|
if (t.readBoolean())
|
|
for (var z = t.readUEG(), $ = 0; $ < z; $++) {
|
|
for (var Z = 0; Z < w + 4; Z++)
|
|
t.readBits(1);
|
|
t.readBits(1)
|
|
}
|
|
var J = 0
|
|
, ee = 1
|
|
, te = 1
|
|
, re = !0
|
|
, ie = 1
|
|
, ne = 0;
|
|
if (t.readBoolean(),
|
|
t.readBoolean(),
|
|
t.readBoolean()) {
|
|
if (t.readBoolean()) {
|
|
var ae = t.readUByte();
|
|
ae > 0 && ae < 16 ? (ee = [1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2][ae - 1],
|
|
te = [1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1][ae - 1]) : 255 === ae && (ee = t.readBits(16),
|
|
te = t.readBits(16))
|
|
}
|
|
if (t.readBoolean() && t.readBoolean(),
|
|
t.readBoolean() && (t.readBits(3),
|
|
t.readBoolean(),
|
|
t.readBoolean() && (t.readUByte(),
|
|
t.readUByte(),
|
|
t.readUByte())),
|
|
t.readBoolean() && (t.readUEG(),
|
|
t.readUEG()),
|
|
t.readBoolean(),
|
|
t.readBoolean(),
|
|
t.readBoolean(),
|
|
t.readBoolean() && (t.skipUEG(),
|
|
t.skipUEG(),
|
|
t.skipUEG(),
|
|
t.skipUEG()),
|
|
t.readBoolean() && (ie = t.readBits(32),
|
|
ne = t.readBits(32),
|
|
t.readBoolean() && t.readUEG(),
|
|
t.readBoolean())) {
|
|
var se = t.readBoolean()
|
|
, oe = t.readBoolean()
|
|
, le = !1;
|
|
(se || oe) && ((le = t.readBoolean()) && (t.readUByte(),
|
|
t.readBits(5),
|
|
t.readBoolean(),
|
|
t.readBits(5)),
|
|
t.readBits(4),
|
|
t.readBits(4),
|
|
le && t.readBits(4),
|
|
t.readBits(5),
|
|
t.readBits(5),
|
|
t.readBits(5));
|
|
for (var ue = 0; ue <= r; ue++) {
|
|
var de = !1;
|
|
(re = t.readBoolean()) || t.readBoolean() ? t.readEG() : de = t.readBoolean();
|
|
var he = de ? 1 : t.readUEG() + 1;
|
|
if (se)
|
|
for (var fe = 0; fe < he; fe++)
|
|
t.readUEG(),
|
|
t.readUEG(),
|
|
le && (t.readUEG(),
|
|
t.readUEG()),
|
|
t.skipBits(1);
|
|
if (oe)
|
|
for (var ce = 0; ce < he; ce++)
|
|
t.readUEG(),
|
|
t.readUEG(),
|
|
le && (t.readUEG(),
|
|
t.readUEG()),
|
|
t.skipBits(1)
|
|
}
|
|
}
|
|
t.readBoolean() && (t.readBoolean(),
|
|
t.readBoolean(),
|
|
t.readBoolean(),
|
|
J = t.readUEG())
|
|
}
|
|
var ge = L
|
|
, ve = I;
|
|
if (R) {
|
|
var me = 1
|
|
, pe = 1;
|
|
1 === A ? me = pe = 2 : 2 == A && (me = 2),
|
|
ge = L - me * b - me * k,
|
|
ve = I - pe * _ - pe * D
|
|
}
|
|
for (var ye = i ? ["A", "B", "C"][i] : "", Ee = s << 24 | o << 16 | l << 8 | u, Te = 0, Se = 0; Se < 32; Se++)
|
|
Te = (Te | (Ee >> Se & 1) << 31 - Se) >>> 0;
|
|
var Ae = Te.toString(16);
|
|
return 1 === a && "2" === Ae && (Ae = "6"),
|
|
{
|
|
codecString: "hvc1." + ye + a + "." + Ae + "." + (n ? "H" : "L") + m + ".B0",
|
|
params: {
|
|
general_tier_flag: n,
|
|
general_profile_idc: a,
|
|
general_profile_space: i,
|
|
general_profile_compatibility_flags: [s, o, l, u],
|
|
general_constraint_indicator_flags: [d, h, f, c, g, v],
|
|
general_level_idc: m,
|
|
bit_depth: P + 8,
|
|
bit_depth_luma_minus8: P,
|
|
bit_depth_chroma_minus8: C,
|
|
min_spatial_segmentation_idc: J,
|
|
chroma_format_idc: A,
|
|
frame_rate: {
|
|
fixed: re,
|
|
fps: ne / ie
|
|
}
|
|
},
|
|
width: ge,
|
|
height: ve,
|
|
pixelRatio: [ee, te]
|
|
}
|
|
}
|
|
,
|
|
r.readPPS = function(e) {
|
|
var t = new In(this.ebsp2rbsp(e));
|
|
t.readUByte(),
|
|
t.readUByte(),
|
|
t.skipUEG(),
|
|
t.skipUEG(),
|
|
t.skipBits(2),
|
|
t.skipBits(3),
|
|
t.skipBits(2),
|
|
t.skipUEG(),
|
|
t.skipUEG(),
|
|
t.skipEG(),
|
|
t.skipBits(2),
|
|
t.readBoolean() && t.skipUEG(),
|
|
t.skipEG(),
|
|
t.skipEG(),
|
|
t.skipBits(4);
|
|
var r = t.readBoolean()
|
|
, i = t.readBoolean()
|
|
, n = 1;
|
|
return i && r ? n = 0 : i ? n = 3 : r && (n = 2),
|
|
{
|
|
parallelismType: n
|
|
}
|
|
}
|
|
,
|
|
r.matchSPS = function(e, t) {
|
|
return String.fromCharCode.apply(null, e).substr(3) === String.fromCharCode.apply(null, t).substr(3)
|
|
}
|
|
,
|
|
t
|
|
}(Ln)
|
|
, bn = 188
|
|
, Dn = function() {
|
|
function e(e, t, r, i) {
|
|
this.logger = void 0,
|
|
this.observer = void 0,
|
|
this.config = void 0,
|
|
this.typeSupported = void 0,
|
|
this.sampleAes = null,
|
|
this.pmtParsed = !1,
|
|
this.audioCodec = void 0,
|
|
this.videoCodec = void 0,
|
|
this._pmtId = -1,
|
|
this._videoTrack = void 0,
|
|
this._audioTrack = void 0,
|
|
this._id3Track = void 0,
|
|
this._txtTrack = void 0,
|
|
this.aacOverFlow = null,
|
|
this.remainderData = null,
|
|
this.videoParser = void 0,
|
|
this.observer = e,
|
|
this.config = t,
|
|
this.typeSupported = r,
|
|
this.logger = i,
|
|
this.videoParser = null
|
|
}
|
|
e.probe = function(t, r) {
|
|
var i = e.syncOffset(t);
|
|
return i > 0 && r.warn("MPEG2-TS detected but first sync word found @ offset " + i),
|
|
-1 !== i
|
|
}
|
|
,
|
|
e.syncOffset = function(e) {
|
|
for (var t = e.length, r = Math.min(940, t - bn) + 1, i = 0; i < r; ) {
|
|
for (var n = !1, a = -1, s = 0, o = i; o < t; o += bn) {
|
|
if (71 !== e[o] || t - o !== bn && 71 !== e[o + bn]) {
|
|
if (s)
|
|
return -1;
|
|
break
|
|
}
|
|
if (s++,
|
|
-1 === a && 0 !== (a = o) && (r = Math.min(a + 18612, e.length - bn) + 1),
|
|
n || (n = 0 === _n(e, o)),
|
|
n && s > 1 && (0 === a && s > 2 || o + bn > r))
|
|
return a
|
|
}
|
|
i++
|
|
}
|
|
return -1
|
|
}
|
|
,
|
|
e.createTrack = function(e, t) {
|
|
return {
|
|
container: "video" === e || "audio" === e ? "video/mp2t" : void 0,
|
|
type: e,
|
|
id: oe[e],
|
|
pid: -1,
|
|
inputTimeScale: 9e4,
|
|
sequenceNumber: 0,
|
|
samples: [],
|
|
dropped: 0,
|
|
duration: "audio" === e ? t : void 0
|
|
}
|
|
}
|
|
;
|
|
var t = e.prototype;
|
|
return t.resetInitSegment = function(t, r, i, n) {
|
|
this.pmtParsed = !1,
|
|
this._pmtId = -1,
|
|
this._videoTrack = e.createTrack("video"),
|
|
this._videoTrack.duration = n,
|
|
this._audioTrack = e.createTrack("audio", n),
|
|
this._id3Track = e.createTrack("id3"),
|
|
this._txtTrack = e.createTrack("text"),
|
|
this._audioTrack.segmentCodec = "aac",
|
|
this.videoParser = null,
|
|
this.aacOverFlow = null,
|
|
this.remainderData = null,
|
|
this.audioCodec = r,
|
|
this.videoCodec = i
|
|
}
|
|
,
|
|
t.resetTimeStamp = function() {}
|
|
,
|
|
t.resetContiguity = function() {
|
|
var e = this._audioTrack
|
|
, t = this._videoTrack
|
|
, r = this._id3Track;
|
|
e && (e.pesData = null),
|
|
t && (t.pesData = null),
|
|
r && (r.pesData = null),
|
|
this.aacOverFlow = null,
|
|
this.remainderData = null
|
|
}
|
|
,
|
|
t.demux = function(t, r, i, n) {
|
|
var a;
|
|
void 0 === i && (i = !1),
|
|
void 0 === n && (n = !1),
|
|
i || (this.sampleAes = null);
|
|
var s = this._videoTrack
|
|
, o = this._audioTrack
|
|
, l = this._id3Track
|
|
, u = this._txtTrack
|
|
, d = s.pid
|
|
, h = s.pesData
|
|
, f = o.pid
|
|
, c = l.pid
|
|
, g = o.pesData
|
|
, v = l.pesData
|
|
, m = null
|
|
, p = this.pmtParsed
|
|
, y = this._pmtId
|
|
, E = t.length;
|
|
if (this.remainderData && (E = (t = Ae(this.remainderData, t)).length,
|
|
this.remainderData = null),
|
|
E < bn && !n)
|
|
return this.remainderData = t,
|
|
{
|
|
audioTrack: o,
|
|
videoTrack: s,
|
|
id3Track: l,
|
|
textTrack: u
|
|
};
|
|
var T = Math.max(0, e.syncOffset(t));
|
|
(E -= (E - T) % bn) < t.byteLength && !n && (this.remainderData = new Uint8Array(t.buffer,E,t.buffer.byteLength - E));
|
|
for (var S = 0, A = T; A < E; A += bn)
|
|
if (71 === t[A]) {
|
|
var L = !!(64 & t[A + 1])
|
|
, I = _n(t, A)
|
|
, R = void 0;
|
|
if ((48 & t[A + 3]) >> 4 > 1) {
|
|
if ((R = A + 5 + t[A + 4]) === A + bn)
|
|
continue
|
|
} else
|
|
R = A + 4;
|
|
switch (I) {
|
|
case d:
|
|
L && (h && (a = xn(h, this.logger)) && (this.readyVideoParser(s.segmentCodec),
|
|
null !== this.videoParser && this.videoParser.parsePES(s, u, a, !1)),
|
|
h = {
|
|
data: [],
|
|
size: 0
|
|
}),
|
|
h && (h.data.push(t.subarray(R, A + bn)),
|
|
h.size += A + bn - R);
|
|
break;
|
|
case f:
|
|
if (L) {
|
|
if (g && (a = xn(g, this.logger)))
|
|
switch (o.segmentCodec) {
|
|
case "aac":
|
|
this.parseAACPES(o, a);
|
|
break;
|
|
case "mp3":
|
|
this.parseMPEGPES(o, a);
|
|
break;
|
|
case "ac3":
|
|
this.parseAC3PES(o, a)
|
|
}
|
|
g = {
|
|
data: [],
|
|
size: 0
|
|
}
|
|
}
|
|
g && (g.data.push(t.subarray(R, A + bn)),
|
|
g.size += A + bn - R);
|
|
break;
|
|
case c:
|
|
L && (v && (a = xn(v, this.logger)) && this.parseID3PES(l, a),
|
|
v = {
|
|
data: [],
|
|
size: 0
|
|
}),
|
|
v && (v.data.push(t.subarray(R, A + bn)),
|
|
v.size += A + bn - R);
|
|
break;
|
|
case 0:
|
|
L && (R += t[R] + 1),
|
|
y = this._pmtId = Pn(t, R);
|
|
break;
|
|
case y:
|
|
L && (R += t[R] + 1);
|
|
var k = Cn(t, R, this.typeSupported, i, this.observer, this.logger);
|
|
(d = k.videoPid) > 0 && (s.pid = d,
|
|
s.segmentCodec = k.segmentVideoCodec),
|
|
(f = k.audioPid) > 0 && (o.pid = f,
|
|
o.segmentCodec = k.segmentAudioCodec),
|
|
(c = k.id3Pid) > 0 && (l.pid = c),
|
|
null === m || p || (this.logger.warn("MPEG-TS PMT found at " + A + " after unknown PID '" + m + "'. Backtracking to sync byte @" + T + " to parse all TS packets."),
|
|
m = null,
|
|
A = T - 188),
|
|
p = this.pmtParsed = !0;
|
|
break;
|
|
case 17:
|
|
case 8191:
|
|
break;
|
|
default:
|
|
m = I
|
|
}
|
|
} else
|
|
S++;
|
|
S > 0 && wn(this.observer, new Error("Found " + S + " TS packet/s that do not start with 0x47"), void 0, this.logger),
|
|
s.pesData = h,
|
|
o.pesData = g,
|
|
l.pesData = v;
|
|
var b = {
|
|
audioTrack: o,
|
|
videoTrack: s,
|
|
id3Track: l,
|
|
textTrack: u
|
|
};
|
|
return n && this.extractRemainingSamples(b),
|
|
b
|
|
}
|
|
,
|
|
t.flush = function() {
|
|
var e, t = this.remainderData;
|
|
return this.remainderData = null,
|
|
e = t ? this.demux(t, -1, !1, !0) : {
|
|
videoTrack: this._videoTrack,
|
|
audioTrack: this._audioTrack,
|
|
id3Track: this._id3Track,
|
|
textTrack: this._txtTrack
|
|
},
|
|
this.extractRemainingSamples(e),
|
|
this.sampleAes ? this.decrypt(e, this.sampleAes) : e
|
|
}
|
|
,
|
|
t.extractRemainingSamples = function(e) {
|
|
var t, r = e.audioTrack, i = e.videoTrack, n = e.id3Track, a = e.textTrack, s = i.pesData, o = r.pesData, l = n.pesData;
|
|
if (s && (t = xn(s, this.logger)) ? (this.readyVideoParser(i.segmentCodec),
|
|
null !== this.videoParser && (this.videoParser.parsePES(i, a, t, !0),
|
|
i.pesData = null)) : i.pesData = s,
|
|
o && (t = xn(o, this.logger))) {
|
|
switch (r.segmentCodec) {
|
|
case "aac":
|
|
this.parseAACPES(r, t);
|
|
break;
|
|
case "mp3":
|
|
this.parseMPEGPES(r, t);
|
|
break;
|
|
case "ac3":
|
|
this.parseAC3PES(r, t)
|
|
}
|
|
r.pesData = null
|
|
} else
|
|
null != o && o.size && this.logger.log("last AAC PES packet truncated,might overlap between fragments"),
|
|
r.pesData = o;
|
|
l && (t = xn(l, this.logger)) ? (this.parseID3PES(n, t),
|
|
n.pesData = null) : n.pesData = l
|
|
}
|
|
,
|
|
t.demuxSampleAes = function(e, t, r) {
|
|
var i = this.demux(e, r, !0, !this.config.progressive)
|
|
, n = this.sampleAes = new An(this.observer,this.config,t);
|
|
return this.decrypt(i, n)
|
|
}
|
|
,
|
|
t.readyVideoParser = function(e) {
|
|
null === this.videoParser && ("avc" === e ? this.videoParser = new Rn : "hevc" === e && (this.videoParser = new kn))
|
|
}
|
|
,
|
|
t.decrypt = function(e, t) {
|
|
return new Promise((function(r) {
|
|
var i = e.audioTrack
|
|
, n = e.videoTrack;
|
|
i.samples && "aac" === i.segmentCodec ? t.decryptAacSamples(i.samples, 0, (function() {
|
|
n.samples ? t.decryptAvcSamples(n.samples, 0, 0, (function() {
|
|
r(e)
|
|
}
|
|
)) : r(e)
|
|
}
|
|
)) : n.samples && t.decryptAvcSamples(n.samples, 0, 0, (function() {
|
|
r(e)
|
|
}
|
|
))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t.destroy = function() {
|
|
this.observer && this.observer.removeAllListeners(),
|
|
this.config = this.logger = this.observer = null,
|
|
this.aacOverFlow = this.videoParser = this.remainderData = this.sampleAes = null,
|
|
this._videoTrack = this._audioTrack = this._id3Track = this._txtTrack = void 0
|
|
}
|
|
,
|
|
t.parseAACPES = function(e, t) {
|
|
var r, i, n, a = 0, s = this.aacOverFlow, o = t.data;
|
|
if (s) {
|
|
this.aacOverFlow = null;
|
|
var l = s.missing
|
|
, u = s.sample.unit.byteLength;
|
|
if (-1 === l)
|
|
o = Ae(s.sample.unit, o);
|
|
else {
|
|
var d = u - l;
|
|
s.sample.unit.set(o.subarray(0, l), d),
|
|
e.samples.push(s.sample),
|
|
a = s.missing
|
|
}
|
|
}
|
|
for (r = a,
|
|
i = o.length; r < i - 1 && !Ni(o, r); r++)
|
|
;
|
|
if (r !== a) {
|
|
var h, f = r < i - 1;
|
|
if (h = f ? "AAC PES did not start with ADTS header,offset:" + r : "No ADTS header found in AAC PES",
|
|
wn(this.observer, new Error(h), f, this.logger),
|
|
!f)
|
|
return
|
|
}
|
|
if (Bi(e, this.observer, o, r, this.audioCodec),
|
|
void 0 !== t.pts)
|
|
n = t.pts;
|
|
else {
|
|
if (!s)
|
|
return void this.logger.warn("[tsdemuxer]: AAC PES unknown PTS");
|
|
var c = Gi(e.samplerate);
|
|
n = s.sample.pts + c
|
|
}
|
|
for (var g, v = 0; r < i; ) {
|
|
if (r += (g = Ki(e, o, r, n, v)).length,
|
|
g.missing) {
|
|
this.aacOverFlow = g;
|
|
break
|
|
}
|
|
for (v++; r < i - 1 && !Ni(o, r); r++)
|
|
;
|
|
}
|
|
}
|
|
,
|
|
t.parseMPEGPES = function(e, t) {
|
|
var r = t.data
|
|
, i = r.length
|
|
, n = 0
|
|
, a = 0
|
|
, s = t.pts;
|
|
if (void 0 !== s)
|
|
for (; a < i; )
|
|
if (fn(r, a)) {
|
|
var o = un(e, r, a, s, n);
|
|
if (!o)
|
|
break;
|
|
a += o.length,
|
|
n++
|
|
} else
|
|
a++;
|
|
else
|
|
this.logger.warn("[tsdemuxer]: MPEG PES unknown PTS")
|
|
}
|
|
,
|
|
t.parseAC3PES = function(e, t) {
|
|
var r = t.data
|
|
, i = t.pts;
|
|
if (void 0 !== i)
|
|
for (var n, a = r.length, s = 0, o = 0; o < a && (n = pn(e, r, o, i, s++)) > 0; )
|
|
o += n;
|
|
else
|
|
this.logger.warn("[tsdemuxer]: AC3 PES unknown PTS")
|
|
}
|
|
,
|
|
t.parseID3PES = function(e, t) {
|
|
if (void 0 !== t.pts) {
|
|
var r = a({}, t, {
|
|
type: this._videoTrack ? Ji.emsg : Ji.audioId3,
|
|
duration: Number.POSITIVE_INFINITY
|
|
});
|
|
e.samples.push(r)
|
|
} else
|
|
this.logger.warn("[tsdemuxer]: ID3 PES unknown PTS")
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function _n(e, t) {
|
|
return ((31 & e[t + 1]) << 8) + e[t + 2]
|
|
}
|
|
function Pn(e, t) {
|
|
return (31 & e[t + 10]) << 8 | e[t + 11]
|
|
}
|
|
function Cn(e, t, r, i, n, a) {
|
|
var s = {
|
|
audioPid: -1,
|
|
videoPid: -1,
|
|
id3Pid: -1,
|
|
segmentVideoCodec: "avc",
|
|
segmentAudioCodec: "aac"
|
|
}
|
|
, o = t + 3 + ((15 & e[t + 1]) << 8 | e[t + 2]) - 4;
|
|
for (t += 12 + ((15 & e[t + 10]) << 8 | e[t + 11]); t < o; ) {
|
|
var l = _n(e, t)
|
|
, u = (15 & e[t + 3]) << 8 | e[t + 4];
|
|
switch (e[t]) {
|
|
case 207:
|
|
if (!i) {
|
|
On("ADTS AAC", a);
|
|
break
|
|
}
|
|
case 15:
|
|
-1 === s.audioPid && (s.audioPid = l);
|
|
break;
|
|
case 21:
|
|
-1 === s.id3Pid && (s.id3Pid = l);
|
|
break;
|
|
case 219:
|
|
if (!i) {
|
|
On("H.264", a);
|
|
break
|
|
}
|
|
case 27:
|
|
-1 === s.videoPid && (s.videoPid = l);
|
|
break;
|
|
case 3:
|
|
case 4:
|
|
r.mpeg || r.mp3 ? -1 === s.audioPid && (s.audioPid = l,
|
|
s.segmentAudioCodec = "mp3") : a.log("MPEG audio found, not supported in this browser");
|
|
break;
|
|
case 193:
|
|
if (!i) {
|
|
On("AC-3", a);
|
|
break
|
|
}
|
|
case 129:
|
|
r.ac3 ? -1 === s.audioPid && (s.audioPid = l,
|
|
s.segmentAudioCodec = "ac3") : a.log("AC-3 audio found, not supported in this browser");
|
|
break;
|
|
case 6:
|
|
if (-1 === s.audioPid && u > 0)
|
|
for (var d = t + 5, h = u; h > 2; ) {
|
|
106 === e[d] && (!0 !== r.ac3 ? a.log("AC-3 audio found, not supported in this browser for now") : (s.audioPid = l,
|
|
s.segmentAudioCodec = "ac3"));
|
|
var f = e[d + 1] + 2;
|
|
d += f,
|
|
h -= f
|
|
}
|
|
break;
|
|
case 194:
|
|
case 135:
|
|
return wn(n, new Error("Unsupported EC-3 in M2TS found"), void 0, a),
|
|
s;
|
|
case 36:
|
|
-1 === s.videoPid && (s.videoPid = l,
|
|
s.segmentVideoCodec = "hevc",
|
|
a.log("HEVC in M2TS found"))
|
|
}
|
|
t += u + 5
|
|
}
|
|
return s
|
|
}
|
|
function wn(e, t, r, i) {
|
|
i.warn("parsing error: " + t.message),
|
|
e.emit(b.ERROR, b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.FRAG_PARSING_ERROR,
|
|
fatal: !1,
|
|
levelRetry: r,
|
|
error: t,
|
|
reason: t.message
|
|
})
|
|
}
|
|
function On(e, t) {
|
|
t.log(e + " with AES-128-CBC encryption found in unencrypted stream")
|
|
}
|
|
function xn(e, t) {
|
|
var r, i, n, a, s, o = 0, l = e.data;
|
|
if (!e || 0 === e.size)
|
|
return null;
|
|
for (; l[0].length < 19 && l.length > 1; )
|
|
l[0] = Ae(l[0], l[1]),
|
|
l.splice(1, 1);
|
|
if (1 === ((r = l[0])[0] << 16) + (r[1] << 8) + r[2]) {
|
|
if ((i = (r[4] << 8) + r[5]) && i > e.size - 6)
|
|
return null;
|
|
var u = r[7];
|
|
192 & u && (a = 536870912 * (14 & r[9]) + 4194304 * (255 & r[10]) + 16384 * (254 & r[11]) + 128 * (255 & r[12]) + (254 & r[13]) / 2,
|
|
64 & u ? a - (s = 536870912 * (14 & r[14]) + 4194304 * (255 & r[15]) + 16384 * (254 & r[16]) + 128 * (255 & r[17]) + (254 & r[18]) / 2) > 54e5 && (t.warn(Math.round((a - s) / 9e4) + "s delta between PTS and DTS, align them"),
|
|
a = s) : s = a);
|
|
var d = (n = r[8]) + 9;
|
|
if (e.size <= d)
|
|
return null;
|
|
e.size -= d;
|
|
for (var h = new Uint8Array(e.size), f = 0, c = l.length; f < c; f++) {
|
|
var g = (r = l[f]).byteLength;
|
|
if (d) {
|
|
if (d > g) {
|
|
d -= g;
|
|
continue
|
|
}
|
|
r = r.subarray(d),
|
|
g -= d,
|
|
d = 0
|
|
}
|
|
h.set(r, o),
|
|
o += g
|
|
}
|
|
return i && (i -= n + 3),
|
|
{
|
|
data: h,
|
|
pts: a,
|
|
dts: s,
|
|
len: i
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
var Mn = function() {
|
|
function e() {}
|
|
return e.getSilentFrame = function(e, t) {
|
|
if ("mp4a.40.2" === e) {
|
|
if (1 === t)
|
|
return new Uint8Array([0, 200, 0, 128, 35, 128]);
|
|
if (2 === t)
|
|
return new Uint8Array([33, 0, 73, 144, 2, 25, 0, 35, 128]);
|
|
if (3 === t)
|
|
return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 142]);
|
|
if (4 === t)
|
|
return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 128, 44, 128, 8, 2, 56]);
|
|
if (5 === t)
|
|
return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 130, 48, 4, 153, 0, 33, 144, 2, 56]);
|
|
if (6 === t)
|
|
return new Uint8Array([0, 200, 0, 128, 32, 132, 1, 38, 64, 8, 100, 0, 130, 48, 4, 153, 0, 33, 144, 2, 0, 178, 0, 32, 8, 224])
|
|
} else {
|
|
if (1 === t)
|
|
return new Uint8Array([1, 64, 34, 128, 163, 78, 230, 128, 186, 8, 0, 0, 0, 28, 6, 241, 193, 10, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 94]);
|
|
if (2 === t)
|
|
return new Uint8Array([1, 64, 34, 128, 163, 94, 230, 128, 186, 8, 0, 0, 0, 0, 149, 0, 6, 241, 161, 10, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 94]);
|
|
if (3 === t)
|
|
return new Uint8Array([1, 64, 34, 128, 163, 94, 230, 128, 186, 8, 0, 0, 0, 0, 149, 0, 6, 241, 161, 10, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 94])
|
|
}
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, Fn = Math.pow(2, 32) - 1
|
|
, Nn = function() {
|
|
function e() {}
|
|
return e.init = function() {
|
|
var t;
|
|
for (t in e.types = {
|
|
avc1: [],
|
|
avcC: [],
|
|
hvc1: [],
|
|
hvcC: [],
|
|
btrt: [],
|
|
dinf: [],
|
|
dref: [],
|
|
esds: [],
|
|
ftyp: [],
|
|
hdlr: [],
|
|
mdat: [],
|
|
mdhd: [],
|
|
mdia: [],
|
|
mfhd: [],
|
|
minf: [],
|
|
moof: [],
|
|
moov: [],
|
|
mp4a: [],
|
|
".mp3": [],
|
|
dac3: [],
|
|
"ac-3": [],
|
|
mvex: [],
|
|
mvhd: [],
|
|
pasp: [],
|
|
sdtp: [],
|
|
stbl: [],
|
|
stco: [],
|
|
stsc: [],
|
|
stsd: [],
|
|
stsz: [],
|
|
stts: [],
|
|
tfdt: [],
|
|
tfhd: [],
|
|
traf: [],
|
|
trak: [],
|
|
trun: [],
|
|
trex: [],
|
|
tkhd: [],
|
|
vmhd: [],
|
|
smhd: []
|
|
},
|
|
e.types)
|
|
e.types.hasOwnProperty(t) && (e.types[t] = [t.charCodeAt(0), t.charCodeAt(1), t.charCodeAt(2), t.charCodeAt(3)]);
|
|
var r = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 118, 105, 100, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 105, 100, 101, 111, 72, 97, 110, 100, 108, 101, 114, 0])
|
|
, i = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 115, 111, 117, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 111, 117, 110, 100, 72, 97, 110, 100, 108, 101, 114, 0]);
|
|
e.HDLR_TYPES = {
|
|
video: r,
|
|
audio: i
|
|
};
|
|
var n = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 117, 114, 108, 32, 0, 0, 0, 1])
|
|
, a = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]);
|
|
e.STTS = e.STSC = e.STCO = a,
|
|
e.STSZ = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
|
|
e.VMHD = new Uint8Array([0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]),
|
|
e.SMHD = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0]),
|
|
e.STSD = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1]);
|
|
var s = new Uint8Array([105, 115, 111, 109])
|
|
, o = new Uint8Array([97, 118, 99, 49])
|
|
, l = new Uint8Array([0, 0, 0, 1]);
|
|
e.FTYP = e.box(e.types.ftyp, s, l, s, o),
|
|
e.DINF = e.box(e.types.dinf, e.box(e.types.dref, n))
|
|
}
|
|
,
|
|
e.box = function(e) {
|
|
for (var t = 8, r = arguments.length, i = new Array(r > 1 ? r - 1 : 0), n = 1; n < r; n++)
|
|
i[n - 1] = arguments[n];
|
|
for (var a = i.length, s = a; a--; )
|
|
t += i[a].byteLength;
|
|
var o = new Uint8Array(t);
|
|
for (o[0] = t >> 24 & 255,
|
|
o[1] = t >> 16 & 255,
|
|
o[2] = t >> 8 & 255,
|
|
o[3] = 255 & t,
|
|
o.set(e, 4),
|
|
a = 0,
|
|
t = 8; a < s; a++)
|
|
o.set(i[a], t),
|
|
t += i[a].byteLength;
|
|
return o
|
|
}
|
|
,
|
|
e.hdlr = function(t) {
|
|
return e.box(e.types.hdlr, e.HDLR_TYPES[t])
|
|
}
|
|
,
|
|
e.mdat = function(t) {
|
|
return e.box(e.types.mdat, t)
|
|
}
|
|
,
|
|
e.mdhd = function(t, r) {
|
|
r *= t;
|
|
var i = Math.floor(r / (Fn + 1))
|
|
, n = Math.floor(r % (Fn + 1));
|
|
return e.box(e.types.mdhd, new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, t >> 24 & 255, t >> 16 & 255, t >> 8 & 255, 255 & t, i >> 24, i >> 16 & 255, i >> 8 & 255, 255 & i, n >> 24, n >> 16 & 255, n >> 8 & 255, 255 & n, 85, 196, 0, 0]))
|
|
}
|
|
,
|
|
e.mdia = function(t) {
|
|
return e.box(e.types.mdia, e.mdhd(t.timescale || 0, t.duration || 0), e.hdlr(t.type), e.minf(t))
|
|
}
|
|
,
|
|
e.mfhd = function(t) {
|
|
return e.box(e.types.mfhd, new Uint8Array([0, 0, 0, 0, t >> 24, t >> 16 & 255, t >> 8 & 255, 255 & t]))
|
|
}
|
|
,
|
|
e.minf = function(t) {
|
|
return "audio" === t.type ? e.box(e.types.minf, e.box(e.types.smhd, e.SMHD), e.DINF, e.stbl(t)) : e.box(e.types.minf, e.box(e.types.vmhd, e.VMHD), e.DINF, e.stbl(t))
|
|
}
|
|
,
|
|
e.moof = function(t, r, i) {
|
|
return e.box(e.types.moof, e.mfhd(t), e.traf(i, r))
|
|
}
|
|
,
|
|
e.moov = function(t) {
|
|
for (var r = t.length, i = []; r--; )
|
|
i[r] = e.trak(t[r]);
|
|
return e.box.apply(null, [e.types.moov, e.mvhd(t[0].timescale || 0, t[0].duration || 0)].concat(i).concat(e.mvex(t)))
|
|
}
|
|
,
|
|
e.mvex = function(t) {
|
|
for (var r = t.length, i = []; r--; )
|
|
i[r] = e.trex(t[r]);
|
|
return e.box.apply(null, [e.types.mvex].concat(i))
|
|
}
|
|
,
|
|
e.mvhd = function(t, r) {
|
|
r *= t;
|
|
var i = Math.floor(r / (Fn + 1))
|
|
, n = Math.floor(r % (Fn + 1))
|
|
, a = new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, t >> 24 & 255, t >> 16 & 255, t >> 8 & 255, 255 & t, i >> 24, i >> 16 & 255, i >> 8 & 255, 255 & i, n >> 24, n >> 16 & 255, n >> 8 & 255, 255 & n, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255]);
|
|
return e.box(e.types.mvhd, a)
|
|
}
|
|
,
|
|
e.sdtp = function(t) {
|
|
var r, i, n = t.samples || [], a = new Uint8Array(4 + n.length);
|
|
for (r = 0; r < n.length; r++)
|
|
i = n[r].flags,
|
|
a[r + 4] = i.dependsOn << 4 | i.isDependedOn << 2 | i.hasRedundancy;
|
|
return e.box(e.types.sdtp, a)
|
|
}
|
|
,
|
|
e.stbl = function(t) {
|
|
return e.box(e.types.stbl, e.stsd(t), e.box(e.types.stts, e.STTS), e.box(e.types.stsc, e.STSC), e.box(e.types.stsz, e.STSZ), e.box(e.types.stco, e.STCO))
|
|
}
|
|
,
|
|
e.avc1 = function(t) {
|
|
var r, i, n, a = [], s = [];
|
|
for (r = 0; r < t.sps.length; r++)
|
|
n = (i = t.sps[r]).byteLength,
|
|
a.push(n >>> 8 & 255),
|
|
a.push(255 & n),
|
|
a = a.concat(Array.prototype.slice.call(i));
|
|
for (r = 0; r < t.pps.length; r++)
|
|
n = (i = t.pps[r]).byteLength,
|
|
s.push(n >>> 8 & 255),
|
|
s.push(255 & n),
|
|
s = s.concat(Array.prototype.slice.call(i));
|
|
var o = e.box(e.types.avcC, new Uint8Array([1, a[3], a[4], a[5], 255, 224 | t.sps.length].concat(a).concat([t.pps.length]).concat(s)))
|
|
, l = t.width
|
|
, u = t.height
|
|
, d = t.pixelRatio[0]
|
|
, h = t.pixelRatio[1];
|
|
return e.box(e.types.avc1, new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, l >> 8 & 255, 255 & l, u >> 8 & 255, 255 & u, 0, 72, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 1, 18, 100, 97, 105, 108, 121, 109, 111, 116, 105, 111, 110, 47, 104, 108, 115, 46, 106, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 17, 17]), o, e.box(e.types.btrt, new Uint8Array([0, 28, 156, 128, 0, 45, 198, 192, 0, 45, 198, 192])), e.box(e.types.pasp, new Uint8Array([d >> 24, d >> 16 & 255, d >> 8 & 255, 255 & d, h >> 24, h >> 16 & 255, h >> 8 & 255, 255 & h])))
|
|
}
|
|
,
|
|
e.esds = function(e) {
|
|
var t = e.config;
|
|
return new Uint8Array([0, 0, 0, 0, 3, 25, 0, 1, 0, 4, 17, 64, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 2].concat(t, [6, 1, 2]))
|
|
}
|
|
,
|
|
e.audioStsd = function(e) {
|
|
var t = e.samplerate || 0;
|
|
return new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, e.channelCount || 0, 0, 16, 0, 0, 0, 0, t >> 8 & 255, 255 & t, 0, 0])
|
|
}
|
|
,
|
|
e.mp4a = function(t) {
|
|
return e.box(e.types.mp4a, e.audioStsd(t), e.box(e.types.esds, e.esds(t)))
|
|
}
|
|
,
|
|
e.mp3 = function(t) {
|
|
return e.box(e.types[".mp3"], e.audioStsd(t))
|
|
}
|
|
,
|
|
e.ac3 = function(t) {
|
|
return e.box(e.types["ac-3"], e.audioStsd(t), e.box(e.types.dac3, t.config))
|
|
}
|
|
,
|
|
e.stsd = function(t) {
|
|
var r = t.segmentCodec;
|
|
if ("audio" === t.type) {
|
|
if ("aac" === r)
|
|
return e.box(e.types.stsd, e.STSD, e.mp4a(t));
|
|
if ("ac3" === r && t.config)
|
|
return e.box(e.types.stsd, e.STSD, e.ac3(t));
|
|
if ("mp3" === r && "mp3" === t.codec)
|
|
return e.box(e.types.stsd, e.STSD, e.mp3(t))
|
|
} else {
|
|
if (!t.pps || !t.sps)
|
|
throw new Error("video track missing pps or sps");
|
|
if ("avc" === r)
|
|
return e.box(e.types.stsd, e.STSD, e.avc1(t));
|
|
if ("hevc" === r && t.vps)
|
|
return e.box(e.types.stsd, e.STSD, e.hvc1(t))
|
|
}
|
|
throw new Error("unsupported " + t.type + " segment codec (" + r + "/" + t.codec + ")")
|
|
}
|
|
,
|
|
e.tkhd = function(t) {
|
|
var r = t.id
|
|
, i = (t.duration || 0) * (t.timescale || 0)
|
|
, n = t.width || 0
|
|
, a = t.height || 0
|
|
, s = Math.floor(i / (Fn + 1))
|
|
, o = Math.floor(i % (Fn + 1));
|
|
return e.box(e.types.tkhd, new Uint8Array([1, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, r >> 24 & 255, r >> 16 & 255, r >> 8 & 255, 255 & r, 0, 0, 0, 0, s >> 24, s >> 16 & 255, s >> 8 & 255, 255 & s, o >> 24, o >> 16 & 255, o >> 8 & 255, 255 & o, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, n >> 8 & 255, 255 & n, 0, 0, a >> 8 & 255, 255 & a, 0, 0]))
|
|
}
|
|
,
|
|
e.traf = function(t, r) {
|
|
var i = e.sdtp(t)
|
|
, n = t.id
|
|
, a = Math.floor(r / (Fn + 1))
|
|
, s = Math.floor(r % (Fn + 1));
|
|
return e.box(e.types.traf, e.box(e.types.tfhd, new Uint8Array([0, 0, 0, 0, n >> 24, n >> 16 & 255, n >> 8 & 255, 255 & n])), e.box(e.types.tfdt, new Uint8Array([1, 0, 0, 0, a >> 24, a >> 16 & 255, a >> 8 & 255, 255 & a, s >> 24, s >> 16 & 255, s >> 8 & 255, 255 & s])), e.trun(t, i.length + 16 + 20 + 8 + 16 + 8 + 8), i)
|
|
}
|
|
,
|
|
e.trak = function(t) {
|
|
return t.duration = t.duration || 4294967295,
|
|
e.box(e.types.trak, e.tkhd(t), e.mdia(t))
|
|
}
|
|
,
|
|
e.trex = function(t) {
|
|
var r = t.id;
|
|
return e.box(e.types.trex, new Uint8Array([0, 0, 0, 0, r >> 24, r >> 16 & 255, r >> 8 & 255, 255 & r, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1]))
|
|
}
|
|
,
|
|
e.trun = function(t, r) {
|
|
var i, n, a, s, o, l, u = t.samples || [], d = u.length, h = 12 + 16 * d, f = new Uint8Array(h);
|
|
for (r += 8 + h,
|
|
f.set(["video" === t.type ? 1 : 0, 0, 15, 1, d >>> 24 & 255, d >>> 16 & 255, d >>> 8 & 255, 255 & d, r >>> 24 & 255, r >>> 16 & 255, r >>> 8 & 255, 255 & r], 0),
|
|
i = 0; i < d; i++)
|
|
a = (n = u[i]).duration,
|
|
s = n.size,
|
|
o = n.flags,
|
|
l = n.cts,
|
|
f.set([a >>> 24 & 255, a >>> 16 & 255, a >>> 8 & 255, 255 & a, s >>> 24 & 255, s >>> 16 & 255, s >>> 8 & 255, 255 & s, o.isLeading << 2 | o.dependsOn, o.isDependedOn << 6 | o.hasRedundancy << 4 | o.paddingValue << 1 | o.isNonSync, 61440 & o.degradPrio, 15 & o.degradPrio, l >>> 24 & 255, l >>> 16 & 255, l >>> 8 & 255, 255 & l], 12 + 16 * i);
|
|
return e.box(e.types.trun, f)
|
|
}
|
|
,
|
|
e.initSegment = function(t) {
|
|
e.types || e.init();
|
|
var r = e.moov(t);
|
|
return Ae(e.FTYP, r)
|
|
}
|
|
,
|
|
e.hvc1 = function(t) {
|
|
for (var r = t.params, i = [t.vps, t.sps, t.pps], n = new Uint8Array([1, r.general_profile_space << 6 | (r.general_tier_flag ? 32 : 0) | r.general_profile_idc, r.general_profile_compatibility_flags[0], r.general_profile_compatibility_flags[1], r.general_profile_compatibility_flags[2], r.general_profile_compatibility_flags[3], r.general_constraint_indicator_flags[0], r.general_constraint_indicator_flags[1], r.general_constraint_indicator_flags[2], r.general_constraint_indicator_flags[3], r.general_constraint_indicator_flags[4], r.general_constraint_indicator_flags[5], r.general_level_idc, 240 | r.min_spatial_segmentation_idc >> 8, 255 & r.min_spatial_segmentation_idc, 252 | r.parallelismType, 252 | r.chroma_format_idc, 248 | r.bit_depth_luma_minus8, 248 | r.bit_depth_chroma_minus8, 0, parseInt(r.frame_rate.fps), 3 | r.temporal_id_nested << 2 | r.num_temporal_layers << 3 | (r.frame_rate.fixed ? 64 : 0), i.length]), a = n.length, s = 0; s < i.length; s += 1) {
|
|
a += 3;
|
|
for (var o = 0; o < i[s].length; o += 1)
|
|
a += 2 + i[s][o].length
|
|
}
|
|
var l = new Uint8Array(a);
|
|
l.set(n, 0),
|
|
a = n.length;
|
|
for (var u = i.length - 1, d = 0; d < i.length; d += 1) {
|
|
l.set(new Uint8Array([32 + d | (d === u ? 128 : 0), 0, i[d].length]), a),
|
|
a += 3;
|
|
for (var h = 0; h < i[d].length; h += 1)
|
|
l.set(new Uint8Array([i[d][h].length >> 8, 255 & i[d][h].length]), a),
|
|
a += 2,
|
|
l.set(i[d][h], a),
|
|
a += i[d][h].length
|
|
}
|
|
var f = e.box(e.types.hvcC, l)
|
|
, c = t.width
|
|
, g = t.height
|
|
, v = t.pixelRatio[0]
|
|
, m = t.pixelRatio[1];
|
|
return e.box(e.types.hvc1, new Uint8Array([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c >> 8 & 255, 255 & c, g >> 8 & 255, 255 & g, 0, 72, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 1, 18, 100, 97, 105, 108, 121, 109, 111, 116, 105, 111, 110, 47, 104, 108, 115, 46, 106, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 17, 17]), f, e.box(e.types.btrt, new Uint8Array([0, 28, 156, 128, 0, 45, 198, 192, 0, 45, 198, 192])), e.box(e.types.pasp, new Uint8Array([v >> 24, v >> 16 & 255, v >> 8 & 255, 255 & v, m >> 24, m >> 16 & 255, m >> 8 & 255, 255 & m])))
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
Nn.types = void 0,
|
|
Nn.HDLR_TYPES = void 0,
|
|
Nn.STTS = void 0,
|
|
Nn.STSC = void 0,
|
|
Nn.STCO = void 0,
|
|
Nn.STSZ = void 0,
|
|
Nn.VMHD = void 0,
|
|
Nn.SMHD = void 0,
|
|
Nn.STSD = void 0,
|
|
Nn.FTYP = void 0,
|
|
Nn.DINF = void 0;
|
|
var Un = 9e4;
|
|
function Bn(e, t, r, i) {
|
|
void 0 === r && (r = 1),
|
|
void 0 === i && (i = !1);
|
|
var n = e * t * r;
|
|
return i ? Math.round(n) : n
|
|
}
|
|
function Gn(e, t) {
|
|
return Bn(e, 1e3, 1 / Un, t)
|
|
}
|
|
var Kn = null
|
|
, Vn = null;
|
|
function Hn(e, t, r, i) {
|
|
return {
|
|
duration: t,
|
|
size: r,
|
|
cts: i,
|
|
flags: {
|
|
isLeading: 0,
|
|
isDependedOn: 0,
|
|
hasRedundancy: 0,
|
|
degradPrio: 0,
|
|
dependsOn: e ? 2 : 1,
|
|
isNonSync: e ? 0 : 1
|
|
}
|
|
}
|
|
}
|
|
var Yn = function(e) {
|
|
function t(t, r, i, n) {
|
|
var a;
|
|
if ((a = e.call(this, "mp4-remuxer", n) || this).observer = void 0,
|
|
a.config = void 0,
|
|
a.typeSupported = void 0,
|
|
a.ISGenerated = !1,
|
|
a._initPTS = null,
|
|
a._initDTS = null,
|
|
a.nextVideoTs = null,
|
|
a.nextAudioTs = null,
|
|
a.videoSampleDuration = null,
|
|
a.isAudioContiguous = !1,
|
|
a.isVideoContiguous = !1,
|
|
a.videoTrackConfig = void 0,
|
|
a.observer = t,
|
|
a.config = r,
|
|
a.typeSupported = i,
|
|
a.ISGenerated = !1,
|
|
null === Kn) {
|
|
var s = (navigator.userAgent || "").match(/Chrome\/(\d+)/i);
|
|
Kn = s ? parseInt(s[1]) : 0
|
|
}
|
|
if (null === Vn) {
|
|
var o = navigator.userAgent.match(/Safari\/(\d+)/i);
|
|
Vn = o ? parseInt(o[1]) : 0
|
|
}
|
|
return a
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.destroy = function() {
|
|
this.config = this.videoTrackConfig = this._initPTS = this._initDTS = null
|
|
}
|
|
,
|
|
r.resetTimeStamp = function(e) {
|
|
this.log("initPTS & initDTS reset"),
|
|
this._initPTS = this._initDTS = e
|
|
}
|
|
,
|
|
r.resetNextTimestamp = function() {
|
|
this.log("reset next timestamp"),
|
|
this.isVideoContiguous = !1,
|
|
this.isAudioContiguous = !1
|
|
}
|
|
,
|
|
r.resetInitSegment = function() {
|
|
this.log("ISGenerated flag reset"),
|
|
this.ISGenerated = !1,
|
|
this.videoTrackConfig = void 0
|
|
}
|
|
,
|
|
r.getVideoStartPts = function(e) {
|
|
var t = !1
|
|
, r = e[0].pts
|
|
, i = e.reduce((function(e, i) {
|
|
var n = i.pts
|
|
, a = n - e;
|
|
return a < -4294967296 && (t = !0,
|
|
a = (n = Wn(n, r)) - e),
|
|
a > 0 ? e : n
|
|
}
|
|
), r);
|
|
return t && this.debug("PTS rollover detected"),
|
|
i
|
|
}
|
|
,
|
|
r.remux = function(e, t, r, i, n, a, s, o) {
|
|
var l, u, d, h, f, c, g = n, v = n, m = e.pid > -1, p = t.pid > -1, y = t.samples.length, E = e.samples.length > 0, T = s && y > 0 || y > 1;
|
|
if ((!m || E) && (!p || T) || this.ISGenerated || s) {
|
|
if (this.ISGenerated) {
|
|
var S, A, L, I, R = this.videoTrackConfig;
|
|
(R && (t.width !== R.width || t.height !== R.height || (null == (S = t.pixelRatio) ? void 0 : S[0]) !== (null == (A = R.pixelRatio) ? void 0 : A[0]) || (null == (L = t.pixelRatio) ? void 0 : L[1]) !== (null == (I = R.pixelRatio) ? void 0 : I[1])) || !R && T || null === this.nextAudioTs && E) && this.resetInitSegment()
|
|
}
|
|
this.ISGenerated || (d = this.generateIS(e, t, n, a));
|
|
var k, b = this.isVideoContiguous, D = -1;
|
|
if (T && (D = function(e) {
|
|
for (var t = 0; t < e.length; t++)
|
|
if (e[t].key)
|
|
return t;
|
|
return -1
|
|
}(t.samples),
|
|
!b && this.config.forceKeyFrameOnDiscontinuity))
|
|
if (c = !0,
|
|
D > 0) {
|
|
this.warn("Dropped " + D + " out of " + y + " video samples due to a missing keyframe");
|
|
var _ = this.getVideoStartPts(t.samples);
|
|
t.samples = t.samples.slice(D),
|
|
t.dropped += D,
|
|
k = v += (t.samples[0].pts - _) / t.inputTimeScale
|
|
} else
|
|
-1 === D && (this.warn("No keyframe found out of " + y + " video samples"),
|
|
c = !1);
|
|
if (this.ISGenerated) {
|
|
if (E && T) {
|
|
var P = this.getVideoStartPts(t.samples)
|
|
, C = (Wn(e.samples[0].pts, P) - P) / t.inputTimeScale;
|
|
g += Math.max(0, C),
|
|
v += Math.max(0, -C)
|
|
}
|
|
if (E) {
|
|
if (e.samplerate || (this.warn("regenerate InitSegment as audio detected"),
|
|
d = this.generateIS(e, t, n, a)),
|
|
u = this.remuxAudio(e, g, this.isAudioContiguous, a, p || T || o === O ? v : void 0),
|
|
T) {
|
|
var w = u ? u.endPTS - u.startPTS : 0;
|
|
t.inputTimeScale || (this.warn("regenerate InitSegment as video detected"),
|
|
d = this.generateIS(e, t, n, a)),
|
|
l = this.remuxVideo(t, v, b, w)
|
|
}
|
|
} else
|
|
T && (l = this.remuxVideo(t, v, b, 0));
|
|
l && (l.firstKeyFrame = D,
|
|
l.independent = -1 !== D,
|
|
l.firstKeyFramePTS = k)
|
|
}
|
|
}
|
|
return this.ISGenerated && this._initPTS && this._initDTS && (r.samples.length && (f = jn(r, n, this._initPTS, this._initDTS)),
|
|
i.samples.length && (h = qn(i, n, this._initPTS))),
|
|
{
|
|
audio: u,
|
|
video: l,
|
|
initSegment: d,
|
|
independent: c,
|
|
text: h,
|
|
id3: f
|
|
}
|
|
}
|
|
,
|
|
r.generateIS = function(e, t, r, i) {
|
|
var n, a, s, o = e.samples, l = t.samples, u = this.typeSupported, d = {}, h = this._initPTS, f = !h || i, c = "audio/mp4", g = -1;
|
|
if (f && (n = a = 1 / 0),
|
|
e.config && o.length) {
|
|
switch (e.timescale = e.samplerate,
|
|
e.segmentCodec) {
|
|
case "mp3":
|
|
u.mpeg ? (c = "audio/mpeg",
|
|
e.codec = "") : u.mp3 && (e.codec = "mp3");
|
|
break;
|
|
case "ac3":
|
|
e.codec = "ac-3"
|
|
}
|
|
d.audio = {
|
|
id: "audio",
|
|
container: c,
|
|
codec: e.codec,
|
|
initSegment: "mp3" === e.segmentCodec && u.mpeg ? new Uint8Array(0) : Nn.initSegment([e]),
|
|
metadata: {
|
|
channelCount: e.channelCount
|
|
}
|
|
},
|
|
f && (g = e.id,
|
|
s = e.inputTimeScale,
|
|
h && s === h.timescale ? f = !1 : n = a = o[0].pts - Math.round(s * r))
|
|
}
|
|
if (t.sps && t.pps && l.length) {
|
|
if (t.timescale = t.inputTimeScale,
|
|
d.video = {
|
|
id: "main",
|
|
container: "video/mp4",
|
|
codec: t.codec,
|
|
initSegment: Nn.initSegment([t]),
|
|
metadata: {
|
|
width: t.width,
|
|
height: t.height
|
|
}
|
|
},
|
|
f)
|
|
if (g = t.id,
|
|
s = t.inputTimeScale,
|
|
h && s === h.timescale)
|
|
f = !1;
|
|
else {
|
|
var v = this.getVideoStartPts(l)
|
|
, m = Math.round(s * r);
|
|
a = Math.min(a, Wn(l[0].dts, v) - m),
|
|
n = Math.min(n, v - m)
|
|
}
|
|
this.videoTrackConfig = {
|
|
width: t.width,
|
|
height: t.height,
|
|
pixelRatio: t.pixelRatio
|
|
}
|
|
}
|
|
if (Object.keys(d).length)
|
|
return this.ISGenerated = !0,
|
|
f ? (h && this.warn("Timestamps at playlist time: " + (i ? "" : "~") + r + " " + n / s + " != initPTS: " + h.baseTime / h.timescale + " (" + h.baseTime + "/" + h.timescale + ") trackId: " + h.trackId),
|
|
this.log("Found initPTS at playlist time: " + r + " offset: " + n / s + " (" + n + "/" + s + ") trackId: " + g),
|
|
this._initPTS = {
|
|
baseTime: n,
|
|
timescale: s,
|
|
trackId: g
|
|
},
|
|
this._initDTS = {
|
|
baseTime: a,
|
|
timescale: s,
|
|
trackId: g
|
|
}) : n = s = void 0,
|
|
{
|
|
tracks: d,
|
|
initPTS: n,
|
|
timescale: s,
|
|
trackId: g
|
|
}
|
|
}
|
|
,
|
|
r.remuxVideo = function(e, t, r, i) {
|
|
var n, s, o = e.inputTimeScale, l = e.samples, u = [], d = l.length, h = this._initPTS, f = h.baseTime * o / h.timescale, c = this.nextVideoTs, g = 8, v = this.videoSampleDuration, m = Number.POSITIVE_INFINITY, p = Number.NEGATIVE_INFINITY, y = !1;
|
|
if (!r || null === c) {
|
|
var E = f + t * o
|
|
, T = l[0].pts - Wn(l[0].dts, l[0].pts);
|
|
Kn && null !== c && Math.abs(E - T - (c + f)) < 15e3 ? r = !0 : c = E - T - f
|
|
}
|
|
for (var S = c + f, A = 0; A < d; A++) {
|
|
var L = l[A];
|
|
L.pts = Wn(L.pts, S),
|
|
L.dts = Wn(L.dts, S),
|
|
L.dts < l[A > 0 ? A - 1 : A].dts && (y = !0)
|
|
}
|
|
y && l.sort((function(e, t) {
|
|
var r = e.dts - t.dts
|
|
, i = e.pts - t.pts;
|
|
return r || i
|
|
}
|
|
)),
|
|
n = l[0].dts;
|
|
var I = (s = l[l.length - 1].dts) - n
|
|
, D = I ? Math.round(I / (d - 1)) : v || e.inputTimeScale / 30;
|
|
if (r) {
|
|
var _ = n - S
|
|
, P = _ > D
|
|
, C = _ < -1;
|
|
if ((P || C) && (P ? this.warn((e.segmentCodec || "").toUpperCase() + ": " + Gn(_, !0) + " ms (" + _ + "dts) hole between fragments detected at " + t.toFixed(3)) : this.warn((e.segmentCodec || "").toUpperCase() + ": " + Gn(-_, !0) + " ms (" + _ + "dts) overlapping between fragments detected at " + t.toFixed(3)),
|
|
!C || S >= l[0].pts || Kn)) {
|
|
n = S;
|
|
var w = l[0].pts - _;
|
|
if (P)
|
|
l[0].dts = n,
|
|
l[0].pts = w;
|
|
else
|
|
for (var O = !0, x = 0; x < l.length && !(l[x].dts > w && O); x++) {
|
|
var M = l[x].pts;
|
|
if (l[x].dts -= _,
|
|
l[x].pts -= _,
|
|
x < l.length - 1) {
|
|
var F = l[x + 1].pts;
|
|
O = F <= l[x].pts == F <= M
|
|
}
|
|
}
|
|
this.log("Video: Initial PTS/DTS adjusted: " + Gn(w, !0) + "/" + Gn(n, !0) + ", delta: " + Gn(_, !0) + " ms")
|
|
}
|
|
}
|
|
for (var N = 0, U = 0, B = n = Math.max(0, n), G = 0; G < d; G++) {
|
|
for (var K = l[G], V = K.units, H = V.length, Y = 0, W = 0; W < H; W++)
|
|
Y += V[W].data.length;
|
|
U += Y,
|
|
N += H,
|
|
K.length = Y,
|
|
K.dts < B ? (K.dts = B,
|
|
B += D / 4 | 0 || 1) : B = K.dts,
|
|
m = Math.min(K.pts, m),
|
|
p = Math.max(K.pts, p)
|
|
}
|
|
s = l[d - 1].dts;
|
|
var j, q = U + 4 * N + 8;
|
|
try {
|
|
j = new Uint8Array(q)
|
|
} catch (e) {
|
|
return void this.observer.emit(b.ERROR, b.ERROR, {
|
|
type: R.MUX_ERROR,
|
|
details: k.REMUX_ALLOC_ERROR,
|
|
fatal: !1,
|
|
error: e,
|
|
bytes: q,
|
|
reason: "fail allocating video mdat " + q
|
|
})
|
|
}
|
|
var X = new DataView(j.buffer);
|
|
X.setUint32(0, q),
|
|
j.set(Nn.types.mdat, 4);
|
|
for (var Q = !1, z = Number.POSITIVE_INFINITY, $ = Number.POSITIVE_INFINITY, Z = Number.NEGATIVE_INFINITY, J = Number.NEGATIVE_INFINITY, ee = 0; ee < d; ee++) {
|
|
for (var te = l[ee], re = te.units, ie = 0, ne = 0, ae = re.length; ne < ae; ne++) {
|
|
var se = re[ne]
|
|
, oe = se.data
|
|
, le = se.data.byteLength;
|
|
X.setUint32(g, le),
|
|
g += 4,
|
|
j.set(oe, g),
|
|
g += le,
|
|
ie += 4 + le
|
|
}
|
|
var ue = void 0;
|
|
if (ee < d - 1)
|
|
v = l[ee + 1].dts - te.dts,
|
|
ue = l[ee + 1].pts - te.pts;
|
|
else {
|
|
var de = this.config
|
|
, he = ee > 0 ? te.dts - l[ee - 1].dts : D;
|
|
if (ue = ee > 0 ? te.pts - l[ee - 1].pts : D,
|
|
de.stretchShortVideoTrack && null !== this.nextAudioTs) {
|
|
var fe = Math.floor(de.maxBufferHole * o)
|
|
, ce = (i ? m + i * o : this.nextAudioTs + f) - te.pts;
|
|
ce > fe ? ((v = ce - he) < 0 ? v = he : Q = !0,
|
|
this.log("It is approximately " + ce / 90 + " ms to the next segment; using duration " + v / 90 + " ms for the last video frame.")) : v = he
|
|
} else
|
|
v = he
|
|
}
|
|
var ge = Math.round(te.pts - te.dts);
|
|
z = Math.min(z, v),
|
|
Z = Math.max(Z, v),
|
|
$ = Math.min($, ue),
|
|
J = Math.max(J, ue),
|
|
u.push(Hn(te.key, v, ie, ge))
|
|
}
|
|
if (u.length)
|
|
if (Kn) {
|
|
if (Kn < 70) {
|
|
var ve = u[0].flags;
|
|
ve.dependsOn = 2,
|
|
ve.isNonSync = 0
|
|
}
|
|
} else if (Vn && J - $ < Z - z && D / Z < .025 && 0 === u[0].cts) {
|
|
this.warn("Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.");
|
|
for (var me = n, pe = 0, ye = u.length; pe < ye; pe++) {
|
|
var Ee = me + u[pe].duration
|
|
, Te = me + u[pe].cts;
|
|
if (pe < ye - 1) {
|
|
var Se = Ee + u[pe + 1].cts;
|
|
u[pe].duration = Se - Te
|
|
} else
|
|
u[pe].duration = pe ? u[pe - 1].duration : D;
|
|
u[pe].cts = 0,
|
|
me = Ee
|
|
}
|
|
}
|
|
var Ae = s + (v = Q || !v ? D : v);
|
|
this.nextVideoTs = c = Ae - f,
|
|
this.videoSampleDuration = v,
|
|
this.isVideoContiguous = !0;
|
|
var Le = {
|
|
data1: Nn.moof(e.sequenceNumber++, n, a(e, {
|
|
samples: u
|
|
})),
|
|
data2: j,
|
|
startPTS: (m - f) / o,
|
|
endPTS: (p + v - f) / o,
|
|
startDTS: (n - f) / o,
|
|
endDTS: c / o,
|
|
type: "video",
|
|
hasAudio: !1,
|
|
hasVideo: !0,
|
|
nb: u.length,
|
|
dropped: e.dropped
|
|
};
|
|
return e.samples = [],
|
|
e.dropped = 0,
|
|
Le
|
|
}
|
|
,
|
|
r.getSamplesPerFrame = function(e) {
|
|
switch (e.segmentCodec) {
|
|
case "mp3":
|
|
return 1152;
|
|
case "ac3":
|
|
return 1536;
|
|
default:
|
|
return 1024
|
|
}
|
|
}
|
|
,
|
|
r.remuxAudio = function(e, t, r, i, n) {
|
|
var s = e.inputTimeScale
|
|
, o = s / (e.samplerate ? e.samplerate : s)
|
|
, l = this.getSamplesPerFrame(e)
|
|
, u = l * o
|
|
, d = this._initPTS
|
|
, h = "mp3" === e.segmentCodec && this.typeSupported.mpeg
|
|
, f = []
|
|
, c = void 0 !== n
|
|
, g = e.samples
|
|
, v = h ? 0 : 8
|
|
, m = this.nextAudioTs || -1
|
|
, p = d.baseTime * s / d.timescale
|
|
, y = p + t * s;
|
|
if (this.isAudioContiguous = r = r || g.length && m > 0 && (i && Math.abs(y - (m + p)) < 9e3 || Math.abs(Wn(g[0].pts, y) - (m + p)) < 20 * u),
|
|
g.forEach((function(e) {
|
|
e.pts = Wn(e.pts, y)
|
|
}
|
|
)),
|
|
!r || m < 0) {
|
|
if (g = g.filter((function(e) {
|
|
return e.pts >= 0
|
|
}
|
|
)),
|
|
!g.length)
|
|
return;
|
|
m = 0 === n ? 0 : i && !c ? Math.max(0, y - p) : g[0].pts - p
|
|
}
|
|
if ("aac" === e.segmentCodec)
|
|
for (var E = this.config.maxAudioFramesDrift, T = 0, S = m + p; T < g.length; T++) {
|
|
var A = g[T]
|
|
, L = A.pts
|
|
, I = L - S
|
|
, D = Math.abs(1e3 * I / s);
|
|
if (I <= -E * u && c)
|
|
0 === T && (this.warn("Audio frame @ " + (L / s).toFixed(3) + "s overlaps marker by " + Math.round(1e3 * I / s) + " ms."),
|
|
this.nextAudioTs = m = L - p,
|
|
S = L);
|
|
else if (I >= E * u && D < 1e4 && c) {
|
|
var _ = Math.round(I / u);
|
|
for (S = L - _ * u; S < 0 && _ && u; )
|
|
_--,
|
|
S += u;
|
|
0 === T && (this.nextAudioTs = m = S - p),
|
|
this.warn("Injecting " + _ + " audio frames @ " + ((S - p) / s).toFixed(3) + "s due to " + Math.round(1e3 * I / s) + " ms gap.");
|
|
for (var P = 0; P < _; P++) {
|
|
var C = Mn.getSilentFrame(e.parsedCodec || e.manifestCodec || e.codec, e.channelCount);
|
|
C || (this.log("Unable to get silent frame for given audio codec; duplicating last frame instead."),
|
|
C = A.unit.subarray()),
|
|
g.splice(T, 0, {
|
|
unit: C,
|
|
pts: S
|
|
}),
|
|
S += u,
|
|
T++
|
|
}
|
|
}
|
|
A.pts = S,
|
|
S += u
|
|
}
|
|
for (var w, O = null, x = null, M = 0, F = g.length; F--; )
|
|
M += g[F].unit.byteLength;
|
|
for (var N = 0, U = g.length; N < U; N++) {
|
|
var B = g[N]
|
|
, G = B.unit
|
|
, K = B.pts;
|
|
if (null !== x)
|
|
f[N - 1].duration = Math.round((K - x) / o);
|
|
else {
|
|
if (r && "aac" === e.segmentCodec && (K = m + p),
|
|
O = K,
|
|
!(M > 0))
|
|
return;
|
|
M += v;
|
|
try {
|
|
w = new Uint8Array(M)
|
|
} catch (e) {
|
|
return void this.observer.emit(b.ERROR, b.ERROR, {
|
|
type: R.MUX_ERROR,
|
|
details: k.REMUX_ALLOC_ERROR,
|
|
fatal: !1,
|
|
error: e,
|
|
bytes: M,
|
|
reason: "fail allocating audio mdat " + M
|
|
})
|
|
}
|
|
h || (new DataView(w.buffer).setUint32(0, M),
|
|
w.set(Nn.types.mdat, 4))
|
|
}
|
|
w.set(G, v);
|
|
var V = G.byteLength;
|
|
v += V,
|
|
f.push(Hn(!0, l, V, 0)),
|
|
x = K
|
|
}
|
|
var H = f.length;
|
|
if (H) {
|
|
var Y = f[f.length - 1];
|
|
m = x - p,
|
|
this.nextAudioTs = m + o * Y.duration;
|
|
var W = h ? new Uint8Array(0) : Nn.moof(e.sequenceNumber++, O / o, a({}, e, {
|
|
samples: f
|
|
}));
|
|
e.samples = [];
|
|
var j = (O - p) / s
|
|
, q = m / s
|
|
, X = {
|
|
data1: W,
|
|
data2: w,
|
|
startPTS: j,
|
|
endPTS: q,
|
|
startDTS: j,
|
|
endDTS: q,
|
|
type: "audio",
|
|
hasAudio: !0,
|
|
hasVideo: !1,
|
|
nb: H
|
|
};
|
|
return this.isAudioContiguous = !0,
|
|
X
|
|
}
|
|
}
|
|
,
|
|
t
|
|
}(N);
|
|
function Wn(e, t) {
|
|
var r;
|
|
if (null === t)
|
|
return e;
|
|
for (r = t < e ? -8589934592 : 8589934592; Math.abs(e - t) > 4294967296; )
|
|
e += r;
|
|
return e
|
|
}
|
|
function jn(e, t, r, i) {
|
|
var n = e.samples.length;
|
|
if (n) {
|
|
for (var a = e.inputTimeScale, s = 0; s < n; s++) {
|
|
var o = e.samples[s];
|
|
o.pts = Wn(o.pts - r.baseTime * a / r.timescale, t * a) / a,
|
|
o.dts = Wn(o.dts - i.baseTime * a / i.timescale, t * a) / a
|
|
}
|
|
var l = e.samples;
|
|
return e.samples = [],
|
|
{
|
|
samples: l
|
|
}
|
|
}
|
|
}
|
|
function qn(e, t, r) {
|
|
var i = e.samples.length;
|
|
if (i) {
|
|
for (var n = e.inputTimeScale, a = 0; a < i; a++) {
|
|
var s = e.samples[a];
|
|
s.pts = Wn(s.pts - r.baseTime * n / r.timescale, t * n) / n
|
|
}
|
|
e.samples.sort((function(e, t) {
|
|
return e.pts - t.pts
|
|
}
|
|
));
|
|
var o = e.samples;
|
|
return e.samples = [],
|
|
{
|
|
samples: o
|
|
}
|
|
}
|
|
}
|
|
var Xn, Qn = function(e) {
|
|
function t(t, r, i, n) {
|
|
var a;
|
|
return (a = e.call(this, "passthrough-remuxer", n) || this).emitInitSegment = !1,
|
|
a.audioCodec = void 0,
|
|
a.videoCodec = void 0,
|
|
a.initData = void 0,
|
|
a.initPTS = null,
|
|
a.initTracks = void 0,
|
|
a.lastEndTime = null,
|
|
a.isVideoContiguous = !1,
|
|
a
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.destroy = function() {}
|
|
,
|
|
r.resetTimeStamp = function(e) {
|
|
this.lastEndTime = null;
|
|
var t = this.initPTS;
|
|
t && e && t.baseTime === e.baseTime && t.timescale === e.timescale || (this.initPTS = e)
|
|
}
|
|
,
|
|
r.resetNextTimestamp = function() {
|
|
this.isVideoContiguous = !1,
|
|
this.lastEndTime = null
|
|
}
|
|
,
|
|
r.resetInitSegment = function(e, t, r, i) {
|
|
this.audioCodec = t,
|
|
this.videoCodec = r,
|
|
this.generateInitSegment(e, i),
|
|
this.emitInitSegment = !0
|
|
}
|
|
,
|
|
r.generateInitSegment = function(e, t) {
|
|
var r = this.audioCodec
|
|
, i = this.videoCodec;
|
|
if (null == e || !e.byteLength)
|
|
return this.initTracks = void 0,
|
|
void (this.initData = void 0);
|
|
var n = this.initData = ve(e)
|
|
, a = n.audio
|
|
, s = n.video;
|
|
if (t)
|
|
!function(e, t) {
|
|
if (e && t) {
|
|
var r = t.keyId;
|
|
r && t.isCommonEncryption && ce(e, ["moov", "trak"]).forEach((function(e) {
|
|
var t = ce(e, ["mdia", "minf", "stbl", "stsd"])[0].subarray(8)
|
|
, i = ce(t, ["enca"])
|
|
, n = i.length > 0;
|
|
n || (i = ce(t, ["encv"])),
|
|
i.forEach((function(e) {
|
|
ce(n ? e.subarray(28) : e.subarray(78), ["sinf"]).forEach((function(e) {
|
|
var t = Se(e);
|
|
if (t) {
|
|
var i = t.subarray(8, 24);
|
|
i.some((function(e) {
|
|
return 0 !== e
|
|
}
|
|
)) || (Y.log("[eme] Patching keyId in 'enc" + (n ? "a" : "v") + ">sinf>>tenc' box: " + X(i) + " -> " + X(r)),
|
|
t.set(r, 8))
|
|
}
|
|
}
|
|
))
|
|
}
|
|
))
|
|
}
|
|
))
|
|
}
|
|
}(e, t);
|
|
else {
|
|
var o = a || s;
|
|
null != o && o.encrypted && this.warn('Init segment with encrypted track with has no key ("' + o.codec + '")!')
|
|
}
|
|
a && (r = $n(a, $, this)),
|
|
s && (i = $n(s, Z, this));
|
|
var l = {};
|
|
a && s ? l.audiovideo = {
|
|
container: "video/mp4",
|
|
codec: r + "," + i,
|
|
supplemental: s.supplemental,
|
|
encrypted: s.encrypted,
|
|
initSegment: e,
|
|
id: "main"
|
|
} : a ? l.audio = {
|
|
container: "audio/mp4",
|
|
codec: r,
|
|
encrypted: a.encrypted,
|
|
initSegment: e,
|
|
id: "audio"
|
|
} : s ? l.video = {
|
|
container: "video/mp4",
|
|
codec: i,
|
|
supplemental: s.supplemental,
|
|
encrypted: s.encrypted,
|
|
initSegment: e,
|
|
id: "main"
|
|
} : this.warn("initSegment does not contain moov or trak boxes."),
|
|
this.initTracks = l
|
|
}
|
|
,
|
|
r.remux = function(e, t, r, i, n, a) {
|
|
var s, o, l = this.initPTS, u = this.lastEndTime, d = {
|
|
audio: void 0,
|
|
video: void 0,
|
|
text: i,
|
|
id3: r,
|
|
initSegment: void 0
|
|
};
|
|
A(u) || (u = this.lastEndTime = n || 0);
|
|
var h = t.samples;
|
|
if (!h.length)
|
|
return d;
|
|
var f = {
|
|
initPTS: void 0,
|
|
timescale: void 0,
|
|
trackId: void 0
|
|
}
|
|
, c = this.initData;
|
|
if (null != (s = c) && s.length || (this.generateInitSegment(h),
|
|
c = this.initData),
|
|
null == (o = c) || !o.length)
|
|
return this.warn("Failed to generate initSegment."),
|
|
d;
|
|
this.emitInitSegment && (f.tracks = this.initTracks,
|
|
this.emitInitSegment = !1);
|
|
var g = function(e, t, r) {
|
|
for (var i = {}, n = ce(e, ["moof", "traf"]), a = 0; a < n.length; a++) {
|
|
var s = n[a]
|
|
, o = ce(s, ["tfhd"])[0]
|
|
, l = de(o, 4)
|
|
, u = t[l];
|
|
if (u) {
|
|
i[l] || (i[l] = {
|
|
start: NaN,
|
|
duration: 0,
|
|
sampleCount: 0,
|
|
timescale: u.timescale,
|
|
type: u.type
|
|
});
|
|
var d = i[l]
|
|
, h = ce(s, ["tfdt"])[0];
|
|
if (h) {
|
|
var f = h[0]
|
|
, c = de(h, 4);
|
|
1 === f && (c === ae ? r.warn("[mp4-demuxer]: Ignoring assumed invalid signed 64-bit track fragment decode time") : (c *= ae + 1,
|
|
c += de(h, 8))),
|
|
A(c) && (!A(d.start) || c < d.start) && (d.start = c)
|
|
}
|
|
var g = u.default
|
|
, v = de(o, 0) | (null == g ? void 0 : g.flags)
|
|
, m = (null == g ? void 0 : g.duration) || 0;
|
|
8 & v && (m = de(o, 2 & v ? 12 : 8));
|
|
for (var p = ce(s, ["trun"]), y = d.start || 0, E = 0, T = m, S = 0; S < p.length; S++) {
|
|
var L = p[S]
|
|
, I = de(L, 4)
|
|
, R = d.sampleCount;
|
|
d.sampleCount += I;
|
|
var k = 1 & L[3]
|
|
, b = 4 & L[3]
|
|
, D = 1 & L[2]
|
|
, _ = 2 & L[2]
|
|
, P = 4 & L[2]
|
|
, C = 8 & L[2]
|
|
, w = 8
|
|
, O = I;
|
|
for (k && (w += 4),
|
|
b && I && (1 & L[w + 1] || void 0 !== d.keyFrameIndex || (d.keyFrameIndex = R),
|
|
w += 4,
|
|
D ? (T = de(L, w),
|
|
w += 4) : T = m,
|
|
_ && (w += 4),
|
|
C && (w += 4),
|
|
y += T,
|
|
E += T,
|
|
O--); O--; )
|
|
D ? (T = de(L, w),
|
|
w += 4) : T = m,
|
|
_ && (w += 4),
|
|
P && (1 & L[w + 1] || void 0 === d.keyFrameIndex && (d.keyFrameIndex = d.sampleCount - (O + 1),
|
|
d.keyFrameStart = y),
|
|
w += 4),
|
|
C && (w += 4),
|
|
y += T,
|
|
E += T;
|
|
!E && m && (E += m * I)
|
|
}
|
|
d.duration += E
|
|
}
|
|
}
|
|
if (!Object.keys(i).some((function(e) {
|
|
return i[e].duration
|
|
}
|
|
))) {
|
|
for (var x = 1 / 0, M = 0, F = ce(e, ["sidx"]), N = 0; N < F.length; N++) {
|
|
var U = ge(F[N]);
|
|
if (null != U && U.references) {
|
|
x = Math.min(x, U.earliestPresentationTime / U.timescale);
|
|
var B = U.references.reduce((function(e, t) {
|
|
return e + t.info.duration || 0
|
|
}
|
|
), 0);
|
|
M = Math.max(M, B + U.earliestPresentationTime / U.timescale)
|
|
}
|
|
}
|
|
M && A(M) && Object.keys(i).forEach((function(e) {
|
|
i[e].duration || (i[e].duration = M * i[e].timescale - i[e].start)
|
|
}
|
|
))
|
|
}
|
|
return i
|
|
}(h, c, this)
|
|
, v = c.audio ? g[c.audio.id] : null
|
|
, m = c.video ? g[c.video.id] : null
|
|
, p = zn(m, 1 / 0)
|
|
, y = zn(v, 1 / 0)
|
|
, E = zn(m, 0, !0)
|
|
, T = zn(v, 0, !0)
|
|
, S = n
|
|
, L = 0
|
|
, I = v && (!m || !l && y < p || l && l.trackId === c.audio.id)
|
|
, R = I ? v : m;
|
|
if (R) {
|
|
var k = R.timescale
|
|
, b = R.start - n * k
|
|
, D = I ? c.audio.id : c.video.id;
|
|
S = R.start / k,
|
|
L = I ? T - y : E - p,
|
|
!a && l || !function(e, t, r, i) {
|
|
if (null === e)
|
|
return !0;
|
|
var n = Math.max(i, 1)
|
|
, a = t - e.baseTime / e.timescale;
|
|
return Math.abs(a - r) > n
|
|
}(l, S, n, L) && k === l.timescale || (l && this.warn("Timestamps at playlist time: " + (a ? "" : "~") + n + " " + b / k + " != initPTS: " + l.baseTime / l.timescale + " (" + l.baseTime + "/" + l.timescale + ") trackId: " + l.trackId),
|
|
this.log("Found initPTS at playlist time: " + n + " offset: " + (S - n) + " (" + b + "/" + k + ") trackId: " + D),
|
|
l = null,
|
|
f.initPTS = b,
|
|
f.timescale = k,
|
|
f.trackId = D)
|
|
} else
|
|
this.warn("No audio or video samples found for initPTS at playlist time: " + n);
|
|
l ? (f.initPTS = l.baseTime,
|
|
f.timescale = l.timescale,
|
|
f.trackId = l.trackId) : (f.timescale && void 0 !== f.trackId && void 0 !== f.initPTS || (this.warn("Could not set initPTS"),
|
|
f.initPTS = S,
|
|
f.timescale = 1,
|
|
f.trackId = -1),
|
|
this.initPTS = l = {
|
|
baseTime: f.initPTS,
|
|
timescale: f.timescale,
|
|
trackId: f.trackId
|
|
});
|
|
var _ = S - l.baseTime / l.timescale
|
|
, P = _ + L;
|
|
L > 0 ? this.lastEndTime = P : (this.warn("Duration parsed from mp4 should be greater than zero"),
|
|
this.resetNextTimestamp());
|
|
var C = !!c.audio
|
|
, w = !!c.video
|
|
, O = "";
|
|
C && (O += "audio"),
|
|
w && (O += "video");
|
|
var x = {
|
|
data1: h,
|
|
startPTS: _,
|
|
startDTS: _,
|
|
endPTS: P,
|
|
endDTS: P,
|
|
type: O,
|
|
hasAudio: C,
|
|
hasVideo: w,
|
|
nb: 1,
|
|
dropped: 0,
|
|
encrypted: !!c.audio && c.audio.encrypted || !!c.video && c.video.encrypted
|
|
};
|
|
d.audio = C && !w ? x : void 0,
|
|
d.video = w ? x : void 0;
|
|
var M = null == m ? void 0 : m.sampleCount;
|
|
if (M) {
|
|
var F = m.keyFrameIndex
|
|
, N = -1 !== F;
|
|
x.nb = M,
|
|
x.dropped = 0 === F || this.isVideoContiguous ? 0 : N ? F : M,
|
|
x.independent = N,
|
|
x.firstKeyFrame = F,
|
|
N && m.keyFrameStart && (x.firstKeyFramePTS = (m.keyFrameStart - l.baseTime) / l.timescale),
|
|
this.isVideoContiguous || (d.independent = N),
|
|
this.isVideoContiguous || (this.isVideoContiguous = N),
|
|
x.dropped && this.warn("fmp4 does not start with IDR: firstIDR " + F + "/" + M + " dropped: " + x.dropped + " start: " + (x.firstKeyFramePTS || "NA"))
|
|
}
|
|
return d.initSegment = f,
|
|
d.id3 = jn(r, n, l, l),
|
|
i.samples.length && (d.text = qn(i, n, l)),
|
|
d
|
|
}
|
|
,
|
|
t
|
|
}(N);
|
|
function zn(e, t, r) {
|
|
return void 0 === r && (r = !1),
|
|
void 0 !== (null == e ? void 0 : e.start) ? (e.start + (r ? e.duration : 0)) / e.timescale : t
|
|
}
|
|
function $n(e, t, r) {
|
|
var i = e.codec;
|
|
return i && i.length > 4 ? i : t === $ ? "ec-3" === i || "ac-3" === i || "alac" === i ? i : "fLaC" === i || "Opus" === i ? Ge(i, !1) : (r.warn('Unhandled audio codec "' + i + '" in mp4 MAP'),
|
|
i || "mp4a") : (r.warn('Unhandled video codec "' + i + '" in mp4 MAP'),
|
|
i || "avc1")
|
|
}
|
|
try {
|
|
Xn = self.performance.now.bind(self.performance)
|
|
} catch (e) {
|
|
Xn = Date.now
|
|
}
|
|
var Zn = [{
|
|
demux: Tn,
|
|
remux: Qn
|
|
}, {
|
|
demux: Dn,
|
|
remux: Yn
|
|
}, {
|
|
demux: gn,
|
|
remux: Yn
|
|
}, {
|
|
demux: yn,
|
|
remux: Yn
|
|
}];
|
|
Zn.splice(2, 0, {
|
|
demux: mn,
|
|
remux: Yn
|
|
});
|
|
var Jn = function() {
|
|
function e(e, t, r, i, n, a) {
|
|
this.asyncResult = !1,
|
|
this.logger = void 0,
|
|
this.observer = void 0,
|
|
this.typeSupported = void 0,
|
|
this.config = void 0,
|
|
this.id = void 0,
|
|
this.demuxer = void 0,
|
|
this.remuxer = void 0,
|
|
this.decrypter = void 0,
|
|
this.probe = void 0,
|
|
this.decryptionPromise = null,
|
|
this.transmuxConfig = void 0,
|
|
this.currentTransmuxState = void 0,
|
|
this.observer = e,
|
|
this.typeSupported = t,
|
|
this.config = r,
|
|
this.id = n,
|
|
this.logger = a
|
|
}
|
|
var t = e.prototype;
|
|
return t.configure = function(e) {
|
|
this.transmuxConfig = e,
|
|
this.decrypter && this.decrypter.reset()
|
|
}
|
|
,
|
|
t.push = function(e, t, r, i) {
|
|
var n = this
|
|
, a = r.transmuxing;
|
|
a.executeStart = Xn();
|
|
var s = new Uint8Array(e)
|
|
, o = this.currentTransmuxState
|
|
, l = this.transmuxConfig;
|
|
i && (this.currentTransmuxState = i);
|
|
var u = i || o
|
|
, d = u.contiguous
|
|
, h = u.discontinuity
|
|
, f = u.trackSwitch
|
|
, c = u.accurateTimeOffset
|
|
, g = u.timeOffset
|
|
, v = u.initSegmentChange
|
|
, m = l.audioCodec
|
|
, p = l.videoCodec
|
|
, y = l.defaultInitPts
|
|
, E = l.duration
|
|
, T = l.initSegmentData
|
|
, S = function(e, t) {
|
|
var r = null;
|
|
return e.byteLength > 0 && null != (null == t ? void 0 : t.key) && null !== t.iv && null != t.method && (r = t),
|
|
r
|
|
}(s, t);
|
|
if (S && Lr(S.method)) {
|
|
var A = this.getDecrypter()
|
|
, L = Ir(S.method);
|
|
if (!A.isSync())
|
|
return this.asyncResult = !0,
|
|
this.decryptionPromise = A.webCryptoDecrypt(s, S.key.buffer, S.iv.buffer, L).then((function(e) {
|
|
var t = n.push(e, null, r);
|
|
return n.decryptionPromise = null,
|
|
t
|
|
}
|
|
)),
|
|
this.decryptionPromise;
|
|
var I = A.softwareDecrypt(s, S.key.buffer, S.iv.buffer, L);
|
|
if (r.part > -1) {
|
|
var D = A.flush();
|
|
I = D ? D.buffer : D
|
|
}
|
|
if (!I)
|
|
return a.executeEnd = Xn(),
|
|
ea(r);
|
|
s = new Uint8Array(I)
|
|
}
|
|
var _ = this.needsProbing(h, f);
|
|
if (_) {
|
|
var P = this.configureTransmuxer(s);
|
|
if (P)
|
|
return this.logger.warn("[transmuxer] " + P.message),
|
|
this.observer.emit(b.ERROR, b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.FRAG_PARSING_ERROR,
|
|
fatal: !1,
|
|
error: P,
|
|
reason: P.message
|
|
}),
|
|
a.executeEnd = Xn(),
|
|
ea(r)
|
|
}
|
|
(h || f || v || _) && this.resetInitSegment(T, m, p, E, t),
|
|
(h || v || _) && this.resetInitialTimestamp(y),
|
|
d || this.resetContiguity();
|
|
var C = this.transmux(s, S, g, c, r);
|
|
this.asyncResult = ta(C);
|
|
var w = this.currentTransmuxState;
|
|
return w.contiguous = !0,
|
|
w.discontinuity = !1,
|
|
w.trackSwitch = !1,
|
|
a.executeEnd = Xn(),
|
|
C
|
|
}
|
|
,
|
|
t.flush = function(e) {
|
|
var t = this
|
|
, r = e.transmuxing;
|
|
r.executeStart = Xn();
|
|
var i = this.decrypter
|
|
, n = this.currentTransmuxState
|
|
, a = this.decryptionPromise;
|
|
if (a)
|
|
return this.asyncResult = !0,
|
|
a.then((function() {
|
|
return t.flush(e)
|
|
}
|
|
));
|
|
var s = []
|
|
, o = n.timeOffset;
|
|
if (i) {
|
|
var l = i.flush();
|
|
l && s.push(this.push(l.buffer, null, e))
|
|
}
|
|
var u = this.demuxer
|
|
, d = this.remuxer;
|
|
if (!u || !d) {
|
|
r.executeEnd = Xn();
|
|
var h = [ea(e)];
|
|
return this.asyncResult ? Promise.resolve(h) : h
|
|
}
|
|
var f = u.flush(o);
|
|
return ta(f) ? (this.asyncResult = !0,
|
|
f.then((function(r) {
|
|
return t.flushRemux(s, r, e),
|
|
s
|
|
}
|
|
))) : (this.flushRemux(s, f, e),
|
|
this.asyncResult ? Promise.resolve(s) : s)
|
|
}
|
|
,
|
|
t.flushRemux = function(e, t, r) {
|
|
var i = t.audioTrack
|
|
, n = t.videoTrack
|
|
, a = t.id3Track
|
|
, s = t.textTrack
|
|
, o = this.currentTransmuxState
|
|
, l = o.accurateTimeOffset
|
|
, u = o.timeOffset;
|
|
this.logger.log("[transmuxer.ts]: Flushed " + this.id + " sn: " + r.sn + (r.part > -1 ? " part: " + r.part : "") + " of " + (this.id === w ? "level" : "track") + " " + r.level);
|
|
var d = this.remuxer.remux(i, n, a, s, u, l, !0, this.id);
|
|
e.push({
|
|
remuxResult: d,
|
|
chunkMeta: r
|
|
}),
|
|
r.transmuxing.executeEnd = Xn()
|
|
}
|
|
,
|
|
t.resetInitialTimestamp = function(e) {
|
|
var t = this.demuxer
|
|
, r = this.remuxer;
|
|
t && r && (t.resetTimeStamp(e),
|
|
r.resetTimeStamp(e))
|
|
}
|
|
,
|
|
t.resetContiguity = function() {
|
|
var e = this.demuxer
|
|
, t = this.remuxer;
|
|
e && t && (e.resetContiguity(),
|
|
t.resetNextTimestamp())
|
|
}
|
|
,
|
|
t.resetInitSegment = function(e, t, r, i, n) {
|
|
var a = this.demuxer
|
|
, s = this.remuxer;
|
|
a && s && (a.resetInitSegment(e, t, r, i),
|
|
s.resetInitSegment(e, t, r, n))
|
|
}
|
|
,
|
|
t.destroy = function() {
|
|
this.demuxer && (this.demuxer.destroy(),
|
|
this.demuxer = void 0),
|
|
this.remuxer && (this.remuxer.destroy(),
|
|
this.remuxer = void 0)
|
|
}
|
|
,
|
|
t.transmux = function(e, t, r, i, n) {
|
|
return t && "SAMPLE-AES" === t.method ? this.transmuxSampleAes(e, t, r, i, n) : this.transmuxUnencrypted(e, r, i, n)
|
|
}
|
|
,
|
|
t.transmuxUnencrypted = function(e, t, r, i) {
|
|
var n = this.demuxer.demux(e, t, !1, !this.config.progressive)
|
|
, a = n.audioTrack
|
|
, s = n.videoTrack
|
|
, o = n.id3Track
|
|
, l = n.textTrack;
|
|
return {
|
|
remuxResult: this.remuxer.remux(a, s, o, l, t, r, !1, this.id),
|
|
chunkMeta: i
|
|
}
|
|
}
|
|
,
|
|
t.transmuxSampleAes = function(e, t, r, i, n) {
|
|
var a = this;
|
|
return this.demuxer.demuxSampleAes(e, t, r).then((function(e) {
|
|
return {
|
|
remuxResult: a.remuxer.remux(e.audioTrack, e.videoTrack, e.id3Track, e.textTrack, r, i, !1, a.id),
|
|
chunkMeta: n
|
|
}
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t.configureTransmuxer = function(e) {
|
|
for (var t, r = this.config, i = this.observer, n = this.typeSupported, a = 0, s = Zn.length; a < s; a++) {
|
|
var o;
|
|
if (null != (o = Zn[a].demux) && o.probe(e, this.logger)) {
|
|
t = Zn[a];
|
|
break
|
|
}
|
|
}
|
|
if (!t)
|
|
return new Error("Failed to find demuxer by probing fragment data");
|
|
var l = this.demuxer
|
|
, u = this.remuxer
|
|
, d = t.remux
|
|
, h = t.demux;
|
|
u && u instanceof d || (this.remuxer = new d(i,r,n,this.logger)),
|
|
l && l instanceof h || (this.demuxer = new h(i,r,n,this.logger),
|
|
this.probe = h.probe)
|
|
}
|
|
,
|
|
t.needsProbing = function(e, t) {
|
|
return !this.demuxer || !this.remuxer || e || t
|
|
}
|
|
,
|
|
t.getDecrypter = function() {
|
|
var e = this.decrypter;
|
|
return e || (e = this.decrypter = new er(this.config)),
|
|
e
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, ea = function(e) {
|
|
return {
|
|
remuxResult: {},
|
|
chunkMeta: e
|
|
}
|
|
};
|
|
function ta(e) {
|
|
return "then"in e && e.then instanceof Function
|
|
}
|
|
var ra = function(e, t, r, i, n) {
|
|
this.audioCodec = void 0,
|
|
this.videoCodec = void 0,
|
|
this.initSegmentData = void 0,
|
|
this.duration = void 0,
|
|
this.defaultInitPts = void 0,
|
|
this.audioCodec = e,
|
|
this.videoCodec = t,
|
|
this.initSegmentData = r,
|
|
this.duration = i,
|
|
this.defaultInitPts = n || null
|
|
}
|
|
, ia = function(e, t, r, i, n, a) {
|
|
this.discontinuity = void 0,
|
|
this.contiguous = void 0,
|
|
this.accurateTimeOffset = void 0,
|
|
this.trackSwitch = void 0,
|
|
this.timeOffset = void 0,
|
|
this.initSegmentChange = void 0,
|
|
this.discontinuity = e,
|
|
this.contiguous = t,
|
|
this.accurateTimeOffset = r,
|
|
this.trackSwitch = i,
|
|
this.timeOffset = n,
|
|
this.initSegmentChange = a
|
|
}
|
|
, na = [];
|
|
function aa(e, t, r) {
|
|
if (!((i = t.remuxResult).audio || i.video || i.text || i.id3 || i.initSegment))
|
|
return !1;
|
|
var i, n = [], a = t.remuxResult, s = a.audio, o = a.video;
|
|
return s && sa(n, s),
|
|
o && sa(n, o),
|
|
e.postMessage({
|
|
event: "transmuxComplete",
|
|
data: t,
|
|
instanceNo: r
|
|
}, n),
|
|
!0
|
|
}
|
|
function sa(e, t) {
|
|
t.data1 && e.push(t.data1.buffer),
|
|
t.data2 && e.push(t.data2.buffer)
|
|
}
|
|
function oa(e, t, r, i) {
|
|
t.reduce((function(t, r) {
|
|
return aa(e, r, i) || t
|
|
}
|
|
), !1) || e.postMessage({
|
|
event: "transmuxComplete",
|
|
data: t[0],
|
|
instanceNo: i
|
|
}),
|
|
e.postMessage({
|
|
event: "flush",
|
|
data: r,
|
|
instanceNo: i
|
|
})
|
|
}
|
|
function la(e, t, r) {
|
|
self.postMessage({
|
|
event: e,
|
|
data: t,
|
|
instanceNo: r
|
|
})
|
|
}
|
|
void 0 !== t && t && self.addEventListener("message", (function(e) {
|
|
var t = e.data
|
|
, r = t.instanceNo;
|
|
if (void 0 !== r) {
|
|
var i = na[r];
|
|
if ("reset" === t.cmd && (delete na[t.resetNo],
|
|
i && i.destroy(),
|
|
t.cmd = "init"),
|
|
"init" === t.cmd) {
|
|
var n = JSON.parse(t.config)
|
|
, a = new E;
|
|
a.on(b.FRAG_DECRYPTED, la),
|
|
a.on(b.ERROR, la);
|
|
var s = H(n.debug, t.id);
|
|
return function(e, t) {
|
|
var r = function(r) {
|
|
e[r] = function() {
|
|
var e = Array.prototype.join.call(arguments, " ");
|
|
la("workerLog", {
|
|
logType: r,
|
|
message: e
|
|
}, t)
|
|
}
|
|
};
|
|
for (var i in e)
|
|
r(i)
|
|
}(s, r),
|
|
na[r] = new Jn(a,t.typeSupported,n,"",t.id,s),
|
|
void la("init", null, r)
|
|
}
|
|
if (i)
|
|
switch (t.cmd) {
|
|
case "configure":
|
|
i.configure(t.config);
|
|
break;
|
|
case "demux":
|
|
var o = i.push(t.data, t.decryptdata, t.chunkMeta, t.state);
|
|
ta(o) ? o.then((function(e) {
|
|
aa(self, e, r)
|
|
}
|
|
)).catch((function(e) {
|
|
la(b.ERROR, {
|
|
instanceNo: r,
|
|
type: R.MEDIA_ERROR,
|
|
details: k.FRAG_PARSING_ERROR,
|
|
chunkMeta: t.chunkMeta,
|
|
fatal: !1,
|
|
error: e,
|
|
err: e,
|
|
reason: "transmuxer-worker push error"
|
|
}, r)
|
|
}
|
|
)) : aa(self, o, r);
|
|
break;
|
|
case "flush":
|
|
var l = t.chunkMeta
|
|
, u = i.flush(l);
|
|
ta(u) ? u.then((function(e) {
|
|
oa(self, e, l, r)
|
|
}
|
|
)).catch((function(e) {
|
|
la(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.FRAG_PARSING_ERROR,
|
|
chunkMeta: t.chunkMeta,
|
|
fatal: !1,
|
|
error: e,
|
|
err: e,
|
|
reason: "transmuxer-worker flush error"
|
|
}, r)
|
|
}
|
|
)) : oa(self, u, l, r)
|
|
}
|
|
}
|
|
}
|
|
));
|
|
var ua = "1.6.12"
|
|
, da = {}
|
|
, ha = 0
|
|
, fa = function() {
|
|
function t(t, r, i, n) {
|
|
var a = this;
|
|
this.error = null,
|
|
this.hls = void 0,
|
|
this.id = void 0,
|
|
this.instanceNo = ha++,
|
|
this.observer = void 0,
|
|
this.frag = null,
|
|
this.part = null,
|
|
this.useWorker = void 0,
|
|
this.workerContext = null,
|
|
this.transmuxer = null,
|
|
this.onTransmuxComplete = void 0,
|
|
this.onFlush = void 0,
|
|
this.onWorkerMessage = function(e) {
|
|
var t = e.data
|
|
, r = a.hls;
|
|
if (r && null != t && t.event && t.instanceNo === a.instanceNo)
|
|
switch (t.event) {
|
|
case "init":
|
|
var i, n = null == (i = a.workerContext) ? void 0 : i.objectURL;
|
|
n && self.URL.revokeObjectURL(n);
|
|
break;
|
|
case "transmuxComplete":
|
|
a.handleTransmuxComplete(t.data);
|
|
break;
|
|
case "flush":
|
|
a.onFlush(t.data);
|
|
break;
|
|
case "workerLog":
|
|
r.logger[t.data.logType] && r.logger[t.data.logType](t.data.message);
|
|
break;
|
|
default:
|
|
t.data = t.data || {},
|
|
t.data.frag = a.frag,
|
|
t.data.part = a.part,
|
|
t.data.id = a.id,
|
|
r.trigger(t.event, t.data)
|
|
}
|
|
}
|
|
,
|
|
this.onWorkerError = function(e) {
|
|
if (a.hls) {
|
|
var t = new Error(e.message + " (" + e.filename + ":" + e.lineno + ")");
|
|
a.hls.config.enableWorker = !1,
|
|
a.hls.logger.warn('Error in "' + a.id + '" Web Worker, fallback to inline'),
|
|
a.hls.trigger(b.ERROR, {
|
|
type: R.OTHER_ERROR,
|
|
details: k.INTERNAL_EXCEPTION,
|
|
fatal: !1,
|
|
event: "demuxerWorker",
|
|
error: t
|
|
})
|
|
}
|
|
}
|
|
;
|
|
var s = t.config;
|
|
this.hls = t,
|
|
this.id = r,
|
|
this.useWorker = !!s.enableWorker,
|
|
this.onTransmuxComplete = i,
|
|
this.onFlush = n;
|
|
var o = function(e, t) {
|
|
(t = t || {}).frag = a.frag || void 0,
|
|
e === b.ERROR && (t.parent = a.id,
|
|
t.part = a.part,
|
|
a.error = t.error),
|
|
a.hls.trigger(e, t)
|
|
};
|
|
this.observer = new E,
|
|
this.observer.on(b.FRAG_DECRYPTED, o),
|
|
this.observer.on(b.ERROR, o);
|
|
var l = Ye(s.preferManagedMediaSource);
|
|
if (this.useWorker && "undefined" != typeof Worker) {
|
|
var u = this.hls.logger;
|
|
s.workerPath;
|
|
try {
|
|
s.workerPath ? (u.log("loading Web Worker " + s.workerPath + ' for "' + r + '"'),
|
|
this.workerContext = function(e) {
|
|
var t = da[e];
|
|
if (t)
|
|
return t.clientCount++,
|
|
t;
|
|
var r = new self.URL(e,self.location.href).href
|
|
, i = {
|
|
worker: new self.Worker(r),
|
|
scriptURL: r,
|
|
clientCount: 1
|
|
};
|
|
return da[e] = i,
|
|
i
|
|
}(s.workerPath)) : (u.log('injecting Web Worker for "' + r + '"'),
|
|
this.workerContext = function() {
|
|
var t = da[ua];
|
|
if (t)
|
|
return t.clientCount++,
|
|
t;
|
|
var r = new self.Blob(["var exports={};var module={exports:exports};function define(f){f()};define.amd=true;(" + e.toString() + ")(true);"],{
|
|
type: "text/javascript"
|
|
})
|
|
, i = self.URL.createObjectURL(r)
|
|
, n = {
|
|
worker: new self.Worker(i),
|
|
objectURL: i,
|
|
clientCount: 1
|
|
};
|
|
return da[ua] = n,
|
|
n
|
|
}());
|
|
var d = this.workerContext.worker;
|
|
d.addEventListener("message", this.onWorkerMessage),
|
|
d.addEventListener("error", this.onWorkerError),
|
|
d.postMessage({
|
|
instanceNo: this.instanceNo,
|
|
cmd: "init",
|
|
typeSupported: l,
|
|
id: r,
|
|
config: lt(s)
|
|
})
|
|
} catch (e) {
|
|
u.warn('Error setting up "' + r + '" Web Worker, fallback to inline', e),
|
|
this.terminateWorker(),
|
|
this.error = null,
|
|
this.transmuxer = new Jn(this.observer,l,s,"",r,t.logger)
|
|
}
|
|
} else
|
|
this.transmuxer = new Jn(this.observer,l,s,"",r,t.logger)
|
|
}
|
|
var r = t.prototype;
|
|
return r.reset = function() {
|
|
if (this.frag = null,
|
|
this.part = null,
|
|
this.workerContext) {
|
|
var e = this.instanceNo;
|
|
this.instanceNo = ha++;
|
|
var t = this.hls.config
|
|
, r = Ye(t.preferManagedMediaSource);
|
|
this.workerContext.worker.postMessage({
|
|
instanceNo: this.instanceNo,
|
|
cmd: "reset",
|
|
resetNo: e,
|
|
typeSupported: r,
|
|
id: this.id,
|
|
config: lt(t)
|
|
})
|
|
}
|
|
}
|
|
,
|
|
r.terminateWorker = function() {
|
|
if (this.workerContext) {
|
|
var e = this.workerContext.worker;
|
|
this.workerContext = null,
|
|
e.removeEventListener("message", this.onWorkerMessage),
|
|
e.removeEventListener("error", this.onWorkerError),
|
|
function(e) {
|
|
var t = da[e || ua];
|
|
if (t && 1 == t.clientCount--) {
|
|
var r = t.worker
|
|
, i = t.objectURL;
|
|
delete da[e || ua],
|
|
i && self.URL.revokeObjectURL(i),
|
|
r.terminate()
|
|
}
|
|
}(this.hls.config.workerPath)
|
|
}
|
|
}
|
|
,
|
|
r.destroy = function() {
|
|
if (this.workerContext)
|
|
this.terminateWorker(),
|
|
this.onWorkerMessage = this.onWorkerError = null;
|
|
else {
|
|
var e = this.transmuxer;
|
|
e && (e.destroy(),
|
|
this.transmuxer = null)
|
|
}
|
|
var t = this.observer;
|
|
t && t.removeAllListeners(),
|
|
this.frag = null,
|
|
this.part = null,
|
|
this.observer = null,
|
|
this.hls = null
|
|
}
|
|
,
|
|
r.push = function(e, t, r, i, n, a, s, o, l, u) {
|
|
var d, h, f = this;
|
|
l.transmuxing.start = self.performance.now();
|
|
var c = this.instanceNo
|
|
, g = this.transmuxer
|
|
, v = a ? a.start : n.start
|
|
, m = n.decryptdata
|
|
, p = this.frag
|
|
, y = !(p && n.cc === p.cc)
|
|
, E = !(p && l.level === p.level)
|
|
, T = p ? l.sn - p.sn : -1
|
|
, S = this.part ? l.part - this.part.index : -1
|
|
, A = 0 === T && l.id > 1 && l.id === (null == p ? void 0 : p.stats.chunkCount)
|
|
, L = !E && (1 === T || 0 === T && (1 === S || A && S <= 0))
|
|
, I = self.performance.now();
|
|
(E || T || 0 === n.stats.parsing.start) && (n.stats.parsing.start = I),
|
|
!a || !S && L || (a.stats.parsing.start = I);
|
|
var R = !(p && (null == (d = n.initSegment) ? void 0 : d.url) === (null == (h = p.initSegment) ? void 0 : h.url))
|
|
, k = new ia(y,L,o,E,v,R);
|
|
if (!L || y || R) {
|
|
this.hls.logger.log("[transmuxer-interface]: Starting new transmux session for " + n.type + " sn: " + l.sn + (l.part > -1 ? " part: " + l.part : "") + " " + (this.id === w ? "level" : "track") + ": " + l.level + " id: " + l.id + "\n discontinuity: " + y + "\n trackSwitch: " + E + "\n contiguous: " + L + "\n accurateTimeOffset: " + o + "\n timeOffset: " + v + "\n initSegmentChange: " + R);
|
|
var b = new ra(r,i,t,s,u);
|
|
this.configureTransmuxer(b)
|
|
}
|
|
if (this.frag = n,
|
|
this.part = a,
|
|
this.workerContext)
|
|
this.workerContext.worker.postMessage({
|
|
instanceNo: c,
|
|
cmd: "demux",
|
|
data: e,
|
|
decryptdata: m,
|
|
chunkMeta: l,
|
|
state: k
|
|
}, e instanceof ArrayBuffer ? [e] : []);
|
|
else if (g) {
|
|
var D = g.push(e, m, l, k);
|
|
ta(D) ? D.then((function(e) {
|
|
f.handleTransmuxComplete(e)
|
|
}
|
|
)).catch((function(e) {
|
|
f.transmuxerError(e, l, "transmuxer-interface push error")
|
|
}
|
|
)) : this.handleTransmuxComplete(D)
|
|
}
|
|
}
|
|
,
|
|
r.flush = function(e) {
|
|
var t = this;
|
|
e.transmuxing.start = self.performance.now();
|
|
var r = this.instanceNo
|
|
, i = this.transmuxer;
|
|
if (this.workerContext)
|
|
this.workerContext.worker.postMessage({
|
|
instanceNo: r,
|
|
cmd: "flush",
|
|
chunkMeta: e
|
|
});
|
|
else if (i) {
|
|
var n = i.flush(e);
|
|
ta(n) ? n.then((function(r) {
|
|
t.handleFlushResult(r, e)
|
|
}
|
|
)).catch((function(r) {
|
|
t.transmuxerError(r, e, "transmuxer-interface flush error")
|
|
}
|
|
)) : this.handleFlushResult(n, e)
|
|
}
|
|
}
|
|
,
|
|
r.transmuxerError = function(e, t, r) {
|
|
this.hls && (this.error = e,
|
|
this.hls.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.FRAG_PARSING_ERROR,
|
|
chunkMeta: t,
|
|
frag: this.frag || void 0,
|
|
part: this.part || void 0,
|
|
fatal: !1,
|
|
error: e,
|
|
err: e,
|
|
reason: r
|
|
}))
|
|
}
|
|
,
|
|
r.handleFlushResult = function(e, t) {
|
|
var r = this;
|
|
e.forEach((function(e) {
|
|
r.handleTransmuxComplete(e)
|
|
}
|
|
)),
|
|
this.onFlush(t)
|
|
}
|
|
,
|
|
r.configureTransmuxer = function(e) {
|
|
var t = this.instanceNo
|
|
, r = this.transmuxer;
|
|
this.workerContext ? this.workerContext.worker.postMessage({
|
|
instanceNo: t,
|
|
cmd: "configure",
|
|
config: e
|
|
}) : r && r.configure(e)
|
|
}
|
|
,
|
|
r.handleTransmuxComplete = function(e) {
|
|
e.chunkMeta.transmuxing.end = self.performance.now(),
|
|
this.onTransmuxComplete(e)
|
|
}
|
|
,
|
|
t
|
|
}()
|
|
, ca = function(e) {
|
|
function t(t, r, i) {
|
|
var n;
|
|
return (n = e.call(this, t, r, i, "audio-stream-controller", O) || this).mainAnchor = null,
|
|
n.mainFragLoading = null,
|
|
n.audioOnly = !1,
|
|
n.bufferedTrack = null,
|
|
n.switchingTrack = null,
|
|
n.trackId = -1,
|
|
n.waitingData = null,
|
|
n.mainDetails = null,
|
|
n.flushing = !1,
|
|
n.bufferFlushed = !1,
|
|
n.cachedTrackLoadedData = null,
|
|
n.registerListeners(),
|
|
n
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.onHandlerDestroying = function() {
|
|
this.unregisterListeners(),
|
|
e.prototype.onHandlerDestroying.call(this),
|
|
this.resetItem()
|
|
}
|
|
,
|
|
r.resetItem = function() {
|
|
this.mainDetails = this.mainAnchor = this.mainFragLoading = this.bufferedTrack = this.switchingTrack = this.waitingData = this.cachedTrackLoadedData = null
|
|
}
|
|
,
|
|
r.registerListeners = function() {
|
|
e.prototype.registerListeners.call(this);
|
|
var t = this.hls;
|
|
t.on(b.LEVEL_LOADED, this.onLevelLoaded, this),
|
|
t.on(b.AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this),
|
|
t.on(b.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this),
|
|
t.on(b.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this),
|
|
t.on(b.BUFFER_RESET, this.onBufferReset, this),
|
|
t.on(b.BUFFER_CREATED, this.onBufferCreated, this),
|
|
t.on(b.BUFFER_FLUSHING, this.onBufferFlushing, this),
|
|
t.on(b.BUFFER_FLUSHED, this.onBufferFlushed, this),
|
|
t.on(b.INIT_PTS_FOUND, this.onInitPtsFound, this),
|
|
t.on(b.FRAG_LOADING, this.onFragLoading, this),
|
|
t.on(b.FRAG_BUFFERED, this.onFragBuffered, this)
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
var t = this.hls;
|
|
t && (e.prototype.unregisterListeners.call(this),
|
|
t.off(b.LEVEL_LOADED, this.onLevelLoaded, this),
|
|
t.off(b.AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this),
|
|
t.off(b.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this),
|
|
t.off(b.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this),
|
|
t.off(b.BUFFER_RESET, this.onBufferReset, this),
|
|
t.off(b.BUFFER_CREATED, this.onBufferCreated, this),
|
|
t.off(b.BUFFER_FLUSHING, this.onBufferFlushing, this),
|
|
t.off(b.BUFFER_FLUSHED, this.onBufferFlushed, this),
|
|
t.off(b.INIT_PTS_FOUND, this.onInitPtsFound, this),
|
|
t.off(b.FRAG_LOADING, this.onFragLoading, this),
|
|
t.off(b.FRAG_BUFFERED, this.onFragBuffered, this))
|
|
}
|
|
,
|
|
r.onInitPtsFound = function(e, t) {
|
|
var r = t.frag
|
|
, i = t.id
|
|
, n = t.initPTS
|
|
, a = t.timescale
|
|
, s = t.trackId;
|
|
if (i === w) {
|
|
var o = r.cc
|
|
, l = this.fragCurrent;
|
|
if (this.initPTS[o] = {
|
|
baseTime: n,
|
|
timescale: a,
|
|
trackId: s
|
|
},
|
|
this.log("InitPTS for cc: " + o + " found from main: " + n / a + " (" + n + "/" + a + ") trackId: " + s),
|
|
this.mainAnchor = r,
|
|
this.state === ki.WAITING_INIT_PTS) {
|
|
var u = this.waitingData;
|
|
(!u && !this.loadingParts || u && u.frag.cc !== o) && this.syncWithAnchor(r, null == u ? void 0 : u.frag)
|
|
} else
|
|
!this.hls.hasEnoughToStart && l && l.cc !== o ? (l.abortRequests(),
|
|
this.syncWithAnchor(r, l)) : this.state === ki.IDLE && this.tick()
|
|
}
|
|
}
|
|
,
|
|
r.getLoadPosition = function() {
|
|
return !this.startFragRequested && this.nextLoadPosition >= 0 ? this.nextLoadPosition : e.prototype.getLoadPosition.call(this)
|
|
}
|
|
,
|
|
r.syncWithAnchor = function(e, t) {
|
|
var r, i = (null == (r = this.mainFragLoading) ? void 0 : r.frag) || null;
|
|
if (!t || (null == i ? void 0 : i.cc) !== t.cc) {
|
|
var n = (i || e).cc
|
|
, a = At(this.getLevelDetails(), n, this.getLoadPosition());
|
|
a && (this.log("Syncing with main frag at " + a.start + " cc " + a.cc),
|
|
this.startFragRequested = !1,
|
|
this.nextLoadPosition = a.start,
|
|
this.resetLoadingState(),
|
|
this.state === ki.IDLE && this.doTickIdle())
|
|
}
|
|
}
|
|
,
|
|
r.startLoad = function(e, t) {
|
|
if (!this.levels)
|
|
return this.startPosition = e,
|
|
void (this.state = ki.STOPPED);
|
|
var r = this.lastCurrentTime;
|
|
this.stopLoad(),
|
|
this.setInterval(100),
|
|
r > 0 && -1 === e ? (this.log("Override startPosition with lastCurrentTime @" + r.toFixed(3)),
|
|
e = r,
|
|
this.state = ki.IDLE) : this.state = ki.WAITING_TRACK,
|
|
this.nextLoadPosition = this.lastCurrentTime = e + this.timelineOffset,
|
|
this.startPosition = t ? -1 : e,
|
|
this.tick()
|
|
}
|
|
,
|
|
r.doTick = function() {
|
|
switch (this.state) {
|
|
case ki.IDLE:
|
|
this.doTickIdle();
|
|
break;
|
|
case ki.WAITING_TRACK:
|
|
var t = this.levels
|
|
, r = this.trackId
|
|
, i = null == t ? void 0 : t[r]
|
|
, n = null == i ? void 0 : i.details;
|
|
if (n && !this.waitForLive(i)) {
|
|
if (this.waitForCdnTuneIn(n))
|
|
break;
|
|
this.state = ki.WAITING_INIT_PTS
|
|
}
|
|
break;
|
|
case ki.FRAG_LOADING_WAITING_RETRY:
|
|
this.checkRetryDate();
|
|
break;
|
|
case ki.WAITING_INIT_PTS:
|
|
var a = this.waitingData;
|
|
if (a) {
|
|
var s = a.frag
|
|
, o = a.part
|
|
, l = a.cache
|
|
, u = a.complete
|
|
, d = this.mainAnchor;
|
|
if (void 0 !== this.initPTS[s.cc]) {
|
|
this.waitingData = null,
|
|
this.state = ki.FRAG_LOADING;
|
|
var h = {
|
|
frag: s,
|
|
part: o,
|
|
payload: l.flush().buffer,
|
|
networkDetails: null
|
|
};
|
|
this._handleFragmentLoadProgress(h),
|
|
u && e.prototype._handleFragmentLoadComplete.call(this, h)
|
|
} else
|
|
d && d.cc !== a.frag.cc && this.syncWithAnchor(d, a.frag)
|
|
} else
|
|
this.state = ki.IDLE
|
|
}
|
|
this.onTickEnd()
|
|
}
|
|
,
|
|
r.resetLoadingState = function() {
|
|
var t = this.waitingData;
|
|
t && (this.fragmentTracker.removeFragment(t.frag),
|
|
this.waitingData = null),
|
|
e.prototype.resetLoadingState.call(this)
|
|
}
|
|
,
|
|
r.onTickEnd = function() {
|
|
var e = this.media;
|
|
null != e && e.readyState && (this.lastCurrentTime = e.currentTime)
|
|
}
|
|
,
|
|
r.doTickIdle = function() {
|
|
var e, t = this.hls, r = this.levels, i = this.media, n = this.trackId, a = t.config;
|
|
if (this.buffering && (i || this.primaryPrefetch || !this.startFragRequested && a.startFragPrefetch) && null != r && r[n]) {
|
|
var s = r[n]
|
|
, o = s.details;
|
|
if (!o || this.waitForLive(s) || this.waitForCdnTuneIn(o))
|
|
return this.state = ki.WAITING_TRACK,
|
|
void (this.startFragRequested = !1);
|
|
var l = this.mediaBuffer ? this.mediaBuffer : this.media;
|
|
this.bufferFlushed && l && (this.bufferFlushed = !1,
|
|
this.afterBufferFlushed(l, $, O));
|
|
var u = this.getFwdBufferInfo(l, O);
|
|
if (null !== u) {
|
|
if (!this.switchingTrack && this._streamEnded(u, o))
|
|
return t.trigger(b.BUFFER_EOS, {
|
|
type: "audio"
|
|
}),
|
|
void (this.state = ki.ENDED);
|
|
var d = u.len
|
|
, h = t.maxBufferLength
|
|
, f = o.fragments
|
|
, c = f[0].start
|
|
, g = this.getLoadPosition()
|
|
, v = this.flushing ? g : u.end;
|
|
if (this.switchingTrack && i) {
|
|
var m = g;
|
|
o.PTSKnown && m < c && (u.end > c || u.nextStart) && (this.log("Alt audio track ahead of main track, seek to start of alt audio track"),
|
|
i.currentTime = c + .05)
|
|
}
|
|
if (!(d >= h && !this.switchingTrack && v < f[f.length - 1].start)) {
|
|
var p = this.getNextFragment(v, o);
|
|
if (p && this.isLoopLoading(p, v) && (p = this.getNextFragmentLoopLoading(p, o, u, w, h)),
|
|
p) {
|
|
var y = (null == (e = this.mainFragLoading) ? void 0 : e.frag) || null;
|
|
if (!this.audioOnly && this.startFragRequested && y && te(p) && !p.endList && (!o.live || !this.loadingParts && v < this.hls.liveSyncPosition) && (this.fragmentTracker.getState(y) === Yt && (this.mainFragLoading = y = null),
|
|
y && te(y))) {
|
|
if (p.start > y.end) {
|
|
var E = this.fragmentTracker.getFragAtPos(v, w);
|
|
E && E.end > y.end && (y = E,
|
|
this.mainFragLoading = {
|
|
frag: E,
|
|
targetBufferTime: null
|
|
})
|
|
}
|
|
if (p.start > y.end)
|
|
return
|
|
}
|
|
this.loadFragment(p, s, v)
|
|
} else
|
|
this.bufferFlushed = !0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.onMediaDetaching = function(t, r) {
|
|
this.bufferFlushed = this.flushing = !1,
|
|
e.prototype.onMediaDetaching.call(this, t, r)
|
|
}
|
|
,
|
|
r.onAudioTracksUpdated = function(e, t) {
|
|
var r = t.audioTracks;
|
|
this.resetTransmuxer(),
|
|
this.levels = r.map((function(e) {
|
|
return new at(e)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.onAudioTrackSwitching = function(e, t) {
|
|
var r = !!t.url;
|
|
this.trackId = t.id;
|
|
var i = this.fragCurrent;
|
|
i && (i.abortRequests(),
|
|
this.removeUnbufferedFrags(i.start)),
|
|
this.resetLoadingState(),
|
|
r ? (this.switchingTrack = t,
|
|
this.flushAudioIfNeeded(t),
|
|
this.state !== ki.STOPPED && (this.setInterval(100),
|
|
this.state = ki.IDLE,
|
|
this.tick())) : (this.resetTransmuxer(),
|
|
this.switchingTrack = null,
|
|
this.bufferedTrack = t,
|
|
this.clearInterval())
|
|
}
|
|
,
|
|
r.onManifestLoading = function() {
|
|
e.prototype.onManifestLoading.call(this),
|
|
this.bufferFlushed = this.flushing = this.audioOnly = !1,
|
|
this.resetItem(),
|
|
this.trackId = -1
|
|
}
|
|
,
|
|
r.onLevelLoaded = function(e, t) {
|
|
this.mainDetails = t.details;
|
|
var r = this.cachedTrackLoadedData;
|
|
r && (this.cachedTrackLoadedData = null,
|
|
this.onAudioTrackLoaded(b.AUDIO_TRACK_LOADED, r))
|
|
}
|
|
,
|
|
r.onAudioTrackLoaded = function(e, t) {
|
|
var r, i = this.levels, n = t.details, a = t.id, s = t.groupId, o = t.track;
|
|
if (i) {
|
|
var l = this.mainDetails;
|
|
if (!l || n.endCC > l.endCC || l.expired)
|
|
return this.cachedTrackLoadedData = t,
|
|
void (this.state !== ki.STOPPED && (this.state = ki.WAITING_TRACK));
|
|
this.cachedTrackLoadedData = null,
|
|
this.log("Audio track " + a + ' "' + o.name + '" of "' + s + '" loaded [' + n.startSN + "," + n.endSN + "]" + (n.lastPartSn ? "[part-" + n.lastPartSn + "-" + n.lastPartIndex + "]" : "") + ",duration:" + n.totalduration);
|
|
var u = i[a]
|
|
, d = 0;
|
|
if (n.live || null != (r = u.details) && r.live) {
|
|
if (this.checkLiveUpdate(n),
|
|
n.deltaUpdateFailed)
|
|
return;
|
|
var h;
|
|
u.details && (d = this.alignPlaylists(n, u.details, null == (h = this.levelLastLoaded) ? void 0 : h.details)),
|
|
n.alignedSliding || (Si(n, l),
|
|
n.alignedSliding || Ai(n, l),
|
|
d = n.fragmentStart)
|
|
}
|
|
u.details = n,
|
|
this.levelLastLoaded = u,
|
|
this.startFragRequested || this.setStartPosition(l, d),
|
|
this.hls.trigger(b.AUDIO_TRACK_UPDATED, {
|
|
details: n,
|
|
id: a,
|
|
groupId: t.groupId
|
|
}),
|
|
this.state !== ki.WAITING_TRACK || this.waitForCdnTuneIn(n) || (this.state = ki.IDLE),
|
|
this.tick()
|
|
} else
|
|
this.warn("Audio tracks reset while loading track " + a + ' "' + o.name + '" of "' + s + '"')
|
|
}
|
|
,
|
|
r._handleFragmentLoadProgress = function(e) {
|
|
var t, r = e.frag, i = e.part, n = e.payload, a = this.config, s = this.trackId, o = this.levels;
|
|
if (o) {
|
|
var l = o[s];
|
|
if (l) {
|
|
var u = l.details;
|
|
if (!u)
|
|
return this.warn("Audio track details undefined on fragment load progress"),
|
|
void this.removeUnbufferedFrags(r.start);
|
|
var d = a.defaultAudioCodec || l.audioCodec || "mp4a.40.2"
|
|
, h = this.transmuxer;
|
|
h || (h = this.transmuxer = new fa(this.hls,O,this._handleTransmuxComplete.bind(this),this._handleTransmuxerFlush.bind(this)));
|
|
var f = this.initPTS[r.cc]
|
|
, c = null == (t = r.initSegment) ? void 0 : t.data;
|
|
if (void 0 !== f) {
|
|
var g = i ? i.index : -1
|
|
, v = -1 !== g
|
|
, m = new or(r.level,r.sn,r.stats.chunkCount,n.byteLength,g,v);
|
|
h.push(n, c, d, "", r, i, u.totalduration, !1, m, f)
|
|
} else
|
|
this.log("Unknown video PTS for cc " + r.cc + ", waiting for video PTS before demuxing audio frag " + r.sn + " of [" + u.startSN + " ," + u.endSN + "],track " + s),
|
|
(this.waitingData = this.waitingData || {
|
|
frag: r,
|
|
part: i,
|
|
cache: new _i,
|
|
complete: !1
|
|
}).cache.push(new Uint8Array(n)),
|
|
this.state !== ki.STOPPED && (this.state = ki.WAITING_INIT_PTS)
|
|
} else
|
|
this.warn("Audio track is undefined on fragment load progress")
|
|
} else
|
|
this.warn("Audio tracks were reset while fragment load was in progress. Fragment " + r.sn + " of level " + r.level + " will not be buffered")
|
|
}
|
|
,
|
|
r._handleFragmentLoadComplete = function(t) {
|
|
this.waitingData ? this.waitingData.complete = !0 : e.prototype._handleFragmentLoadComplete.call(this, t)
|
|
}
|
|
,
|
|
r.onBufferReset = function() {
|
|
this.mediaBuffer = null
|
|
}
|
|
,
|
|
r.onBufferCreated = function(e, t) {
|
|
this.bufferFlushed = this.flushing = !1;
|
|
var r = t.tracks.audio;
|
|
r && (this.mediaBuffer = r.buffer || null)
|
|
}
|
|
,
|
|
r.onFragLoading = function(e, t) {
|
|
!this.audioOnly && t.frag.type === w && te(t.frag) && (this.mainFragLoading = t,
|
|
this.state === ki.IDLE && this.tick())
|
|
}
|
|
,
|
|
r.onFragBuffered = function(e, t) {
|
|
var r = t.frag
|
|
, i = t.part;
|
|
if (r.type === O)
|
|
if (this.fragContextChanged(r))
|
|
this.warn("Fragment " + r.sn + (i ? " p: " + i.index : "") + " of level " + r.level + " finished buffering, but was aborted. state: " + this.state + ", audioSwitch: " + (this.switchingTrack ? this.switchingTrack.name : "false"));
|
|
else {
|
|
if (te(r)) {
|
|
this.fragPrevious = r;
|
|
var n = this.switchingTrack;
|
|
n && (this.bufferedTrack = n,
|
|
this.switchingTrack = null,
|
|
this.hls.trigger(b.AUDIO_TRACK_SWITCHED, d({}, n)))
|
|
}
|
|
this.fragBufferedComplete(r, i),
|
|
this.media && this.tick()
|
|
}
|
|
else
|
|
this.audioOnly || r.type !== w || r.elementaryStreams.video || r.elementaryStreams.audiovideo || (this.audioOnly = !0,
|
|
this.mainFragLoading = null)
|
|
}
|
|
,
|
|
r.onError = function(t, r) {
|
|
var i;
|
|
if (r.fatal)
|
|
this.state = ki.ERROR;
|
|
else
|
|
switch (r.details) {
|
|
case k.FRAG_GAP:
|
|
case k.FRAG_PARSING_ERROR:
|
|
case k.FRAG_DECRYPT_ERROR:
|
|
case k.FRAG_LOAD_ERROR:
|
|
case k.FRAG_LOAD_TIMEOUT:
|
|
case k.KEY_LOAD_ERROR:
|
|
case k.KEY_LOAD_TIMEOUT:
|
|
this.onFragmentOrKeyLoadError(O, r);
|
|
break;
|
|
case k.AUDIO_TRACK_LOAD_ERROR:
|
|
case k.AUDIO_TRACK_LOAD_TIMEOUT:
|
|
case k.LEVEL_PARSING_ERROR:
|
|
r.levelRetry || this.state !== ki.WAITING_TRACK || (null == (i = r.context) ? void 0 : i.type) !== P || (this.state = ki.IDLE);
|
|
break;
|
|
case k.BUFFER_ADD_CODEC_ERROR:
|
|
case k.BUFFER_APPEND_ERROR:
|
|
if ("audio" !== r.parent)
|
|
return;
|
|
this.reduceLengthAndFlushBuffer(r) || this.resetLoadingState();
|
|
break;
|
|
case k.BUFFER_FULL_ERROR:
|
|
if ("audio" !== r.parent)
|
|
return;
|
|
this.reduceLengthAndFlushBuffer(r) && (this.bufferedTrack = null,
|
|
e.prototype.flushMainBuffer.call(this, 0, Number.POSITIVE_INFINITY, "audio"));
|
|
break;
|
|
case k.INTERNAL_EXCEPTION:
|
|
this.recoverWorkerError(r)
|
|
}
|
|
}
|
|
,
|
|
r.onBufferFlushing = function(e, t) {
|
|
t.type !== Z && (this.flushing = !0)
|
|
}
|
|
,
|
|
r.onBufferFlushed = function(e, t) {
|
|
var r = t.type;
|
|
if (r !== Z) {
|
|
this.flushing = !1,
|
|
this.bufferFlushed = !0,
|
|
this.state === ki.ENDED && (this.state = ki.IDLE);
|
|
var i = this.mediaBuffer || this.media;
|
|
i && (this.afterBufferFlushed(i, r, O),
|
|
this.tick())
|
|
}
|
|
}
|
|
,
|
|
r._handleTransmuxComplete = function(e) {
|
|
var t, r = "audio", i = this.hls, n = e.remuxResult, s = e.chunkMeta, o = this.getCurrentContext(s);
|
|
if (o) {
|
|
var l = o.frag
|
|
, u = o.part
|
|
, d = o.level
|
|
, h = d.details
|
|
, f = n.audio
|
|
, c = n.text
|
|
, g = n.id3
|
|
, v = n.initSegment;
|
|
if (!this.fragContextChanged(l) && h) {
|
|
if (this.state = ki.PARSING,
|
|
this.switchingTrack && f && this.completeAudioSwitch(this.switchingTrack),
|
|
null != v && v.tracks) {
|
|
var m = l.initSegment || l;
|
|
if (this.unhandledEncryptionError(v, l))
|
|
return;
|
|
this._bufferInitSegment(d, v.tracks, m, s),
|
|
i.trigger(b.FRAG_PARSING_INIT_SEGMENT, {
|
|
frag: m,
|
|
id: r,
|
|
tracks: v.tracks
|
|
})
|
|
}
|
|
if (f) {
|
|
var p = f.startPTS
|
|
, y = f.endPTS
|
|
, E = f.startDTS
|
|
, T = f.endDTS;
|
|
u && (u.elementaryStreams[$] = {
|
|
startPTS: p,
|
|
endPTS: y,
|
|
startDTS: E,
|
|
endDTS: T
|
|
}),
|
|
l.setElementaryStreamInfo($, p, y, E, T),
|
|
this.bufferFragmentData(f, l, u, s)
|
|
}
|
|
if (null != g && null != (t = g.samples) && t.length) {
|
|
var S = a({
|
|
id: r,
|
|
frag: l,
|
|
details: h
|
|
}, g);
|
|
i.trigger(b.FRAG_PARSING_METADATA, S)
|
|
}
|
|
if (c) {
|
|
var A = a({
|
|
id: r,
|
|
frag: l,
|
|
details: h
|
|
}, c);
|
|
i.trigger(b.FRAG_PARSING_USERDATA, A)
|
|
}
|
|
} else
|
|
this.fragmentTracker.removeFragment(l)
|
|
} else
|
|
this.resetWhenMissingContext(s)
|
|
}
|
|
,
|
|
r._bufferInitSegment = function(e, t, r, i) {
|
|
if (this.state === ki.PARSING && (t.video && delete t.video,
|
|
t.audiovideo && delete t.audiovideo,
|
|
t.audio)) {
|
|
var n = t.audio;
|
|
n.id = O;
|
|
var a = e.audioCodec;
|
|
this.log("Init audio buffer, container:" + n.container + ", codecs[level/parsed]=[" + a + "/" + n.codec + "]"),
|
|
a && 1 === a.split(",").length && (n.levelCodec = a),
|
|
this.hls.trigger(b.BUFFER_CODECS, t);
|
|
var s = n.initSegment;
|
|
if (null != s && s.byteLength) {
|
|
var o = {
|
|
type: "audio",
|
|
frag: r,
|
|
part: null,
|
|
chunkMeta: i,
|
|
parent: r.type,
|
|
data: s
|
|
};
|
|
this.hls.trigger(b.BUFFER_APPENDING, o)
|
|
}
|
|
this.tickImmediate()
|
|
}
|
|
}
|
|
,
|
|
r.loadFragment = function(t, r, i) {
|
|
var n, a = this.fragmentTracker.getState(t);
|
|
if (this.switchingTrack || a === Kt || a === Ht)
|
|
if (te(t))
|
|
if (null != (n = r.details) && n.live && !this.initPTS[t.cc]) {
|
|
this.log("Waiting for video PTS in continuity counter " + t.cc + " of live stream before loading audio fragment " + t.sn + " of level " + this.trackId),
|
|
this.state = ki.WAITING_INIT_PTS;
|
|
var s = this.mainDetails;
|
|
s && s.fragmentStart !== r.details.fragmentStart && Ai(r.details, s)
|
|
} else
|
|
e.prototype.loadFragment.call(this, t, r, i);
|
|
else
|
|
this._loadInitSegment(t, r);
|
|
else
|
|
this.clearTrackerIfNeeded(t)
|
|
}
|
|
,
|
|
r.flushAudioIfNeeded = function(t) {
|
|
if (this.media && this.bufferedTrack) {
|
|
var r = this.bufferedTrack;
|
|
ct({
|
|
name: r.name,
|
|
lang: r.lang,
|
|
assocLang: r.assocLang,
|
|
characteristics: r.characteristics,
|
|
audioCodec: r.audioCodec,
|
|
channels: r.channels
|
|
}, t, gt) || (mt(t.url, this.hls) ? (this.log("Switching audio track : flushing all audio"),
|
|
e.prototype.flushMainBuffer.call(this, 0, Number.POSITIVE_INFINITY, "audio"),
|
|
this.bufferedTrack = null) : this.bufferedTrack = t)
|
|
}
|
|
}
|
|
,
|
|
r.completeAudioSwitch = function(e) {
|
|
var t = this.hls;
|
|
this.flushAudioIfNeeded(e),
|
|
this.bufferedTrack = e,
|
|
this.switchingTrack = null,
|
|
t.trigger(b.AUDIO_TRACK_SWITCHED, d({}, e))
|
|
}
|
|
,
|
|
t
|
|
}(bi)
|
|
, ga = function(e) {
|
|
function t(t, r) {
|
|
var i;
|
|
return (i = e.call(this, r, t.logger) || this).hls = void 0,
|
|
i.canLoad = !1,
|
|
i.timer = -1,
|
|
i.hls = t,
|
|
i
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.destroy = function() {
|
|
this.clearTimer(),
|
|
this.hls = this.log = this.warn = null
|
|
}
|
|
,
|
|
r.clearTimer = function() {
|
|
-1 !== this.timer && (self.clearTimeout(this.timer),
|
|
this.timer = -1)
|
|
}
|
|
,
|
|
r.startLoad = function() {
|
|
this.canLoad = !0,
|
|
this.loadPlaylist()
|
|
}
|
|
,
|
|
r.stopLoad = function() {
|
|
this.canLoad = !1,
|
|
this.clearTimer()
|
|
}
|
|
,
|
|
r.switchParams = function(e, t, r) {
|
|
var i = null == t ? void 0 : t.renditionReports;
|
|
if (i) {
|
|
for (var n = -1, a = 0; a < i.length; a++) {
|
|
var s = i[a]
|
|
, o = void 0;
|
|
try {
|
|
o = new self.URL(s.URI,t.url).href
|
|
} catch (e) {
|
|
this.warn("Could not construct new URL for Rendition Report: " + e),
|
|
o = s.URI || ""
|
|
}
|
|
if (o === e) {
|
|
n = a;
|
|
break
|
|
}
|
|
o === e.substring(0, o.length) && (n = a)
|
|
}
|
|
if (-1 !== n) {
|
|
var l = i[n]
|
|
, u = parseInt(l["LAST-MSN"]) || t.lastPartSn
|
|
, d = parseInt(l["LAST-PART"]) || t.lastPartIndex;
|
|
if (this.hls.config.lowLatencyMode) {
|
|
var h = Math.min(t.age - t.partTarget, t.targetduration);
|
|
d >= 0 && h > t.partTarget && (d += 1)
|
|
}
|
|
var f = r && it(r);
|
|
return new nt(u,d >= 0 ? d : void 0,f)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.loadPlaylist = function(e) {
|
|
this.clearTimer()
|
|
}
|
|
,
|
|
r.loadingPlaylist = function(e, t) {
|
|
this.clearTimer()
|
|
}
|
|
,
|
|
r.shouldLoadPlaylist = function(e) {
|
|
return this.canLoad && !!e && !!e.url && (!e.details || e.details.live)
|
|
}
|
|
,
|
|
r.getUrlWithDirectives = function(e, t) {
|
|
if (t)
|
|
try {
|
|
return t.addDirectives(e)
|
|
} catch (e) {
|
|
this.warn("Could not construct new URL with HLS Delivery Directives: " + e)
|
|
}
|
|
return e
|
|
}
|
|
,
|
|
r.playlistLoaded = function(e, t, r) {
|
|
var i = t.details
|
|
, n = t.stats
|
|
, a = self.performance.now()
|
|
, s = n.loading.first ? Math.max(0, a - n.loading.first) : 0;
|
|
i.advancedDateTime = Date.now() - s;
|
|
var o = this.hls.config.timelineOffset;
|
|
if (o !== i.appliedTimelineOffset) {
|
|
var l = Math.max(o || 0, 0);
|
|
i.appliedTimelineOffset = l,
|
|
i.fragments.forEach((function(e) {
|
|
e.setStart(e.playlistOffset + l)
|
|
}
|
|
))
|
|
}
|
|
if (i.live || null != r && r.live) {
|
|
var u = "levelInfo"in t ? t.levelInfo : t.track;
|
|
if (i.reloaded(r),
|
|
r && i.fragments.length > 0) {
|
|
oi(r, i, this);
|
|
var d = i.playlistParsingError;
|
|
if (d) {
|
|
this.warn(d);
|
|
var h = this.hls;
|
|
if (!h.config.ignorePlaylistParsingErrors) {
|
|
var f, c = t.networkDetails;
|
|
return void h.trigger(b.ERROR, {
|
|
type: R.NETWORK_ERROR,
|
|
details: k.LEVEL_PARSING_ERROR,
|
|
fatal: !1,
|
|
url: i.url,
|
|
error: d,
|
|
reason: d.message,
|
|
level: t.level || void 0,
|
|
parent: null == (f = i.fragments[0]) ? void 0 : f.type,
|
|
networkDetails: c,
|
|
stats: n
|
|
})
|
|
}
|
|
i.playlistParsingError = null
|
|
}
|
|
}
|
|
-1 === i.requestScheduled && (i.requestScheduled = n.loading.start);
|
|
var g, v = this.hls.mainForwardBufferInfo, m = v ? v.end - v.len : 0, p = hi(i, 1e3 * (i.edge - m));
|
|
if (i.requestScheduled + p < a ? i.requestScheduled = a : i.requestScheduled += p,
|
|
this.log("live playlist " + e + " " + (i.advanced ? "REFRESHED " + i.lastPartSn + "-" + i.lastPartIndex : i.updated ? "UPDATED" : "MISSED")),
|
|
!this.canLoad || !i.live)
|
|
return;
|
|
var y = void 0
|
|
, E = void 0;
|
|
if (i.canBlockReload && i.endSN && i.advanced) {
|
|
var T = this.hls.config.lowLatencyMode
|
|
, S = i.lastPartSn
|
|
, A = i.endSN
|
|
, L = i.lastPartIndex
|
|
, I = S === A;
|
|
-1 !== L ? I ? (y = A + 1,
|
|
E = T ? 0 : L) : (y = S,
|
|
E = T ? L + 1 : i.maxPartIndex) : y = A + 1;
|
|
var D = i.age
|
|
, _ = D + i.ageHeader
|
|
, P = Math.min(_ - i.partTarget, 1.5 * i.targetduration);
|
|
if (P > 0) {
|
|
if (_ > 3 * i.targetduration)
|
|
this.log("Playlist last advanced " + D.toFixed(2) + "s ago. Omitting segment and part directives."),
|
|
y = void 0,
|
|
E = void 0;
|
|
else if (null != r && r.tuneInGoal && _ - i.partTarget > r.tuneInGoal)
|
|
this.warn("CDN Tune-in goal increased from: " + r.tuneInGoal + " to: " + P + " with playlist age: " + i.age),
|
|
P = 0;
|
|
else {
|
|
var C = Math.floor(P / i.targetduration);
|
|
y += C,
|
|
void 0 !== E && (E += Math.round(P % i.targetduration / i.partTarget)),
|
|
this.log("CDN Tune-in age: " + i.ageHeader + "s last advanced " + D.toFixed(2) + "s goal: " + P + " skip sn " + C + " to part " + E)
|
|
}
|
|
i.tuneInGoal = P
|
|
}
|
|
if (g = this.getDeliveryDirectives(i, t.deliveryDirectives, y, E),
|
|
T || !I)
|
|
return i.requestScheduled = a,
|
|
void this.loadingPlaylist(u, g)
|
|
} else
|
|
(i.canBlockReload || i.canSkipUntil) && (g = this.getDeliveryDirectives(i, t.deliveryDirectives, y, E));
|
|
g && void 0 !== y && i.canBlockReload && (i.requestScheduled = n.loading.first + Math.max(p - 2 * s, p / 2)),
|
|
this.scheduleLoading(u, g, i)
|
|
} else
|
|
this.clearTimer()
|
|
}
|
|
,
|
|
r.scheduleLoading = function(e, t, r) {
|
|
var i = this
|
|
, n = r || e.details;
|
|
if (n) {
|
|
var a = self.performance.now()
|
|
, s = n.requestScheduled;
|
|
if (a >= s)
|
|
this.loadingPlaylist(e, t);
|
|
else {
|
|
var o = s - a;
|
|
this.log("reload live playlist " + (e.name || e.bitrate + "bps") + " in " + Math.round(o) + " ms"),
|
|
this.clearTimer(),
|
|
this.timer = self.setTimeout((function() {
|
|
return i.loadingPlaylist(e, t)
|
|
}
|
|
), o)
|
|
}
|
|
} else
|
|
this.loadingPlaylist(e, t)
|
|
}
|
|
,
|
|
r.getDeliveryDirectives = function(e, t, r, i) {
|
|
var n = it(e);
|
|
return null != t && t.skip && e.deltaUpdateFailed && (r = t.msn,
|
|
i = t.part,
|
|
n = et),
|
|
new nt(r,i,n)
|
|
}
|
|
,
|
|
r.checkRetry = function(e) {
|
|
var t = this
|
|
, r = e.details
|
|
, i = Lt(e)
|
|
, n = e.errorAction
|
|
, a = n || {}
|
|
, s = a.action
|
|
, o = a.retryCount
|
|
, l = void 0 === o ? 0 : o
|
|
, u = a.retryConfig
|
|
, d = !!n && !!u && (s === xt || !n.resolved && s === wt);
|
|
if (d) {
|
|
var h;
|
|
if (l >= u.maxNumRetry)
|
|
return !1;
|
|
if (i && null != (h = e.context) && h.deliveryDirectives)
|
|
this.warn("Retrying playlist loading " + (l + 1) + "/" + u.maxNumRetry + ' after "' + r + '" without delivery-directives'),
|
|
this.loadPlaylist();
|
|
else {
|
|
var f = bt(u, l);
|
|
this.clearTimer(),
|
|
this.timer = self.setTimeout((function() {
|
|
return t.loadPlaylist()
|
|
}
|
|
), f),
|
|
this.warn("Retrying playlist loading " + (l + 1) + "/" + u.maxNumRetry + ' after "' + r + '" in ' + f + "ms")
|
|
}
|
|
e.levelRetry = !0,
|
|
n.resolved = !0
|
|
}
|
|
return d
|
|
}
|
|
,
|
|
t
|
|
}(N);
|
|
function va(e, t) {
|
|
if (e.length !== t.length)
|
|
return !1;
|
|
for (var r = 0; r < e.length; r++)
|
|
if (!ma(e[r].attrs, t[r].attrs))
|
|
return !1;
|
|
return !0
|
|
}
|
|
function ma(e, t, r) {
|
|
var i = e["STABLE-RENDITION-ID"];
|
|
return i && !r ? i === t["STABLE-RENDITION-ID"] : !(r || ["LANGUAGE", "NAME", "CHARACTERISTICS", "AUTOSELECT", "DEFAULT", "FORCED", "ASSOC-LANGUAGE"]).some((function(r) {
|
|
return e[r] !== t[r]
|
|
}
|
|
))
|
|
}
|
|
function pa(e, t) {
|
|
return t.label.toLowerCase() === e.name.toLowerCase() && (!t.language || t.language.toLowerCase() === (e.lang || "").toLowerCase())
|
|
}
|
|
var ya = function(e) {
|
|
function t(t) {
|
|
var r;
|
|
return (r = e.call(this, t, "audio-track-controller") || this).tracks = [],
|
|
r.groupIds = null,
|
|
r.tracksInGroup = [],
|
|
r.trackId = -1,
|
|
r.currentTrack = null,
|
|
r.selectDefaultTrack = !0,
|
|
r.registerListeners(),
|
|
r
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.registerListeners = function() {
|
|
var e = this.hls;
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.MANIFEST_PARSED, this.onManifestParsed, this),
|
|
e.on(b.LEVEL_LOADING, this.onLevelLoading, this),
|
|
e.on(b.LEVEL_SWITCHING, this.onLevelSwitching, this),
|
|
e.on(b.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this),
|
|
e.on(b.ERROR, this.onError, this)
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.MANIFEST_PARSED, this.onManifestParsed, this),
|
|
e.off(b.LEVEL_LOADING, this.onLevelLoading, this),
|
|
e.off(b.LEVEL_SWITCHING, this.onLevelSwitching, this),
|
|
e.off(b.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this),
|
|
e.off(b.ERROR, this.onError, this)
|
|
}
|
|
,
|
|
r.destroy = function() {
|
|
this.unregisterListeners(),
|
|
this.tracks.length = 0,
|
|
this.tracksInGroup.length = 0,
|
|
this.currentTrack = null,
|
|
e.prototype.destroy.call(this)
|
|
}
|
|
,
|
|
r.onManifestLoading = function() {
|
|
this.tracks = [],
|
|
this.tracksInGroup = [],
|
|
this.groupIds = null,
|
|
this.currentTrack = null,
|
|
this.trackId = -1,
|
|
this.selectDefaultTrack = !0
|
|
}
|
|
,
|
|
r.onManifestParsed = function(e, t) {
|
|
this.tracks = t.audioTracks || []
|
|
}
|
|
,
|
|
r.onAudioTrackLoaded = function(e, t) {
|
|
var r = t.id
|
|
, i = t.groupId
|
|
, n = t.details
|
|
, a = this.tracksInGroup[r];
|
|
if (a && a.groupId === i) {
|
|
var s = a.details;
|
|
a.details = t.details,
|
|
this.log("Audio track " + r + ' "' + a.name + '" lang:' + a.lang + " group:" + i + " loaded [" + n.startSN + "-" + n.endSN + "]"),
|
|
r === this.trackId && this.playlistLoaded(r, t, s)
|
|
} else
|
|
this.warn("Audio track with id:" + r + " and group:" + i + " not found in active group " + (null == a ? void 0 : a.groupId))
|
|
}
|
|
,
|
|
r.onLevelLoading = function(e, t) {
|
|
this.switchLevel(t.level)
|
|
}
|
|
,
|
|
r.onLevelSwitching = function(e, t) {
|
|
this.switchLevel(t.level)
|
|
}
|
|
,
|
|
r.switchLevel = function(e) {
|
|
var t = this.hls.levels[e];
|
|
if (t) {
|
|
var r = t.audioGroups || null
|
|
, i = this.groupIds
|
|
, n = this.currentTrack;
|
|
if (!r || (null == i ? void 0 : i.length) !== (null == r ? void 0 : r.length) || null != r && r.some((function(e) {
|
|
return -1 === (null == i ? void 0 : i.indexOf(e))
|
|
}
|
|
))) {
|
|
this.groupIds = r,
|
|
this.trackId = -1,
|
|
this.currentTrack = null;
|
|
var a = this.tracks.filter((function(e) {
|
|
return !r || -1 !== r.indexOf(e.groupId)
|
|
}
|
|
));
|
|
if (a.length)
|
|
this.selectDefaultTrack && !a.some((function(e) {
|
|
return e.default
|
|
}
|
|
)) && (this.selectDefaultTrack = !1),
|
|
a.forEach((function(e, t) {
|
|
e.id = t
|
|
}
|
|
));
|
|
else if (!n && !this.tracksInGroup.length)
|
|
return;
|
|
this.tracksInGroup = a;
|
|
var s = this.hls.config.audioPreference;
|
|
if (!n && s) {
|
|
var o = ft(s, a, gt);
|
|
if (o > -1)
|
|
n = a[o];
|
|
else {
|
|
var l = ft(s, this.tracks);
|
|
n = this.tracks[l]
|
|
}
|
|
}
|
|
var u = this.findTrackId(n);
|
|
-1 === u && n && (u = this.findTrackId(null));
|
|
var d = {
|
|
audioTracks: a
|
|
};
|
|
this.log("Updating audio tracks, " + a.length + " track(s) found in group(s): " + (null == r ? void 0 : r.join(","))),
|
|
this.hls.trigger(b.AUDIO_TRACKS_UPDATED, d);
|
|
var h = this.trackId;
|
|
if (-1 !== u && -1 === h)
|
|
this.setAudioTrack(u);
|
|
else if (a.length && -1 === h) {
|
|
var f, c = new Error("No audio track selected for current audio group-ID(s): " + (null == (f = this.groupIds) ? void 0 : f.join(",")) + " track count: " + a.length);
|
|
this.warn(c.message),
|
|
this.hls.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.AUDIO_TRACK_LOAD_ERROR,
|
|
fatal: !0,
|
|
error: c
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.onError = function(e, t) {
|
|
!t.fatal && t.context && (t.context.type !== P || t.context.id !== this.trackId || this.groupIds && -1 === this.groupIds.indexOf(t.context.groupId) || this.checkRetry(t))
|
|
}
|
|
,
|
|
r.setAudioOption = function(e) {
|
|
var t = this.hls;
|
|
if (t.config.audioPreference = e,
|
|
e) {
|
|
var r = this.allAudioTracks;
|
|
if (this.selectDefaultTrack = !1,
|
|
r.length) {
|
|
var i = this.currentTrack;
|
|
if (i && ct(e, i, gt))
|
|
return i;
|
|
var n = ft(e, this.tracksInGroup, gt);
|
|
if (n > -1) {
|
|
var a = this.tracksInGroup[n];
|
|
return this.setAudioTrack(n),
|
|
a
|
|
}
|
|
if (i) {
|
|
var s = t.loadLevel;
|
|
-1 === s && (s = t.firstAutoLevel);
|
|
var o = function(e, t, r, i, n) {
|
|
var a = t[i]
|
|
, s = t.reduce((function(e, t, r) {
|
|
var i = t.uri;
|
|
return (e[i] || (e[i] = [])).push(r),
|
|
e
|
|
}
|
|
), {})[a.uri];
|
|
s.length > 1 && (i = Math.max.apply(Math, s));
|
|
var o = a.videoRange
|
|
, l = a.frameRate
|
|
, u = a.codecSet.substring(0, 4)
|
|
, d = vt(t, i, (function(t) {
|
|
if (t.videoRange !== o || t.frameRate !== l || t.codecSet.substring(0, 4) !== u)
|
|
return !1;
|
|
var i = t.audioGroups
|
|
, a = r.filter((function(e) {
|
|
return !i || -1 !== i.indexOf(e.groupId)
|
|
}
|
|
));
|
|
return ft(e, a, n) > -1
|
|
}
|
|
));
|
|
return d > -1 ? d : vt(t, i, (function(t) {
|
|
var i = t.audioGroups
|
|
, a = r.filter((function(e) {
|
|
return !i || -1 !== i.indexOf(e.groupId)
|
|
}
|
|
));
|
|
return ft(e, a, n) > -1
|
|
}
|
|
))
|
|
}(e, t.levels, r, s, gt);
|
|
if (-1 === o)
|
|
return null;
|
|
t.nextLoadLevel = o
|
|
}
|
|
if (e.channels || e.audioCodec) {
|
|
var l = ft(e, r);
|
|
if (l > -1)
|
|
return r[l]
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
,
|
|
r.setAudioTrack = function(e) {
|
|
var t = this.tracksInGroup;
|
|
if (e < 0 || e >= t.length)
|
|
this.warn("Invalid audio track id: " + e);
|
|
else {
|
|
this.selectDefaultTrack = !1;
|
|
var r = this.currentTrack
|
|
, i = t[e]
|
|
, n = i.details && !i.details.live;
|
|
if (!(e === this.trackId && i === r && n || (this.log("Switching to audio-track " + e + ' "' + i.name + '" lang:' + i.lang + " group:" + i.groupId + " channels:" + i.channels),
|
|
this.trackId = e,
|
|
this.currentTrack = i,
|
|
this.hls.trigger(b.AUDIO_TRACK_SWITCHING, d({}, i)),
|
|
n))) {
|
|
var a = this.switchParams(i.url, null == r ? void 0 : r.details, i.details);
|
|
this.loadPlaylist(a)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.findTrackId = function(e) {
|
|
for (var t = this.tracksInGroup, r = 0; r < t.length; r++) {
|
|
var i = t[r];
|
|
if ((!this.selectDefaultTrack || i.default) && (!e || ct(e, i, gt)))
|
|
return r
|
|
}
|
|
if (e) {
|
|
for (var n = e.name, a = e.lang, s = e.assocLang, o = e.characteristics, l = e.audioCodec, u = e.channels, d = 0; d < t.length; d++)
|
|
if (ct({
|
|
name: n,
|
|
lang: a,
|
|
assocLang: s,
|
|
characteristics: o,
|
|
audioCodec: l,
|
|
channels: u
|
|
}, t[d], gt))
|
|
return d;
|
|
for (var h = 0; h < t.length; h++) {
|
|
var f = t[h];
|
|
if (ma(e.attrs, f.attrs, ["LANGUAGE", "ASSOC-LANGUAGE", "CHARACTERISTICS"]))
|
|
return h
|
|
}
|
|
for (var c = 0; c < t.length; c++) {
|
|
var g = t[c];
|
|
if (ma(e.attrs, g.attrs, ["LANGUAGE"]))
|
|
return c
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
,
|
|
r.loadPlaylist = function(t) {
|
|
e.prototype.loadPlaylist.call(this);
|
|
var r = this.currentTrack;
|
|
this.shouldLoadPlaylist(r) && mt(r.url, this.hls) && this.scheduleLoading(r, t)
|
|
}
|
|
,
|
|
r.loadingPlaylist = function(t, r) {
|
|
e.prototype.loadingPlaylist.call(this, t, r);
|
|
var i = t.id
|
|
, n = t.groupId
|
|
, a = this.getUrlWithDirectives(t.url, r)
|
|
, s = t.details
|
|
, o = null == s ? void 0 : s.age;
|
|
this.log("Loading audio-track " + i + ' "' + t.name + '" lang:' + t.lang + " group:" + n + (void 0 !== (null == r ? void 0 : r.msn) ? " at sn " + r.msn + " part " + r.part : "") + (o && s.live ? " age " + o.toFixed(1) + (s.type && " " + s.type || "") : "") + " " + a),
|
|
this.hls.trigger(b.AUDIO_TRACK_LOADING, {
|
|
url: a,
|
|
id: i,
|
|
groupId: n,
|
|
deliveryDirectives: r || null,
|
|
track: t
|
|
})
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "allAudioTracks",
|
|
get: function() {
|
|
return this.tracks
|
|
}
|
|
}, {
|
|
key: "audioTracks",
|
|
get: function() {
|
|
return this.tracksInGroup
|
|
}
|
|
}, {
|
|
key: "audioTrack",
|
|
get: function() {
|
|
return this.trackId
|
|
},
|
|
set: function(e) {
|
|
this.selectDefaultTrack = !1,
|
|
this.setAudioTrack(e)
|
|
}
|
|
}])
|
|
}(ga)
|
|
, Ea = function() {
|
|
function e(e) {
|
|
this.tracks = void 0,
|
|
this.queues = {
|
|
video: [],
|
|
audio: [],
|
|
audiovideo: []
|
|
},
|
|
this.tracks = e
|
|
}
|
|
var t = e.prototype;
|
|
return t.destroy = function() {
|
|
this.tracks = this.queues = null
|
|
}
|
|
,
|
|
t.append = function(e, t, r) {
|
|
if (null !== this.queues && null !== this.tracks) {
|
|
var i = this.queues[t];
|
|
i.push(e),
|
|
1 !== i.length || r || this.executeNext(t)
|
|
}
|
|
}
|
|
,
|
|
t.appendBlocker = function(e) {
|
|
var t = this;
|
|
return new Promise((function(r) {
|
|
var i = {
|
|
label: "async-blocker",
|
|
execute: r,
|
|
onStart: function() {},
|
|
onComplete: function() {},
|
|
onError: function() {}
|
|
};
|
|
t.append(i, e)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t.prependBlocker = function(e) {
|
|
var t = this;
|
|
return new Promise((function(r) {
|
|
if (t.queues) {
|
|
var i = {
|
|
label: "async-blocker-prepend",
|
|
execute: r,
|
|
onStart: function() {},
|
|
onComplete: function() {},
|
|
onError: function() {}
|
|
};
|
|
t.queues[e].unshift(i)
|
|
}
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t.removeBlockers = function() {
|
|
null !== this.queues && [this.queues.video, this.queues.audio, this.queues.audiovideo].forEach((function(e) {
|
|
var t, r = null == (t = e[0]) ? void 0 : t.label;
|
|
"async-blocker" !== r && "async-blocker-prepend" !== r || (e[0].execute(),
|
|
e.splice(0, 1))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t.unblockAudio = function(e) {
|
|
null !== this.queues && this.queues.audio[0] === e && this.shiftAndExecuteNext("audio")
|
|
}
|
|
,
|
|
t.executeNext = function(e) {
|
|
if (null !== this.queues && null !== this.tracks) {
|
|
var t = this.queues[e];
|
|
if (t.length) {
|
|
var r = t[0];
|
|
try {
|
|
r.execute()
|
|
} catch (t) {
|
|
var i;
|
|
if (r.onError(t),
|
|
null === this.queues || null === this.tracks)
|
|
return;
|
|
var n = null == (i = this.tracks[e]) ? void 0 : i.buffer;
|
|
null != n && n.updating || this.shiftAndExecuteNext(e)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
t.shiftAndExecuteNext = function(e) {
|
|
null !== this.queues && (this.queues[e].shift(),
|
|
this.executeNext(e))
|
|
}
|
|
,
|
|
t.current = function(e) {
|
|
var t;
|
|
return (null == (t = this.queues) ? void 0 : t[e][0]) || null
|
|
}
|
|
,
|
|
t.toString = function() {
|
|
var e = this.queues
|
|
, t = this.tracks;
|
|
return null === e || null === t ? "<destroyed>" : "\n" + this.list("video") + "\n" + this.list("audio") + "\n" + this.list("audiovideo") + "}"
|
|
}
|
|
,
|
|
t.list = function(e) {
|
|
var t, r;
|
|
return null != (t = this.queues) && t[e] || null != (r = this.tracks) && r[e] ? e + ": (" + this.listSbInfo(e) + ") " + this.listOps(e) : ""
|
|
}
|
|
,
|
|
t.listSbInfo = function(e) {
|
|
var t, r = null == (t = this.tracks) ? void 0 : t[e], i = null == r ? void 0 : r.buffer;
|
|
return i ? "SourceBuffer" + (i.updating ? " updating" : "") + (r.ended ? " ended" : "") + (r.ending ? " ending" : "") : "none"
|
|
}
|
|
,
|
|
t.listOps = function(e) {
|
|
var t;
|
|
return (null == (t = this.queues) ? void 0 : t[e].map((function(e) {
|
|
return e.label
|
|
}
|
|
)).join(", ")) || ""
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, Ta = /(avc[1234]|hvc1|hev1|dvh[1e]|vp09|av01)(?:\.[^.,]+)+/
|
|
, Sa = "HlsJsTrackRemovedError"
|
|
, Aa = function(e) {
|
|
function t(t) {
|
|
var r;
|
|
return (r = e.call(this, t) || this).name = Sa,
|
|
r
|
|
}
|
|
return o(t, e),
|
|
t
|
|
}(c(Error))
|
|
, La = function(e) {
|
|
function t(t, r) {
|
|
var i, n;
|
|
return (i = e.call(this, "buffer-controller", t.logger) || this).hls = void 0,
|
|
i.fragmentTracker = void 0,
|
|
i.details = null,
|
|
i._objectUrl = null,
|
|
i.operationQueue = null,
|
|
i.bufferCodecEventsTotal = 0,
|
|
i.media = null,
|
|
i.mediaSource = null,
|
|
i.lastMpegAudioChunk = null,
|
|
i.blockedAudioAppend = null,
|
|
i.lastVideoAppendEnd = 0,
|
|
i.appendSource = void 0,
|
|
i.transferData = void 0,
|
|
i.overrides = void 0,
|
|
i.appendErrors = {
|
|
audio: 0,
|
|
video: 0,
|
|
audiovideo: 0
|
|
},
|
|
i.tracks = {},
|
|
i.sourceBuffers = [[null, null], [null, null]],
|
|
i._onEndStreaming = function(e) {
|
|
var t;
|
|
i.hls && "open" === (null == (t = i.mediaSource) ? void 0 : t.readyState) && i.hls.pauseBuffering()
|
|
}
|
|
,
|
|
i._onStartStreaming = function(e) {
|
|
i.hls && i.hls.resumeBuffering()
|
|
}
|
|
,
|
|
i._onMediaSourceOpen = function(e) {
|
|
var t = i
|
|
, r = t.media
|
|
, n = t.mediaSource;
|
|
e && i.log("Media source opened"),
|
|
r && n && (n.removeEventListener("sourceopen", i._onMediaSourceOpen),
|
|
r.removeEventListener("emptied", i._onMediaEmptied),
|
|
i.updateDuration(),
|
|
i.hls.trigger(b.MEDIA_ATTACHED, {
|
|
media: r,
|
|
mediaSource: n
|
|
}),
|
|
null !== i.mediaSource && i.checkPendingTracks())
|
|
}
|
|
,
|
|
i._onMediaSourceClose = function() {
|
|
i.log("Media source closed")
|
|
}
|
|
,
|
|
i._onMediaSourceEnded = function() {
|
|
i.log("Media source ended")
|
|
}
|
|
,
|
|
i._onMediaEmptied = function() {
|
|
var e = i
|
|
, t = e.mediaSrc
|
|
, r = e._objectUrl;
|
|
t !== r && i.error("Media element src was set while attaching MediaSource (" + r + " > " + t + ")")
|
|
}
|
|
,
|
|
i.hls = t,
|
|
i.fragmentTracker = r,
|
|
i.appendSource = (n = W(t.config.preferManagedMediaSource),
|
|
"undefined" != typeof self && n === self.ManagedMediaSource),
|
|
i.initTracks(),
|
|
i.registerListeners(),
|
|
i
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.hasSourceTypes = function() {
|
|
return Object.keys(this.tracks).length > 0
|
|
}
|
|
,
|
|
r.destroy = function() {
|
|
this.unregisterListeners(),
|
|
this.details = null,
|
|
this.lastMpegAudioChunk = this.blockedAudioAppend = null,
|
|
this.transferData = this.overrides = void 0,
|
|
this.operationQueue && (this.operationQueue.destroy(),
|
|
this.operationQueue = null),
|
|
this.hls = this.fragmentTracker = null,
|
|
this._onMediaSourceOpen = this._onMediaSourceClose = null,
|
|
this._onMediaSourceEnded = null,
|
|
this._onStartStreaming = this._onEndStreaming = null
|
|
}
|
|
,
|
|
r.registerListeners = function() {
|
|
var e = this.hls;
|
|
e.on(b.MEDIA_ATTACHING, this.onMediaAttaching, this),
|
|
e.on(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.MANIFEST_PARSED, this.onManifestParsed, this),
|
|
e.on(b.BUFFER_RESET, this.onBufferReset, this),
|
|
e.on(b.BUFFER_APPENDING, this.onBufferAppending, this),
|
|
e.on(b.BUFFER_CODECS, this.onBufferCodecs, this),
|
|
e.on(b.BUFFER_EOS, this.onBufferEos, this),
|
|
e.on(b.BUFFER_FLUSHING, this.onBufferFlushing, this),
|
|
e.on(b.LEVEL_UPDATED, this.onLevelUpdated, this),
|
|
e.on(b.FRAG_PARSED, this.onFragParsed, this),
|
|
e.on(b.FRAG_CHANGED, this.onFragChanged, this),
|
|
e.on(b.ERROR, this.onError, this)
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e.off(b.MEDIA_ATTACHING, this.onMediaAttaching, this),
|
|
e.off(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.MANIFEST_PARSED, this.onManifestParsed, this),
|
|
e.off(b.BUFFER_RESET, this.onBufferReset, this),
|
|
e.off(b.BUFFER_APPENDING, this.onBufferAppending, this),
|
|
e.off(b.BUFFER_CODECS, this.onBufferCodecs, this),
|
|
e.off(b.BUFFER_EOS, this.onBufferEos, this),
|
|
e.off(b.BUFFER_FLUSHING, this.onBufferFlushing, this),
|
|
e.off(b.LEVEL_UPDATED, this.onLevelUpdated, this),
|
|
e.off(b.FRAG_PARSED, this.onFragParsed, this),
|
|
e.off(b.FRAG_CHANGED, this.onFragChanged, this),
|
|
e.off(b.ERROR, this.onError, this)
|
|
}
|
|
,
|
|
r.transferMedia = function() {
|
|
var e = this
|
|
, t = this.media
|
|
, r = this.mediaSource;
|
|
if (!t)
|
|
return null;
|
|
var i = {};
|
|
if (this.operationQueue) {
|
|
var n = this.isUpdating();
|
|
n || this.operationQueue.removeBlockers();
|
|
var s = this.isQueued();
|
|
(n || s) && this.warn("Transfering MediaSource with" + (s ? " operations in queue" : "") + (n ? " updating SourceBuffer(s)" : "") + " " + this.operationQueue),
|
|
this.operationQueue.destroy()
|
|
}
|
|
var o = this.transferData;
|
|
return !this.sourceBufferCount && o && o.mediaSource === r ? a(i, o.tracks) : this.sourceBuffers.forEach((function(t) {
|
|
var r = t[0];
|
|
r && (i[r] = a({}, e.tracks[r]),
|
|
e.removeBuffer(r)),
|
|
t[0] = t[1] = null
|
|
}
|
|
)),
|
|
{
|
|
media: t,
|
|
mediaSource: r,
|
|
tracks: i
|
|
}
|
|
}
|
|
,
|
|
r.initTracks = function() {
|
|
this.sourceBuffers = [[null, null], [null, null]],
|
|
this.tracks = {},
|
|
this.resetQueue(),
|
|
this.resetAppendErrors(),
|
|
this.lastMpegAudioChunk = this.blockedAudioAppend = null,
|
|
this.lastVideoAppendEnd = 0
|
|
}
|
|
,
|
|
r.onManifestLoading = function() {
|
|
this.bufferCodecEventsTotal = 0,
|
|
this.details = null
|
|
}
|
|
,
|
|
r.onManifestParsed = function(e, t) {
|
|
var r, i = 2;
|
|
(t.audio && !t.video || !t.altAudio) && (i = 1),
|
|
this.bufferCodecEventsTotal = i,
|
|
this.log(i + " bufferCodec event(s) expected."),
|
|
null != (r = this.transferData) && r.mediaSource && this.sourceBufferCount && i && this.bufferCreated()
|
|
}
|
|
,
|
|
r.onMediaAttaching = function(e, t) {
|
|
var r = this.media = t.media;
|
|
this.transferData = this.overrides = void 0;
|
|
var i = W(this.appendSource);
|
|
if (i) {
|
|
var n = !!t.mediaSource;
|
|
(n || t.overrides) && (this.transferData = t,
|
|
this.overrides = t.overrides);
|
|
var a = this.mediaSource = t.mediaSource || new i;
|
|
if (this.assignMediaSource(a),
|
|
n)
|
|
this._objectUrl = r.src,
|
|
this.attachTransferred();
|
|
else {
|
|
var s = this._objectUrl = self.URL.createObjectURL(a);
|
|
if (this.appendSource)
|
|
try {
|
|
r.removeAttribute("src");
|
|
var o = self.ManagedMediaSource;
|
|
r.disableRemotePlayback = r.disableRemotePlayback || o && a instanceof o,
|
|
Ia(r),
|
|
function(e, t) {
|
|
var r = self.document.createElement("source");
|
|
r.type = "video/mp4",
|
|
r.src = t,
|
|
e.appendChild(r)
|
|
}(r, s),
|
|
r.load()
|
|
} catch (e) {
|
|
r.src = s
|
|
}
|
|
else
|
|
r.src = s
|
|
}
|
|
r.addEventListener("emptied", this._onMediaEmptied)
|
|
}
|
|
}
|
|
,
|
|
r.assignMediaSource = function(e) {
|
|
var t, r;
|
|
this.log(((null == (t = this.transferData) ? void 0 : t.mediaSource) === e ? "transferred" : "created") + " media source: " + (null == (r = e.constructor) ? void 0 : r.name)),
|
|
e.addEventListener("sourceopen", this._onMediaSourceOpen),
|
|
e.addEventListener("sourceended", this._onMediaSourceEnded),
|
|
e.addEventListener("sourceclose", this._onMediaSourceClose),
|
|
this.appendSource && (e.addEventListener("startstreaming", this._onStartStreaming),
|
|
e.addEventListener("endstreaming", this._onEndStreaming))
|
|
}
|
|
,
|
|
r.attachTransferred = function() {
|
|
var e = this
|
|
, t = this.media
|
|
, r = this.transferData;
|
|
if (r && t) {
|
|
var i = this.tracks
|
|
, n = r.tracks
|
|
, a = n ? Object.keys(n) : null
|
|
, s = a ? a.length : 0
|
|
, o = function() {
|
|
Promise.resolve().then((function() {
|
|
e.media && e.mediaSourceOpenOrEnded && e._onMediaSourceOpen()
|
|
}
|
|
))
|
|
};
|
|
if (n && a && s) {
|
|
if (!this.tracksReady)
|
|
return this.hls.config.startFragPrefetch = !0,
|
|
void this.log("attachTransferred: waiting for SourceBuffer track info");
|
|
if (this.log("attachTransferred: (bufferCodecEventsTotal " + this.bufferCodecEventsTotal + ")\nrequired tracks: " + lt(i, (function(e, t) {
|
|
return "initSegment" === e ? void 0 : t
|
|
}
|
|
)) + ";\ntransfer tracks: " + lt(n, (function(e, t) {
|
|
return "initSegment" === e ? void 0 : t
|
|
}
|
|
)) + "}"),
|
|
!j(n, i)) {
|
|
r.mediaSource = null,
|
|
r.tracks = void 0;
|
|
var l = t.currentTime
|
|
, u = this.details
|
|
, d = Math.max(l, (null == u ? void 0 : u.fragments[0].start) || 0);
|
|
return d - l > 1 ? void this.log("attachTransferred: waiting for playback to reach new tracks start time " + l + " -> " + d) : (this.warn('attachTransferred: resetting MediaSource for incompatible tracks ("' + Object.keys(n) + '"->"' + Object.keys(i) + '") start time: ' + d + " currentTime: " + l),
|
|
this.onMediaDetaching(b.MEDIA_DETACHING, {}),
|
|
this.onMediaAttaching(b.MEDIA_ATTACHING, r),
|
|
void (t.currentTime = d))
|
|
}
|
|
this.transferData = void 0,
|
|
a.forEach((function(t) {
|
|
var r = t
|
|
, i = n[r];
|
|
if (i) {
|
|
var a = i.buffer;
|
|
if (a) {
|
|
var s = e.fragmentTracker
|
|
, o = i.id;
|
|
if (s.hasFragments(o) || s.hasParts(o)) {
|
|
var l = ur.getBuffered(a);
|
|
s.detectEvictedFragments(r, l, o, null, !0)
|
|
}
|
|
var u = Ra(r)
|
|
, d = [r, a];
|
|
e.sourceBuffers[u] = d,
|
|
a.updating && e.operationQueue && e.operationQueue.prependBlocker(r),
|
|
e.trackSourceBuffer(r, i)
|
|
}
|
|
}
|
|
}
|
|
)),
|
|
o(),
|
|
this.bufferCreated()
|
|
} else
|
|
this.log("attachTransferred: MediaSource w/o SourceBuffers"),
|
|
o()
|
|
}
|
|
}
|
|
,
|
|
r.onMediaDetaching = function(e, t) {
|
|
var r = this
|
|
, i = !!t.transferMedia;
|
|
this.transferData = this.overrides = void 0;
|
|
var n = this.media
|
|
, a = this.mediaSource
|
|
, s = this._objectUrl;
|
|
if (a) {
|
|
if (this.log("media source " + (i ? "transferring" : "detaching")),
|
|
i)
|
|
this.sourceBuffers.forEach((function(e) {
|
|
var t = e[0];
|
|
t && r.removeBuffer(t)
|
|
}
|
|
)),
|
|
this.resetQueue();
|
|
else {
|
|
if (this.mediaSourceOpenOrEnded) {
|
|
var o = "open" === a.readyState;
|
|
try {
|
|
for (var l = a.sourceBuffers, u = l.length; u--; )
|
|
o && l[u].abort(),
|
|
a.removeSourceBuffer(l[u]);
|
|
o && a.endOfStream()
|
|
} catch (e) {
|
|
this.warn("onMediaDetaching: " + e.message + " while calling endOfStream")
|
|
}
|
|
}
|
|
this.sourceBufferCount && this.onBufferReset()
|
|
}
|
|
a.removeEventListener("sourceopen", this._onMediaSourceOpen),
|
|
a.removeEventListener("sourceended", this._onMediaSourceEnded),
|
|
a.removeEventListener("sourceclose", this._onMediaSourceClose),
|
|
this.appendSource && (a.removeEventListener("startstreaming", this._onStartStreaming),
|
|
a.removeEventListener("endstreaming", this._onEndStreaming)),
|
|
this.mediaSource = null,
|
|
this._objectUrl = null
|
|
}
|
|
n && (n.removeEventListener("emptied", this._onMediaEmptied),
|
|
i || (s && self.URL.revokeObjectURL(s),
|
|
this.mediaSrc === s ? (n.removeAttribute("src"),
|
|
this.appendSource && Ia(n),
|
|
n.load()) : this.warn("media|source.src was changed by a third party - skip cleanup")),
|
|
this.media = null),
|
|
this.hls.trigger(b.MEDIA_DETACHED, t)
|
|
}
|
|
,
|
|
r.onBufferReset = function() {
|
|
var e = this;
|
|
this.sourceBuffers.forEach((function(t) {
|
|
var r = t[0];
|
|
r && e.resetBuffer(r)
|
|
}
|
|
)),
|
|
this.initTracks()
|
|
}
|
|
,
|
|
r.resetBuffer = function(e) {
|
|
var t, r = null == (t = this.tracks[e]) ? void 0 : t.buffer;
|
|
if (this.removeBuffer(e),
|
|
r)
|
|
try {
|
|
var i;
|
|
null != (i = this.mediaSource) && i.sourceBuffers.length && this.mediaSource.removeSourceBuffer(r)
|
|
} catch (t) {
|
|
this.warn("onBufferReset " + e, t)
|
|
}
|
|
delete this.tracks[e]
|
|
}
|
|
,
|
|
r.removeBuffer = function(e) {
|
|
this.removeBufferListeners(e),
|
|
this.sourceBuffers[Ra(e)] = [null, null];
|
|
var t = this.tracks[e];
|
|
t && (t.buffer = void 0)
|
|
}
|
|
,
|
|
r.resetQueue = function() {
|
|
this.operationQueue && this.operationQueue.destroy(),
|
|
this.operationQueue = new Ea(this.tracks)
|
|
}
|
|
,
|
|
r.onBufferCodecs = function(e, t) {
|
|
var r, i = this, n = this.tracks, a = Object.keys(t);
|
|
this.log('BUFFER_CODECS: "' + a + '" (current SB count ' + this.sourceBufferCount + ")");
|
|
var s = "audiovideo"in t && (n.audio || n.video) || n.audiovideo && ("audio"in t || "video"in t)
|
|
, o = !s && this.sourceBufferCount && this.media && a.some((function(e) {
|
|
return !n[e]
|
|
}
|
|
));
|
|
s || o ? this.warn('Unsupported transition between "' + Object.keys(n) + '" and "' + a + '" SourceBuffers') : (a.forEach((function(e) {
|
|
var r, a, s = t[e], o = s.id, l = s.codec, u = s.levelCodec, d = s.container, h = s.metadata, f = s.supplemental, c = n[e], g = null == (r = i.transferData) || null == (r = r.tracks) ? void 0 : r[e], v = null != g && g.buffer ? g : c, m = (null == v ? void 0 : v.pendingCodec) || (null == v ? void 0 : v.codec), p = null == v ? void 0 : v.levelCodec;
|
|
c || (c = n[e] = {
|
|
buffer: void 0,
|
|
listeners: [],
|
|
codec: l,
|
|
supplemental: f,
|
|
container: d,
|
|
levelCodec: u,
|
|
metadata: h,
|
|
id: o
|
|
});
|
|
var y = Ke(m, p)
|
|
, E = null == y ? void 0 : y.replace(Ta, "$1")
|
|
, T = Ke(l, u)
|
|
, S = null == (a = T) ? void 0 : a.replace(Ta, "$1");
|
|
T && y && E !== S && ("audio" === e.slice(0, 5) && (T = Ge(T, i.appendSource)),
|
|
i.log("switching codec " + m + " to " + T),
|
|
T !== (c.pendingCodec || c.codec) && (c.pendingCodec = T),
|
|
c.container = d,
|
|
i.appendChangeType(e, d, T))
|
|
}
|
|
)),
|
|
(this.tracksReady || this.sourceBufferCount) && (t.tracks = this.sourceBufferTracks),
|
|
this.sourceBufferCount || (this.bufferCodecEventsTotal > 1 && !this.tracks.video && !t.video && "main" === (null == (r = t.audio) ? void 0 : r.id) && (this.log("Main audio-only"),
|
|
this.bufferCodecEventsTotal = 1),
|
|
this.mediaSourceOpenOrEnded && this.checkPendingTracks()))
|
|
}
|
|
,
|
|
r.appendChangeType = function(e, t, r) {
|
|
var i = this
|
|
, n = t + ";codecs=" + r
|
|
, a = {
|
|
label: "change-type=" + n,
|
|
execute: function() {
|
|
var a = i.tracks[e];
|
|
if (a) {
|
|
var s = a.buffer;
|
|
null != s && s.changeType && (i.log("changing " + e + " sourceBuffer type to " + n),
|
|
s.changeType(n),
|
|
a.codec = r,
|
|
a.container = t)
|
|
}
|
|
i.shiftAndExecuteNext(e)
|
|
},
|
|
onStart: function() {},
|
|
onComplete: function() {},
|
|
onError: function(t) {
|
|
i.warn("Failed to change " + e + " SourceBuffer type", t)
|
|
}
|
|
};
|
|
this.append(a, e, this.isPending(this.tracks[e]))
|
|
}
|
|
,
|
|
r.blockAudio = function(e) {
|
|
var t, r = this, i = e.start, n = i + .05 * e.duration;
|
|
if (!0 !== (null == (t = this.fragmentTracker.getAppendedFrag(i, w)) ? void 0 : t.gap)) {
|
|
var a = {
|
|
label: "block-audio",
|
|
execute: function() {
|
|
var e, t = r.tracks.video;
|
|
(r.lastVideoAppendEnd > n || null != t && t.buffer && ur.isBuffered(t.buffer, n) || !0 === (null == (e = r.fragmentTracker.getAppendedFrag(n, w)) ? void 0 : e.gap)) && (r.blockedAudioAppend = null,
|
|
r.shiftAndExecuteNext("audio"))
|
|
},
|
|
onStart: function() {},
|
|
onComplete: function() {},
|
|
onError: function(e) {
|
|
r.warn("Error executing block-audio operation", e)
|
|
}
|
|
};
|
|
this.blockedAudioAppend = {
|
|
op: a,
|
|
frag: e
|
|
},
|
|
this.append(a, "audio", !0)
|
|
}
|
|
}
|
|
,
|
|
r.unblockAudio = function() {
|
|
var e = this.blockedAudioAppend
|
|
, t = this.operationQueue;
|
|
e && t && (this.blockedAudioAppend = null,
|
|
t.unblockAudio(e.op))
|
|
}
|
|
,
|
|
r.onBufferAppending = function(e, t) {
|
|
var r = this
|
|
, i = this.tracks
|
|
, n = t.data
|
|
, a = t.type
|
|
, s = t.parent
|
|
, o = t.frag
|
|
, l = t.part
|
|
, u = t.chunkMeta
|
|
, d = t.offset
|
|
, h = u.buffering[a]
|
|
, f = o.sn
|
|
, c = o.cc
|
|
, g = self.performance.now();
|
|
h.start = g;
|
|
var v = o.stats.buffering
|
|
, m = l ? l.stats.buffering : null;
|
|
0 === v.start && (v.start = g),
|
|
m && 0 === m.start && (m.start = g);
|
|
var p = i.audio
|
|
, y = !1;
|
|
"audio" === a && "audio/mpeg" === (null == p ? void 0 : p.container) && (y = !this.lastMpegAudioChunk || 1 === u.id || this.lastMpegAudioChunk.sn !== u.sn,
|
|
this.lastMpegAudioChunk = u);
|
|
var E = i.video
|
|
, T = null == E ? void 0 : E.buffer;
|
|
if (T && "initSegment" !== f) {
|
|
var S = l || o
|
|
, L = this.blockedAudioAppend;
|
|
if ("audio" !== a || "main" === s || this.blockedAudioAppend || E.ending || E.ended) {
|
|
if ("video" === a) {
|
|
var I = S.end;
|
|
if (L) {
|
|
var D = L.frag.start;
|
|
(I > D || I < this.lastVideoAppendEnd || ur.isBuffered(T, D)) && this.unblockAudio()
|
|
}
|
|
this.lastVideoAppendEnd = I
|
|
}
|
|
} else {
|
|
var _ = S.start + .05 * S.duration
|
|
, P = T.buffered
|
|
, C = this.currentOp("video");
|
|
P.length || C ? !C && !ur.isBuffered(T, _) && this.lastVideoAppendEnd < _ && this.blockAudio(S) : this.blockAudio(S)
|
|
}
|
|
}
|
|
var O = (l || o).start
|
|
, x = {
|
|
label: "append-" + a,
|
|
execute: function() {
|
|
var e;
|
|
h.executeStart = self.performance.now();
|
|
var t = null == (e = r.tracks[a]) ? void 0 : e.buffer;
|
|
t && (y ? r.updateTimestampOffset(t, O, .1, a, f, c) : void 0 !== d && A(d) && r.updateTimestampOffset(t, d, 1e-6, a, f, c)),
|
|
r.appendExecutor(n, a)
|
|
},
|
|
onStart: function() {},
|
|
onComplete: function() {
|
|
var e = self.performance.now();
|
|
h.executeEnd = h.end = e,
|
|
0 === v.first && (v.first = e),
|
|
m && 0 === m.first && (m.first = e);
|
|
var t = {};
|
|
r.sourceBuffers.forEach((function(e) {
|
|
var r = e[0]
|
|
, i = e[1];
|
|
r && (t[r] = ur.getBuffered(i))
|
|
}
|
|
)),
|
|
r.appendErrors[a] = 0,
|
|
"audio" === a || "video" === a ? r.appendErrors.audiovideo = 0 : (r.appendErrors.audio = 0,
|
|
r.appendErrors.video = 0),
|
|
r.hls.trigger(b.BUFFER_APPENDED, {
|
|
type: a,
|
|
frag: o,
|
|
part: l,
|
|
chunkMeta: u,
|
|
parent: o.type,
|
|
timeRanges: t
|
|
})
|
|
},
|
|
onError: function(e) {
|
|
var t, i = {
|
|
type: R.MEDIA_ERROR,
|
|
parent: o.type,
|
|
details: k.BUFFER_APPEND_ERROR,
|
|
sourceBufferName: a,
|
|
frag: o,
|
|
part: l,
|
|
chunkMeta: u,
|
|
error: e,
|
|
err: e,
|
|
fatal: !1
|
|
}, n = null == (t = r.media) ? void 0 : t.error;
|
|
if (e.code === DOMException.QUOTA_EXCEEDED_ERR || "QuotaExceededError" == e.name || "quota"in e)
|
|
i.details = k.BUFFER_FULL_ERROR;
|
|
else if (e.code === DOMException.INVALID_STATE_ERR && r.mediaSourceOpenOrEnded && !n)
|
|
i.errorAction = Gt(!0);
|
|
else if (e.name === Sa && 0 === r.sourceBufferCount)
|
|
i.errorAction = Gt(!0);
|
|
else {
|
|
var s = ++r.appendErrors[a];
|
|
r.warn("Failed " + s + "/" + r.hls.config.appendErrorMaxRetry + ' times to append segment in "' + a + '" sourceBuffer (' + (n || "no media error") + ")"),
|
|
(s >= r.hls.config.appendErrorMaxRetry || n) && (i.fatal = !0)
|
|
}
|
|
r.hls.trigger(b.ERROR, i)
|
|
}
|
|
};
|
|
this.log('queuing "' + a + '" append sn: ' + f + (l ? " p: " + l.index : "") + " of " + (o.type === w ? "level" : "track") + " " + o.level + " cc: " + c),
|
|
this.append(x, a, this.isPending(this.tracks[a]))
|
|
}
|
|
,
|
|
r.getFlushOp = function(e, t, r) {
|
|
var i = this;
|
|
return this.log('queuing "' + e + '" remove ' + t + "-" + r),
|
|
{
|
|
label: "remove",
|
|
execute: function() {
|
|
i.removeExecutor(e, t, r)
|
|
},
|
|
onStart: function() {},
|
|
onComplete: function() {
|
|
i.hls.trigger(b.BUFFER_FLUSHED, {
|
|
type: e
|
|
})
|
|
},
|
|
onError: function(n) {
|
|
i.warn("Failed to remove " + t + "-" + r + ' from "' + e + '" SourceBuffer', n)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.onBufferFlushing = function(e, t) {
|
|
var r = this
|
|
, i = t.type
|
|
, n = t.startOffset
|
|
, a = t.endOffset;
|
|
i ? this.append(this.getFlushOp(i, n, a), i) : this.sourceBuffers.forEach((function(e) {
|
|
var t = e[0];
|
|
t && r.append(r.getFlushOp(t, n, a), t)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.onFragParsed = function(e, t) {
|
|
var r = this
|
|
, i = t.frag
|
|
, n = t.part
|
|
, a = []
|
|
, s = n ? n.elementaryStreams : i.elementaryStreams;
|
|
s[J] ? a.push("audiovideo") : (s[$] && a.push("audio"),
|
|
s[Z] && a.push("video")),
|
|
0 === a.length && this.warn("Fragments must have at least one ElementaryStreamType set. type: " + i.type + " level: " + i.level + " sn: " + i.sn),
|
|
this.blockBuffers((function() {
|
|
var e = self.performance.now();
|
|
i.stats.buffering.end = e,
|
|
n && (n.stats.buffering.end = e);
|
|
var t = n ? n.stats : i.stats;
|
|
r.hls.trigger(b.FRAG_BUFFERED, {
|
|
frag: i,
|
|
part: n,
|
|
stats: t,
|
|
id: i.type
|
|
})
|
|
}
|
|
), a).catch((function(e) {
|
|
r.warn("Fragment buffered callback " + e),
|
|
r.stepOperationQueue(r.sourceBufferTypes)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.onFragChanged = function(e, t) {
|
|
this.trimBuffers()
|
|
}
|
|
,
|
|
r.onBufferEos = function(e, t) {
|
|
var r, i = this;
|
|
this.sourceBuffers.forEach((function(e) {
|
|
var r = e[0];
|
|
if (r) {
|
|
var n = i.tracks[r];
|
|
t.type && t.type !== r || (n.ending = !0,
|
|
n.ended || (n.ended = !0,
|
|
i.log(r + " buffer reached EOS")))
|
|
}
|
|
}
|
|
));
|
|
var n = !1 !== (null == (r = this.overrides) ? void 0 : r.endOfStream);
|
|
this.sourceBufferCount > 0 && !this.sourceBuffers.some((function(e) {
|
|
var t, r = e[0];
|
|
return r && !(null != (t = i.tracks[r]) && t.ended)
|
|
}
|
|
)) ? n ? (this.log("Queueing EOS"),
|
|
this.blockUntilOpen((function() {
|
|
i.tracksEnded();
|
|
var e = i.mediaSource;
|
|
e && "open" === e.readyState ? (i.log("Calling mediaSource.endOfStream()"),
|
|
e.endOfStream(),
|
|
i.hls.trigger(b.BUFFERED_TO_END, void 0)) : e && i.log("Could not call mediaSource.endOfStream(). mediaSource.readyState: " + e.readyState)
|
|
}
|
|
))) : (this.tracksEnded(),
|
|
this.hls.trigger(b.BUFFERED_TO_END, void 0)) : "video" === t.type && this.unblockAudio()
|
|
}
|
|
,
|
|
r.tracksEnded = function() {
|
|
var e = this;
|
|
this.sourceBuffers.forEach((function(t) {
|
|
var r = t[0];
|
|
if (null !== r) {
|
|
var i = e.tracks[r];
|
|
i && (i.ending = !1)
|
|
}
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.onLevelUpdated = function(e, t) {
|
|
var r = t.details;
|
|
r.fragments.length && (this.details = r,
|
|
this.updateDuration())
|
|
}
|
|
,
|
|
r.updateDuration = function() {
|
|
var e = this;
|
|
this.blockUntilOpen((function() {
|
|
var t = e.getDurationAndRange();
|
|
t && e.updateMediaSource(t)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.onError = function(e, t) {
|
|
if (t.details === k.BUFFER_APPEND_ERROR && t.frag) {
|
|
var r, i = null == (r = t.errorAction) ? void 0 : r.nextAutoLevel;
|
|
A(i) && i !== t.frag.level && this.resetAppendErrors()
|
|
}
|
|
}
|
|
,
|
|
r.resetAppendErrors = function() {
|
|
this.appendErrors = {
|
|
audio: 0,
|
|
video: 0,
|
|
audiovideo: 0
|
|
}
|
|
}
|
|
,
|
|
r.trimBuffers = function() {
|
|
var e = this.hls
|
|
, t = this.details
|
|
, r = this.media;
|
|
if (r && null !== t && this.sourceBufferCount) {
|
|
var i = e.config
|
|
, n = r.currentTime
|
|
, a = t.levelTargetDuration
|
|
, s = t.live && null !== i.liveBackBufferLength ? i.liveBackBufferLength : i.backBufferLength;
|
|
if (A(s) && s >= 0) {
|
|
var o = Math.max(s, a)
|
|
, l = Math.floor(n / a) * a - o;
|
|
this.flushBackBuffer(n, a, l)
|
|
}
|
|
var u = i.frontBufferFlushThreshold;
|
|
if (A(u) && u > 0) {
|
|
var d = Math.max(i.maxBufferLength, u)
|
|
, h = Math.max(d, a)
|
|
, f = Math.floor(n / a) * a + h;
|
|
this.flushFrontBuffer(n, a, f)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.flushBackBuffer = function(e, t, r) {
|
|
var i = this;
|
|
this.sourceBuffers.forEach((function(e) {
|
|
var t = e[0]
|
|
, n = e[1];
|
|
if (n) {
|
|
var a = ur.getBuffered(n);
|
|
if (a.length > 0 && r > a.start(0)) {
|
|
var s;
|
|
i.hls.trigger(b.BACK_BUFFER_REACHED, {
|
|
bufferEnd: r
|
|
});
|
|
var o = i.tracks[t];
|
|
if (null != (s = i.details) && s.live)
|
|
i.hls.trigger(b.LIVE_BACK_BUFFER_REACHED, {
|
|
bufferEnd: r
|
|
});
|
|
else if (null != o && o.ended)
|
|
return void i.log("Cannot flush " + t + " back buffer while SourceBuffer is in ended state");
|
|
i.hls.trigger(b.BUFFER_FLUSHING, {
|
|
startOffset: 0,
|
|
endOffset: r,
|
|
type: t
|
|
})
|
|
}
|
|
}
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.flushFrontBuffer = function(e, t, r) {
|
|
var i = this;
|
|
this.sourceBuffers.forEach((function(t) {
|
|
var n = t[0]
|
|
, a = t[1];
|
|
if (a) {
|
|
var s = ur.getBuffered(a)
|
|
, o = s.length;
|
|
if (o < 2)
|
|
return;
|
|
var l = s.start(o - 1)
|
|
, u = s.end(o - 1);
|
|
if (r > l || e >= l && e <= u)
|
|
return;
|
|
i.hls.trigger(b.BUFFER_FLUSHING, {
|
|
startOffset: l,
|
|
endOffset: 1 / 0,
|
|
type: n
|
|
})
|
|
}
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.getDurationAndRange = function() {
|
|
var e, t = this.details, r = this.mediaSource;
|
|
if (!t || !this.media || "open" !== (null == r ? void 0 : r.readyState))
|
|
return null;
|
|
var i = t.edge;
|
|
if (t.live && this.hls.config.liveDurationInfinity) {
|
|
if (t.fragments.length && r.setLiveSeekableRange) {
|
|
var n = Math.max(0, t.fragmentStart);
|
|
return {
|
|
duration: 1 / 0,
|
|
start: n,
|
|
end: Math.max(n, i)
|
|
}
|
|
}
|
|
return {
|
|
duration: 1 / 0
|
|
}
|
|
}
|
|
var a = null == (e = this.overrides) ? void 0 : e.duration;
|
|
if (a)
|
|
return A(a) ? {
|
|
duration: a
|
|
} : null;
|
|
var s = this.media.duration;
|
|
return i > (A(r.duration) ? r.duration : 0) && i > s || !A(s) ? {
|
|
duration: i
|
|
} : null
|
|
}
|
|
,
|
|
r.updateMediaSource = function(e) {
|
|
var t = e.duration
|
|
, r = e.start
|
|
, i = e.end
|
|
, n = this.mediaSource;
|
|
this.media && n && "open" === n.readyState && (n.duration !== t && (A(t) && this.log("Updating MediaSource duration to " + t.toFixed(3)),
|
|
n.duration = t),
|
|
void 0 !== r && void 0 !== i && (this.log("MediaSource duration is set to " + n.duration + ". Setting seekable range to " + r + "-" + i + "."),
|
|
n.setLiveSeekableRange(r, i)))
|
|
}
|
|
,
|
|
r.checkPendingTracks = function() {
|
|
var e = this.bufferCodecEventsTotal
|
|
, t = this.pendingTrackCount
|
|
, r = this.tracks;
|
|
if (this.log("checkPendingTracks (pending: " + t + " codec events expected: " + e + ") " + lt(r)),
|
|
this.tracksReady) {
|
|
var i, n = null == (i = this.transferData) ? void 0 : i.tracks;
|
|
n && Object.keys(n).length ? this.attachTransferred() : this.createSourceBuffers()
|
|
}
|
|
}
|
|
,
|
|
r.bufferCreated = function() {
|
|
var e = this;
|
|
if (this.sourceBufferCount) {
|
|
var t = {};
|
|
this.sourceBuffers.forEach((function(r) {
|
|
var i = r[0]
|
|
, n = r[1];
|
|
if (i) {
|
|
var a = e.tracks[i];
|
|
t[i] = {
|
|
buffer: n,
|
|
container: a.container,
|
|
codec: a.codec,
|
|
supplemental: a.supplemental,
|
|
levelCodec: a.levelCodec,
|
|
id: a.id,
|
|
metadata: a.metadata
|
|
}
|
|
}
|
|
}
|
|
)),
|
|
this.hls.trigger(b.BUFFER_CREATED, {
|
|
tracks: t
|
|
}),
|
|
this.log("SourceBuffers created. Running queue: " + this.operationQueue),
|
|
this.sourceBuffers.forEach((function(t) {
|
|
var r = t[0];
|
|
e.executeNext(r)
|
|
}
|
|
))
|
|
} else {
|
|
var r = new Error("could not create source buffer for media codec(s)");
|
|
this.hls.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.BUFFER_INCOMPATIBLE_CODECS_ERROR,
|
|
fatal: !0,
|
|
error: r,
|
|
reason: r.message
|
|
})
|
|
}
|
|
}
|
|
,
|
|
r.createSourceBuffers = function() {
|
|
var e = this.tracks
|
|
, t = this.sourceBuffers
|
|
, r = this.mediaSource;
|
|
if (!r)
|
|
throw new Error("createSourceBuffers called when mediaSource was null");
|
|
for (var i in e) {
|
|
var n = i
|
|
, a = e[n];
|
|
if (this.isPending(a)) {
|
|
var s = this.getTrackCodec(a, n)
|
|
, o = a.container + ";codecs=" + s;
|
|
a.codec = s,
|
|
this.log("creating sourceBuffer(" + o + ")" + (this.currentOp(n) ? " Queued" : "") + " " + lt(a));
|
|
try {
|
|
var l = r.addSourceBuffer(o)
|
|
, u = Ra(n)
|
|
, d = [n, l];
|
|
t[u] = d,
|
|
a.buffer = l
|
|
} catch (e) {
|
|
var h;
|
|
return this.error("error while trying to add sourceBuffer: " + e.message),
|
|
this.shiftAndExecuteNext(n),
|
|
null == (h = this.operationQueue) || h.removeBlockers(),
|
|
delete this.tracks[n],
|
|
void this.hls.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.BUFFER_ADD_CODEC_ERROR,
|
|
fatal: !1,
|
|
error: e,
|
|
sourceBufferName: n,
|
|
mimeType: o,
|
|
parent: a.id
|
|
})
|
|
}
|
|
this.trackSourceBuffer(n, a)
|
|
}
|
|
}
|
|
this.bufferCreated()
|
|
}
|
|
,
|
|
r.getTrackCodec = function(e, t) {
|
|
var r = e.supplemental
|
|
, i = e.codec;
|
|
r && ("video" === t || "audiovideo" === t) && Oe(r, "video") && (i = function(e, t) {
|
|
var r = [];
|
|
if (e)
|
|
for (var i = e.split(","), n = 0; n < i.length; n++)
|
|
we(i[n], "video") || r.push(i[n]);
|
|
return t && r.push(t),
|
|
r.join(",")
|
|
}(i, r));
|
|
var n = Ke(i, e.levelCodec);
|
|
return n ? "audio" === t.slice(0, 5) ? Ge(n, this.appendSource) : n : ""
|
|
}
|
|
,
|
|
r.trackSourceBuffer = function(e, t) {
|
|
var r = this
|
|
, i = t.buffer;
|
|
if (i) {
|
|
var n = this.getTrackCodec(t, e);
|
|
this.tracks[e] = {
|
|
buffer: i,
|
|
codec: n,
|
|
container: t.container,
|
|
levelCodec: t.levelCodec,
|
|
supplemental: t.supplemental,
|
|
metadata: t.metadata,
|
|
id: t.id,
|
|
listeners: []
|
|
},
|
|
this.removeBufferListeners(e),
|
|
this.addBufferListener(e, "updatestart", this.onSBUpdateStart),
|
|
this.addBufferListener(e, "updateend", this.onSBUpdateEnd),
|
|
this.addBufferListener(e, "error", this.onSBUpdateError),
|
|
this.appendSource && this.addBufferListener(e, "bufferedchange", (function(e, t) {
|
|
var i = t.removedRanges;
|
|
null != i && i.length && r.hls.trigger(b.BUFFER_FLUSHED, {
|
|
type: e
|
|
})
|
|
}
|
|
))
|
|
}
|
|
}
|
|
,
|
|
r.onSBUpdateStart = function(e) {
|
|
var t = this.currentOp(e);
|
|
t && t.onStart()
|
|
}
|
|
,
|
|
r.onSBUpdateEnd = function(e) {
|
|
var t;
|
|
if ("closed" !== (null == (t = this.mediaSource) ? void 0 : t.readyState)) {
|
|
var r = this.currentOp(e);
|
|
r && (r.onComplete(),
|
|
this.shiftAndExecuteNext(e))
|
|
} else
|
|
this.resetBuffer(e)
|
|
}
|
|
,
|
|
r.onSBUpdateError = function(e, t) {
|
|
var r, i = new Error(e + " SourceBuffer error. MediaSource readyState: " + (null == (r = this.mediaSource) ? void 0 : r.readyState));
|
|
this.error("" + i, t),
|
|
this.hls.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.BUFFER_APPENDING_ERROR,
|
|
sourceBufferName: e,
|
|
error: i,
|
|
fatal: !1
|
|
});
|
|
var n = this.currentOp(e);
|
|
n && n.onError(i)
|
|
}
|
|
,
|
|
r.updateTimestampOffset = function(e, t, r, i, n, a) {
|
|
var s = t - e.timestampOffset;
|
|
Math.abs(s) >= r && (this.log("Updating " + i + " SourceBuffer timestampOffset to " + t + " (sn: " + n + " cc: " + a + ")"),
|
|
e.timestampOffset = t)
|
|
}
|
|
,
|
|
r.removeExecutor = function(e, t, r) {
|
|
var i = this.media
|
|
, n = this.mediaSource
|
|
, a = this.tracks[e]
|
|
, s = null == a ? void 0 : a.buffer;
|
|
if (!i || !n || !s)
|
|
return this.warn("Attempting to remove from the " + e + " SourceBuffer, but it does not exist"),
|
|
void this.shiftAndExecuteNext(e);
|
|
var o = A(i.duration) ? i.duration : 1 / 0
|
|
, l = A(n.duration) ? n.duration : 1 / 0
|
|
, u = Math.max(0, t)
|
|
, d = Math.min(r, o, l);
|
|
d > u && (!a.ending || a.ended) ? (a.ended = !1,
|
|
this.log("Removing [" + u + "," + d + "] from the " + e + " SourceBuffer"),
|
|
s.remove(u, d)) : this.shiftAndExecuteNext(e)
|
|
}
|
|
,
|
|
r.appendExecutor = function(e, t) {
|
|
var r = this.tracks[t]
|
|
, i = null == r ? void 0 : r.buffer;
|
|
if (!i)
|
|
throw new Aa("Attempting to append to the " + t + " SourceBuffer, but it does not exist");
|
|
r.ending = !1,
|
|
r.ended = !1,
|
|
i.appendBuffer(e)
|
|
}
|
|
,
|
|
r.blockUntilOpen = function(e) {
|
|
var t = this;
|
|
if (this.isUpdating() || this.isQueued())
|
|
this.blockBuffers(e).catch((function(e) {
|
|
t.warn("SourceBuffer blocked callback " + e),
|
|
t.stepOperationQueue(t.sourceBufferTypes)
|
|
}
|
|
));
|
|
else
|
|
try {
|
|
e()
|
|
} catch (e) {
|
|
this.warn("Callback run without blocking " + this.operationQueue + " " + e)
|
|
}
|
|
}
|
|
,
|
|
r.isUpdating = function() {
|
|
return this.sourceBuffers.some((function(e) {
|
|
var t = e[0]
|
|
, r = e[1];
|
|
return t && r.updating
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.isQueued = function() {
|
|
var e = this;
|
|
return this.sourceBuffers.some((function(t) {
|
|
var r = t[0];
|
|
return r && !!e.currentOp(r)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.isPending = function(e) {
|
|
return !!e && !e.buffer
|
|
}
|
|
,
|
|
r.blockBuffers = function(e, t) {
|
|
var r = this;
|
|
if (void 0 === t && (t = this.sourceBufferTypes),
|
|
!t.length)
|
|
return this.log("Blocking operation requested, but no SourceBuffers exist"),
|
|
Promise.resolve().then(e);
|
|
var i = this.operationQueue
|
|
, n = t.map((function(e) {
|
|
return r.appendBlocker(e)
|
|
}
|
|
));
|
|
return t.length > 1 && !!this.blockedAudioAppend && this.unblockAudio(),
|
|
Promise.all(n).then((function(t) {
|
|
i === r.operationQueue && (e(),
|
|
r.stepOperationQueue(r.sourceBufferTypes))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.stepOperationQueue = function(e) {
|
|
var t = this;
|
|
e.forEach((function(e) {
|
|
var r, i = null == (r = t.tracks[e]) ? void 0 : r.buffer;
|
|
i && !i.updating && t.shiftAndExecuteNext(e)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.append = function(e, t, r) {
|
|
this.operationQueue && this.operationQueue.append(e, t, r)
|
|
}
|
|
,
|
|
r.appendBlocker = function(e) {
|
|
if (this.operationQueue)
|
|
return this.operationQueue.appendBlocker(e)
|
|
}
|
|
,
|
|
r.currentOp = function(e) {
|
|
return this.operationQueue ? this.operationQueue.current(e) : null
|
|
}
|
|
,
|
|
r.executeNext = function(e) {
|
|
e && this.operationQueue && this.operationQueue.executeNext(e)
|
|
}
|
|
,
|
|
r.shiftAndExecuteNext = function(e) {
|
|
this.operationQueue && this.operationQueue.shiftAndExecuteNext(e)
|
|
}
|
|
,
|
|
r.addBufferListener = function(e, t, r) {
|
|
var i = this.tracks[e];
|
|
if (i) {
|
|
var n = i.buffer;
|
|
if (n) {
|
|
var a = r.bind(this, e);
|
|
i.listeners.push({
|
|
event: t,
|
|
listener: a
|
|
}),
|
|
n.addEventListener(t, a)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.removeBufferListeners = function(e) {
|
|
var t = this.tracks[e];
|
|
if (t) {
|
|
var r = t.buffer;
|
|
r && (t.listeners.forEach((function(e) {
|
|
r.removeEventListener(e.event, e.listener)
|
|
}
|
|
)),
|
|
t.listeners.length = 0)
|
|
}
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "mediaSourceOpenOrEnded",
|
|
get: function() {
|
|
var e, t = null == (e = this.mediaSource) ? void 0 : e.readyState;
|
|
return "open" === t || "ended" === t
|
|
}
|
|
}, {
|
|
key: "sourceBufferTracks",
|
|
get: function() {
|
|
var e = this;
|
|
return Object.keys(this.tracks).reduce((function(t, r) {
|
|
var i = e.tracks[r];
|
|
return t[r] = {
|
|
id: i.id,
|
|
container: i.container,
|
|
codec: i.codec,
|
|
levelCodec: i.levelCodec
|
|
},
|
|
t
|
|
}
|
|
), {})
|
|
}
|
|
}, {
|
|
key: "bufferedToEnd",
|
|
get: function() {
|
|
var e = this;
|
|
return this.sourceBufferCount > 0 && !this.sourceBuffers.some((function(t) {
|
|
var r = t[0];
|
|
if (r) {
|
|
var i = e.tracks[r];
|
|
if (i)
|
|
return !i.ended || i.ending
|
|
}
|
|
return !1
|
|
}
|
|
))
|
|
}
|
|
}, {
|
|
key: "tracksReady",
|
|
get: function() {
|
|
var e = this.pendingTrackCount;
|
|
return e > 0 && (e >= this.bufferCodecEventsTotal || this.isPending(this.tracks.audiovideo))
|
|
}
|
|
}, {
|
|
key: "mediaSrc",
|
|
get: function() {
|
|
var e, t, r = (null == (e = this.media) || null == (t = e.querySelector) ? void 0 : t.call(e, "source")) || this.media;
|
|
return null == r ? void 0 : r.src
|
|
}
|
|
}, {
|
|
key: "pendingTrackCount",
|
|
get: function() {
|
|
var e = this;
|
|
return Object.keys(this.tracks).reduce((function(t, r) {
|
|
return t + (e.isPending(e.tracks[r]) ? 1 : 0)
|
|
}
|
|
), 0)
|
|
}
|
|
}, {
|
|
key: "sourceBufferCount",
|
|
get: function() {
|
|
return this.sourceBuffers.reduce((function(e, t) {
|
|
return e + (t[0] ? 1 : 0)
|
|
}
|
|
), 0)
|
|
}
|
|
}, {
|
|
key: "sourceBufferTypes",
|
|
get: function() {
|
|
return this.sourceBuffers.map((function(e) {
|
|
return e[0]
|
|
}
|
|
)).filter((function(e) {
|
|
return !!e
|
|
}
|
|
))
|
|
}
|
|
}])
|
|
}(N);
|
|
function Ia(e) {
|
|
var t = e.querySelectorAll("source");
|
|
[].slice.call(t).forEach((function(t) {
|
|
e.removeChild(t)
|
|
}
|
|
))
|
|
}
|
|
function Ra(e) {
|
|
return "audio" === e ? 1 : 0
|
|
}
|
|
var ka = function() {
|
|
function e(e) {
|
|
this.hls = void 0,
|
|
this.autoLevelCapping = void 0,
|
|
this.firstLevel = void 0,
|
|
this.media = void 0,
|
|
this.restrictedLevels = void 0,
|
|
this.timer = void 0,
|
|
this.clientRect = void 0,
|
|
this.streamController = void 0,
|
|
this.hls = e,
|
|
this.autoLevelCapping = Number.POSITIVE_INFINITY,
|
|
this.firstLevel = -1,
|
|
this.media = null,
|
|
this.restrictedLevels = [],
|
|
this.timer = void 0,
|
|
this.clientRect = null,
|
|
this.registerListeners()
|
|
}
|
|
var t = e.prototype;
|
|
return t.setStreamController = function(e) {
|
|
this.streamController = e
|
|
}
|
|
,
|
|
t.destroy = function() {
|
|
this.hls && this.unregisterListener(),
|
|
this.timer && this.stopCapping(),
|
|
this.media = null,
|
|
this.clientRect = null,
|
|
this.hls = this.streamController = null
|
|
}
|
|
,
|
|
t.registerListeners = function() {
|
|
var e = this.hls;
|
|
e.on(b.FPS_DROP_LEVEL_CAPPING, this.onFpsDropLevelCapping, this),
|
|
e.on(b.MEDIA_ATTACHING, this.onMediaAttaching, this),
|
|
e.on(b.MANIFEST_PARSED, this.onManifestParsed, this),
|
|
e.on(b.LEVELS_UPDATED, this.onLevelsUpdated, this),
|
|
e.on(b.BUFFER_CODECS, this.onBufferCodecs, this),
|
|
e.on(b.MEDIA_DETACHING, this.onMediaDetaching, this)
|
|
}
|
|
,
|
|
t.unregisterListener = function() {
|
|
var e = this.hls;
|
|
e.off(b.FPS_DROP_LEVEL_CAPPING, this.onFpsDropLevelCapping, this),
|
|
e.off(b.MEDIA_ATTACHING, this.onMediaAttaching, this),
|
|
e.off(b.MANIFEST_PARSED, this.onManifestParsed, this),
|
|
e.off(b.LEVELS_UPDATED, this.onLevelsUpdated, this),
|
|
e.off(b.BUFFER_CODECS, this.onBufferCodecs, this),
|
|
e.off(b.MEDIA_DETACHING, this.onMediaDetaching, this)
|
|
}
|
|
,
|
|
t.onFpsDropLevelCapping = function(e, t) {
|
|
var r = this.hls.levels[t.droppedLevel];
|
|
this.isLevelAllowed(r) && this.restrictedLevels.push({
|
|
bitrate: r.bitrate,
|
|
height: r.height,
|
|
width: r.width
|
|
})
|
|
}
|
|
,
|
|
t.onMediaAttaching = function(e, t) {
|
|
this.media = t.media instanceof HTMLVideoElement ? t.media : null,
|
|
this.clientRect = null,
|
|
this.timer && this.hls.levels.length && this.detectPlayerSize()
|
|
}
|
|
,
|
|
t.onManifestParsed = function(e, t) {
|
|
var r = this.hls;
|
|
this.restrictedLevels = [],
|
|
this.firstLevel = t.firstLevel,
|
|
r.config.capLevelToPlayerSize && t.video && this.startCapping()
|
|
}
|
|
,
|
|
t.onLevelsUpdated = function(e, t) {
|
|
this.timer && A(this.autoLevelCapping) && this.detectPlayerSize()
|
|
}
|
|
,
|
|
t.onBufferCodecs = function(e, t) {
|
|
this.hls.config.capLevelToPlayerSize && t.video && this.startCapping()
|
|
}
|
|
,
|
|
t.onMediaDetaching = function() {
|
|
this.stopCapping(),
|
|
this.media = null
|
|
}
|
|
,
|
|
t.detectPlayerSize = function() {
|
|
if (this.media) {
|
|
if (this.mediaHeight <= 0 || this.mediaWidth <= 0)
|
|
return void (this.clientRect = null);
|
|
var e = this.hls.levels;
|
|
if (e.length) {
|
|
var t = this.hls
|
|
, r = this.getMaxLevel(e.length - 1);
|
|
r !== this.autoLevelCapping && t.logger.log("Setting autoLevelCapping to " + r + ": " + e[r].height + "p@" + e[r].bitrate + " for media " + this.mediaWidth + "x" + this.mediaHeight),
|
|
t.autoLevelCapping = r,
|
|
t.autoLevelEnabled && t.autoLevelCapping > this.autoLevelCapping && this.streamController && this.streamController.nextLevelSwitch(),
|
|
this.autoLevelCapping = t.autoLevelCapping
|
|
}
|
|
}
|
|
}
|
|
,
|
|
t.getMaxLevel = function(t) {
|
|
var r = this
|
|
, i = this.hls.levels;
|
|
if (!i.length)
|
|
return -1;
|
|
var n = i.filter((function(e, i) {
|
|
return r.isLevelAllowed(e) && i <= t
|
|
}
|
|
));
|
|
return this.clientRect = null,
|
|
e.getMaxLevelByMediaSize(n, this.mediaWidth, this.mediaHeight)
|
|
}
|
|
,
|
|
t.startCapping = function() {
|
|
this.timer || (this.autoLevelCapping = Number.POSITIVE_INFINITY,
|
|
self.clearInterval(this.timer),
|
|
this.timer = self.setInterval(this.detectPlayerSize.bind(this), 1e3),
|
|
this.detectPlayerSize())
|
|
}
|
|
,
|
|
t.stopCapping = function() {
|
|
this.restrictedLevels = [],
|
|
this.firstLevel = -1,
|
|
this.autoLevelCapping = Number.POSITIVE_INFINITY,
|
|
this.timer && (self.clearInterval(this.timer),
|
|
this.timer = void 0)
|
|
}
|
|
,
|
|
t.getDimensions = function() {
|
|
if (this.clientRect)
|
|
return this.clientRect;
|
|
var e = this.media
|
|
, t = {
|
|
width: 0,
|
|
height: 0
|
|
};
|
|
if (e) {
|
|
var r = e.getBoundingClientRect();
|
|
t.width = r.width,
|
|
t.height = r.height,
|
|
t.width || t.height || (t.width = r.right - r.left || e.width || 0,
|
|
t.height = r.bottom - r.top || e.height || 0)
|
|
}
|
|
return this.clientRect = t,
|
|
t
|
|
}
|
|
,
|
|
t.isLevelAllowed = function(e) {
|
|
return !this.restrictedLevels.some((function(t) {
|
|
return e.bitrate === t.bitrate && e.width === t.width && e.height === t.height
|
|
}
|
|
))
|
|
}
|
|
,
|
|
e.getMaxLevelByMediaSize = function(e, t, r) {
|
|
if (null == e || !e.length)
|
|
return -1;
|
|
for (var i, n, a = e.length - 1, s = Math.max(t, r), o = 0; o < e.length; o += 1) {
|
|
var l = e[o];
|
|
if ((l.width >= s || l.height >= s) && (i = l,
|
|
!(n = e[o + 1]) || i.width !== n.width || i.height !== n.height)) {
|
|
a = o;
|
|
break
|
|
}
|
|
}
|
|
return a
|
|
}
|
|
,
|
|
i(e, [{
|
|
key: "mediaWidth",
|
|
get: function() {
|
|
return this.getDimensions().width * this.contentScaleFactor
|
|
}
|
|
}, {
|
|
key: "mediaHeight",
|
|
get: function() {
|
|
return this.getDimensions().height * this.contentScaleFactor
|
|
}
|
|
}, {
|
|
key: "contentScaleFactor",
|
|
get: function() {
|
|
var e = 1;
|
|
if (!this.hls.config.ignoreDevicePixelRatio)
|
|
try {
|
|
e = self.devicePixelRatio
|
|
} catch (e) {}
|
|
return Math.min(e, this.hls.config.maxDevicePixelRatio)
|
|
}
|
|
}])
|
|
}()
|
|
, ba = {
|
|
MANIFEST: "m",
|
|
AUDIO: "a",
|
|
VIDEO: "v",
|
|
MUXED: "av",
|
|
INIT: "i",
|
|
CAPTION: "c",
|
|
TIMED_TEXT: "tt",
|
|
KEY: "k",
|
|
OTHER: "o"
|
|
}
|
|
, Da = {
|
|
HLS: "h"
|
|
}
|
|
, _a = function e(t, r) {
|
|
Array.isArray(t) && (t = t.map((function(t) {
|
|
return t instanceof e ? t : new e(t)
|
|
}
|
|
))),
|
|
this.value = t,
|
|
this.params = r
|
|
}
|
|
, Pa = "Dict";
|
|
function Ca(e, t, r, i) {
|
|
return new Error("failed to " + e + ' "' + (n = t,
|
|
(Array.isArray(n) ? JSON.stringify(n) : n instanceof Map ? "Map{}" : n instanceof Set ? "Set{}" : "object" == typeof n ? JSON.stringify(n) : String(n)) + '" as ') + r,{
|
|
cause: i
|
|
});
|
|
var n
|
|
}
|
|
function wa(e, t, r) {
|
|
return Ca("serialize", e, t, r)
|
|
}
|
|
var Oa = function(e) {
|
|
this.description = e
|
|
}
|
|
, xa = "Bare Item"
|
|
, Ma = "Boolean"
|
|
, Fa = "Byte Sequence";
|
|
function Na(e) {
|
|
if (!1 === ArrayBuffer.isView(e))
|
|
throw wa(e, Fa);
|
|
return ":" + (t = e,
|
|
btoa(String.fromCharCode.apply(String, t)) + ":");
|
|
var t
|
|
}
|
|
var Ua = "Integer";
|
|
function Ba(e) {
|
|
if (function(e) {
|
|
return e < -999999999999999 || 999999999999999 < e
|
|
}(e))
|
|
throw wa(e, Ua);
|
|
return e.toString()
|
|
}
|
|
function Ga(e, t) {
|
|
if (e < 0)
|
|
return -Ga(-e, t);
|
|
var r = Math.pow(10, t);
|
|
if (Math.abs(e * r % 1 - .5) < Number.EPSILON) {
|
|
var i = Math.floor(e * r);
|
|
return (i % 2 == 0 ? i : i + 1) / r
|
|
}
|
|
return Math.round(e * r) / r
|
|
}
|
|
var Ka = "Decimal";
|
|
function Va(e) {
|
|
var t = Ga(e, 3);
|
|
if (Math.floor(Math.abs(t)).toString().length > 12)
|
|
throw wa(e, Ka);
|
|
var r = t.toString();
|
|
return r.includes(".") ? r : r + ".0"
|
|
}
|
|
var Ha = "String"
|
|
, Ya = /[\x00-\x1f\x7f]+/
|
|
, Wa = "Token";
|
|
function ja(e) {
|
|
var t, r = (t = e).description || t.toString().slice(7, -1);
|
|
if (!1 === /^([a-zA-Z*])([!#$%&'*+\-.^_`|~\w:/]*)$/.test(r))
|
|
throw wa(r, Wa);
|
|
return r
|
|
}
|
|
function qa(e) {
|
|
switch (typeof e) {
|
|
case "number":
|
|
if (!A(e))
|
|
throw wa(e, xa);
|
|
return Number.isInteger(e) ? Ba(e) : Va(e);
|
|
case "string":
|
|
return function(e) {
|
|
if (Ya.test(e))
|
|
throw wa(e, Ha);
|
|
return '"' + e.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + '"'
|
|
}(e);
|
|
case "symbol":
|
|
return ja(e);
|
|
case "boolean":
|
|
return function(e) {
|
|
if ("boolean" != typeof e)
|
|
throw wa(e, Ma);
|
|
return e ? "?1" : "?0"
|
|
}(e);
|
|
case "object":
|
|
if (e instanceof Date)
|
|
return function(e) {
|
|
return "@" + Ba(e.getTime() / 1e3)
|
|
}(e);
|
|
if (e instanceof Uint8Array)
|
|
return Na(e);
|
|
if (e instanceof Oa)
|
|
return ja(e);
|
|
default:
|
|
throw wa(e, xa)
|
|
}
|
|
}
|
|
var Xa = "Key";
|
|
function Qa(e) {
|
|
if (!1 === /^[a-z*][a-z0-9\-_.*]*$/.test(e))
|
|
throw wa(e, Xa);
|
|
return e
|
|
}
|
|
function za(e) {
|
|
return null == e ? "" : Object.entries(e).map((function(e) {
|
|
var t = e[0]
|
|
, r = e[1];
|
|
return !0 === r ? ";" + Qa(t) : ";" + Qa(t) + "=" + qa(r)
|
|
}
|
|
)).join("")
|
|
}
|
|
function $a(e) {
|
|
return e instanceof _a ? "" + qa(e.value) + za(e.params) : qa(e)
|
|
}
|
|
function Za(e, t) {
|
|
if (void 0 === t && (t = {
|
|
whitespace: !0
|
|
}),
|
|
"object" != typeof e || null == e)
|
|
throw wa(e, Pa);
|
|
var r = e instanceof Map ? e.entries() : Object.entries(e)
|
|
, i = (null == t ? void 0 : t.whitespace) ? " " : "";
|
|
return Array.from(r).map((function(e) {
|
|
var t = e[0]
|
|
, r = e[1];
|
|
r instanceof _a == 0 && (r = new _a(r));
|
|
var i, n = Qa(t);
|
|
return !0 === r.value ? n += za(r.params) : (n += "=",
|
|
Array.isArray(r.value) ? n += "(" + (i = r).value.map($a).join(" ") + ")" + za(i.params) : n += $a(r)),
|
|
n
|
|
}
|
|
)).join("," + i)
|
|
}
|
|
function Ja(e, t) {
|
|
return Za(e, t)
|
|
}
|
|
var es = "CMCD-Object"
|
|
, ts = "CMCD-Request"
|
|
, rs = "CMCD-Session"
|
|
, is = "CMCD-Status"
|
|
, ns = {
|
|
br: es,
|
|
ab: es,
|
|
d: es,
|
|
ot: es,
|
|
tb: es,
|
|
tpb: es,
|
|
lb: es,
|
|
tab: es,
|
|
lab: es,
|
|
url: es,
|
|
pb: ts,
|
|
bl: ts,
|
|
tbl: ts,
|
|
dl: ts,
|
|
ltc: ts,
|
|
mtp: ts,
|
|
nor: ts,
|
|
nrr: ts,
|
|
rc: ts,
|
|
sn: ts,
|
|
sta: ts,
|
|
su: ts,
|
|
ttfb: ts,
|
|
ttfbb: ts,
|
|
ttlb: ts,
|
|
cmsdd: ts,
|
|
cmsds: ts,
|
|
smrt: ts,
|
|
df: ts,
|
|
cs: ts,
|
|
ts: ts,
|
|
cid: rs,
|
|
pr: rs,
|
|
sf: rs,
|
|
sid: rs,
|
|
st: rs,
|
|
v: rs,
|
|
msd: rs,
|
|
bs: is,
|
|
bsd: is,
|
|
cdn: is,
|
|
rtp: is,
|
|
bg: is,
|
|
pt: is,
|
|
ec: is,
|
|
e: is
|
|
}
|
|
, as = {
|
|
REQUEST: ts
|
|
};
|
|
function ss(e, t) {
|
|
var r = {};
|
|
if (!e)
|
|
return r;
|
|
var i, n = Object.keys(e), a = t ? (i = t,
|
|
Object.keys(i).reduce((function(e, t) {
|
|
var r;
|
|
return null === (r = i[t]) || void 0 === r || r.forEach((function(r) {
|
|
return e[r] = t
|
|
}
|
|
)),
|
|
e
|
|
}
|
|
), {})) : {};
|
|
return n.reduce((function(t, r) {
|
|
var i, n = ns[r] || a[r] || as.REQUEST;
|
|
return (null !== (i = t[n]) && void 0 !== i ? i : t[n] = {})[r] = e[r],
|
|
t
|
|
}
|
|
), r)
|
|
}
|
|
var os = "event"
|
|
, ls = function(e) {
|
|
return Math.round(e)
|
|
}
|
|
, us = function(e, t) {
|
|
return Array.isArray(e) ? e.map((function(e) {
|
|
return us(e, t)
|
|
}
|
|
)) : e instanceof _a && "string" == typeof e.value ? new _a(us(e.value, t),e.params) : (t.baseUrl && (e = function(e, t) {
|
|
var r = new URL(e)
|
|
, i = new URL(t);
|
|
if (r.origin !== i.origin)
|
|
return e;
|
|
for (var n = r.pathname.split("/").slice(1), a = i.pathname.split("/").slice(1, -1); n[0] === a[0]; )
|
|
n.shift(),
|
|
a.shift();
|
|
for (; a.length; )
|
|
a.shift(),
|
|
n.unshift("..");
|
|
return n.join("/") + r.search + r.hash
|
|
}(e, t.baseUrl)),
|
|
1 === t.version ? encodeURIComponent(e) : e)
|
|
}
|
|
, ds = function(e) {
|
|
return 100 * ls(e / 100)
|
|
}
|
|
, hs = {
|
|
br: ls,
|
|
d: ls,
|
|
bl: ds,
|
|
dl: ds,
|
|
mtp: ds,
|
|
nor: function(e, t) {
|
|
var r = e;
|
|
return t.version >= 2 && (e instanceof _a && "string" == typeof e.value ? r = new _a([e]) : "string" == typeof e && (r = [e])),
|
|
us(r, t)
|
|
},
|
|
rtp: ds,
|
|
tb: ls
|
|
}
|
|
, fs = "request"
|
|
, cs = "response"
|
|
, gs = ["ab", "bg", "bl", "br", "bs", "bsd", "cdn", "cid", "cs", "df", "ec", "lab", "lb", "ltc", "msd", "mtp", "pb", "pr", "pt", "sf", "sid", "sn", "st", "sta", "tab", "tb", "tbl", "tpb", "ts", "v"]
|
|
, vs = ["e"]
|
|
, ms = /^[a-zA-Z0-9-.]+-[a-zA-Z0-9-.]+$/;
|
|
function ps(e) {
|
|
return ms.test(e)
|
|
}
|
|
var ys, Es = ["d", "dl", "nor", "ot", "rtp", "su"], Ts = ["cmsdd", "cmsds", "rc", "smrt", "ttfb", "ttfbb", "ttlb", "url"], Ss = ["bl", "br", "bs", "cid", "d", "dl", "mtp", "nor", "nrr", "ot", "pr", "rtp", "sf", "sid", "st", "su", "tb", "v"];
|
|
function As(e) {
|
|
return Ss.includes(e) || ps(e)
|
|
}
|
|
var Ls = ((ys = {})[cs] = function(e) {
|
|
return gs.includes(e) || Es.includes(e) || Ts.includes(e) || ps(e)
|
|
}
|
|
,
|
|
ys[os] = function(e) {
|
|
return gs.includes(e) || vs.includes(e) || ps(e)
|
|
}
|
|
,
|
|
ys[fs] = function(e) {
|
|
return gs.includes(e) || Es.includes(e) || ps(e)
|
|
}
|
|
,
|
|
ys);
|
|
function Is(e, t) {
|
|
void 0 === t && (t = {});
|
|
var r = {};
|
|
if (null == e || "object" != typeof e)
|
|
return r;
|
|
var i = t.version || e.v || 1
|
|
, n = t.reportingMode || fs
|
|
, s = 1 === i ? As : Ls[n]
|
|
, o = Object.keys(e).filter(s)
|
|
, l = t.filter;
|
|
"function" == typeof l && (o = o.filter(l));
|
|
var u = n === cs || n === os;
|
|
u && !o.includes("ts") && o.push("ts"),
|
|
i > 1 && !o.includes("v") && o.push("v");
|
|
var d = a({}, hs, t.formatters)
|
|
, h = {
|
|
version: i,
|
|
reportingMode: n,
|
|
baseUrl: t.baseUrl
|
|
};
|
|
return o.sort().forEach((function(t) {
|
|
var n = e[t]
|
|
, a = d[t];
|
|
if ("function" == typeof a && (n = a(n, h)),
|
|
"v" === t) {
|
|
if (1 === i)
|
|
return;
|
|
n = i
|
|
}
|
|
"pr" == t && 1 === n || (u && "ts" === t && !A(n) && (n = Date.now()),
|
|
function(e) {
|
|
return "number" == typeof e ? A(e) : null != e && "" !== e && !1 !== e
|
|
}(n) && (function(e) {
|
|
return ["ot", "sf", "st", "e", "sta"].includes(e)
|
|
}(t) && "string" == typeof n && (n = new Oa(n)),
|
|
r[t] = n))
|
|
}
|
|
)),
|
|
r
|
|
}
|
|
function Rs(e, t, r) {
|
|
return a(e, function(e, t) {
|
|
void 0 === t && (t = {});
|
|
var r = {};
|
|
if (!e)
|
|
return r;
|
|
var i = ss(Is(e, t), null == t ? void 0 : t.customHeaderMap);
|
|
return Object.entries(i).reduce((function(e, t) {
|
|
var r = t[0]
|
|
, i = Ja(t[1], {
|
|
whitespace: !1
|
|
});
|
|
return i && (e[r] = i),
|
|
e
|
|
}
|
|
), r)
|
|
}(t, r))
|
|
}
|
|
var ks = "CMCD";
|
|
function bs(e, t) {
|
|
if (void 0 === t && (t = {}),
|
|
!e)
|
|
return "";
|
|
var r = function(e, t) {
|
|
return void 0 === t && (t = {}),
|
|
e ? Ja(Is(e, t), {
|
|
whitespace: !1
|
|
}) : ""
|
|
}(e, t);
|
|
return encodeURIComponent(r)
|
|
}
|
|
var Ds = /CMCD=[^&#]+/;
|
|
function _s(e, t, r) {
|
|
var i = function(e, t) {
|
|
if (void 0 === t && (t = {}),
|
|
!e)
|
|
return "";
|
|
var r = bs(e, t);
|
|
return ks + "=" + r
|
|
}(t, r);
|
|
if (!i)
|
|
return e;
|
|
if (Ds.test(e))
|
|
return e.replace(Ds, i);
|
|
var n = e.includes("?") ? "&" : "?";
|
|
return "" + e + n + i
|
|
}
|
|
var Ps = function() {
|
|
function e(e) {
|
|
var t = this;
|
|
this.hls = void 0,
|
|
this.config = void 0,
|
|
this.media = void 0,
|
|
this.sid = void 0,
|
|
this.cid = void 0,
|
|
this.useHeaders = !1,
|
|
this.includeKeys = void 0,
|
|
this.initialized = !1,
|
|
this.starved = !1,
|
|
this.buffering = !0,
|
|
this.audioBuffer = void 0,
|
|
this.videoBuffer = void 0,
|
|
this.onWaiting = function() {
|
|
t.initialized && (t.starved = !0),
|
|
t.buffering = !0
|
|
}
|
|
,
|
|
this.onPlaying = function() {
|
|
t.initialized || (t.initialized = !0),
|
|
t.buffering = !1
|
|
}
|
|
,
|
|
this.applyPlaylistData = function(e) {
|
|
try {
|
|
t.apply(e, {
|
|
ot: ba.MANIFEST,
|
|
su: !t.initialized
|
|
})
|
|
} catch (e) {
|
|
t.hls.logger.warn("Could not generate manifest CMCD data.", e)
|
|
}
|
|
}
|
|
,
|
|
this.applyFragmentData = function(e) {
|
|
try {
|
|
var r = e.frag
|
|
, i = e.part
|
|
, n = t.hls.levels[r.level]
|
|
, a = t.getObjectType(r)
|
|
, s = {
|
|
d: 1e3 * (i || r).duration,
|
|
ot: a
|
|
};
|
|
a !== ba.VIDEO && a !== ba.AUDIO && a != ba.MUXED || (s.br = n.bitrate / 1e3,
|
|
s.tb = t.getTopBandwidth(a) / 1e3,
|
|
s.bl = t.getBufferLength(a));
|
|
var o = i ? t.getNextPart(i) : t.getNextFrag(r);
|
|
null != o && o.url && o.url !== r.url && (s.nor = o.url),
|
|
t.apply(e, s)
|
|
} catch (e) {
|
|
t.hls.logger.warn("Could not generate segment CMCD data.", e)
|
|
}
|
|
}
|
|
,
|
|
this.hls = e;
|
|
var r = this.config = e.config
|
|
, i = r.cmcd;
|
|
null != i && (r.pLoader = this.createPlaylistLoader(),
|
|
r.fLoader = this.createFragmentLoader(),
|
|
this.sid = i.sessionId || e.sessionId,
|
|
this.cid = i.contentId,
|
|
this.useHeaders = !0 === i.useHeaders,
|
|
this.includeKeys = i.includeKeys,
|
|
this.registerListeners())
|
|
}
|
|
var t = e.prototype;
|
|
return t.registerListeners = function() {
|
|
var e = this.hls;
|
|
e.on(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.on(b.MEDIA_DETACHED, this.onMediaDetached, this),
|
|
e.on(b.BUFFER_CREATED, this.onBufferCreated, this)
|
|
}
|
|
,
|
|
t.unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e.off(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.off(b.MEDIA_DETACHED, this.onMediaDetached, this),
|
|
e.off(b.BUFFER_CREATED, this.onBufferCreated, this)
|
|
}
|
|
,
|
|
t.destroy = function() {
|
|
this.unregisterListeners(),
|
|
this.onMediaDetached(),
|
|
this.hls = this.config = this.audioBuffer = this.videoBuffer = null,
|
|
this.onWaiting = this.onPlaying = this.media = null
|
|
}
|
|
,
|
|
t.onMediaAttached = function(e, t) {
|
|
this.media = t.media,
|
|
this.media.addEventListener("waiting", this.onWaiting),
|
|
this.media.addEventListener("playing", this.onPlaying)
|
|
}
|
|
,
|
|
t.onMediaDetached = function() {
|
|
this.media && (this.media.removeEventListener("waiting", this.onWaiting),
|
|
this.media.removeEventListener("playing", this.onPlaying),
|
|
this.media = null)
|
|
}
|
|
,
|
|
t.onBufferCreated = function(e, t) {
|
|
var r, i;
|
|
this.audioBuffer = null == (r = t.tracks.audio) ? void 0 : r.buffer,
|
|
this.videoBuffer = null == (i = t.tracks.video) ? void 0 : i.buffer
|
|
}
|
|
,
|
|
t.createData = function() {
|
|
var e;
|
|
return {
|
|
v: 1,
|
|
sf: Da.HLS,
|
|
sid: this.sid,
|
|
cid: this.cid,
|
|
pr: null == (e = this.media) ? void 0 : e.playbackRate,
|
|
mtp: this.hls.bandwidthEstimate / 1e3
|
|
}
|
|
}
|
|
,
|
|
t.apply = function(e, t) {
|
|
void 0 === t && (t = {}),
|
|
a(t, this.createData());
|
|
var r = t.ot === ba.INIT || t.ot === ba.VIDEO || t.ot === ba.MUXED;
|
|
this.starved && r && (t.bs = !0,
|
|
t.su = !0,
|
|
this.starved = !1),
|
|
null == t.su && (t.su = this.buffering);
|
|
var i = this.includeKeys;
|
|
i && (t = Object.keys(t).reduce((function(e, r) {
|
|
return i.includes(r) && (e[r] = t[r]),
|
|
e
|
|
}
|
|
), {}));
|
|
var n = {
|
|
baseUrl: e.url
|
|
};
|
|
this.useHeaders ? (e.headers || (e.headers = {}),
|
|
Rs(e.headers, t, n)) : e.url = _s(e.url, t, n)
|
|
}
|
|
,
|
|
t.getNextFrag = function(e) {
|
|
var t, r = null == (t = this.hls.levels[e.level]) ? void 0 : t.details;
|
|
if (r) {
|
|
var i = e.sn - r.startSN;
|
|
return r.fragments[i + 1]
|
|
}
|
|
}
|
|
,
|
|
t.getNextPart = function(e) {
|
|
var t, r = e.index, i = e.fragment, n = null == (t = this.hls.levels[i.level]) || null == (t = t.details) ? void 0 : t.partList;
|
|
if (n)
|
|
for (var a = i.sn, s = n.length - 1; s >= 0; s--) {
|
|
var o = n[s];
|
|
if (o.index === r && o.fragment.sn === a)
|
|
return n[s + 1]
|
|
}
|
|
}
|
|
,
|
|
t.getObjectType = function(e) {
|
|
var t = e.type;
|
|
return "subtitle" === t ? ba.TIMED_TEXT : "initSegment" === e.sn ? ba.INIT : "audio" === t ? ba.AUDIO : "main" === t ? this.hls.audioTracks.length ? ba.VIDEO : ba.MUXED : void 0
|
|
}
|
|
,
|
|
t.getTopBandwidth = function(e) {
|
|
var t, r = 0, i = this.hls;
|
|
if (e === ba.AUDIO)
|
|
t = i.audioTracks;
|
|
else {
|
|
var n = i.maxAutoLevel
|
|
, a = n > -1 ? n + 1 : i.levels.length;
|
|
t = i.levels.slice(0, a)
|
|
}
|
|
return t.forEach((function(e) {
|
|
e.bitrate > r && (r = e.bitrate)
|
|
}
|
|
)),
|
|
r > 0 ? r : NaN
|
|
}
|
|
,
|
|
t.getBufferLength = function(e) {
|
|
var t = this.media
|
|
, r = e === ba.AUDIO ? this.audioBuffer : this.videoBuffer;
|
|
return r && t ? 1e3 * ur.bufferInfo(r, t.currentTime, this.config.maxBufferHole).len : NaN
|
|
}
|
|
,
|
|
t.createPlaylistLoader = function() {
|
|
var e = this.config.pLoader
|
|
, t = this.applyPlaylistData
|
|
, r = e || this.config.loader;
|
|
return function() {
|
|
function e(e) {
|
|
this.loader = void 0,
|
|
this.loader = new r(e)
|
|
}
|
|
var n = e.prototype;
|
|
return n.destroy = function() {
|
|
this.loader.destroy()
|
|
}
|
|
,
|
|
n.abort = function() {
|
|
this.loader.abort()
|
|
}
|
|
,
|
|
n.load = function(e, r, i) {
|
|
t(e),
|
|
this.loader.load(e, r, i)
|
|
}
|
|
,
|
|
i(e, [{
|
|
key: "stats",
|
|
get: function() {
|
|
return this.loader.stats
|
|
}
|
|
}, {
|
|
key: "context",
|
|
get: function() {
|
|
return this.loader.context
|
|
}
|
|
}])
|
|
}()
|
|
}
|
|
,
|
|
t.createFragmentLoader = function() {
|
|
var e = this.config.fLoader
|
|
, t = this.applyFragmentData
|
|
, r = e || this.config.loader;
|
|
return function() {
|
|
function e(e) {
|
|
this.loader = void 0,
|
|
this.loader = new r(e)
|
|
}
|
|
var n = e.prototype;
|
|
return n.destroy = function() {
|
|
this.loader.destroy()
|
|
}
|
|
,
|
|
n.abort = function() {
|
|
this.loader.abort()
|
|
}
|
|
,
|
|
n.load = function(e, r, i) {
|
|
t(e),
|
|
this.loader.load(e, r, i)
|
|
}
|
|
,
|
|
i(e, [{
|
|
key: "stats",
|
|
get: function() {
|
|
return this.loader.stats
|
|
}
|
|
}, {
|
|
key: "context",
|
|
get: function() {
|
|
return this.loader.context
|
|
}
|
|
}])
|
|
}()
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, Cs = function(e) {
|
|
function t(t) {
|
|
var r;
|
|
return (r = e.call(this, "content-steering", t.logger) || this).hls = void 0,
|
|
r.loader = null,
|
|
r.uri = null,
|
|
r.pathwayId = ".",
|
|
r._pathwayPriority = null,
|
|
r.timeToLoad = 300,
|
|
r.reloadTimer = -1,
|
|
r.updated = 0,
|
|
r.started = !1,
|
|
r.enabled = !0,
|
|
r.levels = null,
|
|
r.audioTracks = null,
|
|
r.subtitleTracks = null,
|
|
r.penalizedPathways = {},
|
|
r.hls = t,
|
|
r.registerListeners(),
|
|
r
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.registerListeners = function() {
|
|
var e = this.hls;
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.MANIFEST_LOADED, this.onManifestLoaded, this),
|
|
e.on(b.MANIFEST_PARSED, this.onManifestParsed, this),
|
|
e.on(b.ERROR, this.onError, this)
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.MANIFEST_LOADED, this.onManifestLoaded, this),
|
|
e.off(b.MANIFEST_PARSED, this.onManifestParsed, this),
|
|
e.off(b.ERROR, this.onError, this))
|
|
}
|
|
,
|
|
r.pathways = function() {
|
|
return (this.levels || []).reduce((function(e, t) {
|
|
return -1 === e.indexOf(t.pathwayId) && e.push(t.pathwayId),
|
|
e
|
|
}
|
|
), [])
|
|
}
|
|
,
|
|
r.startLoad = function() {
|
|
if (this.started = !0,
|
|
this.clearTimeout(),
|
|
this.enabled && this.uri) {
|
|
if (this.updated) {
|
|
var e = 1e3 * this.timeToLoad - (performance.now() - this.updated);
|
|
if (e > 0)
|
|
return void this.scheduleRefresh(this.uri, e)
|
|
}
|
|
this.loadSteeringManifest(this.uri)
|
|
}
|
|
}
|
|
,
|
|
r.stopLoad = function() {
|
|
this.started = !1,
|
|
this.loader && (this.loader.destroy(),
|
|
this.loader = null),
|
|
this.clearTimeout()
|
|
}
|
|
,
|
|
r.clearTimeout = function() {
|
|
-1 !== this.reloadTimer && (self.clearTimeout(this.reloadTimer),
|
|
this.reloadTimer = -1)
|
|
}
|
|
,
|
|
r.destroy = function() {
|
|
this.unregisterListeners(),
|
|
this.stopLoad(),
|
|
this.hls = null,
|
|
this.levels = this.audioTracks = this.subtitleTracks = null
|
|
}
|
|
,
|
|
r.removeLevel = function(e) {
|
|
var t = this.levels;
|
|
t && (this.levels = t.filter((function(t) {
|
|
return t !== e
|
|
}
|
|
)))
|
|
}
|
|
,
|
|
r.onManifestLoading = function() {
|
|
this.stopLoad(),
|
|
this.enabled = !0,
|
|
this.timeToLoad = 300,
|
|
this.updated = 0,
|
|
this.uri = null,
|
|
this.pathwayId = ".",
|
|
this.levels = this.audioTracks = this.subtitleTracks = null
|
|
}
|
|
,
|
|
r.onManifestLoaded = function(e, t) {
|
|
var r = t.contentSteering;
|
|
null !== r && (this.pathwayId = r.pathwayId,
|
|
this.uri = r.uri,
|
|
this.started && this.startLoad())
|
|
}
|
|
,
|
|
r.onManifestParsed = function(e, t) {
|
|
this.audioTracks = t.audioTracks,
|
|
this.subtitleTracks = t.subtitleTracks
|
|
}
|
|
,
|
|
r.onError = function(e, t) {
|
|
var r = t.errorAction;
|
|
if ((null == r ? void 0 : r.action) === wt && r.flags === Ft) {
|
|
var i = this.levels
|
|
, n = this._pathwayPriority
|
|
, a = this.pathwayId;
|
|
if (t.context) {
|
|
var s = t.context
|
|
, o = s.groupId
|
|
, l = s.pathwayId
|
|
, u = s.type;
|
|
o && i ? a = this.getPathwayForGroupId(o, u, a) : l && (a = l)
|
|
}
|
|
a in this.penalizedPathways || (this.penalizedPathways[a] = performance.now()),
|
|
!n && i && (n = this.pathways()),
|
|
n && n.length > 1 && (this.updatePathwayPriority(n),
|
|
r.resolved = this.pathwayId !== a),
|
|
t.details !== k.BUFFER_APPEND_ERROR || t.fatal ? r.resolved || this.warn("Could not resolve " + t.details + ' ("' + t.error.message + '") with content-steering for Pathway: ' + a + " levels: " + (i ? i.length : i) + " priorities: " + lt(n) + " penalized: " + lt(this.penalizedPathways)) : r.resolved = !0
|
|
}
|
|
}
|
|
,
|
|
r.filterParsedLevels = function(e) {
|
|
this.levels = e;
|
|
var t = this.getLevelsForPathway(this.pathwayId);
|
|
if (0 === t.length) {
|
|
var r = e[0].pathwayId;
|
|
this.log("No levels found in Pathway " + this.pathwayId + '. Setting initial Pathway to "' + r + '"'),
|
|
t = this.getLevelsForPathway(r),
|
|
this.pathwayId = r
|
|
}
|
|
return t.length !== e.length && this.log("Found " + t.length + "/" + e.length + ' levels in Pathway "' + this.pathwayId + '"'),
|
|
t
|
|
}
|
|
,
|
|
r.getLevelsForPathway = function(e) {
|
|
return null === this.levels ? [] : this.levels.filter((function(t) {
|
|
return e === t.pathwayId
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.updatePathwayPriority = function(e) {
|
|
var t;
|
|
this._pathwayPriority = e;
|
|
var r = this.penalizedPathways
|
|
, i = performance.now();
|
|
Object.keys(r).forEach((function(e) {
|
|
i - r[e] > 3e5 && delete r[e]
|
|
}
|
|
));
|
|
for (var n = 0; n < e.length; n++) {
|
|
var a = e[n];
|
|
if (!(a in r)) {
|
|
if (a === this.pathwayId)
|
|
return;
|
|
var s = this.hls.nextLoadLevel
|
|
, o = this.hls.levels[s];
|
|
if ((t = this.getLevelsForPathway(a)).length > 0) {
|
|
this.log('Setting Pathway to "' + a + '"'),
|
|
this.pathwayId = a,
|
|
vi(t),
|
|
this.hls.trigger(b.LEVELS_UPDATED, {
|
|
levels: t
|
|
});
|
|
var l = this.hls.levels[s];
|
|
o && l && this.levels && (l.attrs["STABLE-VARIANT-ID"] !== o.attrs["STABLE-VARIANT-ID"] && l.bitrate !== o.bitrate && this.log("Unstable Pathways change from bitrate " + o.bitrate + " to " + l.bitrate),
|
|
this.hls.nextLoadLevel = s);
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.getPathwayForGroupId = function(e, t, r) {
|
|
for (var i = this.getLevelsForPathway(r).concat(this.levels || []), n = 0; n < i.length; n++)
|
|
if (t === P && i[n].hasAudioGroup(e) || t === C && i[n].hasSubtitleGroup(e))
|
|
return i[n].pathwayId;
|
|
return r
|
|
}
|
|
,
|
|
r.clonePathways = function(e) {
|
|
var t = this
|
|
, r = this.levels;
|
|
if (r) {
|
|
var i = {}
|
|
, n = {};
|
|
e.forEach((function(e) {
|
|
var a = e.ID
|
|
, s = e["BASE-ID"]
|
|
, o = e["URI-REPLACEMENT"];
|
|
if (!r.some((function(e) {
|
|
return e.pathwayId === a
|
|
}
|
|
))) {
|
|
var l = t.getLevelsForPathway(s).map((function(e) {
|
|
var t = new pr(e.attrs);
|
|
t["PATHWAY-ID"] = a;
|
|
var r = t.AUDIO && t.AUDIO + "_clone_" + a
|
|
, s = t.SUBTITLES && t.SUBTITLES + "_clone_" + a;
|
|
r && (i[t.AUDIO] = r,
|
|
t.AUDIO = r),
|
|
s && (n[t.SUBTITLES] = s,
|
|
t.SUBTITLES = s);
|
|
var l = Os(e.uri, t["STABLE-VARIANT-ID"], "PER-VARIANT-URIS", o)
|
|
, u = new at({
|
|
attrs: t,
|
|
audioCodec: e.audioCodec,
|
|
bitrate: e.bitrate,
|
|
height: e.height,
|
|
name: e.name,
|
|
url: l,
|
|
videoCodec: e.videoCodec,
|
|
width: e.width
|
|
});
|
|
if (e.audioGroups)
|
|
for (var d = 1; d < e.audioGroups.length; d++)
|
|
u.addGroupId("audio", e.audioGroups[d] + "_clone_" + a);
|
|
if (e.subtitleGroups)
|
|
for (var h = 1; h < e.subtitleGroups.length; h++)
|
|
u.addGroupId("text", e.subtitleGroups[h] + "_clone_" + a);
|
|
return u
|
|
}
|
|
));
|
|
r.push.apply(r, l),
|
|
ws(t.audioTracks, i, o, a),
|
|
ws(t.subtitleTracks, n, o, a)
|
|
}
|
|
}
|
|
))
|
|
}
|
|
}
|
|
,
|
|
r.loadSteeringManifest = function(e) {
|
|
var t, r = this, i = this.hls.config, n = i.loader;
|
|
this.loader && this.loader.destroy(),
|
|
this.loader = new n(i);
|
|
try {
|
|
t = new self.URL(e)
|
|
} catch (t) {
|
|
return this.enabled = !1,
|
|
void this.log("Failed to parse Steering Manifest URI: " + e)
|
|
}
|
|
if ("data:" !== t.protocol) {
|
|
var a = 0 | (this.hls.bandwidthEstimate || i.abrEwmaDefaultEstimate);
|
|
t.searchParams.set("_HLS_pathway", this.pathwayId),
|
|
t.searchParams.set("_HLS_throughput", "" + a)
|
|
}
|
|
var s = {
|
|
responseType: "json",
|
|
url: t.href
|
|
}
|
|
, o = i.steeringManifestLoadPolicy.default
|
|
, l = o.errorRetry || o.timeoutRetry || {}
|
|
, u = {
|
|
loadPolicy: o,
|
|
timeout: o.maxLoadTimeMs,
|
|
maxRetry: l.maxNumRetry || 0,
|
|
retryDelay: l.retryDelayMs || 0,
|
|
maxRetryDelay: l.maxRetryDelayMs || 0
|
|
}
|
|
, d = {
|
|
onSuccess: function(e, i, n, a) {
|
|
r.log('Loaded steering manifest: "' + t + '"');
|
|
var s = e.data;
|
|
if (1 === (null == s ? void 0 : s.VERSION)) {
|
|
r.updated = performance.now(),
|
|
r.timeToLoad = s.TTL;
|
|
var o = s["RELOAD-URI"]
|
|
, l = s["PATHWAY-CLONES"]
|
|
, u = s["PATHWAY-PRIORITY"];
|
|
if (o)
|
|
try {
|
|
r.uri = new self.URL(o,t).href
|
|
} catch (e) {
|
|
return r.enabled = !1,
|
|
void r.log("Failed to parse Steering Manifest RELOAD-URI: " + o)
|
|
}
|
|
r.scheduleRefresh(r.uri || n.url),
|
|
l && r.clonePathways(l);
|
|
var d = {
|
|
steeringManifest: s,
|
|
url: t.toString()
|
|
};
|
|
r.hls.trigger(b.STEERING_MANIFEST_LOADED, d),
|
|
u && r.updatePathwayPriority(u)
|
|
} else
|
|
r.log("Steering VERSION " + s.VERSION + " not supported!")
|
|
},
|
|
onError: function(e, t, i, n) {
|
|
if (r.log("Error loading steering manifest: " + e.code + " " + e.text + " (" + t.url + ")"),
|
|
r.stopLoad(),
|
|
410 === e.code)
|
|
return r.enabled = !1,
|
|
void r.log("Steering manifest " + t.url + " no longer available");
|
|
var a = 1e3 * r.timeToLoad;
|
|
if (429 !== e.code)
|
|
r.scheduleRefresh(r.uri || t.url, a);
|
|
else {
|
|
var s = r.loader;
|
|
if ("function" == typeof (null == s ? void 0 : s.getResponseHeader)) {
|
|
var o = s.getResponseHeader("Retry-After");
|
|
o && (a = 1e3 * parseFloat(o))
|
|
}
|
|
r.log("Steering manifest " + t.url + " rate limited")
|
|
}
|
|
},
|
|
onTimeout: function(e, t, i) {
|
|
r.log("Timeout loading steering manifest (" + t.url + ")"),
|
|
r.scheduleRefresh(r.uri || t.url)
|
|
}
|
|
};
|
|
this.log("Requesting steering manifest: " + t),
|
|
this.loader.load(s, u, d)
|
|
}
|
|
,
|
|
r.scheduleRefresh = function(e, t) {
|
|
var r = this;
|
|
void 0 === t && (t = 1e3 * this.timeToLoad),
|
|
this.clearTimeout(),
|
|
this.reloadTimer = self.setTimeout((function() {
|
|
var t, i = null == (t = r.hls) ? void 0 : t.media;
|
|
!i || i.ended ? r.scheduleRefresh(e, 1e3 * r.timeToLoad) : r.loadSteeringManifest(e)
|
|
}
|
|
), t)
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "pathwayPriority",
|
|
get: function() {
|
|
return this._pathwayPriority
|
|
},
|
|
set: function(e) {
|
|
this.updatePathwayPriority(e)
|
|
}
|
|
}])
|
|
}(N);
|
|
function ws(e, t, r, i) {
|
|
e && Object.keys(t).forEach((function(n) {
|
|
var s = e.filter((function(e) {
|
|
return e.groupId === n
|
|
}
|
|
)).map((function(e) {
|
|
var s = a({}, e);
|
|
return s.details = void 0,
|
|
s.attrs = new pr(s.attrs),
|
|
s.url = s.attrs.URI = Os(e.url, e.attrs["STABLE-RENDITION-ID"], "PER-RENDITION-URIS", r),
|
|
s.groupId = s.attrs["GROUP-ID"] = t[n],
|
|
s.attrs["PATHWAY-ID"] = i,
|
|
s
|
|
}
|
|
));
|
|
e.push.apply(e, s)
|
|
}
|
|
))
|
|
}
|
|
function Os(e, t, r, i) {
|
|
var n, a = i.HOST, s = i.PARAMS, o = i[r];
|
|
t && (n = null == o ? void 0 : o[t]) && (e = n);
|
|
var l = new self.URL(e);
|
|
return a && !n && (l.host = a),
|
|
s && Object.keys(s).sort().forEach((function(e) {
|
|
e && l.searchParams.set(e, s[e])
|
|
}
|
|
)),
|
|
l.href
|
|
}
|
|
var xs = function(e) {
|
|
function t(r) {
|
|
var i;
|
|
return (i = e.call(this, "eme", r.logger) || this).hls = void 0,
|
|
i.config = void 0,
|
|
i.media = null,
|
|
i.keyFormatPromise = null,
|
|
i.keySystemAccessPromises = {},
|
|
i._requestLicenseFailureCount = 0,
|
|
i.mediaKeySessions = [],
|
|
i.keyIdToKeySessionPromise = {},
|
|
i.mediaKeys = null,
|
|
i.setMediaKeysQueue = t.CDMCleanupPromise ? [t.CDMCleanupPromise] : [],
|
|
i.bannedKeyIds = {},
|
|
i.onMediaEncrypted = function(e) {
|
|
var t = e.initDataType
|
|
, r = e.initData
|
|
, n = '"' + e.type + '" event: init data type: "' + t + '"';
|
|
if (i.debug(n),
|
|
null !== r) {
|
|
if (!i.keyFormatPromise) {
|
|
var a = Object.keys(i.keySystemAccessPromises);
|
|
a.length || (a = Nr(i.config));
|
|
var s = a.map(Fr).filter((function(e) {
|
|
return !!e
|
|
}
|
|
));
|
|
i.keyFormatPromise = i.getKeyFormatPromise(s)
|
|
}
|
|
i.keyFormatPromise.then((function(a) {
|
|
var s = Mr(a);
|
|
if ("sinf" === t && s === Pr.FAIRPLAY) {
|
|
var o;
|
|
try {
|
|
var l = le(new Uint8Array(r))
|
|
, u = Se(Rr(JSON.parse(l).sinf));
|
|
if (!u)
|
|
throw new Error("'schm' box missing or not cbcs/cenc with schi > tenc");
|
|
o = new Uint8Array(u.subarray(8, 24))
|
|
} catch (e) {
|
|
return void i.warn(n + " Failed to parse sinf: " + e)
|
|
}
|
|
for (var d, h = X(o), f = i, c = f.keyIdToKeySessionPromise, g = f.mediaKeySessions, v = c[h], m = function() {
|
|
var e = g[p]
|
|
, n = e.decryptdata;
|
|
if (!n.keyId)
|
|
return 0;
|
|
var a = X(n.keyId);
|
|
return Sr(o, n.keyId) || -1 !== n.uri.replace(/-/g, "").indexOf(h) ? (v = c[a]) ? (n.pssh || (delete c[a],
|
|
n.pssh = new Uint8Array(r),
|
|
n.keyId = o,
|
|
(v = c[h] = v.then((function() {
|
|
return i.generateRequestWithPreferredKeySession(e, t, r, "encrypted-event-key-match")
|
|
}
|
|
))).catch((function(e) {
|
|
return i.handleError(e)
|
|
}
|
|
))),
|
|
1) : 0 : void 0
|
|
}, p = 0; p < g.length && (0 === (d = m()) || 1 !== d); p++)
|
|
;
|
|
v || i.handleError(new Error("Key ID " + h + " not encountered in playlist. Key-system sessions " + g.length + "."))
|
|
} else
|
|
i.log('Ignoring "' + e.type + '" event with init data type: "' + t + '" for selected key-system ' + s)
|
|
}
|
|
)).catch((function(e) {
|
|
return i.handleError(e)
|
|
}
|
|
))
|
|
}
|
|
}
|
|
,
|
|
i.onWaitingForKey = function(e) {
|
|
i.log('"' + e.type + '" event')
|
|
}
|
|
,
|
|
i.hls = r,
|
|
i.config = r.config,
|
|
i.registerListeners(),
|
|
i
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.destroy = function() {
|
|
this.onDestroying(),
|
|
this.onMediaDetached();
|
|
var e = this.config;
|
|
e.requestMediaKeySystemAccessFunc = null,
|
|
e.licenseXhrSetup = e.licenseResponseCallback = void 0,
|
|
e.drmSystems = e.drmSystemOptions = {},
|
|
this.hls = this.config = this.keyIdToKeySessionPromise = null,
|
|
this.onMediaEncrypted = this.onWaitingForKey = null
|
|
}
|
|
,
|
|
r.registerListeners = function() {
|
|
this.hls.on(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
this.hls.on(b.MEDIA_DETACHED, this.onMediaDetached, this),
|
|
this.hls.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
this.hls.on(b.MANIFEST_LOADED, this.onManifestLoaded, this),
|
|
this.hls.on(b.DESTROYING, this.onDestroying, this)
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
this.hls.off(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
this.hls.off(b.MEDIA_DETACHED, this.onMediaDetached, this),
|
|
this.hls.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
this.hls.off(b.MANIFEST_LOADED, this.onManifestLoaded, this),
|
|
this.hls.off(b.DESTROYING, this.onDestroying, this)
|
|
}
|
|
,
|
|
r.getLicenseServerUrl = function(e) {
|
|
var t = this.config
|
|
, r = t.drmSystems
|
|
, i = t.widevineLicenseUrl
|
|
, n = null == r ? void 0 : r[e];
|
|
return n ? n.licenseUrl : e === Pr.WIDEVINE && i ? i : void 0
|
|
}
|
|
,
|
|
r.getLicenseServerUrlOrThrow = function(e) {
|
|
var t = this.getLicenseServerUrl(e);
|
|
if (void 0 === t)
|
|
throw new Error('no license server URL configured for key-system "' + e + '"');
|
|
return t
|
|
}
|
|
,
|
|
r.getServerCertificateUrl = function(e) {
|
|
var t = this.config.drmSystems
|
|
, r = null == t ? void 0 : t[e];
|
|
if (r)
|
|
return r.serverCertificateUrl;
|
|
this.log('No Server Certificate in config.drmSystems["' + e + '"]')
|
|
}
|
|
,
|
|
r.attemptKeySystemAccess = function(e) {
|
|
var t = this
|
|
, r = this.hls.levels
|
|
, i = function(e, t, r) {
|
|
return !!e && r.indexOf(e) === t
|
|
}
|
|
, n = r.map((function(e) {
|
|
return e.audioCodec
|
|
}
|
|
)).filter(i)
|
|
, a = r.map((function(e) {
|
|
return e.videoCodec
|
|
}
|
|
)).filter(i);
|
|
return n.length + a.length === 0 && a.push("avc1.42e01e"),
|
|
new Promise((function(r, i) {
|
|
var s = function(e) {
|
|
var o = e.shift();
|
|
t.getMediaKeysPromise(o, n, a).then((function(e) {
|
|
return r({
|
|
keySystem: o,
|
|
mediaKeys: e
|
|
})
|
|
}
|
|
)).catch((function(t) {
|
|
e.length ? s(e) : i(t instanceof Ns ? t : new Ns({
|
|
type: R.KEY_SYSTEM_ERROR,
|
|
details: k.KEY_SYSTEM_NO_ACCESS,
|
|
error: t,
|
|
fatal: !0
|
|
},t.message))
|
|
}
|
|
))
|
|
};
|
|
s(e)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.requestMediaKeySystemAccess = function(e, t) {
|
|
var r = this.config.requestMediaKeySystemAccessFunc;
|
|
if ("function" != typeof r) {
|
|
var i = "Configured requestMediaKeySystemAccess is not a function " + r;
|
|
return null === Br && "http:" === self.location.protocol && (i = "navigator.requestMediaKeySystemAccess is not available over insecure protocol " + location.protocol),
|
|
Promise.reject(new Error(i))
|
|
}
|
|
return r(e, t)
|
|
}
|
|
,
|
|
r.getMediaKeysPromise = function(e, t, r) {
|
|
var i, n = this, a = function(e, t, r, i) {
|
|
var n;
|
|
switch (e) {
|
|
case Pr.FAIRPLAY:
|
|
n = ["cenc", "sinf"];
|
|
break;
|
|
case Pr.WIDEVINE:
|
|
case Pr.PLAYREADY:
|
|
n = ["cenc"];
|
|
break;
|
|
case Pr.CLEARKEY:
|
|
n = ["cenc", "keyids"];
|
|
break;
|
|
default:
|
|
throw new Error("Unknown key-system: " + e)
|
|
}
|
|
return function(e, t, r, i) {
|
|
return [{
|
|
initDataTypes: e,
|
|
persistentState: i.persistentState || "optional",
|
|
distinctiveIdentifier: i.distinctiveIdentifier || "optional",
|
|
sessionTypes: i.sessionTypes || [i.sessionType || "temporary"],
|
|
audioCapabilities: t.map((function(e) {
|
|
return {
|
|
contentType: "audio/mp4; codecs=" + e,
|
|
robustness: i.audioRobustness || "",
|
|
encryptionScheme: i.audioEncryptionScheme || null
|
|
}
|
|
}
|
|
)),
|
|
videoCapabilities: r.map((function(e) {
|
|
return {
|
|
contentType: "video/mp4; codecs=" + e,
|
|
robustness: i.videoRobustness || "",
|
|
encryptionScheme: i.videoEncryptionScheme || null
|
|
}
|
|
}
|
|
))
|
|
}]
|
|
}(n, t, r, i)
|
|
}(e, t, r, this.config.drmSystemOptions || {}), s = this.keySystemAccessPromises[e], o = null == (i = s) ? void 0 : i.keySystemAccess;
|
|
if (!o) {
|
|
this.log('Requesting encrypted media "' + e + '" key-system access with config: ' + lt(a)),
|
|
o = this.requestMediaKeySystemAccess(e, a);
|
|
var l = s = this.keySystemAccessPromises[e] = {
|
|
keySystemAccess: o
|
|
};
|
|
return o.catch((function(t) {
|
|
n.log('Failed to obtain access to key-system "' + e + '": ' + t)
|
|
}
|
|
)),
|
|
o.then((function(t) {
|
|
n.log('Access for key-system "' + t.keySystem + '" obtained');
|
|
var r = n.fetchServerCertificate(e);
|
|
n.log('Create media-keys for "' + e + '"');
|
|
var i = l.mediaKeys = t.createMediaKeys().then((function(t) {
|
|
return n.log('Media-keys created for "' + e + '"'),
|
|
l.hasMediaKeys = !0,
|
|
r.then((function(r) {
|
|
return r ? n.setMediaKeysServerCertificate(t, e, r) : t
|
|
}
|
|
))
|
|
}
|
|
));
|
|
return i.catch((function(t) {
|
|
n.error('Failed to create media-keys for "' + e + '"}: ' + t)
|
|
}
|
|
)),
|
|
i
|
|
}
|
|
))
|
|
}
|
|
return o.then((function() {
|
|
return s.mediaKeys
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.createMediaKeySessionContext = function(e) {
|
|
var t = e.decryptdata
|
|
, r = e.keySystem
|
|
, i = e.mediaKeys;
|
|
this.log('Creating key-system session "' + r + '" keyId: ' + X(t.keyId || []) + " keyUri: " + t.uri);
|
|
var n = i.createSession()
|
|
, a = {
|
|
decryptdata: t,
|
|
keySystem: r,
|
|
mediaKeys: i,
|
|
mediaKeysSession: n,
|
|
keyStatus: "status-pending"
|
|
};
|
|
return this.mediaKeySessions.push(a),
|
|
a
|
|
}
|
|
,
|
|
r.renewKeySession = function(e) {
|
|
var t = e.decryptdata;
|
|
if (t.pssh) {
|
|
var r = this.createMediaKeySessionContext(e)
|
|
, i = Ms(t);
|
|
this.keyIdToKeySessionPromise[i] = this.generateRequestWithPreferredKeySession(r, "cenc", t.pssh.buffer, "expired")
|
|
} else
|
|
this.warn("Could not renew expired session. Missing pssh initData.");
|
|
this.removeSession(e)
|
|
}
|
|
,
|
|
r.updateKeySession = function(e, t) {
|
|
var r = e.mediaKeysSession;
|
|
return this.log('Updating key-session "' + r.sessionId + '" for keyId ' + X(e.decryptdata.keyId || []) + "\n } (data length: " + t.byteLength + ")"),
|
|
r.update(t)
|
|
}
|
|
,
|
|
r.getSelectedKeySystemFormats = function() {
|
|
var e = this;
|
|
return Object.keys(this.keySystemAccessPromises).map((function(t) {
|
|
return {
|
|
keySystem: t,
|
|
hasMediaKeys: e.keySystemAccessPromises[t].hasMediaKeys
|
|
}
|
|
}
|
|
)).filter((function(e) {
|
|
return !!e.hasMediaKeys
|
|
}
|
|
)).map((function(e) {
|
|
return Fr(e.keySystem)
|
|
}
|
|
)).filter((function(e) {
|
|
return !!e
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.getKeySystemAccess = function(e) {
|
|
var t = this;
|
|
return this.getKeySystemSelectionPromise(e).then((function(e) {
|
|
var r = e.keySystem
|
|
, i = e.mediaKeys;
|
|
return t.attemptSetMediaKeys(r, i)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.selectKeySystem = function(e) {
|
|
var t = this;
|
|
return new Promise((function(r, i) {
|
|
t.getKeySystemSelectionPromise(e).then((function(e) {
|
|
var t = e.keySystem
|
|
, n = Fr(t);
|
|
n ? r(n) : i(new Error('Unable to find format for key-system "' + t + '"'))
|
|
}
|
|
)).catch(i)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.selectKeySystemFormat = function(e) {
|
|
var t = Object.keys(e.levelkeys || {});
|
|
return this.keyFormatPromise || (this.log("Selecting key-system from fragment (sn: " + e.sn + " " + e.type + ": " + e.level + ") key formats " + t.join(", ")),
|
|
this.keyFormatPromise = this.getKeyFormatPromise(t)),
|
|
this.keyFormatPromise
|
|
}
|
|
,
|
|
r.getKeyFormatPromise = function(e) {
|
|
var t = Nr(this.config)
|
|
, r = e.map(Mr).filter((function(e) {
|
|
return !!e && -1 !== t.indexOf(e)
|
|
}
|
|
));
|
|
return this.selectKeySystem(r)
|
|
}
|
|
,
|
|
r.getKeyStatus = function(e) {
|
|
for (var t = this.mediaKeySessions, r = 0; r < t.length; r++) {
|
|
var i = Fs(e, t[r]);
|
|
if (i)
|
|
return i
|
|
}
|
|
}
|
|
,
|
|
r.loadKey = function(e) {
|
|
var t = this
|
|
, r = e.keyInfo.decryptdata
|
|
, i = Ms(r)
|
|
, n = this.bannedKeyIds[i];
|
|
if (n || "internal-error" === this.getKeyStatus(r)) {
|
|
var a = Us(n || "internal-error", r);
|
|
return this.handleError(a, e.frag),
|
|
Promise.reject(a)
|
|
}
|
|
var s = "(keyId: " + i + ' format: "' + r.keyFormat + '" method: ' + r.method + " uri: " + r.uri + ")";
|
|
this.log("Starting session for key " + s);
|
|
var o = this.keyIdToKeySessionPromise[i];
|
|
if (!o) {
|
|
var l = this.getKeySystemForKeyPromise(r).then((function(i) {
|
|
var n = i.keySystem
|
|
, a = i.mediaKeys;
|
|
return t.throwIfDestroyed(),
|
|
t.log("Handle encrypted media sn: " + e.frag.sn + " " + e.frag.type + ": " + e.frag.level + " using key " + s),
|
|
t.attemptSetMediaKeys(n, a).then((function() {
|
|
return t.throwIfDestroyed(),
|
|
t.createMediaKeySessionContext({
|
|
keySystem: n,
|
|
mediaKeys: a,
|
|
decryptdata: r
|
|
})
|
|
}
|
|
))
|
|
}
|
|
)).then((function(e) {
|
|
var i = r.pssh ? r.pssh.buffer : null;
|
|
return t.generateRequestWithPreferredKeySession(e, "cenc", i, "playlist-key")
|
|
}
|
|
));
|
|
return l.catch((function(r) {
|
|
return t.handleError(r, e.frag)
|
|
}
|
|
)),
|
|
this.keyIdToKeySessionPromise[i] = l,
|
|
l
|
|
}
|
|
return o.catch((function(i) {
|
|
if (i instanceof Ns) {
|
|
var n = d({}, i.data);
|
|
"internal-error" === t.getKeyStatus(r) && (n.decryptdata = r);
|
|
var a = new Ns(n,i.message);
|
|
t.handleError(a, e.frag)
|
|
}
|
|
}
|
|
)),
|
|
o
|
|
}
|
|
,
|
|
r.throwIfDestroyed = function(e) {
|
|
if (!this.hls)
|
|
throw new Error("invalid state")
|
|
}
|
|
,
|
|
r.handleError = function(e, t) {
|
|
if (this.hls)
|
|
if (e instanceof Ns) {
|
|
t && (e.data.frag = t);
|
|
var r = e.data.decryptdata;
|
|
this.error(e.message + (r ? " (" + X(r.keyId || []) + ")" : "")),
|
|
this.hls.trigger(b.ERROR, e.data)
|
|
} else
|
|
this.error(e.message),
|
|
this.hls.trigger(b.ERROR, {
|
|
type: R.KEY_SYSTEM_ERROR,
|
|
details: k.KEY_SYSTEM_NO_KEYS,
|
|
error: e,
|
|
fatal: !0
|
|
})
|
|
}
|
|
,
|
|
r.getKeySystemForKeyPromise = function(e) {
|
|
var t = Ms(e)
|
|
, r = this.keyIdToKeySessionPromise[t];
|
|
if (!r) {
|
|
var i = Mr(e.keyFormat)
|
|
, n = i ? [i] : Nr(this.config);
|
|
return this.attemptKeySystemAccess(n)
|
|
}
|
|
return r
|
|
}
|
|
,
|
|
r.getKeySystemSelectionPromise = function(e) {
|
|
if (e.length || (e = Nr(this.config)),
|
|
0 === e.length)
|
|
throw new Ns({
|
|
type: R.KEY_SYSTEM_ERROR,
|
|
details: k.KEY_SYSTEM_NO_CONFIGURED_LICENSE,
|
|
fatal: !0
|
|
},"Missing key-system license configuration options " + lt({
|
|
drmSystems: this.config.drmSystems
|
|
}));
|
|
return this.attemptKeySystemAccess(e)
|
|
}
|
|
,
|
|
r.attemptSetMediaKeys = function(e, t) {
|
|
var r = this;
|
|
if (this.mediaKeys === t)
|
|
return Promise.resolve();
|
|
var i = this.setMediaKeysQueue.slice();
|
|
this.log('Setting media-keys for "' + e + '"');
|
|
var n = Promise.all(i).then((function() {
|
|
if (!r.media)
|
|
throw r.mediaKeys = null,
|
|
new Error("Attempted to set mediaKeys without media element attached");
|
|
return r.media.setMediaKeys(t)
|
|
}
|
|
));
|
|
return this.mediaKeys = t,
|
|
this.setMediaKeysQueue.push(n),
|
|
n.then((function() {
|
|
r.log('Media-keys set for "' + e + '"'),
|
|
i.push(n),
|
|
r.setMediaKeysQueue = r.setMediaKeysQueue.filter((function(e) {
|
|
return -1 === i.indexOf(e)
|
|
}
|
|
))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.generateRequestWithPreferredKeySession = function(e, t, r, i) {
|
|
var n, a = this, s = null == (n = this.config.drmSystems) || null == (n = n[e.keySystem]) ? void 0 : n.generateRequest;
|
|
if (s)
|
|
try {
|
|
var o = s.call(this.hls, t, r, e);
|
|
if (!o)
|
|
throw new Error("Invalid response from configured generateRequest filter");
|
|
t = o.initDataType,
|
|
r = o.initData ? o.initData : null,
|
|
e.decryptdata.pssh = r ? new Uint8Array(r) : null
|
|
} catch (e) {
|
|
if (this.warn(e.message),
|
|
this.hls && this.hls.config.debug)
|
|
throw e
|
|
}
|
|
if (null === r)
|
|
return this.log('Skipping key-session request for "' + i + '" (no initData)'),
|
|
Promise.resolve(e);
|
|
var l = Ms(e.decryptdata)
|
|
, u = e.decryptdata.uri;
|
|
this.log('Generating key-session request for "' + i + '" keyId: ' + l + " URI: " + u + " (init data type: " + t + " length: " + r.byteLength + ")");
|
|
var d = new E
|
|
, h = e._onmessage = function(t) {
|
|
var r = e.mediaKeysSession;
|
|
if (r) {
|
|
var i = t.messageType
|
|
, n = t.message;
|
|
a.log('"' + i + '" message event for session "' + r.sessionId + '" message size: ' + n.byteLength),
|
|
"license-request" === i || "license-renewal" === i ? a.renewLicense(e, n).catch((function(e) {
|
|
d.eventNames().length ? d.emit("error", e) : a.handleError(e)
|
|
}
|
|
)) : "license-release" === i ? e.keySystem === Pr.FAIRPLAY && a.updateKeySession(e, kr("acknowledged")).then((function() {
|
|
return a.removeSession(e)
|
|
}
|
|
)).catch((function(e) {
|
|
return a.handleError(e)
|
|
}
|
|
)) : a.warn('unhandled media key message type "' + i + '"')
|
|
} else
|
|
d.emit("error", new Error("invalid state"))
|
|
}
|
|
, f = function(e, t) {
|
|
var r;
|
|
t.keyStatus = e,
|
|
e.startsWith("usable") ? d.emit("resolved") : "internal-error" === e || "output-restricted" === e || "output-downscaled" === e ? r = Us(e, t.decryptdata) : "expired" === e ? r = new Error("key expired (keyId: " + l + ")") : "released" === e ? r = new Error("key released") : "status-pending" === e || a.warn('unhandled key status change "' + e + '" (keyId: ' + l + ")"),
|
|
r && (d.eventNames().length ? d.emit("error", r) : a.handleError(r))
|
|
}
|
|
, c = e._onkeystatuseschange = function(t) {
|
|
if (e.mediaKeysSession) {
|
|
var r = a.getKeyStatuses(e);
|
|
if (Object.keys(r).some((function(e) {
|
|
return "status-pending" !== r[e]
|
|
}
|
|
))) {
|
|
if ("expired" === r[l])
|
|
return a.log("Expired key " + lt(r) + ' in key-session "' + e.mediaKeysSession.sessionId + '"'),
|
|
void a.renewKeySession(e);
|
|
var i, n = r[l];
|
|
if (n)
|
|
f(n, e);
|
|
else
|
|
e.keyStatusTimeouts || (e.keyStatusTimeouts = {}),
|
|
(i = e.keyStatusTimeouts)[l] || (i[l] = self.setTimeout((function() {
|
|
if (e.mediaKeysSession && a.mediaKeys) {
|
|
var t = a.getKeyStatus(e.decryptdata);
|
|
if (t && "status-pending" !== t)
|
|
return a.log("No status for keyId " + l + ' in key-session "' + e.mediaKeysSession.sessionId + '". Using session key-status ' + t + " from other session."),
|
|
f(t, e);
|
|
a.log("key status for " + l + ' in key-session "' + e.mediaKeysSession.sessionId + '" timed out after 0ms'),
|
|
f(n = "internal-error", e)
|
|
}
|
|
}
|
|
), 0)),
|
|
a.log("No status for keyId " + l + " (" + lt(r) + ").")
|
|
}
|
|
} else
|
|
d.emit("error", new Error("invalid state"))
|
|
}
|
|
;
|
|
Li(e.mediaKeysSession, "message", h),
|
|
Li(e.mediaKeysSession, "keystatuseschange", c);
|
|
var g = new Promise((function(e, t) {
|
|
d.on("error", t),
|
|
d.on("resolved", e)
|
|
}
|
|
));
|
|
return e.mediaKeysSession.generateRequest(t, r).then((function() {
|
|
a.log('Request generated for key-session "' + e.mediaKeysSession.sessionId + '" keyId: ' + l + " URI: " + u)
|
|
}
|
|
)).catch((function(t) {
|
|
throw new Ns({
|
|
type: R.KEY_SYSTEM_ERROR,
|
|
details: k.KEY_SYSTEM_NO_SESSION,
|
|
error: t,
|
|
decryptdata: e.decryptdata,
|
|
fatal: !1
|
|
},"Error generating key-session request: " + t)
|
|
}
|
|
)).then((function() {
|
|
return g
|
|
}
|
|
)).catch((function(t) {
|
|
return d.removeAllListeners(),
|
|
a.removeSession(e).then((function() {
|
|
throw t
|
|
}
|
|
))
|
|
}
|
|
)).then((function() {
|
|
return d.removeAllListeners(),
|
|
e
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.getKeyStatuses = function(e) {
|
|
var t = this
|
|
, r = {};
|
|
return e.mediaKeysSession.keyStatuses.forEach((function(i, n) {
|
|
if ("string" == typeof n && "object" == typeof i) {
|
|
var a = n;
|
|
n = i,
|
|
i = a
|
|
}
|
|
var s = "buffer"in n ? new Uint8Array(n.buffer,n.byteOffset,n.byteLength) : new Uint8Array(n);
|
|
e.keySystem === Pr.PLAYREADY && 16 === s.length && br(s);
|
|
var o = X(s);
|
|
"internal-error" === i && (t.bannedKeyIds[o] = i),
|
|
t.log('key status change "' + i + '" for keyStatuses keyId: ' + o + ' key-session "' + e.mediaKeysSession.sessionId + '"'),
|
|
r[o] = i
|
|
}
|
|
)),
|
|
r
|
|
}
|
|
,
|
|
r.fetchServerCertificate = function(e) {
|
|
var t = this.config
|
|
, r = new (0,
|
|
t.loader)(t)
|
|
, i = this.getServerCertificateUrl(e);
|
|
return i ? (this.log('Fetching server certificate for "' + e + '"'),
|
|
new Promise((function(n, a) {
|
|
var s = {
|
|
responseType: "arraybuffer",
|
|
url: i
|
|
}
|
|
, o = t.certLoadPolicy.default
|
|
, l = {
|
|
loadPolicy: o,
|
|
timeout: o.maxLoadTimeMs,
|
|
maxRetry: 0,
|
|
retryDelay: 0,
|
|
maxRetryDelay: 0
|
|
}
|
|
, u = {
|
|
onSuccess: function(e, t, r, i) {
|
|
n(e.data)
|
|
},
|
|
onError: function(t, r, n, o) {
|
|
a(new Ns({
|
|
type: R.KEY_SYSTEM_ERROR,
|
|
details: k.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED,
|
|
fatal: !0,
|
|
networkDetails: n,
|
|
response: d({
|
|
url: s.url,
|
|
data: void 0
|
|
}, t)
|
|
},'"' + e + '" certificate request failed (' + i + "). Status: " + t.code + " (" + t.text + ")"))
|
|
},
|
|
onTimeout: function(t, r, n) {
|
|
a(new Ns({
|
|
type: R.KEY_SYSTEM_ERROR,
|
|
details: k.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED,
|
|
fatal: !0,
|
|
networkDetails: n,
|
|
response: {
|
|
url: s.url,
|
|
data: void 0
|
|
}
|
|
},'"' + e + '" certificate request timed out (' + i + ")"))
|
|
},
|
|
onAbort: function(e, t, r) {
|
|
a(new Error("aborted"))
|
|
}
|
|
};
|
|
r.load(s, l, u)
|
|
}
|
|
))) : Promise.resolve()
|
|
}
|
|
,
|
|
r.setMediaKeysServerCertificate = function(e, t, r) {
|
|
var i = this;
|
|
return new Promise((function(n, a) {
|
|
e.setServerCertificate(r).then((function(a) {
|
|
i.log("setServerCertificate " + (a ? "success" : "not supported by CDM") + " (" + r.byteLength + ') on "' + t + '"'),
|
|
n(e)
|
|
}
|
|
)).catch((function(e) {
|
|
a(new Ns({
|
|
type: R.KEY_SYSTEM_ERROR,
|
|
details: k.KEY_SYSTEM_SERVER_CERTIFICATE_UPDATE_FAILED,
|
|
error: e,
|
|
fatal: !0
|
|
},e.message))
|
|
}
|
|
))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.renewLicense = function(e, t) {
|
|
var r = this;
|
|
return this.requestLicense(e, new Uint8Array(t)).then((function(t) {
|
|
return r.updateKeySession(e, new Uint8Array(t)).catch((function(t) {
|
|
throw new Ns({
|
|
type: R.KEY_SYSTEM_ERROR,
|
|
details: k.KEY_SYSTEM_SESSION_UPDATE_FAILED,
|
|
decryptdata: e.decryptdata,
|
|
error: t,
|
|
fatal: !1
|
|
},t.message)
|
|
}
|
|
))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.unpackPlayReadyKeyMessage = function(e, t) {
|
|
var r = String.fromCharCode.apply(null, new Uint16Array(t.buffer));
|
|
if (!r.includes("PlayReadyKeyMessage"))
|
|
return e.setRequestHeader("Content-Type", "text/xml; charset=utf-8"),
|
|
t;
|
|
var i = (new DOMParser).parseFromString(r, "application/xml")
|
|
, n = i.querySelectorAll("HttpHeader");
|
|
if (n.length > 0)
|
|
for (var a, s = 0, o = n.length; s < o; s++) {
|
|
var l, u, d = null == (l = (a = n[s]).querySelector("name")) ? void 0 : l.textContent, h = null == (u = a.querySelector("value")) ? void 0 : u.textContent;
|
|
d && h && e.setRequestHeader(d, h)
|
|
}
|
|
var f = i.querySelector("Challenge")
|
|
, c = null == f ? void 0 : f.textContent;
|
|
if (!c)
|
|
throw new Error("Cannot find <Challenge> in key message");
|
|
return kr(atob(c))
|
|
}
|
|
,
|
|
r.setupLicenseXHR = function(e, t, r, i) {
|
|
var n = this
|
|
, a = this.config.licenseXhrSetup;
|
|
return a ? Promise.resolve().then((function() {
|
|
if (!r.decryptdata)
|
|
throw new Error("Key removed");
|
|
return a.call(n.hls, e, t, r, i)
|
|
}
|
|
)).catch((function(s) {
|
|
if (!r.decryptdata)
|
|
throw s;
|
|
return e.open("POST", t, !0),
|
|
a.call(n.hls, e, t, r, i)
|
|
}
|
|
)).then((function(r) {
|
|
return e.readyState || e.open("POST", t, !0),
|
|
{
|
|
xhr: e,
|
|
licenseChallenge: r || i
|
|
}
|
|
}
|
|
)) : (e.open("POST", t, !0),
|
|
Promise.resolve({
|
|
xhr: e,
|
|
licenseChallenge: i
|
|
}))
|
|
}
|
|
,
|
|
r.requestLicense = function(e, t) {
|
|
var r = this
|
|
, i = this.config.keyLoadPolicy.default;
|
|
return new Promise((function(n, a) {
|
|
var s = r.getLicenseServerUrlOrThrow(e.keySystem);
|
|
r.log("Sending license request to URL: " + s);
|
|
var o = new XMLHttpRequest;
|
|
o.responseType = "arraybuffer",
|
|
o.onreadystatechange = function() {
|
|
if (!r.hls || !e.mediaKeysSession)
|
|
return a(new Error("invalid state"));
|
|
if (4 === o.readyState)
|
|
if (200 === o.status) {
|
|
r._requestLicenseFailureCount = 0;
|
|
var l = o.response;
|
|
r.log("License received " + (l instanceof ArrayBuffer ? l.byteLength : l));
|
|
var u = r.config.licenseResponseCallback;
|
|
if (u)
|
|
try {
|
|
l = u.call(r.hls, o, s, e)
|
|
} catch (e) {
|
|
r.error(e)
|
|
}
|
|
n(l)
|
|
} else {
|
|
var d = i.errorRetry
|
|
, h = d ? d.maxNumRetry : 0;
|
|
if (r._requestLicenseFailureCount++,
|
|
r._requestLicenseFailureCount > h || o.status >= 400 && o.status < 500)
|
|
a(new Ns({
|
|
type: R.KEY_SYSTEM_ERROR,
|
|
details: k.KEY_SYSTEM_LICENSE_REQUEST_FAILED,
|
|
decryptdata: e.decryptdata,
|
|
fatal: !0,
|
|
networkDetails: o,
|
|
response: {
|
|
url: s,
|
|
data: void 0,
|
|
code: o.status,
|
|
text: o.statusText
|
|
}
|
|
},"License Request XHR failed (" + s + "). Status: " + o.status + " (" + o.statusText + ")"));
|
|
else {
|
|
var f = h - r._requestLicenseFailureCount + 1;
|
|
r.warn("Retrying license request, " + f + " attempts left"),
|
|
r.requestLicense(e, t).then(n, a)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
e.licenseXhr && e.licenseXhr.readyState !== XMLHttpRequest.DONE && e.licenseXhr.abort(),
|
|
e.licenseXhr = o,
|
|
r.setupLicenseXHR(o, s, e, t).then((function(t) {
|
|
var i = t.xhr
|
|
, n = t.licenseChallenge;
|
|
e.keySystem == Pr.PLAYREADY && (n = r.unpackPlayReadyKeyMessage(i, n)),
|
|
i.send(n)
|
|
}
|
|
)).catch(a)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.onDestroying = function() {
|
|
this.unregisterListeners(),
|
|
this._clear()
|
|
}
|
|
,
|
|
r.onMediaAttached = function(e, t) {
|
|
if (this.config.emeEnabled) {
|
|
var r = t.media;
|
|
this.media = r,
|
|
Li(r, "encrypted", this.onMediaEncrypted),
|
|
Li(r, "waitingforkey", this.onWaitingForKey)
|
|
}
|
|
}
|
|
,
|
|
r.onMediaDetached = function() {
|
|
var e = this.media;
|
|
e && (Ii(e, "encrypted", this.onMediaEncrypted),
|
|
Ii(e, "waitingforkey", this.onWaitingForKey),
|
|
this.media = null,
|
|
this.mediaKeys = null)
|
|
}
|
|
,
|
|
r._clear = function() {
|
|
var e, r = this;
|
|
if (this._requestLicenseFailureCount = 0,
|
|
this.keyIdToKeySessionPromise = {},
|
|
this.bannedKeyIds = {},
|
|
this.mediaKeys || this.mediaKeySessions.length) {
|
|
var i = this.media
|
|
, n = this.mediaKeySessions.slice();
|
|
this.mediaKeySessions = [],
|
|
this.mediaKeys = null,
|
|
Kr.clearKeyUriToKeyIdMap();
|
|
var a = n.length;
|
|
t.CDMCleanupPromise = Promise.all(n.map((function(e) {
|
|
return r.removeSession(e)
|
|
}
|
|
)).concat((null == i || null == (e = i.setMediaKeys(null)) ? void 0 : e.catch((function(e) {
|
|
r.log("Could not clear media keys: " + e),
|
|
r.hls && r.hls.trigger(b.ERROR, {
|
|
type: R.OTHER_ERROR,
|
|
details: k.KEY_SYSTEM_DESTROY_MEDIA_KEYS_ERROR,
|
|
fatal: !1,
|
|
error: new Error("Could not clear media keys: " + e)
|
|
})
|
|
}
|
|
))) || Promise.resolve())).catch((function(e) {
|
|
r.log("Could not close sessions and clear media keys: " + e),
|
|
r.hls && r.hls.trigger(b.ERROR, {
|
|
type: R.OTHER_ERROR,
|
|
details: k.KEY_SYSTEM_DESTROY_CLOSE_SESSION_ERROR,
|
|
fatal: !1,
|
|
error: new Error("Could not close sessions and clear media keys: " + e)
|
|
})
|
|
}
|
|
)).then((function() {
|
|
a && r.log("finished closing key sessions and clearing media keys")
|
|
}
|
|
))
|
|
}
|
|
}
|
|
,
|
|
r.onManifestLoading = function() {
|
|
this.keyFormatPromise = null,
|
|
this.bannedKeyIds = {}
|
|
}
|
|
,
|
|
r.onManifestLoaded = function(e, t) {
|
|
var r = t.sessionKeys;
|
|
if (r && this.config.emeEnabled && !this.keyFormatPromise) {
|
|
var i = r.reduce((function(e, t) {
|
|
return -1 === e.indexOf(t.keyFormat) && e.push(t.keyFormat),
|
|
e
|
|
}
|
|
), []);
|
|
this.log("Selecting key-system from session-keys " + i.join(", ")),
|
|
this.keyFormatPromise = this.getKeyFormatPromise(i)
|
|
}
|
|
}
|
|
,
|
|
r.removeSession = function(e) {
|
|
var t = this
|
|
, r = e.mediaKeysSession
|
|
, i = e.licenseXhr
|
|
, n = e.decryptdata;
|
|
if (r) {
|
|
this.log('Remove licenses and keys and close session "' + r.sessionId + '" keyId: ' + X((null == n ? void 0 : n.keyId) || [])),
|
|
e._onmessage && (r.removeEventListener("message", e._onmessage),
|
|
e._onmessage = void 0),
|
|
e._onkeystatuseschange && (r.removeEventListener("keystatuseschange", e._onkeystatuseschange),
|
|
e._onkeystatuseschange = void 0),
|
|
i && i.readyState !== XMLHttpRequest.DONE && i.abort(),
|
|
e.mediaKeysSession = e.decryptdata = e.licenseXhr = void 0;
|
|
var a = this.mediaKeySessions.indexOf(e);
|
|
a > -1 && this.mediaKeySessions.splice(a, 1);
|
|
var s = e.keyStatusTimeouts;
|
|
s && Object.keys(s).forEach((function(e) {
|
|
return self.clearTimeout(s[e])
|
|
}
|
|
));
|
|
var o = function(e) {
|
|
var t;
|
|
return !(!e || "persistent-license" !== e.sessionType && (null == (t = e.sessionTypes) || !t.some((function(e) {
|
|
return "persistent-license" === e
|
|
}
|
|
))))
|
|
}(this.config.drmSystemOptions) ? new Promise((function(e, t) {
|
|
self.setTimeout((function() {
|
|
return t(new Error("MediaKeySession.remove() timeout"))
|
|
}
|
|
), 8e3),
|
|
r.remove().then(e).catch(t)
|
|
}
|
|
)) : Promise.resolve();
|
|
return o.catch((function(e) {
|
|
t.log("Could not remove session: " + e),
|
|
t.hls && t.hls.trigger(b.ERROR, {
|
|
type: R.OTHER_ERROR,
|
|
details: k.KEY_SYSTEM_DESTROY_REMOVE_SESSION_ERROR,
|
|
fatal: !1,
|
|
error: new Error("Could not remove session: " + e)
|
|
})
|
|
}
|
|
)).then((function() {
|
|
return r.close()
|
|
}
|
|
)).catch((function(e) {
|
|
t.log("Could not close session: " + e),
|
|
t.hls && t.hls.trigger(b.ERROR, {
|
|
type: R.OTHER_ERROR,
|
|
details: k.KEY_SYSTEM_DESTROY_CLOSE_SESSION_ERROR,
|
|
fatal: !1,
|
|
error: new Error("Could not close session: " + e)
|
|
})
|
|
}
|
|
))
|
|
}
|
|
return Promise.resolve()
|
|
}
|
|
,
|
|
t
|
|
}(N);
|
|
function Ms(e) {
|
|
if (!e)
|
|
throw new Error("Could not read keyId of undefined decryptdata");
|
|
if (null === e.keyId)
|
|
throw new Error("keyId is null");
|
|
return X(e.keyId)
|
|
}
|
|
function Fs(e, t) {
|
|
return e.keyId && t.mediaKeysSession.keyStatuses.has(e.keyId) ? t.mediaKeysSession.keyStatuses.get(e.keyId) : e.matches(t.decryptdata) ? t.keyStatus : void 0
|
|
}
|
|
xs.CDMCleanupPromise = void 0;
|
|
var Ns = function(e) {
|
|
function t(t, r) {
|
|
var i;
|
|
return (i = e.call(this, r) || this).data = void 0,
|
|
t.error || (t.error = new Error(r)),
|
|
i.data = t,
|
|
t.err = t.error,
|
|
i
|
|
}
|
|
return o(t, e),
|
|
t
|
|
}(c(Error));
|
|
function Us(e, t) {
|
|
var r = "output-restricted" === e
|
|
, i = r ? k.KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED : k.KEY_SYSTEM_STATUS_INTERNAL_ERROR;
|
|
return new Ns({
|
|
type: R.KEY_SYSTEM_ERROR,
|
|
details: i,
|
|
fatal: !1,
|
|
decryptdata: t
|
|
},r ? "HDCP level output restricted" : 'key status changed to "' + e + '"')
|
|
}
|
|
var Bs = function() {
|
|
function e(e) {
|
|
this.hls = void 0,
|
|
this.isVideoPlaybackQualityAvailable = !1,
|
|
this.timer = void 0,
|
|
this.media = null,
|
|
this.lastTime = void 0,
|
|
this.lastDroppedFrames = 0,
|
|
this.lastDecodedFrames = 0,
|
|
this.streamController = void 0,
|
|
this.hls = e,
|
|
this.registerListeners()
|
|
}
|
|
var t = e.prototype;
|
|
return t.setStreamController = function(e) {
|
|
this.streamController = e
|
|
}
|
|
,
|
|
t.registerListeners = function() {
|
|
this.hls.on(b.MEDIA_ATTACHING, this.onMediaAttaching, this),
|
|
this.hls.on(b.MEDIA_DETACHING, this.onMediaDetaching, this)
|
|
}
|
|
,
|
|
t.unregisterListeners = function() {
|
|
this.hls.off(b.MEDIA_ATTACHING, this.onMediaAttaching, this),
|
|
this.hls.off(b.MEDIA_DETACHING, this.onMediaDetaching, this)
|
|
}
|
|
,
|
|
t.destroy = function() {
|
|
this.timer && clearInterval(this.timer),
|
|
this.unregisterListeners(),
|
|
this.isVideoPlaybackQualityAvailable = !1,
|
|
this.media = null
|
|
}
|
|
,
|
|
t.onMediaAttaching = function(e, t) {
|
|
var r = this.hls.config;
|
|
if (r.capLevelOnFPSDrop) {
|
|
var i = t.media instanceof self.HTMLVideoElement ? t.media : null;
|
|
this.media = i,
|
|
i && "function" == typeof i.getVideoPlaybackQuality && (this.isVideoPlaybackQualityAvailable = !0),
|
|
self.clearInterval(this.timer),
|
|
this.timer = self.setInterval(this.checkFPSInterval.bind(this), r.fpsDroppedMonitoringPeriod)
|
|
}
|
|
}
|
|
,
|
|
t.onMediaDetaching = function() {
|
|
this.media = null
|
|
}
|
|
,
|
|
t.checkFPS = function(e, t, r) {
|
|
var i = performance.now();
|
|
if (t) {
|
|
if (this.lastTime) {
|
|
var n = i - this.lastTime
|
|
, a = r - this.lastDroppedFrames
|
|
, s = t - this.lastDecodedFrames
|
|
, o = 1e3 * a / n
|
|
, l = this.hls;
|
|
if (l.trigger(b.FPS_DROP, {
|
|
currentDropped: a,
|
|
currentDecoded: s,
|
|
totalDroppedFrames: r
|
|
}),
|
|
o > 0 && a > l.config.fpsDroppedMonitoringThreshold * s) {
|
|
var u = l.currentLevel;
|
|
l.logger.warn("drop FPS ratio greater than max allowed value for currentLevel: " + u),
|
|
u > 0 && (-1 === l.autoLevelCapping || l.autoLevelCapping >= u) && (u -= 1,
|
|
l.trigger(b.FPS_DROP_LEVEL_CAPPING, {
|
|
level: u,
|
|
droppedLevel: l.currentLevel
|
|
}),
|
|
l.autoLevelCapping = u,
|
|
this.streamController.nextLevelSwitch())
|
|
}
|
|
}
|
|
this.lastTime = i,
|
|
this.lastDroppedFrames = r,
|
|
this.lastDecodedFrames = t
|
|
}
|
|
}
|
|
,
|
|
t.checkFPSInterval = function() {
|
|
var e = this.media;
|
|
if (e)
|
|
if (this.isVideoPlaybackQualityAvailable) {
|
|
var t = e.getVideoPlaybackQuality();
|
|
this.checkFPS(e, t.totalVideoFrames, t.droppedVideoFrames)
|
|
} else
|
|
this.checkFPS(e, e.webkitDecodedFrameCount, e.webkitDroppedFrameCount)
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function Gs(e) {
|
|
for (var t = 5381, r = e.length; r; )
|
|
t = 33 * t ^ e.charCodeAt(--r);
|
|
return (t >>> 0).toString()
|
|
}
|
|
var Ks = .025
|
|
, Vs = function(e) {
|
|
return e[e.Point = 0] = "Point",
|
|
e[e.Range = 1] = "Range",
|
|
e
|
|
}({});
|
|
function Hs(e, t, r) {
|
|
return e.identifier + "-" + (r + 1) + "-" + Gs(t)
|
|
}
|
|
var Ys = function() {
|
|
function e(e, t) {
|
|
this.base = void 0,
|
|
this._duration = null,
|
|
this._timelineStart = null,
|
|
this.appendInPlaceDisabled = void 0,
|
|
this.appendInPlaceStarted = void 0,
|
|
this.dateRange = void 0,
|
|
this.hasPlayed = !1,
|
|
this.cumulativeDuration = 0,
|
|
this.resumeOffset = NaN,
|
|
this.playoutLimit = NaN,
|
|
this.restrictions = {
|
|
skip: !1,
|
|
jump: !1
|
|
},
|
|
this.snapOptions = {
|
|
out: !1,
|
|
in: !1
|
|
},
|
|
this.assetList = [],
|
|
this.assetListLoader = void 0,
|
|
this.assetListResponse = null,
|
|
this.resumeAnchor = void 0,
|
|
this.error = void 0,
|
|
this.resetOnResume = void 0,
|
|
this.base = t,
|
|
this.dateRange = e,
|
|
this.setDateRange(e)
|
|
}
|
|
var t = e.prototype;
|
|
return t.setDateRange = function(e) {
|
|
this.dateRange = e,
|
|
this.resumeOffset = e.attr.optionalFloat("X-RESUME-OFFSET", this.resumeOffset),
|
|
this.playoutLimit = e.attr.optionalFloat("X-PLAYOUT-LIMIT", this.playoutLimit),
|
|
this.restrictions = e.attr.enumeratedStringList("X-RESTRICT", this.restrictions),
|
|
this.snapOptions = e.attr.enumeratedStringList("X-SNAP", this.snapOptions)
|
|
}
|
|
,
|
|
t.reset = function() {
|
|
var e;
|
|
this.appendInPlaceStarted = !1,
|
|
null == (e = this.assetListLoader) || e.destroy(),
|
|
this.assetListLoader = void 0,
|
|
this.supplementsPrimary || (this.assetListResponse = null,
|
|
this.assetList = [],
|
|
this._duration = null)
|
|
}
|
|
,
|
|
t.isAssetPastPlayoutLimit = function(e) {
|
|
var t;
|
|
if (e > 0 && e >= this.assetList.length)
|
|
return !0;
|
|
var r = this.playoutLimit;
|
|
return !(e <= 0 || isNaN(r)) && (0 === r || ((null == (t = this.assetList[e]) ? void 0 : t.startOffset) || 0) > r)
|
|
}
|
|
,
|
|
t.findAssetIndex = function(e) {
|
|
return this.assetList.indexOf(e)
|
|
}
|
|
,
|
|
t.toString = function() {
|
|
return '["' + (e = this).identifier + '" ' + (e.cue.pre ? "<pre>" : e.cue.post ? "<post>" : "") + e.timelineStart.toFixed(2) + "-" + e.resumeTime.toFixed(2) + "]";
|
|
var e
|
|
}
|
|
,
|
|
i(e, [{
|
|
key: "identifier",
|
|
get: function() {
|
|
return this.dateRange.id
|
|
}
|
|
}, {
|
|
key: "startDate",
|
|
get: function() {
|
|
return this.dateRange.startDate
|
|
}
|
|
}, {
|
|
key: "startTime",
|
|
get: function() {
|
|
var e = this.dateRange.startTime;
|
|
if (this.snapOptions.out) {
|
|
var t = this.dateRange.tagAnchor;
|
|
if (t)
|
|
return Ws(e, t)
|
|
}
|
|
return e
|
|
}
|
|
}, {
|
|
key: "startOffset",
|
|
get: function() {
|
|
return this.cue.pre ? 0 : this.startTime
|
|
}
|
|
}, {
|
|
key: "startIsAligned",
|
|
get: function() {
|
|
if (0 === this.startTime || this.snapOptions.out)
|
|
return !0;
|
|
var e = this.dateRange.tagAnchor;
|
|
if (e) {
|
|
var t = this.dateRange.startTime;
|
|
return t - Ws(t, e) < .1
|
|
}
|
|
return !1
|
|
}
|
|
}, {
|
|
key: "resumptionOffset",
|
|
get: function() {
|
|
var e = this.resumeOffset
|
|
, t = A(e) ? e : this.duration;
|
|
return this.cumulativeDuration + t
|
|
}
|
|
}, {
|
|
key: "resumeTime",
|
|
get: function() {
|
|
var e = this.startOffset + this.resumptionOffset;
|
|
if (this.snapOptions.in) {
|
|
var t = this.resumeAnchor;
|
|
if (t)
|
|
return Ws(e, t)
|
|
}
|
|
return e
|
|
}
|
|
}, {
|
|
key: "appendInPlace",
|
|
get: function() {
|
|
return !!this.appendInPlaceStarted || !this.appendInPlaceDisabled && !(this.cue.once || this.cue.pre || !this.startIsAligned || !(isNaN(this.playoutLimit) && isNaN(this.resumeOffset) || this.resumeOffset && this.duration && Math.abs(this.resumeOffset - this.duration) < Ks))
|
|
},
|
|
set: function(e) {
|
|
this.appendInPlaceStarted ? this.resetOnResume = !e : this.appendInPlaceDisabled = !e
|
|
}
|
|
}, {
|
|
key: "timelineStart",
|
|
get: function() {
|
|
return null !== this._timelineStart ? this._timelineStart : this.startTime
|
|
},
|
|
set: function(e) {
|
|
this._timelineStart = e
|
|
}
|
|
}, {
|
|
key: "duration",
|
|
get: function() {
|
|
var e, t = this.playoutLimit;
|
|
return e = null !== this._duration ? this._duration : this.dateRange.duration ? this.dateRange.duration : this.dateRange.plannedDuration || 0,
|
|
!isNaN(t) && t < e && (e = t),
|
|
e
|
|
},
|
|
set: function(e) {
|
|
this._duration = e
|
|
}
|
|
}, {
|
|
key: "cue",
|
|
get: function() {
|
|
return this.dateRange.cue
|
|
}
|
|
}, {
|
|
key: "timelineOccupancy",
|
|
get: function() {
|
|
return "RANGE" === this.dateRange.attr["X-TIMELINE-OCCUPIES"] ? Vs.Range : Vs.Point
|
|
}
|
|
}, {
|
|
key: "supplementsPrimary",
|
|
get: function() {
|
|
return "PRIMARY" === this.dateRange.attr["X-TIMELINE-STYLE"]
|
|
}
|
|
}, {
|
|
key: "contentMayVary",
|
|
get: function() {
|
|
return "NO" !== this.dateRange.attr["X-CONTENT-MAY-VARY"]
|
|
}
|
|
}, {
|
|
key: "assetUrl",
|
|
get: function() {
|
|
return this.dateRange.attr["X-ASSET-URI"]
|
|
}
|
|
}, {
|
|
key: "assetListUrl",
|
|
get: function() {
|
|
return this.dateRange.attr["X-ASSET-LIST"]
|
|
}
|
|
}, {
|
|
key: "baseUrl",
|
|
get: function() {
|
|
return this.base.url
|
|
}
|
|
}, {
|
|
key: "assetListLoaded",
|
|
get: function() {
|
|
return this.assetList.length > 0 || null !== this.assetListResponse
|
|
}
|
|
}])
|
|
}();
|
|
function Ws(e, t) {
|
|
return e - t.start < t.duration / 2 && !(Math.abs(e - (t.start + t.duration)) < Ks) ? t.start : t.start + t.duration
|
|
}
|
|
function js(e, t, r) {
|
|
var i = new self.URL(e,r);
|
|
return "data:" !== i.protocol && i.searchParams.set("_HLS_primary_id", t),
|
|
i
|
|
}
|
|
function qs(e, t) {
|
|
for (; null != (r = e.assetList[++t]) && r.error; )
|
|
var r;
|
|
return t
|
|
}
|
|
function Xs(e) {
|
|
var t = e.timelineStart
|
|
, r = e.duration || 0;
|
|
return '["' + e.identifier + '" ' + t.toFixed(2) + "-" + (t + r).toFixed(2) + "]"
|
|
}
|
|
var Qs = function() {
|
|
function e(e, t, r, i) {
|
|
var n = this;
|
|
this.hls = void 0,
|
|
this.interstitial = void 0,
|
|
this.assetItem = void 0,
|
|
this.tracks = null,
|
|
this.hasDetails = !1,
|
|
this.mediaAttached = null,
|
|
this._currentTime = void 0,
|
|
this._bufferedEosTime = void 0,
|
|
this.checkPlayout = function() {
|
|
n.reachedPlayout(n.currentTime) && n.hls && n.hls.trigger(b.PLAYOUT_LIMIT_REACHED, {})
|
|
}
|
|
;
|
|
var a = this.hls = new e(t);
|
|
this.interstitial = r,
|
|
this.assetItem = i;
|
|
var s = function() {
|
|
n.hasDetails = !0
|
|
};
|
|
a.once(b.LEVEL_LOADED, s),
|
|
a.once(b.AUDIO_TRACK_LOADED, s),
|
|
a.once(b.SUBTITLE_TRACK_LOADED, s),
|
|
a.on(b.MEDIA_ATTACHING, (function(e, t) {
|
|
var r = t.media;
|
|
n.removeMediaListeners(),
|
|
n.mediaAttached = r,
|
|
n.interstitial.playoutLimit && (r.addEventListener("timeupdate", n.checkPlayout),
|
|
n.appendInPlace && a.on(b.BUFFER_APPENDED, (function() {
|
|
var e = n.bufferedEnd;
|
|
n.reachedPlayout(e) && (n._bufferedEosTime = e,
|
|
a.trigger(b.BUFFERED_TO_END, void 0))
|
|
}
|
|
)))
|
|
}
|
|
))
|
|
}
|
|
var t = e.prototype;
|
|
return t.loadSource = function() {
|
|
var e = this.hls;
|
|
if (e)
|
|
if (e.url)
|
|
e.levels.length && !e.started && e.startLoad(-1, !0);
|
|
else {
|
|
var t = this.assetItem.uri;
|
|
try {
|
|
t = js(t, e.config.primarySessionId || "").href
|
|
} catch (e) {}
|
|
e.loadSource(t)
|
|
}
|
|
}
|
|
,
|
|
t.bufferedInPlaceToEnd = function(e) {
|
|
var t;
|
|
if (!this.appendInPlace)
|
|
return !1;
|
|
if (null != (t = this.hls) && t.bufferedToEnd)
|
|
return !0;
|
|
if (!e)
|
|
return !1;
|
|
var r = Math.min(this._bufferedEosTime || 1 / 0, this.duration)
|
|
, i = this.timelineOffset
|
|
, n = ur.bufferInfo(e, i, 0);
|
|
return this.getAssetTime(n.end) >= r - .02
|
|
}
|
|
,
|
|
t.reachedPlayout = function(e) {
|
|
var t = this.interstitial.playoutLimit;
|
|
return this.startOffset + e >= t
|
|
}
|
|
,
|
|
t.getAssetTime = function(e) {
|
|
var t = this.timelineOffset
|
|
, r = this.duration;
|
|
return Math.min(Math.max(0, e - t), r)
|
|
}
|
|
,
|
|
t.removeMediaListeners = function() {
|
|
var e = this.mediaAttached;
|
|
e && (this._currentTime = e.currentTime,
|
|
this.bufferSnapShot(),
|
|
e.removeEventListener("timeupdate", this.checkPlayout))
|
|
}
|
|
,
|
|
t.bufferSnapShot = function() {
|
|
var e;
|
|
this.mediaAttached && null != (e = this.hls) && e.bufferedToEnd && (this._bufferedEosTime = this.bufferedEnd)
|
|
}
|
|
,
|
|
t.destroy = function() {
|
|
this.removeMediaListeners(),
|
|
this.hls && this.hls.destroy(),
|
|
this.hls = null,
|
|
this.tracks = this.mediaAttached = this.checkPlayout = null
|
|
}
|
|
,
|
|
t.attachMedia = function(e) {
|
|
var t;
|
|
this.loadSource(),
|
|
null == (t = this.hls) || t.attachMedia(e)
|
|
}
|
|
,
|
|
t.detachMedia = function() {
|
|
var e;
|
|
this.removeMediaListeners(),
|
|
this.mediaAttached = null,
|
|
null == (e = this.hls) || e.detachMedia()
|
|
}
|
|
,
|
|
t.resumeBuffering = function() {
|
|
var e;
|
|
null == (e = this.hls) || e.resumeBuffering()
|
|
}
|
|
,
|
|
t.pauseBuffering = function() {
|
|
var e;
|
|
null == (e = this.hls) || e.pauseBuffering()
|
|
}
|
|
,
|
|
t.transferMedia = function() {
|
|
var e;
|
|
return this.bufferSnapShot(),
|
|
(null == (e = this.hls) ? void 0 : e.transferMedia()) || null
|
|
}
|
|
,
|
|
t.resetDetails = function() {
|
|
var e = this.hls;
|
|
if (e && this.hasDetails) {
|
|
e.stopLoad();
|
|
var t = function(e) {
|
|
return delete e.details
|
|
};
|
|
e.levels.forEach(t),
|
|
e.allAudioTracks.forEach(t),
|
|
e.allSubtitleTracks.forEach(t),
|
|
this.hasDetails = !1
|
|
}
|
|
}
|
|
,
|
|
t.on = function(e, t, r) {
|
|
var i;
|
|
null == (i = this.hls) || i.on(e, t)
|
|
}
|
|
,
|
|
t.once = function(e, t, r) {
|
|
var i;
|
|
null == (i = this.hls) || i.once(e, t)
|
|
}
|
|
,
|
|
t.off = function(e, t, r) {
|
|
var i;
|
|
null == (i = this.hls) || i.off(e, t)
|
|
}
|
|
,
|
|
t.toString = function() {
|
|
var e;
|
|
return "HlsAssetPlayer: " + Xs(this.assetItem) + " " + (null == (e = this.hls) ? void 0 : e.sessionId) + " " + (this.appendInPlace ? "append-in-place" : "")
|
|
}
|
|
,
|
|
i(e, [{
|
|
key: "appendInPlace",
|
|
get: function() {
|
|
return this.interstitial.appendInPlace
|
|
}
|
|
}, {
|
|
key: "destroyed",
|
|
get: function() {
|
|
var e;
|
|
return !(null != (e = this.hls) && e.userConfig)
|
|
}
|
|
}, {
|
|
key: "assetId",
|
|
get: function() {
|
|
return this.assetItem.identifier
|
|
}
|
|
}, {
|
|
key: "interstitialId",
|
|
get: function() {
|
|
return this.assetItem.parentIdentifier
|
|
}
|
|
}, {
|
|
key: "media",
|
|
get: function() {
|
|
var e;
|
|
return (null == (e = this.hls) ? void 0 : e.media) || null
|
|
}
|
|
}, {
|
|
key: "bufferedEnd",
|
|
get: function() {
|
|
var e = this.media || this.mediaAttached;
|
|
if (!e)
|
|
return this._bufferedEosTime ? this._bufferedEosTime : this.currentTime;
|
|
var t = ur.bufferInfo(e, e.currentTime, .001);
|
|
return this.getAssetTime(t.end)
|
|
}
|
|
}, {
|
|
key: "currentTime",
|
|
get: function() {
|
|
var e = this.media || this.mediaAttached;
|
|
return e ? this.getAssetTime(e.currentTime) : this._currentTime || 0
|
|
}
|
|
}, {
|
|
key: "duration",
|
|
get: function() {
|
|
var e = this.assetItem.duration;
|
|
if (!e)
|
|
return 0;
|
|
var t = this.interstitial.playoutLimit;
|
|
if (t) {
|
|
var r = t - this.startOffset;
|
|
if (r > 0 && r < e)
|
|
return r
|
|
}
|
|
return e
|
|
}
|
|
}, {
|
|
key: "remaining",
|
|
get: function() {
|
|
var e = this.duration;
|
|
return e ? Math.max(0, e - this.currentTime) : 0
|
|
}
|
|
}, {
|
|
key: "startOffset",
|
|
get: function() {
|
|
return this.assetItem.startOffset
|
|
}
|
|
}, {
|
|
key: "timelineOffset",
|
|
get: function() {
|
|
var e;
|
|
return (null == (e = this.hls) ? void 0 : e.config.timelineOffset) || 0
|
|
},
|
|
set: function(e) {
|
|
var t = this.timelineOffset;
|
|
if (e !== t) {
|
|
var r = e - t;
|
|
if (Math.abs(r) > 1 / 9e4 && this.hls) {
|
|
if (this.hasDetails)
|
|
throw new Error("Cannot set timelineOffset after playlists are loaded");
|
|
this.hls.config.timelineOffset = e
|
|
}
|
|
}
|
|
}
|
|
}])
|
|
}()
|
|
, zs = function(e) {
|
|
function t(t, r) {
|
|
var i;
|
|
return (i = e.call(this, "interstitials-sched", r) || this).onScheduleUpdate = void 0,
|
|
i.eventMap = {},
|
|
i.events = null,
|
|
i.items = null,
|
|
i.durations = {
|
|
primary: 0,
|
|
playout: 0,
|
|
integrated: 0
|
|
},
|
|
i.onScheduleUpdate = t,
|
|
i
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.destroy = function() {
|
|
this.reset(),
|
|
this.onScheduleUpdate = null
|
|
}
|
|
,
|
|
r.reset = function() {
|
|
this.eventMap = {},
|
|
this.setDurations(0, 0, 0),
|
|
this.events && this.events.forEach((function(e) {
|
|
return e.reset()
|
|
}
|
|
)),
|
|
this.events = this.items = null
|
|
}
|
|
,
|
|
r.resetErrorsInRange = function(e, t) {
|
|
return this.events ? this.events.reduce((function(r, i) {
|
|
return e <= i.startOffset && t > i.startOffset ? (delete i.error,
|
|
r + 1) : r
|
|
}
|
|
), 0) : 0
|
|
}
|
|
,
|
|
r.getEvent = function(e) {
|
|
return e && this.eventMap[e] || null
|
|
}
|
|
,
|
|
r.hasEvent = function(e) {
|
|
return e in this.eventMap
|
|
}
|
|
,
|
|
r.findItemIndex = function(e, t) {
|
|
if (e.event)
|
|
return this.findEventIndex(e.event.identifier);
|
|
var r = -1;
|
|
e.nextEvent ? r = this.findEventIndex(e.nextEvent.identifier) - 1 : e.previousEvent && (r = this.findEventIndex(e.previousEvent.identifier) + 1);
|
|
var i = this.items;
|
|
if (i)
|
|
for (i[r] || (void 0 === t && (t = e.start),
|
|
r = this.findItemIndexAtTime(t)); r >= 0 && null != (n = i[r]) && n.event; ) {
|
|
var n;
|
|
r--
|
|
}
|
|
return r
|
|
}
|
|
,
|
|
r.findItemIndexAtTime = function(e, t) {
|
|
var r = this.items;
|
|
if (r)
|
|
for (var i = 0; i < r.length; i++) {
|
|
var n = r[i];
|
|
if (t && "primary" !== t && (n = n[t]),
|
|
e === n.start || e > n.start && e < n.end)
|
|
return i
|
|
}
|
|
return -1
|
|
}
|
|
,
|
|
r.findJumpRestrictedIndex = function(e, t) {
|
|
var r = this.items;
|
|
if (r)
|
|
for (var i = e; i <= t && r[i]; i++) {
|
|
var n = r[i].event;
|
|
if (null != n && n.restrictions.jump && !n.appendInPlace)
|
|
return i
|
|
}
|
|
return -1
|
|
}
|
|
,
|
|
r.findEventIndex = function(e) {
|
|
var t = this.items;
|
|
if (t)
|
|
for (var r = t.length; r--; ) {
|
|
var i;
|
|
if ((null == (i = t[r].event) ? void 0 : i.identifier) === e)
|
|
return r
|
|
}
|
|
return -1
|
|
}
|
|
,
|
|
r.findAssetIndex = function(e, t) {
|
|
var r = e.assetList
|
|
, i = r.length;
|
|
if (i > 1)
|
|
for (var n = 0; n < i; n++) {
|
|
var a = r[n];
|
|
if (!a.error) {
|
|
var s = a.timelineStart;
|
|
if (t === s || t > s && (t < s + (a.duration || 0) || n === i - 1))
|
|
return n
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
,
|
|
r.parseInterstitialDateRanges = function(e, t) {
|
|
var r = this
|
|
, i = e.main.details
|
|
, n = i.dateRanges
|
|
, a = this.events
|
|
, s = this.parseDateRanges(n, {
|
|
url: i.url
|
|
}, t)
|
|
, o = Object.keys(n)
|
|
, l = a ? a.filter((function(e) {
|
|
return !o.includes(e.identifier)
|
|
}
|
|
)) : [];
|
|
s.length && s.sort((function(e, t) {
|
|
var r = e.cue.pre
|
|
, i = e.cue.post
|
|
, n = t.cue.pre
|
|
, a = t.cue.post;
|
|
if (r && !n)
|
|
return -1;
|
|
if (n && !r)
|
|
return 1;
|
|
if (i && !a)
|
|
return 1;
|
|
if (a && !i)
|
|
return -1;
|
|
if (!(r || n || i || a)) {
|
|
var s = e.startTime
|
|
, o = t.startTime;
|
|
if (s !== o)
|
|
return s - o
|
|
}
|
|
return e.dateRange.tagOrder - t.dateRange.tagOrder
|
|
}
|
|
)),
|
|
this.events = s,
|
|
l.forEach((function(e) {
|
|
r.removeEvent(e)
|
|
}
|
|
)),
|
|
this.updateSchedule(e, l)
|
|
}
|
|
,
|
|
r.updateSchedule = function(e, t, r) {
|
|
void 0 === t && (t = []),
|
|
void 0 === r && (r = !1);
|
|
var i = this.events || [];
|
|
if (i.length || t.length || this.length < 2) {
|
|
var n = this.items
|
|
, a = this.parseSchedule(i, e);
|
|
(r || t.length || (null == n ? void 0 : n.length) !== a.length || a.some((function(e, t) {
|
|
return Math.abs(e.playout.start - n[t].playout.start) > .005 || Math.abs(e.playout.end - n[t].playout.end) > .005
|
|
}
|
|
))) && (this.items = a,
|
|
this.onScheduleUpdate(t, n))
|
|
}
|
|
}
|
|
,
|
|
r.parseDateRanges = function(e, t, r) {
|
|
for (var i = [], n = Object.keys(e), a = 0; a < n.length; a++) {
|
|
var s = n[a]
|
|
, o = e[s];
|
|
if (o.isInterstitial) {
|
|
var l = this.eventMap[s];
|
|
l ? l.setDateRange(o) : (l = new Ys(o,t),
|
|
this.eventMap[s] = l,
|
|
!1 === r && (l.appendInPlace = r)),
|
|
i.push(l)
|
|
}
|
|
}
|
|
return i
|
|
}
|
|
,
|
|
r.parseSchedule = function(e, t) {
|
|
var r = []
|
|
, i = t.main.details
|
|
, n = i.live ? 1 / 0 : i.edge
|
|
, a = 0;
|
|
if ((e = e.filter((function(e) {
|
|
return !(e.error || e.cue.once && e.hasPlayed)
|
|
}
|
|
))).length) {
|
|
this.resolveOffsets(e, t);
|
|
var s = 0
|
|
, o = 0;
|
|
if (e.forEach((function(t, i) {
|
|
var l = t.cue.pre
|
|
, u = t.cue.post
|
|
, d = e[i - 1] || null
|
|
, h = t.appendInPlace
|
|
, f = u ? n : t.startOffset
|
|
, c = t.duration
|
|
, g = t.timelineOccupancy === Vs.Range ? c : 0
|
|
, v = t.resumptionOffset
|
|
, m = (null == d ? void 0 : d.startTime) === f
|
|
, p = f + t.cumulativeDuration
|
|
, y = h ? p + c : f + v;
|
|
if (l || !u && f <= 0) {
|
|
var E = o;
|
|
o += g,
|
|
t.timelineStart = p;
|
|
var T = a;
|
|
a += c,
|
|
r.push({
|
|
event: t,
|
|
start: p,
|
|
end: y,
|
|
playout: {
|
|
start: T,
|
|
end: a
|
|
},
|
|
integrated: {
|
|
start: E,
|
|
end: o
|
|
}
|
|
})
|
|
} else {
|
|
if (!(f <= n))
|
|
return;
|
|
if (!m) {
|
|
var S = f - s;
|
|
if (S > .033) {
|
|
var A = s
|
|
, L = o;
|
|
o += S;
|
|
var I = a;
|
|
a += S;
|
|
var R = {
|
|
previousEvent: e[i - 1] || null,
|
|
nextEvent: t,
|
|
start: A,
|
|
end: A + S,
|
|
playout: {
|
|
start: I,
|
|
end: a
|
|
},
|
|
integrated: {
|
|
start: L,
|
|
end: o
|
|
}
|
|
};
|
|
r.push(R)
|
|
} else
|
|
S > 0 && d && (d.cumulativeDuration += S,
|
|
r[r.length - 1].end = f)
|
|
}
|
|
u && (y = p),
|
|
t.timelineStart = p;
|
|
var k = o;
|
|
o += g;
|
|
var b = a;
|
|
a += c,
|
|
r.push({
|
|
event: t,
|
|
start: p,
|
|
end: y,
|
|
playout: {
|
|
start: b,
|
|
end: a
|
|
},
|
|
integrated: {
|
|
start: k,
|
|
end: o
|
|
}
|
|
})
|
|
}
|
|
var D = t.resumeTime;
|
|
s = u || D > n ? n : D
|
|
}
|
|
)),
|
|
s < n) {
|
|
var l, u = s, d = o, h = n - s;
|
|
o += h;
|
|
var f = a;
|
|
a += h,
|
|
r.push({
|
|
previousEvent: (null == (l = r[r.length - 1]) ? void 0 : l.event) || null,
|
|
nextEvent: null,
|
|
start: s,
|
|
end: u + h,
|
|
playout: {
|
|
start: f,
|
|
end: a
|
|
},
|
|
integrated: {
|
|
start: d,
|
|
end: o
|
|
}
|
|
})
|
|
}
|
|
this.setDurations(n, a, o)
|
|
} else
|
|
r.push({
|
|
previousEvent: null,
|
|
nextEvent: null,
|
|
start: 0,
|
|
end: n,
|
|
playout: {
|
|
start: 0,
|
|
end: n
|
|
},
|
|
integrated: {
|
|
start: 0,
|
|
end: n
|
|
}
|
|
}),
|
|
this.setDurations(n, n, n);
|
|
return r
|
|
}
|
|
,
|
|
r.setDurations = function(e, t, r) {
|
|
this.durations = {
|
|
primary: e,
|
|
playout: t,
|
|
integrated: r
|
|
}
|
|
}
|
|
,
|
|
r.resolveOffsets = function(e, t) {
|
|
var r = this
|
|
, i = t.main.details
|
|
, n = i.live ? 1 / 0 : i.edge
|
|
, a = 0
|
|
, s = -1;
|
|
e.forEach((function(o, l) {
|
|
var u = o.cue.pre
|
|
, d = o.cue.post
|
|
, h = u ? 0 : d ? n : o.startTime;
|
|
r.updateAssetDurations(o),
|
|
s === h ? o.cumulativeDuration = a : (a = 0,
|
|
s = h),
|
|
!d && o.snapOptions.in && (o.resumeAnchor = Et(null, i.fragments, o.startOffset + o.resumptionOffset, 0, 0) || void 0),
|
|
o.appendInPlace && !o.appendInPlaceStarted && (r.primaryCanResumeInPlaceAt(o, t) || (o.appendInPlace = !1)),
|
|
!o.appendInPlace && l + 1 < e.length && e[l + 1].startTime - e[l].resumeTime < .033 && (e[l + 1].appendInPlace = !1,
|
|
e[l + 1].appendInPlace && r.warn("Could not change append strategy for abutting event " + o));
|
|
var f = A(o.resumeOffset) ? o.resumeOffset : o.duration;
|
|
a += f
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.primaryCanResumeInPlaceAt = function(e, t) {
|
|
var r = this
|
|
, i = e.resumeTime
|
|
, n = e.startTime + e.resumptionOffset;
|
|
return Math.abs(i - n) > Ks ? (this.log('"' + e.identifier + '" resumption ' + i + " not aligned with estimated timeline end " + n),
|
|
!1) : !Object.keys(t).some((function(n) {
|
|
var a = t[n].details
|
|
, s = a.edge;
|
|
if (i >= s)
|
|
return r.log('"' + e.identifier + '" resumption ' + i + " past " + n + " playlist end " + s),
|
|
!1;
|
|
var o = Et(null, a.fragments, i);
|
|
if (!o)
|
|
return r.log('"' + e.identifier + '" resumption ' + i + " does not align with any fragments in " + n + " playlist (" + a.fragStart + "-" + a.fragmentEnd + ")"),
|
|
!0;
|
|
var l = "audio" === n ? .175 : 0;
|
|
return !(Math.abs(o.start - i) < Ks + l || Math.abs(o.end - i) < Ks + l || (r.log('"' + e.identifier + '" resumption ' + i + " not aligned with " + n + " fragment bounds (" + o.start + "-" + o.end + " sn: " + o.sn + " cc: " + o.cc + ")"),
|
|
0))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.updateAssetDurations = function(e) {
|
|
if (e.assetListLoaded) {
|
|
for (var t = e.timelineStart, r = 0, i = !1, n = !1, a = 0; a < e.assetList.length; a++) {
|
|
var s = e.assetList[a]
|
|
, o = t + r;
|
|
s.startOffset = r,
|
|
s.timelineStart = o,
|
|
i || (i = null === s.duration),
|
|
n || (n = !!s.error),
|
|
r += s.error ? 0 : s.duration || 0
|
|
}
|
|
e.duration = i && !n ? Math.max(r, e.duration) : r
|
|
}
|
|
}
|
|
,
|
|
r.removeEvent = function(e) {
|
|
e.reset(),
|
|
delete this.eventMap[e.identifier]
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "duration",
|
|
get: function() {
|
|
var e = this.items;
|
|
return e ? e[e.length - 1].end : 0
|
|
}
|
|
}, {
|
|
key: "length",
|
|
get: function() {
|
|
return this.items ? this.items.length : 0
|
|
}
|
|
}, {
|
|
key: "assetIdAtEnd",
|
|
get: function() {
|
|
var e, t = null == (e = this.items) || null == (e = e[this.length - 1]) ? void 0 : e.event;
|
|
if (t) {
|
|
var r = t.assetList
|
|
, i = r[r.length - 1];
|
|
if (i)
|
|
return i.identifier
|
|
}
|
|
return null
|
|
}
|
|
}])
|
|
}(N);
|
|
function $s(e) {
|
|
return "[" + (e.event ? '"' + e.event.identifier + '"' : "primary") + ": " + e.start.toFixed(2) + "-" + e.end.toFixed(2) + "]"
|
|
}
|
|
var Zs = function() {
|
|
function e(e) {
|
|
this.hls = void 0,
|
|
this.hls = e
|
|
}
|
|
var t = e.prototype;
|
|
return t.destroy = function() {
|
|
this.hls = null
|
|
}
|
|
,
|
|
t.loadAssetList = function(e, t) {
|
|
var r, i = this, n = e.assetListUrl;
|
|
try {
|
|
r = js(n, this.hls.sessionId, e.baseUrl)
|
|
} catch (t) {
|
|
var a = this.assignAssetListError(e, k.ASSET_LIST_LOAD_ERROR, t, n);
|
|
return void this.hls.trigger(b.ERROR, a)
|
|
}
|
|
t && "data:" !== r.protocol && r.searchParams.set("_HLS_start_offset", "" + t);
|
|
var s = this.hls.config
|
|
, o = new (0,
|
|
s.loader)(s)
|
|
, l = {
|
|
responseType: "json",
|
|
url: r.href
|
|
}
|
|
, u = s.interstitialAssetListLoadPolicy.default
|
|
, d = {
|
|
loadPolicy: u,
|
|
timeout: u.maxLoadTimeMs,
|
|
maxRetry: 0,
|
|
retryDelay: 0,
|
|
maxRetryDelay: 0
|
|
}
|
|
, h = {
|
|
onSuccess: function(t, r, n, a) {
|
|
var s = t.data
|
|
, o = null == s ? void 0 : s.ASSETS;
|
|
if (Array.isArray(o))
|
|
e.assetListResponse = s,
|
|
i.hls.trigger(b.ASSET_LIST_LOADED, {
|
|
event: e,
|
|
assetListResponse: s,
|
|
networkDetails: a
|
|
});
|
|
else {
|
|
var l = i.assignAssetListError(e, k.ASSET_LIST_PARSING_ERROR, new Error("Invalid interstitial asset list"), n.url, r, a);
|
|
i.hls.trigger(b.ERROR, l)
|
|
}
|
|
},
|
|
onError: function(t, r, n, a) {
|
|
var s = i.assignAssetListError(e, k.ASSET_LIST_LOAD_ERROR, new Error("Error loading X-ASSET-LIST: HTTP status " + t.code + " " + t.text + " (" + r.url + ")"), r.url, a, n);
|
|
i.hls.trigger(b.ERROR, s)
|
|
},
|
|
onTimeout: function(t, r, n) {
|
|
var a = i.assignAssetListError(e, k.ASSET_LIST_LOAD_TIMEOUT, new Error("Timeout loading X-ASSET-LIST (" + r.url + ")"), r.url, t, n);
|
|
i.hls.trigger(b.ERROR, a)
|
|
}
|
|
};
|
|
return o.load(l, d, h),
|
|
this.hls.trigger(b.ASSET_LIST_LOADING, {
|
|
event: e
|
|
}),
|
|
o
|
|
}
|
|
,
|
|
t.assignAssetListError = function(e, t, r, i, n, a) {
|
|
return e.error = r,
|
|
{
|
|
type: R.NETWORK_ERROR,
|
|
details: t,
|
|
fatal: !1,
|
|
interstitial: e,
|
|
url: i,
|
|
error: r,
|
|
networkDetails: a,
|
|
stats: n
|
|
}
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function Js(e) {
|
|
null == e || e.play().catch((function() {}
|
|
))
|
|
}
|
|
function eo(e, t) {
|
|
return "[" + e + "] Advancing timeline position to " + t
|
|
}
|
|
var to = function(e) {
|
|
function t(t, r) {
|
|
var i;
|
|
return (i = e.call(this, "interstitials", t.logger) || this).HlsPlayerClass = void 0,
|
|
i.hls = void 0,
|
|
i.assetListLoader = void 0,
|
|
i.mediaSelection = null,
|
|
i.altSelection = null,
|
|
i.media = null,
|
|
i.detachedData = null,
|
|
i.requiredTracks = null,
|
|
i.manager = null,
|
|
i.playerQueue = [],
|
|
i.bufferedPos = -1,
|
|
i.timelinePos = -1,
|
|
i.schedule = void 0,
|
|
i.playingItem = null,
|
|
i.bufferingItem = null,
|
|
i.waitingItem = null,
|
|
i.endedItem = null,
|
|
i.playingAsset = null,
|
|
i.endedAsset = null,
|
|
i.bufferingAsset = null,
|
|
i.shouldPlay = !1,
|
|
i.onPlay = function() {
|
|
i.shouldPlay = !0
|
|
}
|
|
,
|
|
i.onPause = function() {
|
|
i.shouldPlay = !1
|
|
}
|
|
,
|
|
i.onSeeking = function() {
|
|
var e = i.currentTime;
|
|
if (void 0 !== e && !i.playbackDisabled && i.schedule) {
|
|
var t = e - i.timelinePos;
|
|
if (!(Math.abs(t) < 1 / 7056e5)) {
|
|
var r = t <= -.01;
|
|
i.timelinePos = e,
|
|
i.bufferedPos = e;
|
|
var n = i.playingItem;
|
|
if (n)
|
|
if (r && i.schedule.resetErrorsInRange(e, e - t) && i.updateSchedule(!0),
|
|
i.checkBuffer(),
|
|
r && e < n.start || e >= n.end) {
|
|
var a, s = i.findItemIndex(n), o = i.schedule.findItemIndexAtTime(e);
|
|
if (-1 === o && (o = s + (r ? -1 : 1),
|
|
i.log("seeked " + (r ? "back " : "") + "to position not covered by schedule " + e + " (resolving from " + s + " to " + o + ")")),
|
|
!i.isInterstitial(n) && null != (a = i.media) && a.paused && (i.shouldPlay = !1),
|
|
!r && o > s) {
|
|
var l = i.schedule.findJumpRestrictedIndex(s + 1, o);
|
|
if (l > s)
|
|
return void i.setSchedulePosition(l)
|
|
}
|
|
i.setSchedulePosition(o)
|
|
} else {
|
|
var u = i.playingAsset;
|
|
if (u) {
|
|
var d, h = u.timelineStart, f = u.duration || 0;
|
|
(r && e < h || e >= h + f) && (null != (d = n.event) && d.appendInPlace && (i.clearInterstitial(n.event, n),
|
|
i.flushFrontBuffer(e)),
|
|
i.setScheduleToAssetAtTime(e, u))
|
|
} else if (i.playingLastItem && i.isInterstitial(n)) {
|
|
var c = n.event.assetList[0];
|
|
c && (i.endedItem = i.playingItem,
|
|
i.playingItem = null,
|
|
i.setScheduleToAssetAtTime(e, c))
|
|
}
|
|
}
|
|
else
|
|
i.checkBuffer()
|
|
}
|
|
}
|
|
}
|
|
,
|
|
i.onTimeupdate = function() {
|
|
var e = i.currentTime;
|
|
if (void 0 !== e && !i.playbackDisabled && e > i.timelinePos) {
|
|
i.timelinePos = e,
|
|
e > i.bufferedPos && i.checkBuffer();
|
|
var t = i.playingItem;
|
|
if (t && !i.playingLastItem) {
|
|
if (e >= t.end) {
|
|
i.timelinePos = t.end;
|
|
var r = i.findItemIndex(t);
|
|
i.setSchedulePosition(r + 1)
|
|
}
|
|
var n = i.playingAsset;
|
|
n && e >= n.timelineStart + (n.duration || 0) && i.setScheduleToAssetAtTime(e, n)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
i.onScheduleUpdate = function(e, t) {
|
|
var r = i.schedule;
|
|
if (r) {
|
|
var n = i.playingItem
|
|
, a = r.events || []
|
|
, s = r.items || []
|
|
, o = r.durations
|
|
, l = e.map((function(e) {
|
|
return e.identifier
|
|
}
|
|
))
|
|
, u = !(!a.length && !l.length);
|
|
(u || t) && i.log("INTERSTITIALS_UPDATED (" + a.length + "): " + a + "\nSchedule: " + s.map((function(e) {
|
|
return $s(e)
|
|
}
|
|
)) + " pos: " + i.timelinePos),
|
|
l.length && i.log("Removed events " + l);
|
|
var d = null
|
|
, h = null;
|
|
n && (d = i.updateItem(n, i.timelinePos),
|
|
i.itemsMatch(n, d) ? i.playingItem = d : i.waitingItem = i.endedItem = null),
|
|
i.waitingItem = i.updateItem(i.waitingItem),
|
|
i.endedItem = i.updateItem(i.endedItem);
|
|
var f = i.bufferingItem;
|
|
if (f && (h = i.updateItem(f, i.bufferedPos),
|
|
i.itemsMatch(f, h) ? i.bufferingItem = h : f.event && (i.bufferingItem = i.playingItem,
|
|
i.clearInterstitial(f.event, null))),
|
|
e.forEach((function(e) {
|
|
e.assetList.forEach((function(e) {
|
|
i.clearAssetPlayer(e.identifier, null)
|
|
}
|
|
))
|
|
}
|
|
)),
|
|
i.playerQueue.forEach((function(e) {
|
|
if (e.interstitial.appendInPlace) {
|
|
var t = e.assetItem.timelineStart
|
|
, r = e.timelineOffset - t;
|
|
if (r)
|
|
try {
|
|
e.timelineOffset = t
|
|
} catch (n) {
|
|
Math.abs(r) > Ks && i.warn(n + ' ("' + e.assetId + '" ' + e.timelineOffset + "->" + t + ")")
|
|
}
|
|
}
|
|
}
|
|
)),
|
|
u || t) {
|
|
if (i.hls.trigger(b.INTERSTITIALS_UPDATED, {
|
|
events: a.slice(0),
|
|
schedule: s.slice(0),
|
|
durations: o,
|
|
removedIds: l
|
|
}),
|
|
i.isInterstitial(n) && l.includes(n.event.identifier))
|
|
return i.warn('Interstitial "' + n.event.identifier + '" removed while playing'),
|
|
void i.primaryFallback(n.event);
|
|
n && i.trimInPlace(d, n),
|
|
f && h !== d && i.trimInPlace(h, f),
|
|
i.checkBuffer()
|
|
}
|
|
}
|
|
}
|
|
,
|
|
i.hls = t,
|
|
i.HlsPlayerClass = r,
|
|
i.assetListLoader = new Zs(t),
|
|
i.schedule = new zs(i.onScheduleUpdate,t.logger),
|
|
i.registerListeners(),
|
|
i
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.registerListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.on(b.MEDIA_ATTACHING, this.onMediaAttaching, this),
|
|
e.on(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.on(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.LEVEL_UPDATED, this.onLevelUpdated, this),
|
|
e.on(b.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this),
|
|
e.on(b.AUDIO_TRACK_UPDATED, this.onAudioTrackUpdated, this),
|
|
e.on(b.SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this),
|
|
e.on(b.SUBTITLE_TRACK_UPDATED, this.onSubtitleTrackUpdated, this),
|
|
e.on(b.EVENT_CUE_ENTER, this.onInterstitialCueEnter, this),
|
|
e.on(b.ASSET_LIST_LOADED, this.onAssetListLoaded, this),
|
|
e.on(b.BUFFER_APPENDED, this.onBufferAppended, this),
|
|
e.on(b.BUFFER_FLUSHED, this.onBufferFlushed, this),
|
|
e.on(b.BUFFERED_TO_END, this.onBufferedToEnd, this),
|
|
e.on(b.MEDIA_ENDED, this.onMediaEnded, this),
|
|
e.on(b.ERROR, this.onError, this),
|
|
e.on(b.DESTROYING, this.onDestroying, this))
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.off(b.MEDIA_ATTACHING, this.onMediaAttaching, this),
|
|
e.off(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.off(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.LEVEL_UPDATED, this.onLevelUpdated, this),
|
|
e.off(b.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this),
|
|
e.off(b.AUDIO_TRACK_UPDATED, this.onAudioTrackUpdated, this),
|
|
e.off(b.SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this),
|
|
e.off(b.SUBTITLE_TRACK_UPDATED, this.onSubtitleTrackUpdated, this),
|
|
e.off(b.EVENT_CUE_ENTER, this.onInterstitialCueEnter, this),
|
|
e.off(b.ASSET_LIST_LOADED, this.onAssetListLoaded, this),
|
|
e.off(b.BUFFER_CODECS, this.onBufferCodecs, this),
|
|
e.off(b.BUFFER_APPENDED, this.onBufferAppended, this),
|
|
e.off(b.BUFFER_FLUSHED, this.onBufferFlushed, this),
|
|
e.off(b.BUFFERED_TO_END, this.onBufferedToEnd, this),
|
|
e.off(b.MEDIA_ENDED, this.onMediaEnded, this),
|
|
e.off(b.ERROR, this.onError, this),
|
|
e.off(b.DESTROYING, this.onDestroying, this))
|
|
}
|
|
,
|
|
r.startLoad = function() {
|
|
this.resumeBuffering()
|
|
}
|
|
,
|
|
r.stopLoad = function() {
|
|
this.pauseBuffering()
|
|
}
|
|
,
|
|
r.resumeBuffering = function() {
|
|
var e;
|
|
null == (e = this.getBufferingPlayer()) || e.resumeBuffering()
|
|
}
|
|
,
|
|
r.pauseBuffering = function() {
|
|
var e;
|
|
null == (e = this.getBufferingPlayer()) || e.pauseBuffering()
|
|
}
|
|
,
|
|
r.destroy = function() {
|
|
this.unregisterListeners(),
|
|
this.stopLoad(),
|
|
this.assetListLoader && this.assetListLoader.destroy(),
|
|
this.emptyPlayerQueue(),
|
|
this.clearScheduleState(),
|
|
this.schedule && this.schedule.destroy(),
|
|
this.media = this.detachedData = this.mediaSelection = this.requiredTracks = this.altSelection = this.schedule = this.manager = null,
|
|
this.hls = this.HlsPlayerClass = this.log = null,
|
|
this.assetListLoader = null,
|
|
this.onPlay = this.onPause = this.onSeeking = this.onTimeupdate = null,
|
|
this.onScheduleUpdate = null
|
|
}
|
|
,
|
|
r.onDestroying = function() {
|
|
var e = this.primaryMedia || this.media;
|
|
e && this.removeMediaListeners(e)
|
|
}
|
|
,
|
|
r.removeMediaListeners = function(e) {
|
|
Ii(e, "play", this.onPlay),
|
|
Ii(e, "pause", this.onPause),
|
|
Ii(e, "seeking", this.onSeeking),
|
|
Ii(e, "timeupdate", this.onTimeupdate)
|
|
}
|
|
,
|
|
r.onMediaAttaching = function(e, t) {
|
|
var r = this.media = t.media;
|
|
Li(r, "seeking", this.onSeeking),
|
|
Li(r, "timeupdate", this.onTimeupdate),
|
|
Li(r, "play", this.onPlay),
|
|
Li(r, "pause", this.onPause)
|
|
}
|
|
,
|
|
r.onMediaAttached = function(e, t) {
|
|
var r = this.effectivePlayingItem
|
|
, i = this.detachedData;
|
|
if (this.detachedData = null,
|
|
null === r)
|
|
this.checkStart();
|
|
else if (!i) {
|
|
this.clearScheduleState();
|
|
var n = this.findItemIndex(r);
|
|
this.setSchedulePosition(n)
|
|
}
|
|
}
|
|
,
|
|
r.clearScheduleState = function() {
|
|
this.log("clear schedule state"),
|
|
this.playingItem = this.bufferingItem = this.waitingItem = this.endedItem = this.playingAsset = this.endedAsset = this.bufferingAsset = null
|
|
}
|
|
,
|
|
r.onMediaDetaching = function(e, t) {
|
|
var r = !!t.transferMedia
|
|
, i = this.media;
|
|
if (this.media = null,
|
|
!r && (i && this.removeMediaListeners(i),
|
|
this.detachedData)) {
|
|
var n = this.getBufferingPlayer();
|
|
n && (this.log("Removing schedule state for detachedData and " + n),
|
|
this.playingAsset = this.endedAsset = this.bufferingAsset = this.bufferingItem = this.waitingItem = this.detachedData = null,
|
|
n.detachMedia()),
|
|
this.shouldPlay = !1
|
|
}
|
|
}
|
|
,
|
|
r.isInterstitial = function(e) {
|
|
return !(null == e || !e.event)
|
|
}
|
|
,
|
|
r.retreiveMediaSource = function(e, t) {
|
|
var r = this.getAssetPlayer(e);
|
|
r && this.transferMediaFromPlayer(r, t)
|
|
}
|
|
,
|
|
r.transferMediaFromPlayer = function(e, t) {
|
|
var r = e.interstitial.appendInPlace
|
|
, i = e.media;
|
|
if (r && i === this.primaryMedia) {
|
|
if (this.bufferingAsset = null,
|
|
(!t || this.isInterstitial(t) && !t.event.appendInPlace) && t && i)
|
|
return void (this.detachedData = {
|
|
media: i
|
|
});
|
|
var n = e.transferMedia();
|
|
this.log("transfer MediaSource from " + e + " " + lt(n)),
|
|
this.detachedData = n
|
|
} else
|
|
t && i && (this.shouldPlay || (this.shouldPlay = !i.paused))
|
|
}
|
|
,
|
|
r.transferMediaTo = function(e, t) {
|
|
var r, i, n = this;
|
|
if (e.media !== t) {
|
|
var a, s = null, o = this.hls, l = e !== o, u = l && e.interstitial.appendInPlace, d = null == (r = this.detachedData) ? void 0 : r.mediaSource;
|
|
if (o.media)
|
|
u && (s = o.transferMedia(),
|
|
this.detachedData = s),
|
|
a = "Primary";
|
|
else if (d) {
|
|
var h = this.getBufferingPlayer();
|
|
h ? (s = h.transferMedia(),
|
|
a = "" + h) : a = "detached MediaSource"
|
|
} else
|
|
a = "detached media";
|
|
if (!s)
|
|
if (d)
|
|
s = this.detachedData,
|
|
this.log("using detachedData: MediaSource " + lt(s));
|
|
else if (!this.detachedData || o.media === t) {
|
|
var f = this.playerQueue;
|
|
f.length > 1 && f.forEach((function(e) {
|
|
if (l && e.interstitial.appendInPlace !== u) {
|
|
var t = e.interstitial;
|
|
n.clearInterstitial(e.interstitial, null),
|
|
t.appendInPlace = !1,
|
|
t.appendInPlace && n.warn("Could not change append strategy for queued assets " + t)
|
|
}
|
|
}
|
|
)),
|
|
this.hls.detachMedia(),
|
|
this.detachedData = {
|
|
media: t
|
|
}
|
|
}
|
|
var c = s && "mediaSource"in s && "closed" !== (null == (i = s.mediaSource) ? void 0 : i.readyState)
|
|
, g = c && s ? s : t;
|
|
this.log((c ? "transfering MediaSource" : "attaching media") + " to " + (l ? e : "Primary") + " from " + a + " (media.currentTime: " + t.currentTime + ")");
|
|
var v = this.schedule;
|
|
if (g === s && v) {
|
|
var m = l && e.assetId === v.assetIdAtEnd;
|
|
g.overrides = {
|
|
duration: v.duration,
|
|
endOfStream: !l || m,
|
|
cueRemoval: !l
|
|
}
|
|
}
|
|
e.attachMedia(g)
|
|
}
|
|
}
|
|
,
|
|
r.onInterstitialCueEnter = function() {
|
|
this.onTimeupdate()
|
|
}
|
|
,
|
|
r.checkStart = function() {
|
|
var e = this.schedule
|
|
, t = null == e ? void 0 : e.events;
|
|
if (t && !this.playbackDisabled && this.media) {
|
|
-1 === this.bufferedPos && (this.bufferedPos = 0);
|
|
var r = this.timelinePos
|
|
, i = this.effectivePlayingItem;
|
|
if (-1 === r) {
|
|
var n = this.hls.startPosition;
|
|
if (this.log(eo("checkStart", n)),
|
|
this.timelinePos = n,
|
|
t.length && t[0].cue.pre) {
|
|
var a = e.findEventIndex(t[0].identifier);
|
|
this.setSchedulePosition(a)
|
|
} else if (n >= 0 || !this.primaryLive) {
|
|
var s = this.timelinePos = n > 0 ? n : 0
|
|
, o = e.findItemIndexAtTime(s);
|
|
this.setSchedulePosition(o)
|
|
}
|
|
} else if (i && !this.playingItem) {
|
|
var l = e.findItemIndex(i);
|
|
this.setSchedulePosition(l)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.advanceAssetBuffering = function(e, t) {
|
|
var r = e.event
|
|
, i = r.findAssetIndex(t)
|
|
, n = qs(r, i);
|
|
if (r.isAssetPastPlayoutLimit(n)) {
|
|
if (this.schedule) {
|
|
var a, s = null == (a = this.schedule.items) ? void 0 : a[this.findItemIndex(e) + 1];
|
|
s && this.bufferedToItem(s)
|
|
}
|
|
} else
|
|
this.bufferedToEvent(e, n)
|
|
}
|
|
,
|
|
r.advanceAfterAssetEnded = function(e, t, r) {
|
|
var i = qs(e, r);
|
|
if (e.isAssetPastPlayoutLimit(i)) {
|
|
if (this.schedule) {
|
|
var n = this.schedule.items;
|
|
if (n) {
|
|
var a = t + 1;
|
|
if (a >= n.length)
|
|
return void this.setSchedulePosition(-1);
|
|
var s = e.resumeTime;
|
|
this.timelinePos < s && (this.log(eo("advanceAfterAssetEnded", s)),
|
|
this.timelinePos = s,
|
|
e.appendInPlace && this.advanceInPlace(s),
|
|
this.checkBuffer(this.bufferedPos < s)),
|
|
this.setSchedulePosition(a)
|
|
}
|
|
}
|
|
} else {
|
|
if (e.appendInPlace) {
|
|
var o = e.assetList[i];
|
|
o && this.advanceInPlace(o.timelineStart)
|
|
}
|
|
this.setSchedulePosition(t, i)
|
|
}
|
|
}
|
|
,
|
|
r.setScheduleToAssetAtTime = function(e, t) {
|
|
var r = this.schedule;
|
|
if (r) {
|
|
var i = t.parentIdentifier
|
|
, n = r.getEvent(i);
|
|
if (n) {
|
|
var a = r.findEventIndex(i)
|
|
, s = r.findAssetIndex(n, e);
|
|
this.advanceAfterAssetEnded(n, a, s - 1)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.setSchedulePosition = function(e, t) {
|
|
var r, i = null == (r = this.schedule) ? void 0 : r.items;
|
|
if (i && !this.playbackDisabled) {
|
|
var n = e >= 0 ? i[e] : null;
|
|
this.log("setSchedulePosition " + e + ", " + t + " (" + (n ? $s(n) : n) + ") pos: " + this.timelinePos);
|
|
var a = this.waitingItem || this.playingItem
|
|
, s = this.playingLastItem;
|
|
if (this.isInterstitial(a)) {
|
|
var o = a.event
|
|
, l = this.playingAsset
|
|
, u = null == l ? void 0 : l.identifier
|
|
, d = u ? this.getAssetPlayer(u) : null;
|
|
if (d && u && (!this.eventItemsMatch(a, n) || void 0 !== t && u !== o.assetList[t].identifier)) {
|
|
var h, f = o.findAssetIndex(l);
|
|
if (this.log("INTERSTITIAL_ASSET_ENDED " + (f + 1) + "/" + o.assetList.length + " " + Xs(l)),
|
|
this.endedAsset = l,
|
|
this.playingAsset = null,
|
|
this.hls.trigger(b.INTERSTITIAL_ASSET_ENDED, {
|
|
asset: l,
|
|
assetListIndex: f,
|
|
event: o,
|
|
schedule: i.slice(0),
|
|
scheduleIndex: e,
|
|
player: d
|
|
}),
|
|
a !== this.playingItem)
|
|
return void (this.itemsMatch(a, this.playingItem) && !this.playingAsset && this.advanceAfterAssetEnded(o, this.findItemIndex(this.playingItem), f));
|
|
this.retreiveMediaSource(u, n),
|
|
!d.media || null != (h = this.detachedData) && h.mediaSource || d.detachMedia()
|
|
}
|
|
if (!this.eventItemsMatch(a, n) && (this.endedItem = a,
|
|
this.playingItem = null,
|
|
this.log("INTERSTITIAL_ENDED " + o + " " + $s(a)),
|
|
o.hasPlayed = !0,
|
|
this.hls.trigger(b.INTERSTITIAL_ENDED, {
|
|
event: o,
|
|
schedule: i.slice(0),
|
|
scheduleIndex: e
|
|
}),
|
|
o.cue.once)) {
|
|
var c;
|
|
this.updateSchedule();
|
|
var g = null == (c = this.schedule) ? void 0 : c.items;
|
|
if (n && g) {
|
|
var v = this.findItemIndex(n);
|
|
this.advanceSchedule(v, g, t, a, s)
|
|
}
|
|
return
|
|
}
|
|
}
|
|
this.advanceSchedule(e, i, t, a, s)
|
|
}
|
|
}
|
|
,
|
|
r.advanceSchedule = function(e, t, r, i, n) {
|
|
var a = this
|
|
, s = this.schedule;
|
|
if (s) {
|
|
var o = t[e] || null
|
|
, l = this.primaryMedia
|
|
, u = this.playerQueue;
|
|
if (u.length && u.forEach((function(t) {
|
|
var r = t.interstitial
|
|
, i = s.findEventIndex(r.identifier);
|
|
(i < e || i > e + 1) && a.clearInterstitial(r, o)
|
|
}
|
|
)),
|
|
this.isInterstitial(o)) {
|
|
this.timelinePos = Math.min(Math.max(this.timelinePos, o.start), o.end);
|
|
var d = o.event;
|
|
if (void 0 === r) {
|
|
var h = qs(d, (r = s.findAssetIndex(d, this.timelinePos)) - 1);
|
|
if (d.isAssetPastPlayoutLimit(h) || d.appendInPlace && this.timelinePos === o.end)
|
|
return void this.advanceAfterAssetEnded(d, e, r);
|
|
r = h
|
|
}
|
|
var f = this.waitingItem;
|
|
this.assetsBuffered(o, l) || this.setBufferingItem(o);
|
|
var c = this.preloadAssets(d, r);
|
|
if (this.eventItemsMatch(o, f || i) || (this.waitingItem = o,
|
|
this.log("INTERSTITIAL_STARTED " + $s(o) + " " + (d.appendInPlace ? "append in place" : "")),
|
|
this.hls.trigger(b.INTERSTITIAL_STARTED, {
|
|
event: d,
|
|
schedule: t.slice(0),
|
|
scheduleIndex: e
|
|
})),
|
|
!d.assetListLoaded)
|
|
return void this.log("Waiting for ASSET-LIST to complete loading " + d);
|
|
if (d.assetListLoader && (d.assetListLoader.destroy(),
|
|
d.assetListLoader = void 0),
|
|
!l)
|
|
return void this.log("Waiting for attachMedia to start Interstitial " + d);
|
|
this.waitingItem = this.endedItem = null,
|
|
this.playingItem = o;
|
|
var g = d.assetList[r];
|
|
if (!g)
|
|
return void this.advanceAfterAssetEnded(d, e, r || 0);
|
|
if (c || (c = this.getAssetPlayer(g.identifier)),
|
|
null === c || c.destroyed) {
|
|
var v = d.assetList.length;
|
|
this.warn("asset " + (r + 1) + "/" + v + " player destroyed " + d),
|
|
(c = this.createAssetPlayer(d, g, r)).loadSource()
|
|
}
|
|
if (!this.eventItemsMatch(o, this.bufferingItem) && d.appendInPlace && this.isAssetBuffered(g))
|
|
return;
|
|
this.startAssetPlayer(c, r, t, e, l),
|
|
this.shouldPlay && Js(c.media)
|
|
} else
|
|
o ? (this.resumePrimary(o, e, i),
|
|
this.shouldPlay && Js(this.hls.media)) : n && this.isInterstitial(i) && (this.endedItem = null,
|
|
this.playingItem = i,
|
|
i.event.appendInPlace || this.attachPrimary(s.durations.primary, null))
|
|
}
|
|
}
|
|
,
|
|
r.resumePrimary = function(e, t, r) {
|
|
var i, n;
|
|
if (this.playingItem = e,
|
|
this.playingAsset = this.endedAsset = null,
|
|
this.waitingItem = this.endedItem = null,
|
|
this.bufferedToItem(e),
|
|
this.log("resuming " + $s(e)),
|
|
null == (i = this.detachedData) || !i.mediaSource) {
|
|
var a = this.timelinePos;
|
|
(a < e.start || a >= e.end) && (a = this.getPrimaryResumption(e, t),
|
|
this.log(eo("resumePrimary", a)),
|
|
this.timelinePos = a),
|
|
this.attachPrimary(a, e)
|
|
}
|
|
if (r) {
|
|
var s = null == (n = this.schedule) ? void 0 : n.items;
|
|
s && (this.log("INTERSTITIALS_PRIMARY_RESUMED " + $s(e)),
|
|
this.hls.trigger(b.INTERSTITIALS_PRIMARY_RESUMED, {
|
|
schedule: s.slice(0),
|
|
scheduleIndex: t
|
|
}),
|
|
this.checkBuffer())
|
|
}
|
|
}
|
|
,
|
|
r.getPrimaryResumption = function(e, t) {
|
|
var r = e.start;
|
|
if (this.primaryLive) {
|
|
var i = this.primaryDetails;
|
|
if (0 === t)
|
|
return this.hls.startPosition;
|
|
if (i && (r < i.fragmentStart || r > i.edge))
|
|
return this.hls.liveSyncPosition || -1
|
|
}
|
|
return r
|
|
}
|
|
,
|
|
r.isAssetBuffered = function(e) {
|
|
var t = this.getAssetPlayer(e.identifier);
|
|
return null != t && t.hls ? t.hls.bufferedToEnd : ur.bufferInfo(this.primaryMedia, this.timelinePos, 0).end + 1 >= e.timelineStart + (e.duration || 0)
|
|
}
|
|
,
|
|
r.attachPrimary = function(e, t, r) {
|
|
t ? this.setBufferingItem(t) : this.bufferingItem = this.playingItem,
|
|
this.bufferingAsset = null;
|
|
var i = this.primaryMedia;
|
|
if (i) {
|
|
var n = this.hls;
|
|
n.media ? this.checkBuffer() : (this.transferMediaTo(n, i),
|
|
r && this.startLoadingPrimaryAt(e, r)),
|
|
r || (this.log(eo("attachPrimary", e)),
|
|
this.timelinePos = e,
|
|
this.startLoadingPrimaryAt(e, r))
|
|
}
|
|
}
|
|
,
|
|
r.startLoadingPrimaryAt = function(e, t) {
|
|
var r, i = this.hls;
|
|
!i.loadingEnabled || !i.media || Math.abs(((null == (r = i.mainForwardBufferInfo) ? void 0 : r.start) || i.media.currentTime) - e) > .5 ? i.startLoad(e, t) : i.bufferingEnabled || i.resumeBuffering()
|
|
}
|
|
,
|
|
r.onManifestLoading = function() {
|
|
var e;
|
|
this.stopLoad(),
|
|
null == (e = this.schedule) || e.reset(),
|
|
this.emptyPlayerQueue(),
|
|
this.clearScheduleState(),
|
|
this.shouldPlay = !1,
|
|
this.bufferedPos = this.timelinePos = -1,
|
|
this.mediaSelection = this.altSelection = this.manager = this.requiredTracks = null,
|
|
this.hls.off(b.BUFFER_CODECS, this.onBufferCodecs, this),
|
|
this.hls.on(b.BUFFER_CODECS, this.onBufferCodecs, this)
|
|
}
|
|
,
|
|
r.onLevelUpdated = function(e, t) {
|
|
if (-1 !== t.level && this.schedule) {
|
|
var r = this.hls.levels[t.level];
|
|
if (r.details) {
|
|
var i = d(d({}, this.mediaSelection || this.altSelection), {}, {
|
|
main: r
|
|
});
|
|
this.mediaSelection = i,
|
|
this.schedule.parseInterstitialDateRanges(i, this.hls.config.interstitialAppendInPlace),
|
|
!this.effectivePlayingItem && this.schedule.items && this.checkStart()
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.onAudioTrackUpdated = function(e, t) {
|
|
var r = this.hls.audioTracks[t.id]
|
|
, i = this.mediaSelection;
|
|
if (i) {
|
|
var n = d(d({}, i), {}, {
|
|
audio: r
|
|
});
|
|
this.mediaSelection = n
|
|
} else
|
|
this.altSelection = d(d({}, this.altSelection), {}, {
|
|
audio: r
|
|
})
|
|
}
|
|
,
|
|
r.onSubtitleTrackUpdated = function(e, t) {
|
|
var r = this.hls.subtitleTracks[t.id]
|
|
, i = this.mediaSelection;
|
|
if (i) {
|
|
var n = d(d({}, i), {}, {
|
|
subtitles: r
|
|
});
|
|
this.mediaSelection = n
|
|
} else
|
|
this.altSelection = d(d({}, this.altSelection), {}, {
|
|
subtitles: r
|
|
})
|
|
}
|
|
,
|
|
r.onAudioTrackSwitching = function(e, t) {
|
|
var r = ht(t);
|
|
this.playerQueue.forEach((function(e) {
|
|
var i = e.hls;
|
|
return i && (i.setAudioOption(t) || i.setAudioOption(r))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.onSubtitleTrackSwitch = function(e, t) {
|
|
var r = ht(t);
|
|
this.playerQueue.forEach((function(e) {
|
|
var i = e.hls;
|
|
return i && (i.setSubtitleOption(t) || -1 !== t.id && i.setSubtitleOption(r))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.onBufferCodecs = function(e, t) {
|
|
var r = t.tracks;
|
|
r && (this.requiredTracks = r)
|
|
}
|
|
,
|
|
r.onBufferAppended = function(e, t) {
|
|
this.checkBuffer()
|
|
}
|
|
,
|
|
r.onBufferFlushed = function(e, t) {
|
|
var r = this.playingItem;
|
|
if (r && !this.itemsMatch(r, this.bufferingItem) && !this.isInterstitial(r)) {
|
|
var i = this.timelinePos;
|
|
this.bufferedPos = i,
|
|
this.checkBuffer()
|
|
}
|
|
}
|
|
,
|
|
r.onBufferedToEnd = function(e) {
|
|
if (this.schedule) {
|
|
var t = this.schedule.events;
|
|
if (this.bufferedPos < Number.MAX_VALUE && t) {
|
|
for (var r = 0; r < t.length; r++) {
|
|
var i = t[r];
|
|
if (i.cue.post) {
|
|
var n, a = this.schedule.findEventIndex(i.identifier), s = null == (n = this.schedule.items) ? void 0 : n[a];
|
|
this.isInterstitial(s) && this.eventItemsMatch(s, this.bufferingItem) && this.bufferedToItem(s, 0);
|
|
break
|
|
}
|
|
}
|
|
this.bufferedPos = Number.MAX_VALUE
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.onMediaEnded = function(e) {
|
|
var t = this.playingItem;
|
|
if (!this.playingLastItem && t) {
|
|
var r = this.findItemIndex(t);
|
|
this.setSchedulePosition(r + 1)
|
|
} else
|
|
this.shouldPlay = !1
|
|
}
|
|
,
|
|
r.updateItem = function(e, t) {
|
|
var r, i = null == (r = this.schedule) ? void 0 : r.items;
|
|
return e && i && i[this.findItemIndex(e, t)] || null
|
|
}
|
|
,
|
|
r.trimInPlace = function(e, t) {
|
|
var r = this;
|
|
if (this.isInterstitial(e) && e.event.appendInPlace && t.end - e.end > .25) {
|
|
e.event.assetList.forEach((function(t, i) {
|
|
e.event.isAssetPastPlayoutLimit(i) && r.clearAssetPlayer(t.identifier, null)
|
|
}
|
|
));
|
|
var i = e.end + .25
|
|
, n = ur.bufferInfo(this.primaryMedia, i, 0);
|
|
(n.end > i || (n.nextStart || 0) > i) && (this.log("trim buffered interstitial " + $s(e) + " (was " + $s(t) + ")"),
|
|
this.attachPrimary(i, null, !0),
|
|
this.flushFrontBuffer(i))
|
|
}
|
|
}
|
|
,
|
|
r.itemsMatch = function(e, t) {
|
|
return !!t && (e === t || e.event && t.event && this.eventItemsMatch(e, t) || !e.event && !t.event && this.findItemIndex(e) === this.findItemIndex(t))
|
|
}
|
|
,
|
|
r.eventItemsMatch = function(e, t) {
|
|
var r;
|
|
return !!t && (e === t || e.event.identifier === (null == (r = t.event) ? void 0 : r.identifier))
|
|
}
|
|
,
|
|
r.findItemIndex = function(e, t) {
|
|
return e && this.schedule ? this.schedule.findItemIndex(e, t) : -1
|
|
}
|
|
,
|
|
r.updateSchedule = function(e) {
|
|
var t;
|
|
void 0 === e && (e = !1);
|
|
var r = this.mediaSelection;
|
|
r && (null == (t = this.schedule) || t.updateSchedule(r, [], e))
|
|
}
|
|
,
|
|
r.checkBuffer = function(e) {
|
|
var t, r = null == (t = this.schedule) ? void 0 : t.items;
|
|
if (r) {
|
|
var i = ur.bufferInfo(this.primaryMedia, this.timelinePos, 0);
|
|
e && (this.bufferedPos = this.timelinePos),
|
|
e || (e = i.len < 1),
|
|
this.updateBufferedPos(i.end, r, e)
|
|
}
|
|
}
|
|
,
|
|
r.updateBufferedPos = function(e, t, r) {
|
|
var i = this.schedule
|
|
, n = this.bufferingItem;
|
|
if (!(this.bufferedPos > e) && i)
|
|
if (1 === t.length && this.itemsMatch(t[0], n))
|
|
this.bufferedPos = e;
|
|
else {
|
|
var a = this.playingItem
|
|
, s = this.findItemIndex(a)
|
|
, o = i.findItemIndexAtTime(e);
|
|
if (this.bufferedPos < e) {
|
|
var l, u = this.findItemIndex(n), d = Math.min(u + 1, t.length - 1), h = t[d];
|
|
if ((-1 === o && n && e >= n.end || null != (l = h.event) && l.appendInPlace && e + .01 >= h.start) && (o = d),
|
|
this.isInterstitial(n)) {
|
|
var f = n.event;
|
|
if (d - s > 1 && !1 === f.appendInPlace)
|
|
return;
|
|
if (0 === f.assetList.length && f.assetListLoader)
|
|
return
|
|
}
|
|
if (this.bufferedPos = e,
|
|
o > u && o > s)
|
|
this.bufferedToItem(h);
|
|
else {
|
|
var c = this.primaryDetails;
|
|
this.primaryLive && c && e > c.edge - c.targetduration && h.start < c.edge + this.hls.config.interstitialLiveLookAhead && this.isInterstitial(h) && this.preloadAssets(h.event, 0)
|
|
}
|
|
} else
|
|
r && a && !this.itemsMatch(a, n) && (o === s ? this.bufferedToItem(a) : o === s + 1 && this.bufferedToItem(t[o]))
|
|
}
|
|
}
|
|
,
|
|
r.assetsBuffered = function(e, t) {
|
|
var r = this;
|
|
return 0 !== e.event.assetList.length && !e.event.assetList.some((function(e) {
|
|
var i = r.getAssetPlayer(e.identifier);
|
|
return !(null != i && i.bufferedInPlaceToEnd(t))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.setBufferingItem = function(e) {
|
|
var t = this
|
|
, r = this.bufferingItem
|
|
, i = this.schedule;
|
|
if (!this.itemsMatch(e, r) && i) {
|
|
var n = i.items
|
|
, a = i.events;
|
|
if (!n || !a)
|
|
return r;
|
|
var s = this.isInterstitial(e)
|
|
, o = this.getBufferingPlayer();
|
|
this.bufferingItem = e,
|
|
this.bufferedPos = Math.max(e.start, Math.min(e.end, this.timelinePos));
|
|
var l = o ? o.remaining : r ? r.end - this.timelinePos : 0;
|
|
if (this.log("INTERSTITIALS_BUFFERED_TO_BOUNDARY " + $s(e) + (r ? " (" + l.toFixed(2) + " remaining)" : "")),
|
|
!this.playbackDisabled)
|
|
if (s) {
|
|
var u = i.findAssetIndex(e.event, this.bufferedPos);
|
|
e.event.assetList.forEach((function(e, r) {
|
|
var i = t.getAssetPlayer(e.identifier);
|
|
i && (r === u && i.loadSource(),
|
|
i.resumeBuffering())
|
|
}
|
|
))
|
|
} else
|
|
this.hls.resumeBuffering(),
|
|
this.playerQueue.forEach((function(e) {
|
|
return e.pauseBuffering()
|
|
}
|
|
));
|
|
this.hls.trigger(b.INTERSTITIALS_BUFFERED_TO_BOUNDARY, {
|
|
events: a.slice(0),
|
|
schedule: n.slice(0),
|
|
bufferingIndex: this.findItemIndex(e),
|
|
playingIndex: this.findItemIndex(this.playingItem)
|
|
})
|
|
} else
|
|
this.bufferingItem !== e && (this.bufferingItem = e);
|
|
return r
|
|
}
|
|
,
|
|
r.bufferedToItem = function(e, t) {
|
|
void 0 === t && (t = 0);
|
|
var r = this.setBufferingItem(e);
|
|
if (!this.playbackDisabled)
|
|
if (this.isInterstitial(e))
|
|
this.bufferedToEvent(e, t);
|
|
else if (null !== r) {
|
|
this.bufferingAsset = null;
|
|
var i = this.detachedData;
|
|
i && i.mediaSource ? this.attachPrimary(e.start, e, !0) : this.preloadPrimary(e)
|
|
}
|
|
}
|
|
,
|
|
r.preloadPrimary = function(e) {
|
|
var t = this.findItemIndex(e)
|
|
, r = this.getPrimaryResumption(e, t);
|
|
this.startLoadingPrimaryAt(r)
|
|
}
|
|
,
|
|
r.bufferedToEvent = function(e, t) {
|
|
var r = e.event
|
|
, i = 0 === r.assetList.length && !r.assetListLoader
|
|
, n = r.cue.once;
|
|
if (i || !n) {
|
|
var a = this.preloadAssets(r, t);
|
|
if (null != a && a.interstitial.appendInPlace) {
|
|
var s = this.primaryMedia;
|
|
s && this.bufferAssetPlayer(a, s)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.preloadAssets = function(e, t) {
|
|
var r = e.assetUrl
|
|
, i = e.assetList.length
|
|
, n = 0 === i && !e.assetListLoader
|
|
, a = e.cue.once;
|
|
if (n) {
|
|
var s, o = e.timelineStart;
|
|
if (e.appendInPlace) {
|
|
var l, u = this.playingItem;
|
|
this.isInterstitial(u) || (null == u || null == (l = u.nextEvent) ? void 0 : l.identifier) !== e.identifier || this.flushFrontBuffer(o + .25)
|
|
}
|
|
var d = 0;
|
|
if (!this.playingItem && this.primaryLive && -1 === (d = this.hls.startPosition) && (d = this.hls.liveSyncPosition || 0),
|
|
d && !e.cue.pre && !e.cue.post) {
|
|
var h = d - o;
|
|
h > 0 && (s = Math.round(1e3 * h) / 1e3)
|
|
}
|
|
if (this.log("Load interstitial asset " + (t + 1) + "/" + (r ? 1 : i) + " " + e + (s ? " live-start: " + d + " start-offset: " + s : "")),
|
|
r)
|
|
return this.createAsset(e, 0, 0, o, e.duration, r);
|
|
var f = this.assetListLoader.loadAssetList(e, s);
|
|
f && (e.assetListLoader = f)
|
|
} else if (!a && i) {
|
|
for (var c = t; c < i; c++) {
|
|
var g = e.assetList[c]
|
|
, v = this.getAssetPlayerQueueIndex(g.identifier);
|
|
-1 !== v && !this.playerQueue[v].destroyed || g.error || this.createAssetPlayer(e, g, c)
|
|
}
|
|
var m = e.assetList[t];
|
|
if (m) {
|
|
var p = this.getAssetPlayer(m.identifier);
|
|
return p && p.loadSource(),
|
|
p
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
,
|
|
r.flushFrontBuffer = function(e) {
|
|
var t = this
|
|
, r = this.requiredTracks;
|
|
r && (this.log("Removing front buffer starting at " + e),
|
|
Object.keys(r).forEach((function(r) {
|
|
t.hls.trigger(b.BUFFER_FLUSHING, {
|
|
startOffset: e,
|
|
endOffset: 1 / 0,
|
|
type: r
|
|
})
|
|
}
|
|
)))
|
|
}
|
|
,
|
|
r.getAssetPlayerQueueIndex = function(e) {
|
|
for (var t = this.playerQueue, r = 0; r < t.length; r++)
|
|
if (e === t[r].assetId)
|
|
return r;
|
|
return -1
|
|
}
|
|
,
|
|
r.getAssetPlayer = function(e) {
|
|
var t = this.getAssetPlayerQueueIndex(e);
|
|
return this.playerQueue[t] || null
|
|
}
|
|
,
|
|
r.getBufferingPlayer = function() {
|
|
var e = this.playerQueue
|
|
, t = this.primaryMedia;
|
|
if (t)
|
|
for (var r = 0; r < e.length; r++)
|
|
if (e[r].media === t)
|
|
return e[r];
|
|
return null
|
|
}
|
|
,
|
|
r.createAsset = function(e, t, r, i, n, a) {
|
|
var s = {
|
|
parentIdentifier: e.identifier,
|
|
identifier: Hs(e, a, t),
|
|
duration: n,
|
|
startOffset: r,
|
|
timelineStart: i,
|
|
uri: a
|
|
};
|
|
return this.createAssetPlayer(e, s, t)
|
|
}
|
|
,
|
|
r.createAssetPlayer = function(e, t, r) {
|
|
var i = this
|
|
, n = this.hls
|
|
, s = n.userConfig
|
|
, o = s.videoPreference
|
|
, l = n.loadLevelObj || n.levels[n.currentLevel];
|
|
(o || l) && (o = a({}, o),
|
|
l.videoCodec && (o.videoCodec = l.videoCodec),
|
|
l.videoRange && (o.allowedVideoRanges = [l.videoRange]));
|
|
var u = n.audioTracks[n.audioTrack]
|
|
, h = n.subtitleTracks[n.subtitleTrack]
|
|
, f = 0;
|
|
if (this.primaryLive || e.appendInPlace) {
|
|
var c = this.timelinePos - t.timelineStart;
|
|
if (c > 1) {
|
|
var g = t.duration;
|
|
g && c < g && (f = c)
|
|
}
|
|
}
|
|
var v = t.identifier
|
|
, m = d(d({}, s), {}, {
|
|
maxMaxBufferLength: Math.min(180, n.config.maxMaxBufferLength),
|
|
autoStartLoad: !0,
|
|
startFragPrefetch: !0,
|
|
primarySessionId: n.sessionId,
|
|
assetPlayerId: v,
|
|
abrEwmaDefaultEstimate: n.bandwidthEstimate,
|
|
interstitialsController: void 0,
|
|
startPosition: f,
|
|
liveDurationInfinity: !1,
|
|
testBandwidth: !1,
|
|
videoPreference: o,
|
|
audioPreference: u || s.audioPreference,
|
|
subtitlePreference: h || s.subtitlePreference
|
|
});
|
|
e.appendInPlace && (e.appendInPlaceStarted = !0,
|
|
t.timelineStart && (m.timelineOffset = t.timelineStart));
|
|
var p = m.cmcd;
|
|
null != p && p.sessionId && p.contentId && (m.cmcd = a({}, p, {
|
|
contentId: Gs(t.uri)
|
|
})),
|
|
this.getAssetPlayer(v) && this.warn("Duplicate date range identifier " + e + " and asset " + v);
|
|
var y = new Qs(this.HlsPlayerClass,m,e,t);
|
|
this.playerQueue.push(y),
|
|
e.assetList[r] = t;
|
|
var E = !0
|
|
, T = function(n) {
|
|
if (n.live) {
|
|
var a, s = new Error("Interstitials MUST be VOD assets " + e), o = {
|
|
fatal: !0,
|
|
type: R.OTHER_ERROR,
|
|
details: k.INTERSTITIAL_ASSET_ITEM_ERROR,
|
|
error: s
|
|
}, l = (null == (a = i.schedule) ? void 0 : a.findEventIndex(e.identifier)) || -1;
|
|
i.handleAssetItemError(o, e, l, r, s.message)
|
|
} else {
|
|
var u = n.edge - n.fragmentStart
|
|
, d = t.duration;
|
|
(E || null === d || u > d) && (E = !1,
|
|
i.log('Interstitial asset "' + v + '" duration change ' + d + " > " + u),
|
|
t.duration = u,
|
|
i.updateSchedule())
|
|
}
|
|
};
|
|
y.on(b.LEVEL_UPDATED, (function(e, t) {
|
|
var r = t.details;
|
|
return T(r)
|
|
}
|
|
)),
|
|
y.on(b.LEVEL_PTS_UPDATED, (function(e, t) {
|
|
var r = t.details;
|
|
return T(r)
|
|
}
|
|
)),
|
|
y.on(b.EVENT_CUE_ENTER, (function() {
|
|
return i.onInterstitialCueEnter()
|
|
}
|
|
));
|
|
var S = function(e, t) {
|
|
var r = i.getAssetPlayer(v);
|
|
if (r && t.tracks) {
|
|
r.off(b.BUFFER_CODECS, S),
|
|
r.tracks = t.tracks;
|
|
var n = i.primaryMedia;
|
|
i.bufferingAsset === r.assetItem && n && !r.media && i.bufferAssetPlayer(r, n)
|
|
}
|
|
};
|
|
y.on(b.BUFFER_CODECS, S),
|
|
y.on(b.BUFFERED_TO_END, (function() {
|
|
var r, n = i.getAssetPlayer(v);
|
|
if (i.log("buffered to end of asset " + n),
|
|
n && i.schedule) {
|
|
var a = i.schedule.findEventIndex(e.identifier)
|
|
, s = null == (r = i.schedule.items) ? void 0 : r[a];
|
|
i.isInterstitial(s) && i.advanceAssetBuffering(s, t)
|
|
}
|
|
}
|
|
));
|
|
var A = function(t) {
|
|
return function() {
|
|
if (i.getAssetPlayer(v) && i.schedule) {
|
|
i.shouldPlay = !0;
|
|
var r = i.schedule.findEventIndex(e.identifier);
|
|
i.advanceAfterAssetEnded(e, r, t)
|
|
}
|
|
}
|
|
};
|
|
return y.once(b.MEDIA_ENDED, A(r)),
|
|
y.once(b.PLAYOUT_LIMIT_REACHED, A(1 / 0)),
|
|
y.on(b.ERROR, (function(t, n) {
|
|
if (i.schedule) {
|
|
var a = i.getAssetPlayer(v);
|
|
if (n.details === k.BUFFER_STALLED_ERROR)
|
|
return null != a && a.appendInPlace ? void i.handleInPlaceStall(e) : (i.onTimeupdate(),
|
|
void i.checkBuffer(!0));
|
|
i.handleAssetItemError(n, e, i.schedule.findEventIndex(e.identifier), r, "Asset player error " + n.error + " " + e)
|
|
}
|
|
}
|
|
)),
|
|
y.on(b.DESTROYING, (function() {
|
|
if (i.getAssetPlayer(v) && i.schedule) {
|
|
var t = new Error("Asset player destroyed unexpectedly " + v)
|
|
, n = {
|
|
fatal: !0,
|
|
type: R.OTHER_ERROR,
|
|
details: k.INTERSTITIAL_ASSET_ITEM_ERROR,
|
|
error: t
|
|
};
|
|
i.handleAssetItemError(n, e, i.schedule.findEventIndex(e.identifier), r, t.message)
|
|
}
|
|
}
|
|
)),
|
|
this.log("INTERSTITIAL_ASSET_PLAYER_CREATED " + Xs(t)),
|
|
this.hls.trigger(b.INTERSTITIAL_ASSET_PLAYER_CREATED, {
|
|
asset: t,
|
|
assetListIndex: r,
|
|
event: e,
|
|
player: y
|
|
}),
|
|
y
|
|
}
|
|
,
|
|
r.clearInterstitial = function(e, t) {
|
|
var r = this;
|
|
e.assetList.forEach((function(e) {
|
|
r.clearAssetPlayer(e.identifier, t)
|
|
}
|
|
)),
|
|
e.reset()
|
|
}
|
|
,
|
|
r.resetAssetPlayer = function(e) {
|
|
var t = this.getAssetPlayerQueueIndex(e);
|
|
if (-1 !== t) {
|
|
this.log('reset asset player "' + e + '" after error');
|
|
var r = this.playerQueue[t];
|
|
this.transferMediaFromPlayer(r, null),
|
|
r.resetDetails()
|
|
}
|
|
}
|
|
,
|
|
r.clearAssetPlayer = function(e, t) {
|
|
var r = this.getAssetPlayerQueueIndex(e);
|
|
if (-1 !== r) {
|
|
var i = this.playerQueue[r];
|
|
this.log("clear " + i + " toSegment: " + (t ? $s(t) : t)),
|
|
this.transferMediaFromPlayer(i, t),
|
|
this.playerQueue.splice(r, 1),
|
|
i.destroy()
|
|
}
|
|
}
|
|
,
|
|
r.emptyPlayerQueue = function() {
|
|
for (var e; e = this.playerQueue.pop(); )
|
|
e.destroy();
|
|
this.playerQueue = []
|
|
}
|
|
,
|
|
r.startAssetPlayer = function(e, t, r, i, n) {
|
|
var a = e.interstitial
|
|
, s = e.assetItem
|
|
, o = e.assetId
|
|
, l = a.assetList.length
|
|
, u = this.playingAsset;
|
|
this.endedAsset = null,
|
|
this.playingAsset = s,
|
|
u && u.identifier === o || (u && (this.clearAssetPlayer(u.identifier, r[i]),
|
|
delete u.error),
|
|
this.log("INTERSTITIAL_ASSET_STARTED " + (t + 1) + "/" + l + " " + Xs(s)),
|
|
this.hls.trigger(b.INTERSTITIAL_ASSET_STARTED, {
|
|
asset: s,
|
|
assetListIndex: t,
|
|
event: a,
|
|
schedule: r.slice(0),
|
|
scheduleIndex: i,
|
|
player: e
|
|
})),
|
|
this.bufferAssetPlayer(e, n)
|
|
}
|
|
,
|
|
r.bufferAssetPlayer = function(e, t) {
|
|
var r, i;
|
|
if (this.schedule) {
|
|
var n = e.interstitial
|
|
, a = e.assetItem
|
|
, s = this.schedule.findEventIndex(n.identifier)
|
|
, o = null == (r = this.schedule.items) ? void 0 : r[s];
|
|
if (o) {
|
|
e.loadSource(),
|
|
this.setBufferingItem(o),
|
|
this.bufferingAsset = a;
|
|
var l = this.getBufferingPlayer();
|
|
if (l !== e) {
|
|
var u = n.appendInPlace;
|
|
if (!u || !1 !== (null == l ? void 0 : l.interstitial.appendInPlace)) {
|
|
var d = (null == l ? void 0 : l.tracks) || (null == (i = this.detachedData) ? void 0 : i.tracks) || this.requiredTracks;
|
|
if (u && a !== this.playingAsset) {
|
|
if (!e.tracks)
|
|
return void this.log("Waiting for track info before buffering " + e);
|
|
if (d && !j(d, e.tracks)) {
|
|
var h = new Error("Asset " + Xs(a) + " SourceBuffer tracks ('" + Object.keys(e.tracks) + "') are not compatible with primary content tracks ('" + Object.keys(d) + "')")
|
|
, f = {
|
|
fatal: !0,
|
|
type: R.OTHER_ERROR,
|
|
details: k.INTERSTITIAL_ASSET_ITEM_ERROR,
|
|
error: h
|
|
}
|
|
, c = n.findAssetIndex(a);
|
|
return void this.handleAssetItemError(f, n, s, c, h.message)
|
|
}
|
|
}
|
|
this.transferMediaTo(e, t)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.handleInPlaceStall = function(e) {
|
|
var t = this.schedule
|
|
, r = this.primaryMedia;
|
|
if (t && r) {
|
|
var i = r.currentTime
|
|
, n = t.findAssetIndex(e, i)
|
|
, a = e.assetList[n];
|
|
if (a) {
|
|
var s = this.getAssetPlayer(a.identifier);
|
|
if (s) {
|
|
var o = s.currentTime || i - a.timelineStart
|
|
, l = s.duration - o;
|
|
if (this.warn("Stalled at " + o + " of " + (o + l) + " in " + s + " " + e + " (media.currentTime: " + i + ")"),
|
|
o && (l / r.playbackRate < .5 || s.bufferedInPlaceToEnd(r)) && s.hls) {
|
|
var u = t.findEventIndex(e.identifier);
|
|
this.advanceAfterAssetEnded(e, u, n)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.advanceInPlace = function(e) {
|
|
var t = this.primaryMedia;
|
|
t && t.currentTime < e && (t.currentTime = e)
|
|
}
|
|
,
|
|
r.handleAssetItemError = function(e, t, r, i, n) {
|
|
if (e.details !== k.BUFFER_STALLED_ERROR) {
|
|
var s = t.assetList[i] || null;
|
|
if (this.warn("INTERSTITIAL_ASSET_ERROR " + (s ? Xs(s) : s) + " " + e.error),
|
|
this.schedule) {
|
|
var o = (null == s ? void 0 : s.identifier) || ""
|
|
, l = this.getAssetPlayerQueueIndex(o)
|
|
, u = this.playerQueue[l] || null
|
|
, d = this.schedule.items
|
|
, h = a({}, e, {
|
|
fatal: !1,
|
|
errorAction: Gt(!0),
|
|
asset: s,
|
|
assetListIndex: i,
|
|
event: t,
|
|
schedule: d,
|
|
scheduleIndex: r,
|
|
player: u
|
|
});
|
|
if (this.hls.trigger(b.INTERSTITIAL_ASSET_ERROR, h),
|
|
e.fatal) {
|
|
var f = this.playingAsset
|
|
, c = this.bufferingAsset
|
|
, g = new Error(n);
|
|
if (s && (this.clearAssetPlayer(o, null),
|
|
s.error = g),
|
|
t.assetList.some((function(e) {
|
|
return !e.error
|
|
}
|
|
)))
|
|
for (var v = i; v < t.assetList.length; v++)
|
|
this.resetAssetPlayer(t.assetList[v].identifier);
|
|
else
|
|
t.error = g;
|
|
this.updateSchedule(!0),
|
|
t.error ? this.primaryFallback(t) : f && f.identifier === o ? this.advanceAfterAssetEnded(t, r, i) : c && c.identifier === o && this.isInterstitial(this.bufferingItem) && this.advanceAssetBuffering(this.bufferingItem, c)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.primaryFallback = function(e) {
|
|
var t = e.timelineStart
|
|
, r = this.effectivePlayingItem;
|
|
if (r) {
|
|
this.log('Fallback to primary from event "' + e.identifier + '" start: ' + t + " pos: " + this.timelinePos + " playing: " + $s(r) + " error: " + e.error);
|
|
var i = this.timelinePos;
|
|
-1 === i && (i = this.hls.startPosition);
|
|
var n = this.updateItem(r, i);
|
|
if (this.itemsMatch(r, n) && this.clearInterstitial(e, null),
|
|
e.appendInPlace && (this.attachPrimary(t, null),
|
|
this.flushFrontBuffer(t)),
|
|
!this.schedule)
|
|
return;
|
|
var a = this.schedule.findItemIndexAtTime(i);
|
|
this.setSchedulePosition(a)
|
|
} else
|
|
this.checkStart()
|
|
}
|
|
,
|
|
r.onAssetListLoaded = function(e, t) {
|
|
var r, i, n = this, a = t.event, s = a.identifier, o = t.assetListResponse.ASSETS;
|
|
if (null != (r = this.schedule) && r.hasEvent(s)) {
|
|
var l = a.timelineStart
|
|
, u = a.duration
|
|
, d = 0;
|
|
o.forEach((function(e, t) {
|
|
var r = parseFloat(e.DURATION);
|
|
n.createAsset(a, t, d, l + d, r, e.URI),
|
|
d += r
|
|
}
|
|
)),
|
|
a.duration = d,
|
|
this.log("Loaded asset-list with duration: " + d + " (was: " + u + ") " + a);
|
|
var h = this.waitingItem
|
|
, f = (null == h ? void 0 : h.event.identifier) === s;
|
|
this.updateSchedule();
|
|
var c = null == (i = this.bufferingItem) ? void 0 : i.event;
|
|
if (f) {
|
|
var g, v = this.schedule.findEventIndex(s), m = null == (g = this.schedule.items) ? void 0 : g[v];
|
|
if (m) {
|
|
if (!this.playingItem && this.timelinePos > m.end && this.schedule.findItemIndexAtTime(this.timelinePos) !== v)
|
|
return a.error = new Error("Interstitial no longer within playback range " + this.timelinePos + " " + a),
|
|
this.updateSchedule(!0),
|
|
void this.primaryFallback(a);
|
|
this.setBufferingItem(m)
|
|
}
|
|
this.setSchedulePosition(v)
|
|
} else if ((null == c ? void 0 : c.identifier) === s) {
|
|
var p = a.assetList[0];
|
|
if (p) {
|
|
var y = this.getAssetPlayer(p.identifier);
|
|
if (c.appendInPlace) {
|
|
var E = this.primaryMedia;
|
|
y && E && this.bufferAssetPlayer(y, E)
|
|
} else
|
|
y && y.loadSource()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.onError = function(e, t) {
|
|
if (this.schedule)
|
|
switch (t.details) {
|
|
case k.ASSET_LIST_PARSING_ERROR:
|
|
case k.ASSET_LIST_LOAD_ERROR:
|
|
case k.ASSET_LIST_LOAD_TIMEOUT:
|
|
var r = t.interstitial;
|
|
r && (this.updateSchedule(!0),
|
|
this.primaryFallback(r));
|
|
break;
|
|
case k.BUFFER_STALLED_ERROR:
|
|
var i = this.endedItem || this.waitingItem || this.playingItem;
|
|
if (this.isInterstitial(i) && i.event.appendInPlace)
|
|
return void this.handleInPlaceStall(i.event);
|
|
this.log("Primary player stall @" + this.timelinePos + " bufferedPos: " + this.bufferedPos),
|
|
this.onTimeupdate(),
|
|
this.checkBuffer(!0)
|
|
}
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "interstitialsManager",
|
|
get: function() {
|
|
if (!this.hls)
|
|
return null;
|
|
if (this.manager)
|
|
return this.manager;
|
|
var e = this
|
|
, t = function() {
|
|
return e.bufferingItem || e.waitingItem
|
|
}
|
|
, r = function(t) {
|
|
return t ? e.getAssetPlayer(t.identifier) : t
|
|
}
|
|
, i = function(t, i, a, s, o) {
|
|
if (t) {
|
|
var l = t[i].start
|
|
, u = t.event;
|
|
if (u) {
|
|
if ("playout" === i || u.timelineOccupancy !== Vs.Point) {
|
|
var d = r(a);
|
|
(null == d ? void 0 : d.interstitial) === u && (l += d.assetItem.startOffset + d[o])
|
|
}
|
|
} else
|
|
l += ("bufferedPos" === s ? n() : e[s]) - t.start;
|
|
return l
|
|
}
|
|
return 0
|
|
}
|
|
, n = function() {
|
|
var t = e.bufferedPos;
|
|
return t === Number.MAX_VALUE ? a("primary") : Math.max(t, 0)
|
|
}
|
|
, a = function(t) {
|
|
var r, i;
|
|
return null != (r = e.primaryDetails) && r.live ? e.primaryDetails.edge : (null == (i = e.schedule) ? void 0 : i.durations[t]) || 0
|
|
}
|
|
, s = function(t, n) {
|
|
var a, s, o = e.effectivePlayingItem;
|
|
if ((null == o || null == (a = o.event) || !a.restrictions.skip) && e.schedule) {
|
|
e.log("seek to " + t + ' "' + n + '"');
|
|
var l = e.effectivePlayingItem
|
|
, u = e.schedule.findItemIndexAtTime(t, n)
|
|
, d = null == (s = e.schedule.items) ? void 0 : s[u]
|
|
, h = e.getBufferingPlayer()
|
|
, f = null == h ? void 0 : h.interstitial
|
|
, c = null == f ? void 0 : f.appendInPlace
|
|
, g = l && e.itemsMatch(l, d);
|
|
if (l && (c || g)) {
|
|
var v = r(e.playingAsset)
|
|
, m = (null == v ? void 0 : v.media) || e.primaryMedia;
|
|
if (m) {
|
|
var p = "primary" === n ? m.currentTime : i(l, n, e.playingAsset, "timelinePos", "currentTime")
|
|
, y = t - p
|
|
, E = (c ? p : m.currentTime) + y;
|
|
if (E >= 0 && (!v || c || E <= v.duration))
|
|
return void (m.currentTime = E)
|
|
}
|
|
}
|
|
if (d) {
|
|
var T = t;
|
|
if ("primary" !== n) {
|
|
var S = t - d[n].start;
|
|
T = d.start + S
|
|
}
|
|
var A = !e.isInterstitial(d);
|
|
if (e.isInterstitial(l) && !l.event.appendInPlace || !A && !d.event.appendInPlace) {
|
|
if (l) {
|
|
var L = e.findItemIndex(l);
|
|
if (u > L) {
|
|
var I = e.schedule.findJumpRestrictedIndex(L + 1, u);
|
|
if (I > L)
|
|
return void e.setSchedulePosition(I)
|
|
}
|
|
var R = 0;
|
|
if (A)
|
|
e.timelinePos = T,
|
|
e.checkBuffer();
|
|
else
|
|
for (var k = d.event.assetList, b = t - (d[n] || d).start, D = k.length; D--; ) {
|
|
var _ = k[D];
|
|
if (_.duration && b >= _.startOffset && b < _.startOffset + _.duration) {
|
|
R = D;
|
|
break
|
|
}
|
|
}
|
|
e.setSchedulePosition(u, R)
|
|
}
|
|
} else {
|
|
var P = e.media || (c ? null == h ? void 0 : h.media : null);
|
|
P && (P.currentTime = T)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
, o = function() {
|
|
var r = e.effectivePlayingItem;
|
|
if (e.isInterstitial(r))
|
|
return r;
|
|
var i = t();
|
|
return e.isInterstitial(i) ? i : null
|
|
}
|
|
, l = {
|
|
get bufferedEnd() {
|
|
var r, n = t(), a = e.bufferingItem;
|
|
return a && a === n && (i(a, "playout", e.bufferingAsset, "bufferedPos", "bufferedEnd") - a.playout.start || (null == (r = e.bufferingAsset) ? void 0 : r.startOffset)) || 0
|
|
},
|
|
get currentTime() {
|
|
var t = o()
|
|
, r = e.effectivePlayingItem;
|
|
return r && r === t ? i(r, "playout", e.effectivePlayingAsset, "timelinePos", "currentTime") - r.playout.start : 0
|
|
},
|
|
set currentTime(t) {
|
|
var r = o()
|
|
, i = e.effectivePlayingItem;
|
|
i && i === r && s(t + i.playout.start, "playout")
|
|
},
|
|
get duration() {
|
|
var e = o();
|
|
return e ? e.playout.end - e.playout.start : 0
|
|
},
|
|
get assetPlayers() {
|
|
var t, r = null == (t = o()) ? void 0 : t.event.assetList;
|
|
return r ? r.map((function(t) {
|
|
return e.getAssetPlayer(t.identifier)
|
|
}
|
|
)) : []
|
|
},
|
|
get playingIndex() {
|
|
var t, r = null == (t = o()) ? void 0 : t.event;
|
|
return r && e.effectivePlayingAsset ? r.findAssetIndex(e.effectivePlayingAsset) : -1
|
|
},
|
|
get scheduleItem() {
|
|
return o()
|
|
}
|
|
};
|
|
return this.manager = {
|
|
get events() {
|
|
var t;
|
|
return (null == (t = e.schedule) || null == (t = t.events) ? void 0 : t.slice(0)) || []
|
|
},
|
|
get schedule() {
|
|
var t;
|
|
return (null == (t = e.schedule) || null == (t = t.items) ? void 0 : t.slice(0)) || []
|
|
},
|
|
get interstitialPlayer() {
|
|
return o() ? l : null
|
|
},
|
|
get playerQueue() {
|
|
return e.playerQueue.slice(0)
|
|
},
|
|
get bufferingAsset() {
|
|
return e.bufferingAsset
|
|
},
|
|
get bufferingItem() {
|
|
return t()
|
|
},
|
|
get bufferingIndex() {
|
|
var r = t();
|
|
return e.findItemIndex(r)
|
|
},
|
|
get playingAsset() {
|
|
return e.effectivePlayingAsset
|
|
},
|
|
get playingItem() {
|
|
return e.effectivePlayingItem
|
|
},
|
|
get playingIndex() {
|
|
var t = e.effectivePlayingItem;
|
|
return e.findItemIndex(t)
|
|
},
|
|
primary: {
|
|
get bufferedEnd() {
|
|
return n()
|
|
},
|
|
get currentTime() {
|
|
var t = e.timelinePos;
|
|
return t > 0 ? t : 0
|
|
},
|
|
set currentTime(e) {
|
|
s(e, "primary")
|
|
},
|
|
get duration() {
|
|
return a("primary")
|
|
},
|
|
get seekableStart() {
|
|
var t;
|
|
return (null == (t = e.primaryDetails) ? void 0 : t.fragmentStart) || 0
|
|
}
|
|
},
|
|
integrated: {
|
|
get bufferedEnd() {
|
|
return i(t(), "integrated", e.bufferingAsset, "bufferedPos", "bufferedEnd")
|
|
},
|
|
get currentTime() {
|
|
return i(e.effectivePlayingItem, "integrated", e.effectivePlayingAsset, "timelinePos", "currentTime")
|
|
},
|
|
set currentTime(e) {
|
|
s(e, "integrated")
|
|
},
|
|
get duration() {
|
|
return a("integrated")
|
|
},
|
|
get seekableStart() {
|
|
var t;
|
|
return function(t, r) {
|
|
var i;
|
|
if (0 !== t && "primary" !== r && null != (i = e.schedule) && i.length) {
|
|
var n, a = e.schedule.findItemIndexAtTime(t), s = null == (n = e.schedule.items) ? void 0 : n[a];
|
|
if (s)
|
|
return t + (s[r].start - s.start)
|
|
}
|
|
return t
|
|
}((null == (t = e.primaryDetails) ? void 0 : t.fragmentStart) || 0, "integrated")
|
|
}
|
|
},
|
|
skip: function() {
|
|
var t = e.effectivePlayingItem
|
|
, r = null == t ? void 0 : t.event;
|
|
if (r && !r.restrictions.skip) {
|
|
var i = e.findItemIndex(t);
|
|
if (r.appendInPlace) {
|
|
var n = t.playout.start + t.event.duration;
|
|
s(n + .001, "playout")
|
|
} else
|
|
e.advanceAfterAssetEnded(r, i, 1 / 0)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
key: "effectivePlayingItem",
|
|
get: function() {
|
|
return this.waitingItem || this.playingItem || this.endedItem
|
|
}
|
|
}, {
|
|
key: "effectivePlayingAsset",
|
|
get: function() {
|
|
return this.playingAsset || this.endedAsset
|
|
}
|
|
}, {
|
|
key: "playingLastItem",
|
|
get: function() {
|
|
var e, t = this.playingItem, r = null == (e = this.schedule) ? void 0 : e.items;
|
|
return !!(this.playbackStarted && t && r) && this.findItemIndex(t) === r.length - 1
|
|
}
|
|
}, {
|
|
key: "playbackStarted",
|
|
get: function() {
|
|
return null !== this.effectivePlayingItem
|
|
}
|
|
}, {
|
|
key: "currentTime",
|
|
get: function() {
|
|
var e, t;
|
|
if (null !== this.mediaSelection) {
|
|
var r = this.waitingItem || this.playingItem;
|
|
if (!this.isInterstitial(r) || r.event.appendInPlace) {
|
|
var i = this.media;
|
|
!i && null != (e = this.bufferingItem) && null != (e = e.event) && e.appendInPlace && (i = this.primaryMedia);
|
|
var n = null == (t = i) ? void 0 : t.currentTime;
|
|
if (void 0 !== n && A(n))
|
|
return n
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
key: "primaryMedia",
|
|
get: function() {
|
|
var e;
|
|
return this.media || (null == (e = this.detachedData) ? void 0 : e.media) || null
|
|
}
|
|
}, {
|
|
key: "playbackDisabled",
|
|
get: function() {
|
|
return !1 === this.hls.config.enableInterstitialPlayback
|
|
}
|
|
}, {
|
|
key: "primaryDetails",
|
|
get: function() {
|
|
var e;
|
|
return null == (e = this.mediaSelection) ? void 0 : e.main.details
|
|
}
|
|
}, {
|
|
key: "primaryLive",
|
|
get: function() {
|
|
var e;
|
|
return !(null == (e = this.primaryDetails) || !e.live)
|
|
}
|
|
}])
|
|
}(N)
|
|
, ro = function(e) {
|
|
function t(t, r, i) {
|
|
var n;
|
|
return (n = e.call(this, t, r, i, "subtitle-stream-controller", x) || this).currentTrackId = -1,
|
|
n.tracksBuffered = [],
|
|
n.mainDetails = null,
|
|
n.registerListeners(),
|
|
n
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.onHandlerDestroying = function() {
|
|
this.unregisterListeners(),
|
|
e.prototype.onHandlerDestroying.call(this),
|
|
this.mainDetails = null
|
|
}
|
|
,
|
|
r.registerListeners = function() {
|
|
e.prototype.registerListeners.call(this);
|
|
var t = this.hls;
|
|
t.on(b.LEVEL_LOADED, this.onLevelLoaded, this),
|
|
t.on(b.SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this),
|
|
t.on(b.SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this),
|
|
t.on(b.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this),
|
|
t.on(b.SUBTITLE_FRAG_PROCESSED, this.onSubtitleFragProcessed, this),
|
|
t.on(b.BUFFER_FLUSHING, this.onBufferFlushing, this)
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
e.prototype.unregisterListeners.call(this);
|
|
var t = this.hls;
|
|
t.off(b.LEVEL_LOADED, this.onLevelLoaded, this),
|
|
t.off(b.SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this),
|
|
t.off(b.SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this),
|
|
t.off(b.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this),
|
|
t.off(b.SUBTITLE_FRAG_PROCESSED, this.onSubtitleFragProcessed, this),
|
|
t.off(b.BUFFER_FLUSHING, this.onBufferFlushing, this)
|
|
}
|
|
,
|
|
r.startLoad = function(e, t) {
|
|
this.stopLoad(),
|
|
this.state = ki.IDLE,
|
|
this.setInterval(500),
|
|
this.nextLoadPosition = this.lastCurrentTime = e + this.timelineOffset,
|
|
this.startPosition = t ? -1 : e,
|
|
this.tick()
|
|
}
|
|
,
|
|
r.onManifestLoading = function() {
|
|
e.prototype.onManifestLoading.call(this),
|
|
this.mainDetails = null
|
|
}
|
|
,
|
|
r.onMediaDetaching = function(t, r) {
|
|
this.tracksBuffered = [],
|
|
e.prototype.onMediaDetaching.call(this, t, r)
|
|
}
|
|
,
|
|
r.onLevelLoaded = function(e, t) {
|
|
this.mainDetails = t.details
|
|
}
|
|
,
|
|
r.onSubtitleFragProcessed = function(e, t) {
|
|
var r = t.frag
|
|
, i = t.success;
|
|
if (this.fragContextChanged(r) || (te(r) && (this.fragPrevious = r),
|
|
this.state = ki.IDLE),
|
|
i) {
|
|
var n = this.tracksBuffered[this.currentTrackId];
|
|
if (n) {
|
|
for (var a, s = r.start, o = 0; o < n.length; o++)
|
|
if (s >= n[o].start && s <= n[o].end) {
|
|
a = n[o];
|
|
break
|
|
}
|
|
var l = r.start + r.duration;
|
|
a ? a.end = l : (a = {
|
|
start: s,
|
|
end: l
|
|
},
|
|
n.push(a)),
|
|
this.fragmentTracker.fragBuffered(r),
|
|
this.fragBufferedComplete(r, null),
|
|
this.media && this.tick()
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.onBufferFlushing = function(e, t) {
|
|
var r = t.startOffset
|
|
, i = t.endOffset;
|
|
if (0 === r && i !== Number.POSITIVE_INFINITY) {
|
|
var n = i - 1;
|
|
if (n <= 0)
|
|
return;
|
|
t.endOffsetSubtitles = Math.max(0, n),
|
|
this.tracksBuffered.forEach((function(e) {
|
|
for (var t = 0; t < e.length; )
|
|
if (e[t].end <= n)
|
|
e.shift();
|
|
else {
|
|
if (!(e[t].start < n))
|
|
break;
|
|
e[t].start = n,
|
|
t++
|
|
}
|
|
}
|
|
)),
|
|
this.fragmentTracker.removeFragmentsInRange(r, n, x)
|
|
}
|
|
}
|
|
,
|
|
r.onError = function(e, t) {
|
|
var r = t.frag;
|
|
(null == r ? void 0 : r.type) === x && (t.details === k.FRAG_GAP && this.fragmentTracker.fragBuffered(r, !0),
|
|
this.fragCurrent && this.fragCurrent.abortRequests(),
|
|
this.state !== ki.STOPPED && (this.state = ki.IDLE))
|
|
}
|
|
,
|
|
r.onSubtitleTracksUpdated = function(e, t) {
|
|
var r = this
|
|
, i = t.subtitleTracks;
|
|
this.levels && va(this.levels, i) ? this.levels = i.map((function(e) {
|
|
return new at(e)
|
|
}
|
|
)) : (this.tracksBuffered = [],
|
|
this.levels = i.map((function(e) {
|
|
var t = new at(e);
|
|
return r.tracksBuffered[t.id] = [],
|
|
t
|
|
}
|
|
)),
|
|
this.fragmentTracker.removeFragmentsInRange(0, Number.POSITIVE_INFINITY, x),
|
|
this.fragPrevious = null,
|
|
this.mediaBuffer = null)
|
|
}
|
|
,
|
|
r.onSubtitleTrackSwitch = function(e, t) {
|
|
var r;
|
|
if (this.currentTrackId = t.id,
|
|
null != (r = this.levels) && r.length && -1 !== this.currentTrackId) {
|
|
var i = this.levels[this.currentTrackId];
|
|
null != i && i.details ? this.mediaBuffer = this.mediaBufferTimeRanges : this.mediaBuffer = null,
|
|
i && this.state !== ki.STOPPED && this.setInterval(500)
|
|
} else
|
|
this.clearInterval()
|
|
}
|
|
,
|
|
r.onSubtitleTrackLoaded = function(e, t) {
|
|
var r, i = this.currentTrackId, n = this.levels, a = t.details, s = t.id;
|
|
if (n) {
|
|
var o = n[s];
|
|
if (!(s >= n.length) && o) {
|
|
this.log("Subtitle track " + s + " loaded [" + a.startSN + "," + a.endSN + "]" + (a.lastPartSn ? "[part-" + a.lastPartSn + "-" + a.lastPartIndex + "]" : "") + ",duration:" + a.totalduration),
|
|
this.mediaBuffer = this.mediaBufferTimeRanges;
|
|
var l = 0;
|
|
if (a.live || null != (r = o.details) && r.live) {
|
|
if (a.deltaUpdateFailed)
|
|
return;
|
|
var u = this.mainDetails;
|
|
if (!u)
|
|
return void (this.startFragRequested = !1);
|
|
var d, h = u.fragments[0];
|
|
o.details ? 0 === (l = this.alignPlaylists(a, o.details, null == (d = this.levelLastLoaded) ? void 0 : d.details)) && h && di(a, l = h.start) : a.hasProgramDateTime && u.hasProgramDateTime ? (Ai(a, u),
|
|
l = a.fragmentStart) : h && di(a, l = h.start),
|
|
u && !this.startFragRequested && this.setStartPosition(u, l)
|
|
}
|
|
o.details = a,
|
|
this.levelLastLoaded = o,
|
|
s === i && (this.hls.trigger(b.SUBTITLE_TRACK_UPDATED, {
|
|
details: a,
|
|
id: s,
|
|
groupId: t.groupId
|
|
}),
|
|
this.tick(),
|
|
a.live && !this.fragCurrent && this.media && this.state === ki.IDLE && (Et(null, a.fragments, this.media.currentTime, 0) || (this.warn("Subtitle playlist not aligned with playback"),
|
|
o.details = void 0)))
|
|
}
|
|
} else
|
|
this.warn("Subtitle tracks were reset while loading level " + s)
|
|
}
|
|
,
|
|
r._handleFragmentLoadComplete = function(e) {
|
|
var t = this
|
|
, r = e.frag
|
|
, i = e.payload
|
|
, n = r.decryptdata
|
|
, a = this.hls;
|
|
if (!this.fragContextChanged(r) && i && i.byteLength > 0 && null != n && n.key && n.iv && Lr(n.method)) {
|
|
var s = performance.now();
|
|
this.decrypter.decrypt(new Uint8Array(i), n.key.buffer, n.iv.buffer, Ir(n.method)).catch((function(e) {
|
|
throw a.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.FRAG_DECRYPT_ERROR,
|
|
fatal: !1,
|
|
error: e,
|
|
reason: e.message,
|
|
frag: r
|
|
}),
|
|
e
|
|
}
|
|
)).then((function(e) {
|
|
var t = performance.now();
|
|
a.trigger(b.FRAG_DECRYPTED, {
|
|
frag: r,
|
|
payload: e,
|
|
stats: {
|
|
tstart: s,
|
|
tdecrypt: t
|
|
}
|
|
})
|
|
}
|
|
)).catch((function(e) {
|
|
t.warn(e.name + ": " + e.message),
|
|
t.state = ki.IDLE
|
|
}
|
|
))
|
|
}
|
|
}
|
|
,
|
|
r.doTick = function() {
|
|
if (this.media) {
|
|
if (this.state === ki.IDLE) {
|
|
var e = this.currentTrackId
|
|
, t = this.levels
|
|
, r = null == t ? void 0 : t[e];
|
|
if (!r || !t.length || !r.details)
|
|
return;
|
|
if (this.waitForLive(r))
|
|
return;
|
|
var i = this.config
|
|
, n = this.getLoadPosition()
|
|
, a = ur.bufferedInfo(this.tracksBuffered[this.currentTrackId] || [], n, i.maxBufferHole)
|
|
, s = a.end
|
|
, o = a.len
|
|
, l = r.details;
|
|
if (o > this.hls.maxBufferLength + l.levelTargetDuration)
|
|
return;
|
|
var u = l.fragments
|
|
, d = u.length
|
|
, h = l.edge
|
|
, f = null
|
|
, c = this.fragPrevious;
|
|
if (s < h) {
|
|
var g = i.maxFragLookUpTolerance
|
|
, v = s > h - g ? 0 : g;
|
|
!(f = Et(c, u, Math.max(u[0].start, s), v)) && c && c.start < u[0].start && (f = u[0])
|
|
} else
|
|
f = u[d - 1];
|
|
if (!(f = this.filterReplacedPrimary(f, r.details)))
|
|
return;
|
|
var m = u[f.sn - l.startSN - 1];
|
|
if (m && m.cc === f.cc && this.fragmentTracker.getState(m) === Kt && (f = m),
|
|
this.fragmentTracker.getState(f) === Kt) {
|
|
var p = this.mapToInitFragWhenRequired(f);
|
|
p && this.loadFragment(p, r, s)
|
|
}
|
|
}
|
|
} else
|
|
this.state = ki.IDLE
|
|
}
|
|
,
|
|
r.loadFragment = function(t, r, i) {
|
|
te(t) ? e.prototype.loadFragment.call(this, t, r, i) : this._loadInitSegment(t, r)
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "mediaBufferTimeRanges",
|
|
get: function() {
|
|
return new io(this.tracksBuffered[this.currentTrackId] || [])
|
|
}
|
|
}])
|
|
}(bi)
|
|
, io = function(e) {
|
|
this.buffered = void 0;
|
|
var t = function(t, r, i) {
|
|
if ((r >>>= 0) > i - 1)
|
|
throw new DOMException("Failed to execute '" + t + "' on 'TimeRanges': The index provided (" + r + ") is greater than the maximum bound (" + i + ")");
|
|
return e[r][t]
|
|
};
|
|
this.buffered = {
|
|
get length() {
|
|
return e.length
|
|
},
|
|
end: function(r) {
|
|
return t("end", r, e.length)
|
|
},
|
|
start: function(r) {
|
|
return t("start", r, e.length)
|
|
}
|
|
}
|
|
};
|
|
function no(e, t) {
|
|
var r;
|
|
try {
|
|
r = new Event("addtrack")
|
|
} catch (e) {
|
|
(r = document.createEvent("Event")).initEvent("addtrack", !1, !1)
|
|
}
|
|
r.track = e,
|
|
t.dispatchEvent(r)
|
|
}
|
|
function ao(e, t) {
|
|
var r = e.mode;
|
|
if ("disabled" === r && (e.mode = "hidden"),
|
|
e.cues && !e.cues.getCueById(t.id))
|
|
try {
|
|
if (e.addCue(t),
|
|
!e.cues.getCueById(t.id))
|
|
throw new Error("addCue is failed for: " + t)
|
|
} catch (r) {
|
|
Y.debug("[texttrack-utils]: " + r);
|
|
try {
|
|
var i = new self.TextTrackCue(t.startTime,t.endTime,t.text);
|
|
i.id = t.id,
|
|
e.addCue(i)
|
|
} catch (e) {
|
|
Y.debug("[texttrack-utils]: Legacy TextTrackCue fallback failed: " + e)
|
|
}
|
|
}
|
|
"disabled" === r && (e.mode = r)
|
|
}
|
|
function so(e, t) {
|
|
var r = e.mode;
|
|
if ("disabled" === r && (e.mode = "hidden"),
|
|
e.cues)
|
|
for (var i = e.cues.length; i--; )
|
|
t && e.cues[i].removeEventListener("enter", t),
|
|
e.removeCue(e.cues[i]);
|
|
"disabled" === r && (e.mode = r)
|
|
}
|
|
function oo(e, t, r, i) {
|
|
var n = e.mode;
|
|
if ("disabled" === n && (e.mode = "hidden"),
|
|
e.cues && e.cues.length > 0)
|
|
for (var a = function(e, t, r) {
|
|
var i = []
|
|
, n = function(e, t) {
|
|
if (t <= e[0].startTime)
|
|
return 0;
|
|
var r = e.length - 1;
|
|
if (t > e[r].endTime)
|
|
return -1;
|
|
for (var i, n = 0, a = r; n <= a; )
|
|
if (t < e[i = Math.floor((a + n) / 2)].startTime)
|
|
a = i - 1;
|
|
else {
|
|
if (!(t > e[i].startTime && n < r))
|
|
return i;
|
|
n = i + 1
|
|
}
|
|
return e[n].startTime - t < t - e[a].startTime ? n : a
|
|
}(e, t);
|
|
if (n > -1)
|
|
for (var a = n, s = e.length; a < s; a++) {
|
|
var o = e[a];
|
|
if (o.startTime >= t && o.endTime <= r)
|
|
i.push(o);
|
|
else if (o.startTime > r)
|
|
return i
|
|
}
|
|
return i
|
|
}(e.cues, t, r), s = 0; s < a.length; s++)
|
|
i && !i(a[s]) || e.removeCue(a[s]);
|
|
"disabled" === n && (e.mode = n)
|
|
}
|
|
function lo(e) {
|
|
for (var t = [], r = 0; r < e.length; r++) {
|
|
var i = e[r];
|
|
"subtitles" !== i.kind && "captions" !== i.kind || !i.label || t.push(e[r])
|
|
}
|
|
return t
|
|
}
|
|
var uo = function(e) {
|
|
function t(t) {
|
|
var r;
|
|
return (r = e.call(this, t, "subtitle-track-controller") || this).media = null,
|
|
r.tracks = [],
|
|
r.groupIds = null,
|
|
r.tracksInGroup = [],
|
|
r.trackId = -1,
|
|
r.currentTrack = null,
|
|
r.selectDefaultTrack = !0,
|
|
r.queuedDefaultTrack = -1,
|
|
r.useTextTrackPolling = !1,
|
|
r.subtitlePollingInterval = -1,
|
|
r._subtitleDisplay = !0,
|
|
r.asyncPollTrackChange = function() {
|
|
return r.pollTrackChange(0)
|
|
}
|
|
,
|
|
r.onTextTracksChanged = function() {
|
|
if (r.useTextTrackPolling || self.clearInterval(r.subtitlePollingInterval),
|
|
r.media && r.hls.config.renderTextTracksNatively) {
|
|
for (var e = null, t = lo(r.media.textTracks), i = 0; i < t.length; i++)
|
|
if ("hidden" === t[i].mode)
|
|
e = t[i];
|
|
else if ("showing" === t[i].mode) {
|
|
e = t[i];
|
|
break
|
|
}
|
|
var n = r.findTrackForTextTrack(e);
|
|
r.subtitleTrack !== n && r.setSubtitleTrack(n)
|
|
}
|
|
}
|
|
,
|
|
r.registerListeners(),
|
|
r
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.destroy = function() {
|
|
this.unregisterListeners(),
|
|
this.tracks.length = 0,
|
|
this.tracksInGroup.length = 0,
|
|
this.currentTrack = null,
|
|
this.onTextTracksChanged = this.asyncPollTrackChange = null,
|
|
e.prototype.destroy.call(this)
|
|
}
|
|
,
|
|
r.registerListeners = function() {
|
|
var e = this.hls;
|
|
e.on(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.on(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.MANIFEST_PARSED, this.onManifestParsed, this),
|
|
e.on(b.LEVEL_LOADING, this.onLevelLoading, this),
|
|
e.on(b.LEVEL_SWITCHING, this.onLevelSwitching, this),
|
|
e.on(b.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this),
|
|
e.on(b.ERROR, this.onError, this)
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e.off(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.off(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.MANIFEST_PARSED, this.onManifestParsed, this),
|
|
e.off(b.LEVEL_LOADING, this.onLevelLoading, this),
|
|
e.off(b.LEVEL_SWITCHING, this.onLevelSwitching, this),
|
|
e.off(b.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this),
|
|
e.off(b.ERROR, this.onError, this)
|
|
}
|
|
,
|
|
r.onMediaAttached = function(e, t) {
|
|
this.media = t.media,
|
|
this.media && (this.queuedDefaultTrack > -1 && (this.subtitleTrack = this.queuedDefaultTrack,
|
|
this.queuedDefaultTrack = -1),
|
|
this.useTextTrackPolling = !(this.media.textTracks && "onchange"in this.media.textTracks),
|
|
this.useTextTrackPolling ? this.pollTrackChange(500) : this.media.textTracks.addEventListener("change", this.asyncPollTrackChange))
|
|
}
|
|
,
|
|
r.pollTrackChange = function(e) {
|
|
self.clearInterval(this.subtitlePollingInterval),
|
|
this.subtitlePollingInterval = self.setInterval(this.onTextTracksChanged, e)
|
|
}
|
|
,
|
|
r.onMediaDetaching = function(e, t) {
|
|
var r = this.media;
|
|
if (r) {
|
|
var i = !!t.transferMedia;
|
|
self.clearInterval(this.subtitlePollingInterval),
|
|
this.useTextTrackPolling || r.textTracks.removeEventListener("change", this.asyncPollTrackChange),
|
|
this.trackId > -1 && (this.queuedDefaultTrack = this.trackId),
|
|
this.subtitleTrack = -1,
|
|
this.media = null,
|
|
i || lo(r.textTracks).forEach((function(e) {
|
|
so(e)
|
|
}
|
|
))
|
|
}
|
|
}
|
|
,
|
|
r.onManifestLoading = function() {
|
|
this.tracks = [],
|
|
this.groupIds = null,
|
|
this.tracksInGroup = [],
|
|
this.trackId = -1,
|
|
this.currentTrack = null,
|
|
this.selectDefaultTrack = !0
|
|
}
|
|
,
|
|
r.onManifestParsed = function(e, t) {
|
|
this.tracks = t.subtitleTracks
|
|
}
|
|
,
|
|
r.onSubtitleTrackLoaded = function(e, t) {
|
|
var r = t.id
|
|
, i = t.groupId
|
|
, n = t.details
|
|
, a = this.tracksInGroup[r];
|
|
if (a && a.groupId === i) {
|
|
var s = a.details;
|
|
a.details = t.details,
|
|
this.log("Subtitle track " + r + ' "' + a.name + '" lang:' + a.lang + " group:" + i + " loaded [" + n.startSN + "-" + n.endSN + "]"),
|
|
r === this.trackId && this.playlistLoaded(r, t, s)
|
|
} else
|
|
this.warn("Subtitle track with id:" + r + " and group:" + i + " not found in active group " + (null == a ? void 0 : a.groupId))
|
|
}
|
|
,
|
|
r.onLevelLoading = function(e, t) {
|
|
this.switchLevel(t.level)
|
|
}
|
|
,
|
|
r.onLevelSwitching = function(e, t) {
|
|
this.switchLevel(t.level)
|
|
}
|
|
,
|
|
r.switchLevel = function(e) {
|
|
var t = this.hls.levels[e];
|
|
if (t) {
|
|
var r = t.subtitleGroups || null
|
|
, i = this.groupIds
|
|
, n = this.currentTrack;
|
|
if (!r || (null == i ? void 0 : i.length) !== (null == r ? void 0 : r.length) || null != r && r.some((function(e) {
|
|
return -1 === (null == i ? void 0 : i.indexOf(e))
|
|
}
|
|
))) {
|
|
this.groupIds = r,
|
|
this.trackId = -1,
|
|
this.currentTrack = null;
|
|
var a = this.tracks.filter((function(e) {
|
|
return !r || -1 !== r.indexOf(e.groupId)
|
|
}
|
|
));
|
|
if (a.length)
|
|
this.selectDefaultTrack && !a.some((function(e) {
|
|
return e.default
|
|
}
|
|
)) && (this.selectDefaultTrack = !1),
|
|
a.forEach((function(e, t) {
|
|
e.id = t
|
|
}
|
|
));
|
|
else if (!n && !this.tracksInGroup.length)
|
|
return;
|
|
this.tracksInGroup = a;
|
|
var s = this.hls.config.subtitlePreference;
|
|
if (!n && s) {
|
|
this.selectDefaultTrack = !1;
|
|
var o = ft(s, a);
|
|
if (o > -1)
|
|
n = a[o];
|
|
else {
|
|
var l = ft(s, this.tracks);
|
|
n = this.tracks[l]
|
|
}
|
|
}
|
|
var u = this.findTrackId(n);
|
|
-1 === u && n && (u = this.findTrackId(null));
|
|
var d = {
|
|
subtitleTracks: a
|
|
};
|
|
this.log("Updating subtitle tracks, " + a.length + ' track(s) found in "' + (null == r ? void 0 : r.join(",")) + '" group-id'),
|
|
this.hls.trigger(b.SUBTITLE_TRACKS_UPDATED, d),
|
|
-1 !== u && -1 === this.trackId && this.setSubtitleTrack(u)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.findTrackId = function(e) {
|
|
for (var t = this.tracksInGroup, r = this.selectDefaultTrack, i = 0; i < t.length; i++) {
|
|
var n = t[i];
|
|
if ((!r || n.default) && (r || e) && (!e || ct(n, e)))
|
|
return i
|
|
}
|
|
if (e) {
|
|
for (var a = 0; a < t.length; a++) {
|
|
var s = t[a];
|
|
if (ma(e.attrs, s.attrs, ["LANGUAGE", "ASSOC-LANGUAGE", "CHARACTERISTICS"]))
|
|
return a
|
|
}
|
|
for (var o = 0; o < t.length; o++) {
|
|
var l = t[o];
|
|
if (ma(e.attrs, l.attrs, ["LANGUAGE"]))
|
|
return o
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
,
|
|
r.findTrackForTextTrack = function(e) {
|
|
if (e)
|
|
for (var t = this.tracksInGroup, r = 0; r < t.length; r++)
|
|
if (pa(t[r], e))
|
|
return r;
|
|
return -1
|
|
}
|
|
,
|
|
r.onError = function(e, t) {
|
|
!t.fatal && t.context && (t.context.type !== C || t.context.id !== this.trackId || this.groupIds && -1 === this.groupIds.indexOf(t.context.groupId) || this.checkRetry(t))
|
|
}
|
|
,
|
|
r.setSubtitleOption = function(e) {
|
|
if (this.hls.config.subtitlePreference = e,
|
|
e) {
|
|
if (-1 === e.id)
|
|
return this.setSubtitleTrack(-1),
|
|
null;
|
|
var t = this.allSubtitleTracks;
|
|
if (this.selectDefaultTrack = !1,
|
|
t.length) {
|
|
var r = this.currentTrack;
|
|
if (r && ct(e, r))
|
|
return r;
|
|
var i = ft(e, this.tracksInGroup);
|
|
if (i > -1) {
|
|
var n = this.tracksInGroup[i];
|
|
return this.setSubtitleTrack(i),
|
|
n
|
|
}
|
|
if (r)
|
|
return null;
|
|
var a = ft(e, t);
|
|
if (a > -1)
|
|
return t[a]
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
,
|
|
r.loadPlaylist = function(t) {
|
|
e.prototype.loadPlaylist.call(this),
|
|
this.shouldLoadPlaylist(this.currentTrack) && this.scheduleLoading(this.currentTrack, t)
|
|
}
|
|
,
|
|
r.loadingPlaylist = function(t, r) {
|
|
e.prototype.loadingPlaylist.call(this, t, r);
|
|
var i = t.id
|
|
, n = t.groupId
|
|
, a = this.getUrlWithDirectives(t.url, r)
|
|
, s = t.details
|
|
, o = null == s ? void 0 : s.age;
|
|
this.log("Loading subtitle " + i + ' "' + t.name + '" lang:' + t.lang + " group:" + n + (void 0 !== (null == r ? void 0 : r.msn) ? " at sn " + r.msn + " part " + r.part : "") + (o && s.live ? " age " + o.toFixed(1) + (s.type && " " + s.type || "") : "") + " " + a),
|
|
this.hls.trigger(b.SUBTITLE_TRACK_LOADING, {
|
|
url: a,
|
|
id: i,
|
|
groupId: n,
|
|
deliveryDirectives: r || null,
|
|
track: t
|
|
})
|
|
}
|
|
,
|
|
r.toggleTrackModes = function() {
|
|
var e = this.media;
|
|
if (e) {
|
|
var t, r = lo(e.textTracks), i = this.currentTrack;
|
|
if (i && ((t = r.filter((function(e) {
|
|
return pa(i, e)
|
|
}
|
|
))[0]) || this.warn('Unable to find subtitle TextTrack with name "' + i.name + '" and language "' + i.lang + '"')),
|
|
[].slice.call(r).forEach((function(e) {
|
|
"disabled" !== e.mode && e !== t && (e.mode = "disabled")
|
|
}
|
|
)),
|
|
t) {
|
|
var n = this.subtitleDisplay ? "showing" : "hidden";
|
|
t.mode !== n && (t.mode = n)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.setSubtitleTrack = function(e) {
|
|
var t = this.tracksInGroup;
|
|
if (this.media)
|
|
if (e < -1 || e >= t.length || !A(e))
|
|
this.warn("Invalid subtitle track id: " + e);
|
|
else {
|
|
this.selectDefaultTrack = !1;
|
|
var r = this.currentTrack
|
|
, i = t[e] || null;
|
|
if (this.trackId = e,
|
|
this.currentTrack = i,
|
|
this.toggleTrackModes(),
|
|
i) {
|
|
var n = !!i.details && !i.details.live;
|
|
if (e !== this.trackId || i !== r || !n) {
|
|
this.log("Switching to subtitle-track " + e + (i ? ' "' + i.name + '" lang:' + i.lang + " group:" + i.groupId : ""));
|
|
var a = i.id
|
|
, s = i.groupId
|
|
, o = void 0 === s ? "" : s
|
|
, l = i.name
|
|
, u = i.type
|
|
, d = i.url;
|
|
this.hls.trigger(b.SUBTITLE_TRACK_SWITCH, {
|
|
id: a,
|
|
groupId: o,
|
|
name: l,
|
|
type: u,
|
|
url: d
|
|
});
|
|
var h = this.switchParams(i.url, null == r ? void 0 : r.details, i.details);
|
|
this.loadPlaylist(h)
|
|
}
|
|
} else
|
|
this.hls.trigger(b.SUBTITLE_TRACK_SWITCH, {
|
|
id: e
|
|
})
|
|
}
|
|
else
|
|
this.queuedDefaultTrack = e
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "subtitleDisplay",
|
|
get: function() {
|
|
return this._subtitleDisplay
|
|
},
|
|
set: function(e) {
|
|
this._subtitleDisplay = e,
|
|
this.trackId > -1 && this.toggleTrackModes()
|
|
}
|
|
}, {
|
|
key: "allSubtitleTracks",
|
|
get: function() {
|
|
return this.tracks
|
|
}
|
|
}, {
|
|
key: "subtitleTracks",
|
|
get: function() {
|
|
return this.tracksInGroup
|
|
}
|
|
}, {
|
|
key: "subtitleTrack",
|
|
get: function() {
|
|
return this.trackId
|
|
},
|
|
set: function(e) {
|
|
this.selectDefaultTrack = !1,
|
|
this.setSubtitleTrack(e)
|
|
}
|
|
}])
|
|
}(ga)
|
|
, ho = {
|
|
42: 225,
|
|
92: 233,
|
|
94: 237,
|
|
95: 243,
|
|
96: 250,
|
|
123: 231,
|
|
124: 247,
|
|
125: 209,
|
|
126: 241,
|
|
127: 9608,
|
|
128: 174,
|
|
129: 176,
|
|
130: 189,
|
|
131: 191,
|
|
132: 8482,
|
|
133: 162,
|
|
134: 163,
|
|
135: 9834,
|
|
136: 224,
|
|
137: 32,
|
|
138: 232,
|
|
139: 226,
|
|
140: 234,
|
|
141: 238,
|
|
142: 244,
|
|
143: 251,
|
|
144: 193,
|
|
145: 201,
|
|
146: 211,
|
|
147: 218,
|
|
148: 220,
|
|
149: 252,
|
|
150: 8216,
|
|
151: 161,
|
|
152: 42,
|
|
153: 8217,
|
|
154: 9473,
|
|
155: 169,
|
|
156: 8480,
|
|
157: 8226,
|
|
158: 8220,
|
|
159: 8221,
|
|
160: 192,
|
|
161: 194,
|
|
162: 199,
|
|
163: 200,
|
|
164: 202,
|
|
165: 203,
|
|
166: 235,
|
|
167: 206,
|
|
168: 207,
|
|
169: 239,
|
|
170: 212,
|
|
171: 217,
|
|
172: 249,
|
|
173: 219,
|
|
174: 171,
|
|
175: 187,
|
|
176: 195,
|
|
177: 227,
|
|
178: 205,
|
|
179: 204,
|
|
180: 236,
|
|
181: 210,
|
|
182: 242,
|
|
183: 213,
|
|
184: 245,
|
|
185: 123,
|
|
186: 125,
|
|
187: 92,
|
|
188: 94,
|
|
189: 95,
|
|
190: 124,
|
|
191: 8764,
|
|
192: 196,
|
|
193: 228,
|
|
194: 214,
|
|
195: 246,
|
|
196: 223,
|
|
197: 165,
|
|
198: 164,
|
|
199: 9475,
|
|
200: 197,
|
|
201: 229,
|
|
202: 216,
|
|
203: 248,
|
|
204: 9487,
|
|
205: 9491,
|
|
206: 9495,
|
|
207: 9499
|
|
}
|
|
, fo = function(e) {
|
|
return String.fromCharCode(ho[e] || e)
|
|
}
|
|
, co = 15
|
|
, go = 100
|
|
, vo = {
|
|
17: 1,
|
|
18: 3,
|
|
21: 5,
|
|
22: 7,
|
|
23: 9,
|
|
16: 11,
|
|
19: 12,
|
|
20: 14
|
|
}
|
|
, mo = {
|
|
17: 2,
|
|
18: 4,
|
|
21: 6,
|
|
22: 8,
|
|
23: 10,
|
|
19: 13,
|
|
20: 15
|
|
}
|
|
, po = {
|
|
25: 1,
|
|
26: 3,
|
|
29: 5,
|
|
30: 7,
|
|
31: 9,
|
|
24: 11,
|
|
27: 12,
|
|
28: 14
|
|
}
|
|
, yo = {
|
|
25: 2,
|
|
26: 4,
|
|
29: 6,
|
|
30: 8,
|
|
31: 10,
|
|
27: 13,
|
|
28: 15
|
|
}
|
|
, Eo = ["white", "green", "blue", "cyan", "red", "yellow", "magenta", "black", "transparent"]
|
|
, To = function() {
|
|
function e() {
|
|
this.time = null,
|
|
this.verboseLevel = 0
|
|
}
|
|
return e.prototype.log = function(e, t) {
|
|
if (this.verboseLevel >= e) {
|
|
var r = "function" == typeof t ? t() : t;
|
|
Y.log(this.time + " [" + e + "] " + r)
|
|
}
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, So = function(e) {
|
|
for (var t = [], r = 0; r < e.length; r++)
|
|
t.push(e[r].toString(16));
|
|
return t
|
|
}
|
|
, Ao = function() {
|
|
function e() {
|
|
this.foreground = "white",
|
|
this.underline = !1,
|
|
this.italics = !1,
|
|
this.background = "black",
|
|
this.flash = !1
|
|
}
|
|
var t = e.prototype;
|
|
return t.reset = function() {
|
|
this.foreground = "white",
|
|
this.underline = !1,
|
|
this.italics = !1,
|
|
this.background = "black",
|
|
this.flash = !1
|
|
}
|
|
,
|
|
t.setStyles = function(e) {
|
|
for (var t = ["foreground", "underline", "italics", "background", "flash"], r = 0; r < t.length; r++) {
|
|
var i = t[r];
|
|
e.hasOwnProperty(i) && (this[i] = e[i])
|
|
}
|
|
}
|
|
,
|
|
t.isDefault = function() {
|
|
return "white" === this.foreground && !this.underline && !this.italics && "black" === this.background && !this.flash
|
|
}
|
|
,
|
|
t.equals = function(e) {
|
|
return this.foreground === e.foreground && this.underline === e.underline && this.italics === e.italics && this.background === e.background && this.flash === e.flash
|
|
}
|
|
,
|
|
t.copy = function(e) {
|
|
this.foreground = e.foreground,
|
|
this.underline = e.underline,
|
|
this.italics = e.italics,
|
|
this.background = e.background,
|
|
this.flash = e.flash
|
|
}
|
|
,
|
|
t.toString = function() {
|
|
return "color=" + this.foreground + ", underline=" + this.underline + ", italics=" + this.italics + ", background=" + this.background + ", flash=" + this.flash
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, Lo = function() {
|
|
function e() {
|
|
this.uchar = " ",
|
|
this.penState = new Ao
|
|
}
|
|
var t = e.prototype;
|
|
return t.reset = function() {
|
|
this.uchar = " ",
|
|
this.penState.reset()
|
|
}
|
|
,
|
|
t.setChar = function(e, t) {
|
|
this.uchar = e,
|
|
this.penState.copy(t)
|
|
}
|
|
,
|
|
t.setPenState = function(e) {
|
|
this.penState.copy(e)
|
|
}
|
|
,
|
|
t.equals = function(e) {
|
|
return this.uchar === e.uchar && this.penState.equals(e.penState)
|
|
}
|
|
,
|
|
t.copy = function(e) {
|
|
this.uchar = e.uchar,
|
|
this.penState.copy(e.penState)
|
|
}
|
|
,
|
|
t.isEmpty = function() {
|
|
return " " === this.uchar && this.penState.isDefault()
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, Io = function() {
|
|
function e(e) {
|
|
this.chars = [],
|
|
this.pos = 0,
|
|
this.currPenState = new Ao,
|
|
this.cueStartTime = null,
|
|
this.logger = void 0;
|
|
for (var t = 0; t < go; t++)
|
|
this.chars.push(new Lo);
|
|
this.logger = e
|
|
}
|
|
var t = e.prototype;
|
|
return t.equals = function(e) {
|
|
for (var t = 0; t < go; t++)
|
|
if (!this.chars[t].equals(e.chars[t]))
|
|
return !1;
|
|
return !0
|
|
}
|
|
,
|
|
t.copy = function(e) {
|
|
for (var t = 0; t < go; t++)
|
|
this.chars[t].copy(e.chars[t])
|
|
}
|
|
,
|
|
t.isEmpty = function() {
|
|
for (var e = !0, t = 0; t < go; t++)
|
|
if (!this.chars[t].isEmpty()) {
|
|
e = !1;
|
|
break
|
|
}
|
|
return e
|
|
}
|
|
,
|
|
t.setCursor = function(e) {
|
|
this.pos !== e && (this.pos = e),
|
|
this.pos < 0 ? (this.logger.log(3, "Negative cursor position " + this.pos),
|
|
this.pos = 0) : this.pos > go && (this.logger.log(3, "Too large cursor position " + this.pos),
|
|
this.pos = go)
|
|
}
|
|
,
|
|
t.moveCursor = function(e) {
|
|
var t = this.pos + e;
|
|
if (e > 1)
|
|
for (var r = this.pos + 1; r < t + 1; r++)
|
|
this.chars[r].setPenState(this.currPenState);
|
|
this.setCursor(t)
|
|
}
|
|
,
|
|
t.backSpace = function() {
|
|
this.moveCursor(-1),
|
|
this.chars[this.pos].setChar(" ", this.currPenState)
|
|
}
|
|
,
|
|
t.insertChar = function(e) {
|
|
var t = this;
|
|
e >= 144 && this.backSpace();
|
|
var r = fo(e);
|
|
this.pos >= go ? this.logger.log(0, (function() {
|
|
return "Cannot insert " + e.toString(16) + " (" + r + ") at position " + t.pos + ". Skipping it!"
|
|
}
|
|
)) : (this.chars[this.pos].setChar(r, this.currPenState),
|
|
this.moveCursor(1))
|
|
}
|
|
,
|
|
t.clearFromPos = function(e) {
|
|
var t;
|
|
for (t = e; t < go; t++)
|
|
this.chars[t].reset()
|
|
}
|
|
,
|
|
t.clear = function() {
|
|
this.clearFromPos(0),
|
|
this.pos = 0,
|
|
this.currPenState.reset()
|
|
}
|
|
,
|
|
t.clearToEndOfRow = function() {
|
|
this.clearFromPos(this.pos)
|
|
}
|
|
,
|
|
t.getTextString = function() {
|
|
for (var e = [], t = !0, r = 0; r < go; r++) {
|
|
var i = this.chars[r].uchar;
|
|
" " !== i && (t = !1),
|
|
e.push(i)
|
|
}
|
|
return t ? "" : e.join("")
|
|
}
|
|
,
|
|
t.setPenStyles = function(e) {
|
|
this.currPenState.setStyles(e),
|
|
this.chars[this.pos].setPenState(this.currPenState)
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, Ro = function() {
|
|
function e(e) {
|
|
this.rows = [],
|
|
this.currRow = 14,
|
|
this.nrRollUpRows = null,
|
|
this.lastOutputScreen = null,
|
|
this.logger = void 0;
|
|
for (var t = 0; t < co; t++)
|
|
this.rows.push(new Io(e));
|
|
this.logger = e
|
|
}
|
|
var t = e.prototype;
|
|
return t.reset = function() {
|
|
for (var e = 0; e < co; e++)
|
|
this.rows[e].clear();
|
|
this.currRow = 14
|
|
}
|
|
,
|
|
t.equals = function(e) {
|
|
for (var t = !0, r = 0; r < co; r++)
|
|
if (!this.rows[r].equals(e.rows[r])) {
|
|
t = !1;
|
|
break
|
|
}
|
|
return t
|
|
}
|
|
,
|
|
t.copy = function(e) {
|
|
for (var t = 0; t < co; t++)
|
|
this.rows[t].copy(e.rows[t])
|
|
}
|
|
,
|
|
t.isEmpty = function() {
|
|
for (var e = !0, t = 0; t < co; t++)
|
|
if (!this.rows[t].isEmpty()) {
|
|
e = !1;
|
|
break
|
|
}
|
|
return e
|
|
}
|
|
,
|
|
t.backSpace = function() {
|
|
this.rows[this.currRow].backSpace()
|
|
}
|
|
,
|
|
t.clearToEndOfRow = function() {
|
|
this.rows[this.currRow].clearToEndOfRow()
|
|
}
|
|
,
|
|
t.insertChar = function(e) {
|
|
this.rows[this.currRow].insertChar(e)
|
|
}
|
|
,
|
|
t.setPen = function(e) {
|
|
this.rows[this.currRow].setPenStyles(e)
|
|
}
|
|
,
|
|
t.moveCursor = function(e) {
|
|
this.rows[this.currRow].moveCursor(e)
|
|
}
|
|
,
|
|
t.setCursor = function(e) {
|
|
this.logger.log(2, "setCursor: " + e),
|
|
this.rows[this.currRow].setCursor(e)
|
|
}
|
|
,
|
|
t.setPAC = function(e) {
|
|
this.logger.log(2, (function() {
|
|
return "pacData = " + lt(e)
|
|
}
|
|
));
|
|
var t = e.row - 1;
|
|
if (this.nrRollUpRows && t < this.nrRollUpRows - 1 && (t = this.nrRollUpRows - 1),
|
|
this.nrRollUpRows && this.currRow !== t) {
|
|
for (var r = 0; r < co; r++)
|
|
this.rows[r].clear();
|
|
var i = this.currRow + 1 - this.nrRollUpRows
|
|
, n = this.lastOutputScreen;
|
|
if (n) {
|
|
var a = n.rows[i].cueStartTime
|
|
, s = this.logger.time;
|
|
if (null !== a && null !== s && a < s)
|
|
for (var o = 0; o < this.nrRollUpRows; o++)
|
|
this.rows[t - this.nrRollUpRows + o + 1].copy(n.rows[i + o])
|
|
}
|
|
}
|
|
this.currRow = t;
|
|
var l = this.rows[this.currRow];
|
|
if (null !== e.indent) {
|
|
var u = e.indent
|
|
, d = Math.max(u - 1, 0);
|
|
l.setCursor(e.indent),
|
|
e.color = l.chars[d].penState.foreground
|
|
}
|
|
var h = {
|
|
foreground: e.color,
|
|
underline: e.underline,
|
|
italics: e.italics,
|
|
background: "black",
|
|
flash: !1
|
|
};
|
|
this.setPen(h)
|
|
}
|
|
,
|
|
t.setBkgData = function(e) {
|
|
this.logger.log(2, (function() {
|
|
return "bkgData = " + lt(e)
|
|
}
|
|
)),
|
|
this.backSpace(),
|
|
this.setPen(e),
|
|
this.insertChar(32)
|
|
}
|
|
,
|
|
t.setRollUpRows = function(e) {
|
|
this.nrRollUpRows = e
|
|
}
|
|
,
|
|
t.rollUp = function() {
|
|
var e = this;
|
|
if (null !== this.nrRollUpRows) {
|
|
this.logger.log(1, (function() {
|
|
return e.getDisplayText()
|
|
}
|
|
));
|
|
var t = this.currRow + 1 - this.nrRollUpRows
|
|
, r = this.rows.splice(t, 1)[0];
|
|
r.clear(),
|
|
this.rows.splice(this.currRow, 0, r),
|
|
this.logger.log(2, "Rolling up")
|
|
} else
|
|
this.logger.log(3, "roll_up but nrRollUpRows not set yet")
|
|
}
|
|
,
|
|
t.getDisplayText = function(e) {
|
|
e = e || !1;
|
|
for (var t = [], r = "", i = -1, n = 0; n < co; n++) {
|
|
var a = this.rows[n].getTextString();
|
|
a && (i = n + 1,
|
|
e ? t.push("Row " + i + ": '" + a + "'") : t.push(a.trim()))
|
|
}
|
|
return t.length > 0 && (r = e ? "[" + t.join(" | ") + "]" : t.join("\n")),
|
|
r
|
|
}
|
|
,
|
|
t.getTextAndFormat = function() {
|
|
return this.rows
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, ko = function() {
|
|
function e(e, t, r) {
|
|
this.chNr = void 0,
|
|
this.outputFilter = void 0,
|
|
this.mode = void 0,
|
|
this.verbose = void 0,
|
|
this.displayedMemory = void 0,
|
|
this.nonDisplayedMemory = void 0,
|
|
this.lastOutputScreen = void 0,
|
|
this.currRollUpRow = void 0,
|
|
this.writeScreen = void 0,
|
|
this.cueStartTime = void 0,
|
|
this.logger = void 0,
|
|
this.chNr = e,
|
|
this.outputFilter = t,
|
|
this.mode = null,
|
|
this.verbose = 0,
|
|
this.displayedMemory = new Ro(r),
|
|
this.nonDisplayedMemory = new Ro(r),
|
|
this.lastOutputScreen = new Ro(r),
|
|
this.currRollUpRow = this.displayedMemory.rows[14],
|
|
this.writeScreen = this.displayedMemory,
|
|
this.mode = null,
|
|
this.cueStartTime = null,
|
|
this.logger = r
|
|
}
|
|
var t = e.prototype;
|
|
return t.reset = function() {
|
|
this.mode = null,
|
|
this.displayedMemory.reset(),
|
|
this.nonDisplayedMemory.reset(),
|
|
this.lastOutputScreen.reset(),
|
|
this.outputFilter.reset(),
|
|
this.currRollUpRow = this.displayedMemory.rows[14],
|
|
this.writeScreen = this.displayedMemory,
|
|
this.mode = null,
|
|
this.cueStartTime = null
|
|
}
|
|
,
|
|
t.getHandler = function() {
|
|
return this.outputFilter
|
|
}
|
|
,
|
|
t.setHandler = function(e) {
|
|
this.outputFilter = e
|
|
}
|
|
,
|
|
t.setPAC = function(e) {
|
|
this.writeScreen.setPAC(e)
|
|
}
|
|
,
|
|
t.setBkgData = function(e) {
|
|
this.writeScreen.setBkgData(e)
|
|
}
|
|
,
|
|
t.setMode = function(e) {
|
|
e !== this.mode && (this.mode = e,
|
|
this.logger.log(2, (function() {
|
|
return "MODE=" + e
|
|
}
|
|
)),
|
|
"MODE_POP-ON" === this.mode ? this.writeScreen = this.nonDisplayedMemory : (this.writeScreen = this.displayedMemory,
|
|
this.writeScreen.reset()),
|
|
"MODE_ROLL-UP" !== this.mode && (this.displayedMemory.nrRollUpRows = null,
|
|
this.nonDisplayedMemory.nrRollUpRows = null),
|
|
this.mode = e)
|
|
}
|
|
,
|
|
t.insertChars = function(e) {
|
|
for (var t = this, r = 0; r < e.length; r++)
|
|
this.writeScreen.insertChar(e[r]);
|
|
var i = this.writeScreen === this.displayedMemory ? "DISP" : "NON_DISP";
|
|
this.logger.log(2, (function() {
|
|
return i + ": " + t.writeScreen.getDisplayText(!0)
|
|
}
|
|
)),
|
|
"MODE_PAINT-ON" !== this.mode && "MODE_ROLL-UP" !== this.mode || (this.logger.log(1, (function() {
|
|
return "DISPLAYED: " + t.displayedMemory.getDisplayText(!0)
|
|
}
|
|
)),
|
|
this.outputDataUpdate())
|
|
}
|
|
,
|
|
t.ccRCL = function() {
|
|
this.logger.log(2, "RCL - Resume Caption Loading"),
|
|
this.setMode("MODE_POP-ON")
|
|
}
|
|
,
|
|
t.ccBS = function() {
|
|
this.logger.log(2, "BS - BackSpace"),
|
|
"MODE_TEXT" !== this.mode && (this.writeScreen.backSpace(),
|
|
this.writeScreen === this.displayedMemory && this.outputDataUpdate())
|
|
}
|
|
,
|
|
t.ccAOF = function() {}
|
|
,
|
|
t.ccAON = function() {}
|
|
,
|
|
t.ccDER = function() {
|
|
this.logger.log(2, "DER- Delete to End of Row"),
|
|
this.writeScreen.clearToEndOfRow(),
|
|
this.outputDataUpdate()
|
|
}
|
|
,
|
|
t.ccRU = function(e) {
|
|
this.logger.log(2, "RU(" + e + ") - Roll Up"),
|
|
this.writeScreen = this.displayedMemory,
|
|
this.setMode("MODE_ROLL-UP"),
|
|
this.writeScreen.setRollUpRows(e)
|
|
}
|
|
,
|
|
t.ccFON = function() {
|
|
this.logger.log(2, "FON - Flash On"),
|
|
this.writeScreen.setPen({
|
|
flash: !0
|
|
})
|
|
}
|
|
,
|
|
t.ccRDC = function() {
|
|
this.logger.log(2, "RDC - Resume Direct Captioning"),
|
|
this.setMode("MODE_PAINT-ON")
|
|
}
|
|
,
|
|
t.ccTR = function() {
|
|
this.logger.log(2, "TR"),
|
|
this.setMode("MODE_TEXT")
|
|
}
|
|
,
|
|
t.ccRTD = function() {
|
|
this.logger.log(2, "RTD"),
|
|
this.setMode("MODE_TEXT")
|
|
}
|
|
,
|
|
t.ccEDM = function() {
|
|
this.logger.log(2, "EDM - Erase Displayed Memory"),
|
|
this.displayedMemory.reset(),
|
|
this.outputDataUpdate(!0)
|
|
}
|
|
,
|
|
t.ccCR = function() {
|
|
this.logger.log(2, "CR - Carriage Return"),
|
|
this.writeScreen.rollUp(),
|
|
this.outputDataUpdate(!0)
|
|
}
|
|
,
|
|
t.ccENM = function() {
|
|
this.logger.log(2, "ENM - Erase Non-displayed Memory"),
|
|
this.nonDisplayedMemory.reset()
|
|
}
|
|
,
|
|
t.ccEOC = function() {
|
|
var e = this;
|
|
if (this.logger.log(2, "EOC - End Of Caption"),
|
|
"MODE_POP-ON" === this.mode) {
|
|
var t = this.displayedMemory;
|
|
this.displayedMemory = this.nonDisplayedMemory,
|
|
this.nonDisplayedMemory = t,
|
|
this.writeScreen = this.nonDisplayedMemory,
|
|
this.logger.log(1, (function() {
|
|
return "DISP: " + e.displayedMemory.getDisplayText()
|
|
}
|
|
))
|
|
}
|
|
this.outputDataUpdate(!0)
|
|
}
|
|
,
|
|
t.ccTO = function(e) {
|
|
this.logger.log(2, "TO(" + e + ") - Tab Offset"),
|
|
this.writeScreen.moveCursor(e)
|
|
}
|
|
,
|
|
t.ccMIDROW = function(e) {
|
|
var t = {
|
|
flash: !1
|
|
};
|
|
if (t.underline = e % 2 == 1,
|
|
t.italics = e >= 46,
|
|
t.italics)
|
|
t.foreground = "white";
|
|
else {
|
|
var r = Math.floor(e / 2) - 16;
|
|
t.foreground = ["white", "green", "blue", "cyan", "red", "yellow", "magenta"][r]
|
|
}
|
|
this.logger.log(2, "MIDROW: " + lt(t)),
|
|
this.writeScreen.setPen(t)
|
|
}
|
|
,
|
|
t.outputDataUpdate = function(e) {
|
|
void 0 === e && (e = !1);
|
|
var t = this.logger.time;
|
|
null !== t && this.outputFilter && (null !== this.cueStartTime || this.displayedMemory.isEmpty() ? this.displayedMemory.equals(this.lastOutputScreen) || (this.outputFilter.newCue(this.cueStartTime, t, this.lastOutputScreen),
|
|
e && this.outputFilter.dispatchCue && this.outputFilter.dispatchCue(),
|
|
this.cueStartTime = this.displayedMemory.isEmpty() ? null : t) : this.cueStartTime = t,
|
|
this.lastOutputScreen.copy(this.displayedMemory))
|
|
}
|
|
,
|
|
t.cueSplitAtTime = function(e) {
|
|
this.outputFilter && (this.displayedMemory.isEmpty() || (this.outputFilter.newCue && this.outputFilter.newCue(this.cueStartTime, e, this.displayedMemory),
|
|
this.cueStartTime = e))
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, bo = function() {
|
|
function e(e, t, r) {
|
|
this.channels = void 0,
|
|
this.currentChannel = 0,
|
|
this.cmdHistory = {
|
|
a: null,
|
|
b: null
|
|
},
|
|
this.logger = void 0;
|
|
var i = this.logger = new To;
|
|
this.channels = [null, new ko(e,t,i), new ko(e + 1,r,i)]
|
|
}
|
|
var t = e.prototype;
|
|
return t.getHandler = function(e) {
|
|
return this.channels[e].getHandler()
|
|
}
|
|
,
|
|
t.setHandler = function(e, t) {
|
|
this.channels[e].setHandler(t)
|
|
}
|
|
,
|
|
t.addData = function(e, t) {
|
|
var r = this;
|
|
this.logger.time = e;
|
|
for (var i = function(e) {
|
|
var i = 127 & t[e]
|
|
, n = 127 & t[e + 1]
|
|
, a = !1
|
|
, s = null;
|
|
if (0 === i && 0 === n)
|
|
return 0;
|
|
r.logger.log(3, (function() {
|
|
return "[" + So([t[e], t[e + 1]]) + "] -> (" + So([i, n]) + ")"
|
|
}
|
|
));
|
|
var o = r.cmdHistory;
|
|
if (i >= 16 && i <= 31) {
|
|
if (function(e, t, r) {
|
|
return r.a === e && r.b === t
|
|
}(i, n, o))
|
|
return Do(null, null, o),
|
|
r.logger.log(3, (function() {
|
|
return "Repeated command (" + So([i, n]) + ") is dropped"
|
|
}
|
|
)),
|
|
0;
|
|
Do(i, n, r.cmdHistory),
|
|
(a = r.parseCmd(i, n)) || (a = r.parseMidrow(i, n)),
|
|
a || (a = r.parsePAC(i, n)),
|
|
a || (a = r.parseBackgroundAttributes(i, n))
|
|
} else
|
|
Do(null, null, o);
|
|
if (!a && (s = r.parseChars(i, n))) {
|
|
var l = r.currentChannel;
|
|
l && l > 0 ? r.channels[l].insertChars(s) : r.logger.log(2, "No channel found yet. TEXT-MODE?")
|
|
}
|
|
a || s || r.logger.log(2, (function() {
|
|
return "Couldn't parse cleaned data " + So([i, n]) + " orig: " + So([t[e], t[e + 1]])
|
|
}
|
|
))
|
|
}, n = 0; n < t.length; n += 2)
|
|
i(n)
|
|
}
|
|
,
|
|
t.parseCmd = function(e, t) {
|
|
if (!((20 === e || 28 === e || 21 === e || 29 === e) && t >= 32 && t <= 47 || (23 === e || 31 === e) && t >= 33 && t <= 35))
|
|
return !1;
|
|
var r = 20 === e || 21 === e || 23 === e ? 1 : 2
|
|
, i = this.channels[r];
|
|
return 20 === e || 21 === e || 28 === e || 29 === e ? 32 === t ? i.ccRCL() : 33 === t ? i.ccBS() : 34 === t ? i.ccAOF() : 35 === t ? i.ccAON() : 36 === t ? i.ccDER() : 37 === t ? i.ccRU(2) : 38 === t ? i.ccRU(3) : 39 === t ? i.ccRU(4) : 40 === t ? i.ccFON() : 41 === t ? i.ccRDC() : 42 === t ? i.ccTR() : 43 === t ? i.ccRTD() : 44 === t ? i.ccEDM() : 45 === t ? i.ccCR() : 46 === t ? i.ccENM() : 47 === t && i.ccEOC() : i.ccTO(t - 32),
|
|
this.currentChannel = r,
|
|
!0
|
|
}
|
|
,
|
|
t.parseMidrow = function(e, t) {
|
|
var r = 0;
|
|
if ((17 === e || 25 === e) && t >= 32 && t <= 47) {
|
|
if ((r = 17 === e ? 1 : 2) !== this.currentChannel)
|
|
return this.logger.log(0, "Mismatch channel in midrow parsing"),
|
|
!1;
|
|
var i = this.channels[r];
|
|
return !!i && (i.ccMIDROW(t),
|
|
this.logger.log(3, (function() {
|
|
return "MIDROW (" + So([e, t]) + ")"
|
|
}
|
|
)),
|
|
!0)
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
t.parsePAC = function(e, t) {
|
|
var r;
|
|
if (!((e >= 17 && e <= 23 || e >= 25 && e <= 31) && t >= 64 && t <= 127 || (16 === e || 24 === e) && t >= 64 && t <= 95))
|
|
return !1;
|
|
var i = e <= 23 ? 1 : 2;
|
|
r = t >= 64 && t <= 95 ? 1 === i ? vo[e] : po[e] : 1 === i ? mo[e] : yo[e];
|
|
var n = this.channels[i];
|
|
return !!n && (n.setPAC(this.interpretPAC(r, t)),
|
|
this.currentChannel = i,
|
|
!0)
|
|
}
|
|
,
|
|
t.interpretPAC = function(e, t) {
|
|
var r, i = {
|
|
color: null,
|
|
italics: !1,
|
|
indent: null,
|
|
underline: !1,
|
|
row: e
|
|
};
|
|
return r = t > 95 ? t - 96 : t - 64,
|
|
i.underline = 1 == (1 & r),
|
|
r <= 13 ? i.color = ["white", "green", "blue", "cyan", "red", "yellow", "magenta", "white"][Math.floor(r / 2)] : r <= 15 ? (i.italics = !0,
|
|
i.color = "white") : i.indent = 4 * Math.floor((r - 16) / 2),
|
|
i
|
|
}
|
|
,
|
|
t.parseChars = function(e, t) {
|
|
var r, i, n = null, a = null;
|
|
return e >= 25 ? (r = 2,
|
|
a = e - 8) : (r = 1,
|
|
a = e),
|
|
a >= 17 && a <= 19 ? (i = 17 === a ? t + 80 : 18 === a ? t + 112 : t + 144,
|
|
this.logger.log(2, (function() {
|
|
return "Special char '" + fo(i) + "' in channel " + r
|
|
}
|
|
)),
|
|
n = [i]) : e >= 32 && e <= 127 && (n = 0 === t ? [e] : [e, t]),
|
|
n && this.logger.log(3, (function() {
|
|
return "Char codes = " + So(n).join(",")
|
|
}
|
|
)),
|
|
n
|
|
}
|
|
,
|
|
t.parseBackgroundAttributes = function(e, t) {
|
|
var r;
|
|
if (!((16 === e || 24 === e) && t >= 32 && t <= 47 || (23 === e || 31 === e) && t >= 45 && t <= 47))
|
|
return !1;
|
|
var i = {};
|
|
16 === e || 24 === e ? (r = Math.floor((t - 32) / 2),
|
|
i.background = Eo[r],
|
|
t % 2 == 1 && (i.background = i.background + "_semi")) : 45 === t ? i.background = "transparent" : (i.foreground = "black",
|
|
47 === t && (i.underline = !0));
|
|
var n = e <= 23 ? 1 : 2;
|
|
return this.channels[n].setBkgData(i),
|
|
!0
|
|
}
|
|
,
|
|
t.reset = function() {
|
|
for (var e = 0; e < Object.keys(this.channels).length; e++) {
|
|
var t = this.channels[e];
|
|
t && t.reset()
|
|
}
|
|
Do(null, null, this.cmdHistory)
|
|
}
|
|
,
|
|
t.cueSplitAtTime = function(e) {
|
|
for (var t = 0; t < this.channels.length; t++) {
|
|
var r = this.channels[t];
|
|
r && r.cueSplitAtTime(e)
|
|
}
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function Do(e, t, r) {
|
|
r.a = e,
|
|
r.b = t
|
|
}
|
|
var _o = function() {
|
|
if (null != _r && _r.VTTCue)
|
|
return self.VTTCue;
|
|
var e = ["", "lr", "rl"]
|
|
, t = ["start", "middle", "end", "left", "right"];
|
|
function r(e, t) {
|
|
if ("string" != typeof t)
|
|
return !1;
|
|
if (!Array.isArray(e))
|
|
return !1;
|
|
var r = t.toLowerCase();
|
|
return !!~e.indexOf(r) && r
|
|
}
|
|
function i(e) {
|
|
return r(t, e)
|
|
}
|
|
function n(e) {
|
|
for (var t = arguments.length, r = new Array(t > 1 ? t - 1 : 0), i = 1; i < t; i++)
|
|
r[i - 1] = arguments[i];
|
|
for (var n = 1; n < arguments.length; n++) {
|
|
var a = arguments[n];
|
|
for (var s in a)
|
|
e[s] = a[s]
|
|
}
|
|
return e
|
|
}
|
|
function a(t, a, s) {
|
|
var o = this
|
|
, l = {
|
|
enumerable: !0
|
|
};
|
|
o.hasBeenReset = !1;
|
|
var u = ""
|
|
, d = !1
|
|
, h = t
|
|
, f = a
|
|
, c = s
|
|
, g = null
|
|
, v = ""
|
|
, m = !0
|
|
, p = "auto"
|
|
, y = "start"
|
|
, E = 50
|
|
, T = "middle"
|
|
, S = 50
|
|
, A = "middle";
|
|
Object.defineProperty(o, "id", n({}, l, {
|
|
get: function() {
|
|
return u
|
|
},
|
|
set: function(e) {
|
|
u = "" + e
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "pauseOnExit", n({}, l, {
|
|
get: function() {
|
|
return d
|
|
},
|
|
set: function(e) {
|
|
d = !!e
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "startTime", n({}, l, {
|
|
get: function() {
|
|
return h
|
|
},
|
|
set: function(e) {
|
|
if ("number" != typeof e)
|
|
throw new TypeError("Start time must be set to a number.");
|
|
h = e,
|
|
this.hasBeenReset = !0
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "endTime", n({}, l, {
|
|
get: function() {
|
|
return f
|
|
},
|
|
set: function(e) {
|
|
if ("number" != typeof e)
|
|
throw new TypeError("End time must be set to a number.");
|
|
f = e,
|
|
this.hasBeenReset = !0
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "text", n({}, l, {
|
|
get: function() {
|
|
return c
|
|
},
|
|
set: function(e) {
|
|
c = "" + e,
|
|
this.hasBeenReset = !0
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "region", n({}, l, {
|
|
get: function() {
|
|
return g
|
|
},
|
|
set: function(e) {
|
|
g = e,
|
|
this.hasBeenReset = !0
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "vertical", n({}, l, {
|
|
get: function() {
|
|
return v
|
|
},
|
|
set: function(t) {
|
|
var i = function(t) {
|
|
return r(e, t)
|
|
}(t);
|
|
if (!1 === i)
|
|
throw new SyntaxError("An invalid or illegal string was specified.");
|
|
v = i,
|
|
this.hasBeenReset = !0
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "snapToLines", n({}, l, {
|
|
get: function() {
|
|
return m
|
|
},
|
|
set: function(e) {
|
|
m = !!e,
|
|
this.hasBeenReset = !0
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "line", n({}, l, {
|
|
get: function() {
|
|
return p
|
|
},
|
|
set: function(e) {
|
|
if ("number" != typeof e && "auto" !== e)
|
|
throw new SyntaxError("An invalid number or illegal string was specified.");
|
|
p = e,
|
|
this.hasBeenReset = !0
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "lineAlign", n({}, l, {
|
|
get: function() {
|
|
return y
|
|
},
|
|
set: function(e) {
|
|
var t = i(e);
|
|
if (!t)
|
|
throw new SyntaxError("An invalid or illegal string was specified.");
|
|
y = t,
|
|
this.hasBeenReset = !0
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "position", n({}, l, {
|
|
get: function() {
|
|
return E
|
|
},
|
|
set: function(e) {
|
|
if (e < 0 || e > 100)
|
|
throw new Error("Position must be between 0 and 100.");
|
|
E = e,
|
|
this.hasBeenReset = !0
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "positionAlign", n({}, l, {
|
|
get: function() {
|
|
return T
|
|
},
|
|
set: function(e) {
|
|
var t = i(e);
|
|
if (!t)
|
|
throw new SyntaxError("An invalid or illegal string was specified.");
|
|
T = t,
|
|
this.hasBeenReset = !0
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "size", n({}, l, {
|
|
get: function() {
|
|
return S
|
|
},
|
|
set: function(e) {
|
|
if (e < 0 || e > 100)
|
|
throw new Error("Size must be between 0 and 100.");
|
|
S = e,
|
|
this.hasBeenReset = !0
|
|
}
|
|
})),
|
|
Object.defineProperty(o, "align", n({}, l, {
|
|
get: function() {
|
|
return A
|
|
},
|
|
set: function(e) {
|
|
var t = i(e);
|
|
if (!t)
|
|
throw new SyntaxError("An invalid or illegal string was specified.");
|
|
A = t,
|
|
this.hasBeenReset = !0
|
|
}
|
|
})),
|
|
o.displayState = void 0
|
|
}
|
|
return a.prototype.getCueAsHTML = function() {
|
|
return self.WebVTT.convertCueToDOMTree(self, this.text)
|
|
}
|
|
,
|
|
a
|
|
}()
|
|
, Po = function() {
|
|
function e() {}
|
|
return e.prototype.decode = function(e, t) {
|
|
if (!e)
|
|
return "";
|
|
if ("string" != typeof e)
|
|
throw new Error("Error - expected string data.");
|
|
return decodeURIComponent(encodeURIComponent(e))
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function Co(e) {
|
|
function t(e, t, r, i) {
|
|
return 3600 * (0 | e) + 60 * (0 | t) + (0 | r) + parseFloat(i || 0)
|
|
}
|
|
var r = e.match(/^(?:(\d+):)?(\d{2}):(\d{2})(\.\d+)?/);
|
|
return r ? parseFloat(r[2]) > 59 ? t(r[2], r[3], 0, r[4]) : t(r[1], r[2], r[3], r[4]) : null
|
|
}
|
|
var wo = function() {
|
|
function e() {
|
|
this.values = Object.create(null)
|
|
}
|
|
var t = e.prototype;
|
|
return t.set = function(e, t) {
|
|
this.get(e) || "" === t || (this.values[e] = t)
|
|
}
|
|
,
|
|
t.get = function(e, t, r) {
|
|
return r ? this.has(e) ? this.values[e] : t[r] : this.has(e) ? this.values[e] : t
|
|
}
|
|
,
|
|
t.has = function(e) {
|
|
return e in this.values
|
|
}
|
|
,
|
|
t.alt = function(e, t, r) {
|
|
for (var i = 0; i < r.length; ++i)
|
|
if (t === r[i]) {
|
|
this.set(e, t);
|
|
break
|
|
}
|
|
}
|
|
,
|
|
t.integer = function(e, t) {
|
|
/^-?\d+$/.test(t) && this.set(e, parseInt(t, 10))
|
|
}
|
|
,
|
|
t.percent = function(e, t) {
|
|
if (/^([\d]{1,3})(\.[\d]*)?%$/.test(t)) {
|
|
var r = parseFloat(t);
|
|
if (r >= 0 && r <= 100)
|
|
return this.set(e, r),
|
|
!0
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function Oo(e, t, r, i) {
|
|
var n = i ? e.split(i) : [e];
|
|
for (var a in n)
|
|
if ("string" == typeof n[a]) {
|
|
var s = n[a].split(r);
|
|
2 === s.length && t(s[0], s[1])
|
|
}
|
|
}
|
|
var xo = new _o(0,0,"")
|
|
, Mo = "middle" === xo.align ? "middle" : "center";
|
|
function Fo(e, t, r) {
|
|
var i = e;
|
|
function n() {
|
|
var t = Co(e);
|
|
if (null === t)
|
|
throw new Error("Malformed timestamp: " + i);
|
|
return e = e.replace(/^[^\sa-zA-Z-]+/, ""),
|
|
t
|
|
}
|
|
function a() {
|
|
e = e.replace(/^\s+/, "")
|
|
}
|
|
if (a(),
|
|
t.startTime = n(),
|
|
a(),
|
|
"--\x3e" !== e.slice(0, 3))
|
|
throw new Error("Malformed time stamp (time stamps must be separated by '--\x3e'): " + i);
|
|
e = e.slice(3),
|
|
a(),
|
|
t.endTime = n(),
|
|
a(),
|
|
function(e, t) {
|
|
var i = new wo;
|
|
Oo(e, (function(e, t) {
|
|
var n;
|
|
switch (e) {
|
|
case "region":
|
|
for (var a = r.length - 1; a >= 0; a--)
|
|
if (r[a].id === t) {
|
|
i.set(e, r[a].region);
|
|
break
|
|
}
|
|
break;
|
|
case "vertical":
|
|
i.alt(e, t, ["rl", "lr"]);
|
|
break;
|
|
case "line":
|
|
n = t.split(","),
|
|
i.integer(e, n[0]),
|
|
i.percent(e, n[0]) && i.set("snapToLines", !1),
|
|
i.alt(e, n[0], ["auto"]),
|
|
2 === n.length && i.alt("lineAlign", n[1], ["start", Mo, "end"]);
|
|
break;
|
|
case "position":
|
|
n = t.split(","),
|
|
i.percent(e, n[0]),
|
|
2 === n.length && i.alt("positionAlign", n[1], ["start", Mo, "end", "line-left", "line-right", "auto"]);
|
|
break;
|
|
case "size":
|
|
i.percent(e, t);
|
|
break;
|
|
case "align":
|
|
i.alt(e, t, ["start", Mo, "end", "left", "right"])
|
|
}
|
|
}
|
|
), /:/, /\s/),
|
|
t.region = i.get("region", null),
|
|
t.vertical = i.get("vertical", "");
|
|
var n = i.get("line", "auto");
|
|
"auto" === n && -1 === xo.line && (n = -1),
|
|
t.line = n,
|
|
t.lineAlign = i.get("lineAlign", "start"),
|
|
t.snapToLines = i.get("snapToLines", !0),
|
|
t.size = i.get("size", 100),
|
|
t.align = i.get("align", Mo);
|
|
var a = i.get("position", "auto");
|
|
"auto" === a && 50 === xo.position && (a = "start" === t.align || "left" === t.align ? 0 : "end" === t.align || "right" === t.align ? 100 : 50),
|
|
t.position = a
|
|
}(e, t)
|
|
}
|
|
function No(e) {
|
|
return e.replace(/<br(?: \/)?>/gi, "\n")
|
|
}
|
|
var Uo = function() {
|
|
function e() {
|
|
this.state = "INITIAL",
|
|
this.buffer = "",
|
|
this.decoder = new Po,
|
|
this.regionList = [],
|
|
this.cue = null,
|
|
this.oncue = void 0,
|
|
this.onparsingerror = void 0,
|
|
this.onflush = void 0
|
|
}
|
|
var t = e.prototype;
|
|
return t.parse = function(e) {
|
|
var t = this;
|
|
function r() {
|
|
var e = t.buffer
|
|
, r = 0;
|
|
for (e = No(e); r < e.length && "\r" !== e[r] && "\n" !== e[r]; )
|
|
++r;
|
|
var i = e.slice(0, r);
|
|
return "\r" === e[r] && ++r,
|
|
"\n" === e[r] && ++r,
|
|
t.buffer = e.slice(r),
|
|
i
|
|
}
|
|
e && (t.buffer += t.decoder.decode(e, {
|
|
stream: !0
|
|
}));
|
|
try {
|
|
var i = "";
|
|
if ("INITIAL" === t.state) {
|
|
if (!/\r\n|\n/.test(t.buffer))
|
|
return this;
|
|
var n = (i = r()).match(/^()?WEBVTT([ \t].*)?$/);
|
|
if (null == n || !n[0])
|
|
throw new Error("Malformed WebVTT signature.");
|
|
t.state = "HEADER"
|
|
}
|
|
for (var a = !1; t.buffer; ) {
|
|
if (!/\r\n|\n/.test(t.buffer))
|
|
return this;
|
|
switch (a ? a = !1 : i = r(),
|
|
t.state) {
|
|
case "HEADER":
|
|
/:/.test(i) ? Oo(i, (function(e, t) {}
|
|
), /:/) : i || (t.state = "ID");
|
|
continue;
|
|
case "NOTE":
|
|
i || (t.state = "ID");
|
|
continue;
|
|
case "ID":
|
|
if (/^NOTE($|[ \t])/.test(i)) {
|
|
t.state = "NOTE";
|
|
break
|
|
}
|
|
if (!i)
|
|
continue;
|
|
if (t.cue = new _o(0,0,""),
|
|
t.state = "CUE",
|
|
-1 === i.indexOf("--\x3e")) {
|
|
t.cue.id = i;
|
|
continue
|
|
}
|
|
case "CUE":
|
|
if (!t.cue) {
|
|
t.state = "BADCUE";
|
|
continue
|
|
}
|
|
try {
|
|
Fo(i, t.cue, t.regionList)
|
|
} catch (e) {
|
|
t.cue = null,
|
|
t.state = "BADCUE";
|
|
continue
|
|
}
|
|
t.state = "CUETEXT";
|
|
continue;
|
|
case "CUETEXT":
|
|
var s = -1 !== i.indexOf("--\x3e");
|
|
if (!i || s && (a = !0)) {
|
|
t.oncue && t.cue && t.oncue(t.cue),
|
|
t.cue = null,
|
|
t.state = "ID";
|
|
continue
|
|
}
|
|
if (null === t.cue)
|
|
continue;
|
|
t.cue.text && (t.cue.text += "\n"),
|
|
t.cue.text += i;
|
|
continue;
|
|
case "BADCUE":
|
|
i || (t.state = "ID")
|
|
}
|
|
}
|
|
} catch (e) {
|
|
"CUETEXT" === t.state && t.cue && t.oncue && t.oncue(t.cue),
|
|
t.cue = null,
|
|
t.state = "INITIAL" === t.state ? "BADWEBVTT" : "BADCUE"
|
|
}
|
|
return this
|
|
}
|
|
,
|
|
t.flush = function() {
|
|
var e = this;
|
|
try {
|
|
if ((e.cue || "HEADER" === e.state) && (e.buffer += "\n\n",
|
|
e.parse()),
|
|
"INITIAL" === e.state || "BADWEBVTT" === e.state)
|
|
throw new Error("Malformed WebVTT signature.")
|
|
} catch (t) {
|
|
e.onparsingerror && e.onparsingerror(t)
|
|
}
|
|
return e.onflush && e.onflush(),
|
|
this
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, Bo = /\r\n|\n\r|\n|\r/g
|
|
, Go = function(e, t, r) {
|
|
return void 0 === r && (r = 0),
|
|
e.slice(r, r + t.length) === t
|
|
};
|
|
function Ko(e, t, r) {
|
|
return Gs(e.toString()) + Gs(t.toString()) + Gs(r)
|
|
}
|
|
function Vo(e, t, r, i, n, a, s) {
|
|
var o, l, u, d = new Uo, h = q(new Uint8Array(e)).trim().replace(Bo, "\n").split("\n"), f = [], c = t ? (o = t.baseTime,
|
|
void 0 === (l = t.timescale) && (l = 1),
|
|
Bn(o, Un, 1 / l)) : 0, g = "00:00.000", v = 0, m = 0, p = !0;
|
|
d.oncue = function(e) {
|
|
var a = r[i]
|
|
, s = r.ccOffset
|
|
, o = (v - c) / 9e4;
|
|
if (null != a && a.new && (void 0 !== m ? s = r.ccOffset = a.start : function(e, t, r) {
|
|
var i = e[t]
|
|
, n = e[i.prevCC];
|
|
if (!n || !n.new && i.new)
|
|
return e.ccOffset = e.presentationOffset = i.start,
|
|
void (i.new = !1);
|
|
for (; null != (a = n) && a.new; ) {
|
|
var a;
|
|
e.ccOffset += i.start - n.start,
|
|
i.new = !1,
|
|
n = e[(i = n).prevCC]
|
|
}
|
|
e.presentationOffset = r
|
|
}(r, i, o)),
|
|
o) {
|
|
if (!t)
|
|
return void (u = new Error("Missing initPTS for VTT MPEGTS"));
|
|
s = o - r.presentationOffset
|
|
}
|
|
var l = e.endTime - e.startTime
|
|
, d = Wn(9e4 * (e.startTime + s - m), 9e4 * n) / 9e4;
|
|
e.startTime = Math.max(d, 0),
|
|
e.endTime = Math.max(d + l, 0);
|
|
var h = e.text.trim();
|
|
e.text = decodeURIComponent(encodeURIComponent(h)),
|
|
e.id || (e.id = Ko(e.startTime, e.endTime, h)),
|
|
e.endTime > 0 && f.push(e)
|
|
}
|
|
,
|
|
d.onparsingerror = function(e) {
|
|
u = e
|
|
}
|
|
,
|
|
d.onflush = function() {
|
|
u ? s(u) : a(f)
|
|
}
|
|
,
|
|
h.forEach((function(e) {
|
|
if (p) {
|
|
if (Go(e, "X-TIMESTAMP-MAP=")) {
|
|
p = !1,
|
|
e.slice(16).split(",").forEach((function(e) {
|
|
Go(e, "LOCAL:") ? g = e.slice(6) : Go(e, "MPEGTS:") && (v = parseInt(e.slice(7)))
|
|
}
|
|
));
|
|
try {
|
|
m = function(e) {
|
|
var t = parseInt(e.slice(-3))
|
|
, r = parseInt(e.slice(-6, -4))
|
|
, i = parseInt(e.slice(-9, -7))
|
|
, n = e.length > 9 ? parseInt(e.substring(0, e.indexOf(":"))) : 0;
|
|
if (!(A(t) && A(r) && A(i) && A(n)))
|
|
throw Error("Malformed X-TIMESTAMP-MAP: Local:" + e);
|
|
return t += 1e3 * r,
|
|
(t += 6e4 * i) + 36e5 * n
|
|
}(g) / 1e3
|
|
} catch (e) {
|
|
u = e
|
|
}
|
|
return
|
|
}
|
|
"" === e && (p = !1)
|
|
}
|
|
d.parse(e + "\n")
|
|
}
|
|
)),
|
|
d.flush()
|
|
}
|
|
var Ho = "stpp.ttml.im1t"
|
|
, Yo = /^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/
|
|
, Wo = /^(\d*(?:\.\d*)?)(h|m|s|ms|f|t)$/
|
|
, jo = {
|
|
left: "start",
|
|
center: "center",
|
|
right: "end",
|
|
start: "start",
|
|
end: "end"
|
|
};
|
|
function qo(e, t, r, i) {
|
|
var n = ce(new Uint8Array(e), ["mdat"]);
|
|
if (0 !== n.length) {
|
|
var s, o, l, u, d = n.map((function(e) {
|
|
return q(e)
|
|
}
|
|
)), h = (s = t.baseTime,
|
|
o = 1,
|
|
void 0 === (l = t.timescale) && (l = 1),
|
|
void 0 === u && (u = !1),
|
|
Bn(s, o, 1 / l, u));
|
|
try {
|
|
d.forEach((function(e) {
|
|
return r(function(e, t) {
|
|
var r = (new DOMParser).parseFromString(e, "text/xml")
|
|
, i = r.getElementsByTagName("tt")[0];
|
|
if (!i)
|
|
throw new Error("Invalid ttml");
|
|
var n = {
|
|
frameRate: 30,
|
|
subFrameRate: 1,
|
|
frameRateMultiplier: 0,
|
|
tickRate: 0
|
|
}
|
|
, s = Object.keys(n).reduce((function(e, t) {
|
|
return e[t] = i.getAttribute("ttp:" + t) || n[t],
|
|
e
|
|
}
|
|
), {})
|
|
, o = "preserve" !== i.getAttribute("xml:space")
|
|
, l = Qo(Xo(i, "styling", "style"))
|
|
, u = Qo(Xo(i, "layout", "region"))
|
|
, d = Xo(i, "body", "[begin]");
|
|
return [].map.call(d, (function(e) {
|
|
var r = zo(e, o);
|
|
if (!r || !e.hasAttribute("begin"))
|
|
return null;
|
|
var i = Jo(e.getAttribute("begin"), s)
|
|
, n = Jo(e.getAttribute("dur"), s)
|
|
, d = Jo(e.getAttribute("end"), s);
|
|
if (null === i)
|
|
throw Zo(e);
|
|
if (null === d) {
|
|
if (null === n)
|
|
throw Zo(e);
|
|
d = i + n
|
|
}
|
|
var h = new _o(i - t,d - t,r);
|
|
h.id = Ko(h.startTime, h.endTime, h.text);
|
|
var f = function(e, t, r) {
|
|
var i = "http://www.w3.org/ns/ttml#styling"
|
|
, n = null
|
|
, a = ["displayAlign", "textAlign", "color", "backgroundColor", "fontSize", "fontFamily"]
|
|
, s = null != e && e.hasAttribute("style") ? e.getAttribute("style") : null;
|
|
return s && r.hasOwnProperty(s) && (n = r[s]),
|
|
a.reduce((function(r, a) {
|
|
var s = $o(t, i, a) || $o(e, i, a) || $o(n, i, a);
|
|
return s && (r[a] = s),
|
|
r
|
|
}
|
|
), {})
|
|
}(u[e.getAttribute("region")], l[e.getAttribute("style")], l)
|
|
, c = f.textAlign;
|
|
if (c) {
|
|
var g = jo[c];
|
|
g && (h.lineAlign = g),
|
|
h.align = c
|
|
}
|
|
return a(h, f),
|
|
h
|
|
}
|
|
)).filter((function(e) {
|
|
return null !== e
|
|
}
|
|
))
|
|
}(e, h))
|
|
}
|
|
))
|
|
} catch (e) {
|
|
i(e)
|
|
}
|
|
} else
|
|
i(new Error("Could not parse IMSC1 mdat"))
|
|
}
|
|
function Xo(e, t, r) {
|
|
var i = e.getElementsByTagName(t)[0];
|
|
return i ? [].slice.call(i.querySelectorAll(r)) : []
|
|
}
|
|
function Qo(e) {
|
|
return e.reduce((function(e, t) {
|
|
var r = t.getAttribute("xml:id");
|
|
return r && (e[r] = t),
|
|
e
|
|
}
|
|
), {})
|
|
}
|
|
function zo(e, t) {
|
|
return [].slice.call(e.childNodes).reduce((function(e, r, i) {
|
|
var n;
|
|
return "br" === r.nodeName && i ? e + "\n" : null != (n = r.childNodes) && n.length ? zo(r, t) : t ? e + r.textContent.trim().replace(/\s+/g, " ") : e + r.textContent
|
|
}
|
|
), "")
|
|
}
|
|
function $o(e, t, r) {
|
|
return e && e.hasAttributeNS(t, r) ? e.getAttributeNS(t, r) : null
|
|
}
|
|
function Zo(e) {
|
|
return new Error("Could not parse ttml timestamp " + e)
|
|
}
|
|
function Jo(e, t) {
|
|
if (!e)
|
|
return null;
|
|
var r = Co(e);
|
|
return null === r && (Yo.test(e) ? r = function(e, t) {
|
|
var r = Yo.exec(e)
|
|
, i = (0 | r[4]) + (0 | r[5]) / t.subFrameRate;
|
|
return 3600 * (0 | r[1]) + 60 * (0 | r[2]) + (0 | r[3]) + i / t.frameRate
|
|
}(e, t) : Wo.test(e) && (r = function(e, t) {
|
|
var r = Wo.exec(e)
|
|
, i = Number(r[1]);
|
|
switch (r[2]) {
|
|
case "h":
|
|
return 3600 * i;
|
|
case "m":
|
|
return 60 * i;
|
|
case "ms":
|
|
return 1e3 * i;
|
|
case "f":
|
|
return i / t.frameRate;
|
|
case "t":
|
|
return i / t.tickRate
|
|
}
|
|
return i
|
|
}(e, t))),
|
|
r
|
|
}
|
|
var el = function() {
|
|
function e(e, t) {
|
|
this.timelineController = void 0,
|
|
this.cueRanges = [],
|
|
this.trackName = void 0,
|
|
this.startTime = null,
|
|
this.endTime = null,
|
|
this.screen = null,
|
|
this.timelineController = e,
|
|
this.trackName = t
|
|
}
|
|
var t = e.prototype;
|
|
return t.dispatchCue = function() {
|
|
null !== this.startTime && (this.timelineController.addCues(this.trackName, this.startTime, this.endTime, this.screen, this.cueRanges),
|
|
this.startTime = null)
|
|
}
|
|
,
|
|
t.newCue = function(e, t, r) {
|
|
(null === this.startTime || this.startTime > e) && (this.startTime = e),
|
|
this.endTime = t,
|
|
this.screen = r,
|
|
this.timelineController.createCaptionsTrack(this.trackName)
|
|
}
|
|
,
|
|
t.reset = function() {
|
|
this.cueRanges = [],
|
|
this.startTime = null
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, tl = function() {
|
|
function e(e) {
|
|
this.hls = void 0,
|
|
this.media = null,
|
|
this.config = void 0,
|
|
this.enabled = !0,
|
|
this.Cues = void 0,
|
|
this.textTracks = [],
|
|
this.tracks = [],
|
|
this.initPTS = [],
|
|
this.unparsedVttFrags = [],
|
|
this.captionsTracks = {},
|
|
this.nonNativeCaptionsTracks = {},
|
|
this.cea608Parser1 = void 0,
|
|
this.cea608Parser2 = void 0,
|
|
this.lastCc = -1,
|
|
this.lastSn = -1,
|
|
this.lastPartIndex = -1,
|
|
this.prevCC = -1,
|
|
this.vttCCs = {
|
|
ccOffset: 0,
|
|
presentationOffset: 0,
|
|
0: {
|
|
start: 0,
|
|
prevCC: -1,
|
|
new: !0
|
|
}
|
|
},
|
|
this.captionsProperties = void 0,
|
|
this.hls = e,
|
|
this.config = e.config,
|
|
this.Cues = e.config.cueHandler,
|
|
this.captionsProperties = {
|
|
textTrack1: {
|
|
label: this.config.captionsTextTrack1Label,
|
|
languageCode: this.config.captionsTextTrack1LanguageCode
|
|
},
|
|
textTrack2: {
|
|
label: this.config.captionsTextTrack2Label,
|
|
languageCode: this.config.captionsTextTrack2LanguageCode
|
|
},
|
|
textTrack3: {
|
|
label: this.config.captionsTextTrack3Label,
|
|
languageCode: this.config.captionsTextTrack3LanguageCode
|
|
},
|
|
textTrack4: {
|
|
label: this.config.captionsTextTrack4Label,
|
|
languageCode: this.config.captionsTextTrack4LanguageCode
|
|
}
|
|
},
|
|
e.on(b.MEDIA_ATTACHING, this.onMediaAttaching, this),
|
|
e.on(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.MANIFEST_LOADED, this.onManifestLoaded, this),
|
|
e.on(b.SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this),
|
|
e.on(b.FRAG_LOADING, this.onFragLoading, this),
|
|
e.on(b.FRAG_LOADED, this.onFragLoaded, this),
|
|
e.on(b.FRAG_PARSING_USERDATA, this.onFragParsingUserdata, this),
|
|
e.on(b.FRAG_DECRYPTED, this.onFragDecrypted, this),
|
|
e.on(b.INIT_PTS_FOUND, this.onInitPtsFound, this),
|
|
e.on(b.SUBTITLE_TRACKS_CLEARED, this.onSubtitleTracksCleared, this),
|
|
e.on(b.BUFFER_FLUSHING, this.onBufferFlushing, this)
|
|
}
|
|
var t = e.prototype;
|
|
return t.destroy = function() {
|
|
var e = this.hls;
|
|
e.off(b.MEDIA_ATTACHING, this.onMediaAttaching, this),
|
|
e.off(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.MANIFEST_LOADED, this.onManifestLoaded, this),
|
|
e.off(b.SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this),
|
|
e.off(b.FRAG_LOADING, this.onFragLoading, this),
|
|
e.off(b.FRAG_LOADED, this.onFragLoaded, this),
|
|
e.off(b.FRAG_PARSING_USERDATA, this.onFragParsingUserdata, this),
|
|
e.off(b.FRAG_DECRYPTED, this.onFragDecrypted, this),
|
|
e.off(b.INIT_PTS_FOUND, this.onInitPtsFound, this),
|
|
e.off(b.SUBTITLE_TRACKS_CLEARED, this.onSubtitleTracksCleared, this),
|
|
e.off(b.BUFFER_FLUSHING, this.onBufferFlushing, this),
|
|
this.hls = this.config = this.media = null,
|
|
this.cea608Parser1 = this.cea608Parser2 = void 0
|
|
}
|
|
,
|
|
t.initCea608Parsers = function() {
|
|
var e = new el(this,"textTrack1")
|
|
, t = new el(this,"textTrack2")
|
|
, r = new el(this,"textTrack3")
|
|
, i = new el(this,"textTrack4");
|
|
this.cea608Parser1 = new bo(1,e,t),
|
|
this.cea608Parser2 = new bo(3,r,i)
|
|
}
|
|
,
|
|
t.addCues = function(e, t, r, i, n) {
|
|
for (var a, s, o, l, u = !1, d = n.length; d--; ) {
|
|
var h = n[d]
|
|
, f = (a = h[0],
|
|
s = h[1],
|
|
o = t,
|
|
l = r,
|
|
Math.min(s, l) - Math.max(a, o));
|
|
if (f >= 0 && (h[0] = Math.min(h[0], t),
|
|
h[1] = Math.max(h[1], r),
|
|
u = !0,
|
|
f / (r - t) > .5))
|
|
return
|
|
}
|
|
if (u || n.push([t, r]),
|
|
this.config.renderTextTracksNatively) {
|
|
var c = this.captionsTracks[e];
|
|
this.Cues.newCue(c, t, r, i)
|
|
} else {
|
|
var g = this.Cues.newCue(null, t, r, i);
|
|
this.hls.trigger(b.CUES_PARSED, {
|
|
type: "captions",
|
|
cues: g,
|
|
track: e
|
|
})
|
|
}
|
|
}
|
|
,
|
|
t.onInitPtsFound = function(e, t) {
|
|
var r = this
|
|
, i = t.frag
|
|
, n = t.id
|
|
, a = t.initPTS
|
|
, s = t.timescale
|
|
, o = t.trackId
|
|
, l = this.unparsedVttFrags;
|
|
n === w && (this.initPTS[i.cc] = {
|
|
baseTime: a,
|
|
timescale: s,
|
|
trackId: o
|
|
}),
|
|
l.length && (this.unparsedVttFrags = [],
|
|
l.forEach((function(e) {
|
|
r.initPTS[e.frag.cc] ? r.onFragLoaded(b.FRAG_LOADED, e) : r.hls.trigger(b.SUBTITLE_FRAG_PROCESSED, {
|
|
success: !1,
|
|
frag: e.frag,
|
|
error: new Error("Subtitle discontinuity domain does not match main")
|
|
})
|
|
}
|
|
)))
|
|
}
|
|
,
|
|
t.getExistingTrack = function(e, t) {
|
|
var r = this.media;
|
|
if (r)
|
|
for (var i = 0; i < r.textTracks.length; i++) {
|
|
var n = r.textTracks[i];
|
|
if (il(n, {
|
|
name: e,
|
|
lang: t,
|
|
characteristics: "transcribes-spoken-dialog,describes-music-and-sound"
|
|
}))
|
|
return n
|
|
}
|
|
return null
|
|
}
|
|
,
|
|
t.createCaptionsTrack = function(e) {
|
|
this.config.renderTextTracksNatively ? this.createNativeTrack(e) : this.createNonNativeTrack(e)
|
|
}
|
|
,
|
|
t.createNativeTrack = function(e) {
|
|
if (!this.captionsTracks[e]) {
|
|
var t = this.captionsProperties
|
|
, r = this.captionsTracks
|
|
, i = this.media
|
|
, n = t[e]
|
|
, a = n.label
|
|
, s = n.languageCode
|
|
, o = this.getExistingTrack(a, s);
|
|
if (o)
|
|
r[e] = o,
|
|
so(r[e]),
|
|
no(r[e], i);
|
|
else {
|
|
var l = this.createTextTrack("captions", a, s);
|
|
l && (l[e] = !0,
|
|
r[e] = l)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
t.createNonNativeTrack = function(e) {
|
|
if (!this.nonNativeCaptionsTracks[e]) {
|
|
var t = this.captionsProperties[e];
|
|
if (t) {
|
|
var r = {
|
|
_id: e,
|
|
label: t.label,
|
|
kind: "captions",
|
|
default: !!t.media && !!t.media.default,
|
|
closedCaptions: t.media
|
|
};
|
|
this.nonNativeCaptionsTracks[e] = r,
|
|
this.hls.trigger(b.NON_NATIVE_TEXT_TRACKS_FOUND, {
|
|
tracks: [r]
|
|
})
|
|
}
|
|
}
|
|
}
|
|
,
|
|
t.createTextTrack = function(e, t, r) {
|
|
var i = this.media;
|
|
if (i)
|
|
return i.addTextTrack(e, t, r)
|
|
}
|
|
,
|
|
t.onMediaAttaching = function(e, t) {
|
|
this.media = t.media,
|
|
t.mediaSource || this._cleanTracks()
|
|
}
|
|
,
|
|
t.onMediaDetaching = function(e, t) {
|
|
var r = !!t.transferMedia;
|
|
if (this.media = null,
|
|
!r) {
|
|
var i = this.captionsTracks;
|
|
Object.keys(i).forEach((function(e) {
|
|
so(i[e]),
|
|
delete i[e]
|
|
}
|
|
)),
|
|
this.nonNativeCaptionsTracks = {}
|
|
}
|
|
}
|
|
,
|
|
t.onManifestLoading = function() {
|
|
this.lastCc = -1,
|
|
this.lastSn = -1,
|
|
this.lastPartIndex = -1,
|
|
this.prevCC = -1,
|
|
this.vttCCs = {
|
|
ccOffset: 0,
|
|
presentationOffset: 0,
|
|
0: {
|
|
start: 0,
|
|
prevCC: -1,
|
|
new: !0
|
|
}
|
|
},
|
|
this._cleanTracks(),
|
|
this.tracks = [],
|
|
this.captionsTracks = {},
|
|
this.nonNativeCaptionsTracks = {},
|
|
this.textTracks = [],
|
|
this.unparsedVttFrags = [],
|
|
this.initPTS = [],
|
|
this.cea608Parser1 && this.cea608Parser2 && (this.cea608Parser1.reset(),
|
|
this.cea608Parser2.reset())
|
|
}
|
|
,
|
|
t._cleanTracks = function() {
|
|
var e = this.media;
|
|
if (e) {
|
|
var t = e.textTracks;
|
|
if (t)
|
|
for (var r = 0; r < t.length; r++)
|
|
so(t[r])
|
|
}
|
|
}
|
|
,
|
|
t.onSubtitleTracksUpdated = function(e, t) {
|
|
var r = this
|
|
, i = t.subtitleTracks || []
|
|
, n = i.some((function(e) {
|
|
return e.textCodec === Ho
|
|
}
|
|
));
|
|
if (this.config.enableWebVTT || n && this.config.enableIMSC1) {
|
|
if (va(this.tracks, i))
|
|
return void (this.tracks = i);
|
|
if (this.textTracks = [],
|
|
this.tracks = i,
|
|
this.config.renderTextTracksNatively) {
|
|
var a = this.media
|
|
, s = a ? lo(a.textTracks) : null;
|
|
if (this.tracks.forEach((function(e, t) {
|
|
var i;
|
|
if (s) {
|
|
for (var n = null, a = 0; a < s.length; a++)
|
|
if (s[a] && il(s[a], e)) {
|
|
n = s[a],
|
|
s[a] = null;
|
|
break
|
|
}
|
|
n && (i = n)
|
|
}
|
|
if (i)
|
|
so(i);
|
|
else {
|
|
var o = rl(e);
|
|
(i = r.createTextTrack(o, e.name, e.lang)) && (i.mode = "disabled")
|
|
}
|
|
i && r.textTracks.push(i)
|
|
}
|
|
)),
|
|
null != s && s.length) {
|
|
var o = s.filter((function(e) {
|
|
return null !== e
|
|
}
|
|
)).map((function(e) {
|
|
return e.label
|
|
}
|
|
));
|
|
o.length && this.hls.logger.warn("Media element contains unused subtitle tracks: " + o.join(", ") + ". Replace media element for each source to clear TextTracks and captions menu.")
|
|
}
|
|
} else if (this.tracks.length) {
|
|
var l = this.tracks.map((function(e) {
|
|
return {
|
|
label: e.name,
|
|
kind: e.type.toLowerCase(),
|
|
default: e.default,
|
|
subtitleTrack: e
|
|
}
|
|
}
|
|
));
|
|
this.hls.trigger(b.NON_NATIVE_TEXT_TRACKS_FOUND, {
|
|
tracks: l
|
|
})
|
|
}
|
|
}
|
|
}
|
|
,
|
|
t.onManifestLoaded = function(e, t) {
|
|
var r = this;
|
|
this.config.enableCEA708Captions && t.captions && t.captions.forEach((function(e) {
|
|
var t = /(?:CC|SERVICE)([1-4])/.exec(e.instreamId);
|
|
if (t) {
|
|
var i = "textTrack" + t[1]
|
|
, n = r.captionsProperties[i];
|
|
n && (n.label = e.name,
|
|
e.lang && (n.languageCode = e.lang),
|
|
n.media = e)
|
|
}
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t.closedCaptionsForLevel = function(e) {
|
|
var t = this.hls.levels[e.level];
|
|
return null == t ? void 0 : t.attrs["CLOSED-CAPTIONS"]
|
|
}
|
|
,
|
|
t.onFragLoading = function(e, t) {
|
|
if (this.enabled && t.frag.type === w) {
|
|
var r, i, n = this.cea608Parser1, a = this.cea608Parser2, s = this.lastSn, o = t.frag, l = o.cc, u = o.sn, d = null != (r = null == (i = t.part) ? void 0 : i.index) ? r : -1;
|
|
n && a && (u !== s + 1 || u === s && d !== this.lastPartIndex + 1 || l !== this.lastCc) && (n.reset(),
|
|
a.reset()),
|
|
this.lastCc = l,
|
|
this.lastSn = u,
|
|
this.lastPartIndex = d
|
|
}
|
|
}
|
|
,
|
|
t.onFragLoaded = function(e, t) {
|
|
var r = t.frag
|
|
, i = t.payload;
|
|
if (r.type === x)
|
|
if (i.byteLength) {
|
|
var n = r.decryptdata
|
|
, a = "stats"in t;
|
|
if (null == n || !n.encrypted || a) {
|
|
var s = this.tracks[r.level]
|
|
, o = this.vttCCs;
|
|
o[r.cc] || (o[r.cc] = {
|
|
start: r.start,
|
|
prevCC: this.prevCC,
|
|
new: !0
|
|
},
|
|
this.prevCC = r.cc),
|
|
s && s.textCodec === Ho ? this._parseIMSC1(r, i) : this._parseVTTs(t)
|
|
}
|
|
} else
|
|
this.hls.trigger(b.SUBTITLE_FRAG_PROCESSED, {
|
|
success: !1,
|
|
frag: r,
|
|
error: new Error("Empty subtitle payload")
|
|
})
|
|
}
|
|
,
|
|
t._parseIMSC1 = function(e, t) {
|
|
var r = this
|
|
, i = this.hls;
|
|
qo(t, this.initPTS[e.cc], (function(t) {
|
|
r._appendCues(t, e.level),
|
|
i.trigger(b.SUBTITLE_FRAG_PROCESSED, {
|
|
success: !0,
|
|
frag: e
|
|
})
|
|
}
|
|
), (function(t) {
|
|
i.logger.log("Failed to parse IMSC1: " + t),
|
|
i.trigger(b.SUBTITLE_FRAG_PROCESSED, {
|
|
success: !1,
|
|
frag: e,
|
|
error: t
|
|
})
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t._parseVTTs = function(e) {
|
|
var t, r = this, i = e.frag, n = e.payload, a = this.initPTS, s = this.unparsedVttFrags, o = a.length - 1;
|
|
if (a[i.cc] || -1 !== o) {
|
|
var l = this.hls;
|
|
Vo(null != (t = i.initSegment) && t.data ? Ae(i.initSegment.data, new Uint8Array(n)).buffer : n, this.initPTS[i.cc], this.vttCCs, i.cc, i.start, (function(e) {
|
|
r._appendCues(e, i.level),
|
|
l.trigger(b.SUBTITLE_FRAG_PROCESSED, {
|
|
success: !0,
|
|
frag: i
|
|
})
|
|
}
|
|
), (function(t) {
|
|
var a = "Missing initPTS for VTT MPEGTS" === t.message;
|
|
a ? s.push(e) : r._fallbackToIMSC1(i, n),
|
|
l.logger.log("Failed to parse VTT cue: " + t),
|
|
a && o > i.cc || l.trigger(b.SUBTITLE_FRAG_PROCESSED, {
|
|
success: !1,
|
|
frag: i,
|
|
error: t
|
|
})
|
|
}
|
|
))
|
|
} else
|
|
s.push(e)
|
|
}
|
|
,
|
|
t._fallbackToIMSC1 = function(e, t) {
|
|
var r = this
|
|
, i = this.tracks[e.level];
|
|
i.textCodec || qo(t, this.initPTS[e.cc], (function() {
|
|
i.textCodec = Ho,
|
|
r._parseIMSC1(e, t)
|
|
}
|
|
), (function() {
|
|
i.textCodec = "wvtt"
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t._appendCues = function(e, t) {
|
|
var r = this.hls;
|
|
if (this.config.renderTextTracksNatively) {
|
|
var i = this.textTracks[t];
|
|
if (!i || "disabled" === i.mode)
|
|
return;
|
|
e.forEach((function(e) {
|
|
return ao(i, e)
|
|
}
|
|
))
|
|
} else {
|
|
var n = this.tracks[t];
|
|
if (!n)
|
|
return;
|
|
var a = n.default ? "default" : "subtitles" + t;
|
|
r.trigger(b.CUES_PARSED, {
|
|
type: "subtitles",
|
|
cues: e,
|
|
track: a
|
|
})
|
|
}
|
|
}
|
|
,
|
|
t.onFragDecrypted = function(e, t) {
|
|
t.frag.type === x && this.onFragLoaded(b.FRAG_LOADED, t)
|
|
}
|
|
,
|
|
t.onSubtitleTracksCleared = function() {
|
|
this.tracks = [],
|
|
this.captionsTracks = {}
|
|
}
|
|
,
|
|
t.onFragParsingUserdata = function(e, t) {
|
|
if (this.enabled && this.config.enableCEA708Captions) {
|
|
var r = t.frag
|
|
, i = t.samples;
|
|
if (r.type !== w || "NONE" !== this.closedCaptionsForLevel(r))
|
|
for (var n = 0; n < i.length; n++) {
|
|
var a = i[n].bytes;
|
|
if (a) {
|
|
this.cea608Parser1 || this.initCea608Parsers();
|
|
var s = this.extractCea608Data(a);
|
|
this.cea608Parser1.addData(i[n].pts, s[0]),
|
|
this.cea608Parser2.addData(i[n].pts, s[1])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
t.onBufferFlushing = function(e, t) {
|
|
var r = t.startOffset
|
|
, i = t.endOffset
|
|
, n = t.endOffsetSubtitles
|
|
, a = t.type
|
|
, s = this.media;
|
|
if (s && !(s.currentTime < i)) {
|
|
if (!a || "video" === a) {
|
|
var o = this.captionsTracks;
|
|
Object.keys(o).forEach((function(e) {
|
|
return oo(o[e], r, i)
|
|
}
|
|
))
|
|
}
|
|
if (this.config.renderTextTracksNatively && 0 === r && void 0 !== n) {
|
|
var l = this.textTracks;
|
|
Object.keys(l).forEach((function(e) {
|
|
return oo(l[e], r, n)
|
|
}
|
|
))
|
|
}
|
|
}
|
|
}
|
|
,
|
|
t.extractCea608Data = function(e) {
|
|
for (var t = [[], []], r = 31 & e[0], i = 2, n = 0; n < r; n++) {
|
|
var a = e[i++]
|
|
, s = 127 & e[i++]
|
|
, o = 127 & e[i++];
|
|
if ((0 !== s || 0 !== o) && 0 != (4 & a)) {
|
|
var l = 3 & a;
|
|
0 !== l && 1 !== l || (t[l].push(s),
|
|
t[l].push(o))
|
|
}
|
|
}
|
|
return t
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function rl(e) {
|
|
return e.characteristics && /transcribes-spoken-dialog/gi.test(e.characteristics) && /describes-music-and-sound/gi.test(e.characteristics) ? "captions" : "subtitles"
|
|
}
|
|
function il(e, t) {
|
|
return !!e && e.kind === rl(t) && pa(t, e)
|
|
}
|
|
var nl = /\s/
|
|
, al = {
|
|
newCue: function(e, t, r, i) {
|
|
for (var n, a, s, o, l, u = [], d = self.VTTCue || self.TextTrackCue, h = 0; h < i.rows.length; h++)
|
|
if (s = !0,
|
|
o = 0,
|
|
l = "",
|
|
!(n = i.rows[h]).isEmpty()) {
|
|
for (var f, c = 0; c < n.chars.length; c++)
|
|
nl.test(n.chars[c].uchar) && s ? o++ : (l += n.chars[c].uchar,
|
|
s = !1);
|
|
n.cueStartTime = t,
|
|
t === r && (r += 1e-4),
|
|
o >= 16 ? o-- : o++;
|
|
var g = No(l.trim())
|
|
, v = Ko(t, r, g);
|
|
null != e && null != (f = e.cues) && f.getCueById(v) || ((a = new d(t,r,g)).id = v,
|
|
a.line = h + 1,
|
|
a.align = "left",
|
|
a.position = 10 + Math.min(80, 10 * Math.floor(8 * o / 32)),
|
|
u.push(a))
|
|
}
|
|
return e && u.length && (u.sort((function(e, t) {
|
|
return "auto" === e.line || "auto" === t.line ? 0 : e.line > 8 && t.line > 8 ? t.line - e.line : e.line - t.line
|
|
}
|
|
)),
|
|
u.forEach((function(t) {
|
|
return ao(e, t)
|
|
}
|
|
))),
|
|
u
|
|
}
|
|
}
|
|
, sl = /(\d+)-(\d+)\/(\d+)/
|
|
, ol = function() {
|
|
function e(e) {
|
|
this.fetchSetup = void 0,
|
|
this.requestTimeout = void 0,
|
|
this.request = null,
|
|
this.response = null,
|
|
this.controller = void 0,
|
|
this.context = null,
|
|
this.config = null,
|
|
this.callbacks = null,
|
|
this.stats = void 0,
|
|
this.loader = null,
|
|
this.fetchSetup = e.fetchSetup || ll,
|
|
this.controller = new self.AbortController,
|
|
this.stats = new z
|
|
}
|
|
var t = e.prototype;
|
|
return t.destroy = function() {
|
|
this.loader = this.callbacks = this.context = this.config = this.request = null,
|
|
this.abortInternal(),
|
|
this.response = null,
|
|
this.fetchSetup = this.controller = this.stats = null
|
|
}
|
|
,
|
|
t.abortInternal = function() {
|
|
this.controller && !this.stats.loading.end && (this.stats.aborted = !0,
|
|
this.controller.abort())
|
|
}
|
|
,
|
|
t.abort = function() {
|
|
var e;
|
|
this.abortInternal(),
|
|
null != (e = this.callbacks) && e.onAbort && this.callbacks.onAbort(this.stats, this.context, this.response)
|
|
}
|
|
,
|
|
t.load = function(e, t, r) {
|
|
var i = this
|
|
, n = this.stats;
|
|
if (n.loading.start)
|
|
throw new Error("Loader can only be used once.");
|
|
n.loading.start = self.performance.now();
|
|
var s = function(e, t) {
|
|
var r = {
|
|
method: "GET",
|
|
mode: "cors",
|
|
credentials: "same-origin",
|
|
signal: t,
|
|
headers: new self.Headers(a({}, e.headers))
|
|
};
|
|
return e.rangeEnd && r.headers.set("Range", "bytes=" + e.rangeStart + "-" + String(e.rangeEnd - 1)),
|
|
r
|
|
}(e, this.controller.signal)
|
|
, o = "arraybuffer" === e.responseType
|
|
, l = o ? "byteLength" : "length"
|
|
, u = t.loadPolicy
|
|
, d = u.maxTimeToFirstByteMs
|
|
, h = u.maxLoadTimeMs;
|
|
this.context = e,
|
|
this.config = t,
|
|
this.callbacks = r,
|
|
this.request = this.fetchSetup(e, s),
|
|
self.clearTimeout(this.requestTimeout),
|
|
t.timeout = d && A(d) ? d : h,
|
|
this.requestTimeout = self.setTimeout((function() {
|
|
i.callbacks && (i.abortInternal(),
|
|
i.callbacks.onTimeout(n, e, i.response))
|
|
}
|
|
), t.timeout),
|
|
(ta(this.request) ? this.request.then(self.fetch) : self.fetch(this.request)).then((function(r) {
|
|
var a;
|
|
i.response = i.loader = r;
|
|
var s = Math.max(self.performance.now(), n.loading.start);
|
|
if (self.clearTimeout(i.requestTimeout),
|
|
t.timeout = h,
|
|
i.requestTimeout = self.setTimeout((function() {
|
|
i.callbacks && (i.abortInternal(),
|
|
i.callbacks.onTimeout(n, e, i.response))
|
|
}
|
|
), h - (s - n.loading.start)),
|
|
!r.ok) {
|
|
var l = r.status
|
|
, u = r.statusText;
|
|
throw new ul(u || "fetch, bad network response",l,r)
|
|
}
|
|
n.loading.first = s,
|
|
n.total = function(e) {
|
|
var t = e.get("Content-Range");
|
|
if (t) {
|
|
var r = function(e) {
|
|
var t = sl.exec(e);
|
|
if (t)
|
|
return parseInt(t[2]) - parseInt(t[1]) + 1
|
|
}(t);
|
|
if (A(r))
|
|
return r
|
|
}
|
|
var i = e.get("Content-Length");
|
|
if (i)
|
|
return parseInt(i)
|
|
}(r.headers) || n.total;
|
|
var d = null == (a = i.callbacks) ? void 0 : a.onProgress;
|
|
return d && A(t.highWaterMark) ? i.loadProgressively(r, n, e, t.highWaterMark, d) : o ? r.arrayBuffer() : "json" === e.responseType ? r.json() : r.text()
|
|
}
|
|
)).then((function(r) {
|
|
var a, s, o = i.response;
|
|
if (!o)
|
|
throw new Error("loader destroyed");
|
|
self.clearTimeout(i.requestTimeout),
|
|
n.loading.end = Math.max(self.performance.now(), n.loading.first);
|
|
var u = r[l];
|
|
u && (n.loaded = n.total = u);
|
|
var d = {
|
|
url: o.url,
|
|
data: r,
|
|
code: o.status
|
|
}
|
|
, h = null == (a = i.callbacks) ? void 0 : a.onProgress;
|
|
h && !A(t.highWaterMark) && h(n, e, r, o),
|
|
null == (s = i.callbacks) || s.onSuccess(d, n, e, o)
|
|
}
|
|
)).catch((function(t) {
|
|
var r;
|
|
if (self.clearTimeout(i.requestTimeout),
|
|
!n.aborted) {
|
|
var a = t && t.code || 0
|
|
, s = t ? t.message : null;
|
|
null == (r = i.callbacks) || r.onError({
|
|
code: a,
|
|
text: s
|
|
}, e, t ? t.details : null, n)
|
|
}
|
|
}
|
|
))
|
|
}
|
|
,
|
|
t.getCacheAge = function() {
|
|
var e = null;
|
|
if (this.response) {
|
|
var t = this.response.headers.get("age");
|
|
e = t ? parseFloat(t) : null
|
|
}
|
|
return e
|
|
}
|
|
,
|
|
t.getResponseHeader = function(e) {
|
|
return this.response ? this.response.headers.get(e) : null
|
|
}
|
|
,
|
|
t.loadProgressively = function(e, t, r, i, n) {
|
|
void 0 === i && (i = 0);
|
|
var a = new _i
|
|
, s = e.body.getReader()
|
|
, o = function() {
|
|
return s.read().then((function(s) {
|
|
if (s.done)
|
|
return a.dataLength && n(t, r, a.flush().buffer, e),
|
|
Promise.resolve(new ArrayBuffer(0));
|
|
var l = s.value
|
|
, u = l.length;
|
|
return t.loaded += u,
|
|
u < i || a.dataLength ? (a.push(l),
|
|
a.dataLength >= i && n(t, r, a.flush().buffer, e)) : n(t, r, l.buffer, e),
|
|
o()
|
|
}
|
|
)).catch((function() {
|
|
return Promise.reject()
|
|
}
|
|
))
|
|
};
|
|
return o()
|
|
}
|
|
,
|
|
e
|
|
}();
|
|
function ll(e, t) {
|
|
return new self.Request(e.url,t)
|
|
}
|
|
var ul = function(e) {
|
|
function t(t, r, i) {
|
|
var n;
|
|
return (n = e.call(this, t) || this).code = void 0,
|
|
n.details = void 0,
|
|
n.code = r,
|
|
n.details = i,
|
|
n
|
|
}
|
|
return o(t, e),
|
|
t
|
|
}(c(Error))
|
|
, dl = /^age:\s*[\d.]+\s*$/im
|
|
, hl = function() {
|
|
function e(e) {
|
|
this.xhrSetup = void 0,
|
|
this.requestTimeout = void 0,
|
|
this.retryTimeout = void 0,
|
|
this.retryDelay = void 0,
|
|
this.config = null,
|
|
this.callbacks = null,
|
|
this.context = null,
|
|
this.loader = null,
|
|
this.stats = void 0,
|
|
this.xhrSetup = e && e.xhrSetup || null,
|
|
this.stats = new z,
|
|
this.retryDelay = 0
|
|
}
|
|
var t = e.prototype;
|
|
return t.destroy = function() {
|
|
this.callbacks = null,
|
|
this.abortInternal(),
|
|
this.loader = null,
|
|
this.config = null,
|
|
this.context = null,
|
|
this.xhrSetup = null
|
|
}
|
|
,
|
|
t.abortInternal = function() {
|
|
var e = this.loader;
|
|
self.clearTimeout(this.requestTimeout),
|
|
self.clearTimeout(this.retryTimeout),
|
|
e && (e.onreadystatechange = null,
|
|
e.onprogress = null,
|
|
4 !== e.readyState && (this.stats.aborted = !0,
|
|
e.abort()))
|
|
}
|
|
,
|
|
t.abort = function() {
|
|
var e;
|
|
this.abortInternal(),
|
|
null != (e = this.callbacks) && e.onAbort && this.callbacks.onAbort(this.stats, this.context, this.loader)
|
|
}
|
|
,
|
|
t.load = function(e, t, r) {
|
|
if (this.stats.loading.start)
|
|
throw new Error("Loader can only be used once.");
|
|
this.stats.loading.start = self.performance.now(),
|
|
this.context = e,
|
|
this.config = t,
|
|
this.callbacks = r,
|
|
this.loadInternal()
|
|
}
|
|
,
|
|
t.loadInternal = function() {
|
|
var e = this
|
|
, t = this.config
|
|
, r = this.context;
|
|
if (t && r) {
|
|
var i = this.loader = new self.XMLHttpRequest
|
|
, n = this.stats;
|
|
n.loading.first = 0,
|
|
n.loaded = 0,
|
|
n.aborted = !1;
|
|
var a = this.xhrSetup;
|
|
a ? Promise.resolve().then((function() {
|
|
if (e.loader === i && !e.stats.aborted)
|
|
return a(i, r.url)
|
|
}
|
|
)).catch((function(t) {
|
|
if (e.loader === i && !e.stats.aborted)
|
|
return i.open("GET", r.url, !0),
|
|
a(i, r.url)
|
|
}
|
|
)).then((function() {
|
|
e.loader !== i || e.stats.aborted || e.openAndSendXhr(i, r, t)
|
|
}
|
|
)).catch((function(t) {
|
|
var a;
|
|
null == (a = e.callbacks) || a.onError({
|
|
code: i.status,
|
|
text: t.message
|
|
}, r, i, n)
|
|
}
|
|
)) : this.openAndSendXhr(i, r, t)
|
|
}
|
|
}
|
|
,
|
|
t.openAndSendXhr = function(e, t, r) {
|
|
e.readyState || e.open("GET", t.url, !0);
|
|
var i = t.headers
|
|
, n = r.loadPolicy
|
|
, a = n.maxTimeToFirstByteMs
|
|
, s = n.maxLoadTimeMs;
|
|
if (i)
|
|
for (var o in i)
|
|
e.setRequestHeader(o, i[o]);
|
|
t.rangeEnd && e.setRequestHeader("Range", "bytes=" + t.rangeStart + "-" + (t.rangeEnd - 1)),
|
|
e.onreadystatechange = this.readystatechange.bind(this),
|
|
e.onprogress = this.loadprogress.bind(this),
|
|
e.responseType = t.responseType,
|
|
self.clearTimeout(this.requestTimeout),
|
|
r.timeout = a && A(a) ? a : s,
|
|
this.requestTimeout = self.setTimeout(this.loadtimeout.bind(this), r.timeout),
|
|
e.send()
|
|
}
|
|
,
|
|
t.readystatechange = function() {
|
|
var e = this.context
|
|
, t = this.loader
|
|
, r = this.stats;
|
|
if (e && t) {
|
|
var i = t.readyState
|
|
, n = this.config;
|
|
if (!r.aborted && i >= 2 && (0 === r.loading.first && (r.loading.first = Math.max(self.performance.now(), r.loading.start),
|
|
n.timeout !== n.loadPolicy.maxLoadTimeMs && (self.clearTimeout(this.requestTimeout),
|
|
n.timeout = n.loadPolicy.maxLoadTimeMs,
|
|
this.requestTimeout = self.setTimeout(this.loadtimeout.bind(this), n.loadPolicy.maxLoadTimeMs - (r.loading.first - r.loading.start)))),
|
|
4 === i)) {
|
|
self.clearTimeout(this.requestTimeout),
|
|
t.onreadystatechange = null,
|
|
t.onprogress = null;
|
|
var a = t.status
|
|
, s = "text" === t.responseType ? t.responseText : null;
|
|
if (a >= 200 && a < 300) {
|
|
var o = null != s ? s : t.response;
|
|
if (null != o) {
|
|
var l, u;
|
|
r.loading.end = Math.max(self.performance.now(), r.loading.first);
|
|
var d = "arraybuffer" === t.responseType ? o.byteLength : o.length;
|
|
r.loaded = r.total = d,
|
|
r.bwEstimate = 8e3 * r.total / (r.loading.end - r.loading.first);
|
|
var h = null == (l = this.callbacks) ? void 0 : l.onProgress;
|
|
h && h(r, e, o, t);
|
|
var f = {
|
|
url: t.responseURL,
|
|
data: o,
|
|
code: a
|
|
};
|
|
return void (null == (u = this.callbacks) || u.onSuccess(f, r, e, t))
|
|
}
|
|
}
|
|
var c, g = n.loadPolicy.errorRetry;
|
|
_t(g, r.retry, !1, {
|
|
url: e.url,
|
|
data: void 0,
|
|
code: a
|
|
}) ? this.retry(g) : (Y.error(a + " while loading " + e.url),
|
|
null == (c = this.callbacks) || c.onError({
|
|
code: a,
|
|
text: t.statusText
|
|
}, e, t, r))
|
|
}
|
|
}
|
|
}
|
|
,
|
|
t.loadtimeout = function() {
|
|
if (this.config) {
|
|
var e = this.config.loadPolicy.timeoutRetry;
|
|
if (_t(e, this.stats.retry, !0))
|
|
this.retry(e);
|
|
else {
|
|
var t;
|
|
Y.warn("timeout while loading " + (null == (t = this.context) ? void 0 : t.url));
|
|
var r = this.callbacks;
|
|
r && (this.abortInternal(),
|
|
r.onTimeout(this.stats, this.context, this.loader))
|
|
}
|
|
}
|
|
}
|
|
,
|
|
t.retry = function(e) {
|
|
var t = this.context
|
|
, r = this.stats;
|
|
this.retryDelay = bt(e, r.retry),
|
|
r.retry++,
|
|
Y.warn((status ? "HTTP Status " + status : "Timeout") + " while loading " + (null == t ? void 0 : t.url) + ", retrying " + r.retry + "/" + e.maxNumRetry + " in " + this.retryDelay + "ms"),
|
|
this.abortInternal(),
|
|
this.loader = null,
|
|
self.clearTimeout(this.retryTimeout),
|
|
this.retryTimeout = self.setTimeout(this.loadInternal.bind(this), this.retryDelay)
|
|
}
|
|
,
|
|
t.loadprogress = function(e) {
|
|
var t = this.stats;
|
|
t.loaded = e.loaded,
|
|
e.lengthComputable && (t.total = e.total)
|
|
}
|
|
,
|
|
t.getCacheAge = function() {
|
|
var e = null;
|
|
if (this.loader && dl.test(this.loader.getAllResponseHeaders())) {
|
|
var t = this.loader.getResponseHeader("age");
|
|
e = t ? parseFloat(t) : null
|
|
}
|
|
return e
|
|
}
|
|
,
|
|
t.getResponseHeader = function(e) {
|
|
return this.loader && new RegExp("^" + e + ":\\s*[\\d.]+\\s*$","im").test(this.loader.getAllResponseHeaders()) ? this.loader.getResponseHeader(e) : null
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, fl = d(d({
|
|
autoStartLoad: !0,
|
|
startPosition: -1,
|
|
defaultAudioCodec: void 0,
|
|
debug: !1,
|
|
capLevelOnFPSDrop: !1,
|
|
capLevelToPlayerSize: !1,
|
|
ignoreDevicePixelRatio: !1,
|
|
maxDevicePixelRatio: Number.POSITIVE_INFINITY,
|
|
preferManagedMediaSource: !0,
|
|
initialLiveManifestSize: 1,
|
|
maxBufferLength: 30,
|
|
backBufferLength: 1 / 0,
|
|
frontBufferFlushThreshold: 1 / 0,
|
|
startOnSegmentBoundary: !1,
|
|
maxBufferSize: 6e7,
|
|
maxFragLookUpTolerance: .25,
|
|
maxBufferHole: .1,
|
|
detectStallWithCurrentTimeMs: 1250,
|
|
highBufferWatchdogPeriod: 2,
|
|
nudgeOffset: .1,
|
|
nudgeMaxRetry: 3,
|
|
nudgeOnVideoHole: !0,
|
|
liveSyncMode: "edge",
|
|
liveSyncDurationCount: 3,
|
|
liveSyncOnStallIncrease: 1,
|
|
liveMaxLatencyDurationCount: 1 / 0,
|
|
liveSyncDuration: void 0,
|
|
liveMaxLatencyDuration: void 0,
|
|
maxLiveSyncPlaybackRate: 1,
|
|
liveDurationInfinity: !1,
|
|
liveBackBufferLength: null,
|
|
maxMaxBufferLength: 600,
|
|
enableWorker: !0,
|
|
workerPath: null,
|
|
enableSoftwareAES: !0,
|
|
startLevel: void 0,
|
|
startFragPrefetch: !1,
|
|
fpsDroppedMonitoringPeriod: 5e3,
|
|
fpsDroppedMonitoringThreshold: .2,
|
|
appendErrorMaxRetry: 3,
|
|
ignorePlaylistParsingErrors: !1,
|
|
loader: hl,
|
|
fLoader: void 0,
|
|
pLoader: void 0,
|
|
xhrSetup: void 0,
|
|
licenseXhrSetup: void 0,
|
|
licenseResponseCallback: void 0,
|
|
abrController: pt,
|
|
bufferController: La,
|
|
capLevelController: ka,
|
|
errorController: Bt,
|
|
fpsController: Bs,
|
|
stretchShortVideoTrack: !1,
|
|
maxAudioFramesDrift: 1,
|
|
forceKeyFrameOnDiscontinuity: !0,
|
|
abrEwmaFastLive: 3,
|
|
abrEwmaSlowLive: 9,
|
|
abrEwmaFastVoD: 3,
|
|
abrEwmaSlowVoD: 9,
|
|
abrEwmaDefaultEstimate: 5e5,
|
|
abrEwmaDefaultEstimateMax: 5e6,
|
|
abrBandWidthFactor: .95,
|
|
abrBandWidthUpFactor: .7,
|
|
abrMaxWithRealBitrate: !1,
|
|
maxStarvationDelay: 4,
|
|
maxLoadingDelay: 4,
|
|
minAutoBitrate: 0,
|
|
emeEnabled: !1,
|
|
widevineLicenseUrl: void 0,
|
|
drmSystems: {},
|
|
drmSystemOptions: {},
|
|
requestMediaKeySystemAccessFunc: Br,
|
|
requireKeySystemAccessOnStart: !1,
|
|
testBandwidth: !0,
|
|
progressive: !1,
|
|
lowLatencyMode: !0,
|
|
cmcd: void 0,
|
|
enableDateRangeMetadataCues: !0,
|
|
enableEmsgMetadataCues: !0,
|
|
enableEmsgKLVMetadata: !1,
|
|
enableID3MetadataCues: !0,
|
|
enableInterstitialPlayback: !0,
|
|
interstitialAppendInPlace: !0,
|
|
interstitialLiveLookAhead: 10,
|
|
useMediaCapabilities: !0,
|
|
preserveManualLevelOnError: !1,
|
|
certLoadPolicy: {
|
|
default: {
|
|
maxTimeToFirstByteMs: 8e3,
|
|
maxLoadTimeMs: 2e4,
|
|
timeoutRetry: null,
|
|
errorRetry: null
|
|
}
|
|
},
|
|
keyLoadPolicy: {
|
|
default: {
|
|
maxTimeToFirstByteMs: 8e3,
|
|
maxLoadTimeMs: 2e4,
|
|
timeoutRetry: {
|
|
maxNumRetry: 1,
|
|
retryDelayMs: 1e3,
|
|
maxRetryDelayMs: 2e4,
|
|
backoff: "linear"
|
|
},
|
|
errorRetry: {
|
|
maxNumRetry: 8,
|
|
retryDelayMs: 1e3,
|
|
maxRetryDelayMs: 2e4,
|
|
backoff: "linear"
|
|
}
|
|
}
|
|
},
|
|
manifestLoadPolicy: {
|
|
default: {
|
|
maxTimeToFirstByteMs: 1 / 0,
|
|
maxLoadTimeMs: 2e4,
|
|
timeoutRetry: {
|
|
maxNumRetry: 2,
|
|
retryDelayMs: 0,
|
|
maxRetryDelayMs: 0
|
|
},
|
|
errorRetry: {
|
|
maxNumRetry: 1,
|
|
retryDelayMs: 1e3,
|
|
maxRetryDelayMs: 8e3
|
|
}
|
|
}
|
|
},
|
|
playlistLoadPolicy: {
|
|
default: {
|
|
maxTimeToFirstByteMs: 1e4,
|
|
maxLoadTimeMs: 2e4,
|
|
timeoutRetry: {
|
|
maxNumRetry: 2,
|
|
retryDelayMs: 0,
|
|
maxRetryDelayMs: 0
|
|
},
|
|
errorRetry: {
|
|
maxNumRetry: 2,
|
|
retryDelayMs: 1e3,
|
|
maxRetryDelayMs: 8e3
|
|
}
|
|
}
|
|
},
|
|
fragLoadPolicy: {
|
|
default: {
|
|
maxTimeToFirstByteMs: 1e4,
|
|
maxLoadTimeMs: 12e4,
|
|
timeoutRetry: {
|
|
maxNumRetry: 4,
|
|
retryDelayMs: 0,
|
|
maxRetryDelayMs: 0
|
|
},
|
|
errorRetry: {
|
|
maxNumRetry: 6,
|
|
retryDelayMs: 1e3,
|
|
maxRetryDelayMs: 8e3
|
|
}
|
|
}
|
|
},
|
|
steeringManifestLoadPolicy: {
|
|
default: {
|
|
maxTimeToFirstByteMs: 1e4,
|
|
maxLoadTimeMs: 2e4,
|
|
timeoutRetry: {
|
|
maxNumRetry: 2,
|
|
retryDelayMs: 0,
|
|
maxRetryDelayMs: 0
|
|
},
|
|
errorRetry: {
|
|
maxNumRetry: 1,
|
|
retryDelayMs: 1e3,
|
|
maxRetryDelayMs: 8e3
|
|
}
|
|
}
|
|
},
|
|
interstitialAssetListLoadPolicy: {
|
|
default: {
|
|
maxTimeToFirstByteMs: 1e4,
|
|
maxLoadTimeMs: 3e4,
|
|
timeoutRetry: {
|
|
maxNumRetry: 0,
|
|
retryDelayMs: 0,
|
|
maxRetryDelayMs: 0
|
|
},
|
|
errorRetry: {
|
|
maxNumRetry: 0,
|
|
retryDelayMs: 1e3,
|
|
maxRetryDelayMs: 8e3
|
|
}
|
|
}
|
|
},
|
|
manifestLoadingTimeOut: 1e4,
|
|
manifestLoadingMaxRetry: 1,
|
|
manifestLoadingRetryDelay: 1e3,
|
|
manifestLoadingMaxRetryTimeout: 64e3,
|
|
levelLoadingTimeOut: 1e4,
|
|
levelLoadingMaxRetry: 4,
|
|
levelLoadingRetryDelay: 1e3,
|
|
levelLoadingMaxRetryTimeout: 64e3,
|
|
fragLoadingTimeOut: 2e4,
|
|
fragLoadingMaxRetry: 6,
|
|
fragLoadingRetryDelay: 1e3,
|
|
fragLoadingMaxRetryTimeout: 64e3
|
|
}, {
|
|
cueHandler: al,
|
|
enableWebVTT: !0,
|
|
enableIMSC1: !0,
|
|
enableCEA708Captions: !0,
|
|
captionsTextTrack1Label: "English",
|
|
captionsTextTrack1LanguageCode: "en",
|
|
captionsTextTrack2Label: "Spanish",
|
|
captionsTextTrack2LanguageCode: "es",
|
|
captionsTextTrack3Label: "Unknown CC",
|
|
captionsTextTrack3LanguageCode: "",
|
|
captionsTextTrack4Label: "Unknown CC",
|
|
captionsTextTrack4LanguageCode: "",
|
|
renderTextTracksNatively: !0
|
|
}), {}, {
|
|
subtitleStreamController: ro,
|
|
subtitleTrackController: uo,
|
|
timelineController: tl,
|
|
audioStreamController: ca,
|
|
audioTrackController: ya,
|
|
emeController: xs,
|
|
cmcdController: Ps,
|
|
contentSteeringController: Cs,
|
|
interstitialsController: to
|
|
});
|
|
function cl(e) {
|
|
return e && "object" == typeof e ? Array.isArray(e) ? e.map(cl) : Object.keys(e).reduce((function(t, r) {
|
|
return t[r] = cl(e[r]),
|
|
t
|
|
}
|
|
), {}) : e
|
|
}
|
|
function gl(e, t) {
|
|
var r = e.loader;
|
|
r !== ol && r !== hl ? (t.log("[config]: Custom loader detected, cannot enable progressive streaming"),
|
|
e.progressive = !1) : function() {
|
|
if (self.fetch && self.AbortController && self.ReadableStream && self.Request)
|
|
try {
|
|
return new self.ReadableStream({}),
|
|
!0
|
|
} catch (e) {}
|
|
return !1
|
|
}() && (e.loader = ol,
|
|
e.progressive = !0,
|
|
e.enableSoftwareAES = !0,
|
|
t.log("[config]: Progressive streaming enabled, using FetchLoader"))
|
|
}
|
|
var vl = function(e) {
|
|
function t(t, r) {
|
|
var i;
|
|
return (i = e.call(this, "gap-controller", t.logger) || this).hls = void 0,
|
|
i.fragmentTracker = void 0,
|
|
i.media = null,
|
|
i.mediaSource = void 0,
|
|
i.nudgeRetry = 0,
|
|
i.stallReported = !1,
|
|
i.stalled = null,
|
|
i.moved = !1,
|
|
i.seeking = !1,
|
|
i.buffered = {},
|
|
i.lastCurrentTime = 0,
|
|
i.ended = 0,
|
|
i.waiting = 0,
|
|
i.onMediaPlaying = function() {
|
|
i.ended = 0,
|
|
i.waiting = 0
|
|
}
|
|
,
|
|
i.onMediaWaiting = function() {
|
|
var e;
|
|
null != (e = i.media) && e.seeking || (i.waiting = self.performance.now(),
|
|
i.tick())
|
|
}
|
|
,
|
|
i.onMediaEnded = function() {
|
|
var e;
|
|
i.hls && (i.ended = (null == (e = i.media) ? void 0 : e.currentTime) || 1,
|
|
i.hls.trigger(b.MEDIA_ENDED, {
|
|
stalled: !1
|
|
}))
|
|
}
|
|
,
|
|
i.hls = t,
|
|
i.fragmentTracker = r,
|
|
i.registerListeners(),
|
|
i
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.registerListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.on(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.on(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.on(b.BUFFER_APPENDED, this.onBufferAppended, this))
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.off(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.off(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.off(b.BUFFER_APPENDED, this.onBufferAppended, this))
|
|
}
|
|
,
|
|
r.destroy = function() {
|
|
e.prototype.destroy.call(this),
|
|
this.unregisterListeners(),
|
|
this.media = this.hls = this.fragmentTracker = null,
|
|
this.mediaSource = void 0
|
|
}
|
|
,
|
|
r.onMediaAttached = function(e, t) {
|
|
this.setInterval(100),
|
|
this.mediaSource = t.mediaSource;
|
|
var r = this.media = t.media;
|
|
Li(r, "playing", this.onMediaPlaying),
|
|
Li(r, "waiting", this.onMediaWaiting),
|
|
Li(r, "ended", this.onMediaEnded)
|
|
}
|
|
,
|
|
r.onMediaDetaching = function(e, t) {
|
|
this.clearInterval();
|
|
var r = this.media;
|
|
r && (Ii(r, "playing", this.onMediaPlaying),
|
|
Ii(r, "waiting", this.onMediaWaiting),
|
|
Ii(r, "ended", this.onMediaEnded),
|
|
this.media = null),
|
|
this.mediaSource = void 0
|
|
}
|
|
,
|
|
r.onBufferAppended = function(e, t) {
|
|
this.buffered = t.timeRanges
|
|
}
|
|
,
|
|
r.tick = function() {
|
|
var e;
|
|
if (null != (e = this.media) && e.readyState && this.hasBuffered) {
|
|
var t = this.media.currentTime;
|
|
this.poll(t, this.lastCurrentTime),
|
|
this.lastCurrentTime = t
|
|
}
|
|
}
|
|
,
|
|
r.poll = function(e, t) {
|
|
var r, i, n = null == (r = this.hls) ? void 0 : r.config;
|
|
if (n) {
|
|
var a = this.media;
|
|
if (a) {
|
|
var s = a.seeking
|
|
, o = this.seeking && !s
|
|
, l = !this.seeking && s
|
|
, u = a.paused && !s || a.ended || 0 === a.playbackRate;
|
|
if (this.seeking = s,
|
|
e !== t)
|
|
return t && (this.ended = 0),
|
|
this.moved = !0,
|
|
s || (this.nudgeRetry = 0,
|
|
n.nudgeOnVideoHole && !u && e > t && this.nudgeOnVideoHole(e, t)),
|
|
void (0 === this.waiting && this.stallResolved(e));
|
|
if (l || o)
|
|
o && this.stallResolved(e);
|
|
else {
|
|
if (u)
|
|
return this.nudgeRetry = 0,
|
|
this.stallResolved(e),
|
|
void (!this.ended && a.ended && this.hls && (this.ended = e || 1,
|
|
this.hls.trigger(b.MEDIA_ENDED, {
|
|
stalled: !1
|
|
})));
|
|
if (ur.getBuffered(a).length) {
|
|
var d = ur.bufferInfo(a, e, 0)
|
|
, h = d.nextStart || 0
|
|
, f = this.fragmentTracker;
|
|
if (s && f && this.hls) {
|
|
var c = ml(this.hls.inFlightFragments, e)
|
|
, g = d.len > 2
|
|
, v = !h || c || h - e > 2 && !f.getPartialFragment(e);
|
|
if (g || v)
|
|
return;
|
|
this.moved = !1
|
|
}
|
|
var m = null == (i = this.hls) ? void 0 : i.latestLevelDetails;
|
|
if (!this.moved && null !== this.stalled && f) {
|
|
if (!(d.len > 0 || h))
|
|
return;
|
|
var p = Math.max(h, d.start || 0) - e
|
|
, y = null != m && m.live ? 2 * m.targetduration : 2
|
|
, E = yl(e, f);
|
|
if (p > 0 && (p <= y || E))
|
|
return void (a.paused || this._trySkipBufferHole(E))
|
|
}
|
|
var T = n.detectStallWithCurrentTimeMs
|
|
, S = self.performance.now()
|
|
, A = this.waiting
|
|
, L = this.stalled;
|
|
if (null === L) {
|
|
if (!(A > 0 && S - A < T))
|
|
return void (this.stalled = S);
|
|
L = this.stalled = A
|
|
}
|
|
var I = S - L;
|
|
if (!s && (I >= T || A) && this.hls) {
|
|
var R;
|
|
if ("ended" === (null == (R = this.mediaSource) ? void 0 : R.readyState) && (null == m || !m.live) && Math.abs(e - ((null == m ? void 0 : m.edge) || 0)) < 1) {
|
|
if (this.ended)
|
|
return;
|
|
return this.ended = e || 1,
|
|
void this.hls.trigger(b.MEDIA_ENDED, {
|
|
stalled: !0
|
|
})
|
|
}
|
|
if (this._reportStall(d),
|
|
!this.media || !this.hls)
|
|
return
|
|
}
|
|
var k = ur.bufferInfo(a, e, n.maxBufferHole);
|
|
this._tryFixBufferStall(k, I, e)
|
|
} else
|
|
this.nudgeRetry = 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.stallResolved = function(e) {
|
|
var t = this.stalled;
|
|
if (t && this.hls && (this.stalled = null,
|
|
this.stallReported)) {
|
|
var r = self.performance.now() - t;
|
|
this.log("playback not stuck anymore @" + e + ", after " + Math.round(r) + "ms"),
|
|
this.stallReported = !1,
|
|
this.waiting = 0,
|
|
this.hls.trigger(b.STALL_RESOLVED, {})
|
|
}
|
|
}
|
|
,
|
|
r.nudgeOnVideoHole = function(e, t) {
|
|
var r, i = this.buffered.video;
|
|
if (this.hls && this.media && this.fragmentTracker && null != (r = this.buffered.audio) && r.length && i && i.length > 1 && e > i.end(0)) {
|
|
var n = ur.bufferedInfo(ur.timeRangesToArray(this.buffered.audio), e, 0);
|
|
if (n.len > 1 && t >= n.start) {
|
|
var a = ur.timeRangesToArray(i)
|
|
, s = ur.bufferedInfo(a, t, 0).bufferedIndex;
|
|
if (s > -1 && s < a.length - 1) {
|
|
var o = ur.bufferedInfo(a, e, 0).bufferedIndex
|
|
, l = a[s].end
|
|
, u = a[s + 1].start;
|
|
if ((-1 === o || o > s) && u - l < 1 && e - l < 2) {
|
|
var d = new Error("nudging playhead to flush pipeline after video hole. currentTime: " + e + " hole: " + l + " -> " + u + " buffered index: " + o);
|
|
this.warn(d.message),
|
|
this.media.currentTime += 1e-6;
|
|
var h = yl(e, this.fragmentTracker);
|
|
h && "fragment"in h ? h = h.fragment : h || (h = void 0);
|
|
var f = ur.bufferInfo(this.media, e, 0);
|
|
this.hls.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.BUFFER_SEEK_OVER_HOLE,
|
|
fatal: !1,
|
|
error: d,
|
|
reason: d.message,
|
|
frag: h,
|
|
buffer: f.len,
|
|
bufferInfo: f
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r._tryFixBufferStall = function(e, t, r) {
|
|
var i, n, a = this.fragmentTracker, s = this.media, o = null == (i = this.hls) ? void 0 : i.config;
|
|
if (s && a && o) {
|
|
var l = null == (n = this.hls) ? void 0 : n.latestLevelDetails
|
|
, u = yl(r, a);
|
|
if ((u || null != l && l.live && r < l.fragmentStart) && (this._trySkipBufferHole(u) || !this.media))
|
|
return;
|
|
var d = e.buffered
|
|
, h = this.adjacentTraversal(e, r);
|
|
(d && d.length > 1 && e.len > o.maxBufferHole || e.nextStart && (e.nextStart - r < o.maxBufferHole || h)) && (t > 1e3 * o.highBufferWatchdogPeriod || this.waiting) && (this.warn("Trying to nudge playhead over buffer-hole"),
|
|
this._tryNudgeBuffer(e))
|
|
}
|
|
}
|
|
,
|
|
r.adjacentTraversal = function(e, t) {
|
|
var r = this.fragmentTracker
|
|
, i = e.nextStart;
|
|
if (r && i) {
|
|
var n = r.getFragAtPos(t, w)
|
|
, a = r.getFragAtPos(i, w);
|
|
if (n && a)
|
|
return a.sn - n.sn < 2
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
r._reportStall = function(e) {
|
|
var t = this.hls
|
|
, r = this.media
|
|
, i = this.stallReported
|
|
, n = this.stalled;
|
|
if (!i && null !== n && r && t) {
|
|
this.stallReported = !0;
|
|
var a = new Error("Playback stalling at @" + r.currentTime + " due to low buffer (" + lt(e) + ")");
|
|
this.warn(a.message),
|
|
t.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.BUFFER_STALLED_ERROR,
|
|
fatal: !1,
|
|
error: a,
|
|
buffer: e.len,
|
|
bufferInfo: e,
|
|
stalled: {
|
|
start: n
|
|
}
|
|
})
|
|
}
|
|
}
|
|
,
|
|
r._trySkipBufferHole = function(e) {
|
|
var t, r = this.fragmentTracker, i = this.media, n = null == (t = this.hls) ? void 0 : t.config;
|
|
if (!i || !r || !n)
|
|
return 0;
|
|
var a = i.currentTime
|
|
, s = ur.bufferInfo(i, a, 0)
|
|
, o = a < s.start ? s.start : s.nextStart;
|
|
if (o && this.hls) {
|
|
var l = s.len <= n.maxBufferHole
|
|
, u = s.len > 0 && s.len < 1 && i.readyState < 3
|
|
, d = o - a;
|
|
if (d > 0 && (l || u)) {
|
|
if (d > n.maxBufferHole) {
|
|
var h = !1;
|
|
if (0 === a) {
|
|
var f = r.getAppendedFrag(0, w);
|
|
f && o < f.end && (h = !0)
|
|
}
|
|
if (!h && e) {
|
|
var c;
|
|
if (null == (c = this.hls.loadLevelObj) || !c.details)
|
|
return 0;
|
|
if (ml(this.hls.inFlightFragments, o))
|
|
return 0;
|
|
for (var g = !1, v = e.end; v < o; ) {
|
|
var m = yl(v, r);
|
|
if (!m) {
|
|
g = !0;
|
|
break
|
|
}
|
|
v += m.duration
|
|
}
|
|
if (g)
|
|
return 0
|
|
}
|
|
}
|
|
var p = Math.max(o + .05, a + .1);
|
|
if (this.warn("skipping hole, adjusting currentTime from " + a + " to " + p),
|
|
this.moved = !0,
|
|
i.currentTime = p,
|
|
null == e || !e.gap) {
|
|
var y = new Error("fragment loaded with buffer holes, seeking from " + a + " to " + p)
|
|
, E = {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.BUFFER_SEEK_OVER_HOLE,
|
|
fatal: !1,
|
|
error: y,
|
|
reason: y.message,
|
|
buffer: s.len,
|
|
bufferInfo: s
|
|
};
|
|
e && ("fragment"in e ? E.part = e : E.frag = e),
|
|
this.hls.trigger(b.ERROR, E)
|
|
}
|
|
return p
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
,
|
|
r._tryNudgeBuffer = function(e) {
|
|
var t = this.hls
|
|
, r = this.media
|
|
, i = this.nudgeRetry
|
|
, n = null == t ? void 0 : t.config;
|
|
if (!r || !n)
|
|
return 0;
|
|
var a = r.currentTime;
|
|
if (this.nudgeRetry++,
|
|
i < n.nudgeMaxRetry) {
|
|
var s = a + (i + 1) * n.nudgeOffset
|
|
, o = new Error("Nudging 'currentTime' from " + a + " to " + s);
|
|
this.warn(o.message),
|
|
r.currentTime = s,
|
|
t.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.BUFFER_NUDGE_ON_STALL,
|
|
error: o,
|
|
fatal: !1,
|
|
buffer: e.len,
|
|
bufferInfo: e
|
|
})
|
|
} else {
|
|
var l = new Error("Playhead still not moving while enough data buffered @" + a + " after " + n.nudgeMaxRetry + " nudges");
|
|
this.error(l.message),
|
|
t.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.BUFFER_STALLED_ERROR,
|
|
error: l,
|
|
fatal: !0,
|
|
buffer: e.len,
|
|
bufferInfo: e
|
|
})
|
|
}
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "hasBuffered",
|
|
get: function() {
|
|
return Object.keys(this.buffered).length > 0
|
|
}
|
|
}])
|
|
}(sr);
|
|
function ml(e, t) {
|
|
var r = pl(e.main);
|
|
if (r && r.start <= t)
|
|
return r;
|
|
var i = pl(e.audio);
|
|
return i && i.start <= t ? i : null
|
|
}
|
|
function pl(e) {
|
|
if (!e)
|
|
return null;
|
|
switch (e.state) {
|
|
case ki.IDLE:
|
|
case ki.STOPPED:
|
|
case ki.ENDED:
|
|
case ki.ERROR:
|
|
return null
|
|
}
|
|
return e.frag
|
|
}
|
|
function yl(e, t) {
|
|
return t.getAppendedFrag(e, w) || t.getPartialFragment(e)
|
|
}
|
|
function El() {
|
|
if ("undefined" != typeof self)
|
|
return self.VTTCue || self.TextTrackCue
|
|
}
|
|
function Tl(e, t, r, i, n) {
|
|
var a = new e(t,r,"");
|
|
try {
|
|
a.value = i,
|
|
n && (a.type = n)
|
|
} catch (s) {
|
|
a = new e(t,r,lt(n ? d({
|
|
type: n
|
|
}, i) : i))
|
|
}
|
|
return a
|
|
}
|
|
var Sl = function() {
|
|
var e = El();
|
|
try {
|
|
e && new e(0,Number.POSITIVE_INFINITY,"")
|
|
} catch (e) {
|
|
return Number.MAX_VALUE
|
|
}
|
|
return Number.POSITIVE_INFINITY
|
|
}()
|
|
, Al = function() {
|
|
function e(e) {
|
|
var t = this;
|
|
this.hls = void 0,
|
|
this.id3Track = null,
|
|
this.media = null,
|
|
this.dateRangeCuesAppended = {},
|
|
this.removeCues = !0,
|
|
this.assetCue = void 0,
|
|
this.onEventCueEnter = function() {
|
|
t.hls && t.hls.trigger(b.EVENT_CUE_ENTER, {})
|
|
}
|
|
,
|
|
this.hls = e,
|
|
this._registerListeners()
|
|
}
|
|
var t = e.prototype;
|
|
return t.destroy = function() {
|
|
this._unregisterListeners(),
|
|
this.id3Track = null,
|
|
this.media = null,
|
|
this.dateRangeCuesAppended = {},
|
|
this.hls = this.onEventCueEnter = null
|
|
}
|
|
,
|
|
t._registerListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.on(b.MEDIA_ATTACHING, this.onMediaAttaching, this),
|
|
e.on(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.on(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.FRAG_PARSING_METADATA, this.onFragParsingMetadata, this),
|
|
e.on(b.BUFFER_FLUSHING, this.onBufferFlushing, this),
|
|
e.on(b.LEVEL_UPDATED, this.onLevelUpdated, this),
|
|
e.on(b.LEVEL_PTS_UPDATED, this.onLevelPtsUpdated, this))
|
|
}
|
|
,
|
|
t._unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.off(b.MEDIA_ATTACHING, this.onMediaAttaching, this),
|
|
e.off(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.off(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.FRAG_PARSING_METADATA, this.onFragParsingMetadata, this),
|
|
e.off(b.BUFFER_FLUSHING, this.onBufferFlushing, this),
|
|
e.off(b.LEVEL_UPDATED, this.onLevelUpdated, this),
|
|
e.off(b.LEVEL_PTS_UPDATED, this.onLevelPtsUpdated, this))
|
|
}
|
|
,
|
|
t.onMediaAttaching = function(e, t) {
|
|
var r;
|
|
this.media = t.media,
|
|
!1 === (null == (r = t.overrides) ? void 0 : r.cueRemoval) && (this.removeCues = !1)
|
|
}
|
|
,
|
|
t.onMediaAttached = function() {
|
|
var e, t = null == (e = this.hls) ? void 0 : e.latestLevelDetails;
|
|
t && this.updateDateRangeCues(t)
|
|
}
|
|
,
|
|
t.onMediaDetaching = function(e, t) {
|
|
this.media = null,
|
|
t.transferMedia || (this.id3Track && (this.removeCues && so(this.id3Track, this.onEventCueEnter),
|
|
this.id3Track = null),
|
|
this.dateRangeCuesAppended = {})
|
|
}
|
|
,
|
|
t.onManifestLoading = function() {
|
|
this.dateRangeCuesAppended = {}
|
|
}
|
|
,
|
|
t.createTrack = function(e) {
|
|
var t = this.getID3Track(e.textTracks);
|
|
return t.mode = "hidden",
|
|
t
|
|
}
|
|
,
|
|
t.getID3Track = function(e) {
|
|
if (this.media) {
|
|
for (var t = 0; t < e.length; t++) {
|
|
var r = e[t];
|
|
if ("metadata" === r.kind && "id3" === r.label)
|
|
return no(r, this.media),
|
|
r
|
|
}
|
|
return this.media.addTextTrack("metadata", "id3")
|
|
}
|
|
}
|
|
,
|
|
t.onFragParsingMetadata = function(e, t) {
|
|
if (this.media && this.hls) {
|
|
var r = this.hls.config
|
|
, i = r.enableEmsgMetadataCues
|
|
, n = r.enableID3MetadataCues;
|
|
if (i || n) {
|
|
var a = t.samples;
|
|
this.id3Track || (this.id3Track = this.createTrack(this.media));
|
|
var s = El();
|
|
if (s)
|
|
for (var o = 0; o < a.length; o++) {
|
|
var l = a[o].type;
|
|
if ((l !== Ji.emsg || i) && n) {
|
|
var u = Qi(a[o].data)
|
|
, d = a[o].pts
|
|
, h = d + a[o].duration;
|
|
h > Sl && (h = Sl),
|
|
h - d <= 0 && (h = d + .25);
|
|
for (var f = 0; f < u.length; f++) {
|
|
var c = u[f];
|
|
if (!zi(c)) {
|
|
this.updateId3CueEnds(d, l);
|
|
var g = Tl(s, d, h, c, l);
|
|
g && this.id3Track.addCue(g)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
t.updateId3CueEnds = function(e, t) {
|
|
var r, i = null == (r = this.id3Track) ? void 0 : r.cues;
|
|
if (i)
|
|
for (var n = i.length; n--; ) {
|
|
var a = i[n];
|
|
a.type === t && a.startTime < e && a.endTime === Sl && (a.endTime = e)
|
|
}
|
|
}
|
|
,
|
|
t.onBufferFlushing = function(e, t) {
|
|
var r = t.startOffset
|
|
, i = t.endOffset
|
|
, n = t.type
|
|
, a = this.id3Track
|
|
, s = this.hls;
|
|
if (s) {
|
|
var o = s.config
|
|
, l = o.enableEmsgMetadataCues
|
|
, u = o.enableID3MetadataCues;
|
|
a && (l || u) && oo(a, r, i, "audio" === n ? function(e) {
|
|
return e.type === Ji.audioId3 && u
|
|
}
|
|
: "video" === n ? function(e) {
|
|
return e.type === Ji.emsg && l
|
|
}
|
|
: function(e) {
|
|
return e.type === Ji.audioId3 && u || e.type === Ji.emsg && l
|
|
}
|
|
)
|
|
}
|
|
}
|
|
,
|
|
t.onLevelUpdated = function(e, t) {
|
|
var r = t.details;
|
|
this.updateDateRangeCues(r, !0)
|
|
}
|
|
,
|
|
t.onLevelPtsUpdated = function(e, t) {
|
|
Math.abs(t.drift) > .01 && this.updateDateRangeCues(t.details)
|
|
}
|
|
,
|
|
t.updateDateRangeCues = function(e, t) {
|
|
var r = this;
|
|
if (this.hls && this.media) {
|
|
var i = this.hls.config
|
|
, n = i.assetPlayerId
|
|
, a = i.timelineOffset
|
|
, s = i.enableDateRangeMetadataCues
|
|
, o = i.interstitialsController;
|
|
if (s) {
|
|
var l = El();
|
|
if (n && a && !o) {
|
|
var u = e.fragmentStart
|
|
, d = e.fragmentEnd
|
|
, h = this.assetCue;
|
|
h ? (h.startTime = u,
|
|
h.endTime = d) : l && (h = this.assetCue = Tl(l, u, d, {
|
|
assetPlayerId: this.hls.config.assetPlayerId
|
|
}, "hlsjs.interstitial.asset")) && (h.id = n,
|
|
this.id3Track || (this.id3Track = this.createTrack(this.media)),
|
|
this.id3Track.addCue(h),
|
|
h.addEventListener("enter", this.onEventCueEnter))
|
|
}
|
|
if (e.hasProgramDateTime) {
|
|
var f, c = this.id3Track, g = e.dateRanges, v = Object.keys(g), m = this.dateRangeCuesAppended;
|
|
if (c && t)
|
|
if (null != (f = c.cues) && f.length)
|
|
for (var p = Object.keys(m).filter((function(e) {
|
|
return !v.includes(e)
|
|
}
|
|
)), y = function() {
|
|
var e, t = p[E], i = null == (e = m[t]) ? void 0 : e.cues;
|
|
delete m[t],
|
|
i && Object.keys(i).forEach((function(e) {
|
|
var t = i[e];
|
|
if (t) {
|
|
t.removeEventListener("enter", r.onEventCueEnter);
|
|
try {
|
|
c.removeCue(t)
|
|
} catch (e) {}
|
|
}
|
|
}
|
|
))
|
|
}, E = p.length; E--; )
|
|
y();
|
|
else
|
|
m = this.dateRangeCuesAppended = {};
|
|
var T = e.fragments[e.fragments.length - 1];
|
|
if (0 !== v.length && A(null == T ? void 0 : T.programDateTime)) {
|
|
this.id3Track || (this.id3Track = this.createTrack(this.media));
|
|
for (var S = function() {
|
|
var e = v[L]
|
|
, t = g[e]
|
|
, i = t.startTime
|
|
, n = m[e]
|
|
, a = (null == n ? void 0 : n.cues) || {}
|
|
, s = (null == n ? void 0 : n.durationKnown) || !1
|
|
, u = Sl
|
|
, d = t.duration;
|
|
if (t.endDate && null !== d)
|
|
u = i + d,
|
|
s = !0;
|
|
else if (t.endOnNext && !s) {
|
|
var h = v.reduce((function(e, r) {
|
|
if (r !== t.id) {
|
|
var i = g[r];
|
|
if (i.class === t.class && i.startDate > t.startDate && (!e || t.startDate < e.startDate))
|
|
return i
|
|
}
|
|
return e
|
|
}
|
|
), null);
|
|
h && (u = h.startTime,
|
|
s = !0)
|
|
}
|
|
for (var f, c = Object.keys(t.attr), p = 0; p < c.length; p++) {
|
|
var y = c[p];
|
|
if ("ID" !== (f = y) && "CLASS" !== f && "CUE" !== f && "START-DATE" !== f && "DURATION" !== f && "END-DATE" !== f && "END-ON-NEXT" !== f) {
|
|
var E = a[y];
|
|
if (E)
|
|
!s || null != n && n.durationKnown ? Math.abs(E.startTime - i) > .01 && (E.startTime = i,
|
|
E.endTime = u) : E.endTime = u;
|
|
else if (l) {
|
|
var T = t.attr[y];
|
|
yr(y) && (T = Q(T));
|
|
var S = Tl(l, i, u, {
|
|
key: y,
|
|
data: T
|
|
}, Ji.dateRange);
|
|
S && (S.id = e,
|
|
r.id3Track.addCue(S),
|
|
a[y] = S,
|
|
o && ("X-ASSET-LIST" !== y && "X-ASSET-URL" !== y || S.addEventListener("enter", r.onEventCueEnter)))
|
|
}
|
|
}
|
|
}
|
|
m[e] = {
|
|
cues: a,
|
|
dateRange: t,
|
|
durationKnown: s
|
|
}
|
|
}, L = 0; L < v.length; L++)
|
|
S()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, Ll = function() {
|
|
function e(e) {
|
|
var t = this;
|
|
this.hls = void 0,
|
|
this.config = void 0,
|
|
this.media = null,
|
|
this.currentTime = 0,
|
|
this.stallCount = 0,
|
|
this._latency = null,
|
|
this._targetLatencyUpdated = !1,
|
|
this.onTimeupdate = function() {
|
|
var e = t.media
|
|
, r = t.levelDetails;
|
|
if (e && r) {
|
|
t.currentTime = e.currentTime;
|
|
var i = t.computeLatency();
|
|
if (null !== i) {
|
|
t._latency = i;
|
|
var n = t.config
|
|
, a = n.lowLatencyMode
|
|
, s = n.maxLiveSyncPlaybackRate;
|
|
if (a && 1 !== s && r.live) {
|
|
var o = t.targetLatency;
|
|
if (null !== o) {
|
|
var l = i - o;
|
|
if (l < Math.min(t.maxLatency, o + r.targetduration) && l > .05 && t.forwardBufferLength > 1) {
|
|
var u = Math.min(2, Math.max(1, s))
|
|
, d = Math.round(2 / (1 + Math.exp(-.75 * l - t.edgeStalled)) * 20) / 20
|
|
, h = Math.min(u, Math.max(1, d));
|
|
t.changeMediaPlaybackRate(e, h)
|
|
} else
|
|
1 !== e.playbackRate && 0 !== e.playbackRate && t.changeMediaPlaybackRate(e, 1)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
this.hls = e,
|
|
this.config = e.config,
|
|
this.registerListeners()
|
|
}
|
|
var t = e.prototype;
|
|
return t.destroy = function() {
|
|
this.unregisterListeners(),
|
|
this.onMediaDetaching(),
|
|
this.hls = null
|
|
}
|
|
,
|
|
t.registerListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.on(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.on(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.LEVEL_UPDATED, this.onLevelUpdated, this),
|
|
e.on(b.ERROR, this.onError, this))
|
|
}
|
|
,
|
|
t.unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e && (e.off(b.MEDIA_ATTACHED, this.onMediaAttached, this),
|
|
e.off(b.MEDIA_DETACHING, this.onMediaDetaching, this),
|
|
e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.LEVEL_UPDATED, this.onLevelUpdated, this),
|
|
e.off(b.ERROR, this.onError, this))
|
|
}
|
|
,
|
|
t.onMediaAttached = function(e, t) {
|
|
this.media = t.media,
|
|
this.media.addEventListener("timeupdate", this.onTimeupdate)
|
|
}
|
|
,
|
|
t.onMediaDetaching = function() {
|
|
this.media && (this.media.removeEventListener("timeupdate", this.onTimeupdate),
|
|
this.media = null)
|
|
}
|
|
,
|
|
t.onManifestLoading = function() {
|
|
this._latency = null,
|
|
this.stallCount = 0
|
|
}
|
|
,
|
|
t.onLevelUpdated = function(e, t) {
|
|
var r = t.details;
|
|
r.advanced && this.onTimeupdate(),
|
|
!r.live && this.media && this.media.removeEventListener("timeupdate", this.onTimeupdate)
|
|
}
|
|
,
|
|
t.onError = function(e, t) {
|
|
var r;
|
|
t.details === k.BUFFER_STALLED_ERROR && (this.stallCount++,
|
|
this.hls && null != (r = this.levelDetails) && r.live && this.hls.logger.warn("[latency-controller]: Stall detected, adjusting target latency"))
|
|
}
|
|
,
|
|
t.changeMediaPlaybackRate = function(e, t) {
|
|
var r, i;
|
|
e.playbackRate !== t && (null == (r = this.hls) || r.logger.debug("[latency-controller]: latency=" + this.latency.toFixed(3) + ", targetLatency=" + (null == (i = this.targetLatency) ? void 0 : i.toFixed(3)) + ", forwardBufferLength=" + this.forwardBufferLength.toFixed(3) + ": adjusting playback rate from " + e.playbackRate + " to " + t),
|
|
e.playbackRate = t)
|
|
}
|
|
,
|
|
t.estimateLiveEdge = function() {
|
|
var e = this.levelDetails;
|
|
return null === e ? null : e.edge + e.age
|
|
}
|
|
,
|
|
t.computeLatency = function() {
|
|
var e = this.estimateLiveEdge();
|
|
return null === e ? null : e - this.currentTime
|
|
}
|
|
,
|
|
i(e, [{
|
|
key: "levelDetails",
|
|
get: function() {
|
|
var e;
|
|
return (null == (e = this.hls) ? void 0 : e.latestLevelDetails) || null
|
|
}
|
|
}, {
|
|
key: "latency",
|
|
get: function() {
|
|
return this._latency || 0
|
|
}
|
|
}, {
|
|
key: "maxLatency",
|
|
get: function() {
|
|
var e = this.config;
|
|
if (void 0 !== e.liveMaxLatencyDuration)
|
|
return e.liveMaxLatencyDuration;
|
|
var t = this.levelDetails;
|
|
return t ? e.liveMaxLatencyDurationCount * t.targetduration : 0
|
|
}
|
|
}, {
|
|
key: "targetLatency",
|
|
get: function() {
|
|
var e = this.levelDetails;
|
|
if (null === e || null === this.hls)
|
|
return null;
|
|
var t = e.holdBack
|
|
, r = e.partHoldBack
|
|
, i = e.targetduration
|
|
, n = this.config
|
|
, a = n.liveSyncDuration
|
|
, s = n.liveSyncDurationCount
|
|
, o = n.lowLatencyMode
|
|
, l = this.hls.userConfig
|
|
, u = o && r || t;
|
|
(this._targetLatencyUpdated || l.liveSyncDuration || l.liveSyncDurationCount || 0 === u) && (u = void 0 !== a ? a : s * i);
|
|
var d = i;
|
|
return u + Math.min(this.stallCount * this.config.liveSyncOnStallIncrease, d)
|
|
},
|
|
set: function(e) {
|
|
this.stallCount = 0,
|
|
this.config.liveSyncDuration = e,
|
|
this._targetLatencyUpdated = !0
|
|
}
|
|
}, {
|
|
key: "liveSyncPosition",
|
|
get: function() {
|
|
var e = this.estimateLiveEdge()
|
|
, t = this.targetLatency;
|
|
if (null === e || null === t)
|
|
return null;
|
|
var r = this.levelDetails;
|
|
if (null === r)
|
|
return null;
|
|
var i = r.edge
|
|
, n = e - t - this.edgeStalled
|
|
, a = i - r.totalduration
|
|
, s = i - (this.config.lowLatencyMode && r.partTarget || r.targetduration);
|
|
return Math.min(Math.max(a, n), s)
|
|
}
|
|
}, {
|
|
key: "drift",
|
|
get: function() {
|
|
var e = this.levelDetails;
|
|
return null === e ? 1 : e.drift
|
|
}
|
|
}, {
|
|
key: "edgeStalled",
|
|
get: function() {
|
|
var e = this.levelDetails;
|
|
if (null === e)
|
|
return 0;
|
|
var t = 3 * (this.config.lowLatencyMode && e.partTarget || e.targetduration);
|
|
return Math.max(e.age - t, 0)
|
|
}
|
|
}, {
|
|
key: "forwardBufferLength",
|
|
get: function() {
|
|
var e = this.media
|
|
, t = this.levelDetails;
|
|
if (!e || !t)
|
|
return 0;
|
|
var r = e.buffered.length;
|
|
return (r ? e.buffered.end(r - 1) : t.edge) - this.currentTime
|
|
}
|
|
}])
|
|
}()
|
|
, Il = function(e) {
|
|
function t(t, r) {
|
|
var i;
|
|
return (i = e.call(this, t, "level-controller") || this)._levels = [],
|
|
i._firstLevel = -1,
|
|
i._maxAutoLevel = -1,
|
|
i._startLevel = void 0,
|
|
i.currentLevel = null,
|
|
i.currentLevelIndex = -1,
|
|
i.manualLevelIndex = -1,
|
|
i.steering = void 0,
|
|
i.onParsedComplete = void 0,
|
|
i.steering = r,
|
|
i._registerListeners(),
|
|
i
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r._registerListeners = function() {
|
|
var e = this.hls;
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.MANIFEST_LOADED, this.onManifestLoaded, this),
|
|
e.on(b.LEVEL_LOADED, this.onLevelLoaded, this),
|
|
e.on(b.LEVELS_UPDATED, this.onLevelsUpdated, this),
|
|
e.on(b.FRAG_BUFFERED, this.onFragBuffered, this),
|
|
e.on(b.ERROR, this.onError, this)
|
|
}
|
|
,
|
|
r._unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.MANIFEST_LOADED, this.onManifestLoaded, this),
|
|
e.off(b.LEVEL_LOADED, this.onLevelLoaded, this),
|
|
e.off(b.LEVELS_UPDATED, this.onLevelsUpdated, this),
|
|
e.off(b.FRAG_BUFFERED, this.onFragBuffered, this),
|
|
e.off(b.ERROR, this.onError, this)
|
|
}
|
|
,
|
|
r.destroy = function() {
|
|
this._unregisterListeners(),
|
|
this.steering = null,
|
|
this.resetLevels(),
|
|
e.prototype.destroy.call(this)
|
|
}
|
|
,
|
|
r.stopLoad = function() {
|
|
this._levels.forEach((function(e) {
|
|
e.loadError = 0,
|
|
e.fragmentError = 0
|
|
}
|
|
)),
|
|
e.prototype.stopLoad.call(this)
|
|
}
|
|
,
|
|
r.resetLevels = function() {
|
|
this._startLevel = void 0,
|
|
this.manualLevelIndex = -1,
|
|
this.currentLevelIndex = -1,
|
|
this.currentLevel = null,
|
|
this._levels = [],
|
|
this._maxAutoLevel = -1
|
|
}
|
|
,
|
|
r.onManifestLoading = function(e, t) {
|
|
this.resetLevels()
|
|
}
|
|
,
|
|
r.onManifestLoaded = function(e, t) {
|
|
var r = this
|
|
, i = this.hls.config.preferManagedMediaSource
|
|
, n = []
|
|
, a = {}
|
|
, s = {}
|
|
, o = !1
|
|
, l = !1
|
|
, u = !1;
|
|
t.levels.forEach((function(e) {
|
|
var t = e.attrs
|
|
, d = e.audioCodec
|
|
, h = e.videoCodec;
|
|
d && (e.audioCodec = d = Ge(d, i) || void 0),
|
|
h && (h = e.videoCodec = function(e) {
|
|
for (var t = e.split(","), r = 0; r < t.length; r++) {
|
|
var i = t[r].split(".");
|
|
i.length > 2 && "avc1" === i[0] && (t[r] = "avc1." + parseInt(i[1]).toString(16) + ("000" + parseInt(i[2]).toString(16)).slice(-4))
|
|
}
|
|
return t.join(",")
|
|
}(h));
|
|
var f = e.width
|
|
, c = e.height
|
|
, g = e.unknownCodecs
|
|
, v = (null == g ? void 0 : g.length) || 0;
|
|
if (o || (o = !(!f || !c)),
|
|
l || (l = !!h),
|
|
u || (u = !!d),
|
|
v || d && !r.isAudioSupported(d) || h && !r.isVideoSupported(h))
|
|
r.log('Some or all CODECS not supported "' + t.CODECS + '"');
|
|
else {
|
|
var m = t.CODECS
|
|
, p = t["FRAME-RATE"]
|
|
, y = t["HDCP-LEVEL"]
|
|
, E = t["PATHWAY-ID"]
|
|
, T = t.RESOLUTION
|
|
, S = t["VIDEO-RANGE"]
|
|
, A = (E || ".") + "-" + e.bitrate + "-" + T + "-" + p + "-" + m + "-" + S + "-" + y;
|
|
if (a[A])
|
|
if (a[A].uri === e.url || e.attrs["PATHWAY-ID"])
|
|
a[A].addGroupId("audio", t.AUDIO),
|
|
a[A].addGroupId("text", t.SUBTITLES);
|
|
else {
|
|
var L = s[A] += 1;
|
|
e.attrs["PATHWAY-ID"] = new Array(L + 1).join(".");
|
|
var I = r.createLevel(e);
|
|
a[A] = I,
|
|
n.push(I)
|
|
}
|
|
else {
|
|
var R = r.createLevel(e);
|
|
a[A] = R,
|
|
s[A] = 1,
|
|
n.push(R)
|
|
}
|
|
}
|
|
}
|
|
)),
|
|
this.filterAndSortMediaOptions(n, t, o, l, u)
|
|
}
|
|
,
|
|
r.createLevel = function(e) {
|
|
var t = new at(e)
|
|
, r = e.supplemental;
|
|
if (null != r && r.videoCodec && !this.isVideoSupported(r.videoCodec)) {
|
|
var i = new Error('SUPPLEMENTAL-CODECS not supported "' + r.videoCodec + '"');
|
|
this.log(i.message),
|
|
t.supportedResult = Xe(i, [])
|
|
}
|
|
return t
|
|
}
|
|
,
|
|
r.isAudioSupported = function(e) {
|
|
return Oe(e, "audio", this.hls.config.preferManagedMediaSource)
|
|
}
|
|
,
|
|
r.isVideoSupported = function(e) {
|
|
return Oe(e, "video", this.hls.config.preferManagedMediaSource)
|
|
}
|
|
,
|
|
r.filterAndSortMediaOptions = function(e, t, r, i, n) {
|
|
var a, s = this, o = [], l = [], u = e, d = (null == (a = t.stats) ? void 0 : a.parsing) || {};
|
|
if ((r || i) && n && (u = u.filter((function(e) {
|
|
var t, r = e.videoCodec, i = e.videoRange, n = e.width, a = e.height;
|
|
return (!!r || !(!n || !a)) && !!(t = i) && Je.indexOf(t) > -1
|
|
}
|
|
))),
|
|
0 === u.length)
|
|
return Promise.resolve().then((function() {
|
|
if (s.hls) {
|
|
var e = "no level with compatible codecs found in manifest"
|
|
, r = e;
|
|
t.levels.length && (r = "one or more CODECS in variant not supported: " + lt(t.levels.map((function(e) {
|
|
return e.attrs.CODECS
|
|
}
|
|
)).filter((function(e, t, r) {
|
|
return r.indexOf(e) === t
|
|
}
|
|
))),
|
|
s.warn(r),
|
|
e += " (" + r + ")");
|
|
var i = new Error(e);
|
|
s.hls.trigger(b.ERROR, {
|
|
type: R.MEDIA_ERROR,
|
|
details: k.MANIFEST_INCOMPATIBLE_CODECS_ERROR,
|
|
fatal: !0,
|
|
url: t.url,
|
|
error: i,
|
|
reason: r
|
|
})
|
|
}
|
|
}
|
|
)),
|
|
void (d.end = performance.now());
|
|
t.audioTracks && Rl(o = t.audioTracks.filter((function(e) {
|
|
return !e.audioCodec || s.isAudioSupported(e.audioCodec)
|
|
}
|
|
))),
|
|
t.subtitles && Rl(l = t.subtitles);
|
|
var h = u.slice(0);
|
|
u.sort((function(e, t) {
|
|
if (e.attrs["HDCP-LEVEL"] !== t.attrs["HDCP-LEVEL"])
|
|
return (e.attrs["HDCP-LEVEL"] || "") > (t.attrs["HDCP-LEVEL"] || "") ? 1 : -1;
|
|
if (r && e.height !== t.height)
|
|
return e.height - t.height;
|
|
if (e.frameRate !== t.frameRate)
|
|
return e.frameRate - t.frameRate;
|
|
if (e.videoRange !== t.videoRange)
|
|
return Je.indexOf(e.videoRange) - Je.indexOf(t.videoRange);
|
|
if (e.videoCodec !== t.videoCodec) {
|
|
var i = Fe(e.videoCodec)
|
|
, n = Fe(t.videoCodec);
|
|
if (i !== n)
|
|
return n - i
|
|
}
|
|
if (e.uri === t.uri && e.codecSet !== t.codecSet) {
|
|
var a = Ne(e.codecSet)
|
|
, s = Ne(t.codecSet);
|
|
if (a !== s)
|
|
return s - a
|
|
}
|
|
return e.averageBitrate !== t.averageBitrate ? e.averageBitrate - t.averageBitrate : 0
|
|
}
|
|
));
|
|
var f = h[0];
|
|
if (this.steering && (u = this.steering.filterParsedLevels(u)).length !== h.length)
|
|
for (var c = 0; c < h.length; c++)
|
|
if (h[c].pathwayId === u[0].pathwayId) {
|
|
f = h[c];
|
|
break
|
|
}
|
|
this._levels = u;
|
|
for (var g = 0; g < u.length; g++)
|
|
if (u[g] === f) {
|
|
var v;
|
|
this._firstLevel = g;
|
|
var m = f.bitrate
|
|
, p = this.hls.bandwidthEstimate;
|
|
if (this.log("manifest loaded, " + u.length + " level(s) found, first bitrate: " + m),
|
|
void 0 === (null == (v = this.hls.userConfig) ? void 0 : v.abrEwmaDefaultEstimate)) {
|
|
var y = Math.min(m, this.hls.config.abrEwmaDefaultEstimateMax);
|
|
y > p && p === this.hls.abrEwmaDefaultEstimate && (this.hls.bandwidthEstimate = y)
|
|
}
|
|
break
|
|
}
|
|
var E = n && !i
|
|
, T = this.hls.config
|
|
, S = !(!T.audioStreamController || !T.audioTrackController)
|
|
, A = {
|
|
levels: u,
|
|
audioTracks: o,
|
|
subtitleTracks: l,
|
|
sessionData: t.sessionData,
|
|
sessionKeys: t.sessionKeys,
|
|
firstLevel: this._firstLevel,
|
|
stats: t.stats,
|
|
audio: n,
|
|
video: i,
|
|
altAudio: S && !E && o.some((function(e) {
|
|
return !!e.url
|
|
}
|
|
))
|
|
};
|
|
d.end = performance.now(),
|
|
this.hls.trigger(b.MANIFEST_PARSED, A)
|
|
}
|
|
,
|
|
r.onError = function(e, t) {
|
|
!t.fatal && t.context && t.context.type === _ && t.context.level === this.level && this.checkRetry(t)
|
|
}
|
|
,
|
|
r.onFragBuffered = function(e, t) {
|
|
var r = t.frag;
|
|
if (void 0 !== r && r.type === w) {
|
|
var i = r.elementaryStreams;
|
|
if (!Object.keys(i).some((function(e) {
|
|
return !!i[e]
|
|
}
|
|
)))
|
|
return;
|
|
var n = this._levels[r.level];
|
|
null != n && n.loadError && (this.log("Resetting level error count of " + n.loadError + " on frag buffered"),
|
|
n.loadError = 0)
|
|
}
|
|
}
|
|
,
|
|
r.onLevelLoaded = function(e, t) {
|
|
var r, i, n = t.level, a = t.details, s = t.levelInfo;
|
|
if (!s)
|
|
return this.warn("Invalid level index " + n),
|
|
void (null != (i = t.deliveryDirectives) && i.skip && (a.deltaUpdateFailed = !0));
|
|
if (s === this.currentLevel || t.withoutMultiVariant) {
|
|
0 === s.fragmentError && (s.loadError = 0);
|
|
var o = s.details;
|
|
o === t.details && o.advanced && (o = void 0),
|
|
this.playlistLoaded(n, t, o)
|
|
} else
|
|
null != (r = t.deliveryDirectives) && r.skip && (a.deltaUpdateFailed = !0)
|
|
}
|
|
,
|
|
r.loadPlaylist = function(t) {
|
|
e.prototype.loadPlaylist.call(this),
|
|
this.shouldLoadPlaylist(this.currentLevel) && this.scheduleLoading(this.currentLevel, t)
|
|
}
|
|
,
|
|
r.loadingPlaylist = function(t, r) {
|
|
e.prototype.loadingPlaylist.call(this, t, r);
|
|
var i = this.getUrlWithDirectives(t.uri, r)
|
|
, n = this.currentLevelIndex
|
|
, a = t.attrs["PATHWAY-ID"]
|
|
, s = t.details
|
|
, o = null == s ? void 0 : s.age;
|
|
this.log("Loading level index " + n + (void 0 !== (null == r ? void 0 : r.msn) ? " at sn " + r.msn + " part " + r.part : "") + (a ? " Pathway " + a : "") + (o && s.live ? " age " + o.toFixed(1) + (s.type && " " + s.type || "") : "") + " " + i),
|
|
this.hls.trigger(b.LEVEL_LOADING, {
|
|
url: i,
|
|
level: n,
|
|
levelInfo: t,
|
|
pathwayId: t.attrs["PATHWAY-ID"],
|
|
id: 0,
|
|
deliveryDirectives: r || null
|
|
})
|
|
}
|
|
,
|
|
r.removeLevel = function(e) {
|
|
var t, r = this;
|
|
if (1 !== this._levels.length) {
|
|
var i = this._levels.filter((function(t, i) {
|
|
return i !== e || (r.steering && r.steering.removeLevel(t),
|
|
t === r.currentLevel && (r.currentLevel = null,
|
|
r.currentLevelIndex = -1,
|
|
t.details && t.details.fragments.forEach((function(e) {
|
|
return e.level = -1
|
|
}
|
|
))),
|
|
!1)
|
|
}
|
|
));
|
|
vi(i),
|
|
this._levels = i,
|
|
this.currentLevelIndex > -1 && null != (t = this.currentLevel) && t.details && (this.currentLevelIndex = this.currentLevel.details.fragments[0].level),
|
|
this.manualLevelIndex > -1 && (this.manualLevelIndex = this.currentLevelIndex);
|
|
var n = i.length - 1;
|
|
this._firstLevel = Math.min(this._firstLevel, n),
|
|
this._startLevel && (this._startLevel = Math.min(this._startLevel, n)),
|
|
this.hls.trigger(b.LEVELS_UPDATED, {
|
|
levels: i
|
|
})
|
|
}
|
|
}
|
|
,
|
|
r.onLevelsUpdated = function(e, t) {
|
|
var r = t.levels;
|
|
this._levels = r
|
|
}
|
|
,
|
|
r.checkMaxAutoUpdated = function() {
|
|
var e = this.hls
|
|
, t = e.autoLevelCapping
|
|
, r = e.maxAutoLevel
|
|
, i = e.maxHdcpLevel;
|
|
this._maxAutoLevel !== r && (this._maxAutoLevel = r,
|
|
this.hls.trigger(b.MAX_AUTO_LEVEL_UPDATED, {
|
|
autoLevelCapping: t,
|
|
levels: this.levels,
|
|
maxAutoLevel: r,
|
|
minAutoLevel: this.hls.minAutoLevel,
|
|
maxHdcpLevel: i
|
|
}))
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "levels",
|
|
get: function() {
|
|
return 0 === this._levels.length ? null : this._levels
|
|
}
|
|
}, {
|
|
key: "loadLevelObj",
|
|
get: function() {
|
|
return this.currentLevel
|
|
}
|
|
}, {
|
|
key: "level",
|
|
get: function() {
|
|
return this.currentLevelIndex
|
|
},
|
|
set: function(e) {
|
|
var t = this._levels;
|
|
if (0 !== t.length) {
|
|
if (e < 0 || e >= t.length) {
|
|
var r = new Error("invalid level idx")
|
|
, i = e < 0;
|
|
if (this.hls.trigger(b.ERROR, {
|
|
type: R.OTHER_ERROR,
|
|
details: k.LEVEL_SWITCH_ERROR,
|
|
level: e,
|
|
fatal: i,
|
|
error: r,
|
|
reason: r.message
|
|
}),
|
|
i)
|
|
return;
|
|
e = Math.min(e, t.length - 1)
|
|
}
|
|
var n = this.currentLevelIndex
|
|
, a = this.currentLevel
|
|
, s = a ? a.attrs["PATHWAY-ID"] : void 0
|
|
, o = t[e]
|
|
, l = o.attrs["PATHWAY-ID"];
|
|
if (this.currentLevelIndex = e,
|
|
this.currentLevel = o,
|
|
n !== e || !a || s !== l) {
|
|
this.log("Switching to level " + e + " (" + (o.height ? o.height + "p " : "") + (o.videoRange ? o.videoRange + " " : "") + (o.codecSet ? o.codecSet + " " : "") + "@" + o.bitrate + ")" + (l ? " with Pathway " + l : "") + " from level " + n + (s ? " with Pathway " + s : ""));
|
|
var u = {
|
|
level: e,
|
|
attrs: o.attrs,
|
|
details: o.details,
|
|
bitrate: o.bitrate,
|
|
averageBitrate: o.averageBitrate,
|
|
maxBitrate: o.maxBitrate,
|
|
realBitrate: o.realBitrate,
|
|
width: o.width,
|
|
height: o.height,
|
|
codecSet: o.codecSet,
|
|
audioCodec: o.audioCodec,
|
|
videoCodec: o.videoCodec,
|
|
audioGroups: o.audioGroups,
|
|
subtitleGroups: o.subtitleGroups,
|
|
loaded: o.loaded,
|
|
loadError: o.loadError,
|
|
fragmentError: o.fragmentError,
|
|
name: o.name,
|
|
id: o.id,
|
|
uri: o.uri,
|
|
url: o.url,
|
|
urlId: 0,
|
|
audioGroupIds: o.audioGroupIds,
|
|
textGroupIds: o.textGroupIds
|
|
};
|
|
this.hls.trigger(b.LEVEL_SWITCHING, u);
|
|
var d = o.details;
|
|
if (!d || d.live) {
|
|
var h = this.switchParams(o.uri, null == a ? void 0 : a.details, d);
|
|
this.loadPlaylist(h)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
key: "manualLevel",
|
|
get: function() {
|
|
return this.manualLevelIndex
|
|
},
|
|
set: function(e) {
|
|
this.manualLevelIndex = e,
|
|
void 0 === this._startLevel && (this._startLevel = e),
|
|
-1 !== e && (this.level = e)
|
|
}
|
|
}, {
|
|
key: "firstLevel",
|
|
get: function() {
|
|
return this._firstLevel
|
|
},
|
|
set: function(e) {
|
|
this._firstLevel = e
|
|
}
|
|
}, {
|
|
key: "startLevel",
|
|
get: function() {
|
|
if (void 0 === this._startLevel) {
|
|
var e = this.hls.config.startLevel;
|
|
return void 0 !== e ? e : this.hls.firstAutoLevel
|
|
}
|
|
return this._startLevel
|
|
},
|
|
set: function(e) {
|
|
this._startLevel = e
|
|
}
|
|
}, {
|
|
key: "pathways",
|
|
get: function() {
|
|
return this.steering ? this.steering.pathways() : []
|
|
}
|
|
}, {
|
|
key: "pathwayPriority",
|
|
get: function() {
|
|
return this.steering ? this.steering.pathwayPriority : null
|
|
},
|
|
set: function(e) {
|
|
if (this.steering) {
|
|
var t = this.steering.pathways()
|
|
, r = e.filter((function(e) {
|
|
return -1 !== t.indexOf(e)
|
|
}
|
|
));
|
|
if (e.length < 1)
|
|
return void this.warn("pathwayPriority " + e + " should contain at least one pathway from list: " + t);
|
|
this.steering.pathwayPriority = r
|
|
}
|
|
}
|
|
}, {
|
|
key: "nextLoadLevel",
|
|
get: function() {
|
|
return -1 !== this.manualLevelIndex ? this.manualLevelIndex : this.hls.nextAutoLevel
|
|
},
|
|
set: function(e) {
|
|
this.level = e,
|
|
-1 === this.manualLevelIndex && (this.hls.nextAutoLevel = e)
|
|
}
|
|
}])
|
|
}(ga);
|
|
function Rl(e) {
|
|
var t = {};
|
|
e.forEach((function(e) {
|
|
var r = e.groupId || "";
|
|
e.id = t[r] = t[r] || 0,
|
|
t[r]++
|
|
}
|
|
))
|
|
}
|
|
function kl() {
|
|
return self.SourceBuffer || self.WebKitSourceBuffer
|
|
}
|
|
function bl() {
|
|
if (!W())
|
|
return !1;
|
|
var e = kl();
|
|
return !e || e.prototype && "function" == typeof e.prototype.appendBuffer && "function" == typeof e.prototype.remove
|
|
}
|
|
var Dl = function(e) {
|
|
function t(t, r, i) {
|
|
var n;
|
|
return (n = e.call(this, t, r, i, "stream-controller", w) || this).audioCodecSwap = !1,
|
|
n.level = -1,
|
|
n._forceStartLoad = !1,
|
|
n._hasEnoughToStart = !1,
|
|
n.altAudio = 0,
|
|
n.audioOnly = !1,
|
|
n.fragPlaying = null,
|
|
n.fragLastKbps = 0,
|
|
n.couldBacktrack = !1,
|
|
n.backtrackFragment = null,
|
|
n.audioCodecSwitch = !1,
|
|
n.videoBuffer = null,
|
|
n.onMediaPlaying = function() {
|
|
n.tick()
|
|
}
|
|
,
|
|
n.onMediaSeeked = function() {
|
|
var e = n.media
|
|
, t = e ? e.currentTime : null;
|
|
if (null !== t && A(t) && (n.log("Media seeked to " + t.toFixed(3)),
|
|
n.getBufferedFrag(t))) {
|
|
var r = n.getFwdBufferInfoAtPos(e, t, w, 0);
|
|
null !== r && 0 !== r.len ? n.tick() : n.warn("Main forward buffer length at " + t + ' on "seeked" event ' + (r ? r.len : "empty") + ")")
|
|
}
|
|
}
|
|
,
|
|
n.registerListeners(),
|
|
n
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.registerListeners = function() {
|
|
e.prototype.registerListeners.call(this);
|
|
var t = this.hls;
|
|
t.on(b.MANIFEST_PARSED, this.onManifestParsed, this),
|
|
t.on(b.LEVEL_LOADING, this.onLevelLoading, this),
|
|
t.on(b.LEVEL_LOADED, this.onLevelLoaded, this),
|
|
t.on(b.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this),
|
|
t.on(b.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this),
|
|
t.on(b.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this),
|
|
t.on(b.BUFFER_CREATED, this.onBufferCreated, this),
|
|
t.on(b.BUFFER_FLUSHED, this.onBufferFlushed, this),
|
|
t.on(b.LEVELS_UPDATED, this.onLevelsUpdated, this),
|
|
t.on(b.FRAG_BUFFERED, this.onFragBuffered, this)
|
|
}
|
|
,
|
|
r.unregisterListeners = function() {
|
|
e.prototype.unregisterListeners.call(this);
|
|
var t = this.hls;
|
|
t.off(b.MANIFEST_PARSED, this.onManifestParsed, this),
|
|
t.off(b.LEVEL_LOADED, this.onLevelLoaded, this),
|
|
t.off(b.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this),
|
|
t.off(b.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this),
|
|
t.off(b.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this),
|
|
t.off(b.BUFFER_CREATED, this.onBufferCreated, this),
|
|
t.off(b.BUFFER_FLUSHED, this.onBufferFlushed, this),
|
|
t.off(b.LEVELS_UPDATED, this.onLevelsUpdated, this),
|
|
t.off(b.FRAG_BUFFERED, this.onFragBuffered, this)
|
|
}
|
|
,
|
|
r.onHandlerDestroying = function() {
|
|
this.onMediaPlaying = this.onMediaSeeked = null,
|
|
this.unregisterListeners(),
|
|
e.prototype.onHandlerDestroying.call(this)
|
|
}
|
|
,
|
|
r.startLoad = function(e, t) {
|
|
if (this.levels) {
|
|
var r = this.lastCurrentTime
|
|
, i = this.hls;
|
|
if (this.stopLoad(),
|
|
this.setInterval(100),
|
|
this.level = -1,
|
|
!this.startFragRequested) {
|
|
var n = i.startLevel;
|
|
-1 === n && (i.config.testBandwidth && this.levels.length > 1 ? (n = 0,
|
|
this.bitrateTest = !0) : n = i.firstAutoLevel),
|
|
i.nextLoadLevel = n,
|
|
this.level = i.loadLevel,
|
|
this._hasEnoughToStart = !!t
|
|
}
|
|
r > 0 && -1 === e && !t && (this.log("Override startPosition with lastCurrentTime @" + r.toFixed(3)),
|
|
e = r),
|
|
this.state = ki.IDLE,
|
|
this.nextLoadPosition = this.lastCurrentTime = e + this.timelineOffset,
|
|
this.startPosition = t ? -1 : e,
|
|
this.tick()
|
|
} else
|
|
this._forceStartLoad = !0,
|
|
this.state = ki.STOPPED
|
|
}
|
|
,
|
|
r.stopLoad = function() {
|
|
this._forceStartLoad = !1,
|
|
e.prototype.stopLoad.call(this)
|
|
}
|
|
,
|
|
r.doTick = function() {
|
|
switch (this.state) {
|
|
case ki.WAITING_LEVEL:
|
|
var e = this.levels
|
|
, t = this.level
|
|
, r = null == e ? void 0 : e[t]
|
|
, i = null == r ? void 0 : r.details;
|
|
if (i && (!i.live || this.levelLastLoaded === r && !this.waitForLive(r))) {
|
|
if (this.waitForCdnTuneIn(i))
|
|
break;
|
|
this.state = ki.IDLE;
|
|
break
|
|
}
|
|
if (this.hls.nextLoadLevel !== this.level) {
|
|
this.state = ki.IDLE;
|
|
break
|
|
}
|
|
break;
|
|
case ki.FRAG_LOADING_WAITING_RETRY:
|
|
this.checkRetryDate()
|
|
}
|
|
this.state === ki.IDLE && this.doTickIdle(),
|
|
this.onTickEnd()
|
|
}
|
|
,
|
|
r.onTickEnd = function() {
|
|
var t;
|
|
e.prototype.onTickEnd.call(this),
|
|
null != (t = this.media) && t.readyState && !1 === this.media.seeking && (this.lastCurrentTime = this.media.currentTime),
|
|
this.checkFragmentChanged()
|
|
}
|
|
,
|
|
r.doTickIdle = function() {
|
|
var e = this.hls
|
|
, t = this.levelLastLoaded
|
|
, r = this.levels
|
|
, i = this.media;
|
|
if (null !== t && (i || this.primaryPrefetch || !this.startFragRequested && e.config.startFragPrefetch) && (!this.altAudio || !this.audioOnly)) {
|
|
var n = this.buffering ? e.nextLoadLevel : e.loadLevel;
|
|
if (null != r && r[n]) {
|
|
var a = r[n]
|
|
, s = this.getMainFwdBufferInfo();
|
|
if (null !== s) {
|
|
var o = this.getLevelDetails();
|
|
if (o && this._streamEnded(s, o)) {
|
|
var l = {};
|
|
return 2 === this.altAudio && (l.type = "video"),
|
|
this.hls.trigger(b.BUFFER_EOS, l),
|
|
void (this.state = ki.ENDED)
|
|
}
|
|
if (this.buffering) {
|
|
e.loadLevel !== n && -1 === e.manualLevel && this.log("Adapting to level " + n + " from level " + this.level),
|
|
this.level = e.nextLoadLevel = n;
|
|
var u = a.details;
|
|
if (!u || this.state === ki.WAITING_LEVEL || this.waitForLive(a))
|
|
return this.level = n,
|
|
this.state = ki.WAITING_LEVEL,
|
|
void (this.startFragRequested = !1);
|
|
var d = s.len
|
|
, h = this.getMaxBufferLength(a.maxBitrate);
|
|
if (!(d >= h)) {
|
|
this.backtrackFragment && this.backtrackFragment.start > s.end && (this.backtrackFragment = null);
|
|
var f = this.backtrackFragment ? this.backtrackFragment.start : s.end
|
|
, c = this.getNextFragment(f, u);
|
|
if (this.couldBacktrack && !this.fragPrevious && c && te(c) && this.fragmentTracker.getState(c) !== Yt) {
|
|
var g, v = (null != (g = this.backtrackFragment) ? g : c).sn - u.startSN, m = u.fragments[v - 1];
|
|
m && c.cc === m.cc && (c = m,
|
|
this.fragmentTracker.removeFragment(m))
|
|
} else
|
|
this.backtrackFragment && s.len && (this.backtrackFragment = null);
|
|
if (c && this.isLoopLoading(c, f)) {
|
|
if (!c.gap) {
|
|
var p = this.audioOnly && !this.altAudio ? $ : Z
|
|
, y = (p === Z ? this.videoBuffer : this.mediaBuffer) || this.media;
|
|
y && this.afterBufferFlushed(y, p, w)
|
|
}
|
|
c = this.getNextFragmentLoopLoading(c, u, s, w, h)
|
|
}
|
|
c && (!c.initSegment || c.initSegment.data || this.bitrateTest || (c = c.initSegment),
|
|
this.loadFragment(c, a, f))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.loadFragment = function(t, r, i) {
|
|
var n = this.fragmentTracker.getState(t);
|
|
n === Kt || n === Ht ? te(t) ? this.bitrateTest ? (this.log("Fragment " + t.sn + " of level " + t.level + " is being downloaded to test bitrate and will not be buffered"),
|
|
this._loadBitrateTestFrag(t, r)) : e.prototype.loadFragment.call(this, t, r, i) : this._loadInitSegment(t, r) : this.clearTrackerIfNeeded(t)
|
|
}
|
|
,
|
|
r.getBufferedFrag = function(e) {
|
|
return this.fragmentTracker.getBufferedFrag(e, w)
|
|
}
|
|
,
|
|
r.followingBufferedFrag = function(e) {
|
|
return e ? this.getBufferedFrag(e.end + .5) : null
|
|
}
|
|
,
|
|
r.immediateLevelSwitch = function() {
|
|
this.abortCurrentFrag(),
|
|
this.flushMainBuffer(0, Number.POSITIVE_INFINITY)
|
|
}
|
|
,
|
|
r.nextLevelSwitch = function() {
|
|
var e = this.levels
|
|
, t = this.media;
|
|
if (null != t && t.readyState) {
|
|
var r, i = this.getAppendedFrag(t.currentTime);
|
|
i && i.start > 1 && this.flushMainBuffer(0, i.start - 1);
|
|
var n = this.getLevelDetails();
|
|
if (null != n && n.live) {
|
|
var a = this.getMainFwdBufferInfo();
|
|
if (!a || a.len < 2 * n.targetduration)
|
|
return
|
|
}
|
|
if (!t.paused && e) {
|
|
var s = e[this.hls.nextLoadLevel]
|
|
, o = this.fragLastKbps;
|
|
r = o && this.fragCurrent ? this.fragCurrent.duration * s.maxBitrate / (1e3 * o) + 1 : 0
|
|
} else
|
|
r = 0;
|
|
var l = this.getBufferedFrag(t.currentTime + r);
|
|
if (l) {
|
|
var u = this.followingBufferedFrag(l);
|
|
if (u) {
|
|
this.abortCurrentFrag();
|
|
var d = u.maxStartPTS ? u.maxStartPTS : u.start
|
|
, h = u.duration
|
|
, f = Math.max(l.end, d + Math.min(Math.max(h - this.config.maxFragLookUpTolerance, h * (this.couldBacktrack ? .5 : .125)), h * (this.couldBacktrack ? .75 : .25)));
|
|
this.flushMainBuffer(f, Number.POSITIVE_INFINITY)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.abortCurrentFrag = function() {
|
|
var e = this.fragCurrent;
|
|
switch (this.fragCurrent = null,
|
|
this.backtrackFragment = null,
|
|
e && (e.abortRequests(),
|
|
this.fragmentTracker.removeFragment(e)),
|
|
this.state) {
|
|
case ki.KEY_LOADING:
|
|
case ki.FRAG_LOADING:
|
|
case ki.FRAG_LOADING_WAITING_RETRY:
|
|
case ki.PARSING:
|
|
case ki.PARSED:
|
|
this.state = ki.IDLE
|
|
}
|
|
this.nextLoadPosition = this.getLoadPosition()
|
|
}
|
|
,
|
|
r.flushMainBuffer = function(t, r) {
|
|
e.prototype.flushMainBuffer.call(this, t, r, 2 === this.altAudio ? "video" : null)
|
|
}
|
|
,
|
|
r.onMediaAttached = function(t, r) {
|
|
e.prototype.onMediaAttached.call(this, t, r);
|
|
var i = r.media;
|
|
Li(i, "playing", this.onMediaPlaying),
|
|
Li(i, "seeked", this.onMediaSeeked)
|
|
}
|
|
,
|
|
r.onMediaDetaching = function(t, r) {
|
|
var i = this.media;
|
|
i && (Ii(i, "playing", this.onMediaPlaying),
|
|
Ii(i, "seeked", this.onMediaSeeked)),
|
|
this.videoBuffer = null,
|
|
this.fragPlaying = null,
|
|
e.prototype.onMediaDetaching.call(this, t, r),
|
|
r.transferMedia || (this._hasEnoughToStart = !1)
|
|
}
|
|
,
|
|
r.onManifestLoading = function() {
|
|
e.prototype.onManifestLoading.call(this),
|
|
this.log("Trigger BUFFER_RESET"),
|
|
this.hls.trigger(b.BUFFER_RESET, void 0),
|
|
this.couldBacktrack = !1,
|
|
this.fragLastKbps = 0,
|
|
this.fragPlaying = this.backtrackFragment = null,
|
|
this.altAudio = 0,
|
|
this.audioOnly = !1
|
|
}
|
|
,
|
|
r.onManifestParsed = function(e, t) {
|
|
for (var r, i, n = !1, a = !1, s = 0; s < t.levels.length; s++) {
|
|
var o = t.levels[s].audioCodec;
|
|
o && (n = n || -1 !== o.indexOf("mp4a.40.2"),
|
|
a = a || -1 !== o.indexOf("mp4a.40.5"))
|
|
}
|
|
this.audioCodecSwitch = n && a && !("function" == typeof (null == (i = kl()) || null == (r = i.prototype) ? void 0 : r.changeType)),
|
|
this.audioCodecSwitch && this.log("Both AAC/HE-AAC audio found in levels; declaring level codec as HE-AAC"),
|
|
this.levels = t.levels,
|
|
this.startFragRequested = !1
|
|
}
|
|
,
|
|
r.onLevelLoading = function(e, t) {
|
|
if (this.levels && this.state === ki.IDLE) {
|
|
var r = t.levelInfo;
|
|
(!r.details || r.details.live && (this.levelLastLoaded !== r || r.details.expired) || this.waitForCdnTuneIn(r.details)) && (this.state = ki.WAITING_LEVEL)
|
|
}
|
|
}
|
|
,
|
|
r.onLevelLoaded = function(e, t) {
|
|
var r, i = this.levels, n = this.startFragRequested, a = t.level, s = t.details, o = s.totalduration;
|
|
if (i) {
|
|
this.log("Level " + a + " loaded [" + s.startSN + "," + s.endSN + "]" + (s.lastPartSn ? "[part-" + s.lastPartSn + "-" + s.lastPartIndex + "]" : "") + ", cc [" + s.startCC + ", " + s.endCC + "] duration:" + o);
|
|
var l = t.levelInfo
|
|
, u = this.fragCurrent;
|
|
!u || this.state !== ki.FRAG_LOADING && this.state !== ki.FRAG_LOADING_WAITING_RETRY || u.level !== t.level && u.loader && this.abortCurrentFrag();
|
|
var d = 0;
|
|
if (s.live || null != (r = l.details) && r.live) {
|
|
var h;
|
|
if (this.checkLiveUpdate(s),
|
|
s.deltaUpdateFailed)
|
|
return;
|
|
d = this.alignPlaylists(s, l.details, null == (h = this.levelLastLoaded) ? void 0 : h.details)
|
|
}
|
|
if (l.details = s,
|
|
this.levelLastLoaded = l,
|
|
n || this.setStartPosition(s, d),
|
|
this.hls.trigger(b.LEVEL_UPDATED, {
|
|
details: s,
|
|
level: a
|
|
}),
|
|
this.state === ki.WAITING_LEVEL) {
|
|
if (this.waitForCdnTuneIn(s))
|
|
return;
|
|
this.state = ki.IDLE
|
|
}
|
|
n && s.live && this.synchronizeToLiveEdge(s),
|
|
this.tick()
|
|
} else
|
|
this.warn("Levels were reset while loading level " + a)
|
|
}
|
|
,
|
|
r.synchronizeToLiveEdge = function(e) {
|
|
var t = this.config
|
|
, r = this.media;
|
|
if (r) {
|
|
var i = this.hls.liveSyncPosition
|
|
, n = this.getLoadPosition()
|
|
, a = e.fragmentStart
|
|
, s = e.edge
|
|
, o = n >= a - t.maxFragLookUpTolerance && n <= s;
|
|
if (null !== i && r.duration > i && (n < i || !o)) {
|
|
var l = void 0 !== t.liveMaxLatencyDuration ? t.liveMaxLatencyDuration : t.liveMaxLatencyDurationCount * e.targetduration;
|
|
if ((!o && r.readyState < 4 || n < s - l) && (this._hasEnoughToStart || (this.nextLoadPosition = i),
|
|
r.readyState))
|
|
if (this.warn("Playback: " + n.toFixed(3) + " is located too far from the end of live sliding playlist: " + s + ", reset currentTime to : " + i.toFixed(3)),
|
|
"buffered" === this.config.liveSyncMode) {
|
|
var u, d = ur.bufferInfo(r, i, 0);
|
|
if (null == (u = d.buffered) || !u.length)
|
|
return void (r.currentTime = i);
|
|
if (d.start <= n)
|
|
return void (r.currentTime = i);
|
|
var h = ur.bufferedInfo(d.buffered, n, 0).nextStart;
|
|
h && (r.currentTime = h)
|
|
} else
|
|
r.currentTime = i
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r._handleFragmentLoadProgress = function(e) {
|
|
var t, r = e.frag, i = e.part, n = e.payload, a = this.levels;
|
|
if (a) {
|
|
var s = a[r.level];
|
|
if (s) {
|
|
var o = s.details;
|
|
if (!o)
|
|
return this.warn("Dropping fragment " + r.sn + " of level " + r.level + " after level details were reset"),
|
|
void this.fragmentTracker.removeFragment(r);
|
|
var l = s.videoCodec
|
|
, u = o.PTSKnown || !o.live
|
|
, d = null == (t = r.initSegment) ? void 0 : t.data
|
|
, h = this._getAudioCodec(s)
|
|
, f = this.transmuxer = this.transmuxer || new fa(this.hls,w,this._handleTransmuxComplete.bind(this),this._handleTransmuxerFlush.bind(this))
|
|
, c = i ? i.index : -1
|
|
, g = -1 !== c
|
|
, v = new or(r.level,r.sn,r.stats.chunkCount,n.byteLength,c,g)
|
|
, m = this.initPTS[r.cc];
|
|
f.push(n, d, h, l, r, i, o.totalduration, u, v, m)
|
|
} else
|
|
this.warn("Level " + r.level + " not found on progress")
|
|
} else
|
|
this.warn("Levels were reset while fragment load was in progress. Fragment " + r.sn + " of level " + r.level + " will not be buffered")
|
|
}
|
|
,
|
|
r.onAudioTrackSwitching = function(e, t) {
|
|
var r = this
|
|
, i = this.hls
|
|
, n = 2 === this.altAudio;
|
|
if (mt(t.url, i))
|
|
this.altAudio = 1;
|
|
else {
|
|
if (this.mediaBuffer !== this.media) {
|
|
this.log("Switching on main audio, use media.buffered to schedule main fragment loading"),
|
|
this.mediaBuffer = this.media;
|
|
var a = this.fragCurrent;
|
|
a && (this.log("Switching to main audio track, cancel main fragment load"),
|
|
a.abortRequests(),
|
|
this.fragmentTracker.removeFragment(a)),
|
|
this.resetTransmuxer(),
|
|
this.resetLoadingState()
|
|
} else
|
|
this.audioOnly && this.resetTransmuxer();
|
|
if (n)
|
|
return this.fragmentTracker.removeAllFragments(),
|
|
i.once(b.BUFFER_FLUSHED, (function() {
|
|
r.hls && r.hls.trigger(b.AUDIO_TRACK_SWITCHED, t)
|
|
}
|
|
)),
|
|
void i.trigger(b.BUFFER_FLUSHING, {
|
|
startOffset: 0,
|
|
endOffset: Number.POSITIVE_INFINITY,
|
|
type: null
|
|
});
|
|
i.trigger(b.AUDIO_TRACK_SWITCHED, t)
|
|
}
|
|
}
|
|
,
|
|
r.onAudioTrackSwitched = function(e, t) {
|
|
var r = mt(t.url, this.hls);
|
|
if (r) {
|
|
var i = this.videoBuffer;
|
|
i && this.mediaBuffer !== i && (this.log("Switching on alternate audio, use video.buffered to schedule main fragment loading"),
|
|
this.mediaBuffer = i)
|
|
}
|
|
this.altAudio = r ? 2 : 0,
|
|
this.tick()
|
|
}
|
|
,
|
|
r.onBufferCreated = function(e, t) {
|
|
var r, i, n = t.tracks, a = !1;
|
|
for (var s in n) {
|
|
var o = n[s];
|
|
if ("main" === o.id) {
|
|
if (i = s,
|
|
r = o,
|
|
"video" === s) {
|
|
var l = n[s];
|
|
l && (this.videoBuffer = l.buffer)
|
|
}
|
|
} else
|
|
a = !0
|
|
}
|
|
a && r ? (this.log("Alternate track found, use " + i + ".buffered to schedule main fragment loading"),
|
|
this.mediaBuffer = r.buffer) : this.mediaBuffer = this.media
|
|
}
|
|
,
|
|
r.onFragBuffered = function(e, t) {
|
|
var r = t.frag
|
|
, i = t.part
|
|
, n = r.type === w;
|
|
if (n) {
|
|
if (this.fragContextChanged(r))
|
|
return this.warn("Fragment " + r.sn + (i ? " p: " + i.index : "") + " of level " + r.level + " finished buffering, but was aborted. state: " + this.state),
|
|
void (this.state === ki.PARSED && (this.state = ki.IDLE));
|
|
var a = i ? i.stats : r.stats;
|
|
this.fragLastKbps = Math.round(8 * a.total / (a.buffering.end - a.loading.first)),
|
|
te(r) && (this.fragPrevious = r),
|
|
this.fragBufferedComplete(r, i)
|
|
}
|
|
var s = this.media;
|
|
s && (!this._hasEnoughToStart && ur.getBuffered(s).length && (this._hasEnoughToStart = !0,
|
|
this.seekToStartPos()),
|
|
n && this.tick())
|
|
}
|
|
,
|
|
r.onError = function(e, t) {
|
|
var r;
|
|
if (t.fatal)
|
|
this.state = ki.ERROR;
|
|
else
|
|
switch (t.details) {
|
|
case k.FRAG_GAP:
|
|
case k.FRAG_PARSING_ERROR:
|
|
case k.FRAG_DECRYPT_ERROR:
|
|
case k.FRAG_LOAD_ERROR:
|
|
case k.FRAG_LOAD_TIMEOUT:
|
|
case k.KEY_LOAD_ERROR:
|
|
case k.KEY_LOAD_TIMEOUT:
|
|
this.onFragmentOrKeyLoadError(w, t);
|
|
break;
|
|
case k.LEVEL_LOAD_ERROR:
|
|
case k.LEVEL_LOAD_TIMEOUT:
|
|
case k.LEVEL_PARSING_ERROR:
|
|
t.levelRetry || this.state !== ki.WAITING_LEVEL || (null == (r = t.context) ? void 0 : r.type) !== _ || (this.state = ki.IDLE);
|
|
break;
|
|
case k.BUFFER_ADD_CODEC_ERROR:
|
|
case k.BUFFER_APPEND_ERROR:
|
|
if ("main" !== t.parent)
|
|
return;
|
|
this.reduceLengthAndFlushBuffer(t) && this.resetLoadingState();
|
|
break;
|
|
case k.BUFFER_FULL_ERROR:
|
|
if ("main" !== t.parent)
|
|
return;
|
|
this.reduceLengthAndFlushBuffer(t) && (!this.config.interstitialsController && this.config.assetPlayerId ? this._hasEnoughToStart = !0 : this.flushMainBuffer(0, Number.POSITIVE_INFINITY));
|
|
break;
|
|
case k.INTERNAL_EXCEPTION:
|
|
this.recoverWorkerError(t)
|
|
}
|
|
}
|
|
,
|
|
r.onFragLoadEmergencyAborted = function() {
|
|
this.state = ki.IDLE,
|
|
this._hasEnoughToStart || (this.startFragRequested = !1,
|
|
this.nextLoadPosition = this.lastCurrentTime),
|
|
this.tickImmediate()
|
|
}
|
|
,
|
|
r.onBufferFlushed = function(e, t) {
|
|
var r = t.type;
|
|
if (r !== $ || !this.altAudio) {
|
|
var i = (r === Z ? this.videoBuffer : this.mediaBuffer) || this.media;
|
|
i && (this.afterBufferFlushed(i, r, w),
|
|
this.tick())
|
|
}
|
|
}
|
|
,
|
|
r.onLevelsUpdated = function(e, t) {
|
|
this.level > -1 && this.fragCurrent && (this.level = this.fragCurrent.level,
|
|
-1 === this.level && this.resetWhenMissingContext(this.fragCurrent)),
|
|
this.levels = t.levels
|
|
}
|
|
,
|
|
r.swapAudioCodec = function() {
|
|
this.audioCodecSwap = !this.audioCodecSwap
|
|
}
|
|
,
|
|
r.seekToStartPos = function() {
|
|
var e = this.media;
|
|
if (e) {
|
|
var t = e.currentTime
|
|
, r = this.startPosition;
|
|
if (r >= 0 && t < r) {
|
|
if (e.seeking)
|
|
return void this.log("could not seek to " + r + ", already seeking at " + t);
|
|
var i = this.timelineOffset;
|
|
i && r && (r += i);
|
|
var n = this.getLevelDetails()
|
|
, a = ur.getBuffered(e)
|
|
, s = a.length ? a.start(0) : 0
|
|
, o = s - r
|
|
, l = Math.max(this.config.maxBufferHole, this.config.maxFragLookUpTolerance);
|
|
(this.config.startOnSegmentBoundary || o > 0 && (o < l || this.loadingParts && o < 2 * ((null == n ? void 0 : n.partTarget) || 0))) && (this.log("adjusting start position by " + o + " to match buffer start"),
|
|
r += o,
|
|
this.startPosition = r),
|
|
t < r && (this.log("seek to target start position " + r + " from current time " + t + " buffer start " + s),
|
|
e.currentTime = r)
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r._getAudioCodec = function(e) {
|
|
var t = this.config.defaultAudioCodec || e.audioCodec;
|
|
return this.audioCodecSwap && t && (this.log("Swapping audio codec"),
|
|
t = -1 !== t.indexOf("mp4a.40.5") ? "mp4a.40.2" : "mp4a.40.5"),
|
|
t
|
|
}
|
|
,
|
|
r._loadBitrateTestFrag = function(e, t) {
|
|
var r = this;
|
|
e.bitrateTest = !0,
|
|
this._doFragLoad(e, t).then((function(e) {
|
|
var i = r.hls
|
|
, n = null == e ? void 0 : e.frag;
|
|
if (n && !r.fragContextChanged(n)) {
|
|
t.fragmentError = 0,
|
|
r.state = ki.IDLE,
|
|
r.startFragRequested = !1,
|
|
r.bitrateTest = !1;
|
|
var a = n.stats;
|
|
a.parsing.start = a.parsing.end = a.buffering.start = a.buffering.end = self.performance.now(),
|
|
i.trigger(b.FRAG_LOADED, e),
|
|
n.bitrateTest = !1
|
|
}
|
|
}
|
|
)).catch((function(t) {
|
|
r.state !== ki.STOPPED && r.state !== ki.ERROR && (r.warn(t),
|
|
r.resetFragmentLoading(e))
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r._handleTransmuxComplete = function(e) {
|
|
var t = this.playlistType
|
|
, r = this.hls
|
|
, i = e.remuxResult
|
|
, n = e.chunkMeta
|
|
, a = this.getCurrentContext(n);
|
|
if (a) {
|
|
var s = a.frag
|
|
, o = a.part
|
|
, l = a.level
|
|
, u = i.video
|
|
, d = i.text
|
|
, h = i.id3
|
|
, f = i.initSegment
|
|
, c = l.details
|
|
, g = this.altAudio ? void 0 : i.audio;
|
|
if (this.fragContextChanged(s))
|
|
this.fragmentTracker.removeFragment(s);
|
|
else {
|
|
if (this.state = ki.PARSING,
|
|
f) {
|
|
var v = f.tracks;
|
|
if (v) {
|
|
var m = s.initSegment || s;
|
|
if (this.unhandledEncryptionError(f, s))
|
|
return;
|
|
this._bufferInitSegment(l, v, m, n),
|
|
r.trigger(b.FRAG_PARSING_INIT_SEGMENT, {
|
|
frag: m,
|
|
id: t,
|
|
tracks: v
|
|
})
|
|
}
|
|
var p = f.initPTS
|
|
, y = f.timescale
|
|
, E = this.initPTS[s.cc];
|
|
if (A(p) && (!E || E.baseTime !== p || E.timescale !== y)) {
|
|
var T = f.trackId;
|
|
this.initPTS[s.cc] = {
|
|
baseTime: p,
|
|
timescale: y,
|
|
trackId: T
|
|
},
|
|
r.trigger(b.INIT_PTS_FOUND, {
|
|
frag: s,
|
|
id: t,
|
|
initPTS: p,
|
|
timescale: y,
|
|
trackId: T
|
|
})
|
|
}
|
|
}
|
|
if (u && c) {
|
|
g && "audiovideo" === u.type && this.logMuxedErr(s);
|
|
var S = c.fragments[s.sn - 1 - c.startSN]
|
|
, L = s.sn === c.startSN
|
|
, I = !S || s.cc > S.cc;
|
|
if (!1 !== i.independent) {
|
|
var R = u.startPTS
|
|
, k = u.endPTS
|
|
, D = u.startDTS
|
|
, _ = u.endDTS;
|
|
if (o)
|
|
o.elementaryStreams[u.type] = {
|
|
startPTS: R,
|
|
endPTS: k,
|
|
startDTS: D,
|
|
endDTS: _
|
|
};
|
|
else if (u.firstKeyFrame && u.independent && 1 === n.id && !I && (this.couldBacktrack = !0),
|
|
u.dropped && u.independent) {
|
|
var P = this.getMainFwdBufferInfo()
|
|
, C = (P ? P.end : this.getLoadPosition()) + this.config.maxBufferHole
|
|
, w = u.firstKeyFramePTS ? u.firstKeyFramePTS : R;
|
|
if (!L && C < w - this.config.maxBufferHole && !I)
|
|
return void this.backtrack(s);
|
|
I && (s.gap = !0),
|
|
s.setElementaryStreamInfo(u.type, s.start, k, s.start, _, !0)
|
|
} else
|
|
L && R - (c.appliedTimelineOffset || 0) > 2 && (s.gap = !0);
|
|
s.setElementaryStreamInfo(u.type, R, k, D, _),
|
|
this.backtrackFragment && (this.backtrackFragment = s),
|
|
this.bufferFragmentData(u, s, o, n, L || I)
|
|
} else {
|
|
if (!L && !I)
|
|
return void this.backtrack(s);
|
|
s.gap = !0
|
|
}
|
|
}
|
|
if (g) {
|
|
var O = g.startPTS
|
|
, x = g.endPTS
|
|
, M = g.startDTS
|
|
, F = g.endDTS;
|
|
o && (o.elementaryStreams[$] = {
|
|
startPTS: O,
|
|
endPTS: x,
|
|
startDTS: M,
|
|
endDTS: F
|
|
}),
|
|
s.setElementaryStreamInfo($, O, x, M, F),
|
|
this.bufferFragmentData(g, s, o, n)
|
|
}
|
|
if (c && null != h && h.samples.length) {
|
|
var N = {
|
|
id: t,
|
|
frag: s,
|
|
details: c,
|
|
samples: h.samples
|
|
};
|
|
r.trigger(b.FRAG_PARSING_METADATA, N)
|
|
}
|
|
if (c && d) {
|
|
var U = {
|
|
id: t,
|
|
frag: s,
|
|
details: c,
|
|
samples: d.samples
|
|
};
|
|
r.trigger(b.FRAG_PARSING_USERDATA, U)
|
|
}
|
|
}
|
|
} else
|
|
this.resetWhenMissingContext(n)
|
|
}
|
|
,
|
|
r.logMuxedErr = function(e) {
|
|
this.warn((te(e) ? "Media" : "Init") + " segment with muxed audiovideo where only video expected: " + e.url)
|
|
}
|
|
,
|
|
r._bufferInitSegment = function(e, t, r, i) {
|
|
var n = this;
|
|
if (this.state === ki.PARSING) {
|
|
this.audioOnly = !!t.audio && !t.video,
|
|
this.altAudio && !this.audioOnly && (delete t.audio,
|
|
t.audiovideo && this.logMuxedErr(r));
|
|
var a = t.audio
|
|
, s = t.video
|
|
, o = t.audiovideo;
|
|
if (a) {
|
|
var l = e.audioCodec
|
|
, u = Ke(a.codec, l);
|
|
"mp4a" === u && (u = "mp4a.40.5");
|
|
var d = navigator.userAgent.toLowerCase();
|
|
if (this.audioCodecSwitch) {
|
|
u && (u = -1 !== u.indexOf("mp4a.40.5") ? "mp4a.40.2" : "mp4a.40.5");
|
|
var h = a.metadata;
|
|
h && "channelCount"in h && 1 !== (h.channelCount || 1) && -1 === d.indexOf("firefox") && (u = "mp4a.40.5")
|
|
}
|
|
u && -1 !== u.indexOf("mp4a.40.5") && -1 !== d.indexOf("android") && "audio/mpeg" !== a.container && (u = "mp4a.40.2",
|
|
this.log("Android: force audio codec to " + u)),
|
|
l && l !== u && this.log('Swapping manifest audio codec "' + l + '" for "' + u + '"'),
|
|
a.levelCodec = u,
|
|
a.id = w,
|
|
this.log("Init audio buffer, container:" + a.container + ", codecs[selected/level/parsed]=[" + (u || "") + "/" + (l || "") + "/" + a.codec + "]"),
|
|
delete t.audiovideo
|
|
}
|
|
if (s) {
|
|
s.levelCodec = e.videoCodec,
|
|
s.id = w;
|
|
var f = s.codec;
|
|
if (4 === (null == f ? void 0 : f.length))
|
|
switch (f) {
|
|
case "hvc1":
|
|
case "hev1":
|
|
s.codec = "hvc1.1.6.L120.90";
|
|
break;
|
|
case "av01":
|
|
s.codec = "av01.0.04M.08";
|
|
break;
|
|
case "avc1":
|
|
s.codec = "avc1.42e01e"
|
|
}
|
|
this.log("Init video buffer, container:" + s.container + ", codecs[level/parsed]=[" + (e.videoCodec || "") + "/" + f + "]" + (s.codec !== f ? " parsed-corrected=" + s.codec : "") + (s.supplemental ? " supplemental=" + s.supplemental : "")),
|
|
delete t.audiovideo
|
|
}
|
|
o && (this.log("Init audiovideo buffer, container:" + o.container + ", codecs[level/parsed]=[" + e.codecs + "/" + o.codec + "]"),
|
|
delete t.video,
|
|
delete t.audio);
|
|
var c = Object.keys(t);
|
|
if (c.length) {
|
|
if (this.hls.trigger(b.BUFFER_CODECS, t),
|
|
!this.hls)
|
|
return;
|
|
c.forEach((function(e) {
|
|
var a = t[e].initSegment;
|
|
null != a && a.byteLength && n.hls.trigger(b.BUFFER_APPENDING, {
|
|
type: e,
|
|
data: a,
|
|
frag: r,
|
|
part: null,
|
|
chunkMeta: i,
|
|
parent: r.type
|
|
})
|
|
}
|
|
))
|
|
}
|
|
this.tickImmediate()
|
|
}
|
|
}
|
|
,
|
|
r.getMainFwdBufferInfo = function() {
|
|
var e = this.mediaBuffer && 2 === this.altAudio ? this.mediaBuffer : this.media;
|
|
return this.getFwdBufferInfo(e, w)
|
|
}
|
|
,
|
|
r.backtrack = function(e) {
|
|
this.couldBacktrack = !0,
|
|
this.backtrackFragment = e,
|
|
this.resetTransmuxer(),
|
|
this.flushBufferGap(e),
|
|
this.fragmentTracker.removeFragment(e),
|
|
this.fragPrevious = null,
|
|
this.nextLoadPosition = e.start,
|
|
this.state = ki.IDLE
|
|
}
|
|
,
|
|
r.checkFragmentChanged = function() {
|
|
var e = this.media
|
|
, t = null;
|
|
if (e && e.readyState > 1 && !1 === e.seeking) {
|
|
var r = e.currentTime;
|
|
if (ur.isBuffered(e, r) ? t = this.getAppendedFrag(r) : ur.isBuffered(e, r + .1) && (t = this.getAppendedFrag(r + .1)),
|
|
t) {
|
|
this.backtrackFragment = null;
|
|
var i = this.fragPlaying
|
|
, n = t.level;
|
|
i && t.sn === i.sn && i.level === n || (this.fragPlaying = t,
|
|
this.hls.trigger(b.FRAG_CHANGED, {
|
|
frag: t
|
|
}),
|
|
i && i.level === n || this.hls.trigger(b.LEVEL_SWITCHED, {
|
|
level: n
|
|
}))
|
|
}
|
|
}
|
|
}
|
|
,
|
|
i(t, [{
|
|
key: "hasEnoughToStart",
|
|
get: function() {
|
|
return this._hasEnoughToStart
|
|
}
|
|
}, {
|
|
key: "maxBufferLength",
|
|
get: function() {
|
|
var e = this.levels
|
|
, t = this.level
|
|
, r = null == e ? void 0 : e[t];
|
|
return r ? this.getMaxBufferLength(r.maxBitrate) : this.config.maxBufferLength
|
|
}
|
|
}, {
|
|
key: "nextLevel",
|
|
get: function() {
|
|
var e = this.nextBufferedFrag;
|
|
return e ? e.level : -1
|
|
}
|
|
}, {
|
|
key: "currentFrag",
|
|
get: function() {
|
|
var e;
|
|
if (this.fragPlaying)
|
|
return this.fragPlaying;
|
|
var t = (null == (e = this.media) ? void 0 : e.currentTime) || this.lastCurrentTime;
|
|
return A(t) ? this.getAppendedFrag(t) : null
|
|
}
|
|
}, {
|
|
key: "currentProgramDateTime",
|
|
get: function() {
|
|
var e, t = (null == (e = this.media) ? void 0 : e.currentTime) || this.lastCurrentTime;
|
|
if (A(t)) {
|
|
var r = this.getLevelDetails()
|
|
, i = this.currentFrag || (r ? Et(null, r.fragments, t) : null);
|
|
if (i) {
|
|
var n = i.programDateTime;
|
|
if (null !== n) {
|
|
var a = n + 1e3 * (t - i.start);
|
|
return new Date(a)
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
}, {
|
|
key: "currentLevel",
|
|
get: function() {
|
|
var e = this.currentFrag;
|
|
return e ? e.level : -1
|
|
}
|
|
}, {
|
|
key: "nextBufferedFrag",
|
|
get: function() {
|
|
var e = this.currentFrag;
|
|
return e ? this.followingBufferedFrag(e) : null
|
|
}
|
|
}, {
|
|
key: "forceStartLoad",
|
|
get: function() {
|
|
return this._forceStartLoad
|
|
}
|
|
}])
|
|
}(bi)
|
|
, _l = function(e) {
|
|
function t(t, r) {
|
|
var i;
|
|
return (i = e.call(this, "key-loader", r) || this).config = void 0,
|
|
i.keyIdToKeyInfo = {},
|
|
i.emeController = null,
|
|
i.config = t,
|
|
i
|
|
}
|
|
o(t, e);
|
|
var r = t.prototype;
|
|
return r.abort = function(e) {
|
|
for (var t in this.keyIdToKeyInfo) {
|
|
var r = this.keyIdToKeyInfo[t].loader;
|
|
if (r) {
|
|
var i;
|
|
if (e && e !== (null == (i = r.context) ? void 0 : i.frag.type))
|
|
return;
|
|
r.abort()
|
|
}
|
|
}
|
|
}
|
|
,
|
|
r.detach = function() {
|
|
for (var e in this.keyIdToKeyInfo) {
|
|
var t = this.keyIdToKeyInfo[e];
|
|
(t.mediaKeySessionContext || t.decryptdata.isCommonEncryption) && delete this.keyIdToKeyInfo[e]
|
|
}
|
|
}
|
|
,
|
|
r.destroy = function() {
|
|
for (var e in this.detach(),
|
|
this.keyIdToKeyInfo) {
|
|
var t = this.keyIdToKeyInfo[e].loader;
|
|
t && t.destroy()
|
|
}
|
|
this.keyIdToKeyInfo = {}
|
|
}
|
|
,
|
|
r.createKeyLoadError = function(e, t, r, i, n) {
|
|
return void 0 === t && (t = k.KEY_LOAD_ERROR),
|
|
new ar({
|
|
type: R.NETWORK_ERROR,
|
|
details: t,
|
|
fatal: !1,
|
|
frag: e,
|
|
response: n,
|
|
error: r,
|
|
networkDetails: i
|
|
})
|
|
}
|
|
,
|
|
r.loadClear = function(e, t, r) {
|
|
var i = this;
|
|
if (this.emeController && this.config.emeEnabled && !this.emeController.getSelectedKeySystemFormats().length) {
|
|
if (t.length)
|
|
for (var n, a = function() {
|
|
var n = t[s];
|
|
if (e.cc <= n.cc && (!te(e) || !te(n) || e.sn < n.sn) || !r && s == o - 1)
|
|
return {
|
|
v: i.emeController.selectKeySystemFormat(n).then((function(e) {
|
|
if (i.emeController) {
|
|
n.setKeyFormat(e);
|
|
var t = Mr(e);
|
|
return t ? i.emeController.getKeySystemAccess([t]) : void 0
|
|
}
|
|
}
|
|
))
|
|
}
|
|
}, s = 0, o = t.length; s < o; s++)
|
|
if (n = a())
|
|
return n.v;
|
|
if (this.config.requireKeySystemAccessOnStart) {
|
|
var l = Nr(this.config);
|
|
if (l.length)
|
|
return this.emeController.getKeySystemAccess(l)
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
,
|
|
r.load = function(e) {
|
|
var t = this;
|
|
return !e.decryptdata && e.encrypted && this.emeController && this.config.emeEnabled ? this.emeController.selectKeySystemFormat(e).then((function(r) {
|
|
return t.loadInternal(e, r)
|
|
}
|
|
)) : this.loadInternal(e)
|
|
}
|
|
,
|
|
r.loadInternal = function(e, t) {
|
|
var r, i;
|
|
t && e.setKeyFormat(t);
|
|
var n = e.decryptdata;
|
|
if (!n) {
|
|
var a = new Error(t ? "Expected frag.decryptdata to be defined after setting format " + t : "Missing decryption data on fragment in onKeyLoading (emeEnabled with controller: " + (this.emeController && this.config.emeEnabled) + ")");
|
|
return Promise.reject(this.createKeyLoadError(e, k.KEY_LOAD_ERROR, a))
|
|
}
|
|
var s = n.uri;
|
|
if (!s)
|
|
return Promise.reject(this.createKeyLoadError(e, k.KEY_LOAD_ERROR, new Error('Invalid key URI: "' + s + '"')));
|
|
var o = Pl(n)
|
|
, l = this.keyIdToKeyInfo[o];
|
|
if (null != (r = l) && r.decryptdata.key)
|
|
return n.key = l.decryptdata.key,
|
|
Promise.resolve({
|
|
frag: e,
|
|
keyInfo: l
|
|
});
|
|
if (this.emeController && null != (i = l) && i.keyLoadPromise)
|
|
switch (this.emeController.getKeyStatus(l.decryptdata)) {
|
|
case "usable":
|
|
case "usable-in-future":
|
|
return l.keyLoadPromise.then((function(t) {
|
|
var r = t.keyInfo;
|
|
return n.key = r.decryptdata.key,
|
|
{
|
|
frag: e,
|
|
keyInfo: r
|
|
}
|
|
}
|
|
))
|
|
}
|
|
switch (this.log((this.keyIdToKeyInfo[o] ? "Rel" : "L") + "oading" + (n.keyId ? " keyId: " + X(n.keyId) : "") + " URI: " + n.uri + " from " + e.type + " " + e.level),
|
|
l = this.keyIdToKeyInfo[o] = {
|
|
decryptdata: n,
|
|
keyLoadPromise: null,
|
|
loader: null,
|
|
mediaKeySessionContext: null
|
|
},
|
|
n.method) {
|
|
case "SAMPLE-AES":
|
|
case "SAMPLE-AES-CENC":
|
|
case "SAMPLE-AES-CTR":
|
|
return "identity" === n.keyFormat ? this.loadKeyHTTP(l, e) : this.loadKeyEME(l, e);
|
|
case "AES-128":
|
|
case "AES-256":
|
|
case "AES-256-CTR":
|
|
return this.loadKeyHTTP(l, e);
|
|
default:
|
|
return Promise.reject(this.createKeyLoadError(e, k.KEY_LOAD_ERROR, new Error('Key supplied with unsupported METHOD: "' + n.method + '"')))
|
|
}
|
|
}
|
|
,
|
|
r.loadKeyEME = function(e, t) {
|
|
var r = {
|
|
frag: t,
|
|
keyInfo: e
|
|
};
|
|
if (this.emeController && this.config.emeEnabled) {
|
|
var i = this.emeController.loadKey(r);
|
|
return (e.keyLoadPromise = i.then((function(t) {
|
|
return e.mediaKeySessionContext = t,
|
|
r
|
|
}
|
|
))).catch((function(r) {
|
|
throw e.keyLoadPromise = null,
|
|
"data"in r && (r.data.frag = t),
|
|
r
|
|
}
|
|
))
|
|
}
|
|
return Promise.resolve(r)
|
|
}
|
|
,
|
|
r.loadKeyHTTP = function(e, t) {
|
|
var r = this
|
|
, i = this.config
|
|
, n = new (0,
|
|
i.loader)(i);
|
|
return t.keyLoader = e.loader = n,
|
|
e.keyLoadPromise = new Promise((function(a, s) {
|
|
var o = {
|
|
keyInfo: e,
|
|
frag: t,
|
|
responseType: "arraybuffer",
|
|
url: e.decryptdata.uri
|
|
}
|
|
, l = i.keyLoadPolicy.default
|
|
, u = {
|
|
loadPolicy: l,
|
|
timeout: l.maxLoadTimeMs,
|
|
maxRetry: 0,
|
|
retryDelay: 0,
|
|
maxRetryDelay: 0
|
|
}
|
|
, h = {
|
|
onSuccess: function(e, t, i, n) {
|
|
var o = i.frag
|
|
, l = i.keyInfo
|
|
, u = Pl(l.decryptdata);
|
|
if (!o.decryptdata || l !== r.keyIdToKeyInfo[u])
|
|
return s(r.createKeyLoadError(o, k.KEY_LOAD_ERROR, new Error("after key load, decryptdata unset or changed"), n));
|
|
l.decryptdata.key = o.decryptdata.key = new Uint8Array(e.data),
|
|
o.keyLoader = null,
|
|
l.loader = null,
|
|
a({
|
|
frag: o,
|
|
keyInfo: l
|
|
})
|
|
},
|
|
onError: function(e, i, n, a) {
|
|
r.resetLoader(i),
|
|
s(r.createKeyLoadError(t, k.KEY_LOAD_ERROR, new Error("HTTP Error " + e.code + " loading key " + e.text), n, d({
|
|
url: o.url,
|
|
data: void 0
|
|
}, e)))
|
|
},
|
|
onTimeout: function(e, i, n) {
|
|
r.resetLoader(i),
|
|
s(r.createKeyLoadError(t, k.KEY_LOAD_TIMEOUT, new Error("key loading timed out"), n))
|
|
},
|
|
onAbort: function(e, i, n) {
|
|
r.resetLoader(i),
|
|
s(r.createKeyLoadError(t, k.INTERNAL_ABORTED, new Error("key loading aborted"), n))
|
|
}
|
|
};
|
|
n.load(o, u, h)
|
|
}
|
|
))
|
|
}
|
|
,
|
|
r.resetLoader = function(e) {
|
|
var t = e.frag
|
|
, r = e.keyInfo
|
|
, i = e.url
|
|
, n = r.loader;
|
|
t.keyLoader === n && (t.keyLoader = null,
|
|
r.loader = null);
|
|
var a = Pl(r.decryptdata) || i;
|
|
delete this.keyIdToKeyInfo[a],
|
|
n && n.destroy()
|
|
}
|
|
,
|
|
t
|
|
}(N);
|
|
function Pl(e) {
|
|
if (e.keyFormat !== wr) {
|
|
var t = e.keyId;
|
|
if (t)
|
|
return X(t)
|
|
}
|
|
return e.uri
|
|
}
|
|
function Cl(e) {
|
|
switch (e.type) {
|
|
case P:
|
|
return O;
|
|
case C:
|
|
return x;
|
|
default:
|
|
return w
|
|
}
|
|
}
|
|
function wl(e, t) {
|
|
var r = e.url;
|
|
return void 0 !== r && 0 !== r.indexOf("data:") || (r = t.url),
|
|
r
|
|
}
|
|
var Ol = function() {
|
|
function e(e) {
|
|
this.hls = void 0,
|
|
this.loaders = Object.create(null),
|
|
this.variableList = null,
|
|
this.onManifestLoaded = this.checkAutostartLoad,
|
|
this.hls = e,
|
|
this.registerListeners()
|
|
}
|
|
var t = e.prototype;
|
|
return t.startLoad = function(e) {}
|
|
,
|
|
t.stopLoad = function() {
|
|
this.destroyInternalLoaders()
|
|
}
|
|
,
|
|
t.registerListeners = function() {
|
|
var e = this.hls;
|
|
e.on(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.on(b.LEVEL_LOADING, this.onLevelLoading, this),
|
|
e.on(b.AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this),
|
|
e.on(b.SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this),
|
|
e.on(b.LEVELS_UPDATED, this.onLevelsUpdated, this)
|
|
}
|
|
,
|
|
t.unregisterListeners = function() {
|
|
var e = this.hls;
|
|
e.off(b.MANIFEST_LOADING, this.onManifestLoading, this),
|
|
e.off(b.LEVEL_LOADING, this.onLevelLoading, this),
|
|
e.off(b.AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this),
|
|
e.off(b.SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this),
|
|
e.off(b.LEVELS_UPDATED, this.onLevelsUpdated, this)
|
|
}
|
|
,
|
|
t.createInternalLoader = function(e) {
|
|
var t = this.hls.config
|
|
, r = t.pLoader
|
|
, i = t.loader
|
|
, n = new (r || i)(t);
|
|
return this.loaders[e.type] = n,
|
|
n
|
|
}
|
|
,
|
|
t.getInternalLoader = function(e) {
|
|
return this.loaders[e.type]
|
|
}
|
|
,
|
|
t.resetInternalLoader = function(e) {
|
|
this.loaders[e] && delete this.loaders[e]
|
|
}
|
|
,
|
|
t.destroyInternalLoaders = function() {
|
|
for (var e in this.loaders) {
|
|
var t = this.loaders[e];
|
|
t && t.destroy(),
|
|
this.resetInternalLoader(e)
|
|
}
|
|
}
|
|
,
|
|
t.destroy = function() {
|
|
this.variableList = null,
|
|
this.unregisterListeners(),
|
|
this.destroyInternalLoaders()
|
|
}
|
|
,
|
|
t.onManifestLoading = function(e, t) {
|
|
var r = t.url;
|
|
this.variableList = null,
|
|
this.load({
|
|
id: null,
|
|
level: 0,
|
|
responseType: "text",
|
|
type: D,
|
|
url: r,
|
|
deliveryDirectives: null,
|
|
levelOrTrack: null
|
|
})
|
|
}
|
|
,
|
|
t.onLevelLoading = function(e, t) {
|
|
var r = t.id
|
|
, i = t.level
|
|
, n = t.pathwayId
|
|
, a = t.url
|
|
, s = t.deliveryDirectives
|
|
, o = t.levelInfo;
|
|
this.load({
|
|
id: r,
|
|
level: i,
|
|
pathwayId: n,
|
|
responseType: "text",
|
|
type: _,
|
|
url: a,
|
|
deliveryDirectives: s,
|
|
levelOrTrack: o
|
|
})
|
|
}
|
|
,
|
|
t.onAudioTrackLoading = function(e, t) {
|
|
var r = t.id
|
|
, i = t.groupId
|
|
, n = t.url
|
|
, a = t.deliveryDirectives
|
|
, s = t.track;
|
|
this.load({
|
|
id: r,
|
|
groupId: i,
|
|
level: null,
|
|
responseType: "text",
|
|
type: P,
|
|
url: n,
|
|
deliveryDirectives: a,
|
|
levelOrTrack: s
|
|
})
|
|
}
|
|
,
|
|
t.onSubtitleTrackLoading = function(e, t) {
|
|
var r = t.id
|
|
, i = t.groupId
|
|
, n = t.url
|
|
, a = t.deliveryDirectives
|
|
, s = t.track;
|
|
this.load({
|
|
id: r,
|
|
groupId: i,
|
|
level: null,
|
|
responseType: "text",
|
|
type: C,
|
|
url: n,
|
|
deliveryDirectives: a,
|
|
levelOrTrack: s
|
|
})
|
|
}
|
|
,
|
|
t.onLevelsUpdated = function(e, t) {
|
|
var r = this.loaders[_];
|
|
if (r) {
|
|
var i = r.context;
|
|
i && !t.levels.some((function(e) {
|
|
return e === i.levelOrTrack
|
|
}
|
|
)) && (r.abort(),
|
|
delete this.loaders[_])
|
|
}
|
|
}
|
|
,
|
|
t.load = function(e) {
|
|
var t, r, i, n = this, s = this.hls.config, o = this.getInternalLoader(e);
|
|
if (o) {
|
|
var l = this.hls.logger
|
|
, u = o.context;
|
|
if (u && u.levelOrTrack === e.levelOrTrack && (u.url === e.url || u.deliveryDirectives && !e.deliveryDirectives))
|
|
return void (u.url === e.url ? l.log("[playlist-loader]: ignore " + e.url + " ongoing request") : l.log("[playlist-loader]: ignore " + e.url + " in favor of " + u.url));
|
|
l.log("[playlist-loader]: aborting previous loader for type: " + e.type),
|
|
o.abort()
|
|
}
|
|
if (r = e.type === D ? s.manifestLoadPolicy.default : a({}, s.playlistLoadPolicy.default, {
|
|
timeoutRetry: null,
|
|
errorRetry: null
|
|
}),
|
|
o = this.createInternalLoader(e),
|
|
A(null == (t = e.deliveryDirectives) ? void 0 : t.part) && (e.type === _ && null !== e.level ? i = this.hls.levels[e.level].details : e.type === P && null !== e.id ? i = this.hls.audioTracks[e.id].details : e.type === C && null !== e.id && (i = this.hls.subtitleTracks[e.id].details),
|
|
i)) {
|
|
var d = i.partTarget
|
|
, h = i.targetduration;
|
|
if (d && h) {
|
|
var f = 1e3 * Math.max(3 * d, .8 * h);
|
|
r = a({}, r, {
|
|
maxTimeToFirstByteMs: Math.min(f, r.maxTimeToFirstByteMs),
|
|
maxLoadTimeMs: Math.min(f, r.maxTimeToFirstByteMs)
|
|
})
|
|
}
|
|
}
|
|
var c = r.errorRetry || r.timeoutRetry || {}
|
|
, g = {
|
|
loadPolicy: r,
|
|
timeout: r.maxLoadTimeMs,
|
|
maxRetry: c.maxNumRetry || 0,
|
|
retryDelay: c.retryDelayMs || 0,
|
|
maxRetryDelay: c.maxRetryDelayMs || 0
|
|
}
|
|
, v = {
|
|
onSuccess: function(e, t, r, i) {
|
|
var a = n.getInternalLoader(r);
|
|
n.resetInternalLoader(r.type);
|
|
var s = e.data;
|
|
t.parsing.start = performance.now(),
|
|
qr.isMediaPlaylist(s) || r.type !== D ? n.handleTrackOrLevelPlaylist(e, t, r, i || null, a) : n.handleMasterPlaylist(e, t, r, i)
|
|
},
|
|
onError: function(e, t, r, i) {
|
|
n.handleNetworkError(t, r, !1, e, i)
|
|
},
|
|
onTimeout: function(e, t, r) {
|
|
n.handleNetworkError(t, r, !0, void 0, e)
|
|
}
|
|
};
|
|
o.load(e, g, v)
|
|
}
|
|
,
|
|
t.checkAutostartLoad = function() {
|
|
if (this.hls) {
|
|
var e = this.hls
|
|
, t = e.config
|
|
, r = t.autoStartLoad
|
|
, i = t.startPosition
|
|
, n = e.forceStartLoad;
|
|
(r || n) && (this.hls.logger.log((r ? "auto" : "force") + " startLoad with configured startPosition " + i),
|
|
this.hls.startLoad(i))
|
|
}
|
|
}
|
|
,
|
|
t.handleMasterPlaylist = function(e, t, r, i) {
|
|
var n = this
|
|
, a = this.hls
|
|
, s = e.data
|
|
, o = wl(e, r)
|
|
, l = qr.parseMasterPlaylist(s, o);
|
|
if (l.playlistParsingError)
|
|
return t.parsing.end = performance.now(),
|
|
void this.handleManifestParsingError(e, r, l.playlistParsingError, i, t);
|
|
var u = l.contentSteering
|
|
, d = l.levels
|
|
, h = l.sessionData
|
|
, f = l.sessionKeys
|
|
, c = l.startTimeOffset
|
|
, g = l.variableList;
|
|
this.variableList = g,
|
|
d.forEach((function(e) {
|
|
var t = e.unknownCodecs;
|
|
if (t)
|
|
for (var r = n.hls.config.preferManagedMediaSource, i = e.audioCodec, a = e.videoCodec, s = t.length; s--; ) {
|
|
var o = t[s];
|
|
Oe(o, "audio", r) ? (e.audioCodec = i = i ? i + "," + o : o,
|
|
Ce.audio[i.substring(0, 4)] = 2,
|
|
t.splice(s, 1)) : Oe(o, "video", r) && (e.videoCodec = a = a ? a + "," + o : o,
|
|
Ce.video[a.substring(0, 4)] = 2,
|
|
t.splice(s, 1))
|
|
}
|
|
}
|
|
));
|
|
var v = qr.parseMasterPlaylistMedia(s, o, l)
|
|
, m = v.AUDIO
|
|
, p = void 0 === m ? [] : m
|
|
, y = v.SUBTITLES
|
|
, E = v["CLOSED-CAPTIONS"];
|
|
p.length && (p.some((function(e) {
|
|
return !e.url
|
|
}
|
|
)) || !d[0].audioCodec || d[0].attrs.AUDIO || (this.hls.logger.log("[playlist-loader]: audio codec signaled in quality level, but no embedded audio track signaled, create one"),
|
|
p.unshift({
|
|
type: "main",
|
|
name: "main",
|
|
groupId: "main",
|
|
default: !1,
|
|
autoselect: !1,
|
|
forced: !1,
|
|
id: -1,
|
|
attrs: new pr({}),
|
|
bitrate: 0,
|
|
url: ""
|
|
}))),
|
|
a.trigger(b.MANIFEST_LOADED, {
|
|
levels: d,
|
|
audioTracks: p,
|
|
subtitles: y,
|
|
captions: E,
|
|
contentSteering: u,
|
|
url: o,
|
|
stats: t,
|
|
networkDetails: i,
|
|
sessionData: h,
|
|
sessionKeys: f,
|
|
startTimeOffset: c,
|
|
variableList: g
|
|
})
|
|
}
|
|
,
|
|
t.handleTrackOrLevelPlaylist = function(e, t, r, i, n) {
|
|
var a = this.hls
|
|
, s = r.id
|
|
, o = r.level
|
|
, l = r.type
|
|
, u = wl(e, r)
|
|
, d = A(o) ? o : A(s) ? s : 0
|
|
, h = Cl(r)
|
|
, f = qr.parseLevelPlaylist(e.data, u, d, h, 0, this.variableList);
|
|
if (l === D) {
|
|
var c = {
|
|
attrs: new pr({}),
|
|
bitrate: 0,
|
|
details: f,
|
|
name: "",
|
|
url: u
|
|
};
|
|
f.requestScheduled = t.loading.start + hi(f, 0),
|
|
a.trigger(b.MANIFEST_LOADED, {
|
|
levels: [c],
|
|
audioTracks: [],
|
|
url: u,
|
|
stats: t,
|
|
networkDetails: i,
|
|
sessionData: null,
|
|
sessionKeys: null,
|
|
contentSteering: null,
|
|
startTimeOffset: null,
|
|
variableList: null
|
|
})
|
|
}
|
|
t.parsing.end = performance.now(),
|
|
r.levelDetails = f,
|
|
this.handlePlaylistLoaded(f, e, t, r, i, n)
|
|
}
|
|
,
|
|
t.handleManifestParsingError = function(e, t, r, i, n) {
|
|
this.hls.trigger(b.ERROR, {
|
|
type: R.NETWORK_ERROR,
|
|
details: k.MANIFEST_PARSING_ERROR,
|
|
fatal: t.type === D,
|
|
url: e.url,
|
|
err: r,
|
|
error: r,
|
|
reason: r.message,
|
|
response: e,
|
|
context: t,
|
|
networkDetails: i,
|
|
stats: n
|
|
})
|
|
}
|
|
,
|
|
t.handleNetworkError = function(e, t, r, i, n) {
|
|
void 0 === r && (r = !1);
|
|
var a = "A network " + (r ? "timeout" : "error" + (i ? " (status " + i.code + ")" : "")) + " occurred while loading " + e.type;
|
|
e.type === _ ? a += ": " + e.level + " id: " + e.id : e.type !== P && e.type !== C || (a += " id: " + e.id + ' group-id: "' + e.groupId + '"');
|
|
var s = new Error(a);
|
|
this.hls.logger.warn("[playlist-loader]: " + a);
|
|
var o = k.UNKNOWN
|
|
, l = !1
|
|
, u = this.getInternalLoader(e);
|
|
switch (e.type) {
|
|
case D:
|
|
o = r ? k.MANIFEST_LOAD_TIMEOUT : k.MANIFEST_LOAD_ERROR,
|
|
l = !0;
|
|
break;
|
|
case _:
|
|
o = r ? k.LEVEL_LOAD_TIMEOUT : k.LEVEL_LOAD_ERROR,
|
|
l = !1;
|
|
break;
|
|
case P:
|
|
o = r ? k.AUDIO_TRACK_LOAD_TIMEOUT : k.AUDIO_TRACK_LOAD_ERROR,
|
|
l = !1;
|
|
break;
|
|
case C:
|
|
o = r ? k.SUBTITLE_TRACK_LOAD_TIMEOUT : k.SUBTITLE_LOAD_ERROR,
|
|
l = !1
|
|
}
|
|
u && this.resetInternalLoader(e.type);
|
|
var h = {
|
|
type: R.NETWORK_ERROR,
|
|
details: o,
|
|
fatal: l,
|
|
url: e.url,
|
|
loader: u,
|
|
context: e,
|
|
error: s,
|
|
networkDetails: t,
|
|
stats: n
|
|
};
|
|
if (i) {
|
|
var f = (null == t ? void 0 : t.url) || e.url;
|
|
h.response = d({
|
|
url: f,
|
|
data: void 0
|
|
}, i)
|
|
}
|
|
this.hls.trigger(b.ERROR, h)
|
|
}
|
|
,
|
|
t.handlePlaylistLoaded = function(e, t, r, i, n, a) {
|
|
var s = this.hls
|
|
, o = i.type
|
|
, l = i.level
|
|
, u = i.levelOrTrack
|
|
, d = i.id
|
|
, h = i.groupId
|
|
, f = i.deliveryDirectives
|
|
, c = wl(t, i)
|
|
, g = Cl(i)
|
|
, v = "number" == typeof i.level && g === w ? l : void 0
|
|
, m = e.playlistParsingError;
|
|
if (m) {
|
|
if (this.hls.logger.warn(m + " " + e.url),
|
|
!s.config.ignorePlaylistParsingErrors)
|
|
return void s.trigger(b.ERROR, {
|
|
type: R.NETWORK_ERROR,
|
|
details: k.LEVEL_PARSING_ERROR,
|
|
fatal: !1,
|
|
url: c,
|
|
error: m,
|
|
reason: m.message,
|
|
response: t,
|
|
context: i,
|
|
level: v,
|
|
parent: g,
|
|
networkDetails: n,
|
|
stats: r
|
|
});
|
|
e.playlistParsingError = null
|
|
}
|
|
if (e.fragments.length)
|
|
switch (e.live && a && (a.getCacheAge && (e.ageHeader = a.getCacheAge() || 0),
|
|
a.getCacheAge && !isNaN(e.ageHeader) || (e.ageHeader = 0)),
|
|
o) {
|
|
case D:
|
|
case _:
|
|
if (v)
|
|
if (u) {
|
|
if (u !== s.levels[v]) {
|
|
var p = s.levels.indexOf(u);
|
|
p > -1 && (v = p)
|
|
}
|
|
} else
|
|
v = 0;
|
|
s.trigger(b.LEVEL_LOADED, {
|
|
details: e,
|
|
levelInfo: u || s.levels[0],
|
|
level: v || 0,
|
|
id: d || 0,
|
|
stats: r,
|
|
networkDetails: n,
|
|
deliveryDirectives: f,
|
|
withoutMultiVariant: o === D
|
|
});
|
|
break;
|
|
case P:
|
|
s.trigger(b.AUDIO_TRACK_LOADED, {
|
|
details: e,
|
|
track: u,
|
|
id: d || 0,
|
|
groupId: h || "",
|
|
stats: r,
|
|
networkDetails: n,
|
|
deliveryDirectives: f
|
|
});
|
|
break;
|
|
case C:
|
|
s.trigger(b.SUBTITLE_TRACK_LOADED, {
|
|
details: e,
|
|
track: u,
|
|
id: d || 0,
|
|
groupId: h || "",
|
|
stats: r,
|
|
networkDetails: n,
|
|
deliveryDirectives: f
|
|
})
|
|
}
|
|
else {
|
|
var y = e.playlistParsingError = new Error("No Segments found in Playlist");
|
|
s.trigger(b.ERROR, {
|
|
type: R.NETWORK_ERROR,
|
|
details: k.LEVEL_EMPTY_ERROR,
|
|
fatal: !1,
|
|
url: c,
|
|
error: y,
|
|
reason: y.message,
|
|
response: t,
|
|
context: i,
|
|
level: v,
|
|
parent: g,
|
|
networkDetails: n,
|
|
stats: r
|
|
})
|
|
}
|
|
}
|
|
,
|
|
e
|
|
}()
|
|
, xl = function() {
|
|
function e(t) {
|
|
void 0 === t && (t = {}),
|
|
this.config = void 0,
|
|
this.userConfig = void 0,
|
|
this.logger = void 0,
|
|
this.coreComponents = void 0,
|
|
this.networkControllers = void 0,
|
|
this._emitter = new E,
|
|
this._autoLevelCapping = -1,
|
|
this._maxHdcpLevel = null,
|
|
this.abrController = void 0,
|
|
this.bufferController = void 0,
|
|
this.capLevelController = void 0,
|
|
this.latencyController = void 0,
|
|
this.levelController = void 0,
|
|
this.streamController = void 0,
|
|
this.audioStreamController = void 0,
|
|
this.subtititleStreamController = void 0,
|
|
this.audioTrackController = void 0,
|
|
this.subtitleTrackController = void 0,
|
|
this.interstitialsController = void 0,
|
|
this.gapController = void 0,
|
|
this.emeController = void 0,
|
|
this.cmcdController = void 0,
|
|
this._media = null,
|
|
this._url = null,
|
|
this._sessionId = void 0,
|
|
this.triggeringException = void 0,
|
|
this.started = !1;
|
|
var r = this.logger = H(t.debug || !1, "Hls instance", t.assetPlayerId)
|
|
, i = this.config = function(e, t, r) {
|
|
if ((t.liveSyncDurationCount || t.liveMaxLatencyDurationCount) && (t.liveSyncDuration || t.liveMaxLatencyDuration))
|
|
throw new Error("Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration");
|
|
if (void 0 !== t.liveMaxLatencyDurationCount && (void 0 === t.liveSyncDurationCount || t.liveMaxLatencyDurationCount <= t.liveSyncDurationCount))
|
|
throw new Error('Illegal hls.js config: "liveMaxLatencyDurationCount" must be greater than "liveSyncDurationCount"');
|
|
if (void 0 !== t.liveMaxLatencyDuration && (void 0 === t.liveSyncDuration || t.liveMaxLatencyDuration <= t.liveSyncDuration))
|
|
throw new Error('Illegal hls.js config: "liveMaxLatencyDuration" must be greater than "liveSyncDuration"');
|
|
var i = cl(e)
|
|
, n = ["TimeOut", "MaxRetry", "RetryDelay", "MaxRetryTimeout"];
|
|
return ["manifest", "level", "frag"].forEach((function(e) {
|
|
var a = ("level" === e ? "playlist" : e) + "LoadPolicy"
|
|
, s = void 0 === t[a]
|
|
, o = [];
|
|
n.forEach((function(r) {
|
|
var n = e + "Loading" + r
|
|
, l = t[n];
|
|
if (void 0 !== l && s) {
|
|
o.push(n);
|
|
var u = i[a].default;
|
|
switch (t[a] = {
|
|
default: u
|
|
},
|
|
r) {
|
|
case "TimeOut":
|
|
u.maxLoadTimeMs = l,
|
|
u.maxTimeToFirstByteMs = l;
|
|
break;
|
|
case "MaxRetry":
|
|
u.errorRetry.maxNumRetry = l,
|
|
u.timeoutRetry.maxNumRetry = l;
|
|
break;
|
|
case "RetryDelay":
|
|
u.errorRetry.retryDelayMs = l,
|
|
u.timeoutRetry.retryDelayMs = l;
|
|
break;
|
|
case "MaxRetryTimeout":
|
|
u.errorRetry.maxRetryDelayMs = l,
|
|
u.timeoutRetry.maxRetryDelayMs = l
|
|
}
|
|
}
|
|
}
|
|
)),
|
|
o.length && r.warn('hls.js config: "' + o.join('", "') + '" setting(s) are deprecated, use "' + a + '": ' + lt(t[a]))
|
|
}
|
|
)),
|
|
d(d({}, i), t)
|
|
}(e.DefaultConfig, t, r);
|
|
this.userConfig = t,
|
|
i.progressive && gl(i, r);
|
|
var n = i.abrController
|
|
, a = i.bufferController
|
|
, s = i.capLevelController
|
|
, o = i.errorController
|
|
, l = i.fpsController
|
|
, u = new o(this)
|
|
, h = this.abrController = new n(this)
|
|
, f = new Wt(this)
|
|
, c = i.interstitialsController
|
|
, g = c ? this.interstitialsController = new c(this,e) : null
|
|
, v = this.bufferController = new a(this,f)
|
|
, m = this.capLevelController = new s(this)
|
|
, p = new l(this)
|
|
, y = new Ol(this)
|
|
, T = i.contentSteeringController
|
|
, S = T ? new T(this) : null
|
|
, A = this.levelController = new Il(this,S)
|
|
, L = new Al(this)
|
|
, I = new _l(this.config,this.logger)
|
|
, R = this.streamController = new Dl(this,f,I)
|
|
, k = this.gapController = new vl(this,f);
|
|
m.setStreamController(R),
|
|
p.setStreamController(R);
|
|
var D = [y, A, R];
|
|
g && D.splice(1, 0, g),
|
|
S && D.splice(1, 0, S),
|
|
this.networkControllers = D;
|
|
var _ = [h, v, k, m, p, L, f];
|
|
this.audioTrackController = this.createController(i.audioTrackController, D);
|
|
var P = i.audioStreamController;
|
|
P && D.push(this.audioStreamController = new P(this,f,I)),
|
|
this.subtitleTrackController = this.createController(i.subtitleTrackController, D);
|
|
var C = i.subtitleStreamController;
|
|
C && D.push(this.subtititleStreamController = new C(this,f,I)),
|
|
this.createController(i.timelineController, _),
|
|
I.emeController = this.emeController = this.createController(i.emeController, _),
|
|
this.cmcdController = this.createController(i.cmcdController, _),
|
|
this.latencyController = this.createController(Ll, _),
|
|
this.coreComponents = _,
|
|
D.push(u);
|
|
var w = u.onErrorOut;
|
|
"function" == typeof w && this.on(b.ERROR, w, u),
|
|
this.on(b.MANIFEST_LOADED, y.onManifestLoaded, y)
|
|
}
|
|
e.isMSESupported = function() {
|
|
return bl()
|
|
}
|
|
,
|
|
e.isSupported = function() {
|
|
return function() {
|
|
if (!bl())
|
|
return !1;
|
|
var e = W();
|
|
return "function" == typeof (null == e ? void 0 : e.isTypeSupported) && (["avc1.42E01E,mp4a.40.2", "av01.0.01M.08", "vp09.00.50.08"].some((function(t) {
|
|
return e.isTypeSupported(Me(t, "video"))
|
|
}
|
|
)) || ["mp4a.40.2", "fLaC"].some((function(t) {
|
|
return e.isTypeSupported(Me(t, "audio"))
|
|
}
|
|
)))
|
|
}()
|
|
}
|
|
,
|
|
e.getMediaSource = function() {
|
|
return W()
|
|
}
|
|
;
|
|
var t = e.prototype;
|
|
return t.createController = function(e, t) {
|
|
if (e) {
|
|
var r = new e(this);
|
|
return t && t.push(r),
|
|
r
|
|
}
|
|
return null
|
|
}
|
|
,
|
|
t.on = function(e, t, r) {
|
|
void 0 === r && (r = this),
|
|
this._emitter.on(e, t, r)
|
|
}
|
|
,
|
|
t.once = function(e, t, r) {
|
|
void 0 === r && (r = this),
|
|
this._emitter.once(e, t, r)
|
|
}
|
|
,
|
|
t.removeAllListeners = function(e) {
|
|
this._emitter.removeAllListeners(e)
|
|
}
|
|
,
|
|
t.off = function(e, t, r, i) {
|
|
void 0 === r && (r = this),
|
|
this._emitter.off(e, t, r, i)
|
|
}
|
|
,
|
|
t.listeners = function(e) {
|
|
return this._emitter.listeners(e)
|
|
}
|
|
,
|
|
t.emit = function(e, t, r) {
|
|
return this._emitter.emit(e, t, r)
|
|
}
|
|
,
|
|
t.trigger = function(e, t) {
|
|
if (this.config.debug)
|
|
return this.emit(e, e, t);
|
|
try {
|
|
return this.emit(e, e, t)
|
|
} catch (t) {
|
|
if (this.logger.error("An internal error happened while handling event " + e + '. Error message: "' + t.message + '". Here is a stacktrace:', t),
|
|
!this.triggeringException) {
|
|
this.triggeringException = !0;
|
|
var r = e === b.ERROR;
|
|
this.trigger(b.ERROR, {
|
|
type: R.OTHER_ERROR,
|
|
details: k.INTERNAL_EXCEPTION,
|
|
fatal: r,
|
|
event: e,
|
|
error: t
|
|
}),
|
|
this.triggeringException = !1
|
|
}
|
|
}
|
|
return !1
|
|
}
|
|
,
|
|
t.listenerCount = function(e) {
|
|
return this._emitter.listenerCount(e)
|
|
}
|
|
,
|
|
t.destroy = function() {
|
|
this.logger.log("destroy"),
|
|
this.trigger(b.DESTROYING, void 0),
|
|
this.detachMedia(),
|
|
this.removeAllListeners(),
|
|
this._autoLevelCapping = -1,
|
|
this._url = null,
|
|
this.networkControllers.forEach((function(e) {
|
|
return e.destroy()
|
|
}
|
|
)),
|
|
this.networkControllers.length = 0,
|
|
this.coreComponents.forEach((function(e) {
|
|
return e.destroy()
|
|
}
|
|
)),
|
|
this.coreComponents.length = 0;
|
|
var e = this.config;
|
|
e.xhrSetup = e.fetchSetup = void 0,
|
|
this.userConfig = null
|
|
}
|
|
,
|
|
t.attachMedia = function(e) {
|
|
if (!e || "media"in e && !e.media) {
|
|
var t = new Error("attachMedia failed: invalid argument (" + e + ")");
|
|
this.trigger(b.ERROR, {
|
|
type: R.OTHER_ERROR,
|
|
details: k.ATTACH_MEDIA_ERROR,
|
|
fatal: !0,
|
|
error: t
|
|
})
|
|
} else {
|
|
this.logger.log("attachMedia"),
|
|
this._media && (this.logger.warn("media must be detached before attaching"),
|
|
this.detachMedia());
|
|
var r = "media"in e
|
|
, i = r ? e.media : e
|
|
, n = r ? e : {
|
|
media: i
|
|
};
|
|
this._media = i,
|
|
this.trigger(b.MEDIA_ATTACHING, n)
|
|
}
|
|
}
|
|
,
|
|
t.detachMedia = function() {
|
|
this.logger.log("detachMedia"),
|
|
this.trigger(b.MEDIA_DETACHING, {}),
|
|
this._media = null
|
|
}
|
|
,
|
|
t.transferMedia = function() {
|
|
this._media = null;
|
|
var e = this.bufferController.transferMedia();
|
|
return this.trigger(b.MEDIA_DETACHING, {
|
|
transferMedia: e
|
|
}),
|
|
e
|
|
}
|
|
,
|
|
t.loadSource = function(e) {
|
|
this.stopLoad();
|
|
var t = this.media
|
|
, r = this._url
|
|
, i = this._url = S.buildAbsoluteURL(self.location.href, e, {
|
|
alwaysNormalize: !0
|
|
});
|
|
this._autoLevelCapping = -1,
|
|
this._maxHdcpLevel = null,
|
|
this.logger.log("loadSource:" + i),
|
|
t && r && (r !== i || this.bufferController.hasSourceTypes()) && (this.detachMedia(),
|
|
this.attachMedia(t)),
|
|
this.trigger(b.MANIFEST_LOADING, {
|
|
url: e
|
|
})
|
|
}
|
|
,
|
|
t.startLoad = function(e, t) {
|
|
void 0 === e && (e = -1),
|
|
this.logger.log("startLoad(" + e + (t ? ", <skip seek to start>" : "") + ")"),
|
|
this.started = !0,
|
|
this.resumeBuffering();
|
|
for (var r = 0; r < this.networkControllers.length && (this.networkControllers[r].startLoad(e, t),
|
|
this.started && this.networkControllers); r++)
|
|
;
|
|
}
|
|
,
|
|
t.stopLoad = function() {
|
|
this.logger.log("stopLoad"),
|
|
this.started = !1;
|
|
for (var e = 0; e < this.networkControllers.length && (this.networkControllers[e].stopLoad(),
|
|
!this.started && this.networkControllers); e++)
|
|
;
|
|
}
|
|
,
|
|
t.resumeBuffering = function() {
|
|
this.bufferingEnabled || (this.logger.log("resume buffering"),
|
|
this.networkControllers.forEach((function(e) {
|
|
e.resumeBuffering && e.resumeBuffering()
|
|
}
|
|
)))
|
|
}
|
|
,
|
|
t.pauseBuffering = function() {
|
|
this.bufferingEnabled && (this.logger.log("pause buffering"),
|
|
this.networkControllers.forEach((function(e) {
|
|
e.pauseBuffering && e.pauseBuffering()
|
|
}
|
|
)))
|
|
}
|
|
,
|
|
t.swapAudioCodec = function() {
|
|
this.logger.log("swapAudioCodec"),
|
|
this.streamController.swapAudioCodec()
|
|
}
|
|
,
|
|
t.recoverMediaError = function() {
|
|
this.logger.log("recoverMediaError");
|
|
var e = this._media
|
|
, t = null == e ? void 0 : e.currentTime;
|
|
this.detachMedia(),
|
|
e && (this.attachMedia(e),
|
|
t && this.startLoad(t))
|
|
}
|
|
,
|
|
t.removeLevel = function(e) {
|
|
this.levelController.removeLevel(e)
|
|
}
|
|
,
|
|
t.setAudioOption = function(e) {
|
|
var t;
|
|
return (null == (t = this.audioTrackController) ? void 0 : t.setAudioOption(e)) || null
|
|
}
|
|
,
|
|
t.setSubtitleOption = function(e) {
|
|
var t;
|
|
return (null == (t = this.subtitleTrackController) ? void 0 : t.setSubtitleOption(e)) || null
|
|
}
|
|
,
|
|
t.getMediaDecodingInfo = function(e, t) {
|
|
return void 0 === t && (t = this.allAudioTracks),
|
|
Qe(e, dt(t), navigator.mediaCapabilities)
|
|
}
|
|
,
|
|
i(e, [{
|
|
key: "url",
|
|
get: function() {
|
|
return this._url
|
|
}
|
|
}, {
|
|
key: "hasEnoughToStart",
|
|
get: function() {
|
|
return this.streamController.hasEnoughToStart
|
|
}
|
|
}, {
|
|
key: "startPosition",
|
|
get: function() {
|
|
return this.streamController.startPositionValue
|
|
}
|
|
}, {
|
|
key: "loadingEnabled",
|
|
get: function() {
|
|
return this.started
|
|
}
|
|
}, {
|
|
key: "bufferingEnabled",
|
|
get: function() {
|
|
return this.streamController.bufferingEnabled
|
|
}
|
|
}, {
|
|
key: "inFlightFragments",
|
|
get: function() {
|
|
var e, t = ((e = {})[w] = this.streamController.inFlightFrag,
|
|
e);
|
|
return this.audioStreamController && (t[O] = this.audioStreamController.inFlightFrag),
|
|
this.subtititleStreamController && (t[x] = this.subtititleStreamController.inFlightFrag),
|
|
t
|
|
}
|
|
}, {
|
|
key: "sessionId",
|
|
get: function() {
|
|
var e = this._sessionId;
|
|
return e || (e = this._sessionId = function() {
|
|
try {
|
|
return crypto.randomUUID()
|
|
} catch (i) {
|
|
try {
|
|
var e = URL.createObjectURL(new Blob)
|
|
, t = e.toString();
|
|
return URL.revokeObjectURL(e),
|
|
t.slice(t.lastIndexOf("/") + 1)
|
|
} catch (e) {
|
|
var r = (new Date).getTime();
|
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (function(e) {
|
|
var t = (r + 16 * Math.random()) % 16 | 0;
|
|
return r = Math.floor(r / 16),
|
|
("x" == e ? t : 3 & t | 8).toString(16)
|
|
}
|
|
))
|
|
}
|
|
}
|
|
}()),
|
|
e
|
|
}
|
|
}, {
|
|
key: "levels",
|
|
get: function() {
|
|
var e = this.levelController.levels;
|
|
return e || []
|
|
}
|
|
}, {
|
|
key: "latestLevelDetails",
|
|
get: function() {
|
|
return this.streamController.getLevelDetails() || null
|
|
}
|
|
}, {
|
|
key: "loadLevelObj",
|
|
get: function() {
|
|
return this.levelController.loadLevelObj
|
|
}
|
|
}, {
|
|
key: "currentLevel",
|
|
get: function() {
|
|
return this.streamController.currentLevel
|
|
},
|
|
set: function(e) {
|
|
this.logger.log("set currentLevel:" + e),
|
|
this.levelController.manualLevel = e,
|
|
this.streamController.immediateLevelSwitch()
|
|
}
|
|
}, {
|
|
key: "nextLevel",
|
|
get: function() {
|
|
return this.streamController.nextLevel
|
|
},
|
|
set: function(e) {
|
|
this.logger.log("set nextLevel:" + e),
|
|
this.levelController.manualLevel = e,
|
|
this.streamController.nextLevelSwitch()
|
|
}
|
|
}, {
|
|
key: "loadLevel",
|
|
get: function() {
|
|
return this.levelController.level
|
|
},
|
|
set: function(e) {
|
|
this.logger.log("set loadLevel:" + e),
|
|
this.levelController.manualLevel = e
|
|
}
|
|
}, {
|
|
key: "nextLoadLevel",
|
|
get: function() {
|
|
return this.levelController.nextLoadLevel
|
|
},
|
|
set: function(e) {
|
|
this.levelController.nextLoadLevel = e
|
|
}
|
|
}, {
|
|
key: "firstLevel",
|
|
get: function() {
|
|
return Math.max(this.levelController.firstLevel, this.minAutoLevel)
|
|
},
|
|
set: function(e) {
|
|
this.logger.log("set firstLevel:" + e),
|
|
this.levelController.firstLevel = e
|
|
}
|
|
}, {
|
|
key: "startLevel",
|
|
get: function() {
|
|
var e = this.levelController.startLevel;
|
|
return -1 === e && this.abrController.forcedAutoLevel > -1 ? this.abrController.forcedAutoLevel : e
|
|
},
|
|
set: function(e) {
|
|
this.logger.log("set startLevel:" + e),
|
|
-1 !== e && (e = Math.max(e, this.minAutoLevel)),
|
|
this.levelController.startLevel = e
|
|
}
|
|
}, {
|
|
key: "capLevelToPlayerSize",
|
|
get: function() {
|
|
return this.config.capLevelToPlayerSize
|
|
},
|
|
set: function(e) {
|
|
var t = !!e;
|
|
t !== this.config.capLevelToPlayerSize && (t ? this.capLevelController.startCapping() : (this.capLevelController.stopCapping(),
|
|
this.autoLevelCapping = -1,
|
|
this.streamController.nextLevelSwitch()),
|
|
this.config.capLevelToPlayerSize = t)
|
|
}
|
|
}, {
|
|
key: "autoLevelCapping",
|
|
get: function() {
|
|
return this._autoLevelCapping
|
|
},
|
|
set: function(e) {
|
|
this._autoLevelCapping !== e && (this.logger.log("set autoLevelCapping:" + e),
|
|
this._autoLevelCapping = e,
|
|
this.levelController.checkMaxAutoUpdated())
|
|
}
|
|
}, {
|
|
key: "bandwidthEstimate",
|
|
get: function() {
|
|
var e = this.abrController.bwEstimator;
|
|
return e ? e.getEstimate() : NaN
|
|
},
|
|
set: function(e) {
|
|
this.abrController.resetEstimator(e)
|
|
}
|
|
}, {
|
|
key: "abrEwmaDefaultEstimate",
|
|
get: function() {
|
|
var e = this.abrController.bwEstimator;
|
|
return e ? e.defaultEstimate : NaN
|
|
}
|
|
}, {
|
|
key: "ttfbEstimate",
|
|
get: function() {
|
|
var e = this.abrController.bwEstimator;
|
|
return e ? e.getEstimateTTFB() : NaN
|
|
}
|
|
}, {
|
|
key: "maxHdcpLevel",
|
|
get: function() {
|
|
return this._maxHdcpLevel
|
|
},
|
|
set: function(e) {
|
|
(function(e) {
|
|
return Ze.indexOf(e) > -1
|
|
}
|
|
)(e) && this._maxHdcpLevel !== e && (this._maxHdcpLevel = e,
|
|
this.levelController.checkMaxAutoUpdated())
|
|
}
|
|
}, {
|
|
key: "autoLevelEnabled",
|
|
get: function() {
|
|
return -1 === this.levelController.manualLevel
|
|
}
|
|
}, {
|
|
key: "manualLevel",
|
|
get: function() {
|
|
return this.levelController.manualLevel
|
|
}
|
|
}, {
|
|
key: "minAutoLevel",
|
|
get: function() {
|
|
var e = this.levels
|
|
, t = this.config.minAutoBitrate;
|
|
if (!e)
|
|
return 0;
|
|
for (var r = e.length, i = 0; i < r; i++)
|
|
if (e[i].maxBitrate >= t)
|
|
return i;
|
|
return 0
|
|
}
|
|
}, {
|
|
key: "maxAutoLevel",
|
|
get: function() {
|
|
var e, t = this.levels, r = this.autoLevelCapping, i = this.maxHdcpLevel;
|
|
if (e = -1 === r && null != t && t.length ? t.length - 1 : r,
|
|
i)
|
|
for (var n = e; n--; ) {
|
|
var a = t[n].attrs["HDCP-LEVEL"];
|
|
if (a && a <= i)
|
|
return n
|
|
}
|
|
return e
|
|
}
|
|
}, {
|
|
key: "firstAutoLevel",
|
|
get: function() {
|
|
return this.abrController.firstAutoLevel
|
|
}
|
|
}, {
|
|
key: "nextAutoLevel",
|
|
get: function() {
|
|
return this.abrController.nextAutoLevel
|
|
},
|
|
set: function(e) {
|
|
this.abrController.nextAutoLevel = e
|
|
}
|
|
}, {
|
|
key: "playingDate",
|
|
get: function() {
|
|
return this.streamController.currentProgramDateTime
|
|
}
|
|
}, {
|
|
key: "mainForwardBufferInfo",
|
|
get: function() {
|
|
return this.streamController.getMainFwdBufferInfo()
|
|
}
|
|
}, {
|
|
key: "maxBufferLength",
|
|
get: function() {
|
|
return this.streamController.maxBufferLength
|
|
}
|
|
}, {
|
|
key: "allAudioTracks",
|
|
get: function() {
|
|
var e = this.audioTrackController;
|
|
return e ? e.allAudioTracks : []
|
|
}
|
|
}, {
|
|
key: "audioTracks",
|
|
get: function() {
|
|
var e = this.audioTrackController;
|
|
return e ? e.audioTracks : []
|
|
}
|
|
}, {
|
|
key: "audioTrack",
|
|
get: function() {
|
|
var e = this.audioTrackController;
|
|
return e ? e.audioTrack : -1
|
|
},
|
|
set: function(e) {
|
|
var t = this.audioTrackController;
|
|
t && (t.audioTrack = e)
|
|
}
|
|
}, {
|
|
key: "allSubtitleTracks",
|
|
get: function() {
|
|
var e = this.subtitleTrackController;
|
|
return e ? e.allSubtitleTracks : []
|
|
}
|
|
}, {
|
|
key: "subtitleTracks",
|
|
get: function() {
|
|
var e = this.subtitleTrackController;
|
|
return e ? e.subtitleTracks : []
|
|
}
|
|
}, {
|
|
key: "subtitleTrack",
|
|
get: function() {
|
|
var e = this.subtitleTrackController;
|
|
return e ? e.subtitleTrack : -1
|
|
},
|
|
set: function(e) {
|
|
var t = this.subtitleTrackController;
|
|
t && (t.subtitleTrack = e)
|
|
}
|
|
}, {
|
|
key: "media",
|
|
get: function() {
|
|
return this._media
|
|
}
|
|
}, {
|
|
key: "subtitleDisplay",
|
|
get: function() {
|
|
var e = this.subtitleTrackController;
|
|
return !!e && e.subtitleDisplay
|
|
},
|
|
set: function(e) {
|
|
var t = this.subtitleTrackController;
|
|
t && (t.subtitleDisplay = e)
|
|
}
|
|
}, {
|
|
key: "lowLatencyMode",
|
|
get: function() {
|
|
return this.config.lowLatencyMode
|
|
},
|
|
set: function(e) {
|
|
this.config.lowLatencyMode = e
|
|
}
|
|
}, {
|
|
key: "liveSyncPosition",
|
|
get: function() {
|
|
return this.latencyController.liveSyncPosition
|
|
}
|
|
}, {
|
|
key: "latency",
|
|
get: function() {
|
|
return this.latencyController.latency
|
|
}
|
|
}, {
|
|
key: "maxLatency",
|
|
get: function() {
|
|
return this.latencyController.maxLatency
|
|
}
|
|
}, {
|
|
key: "targetLatency",
|
|
get: function() {
|
|
return this.latencyController.targetLatency
|
|
},
|
|
set: function(e) {
|
|
this.latencyController.targetLatency = e
|
|
}
|
|
}, {
|
|
key: "drift",
|
|
get: function() {
|
|
return this.latencyController.drift
|
|
}
|
|
}, {
|
|
key: "forceStartLoad",
|
|
get: function() {
|
|
return this.streamController.forceStartLoad
|
|
}
|
|
}, {
|
|
key: "pathways",
|
|
get: function() {
|
|
return this.levelController.pathways
|
|
}
|
|
}, {
|
|
key: "pathwayPriority",
|
|
get: function() {
|
|
return this.levelController.pathwayPriority
|
|
},
|
|
set: function(e) {
|
|
this.levelController.pathwayPriority = e
|
|
}
|
|
}, {
|
|
key: "bufferedToEnd",
|
|
get: function() {
|
|
var e;
|
|
return !(null == (e = this.bufferController) || !e.bufferedToEnd)
|
|
}
|
|
}, {
|
|
key: "interstitialsManager",
|
|
get: function() {
|
|
var e;
|
|
return (null == (e = this.interstitialsController) ? void 0 : e.interstitialsManager) || null
|
|
}
|
|
}], [{
|
|
key: "version",
|
|
get: function() {
|
|
return ua
|
|
}
|
|
}, {
|
|
key: "Events",
|
|
get: function() {
|
|
return b
|
|
}
|
|
}, {
|
|
key: "MetadataSchema",
|
|
get: function() {
|
|
return Ji
|
|
}
|
|
}, {
|
|
key: "ErrorTypes",
|
|
get: function() {
|
|
return R
|
|
}
|
|
}, {
|
|
key: "ErrorDetails",
|
|
get: function() {
|
|
return k
|
|
}
|
|
}, {
|
|
key: "DefaultConfig",
|
|
get: function() {
|
|
return e.defaultConfig ? e.defaultConfig : fl
|
|
},
|
|
set: function(t) {
|
|
e.defaultConfig = t
|
|
}
|
|
}])
|
|
}();
|
|
return xl.defaultConfig = void 0,
|
|
xl
|
|
}
|
|
,
|
|
"object" == typeof exports && "undefined" != typeof module ? module.exports = i() : "function" == typeof define && define.amd ? define(i) : (r = "undefined" != typeof globalThis ? globalThis : r || self).Hls = i()
|
|
}(!1);
|
|
//# sourceMappingURL=hls.min.js.map
|
|
|