hls.js 1.6.0-beta.3.0.canary.10979 → 1.6.0-beta.3.0.canary.10981
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hls.js +4424 -4377
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +5652 -5590
- package/dist/hls.light.js.map +1 -1
- package/dist/hls.light.min.js +1 -1
- package/dist/hls.light.min.js.map +1 -1
- package/dist/hls.light.mjs +3794 -3736
- package/dist/hls.light.mjs.map +1 -1
- package/dist/hls.min.js +1 -1
- package/dist/hls.min.js.map +1 -1
- package/dist/hls.mjs +4440 -4395
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/dist/hls.worker.js.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +2 -1
- package/src/controller/abr-controller.ts +6 -4
- package/src/controller/audio-stream-controller.ts +7 -5
- package/src/controller/buffer-controller.ts +13 -7
- package/src/controller/content-steering-controller.ts +3 -2
- package/src/controller/eme-controller.ts +3 -2
- package/src/controller/error-controller.ts +14 -0
- package/src/controller/gap-controller.ts +2 -1
- package/src/controller/id3-track-controller.ts +2 -1
- package/src/controller/level-controller.ts +2 -1
- package/src/controller/stream-controller.ts +8 -6
- package/src/demux/transmuxer-interface.ts +3 -2
- package/src/utils/cea-608-parser.ts +4 -9
- package/src/utils/codecs.ts +14 -1
- package/src/utils/level-helper.ts +2 -1
- package/src/utils/mediacapabilities-helper.ts +31 -4
- package/src/utils/mp4-tools.ts +2 -3
- package/src/utils/rendition-helper.ts +2 -3
- package/src/utils/safe-json-stringify.ts +10 -3
package/dist/hls.worker.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"hls.worker.js.map","sources":["node_modules/eventemitter3/index.js","node_modules/@svta/common-media-library/dist/id3/util/isId3Footer.js","node_modules/@svta/common-media-library/dist/id3/util/isId3Header.js","node_modules/@svta/common-media-library/dist/id3/util/readId3Size.js","node_modules/@svta/common-media-library/dist/id3/getId3Data.js","src/errors.ts","src/events.ts","src/utils/logger.ts","src/demux/audio/adts.ts","src/polyfills/number.ts","node_modules/@svta/common-media-library/dist/id3/canParseId3.js","node_modules/@svta/common-media-library/dist/utils/utf8ArrayToStr.js","node_modules/@svta/common-media-library/dist/id3/util/utf8.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3ImageFrame.js","node_modules/@svta/common-media-library/dist/id3/util/toArrayBuffer.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3Frame.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3PrivFrame.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3UrlFrame.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3TextFrame.js","node_modules/@svta/common-media-library/dist/id3/util/getId3FrameData.js","node_modules/@svta/common-media-library/dist/id3/getId3Frames.js","node_modules/@svta/common-media-library/dist/id3/isId3TimestampFrame.js","node_modules/@svta/common-media-library/dist/id3/util/readId3Timestamp.js","node_modules/@svta/common-media-library/dist/id3/getId3Timestamp.js","src/types/demuxer.ts","src/utils/hex.ts","src/utils/typed-array.ts","node_modules/url-toolkit/src/url-toolkit.js","src/loader/fragment.ts","src/utils/mp4-tools.ts","src/demux/dummy-demuxed-track.ts","src/demux/audio/base-audio-demuxer.ts","src/demux/audio/mpegaudio.ts","src/demux/audio/aacdemuxer.ts","src/demux/audio/dolby.ts","src/demux/audio/ac3-demuxer.ts","src/demux/audio/mp3demuxer.ts","src/crypt/decrypter-aes-mode.ts","src/crypt/aes-crypto.ts","src/crypt/aes-decryptor.ts","src/crypt/fast-aes-key.ts","src/crypt/decrypter.ts","src/demux/mp4demuxer.ts","src/demux/sample-aes.ts","src/demux/video/base-video-parser.ts","src/demux/video/exp-golomb.ts","src/demux/video/avc-video-parser.ts","src/demux/video/hevc-video-parser.ts","src/demux/tsdemuxer.ts","src/remux/aac-helper.ts","src/remux/mp4-generator.ts","src/types/loader.ts","src/utils/timescale-conversion.ts","src/remux/mp4-remuxer.ts","src/utils/mediasource-helper.ts","src/utils/codecs.ts","src/remux/passthrough-remuxer.ts","src/demux/transmuxer.ts","src/utils/encryption-methods-util.ts","src/demux/transmuxer-worker.ts"],"sourcesContent":["'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') {\n throw new TypeError('The listener must be a function');\n }\n\n var listener = new EE(fn, context || emitter, once)\n , evt = prefix ? prefix + event : event;\n\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [emitter._events[evt], listener];\n\n return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new Events();\n else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n var evt = prefix ? prefix + event : event\n , handlers = this._events[evt];\n\n if (!handlers) return [];\n if (handlers.fn) return [handlers.fn];\n\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n ee[i] = handlers[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = prefix ? prefix + event : event\n , listeners = this._events[evt];\n\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n clearEvent(this, evt);\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn &&\n (!once || listeners.once) &&\n (!context || listeners.context === context)\n ) {\n clearEvent(this, evt);\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn ||\n (once && !listeners[i].once) ||\n (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else clearEvent(this, evt);\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) clearEvent(this, evt);\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n","/**\n * Returns true if an ID3 footer can be found at offset in data\n *\n * @param data - The data to search in\n * @param offset - The offset at which to start searching\n *\n * @returns `true` if an ID3 footer is found\n *\n * @internal\n *\n * @group ID3\n */\nexport function isId3Footer(data, offset) {\n /*\n * The footer is a copy of the header, but with a different identifier\n */\n if (offset + 10 <= data.length) {\n // look for '3DI' identifier\n if (data[offset] === 0x33 &&\n data[offset + 1] === 0x44 &&\n data[offset + 2] === 0x49) {\n // check version is within range\n if (data[offset + 3] < 0xff && data[offset + 4] < 0xff) {\n // check size is within range\n if (data[offset + 6] < 0x80 &&\n data[offset + 7] < 0x80 &&\n data[offset + 8] < 0x80 &&\n data[offset + 9] < 0x80) {\n return true;\n }\n }\n }\n }\n return false;\n}\n//# sourceMappingURL=isId3Footer.js.map","/**\n * Returns true if an ID3 header can be found at offset in data\n *\n * @param data - The data to search in\n * @param offset - The offset at which to start searching\n *\n * @returns `true` if an ID3 header is found\n *\n * @internal\n *\n * @group ID3\n */\nexport function isId3Header(data, offset) {\n /*\n * http://id3.org/id3v2.3.0\n * [0] = 'I'\n * [1] = 'D'\n * [2] = '3'\n * [3,4] = {Version}\n * [5] = {Flags}\n * [6-9] = {ID3 Size}\n *\n * An ID3v2 tag can be detected with the following pattern:\n * $49 44 33 yy yy xx zz zz zz zz\n * Where yy is less than $FF, xx is the 'flags' byte and zz is less than $80\n */\n if (offset + 10 <= data.length) {\n // look for 'ID3' identifier\n if (data[offset] === 0x49 &&\n data[offset + 1] === 0x44 &&\n data[offset + 2] === 0x33) {\n // check version is within range\n if (data[offset + 3] < 0xff && data[offset + 4] < 0xff) {\n // check size is within range\n if (data[offset + 6] < 0x80 &&\n data[offset + 7] < 0x80 &&\n data[offset + 8] < 0x80 &&\n data[offset + 9] < 0x80) {\n return true;\n }\n }\n }\n }\n return false;\n}\n//# sourceMappingURL=isId3Header.js.map","/**\n * Read ID3 size\n *\n * @param data - The data to read from\n * @param offset - The offset at which to start reading\n *\n * @returns The size\n *\n * @internal\n *\n * @group ID3\n */\nexport function readId3Size(data, offset) {\n let size = 0;\n size = (data[offset] & 0x7f) << 21;\n size |= (data[offset + 1] & 0x7f) << 14;\n size |= (data[offset + 2] & 0x7f) << 7;\n size |= data[offset + 3] & 0x7f;\n return size;\n}\n//# sourceMappingURL=readId3Size.js.map","import { isId3Footer } from './util/isId3Footer.js';\nimport { isId3Header } from './util/isId3Header.js';\nimport { readId3Size } from './util/readId3Size.js';\n/**\n * Returns any adjacent ID3 tags found in data starting at offset, as one block of data\n *\n * @param data - The data to search in\n * @param offset - The offset at which to start searching\n *\n * @returns The block of data containing any ID3 tags found\n * or `undefined` if no header is found at the starting offset\n *\n * @internal\n *\n * @group ID3\n */\nexport function getId3Data(data, offset) {\n const front = offset;\n let length = 0;\n while (isId3Header(data, offset)) {\n // ID3 header is 10 bytes\n length += 10;\n const size = readId3Size(data, offset + 6);\n length += size;\n if (isId3Footer(data, offset + 10)) {\n // ID3 footer is 10 bytes\n length += 10;\n }\n offset += length;\n }\n if (length > 0) {\n return data.subarray(front, front + length);\n }\n return undefined;\n}\n//# sourceMappingURL=getId3Data.js.map","export enum ErrorTypes {\n // Identifier for a network error (loading error / timeout ...)\n NETWORK_ERROR = 'networkError',\n // Identifier for a media Error (video/parsing/mediasource error)\n MEDIA_ERROR = 'mediaError',\n // EME (encrypted media extensions) errors\n KEY_SYSTEM_ERROR = 'keySystemError',\n // Identifier for a mux Error (demuxing/remuxing)\n MUX_ERROR = 'muxError',\n // Identifier for all other errors\n OTHER_ERROR = 'otherError',\n}\n\nexport enum ErrorDetails {\n KEY_SYSTEM_NO_KEYS = 'keySystemNoKeys',\n KEY_SYSTEM_NO_ACCESS = 'keySystemNoAccess',\n KEY_SYSTEM_NO_SESSION = 'keySystemNoSession',\n KEY_SYSTEM_NO_CONFIGURED_LICENSE = 'keySystemNoConfiguredLicense',\n KEY_SYSTEM_LICENSE_REQUEST_FAILED = 'keySystemLicenseRequestFailed',\n KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED = 'keySystemServerCertificateRequestFailed',\n KEY_SYSTEM_SERVER_CERTIFICATE_UPDATE_FAILED = 'keySystemServerCertificateUpdateFailed',\n KEY_SYSTEM_SESSION_UPDATE_FAILED = 'keySystemSessionUpdateFailed',\n KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED = 'keySystemStatusOutputRestricted',\n KEY_SYSTEM_STATUS_INTERNAL_ERROR = 'keySystemStatusInternalError',\n KEY_SYSTEM_DESTROY_MEDIA_KEYS_ERROR = 'keySystemDestroyMediaKeysError',\n KEY_SYSTEM_DESTROY_CLOSE_SESSION_ERROR = 'keySystemDestroyCloseSessionError',\n KEY_SYSTEM_DESTROY_REMOVE_SESSION_ERROR = 'keySystemDestroyRemoveSessionError',\n // Identifier for a manifest load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n MANIFEST_LOAD_ERROR = 'manifestLoadError',\n // Identifier for a manifest load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n MANIFEST_LOAD_TIMEOUT = 'manifestLoadTimeOut',\n // Identifier for a manifest parsing error - data: { url : faulty URL, reason : error reason}\n MANIFEST_PARSING_ERROR = 'manifestParsingError',\n // Identifier for a manifest with only incompatible codecs error - data: { url : faulty URL, reason : error reason}\n MANIFEST_INCOMPATIBLE_CODECS_ERROR = 'manifestIncompatibleCodecsError',\n // Identifier for a level which contains no fragments - data: { url: faulty URL, reason: \"no fragments found in level\", level: index of the bad level }\n LEVEL_EMPTY_ERROR = 'levelEmptyError',\n // Identifier for a level load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n LEVEL_LOAD_ERROR = 'levelLoadError',\n // Identifier for a level load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n LEVEL_LOAD_TIMEOUT = 'levelLoadTimeOut',\n // Identifier for a level parse error - data: { url : faulty URL, error: Error, reason: error message }\n LEVEL_PARSING_ERROR = 'levelParsingError',\n // Identifier for a level switch error - data: { level : faulty level Id, event : error description}\n LEVEL_SWITCH_ERROR = 'levelSwitchError',\n // Identifier for an audio track load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n AUDIO_TRACK_LOAD_ERROR = 'audioTrackLoadError',\n // Identifier for an audio track load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n AUDIO_TRACK_LOAD_TIMEOUT = 'audioTrackLoadTimeOut',\n // Identifier for a subtitle track load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n SUBTITLE_LOAD_ERROR = 'subtitleTrackLoadError',\n // Identifier for a subtitle track load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n SUBTITLE_TRACK_LOAD_TIMEOUT = 'subtitleTrackLoadTimeOut',\n // Identifier for fragment load error - data: { frag : fragment object, response : { code: error code, text: error text }}\n FRAG_LOAD_ERROR = 'fragLoadError',\n // Identifier for fragment load timeout error - data: { frag : fragment object}\n FRAG_LOAD_TIMEOUT = 'fragLoadTimeOut',\n // Identifier for a fragment decryption error event - data: {id : demuxer Id,frag: fragment object, reason : parsing error description }\n FRAG_DECRYPT_ERROR = 'fragDecryptError',\n // Identifier for a fragment parsing error event - data: { id : demuxer Id, reason : parsing error description }\n // will be renamed DEMUX_PARSING_ERROR and switched to MUX_ERROR in the next major release\n FRAG_PARSING_ERROR = 'fragParsingError',\n // Identifier for a fragment or part load skipped because of a GAP tag or attribute\n FRAG_GAP = 'fragGap',\n // Identifier for a remux alloc error event - data: { id : demuxer Id, frag : fragment object, bytes : nb of bytes on which allocation failed , reason : error text }\n REMUX_ALLOC_ERROR = 'remuxAllocError',\n // Identifier for decrypt key load error - data: { frag : fragment object, response : { code: error code, text: error text }}\n KEY_LOAD_ERROR = 'keyLoadError',\n // Identifier for decrypt key load timeout error - data: { frag : fragment object}\n KEY_LOAD_TIMEOUT = 'keyLoadTimeOut',\n // Triggered when an exception occurs while adding a sourceBuffer to MediaSource - data : { error : exception , mimeType : mimeType }\n BUFFER_ADD_CODEC_ERROR = 'bufferAddCodecError',\n // Triggered when source buffer(s) could not be created using level (manifest CODECS attribute), parsed media, or best guess codec(s) - data: { reason : error reason }\n BUFFER_INCOMPATIBLE_CODECS_ERROR = 'bufferIncompatibleCodecsError',\n // Identifier for a buffer append error - data: append error description\n BUFFER_APPEND_ERROR = 'bufferAppendError',\n // Identifier for a buffer appending error event - data: appending error description\n BUFFER_APPENDING_ERROR = 'bufferAppendingError',\n // Identifier for a buffer stalled error event\n BUFFER_STALLED_ERROR = 'bufferStalledError',\n // Identifier for a buffer full event\n BUFFER_FULL_ERROR = 'bufferFullError',\n // Identifier for a buffer seek over hole event\n BUFFER_SEEK_OVER_HOLE = 'bufferSeekOverHole',\n // Identifier for a buffer nudge on stall (playback is stuck although currentTime is in a buffered area)\n BUFFER_NUDGE_ON_STALL = 'bufferNudgeOnStall',\n // Identifier for a Interstitial Asset List load error - data: { url: faulty URL, response: { code: error code, text: error text } }\n ASSET_LIST_LOAD_ERROR = 'assetListLoadError',\n // Identifier for a Interstitial Asset List load timeout - data: { url: faulty URL, response: { code: error code, text: error text } }\n ASSET_LIST_LOAD_TIMEOUT = 'assetListLoadTimeout',\n // Identifier for a Interstitial Asset List parsing error - data: { url : faulty URL, reason : error reason, response : { code: error code, text: error text }}\n ASSET_LIST_PARSING_ERROR = 'assetListParsingError',\n // Identifier for a Interstitial Asset List parsing error - data: { url : faulty URL, reason : error reason, response : { code: error code, text: error text }}\n INTERSTITIAL_ASSET_ITEM_ERROR = 'interstitialAssetItemError',\n // Identifier for an internal exception happening inside hls.js while handling an event\n INTERNAL_EXCEPTION = 'internalException',\n // Identifier for an internal call to abort a loader\n INTERNAL_ABORTED = 'aborted',\n // Triggered when attachMedia fails\n ATTACH_MEDIA_ERROR = 'attachMediaError',\n // Uncategorized error\n UNKNOWN = 'unknown',\n}\n","import type {\n AssetListLoadedData,\n AssetListLoadingData,\n AudioTrackLoadedData,\n AudioTracksUpdatedData,\n AudioTrackSwitchedData,\n AudioTrackSwitchingData,\n AudioTrackUpdatedData,\n BackBufferData,\n BufferAppendedData,\n BufferAppendingData,\n BufferCodecsData,\n BufferCreatedData,\n BufferEOSData,\n BufferFlushedData,\n BufferFlushingData,\n CuesParsedData,\n ErrorData,\n FPSDropData,\n FPSDropLevelCappingData,\n FragBufferedData,\n FragChangedData,\n FragDecryptedData,\n FragLoadedData,\n FragLoadEmergencyAbortedData,\n FragLoadingData,\n FragParsedData,\n FragParsingInitSegmentData,\n FragParsingMetadataData,\n FragParsingUserdataData,\n InitPTSFoundData,\n InterstitialAssetEndedData,\n InterstitialAssetErrorData,\n InterstitialAssetPlayerCreatedData,\n InterstitialAssetStartedData,\n InterstitialEndedData,\n InterstitialsBufferedToBoundaryData,\n InterstitialsPrimaryResumed,\n InterstitialStartedData,\n InterstitialsUpdatedData,\n KeyLoadedData,\n KeyLoadingData,\n LevelLoadedData,\n LevelLoadingData,\n LevelPTSUpdatedData,\n LevelsUpdatedData,\n LevelSwitchedData,\n LevelSwitchingData,\n LevelUpdatedData,\n LiveBackBufferData,\n ManifestLoadedData,\n ManifestLoadingData,\n ManifestParsedData,\n MaxAutoLevelUpdatedData,\n MediaAttachedData,\n MediaAttachingData,\n MediaDetachedData,\n MediaDetachingData,\n MediaEndedData,\n NonNativeTextTracksData,\n SteeringManifestLoadedData,\n SubtitleFragProcessedData,\n SubtitleTrackLoadedData,\n SubtitleTracksUpdatedData,\n SubtitleTrackSwitchData,\n SubtitleTrackUpdatedData,\n TrackLoadingData,\n} from './types/events';\n\nexport enum Events {\n // Fired before MediaSource is attaching to media element\n MEDIA_ATTACHING = 'hlsMediaAttaching',\n // Fired when MediaSource has been successfully attached to media element\n MEDIA_ATTACHED = 'hlsMediaAttached',\n // Fired before detaching MediaSource from media element\n MEDIA_DETACHING = 'hlsMediaDetaching',\n // Fired when MediaSource has been detached from media element\n MEDIA_DETACHED = 'hlsMediaDetached',\n // Fired when HTMLMediaElement dispatches \"ended\" event, or stalls at end of VOD program\n MEDIA_ENDED = 'hlsMediaEnded',\n // Fired after playback stall is resolved with playing, seeked, or ended event following BUFFER_STALLED_ERROR\n STALL_RESOLVED = 'hlsStallResolved',\n // Fired when the buffer is going to be reset\n BUFFER_RESET = 'hlsBufferReset',\n // Fired when we know about the codecs that we need buffers for to push into - data: {tracks : { container, codec, levelCodec, initSegment, metadata }}\n BUFFER_CODECS = 'hlsBufferCodecs',\n // fired when sourcebuffers have been created - data: { tracks : tracks }\n BUFFER_CREATED = 'hlsBufferCreated',\n // fired when we append a segment to the buffer - data: { segment: segment object }\n BUFFER_APPENDING = 'hlsBufferAppending',\n // fired when we are done with appending a media segment to the buffer - data : { parent : segment parent that triggered BUFFER_APPENDING, pending : nb of segments waiting for appending for this segment parent}\n BUFFER_APPENDED = 'hlsBufferAppended',\n // fired when the stream is finished and we want to notify the media buffer that there will be no more data - data: { }\n BUFFER_EOS = 'hlsBufferEos',\n // fired when all buffers are full to the end of the program, after calling MediaSource.endOfStream() (unless restricted)\n BUFFERED_TO_END = 'hlsBufferedToEnd',\n // fired when the media buffer should be flushed - data { startOffset, endOffset }\n BUFFER_FLUSHING = 'hlsBufferFlushing',\n // fired when the media buffer has been flushed - data: { }\n BUFFER_FLUSHED = 'hlsBufferFlushed',\n // fired to signal that a manifest loading starts - data: { url : manifestURL}\n MANIFEST_LOADING = 'hlsManifestLoading',\n // fired after manifest has been loaded - data: { levels : [available quality levels], audioTracks : [ available audio tracks ], url : manifestURL, stats : LoaderStats }\n MANIFEST_LOADED = 'hlsManifestLoaded',\n // fired after manifest has been parsed - data: { levels : [available quality levels], firstLevel : index of first quality level appearing in Manifest}\n MANIFEST_PARSED = 'hlsManifestParsed',\n // fired when a level switch is requested - data: { level : id of new level }\n LEVEL_SWITCHING = 'hlsLevelSwitching',\n // fired when a level switch is effective - data: { level : id of new level }\n LEVEL_SWITCHED = 'hlsLevelSwitched',\n // fired when a level playlist loading starts - data: { url : level URL, level : id of level being loaded}\n LEVEL_LOADING = 'hlsLevelLoading',\n // fired when a level playlist loading finishes - data: { details : levelDetails object, level : id of loaded level, stats : LoaderStats }\n LEVEL_LOADED = 'hlsLevelLoaded',\n // fired when a level's details have been updated based on previous details, after it has been loaded - data: { details : levelDetails object, level : id of updated level }\n LEVEL_UPDATED = 'hlsLevelUpdated',\n // fired when a level's PTS information has been updated after parsing a fragment - data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }\n LEVEL_PTS_UPDATED = 'hlsLevelPtsUpdated',\n // fired to notify that levels have changed after removing a level - data: { levels : [available quality levels] }\n LEVELS_UPDATED = 'hlsLevelsUpdated',\n // fired to notify that audio track lists has been updated - data: { audioTracks : audioTracks }\n AUDIO_TRACKS_UPDATED = 'hlsAudioTracksUpdated',\n // fired when an audio track switching is requested - data: { id : audio track id }\n AUDIO_TRACK_SWITCHING = 'hlsAudioTrackSwitching',\n // fired when an audio track switch actually occurs - data: { id : audio track id }\n AUDIO_TRACK_SWITCHED = 'hlsAudioTrackSwitched',\n // fired when an audio track loading starts - data: { url : audio track URL, id : audio track id }\n AUDIO_TRACK_LOADING = 'hlsAudioTrackLoading',\n // fired when an audio track loading finishes - data: { details : levelDetails object, id : audio track id, stats : LoaderStats }\n AUDIO_TRACK_LOADED = 'hlsAudioTrackLoaded',\n // fired when an audio tracks's details have been updated based on previous details, after it has been loaded - data: { details : levelDetails object, id : track id }\n AUDIO_TRACK_UPDATED = 'hlsAudioTrackUpdated',\n // fired to notify that subtitle track lists has been updated - data: { subtitleTracks : subtitleTracks }\n SUBTITLE_TRACKS_UPDATED = 'hlsSubtitleTracksUpdated',\n // fired to notify that subtitle tracks were cleared as a result of stopping the media\n SUBTITLE_TRACKS_CLEARED = 'hlsSubtitleTracksCleared',\n // fired when an subtitle track switch occurs - data: { id : subtitle track id }\n SUBTITLE_TRACK_SWITCH = 'hlsSubtitleTrackSwitch',\n // fired when a subtitle track loading starts - data: { url : subtitle track URL, id : subtitle track id }\n SUBTITLE_TRACK_LOADING = 'hlsSubtitleTrackLoading',\n // fired when a subtitle track loading finishes - data: { details : levelDetails object, id : subtitle track id, stats : LoaderStats }\n SUBTITLE_TRACK_LOADED = 'hlsSubtitleTrackLoaded',\n // fired when a subtitle racks's details have been updated based on previous details, after it has been loaded - data: { details : levelDetails object, id : track id }\n SUBTITLE_TRACK_UPDATED = 'hlsSubtitleTrackUpdated',\n // fired when a subtitle fragment has been processed - data: { success : boolean, frag : the processed frag }\n SUBTITLE_FRAG_PROCESSED = 'hlsSubtitleFragProcessed',\n // fired when a set of VTTCues to be managed externally has been parsed - data: { type: string, track: string, cues: [ VTTCue ] }\n CUES_PARSED = 'hlsCuesParsed',\n // fired when a text track to be managed externally is found - data: { tracks: [ { label: string, kind: string, default: boolean } ] }\n NON_NATIVE_TEXT_TRACKS_FOUND = 'hlsNonNativeTextTracksFound',\n // fired when the first timestamp is found - data: { id : demuxer id, initPTS: initPTS, timescale: timescale, frag : fragment object }\n INIT_PTS_FOUND = 'hlsInitPtsFound',\n // fired when a fragment loading starts - data: { frag : fragment object }\n FRAG_LOADING = 'hlsFragLoading',\n // fired when a fragment loading is progressing - data: { frag : fragment object, { trequest, tfirst, loaded } }\n // FRAG_LOAD_PROGRESS = 'hlsFragLoadProgress',\n // Identifier for fragment load aborting for emergency switch down - data: { frag : fragment object }\n FRAG_LOAD_EMERGENCY_ABORTED = 'hlsFragLoadEmergencyAborted',\n // fired when a fragment loading is completed - data: { frag : fragment object, payload : fragment payload, stats : LoaderStats }\n FRAG_LOADED = 'hlsFragLoaded',\n // fired when a fragment has finished decrypting - data: { id : demuxer id, frag: fragment object, payload : fragment payload, stats : { tstart, tdecrypt } }\n FRAG_DECRYPTED = 'hlsFragDecrypted',\n // fired when Init Segment has been extracted from fragment - data: { id : demuxer id, frag: fragment object, moov : moov MP4 box, codecs : codecs found while parsing fragment }\n FRAG_PARSING_INIT_SEGMENT = 'hlsFragParsingInitSegment',\n // fired when parsing sei text is completed - data: { id : demuxer id, frag: fragment object, samples : [ sei samples pes ] }\n FRAG_PARSING_USERDATA = 'hlsFragParsingUserdata',\n // fired when parsing id3 is completed - data: { id : demuxer id, frag: fragment object, samples : [ id3 samples pes ] }\n FRAG_PARSING_METADATA = 'hlsFragParsingMetadata',\n // fired when data have been extracted from fragment - data: { id : demuxer id, frag: fragment object, data1 : moof MP4 box or TS fragments, data2 : mdat MP4 box or null}\n // FRAG_PARSING_DATA = 'hlsFragParsingData',\n // fired when fragment parsing is completed - data: { id : demuxer id, frag: fragment object }\n FRAG_PARSED = 'hlsFragParsed',\n // fired when fragment remuxed MP4 boxes have all been appended into SourceBuffer - data: { id : demuxer id, frag : fragment object, stats : LoaderStats }\n FRAG_BUFFERED = 'hlsFragBuffered',\n // fired when fragment matching with current media position is changing - data : { id : demuxer id, frag : fragment object }\n FRAG_CHANGED = 'hlsFragChanged',\n // Identifier for a FPS drop event - data: { currentDropped, currentDecoded, totalDroppedFrames }\n FPS_DROP = 'hlsFpsDrop',\n // triggered when FPS drop triggers auto level capping - data: { level, droppedLevel }\n FPS_DROP_LEVEL_CAPPING = 'hlsFpsDropLevelCapping',\n // triggered when maxAutoLevel changes - data { autoLevelCapping, levels, maxAutoLevel, minAutoLevel, maxHdcpLevel }\n MAX_AUTO_LEVEL_UPDATED = 'hlsMaxAutoLevelUpdated',\n // Identifier for an error event - data: { type : error type, details : error details, fatal : if true, hls.js cannot/will not try to recover, if false, hls.js will try to recover,other error specific data }\n ERROR = 'hlsError',\n // fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a media to the instance of hls.js to handle mid-rolls for example - data: { }\n DESTROYING = 'hlsDestroying',\n // fired when a decrypt key loading starts - data: { frag : fragment object }\n KEY_LOADING = 'hlsKeyLoading',\n // fired when a decrypt key loading is completed - data: { frag : fragment object, keyInfo : KeyLoaderInfo }\n KEY_LOADED = 'hlsKeyLoaded',\n // deprecated; please use BACK_BUFFER_REACHED - data : { bufferEnd: number }\n LIVE_BACK_BUFFER_REACHED = 'hlsLiveBackBufferReached',\n // fired when the back buffer is reached as defined by the backBufferLength config option - data : { bufferEnd: number }\n BACK_BUFFER_REACHED = 'hlsBackBufferReached',\n // fired after steering manifest has been loaded - data: { steeringManifest: SteeringManifest object, url: steering manifest URL }\n STEERING_MANIFEST_LOADED = 'hlsSteeringManifestLoaded',\n // fired when asset list has begun loading\n ASSET_LIST_LOADING = 'hlsAssetListLoading',\n // fired when a valid asset list is loaded\n ASSET_LIST_LOADED = 'hlsAssetListLoaded',\n // fired when the list of Interstitial Events and Interstitial Schedule is updated\n INTERSTITIALS_UPDATED = 'hlsInterstitialsUpdated',\n // fired when the buffer reaches an Interstitial Schedule boundary (both Primary segments and Interstitial Assets)\n INTERSTITIALS_BUFFERED_TO_BOUNDARY = 'hlsInterstitialsBufferedToBoundary',\n // fired when a player instance for an Interstitial Asset has been created\n INTERSTITIAL_ASSET_PLAYER_CREATED = 'hlsInterstitialAssetPlayerCreated',\n // Interstitial playback started\n INTERSTITIAL_STARTED = 'hlsInterstitialStarted',\n // InterstitialAsset playback started\n INTERSTITIAL_ASSET_STARTED = 'hlsInterstitialAssetStarted',\n // InterstitialAsset playback ended\n INTERSTITIAL_ASSET_ENDED = 'hlsInterstitialAssetEnded',\n // InterstitialAsset playback errored\n INTERSTITIAL_ASSET_ERROR = 'hlsInterstitialAssetError',\n // Interstitial playback ended\n INTERSTITIAL_ENDED = 'hlsInterstitialEnded',\n // Interstitial schedule resumed primary playback\n INTERSTITIALS_PRIMARY_RESUMED = 'hlsInterstitialsPrimaryResumed',\n // Interstitial players dispatch this event when playout limit is reached\n PLAYOUT_LIMIT_REACHED = 'hlsPlayoutLimitReached',\n // Event DateRange cue \"enter\" event dispatched\n EVENT_CUE_ENTER = 'hlsEventCueEnter',\n}\n\n/**\n * Defines each Event type and payload by Event name. Used in {@link hls.js#HlsEventEmitter} to strongly type the event listener API.\n */\nexport interface HlsListeners {\n [Events.MEDIA_ATTACHING]: (\n event: Events.MEDIA_ATTACHING,\n data: MediaAttachingData,\n ) => void;\n [Events.MEDIA_ATTACHED]: (\n event: Events.MEDIA_ATTACHED,\n data: MediaAttachedData,\n ) => void;\n [Events.MEDIA_DETACHING]: (\n event: Events.MEDIA_DETACHING,\n data: MediaDetachingData,\n ) => void;\n [Events.MEDIA_DETACHED]: (\n event: Events.MEDIA_DETACHED,\n data: MediaDetachedData,\n ) => void;\n [Events.MEDIA_ENDED]: (\n event: Events.MEDIA_ENDED,\n data: MediaEndedData,\n ) => void;\n [Events.STALL_RESOLVED]: (event: Events.STALL_RESOLVED, data: {}) => void;\n [Events.BUFFER_RESET]: (event: Events.BUFFER_RESET) => void;\n [Events.BUFFER_CODECS]: (\n event: Events.BUFFER_CODECS,\n data: BufferCodecsData,\n ) => void;\n [Events.BUFFER_CREATED]: (\n event: Events.BUFFER_CREATED,\n data: BufferCreatedData,\n ) => void;\n [Events.BUFFER_APPENDING]: (\n event: Events.BUFFER_APPENDING,\n data: BufferAppendingData,\n ) => void;\n [Events.BUFFER_APPENDED]: (\n event: Events.BUFFER_APPENDED,\n data: BufferAppendedData,\n ) => void;\n [Events.BUFFER_EOS]: (event: Events.BUFFER_EOS, data: BufferEOSData) => void;\n [Events.BUFFERED_TO_END]: (event: Events.BUFFERED_TO_END) => void;\n [Events.BUFFER_FLUSHING]: (\n event: Events.BUFFER_FLUSHING,\n data: BufferFlushingData,\n ) => void;\n [Events.BUFFER_FLUSHED]: (\n event: Events.BUFFER_FLUSHED,\n data: BufferFlushedData,\n ) => void;\n [Events.MANIFEST_LOADING]: (\n event: Events.MANIFEST_LOADING,\n data: ManifestLoadingData,\n ) => void;\n [Events.MANIFEST_LOADED]: (\n event: Events.MANIFEST_LOADED,\n data: ManifestLoadedData,\n ) => void;\n [Events.MANIFEST_PARSED]: (\n event: Events.MANIFEST_PARSED,\n data: ManifestParsedData,\n ) => void;\n [Events.LEVEL_SWITCHING]: (\n event: Events.LEVEL_SWITCHING,\n data: LevelSwitchingData,\n ) => void;\n [Events.LEVEL_SWITCHED]: (\n event: Events.LEVEL_SWITCHED,\n data: LevelSwitchedData,\n ) => void;\n [Events.LEVEL_LOADING]: (\n event: Events.LEVEL_LOADING,\n data: LevelLoadingData,\n ) => void;\n [Events.LEVEL_LOADED]: (\n event: Events.LEVEL_LOADED,\n data: LevelLoadedData,\n ) => void;\n [Events.LEVEL_UPDATED]: (\n event: Events.LEVEL_UPDATED,\n data: LevelUpdatedData,\n ) => void;\n [Events.LEVEL_PTS_UPDATED]: (\n event: Events.LEVEL_PTS_UPDATED,\n data: LevelPTSUpdatedData,\n ) => void;\n [Events.LEVELS_UPDATED]: (\n event: Events.LEVELS_UPDATED,\n data: LevelsUpdatedData,\n ) => void;\n [Events.AUDIO_TRACKS_UPDATED]: (\n event: Events.AUDIO_TRACKS_UPDATED,\n data: AudioTracksUpdatedData,\n ) => void;\n [Events.AUDIO_TRACK_SWITCHING]: (\n event: Events.AUDIO_TRACK_SWITCHING,\n data: AudioTrackSwitchingData,\n ) => void;\n [Events.AUDIO_TRACK_SWITCHED]: (\n event: Events.AUDIO_TRACK_SWITCHED,\n data: AudioTrackSwitchedData,\n ) => void;\n [Events.AUDIO_TRACK_LOADING]: (\n event: Events.AUDIO_TRACK_LOADING,\n data: TrackLoadingData,\n ) => void;\n [Events.AUDIO_TRACK_LOADED]: (\n event: Events.AUDIO_TRACK_LOADED,\n data: AudioTrackLoadedData,\n ) => void;\n [Events.AUDIO_TRACK_UPDATED]: (\n event: Events.AUDIO_TRACK_UPDATED,\n data: AudioTrackUpdatedData,\n ) => void;\n [Events.SUBTITLE_TRACKS_UPDATED]: (\n event: Events.SUBTITLE_TRACKS_UPDATED,\n data: SubtitleTracksUpdatedData,\n ) => void;\n [Events.SUBTITLE_TRACKS_CLEARED]: (\n event: Events.SUBTITLE_TRACKS_CLEARED,\n ) => void;\n [Events.SUBTITLE_TRACK_SWITCH]: (\n event: Events.SUBTITLE_TRACK_SWITCH,\n data: SubtitleTrackSwitchData,\n ) => void;\n [Events.SUBTITLE_TRACK_LOADING]: (\n event: Events.SUBTITLE_TRACK_LOADING,\n data: TrackLoadingData,\n ) => void;\n [Events.SUBTITLE_TRACK_LOADED]: (\n event: Events.SUBTITLE_TRACK_LOADED,\n data: SubtitleTrackLoadedData,\n ) => void;\n [Events.SUBTITLE_TRACK_UPDATED]: (\n event: Events.SUBTITLE_TRACK_UPDATED,\n data: SubtitleTrackUpdatedData,\n ) => void;\n [Events.SUBTITLE_FRAG_PROCESSED]: (\n event: Events.SUBTITLE_FRAG_PROCESSED,\n data: SubtitleFragProcessedData,\n ) => void;\n [Events.CUES_PARSED]: (\n event: Events.CUES_PARSED,\n data: CuesParsedData,\n ) => void;\n [Events.NON_NATIVE_TEXT_TRACKS_FOUND]: (\n event: Events.NON_NATIVE_TEXT_TRACKS_FOUND,\n data: NonNativeTextTracksData,\n ) => void;\n [Events.INIT_PTS_FOUND]: (\n event: Events.INIT_PTS_FOUND,\n data: InitPTSFoundData,\n ) => void;\n [Events.FRAG_LOADING]: (\n event: Events.FRAG_LOADING,\n data: FragLoadingData,\n ) => void;\n // [Events.FRAG_LOAD_PROGRESS]: TodoEventType\n [Events.FRAG_LOAD_EMERGENCY_ABORTED]: (\n event: Events.FRAG_LOAD_EMERGENCY_ABORTED,\n data: FragLoadEmergencyAbortedData,\n ) => void;\n [Events.FRAG_LOADED]: (\n event: Events.FRAG_LOADED,\n data: FragLoadedData,\n ) => void;\n [Events.FRAG_DECRYPTED]: (\n event: Events.FRAG_DECRYPTED,\n data: FragDecryptedData,\n ) => void;\n [Events.FRAG_PARSING_INIT_SEGMENT]: (\n event: Events.FRAG_PARSING_INIT_SEGMENT,\n data: FragParsingInitSegmentData,\n ) => void;\n [Events.FRAG_PARSING_USERDATA]: (\n event: Events.FRAG_PARSING_USERDATA,\n data: FragParsingUserdataData,\n ) => void;\n [Events.FRAG_PARSING_METADATA]: (\n event: Events.FRAG_PARSING_METADATA,\n data: FragParsingMetadataData,\n ) => void;\n // [Events.FRAG_PARSING_DATA]: TodoEventType\n [Events.FRAG_PARSED]: (\n event: Events.FRAG_PARSED,\n data: FragParsedData,\n ) => void;\n [Events.FRAG_BUFFERED]: (\n event: Events.FRAG_BUFFERED,\n data: FragBufferedData,\n ) => void;\n [Events.FRAG_CHANGED]: (\n event: Events.FRAG_CHANGED,\n data: FragChangedData,\n ) => void;\n [Events.FPS_DROP]: (event: Events.FPS_DROP, data: FPSDropData) => void;\n [Events.FPS_DROP_LEVEL_CAPPING]: (\n event: Events.FPS_DROP_LEVEL_CAPPING,\n data: FPSDropLevelCappingData,\n ) => void;\n [Events.MAX_AUTO_LEVEL_UPDATED]: (\n event: Events.MAX_AUTO_LEVEL_UPDATED,\n data: MaxAutoLevelUpdatedData,\n ) => void;\n [Events.ERROR]: (event: Events.ERROR, data: ErrorData) => void;\n [Events.DESTROYING]: (event: Events.DESTROYING) => void;\n [Events.KEY_LOADING]: (\n event: Events.KEY_LOADING,\n data: KeyLoadingData,\n ) => void;\n [Events.KEY_LOADED]: (event: Events.KEY_LOADED, data: KeyLoadedData) => void;\n [Events.LIVE_BACK_BUFFER_REACHED]: (\n event: Events.LIVE_BACK_BUFFER_REACHED,\n data: LiveBackBufferData,\n ) => void;\n [Events.BACK_BUFFER_REACHED]: (\n event: Events.BACK_BUFFER_REACHED,\n data: BackBufferData,\n ) => void;\n [Events.STEERING_MANIFEST_LOADED]: (\n event: Events.STEERING_MANIFEST_LOADED,\n data: SteeringManifestLoadedData,\n ) => void;\n [Events.ASSET_LIST_LOADING]: (\n event: Events.ASSET_LIST_LOADING,\n data: AssetListLoadingData,\n ) => void;\n [Events.ASSET_LIST_LOADED]: (\n event: Events.ASSET_LIST_LOADED,\n data: AssetListLoadedData,\n ) => void;\n [Events.INTERSTITIALS_UPDATED]: (\n event: Events.INTERSTITIALS_UPDATED,\n data: InterstitialsUpdatedData,\n ) => void;\n [Events.INTERSTITIALS_BUFFERED_TO_BOUNDARY]: (\n event: Events.INTERSTITIALS_BUFFERED_TO_BOUNDARY,\n data: InterstitialsBufferedToBoundaryData,\n ) => void;\n [Events.INTERSTITIAL_ASSET_PLAYER_CREATED]: (\n event: Events.INTERSTITIAL_ASSET_PLAYER_CREATED,\n data: InterstitialAssetPlayerCreatedData,\n ) => void;\n [Events.INTERSTITIAL_STARTED]: (\n event: Events.INTERSTITIAL_STARTED,\n data: InterstitialStartedData,\n ) => void;\n [Events.INTERSTITIAL_ASSET_STARTED]: (\n event: Events.INTERSTITIAL_ASSET_STARTED,\n data: InterstitialAssetStartedData,\n ) => void;\n [Events.INTERSTITIAL_ASSET_ENDED]: (\n event: Events.INTERSTITIAL_ASSET_ENDED,\n data: InterstitialAssetEndedData,\n ) => void;\n [Events.INTERSTITIAL_ASSET_ERROR]: (\n event: Events.INTERSTITIAL_ASSET_ERROR,\n data: InterstitialAssetErrorData,\n ) => void;\n [Events.INTERSTITIAL_ENDED]: (\n event: Events.INTERSTITIAL_ENDED,\n data: InterstitialEndedData,\n ) => void;\n [Events.INTERSTITIALS_PRIMARY_RESUMED]: (\n event: Events.INTERSTITIALS_PRIMARY_RESUMED,\n data: InterstitialsPrimaryResumed,\n ) => void;\n [Events.PLAYOUT_LIMIT_REACHED]: (\n event: Events.PLAYOUT_LIMIT_REACHED,\n data: {},\n ) => void;\n [Events.EVENT_CUE_ENTER]: (event: Events.EVENT_CUE_ENTER, data: {}) => void;\n}\nexport interface HlsEventEmitter {\n on<E extends keyof HlsListeners, Context = undefined>(\n event: E,\n listener: HlsListeners[E],\n context?: Context,\n ): void;\n once<E extends keyof HlsListeners, Context = undefined>(\n event: E,\n listener: HlsListeners[E],\n context?: Context,\n ): void;\n\n removeAllListeners<E extends keyof HlsListeners>(event?: E): void;\n off<E extends keyof HlsListeners, Context = undefined>(\n event: E,\n listener?: HlsListeners[E],\n context?: Context,\n once?: boolean,\n ): void;\n\n listeners<E extends keyof HlsListeners>(event: E): HlsListeners[E][];\n emit<E extends keyof HlsListeners>(\n event: E,\n name: E,\n eventObject: Parameters<HlsListeners[E]>[1],\n ): boolean;\n listenerCount<E extends keyof HlsListeners>(event: E): number;\n}\n","export interface ILogFunction {\n (message?: any, ...optionalParams: any[]): void;\n}\n\nexport interface ILogger {\n trace: ILogFunction;\n debug: ILogFunction;\n log: ILogFunction;\n warn: ILogFunction;\n info: ILogFunction;\n error: ILogFunction;\n}\n\nexport class Logger implements ILogger {\n trace: ILogFunction;\n debug: ILogFunction;\n log: ILogFunction;\n warn: ILogFunction;\n info: ILogFunction;\n error: ILogFunction;\n\n constructor(label: string, logger: ILogger) {\n const lb = `[${label}]:`;\n this.trace = noop;\n this.debug = logger.debug.bind(null, lb);\n this.log = logger.log.bind(null, lb);\n this.warn = logger.warn.bind(null, lb);\n this.info = logger.info.bind(null, lb);\n this.error = logger.error.bind(null, lb);\n }\n}\n\nconst noop: ILogFunction = function () {};\n\nconst fakeLogger: ILogger = {\n trace: noop,\n debug: noop,\n log: noop,\n warn: noop,\n info: noop,\n error: noop,\n};\n\nfunction createLogger() {\n return Object.assign({}, fakeLogger);\n}\n\n// let lastCallTime;\n// function formatMsgWithTimeInfo(type, msg) {\n// const now = Date.now();\n// const diff = lastCallTime ? '+' + (now - lastCallTime) : '0';\n// lastCallTime = now;\n// msg = (new Date(now)).toISOString() + ' | [' + type + '] > ' + msg + ' ( ' + diff + ' ms )';\n// return msg;\n// }\n\nfunction consolePrintFn(type: string, id: string | undefined): ILogFunction {\n const func: ILogFunction = self.console[type];\n return func\n ? func.bind(self.console, `${id ? '[' + id + '] ' : ''}[${type}] >`)\n : noop;\n}\n\nfunction getLoggerFn(\n key: string,\n debugConfig: boolean | Partial<ILogger>,\n id?: string,\n): ILogFunction {\n return debugConfig[key]\n ? debugConfig[key].bind(debugConfig)\n : consolePrintFn(key, id);\n}\n\nconst exportedLogger: ILogger = createLogger();\n\nexport function enableLogs(\n debugConfig: boolean | ILogger,\n context: string,\n id?: string | undefined,\n): ILogger {\n // check that console is available\n const newLogger = createLogger();\n if (\n (typeof console === 'object' && debugConfig === true) ||\n typeof debugConfig === 'object'\n ) {\n const keys: (keyof ILogger)[] = [\n // Remove out from list here to hard-disable a log-level\n // 'trace',\n 'debug',\n 'log',\n 'info',\n 'warn',\n 'error',\n ];\n keys.forEach((key) => {\n newLogger[key] = getLoggerFn(key, debugConfig, id);\n });\n // Some browsers don't allow to use bind on console object anyway\n // fallback to default if needed\n try {\n newLogger.log(\n `Debug logs enabled for \"${context}\" in hls.js version ${__VERSION__}`,\n );\n } catch (e) {\n /* log fn threw an exception. All logger methods are no-ops. */\n return createLogger();\n }\n // global exported logger uses the same functions as new logger without `id`\n keys.forEach((key) => {\n exportedLogger[key] = getLoggerFn(key, debugConfig);\n });\n } else {\n // Reset global exported logger\n Object.assign(exportedLogger, newLogger);\n }\n return newLogger;\n}\n\nexport const logger: ILogger = exportedLogger;\n","/**\n * ADTS parser helper\n * @link https://wiki.multimedia.cx/index.php?title=ADTS\n */\nimport { ErrorDetails, ErrorTypes } from '../../errors';\nimport { Events } from '../../events';\nimport { logger } from '../../utils/logger';\nimport type { HlsEventEmitter } from '../../events';\nimport type {\n AudioFrame,\n AudioSample,\n DemuxedAudioTrack,\n} from '../../types/demuxer';\n\ntype AudioConfig = {\n config: [number, number];\n samplerate: number;\n channelCount: number;\n codec: string;\n parsedCodec: string;\n manifestCodec: string | undefined;\n};\n\ntype FrameHeader = {\n headerLength: number;\n frameLength: number;\n};\n\nexport function getAudioConfig(\n observer: HlsEventEmitter,\n data: Uint8Array,\n offset: number,\n manifestCodec: string | undefined,\n): AudioConfig | void {\n const adtsSamplingRates = [\n 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025,\n 8000, 7350,\n ];\n const byte2 = data[offset + 2];\n const adtsSamplingIndex = (byte2 >> 2) & 0xf;\n if (adtsSamplingIndex > 12) {\n const error = new Error(`invalid ADTS sampling index:${adtsSamplingIndex}`);\n observer.emit(Events.ERROR, Events.ERROR, {\n type: ErrorTypes.MEDIA_ERROR,\n details: ErrorDetails.FRAG_PARSING_ERROR,\n fatal: true,\n error,\n reason: error.message,\n });\n return;\n }\n // MPEG-4 Audio Object Type (profile_ObjectType+1)\n const adtsObjectType = ((byte2 >> 6) & 0x3) + 1;\n const channelCount = ((data[offset + 3] >> 6) & 0x3) | ((byte2 & 1) << 2);\n const codec = 'mp4a.40.' + adtsObjectType;\n /* refer to http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config\n ISO/IEC 14496-3 - Table 1.13 — Syntax of AudioSpecificConfig()\n Audio Profile / Audio Object Type\n 0: Null\n 1: AAC Main\n 2: AAC LC (Low Complexity)\n 3: AAC SSR (Scalable Sample Rate)\n 4: AAC LTP (Long Term Prediction)\n 5: SBR (Spectral Band Replication)\n 6: AAC Scalable\n sampling freq\n 0: 96000 Hz\n 1: 88200 Hz\n 2: 64000 Hz\n 3: 48000 Hz\n 4: 44100 Hz\n 5: 32000 Hz\n 6: 24000 Hz\n 7: 22050 Hz\n 8: 16000 Hz\n 9: 12000 Hz\n 10: 11025 Hz\n 11: 8000 Hz\n 12: 7350 Hz\n 13: Reserved\n 14: Reserved\n 15: frequency is written explictly\n Channel Configurations\n These are the channel configurations:\n 0: Defined in AOT Specifc Config\n 1: 1 channel: front-center\n 2: 2 channels: front-left, front-right\n */\n // audioObjectType = profile => profile, the MPEG-4 Audio Object Type minus 1\n const samplerate = adtsSamplingRates[adtsSamplingIndex];\n let aacSampleIndex = adtsSamplingIndex;\n if (adtsObjectType === 5 || adtsObjectType === 29) {\n // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies\n // there is a factor 2 between frame sample rate and output sample rate\n // multiply frequency by 2 (see table above, equivalent to substract 3)\n aacSampleIndex -= 3;\n }\n const config: [number, number] = [\n (adtsObjectType << 3) | ((aacSampleIndex & 0x0e) >> 1),\n ((aacSampleIndex & 0x01) << 7) | (channelCount << 3),\n ];\n logger.log(\n `manifest codec:${manifestCodec}, parsed codec:${codec}, channels:${channelCount}, rate:${samplerate} (ADTS object type:${adtsObjectType} sampling index:${adtsSamplingIndex})`,\n );\n return {\n config,\n samplerate,\n channelCount,\n codec,\n parsedCodec: codec,\n manifestCodec,\n };\n}\n\nexport function isHeaderPattern(data: Uint8Array, offset: number): boolean {\n return data[offset] === 0xff && (data[offset + 1] & 0xf6) === 0xf0;\n}\n\nexport function getHeaderLength(data: Uint8Array, offset: number): number {\n return data[offset + 1] & 0x01 ? 7 : 9;\n}\n\nexport function getFullFrameLength(data: Uint8Array, offset: number): number {\n return (\n ((data[offset + 3] & 0x03) << 11) |\n (data[offset + 4] << 3) |\n ((data[offset + 5] & 0xe0) >>> 5)\n );\n}\n\nexport function canGetFrameLength(data: Uint8Array, offset: number): boolean {\n return offset + 5 < data.length;\n}\n\nexport function isHeader(data: Uint8Array, offset: number): boolean {\n // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1\n // Layer bits (position 14 and 15) in header should be always 0 for ADTS\n // More info https://wiki.multimedia.cx/index.php?title=ADTS\n return offset + 1 < data.length && isHeaderPattern(data, offset);\n}\n\nexport function canParse(data: Uint8Array, offset: number): boolean {\n return (\n canGetFrameLength(data, offset) &&\n isHeaderPattern(data, offset) &&\n getFullFrameLength(data, offset) <= data.length - offset\n );\n}\n\nexport function probe(data: Uint8Array, offset: number): boolean {\n // same as isHeader but we also check that ADTS frame follows last ADTS frame\n // or end of data is reached\n if (isHeader(data, offset)) {\n // ADTS header Length\n const headerLength = getHeaderLength(data, offset);\n if (offset + headerLength >= data.length) {\n return false;\n }\n // ADTS frame Length\n const frameLength = getFullFrameLength(data, offset);\n if (frameLength <= headerLength) {\n return false;\n }\n\n const newOffset = offset + frameLength;\n return newOffset === data.length || isHeader(data, newOffset);\n }\n return false;\n}\n\nexport function initTrackConfig(\n track: DemuxedAudioTrack,\n observer: HlsEventEmitter,\n data: Uint8Array,\n offset: number,\n audioCodec: string | undefined,\n) {\n if (!track.samplerate) {\n const config = getAudioConfig(observer, data, offset, audioCodec);\n if (!config) {\n return;\n }\n Object.assign(track, config);\n }\n}\n\nexport function getFrameDuration(samplerate: number): number {\n return (1024 * 90000) / samplerate;\n}\n\nexport function parseFrameHeader(\n data: Uint8Array,\n offset: number,\n): FrameHeader | void {\n // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header\n const headerLength = getHeaderLength(data, offset);\n if (offset + headerLength <= data.length) {\n // retrieve frame size\n const frameLength = getFullFrameLength(data, offset) - headerLength;\n if (frameLength > 0) {\n // logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}`);\n return { headerLength, frameLength };\n }\n }\n}\n\nexport function appendFrame(\n track: DemuxedAudioTrack,\n data: Uint8Array,\n offset: number,\n pts: number,\n frameIndex: number,\n): AudioFrame {\n const frameDuration = getFrameDuration(track.samplerate as number);\n const stamp = pts + frameIndex * frameDuration;\n const header = parseFrameHeader(data, offset);\n let unit: Uint8Array;\n if (header) {\n const { frameLength, headerLength } = header;\n const length = headerLength + frameLength;\n const missing = Math.max(0, offset + length - data.length);\n // logger.log(`AAC frame ${frameIndex}, pts:${stamp} length@offset/total: ${frameLength}@${offset+headerLength}/${data.byteLength} missing: ${missing}`);\n if (missing) {\n unit = new Uint8Array(length - headerLength);\n unit.set(data.subarray(offset + headerLength, data.length), 0);\n } else {\n unit = data.subarray(offset + headerLength, offset + length);\n }\n\n const sample: AudioSample = {\n unit,\n pts: stamp,\n };\n if (!missing) {\n track.samples.push(sample as AudioSample);\n }\n\n return { sample, length, missing };\n }\n // overflow incomplete header\n const length = data.length - offset;\n unit = new Uint8Array(length);\n unit.set(data.subarray(offset, data.length), 0);\n const sample: AudioSample = {\n unit,\n pts: stamp,\n };\n return { sample, length, missing: -1 };\n}\n","// https://caniuse.com/mdn-javascript_builtins_number_isfinite\nexport const isFiniteNumber =\n Number.isFinite ||\n function (value) {\n return typeof value === 'number' && isFinite(value);\n };\n\n// https://caniuse.com/mdn-javascript_builtins_number_issafeinteger\nexport const isSafeInteger =\n Number.isSafeInteger ||\n function (value) {\n return typeof value === 'number' && Math.abs(value) <= MAX_SAFE_INTEGER;\n };\n\nexport const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;\n","import { isId3Header } from './util/isId3Header.js';\nimport { readId3Size } from './util/readId3Size.js';\n/**\n * Checks if the given data contains an ID3 tag.\n *\n * @param data - The data to check\n * @param offset - The offset at which to start checking\n *\n * @returns `true` if an ID3 tag is found\n *\n * @group ID3\n *\n * @beta\n */\nexport function canParseId3(data, offset) {\n return (isId3Header(data, offset) &&\n readId3Size(data, offset + 6) + 10 <= data.length - offset);\n}\n//# sourceMappingURL=canParseId3.js.map","// http://stackoverflow.com/questions/8936984/uint8array-to-string-in-javascript/22373197\n// http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt\n/* utf.js - UTF-8 <=> UTF-16 convertion\n *\n * Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>\n * Version: 1.0\n * LastModified: Dec 25 1999\n * This library is free. You can redistribute it and/or modify it.\n */\n/**\n * Converts a UTF-8 array to a string.\n *\n * @param array - The UTF-8 array to convert\n *\n * @returns The string\n *\n * @group Utils\n *\n * @beta\n */\nexport function utf8ArrayToStr(array, exitOnNull = false) {\n if (typeof TextDecoder !== 'undefined') {\n const decoder = new TextDecoder('utf-8');\n const decoded = decoder.decode(array);\n if (exitOnNull) {\n // grab up to the first null\n const idx = decoded.indexOf('\\0');\n return idx !== -1 ? decoded.substring(0, idx) : decoded;\n }\n // remove any null characters\n return decoded.replace(/\\0/g, '');\n }\n const len = array.length;\n let c;\n let char2;\n let char3;\n let out = '';\n let i = 0;\n while (i < len) {\n c = array[i++];\n if (c === 0x00 && exitOnNull) {\n return out;\n }\n else if (c === 0x00 || c === 0x03) {\n // If the character is 3 (END_OF_TEXT) or 0 (NULL) then skip it\n continue;\n }\n switch (c >> 4) {\n case 0:\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n case 6:\n case 7:\n // 0xxxxxxx\n out += String.fromCharCode(c);\n break;\n case 12:\n case 13:\n // 110x xxxx 10xx xxxx\n char2 = array[i++];\n out += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f));\n break;\n case 14:\n // 1110 xxxx 10xx xxxx 10xx xxxx\n char2 = array[i++];\n char3 = array[i++];\n out += String.fromCharCode(((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0));\n break;\n default:\n }\n }\n return out;\n}\n//# sourceMappingURL=utf8ArrayToStr.js.map","export function toUint8(data, offset = 0, length = Infinity) {\n return view(data, offset, length, Uint8Array);\n}\nfunction view(data, offset, length, Type) {\n const buffer = unsafeGetArrayBuffer(data);\n let bytesPerElement = 1;\n if ('BYTES_PER_ELEMENT' in Type) {\n bytesPerElement = Type.BYTES_PER_ELEMENT;\n }\n // Absolute end of the |data| view within |buffer|.\n const dataOffset = isArrayBufferView(data) ? data.byteOffset : 0;\n const dataEnd = ((dataOffset) + data.byteLength) / bytesPerElement;\n // Absolute start of the result within |buffer|.\n const rawStart = ((dataOffset) + offset) / bytesPerElement;\n const start = Math.floor(Math.max(0, Math.min(rawStart, dataEnd)));\n // Absolute end of the result within |buffer|.\n const end = Math.floor(Math.min(start + Math.max(length, 0), dataEnd));\n return new Type(buffer, start, end - start);\n}\nfunction unsafeGetArrayBuffer(view) {\n if (view instanceof ArrayBuffer) {\n return view;\n }\n else {\n return view.buffer;\n }\n}\nfunction isArrayBufferView(obj) {\n return obj && obj.buffer instanceof ArrayBuffer && obj.byteLength !== undefined && obj.byteOffset !== undefined;\n}\n//# sourceMappingURL=utf8.js.map","import { utf8ArrayToStr } from '../../utils.js';\nimport { toArrayBuffer } from './toArrayBuffer.js';\nimport { toUint8 } from './utf8.js';\nexport function decodeId3ImageFrame(frame) {\n const metadataFrame = {\n key: frame.type,\n description: '',\n data: '',\n mimeType: null,\n pictureType: null,\n };\n const utf8Encoding = 0x03;\n if (frame.size < 2) {\n return undefined;\n }\n if (frame.data[0] !== utf8Encoding) {\n console.log('Ignore frame with unrecognized character ' + 'encoding');\n return undefined;\n }\n const mimeTypeEndIndex = frame.data.subarray(1).indexOf(0);\n if (mimeTypeEndIndex === -1) {\n return undefined;\n }\n const mimeType = utf8ArrayToStr(toUint8(frame.data, 1, mimeTypeEndIndex));\n const pictureType = frame.data[2 + mimeTypeEndIndex];\n const descriptionEndIndex = frame.data\n .subarray(3 + mimeTypeEndIndex)\n .indexOf(0);\n if (descriptionEndIndex === -1) {\n return undefined;\n }\n const description = utf8ArrayToStr(toUint8(frame.data, 3 + mimeTypeEndIndex, descriptionEndIndex));\n let data;\n if (mimeType === '-->') {\n data = utf8ArrayToStr(toUint8(frame.data, 4 + mimeTypeEndIndex + descriptionEndIndex));\n }\n else {\n data = toArrayBuffer(frame.data.subarray(4 + mimeTypeEndIndex + descriptionEndIndex));\n }\n metadataFrame.mimeType = mimeType;\n metadataFrame.pictureType = pictureType;\n metadataFrame.description = description;\n metadataFrame.data = data;\n return metadataFrame;\n}\n//# sourceMappingURL=decodeId3ImageFrame.js.map","export function toArrayBuffer(view) {\n if (view instanceof ArrayBuffer) {\n return view;\n }\n else {\n if (view.byteOffset == 0 && view.byteLength == view.buffer.byteLength) {\n // This is a TypedArray over the whole buffer.\n return view.buffer;\n }\n // This is a 'view' on the buffer. Create a new buffer that only contains\n // the data. Note that since this isn't an ArrayBuffer, the 'new' call\n // will allocate a new buffer to hold the copy.\n return new Uint8Array(view).buffer;\n }\n}\n//# sourceMappingURL=toArrayBuffer.js.map","import { decodeId3PrivFrame } from './decodeId3PrivFrame.js';\nimport { decodeId3TextFrame } from './decodeId3TextFrame.js';\nimport { decodeId3UrlFrame } from './decodeId3UrlFrame.js';\nimport { decodeId3ImageFrame } from './decodeId3ImageFrame.js';\n/**\n * Decode an ID3 frame.\n *\n * @param frame - the ID3 frame\n *\n * @returns The decoded ID3 frame\n *\n * @internal\n *\n * @group ID3\n */\nexport function decodeId3Frame(frame) {\n if (frame.type === 'PRIV') {\n return decodeId3PrivFrame(frame);\n }\n else if (frame.type[0] === 'W') {\n return decodeId3UrlFrame(frame);\n }\n else if (frame.type === 'APIC') {\n return decodeId3ImageFrame(frame);\n }\n return decodeId3TextFrame(frame);\n}\n//# sourceMappingURL=decodeId3Frame.js.map","import { utf8ArrayToStr } from '../../utils/utf8ArrayToStr.js';\n/**\n * Decode an ID3 PRIV frame.\n *\n * @param frame - the ID3 PRIV frame\n *\n * @returns The decoded ID3 PRIV frame\n *\n * @internal\n *\n * @group ID3\n */\nexport function decodeId3PrivFrame(frame) {\n /*\n Format: <text string>\\0<binary data>\n */\n if (frame.size < 2) {\n return undefined;\n }\n const owner = utf8ArrayToStr(frame.data, true);\n const privateData = new Uint8Array(frame.data.subarray(owner.length + 1));\n return { key: frame.type, info: owner, data: privateData.buffer };\n}\n//# sourceMappingURL=decodeId3PrivFrame.js.map","import { utf8ArrayToStr } from '../../utils/utf8ArrayToStr.js';\n/**\n * Decode a URL frame\n *\n * @param frame - the ID3 URL frame\n *\n * @returns The decoded ID3 URL frame\n *\n * @internal\n *\n * @group ID3\n */\nexport function decodeId3UrlFrame(frame) {\n if (frame.type === 'WXXX') {\n /*\n Format:\n [0] = {Text Encoding}\n [1-?] = {Description}\\0{URL}\n */\n if (frame.size < 2) {\n return undefined;\n }\n let index = 1;\n const description = utf8ArrayToStr(frame.data.subarray(index), true);\n index += description.length + 1;\n const value = utf8ArrayToStr(frame.data.subarray(index));\n return { key: frame.type, info: description, data: value };\n }\n /*\n Format:\n [0-?] = {URL}\n */\n const url = utf8ArrayToStr(frame.data);\n return { key: frame.type, info: '', data: url };\n}\n//# sourceMappingURL=decodeId3UrlFrame.js.map","import { utf8ArrayToStr } from '../../utils/utf8ArrayToStr.js';\n/**\n * Decodes an ID3 text frame\n *\n * @param frame - the ID3 text frame\n *\n * @returns The decoded ID3 text frame\n *\n * @internal\n *\n * @group ID3\n */\nexport function decodeId3TextFrame(frame) {\n if (frame.size < 2) {\n return undefined;\n }\n if (frame.type === 'TXXX') {\n /*\n Format:\n [0] = {Text Encoding}\n [1-?] = {Description}\\0{Value}\n */\n let index = 1;\n const description = utf8ArrayToStr(frame.data.subarray(index), true);\n index += description.length + 1;\n const value = utf8ArrayToStr(frame.data.subarray(index));\n return { key: frame.type, info: description, data: value };\n }\n /*\n Format:\n [0] = {Text Encoding}\n [1-?] = {Value}\n */\n const text = utf8ArrayToStr(frame.data.subarray(1));\n return { key: frame.type, info: '', data: text };\n}\n//# sourceMappingURL=decodeId3TextFrame.js.map","import { readId3Size } from './readId3Size.js';\n/**\n * Returns the data of an ID3 frame.\n *\n * @param data - The data to read from\n *\n * @returns The data of the ID3 frame\n *\n * @internal\n *\n * @group ID3\n */\nexport function getId3FrameData(data) {\n /*\n Frame ID $xx xx xx xx (four characters)\n Size $xx xx xx xx\n Flags $xx xx\n */\n const type = String.fromCharCode(data[0], data[1], data[2], data[3]);\n const size = readId3Size(data, 4);\n // skip frame id, size, and flags\n const offset = 10;\n return { type, size, data: data.subarray(offset, offset + size) };\n}\n//# sourceMappingURL=getId3FrameData.js.map","import { decodeId3Frame } from './util/decodeId3Frame.js';\nimport { getId3FrameData } from './util/getId3FrameData.js';\nimport { isId3Footer } from './util/isId3Footer.js';\nimport { isId3Header } from './util/isId3Header.js';\nimport { readId3Size } from './util/readId3Size.js';\nconst HEADER_FOOTER_SIZE = 10;\nconst FRAME_SIZE = 10;\n/**\n * Returns an array of ID3 frames found in all the ID3 tags in the id3Data\n *\n * @param id3Data - The ID3 data containing one or more ID3 tags\n *\n * @returns Array of ID3 frame objects\n *\n * @group ID3\n *\n * @beta\n */\nexport function getId3Frames(id3Data) {\n let offset = 0;\n const frames = [];\n while (isId3Header(id3Data, offset)) {\n const size = readId3Size(id3Data, offset + 6);\n if ((id3Data[offset + 5] >> 6) & 1) {\n // skip extended header\n offset += HEADER_FOOTER_SIZE;\n }\n // skip past ID3 header\n offset += HEADER_FOOTER_SIZE;\n const end = offset + size;\n // loop through frames in the ID3 tag\n while (offset + FRAME_SIZE < end) {\n const frameData = getId3FrameData(id3Data.subarray(offset));\n const frame = decodeId3Frame(frameData);\n if (frame) {\n frames.push(frame);\n }\n // skip frame header and frame data\n offset += frameData.size + HEADER_FOOTER_SIZE;\n }\n if (isId3Footer(id3Data, offset)) {\n offset += HEADER_FOOTER_SIZE;\n }\n }\n return frames;\n}\n//# sourceMappingURL=getId3Frames.js.map","/**\n * Returns true if the ID3 frame is an Elementary Stream timestamp frame\n *\n * @param frame - the ID3 frame\n *\n * @returns `true` if the ID3 frame is an Elementary Stream timestamp frame\n *\n * @internal\n *\n * @group ID3\n */\nexport function isId3TimestampFrame(frame) {\n return (frame &&\n frame.key === 'PRIV' &&\n frame.info === 'com.apple.streaming.transportStreamTimestamp');\n}\n//# sourceMappingURL=isId3TimestampFrame.js.map","/**\n * Read a 33 bit timestamp from an ID3 frame.\n *\n * @param timeStampFrame - the ID3 frame\n *\n * @returns The timestamp\n *\n * @internal\n *\n * @group ID3\n */\nexport function readId3Timestamp(timeStampFrame) {\n if (timeStampFrame.data.byteLength === 8) {\n const data = new Uint8Array(timeStampFrame.data);\n // timestamp is 33 bit expressed as a big-endian eight-octet number,\n // with the upper 31 bits set to zero.\n const pts33Bit = data[3] & 0x1;\n let timestamp = (data[4] << 23) + (data[5] << 15) + (data[6] << 7) + data[7];\n timestamp /= 45;\n if (pts33Bit) {\n timestamp += 47721858.84;\n } // 2^32 / 90\n return Math.round(timestamp);\n }\n return undefined;\n}\n//# sourceMappingURL=readId3Timestamp.js.map","import { getId3Frames } from './getId3Frames.js';\nimport { isId3TimestampFrame } from './isId3TimestampFrame.js';\nimport { readId3Timestamp } from './util/readId3Timestamp.js';\n/**\n * Searches for the Elementary Stream timestamp found in the ID3 data chunk\n *\n * @param data - Block of data containing one or more ID3 tags\n *\n * @returns The timestamp\n *\n * @group ID3\n *\n * @beta\n */\nexport function getId3Timestamp(data) {\n const frames = getId3Frames(data);\n for (let i = 0; i < frames.length; i++) {\n const frame = frames[i];\n if (isId3TimestampFrame(frame)) {\n return readId3Timestamp(frame);\n }\n }\n return undefined;\n}\n//# sourceMappingURL=getId3Timestamp.js.map","import type { RationalTimestamp } from '../utils/timescale-conversion';\n\nexport interface Demuxer {\n demux(\n data: Uint8Array,\n timeOffset: number,\n isSampleAes?: boolean,\n flush?: boolean,\n ): DemuxerResult;\n demuxSampleAes(\n data: Uint8Array,\n keyData: KeyData,\n timeOffset: number,\n ): Promise<DemuxerResult>;\n flush(timeOffset?: number): DemuxerResult | Promise<DemuxerResult>;\n destroy(): void;\n resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n );\n resetTimeStamp(defaultInitPTS?: RationalTimestamp | null): void;\n resetContiguity(): void;\n}\n\nexport interface DemuxerResult {\n audioTrack: DemuxedAudioTrack;\n videoTrack: DemuxedVideoTrackBase;\n id3Track: DemuxedMetadataTrack;\n textTrack: DemuxedUserdataTrack;\n}\n\nexport interface DemuxedTrack {\n type: string;\n id: number;\n pid: number;\n inputTimeScale: number;\n sequenceNumber: number;\n samples:\n | AudioSample[]\n | VideoSample[]\n | MetadataSample[]\n | UserdataSample[]\n | Uint8Array;\n timescale?: number;\n container?: string;\n dropped: number;\n duration?: number;\n pesData?: ElementaryStreamData | null;\n codec?: string;\n}\n\nexport interface PassthroughTrack extends DemuxedTrack {\n sampleDuration: number;\n samples: Uint8Array;\n timescale: number;\n duration: number;\n codec: string;\n}\nexport interface DemuxedAudioTrack extends DemuxedTrack {\n type: 'audio';\n segmentCodec: 'aac' | 'ac3' | 'mp3';\n config?: number[] | Uint8Array;\n samplerate?: number;\n channelCount?: number;\n manifestCodec?: string;\n parsedCodec?: string;\n samples: AudioSample[];\n}\n\nexport type DemuxedAC3 = DemuxedAudioTrack & {\n segmentCodec: 'ac3';\n config: Uint8Array;\n};\n\nexport interface DemuxedVideoTrackBase extends DemuxedTrack {\n width?: number;\n height?: number;\n pixelRatio?: [number, number];\n audFound?: boolean;\n vps?: Uint8Array[];\n pps?: Uint8Array[];\n sps?: Uint8Array[];\n naluState?: number;\n segmentCodec?: string;\n manifestCodec?: string;\n samples: VideoSample[] | Uint8Array;\n params?: object;\n}\n\nexport interface DemuxedVideoTrack extends DemuxedVideoTrackBase {\n type: 'video';\n segmentCodec: 'avc' | 'hevc';\n samples: VideoSample[];\n pixelRatio: [number, number];\n width: number;\n height: number;\n}\n\nexport type DemuxedAVC1 = DemuxedVideoTrack & {\n segmentCodec: 'avc';\n pps: Uint8Array[];\n sps: Uint8Array[];\n};\n\nexport type DemuxedHEVC = DemuxedVideoTrack & {\n segmentCodec: 'hevc';\n params: {\n general_profile_space: number;\n general_tier_flag: number;\n general_profile_idc: number;\n general_profile_compatibility_flags: number[];\n general_constraint_indicator_flags: number[];\n general_level_idc: number;\n min_spatial_segmentation_idc: number;\n parallelismType: number;\n chroma_format_idc: number;\n bit_depth_luma_minus8: number;\n bit_depth_chroma_minus8: number;\n frame_rate: { fps: string; fixed: boolean };\n temporal_id_nested: number;\n num_temporal_layers: number;\n };\n pps: Uint8Array[];\n sps: Uint8Array[];\n vps: Uint8Array;\n};\n\nexport interface DemuxedMetadataTrack extends DemuxedTrack {\n samples: MetadataSample[];\n}\n\nexport interface DemuxedUserdataTrack extends DemuxedTrack {\n samples: UserdataSample[];\n}\n\nexport enum MetadataSchema {\n audioId3 = 'org.id3',\n dateRange = 'com.apple.quicktime.HLS',\n emsg = 'https://aomedia.org/emsg/ID3',\n misbklv = 'urn:misb:KLV:bin:1910.1',\n}\nexport interface MetadataSample {\n pts: number;\n dts: number;\n duration: number;\n len?: number;\n data: Uint8Array;\n type: MetadataSchema;\n}\n\nexport interface UserdataSample {\n pts: number;\n bytes?: Uint8Array;\n type?: number;\n payloadType?: number;\n uuid?: string;\n userData?: string;\n userDataBytes?: Uint8Array;\n}\n\nexport interface VideoSample {\n dts: number;\n pts: number;\n key: boolean;\n frame: boolean;\n units: VideoSampleUnit[];\n length: number;\n}\n\nexport interface VideoSampleUnit {\n data: Uint8Array;\n type: number;\n state?: number;\n}\n\nexport type AudioSample = {\n unit: Uint8Array;\n pts: number;\n};\n\nexport type AudioFrame = {\n sample: AudioSample;\n length: number;\n missing: number;\n};\n\nexport interface ElementaryStreamData {\n data: Uint8Array[];\n size: number;\n}\n\nexport interface KeyData {\n method: string;\n key: Uint8Array;\n iv: Uint8Array;\n}\n","/**\n * hex dump helper class\n */\n\nconst Hex = {\n hexDump: function (array: Uint8Array) {\n let str = '';\n for (let i = 0; i < array.length; i++) {\n let h = array[i].toString(16);\n if (h.length < 2) {\n h = '0' + h;\n }\n\n str += h;\n }\n return str;\n },\n};\n\nexport default Hex;\n","export function sliceUint8(\n array: Uint8Array,\n start?: number,\n end?: number,\n): Uint8Array {\n // @ts-expect-error This polyfills IE11 usage of Uint8Array slice.\n // It always exists in the TypeScript definition so fails, but it fails at runtime on IE11.\n return Uint8Array.prototype.slice\n ? array.slice(start, end)\n : new Uint8Array(Array.prototype.slice.call(array, start, end));\n}\n","// see https://tools.ietf.org/html/rfc1808\n\n(function (root) {\n var URL_REGEX =\n /^(?=((?:[a-zA-Z0-9+\\-.]+:)?))\\1(?=((?:\\/\\/[^\\/?#]*)?))\\2(?=((?:(?:[^?#\\/]*\\/)*[^;?#\\/]*)?))\\3((?:;[^?#]*)?)(\\?[^#]*)?(#[^]*)?$/;\n var FIRST_SEGMENT_REGEX = /^(?=([^\\/?#]*))\\1([^]*)$/;\n var SLASH_DOT_REGEX = /(?:\\/|^)\\.(?=\\/)/g;\n var SLASH_DOT_DOT_REGEX = /(?:\\/|^)\\.\\.\\/(?!\\.\\.\\/)[^\\/]*(?=\\/)/g;\n\n var URLToolkit = {\n // If opts.alwaysNormalize is true then the path will always be normalized even when it starts with / or //\n // E.g\n // With opts.alwaysNormalize = false (default, spec compliant)\n // http://a.com/b/cd + /e/f/../g => http://a.com/e/f/../g\n // With opts.alwaysNormalize = true (not spec compliant)\n // http://a.com/b/cd + /e/f/../g => http://a.com/e/g\n buildAbsoluteURL: function (baseURL, relativeURL, opts) {\n opts = opts || {};\n // remove any remaining space and CRLF\n baseURL = baseURL.trim();\n relativeURL = relativeURL.trim();\n if (!relativeURL) {\n // 2a) If the embedded URL is entirely empty, it inherits the\n // entire base URL (i.e., is set equal to the base URL)\n // and we are done.\n if (!opts.alwaysNormalize) {\n return baseURL;\n }\n var basePartsForNormalise = URLToolkit.parseURL(baseURL);\n if (!basePartsForNormalise) {\n throw new Error('Error trying to parse base URL.');\n }\n basePartsForNormalise.path = URLToolkit.normalizePath(\n basePartsForNormalise.path\n );\n return URLToolkit.buildURLFromParts(basePartsForNormalise);\n }\n var relativeParts = URLToolkit.parseURL(relativeURL);\n if (!relativeParts) {\n throw new Error('Error trying to parse relative URL.');\n }\n if (relativeParts.scheme) {\n // 2b) If the embedded URL starts with a scheme name, it is\n // interpreted as an absolute URL and we are done.\n if (!opts.alwaysNormalize) {\n return relativeURL;\n }\n relativeParts.path = URLToolkit.normalizePath(relativeParts.path);\n return URLToolkit.buildURLFromParts(relativeParts);\n }\n var baseParts = URLToolkit.parseURL(baseURL);\n if (!baseParts) {\n throw new Error('Error trying to parse base URL.');\n }\n if (!baseParts.netLoc && baseParts.path && baseParts.path[0] !== '/') {\n // If netLoc missing and path doesn't start with '/', assume everthing before the first '/' is the netLoc\n // This causes 'example.com/a' to be handled as '//example.com/a' instead of '/example.com/a'\n var pathParts = FIRST_SEGMENT_REGEX.exec(baseParts.path);\n baseParts.netLoc = pathParts[1];\n baseParts.path = pathParts[2];\n }\n if (baseParts.netLoc && !baseParts.path) {\n baseParts.path = '/';\n }\n var builtParts = {\n // 2c) Otherwise, the embedded URL inherits the scheme of\n // the base URL.\n scheme: baseParts.scheme,\n netLoc: relativeParts.netLoc,\n path: null,\n params: relativeParts.params,\n query: relativeParts.query,\n fragment: relativeParts.fragment,\n };\n if (!relativeParts.netLoc) {\n // 3) If the embedded URL's <net_loc> is non-empty, we skip to\n // Step 7. Otherwise, the embedded URL inherits the <net_loc>\n // (if any) of the base URL.\n builtParts.netLoc = baseParts.netLoc;\n // 4) If the embedded URL path is preceded by a slash \"/\", the\n // path is not relative and we skip to Step 7.\n if (relativeParts.path[0] !== '/') {\n if (!relativeParts.path) {\n // 5) If the embedded URL path is empty (and not preceded by a\n // slash), then the embedded URL inherits the base URL path\n builtParts.path = baseParts.path;\n // 5a) if the embedded URL's <params> is non-empty, we skip to\n // step 7; otherwise, it inherits the <params> of the base\n // URL (if any) and\n if (!relativeParts.params) {\n builtParts.params = baseParts.params;\n // 5b) if the embedded URL's <query> is non-empty, we skip to\n // step 7; otherwise, it inherits the <query> of the base\n // URL (if any) and we skip to step 7.\n if (!relativeParts.query) {\n builtParts.query = baseParts.query;\n }\n }\n } else {\n // 6) The last segment of the base URL's path (anything\n // following the rightmost slash \"/\", or the entire path if no\n // slash is present) is removed and the embedded URL's path is\n // appended in its place.\n var baseURLPath = baseParts.path;\n var newPath =\n baseURLPath.substring(0, baseURLPath.lastIndexOf('/') + 1) +\n relativeParts.path;\n builtParts.path = URLToolkit.normalizePath(newPath);\n }\n }\n }\n if (builtParts.path === null) {\n builtParts.path = opts.alwaysNormalize\n ? URLToolkit.normalizePath(relativeParts.path)\n : relativeParts.path;\n }\n return URLToolkit.buildURLFromParts(builtParts);\n },\n parseURL: function (url) {\n var parts = URL_REGEX.exec(url);\n if (!parts) {\n return null;\n }\n return {\n scheme: parts[1] || '',\n netLoc: parts[2] || '',\n path: parts[3] || '',\n params: parts[4] || '',\n query: parts[5] || '',\n fragment: parts[6] || '',\n };\n },\n normalizePath: function (path) {\n // The following operations are\n // then applied, in order, to the new path:\n // 6a) All occurrences of \"./\", where \".\" is a complete path\n // segment, are removed.\n // 6b) If the path ends with \".\" as a complete path segment,\n // that \".\" is removed.\n path = path.split('').reverse().join('').replace(SLASH_DOT_REGEX, '');\n // 6c) All occurrences of \"<segment>/../\", where <segment> is a\n // complete path segment not equal to \"..\", are removed.\n // Removal of these path segments is performed iteratively,\n // removing the leftmost matching pattern on each iteration,\n // until no matching pattern remains.\n // 6d) If the path ends with \"<segment>/..\", where <segment> is a\n // complete path segment not equal to \"..\", that\n // \"<segment>/..\" is removed.\n while (\n path.length !== (path = path.replace(SLASH_DOT_DOT_REGEX, '')).length\n ) {}\n return path.split('').reverse().join('');\n },\n buildURLFromParts: function (parts) {\n return (\n parts.scheme +\n parts.netLoc +\n parts.path +\n parts.params +\n parts.query +\n parts.fragment\n );\n },\n };\n\n if (typeof exports === 'object' && typeof module === 'object')\n module.exports = URLToolkit;\n else if (typeof define === 'function' && define.amd)\n define([], function () {\n return URLToolkit;\n });\n else if (typeof exports === 'object') exports['URLToolkit'] = URLToolkit;\n else root['URLToolkit'] = URLToolkit;\n})(this);\n","import { buildAbsoluteURL } from 'url-toolkit';\nimport { LoadStats } from './load-stats';\nimport type { LevelKey } from './level-key';\nimport type {\n FragmentLoaderContext,\n KeyLoaderContext,\n Loader,\n PlaylistLevelType,\n} from '../types/loader';\nimport type { AttrList } from '../utils/attr-list';\nimport type { KeySystemFormats } from '../utils/mediakeys-helper';\n\nexport const enum ElementaryStreamTypes {\n AUDIO = 'audio',\n VIDEO = 'video',\n AUDIOVIDEO = 'audiovideo',\n}\n\nexport interface ElementaryStreamInfo {\n startPTS: number;\n endPTS: number;\n startDTS: number;\n endDTS: number;\n partial?: boolean;\n}\n\nexport type ElementaryStreams = Record<\n ElementaryStreamTypes,\n ElementaryStreamInfo | null\n>;\n\nexport type Base = {\n url: string;\n};\n\nexport class BaseSegment {\n private _byteRange: [number, number] | null = null;\n private _url: string | null = null;\n private _stats: LoadStats | null = null;\n private _streams: ElementaryStreams | null = null;\n\n // baseurl is the URL to the playlist\n public readonly base: Base;\n\n // relurl is the portion of the URL that comes from inside the playlist.\n public relurl?: string;\n\n constructor(base: Base | string) {\n if (typeof base === 'string') {\n base = { url: base };\n }\n this.base = base;\n makeEnumerable(this, 'stats');\n }\n\n // setByteRange converts a EXT-X-BYTERANGE attribute into a two element array\n setByteRange(value: string, previous?: BaseSegment) {\n const params = value.split('@', 2);\n let start: number;\n if (params.length === 1) {\n start = previous?.byteRangeEndOffset || 0;\n } else {\n start = parseInt(params[1]);\n }\n this._byteRange = [start, parseInt(params[0]) + start];\n }\n\n get baseurl(): string {\n return this.base.url;\n }\n\n get byteRange(): [number, number] | [] {\n if (this._byteRange === null) {\n return [];\n }\n\n return this._byteRange;\n }\n\n get byteRangeStartOffset(): number | undefined {\n return this.byteRange[0];\n }\n\n get byteRangeEndOffset(): number | undefined {\n return this.byteRange[1];\n }\n\n get elementaryStreams(): ElementaryStreams {\n if (this._streams === null) {\n this._streams = {\n [ElementaryStreamTypes.AUDIO]: null,\n [ElementaryStreamTypes.VIDEO]: null,\n [ElementaryStreamTypes.AUDIOVIDEO]: null,\n };\n }\n return this._streams;\n }\n\n set elementaryStreams(value: ElementaryStreams) {\n this._streams = value;\n }\n\n get hasStats(): boolean {\n return this._stats !== null;\n }\n\n get hasStreams(): boolean {\n return this._streams !== null;\n }\n\n get stats(): LoadStats {\n if (this._stats === null) {\n this._stats = new LoadStats();\n }\n return this._stats;\n }\n\n set stats(value: LoadStats) {\n this._stats = value;\n }\n\n get url(): string {\n if (!this._url && this.baseurl && this.relurl) {\n this._url = buildAbsoluteURL(this.baseurl, this.relurl, {\n alwaysNormalize: true,\n });\n }\n return this._url || '';\n }\n\n set url(value: string) {\n this._url = value;\n }\n\n clearElementaryStreamInfo() {\n const { elementaryStreams } = this;\n elementaryStreams[ElementaryStreamTypes.AUDIO] = null;\n elementaryStreams[ElementaryStreamTypes.VIDEO] = null;\n elementaryStreams[ElementaryStreamTypes.AUDIOVIDEO] = null;\n }\n}\n\nexport interface MediaFragment extends Fragment {\n sn: number;\n ref: MediaFragmentRef;\n}\n\nexport type MediaFragmentRef = {\n base: Base;\n start: number;\n duration: number;\n sn: number;\n programDateTime: number | null;\n};\n\nexport function isMediaFragment(frag: Fragment): frag is MediaFragment {\n return frag.sn !== 'initSegment';\n}\n\n/**\n * Object representing parsed data from an HLS Segment. Found in {@link hls.js#LevelDetails.fragments}.\n */\nexport class Fragment extends BaseSegment {\n private _decryptdata: LevelKey | null = null;\n private _programDateTime: number | null = null;\n private _ref: MediaFragmentRef | null = null;\n // Approximate bit rate of the fragment expressed in bits per second (bps) as indicated by the last EXT-X-BITRATE (kbps) tag\n private _bitrate?: number;\n\n public rawProgramDateTime: string | null = null;\n public tagList: Array<string[]> = [];\n\n // EXTINF has to be present for a m3u8 to be considered valid\n public duration: number = 0;\n // sn notates the sequence number for a segment, and if set to a string can be 'initSegment'\n public sn: number | 'initSegment' = 0;\n // levelkeys are the EXT-X-KEY tags that apply to this segment for decryption\n // core difference from the private field _decryptdata is the lack of the initialized IV\n // _decryptdata will set the IV for this segment based on the segment number in the fragment\n public levelkeys?: { [key: string]: LevelKey };\n // A string representing the fragment type\n public readonly type: PlaylistLevelType;\n // A reference to the loader. Set while the fragment is loading, and removed afterwards. Used to abort fragment loading\n public loader: Loader<FragmentLoaderContext> | null = null;\n // A reference to the key loader. Set while the key is loading, and removed afterwards. Used to abort key loading\n public keyLoader: Loader<KeyLoaderContext> | null = null;\n // The level/track index to which the fragment belongs\n public level: number = -1;\n // The continuity counter of the fragment\n public cc: number = 0;\n // The starting Presentation Time Stamp (PTS) of the fragment. Set after transmux complete.\n public startPTS?: number;\n // The ending Presentation Time Stamp (PTS) of the fragment. Set after transmux complete.\n public endPTS?: number;\n // The starting Decode Time Stamp (DTS) of the fragment. Set after transmux complete.\n public startDTS?: number;\n // The ending Decode Time Stamp (DTS) of the fragment. Set after transmux complete.\n public endDTS?: number;\n // The start time of the fragment, as listed in the manifest. Updated after transmux complete.\n public start: number = 0;\n // The offset time (seconds) of the fragment from the start of the Playlist\n public playlistOffset: number = 0;\n // Set by `updateFragPTSDTS` in level-helper\n public deltaPTS?: number;\n // The maximum starting Presentation Time Stamp (audio/video PTS) of the fragment. Set after transmux complete.\n public maxStartPTS?: number;\n // The minimum ending Presentation Time Stamp (audio/video PTS) of the fragment. Set after transmux complete.\n public minEndPTS?: number;\n // Init Segment bytes (unset for media segments)\n public data?: Uint8Array;\n // A flag indicating whether the segment was downloaded in order to test bitrate, and was not buffered\n public bitrateTest: boolean = false;\n // #EXTINF segment title\n public title: string | null = null;\n // The Media Initialization Section for this segment\n public initSegment: Fragment | null = null;\n // Fragment is the last fragment in the media playlist\n public endList?: boolean;\n // Fragment is marked by an EXT-X-GAP tag indicating that it does not contain media data and should not be loaded\n public gap?: boolean;\n // Deprecated\n public urlId: number = 0;\n\n constructor(type: PlaylistLevelType, base: Base | string) {\n super(base);\n this.type = type;\n }\n\n get byteLength(): number | null {\n if (this.hasStats) {\n const total = this.stats.total;\n if (total) {\n return total;\n }\n }\n if (this.byteRange) {\n const start = this.byteRange[0];\n const end = this.byteRange[1];\n if (Number.isFinite(start) && Number.isFinite(end)) {\n return (end as number) - (start as number);\n }\n }\n return null;\n }\n\n get bitrate(): number | null {\n if (this.byteLength) {\n return (this.byteLength * 8) / this.duration;\n }\n if (this._bitrate) {\n return this._bitrate;\n }\n return null;\n }\n\n set bitrate(value: number) {\n this._bitrate = value;\n }\n\n get decryptdata(): LevelKey | null {\n const { levelkeys } = this;\n if (!levelkeys && !this._decryptdata) {\n return null;\n }\n\n if (!this._decryptdata && this.levelkeys && !this.levelkeys.NONE) {\n const key = this.levelkeys.identity;\n if (key) {\n this._decryptdata = key.getDecryptData(this.sn);\n } else {\n const keyFormats = Object.keys(this.levelkeys);\n if (keyFormats.length === 1) {\n return (this._decryptdata = this.levelkeys[\n keyFormats[0]\n ].getDecryptData(this.sn));\n } else {\n // Multiple keys. key-loader to call Fragment.setKeyFormat based on selected key-system.\n }\n }\n }\n\n return this._decryptdata;\n }\n\n get end(): number {\n return this.start + this.duration;\n }\n\n get endProgramDateTime() {\n if (this.programDateTime === null) {\n return null;\n }\n\n const duration = !Number.isFinite(this.duration) ? 0 : this.duration;\n\n return this.programDateTime + duration * 1000;\n }\n\n get encrypted() {\n // At the m3u8-parser level we need to add support for manifest signalled keyformats\n // when we want the fragment to start reporting that it is encrypted.\n // Currently, keyFormat will only be set for identity keys\n if (this._decryptdata?.encrypted) {\n return true;\n } else if (this.levelkeys) {\n const keyFormats = Object.keys(this.levelkeys);\n const len = keyFormats.length;\n if (len > 1 || (len === 1 && this.levelkeys[keyFormats[0]].encrypted)) {\n return true;\n }\n }\n return false;\n }\n\n get programDateTime(): number | null {\n if (this._programDateTime === null && this.rawProgramDateTime) {\n this.programDateTime = Date.parse(this.rawProgramDateTime);\n }\n return this._programDateTime;\n }\n\n set programDateTime(value: number | null) {\n if (!Number.isFinite(value)) {\n this._programDateTime = this.rawProgramDateTime = null;\n return;\n }\n this._programDateTime = value;\n }\n\n get ref(): MediaFragmentRef | null {\n if (!isMediaFragment(this)) {\n return null;\n }\n if (!this._ref) {\n this._ref = {\n base: this.base,\n start: this.start,\n duration: this.duration,\n sn: this.sn,\n programDateTime: this.programDateTime,\n };\n }\n return this._ref;\n }\n\n addStart(value: number) {\n this.setStart(this.start + value);\n }\n\n setStart(value: number) {\n this.start = value;\n if (this._ref) {\n this._ref.start = value;\n }\n }\n\n setDuration(value: number) {\n this.duration = value;\n if (this._ref) {\n this._ref.duration = value;\n }\n }\n\n setKeyFormat(keyFormat: KeySystemFormats) {\n if (this.levelkeys) {\n const key = this.levelkeys[keyFormat];\n if (key && !this._decryptdata) {\n this._decryptdata = key.getDecryptData(this.sn);\n }\n }\n }\n\n abortRequests(): void {\n this.loader?.abort();\n this.keyLoader?.abort();\n }\n\n setElementaryStreamInfo(\n type: ElementaryStreamTypes,\n startPTS: number,\n endPTS: number,\n startDTS: number,\n endDTS: number,\n partial: boolean = false,\n ) {\n const { elementaryStreams } = this;\n const info = elementaryStreams[type];\n if (!info) {\n elementaryStreams[type] = {\n startPTS,\n endPTS,\n startDTS,\n endDTS,\n partial,\n };\n return;\n }\n\n info.startPTS = Math.min(info.startPTS, startPTS);\n info.endPTS = Math.max(info.endPTS, endPTS);\n info.startDTS = Math.min(info.startDTS, startDTS);\n info.endDTS = Math.max(info.endDTS, endDTS);\n }\n}\n\n/**\n * Object representing parsed data from an HLS Partial Segment. Found in {@link hls.js#LevelDetails.partList}.\n */\nexport class Part extends BaseSegment {\n public readonly fragOffset: number = 0;\n public readonly duration: number = 0;\n public readonly gap: boolean = false;\n public readonly independent: boolean = false;\n public readonly relurl: string;\n public readonly fragment: MediaFragment;\n public readonly index: number;\n\n constructor(\n partAttrs: AttrList,\n frag: MediaFragment,\n base: Base | string,\n index: number,\n previous?: Part,\n ) {\n super(base);\n this.duration = partAttrs.decimalFloatingPoint('DURATION');\n this.gap = partAttrs.bool('GAP');\n this.independent = partAttrs.bool('INDEPENDENT');\n this.relurl = partAttrs.enumeratedString('URI') as string;\n this.fragment = frag;\n this.index = index;\n const byteRange = partAttrs.enumeratedString('BYTERANGE');\n if (byteRange) {\n this.setByteRange(byteRange, previous);\n }\n if (previous) {\n this.fragOffset = previous.fragOffset + previous.duration;\n }\n }\n\n get start(): number {\n return this.fragment.start + this.fragOffset;\n }\n\n get end(): number {\n return this.start + this.duration;\n }\n\n get loaded(): boolean {\n const { elementaryStreams } = this;\n return !!(\n elementaryStreams.audio ||\n elementaryStreams.video ||\n elementaryStreams.audiovideo\n );\n }\n}\n\nfunction getOwnPropertyDescriptorFromPrototypeChain(\n object: Object | undefined,\n property: string,\n) {\n const prototype = Object.getPrototypeOf(object);\n if (prototype) {\n const propertyDescriptor = Object.getOwnPropertyDescriptor(\n prototype,\n property,\n );\n if (propertyDescriptor) {\n return propertyDescriptor;\n }\n return getOwnPropertyDescriptorFromPrototypeChain(prototype, property);\n }\n}\n\nfunction makeEnumerable(object: Object, property: string) {\n const d = getOwnPropertyDescriptorFromPrototypeChain(object, property);\n if (d) {\n d.enumerable = true;\n Object.defineProperty(object, property, d);\n }\n}\n","import { utf8ArrayToStr } from '@svta/common-media-library/utils/utf8ArrayToStr';\nimport Hex from './hex';\nimport { sliceUint8 } from './typed-array';\nimport { ElementaryStreamTypes } from '../loader/fragment';\nimport { logger } from '../utils/logger';\nimport type { KeySystemIds } from './mediakeys-helper';\nimport type { DecryptData } from '../loader/level-key';\nimport type { PassthroughTrack, UserdataSample } from '../types/demuxer';\n\nconst UINT32_MAX = Math.pow(2, 32) - 1;\nconst push = [].push;\n\n// We are using fixed track IDs for driving the MP4 remuxer\n// instead of following the TS PIDs.\n// There is no reason not to do this and some browsers/SourceBuffer-demuxers\n// may not like if there are TrackID \"switches\"\n// See https://github.com/video-dev/hls.js/issues/1331\n// Here we are mapping our internal track types to constant MP4 track IDs\n// With MSE currently one can only have one track of each, and we are muxing\n// whatever video/audio rendition in them.\nexport const RemuxerTrackIdConfig = {\n video: 1,\n audio: 2,\n id3: 3,\n text: 4,\n};\n\nexport function bin2str(data: Uint8Array): string {\n return String.fromCharCode.apply(null, data);\n}\n\nexport function readUint16(buffer: Uint8Array, offset: number): number {\n const val = (buffer[offset] << 8) | buffer[offset + 1];\n return val < 0 ? 65536 + val : val;\n}\n\nexport function readUint32(buffer: Uint8Array, offset: number): number {\n const val = readSint32(buffer, offset);\n return val < 0 ? 4294967296 + val : val;\n}\n\nexport function readUint64(buffer: Uint8Array, offset: number) {\n let result = readUint32(buffer, offset);\n result *= Math.pow(2, 32);\n result += readUint32(buffer, offset + 4);\n return result;\n}\n\nexport function readSint32(buffer: Uint8Array, offset: number): number {\n return (\n (buffer[offset] << 24) |\n (buffer[offset + 1] << 16) |\n (buffer[offset + 2] << 8) |\n buffer[offset + 3]\n );\n}\n\nexport function writeUint32(buffer: Uint8Array, offset: number, value: number) {\n buffer[offset] = value >> 24;\n buffer[offset + 1] = (value >> 16) & 0xff;\n buffer[offset + 2] = (value >> 8) & 0xff;\n buffer[offset + 3] = value & 0xff;\n}\n\n// Find \"moof\" box\nexport function hasMoofData(data: Uint8Array): boolean {\n const end = data.byteLength;\n for (let i = 0; i < end; ) {\n const size = readUint32(data, i);\n if (\n size > 8 &&\n data[i + 4] === 0x6d &&\n data[i + 5] === 0x6f &&\n data[i + 6] === 0x6f &&\n data[i + 7] === 0x66\n ) {\n return true;\n }\n i = size > 1 ? i + size : end;\n }\n return false;\n}\n\n// Find the data for a box specified by its path\nexport function findBox(data: Uint8Array, path: string[]): Uint8Array[] {\n const results = [] as Uint8Array[];\n if (!path.length) {\n // short-circuit the search for empty paths\n return results;\n }\n const end = data.byteLength;\n\n for (let i = 0; i < end; ) {\n const size = readUint32(data, i);\n const type = bin2str(data.subarray(i + 4, i + 8));\n const endbox = size > 1 ? i + size : end;\n if (type === path[0]) {\n if (path.length === 1) {\n // this is the end of the path and we've found the box we were\n // looking for\n results.push(data.subarray(i + 8, endbox));\n } else {\n // recursively search for the next box along the path\n const subresults = findBox(data.subarray(i + 8, endbox), path.slice(1));\n if (subresults.length) {\n push.apply(results, subresults);\n }\n }\n }\n i = endbox;\n }\n\n // we've finished searching all of data\n return results;\n}\n\ntype SidxInfo = {\n earliestPresentationTime: number;\n timescale: number;\n version: number;\n referencesCount: number;\n references: any[];\n};\n\nexport function parseSegmentIndex(sidx: Uint8Array): SidxInfo | null {\n const references: any[] = [];\n\n const version = sidx[0];\n\n // set initial offset, we skip the reference ID (not needed)\n let index = 8;\n\n const timescale = readUint32(sidx, index);\n index += 4;\n\n let earliestPresentationTime = 0;\n let firstOffset = 0;\n\n if (version === 0) {\n earliestPresentationTime = readUint32(sidx, index);\n firstOffset = readUint32(sidx, index + 4);\n index += 8;\n } else {\n earliestPresentationTime = readUint64(sidx, index);\n firstOffset = readUint64(sidx, index + 8);\n index += 16;\n }\n\n // skip reserved\n index += 2;\n\n let startByte = sidx.length + firstOffset;\n\n const referencesCount = readUint16(sidx, index);\n index += 2;\n\n for (let i = 0; i < referencesCount; i++) {\n let referenceIndex = index;\n\n const referenceInfo = readUint32(sidx, referenceIndex);\n referenceIndex += 4;\n\n const referenceSize = referenceInfo & 0x7fffffff;\n const referenceType = (referenceInfo & 0x80000000) >>> 31;\n\n if (referenceType === 1) {\n logger.warn('SIDX has hierarchical references (not supported)');\n return null;\n }\n\n const subsegmentDuration = readUint32(sidx, referenceIndex);\n referenceIndex += 4;\n\n references.push({\n referenceSize,\n subsegmentDuration, // unscaled\n info: {\n duration: subsegmentDuration / timescale,\n start: startByte,\n end: startByte + referenceSize - 1,\n },\n });\n\n startByte += referenceSize;\n\n // Skipping 1 bit for |startsWithSap|, 3 bits for |sapType|, and 28 bits\n // for |sapDelta|.\n referenceIndex += 4;\n\n // skip to next ref\n index = referenceIndex;\n }\n\n return {\n earliestPresentationTime,\n timescale,\n version,\n referencesCount,\n references,\n };\n}\n\n/**\n * Parses an MP4 initialization segment and extracts stream type and\n * timescale values for any declared tracks. Timescale values indicate the\n * number of clock ticks per second to assume for time-based values\n * elsewhere in the MP4.\n *\n * To determine the start time of an MP4, you need two pieces of\n * information: the timescale unit and the earliest base media decode\n * time. Multiple timescales can be specified within an MP4 but the\n * base media decode time is always expressed in the timescale from\n * the media header box for the track:\n * ```\n * moov > trak > mdia > mdhd.timescale\n * moov > trak > mdia > hdlr\n * ```\n * @param initSegment the bytes of the init segment\n * @returns a hash of track type to timescale values or null if\n * the init segment is malformed.\n */\n\nexport interface InitDataTrack {\n timescale: number;\n id: number;\n codec: string;\n}\n\ntype HdlrType = ElementaryStreamTypes.AUDIO | ElementaryStreamTypes.VIDEO;\n\nexport interface InitData extends Array<any> {\n [index: number]:\n | {\n timescale: number;\n type: HdlrType;\n default?: {\n duration: number;\n flags: number;\n };\n }\n | undefined;\n audio?: InitDataTrack;\n video?: InitDataTrack;\n caption?: InitDataTrack;\n}\n\nexport function parseInitSegment(initSegment: Uint8Array): InitData {\n const result: InitData = [];\n const traks = findBox(initSegment, ['moov', 'trak']);\n for (let i = 0; i < traks.length; i++) {\n const trak = traks[i];\n const tkhd = findBox(trak, ['tkhd'])[0];\n if (tkhd) {\n let version = tkhd[0];\n const trackId = readUint32(tkhd, version === 0 ? 12 : 20);\n const mdhd = findBox(trak, ['mdia', 'mdhd'])[0];\n if (mdhd) {\n version = mdhd[0];\n const timescale = readUint32(mdhd, version === 0 ? 12 : 20);\n const hdlr = findBox(trak, ['mdia', 'hdlr'])[0];\n if (hdlr) {\n const hdlrType = bin2str(hdlr.subarray(8, 12));\n const type: HdlrType | undefined = {\n soun: ElementaryStreamTypes.AUDIO as const,\n vide: ElementaryStreamTypes.VIDEO as const,\n }[hdlrType];\n if (type) {\n // Parse codec details\n const stsd = findBox(trak, ['mdia', 'minf', 'stbl', 'stsd'])[0];\n const stsdData = parseStsd(stsd);\n result[trackId] = { timescale, type };\n result[type] = { timescale, id: trackId, ...stsdData };\n }\n }\n }\n }\n }\n\n const trex = findBox(initSegment, ['moov', 'mvex', 'trex']);\n trex.forEach((trex) => {\n const trackId = readUint32(trex, 4);\n const track = result[trackId];\n if (track) {\n track.default = {\n duration: readUint32(trex, 12),\n flags: readUint32(trex, 20),\n };\n }\n });\n\n return result;\n}\n\nfunction parseStsd(stsd: Uint8Array): { codec: string; encrypted: boolean } {\n const sampleEntries = stsd.subarray(8);\n const sampleEntriesEnd = sampleEntries.subarray(8 + 78);\n const fourCC = bin2str(sampleEntries.subarray(4, 8));\n let codec = fourCC;\n const encrypted = fourCC === 'enca' || fourCC === 'encv';\n if (encrypted) {\n const encBox = findBox(sampleEntries, [fourCC])[0];\n const encBoxChildren = encBox.subarray(fourCC === 'enca' ? 28 : 78);\n const sinfs = findBox(encBoxChildren, ['sinf']);\n sinfs.forEach((sinf) => {\n const schm = findBox(sinf, ['schm'])[0];\n if (schm) {\n const scheme = bin2str(schm.subarray(4, 8));\n if (scheme === 'cbcs' || scheme === 'cenc') {\n const frma = findBox(sinf, ['frma'])[0];\n if (frma) {\n // for encrypted content codec fourCC will be in frma\n codec = bin2str(frma);\n }\n }\n }\n });\n }\n switch (codec) {\n case 'avc1':\n case 'avc2':\n case 'avc3':\n case 'avc4': {\n // extract profile + compatibility + level out of avcC box\n const avcCBox = findBox(sampleEntriesEnd, ['avcC'])[0];\n codec += '.' + toHex(avcCBox[1]) + toHex(avcCBox[2]) + toHex(avcCBox[3]);\n break;\n }\n case 'mp4a': {\n const codecBox = findBox(sampleEntries, [fourCC])[0];\n const esdsBox = findBox(codecBox.subarray(28), ['esds'])[0];\n if (esdsBox && esdsBox.length > 7) {\n let i = 4;\n // ES Descriptor tag\n if (esdsBox[i++] !== 0x03) {\n break;\n }\n i = skipBERInteger(esdsBox, i);\n i += 2; // skip es_id;\n const flags = esdsBox[i++];\n if (flags & 0x80) {\n i += 2; // skip dependency es_id\n }\n if (flags & 0x40) {\n i += esdsBox[i++]; // skip URL\n }\n // Decoder config descriptor\n if (esdsBox[i++] !== 0x04) {\n break;\n }\n i = skipBERInteger(esdsBox, i);\n const objectType = esdsBox[i++];\n if (objectType === 0x40) {\n codec += '.' + toHex(objectType);\n } else {\n break;\n }\n i += 12;\n // Decoder specific info\n if (esdsBox[i++] !== 0x05) {\n break;\n }\n i = skipBERInteger(esdsBox, i);\n const firstByte = esdsBox[i++];\n let audioObjectType = (firstByte & 0xf8) >> 3;\n if (audioObjectType === 31) {\n audioObjectType +=\n 1 + ((firstByte & 0x7) << 3) + ((esdsBox[i] & 0xe0) >> 5);\n }\n codec += '.' + audioObjectType;\n }\n break;\n }\n case 'hvc1':\n case 'hev1': {\n const hvcCBox = findBox(sampleEntriesEnd, ['hvcC'])[0];\n const profileByte = hvcCBox[1];\n const profileSpace = ['', 'A', 'B', 'C'][profileByte >> 6];\n const generalProfileIdc = profileByte & 0x1f;\n const profileCompat = readUint32(hvcCBox, 2);\n const tierFlag = (profileByte & 0x20) >> 5 ? 'H' : 'L';\n const levelIDC = hvcCBox[12];\n const constraintIndicator = hvcCBox.subarray(6, 12);\n codec += '.' + profileSpace + generalProfileIdc;\n codec += '.' + profileCompat.toString(16).toUpperCase();\n codec += '.' + tierFlag + levelIDC;\n let constraintString = '';\n for (let i = constraintIndicator.length; i--; ) {\n const byte = constraintIndicator[i];\n if (byte || constraintString) {\n const encodedByte = byte.toString(16).toUpperCase();\n constraintString = '.' + encodedByte + constraintString;\n }\n }\n codec += constraintString;\n break;\n }\n case 'dvh1':\n case 'dvhe': {\n const dvcCBox = findBox(sampleEntriesEnd, ['dvcC'])[0];\n const profile = (dvcCBox[2] >> 1) & 0x7f;\n const level = ((dvcCBox[2] << 5) & 0x20) | ((dvcCBox[3] >> 3) & 0x1f);\n codec += '.' + addLeadingZero(profile) + '.' + addLeadingZero(level);\n break;\n }\n case 'vp09': {\n const vpcCBox = findBox(sampleEntriesEnd, ['vpcC'])[0];\n const profile = vpcCBox[4];\n const level = vpcCBox[5];\n const bitDepth = (vpcCBox[6] >> 4) & 0x0f;\n codec +=\n '.' +\n addLeadingZero(profile) +\n '.' +\n addLeadingZero(level) +\n '.' +\n addLeadingZero(bitDepth);\n break;\n }\n case 'av01': {\n const av1CBox = findBox(sampleEntriesEnd, ['av1C'])[0];\n const profile = av1CBox[1] >>> 5;\n const level = av1CBox[1] & 0x1f;\n const tierFlag = av1CBox[2] >>> 7 ? 'H' : 'M';\n const highBitDepth = (av1CBox[2] & 0x40) >> 6;\n const twelveBit = (av1CBox[2] & 0x20) >> 5;\n const bitDepth =\n profile === 2 && highBitDepth\n ? twelveBit\n ? 12\n : 10\n : highBitDepth\n ? 10\n : 8;\n const monochrome = (av1CBox[2] & 0x10) >> 4;\n const chromaSubsamplingX = (av1CBox[2] & 0x08) >> 3;\n const chromaSubsamplingY = (av1CBox[2] & 0x04) >> 2;\n const chromaSamplePosition = av1CBox[2] & 0x03;\n // TODO: parse color_description_present_flag\n // default it to BT.709/limited range for now\n // more info https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox-syntax\n const colorPrimaries = 1;\n const transferCharacteristics = 1;\n const matrixCoefficients = 1;\n const videoFullRangeFlag = 0;\n codec +=\n '.' +\n profile +\n '.' +\n addLeadingZero(level) +\n tierFlag +\n '.' +\n addLeadingZero(bitDepth) +\n '.' +\n monochrome +\n '.' +\n chromaSubsamplingX +\n chromaSubsamplingY +\n chromaSamplePosition +\n '.' +\n addLeadingZero(colorPrimaries) +\n '.' +\n addLeadingZero(transferCharacteristics) +\n '.' +\n addLeadingZero(matrixCoefficients) +\n '.' +\n videoFullRangeFlag;\n break;\n }\n case 'ac-3':\n case 'ec-3':\n case 'alac':\n case 'fLaC':\n case 'Opus':\n default:\n break;\n }\n return { codec, encrypted };\n}\n\nfunction skipBERInteger(bytes: Uint8Array, i: number): number {\n const limit = i + 5;\n while (bytes[i++] & 0x80 && i < limit) {\n /* do nothing */\n }\n return i;\n}\n\nfunction toHex(x: number): string {\n return ('0' + x.toString(16).toUpperCase()).slice(-2);\n}\n\nfunction addLeadingZero(num: number): string {\n return (num < 10 ? '0' : '') + num;\n}\n\nexport function patchEncyptionData(\n initSegment: Uint8Array | undefined,\n decryptdata: DecryptData | null,\n): Uint8Array | undefined {\n if (!initSegment || !decryptdata) {\n return initSegment;\n }\n const keyId = decryptdata.keyId;\n if (keyId && decryptdata.isCommonEncryption) {\n const traks = findBox(initSegment, ['moov', 'trak']);\n traks.forEach((trak) => {\n const stsd = findBox(trak, ['mdia', 'minf', 'stbl', 'stsd'])[0];\n\n // skip the sample entry count\n const sampleEntries = stsd.subarray(8);\n let encBoxes = findBox(sampleEntries, ['enca']);\n const isAudio = encBoxes.length > 0;\n if (!isAudio) {\n encBoxes = findBox(sampleEntries, ['encv']);\n }\n encBoxes.forEach((enc) => {\n const encBoxChildren = isAudio ? enc.subarray(28) : enc.subarray(78);\n const sinfBoxes = findBox(encBoxChildren, ['sinf']);\n sinfBoxes.forEach((sinf) => {\n const tenc = parseSinf(sinf);\n if (tenc) {\n // Look for default key id (keyID offset is always 8 within the tenc box):\n const tencKeyId = tenc.subarray(8, 24);\n if (!tencKeyId.some((b) => b !== 0)) {\n logger.log(\n `[eme] Patching keyId in 'enc${\n isAudio ? 'a' : 'v'\n }>sinf>>tenc' box: ${Hex.hexDump(tencKeyId)} -> ${Hex.hexDump(\n keyId,\n )}`,\n );\n tenc.set(keyId, 8);\n }\n }\n });\n });\n });\n }\n\n return initSegment;\n}\n\nexport function parseSinf(sinf: Uint8Array): Uint8Array | null {\n const schm = findBox(sinf, ['schm'])[0];\n if (schm) {\n const scheme = bin2str(schm.subarray(4, 8));\n if (scheme === 'cbcs' || scheme === 'cenc') {\n return findBox(sinf, ['schi', 'tenc'])[0];\n }\n }\n return null;\n}\n\n/**\n * Determine the base media decode start time, in seconds, for an MP4\n * fragment. If multiple fragments are specified, the earliest time is\n * returned.\n *\n * The base media decode time can be parsed from track fragment\n * metadata:\n * ```\n * moof > traf > tfdt.baseMediaDecodeTime\n * ```\n * It requires the timescale value from the mdhd to interpret.\n *\n * @param initData - a hash of track type to timescale values\n * @param fmp4 - the bytes of the mp4 fragment\n * @returns the earliest base media decode start time for the\n * fragment, in seconds\n */\nexport function getStartDTS(\n initData: InitData,\n fmp4: Uint8Array,\n): number | null {\n // we need info from two children of each track fragment box\n return findBox(fmp4, ['moof', 'traf']).reduce(\n (result: number | null, traf) => {\n const tfdt = findBox(traf, ['tfdt'])[0];\n const version = tfdt[0];\n const start = findBox(traf, ['tfhd']).reduce(\n (result: number | null, tfhd) => {\n // get the track id from the tfhd\n const id = readUint32(tfhd, 4);\n const track = initData[id];\n if (track) {\n let baseTime = readUint32(tfdt, 4);\n if (version === 1) {\n // If value is too large, assume signed 64-bit. Negative track fragment decode times are invalid, but they exist in the wild.\n // This prevents large values from being used for initPTS, which can cause playlist sync issues.\n // https://github.com/video-dev/hls.js/issues/5303\n if (baseTime === UINT32_MAX) {\n logger.warn(\n `[mp4-demuxer]: Ignoring assumed invalid signed 64-bit track fragment decode time`,\n );\n return result;\n }\n baseTime *= UINT32_MAX + 1;\n baseTime += readUint32(tfdt, 8);\n }\n // assume a 90kHz clock if no timescale was specified\n const scale = track.timescale || 90e3;\n // convert base time to seconds\n const startTime = baseTime / scale;\n if (\n Number.isFinite(startTime) &&\n (result === null || startTime < result)\n ) {\n return startTime;\n }\n }\n return result;\n },\n null,\n );\n if (\n start !== null &&\n Number.isFinite(start) &&\n (result === null || start < result)\n ) {\n return start;\n }\n return result;\n },\n null,\n );\n}\n\n/*\n For Reference:\n aligned(8) class TrackFragmentHeaderBox\n extends FullBox(‘tfhd’, 0, tf_flags){\n unsigned int(32) track_ID;\n // all the following are optional fields\n unsigned int(64) base_data_offset;\n unsigned int(32) sample_description_index;\n unsigned int(32) default_sample_duration;\n unsigned int(32) default_sample_size;\n unsigned int(32) default_sample_flags\n }\n */\nexport function getDuration(data: Uint8Array, initData: InitData) {\n let rawDuration = 0;\n let videoDuration = 0;\n let audioDuration = 0;\n const trafs = findBox(data, ['moof', 'traf']);\n for (let i = 0; i < trafs.length; i++) {\n const traf = trafs[i];\n // There is only one tfhd & trun per traf\n // This is true for CMAF style content, and we should perhaps check the ftyp\n // and only look for a single trun then, but for ISOBMFF we should check\n // for multiple track runs.\n const tfhd = findBox(traf, ['tfhd'])[0];\n // get the track id from the tfhd\n const id = readUint32(tfhd, 4);\n const track = initData[id];\n if (!track) {\n continue;\n }\n const trackDefault = track.default;\n const tfhdFlags = readUint32(tfhd, 0) | trackDefault?.flags!;\n let sampleDuration: number | undefined = trackDefault?.duration;\n if (tfhdFlags & 0x000008) {\n // 0x000008 indicates the presence of the default_sample_duration field\n if (tfhdFlags & 0x000002) {\n // 0x000002 indicates the presence of the sample_description_index field, which precedes default_sample_duration\n // If present, the default_sample_duration exists at byte offset 12\n sampleDuration = readUint32(tfhd, 12);\n } else {\n // Otherwise, the duration is at byte offset 8\n sampleDuration = readUint32(tfhd, 8);\n }\n }\n // assume a 90kHz clock if no timescale was specified\n const timescale = track.timescale || 90e3;\n const truns = findBox(traf, ['trun']);\n for (let j = 0; j < truns.length; j++) {\n rawDuration = computeRawDurationFromSamples(truns[j]);\n if (!rawDuration && sampleDuration) {\n const sampleCount = readUint32(truns[j], 4);\n rawDuration = sampleDuration * sampleCount;\n }\n if (track.type === ElementaryStreamTypes.VIDEO) {\n videoDuration += rawDuration / timescale;\n } else if (track.type === ElementaryStreamTypes.AUDIO) {\n audioDuration += rawDuration / timescale;\n }\n }\n }\n if (videoDuration === 0 && audioDuration === 0) {\n // If duration samples are not available in the traf use sidx subsegment_duration\n let sidxMinStart = Infinity;\n let sidxMaxEnd = 0;\n let sidxDuration = 0;\n const sidxs = findBox(data, ['sidx']);\n for (let i = 0; i < sidxs.length; i++) {\n const sidx = parseSegmentIndex(sidxs[i]);\n if (sidx?.references) {\n sidxMinStart = Math.min(\n sidxMinStart,\n sidx.earliestPresentationTime / sidx.timescale,\n );\n const subSegmentDuration = sidx.references.reduce(\n (dur, ref) => dur + ref.info.duration || 0,\n 0,\n );\n sidxMaxEnd = Math.max(\n sidxMaxEnd,\n subSegmentDuration + sidx.earliestPresentationTime / sidx.timescale,\n );\n sidxDuration = sidxMaxEnd - sidxMinStart;\n }\n }\n if (sidxDuration && Number.isFinite(sidxDuration)) {\n return sidxDuration;\n }\n }\n if (videoDuration) {\n return videoDuration;\n }\n return audioDuration;\n}\n\n/*\n For Reference:\n aligned(8) class TrackRunBox\n extends FullBox(‘trun’, version, tr_flags) {\n unsigned int(32) sample_count;\n // the following are optional fields\n signed int(32) data_offset;\n unsigned int(32) first_sample_flags;\n // all fields in the following array are optional\n {\n unsigned int(32) sample_duration;\n unsigned int(32) sample_size;\n unsigned int(32) sample_flags\n if (version == 0)\n { unsigned int(32)\n else\n { signed int(32)\n }[ sample_count ]\n }\n */\nexport function computeRawDurationFromSamples(trun): number {\n const flags = readUint32(trun, 0);\n // Flags are at offset 0, non-optional sample_count is at offset 4. Therefore we start 8 bytes in.\n // Each field is an int32, which is 4 bytes\n let offset = 8;\n // data-offset-present flag\n if (flags & 0x000001) {\n offset += 4;\n }\n // first-sample-flags-present flag\n if (flags & 0x000004) {\n offset += 4;\n }\n\n let duration = 0;\n const sampleCount = readUint32(trun, 4);\n for (let i = 0; i < sampleCount; i++) {\n // sample-duration-present flag\n if (flags & 0x000100) {\n const sampleDuration = readUint32(trun, offset);\n duration += sampleDuration;\n offset += 4;\n }\n // sample-size-present flag\n if (flags & 0x000200) {\n offset += 4;\n }\n // sample-flags-present flag\n if (flags & 0x000400) {\n offset += 4;\n }\n // sample-composition-time-offsets-present flag\n if (flags & 0x000800) {\n offset += 4;\n }\n }\n return duration;\n}\n\nexport function offsetStartDTS(\n initData: InitData,\n fmp4: Uint8Array,\n timeOffset: number,\n) {\n findBox(fmp4, ['moof', 'traf']).forEach((traf) => {\n findBox(traf, ['tfhd']).forEach((tfhd) => {\n // get the track id from the tfhd\n const id = readUint32(tfhd, 4);\n const track = initData[id];\n if (!track) {\n return;\n }\n // assume a 90kHz clock if no timescale was specified\n const timescale = track.timescale || 90e3;\n // get the base media decode time from the tfdt\n findBox(traf, ['tfdt']).forEach((tfdt) => {\n const version = tfdt[0];\n const offset = timeOffset * timescale;\n if (offset) {\n let baseMediaDecodeTime = readUint32(tfdt, 4);\n if (version === 0) {\n baseMediaDecodeTime -= offset;\n baseMediaDecodeTime = Math.max(baseMediaDecodeTime, 0);\n writeUint32(tfdt, 4, baseMediaDecodeTime);\n } else {\n baseMediaDecodeTime *= Math.pow(2, 32);\n baseMediaDecodeTime += readUint32(tfdt, 8);\n baseMediaDecodeTime -= offset;\n baseMediaDecodeTime = Math.max(baseMediaDecodeTime, 0);\n const upper = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1));\n const lower = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1));\n writeUint32(tfdt, 4, upper);\n writeUint32(tfdt, 8, lower);\n }\n }\n });\n });\n });\n}\n\n// TODO: Check if the last moof+mdat pair is part of the valid range\nexport function segmentValidRange(data: Uint8Array): SegmentedRange {\n const segmentedRange: SegmentedRange = {\n valid: null,\n remainder: null,\n };\n\n const moofs = findBox(data, ['moof']);\n if (moofs.length < 2) {\n segmentedRange.remainder = data;\n return segmentedRange;\n }\n const last = moofs[moofs.length - 1];\n // Offset by 8 bytes; findBox offsets the start by as much\n segmentedRange.valid = sliceUint8(data, 0, last.byteOffset - 8);\n segmentedRange.remainder = sliceUint8(data, last.byteOffset - 8);\n return segmentedRange;\n}\n\nexport interface SegmentedRange {\n valid: Uint8Array | null;\n remainder: Uint8Array | null;\n}\n\nexport function appendUint8Array(\n data1: Uint8Array,\n data2: Uint8Array,\n): Uint8Array {\n const temp = new Uint8Array(data1.length + data2.length);\n temp.set(data1);\n temp.set(data2, data1.length);\n\n return temp;\n}\n\nexport interface IEmsgParsingData {\n schemeIdUri: string;\n value: string;\n timeScale: number;\n presentationTimeDelta?: number;\n presentationTime?: number;\n eventDuration: number;\n id: number;\n payload: Uint8Array;\n}\n\nexport function parseSamples(\n timeOffset: number,\n track: PassthroughTrack,\n): UserdataSample[] {\n const seiSamples = [] as UserdataSample[];\n const videoData = track.samples;\n const timescale = track.timescale;\n const trackId = track.id;\n let isHEVCFlavor = false;\n\n const moofs = findBox(videoData, ['moof']);\n moofs.map((moof) => {\n const moofOffset = moof.byteOffset - 8;\n const trafs = findBox(moof, ['traf']);\n trafs.map((traf) => {\n // get the base media decode time from the tfdt\n const baseTime = findBox(traf, ['tfdt']).map((tfdt) => {\n const version = tfdt[0];\n let result = readUint32(tfdt, 4);\n if (version === 1) {\n result *= Math.pow(2, 32);\n result += readUint32(tfdt, 8);\n }\n return result / timescale;\n })[0];\n\n if (baseTime !== undefined) {\n timeOffset = baseTime;\n }\n\n return findBox(traf, ['tfhd']).map((tfhd) => {\n const id = readUint32(tfhd, 4);\n const tfhdFlags = readUint32(tfhd, 0) & 0xffffff;\n const baseDataOffsetPresent = (tfhdFlags & 0x000001) !== 0;\n const sampleDescriptionIndexPresent = (tfhdFlags & 0x000002) !== 0;\n const defaultSampleDurationPresent = (tfhdFlags & 0x000008) !== 0;\n let defaultSampleDuration = 0;\n const defaultSampleSizePresent = (tfhdFlags & 0x000010) !== 0;\n let defaultSampleSize = 0;\n const defaultSampleFlagsPresent = (tfhdFlags & 0x000020) !== 0;\n let tfhdOffset = 8;\n\n if (id === trackId) {\n if (baseDataOffsetPresent) {\n tfhdOffset += 8;\n }\n if (sampleDescriptionIndexPresent) {\n tfhdOffset += 4;\n }\n if (defaultSampleDurationPresent) {\n defaultSampleDuration = readUint32(tfhd, tfhdOffset);\n tfhdOffset += 4;\n }\n if (defaultSampleSizePresent) {\n defaultSampleSize = readUint32(tfhd, tfhdOffset);\n tfhdOffset += 4;\n }\n if (defaultSampleFlagsPresent) {\n tfhdOffset += 4;\n }\n if (track.type === 'video') {\n isHEVCFlavor = isHEVC(track.codec);\n }\n\n findBox(traf, ['trun']).map((trun) => {\n const version = trun[0];\n const flags = readUint32(trun, 0) & 0xffffff;\n const dataOffsetPresent = (flags & 0x000001) !== 0;\n let dataOffset = 0;\n const firstSampleFlagsPresent = (flags & 0x000004) !== 0;\n const sampleDurationPresent = (flags & 0x000100) !== 0;\n let sampleDuration = 0;\n const sampleSizePresent = (flags & 0x000200) !== 0;\n let sampleSize = 0;\n const sampleFlagsPresent = (flags & 0x000400) !== 0;\n const sampleCompositionOffsetsPresent = (flags & 0x000800) !== 0;\n let compositionOffset = 0;\n const sampleCount = readUint32(trun, 4);\n let trunOffset = 8; // past version, flags, and sample count\n\n if (dataOffsetPresent) {\n dataOffset = readUint32(trun, trunOffset);\n trunOffset += 4;\n }\n if (firstSampleFlagsPresent) {\n trunOffset += 4;\n }\n\n let sampleOffset = dataOffset + moofOffset;\n\n for (let ix = 0; ix < sampleCount; ix++) {\n if (sampleDurationPresent) {\n sampleDuration = readUint32(trun, trunOffset);\n trunOffset += 4;\n } else {\n sampleDuration = defaultSampleDuration;\n }\n if (sampleSizePresent) {\n sampleSize = readUint32(trun, trunOffset);\n trunOffset += 4;\n } else {\n sampleSize = defaultSampleSize;\n }\n if (sampleFlagsPresent) {\n trunOffset += 4;\n }\n if (sampleCompositionOffsetsPresent) {\n if (version === 0) {\n compositionOffset = readUint32(trun, trunOffset);\n } else {\n compositionOffset = readSint32(trun, trunOffset);\n }\n trunOffset += 4;\n }\n if (track.type === ElementaryStreamTypes.VIDEO) {\n let naluTotalSize = 0;\n while (naluTotalSize < sampleSize) {\n const naluSize = readUint32(videoData, sampleOffset);\n sampleOffset += 4;\n if (isSEIMessage(isHEVCFlavor, videoData[sampleOffset])) {\n const data = videoData.subarray(\n sampleOffset,\n sampleOffset + naluSize,\n );\n parseSEIMessageFromNALu(\n data,\n isHEVCFlavor ? 2 : 1,\n timeOffset + compositionOffset / timescale,\n seiSamples,\n );\n }\n sampleOffset += naluSize;\n naluTotalSize += naluSize + 4;\n }\n }\n\n timeOffset += sampleDuration / timescale;\n }\n });\n }\n });\n });\n });\n return seiSamples;\n}\n\nfunction isHEVC(codec: string) {\n if (!codec) {\n return false;\n }\n const delimit = codec.indexOf('.');\n const baseCodec = delimit < 0 ? codec : codec.substring(0, delimit);\n return (\n baseCodec === 'hvc1' ||\n baseCodec === 'hev1' ||\n // Dolby Vision\n baseCodec === 'dvh1' ||\n baseCodec === 'dvhe'\n );\n}\n\nfunction isSEIMessage(isHEVCFlavor: boolean, naluHeader: number) {\n if (isHEVCFlavor) {\n const naluType = (naluHeader >> 1) & 0x3f;\n return naluType === 39 || naluType === 40;\n } else {\n const naluType = naluHeader & 0x1f;\n return naluType === 6;\n }\n}\n\nexport function parseSEIMessageFromNALu(\n unescapedData: Uint8Array,\n headerSize: number,\n pts: number,\n samples: UserdataSample[],\n) {\n const data = discardEPB(unescapedData);\n let seiPtr = 0;\n // skip nal header\n seiPtr += headerSize;\n let payloadType = 0;\n let payloadSize = 0;\n let b = 0;\n\n while (seiPtr < data.length) {\n payloadType = 0;\n do {\n if (seiPtr >= data.length) {\n break;\n }\n b = data[seiPtr++];\n payloadType += b;\n } while (b === 0xff);\n\n // Parse payload size.\n payloadSize = 0;\n do {\n if (seiPtr >= data.length) {\n break;\n }\n b = data[seiPtr++];\n payloadSize += b;\n } while (b === 0xff);\n\n const leftOver = data.length - seiPtr;\n // Create a variable to process the payload\n let payPtr = seiPtr;\n\n // Increment the seiPtr to the end of the payload\n if (payloadSize < leftOver) {\n seiPtr += payloadSize;\n } else if (payloadSize > leftOver) {\n // Some type of corruption has happened?\n logger.error(\n `Malformed SEI payload. ${payloadSize} is too small, only ${leftOver} bytes left to parse.`,\n );\n // We might be able to parse some data, but let's be safe and ignore it.\n break;\n }\n\n if (payloadType === 4) {\n const countryCode = data[payPtr++];\n if (countryCode === 181) {\n const providerCode = readUint16(data, payPtr);\n payPtr += 2;\n\n if (providerCode === 49) {\n const userStructure = readUint32(data, payPtr);\n payPtr += 4;\n\n if (userStructure === 0x47413934) {\n const userDataType = data[payPtr++];\n\n // Raw CEA-608 bytes wrapped in CEA-708 packet\n if (userDataType === 3) {\n const firstByte = data[payPtr++];\n const totalCCs = 0x1f & firstByte;\n const enabled = 0x40 & firstByte;\n const totalBytes = enabled ? 2 + totalCCs * 3 : 0;\n const byteArray = new Uint8Array(totalBytes);\n if (enabled) {\n byteArray[0] = firstByte;\n for (let i = 1; i < totalBytes; i++) {\n byteArray[i] = data[payPtr++];\n }\n }\n\n samples.push({\n type: userDataType,\n payloadType,\n pts,\n bytes: byteArray,\n });\n }\n }\n }\n }\n } else if (payloadType === 5) {\n if (payloadSize > 16) {\n const uuidStrArray: Array<string> = [];\n for (let i = 0; i < 16; i++) {\n const b = data[payPtr++].toString(16);\n uuidStrArray.push(b.length == 1 ? '0' + b : b);\n\n if (i === 3 || i === 5 || i === 7 || i === 9) {\n uuidStrArray.push('-');\n }\n }\n const length = payloadSize - 16;\n const userDataBytes = new Uint8Array(length);\n for (let i = 0; i < length; i++) {\n userDataBytes[i] = data[payPtr++];\n }\n\n samples.push({\n payloadType,\n pts,\n uuid: uuidStrArray.join(''),\n userData: utf8ArrayToStr(userDataBytes),\n userDataBytes,\n });\n }\n }\n }\n}\n\n/**\n * remove Emulation Prevention bytes from a RBSP\n */\nexport function discardEPB(data: Uint8Array): Uint8Array {\n const length = data.byteLength;\n const EPBPositions = [] as Array<number>;\n let i = 1;\n\n // Find all `Emulation Prevention Bytes`\n while (i < length - 2) {\n if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 0x03) {\n EPBPositions.push(i + 2);\n i += 2;\n } else {\n i++;\n }\n }\n\n // If no Emulation Prevention Bytes were found just return the original\n // array\n if (EPBPositions.length === 0) {\n return data;\n }\n\n // Create a new array to hold the NAL unit data\n const newLength = length - EPBPositions.length;\n const newData = new Uint8Array(newLength);\n let sourceIndex = 0;\n\n for (i = 0; i < newLength; sourceIndex++, i++) {\n if (sourceIndex === EPBPositions[0]) {\n // Skip this byte\n sourceIndex++;\n // Remove this position index\n EPBPositions.shift();\n }\n newData[i] = data[sourceIndex];\n }\n return newData;\n}\n\nexport function parseEmsg(data: Uint8Array): IEmsgParsingData {\n const version = data[0];\n let schemeIdUri: string = '';\n let value: string = '';\n let timeScale: number = 0;\n let presentationTimeDelta: number = 0;\n let presentationTime: number = 0;\n let eventDuration: number = 0;\n let id: number = 0;\n let offset: number = 0;\n\n if (version === 0) {\n while (bin2str(data.subarray(offset, offset + 1)) !== '\\0') {\n schemeIdUri += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n }\n\n schemeIdUri += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n\n while (bin2str(data.subarray(offset, offset + 1)) !== '\\0') {\n value += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n }\n\n value += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n\n timeScale = readUint32(data, 12);\n presentationTimeDelta = readUint32(data, 16);\n eventDuration = readUint32(data, 20);\n id = readUint32(data, 24);\n offset = 28;\n } else if (version === 1) {\n offset += 4;\n timeScale = readUint32(data, offset);\n offset += 4;\n const leftPresentationTime = readUint32(data, offset);\n offset += 4;\n const rightPresentationTime = readUint32(data, offset);\n offset += 4;\n presentationTime = 2 ** 32 * leftPresentationTime + rightPresentationTime;\n if (!Number.isSafeInteger(presentationTime)) {\n presentationTime = Number.MAX_SAFE_INTEGER;\n logger.warn(\n 'Presentation time exceeds safe integer limit and wrapped to max safe integer in parsing emsg box',\n );\n }\n\n eventDuration = readUint32(data, offset);\n offset += 4;\n id = readUint32(data, offset);\n offset += 4;\n\n while (bin2str(data.subarray(offset, offset + 1)) !== '\\0') {\n schemeIdUri += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n }\n\n schemeIdUri += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n\n while (bin2str(data.subarray(offset, offset + 1)) !== '\\0') {\n value += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n }\n\n value += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n }\n const payload = data.subarray(offset, data.byteLength);\n\n return {\n schemeIdUri,\n value,\n timeScale,\n presentationTime,\n presentationTimeDelta,\n eventDuration,\n id,\n payload,\n };\n}\n\nexport function mp4Box(type: ArrayLike<number>, ...payload: Uint8Array[]) {\n const len = payload.length;\n let size = 8;\n let i = len;\n while (i--) {\n size += payload[i].byteLength;\n }\n const result = new Uint8Array(size);\n result[0] = (size >> 24) & 0xff;\n result[1] = (size >> 16) & 0xff;\n result[2] = (size >> 8) & 0xff;\n result[3] = size & 0xff;\n result.set(type, 4);\n for (i = 0, size = 8; i < len; i++) {\n result.set(payload[i], size);\n size += payload[i].byteLength;\n }\n return result;\n}\n\nexport function mp4pssh(\n systemId: Uint8Array,\n keyids: Array<Uint8Array> | null,\n data: Uint8Array,\n) {\n if (systemId.byteLength !== 16) {\n throw new RangeError('Invalid system id');\n }\n let version;\n let kids;\n if (keyids) {\n version = 1;\n kids = new Uint8Array(keyids.length * 16);\n for (let ix = 0; ix < keyids.length; ix++) {\n const k = keyids[ix]; // uint8array\n if (k.byteLength !== 16) {\n throw new RangeError('Invalid key');\n }\n kids.set(k, ix * 16);\n }\n } else {\n version = 0;\n kids = new Uint8Array();\n }\n let kidCount;\n if (version > 0) {\n kidCount = new Uint8Array(4);\n if (keyids!.length > 0) {\n new DataView(kidCount.buffer).setUint32(0, keyids!.length, false);\n }\n } else {\n kidCount = new Uint8Array();\n }\n const dataSize = new Uint8Array(4);\n if (data && data.byteLength > 0) {\n new DataView(dataSize.buffer).setUint32(0, data.byteLength, false);\n }\n return mp4Box(\n [112, 115, 115, 104],\n new Uint8Array([\n version,\n 0x00,\n 0x00,\n 0x00, // Flags\n ]),\n systemId, // 16 bytes\n kidCount,\n kids,\n dataSize,\n data || new Uint8Array(),\n );\n}\n\nexport type PsshData = {\n version: 0 | 1;\n systemId: KeySystemIds;\n kids: null | Uint8Array[];\n data: null | Uint8Array;\n offset: number;\n size: number;\n};\n\nexport type PsshInvalidResult = {\n systemId?: undefined;\n offset: number;\n size: number;\n};\n\nexport function parseMultiPssh(\n initData: ArrayBuffer,\n): (PsshData | PsshInvalidResult)[] {\n const results: (PsshData | PsshInvalidResult)[] = [];\n if (initData instanceof ArrayBuffer) {\n const length = initData.byteLength;\n let offset = 0;\n while (offset + 32 < length) {\n const view = new DataView(initData, offset);\n const pssh = parsePssh(view);\n results.push(pssh);\n offset += pssh.size;\n }\n }\n return results;\n}\n\nfunction parsePssh(view: DataView): PsshData | PsshInvalidResult {\n const size = view.getUint32(0);\n const offset = view.byteOffset;\n const length = view.byteLength;\n if (length < size) {\n return {\n offset,\n size: length,\n };\n }\n const type = view.getUint32(4);\n if (type !== 0x70737368) {\n return { offset, size };\n }\n const version = view.getUint32(8) >>> 24;\n if (version !== 0 && version !== 1) {\n return { offset, size };\n }\n const buffer = view.buffer;\n const systemId = Hex.hexDump(\n new Uint8Array(buffer, offset + 12, 16),\n ) as KeySystemIds;\n const dataSizeOrKidCount = view.getUint32(28);\n let kids: null | Uint8Array[] = null;\n let data: null | Uint8Array = null;\n if (version === 0) {\n if (size - 32 < dataSizeOrKidCount || dataSizeOrKidCount < 22) {\n return { offset, size };\n }\n data = new Uint8Array(buffer, offset + 32, dataSizeOrKidCount);\n } else if (version === 1) {\n if (\n !dataSizeOrKidCount ||\n length < offset + 32 + dataSizeOrKidCount * 16 + 16\n ) {\n return { offset, size };\n }\n kids = [];\n for (let i = 0; i < dataSizeOrKidCount; i++) {\n kids.push(new Uint8Array(buffer, offset + 32 + i * 16, 16));\n }\n }\n return {\n version,\n systemId,\n kids,\n data,\n offset,\n size,\n };\n}\n","import type { DemuxedTrack } from '../types/demuxer';\n\nexport function dummyTrack(type = '', inputTimeScale = 90000): DemuxedTrack {\n return {\n type,\n id: -1,\n pid: -1,\n inputTimeScale,\n sequenceNumber: -1,\n samples: [],\n dropped: 0,\n };\n}\n","import { canParseId3 } from '@svta/common-media-library/id3/canParseId3';\nimport { getId3Data } from '@svta/common-media-library/id3/getId3Data';\nimport { getId3Timestamp } from '@svta/common-media-library/id3/getId3Timestamp';\nimport {\n type AudioFrame,\n type DemuxedAudioTrack,\n type DemuxedMetadataTrack,\n type DemuxedUserdataTrack,\n type DemuxedVideoTrackBase,\n type Demuxer,\n type DemuxerResult,\n type KeyData,\n MetadataSchema,\n} from '../../types/demuxer';\nimport { appendUint8Array } from '../../utils/mp4-tools';\nimport { sliceUint8 } from '../../utils/typed-array';\nimport { dummyTrack } from '../dummy-demuxed-track';\nimport type { RationalTimestamp } from '../../utils/timescale-conversion';\n\nclass BaseAudioDemuxer implements Demuxer {\n protected _audioTrack?: DemuxedAudioTrack;\n protected _id3Track?: DemuxedMetadataTrack;\n protected frameIndex: number = 0;\n protected cachedData: Uint8Array | null = null;\n protected basePTS: number | null = null;\n protected initPTS: RationalTimestamp | null = null;\n protected lastPTS: number | null = null;\n\n resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n ) {\n this._id3Track = {\n type: 'id3',\n id: 3,\n pid: -1,\n inputTimeScale: 90000,\n sequenceNumber: 0,\n samples: [],\n dropped: 0,\n };\n }\n\n resetTimeStamp(deaultTimestamp: RationalTimestamp | null) {\n this.initPTS = deaultTimestamp;\n this.resetContiguity();\n }\n\n resetContiguity(): void {\n this.basePTS = null;\n this.lastPTS = null;\n this.frameIndex = 0;\n }\n\n canParse(data: Uint8Array, offset: number): boolean {\n return false;\n }\n\n appendFrame(\n track: DemuxedAudioTrack,\n data: Uint8Array,\n offset: number,\n ): AudioFrame | void {}\n\n // feed incoming data to the front of the parsing pipeline\n demux(data: Uint8Array, timeOffset: number): DemuxerResult {\n if (this.cachedData) {\n data = appendUint8Array(this.cachedData, data);\n this.cachedData = null;\n }\n\n let id3Data: Uint8Array | undefined = getId3Data(data, 0);\n let offset = id3Data ? id3Data.length : 0;\n let lastDataIndex;\n const track = this._audioTrack as DemuxedAudioTrack;\n const id3Track = this._id3Track as DemuxedMetadataTrack;\n const timestamp = id3Data ? getId3Timestamp(id3Data) : undefined;\n const length = data.length;\n\n if (\n this.basePTS === null ||\n (this.frameIndex === 0 && Number.isFinite(timestamp))\n ) {\n this.basePTS = initPTSFn(timestamp, timeOffset, this.initPTS);\n this.lastPTS = this.basePTS;\n }\n\n if (this.lastPTS === null) {\n this.lastPTS = this.basePTS;\n }\n\n // more expressive than alternative: id3Data?.length\n if (id3Data && id3Data.length > 0) {\n id3Track.samples.push({\n pts: this.lastPTS,\n dts: this.lastPTS,\n data: id3Data,\n type: MetadataSchema.audioId3,\n duration: Number.POSITIVE_INFINITY,\n });\n }\n\n while (offset < length) {\n if (this.canParse(data, offset)) {\n const frame = this.appendFrame(track, data, offset);\n if (frame) {\n this.frameIndex++;\n this.lastPTS = frame.sample.pts;\n offset += frame.length;\n lastDataIndex = offset;\n } else {\n offset = length;\n }\n } else if (canParseId3(data, offset)) {\n // after a canParse, a call to getId3Data *should* always returns some data\n id3Data = getId3Data(data, offset)!;\n id3Track.samples.push({\n pts: this.lastPTS,\n dts: this.lastPTS,\n data: id3Data,\n type: MetadataSchema.audioId3,\n duration: Number.POSITIVE_INFINITY,\n });\n offset += id3Data.length;\n lastDataIndex = offset;\n } else {\n offset++;\n }\n if (offset === length && lastDataIndex !== length) {\n const partialData = sliceUint8(data, lastDataIndex);\n if (this.cachedData) {\n this.cachedData = appendUint8Array(this.cachedData, partialData);\n } else {\n this.cachedData = partialData;\n }\n }\n }\n\n return {\n audioTrack: track,\n videoTrack: dummyTrack() as DemuxedVideoTrackBase,\n id3Track,\n textTrack: dummyTrack() as DemuxedUserdataTrack,\n };\n }\n\n demuxSampleAes(\n data: Uint8Array,\n keyData: KeyData,\n timeOffset: number,\n ): Promise<DemuxerResult> {\n return Promise.reject(\n new Error(\n `[${this}] This demuxer does not support Sample-AES decryption`,\n ),\n );\n }\n\n flush(timeOffset: number): DemuxerResult {\n // Parse cache in case of remaining frames.\n const cachedData = this.cachedData;\n if (cachedData) {\n this.cachedData = null;\n this.demux(cachedData, 0);\n }\n\n return {\n audioTrack: this._audioTrack as DemuxedAudioTrack,\n videoTrack: dummyTrack() as DemuxedVideoTrackBase,\n id3Track: this._id3Track as DemuxedMetadataTrack,\n textTrack: dummyTrack() as DemuxedUserdataTrack,\n };\n }\n\n destroy() {\n this.cachedData = null;\n // @ts-ignore\n this._audioTrack = this._id3Track = undefined;\n }\n}\n\n/**\n * Initialize PTS\n * <p>\n * use timestamp unless it is undefined, NaN or Infinity\n * </p>\n */\nexport const initPTSFn = (\n timestamp: number | undefined,\n timeOffset: number,\n initPTS: RationalTimestamp | null,\n): number => {\n if (Number.isFinite(timestamp as number)) {\n return timestamp! * 90;\n }\n const init90kHz = initPTS\n ? (initPTS.baseTime * 90000) / initPTS.timescale\n : 0;\n return timeOffset * 90000 + init90kHz;\n};\nexport default BaseAudioDemuxer;\n","/**\n * MPEG parser helper\n */\nimport type { DemuxedAudioTrack } from '../../types/demuxer';\n\nlet chromeVersion: number | null = null;\n\nconst BitratesMap = [\n 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56,\n 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80,\n 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112, 128, 144,\n 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144,\n 160,\n];\n\nconst SamplingRateMap = [\n 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000,\n];\n\nconst SamplesCoefficients = [\n // MPEG 2.5\n [\n 0, // Reserved\n 72, // Layer3\n 144, // Layer2\n 12, // Layer1\n ],\n // Reserved\n [\n 0, // Reserved\n 0, // Layer3\n 0, // Layer2\n 0, // Layer1\n ],\n // MPEG 2\n [\n 0, // Reserved\n 72, // Layer3\n 144, // Layer2\n 12, // Layer1\n ],\n // MPEG 1\n [\n 0, // Reserved\n 144, // Layer3\n 144, // Layer2\n 12, // Layer1\n ],\n];\n\nconst BytesInSlot = [\n 0, // Reserved\n 1, // Layer3\n 1, // Layer2\n 4, // Layer1\n];\n\nexport function appendFrame(\n track: DemuxedAudioTrack,\n data: Uint8Array,\n offset: number,\n pts: number,\n frameIndex: number,\n) {\n // Using http://www.datavoyage.com/mpgscript/mpeghdr.htm as a reference\n if (offset + 24 > data.length) {\n return;\n }\n\n const header = parseHeader(data, offset);\n if (header && offset + header.frameLength <= data.length) {\n const frameDuration = (header.samplesPerFrame * 90000) / header.sampleRate;\n const stamp = pts + frameIndex * frameDuration;\n const sample = {\n unit: data.subarray(offset, offset + header.frameLength),\n pts: stamp,\n dts: stamp,\n };\n\n track.config = [];\n track.channelCount = header.channelCount;\n track.samplerate = header.sampleRate;\n track.samples.push(sample);\n\n return { sample, length: header.frameLength, missing: 0 };\n }\n}\n\nexport function parseHeader(data: Uint8Array, offset: number) {\n const mpegVersion = (data[offset + 1] >> 3) & 3;\n const mpegLayer = (data[offset + 1] >> 1) & 3;\n const bitRateIndex = (data[offset + 2] >> 4) & 15;\n const sampleRateIndex = (data[offset + 2] >> 2) & 3;\n if (\n mpegVersion !== 1 &&\n bitRateIndex !== 0 &&\n bitRateIndex !== 15 &&\n sampleRateIndex !== 3\n ) {\n const paddingBit = (data[offset + 2] >> 1) & 1;\n const channelMode = data[offset + 3] >> 6;\n const columnInBitrates =\n mpegVersion === 3 ? 3 - mpegLayer : mpegLayer === 3 ? 3 : 4;\n const bitRate =\n BitratesMap[columnInBitrates * 14 + bitRateIndex - 1] * 1000;\n const columnInSampleRates =\n mpegVersion === 3 ? 0 : mpegVersion === 2 ? 1 : 2;\n const sampleRate =\n SamplingRateMap[columnInSampleRates * 3 + sampleRateIndex];\n const channelCount = channelMode === 3 ? 1 : 2; // If bits of channel mode are `11` then it is a single channel (Mono)\n const sampleCoefficient = SamplesCoefficients[mpegVersion][mpegLayer];\n const bytesInSlot = BytesInSlot[mpegLayer];\n const samplesPerFrame = sampleCoefficient * 8 * bytesInSlot;\n const frameLength =\n Math.floor((sampleCoefficient * bitRate) / sampleRate + paddingBit) *\n bytesInSlot;\n\n if (chromeVersion === null) {\n const userAgent = navigator.userAgent || '';\n const result = userAgent.match(/Chrome\\/(\\d+)/i);\n chromeVersion = result ? parseInt(result[1]) : 0;\n }\n const needChromeFix = !!chromeVersion && chromeVersion <= 87;\n\n if (\n needChromeFix &&\n mpegLayer === 2 &&\n bitRate >= 224000 &&\n channelMode === 0\n ) {\n // Work around bug in Chromium by setting channelMode to dual-channel (01) instead of stereo (00)\n data[offset + 3] = data[offset + 3] | 0x80;\n }\n\n return { sampleRate, channelCount, frameLength, samplesPerFrame };\n }\n}\n\nexport function isHeaderPattern(data: Uint8Array, offset: number): boolean {\n return (\n data[offset] === 0xff &&\n (data[offset + 1] & 0xe0) === 0xe0 &&\n (data[offset + 1] & 0x06) !== 0x00\n );\n}\n\nexport function isHeader(data: Uint8Array, offset: number): boolean {\n // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1\n // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)\n // More info http://www.mp3-tech.org/programmer/frame_header.html\n return offset + 1 < data.length && isHeaderPattern(data, offset);\n}\n\nexport function canParse(data: Uint8Array, offset: number): boolean {\n const headerSize = 4;\n\n return isHeaderPattern(data, offset) && headerSize <= data.length - offset;\n}\n\nexport function probe(data: Uint8Array, offset: number): boolean {\n // same as isHeader but we also check that MPEG frame follows last MPEG frame\n // or end of data is reached\n if (offset + 1 < data.length && isHeaderPattern(data, offset)) {\n // MPEG header Length\n const headerLength = 4;\n // MPEG frame Length\n const header = parseHeader(data, offset);\n let frameLength = headerLength;\n if (header?.frameLength) {\n frameLength = header.frameLength;\n }\n\n const newOffset = offset + frameLength;\n return newOffset === data.length || isHeader(data, newOffset);\n }\n return false;\n}\n","/**\n * AAC demuxer\n */\nimport { getId3Data } from '@svta/common-media-library/id3/getId3Data';\nimport * as ADTS from './adts';\nimport BaseAudioDemuxer from './base-audio-demuxer';\nimport * as MpegAudio from './mpegaudio';\nimport type { HlsConfig } from '../../config';\nimport type { HlsEventEmitter } from '../../events';\nimport type { DemuxedAudioTrack } from '../../types/demuxer';\nimport type { ILogger } from '../../utils/logger';\n\nclass AACDemuxer extends BaseAudioDemuxer {\n private readonly observer: HlsEventEmitter;\n private readonly config: HlsConfig;\n\n constructor(observer: HlsEventEmitter, config) {\n super();\n this.observer = observer;\n this.config = config;\n }\n\n resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n ) {\n super.resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration);\n this._audioTrack = {\n container: 'audio/adts',\n type: 'audio',\n id: 2,\n pid: -1,\n sequenceNumber: 0,\n segmentCodec: 'aac',\n samples: [],\n manifestCodec: audioCodec,\n duration: trackDuration,\n inputTimeScale: 90000,\n dropped: 0,\n };\n }\n\n // Source for probe info - https://wiki.multimedia.cx/index.php?title=ADTS\n static probe(data: Uint8Array | undefined, logger: ILogger): boolean {\n if (!data) {\n return false;\n }\n\n // Check for the ADTS sync word\n // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1\n // Layer bits (position 14 and 15) in header should be always 0 for ADTS\n // More info https://wiki.multimedia.cx/index.php?title=ADTS\n const id3Data = getId3Data(data, 0);\n let offset = id3Data?.length || 0;\n\n if (MpegAudio.probe(data, offset)) {\n return false;\n }\n\n for (let length = data.length; offset < length; offset++) {\n if (ADTS.probe(data, offset)) {\n logger.log('ADTS sync word found !');\n return true;\n }\n }\n return false;\n }\n\n canParse(data, offset) {\n return ADTS.canParse(data, offset);\n }\n\n appendFrame(track: DemuxedAudioTrack, data: Uint8Array, offset: number) {\n ADTS.initTrackConfig(\n track,\n this.observer,\n data,\n offset,\n track.manifestCodec,\n );\n const frame = ADTS.appendFrame(\n track,\n data,\n offset,\n this.basePTS as number,\n this.frameIndex,\n );\n if (frame && frame.missing === 0) {\n return frame;\n }\n }\n}\n\nexport default AACDemuxer;\n","export const getAudioBSID = (data: Uint8Array, offset: number): number => {\n // check the bsid to confirm ac-3 | ec-3\n let bsid = 0;\n let numBits = 5;\n offset += numBits;\n const temp = new Uint32Array(1); // unsigned 32 bit for temporary storage\n const mask = new Uint32Array(1); // unsigned 32 bit mask value\n const byte = new Uint8Array(1); // unsigned 8 bit for temporary storage\n while (numBits > 0) {\n byte[0] = data[offset];\n // read remaining bits, upto 8 bits at a time\n const bits = Math.min(numBits, 8);\n const shift = 8 - bits;\n mask[0] = (0xff000000 >>> (24 + shift)) << shift;\n temp[0] = (byte[0] & mask[0]) >> shift;\n bsid = !bsid ? temp[0] : (bsid << bits) | temp[0];\n offset += 1;\n numBits -= bits;\n }\n return bsid;\n};\n","import { getId3Data } from '@svta/common-media-library/id3/getId3Data';\nimport { getId3Timestamp } from '@svta/common-media-library/id3/getId3Timestamp';\nimport BaseAudioDemuxer from './base-audio-demuxer';\nimport { getAudioBSID } from './dolby';\nimport type { HlsEventEmitter } from '../../events';\nimport type { AudioFrame, DemuxedAudioTrack } from '../../types/demuxer';\n\nexport class AC3Demuxer extends BaseAudioDemuxer {\n private readonly observer: HlsEventEmitter;\n\n constructor(observer: HlsEventEmitter) {\n super();\n this.observer = observer;\n }\n\n resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n ) {\n super.resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration);\n this._audioTrack = {\n container: 'audio/ac-3',\n type: 'audio',\n id: 2,\n pid: -1,\n sequenceNumber: 0,\n segmentCodec: 'ac3',\n samples: [],\n manifestCodec: audioCodec,\n duration: trackDuration,\n inputTimeScale: 90000,\n dropped: 0,\n };\n }\n\n canParse(data: Uint8Array, offset: number): boolean {\n return offset + 64 < data.length;\n }\n\n appendFrame(\n track: DemuxedAudioTrack,\n data: Uint8Array,\n offset: number,\n ): AudioFrame | void {\n const frameLength = appendFrame(\n track,\n data,\n offset,\n this.basePTS as number,\n this.frameIndex,\n );\n if (frameLength !== -1) {\n const sample = track.samples[track.samples.length - 1];\n return { sample, length: frameLength, missing: 0 };\n }\n }\n\n static probe(data: Uint8Array | undefined): boolean {\n if (!data) {\n return false;\n }\n\n const id3Data = getId3Data(data, 0);\n if (!id3Data) {\n return false;\n }\n\n // look for the ac-3 sync bytes\n const offset = id3Data.length;\n if (\n data[offset] === 0x0b &&\n data[offset + 1] === 0x77 &&\n getId3Timestamp(id3Data) !== undefined &&\n // check the bsid to confirm ac-3\n getAudioBSID(data, offset) < 16\n ) {\n return true;\n }\n return false;\n }\n}\n\nexport function appendFrame(\n track: DemuxedAudioTrack,\n data: Uint8Array,\n start: number,\n pts: number,\n frameIndex: number,\n): number {\n if (start + 8 > data.length) {\n return -1; // not enough bytes left\n }\n\n if (data[start] !== 0x0b || data[start + 1] !== 0x77) {\n return -1; // invalid magic\n }\n\n // get sample rate\n const samplingRateCode = data[start + 4] >> 6;\n if (samplingRateCode >= 3) {\n return -1; // invalid sampling rate\n }\n\n const samplingRateMap = [48000, 44100, 32000];\n const sampleRate = samplingRateMap[samplingRateCode];\n\n // get frame size\n const frameSizeCode = data[start + 4] & 0x3f;\n const frameSizeMap = [\n 64, 69, 96, 64, 70, 96, 80, 87, 120, 80, 88, 120, 96, 104, 144, 96, 105,\n 144, 112, 121, 168, 112, 122, 168, 128, 139, 192, 128, 140, 192, 160, 174,\n 240, 160, 175, 240, 192, 208, 288, 192, 209, 288, 224, 243, 336, 224, 244,\n 336, 256, 278, 384, 256, 279, 384, 320, 348, 480, 320, 349, 480, 384, 417,\n 576, 384, 418, 576, 448, 487, 672, 448, 488, 672, 512, 557, 768, 512, 558,\n 768, 640, 696, 960, 640, 697, 960, 768, 835, 1152, 768, 836, 1152, 896, 975,\n 1344, 896, 976, 1344, 1024, 1114, 1536, 1024, 1115, 1536, 1152, 1253, 1728,\n 1152, 1254, 1728, 1280, 1393, 1920, 1280, 1394, 1920,\n ];\n\n const frameLength = frameSizeMap[frameSizeCode * 3 + samplingRateCode] * 2;\n if (start + frameLength > data.length) {\n return -1;\n }\n\n // get channel count\n const channelMode = data[start + 6] >> 5;\n let skipCount = 0;\n if (channelMode === 2) {\n skipCount += 2;\n } else {\n if (channelMode & 1 && channelMode !== 1) {\n skipCount += 2;\n }\n if (channelMode & 4) {\n skipCount += 2;\n }\n }\n\n const lfeon =\n (((data[start + 6] << 8) | data[start + 7]) >> (12 - skipCount)) & 1;\n\n const channelsMap = [2, 1, 2, 3, 3, 4, 4, 5];\n const channelCount = channelsMap[channelMode] + lfeon;\n\n // build dac3 box\n const bsid = data[start + 5] >> 3;\n const bsmod = data[start + 5] & 7;\n\n const config = new Uint8Array([\n (samplingRateCode << 6) | (bsid << 1) | (bsmod >> 2),\n ((bsmod & 3) << 6) |\n (channelMode << 3) |\n (lfeon << 2) |\n (frameSizeCode >> 4),\n (frameSizeCode << 4) & 0xe0,\n ]);\n\n const frameDuration = (1536 / sampleRate) * 90000;\n const stamp = pts + frameIndex * frameDuration;\n const unit = data.subarray(start, start + frameLength);\n\n track.config = config;\n track.channelCount = channelCount;\n track.samplerate = sampleRate;\n track.samples.push({ unit, pts: stamp });\n\n return frameLength;\n}\n","/**\n * MP3 demuxer\n */\nimport { getId3Data } from '@svta/common-media-library/id3/getId3Data';\nimport { getId3Timestamp } from '@svta/common-media-library/id3/getId3Timestamp';\nimport BaseAudioDemuxer from './base-audio-demuxer';\nimport { getAudioBSID } from './dolby';\nimport * as MpegAudio from './mpegaudio';\nimport { logger } from '../../utils/logger';\n\nclass MP3Demuxer extends BaseAudioDemuxer {\n resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n ) {\n super.resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration);\n this._audioTrack = {\n container: 'audio/mpeg',\n type: 'audio',\n id: 2,\n pid: -1,\n sequenceNumber: 0,\n segmentCodec: 'mp3',\n samples: [],\n manifestCodec: audioCodec,\n duration: trackDuration,\n inputTimeScale: 90000,\n dropped: 0,\n };\n }\n\n static probe(data: Uint8Array | undefined): boolean {\n if (!data) {\n return false;\n }\n\n // check if data contains ID3 timestamp and MPEG sync word\n // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1\n // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)\n // More info http://www.mp3-tech.org/programmer/frame_header.html\n const id3Data = getId3Data(data, 0);\n let offset = id3Data?.length || 0;\n\n // Check for ac-3|ec-3 sync bytes and return false if present\n if (\n id3Data &&\n data[offset] === 0x0b &&\n data[offset + 1] === 0x77 &&\n getId3Timestamp(id3Data) !== undefined &&\n // check the bsid to confirm ac-3 or ec-3 (not mp3)\n getAudioBSID(data, offset) <= 16\n ) {\n return false;\n }\n\n for (let length = data.length; offset < length; offset++) {\n if (MpegAudio.probe(data, offset)) {\n logger.log('MPEG Audio sync word found !');\n return true;\n }\n }\n return false;\n }\n\n canParse(data, offset) {\n return MpegAudio.canParse(data, offset);\n }\n\n appendFrame(track, data, offset) {\n if (this.basePTS === null) {\n return;\n }\n return MpegAudio.appendFrame(\n track,\n data,\n offset,\n this.basePTS,\n this.frameIndex,\n );\n }\n}\n\nexport default MP3Demuxer;\n","export const enum DecrypterAesMode {\n cbc = 0,\n ctr = 1,\n}\n","import { DecrypterAesMode } from './decrypter-aes-mode';\n\nexport default class AESCrypto {\n private subtle: SubtleCrypto;\n private aesIV: Uint8Array;\n private aesMode: DecrypterAesMode;\n\n constructor(subtle: SubtleCrypto, iv: Uint8Array, aesMode: DecrypterAesMode) {\n this.subtle = subtle;\n this.aesIV = iv;\n this.aesMode = aesMode;\n }\n\n decrypt(data: ArrayBuffer, key: CryptoKey) {\n switch (this.aesMode) {\n case DecrypterAesMode.cbc:\n return this.subtle.decrypt(\n { name: 'AES-CBC', iv: this.aesIV },\n key,\n data,\n );\n case DecrypterAesMode.ctr:\n return this.subtle.decrypt(\n { name: 'AES-CTR', counter: this.aesIV, length: 64 }, //64 : NIST SP800-38A standard suggests that the counter should occupy half of the counter block\n key,\n data,\n );\n default:\n throw new Error(`[AESCrypto] invalid aes mode ${this.aesMode}`);\n }\n }\n}\n","import { sliceUint8 } from '../utils/typed-array';\n\n// PKCS7\nexport function removePadding(array: Uint8Array): Uint8Array {\n const outputBytes = array.byteLength;\n const paddingBytes =\n outputBytes && new DataView(array.buffer).getUint8(outputBytes - 1);\n if (paddingBytes) {\n return sliceUint8(array, 0, outputBytes - paddingBytes);\n }\n return array;\n}\n\nexport default class AESDecryptor {\n private rcon: Array<number> = [\n 0x0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36,\n ];\n private subMix: Array<Uint32Array> = [\n new Uint32Array(256),\n new Uint32Array(256),\n new Uint32Array(256),\n new Uint32Array(256),\n ];\n private invSubMix: Array<Uint32Array> = [\n new Uint32Array(256),\n new Uint32Array(256),\n new Uint32Array(256),\n new Uint32Array(256),\n ];\n private sBox: Uint32Array = new Uint32Array(256);\n private invSBox: Uint32Array = new Uint32Array(256);\n private key: Uint32Array = new Uint32Array(0);\n\n private ksRows: number = 0;\n private keySize: number = 0;\n private keySchedule!: Uint32Array;\n private invKeySchedule!: Uint32Array;\n\n constructor() {\n this.initTable();\n }\n\n // Using view.getUint32() also swaps the byte order.\n uint8ArrayToUint32Array_(arrayBuffer) {\n const view = new DataView(arrayBuffer);\n const newArray = new Uint32Array(4);\n for (let i = 0; i < 4; i++) {\n newArray[i] = view.getUint32(i * 4);\n }\n\n return newArray;\n }\n\n initTable() {\n const sBox = this.sBox;\n const invSBox = this.invSBox;\n const subMix = this.subMix;\n const subMix0 = subMix[0];\n const subMix1 = subMix[1];\n const subMix2 = subMix[2];\n const subMix3 = subMix[3];\n const invSubMix = this.invSubMix;\n const invSubMix0 = invSubMix[0];\n const invSubMix1 = invSubMix[1];\n const invSubMix2 = invSubMix[2];\n const invSubMix3 = invSubMix[3];\n\n const d = new Uint32Array(256);\n let x = 0;\n let xi = 0;\n let i = 0;\n for (i = 0; i < 256; i++) {\n if (i < 128) {\n d[i] = i << 1;\n } else {\n d[i] = (i << 1) ^ 0x11b;\n }\n }\n\n for (i = 0; i < 256; i++) {\n let sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);\n sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;\n sBox[x] = sx;\n invSBox[sx] = x;\n\n // Compute multiplication\n const x2 = d[x];\n const x4 = d[x2];\n const x8 = d[x4];\n\n // Compute sub/invSub bytes, mix columns tables\n let t = (d[sx] * 0x101) ^ (sx * 0x1010100);\n subMix0[x] = (t << 24) | (t >>> 8);\n subMix1[x] = (t << 16) | (t >>> 16);\n subMix2[x] = (t << 8) | (t >>> 24);\n subMix3[x] = t;\n\n // Compute inv sub bytes, inv mix columns tables\n t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);\n invSubMix0[sx] = (t << 24) | (t >>> 8);\n invSubMix1[sx] = (t << 16) | (t >>> 16);\n invSubMix2[sx] = (t << 8) | (t >>> 24);\n invSubMix3[sx] = t;\n\n // Compute next counter\n if (!x) {\n x = xi = 1;\n } else {\n x = x2 ^ d[d[d[x8 ^ x2]]];\n xi ^= d[d[xi]];\n }\n }\n }\n\n expandKey(keyBuffer: ArrayBuffer) {\n // convert keyBuffer to Uint32Array\n const key = this.uint8ArrayToUint32Array_(keyBuffer);\n let sameKey = true;\n let offset = 0;\n\n while (offset < key.length && sameKey) {\n sameKey = key[offset] === this.key[offset];\n offset++;\n }\n\n if (sameKey) {\n return;\n }\n\n this.key = key;\n const keySize = (this.keySize = key.length);\n\n if (keySize !== 4 && keySize !== 6 && keySize !== 8) {\n throw new Error('Invalid aes key size=' + keySize);\n }\n\n const ksRows = (this.ksRows = (keySize + 6 + 1) * 4);\n let ksRow;\n let invKsRow;\n\n const keySchedule = (this.keySchedule = new Uint32Array(ksRows));\n const invKeySchedule = (this.invKeySchedule = new Uint32Array(ksRows));\n const sbox = this.sBox;\n const rcon = this.rcon;\n\n const invSubMix = this.invSubMix;\n const invSubMix0 = invSubMix[0];\n const invSubMix1 = invSubMix[1];\n const invSubMix2 = invSubMix[2];\n const invSubMix3 = invSubMix[3];\n\n let prev;\n let t;\n\n for (ksRow = 0; ksRow < ksRows; ksRow++) {\n if (ksRow < keySize) {\n prev = keySchedule[ksRow] = key[ksRow];\n continue;\n }\n t = prev;\n\n if (ksRow % keySize === 0) {\n // Rot word\n t = (t << 8) | (t >>> 24);\n\n // Sub word\n t =\n (sbox[t >>> 24] << 24) |\n (sbox[(t >>> 16) & 0xff] << 16) |\n (sbox[(t >>> 8) & 0xff] << 8) |\n sbox[t & 0xff];\n\n // Mix Rcon\n t ^= rcon[(ksRow / keySize) | 0] << 24;\n } else if (keySize > 6 && ksRow % keySize === 4) {\n // Sub word\n t =\n (sbox[t >>> 24] << 24) |\n (sbox[(t >>> 16) & 0xff] << 16) |\n (sbox[(t >>> 8) & 0xff] << 8) |\n sbox[t & 0xff];\n }\n\n keySchedule[ksRow] = prev = (keySchedule[ksRow - keySize] ^ t) >>> 0;\n }\n\n for (invKsRow = 0; invKsRow < ksRows; invKsRow++) {\n ksRow = ksRows - invKsRow;\n if (invKsRow & 3) {\n t = keySchedule[ksRow];\n } else {\n t = keySchedule[ksRow - 4];\n }\n\n if (invKsRow < 4 || ksRow <= 4) {\n invKeySchedule[invKsRow] = t;\n } else {\n invKeySchedule[invKsRow] =\n invSubMix0[sbox[t >>> 24]] ^\n invSubMix1[sbox[(t >>> 16) & 0xff]] ^\n invSubMix2[sbox[(t >>> 8) & 0xff]] ^\n invSubMix3[sbox[t & 0xff]];\n }\n\n invKeySchedule[invKsRow] = invKeySchedule[invKsRow] >>> 0;\n }\n }\n\n // Adding this as a method greatly improves performance.\n networkToHostOrderSwap(word) {\n return (\n (word << 24) |\n ((word & 0xff00) << 8) |\n ((word & 0xff0000) >> 8) |\n (word >>> 24)\n );\n }\n\n decrypt(inputArrayBuffer: ArrayBuffer, offset: number, aesIV: ArrayBuffer) {\n const nRounds = this.keySize + 6;\n const invKeySchedule = this.invKeySchedule;\n const invSBOX = this.invSBox;\n\n const invSubMix = this.invSubMix;\n const invSubMix0 = invSubMix[0];\n const invSubMix1 = invSubMix[1];\n const invSubMix2 = invSubMix[2];\n const invSubMix3 = invSubMix[3];\n\n const initVector = this.uint8ArrayToUint32Array_(aesIV);\n let initVector0 = initVector[0];\n let initVector1 = initVector[1];\n let initVector2 = initVector[2];\n let initVector3 = initVector[3];\n\n const inputInt32 = new Int32Array(inputArrayBuffer);\n const outputInt32 = new Int32Array(inputInt32.length);\n\n let t0, t1, t2, t3;\n let s0, s1, s2, s3;\n let inputWords0, inputWords1, inputWords2, inputWords3;\n\n let ksRow, i;\n const swapWord = this.networkToHostOrderSwap;\n\n while (offset < inputInt32.length) {\n inputWords0 = swapWord(inputInt32[offset]);\n inputWords1 = swapWord(inputInt32[offset + 1]);\n inputWords2 = swapWord(inputInt32[offset + 2]);\n inputWords3 = swapWord(inputInt32[offset + 3]);\n\n s0 = inputWords0 ^ invKeySchedule[0];\n s1 = inputWords3 ^ invKeySchedule[1];\n s2 = inputWords2 ^ invKeySchedule[2];\n s3 = inputWords1 ^ invKeySchedule[3];\n\n ksRow = 4;\n\n // Iterate through the rounds of decryption\n for (i = 1; i < nRounds; i++) {\n t0 =\n invSubMix0[s0 >>> 24] ^\n invSubMix1[(s1 >> 16) & 0xff] ^\n invSubMix2[(s2 >> 8) & 0xff] ^\n invSubMix3[s3 & 0xff] ^\n invKeySchedule[ksRow];\n t1 =\n invSubMix0[s1 >>> 24] ^\n invSubMix1[(s2 >> 16) & 0xff] ^\n invSubMix2[(s3 >> 8) & 0xff] ^\n invSubMix3[s0 & 0xff] ^\n invKeySchedule[ksRow + 1];\n t2 =\n invSubMix0[s2 >>> 24] ^\n invSubMix1[(s3 >> 16) & 0xff] ^\n invSubMix2[(s0 >> 8) & 0xff] ^\n invSubMix3[s1 & 0xff] ^\n invKeySchedule[ksRow + 2];\n t3 =\n invSubMix0[s3 >>> 24] ^\n invSubMix1[(s0 >> 16) & 0xff] ^\n invSubMix2[(s1 >> 8) & 0xff] ^\n invSubMix3[s2 & 0xff] ^\n invKeySchedule[ksRow + 3];\n // Update state\n s0 = t0;\n s1 = t1;\n s2 = t2;\n s3 = t3;\n\n ksRow = ksRow + 4;\n }\n\n // Shift rows, sub bytes, add round key\n t0 =\n (invSBOX[s0 >>> 24] << 24) ^\n (invSBOX[(s1 >> 16) & 0xff] << 16) ^\n (invSBOX[(s2 >> 8) & 0xff] << 8) ^\n invSBOX[s3 & 0xff] ^\n invKeySchedule[ksRow];\n t1 =\n (invSBOX[s1 >>> 24] << 24) ^\n (invSBOX[(s2 >> 16) & 0xff] << 16) ^\n (invSBOX[(s3 >> 8) & 0xff] << 8) ^\n invSBOX[s0 & 0xff] ^\n invKeySchedule[ksRow + 1];\n t2 =\n (invSBOX[s2 >>> 24] << 24) ^\n (invSBOX[(s3 >> 16) & 0xff] << 16) ^\n (invSBOX[(s0 >> 8) & 0xff] << 8) ^\n invSBOX[s1 & 0xff] ^\n invKeySchedule[ksRow + 2];\n t3 =\n (invSBOX[s3 >>> 24] << 24) ^\n (invSBOX[(s0 >> 16) & 0xff] << 16) ^\n (invSBOX[(s1 >> 8) & 0xff] << 8) ^\n invSBOX[s2 & 0xff] ^\n invKeySchedule[ksRow + 3];\n\n // Write\n outputInt32[offset] = swapWord(t0 ^ initVector0);\n outputInt32[offset + 1] = swapWord(t3 ^ initVector1);\n outputInt32[offset + 2] = swapWord(t2 ^ initVector2);\n outputInt32[offset + 3] = swapWord(t1 ^ initVector3);\n\n // reset initVector to last 4 unsigned int\n initVector0 = inputWords0;\n initVector1 = inputWords1;\n initVector2 = inputWords2;\n initVector3 = inputWords3;\n\n offset = offset + 4;\n }\n\n return outputInt32.buffer;\n }\n}\n","import { DecrypterAesMode } from './decrypter-aes-mode';\n\nexport default class FastAESKey {\n private subtle: SubtleCrypto;\n private key: ArrayBuffer;\n private aesMode: DecrypterAesMode;\n\n constructor(\n subtle: SubtleCrypto,\n key: ArrayBuffer,\n aesMode: DecrypterAesMode,\n ) {\n this.subtle = subtle;\n this.key = key;\n this.aesMode = aesMode;\n }\n\n expandKey() {\n const subtleAlgoName = getSubtleAlgoName(this.aesMode);\n return this.subtle.importKey(\n 'raw',\n this.key,\n { name: subtleAlgoName },\n false,\n ['encrypt', 'decrypt'],\n );\n }\n}\n\nfunction getSubtleAlgoName(aesMode: DecrypterAesMode) {\n switch (aesMode) {\n case DecrypterAesMode.cbc:\n return 'AES-CBC';\n case DecrypterAesMode.ctr:\n return 'AES-CTR';\n default:\n throw new Error(`[FastAESKey] invalid aes mode ${aesMode}`);\n }\n}\n","import AESCrypto from './aes-crypto';\nimport AESDecryptor, { removePadding } from './aes-decryptor';\nimport { DecrypterAesMode } from './decrypter-aes-mode';\nimport FastAESKey from './fast-aes-key';\nimport { logger } from '../utils/logger';\nimport { appendUint8Array } from '../utils/mp4-tools';\nimport { sliceUint8 } from '../utils/typed-array';\nimport type { HlsConfig } from '../config';\n\nconst CHUNK_SIZE = 16; // 16 bytes, 128 bits\n\nexport default class Decrypter {\n private logEnabled: boolean = true;\n private removePKCS7Padding: boolean;\n private subtle: SubtleCrypto | null = null;\n private softwareDecrypter: AESDecryptor | null = null;\n private key: ArrayBuffer | null = null;\n private fastAesKey: FastAESKey | null = null;\n private remainderData: Uint8Array | null = null;\n private currentIV: ArrayBuffer | null = null;\n private currentResult: ArrayBuffer | null = null;\n private useSoftware: boolean;\n private enableSoftwareAES: boolean;\n\n constructor(config: HlsConfig, { removePKCS7Padding = true } = {}) {\n this.enableSoftwareAES = config.enableSoftwareAES;\n this.removePKCS7Padding = removePKCS7Padding;\n // built in decryptor expects PKCS7 padding\n if (removePKCS7Padding) {\n try {\n const browserCrypto = self.crypto;\n if (browserCrypto) {\n this.subtle =\n browserCrypto.subtle ||\n ((browserCrypto as any).webkitSubtle as SubtleCrypto);\n }\n } catch (e) {\n /* no-op */\n }\n }\n this.useSoftware = !this.subtle;\n }\n\n destroy() {\n this.subtle = null;\n this.softwareDecrypter = null;\n this.key = null;\n this.fastAesKey = null;\n this.remainderData = null;\n this.currentIV = null;\n this.currentResult = null;\n }\n\n public isSync() {\n return this.useSoftware;\n }\n\n public flush(): Uint8Array | null {\n const { currentResult, remainderData } = this;\n if (!currentResult || remainderData) {\n this.reset();\n return null;\n }\n const data = new Uint8Array(currentResult);\n this.reset();\n if (this.removePKCS7Padding) {\n return removePadding(data);\n }\n return data;\n }\n\n public reset() {\n this.currentResult = null;\n this.currentIV = null;\n this.remainderData = null;\n if (this.softwareDecrypter) {\n this.softwareDecrypter = null;\n }\n }\n\n public decrypt(\n data: Uint8Array | ArrayBuffer,\n key: ArrayBuffer,\n iv: ArrayBuffer,\n aesMode: DecrypterAesMode,\n ): Promise<ArrayBuffer> {\n if (this.useSoftware) {\n return new Promise((resolve, reject) => {\n const dataView = ArrayBuffer.isView(data) ? data : new Uint8Array(data);\n this.softwareDecrypt(dataView, key, iv, aesMode);\n const decryptResult = this.flush();\n if (decryptResult) {\n resolve(decryptResult.buffer);\n } else {\n reject(new Error('[softwareDecrypt] Failed to decrypt data'));\n }\n });\n }\n return this.webCryptoDecrypt(new Uint8Array(data), key, iv, aesMode);\n }\n\n // Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached\n // data is handled in the flush() call\n public softwareDecrypt(\n data: Uint8Array,\n key: ArrayBuffer,\n iv: ArrayBuffer,\n aesMode: DecrypterAesMode,\n ): ArrayBuffer | null {\n const { currentIV, currentResult, remainderData } = this;\n if (aesMode !== DecrypterAesMode.cbc || key.byteLength !== 16) {\n logger.warn('SoftwareDecrypt: can only handle AES-128-CBC');\n return null;\n }\n this.logOnce('JS AES decrypt');\n // The output is staggered during progressive parsing - the current result is cached, and emitted on the next call\n // This is done in order to strip PKCS7 padding, which is found at the end of each segment. We only know we've reached\n // the end on flush(), but by that time we have already received all bytes for the segment.\n // Progressive decryption does not work with WebCrypto\n\n if (remainderData) {\n data = appendUint8Array(remainderData, data);\n this.remainderData = null;\n }\n\n // Byte length must be a multiple of 16 (AES-128 = 128 bit blocks = 16 bytes)\n const currentChunk = this.getValidChunk(data);\n if (!currentChunk.length) {\n return null;\n }\n\n if (currentIV) {\n iv = currentIV;\n }\n\n let softwareDecrypter = this.softwareDecrypter;\n if (!softwareDecrypter) {\n softwareDecrypter = this.softwareDecrypter = new AESDecryptor();\n }\n softwareDecrypter.expandKey(key);\n\n const result = currentResult;\n\n this.currentResult = softwareDecrypter.decrypt(currentChunk.buffer, 0, iv);\n this.currentIV = sliceUint8(currentChunk, -16).buffer;\n\n if (!result) {\n return null;\n }\n return result;\n }\n\n public webCryptoDecrypt(\n data: Uint8Array,\n key: ArrayBuffer,\n iv: ArrayBuffer,\n aesMode: DecrypterAesMode,\n ): Promise<ArrayBuffer> {\n if (this.key !== key || !this.fastAesKey) {\n if (!this.subtle) {\n return Promise.resolve(this.onWebCryptoError(data, key, iv, aesMode));\n }\n this.key = key;\n this.fastAesKey = new FastAESKey(this.subtle, key, aesMode);\n }\n return this.fastAesKey\n .expandKey()\n .then((aesKey: CryptoKey) => {\n // decrypt using web crypto\n if (!this.subtle) {\n return Promise.reject(new Error('web crypto not initialized'));\n }\n this.logOnce('WebCrypto AES decrypt');\n const crypto = new AESCrypto(this.subtle, new Uint8Array(iv), aesMode);\n return crypto.decrypt(data.buffer, aesKey);\n })\n .catch((err) => {\n logger.warn(\n `[decrypter]: WebCrypto Error, disable WebCrypto API, ${err.name}: ${err.message}`,\n );\n\n return this.onWebCryptoError(data, key, iv, aesMode);\n });\n }\n\n private onWebCryptoError(\n data: Uint8Array,\n key: ArrayBuffer,\n iv: ArrayBuffer,\n aesMode: DecrypterAesMode,\n ): ArrayBuffer | never {\n const enableSoftwareAES = this.enableSoftwareAES;\n if (enableSoftwareAES) {\n this.useSoftware = true;\n this.logEnabled = true;\n this.softwareDecrypt(data, key, iv, aesMode);\n const decryptResult = this.flush();\n if (decryptResult) {\n return decryptResult.buffer;\n }\n }\n throw new Error(\n 'WebCrypto' +\n (enableSoftwareAES ? ' and softwareDecrypt' : '') +\n ': failed to decrypt data',\n );\n }\n\n private getValidChunk(data: Uint8Array): Uint8Array {\n let currentChunk = data;\n const splitPoint = data.length - (data.length % CHUNK_SIZE);\n if (splitPoint !== data.length) {\n currentChunk = sliceUint8(data, 0, splitPoint);\n this.remainderData = sliceUint8(data, splitPoint);\n }\n return currentChunk;\n }\n\n private logOnce(msg: string) {\n if (!this.logEnabled) {\n return;\n }\n logger.log(`[decrypter]: ${msg}`);\n this.logEnabled = false;\n }\n}\n","/**\n * MP4 demuxer\n */\nimport { dummyTrack } from './dummy-demuxed-track';\nimport {\n type DemuxedAudioTrack,\n type DemuxedMetadataTrack,\n type DemuxedUserdataTrack,\n type Demuxer,\n type DemuxerResult,\n type KeyData,\n MetadataSchema,\n type PassthroughTrack,\n} from '../types/demuxer';\nimport {\n appendUint8Array,\n findBox,\n hasMoofData,\n parseEmsg,\n parseInitSegment,\n parseSamples,\n RemuxerTrackIdConfig,\n segmentValidRange,\n} from '../utils/mp4-tools';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport type { IEmsgParsingData } from '../utils/mp4-tools';\n\nconst emsgSchemePattern = /\\/emsg[-/]ID3/i;\n\nclass MP4Demuxer implements Demuxer {\n private remainderData: Uint8Array | null = null;\n private timeOffset: number = 0;\n private config: HlsConfig;\n private videoTrack?: PassthroughTrack;\n private audioTrack?: DemuxedAudioTrack;\n private id3Track?: DemuxedMetadataTrack;\n private txtTrack?: DemuxedUserdataTrack;\n\n constructor(observer: HlsEventEmitter, config: HlsConfig) {\n this.config = config;\n }\n\n public resetTimeStamp() {}\n\n public resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n ) {\n const videoTrack = (this.videoTrack = dummyTrack(\n 'video',\n 1,\n ) as PassthroughTrack);\n const audioTrack = (this.audioTrack = dummyTrack(\n 'audio',\n 1,\n ) as DemuxedAudioTrack);\n const captionTrack = (this.txtTrack = dummyTrack(\n 'text',\n 1,\n ) as DemuxedUserdataTrack);\n\n this.id3Track = dummyTrack('id3', 1) as DemuxedMetadataTrack;\n this.timeOffset = 0;\n\n if (!initSegment?.byteLength) {\n return;\n }\n const initData = parseInitSegment(initSegment);\n\n if (initData.video) {\n const { id, timescale, codec } = initData.video;\n videoTrack.id = id;\n videoTrack.timescale = captionTrack.timescale = timescale;\n videoTrack.codec = codec;\n }\n\n if (initData.audio) {\n const { id, timescale, codec } = initData.audio;\n audioTrack.id = id;\n audioTrack.timescale = timescale;\n audioTrack.codec = codec;\n }\n\n captionTrack.id = RemuxerTrackIdConfig.text;\n videoTrack.sampleDuration = 0;\n videoTrack.duration = audioTrack.duration = trackDuration;\n }\n\n public resetContiguity(): void {\n this.remainderData = null;\n }\n\n static probe(data: Uint8Array) {\n return hasMoofData(data);\n }\n\n public demux(data: Uint8Array, timeOffset: number): DemuxerResult {\n this.timeOffset = timeOffset;\n // Load all data into the avc track. The CMAF remuxer will look for the data in the samples object; the rest of the fields do not matter\n let videoSamples = data;\n const videoTrack = this.videoTrack as PassthroughTrack;\n const textTrack = this.txtTrack as DemuxedUserdataTrack;\n if (this.config.progressive) {\n // Split the bytestream into two ranges: one encompassing all data up until the start of the last moof, and everything else.\n // This is done to guarantee that we're sending valid data to MSE - when demuxing progressively, we have no guarantee\n // that the fetch loader gives us flush moof+mdat pairs. If we push jagged data to MSE, it will throw an exception.\n if (this.remainderData) {\n videoSamples = appendUint8Array(this.remainderData, data);\n }\n const segmentedData = segmentValidRange(videoSamples);\n this.remainderData = segmentedData.remainder;\n videoTrack.samples = segmentedData.valid || new Uint8Array();\n } else {\n videoTrack.samples = videoSamples;\n }\n const id3Track = this.extractID3Track(videoTrack, timeOffset);\n textTrack.samples = parseSamples(timeOffset, videoTrack);\n\n return {\n videoTrack,\n audioTrack: this.audioTrack as DemuxedAudioTrack,\n id3Track,\n textTrack: this.txtTrack as DemuxedUserdataTrack,\n };\n }\n\n public flush() {\n const timeOffset = this.timeOffset;\n const videoTrack = this.videoTrack as PassthroughTrack;\n const textTrack = this.txtTrack as DemuxedUserdataTrack;\n videoTrack.samples = this.remainderData || new Uint8Array();\n this.remainderData = null;\n\n const id3Track = this.extractID3Track(videoTrack, this.timeOffset);\n textTrack.samples = parseSamples(timeOffset, videoTrack);\n\n return {\n videoTrack,\n audioTrack: dummyTrack() as DemuxedAudioTrack,\n id3Track,\n textTrack: dummyTrack() as DemuxedUserdataTrack,\n };\n }\n\n private extractID3Track(\n videoTrack: PassthroughTrack,\n timeOffset: number,\n ): DemuxedMetadataTrack {\n const id3Track = this.id3Track as DemuxedMetadataTrack;\n if (videoTrack.samples.length) {\n const emsgs = findBox(videoTrack.samples, ['emsg']);\n if (emsgs) {\n emsgs.forEach((data: Uint8Array) => {\n const emsgInfo = parseEmsg(data);\n if (emsgSchemePattern.test(emsgInfo.schemeIdUri)) {\n const pts = getEmsgStartTime(emsgInfo, timeOffset);\n let duration =\n emsgInfo.eventDuration === 0xffffffff\n ? Number.POSITIVE_INFINITY\n : emsgInfo.eventDuration / emsgInfo.timeScale;\n // Safari takes anything <= 0.001 seconds and maps it to Infinity\n if (duration <= 0.001) {\n duration = Number.POSITIVE_INFINITY;\n }\n const payload = emsgInfo.payload;\n id3Track.samples.push({\n data: payload,\n len: payload.byteLength,\n dts: pts,\n pts: pts,\n type: MetadataSchema.emsg,\n duration: duration,\n });\n } else if (\n this.config.enableEmsgKLVMetadata &&\n emsgInfo.schemeIdUri.startsWith('urn:misb:KLV:bin:1910.1')\n ) {\n const pts = getEmsgStartTime(emsgInfo, timeOffset);\n id3Track.samples.push({\n data: emsgInfo.payload,\n len: emsgInfo.payload.byteLength,\n dts: pts,\n pts: pts,\n type: MetadataSchema.misbklv,\n duration: Number.POSITIVE_INFINITY,\n });\n }\n });\n }\n }\n return id3Track;\n }\n\n demuxSampleAes(\n data: Uint8Array,\n keyData: KeyData,\n timeOffset: number,\n ): Promise<DemuxerResult> {\n return Promise.reject(\n new Error('The MP4 demuxer does not support SAMPLE-AES decryption'),\n );\n }\n\n destroy() {\n // @ts-ignore\n this.config = null;\n this.remainderData = null;\n this.videoTrack =\n this.audioTrack =\n this.id3Track =\n this.txtTrack =\n undefined;\n }\n}\n\nfunction getEmsgStartTime(\n emsgInfo: IEmsgParsingData,\n timeOffset: number,\n): number {\n return Number.isFinite(emsgInfo.presentationTime)\n ? (emsgInfo.presentationTime as number) / emsgInfo.timeScale\n : timeOffset +\n (emsgInfo.presentationTimeDelta as number) / emsgInfo.timeScale;\n}\n\nexport default MP4Demuxer;\n","/**\n * SAMPLE-AES decrypter\n */\n\nimport Decrypter from '../crypt/decrypter';\nimport { DecrypterAesMode } from '../crypt/decrypter-aes-mode';\nimport { discardEPB } from '../utils/mp4-tools';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport type {\n AudioSample,\n DemuxedVideoTrackBase,\n KeyData,\n VideoSample,\n VideoSampleUnit,\n} from '../types/demuxer';\n\nclass SampleAesDecrypter {\n private keyData: KeyData;\n private decrypter: Decrypter;\n\n constructor(observer: HlsEventEmitter, config: HlsConfig, keyData: KeyData) {\n this.keyData = keyData;\n this.decrypter = new Decrypter(config, {\n removePKCS7Padding: false,\n });\n }\n\n decryptBuffer(encryptedData: Uint8Array | ArrayBuffer): Promise<ArrayBuffer> {\n return this.decrypter.decrypt(\n encryptedData,\n this.keyData.key.buffer,\n this.keyData.iv.buffer,\n DecrypterAesMode.cbc,\n );\n }\n\n // AAC - encrypt all full 16 bytes blocks starting from offset 16\n private decryptAacSample(\n samples: AudioSample[],\n sampleIndex: number,\n callback: () => void,\n ) {\n const curUnit = samples[sampleIndex].unit;\n if (curUnit.length <= 16) {\n // No encrypted portion in this sample (first 16 bytes is not\n // encrypted, see https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption/Encryption/Encryption.html),\n return;\n }\n const encryptedData = curUnit.subarray(\n 16,\n curUnit.length - (curUnit.length % 16),\n );\n const encryptedBuffer = encryptedData.buffer.slice(\n encryptedData.byteOffset,\n encryptedData.byteOffset + encryptedData.length,\n );\n\n this.decryptBuffer(encryptedBuffer).then((decryptedBuffer: ArrayBuffer) => {\n const decryptedData = new Uint8Array(decryptedBuffer);\n curUnit.set(decryptedData, 16);\n\n if (!this.decrypter.isSync()) {\n this.decryptAacSamples(samples, sampleIndex + 1, callback);\n }\n });\n }\n\n decryptAacSamples(\n samples: AudioSample[],\n sampleIndex: number,\n callback: () => void,\n ) {\n for (; ; sampleIndex++) {\n if (sampleIndex >= samples.length) {\n callback();\n return;\n }\n\n if (samples[sampleIndex].unit.length < 32) {\n continue;\n }\n\n this.decryptAacSample(samples, sampleIndex, callback);\n\n if (!this.decrypter.isSync()) {\n return;\n }\n }\n }\n\n // AVC - encrypt one 16 bytes block out of ten, starting from offset 32\n getAvcEncryptedData(decodedData: Uint8Array) {\n const encryptedDataLen =\n Math.floor((decodedData.length - 48) / 160) * 16 + 16;\n const encryptedData = new Int8Array(encryptedDataLen);\n let outputPos = 0;\n for (\n let inputPos = 32;\n inputPos < decodedData.length - 16;\n inputPos += 160, outputPos += 16\n ) {\n encryptedData.set(\n decodedData.subarray(inputPos, inputPos + 16),\n outputPos,\n );\n }\n\n return encryptedData;\n }\n\n getAvcDecryptedUnit(\n decodedData: Uint8Array,\n decryptedData: ArrayLike<number> | ArrayBuffer | SharedArrayBuffer,\n ) {\n const uint8DecryptedData = new Uint8Array(decryptedData);\n let inputPos = 0;\n for (\n let outputPos = 32;\n outputPos < decodedData.length - 16;\n outputPos += 160, inputPos += 16\n ) {\n decodedData.set(\n uint8DecryptedData.subarray(inputPos, inputPos + 16),\n outputPos,\n );\n }\n\n return decodedData;\n }\n\n decryptAvcSample(\n samples: VideoSample[],\n sampleIndex: number,\n unitIndex: number,\n callback: () => void,\n curUnit: VideoSampleUnit,\n ) {\n const decodedData = discardEPB(curUnit.data);\n const encryptedData = this.getAvcEncryptedData(decodedData);\n\n this.decryptBuffer(encryptedData.buffer).then(\n (decryptedBuffer: ArrayBuffer) => {\n curUnit.data = this.getAvcDecryptedUnit(decodedData, decryptedBuffer);\n\n if (!this.decrypter.isSync()) {\n this.decryptAvcSamples(samples, sampleIndex, unitIndex + 1, callback);\n }\n },\n );\n }\n\n decryptAvcSamples(\n samples: DemuxedVideoTrackBase['samples'],\n sampleIndex: number,\n unitIndex: number,\n callback: () => void,\n ) {\n if (samples instanceof Uint8Array) {\n throw new Error('Cannot decrypt samples of type Uint8Array');\n }\n\n for (; ; sampleIndex++, unitIndex = 0) {\n if (sampleIndex >= samples.length) {\n callback();\n return;\n }\n\n const curUnits = samples[sampleIndex].units;\n for (; ; unitIndex++) {\n if (unitIndex >= curUnits.length) {\n break;\n }\n\n const curUnit = curUnits[unitIndex];\n if (\n curUnit.data.length <= 48 ||\n (curUnit.type !== 1 && curUnit.type !== 5)\n ) {\n continue;\n }\n\n this.decryptAvcSample(\n samples,\n sampleIndex,\n unitIndex,\n callback,\n curUnit,\n );\n\n if (!this.decrypter.isSync()) {\n return;\n }\n }\n }\n }\n}\n\nexport default SampleAesDecrypter;\n","import { appendUint8Array } from '../../utils/mp4-tools';\nimport type {\n DemuxedUserdataTrack,\n DemuxedVideoTrack,\n VideoSample,\n VideoSampleUnit,\n} from '../../types/demuxer';\nimport type { ParsedVideoSample } from '../tsdemuxer';\nimport type { PES } from '../tsdemuxer';\n\nabstract class BaseVideoParser {\n protected VideoSample: ParsedVideoSample | null = null;\n\n protected createVideoSample(\n key: boolean,\n pts: number | undefined,\n dts: number | undefined,\n ): ParsedVideoSample {\n return {\n key,\n frame: false,\n pts,\n dts,\n units: [],\n length: 0,\n };\n }\n\n protected getLastNalUnit(\n samples: VideoSample[],\n ): VideoSampleUnit | undefined {\n let VideoSample = this.VideoSample;\n let lastUnit: VideoSampleUnit | undefined;\n // try to fallback to previous sample if current one is empty\n if (!VideoSample || VideoSample.units.length === 0) {\n VideoSample = samples[samples.length - 1];\n }\n if (VideoSample?.units) {\n const units = VideoSample.units;\n lastUnit = units[units.length - 1];\n }\n return lastUnit;\n }\n\n protected pushAccessUnit(\n VideoSample: ParsedVideoSample,\n videoTrack: DemuxedVideoTrack,\n ) {\n if (VideoSample.units.length && VideoSample.frame) {\n // if sample does not have PTS/DTS, patch with last sample PTS/DTS\n if (VideoSample.pts === undefined) {\n const samples = videoTrack.samples;\n const nbSamples = samples.length;\n if (nbSamples) {\n const lastSample = samples[nbSamples - 1];\n VideoSample.pts = lastSample.pts;\n VideoSample.dts = lastSample.dts;\n } else {\n // dropping samples, no timestamp found\n videoTrack.dropped++;\n return;\n }\n }\n videoTrack.samples.push(VideoSample as VideoSample);\n }\n }\n\n abstract parsePES(\n track: DemuxedVideoTrack,\n textTrack: DemuxedUserdataTrack,\n pes: PES,\n last: boolean,\n );\n\n protected abstract getNALuType(data: Uint8Array, offset: number): number;\n\n protected parseNALu(\n track: DemuxedVideoTrack,\n array: Uint8Array,\n endOfSegment: boolean,\n ): Array<{\n data: Uint8Array;\n type: number;\n state?: number;\n }> {\n const len = array.byteLength;\n let state = track.naluState || 0;\n const lastState = state;\n const units: VideoSampleUnit[] = [];\n let i = 0;\n let value: number;\n let overflow: number;\n let unitType: number;\n let lastUnitStart = -1;\n let lastUnitType: number = 0;\n // logger.log('PES:' + Hex.hexDump(array));\n\n if (state === -1) {\n // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet\n lastUnitStart = 0;\n // NALu type is value read from offset 0\n lastUnitType = this.getNALuType(array, 0);\n state = 0;\n i = 1;\n }\n\n while (i < len) {\n value = array[i++];\n // optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case\n if (!state) {\n state = value ? 0 : 1;\n continue;\n }\n if (state === 1) {\n state = value ? 0 : 2;\n continue;\n }\n // here we have state either equal to 2 or 3\n if (!value) {\n state = 3;\n } else if (value === 1) {\n overflow = i - state - 1;\n if (lastUnitStart >= 0) {\n const unit: VideoSampleUnit = {\n data: array.subarray(lastUnitStart, overflow),\n type: lastUnitType,\n };\n // logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);\n units.push(unit);\n } else {\n // lastUnitStart is undefined => this is the first start code found in this PES packet\n // first check if start code delimiter is overlapping between 2 PES packets,\n // ie it started in last packet (lastState not zero)\n // and ended at the beginning of this PES packet (i <= 4 - lastState)\n const lastUnit = this.getLastNalUnit(track.samples);\n if (lastUnit) {\n if (lastState && i <= 4 - lastState) {\n // start delimiter overlapping between PES packets\n // strip start delimiter bytes from the end of last NAL unit\n // check if lastUnit had a state different from zero\n if (lastUnit.state) {\n // strip last bytes\n lastUnit.data = lastUnit.data.subarray(\n 0,\n lastUnit.data.byteLength - lastState,\n );\n }\n }\n // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.\n\n if (overflow > 0) {\n // logger.log('first NALU found with overflow:' + overflow);\n lastUnit.data = appendUint8Array(\n lastUnit.data,\n array.subarray(0, overflow),\n );\n lastUnit.state = 0;\n }\n }\n }\n // check if we can read unit type\n if (i < len) {\n unitType = this.getNALuType(array, i);\n // logger.log('find NALU @ offset:' + i + ',type:' + unitType);\n lastUnitStart = i;\n lastUnitType = unitType;\n state = 0;\n } else {\n // not enough byte to read unit type. let's read it on next PES parsing\n state = -1;\n }\n } else {\n state = 0;\n }\n }\n if (lastUnitStart >= 0 && state >= 0) {\n const unit: VideoSampleUnit = {\n data: array.subarray(lastUnitStart, len),\n type: lastUnitType,\n state: state,\n };\n units.push(unit);\n // logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);\n }\n // no NALu found\n if (units.length === 0) {\n // append pes.data to previous NAL unit\n const lastUnit = this.getLastNalUnit(track.samples);\n if (lastUnit) {\n lastUnit.data = appendUint8Array(lastUnit.data, array);\n }\n }\n track.naluState = state;\n return units;\n }\n}\n\nexport default BaseVideoParser;\n","/**\n * Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264.\n */\n\nimport { logger } from '../../utils/logger';\n\nclass ExpGolomb {\n private data: Uint8Array;\n public bytesAvailable: number;\n private word: number;\n private bitsAvailable: number;\n\n constructor(data: Uint8Array) {\n this.data = data;\n // the number of bytes left to examine in this.data\n this.bytesAvailable = data.byteLength;\n // the current word being examined\n this.word = 0; // :uint\n // the number of bits left to examine in the current word\n this.bitsAvailable = 0; // :uint\n }\n\n // ():void\n loadWord(): void {\n const data = this.data;\n const bytesAvailable = this.bytesAvailable;\n const position = data.byteLength - bytesAvailable;\n const workingBytes = new Uint8Array(4);\n const availableBytes = Math.min(4, bytesAvailable);\n if (availableBytes === 0) {\n throw new Error('no bytes available');\n }\n\n workingBytes.set(data.subarray(position, position + availableBytes));\n this.word = new DataView(workingBytes.buffer).getUint32(0);\n // track the amount of this.data that has been processed\n this.bitsAvailable = availableBytes * 8;\n this.bytesAvailable -= availableBytes;\n }\n\n // (count:int):void\n skipBits(count: number): void {\n let skipBytes; // :int\n count = Math.min(count, this.bytesAvailable * 8 + this.bitsAvailable);\n if (this.bitsAvailable > count) {\n this.word <<= count;\n this.bitsAvailable -= count;\n } else {\n count -= this.bitsAvailable;\n skipBytes = count >> 3;\n count -= skipBytes << 3;\n this.bytesAvailable -= skipBytes;\n this.loadWord();\n this.word <<= count;\n this.bitsAvailable -= count;\n }\n }\n\n // (size:int):uint\n readBits(size: number): number {\n let bits = Math.min(this.bitsAvailable, size); // :uint\n const valu = this.word >>> (32 - bits); // :uint\n if (size > 32) {\n logger.error('Cannot read more than 32 bits at a time');\n }\n\n this.bitsAvailable -= bits;\n if (this.bitsAvailable > 0) {\n this.word <<= bits;\n } else if (this.bytesAvailable > 0) {\n this.loadWord();\n } else {\n throw new Error('no bits available');\n }\n\n bits = size - bits;\n if (bits > 0 && this.bitsAvailable) {\n return (valu << bits) | this.readBits(bits);\n } else {\n return valu;\n }\n }\n\n // ():uint\n skipLZ(): number {\n let leadingZeroCount; // :uint\n for (\n leadingZeroCount = 0;\n leadingZeroCount < this.bitsAvailable;\n ++leadingZeroCount\n ) {\n if ((this.word & (0x80000000 >>> leadingZeroCount)) !== 0) {\n // the first bit of working word is 1\n this.word <<= leadingZeroCount;\n this.bitsAvailable -= leadingZeroCount;\n return leadingZeroCount;\n }\n }\n // we exhausted word and still have not found a 1\n this.loadWord();\n return leadingZeroCount + this.skipLZ();\n }\n\n // ():void\n skipUEG(): void {\n this.skipBits(1 + this.skipLZ());\n }\n\n // ():void\n skipEG(): void {\n this.skipBits(1 + this.skipLZ());\n }\n\n // ():uint\n readUEG(): number {\n const clz = this.skipLZ(); // :uint\n return this.readBits(clz + 1) - 1;\n }\n\n // ():int\n readEG(): number {\n const valu = this.readUEG(); // :int\n if (0x01 & valu) {\n // the number is odd if the low order bit is set\n return (1 + valu) >>> 1; // add 1 to make it even, and divide by 2\n } else {\n return -1 * (valu >>> 1); // divide by two then make it negative\n }\n }\n\n // Some convenience functions\n // :Boolean\n readBoolean(): boolean {\n return this.readBits(1) === 1;\n }\n\n // ():int\n readUByte(): number {\n return this.readBits(8);\n }\n\n // ():int\n readUShort(): number {\n return this.readBits(16);\n }\n\n // ():int\n readUInt(): number {\n return this.readBits(32);\n }\n}\n\nexport default ExpGolomb;\n","import BaseVideoParser from './base-video-parser';\nimport ExpGolomb from './exp-golomb';\nimport { parseSEIMessageFromNALu } from '../../utils/mp4-tools';\nimport type {\n DemuxedUserdataTrack,\n DemuxedVideoTrack,\n} from '../../types/demuxer';\nimport type { PES } from '../tsdemuxer';\n\nclass AvcVideoParser extends BaseVideoParser {\n public parsePES(\n track: DemuxedVideoTrack,\n textTrack: DemuxedUserdataTrack,\n pes: PES,\n endOfSegment: boolean,\n ) {\n const units = this.parseNALu(track, pes.data, endOfSegment);\n let VideoSample = this.VideoSample;\n let push: boolean;\n let spsfound = false;\n // free pes.data to save up some memory\n (pes as any).data = null;\n\n // if new NAL units found and last sample still there, let's push ...\n // this helps parsing streams with missing AUD (only do this if AUD never found)\n if (VideoSample && units.length && !track.audFound) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = this.VideoSample = this.createVideoSample(\n false,\n pes.pts,\n pes.dts,\n );\n }\n\n units.forEach((unit) => {\n switch (unit.type) {\n // NDR\n case 1: {\n let iskey = false;\n push = true;\n const data = unit.data;\n // only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)\n if (spsfound && data.length > 4) {\n // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR\n const sliceType = this.readSliceType(data);\n // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice\n // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.\n // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.\n // I slice: A slice that is not an SI slice that is decoded using intra prediction only.\n // if (sliceType === 2 || sliceType === 7) {\n if (\n sliceType === 2 ||\n sliceType === 4 ||\n sliceType === 7 ||\n sliceType === 9\n ) {\n iskey = true;\n }\n }\n\n if (iskey) {\n // if we have non-keyframe data already, that cannot belong to the same frame as a keyframe, so force a push\n if (VideoSample?.frame && !VideoSample.key) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = this.VideoSample = null;\n }\n }\n\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n true,\n pes.pts,\n pes.dts,\n );\n }\n VideoSample.frame = true;\n VideoSample.key = iskey;\n\n break;\n // IDR\n }\n case 5:\n push = true;\n // handle PES not starting with AUD\n // if we have frame data already, that cannot belong to the same frame, so force a push\n if (VideoSample?.frame && !VideoSample.key) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = this.VideoSample = null;\n }\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n true,\n pes.pts,\n pes.dts,\n );\n }\n\n VideoSample.key = true;\n VideoSample.frame = true;\n break;\n // SEI\n case 6: {\n push = true;\n parseSEIMessageFromNALu(\n unit.data,\n 1,\n pes.pts as number,\n textTrack.samples,\n );\n break;\n // SPS\n }\n case 7: {\n push = true;\n spsfound = true;\n const sps = unit.data;\n const config = this.readSPS(sps);\n if (\n !track.sps ||\n track.width !== config.width ||\n track.height !== config.height ||\n track.pixelRatio?.[0] !== config.pixelRatio[0] ||\n track.pixelRatio?.[1] !== config.pixelRatio[1]\n ) {\n track.width = config.width;\n track.height = config.height;\n track.pixelRatio = config.pixelRatio;\n track.sps = [sps];\n const codecarray = sps.subarray(1, 4);\n let codecstring = 'avc1.';\n for (let i = 0; i < 3; i++) {\n let h = codecarray[i].toString(16);\n if (h.length < 2) {\n h = '0' + h;\n }\n\n codecstring += h;\n }\n track.codec = codecstring;\n }\n break;\n }\n // PPS\n case 8:\n push = true;\n\n track.pps = [unit.data];\n\n break;\n // AUD\n case 9:\n push = true;\n track.audFound = true;\n if (VideoSample?.frame) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = null;\n }\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n false,\n pes.pts,\n pes.dts,\n );\n }\n break;\n // Filler Data\n case 12:\n push = true;\n break;\n default:\n push = false;\n\n break;\n }\n if (VideoSample && push) {\n const units = VideoSample.units;\n units.push(unit);\n }\n });\n // if last PES packet, push samples\n if (endOfSegment && VideoSample) {\n this.pushAccessUnit(VideoSample, track);\n this.VideoSample = null;\n }\n }\n\n protected getNALuType(data: Uint8Array, offset: number): number {\n return data[offset] & 0x1f;\n }\n\n readSliceType(data: Uint8Array) {\n const eg = new ExpGolomb(data);\n // skip NALu type\n eg.readUByte();\n // discard first_mb_in_slice\n eg.readUEG();\n // return slice_type\n return eg.readUEG();\n }\n\n /**\n * The scaling list is optionally transmitted as part of a sequence parameter\n * set and is not relevant to transmuxing.\n * @param count the number of entries in this scaling list\n * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1\n */\n skipScalingList(count: number, reader: ExpGolomb): void {\n let lastScale = 8;\n let nextScale = 8;\n let deltaScale;\n for (let j = 0; j < count; j++) {\n if (nextScale !== 0) {\n deltaScale = reader.readEG();\n nextScale = (lastScale + deltaScale + 256) % 256;\n }\n lastScale = nextScale === 0 ? lastScale : nextScale;\n }\n }\n\n /**\n * Read a sequence parameter set and return some interesting video\n * properties. A sequence parameter set is the H264 metadata that\n * describes the properties of upcoming video frames.\n * @returns an object with configuration parsed from the\n * sequence parameter set, including the dimensions of the\n * associated video frames.\n */\n readSPS(sps: Uint8Array): {\n width: number;\n height: number;\n pixelRatio: [number, number];\n } {\n const eg = new ExpGolomb(sps);\n let frameCropLeftOffset = 0;\n let frameCropRightOffset = 0;\n let frameCropTopOffset = 0;\n let frameCropBottomOffset = 0;\n let numRefFramesInPicOrderCntCycle;\n let scalingListCount;\n let i;\n const readUByte = eg.readUByte.bind(eg);\n const readBits = eg.readBits.bind(eg);\n const readUEG = eg.readUEG.bind(eg);\n const readBoolean = eg.readBoolean.bind(eg);\n const skipBits = eg.skipBits.bind(eg);\n const skipEG = eg.skipEG.bind(eg);\n const skipUEG = eg.skipUEG.bind(eg);\n const skipScalingList = this.skipScalingList.bind(this);\n\n readUByte();\n const profileIdc = readUByte(); // profile_idc\n readBits(5); // profileCompat constraint_set[0-4]_flag, u(5)\n skipBits(3); // reserved_zero_3bits u(3),\n readUByte(); // level_idc u(8)\n skipUEG(); // seq_parameter_set_id\n // some profiles have more optional data we don't need\n if (\n profileIdc === 100 ||\n profileIdc === 110 ||\n profileIdc === 122 ||\n profileIdc === 244 ||\n profileIdc === 44 ||\n profileIdc === 83 ||\n profileIdc === 86 ||\n profileIdc === 118 ||\n profileIdc === 128\n ) {\n const chromaFormatIdc = readUEG();\n if (chromaFormatIdc === 3) {\n skipBits(1);\n } // separate_colour_plane_flag\n\n skipUEG(); // bit_depth_luma_minus8\n skipUEG(); // bit_depth_chroma_minus8\n skipBits(1); // qpprime_y_zero_transform_bypass_flag\n if (readBoolean()) {\n // seq_scaling_matrix_present_flag\n scalingListCount = chromaFormatIdc !== 3 ? 8 : 12;\n for (i = 0; i < scalingListCount; i++) {\n if (readBoolean()) {\n // seq_scaling_list_present_flag[ i ]\n if (i < 6) {\n skipScalingList(16, eg);\n } else {\n skipScalingList(64, eg);\n }\n }\n }\n }\n }\n skipUEG(); // log2_max_frame_num_minus4\n const picOrderCntType = readUEG();\n if (picOrderCntType === 0) {\n readUEG(); // log2_max_pic_order_cnt_lsb_minus4\n } else if (picOrderCntType === 1) {\n skipBits(1); // delta_pic_order_always_zero_flag\n skipEG(); // offset_for_non_ref_pic\n skipEG(); // offset_for_top_to_bottom_field\n numRefFramesInPicOrderCntCycle = readUEG();\n for (i = 0; i < numRefFramesInPicOrderCntCycle; i++) {\n skipEG();\n } // offset_for_ref_frame[ i ]\n }\n skipUEG(); // max_num_ref_frames\n skipBits(1); // gaps_in_frame_num_value_allowed_flag\n const picWidthInMbsMinus1 = readUEG();\n const picHeightInMapUnitsMinus1 = readUEG();\n const frameMbsOnlyFlag = readBits(1);\n if (frameMbsOnlyFlag === 0) {\n skipBits(1);\n } // mb_adaptive_frame_field_flag\n\n skipBits(1); // direct_8x8_inference_flag\n if (readBoolean()) {\n // frame_cropping_flag\n frameCropLeftOffset = readUEG();\n frameCropRightOffset = readUEG();\n frameCropTopOffset = readUEG();\n frameCropBottomOffset = readUEG();\n }\n let pixelRatio: [number, number] = [1, 1];\n if (readBoolean()) {\n // vui_parameters_present_flag\n if (readBoolean()) {\n // aspect_ratio_info_present_flag\n const aspectRatioIdc = readUByte();\n switch (aspectRatioIdc) {\n case 1:\n pixelRatio = [1, 1];\n break;\n case 2:\n pixelRatio = [12, 11];\n break;\n case 3:\n pixelRatio = [10, 11];\n break;\n case 4:\n pixelRatio = [16, 11];\n break;\n case 5:\n pixelRatio = [40, 33];\n break;\n case 6:\n pixelRatio = [24, 11];\n break;\n case 7:\n pixelRatio = [20, 11];\n break;\n case 8:\n pixelRatio = [32, 11];\n break;\n case 9:\n pixelRatio = [80, 33];\n break;\n case 10:\n pixelRatio = [18, 11];\n break;\n case 11:\n pixelRatio = [15, 11];\n break;\n case 12:\n pixelRatio = [64, 33];\n break;\n case 13:\n pixelRatio = [160, 99];\n break;\n case 14:\n pixelRatio = [4, 3];\n break;\n case 15:\n pixelRatio = [3, 2];\n break;\n case 16:\n pixelRatio = [2, 1];\n break;\n case 255: {\n pixelRatio = [\n (readUByte() << 8) | readUByte(),\n (readUByte() << 8) | readUByte(),\n ];\n break;\n }\n }\n }\n }\n return {\n width: Math.ceil(\n (picWidthInMbsMinus1 + 1) * 16 -\n frameCropLeftOffset * 2 -\n frameCropRightOffset * 2,\n ),\n height:\n (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 -\n (frameMbsOnlyFlag ? 2 : 4) *\n (frameCropTopOffset + frameCropBottomOffset),\n pixelRatio: pixelRatio,\n };\n }\n}\n\nexport default AvcVideoParser;\n","import BaseVideoParser from './base-video-parser';\nimport ExpGolomb from './exp-golomb';\nimport { parseSEIMessageFromNALu } from '../../utils/mp4-tools';\nimport type {\n DemuxedUserdataTrack,\n DemuxedVideoTrack,\n} from '../../types/demuxer';\nimport type { ParsedVideoSample } from '../tsdemuxer';\nimport type { PES } from '../tsdemuxer';\n\nclass HevcVideoParser extends BaseVideoParser {\n protected initVPS: Uint8Array | null = null;\n\n public parsePES(\n track: DemuxedVideoTrack,\n textTrack: DemuxedUserdataTrack,\n pes: PES,\n endOfSegment: boolean,\n ) {\n const units = this.parseNALu(track, pes.data, endOfSegment);\n let VideoSample = this.VideoSample;\n let push: boolean;\n let spsfound = false;\n // free pes.data to save up some memory\n (pes as any).data = null;\n\n // if new NAL units found and last sample still there, let's push ...\n // this helps parsing streams with missing AUD (only do this if AUD never found)\n if (VideoSample && units.length && !track.audFound) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = this.VideoSample = this.createVideoSample(\n false,\n pes.pts,\n pes.dts,\n );\n }\n\n units.forEach((unit) => {\n switch (unit.type) {\n // NON-IDR, NON RANDOM ACCESS SLICE\n case 0:\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n case 6:\n case 7:\n case 8:\n case 9:\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n false,\n pes.pts,\n pes.dts,\n );\n }\n VideoSample.frame = true;\n push = true;\n break;\n\n // CRA, BLA (random access picture)\n case 16:\n case 17:\n case 18:\n case 21:\n push = true;\n if (spsfound) {\n // handle PES not starting with AUD\n // if we have frame data already, that cannot belong to the same frame, so force a push\n if (VideoSample?.frame && !VideoSample.key) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = this.VideoSample = null;\n }\n }\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n true,\n pes.pts,\n pes.dts,\n );\n }\n\n VideoSample.key = true;\n VideoSample.frame = true;\n break;\n\n // IDR\n case 19:\n case 20:\n push = true;\n // handle PES not starting with AUD\n // if we have frame data already, that cannot belong to the same frame, so force a push\n if (VideoSample?.frame && !VideoSample.key) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = this.VideoSample = null;\n }\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n true,\n pes.pts,\n pes.dts,\n );\n }\n\n VideoSample.key = true;\n VideoSample.frame = true;\n break;\n\n // SEI\n case 39:\n push = true;\n parseSEIMessageFromNALu(\n unit.data,\n 2, // NALu header size\n pes.pts as number,\n textTrack.samples,\n );\n break;\n\n // VPS\n case 32:\n push = true;\n if (!track.vps) {\n if (typeof track.params !== 'object') {\n track.params = {};\n }\n track.params = Object.assign(track.params, this.readVPS(unit.data));\n this.initVPS = unit.data;\n }\n track.vps = [unit.data];\n break;\n\n // SPS\n case 33:\n push = true;\n spsfound = true;\n if (\n track.vps !== undefined &&\n track.vps[0] !== this.initVPS &&\n track.sps !== undefined &&\n !this.matchSPS(track.sps[0], unit.data)\n ) {\n this.initVPS = track.vps[0];\n track.sps = track.pps = undefined;\n }\n if (!track.sps) {\n const config = this.readSPS(unit.data);\n track.width = config.width;\n track.height = config.height;\n track.pixelRatio = config.pixelRatio;\n track.codec = config.codecString;\n track.sps = [];\n if (typeof track.params !== 'object') {\n track.params = {};\n }\n for (const prop in config.params) {\n track.params[prop] = config.params[prop];\n }\n }\n this.pushParameterSet(track.sps, unit.data, track.vps);\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n true,\n pes.pts,\n pes.dts,\n );\n }\n VideoSample.key = true;\n break;\n\n // PPS\n case 34:\n push = true;\n if (typeof track.params === 'object') {\n if (!track.pps) {\n track.pps = [];\n const config = this.readPPS(unit.data);\n for (const prop in config) {\n track.params[prop] = config[prop];\n }\n }\n this.pushParameterSet(track.pps, unit.data, track.vps);\n }\n break;\n\n // ACCESS UNIT DELIMITER\n case 35:\n push = true;\n track.audFound = true;\n if (VideoSample?.frame) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = null;\n }\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n false,\n pes.pts,\n pes.dts,\n );\n }\n break;\n\n default:\n push = false;\n break;\n }\n if (VideoSample && push) {\n const units = VideoSample.units;\n units.push(unit);\n }\n });\n // if last PES packet, push samples\n if (endOfSegment && VideoSample) {\n this.pushAccessUnit(VideoSample, track);\n this.VideoSample = null;\n }\n }\n\n private pushParameterSet(\n parameterSets: Uint8Array[],\n data: Uint8Array,\n vps: Uint8Array[] | undefined,\n ) {\n if ((vps && vps[0] === this.initVPS) || (!vps && !parameterSets.length)) {\n parameterSets.push(data);\n }\n }\n\n protected getNALuType(data: Uint8Array, offset: number): number {\n return (data[offset] & 0x7e) >>> 1;\n }\n\n protected ebsp2rbsp(arr: Uint8Array): Uint8Array {\n const dst = new Uint8Array(arr.byteLength);\n let dstIdx = 0;\n for (let i = 0; i < arr.byteLength; i++) {\n if (i >= 2) {\n // Unescape: Skip 0x03 after 00 00\n if (arr[i] === 0x03 && arr[i - 1] === 0x00 && arr[i - 2] === 0x00) {\n continue;\n }\n }\n dst[dstIdx] = arr[i];\n dstIdx++;\n }\n return new Uint8Array(dst.buffer, 0, dstIdx);\n }\n\n protected pushAccessUnit(\n VideoSample: ParsedVideoSample,\n videoTrack: DemuxedVideoTrack,\n ) {\n super.pushAccessUnit(VideoSample, videoTrack);\n if (this.initVPS) {\n this.initVPS = null; // null initVPS to prevent possible track's sps/pps growth until next VPS\n }\n }\n\n readVPS(vps: Uint8Array): {\n numTemporalLayers: number;\n temporalIdNested: boolean;\n } {\n const eg = new ExpGolomb(vps);\n // remove header\n eg.readUByte();\n eg.readUByte();\n\n eg.readBits(4); // video_parameter_set_id\n eg.skipBits(2);\n eg.readBits(6); // max_layers_minus1\n const max_sub_layers_minus1 = eg.readBits(3);\n const temporal_id_nesting_flag = eg.readBoolean();\n // ...vui fps can be here, but empty fps value is not critical for metadata\n\n return {\n numTemporalLayers: max_sub_layers_minus1 + 1,\n temporalIdNested: temporal_id_nesting_flag,\n };\n }\n\n readSPS(sps: Uint8Array): {\n codecString: string;\n params: object;\n width: number;\n height: number;\n pixelRatio: [number, number];\n } {\n const eg = new ExpGolomb(this.ebsp2rbsp(sps));\n eg.readUByte();\n eg.readUByte();\n\n eg.readBits(4); //video_parameter_set_id\n const max_sub_layers_minus1 = eg.readBits(3);\n eg.readBoolean(); // temporal_id_nesting_flag\n\n // profile_tier_level\n const general_profile_space = eg.readBits(2);\n const general_tier_flag = eg.readBoolean();\n const general_profile_idc = eg.readBits(5);\n const general_profile_compatibility_flags_1 = eg.readUByte();\n const general_profile_compatibility_flags_2 = eg.readUByte();\n const general_profile_compatibility_flags_3 = eg.readUByte();\n const general_profile_compatibility_flags_4 = eg.readUByte();\n const general_constraint_indicator_flags_1 = eg.readUByte();\n const general_constraint_indicator_flags_2 = eg.readUByte();\n const general_constraint_indicator_flags_3 = eg.readUByte();\n const general_constraint_indicator_flags_4 = eg.readUByte();\n const general_constraint_indicator_flags_5 = eg.readUByte();\n const general_constraint_indicator_flags_6 = eg.readUByte();\n const general_level_idc = eg.readUByte();\n const sub_layer_profile_present_flags: boolean[] = [];\n const sub_layer_level_present_flags: boolean[] = [];\n for (let i = 0; i < max_sub_layers_minus1; i++) {\n sub_layer_profile_present_flags.push(eg.readBoolean());\n sub_layer_level_present_flags.push(eg.readBoolean());\n }\n if (max_sub_layers_minus1 > 0) {\n for (let i = max_sub_layers_minus1; i < 8; i++) {\n eg.readBits(2);\n }\n }\n for (let i = 0; i < max_sub_layers_minus1; i++) {\n if (sub_layer_profile_present_flags[i]) {\n eg.readUByte(); // sub_layer_profile_space, sub_layer_tier_flag, sub_layer_profile_idc\n eg.readUByte();\n eg.readUByte();\n eg.readUByte();\n eg.readUByte(); // sub_layer_profile_compatibility_flag\n eg.readUByte();\n eg.readUByte();\n eg.readUByte();\n eg.readUByte();\n eg.readUByte();\n eg.readUByte();\n }\n if (sub_layer_level_present_flags[i]) {\n eg.readUByte();\n }\n }\n\n eg.readUEG(); // seq_parameter_set_id\n const chroma_format_idc = eg.readUEG();\n if (chroma_format_idc == 3) {\n eg.skipBits(1); //separate_colour_plane_flag\n }\n const pic_width_in_luma_samples = eg.readUEG();\n const pic_height_in_luma_samples = eg.readUEG();\n const conformance_window_flag = eg.readBoolean();\n let pic_left_offset = 0,\n pic_right_offset = 0,\n pic_top_offset = 0,\n pic_bottom_offset = 0;\n if (conformance_window_flag) {\n pic_left_offset += eg.readUEG();\n pic_right_offset += eg.readUEG();\n pic_top_offset += eg.readUEG();\n pic_bottom_offset += eg.readUEG();\n }\n const bit_depth_luma_minus8 = eg.readUEG();\n const bit_depth_chroma_minus8 = eg.readUEG();\n const log2_max_pic_order_cnt_lsb_minus4 = eg.readUEG();\n const sub_layer_ordering_info_present_flag = eg.readBoolean();\n for (\n let i = sub_layer_ordering_info_present_flag ? 0 : max_sub_layers_minus1;\n i <= max_sub_layers_minus1;\n i++\n ) {\n eg.skipUEG(); // max_dec_pic_buffering_minus1[i]\n eg.skipUEG(); // max_num_reorder_pics[i]\n eg.skipUEG(); // max_latency_increase_plus1[i]\n }\n eg.skipUEG(); // log2_min_luma_coding_block_size_minus3\n eg.skipUEG(); // log2_diff_max_min_luma_coding_block_size\n eg.skipUEG(); // log2_min_transform_block_size_minus2\n eg.skipUEG(); // log2_diff_max_min_transform_block_size\n eg.skipUEG(); // max_transform_hierarchy_depth_inter\n eg.skipUEG(); // max_transform_hierarchy_depth_intra\n const scaling_list_enabled_flag = eg.readBoolean();\n if (scaling_list_enabled_flag) {\n const sps_scaling_list_data_present_flag = eg.readBoolean();\n if (sps_scaling_list_data_present_flag) {\n for (let sizeId = 0; sizeId < 4; sizeId++) {\n for (\n let matrixId = 0;\n matrixId < (sizeId === 3 ? 2 : 6);\n matrixId++\n ) {\n const scaling_list_pred_mode_flag = eg.readBoolean();\n if (!scaling_list_pred_mode_flag) {\n eg.readUEG(); // scaling_list_pred_matrix_id_delta\n } else {\n const coefNum = Math.min(64, 1 << (4 + (sizeId << 1)));\n if (sizeId > 1) {\n eg.readEG();\n }\n for (let i = 0; i < coefNum; i++) {\n eg.readEG();\n }\n }\n }\n }\n }\n }\n\n eg.readBoolean(); // amp_enabled_flag\n eg.readBoolean(); // sample_adaptive_offset_enabled_flag\n const pcm_enabled_flag = eg.readBoolean();\n if (pcm_enabled_flag) {\n eg.readUByte();\n eg.skipUEG();\n eg.skipUEG();\n eg.readBoolean();\n }\n const num_short_term_ref_pic_sets = eg.readUEG();\n let num_delta_pocs = 0;\n for (let i = 0; i < num_short_term_ref_pic_sets; i++) {\n let inter_ref_pic_set_prediction_flag = false;\n if (i !== 0) {\n inter_ref_pic_set_prediction_flag = eg.readBoolean();\n }\n if (inter_ref_pic_set_prediction_flag) {\n if (i === num_short_term_ref_pic_sets) {\n eg.readUEG();\n }\n eg.readBoolean();\n eg.readUEG();\n let next_num_delta_pocs = 0;\n for (let j = 0; j <= num_delta_pocs; j++) {\n const used_by_curr_pic_flag = eg.readBoolean();\n let use_delta_flag = false;\n if (!used_by_curr_pic_flag) {\n use_delta_flag = eg.readBoolean();\n }\n if (used_by_curr_pic_flag || use_delta_flag) {\n next_num_delta_pocs++;\n }\n }\n num_delta_pocs = next_num_delta_pocs;\n } else {\n const num_negative_pics = eg.readUEG();\n const num_positive_pics = eg.readUEG();\n num_delta_pocs = num_negative_pics + num_positive_pics;\n for (let j = 0; j < num_negative_pics; j++) {\n eg.readUEG();\n eg.readBoolean();\n }\n for (let j = 0; j < num_positive_pics; j++) {\n eg.readUEG();\n eg.readBoolean();\n }\n }\n }\n\n const long_term_ref_pics_present_flag = eg.readBoolean();\n if (long_term_ref_pics_present_flag) {\n const num_long_term_ref_pics_sps = eg.readUEG();\n for (let i = 0; i < num_long_term_ref_pics_sps; i++) {\n for (let j = 0; j < log2_max_pic_order_cnt_lsb_minus4 + 4; j++) {\n eg.readBits(1);\n }\n eg.readBits(1);\n }\n }\n\n let min_spatial_segmentation_idc = 0;\n let sar_width = 1,\n sar_height = 1;\n let fps_fixed = true,\n fps_den = 1,\n fps_num = 0;\n eg.readBoolean(); // sps_temporal_mvp_enabled_flag\n eg.readBoolean(); // strong_intra_smoothing_enabled_flag\n let default_display_window_flag = false;\n const vui_parameters_present_flag = eg.readBoolean();\n if (vui_parameters_present_flag) {\n const aspect_ratio_info_present_flag = eg.readBoolean();\n if (aspect_ratio_info_present_flag) {\n const aspect_ratio_idc = eg.readUByte();\n const sar_width_table = [\n 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2,\n ];\n const sar_height_table = [\n 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1,\n ];\n if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {\n sar_width = sar_width_table[aspect_ratio_idc - 1];\n sar_height = sar_height_table[aspect_ratio_idc - 1];\n } else if (aspect_ratio_idc === 255) {\n sar_width = eg.readBits(16);\n sar_height = eg.readBits(16);\n }\n }\n const overscan_info_present_flag = eg.readBoolean();\n if (overscan_info_present_flag) {\n eg.readBoolean();\n }\n const video_signal_type_present_flag = eg.readBoolean();\n if (video_signal_type_present_flag) {\n eg.readBits(3);\n eg.readBoolean();\n const colour_description_present_flag = eg.readBoolean();\n if (colour_description_present_flag) {\n eg.readUByte();\n eg.readUByte();\n eg.readUByte();\n }\n }\n const chroma_loc_info_present_flag = eg.readBoolean();\n if (chroma_loc_info_present_flag) {\n eg.readUEG();\n eg.readUEG();\n }\n eg.readBoolean(); // neutral_chroma_indication_flag\n eg.readBoolean(); // field_seq_flag\n eg.readBoolean(); // frame_field_info_present_flag\n default_display_window_flag = eg.readBoolean();\n if (default_display_window_flag) {\n pic_left_offset += eg.readUEG();\n pic_right_offset += eg.readUEG();\n pic_top_offset += eg.readUEG();\n pic_bottom_offset += eg.readUEG();\n }\n const vui_timing_info_present_flag = eg.readBoolean();\n if (vui_timing_info_present_flag) {\n fps_den = eg.readBits(32);\n fps_num = eg.readBits(32);\n const vui_poc_proportional_to_timing_flag = eg.readBoolean();\n if (vui_poc_proportional_to_timing_flag) {\n eg.readUEG();\n }\n const vui_hrd_parameters_present_flag = eg.readBoolean();\n if (vui_hrd_parameters_present_flag) {\n //const commonInfPresentFlag = true;\n //if (commonInfPresentFlag) {\n const nal_hrd_parameters_present_flag = eg.readBoolean();\n const vcl_hrd_parameters_present_flag = eg.readBoolean();\n let sub_pic_hrd_params_present_flag = false;\n if (\n nal_hrd_parameters_present_flag ||\n vcl_hrd_parameters_present_flag\n ) {\n sub_pic_hrd_params_present_flag = eg.readBoolean();\n if (sub_pic_hrd_params_present_flag) {\n eg.readUByte();\n eg.readBits(5);\n eg.readBoolean();\n eg.readBits(5);\n }\n eg.readBits(4); // bit_rate_scale\n eg.readBits(4); // cpb_size_scale\n if (sub_pic_hrd_params_present_flag) {\n eg.readBits(4);\n }\n eg.readBits(5);\n eg.readBits(5);\n eg.readBits(5);\n }\n //}\n for (let i = 0; i <= max_sub_layers_minus1; i++) {\n fps_fixed = eg.readBoolean(); // fixed_pic_rate_general_flag\n const fixed_pic_rate_within_cvs_flag =\n fps_fixed || eg.readBoolean();\n let low_delay_hrd_flag = false;\n if (fixed_pic_rate_within_cvs_flag) {\n eg.readEG();\n } else {\n low_delay_hrd_flag = eg.readBoolean();\n }\n const cpb_cnt = low_delay_hrd_flag ? 1 : eg.readUEG() + 1;\n if (nal_hrd_parameters_present_flag) {\n for (let j = 0; j < cpb_cnt; j++) {\n eg.readUEG();\n eg.readUEG();\n if (sub_pic_hrd_params_present_flag) {\n eg.readUEG();\n eg.readUEG();\n }\n eg.skipBits(1);\n }\n }\n if (vcl_hrd_parameters_present_flag) {\n for (let j = 0; j < cpb_cnt; j++) {\n eg.readUEG();\n eg.readUEG();\n if (sub_pic_hrd_params_present_flag) {\n eg.readUEG();\n eg.readUEG();\n }\n eg.skipBits(1);\n }\n }\n }\n }\n }\n const bitstream_restriction_flag = eg.readBoolean();\n if (bitstream_restriction_flag) {\n eg.readBoolean(); // tiles_fixed_structure_flag\n eg.readBoolean(); // motion_vectors_over_pic_boundaries_flag\n eg.readBoolean(); // restricted_ref_pic_lists_flag\n min_spatial_segmentation_idc = eg.readUEG();\n }\n }\n\n let width = pic_width_in_luma_samples,\n height = pic_height_in_luma_samples;\n if (conformance_window_flag || default_display_window_flag) {\n let chroma_scale_w = 1,\n chroma_scale_h = 1;\n if (chroma_format_idc === 1) {\n // YUV 420\n chroma_scale_w = chroma_scale_h = 2;\n } else if (chroma_format_idc == 2) {\n // YUV 422\n chroma_scale_w = 2;\n }\n width =\n pic_width_in_luma_samples -\n chroma_scale_w * pic_right_offset -\n chroma_scale_w * pic_left_offset;\n height =\n pic_height_in_luma_samples -\n chroma_scale_h * pic_bottom_offset -\n chroma_scale_h * pic_top_offset;\n }\n\n const profile_space_string = general_profile_space\n ? ['A', 'B', 'C'][general_profile_space]\n : '';\n const profile_compatibility_buf =\n (general_profile_compatibility_flags_1 << 24) |\n (general_profile_compatibility_flags_2 << 16) |\n (general_profile_compatibility_flags_3 << 8) |\n general_profile_compatibility_flags_4;\n let profile_compatibility_rev = 0;\n for (let i = 0; i < 32; i++) {\n profile_compatibility_rev =\n (profile_compatibility_rev |\n (((profile_compatibility_buf >> i) & 1) << (31 - i))) >>>\n 0; // reverse bit position (and cast as UInt32)\n }\n let profile_compatibility_flags_string =\n profile_compatibility_rev.toString(16);\n if (\n general_profile_idc === 1 &&\n profile_compatibility_flags_string === '2'\n ) {\n profile_compatibility_flags_string = '6';\n }\n const tier_flag_string = general_tier_flag ? 'H' : 'L';\n\n return {\n codecString: `hvc1.${profile_space_string}${general_profile_idc}.${profile_compatibility_flags_string}.${tier_flag_string}${general_level_idc}.B0`,\n params: {\n general_tier_flag,\n general_profile_idc,\n general_profile_space,\n general_profile_compatibility_flags: [\n general_profile_compatibility_flags_1,\n general_profile_compatibility_flags_2,\n general_profile_compatibility_flags_3,\n general_profile_compatibility_flags_4,\n ],\n general_constraint_indicator_flags: [\n general_constraint_indicator_flags_1,\n general_constraint_indicator_flags_2,\n general_constraint_indicator_flags_3,\n general_constraint_indicator_flags_4,\n general_constraint_indicator_flags_5,\n general_constraint_indicator_flags_6,\n ],\n general_level_idc,\n bit_depth: bit_depth_luma_minus8 + 8,\n bit_depth_luma_minus8,\n bit_depth_chroma_minus8,\n min_spatial_segmentation_idc,\n chroma_format_idc: chroma_format_idc,\n frame_rate: {\n fixed: fps_fixed,\n fps: fps_num / fps_den,\n },\n },\n width,\n height,\n pixelRatio: [sar_width, sar_height],\n };\n }\n\n readPPS(pps: Uint8Array): {\n parallelismType: number;\n } {\n const eg = new ExpGolomb(this.ebsp2rbsp(pps));\n eg.readUByte();\n eg.readUByte();\n eg.skipUEG(); // pic_parameter_set_id\n eg.skipUEG(); // seq_parameter_set_id\n eg.skipBits(2); // dependent_slice_segments_enabled_flag, output_flag_present_flag\n eg.skipBits(3); // num_extra_slice_header_bits\n eg.skipBits(2); // sign_data_hiding_enabled_flag, cabac_init_present_flag\n eg.skipUEG();\n eg.skipUEG();\n eg.skipEG(); // init_qp_minus26\n eg.skipBits(2); // constrained_intra_pred_flag, transform_skip_enabled_flag\n const cu_qp_delta_enabled_flag = eg.readBoolean();\n if (cu_qp_delta_enabled_flag) {\n eg.skipUEG();\n }\n eg.skipEG(); // cb_qp_offset\n eg.skipEG(); // cr_qp_offset\n eg.skipBits(4); // pps_slice_chroma_qp_offsets_present_flag, weighted_pred_flag, weighted_bipred_flag, transquant_bypass_enabled_flag\n const tiles_enabled_flag = eg.readBoolean();\n const entropy_coding_sync_enabled_flag = eg.readBoolean();\n let parallelismType = 1; // slice-based parallel decoding\n if (entropy_coding_sync_enabled_flag && tiles_enabled_flag) {\n parallelismType = 0; // mixed-type parallel decoding\n } else if (entropy_coding_sync_enabled_flag) {\n parallelismType = 3; // wavefront-based parallel decoding\n } else if (tiles_enabled_flag) {\n parallelismType = 2; // tile-based parallel decoding\n }\n\n return {\n parallelismType,\n };\n }\n\n matchSPS(sps1: Uint8Array, sps2: Uint8Array): boolean {\n // compare without headers and VPS related params\n return (\n String.fromCharCode.apply(null, sps1).substr(3) ===\n String.fromCharCode.apply(null, sps2).substr(3)\n );\n }\n}\n\nexport default HevcVideoParser;\n","/**\n * highly optimized TS demuxer:\n * parse PAT, PMT\n * extract PES packet from audio and video PIDs\n * extract AVC/H264 (or HEVC/H265) NAL units and AAC/ADTS samples from PES packet\n * trigger the remuxer upon parsing completion\n * it also tries to workaround as best as it can audio codec switch (HE-AAC to AAC and vice versa), without having to restart the MediaSource.\n * it also controls the remuxing process :\n * upon discontinuity or level switch detection, it will also notifies the remuxer so that it can reset its state.\n */\n\nimport * as AC3 from './audio/ac3-demuxer';\nimport * as ADTS from './audio/adts';\nimport * as MpegAudio from './audio/mpegaudio';\nimport SampleAesDecrypter from './sample-aes';\nimport AvcVideoParser from './video/avc-video-parser';\nimport HevcVideoParser from './video/hevc-video-parser';\nimport { ErrorDetails, ErrorTypes } from '../errors';\nimport { Events } from '../events';\nimport {\n type DemuxedAudioTrack,\n type DemuxedMetadataTrack,\n type DemuxedTrack,\n type DemuxedUserdataTrack,\n type DemuxedVideoTrack,\n type Demuxer,\n type DemuxerResult,\n type ElementaryStreamData,\n type KeyData,\n MetadataSchema,\n type VideoSample,\n} from '../types/demuxer';\nimport { appendUint8Array, RemuxerTrackIdConfig } from '../utils/mp4-tools';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport type BaseVideoParser from './video/base-video-parser';\nimport type { AudioFrame } from '../types/demuxer';\nimport type { TypeSupported } from '../utils/codecs';\nimport type { ILogger } from '../utils/logger';\n\nexport type ParsedTimestamp = {\n pts?: number;\n dts?: number;\n};\n\nexport type PES = ParsedTimestamp & {\n data: Uint8Array;\n len: number;\n};\n\nexport type ParsedVideoSample = ParsedTimestamp &\n Omit<VideoSample, 'pts' | 'dts'>;\n\nconst PACKET_LENGTH = 188;\n\nclass TSDemuxer implements Demuxer {\n private readonly logger: ILogger;\n private readonly observer: HlsEventEmitter;\n private readonly config: HlsConfig;\n private readonly typeSupported: TypeSupported;\n\n private sampleAes: SampleAesDecrypter | null = null;\n private pmtParsed: boolean = false;\n private audioCodec?: string;\n private videoCodec?: string;\n private _pmtId: number = -1;\n\n private _videoTrack?: DemuxedVideoTrack;\n private _audioTrack?: DemuxedAudioTrack;\n private _id3Track?: DemuxedMetadataTrack;\n private _txtTrack?: DemuxedUserdataTrack;\n private aacOverFlow: AudioFrame | null = null;\n private remainderData: Uint8Array | null = null;\n private videoParser: BaseVideoParser | null;\n\n constructor(\n observer: HlsEventEmitter,\n config: HlsConfig,\n typeSupported: TypeSupported,\n logger: ILogger,\n ) {\n this.observer = observer;\n this.config = config;\n this.typeSupported = typeSupported;\n this.logger = logger;\n this.videoParser = null;\n }\n\n static probe(data: Uint8Array, logger: ILogger) {\n const syncOffset = TSDemuxer.syncOffset(data);\n if (syncOffset > 0) {\n logger.warn(\n `MPEG2-TS detected but first sync word found @ offset ${syncOffset}`,\n );\n }\n return syncOffset !== -1;\n }\n\n static syncOffset(data: Uint8Array): number {\n const length = data.length;\n let scanwindow = Math.min(PACKET_LENGTH * 5, length - PACKET_LENGTH) + 1;\n let i = 0;\n while (i < scanwindow) {\n // a TS init segment should contain at least 2 TS packets: PAT and PMT, each starting with 0x47\n let foundPat = false;\n let packetStart = -1;\n let tsPackets = 0;\n for (let j = i; j < length; j += PACKET_LENGTH) {\n if (\n data[j] === 0x47 &&\n (length - j === PACKET_LENGTH || data[j + PACKET_LENGTH] === 0x47)\n ) {\n tsPackets++;\n if (packetStart === -1) {\n packetStart = j;\n // First sync word found at offset, increase scan length (#5251)\n if (packetStart !== 0) {\n scanwindow =\n Math.min(\n packetStart + PACKET_LENGTH * 99,\n data.length - PACKET_LENGTH,\n ) + 1;\n }\n }\n if (!foundPat) {\n foundPat = parsePID(data, j) === 0;\n }\n // Sync word found at 0 with 3 packets, or found at offset least 2 packets up to scanwindow (#5501)\n if (\n foundPat &&\n tsPackets > 1 &&\n ((packetStart === 0 && tsPackets > 2) ||\n j + PACKET_LENGTH > scanwindow)\n ) {\n return packetStart;\n }\n } else if (tsPackets) {\n // Exit if sync word found, but does not contain contiguous packets\n return -1;\n } else {\n break;\n }\n }\n i++;\n }\n return -1;\n }\n\n /**\n * Creates a track model internal to demuxer used to drive remuxing input\n */\n static createTrack(\n type: 'audio' | 'video' | 'id3' | 'text',\n duration?: number,\n ): DemuxedTrack {\n return {\n container:\n type === 'video' || type === 'audio' ? 'video/mp2t' : undefined,\n type,\n id: RemuxerTrackIdConfig[type],\n pid: -1,\n inputTimeScale: 90000,\n sequenceNumber: 0,\n samples: [],\n dropped: 0,\n duration: type === 'audio' ? duration : undefined,\n };\n }\n\n /**\n * Initializes a new init segment on the demuxer/remuxer interface. Needed for discontinuities/track-switches (or at stream start)\n * Resets all internal track instances of the demuxer.\n */\n public resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string,\n videoCodec: string,\n trackDuration: number,\n ) {\n this.pmtParsed = false;\n this._pmtId = -1;\n\n this._videoTrack = TSDemuxer.createTrack('video') as DemuxedVideoTrack;\n this._videoTrack.duration = trackDuration;\n this._audioTrack = TSDemuxer.createTrack(\n 'audio',\n trackDuration,\n ) as DemuxedAudioTrack;\n this._id3Track = TSDemuxer.createTrack('id3') as DemuxedMetadataTrack;\n this._txtTrack = TSDemuxer.createTrack('text') as DemuxedUserdataTrack;\n this._audioTrack.segmentCodec = 'aac';\n\n // flush any partial content\n this.aacOverFlow = null;\n this.remainderData = null;\n this.audioCodec = audioCodec;\n this.videoCodec = videoCodec;\n }\n\n public resetTimeStamp() {}\n\n public resetContiguity(): void {\n const { _audioTrack, _videoTrack, _id3Track } = this;\n if (_audioTrack) {\n _audioTrack.pesData = null;\n }\n if (_videoTrack) {\n _videoTrack.pesData = null;\n }\n if (_id3Track) {\n _id3Track.pesData = null;\n }\n this.aacOverFlow = null;\n this.remainderData = null;\n }\n\n public demux(\n data: Uint8Array,\n timeOffset: number,\n isSampleAes = false,\n flush = false,\n ): DemuxerResult {\n if (!isSampleAes) {\n this.sampleAes = null;\n }\n\n let pes: PES | null;\n\n const videoTrack = this._videoTrack as DemuxedVideoTrack;\n const audioTrack = this._audioTrack as DemuxedAudioTrack;\n const id3Track = this._id3Track as DemuxedMetadataTrack;\n const textTrack = this._txtTrack as DemuxedUserdataTrack;\n\n let videoPid = videoTrack.pid;\n let videoData = videoTrack.pesData;\n let audioPid = audioTrack.pid;\n let id3Pid = id3Track.pid;\n let audioData = audioTrack.pesData;\n let id3Data = id3Track.pesData;\n let unknownPID: number | null = null;\n let pmtParsed = this.pmtParsed;\n let pmtId = this._pmtId;\n\n let len = data.length;\n if (this.remainderData) {\n data = appendUint8Array(this.remainderData, data);\n len = data.length;\n this.remainderData = null;\n }\n\n if (len < PACKET_LENGTH && !flush) {\n this.remainderData = data;\n return {\n audioTrack,\n videoTrack,\n id3Track,\n textTrack,\n };\n }\n\n const syncOffset = Math.max(0, TSDemuxer.syncOffset(data));\n len -= (len - syncOffset) % PACKET_LENGTH;\n if (len < data.byteLength && !flush) {\n this.remainderData = new Uint8Array(\n data.buffer,\n len,\n data.buffer.byteLength - len,\n );\n }\n\n // loop through TS packets\n let tsPacketErrors = 0;\n for (let start = syncOffset; start < len; start += PACKET_LENGTH) {\n if (data[start] === 0x47) {\n const stt = !!(data[start + 1] & 0x40);\n const pid = parsePID(data, start);\n const atf = (data[start + 3] & 0x30) >> 4;\n\n // if an adaption field is present, its length is specified by the fifth byte of the TS packet header.\n let offset: number;\n if (atf > 1) {\n offset = start + 5 + data[start + 4];\n // continue if there is only adaptation field\n if (offset === start + PACKET_LENGTH) {\n continue;\n }\n } else {\n offset = start + 4;\n }\n switch (pid) {\n case videoPid:\n if (stt) {\n if (videoData && (pes = parsePES(videoData, this.logger))) {\n if (this.videoParser === null) {\n switch (videoTrack.segmentCodec) {\n case 'avc':\n this.videoParser = new AvcVideoParser();\n break;\n case 'hevc':\n if (__USE_M2TS_ADVANCED_CODECS__) {\n this.videoParser = new HevcVideoParser();\n }\n break;\n }\n }\n if (this.videoParser !== null) {\n this.videoParser.parsePES(videoTrack, textTrack, pes, false);\n }\n }\n\n videoData = { data: [], size: 0 };\n }\n if (videoData) {\n videoData.data.push(data.subarray(offset, start + PACKET_LENGTH));\n videoData.size += start + PACKET_LENGTH - offset;\n }\n break;\n case audioPid:\n if (stt) {\n if (audioData && (pes = parsePES(audioData, this.logger))) {\n switch (audioTrack.segmentCodec) {\n case 'aac':\n this.parseAACPES(audioTrack, pes);\n break;\n case 'mp3':\n this.parseMPEGPES(audioTrack, pes);\n break;\n case 'ac3':\n if (__USE_M2TS_ADVANCED_CODECS__) {\n this.parseAC3PES(audioTrack, pes);\n }\n break;\n }\n }\n audioData = { data: [], size: 0 };\n }\n if (audioData) {\n audioData.data.push(data.subarray(offset, start + PACKET_LENGTH));\n audioData.size += start + PACKET_LENGTH - offset;\n }\n break;\n case id3Pid:\n if (stt) {\n if (id3Data && (pes = parsePES(id3Data, this.logger))) {\n this.parseID3PES(id3Track, pes);\n }\n\n id3Data = { data: [], size: 0 };\n }\n if (id3Data) {\n id3Data.data.push(data.subarray(offset, start + PACKET_LENGTH));\n id3Data.size += start + PACKET_LENGTH - offset;\n }\n break;\n case 0:\n if (stt) {\n offset += data[offset] + 1;\n }\n\n pmtId = this._pmtId = parsePAT(data, offset);\n // this.logger.log('PMT PID:' + this._pmtId);\n break;\n case pmtId: {\n if (stt) {\n offset += data[offset] + 1;\n }\n\n const parsedPIDs = parsePMT(\n data,\n offset,\n this.typeSupported,\n isSampleAes,\n this.observer,\n this.logger,\n );\n\n // only update track id if track PID found while parsing PMT\n // this is to avoid resetting the PID to -1 in case\n // track PID transiently disappears from the stream\n // this could happen in case of transient missing audio samples for example\n // NOTE this is only the PID of the track as found in TS,\n // but we are not using this for MP4 track IDs.\n videoPid = parsedPIDs.videoPid;\n if (videoPid > 0) {\n videoTrack.pid = videoPid;\n videoTrack.segmentCodec = parsedPIDs.segmentVideoCodec;\n }\n\n audioPid = parsedPIDs.audioPid;\n if (audioPid > 0) {\n audioTrack.pid = audioPid;\n audioTrack.segmentCodec = parsedPIDs.segmentAudioCodec;\n }\n id3Pid = parsedPIDs.id3Pid;\n if (id3Pid > 0) {\n id3Track.pid = id3Pid;\n }\n\n if (unknownPID !== null && !pmtParsed) {\n this.logger.warn(\n `MPEG-TS PMT found at ${start} after unknown PID '${unknownPID}'. Backtracking to sync byte @${syncOffset} to parse all TS packets.`,\n );\n unknownPID = null;\n // we set it to -188, the += 188 in the for loop will reset start to 0\n start = syncOffset - 188;\n }\n pmtParsed = this.pmtParsed = true;\n break;\n }\n case 0x11:\n case 0x1fff:\n break;\n default:\n unknownPID = pid;\n break;\n }\n } else {\n tsPacketErrors++;\n }\n }\n\n if (tsPacketErrors > 0) {\n emitParsingError(\n this.observer,\n new Error(\n `Found ${tsPacketErrors} TS packet/s that do not start with 0x47`,\n ),\n undefined,\n this.logger,\n );\n }\n\n videoTrack.pesData = videoData;\n audioTrack.pesData = audioData;\n id3Track.pesData = id3Data;\n\n const demuxResult: DemuxerResult = {\n audioTrack,\n videoTrack,\n id3Track,\n textTrack,\n };\n\n if (flush) {\n this.extractRemainingSamples(demuxResult);\n }\n\n return demuxResult;\n }\n\n public flush(): DemuxerResult | Promise<DemuxerResult> {\n const { remainderData } = this;\n this.remainderData = null;\n let result: DemuxerResult;\n if (remainderData) {\n result = this.demux(remainderData, -1, false, true);\n } else {\n result = {\n videoTrack: this._videoTrack as DemuxedVideoTrack,\n audioTrack: this._audioTrack as DemuxedAudioTrack,\n id3Track: this._id3Track as DemuxedMetadataTrack,\n textTrack: this._txtTrack as DemuxedUserdataTrack,\n };\n }\n this.extractRemainingSamples(result);\n if (this.sampleAes) {\n return this.decrypt(result, this.sampleAes);\n }\n return result;\n }\n\n private extractRemainingSamples(demuxResult: DemuxerResult) {\n const { audioTrack, videoTrack, id3Track, textTrack } = demuxResult;\n const videoData = videoTrack.pesData;\n const audioData = audioTrack.pesData;\n const id3Data = id3Track.pesData;\n // try to parse last PES packets\n let pes: PES | null;\n if (videoData && (pes = parsePES(videoData, this.logger))) {\n if (this.videoParser === null) {\n switch (videoTrack.segmentCodec) {\n case 'avc':\n this.videoParser = new AvcVideoParser();\n break;\n case 'hevc':\n if (__USE_M2TS_ADVANCED_CODECS__) {\n this.videoParser = new HevcVideoParser();\n }\n break;\n }\n }\n if (this.videoParser !== null) {\n this.videoParser.parsePES(\n videoTrack as DemuxedVideoTrack,\n textTrack as DemuxedUserdataTrack,\n pes,\n true,\n );\n videoTrack.pesData = null;\n }\n } else {\n // either avcData null or PES truncated, keep it for next frag parsing\n videoTrack.pesData = videoData;\n }\n\n if (audioData && (pes = parsePES(audioData, this.logger))) {\n switch (audioTrack.segmentCodec) {\n case 'aac':\n this.parseAACPES(audioTrack, pes);\n break;\n case 'mp3':\n this.parseMPEGPES(audioTrack, pes);\n break;\n case 'ac3':\n if (__USE_M2TS_ADVANCED_CODECS__) {\n this.parseAC3PES(audioTrack, pes);\n }\n break;\n }\n audioTrack.pesData = null;\n } else {\n if (audioData?.size) {\n this.logger.log(\n 'last AAC PES packet truncated,might overlap between fragments',\n );\n }\n\n // either audioData null or PES truncated, keep it for next frag parsing\n audioTrack.pesData = audioData;\n }\n\n if (id3Data && (pes = parsePES(id3Data, this.logger))) {\n this.parseID3PES(id3Track, pes);\n id3Track.pesData = null;\n } else {\n // either id3Data null or PES truncated, keep it for next frag parsing\n id3Track.pesData = id3Data;\n }\n }\n\n public demuxSampleAes(\n data: Uint8Array,\n keyData: KeyData,\n timeOffset: number,\n ): Promise<DemuxerResult> {\n const demuxResult = this.demux(\n data,\n timeOffset,\n true,\n !this.config.progressive,\n );\n const sampleAes = (this.sampleAes = new SampleAesDecrypter(\n this.observer,\n this.config,\n keyData,\n ));\n return this.decrypt(demuxResult, sampleAes);\n }\n\n private decrypt(\n demuxResult: DemuxerResult,\n sampleAes: SampleAesDecrypter,\n ): Promise<DemuxerResult> {\n return new Promise((resolve) => {\n const { audioTrack, videoTrack } = demuxResult;\n if (audioTrack.samples && audioTrack.segmentCodec === 'aac') {\n sampleAes.decryptAacSamples(audioTrack.samples, 0, () => {\n if (videoTrack.samples) {\n sampleAes.decryptAvcSamples(videoTrack.samples, 0, 0, () => {\n resolve(demuxResult);\n });\n } else {\n resolve(demuxResult);\n }\n });\n } else if (videoTrack.samples) {\n sampleAes.decryptAvcSamples(videoTrack.samples, 0, 0, () => {\n resolve(demuxResult);\n });\n }\n });\n }\n\n public destroy() {\n if (this.observer) {\n this.observer.removeAllListeners();\n }\n // @ts-ignore\n this.config = this.logger = this.observer = null;\n this.aacOverFlow =\n this.videoParser =\n this.remainderData =\n this.sampleAes =\n null;\n this._videoTrack =\n this._audioTrack =\n this._id3Track =\n this._txtTrack =\n undefined;\n }\n\n private parseAACPES(track: DemuxedAudioTrack, pes: PES) {\n let startOffset = 0;\n const aacOverFlow = this.aacOverFlow;\n let data = pes.data;\n if (aacOverFlow) {\n this.aacOverFlow = null;\n const frameMissingBytes = aacOverFlow.missing;\n const sampleLength = aacOverFlow.sample.unit.byteLength;\n // logger.log(`AAC: append overflowing ${sampleLength} bytes to beginning of new PES`);\n if (frameMissingBytes === -1) {\n data = appendUint8Array(aacOverFlow.sample.unit, data);\n } else {\n const frameOverflowBytes = sampleLength - frameMissingBytes;\n aacOverFlow.sample.unit.set(\n data.subarray(0, frameMissingBytes),\n frameOverflowBytes,\n );\n track.samples.push(aacOverFlow.sample);\n startOffset = aacOverFlow.missing;\n }\n }\n // look for ADTS header (0xFFFx)\n let offset: number;\n let len: number;\n for (offset = startOffset, len = data.length; offset < len - 1; offset++) {\n if (ADTS.isHeader(data, offset)) {\n break;\n }\n }\n // if ADTS header does not start straight from the beginning of the PES payload, raise an error\n if (offset !== startOffset) {\n let reason: string;\n const recoverable = offset < len - 1;\n if (recoverable) {\n reason = `AAC PES did not start with ADTS header,offset:${offset}`;\n } else {\n reason = 'No ADTS header found in AAC PES';\n }\n emitParsingError(\n this.observer,\n new Error(reason),\n recoverable,\n this.logger,\n );\n if (!recoverable) {\n return;\n }\n }\n\n ADTS.initTrackConfig(track, this.observer, data, offset, this.audioCodec);\n\n let pts: number;\n if (pes.pts !== undefined) {\n pts = pes.pts;\n } else if (aacOverFlow) {\n // if last AAC frame is overflowing, we should ensure timestamps are contiguous:\n // first sample PTS should be equal to last sample PTS + frameDuration\n const frameDuration = ADTS.getFrameDuration(track.samplerate as number);\n pts = aacOverFlow.sample.pts + frameDuration;\n } else {\n this.logger.warn('[tsdemuxer]: AAC PES unknown PTS');\n return;\n }\n\n // scan for aac samples\n let frameIndex = 0;\n let frame;\n while (offset < len) {\n frame = ADTS.appendFrame(track, data, offset, pts, frameIndex);\n offset += frame.length;\n if (!frame.missing) {\n frameIndex++;\n for (; offset < len - 1; offset++) {\n if (ADTS.isHeader(data, offset)) {\n break;\n }\n }\n } else {\n this.aacOverFlow = frame;\n break;\n }\n }\n }\n\n private parseMPEGPES(track: DemuxedAudioTrack, pes: PES) {\n const data = pes.data;\n const length = data.length;\n let frameIndex = 0;\n let offset = 0;\n const pts = pes.pts;\n if (pts === undefined) {\n this.logger.warn('[tsdemuxer]: MPEG PES unknown PTS');\n return;\n }\n\n while (offset < length) {\n if (MpegAudio.isHeader(data, offset)) {\n const frame = MpegAudio.appendFrame(\n track,\n data,\n offset,\n pts,\n frameIndex,\n );\n if (frame) {\n offset += frame.length;\n frameIndex++;\n } else {\n // logger.log('Unable to parse Mpeg audio frame');\n break;\n }\n } else {\n // nothing found, keep looking\n offset++;\n }\n }\n }\n\n private parseAC3PES(track: DemuxedAudioTrack, pes: PES) {\n if (__USE_M2TS_ADVANCED_CODECS__) {\n const data = pes.data;\n const pts = pes.pts;\n if (pts === undefined) {\n this.logger.warn('[tsdemuxer]: AC3 PES unknown PTS');\n return;\n }\n const length = data.length;\n let frameIndex = 0;\n let offset = 0;\n let parsed;\n\n while (\n offset < length &&\n (parsed = AC3.appendFrame(track, data, offset, pts, frameIndex++)) > 0\n ) {\n offset += parsed;\n }\n }\n }\n\n private parseID3PES(id3Track: DemuxedMetadataTrack, pes: PES) {\n if (pes.pts === undefined) {\n this.logger.warn('[tsdemuxer]: ID3 PES unknown PTS');\n return;\n }\n const id3Sample = Object.assign({}, pes as Required<PES>, {\n type: this._videoTrack ? MetadataSchema.emsg : MetadataSchema.audioId3,\n duration: Number.POSITIVE_INFINITY,\n });\n id3Track.samples.push(id3Sample);\n }\n}\n\nfunction parsePID(data: Uint8Array, offset: number): number {\n // pid is a 13-bit field starting at the last bit of TS[1]\n return ((data[offset + 1] & 0x1f) << 8) + data[offset + 2];\n}\n\nfunction parsePAT(data: Uint8Array, offset: number): number {\n // skip the PSI header and parse the first PMT entry\n return ((data[offset + 10] & 0x1f) << 8) | data[offset + 11];\n}\n\nfunction parsePMT(\n data: Uint8Array,\n offset: number,\n typeSupported: TypeSupported,\n isSampleAes: boolean,\n observer: HlsEventEmitter,\n logger: ILogger,\n) {\n const result = {\n audioPid: -1,\n videoPid: -1,\n id3Pid: -1,\n segmentVideoCodec: 'avc' as 'avc' | 'hevc',\n segmentAudioCodec: 'aac' as 'aac' | 'ac3' | 'mp3',\n };\n const sectionLength = ((data[offset + 1] & 0x0f) << 8) | data[offset + 2];\n const tableEnd = offset + 3 + sectionLength - 4;\n // to determine where the table is, we have to figure out how\n // long the program info descriptors are\n const programInfoLength =\n ((data[offset + 10] & 0x0f) << 8) | data[offset + 11];\n // advance the offset to the first entry in the mapping table\n offset += 12 + programInfoLength;\n while (offset < tableEnd) {\n const pid = parsePID(data, offset);\n const esInfoLength = ((data[offset + 3] & 0x0f) << 8) | data[offset + 4];\n switch (data[offset]) {\n case 0xcf: // SAMPLE-AES AAC\n if (!isSampleAes) {\n logEncryptedSamplesFoundInUnencryptedStream('ADTS AAC', logger);\n break;\n }\n /* falls through */\n case 0x0f: // ISO/IEC 13818-7 ADTS AAC (MPEG-2 lower bit-rate audio)\n // logger.log('AAC PID:' + pid);\n if (result.audioPid === -1) {\n result.audioPid = pid;\n }\n\n break;\n\n // Packetized metadata (ID3)\n case 0x15:\n // logger.log('ID3 PID:' + pid);\n if (result.id3Pid === -1) {\n result.id3Pid = pid;\n }\n\n break;\n\n case 0xdb: // SAMPLE-AES AVC\n if (!isSampleAes) {\n logEncryptedSamplesFoundInUnencryptedStream('H.264', logger);\n break;\n }\n /* falls through */\n case 0x1b: // ITU-T Rec. H.264 and ISO/IEC 14496-10 (lower bit-rate video)\n // logger.log('AVC PID:' + pid);\n if (result.videoPid === -1) {\n result.videoPid = pid;\n }\n\n break;\n\n // ISO/IEC 11172-3 (MPEG-1 audio)\n // or ISO/IEC 13818-3 (MPEG-2 halved sample rate audio)\n case 0x03:\n case 0x04:\n // logger.log('MPEG PID:' + pid);\n if (!typeSupported.mpeg && !typeSupported.mp3) {\n logger.log('MPEG audio found, not supported in this browser');\n } else if (result.audioPid === -1) {\n result.audioPid = pid;\n result.segmentAudioCodec = 'mp3';\n }\n break;\n\n case 0xc1: // SAMPLE-AES AC3\n if (!isSampleAes) {\n logEncryptedSamplesFoundInUnencryptedStream('AC-3', logger);\n break;\n }\n /* falls through */\n case 0x81:\n if (__USE_M2TS_ADVANCED_CODECS__) {\n if (!typeSupported.ac3) {\n logger.log('AC-3 audio found, not supported in this browser');\n } else if (result.audioPid === -1) {\n result.audioPid = pid;\n result.segmentAudioCodec = 'ac3';\n }\n } else {\n logger.warn('AC-3 in M2TS support not included in build');\n }\n break;\n\n case 0x06:\n // stream_type 6 can mean a lot of different things in case of DVB.\n // We need to look at the descriptors. Right now, we're only interested\n // in AC-3 audio, so we do the descriptor parsing only when we don't have\n // an audio PID yet.\n if (result.audioPid === -1 && esInfoLength > 0) {\n let parsePos = offset + 5;\n let remaining = esInfoLength;\n\n while (remaining > 2) {\n const descriptorId = data[parsePos];\n\n switch (descriptorId) {\n case 0x6a: // DVB Descriptor for AC-3\n if (__USE_M2TS_ADVANCED_CODECS__) {\n if (typeSupported.ac3 !== true) {\n logger.log(\n 'AC-3 audio found, not supported in this browser for now',\n );\n } else {\n result.audioPid = pid;\n result.segmentAudioCodec = 'ac3';\n }\n } else {\n logger.warn('AC-3 in M2TS support not included in build');\n }\n break;\n }\n\n const descriptorLen = data[parsePos + 1] + 2;\n parsePos += descriptorLen;\n remaining -= descriptorLen;\n }\n }\n break;\n\n case 0xc2: // SAMPLE-AES EC3\n /* falls through */\n case 0x87:\n emitParsingError(\n observer,\n new Error('Unsupported EC-3 in M2TS found'),\n undefined,\n logger,\n );\n return result;\n\n case 0x24: // ITU-T Rec. H.265 and ISO/IEC 23008-2 (HEVC)\n if (__USE_M2TS_ADVANCED_CODECS__) {\n if (result.videoPid === -1) {\n result.videoPid = pid;\n result.segmentVideoCodec = 'hevc';\n logger.log('HEVC in M2TS found');\n }\n } else {\n emitParsingError(\n observer,\n new Error('Unsupported HEVC in M2TS found'),\n undefined,\n logger,\n );\n return result;\n }\n break;\n\n default:\n // logger.log('unknown stream type:' + data[offset]);\n break;\n }\n // move to the next table entry\n // skip past the elementary stream descriptors, if present\n offset += esInfoLength + 5;\n }\n return result;\n}\n\nfunction emitParsingError(\n observer: HlsEventEmitter,\n error: Error,\n levelRetry: boolean | undefined,\n logger: ILogger,\n) {\n logger.warn(`parsing error: ${error.message}`);\n observer.emit(Events.ERROR, Events.ERROR, {\n type: ErrorTypes.MEDIA_ERROR,\n details: ErrorDetails.FRAG_PARSING_ERROR,\n fatal: false,\n levelRetry,\n error,\n reason: error.message,\n });\n}\n\nfunction logEncryptedSamplesFoundInUnencryptedStream(\n type: string,\n logger: ILogger,\n) {\n logger.log(`${type} with AES-128-CBC encryption found in unencrypted stream`);\n}\n\nfunction parsePES(stream: ElementaryStreamData, logger: ILogger): PES | null {\n let i = 0;\n let frag: Uint8Array;\n let pesLen: number;\n let pesHdrLen: number;\n let pesPts: number | undefined;\n let pesDts: number | undefined;\n const data = stream.data;\n // safety check\n if (!stream || stream.size === 0) {\n return null;\n }\n\n // we might need up to 19 bytes to read PES header\n // if first chunk of data is less than 19 bytes, let's merge it with following ones until we get 19 bytes\n // usually only one merge is needed (and this is rare ...)\n while (data[0].length < 19 && data.length > 1) {\n data[0] = appendUint8Array(data[0], data[1]);\n data.splice(1, 1);\n }\n // retrieve PTS/DTS from first fragment\n frag = data[0];\n const pesPrefix = (frag[0] << 16) + (frag[1] << 8) + frag[2];\n if (pesPrefix === 1) {\n pesLen = (frag[4] << 8) + frag[5];\n // if PES parsed length is not zero and greater than total received length, stop parsing. PES might be truncated\n // minus 6 : PES header size\n if (pesLen && pesLen > stream.size - 6) {\n return null;\n }\n\n const pesFlags = frag[7];\n if (pesFlags & 0xc0) {\n /* PES header described here : http://dvd.sourceforge.net/dvdinfo/pes-hdr.html\n as PTS / DTS is 33 bit we cannot use bitwise operator in JS,\n as Bitwise operators treat their operands as a sequence of 32 bits */\n pesPts =\n (frag[9] & 0x0e) * 536870912 + // 1 << 29\n (frag[10] & 0xff) * 4194304 + // 1 << 22\n (frag[11] & 0xfe) * 16384 + // 1 << 14\n (frag[12] & 0xff) * 128 + // 1 << 7\n (frag[13] & 0xfe) / 2;\n\n if (pesFlags & 0x40) {\n pesDts =\n (frag[14] & 0x0e) * 536870912 + // 1 << 29\n (frag[15] & 0xff) * 4194304 + // 1 << 22\n (frag[16] & 0xfe) * 16384 + // 1 << 14\n (frag[17] & 0xff) * 128 + // 1 << 7\n (frag[18] & 0xfe) / 2;\n\n if (pesPts - pesDts > 60 * 90000) {\n logger.warn(\n `${Math.round(\n (pesPts - pesDts) / 90000,\n )}s delta between PTS and DTS, align them`,\n );\n pesPts = pesDts;\n }\n } else {\n pesDts = pesPts;\n }\n }\n pesHdrLen = frag[8];\n // 9 bytes : 6 bytes for PES header + 3 bytes for PES extension\n let payloadStartOffset = pesHdrLen + 9;\n if (stream.size <= payloadStartOffset) {\n return null;\n }\n stream.size -= payloadStartOffset;\n // reassemble PES packet\n const pesData = new Uint8Array(stream.size);\n for (let j = 0, dataLen = data.length; j < dataLen; j++) {\n frag = data[j];\n let len = frag.byteLength;\n if (payloadStartOffset) {\n if (payloadStartOffset > len) {\n // trim full frag if PES header bigger than frag\n payloadStartOffset -= len;\n continue;\n } else {\n // trim partial frag if PES header smaller than frag\n frag = frag.subarray(payloadStartOffset);\n len -= payloadStartOffset;\n payloadStartOffset = 0;\n }\n }\n pesData.set(frag, i);\n i += len;\n }\n if (pesLen) {\n // payload size : remove PES header + PES extension\n pesLen -= pesHdrLen + 3;\n }\n return { data: pesData, pts: pesPts, dts: pesDts, len: pesLen };\n }\n return null;\n}\n\nexport default TSDemuxer;\n","/**\n * AAC helper\n */\n\nclass AAC {\n static getSilentFrame(\n codec?: string,\n channelCount?: number,\n ): Uint8Array | undefined {\n switch (codec) {\n case 'mp4a.40.2':\n if (channelCount === 1) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);\n } else if (channelCount === 2) {\n return new Uint8Array([\n 0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80,\n ]);\n } else if (channelCount === 3) {\n return new Uint8Array([\n 0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64,\n 0x00, 0x8e,\n ]);\n } else if (channelCount === 4) {\n return new Uint8Array([\n 0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64,\n 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38,\n ]);\n } else if (channelCount === 5) {\n return new Uint8Array([\n 0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64,\n 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38,\n ]);\n } else if (channelCount === 6) {\n return new Uint8Array([\n 0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64,\n 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2,\n 0x00, 0x20, 0x08, 0xe0,\n ]);\n }\n\n break;\n // handle HE-AAC below (mp4a.40.5 / mp4a.40.29)\n default:\n if (channelCount === 1) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0:d=0.05\" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([\n 0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0,\n 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5e,\n ]);\n } else if (channelCount === 2) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0|0:d=0.05\" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([\n 0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0,\n 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5e,\n ]);\n } else if (channelCount === 3) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0|0|0:d=0.05\" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([\n 0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0,\n 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5e,\n ]);\n }\n break;\n }\n return undefined;\n }\n}\n\nexport default AAC;\n","/**\n * Generate MP4 Box\n */\n\nimport { appendUint8Array } from '../utils/mp4-tools';\nimport type {\n DemuxedAC3,\n DemuxedAudioTrack,\n DemuxedAVC1,\n DemuxedHEVC,\n DemuxedVideoTrack,\n} from '../types/demuxer';\nimport type {\n Mp4SampleFlags,\n RemuxedAudioTrackSamples,\n RemuxedVideoTrackSamples,\n} from '../types/remuxer';\n\ntype MediaTrackType = DemuxedAudioTrack | DemuxedVideoTrack;\ntype RemuxedTrackType = RemuxedAudioTrackSamples | RemuxedVideoTrackSamples;\n\ntype HdlrTypes = {\n video: Uint8Array;\n audio: Uint8Array;\n};\n\nconst UINT32_MAX = Math.pow(2, 32) - 1;\n\nclass MP4 {\n public static types: Record<string, number[]>;\n private static HDLR_TYPES: HdlrTypes;\n private static STTS: Uint8Array;\n private static STSC: Uint8Array;\n private static STCO: Uint8Array;\n private static STSZ: Uint8Array;\n private static VMHD: Uint8Array;\n private static SMHD: Uint8Array;\n private static STSD: Uint8Array;\n private static FTYP: Uint8Array;\n private static DINF: Uint8Array;\n\n static init() {\n MP4.types = {\n avc1: [], // codingname\n avcC: [],\n hvc1: [],\n hvcC: [],\n btrt: [],\n dinf: [],\n dref: [],\n esds: [],\n ftyp: [],\n hdlr: [],\n mdat: [],\n mdhd: [],\n mdia: [],\n mfhd: [],\n minf: [],\n moof: [],\n moov: [],\n mp4a: [],\n '.mp3': [],\n dac3: [],\n 'ac-3': [],\n mvex: [],\n mvhd: [],\n pasp: [],\n sdtp: [],\n stbl: [],\n stco: [],\n stsc: [],\n stsd: [],\n stsz: [],\n stts: [],\n tfdt: [],\n tfhd: [],\n traf: [],\n trak: [],\n trun: [],\n trex: [],\n tkhd: [],\n vmhd: [],\n smhd: [],\n };\n\n let i: string;\n for (i in MP4.types) {\n if (MP4.types.hasOwnProperty(i)) {\n MP4.types[i] = [\n i.charCodeAt(0),\n i.charCodeAt(1),\n i.charCodeAt(2),\n i.charCodeAt(3),\n ];\n }\n }\n\n const videoHdlr = new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00, // pre_defined\n 0x76,\n 0x69,\n 0x64,\n 0x65, // handler_type: 'vide'\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x56,\n 0x69,\n 0x64,\n 0x65,\n 0x6f,\n 0x48,\n 0x61,\n 0x6e,\n 0x64,\n 0x6c,\n 0x65,\n 0x72,\n 0x00, // name: 'VideoHandler'\n ]);\n\n const audioHdlr = new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00, // pre_defined\n 0x73,\n 0x6f,\n 0x75,\n 0x6e, // handler_type: 'soun'\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x53,\n 0x6f,\n 0x75,\n 0x6e,\n 0x64,\n 0x48,\n 0x61,\n 0x6e,\n 0x64,\n 0x6c,\n 0x65,\n 0x72,\n 0x00, // name: 'SoundHandler'\n ]);\n\n MP4.HDLR_TYPES = {\n video: videoHdlr,\n audio: audioHdlr,\n };\n\n const dref = new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x01, // entry_count\n 0x00,\n 0x00,\n 0x00,\n 0x0c, // entry_size\n 0x75,\n 0x72,\n 0x6c,\n 0x20, // 'url' type\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x01, // entry_flags\n ]);\n\n const stco = new Uint8Array([\n 0x00, // version\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00, // entry_count\n ]);\n\n MP4.STTS = MP4.STSC = MP4.STCO = stco;\n\n MP4.STSZ = new Uint8Array([\n 0x00, // version\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00, // sample_size\n 0x00,\n 0x00,\n 0x00,\n 0x00, // sample_count\n ]);\n MP4.VMHD = new Uint8Array([\n 0x00, // version\n 0x00,\n 0x00,\n 0x01, // flags\n 0x00,\n 0x00, // graphicsmode\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // opcolor\n ]);\n MP4.SMHD = new Uint8Array([\n 0x00, // version\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00, // balance\n 0x00,\n 0x00, // reserved\n ]);\n\n MP4.STSD = new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x01,\n ]); // entry_count\n\n const majorBrand = new Uint8Array([105, 115, 111, 109]); // isom\n const avc1Brand = new Uint8Array([97, 118, 99, 49]); // avc1\n const minorVersion = new Uint8Array([0, 0, 0, 1]);\n\n MP4.FTYP = MP4.box(\n MP4.types.ftyp,\n majorBrand,\n minorVersion,\n majorBrand,\n avc1Brand,\n );\n MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref));\n }\n\n static box(type: number[], ...payload: Uint8Array[]) {\n let size = 8;\n let i = payload.length;\n const len = i;\n // calculate the total size we need to allocate\n while (i--) {\n size += payload[i].byteLength;\n }\n\n const result = new Uint8Array(size);\n result[0] = (size >> 24) & 0xff;\n result[1] = (size >> 16) & 0xff;\n result[2] = (size >> 8) & 0xff;\n result[3] = size & 0xff;\n result.set(type, 4);\n // copy the payload into the result\n for (i = 0, size = 8; i < len; i++) {\n // copy payload[i] array @ offset size\n result.set(payload[i], size);\n size += payload[i].byteLength;\n }\n return result;\n }\n\n static hdlr(type: keyof HdlrTypes) {\n return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]);\n }\n\n static mdat(data: Uint8Array) {\n return MP4.box(MP4.types.mdat, data);\n }\n\n static mdhd(timescale: number, duration: number) {\n duration *= timescale;\n const upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));\n const lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));\n return MP4.box(\n MP4.types.mdhd,\n new Uint8Array([\n 0x01, // version 1\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x02, // creation_time\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x03, // modification_time\n (timescale >> 24) & 0xff,\n (timescale >> 16) & 0xff,\n (timescale >> 8) & 0xff,\n timescale & 0xff, // timescale\n upperWordDuration >> 24,\n (upperWordDuration >> 16) & 0xff,\n (upperWordDuration >> 8) & 0xff,\n upperWordDuration & 0xff,\n lowerWordDuration >> 24,\n (lowerWordDuration >> 16) & 0xff,\n (lowerWordDuration >> 8) & 0xff,\n lowerWordDuration & 0xff,\n 0x55,\n 0xc4, // 'und' language (undetermined)\n 0x00,\n 0x00,\n ]),\n );\n }\n\n static mdia(track: MediaTrackType) {\n return MP4.box(\n MP4.types.mdia,\n MP4.mdhd(track.timescale || 0, track.duration || 0),\n MP4.hdlr(track.type),\n MP4.minf(track),\n );\n }\n\n static mfhd(sequenceNumber: number) {\n return MP4.box(\n MP4.types.mfhd,\n new Uint8Array([\n 0x00,\n 0x00,\n 0x00,\n 0x00, // flags\n sequenceNumber >> 24,\n (sequenceNumber >> 16) & 0xff,\n (sequenceNumber >> 8) & 0xff,\n sequenceNumber & 0xff, // sequence_number\n ]),\n );\n }\n\n static minf(track: MediaTrackType) {\n if (track.type === 'audio') {\n return MP4.box(\n MP4.types.minf,\n MP4.box(MP4.types.smhd, MP4.SMHD),\n MP4.DINF,\n MP4.stbl(track),\n );\n } else {\n return MP4.box(\n MP4.types.minf,\n MP4.box(MP4.types.vmhd, MP4.VMHD),\n MP4.DINF,\n MP4.stbl(track),\n );\n }\n }\n\n static moof(\n sn: number,\n baseMediaDecodeTime: number,\n track: RemuxedTrackType,\n ) {\n return MP4.box(\n MP4.types.moof,\n MP4.mfhd(sn),\n MP4.traf(track, baseMediaDecodeTime),\n );\n }\n\n static moov(tracks: MediaTrackType[]) {\n let i = tracks.length;\n const boxes: Uint8Array[] = [];\n\n while (i--) {\n boxes[i] = MP4.trak(tracks[i]);\n }\n\n return MP4.box.apply(\n null,\n [\n MP4.types.moov,\n MP4.mvhd(tracks[0].timescale || 0, tracks[0].duration || 0),\n ]\n .concat(boxes)\n .concat(MP4.mvex(tracks)),\n );\n }\n\n static mvex(tracks: MediaTrackType[]) {\n let i = tracks.length;\n const boxes: Uint8Array[] = [];\n\n while (i--) {\n boxes[i] = MP4.trex(tracks[i]);\n }\n\n return MP4.box.apply(null, [MP4.types.mvex, ...boxes]);\n }\n\n static mvhd(timescale: number, duration: number) {\n duration *= timescale;\n const upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));\n const lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));\n const bytes = new Uint8Array([\n 0x01, // version 1\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x02, // creation_time\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x03, // modification_time\n (timescale >> 24) & 0xff,\n (timescale >> 16) & 0xff,\n (timescale >> 8) & 0xff,\n timescale & 0xff, // timescale\n upperWordDuration >> 24,\n (upperWordDuration >> 16) & 0xff,\n (upperWordDuration >> 8) & 0xff,\n upperWordDuration & 0xff,\n lowerWordDuration >> 24,\n (lowerWordDuration >> 16) & 0xff,\n (lowerWordDuration >> 8) & 0xff,\n lowerWordDuration & 0xff,\n 0x00,\n 0x01,\n 0x00,\n 0x00, // 1.0 rate\n 0x01,\n 0x00, // 1.0 volume\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x01,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x40,\n 0x00,\n 0x00,\n 0x00, // transformation: unity matrix\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // pre_defined\n 0xff,\n 0xff,\n 0xff,\n 0xff, // next_track_ID\n ]);\n return MP4.box(MP4.types.mvhd, bytes);\n }\n\n static sdtp(track: RemuxedTrackType) {\n const samples = track.samples || [];\n const bytes = new Uint8Array(4 + samples.length);\n let i: number;\n let flags: Mp4SampleFlags;\n // leave the full box header (4 bytes) all zero\n // write the sample table\n for (i = 0; i < samples.length; i++) {\n flags = samples[i].flags;\n bytes[i + 4] =\n (flags.dependsOn << 4) |\n (flags.isDependedOn << 2) |\n flags.hasRedundancy;\n }\n\n return MP4.box(MP4.types.sdtp, bytes);\n }\n\n static stbl(track: MediaTrackType) {\n return MP4.box(\n MP4.types.stbl,\n MP4.stsd(track),\n MP4.box(MP4.types.stts, MP4.STTS),\n MP4.box(MP4.types.stsc, MP4.STSC),\n MP4.box(MP4.types.stsz, MP4.STSZ),\n MP4.box(MP4.types.stco, MP4.STCO),\n );\n }\n\n static avc1(track: DemuxedAVC1) {\n let sps: number[] = [];\n let pps: number[] = [];\n let i;\n let data;\n let len;\n // assemble the SPSs\n\n for (i = 0; i < track.sps.length; i++) {\n data = track.sps[i];\n len = data.byteLength;\n sps.push((len >>> 8) & 0xff);\n sps.push(len & 0xff);\n\n // SPS\n sps = sps.concat(Array.prototype.slice.call(data));\n }\n\n // assemble the PPSs\n for (i = 0; i < track.pps.length; i++) {\n data = track.pps[i];\n len = data.byteLength;\n pps.push((len >>> 8) & 0xff);\n pps.push(len & 0xff);\n\n pps = pps.concat(Array.prototype.slice.call(data));\n }\n\n const avcc = MP4.box(\n MP4.types.avcC,\n new Uint8Array(\n [\n 0x01, // version\n sps[3], // profile\n sps[4], // profile compat\n sps[5], // level\n 0xfc | 3, // lengthSizeMinusOne, hard-coded to 4 bytes\n 0xe0 | track.sps.length, // 3bit reserved (111) + numOfSequenceParameterSets\n ]\n .concat(sps)\n .concat([\n track.pps.length, // numOfPictureParameterSets\n ])\n .concat(pps),\n ),\n ); // \"PPS\"\n const width = track.width;\n const height = track.height;\n const hSpacing = track.pixelRatio[0];\n const vSpacing = track.pixelRatio[1];\n\n return MP4.box(\n MP4.types.avc1,\n new Uint8Array([\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01, // data_reference_index\n 0x00,\n 0x00, // pre_defined\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // pre_defined\n (width >> 8) & 0xff,\n width & 0xff, // width\n (height >> 8) & 0xff,\n height & 0xff, // height\n 0x00,\n 0x48,\n 0x00,\n 0x00, // horizresolution\n 0x00,\n 0x48,\n 0x00,\n 0x00, // vertresolution\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01, // frame_count\n 0x12,\n 0x64,\n 0x61,\n 0x69,\n 0x6c, // dailymotion/hls.js\n 0x79,\n 0x6d,\n 0x6f,\n 0x74,\n 0x69,\n 0x6f,\n 0x6e,\n 0x2f,\n 0x68,\n 0x6c,\n 0x73,\n 0x2e,\n 0x6a,\n 0x73,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // compressorname\n 0x00,\n 0x18, // depth = 24\n 0x11,\n 0x11,\n ]), // pre_defined = -1\n avcc,\n MP4.box(\n MP4.types.btrt,\n new Uint8Array([\n 0x00,\n 0x1c,\n 0x9c,\n 0x80, // bufferSizeDB\n 0x00,\n 0x2d,\n 0xc6,\n 0xc0, // maxBitrate\n 0x00,\n 0x2d,\n 0xc6,\n 0xc0,\n ]),\n ), // avgBitrate\n MP4.box(\n MP4.types.pasp,\n new Uint8Array([\n hSpacing >> 24, // hSpacing\n (hSpacing >> 16) & 0xff,\n (hSpacing >> 8) & 0xff,\n hSpacing & 0xff,\n vSpacing >> 24, // vSpacing\n (vSpacing >> 16) & 0xff,\n (vSpacing >> 8) & 0xff,\n vSpacing & 0xff,\n ]),\n ),\n );\n }\n\n static esds(track: DemuxedAudioTrack) {\n const config = track.config as [number, number];\n return new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n\n 0x03, // descriptor_type\n 0x19, // length\n\n 0x00,\n 0x01, // es_id\n\n 0x00, // stream_priority\n\n 0x04, // descriptor_type\n 0x11, // length\n 0x40, // codec : mpeg4_audio\n 0x15, // stream_type\n 0x00,\n 0x00,\n 0x00, // buffer_size\n 0x00,\n 0x00,\n 0x00,\n 0x00, // maxBitrate\n 0x00,\n 0x00,\n 0x00,\n 0x00, // avgBitrate\n\n 0x05, // descriptor_type\n 0x02, // length\n ...config,\n 0x06,\n 0x01,\n 0x02, // GASpecificConfig)); // length + audio config descriptor\n ]);\n }\n\n static audioStsd(track: DemuxedAudioTrack) {\n const samplerate = track.samplerate || 0;\n return new Uint8Array([\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01, // data_reference_index\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n track.channelCount || 0, // channelcount\n 0x00,\n 0x10, // sampleSize:16bits\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved2\n (samplerate >> 8) & 0xff,\n samplerate & 0xff, //\n 0x00,\n 0x00,\n ]);\n }\n\n static mp4a(track: DemuxedAudioTrack) {\n return MP4.box(\n MP4.types.mp4a,\n MP4.audioStsd(track),\n MP4.box(MP4.types.esds, MP4.esds(track)),\n );\n }\n\n static mp3(track: DemuxedAudioTrack) {\n return MP4.box(MP4.types['.mp3'], MP4.audioStsd(track));\n }\n\n static ac3(track: DemuxedAudioTrack) {\n return MP4.box(\n MP4.types['ac-3'],\n MP4.audioStsd(track),\n MP4.box(MP4.types.dac3, track.config as Uint8Array),\n );\n }\n\n static stsd(track: MediaTrackType | DemuxedAC3): Uint8Array {\n const { segmentCodec } = track;\n if (track.type === 'audio') {\n if (segmentCodec === 'aac') {\n return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));\n }\n if (\n __USE_M2TS_ADVANCED_CODECS__ &&\n segmentCodec === 'ac3' &&\n track.config\n ) {\n return MP4.box(MP4.types.stsd, MP4.STSD, MP4.ac3(track));\n }\n if (segmentCodec === 'mp3' && track.codec === 'mp3') {\n return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp3(track));\n }\n } else {\n if (track.pps && track.sps) {\n if (segmentCodec === 'avc') {\n return MP4.box(\n MP4.types.stsd,\n MP4.STSD,\n MP4.avc1(track as DemuxedAVC1),\n );\n }\n if (\n __USE_M2TS_ADVANCED_CODECS__ &&\n segmentCodec === 'hevc' &&\n track.vps\n ) {\n return MP4.box(\n MP4.types.stsd,\n MP4.STSD,\n MP4.hvc1(track as DemuxedHEVC),\n );\n }\n } else {\n throw new Error(`video track missing pps or sps`);\n }\n }\n\n throw new Error(\n `unsupported ${track.type} segment codec (${segmentCodec}/${track.codec})`,\n );\n }\n\n static tkhd(track: MediaTrackType) {\n const id = track.id;\n const duration = (track.duration || 0) * (track.timescale || 0);\n const width = (track as any).width || 0;\n const height = (track as any).height || 0;\n const upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));\n const lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));\n return MP4.box(\n MP4.types.tkhd,\n new Uint8Array([\n 0x01, // version 1\n 0x00,\n 0x00,\n 0x07, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x02, // creation_time\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x03, // modification_time\n (id >> 24) & 0xff,\n (id >> 16) & 0xff,\n (id >> 8) & 0xff,\n id & 0xff, // track_ID\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n upperWordDuration >> 24,\n (upperWordDuration >> 16) & 0xff,\n (upperWordDuration >> 8) & 0xff,\n upperWordDuration & 0xff,\n lowerWordDuration >> 24,\n (lowerWordDuration >> 16) & 0xff,\n (lowerWordDuration >> 8) & 0xff,\n lowerWordDuration & 0xff,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00, // layer\n 0x00,\n 0x00, // alternate_group\n 0x00,\n 0x00, // non-audio track volume\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x01,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x40,\n 0x00,\n 0x00,\n 0x00, // transformation: unity matrix\n (width >> 8) & 0xff,\n width & 0xff,\n 0x00,\n 0x00, // width\n (height >> 8) & 0xff,\n height & 0xff,\n 0x00,\n 0x00, // height\n ]),\n );\n }\n\n static traf(track: RemuxedTrackType, baseMediaDecodeTime: number) {\n const sampleDependencyTable = MP4.sdtp(track);\n const id = track.id;\n const upperWordBaseMediaDecodeTime = Math.floor(\n baseMediaDecodeTime / (UINT32_MAX + 1),\n );\n const lowerWordBaseMediaDecodeTime = Math.floor(\n baseMediaDecodeTime % (UINT32_MAX + 1),\n );\n return MP4.box(\n MP4.types.traf,\n MP4.box(\n MP4.types.tfhd,\n new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n id >> 24,\n (id >> 16) & 0xff,\n (id >> 8) & 0xff,\n id & 0xff, // track_ID\n ]),\n ),\n MP4.box(\n MP4.types.tfdt,\n new Uint8Array([\n 0x01, // version 1\n 0x00,\n 0x00,\n 0x00, // flags\n upperWordBaseMediaDecodeTime >> 24,\n (upperWordBaseMediaDecodeTime >> 16) & 0xff,\n (upperWordBaseMediaDecodeTime >> 8) & 0xff,\n upperWordBaseMediaDecodeTime & 0xff,\n lowerWordBaseMediaDecodeTime >> 24,\n (lowerWordBaseMediaDecodeTime >> 16) & 0xff,\n (lowerWordBaseMediaDecodeTime >> 8) & 0xff,\n lowerWordBaseMediaDecodeTime & 0xff,\n ]),\n ),\n MP4.trun(\n track,\n sampleDependencyTable.length +\n 16 + // tfhd\n 20 + // tfdt\n 8 + // traf header\n 16 + // mfhd\n 8 + // moof header\n 8,\n ), // mdat header\n sampleDependencyTable,\n );\n }\n\n /**\n * Generate a track box.\n * @param track a track definition\n */\n static trak(track: MediaTrackType) {\n track.duration = track.duration || 0xffffffff;\n return MP4.box(MP4.types.trak, MP4.tkhd(track), MP4.mdia(track));\n }\n\n static trex(track: MediaTrackType) {\n const id = track.id;\n return MP4.box(\n MP4.types.trex,\n new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n id >> 24,\n (id >> 16) & 0xff,\n (id >> 8) & 0xff,\n id & 0xff, // track_ID\n 0x00,\n 0x00,\n 0x00,\n 0x01, // default_sample_description_index\n 0x00,\n 0x00,\n 0x00,\n 0x00, // default_sample_duration\n 0x00,\n 0x00,\n 0x00,\n 0x00, // default_sample_size\n 0x00,\n 0x01,\n 0x00,\n 0x01, // default_sample_flags\n ]),\n );\n }\n\n static trun(track: MediaTrackType, offset: number) {\n const samples = track.samples || [];\n const len = samples.length;\n const arraylen = 12 + 16 * len;\n const array = new Uint8Array(arraylen);\n let i;\n let sample;\n let duration;\n let size;\n let flags;\n let cts;\n offset += 8 + arraylen;\n array.set(\n [\n track.type === 'video' ? 0x01 : 0x00, // version 1 for video with signed-int sample_composition_time_offset\n 0x00,\n 0x0f,\n 0x01, // flags\n (len >>> 24) & 0xff,\n (len >>> 16) & 0xff,\n (len >>> 8) & 0xff,\n len & 0xff, // sample_count\n (offset >>> 24) & 0xff,\n (offset >>> 16) & 0xff,\n (offset >>> 8) & 0xff,\n offset & 0xff, // data_offset\n ],\n 0,\n );\n for (i = 0; i < len; i++) {\n sample = samples[i];\n duration = sample.duration;\n size = sample.size;\n flags = sample.flags;\n cts = sample.cts;\n array.set(\n [\n (duration >>> 24) & 0xff,\n (duration >>> 16) & 0xff,\n (duration >>> 8) & 0xff,\n duration & 0xff, // sample_duration\n (size >>> 24) & 0xff,\n (size >>> 16) & 0xff,\n (size >>> 8) & 0xff,\n size & 0xff, // sample_size\n (flags.isLeading << 2) | flags.dependsOn,\n (flags.isDependedOn << 6) |\n (flags.hasRedundancy << 4) |\n (flags.paddingValue << 1) |\n flags.isNonSync,\n flags.degradPrio & (0xf0 << 8),\n flags.degradPrio & 0x0f, // sample_flags\n (cts >>> 24) & 0xff,\n (cts >>> 16) & 0xff,\n (cts >>> 8) & 0xff,\n cts & 0xff, // sample_composition_time_offset\n ],\n 12 + 16 * i,\n );\n }\n return MP4.box(MP4.types.trun, array);\n }\n\n static initSegment(tracks: MediaTrackType[]) {\n if (!MP4.types) {\n MP4.init();\n }\n\n const movie = MP4.moov(tracks);\n const result = appendUint8Array(MP4.FTYP, movie);\n return result;\n }\n\n static hvc1(track: DemuxedHEVC) {\n if (!__USE_M2TS_ADVANCED_CODECS__) {\n return new Uint8Array();\n }\n const ps = track.params;\n const units: Uint8Array[][] = [track.vps, track.sps, track.pps];\n const NALuLengthSize = 4;\n const config = new Uint8Array([\n 0x01,\n (ps.general_profile_space << 6) |\n (ps.general_tier_flag ? 32 : 0) |\n ps.general_profile_idc,\n ps.general_profile_compatibility_flags[0],\n ps.general_profile_compatibility_flags[1],\n ps.general_profile_compatibility_flags[2],\n ps.general_profile_compatibility_flags[3],\n ps.general_constraint_indicator_flags[0],\n ps.general_constraint_indicator_flags[1],\n ps.general_constraint_indicator_flags[2],\n ps.general_constraint_indicator_flags[3],\n ps.general_constraint_indicator_flags[4],\n ps.general_constraint_indicator_flags[5],\n ps.general_level_idc,\n 240 | (ps.min_spatial_segmentation_idc >> 8),\n 255 & ps.min_spatial_segmentation_idc,\n 252 | ps.parallelismType,\n 252 | ps.chroma_format_idc,\n 248 | ps.bit_depth_luma_minus8,\n 248 | ps.bit_depth_chroma_minus8,\n 0x00,\n parseInt(ps.frame_rate.fps),\n (NALuLengthSize - 1) |\n (ps.temporal_id_nested << 2) |\n (ps.num_temporal_layers << 3) |\n (ps.frame_rate.fixed ? 64 : 0),\n units.length,\n ]);\n\n // compute hvcC size in bytes\n let length = config.length;\n for (let i = 0; i < units.length; i += 1) {\n length += 3;\n for (let j = 0; j < units[i].length; j += 1) {\n length += 2 + units[i][j].length;\n }\n }\n\n const hvcC = new Uint8Array(length);\n hvcC.set(config, 0);\n length = config.length;\n // append parameter set units: one vps, one or more sps and pps\n const iMax = units.length - 1;\n for (let i = 0; i < units.length; i += 1) {\n hvcC.set(\n new Uint8Array([\n (32 + i) | (i === iMax ? 128 : 0),\n 0x00,\n units[i].length,\n ]),\n length,\n );\n length += 3;\n for (let j = 0; j < units[i].length; j += 1) {\n hvcC.set(\n new Uint8Array([units[i][j].length >> 8, units[i][j].length & 255]),\n length,\n );\n length += 2;\n hvcC.set(units[i][j], length);\n length += units[i][j].length;\n }\n }\n const hvcc = MP4.box(MP4.types.hvcC, hvcC);\n const width = track.width;\n const height = track.height;\n const hSpacing = track.pixelRatio[0];\n const vSpacing = track.pixelRatio[1];\n\n return MP4.box(\n MP4.types.hvc1,\n new Uint8Array([\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01, // data_reference_index\n 0x00,\n 0x00, // pre_defined\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // pre_defined\n (width >> 8) & 0xff,\n width & 0xff, // width\n (height >> 8) & 0xff,\n height & 0xff, // height\n 0x00,\n 0x48,\n 0x00,\n 0x00, // horizresolution\n 0x00,\n 0x48,\n 0x00,\n 0x00, // vertresolution\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01, // frame_count\n 0x12,\n 0x64,\n 0x61,\n 0x69,\n 0x6c, // dailymotion/hls.js\n 0x79,\n 0x6d,\n 0x6f,\n 0x74,\n 0x69,\n 0x6f,\n 0x6e,\n 0x2f,\n 0x68,\n 0x6c,\n 0x73,\n 0x2e,\n 0x6a,\n 0x73,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // compressorname\n 0x00,\n 0x18, // depth = 24\n 0x11,\n 0x11,\n ]), // pre_defined = -1\n hvcc,\n MP4.box(\n MP4.types.btrt,\n new Uint8Array([\n 0x00,\n 0x1c,\n 0x9c,\n 0x80, // bufferSizeDB\n 0x00,\n 0x2d,\n 0xc6,\n 0xc0, // maxBitrate\n 0x00,\n 0x2d,\n 0xc6,\n 0xc0,\n ]),\n ), // avgBitrate\n MP4.box(\n MP4.types.pasp,\n new Uint8Array([\n hSpacing >> 24, // hSpacing\n (hSpacing >> 16) & 0xff,\n (hSpacing >> 8) & 0xff,\n hSpacing & 0xff,\n vSpacing >> 24, // vSpacing\n (vSpacing >> 16) & 0xff,\n (vSpacing >> 8) & 0xff,\n vSpacing & 0xff,\n ]),\n ),\n );\n }\n}\n\nexport default MP4;\n","import type { LoaderConfig } from '../config';\nimport type { HlsUrlParameters, Level } from './level';\nimport type { MediaPlaylist } from './media-playlist';\nimport type { Fragment } from '../loader/fragment';\nimport type { Part } from '../loader/fragment';\nimport type { KeyLoaderInfo } from '../loader/key-loader';\nimport type { LevelDetails } from '../loader/level-details';\n\nexport interface LoaderContext {\n // target URL\n url: string;\n // loader response type (arraybuffer or default response type for playlist)\n responseType: string;\n // headers\n headers?: Record<string, string>;\n // start byte range offset\n rangeStart?: number;\n // end byte range offset\n rangeEnd?: number;\n // true if onProgress should report partial chunk of loaded content\n progressData?: boolean;\n}\n\nexport interface FragmentLoaderContext extends LoaderContext {\n frag: Fragment;\n part: Part | null;\n resetIV?: boolean;\n}\n\nexport interface KeyLoaderContext extends LoaderContext {\n keyInfo: KeyLoaderInfo;\n frag: Fragment;\n}\n\nexport interface LoaderConfiguration {\n // LoaderConfig policy that overrides required settings\n loadPolicy: LoaderConfig;\n /**\n * @deprecated use LoaderConfig timeoutRetry and errorRetry maxNumRetry\n */\n // Max number of load retries\n maxRetry: number;\n /**\n * @deprecated use LoaderConfig maxTimeToFirstByteMs and maxLoadTimeMs\n */\n // Timeout after which `onTimeOut` callback will be triggered\n // when loading has not finished after that delay\n timeout: number;\n /**\n * @deprecated use LoaderConfig timeoutRetry and errorRetry retryDelayMs\n */\n // Delay between an I/O error and following connection retry (ms).\n // This to avoid spamming the server\n retryDelay: number;\n /**\n * @deprecated use LoaderConfig timeoutRetry and errorRetry maxRetryDelayMs\n */\n // max connection retry delay (ms)\n maxRetryDelay: number;\n // When streaming progressively, this is the minimum chunk size required to emit a PROGRESS event\n highWaterMark?: number;\n}\n\nexport interface LoaderResponse {\n url: string;\n data?: string | ArrayBuffer | Object;\n // Errors can include HTTP status code and error message\n // Successful responses should include status code 200\n code?: number;\n text?: string;\n}\n\nexport interface LoaderStats {\n aborted: boolean;\n loaded: number;\n retry: number;\n total: number;\n chunkCount: number;\n bwEstimate: number;\n loading: HlsProgressivePerformanceTiming;\n parsing: HlsPerformanceTiming;\n buffering: HlsProgressivePerformanceTiming;\n}\n\nexport interface HlsPerformanceTiming {\n start: number;\n end: number;\n}\n\nexport interface HlsChunkPerformanceTiming extends HlsPerformanceTiming {\n executeStart: number;\n executeEnd: number;\n}\n\nexport interface HlsProgressivePerformanceTiming extends HlsPerformanceTiming {\n first: number;\n}\n\nexport type LoaderOnSuccess<T extends LoaderContext> = (\n response: LoaderResponse,\n stats: LoaderStats,\n context: T,\n networkDetails: any,\n) => void;\n\nexport type LoaderOnProgress<T extends LoaderContext> = (\n stats: LoaderStats,\n context: T,\n data: string | ArrayBuffer,\n networkDetails: any,\n) => void;\n\nexport type LoaderOnError<T extends LoaderContext> = (\n error: {\n // error status code\n code: number;\n // error description\n text: string;\n },\n context: T,\n networkDetails: any,\n stats: LoaderStats,\n) => void;\n\nexport type LoaderOnTimeout<T extends LoaderContext> = (\n stats: LoaderStats,\n context: T,\n networkDetails: any,\n) => void;\n\nexport type LoaderOnAbort<T extends LoaderContext> = (\n stats: LoaderStats,\n context: T,\n networkDetails: any,\n) => void;\n\nexport interface LoaderCallbacks<T extends LoaderContext> {\n onSuccess: LoaderOnSuccess<T>;\n onError: LoaderOnError<T>;\n onTimeout: LoaderOnTimeout<T>;\n onAbort?: LoaderOnAbort<T>;\n onProgress?: LoaderOnProgress<T>;\n}\n\nexport interface Loader<T extends LoaderContext> {\n destroy(): void;\n abort(): void;\n load(\n context: T,\n config: LoaderConfiguration,\n callbacks: LoaderCallbacks<T>,\n ): void;\n /**\n * `getCacheAge()` is called by hls.js to get the duration that a given object\n * has been sitting in a cache proxy when playing live. If implemented,\n * this should return a value in seconds.\n *\n * For HTTP based loaders, this should return the contents of the \"age\" header.\n *\n * @returns time object being lodaded\n */\n getCacheAge?: () => number | null;\n getResponseHeader?: (name: string) => string | null;\n context: T | null;\n stats: LoaderStats;\n}\n\nexport const enum PlaylistContextType {\n MANIFEST = 'manifest',\n LEVEL = 'level',\n AUDIO_TRACK = 'audioTrack',\n SUBTITLE_TRACK = 'subtitleTrack',\n}\n\nexport const enum PlaylistLevelType {\n MAIN = 'main',\n AUDIO = 'audio',\n SUBTITLE = 'subtitle',\n}\n\nexport interface PlaylistLoaderContext extends LoaderContext {\n type: PlaylistContextType;\n // the level index to load\n level: number | null;\n // level or track id from LevelLoadingData / TrackLoadingData\n id: number | null;\n // Media Playlist Group ID\n groupId?: string;\n // Content Steering Pathway ID (or undefined for default Pathway \".\")\n pathwayId?: string;\n // internal representation of a parsed m3u8 level playlist\n levelDetails?: LevelDetails;\n // Blocking playlist request delivery directives (or null id none were added to playlist url\n deliveryDirectives: HlsUrlParameters | null;\n // Reference to level or track object in hls.levels, hls.allAudioTracks, or hls.allSubtitleTracks (null when loading MVP)\n levelOrTrack: Level | MediaPlaylist | null;\n}\n","const MPEG_TS_CLOCK_FREQ_HZ = 90000;\n\nexport type RationalTimestamp = {\n baseTime: number; // ticks\n timescale: number; // ticks per second\n};\n\nexport function toTimescaleFromBase(\n baseTime: number,\n destScale: number,\n srcBase: number = 1,\n round: boolean = false,\n): number {\n const result = baseTime * destScale * srcBase; // equivalent to `(value * scale) / (1 / base)`\n return round ? Math.round(result) : result;\n}\n\nexport function toTimescaleFromScale(\n baseTime: number,\n destScale: number,\n srcScale: number = 1,\n round: boolean = false,\n): number {\n return toTimescaleFromBase(baseTime, destScale, 1 / srcScale, round);\n}\n\nexport function toMsFromMpegTsClock(\n baseTime: number,\n round: boolean = false,\n): number {\n return toTimescaleFromBase(baseTime, 1000, 1 / MPEG_TS_CLOCK_FREQ_HZ, round);\n}\n\nexport function toMpegTsClockFromTimescale(\n baseTime: number,\n srcScale: number = 1,\n): number {\n return toTimescaleFromBase(baseTime, MPEG_TS_CLOCK_FREQ_HZ, 1 / srcScale);\n}\n","import AAC from './aac-helper';\nimport MP4 from './mp4-generator';\nimport { ErrorDetails, ErrorTypes } from '../errors';\nimport { Events } from '../events';\nimport { PlaylistLevelType } from '../types/loader';\nimport { toMsFromMpegTsClock } from '../utils/timescale-conversion';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport type { SourceBufferName } from '../types/buffer';\nimport type {\n AudioSample,\n DemuxedAudioTrack,\n DemuxedMetadataTrack,\n DemuxedUserdataTrack,\n DemuxedVideoTrack,\n VideoSample,\n} from '../types/demuxer';\nimport type {\n InitSegmentData,\n Mp4Sample,\n RemuxedMetadata,\n RemuxedTrack,\n RemuxedUserdata,\n Remuxer,\n RemuxerResult,\n} from '../types/remuxer';\nimport type { TrackSet } from '../types/track';\nimport type { TypeSupported } from '../utils/codecs';\nimport type { ILogger } from '../utils/logger';\nimport type { RationalTimestamp } from '../utils/timescale-conversion';\n\nconst MAX_SILENT_FRAME_DURATION = 10 * 1000; // 10 seconds\nconst AAC_SAMPLES_PER_FRAME = 1024;\nconst MPEG_AUDIO_SAMPLE_PER_FRAME = 1152;\nconst AC3_SAMPLES_PER_FRAME = 1536;\n\nlet chromeVersion: number | null = null;\nlet safariWebkitVersion: number | null = null;\n\nfunction createMp4Sample(\n isKeyframe: boolean,\n duration: number,\n size: number,\n cts: number,\n): Mp4Sample {\n return {\n duration,\n size,\n cts,\n flags: {\n isLeading: 0,\n isDependedOn: 0,\n hasRedundancy: 0,\n degradPrio: 0,\n dependsOn: isKeyframe ? 2 : 1,\n isNonSync: isKeyframe ? 0 : 1,\n },\n };\n}\nexport default class MP4Remuxer implements Remuxer {\n private readonly logger: ILogger;\n private readonly observer: HlsEventEmitter;\n private readonly config: HlsConfig;\n private readonly typeSupported: TypeSupported;\n private ISGenerated: boolean = false;\n private _initPTS: RationalTimestamp | null = null;\n private _initDTS: RationalTimestamp | null = null;\n private nextAvcDts: number | null = null;\n private nextAudioPts: number | null = null;\n private videoSampleDuration: number | null = null;\n private isAudioContiguous: boolean = false;\n private isVideoContiguous: boolean = false;\n private videoTrackConfig?: {\n width?: number;\n height?: number;\n pixelRatio?: [number, number];\n };\n\n constructor(\n observer: HlsEventEmitter,\n config: HlsConfig,\n typeSupported: TypeSupported,\n logger: ILogger,\n ) {\n this.observer = observer;\n this.config = config;\n this.typeSupported = typeSupported;\n this.logger = logger;\n this.ISGenerated = false;\n\n if (chromeVersion === null) {\n const userAgent = navigator.userAgent || '';\n const result = userAgent.match(/Chrome\\/(\\d+)/i);\n chromeVersion = result ? parseInt(result[1]) : 0;\n }\n if (safariWebkitVersion === null) {\n const result = navigator.userAgent.match(/Safari\\/(\\d+)/i);\n safariWebkitVersion = result ? parseInt(result[1]) : 0;\n }\n }\n\n destroy() {\n // @ts-ignore\n this.config = this.videoTrackConfig = this._initPTS = this._initDTS = null;\n }\n\n resetTimeStamp(defaultTimeStamp: RationalTimestamp | null) {\n this.logger.log('[mp4-remuxer]: initPTS & initDTS reset');\n this._initPTS = this._initDTS = defaultTimeStamp;\n }\n\n resetNextTimestamp() {\n this.logger.log('[mp4-remuxer]: reset next timestamp');\n this.isVideoContiguous = false;\n this.isAudioContiguous = false;\n }\n\n resetInitSegment() {\n this.logger.log('[mp4-remuxer]: ISGenerated flag reset');\n this.ISGenerated = false;\n this.videoTrackConfig = undefined;\n }\n\n getVideoStartPts(videoSamples: VideoSample[]) {\n // Get the minimum PTS value relative to the first sample's PTS, normalized for 33-bit wrapping\n let rolloverDetected = false;\n const firstPts = videoSamples[0].pts;\n const startPTS = videoSamples.reduce((minPTS, sample) => {\n let pts = sample.pts;\n let delta = pts - minPTS;\n if (delta < -4294967296) {\n // 2^32, see PTSNormalize for reasoning, but we're hitting a rollover here, and we don't want that to impact the timeOffset calculation\n rolloverDetected = true;\n pts = normalizePts(pts, firstPts);\n delta = pts - minPTS;\n }\n if (delta > 0) {\n return minPTS;\n }\n return pts;\n }, firstPts);\n if (rolloverDetected) {\n this.logger.debug('PTS rollover detected');\n }\n return startPTS;\n }\n\n remux(\n audioTrack: DemuxedAudioTrack,\n videoTrack: DemuxedVideoTrack,\n id3Track: DemuxedMetadataTrack,\n textTrack: DemuxedUserdataTrack,\n timeOffset: number,\n accurateTimeOffset: boolean,\n flush: boolean,\n playlistType: PlaylistLevelType,\n ): RemuxerResult {\n let video: RemuxedTrack | undefined;\n let audio: RemuxedTrack | undefined;\n let initSegment: InitSegmentData | undefined;\n let text: RemuxedUserdata | undefined;\n let id3: RemuxedMetadata | undefined;\n let independent: boolean | undefined;\n let audioTimeOffset = timeOffset;\n let videoTimeOffset = timeOffset;\n\n // If we're remuxing audio and video progressively, wait until we've received enough samples for each track before proceeding.\n // This is done to synchronize the audio and video streams. We know if the current segment will have samples if the \"pid\"\n // parameter is greater than -1. The pid is set when the PMT is parsed, which contains the tracks list.\n // However, if the initSegment has already been generated, or we've reached the end of a segment (flush),\n // then we can remux one track without waiting for the other.\n const hasAudio = audioTrack.pid > -1;\n const hasVideo = videoTrack.pid > -1;\n const length = videoTrack.samples.length;\n const enoughAudioSamples = audioTrack.samples.length > 0;\n const enoughVideoSamples = (flush && length > 0) || length > 1;\n const canRemuxAvc =\n ((!hasAudio || enoughAudioSamples) &&\n (!hasVideo || enoughVideoSamples)) ||\n this.ISGenerated ||\n flush;\n\n if (canRemuxAvc) {\n if (this.ISGenerated) {\n const config = this.videoTrackConfig;\n if (\n (config &&\n (videoTrack.width !== config.width ||\n videoTrack.height !== config.height ||\n videoTrack.pixelRatio?.[0] !== config.pixelRatio?.[0] ||\n videoTrack.pixelRatio?.[1] !== config.pixelRatio?.[1])) ||\n (!config && enoughVideoSamples) ||\n (this.nextAudioPts === null && enoughAudioSamples)\n ) {\n this.resetInitSegment();\n }\n }\n if (!this.ISGenerated) {\n initSegment = this.generateIS(\n audioTrack,\n videoTrack,\n timeOffset,\n accurateTimeOffset,\n );\n }\n\n const isVideoContiguous = this.isVideoContiguous;\n let firstKeyFrameIndex = -1;\n let firstKeyFramePTS;\n\n if (enoughVideoSamples) {\n firstKeyFrameIndex = findKeyframeIndex(videoTrack.samples);\n if (!isVideoContiguous && this.config.forceKeyFrameOnDiscontinuity) {\n independent = true;\n if (firstKeyFrameIndex > 0) {\n this.logger.warn(\n `[mp4-remuxer]: Dropped ${firstKeyFrameIndex} out of ${length} video samples due to a missing keyframe`,\n );\n const startPTS = this.getVideoStartPts(videoTrack.samples);\n videoTrack.samples = videoTrack.samples.slice(firstKeyFrameIndex);\n videoTrack.dropped += firstKeyFrameIndex;\n videoTimeOffset +=\n (videoTrack.samples[0].pts - startPTS) /\n videoTrack.inputTimeScale;\n firstKeyFramePTS = videoTimeOffset;\n } else if (firstKeyFrameIndex === -1) {\n this.logger.warn(\n `[mp4-remuxer]: No keyframe found out of ${length} video samples`,\n );\n independent = false;\n }\n }\n }\n\n if (this.ISGenerated) {\n if (enoughAudioSamples && enoughVideoSamples) {\n // timeOffset is expected to be the offset of the first timestamp of this fragment (first DTS)\n // if first audio DTS is not aligned with first video DTS then we need to take that into account\n // when providing timeOffset to remuxAudio / remuxVideo. if we don't do that, there might be a permanent / small\n // drift between audio and video streams\n const startPTS = this.getVideoStartPts(videoTrack.samples);\n const tsDelta =\n normalizePts(audioTrack.samples[0].pts, startPTS) - startPTS;\n const audiovideoTimestampDelta = tsDelta / videoTrack.inputTimeScale;\n audioTimeOffset += Math.max(0, audiovideoTimestampDelta);\n videoTimeOffset += Math.max(0, -audiovideoTimestampDelta);\n }\n\n // Purposefully remuxing audio before video, so that remuxVideo can use nextAudioPts, which is calculated in remuxAudio.\n if (enoughAudioSamples) {\n // if initSegment was generated without audio samples, regenerate it again\n if (!audioTrack.samplerate) {\n this.logger.warn(\n '[mp4-remuxer]: regenerate InitSegment as audio detected',\n );\n initSegment = this.generateIS(\n audioTrack,\n videoTrack,\n timeOffset,\n accurateTimeOffset,\n );\n }\n audio = this.remuxAudio(\n audioTrack,\n audioTimeOffset,\n this.isAudioContiguous,\n accurateTimeOffset,\n hasVideo ||\n enoughVideoSamples ||\n playlistType === PlaylistLevelType.AUDIO\n ? videoTimeOffset\n : undefined,\n );\n if (enoughVideoSamples) {\n const audioTrackLength = audio ? audio.endPTS - audio.startPTS : 0;\n // if initSegment was generated without video samples, regenerate it again\n if (!videoTrack.inputTimeScale) {\n this.logger.warn(\n '[mp4-remuxer]: regenerate InitSegment as video detected',\n );\n initSegment = this.generateIS(\n audioTrack,\n videoTrack,\n timeOffset,\n accurateTimeOffset,\n );\n }\n video = this.remuxVideo(\n videoTrack,\n videoTimeOffset,\n isVideoContiguous,\n audioTrackLength,\n );\n }\n } else if (enoughVideoSamples) {\n video = this.remuxVideo(\n videoTrack,\n videoTimeOffset,\n isVideoContiguous,\n 0,\n );\n }\n if (video) {\n video.firstKeyFrame = firstKeyFrameIndex;\n video.independent = firstKeyFrameIndex !== -1;\n video.firstKeyFramePTS = firstKeyFramePTS;\n }\n }\n }\n\n // Allow ID3 and text to remux, even if more audio/video samples are required\n if (this.ISGenerated && this._initPTS && this._initDTS) {\n if (id3Track.samples.length) {\n id3 = flushTextTrackMetadataCueSamples(\n id3Track,\n timeOffset,\n this._initPTS,\n this._initDTS,\n );\n }\n\n if (textTrack.samples.length) {\n text = flushTextTrackUserdataCueSamples(\n textTrack,\n timeOffset,\n this._initPTS,\n );\n }\n }\n\n return {\n audio,\n video,\n initSegment,\n independent,\n text,\n id3,\n };\n }\n\n generateIS(\n audioTrack: DemuxedAudioTrack,\n videoTrack: DemuxedVideoTrack,\n timeOffset: number,\n accurateTimeOffset: boolean,\n ): InitSegmentData | undefined {\n const audioSamples = audioTrack.samples;\n const videoSamples = videoTrack.samples;\n const typeSupported = this.typeSupported;\n const tracks: TrackSet = {};\n const _initPTS = this._initPTS;\n let computePTSDTS = !_initPTS || accurateTimeOffset;\n let container = 'audio/mp4';\n let initPTS: number | undefined;\n let initDTS: number | undefined;\n let timescale: number | undefined;\n\n if (computePTSDTS) {\n initPTS = initDTS = Infinity;\n }\n\n if (audioTrack.config && audioSamples.length) {\n // let's use audio sampling rate as MP4 time scale.\n // rationale is that there is a integer nb of audio frames per audio sample (1024 for AAC)\n // using audio sampling rate here helps having an integer MP4 frame duration\n // this avoids potential rounding issue and AV sync issue\n audioTrack.timescale = audioTrack.samplerate;\n switch (audioTrack.segmentCodec) {\n case 'mp3':\n if (typeSupported.mpeg) {\n // Chrome and Safari\n container = 'audio/mpeg';\n audioTrack.codec = '';\n } else if (typeSupported.mp3) {\n // Firefox\n audioTrack.codec = 'mp3';\n }\n break;\n\n case 'ac3':\n audioTrack.codec = 'ac-3';\n break;\n }\n tracks.audio = {\n id: 'audio',\n container: container,\n codec: audioTrack.codec,\n initSegment:\n audioTrack.segmentCodec === 'mp3' && typeSupported.mpeg\n ? new Uint8Array(0)\n : MP4.initSegment([audioTrack]),\n metadata: {\n channelCount: audioTrack.channelCount,\n },\n };\n if (computePTSDTS) {\n timescale = audioTrack.inputTimeScale;\n if (!_initPTS || timescale !== _initPTS.timescale) {\n // remember first PTS of this demuxing context. for audio, PTS = DTS\n initPTS = initDTS =\n audioSamples[0].pts - Math.round(timescale * timeOffset);\n } else {\n computePTSDTS = false;\n }\n }\n }\n\n if (videoTrack.sps && videoTrack.pps && videoSamples.length) {\n // let's use input time scale as MP4 video timescale\n // we use input time scale straight away to avoid rounding issues on frame duration / cts computation\n videoTrack.timescale = videoTrack.inputTimeScale;\n tracks.video = {\n id: 'main',\n container: 'video/mp4',\n codec: videoTrack.codec,\n initSegment: MP4.initSegment([videoTrack]),\n metadata: {\n width: videoTrack.width,\n height: videoTrack.height,\n },\n };\n if (computePTSDTS) {\n timescale = videoTrack.inputTimeScale;\n if (!_initPTS || timescale !== _initPTS.timescale) {\n const startPTS = this.getVideoStartPts(videoSamples);\n const startOffset = Math.round(timescale * timeOffset);\n initDTS = Math.min(\n initDTS as number,\n normalizePts(videoSamples[0].dts, startPTS) - startOffset,\n );\n initPTS = Math.min(initPTS as number, startPTS - startOffset);\n } else {\n computePTSDTS = false;\n }\n }\n this.videoTrackConfig = {\n width: videoTrack.width,\n height: videoTrack.height,\n pixelRatio: videoTrack.pixelRatio,\n };\n }\n\n if (Object.keys(tracks).length) {\n this.ISGenerated = true;\n if (computePTSDTS) {\n this._initPTS = {\n baseTime: initPTS as number,\n timescale: timescale as number,\n };\n this._initDTS = {\n baseTime: initDTS as number,\n timescale: timescale as number,\n };\n } else {\n initPTS = timescale = undefined;\n }\n\n return {\n tracks,\n initPTS,\n timescale,\n };\n }\n }\n\n remuxVideo(\n track: DemuxedVideoTrack,\n timeOffset: number,\n contiguous: boolean,\n audioTrackLength: number,\n ): RemuxedTrack | undefined {\n const timeScale: number = track.inputTimeScale;\n const inputSamples: Array<VideoSample> = track.samples;\n const outputSamples: Array<Mp4Sample> = [];\n const nbSamples = inputSamples.length;\n const initPTS = this._initPTS as RationalTimestamp;\n let nextAvcDts = this.nextAvcDts;\n let offset = 8;\n let mp4SampleDuration = this.videoSampleDuration;\n let firstDTS;\n let lastDTS;\n let minPTS: number = Number.POSITIVE_INFINITY;\n let maxPTS: number = Number.NEGATIVE_INFINITY;\n let sortSamples = false;\n\n // if parsed fragment is contiguous with last one, let's use last DTS value as reference\n if (!contiguous || nextAvcDts === null) {\n const pts = timeOffset * timeScale;\n const cts =\n inputSamples[0].pts -\n normalizePts(inputSamples[0].dts, inputSamples[0].pts);\n if (\n chromeVersion &&\n nextAvcDts !== null &&\n Math.abs(pts - cts - nextAvcDts) < 15000\n ) {\n // treat as contigous to adjust samples that would otherwise produce video buffer gaps in Chrome\n contiguous = true;\n } else {\n // if not contiguous, let's use target timeOffset\n nextAvcDts = pts - cts;\n }\n }\n\n // PTS is coded on 33bits, and can loop from -2^32 to 2^32\n // PTSNormalize will make PTS/DTS value monotonic, we use last known DTS value as reference value\n const initTime = (initPTS.baseTime * timeScale) / initPTS.timescale;\n for (let i = 0; i < nbSamples; i++) {\n const sample = inputSamples[i];\n sample.pts = normalizePts(sample.pts - initTime, nextAvcDts);\n sample.dts = normalizePts(sample.dts - initTime, nextAvcDts);\n if (sample.dts < inputSamples[i > 0 ? i - 1 : i].dts) {\n sortSamples = true;\n }\n }\n\n // sort video samples by DTS then PTS then demux id order\n if (sortSamples) {\n inputSamples.sort(function (a, b) {\n const deltadts = a.dts - b.dts;\n const deltapts = a.pts - b.pts;\n return deltadts || deltapts;\n });\n }\n\n // Get first/last DTS\n firstDTS = inputSamples[0].dts;\n lastDTS = inputSamples[inputSamples.length - 1].dts;\n\n // Sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS\n // set this constant duration as being the avg delta between consecutive DTS.\n const inputDuration = lastDTS - firstDTS;\n const averageSampleDuration = inputDuration\n ? Math.round(inputDuration / (nbSamples - 1))\n : mp4SampleDuration || track.inputTimeScale / 30;\n\n // if fragment are contiguous, detect hole/overlapping between fragments\n if (contiguous) {\n // check timestamp continuity across consecutive fragments (this is to remove inter-fragment gap/hole)\n const delta = firstDTS - nextAvcDts;\n const foundHole = delta > averageSampleDuration;\n const foundOverlap = delta < -1;\n if (foundHole || foundOverlap) {\n if (foundHole) {\n this.logger.warn(\n `${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(\n delta,\n true,\n )} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(\n 3,\n )}`,\n );\n } else {\n this.logger.warn(\n `${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(\n -delta,\n true,\n )} ms (${delta}dts) overlapping between fragments detected at ${timeOffset.toFixed(\n 3,\n )}`,\n );\n }\n if (\n !foundOverlap ||\n nextAvcDts >= inputSamples[0].pts ||\n chromeVersion\n ) {\n firstDTS = nextAvcDts;\n const firstPTS = inputSamples[0].pts - delta;\n if (foundHole) {\n inputSamples[0].dts = firstDTS;\n inputSamples[0].pts = firstPTS;\n } else {\n let isPTSOrderRetained = true;\n for (let i = 0; i < inputSamples.length; i++) {\n if (inputSamples[i].dts > firstPTS && isPTSOrderRetained) {\n break;\n }\n\n const prevPTS = inputSamples[i].pts;\n inputSamples[i].dts -= delta;\n inputSamples[i].pts -= delta;\n\n // check to see if this sample's PTS order has changed\n // relative to the next one\n if (i < inputSamples.length - 1) {\n const nextSamplePTS = inputSamples[i + 1].pts;\n const currentSamplePTS = inputSamples[i].pts;\n\n const currentOrder = nextSamplePTS <= currentSamplePTS;\n const prevOrder = nextSamplePTS <= prevPTS;\n\n isPTSOrderRetained = currentOrder == prevOrder;\n }\n }\n }\n this.logger.log(\n `Video: Initial PTS/DTS adjusted: ${toMsFromMpegTsClock(\n firstPTS,\n true,\n )}/${toMsFromMpegTsClock(\n firstDTS,\n true,\n )}, delta: ${toMsFromMpegTsClock(delta, true)} ms`,\n );\n }\n }\n }\n\n firstDTS = Math.max(0, firstDTS);\n\n let nbNalu = 0;\n let naluLen = 0;\n let dtsStep = firstDTS;\n for (let i = 0; i < nbSamples; i++) {\n // compute total/avc sample length and nb of NAL units\n const sample = inputSamples[i];\n const units = sample.units;\n const nbUnits = units.length;\n let sampleLen = 0;\n for (let j = 0; j < nbUnits; j++) {\n sampleLen += units[j].data.length;\n }\n\n naluLen += sampleLen;\n nbNalu += nbUnits;\n sample.length = sampleLen;\n\n // ensure sample monotonic DTS\n if (sample.dts < dtsStep) {\n sample.dts = dtsStep;\n dtsStep += (averageSampleDuration / 4) | 0 || 1;\n } else {\n dtsStep = sample.dts;\n }\n\n minPTS = Math.min(sample.pts, minPTS);\n maxPTS = Math.max(sample.pts, maxPTS);\n }\n lastDTS = inputSamples[nbSamples - 1].dts;\n\n /* concatenate the video data and construct the mdat in place\n (need 8 more bytes to fill length and mpdat type) */\n const mdatSize = naluLen + 4 * nbNalu + 8;\n let mdat;\n try {\n mdat = new Uint8Array(mdatSize);\n } catch (err) {\n this.observer.emit(Events.ERROR, Events.ERROR, {\n type: ErrorTypes.MUX_ERROR,\n details: ErrorDetails.REMUX_ALLOC_ERROR,\n fatal: false,\n error: err,\n bytes: mdatSize,\n reason: `fail allocating video mdat ${mdatSize}`,\n });\n return;\n }\n const view = new DataView(mdat.buffer);\n view.setUint32(0, mdatSize);\n mdat.set(MP4.types.mdat, 4);\n\n let stretchedLastFrame = false;\n let minDtsDelta = Number.POSITIVE_INFINITY;\n let minPtsDelta = Number.POSITIVE_INFINITY;\n let maxDtsDelta = Number.NEGATIVE_INFINITY;\n let maxPtsDelta = Number.NEGATIVE_INFINITY;\n for (let i = 0; i < nbSamples; i++) {\n const VideoSample = inputSamples[i];\n const VideoSampleUnits = VideoSample.units;\n let mp4SampleLength = 0;\n // convert NALU bitstream to MP4 format (prepend NALU with size field)\n for (let j = 0, nbUnits = VideoSampleUnits.length; j < nbUnits; j++) {\n const unit = VideoSampleUnits[j];\n const unitData = unit.data;\n const unitDataLen = unit.data.byteLength;\n view.setUint32(offset, unitDataLen);\n offset += 4;\n mdat.set(unitData, offset);\n offset += unitDataLen;\n mp4SampleLength += 4 + unitDataLen;\n }\n\n // expected sample duration is the Decoding Timestamp diff of consecutive samples\n let ptsDelta;\n if (i < nbSamples - 1) {\n mp4SampleDuration = inputSamples[i + 1].dts - VideoSample.dts;\n ptsDelta = inputSamples[i + 1].pts - VideoSample.pts;\n } else {\n const config = this.config;\n const lastFrameDuration =\n i > 0\n ? VideoSample.dts - inputSamples[i - 1].dts\n : averageSampleDuration;\n ptsDelta =\n i > 0\n ? VideoSample.pts - inputSamples[i - 1].pts\n : averageSampleDuration;\n if (config.stretchShortVideoTrack && this.nextAudioPts !== null) {\n // In some cases, a segment's audio track duration may exceed the video track duration.\n // Since we've already remuxed audio, and we know how long the audio track is, we look to\n // see if the delta to the next segment is longer than maxBufferHole.\n // If so, playback would potentially get stuck, so we artificially inflate\n // the duration of the last frame to minimize any potential gap between segments.\n const gapTolerance = Math.floor(config.maxBufferHole * timeScale);\n const deltaToFrameEnd =\n (audioTrackLength\n ? minPTS + audioTrackLength * timeScale\n : this.nextAudioPts) - VideoSample.pts;\n if (deltaToFrameEnd > gapTolerance) {\n // We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video\n // frame overlap. maxBufferHole should be >> lastFrameDuration anyway.\n mp4SampleDuration = deltaToFrameEnd - lastFrameDuration;\n if (mp4SampleDuration < 0) {\n mp4SampleDuration = lastFrameDuration;\n } else {\n stretchedLastFrame = true;\n }\n this.logger.log(\n `[mp4-remuxer]: It is approximately ${\n deltaToFrameEnd / 90\n } ms to the next segment; using duration ${\n mp4SampleDuration / 90\n } ms for the last video frame.`,\n );\n } else {\n mp4SampleDuration = lastFrameDuration;\n }\n } else {\n mp4SampleDuration = lastFrameDuration;\n }\n }\n const compositionTimeOffset = Math.round(\n VideoSample.pts - VideoSample.dts,\n );\n minDtsDelta = Math.min(minDtsDelta, mp4SampleDuration);\n maxDtsDelta = Math.max(maxDtsDelta, mp4SampleDuration);\n minPtsDelta = Math.min(minPtsDelta, ptsDelta);\n maxPtsDelta = Math.max(maxPtsDelta, ptsDelta);\n\n outputSamples.push(\n createMp4Sample(\n VideoSample.key,\n mp4SampleDuration,\n mp4SampleLength,\n compositionTimeOffset,\n ),\n );\n }\n\n if (outputSamples.length) {\n if (chromeVersion) {\n if (chromeVersion < 70) {\n // Chrome workaround, mark first sample as being a Random Access Point (keyframe) to avoid sourcebuffer append issue\n // https://code.google.com/p/chromium/issues/detail?id=229412\n const flags = outputSamples[0].flags;\n flags.dependsOn = 2;\n flags.isNonSync = 0;\n }\n } else if (safariWebkitVersion) {\n // Fix for \"CNN special report, with CC\" in test-streams (Safari browser only)\n // Ignore DTS when frame durations are irregular. Safari MSE does not handle this leading to gaps.\n if (\n maxPtsDelta - minPtsDelta < maxDtsDelta - minDtsDelta &&\n averageSampleDuration / maxDtsDelta < 0.025 &&\n outputSamples[0].cts === 0\n ) {\n this.logger.warn(\n 'Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.',\n );\n let dts = firstDTS;\n for (let i = 0, len = outputSamples.length; i < len; i++) {\n const nextDts = dts + outputSamples[i].duration;\n const pts = dts + outputSamples[i].cts;\n if (i < len - 1) {\n const nextPts = nextDts + outputSamples[i + 1].cts;\n outputSamples[i].duration = nextPts - pts;\n } else {\n outputSamples[i].duration = i\n ? outputSamples[i - 1].duration\n : averageSampleDuration;\n }\n outputSamples[i].cts = 0;\n dts = nextDts;\n }\n }\n }\n }\n // next AVC/HEVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)\n mp4SampleDuration =\n stretchedLastFrame || !mp4SampleDuration\n ? averageSampleDuration\n : mp4SampleDuration;\n this.nextAvcDts = nextAvcDts = lastDTS + mp4SampleDuration;\n this.videoSampleDuration = mp4SampleDuration;\n this.isVideoContiguous = true;\n const moof = MP4.moof(\n track.sequenceNumber++,\n firstDTS,\n Object.assign(track, {\n samples: outputSamples,\n }),\n );\n const type: SourceBufferName = 'video';\n const data = {\n data1: moof,\n data2: mdat,\n startPTS: minPTS / timeScale,\n endPTS: (maxPTS + mp4SampleDuration) / timeScale,\n startDTS: firstDTS / timeScale,\n endDTS: (nextAvcDts as number) / timeScale,\n type,\n hasAudio: false,\n hasVideo: true,\n nb: outputSamples.length,\n dropped: track.dropped,\n };\n track.samples = [];\n track.dropped = 0;\n return data;\n }\n\n getSamplesPerFrame(track: DemuxedAudioTrack) {\n switch (track.segmentCodec) {\n case 'mp3':\n return MPEG_AUDIO_SAMPLE_PER_FRAME;\n case 'ac3':\n return AC3_SAMPLES_PER_FRAME;\n default:\n return AAC_SAMPLES_PER_FRAME;\n }\n }\n\n remuxAudio(\n track: DemuxedAudioTrack,\n timeOffset: number,\n contiguous: boolean,\n accurateTimeOffset: boolean,\n videoTimeOffset?: number,\n ): RemuxedTrack | undefined {\n const inputTimeScale: number = track.inputTimeScale;\n const mp4timeScale: number = track.samplerate\n ? track.samplerate\n : inputTimeScale;\n const scaleFactor: number = inputTimeScale / mp4timeScale;\n const mp4SampleDuration: number = this.getSamplesPerFrame(track);\n const inputSampleDuration: number = mp4SampleDuration * scaleFactor;\n const initPTS = this._initPTS as RationalTimestamp;\n const rawMPEG: boolean =\n track.segmentCodec === 'mp3' && this.typeSupported.mpeg;\n const outputSamples: Array<Mp4Sample> = [];\n const alignedWithVideo = videoTimeOffset !== undefined;\n\n let inputSamples: Array<AudioSample> = track.samples;\n let offset: number = rawMPEG ? 0 : 8;\n let nextAudioPts: number = this.nextAudioPts || -1;\n\n // window.audioSamples ? window.audioSamples.push(inputSamples.map(s => s.pts)) : (window.audioSamples = [inputSamples.map(s => s.pts)]);\n\n // for audio samples, also consider consecutive fragments as being contiguous (even if a level switch occurs),\n // for sake of clarity:\n // consecutive fragments are frags with\n // - less than 100ms gaps between new time offset (if accurate) and next expected PTS OR\n // - less than 20 audio frames distance\n // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)\n // this helps ensuring audio continuity\n // and this also avoids audio glitches/cut when switching quality, or reporting wrong duration on first audio frame\n const timeOffsetMpegTS = timeOffset * inputTimeScale;\n const initTime = (initPTS.baseTime * inputTimeScale) / initPTS.timescale;\n this.isAudioContiguous = contiguous =\n contiguous ||\n ((inputSamples.length &&\n nextAudioPts > 0 &&\n ((accurateTimeOffset &&\n Math.abs(timeOffsetMpegTS - nextAudioPts) < 9000) ||\n Math.abs(\n normalizePts(inputSamples[0].pts - initTime, timeOffsetMpegTS) -\n nextAudioPts,\n ) <\n 20 * inputSampleDuration)) as boolean);\n\n // compute normalized PTS\n inputSamples.forEach(function (sample) {\n sample.pts = normalizePts(sample.pts - initTime, timeOffsetMpegTS);\n });\n\n if (!contiguous || nextAudioPts < 0) {\n // filter out sample with negative PTS that are not playable anyway\n // if we don't remove these negative samples, they will shift all audio samples forward.\n // leading to audio overlap between current / next fragment\n inputSamples = inputSamples.filter((sample) => sample.pts >= 0);\n\n // in case all samples have negative PTS, and have been filtered out, return now\n if (!inputSamples.length) {\n return;\n }\n\n if (videoTimeOffset === 0) {\n // Set the start to 0 to match video so that start gaps larger than inputSampleDuration are filled with silence\n nextAudioPts = 0;\n } else if (accurateTimeOffset && !alignedWithVideo) {\n // When not seeking, not live, and LevelDetails.PTSKnown, use fragment start as predicted next audio PTS\n nextAudioPts = Math.max(0, timeOffsetMpegTS);\n } else {\n // if frags are not contiguous and if we cant trust time offset, let's use first sample PTS as next audio PTS\n nextAudioPts = inputSamples[0].pts;\n }\n }\n\n // If the audio track is missing samples, the frames seem to get \"left-shifted\" within the\n // resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment.\n // In an effort to prevent this from happening, we inject frames here where there are gaps.\n // When possible, we inject a silent frame; when that's not possible, we duplicate the last\n // frame.\n\n if (track.segmentCodec === 'aac') {\n const maxAudioFramesDrift = this.config.maxAudioFramesDrift;\n for (let i = 0, nextPts = nextAudioPts; i < inputSamples.length; i++) {\n // First, let's see how far off this frame is from where we expect it to be\n const sample = inputSamples[i];\n const pts = sample.pts;\n const delta = pts - nextPts;\n const duration = Math.abs((1000 * delta) / inputTimeScale);\n\n // When remuxing with video, if we're overlapping by more than a duration, drop this sample to stay in sync\n if (\n delta <= -maxAudioFramesDrift * inputSampleDuration &&\n alignedWithVideo\n ) {\n if (i === 0) {\n this.logger.warn(\n `Audio frame @ ${(pts / inputTimeScale).toFixed(\n 3,\n )}s overlaps nextAudioPts by ${Math.round(\n (1000 * delta) / inputTimeScale,\n )} ms.`,\n );\n this.nextAudioPts = nextAudioPts = nextPts = pts;\n }\n } // eslint-disable-line brace-style\n\n // Insert missing frames if:\n // 1: We're more than maxAudioFramesDrift frame away\n // 2: Not more than MAX_SILENT_FRAME_DURATION away\n // 3: currentTime (aka nextPtsNorm) is not 0\n // 4: remuxing with video (videoTimeOffset !== undefined)\n else if (\n delta >= maxAudioFramesDrift * inputSampleDuration &&\n duration < MAX_SILENT_FRAME_DURATION &&\n alignedWithVideo\n ) {\n let missing = Math.round(delta / inputSampleDuration);\n // Adjust nextPts so that silent samples are aligned with media pts. This will prevent media samples from\n // later being shifted if nextPts is based on timeOffset and delta is not a multiple of inputSampleDuration.\n nextPts = pts - missing * inputSampleDuration;\n if (nextPts < 0) {\n missing--;\n nextPts += inputSampleDuration;\n }\n if (i === 0) {\n this.nextAudioPts = nextAudioPts = nextPts;\n }\n this.logger.warn(\n `[mp4-remuxer]: Injecting ${missing} audio frame @ ${(\n nextPts / inputTimeScale\n ).toFixed(3)}s due to ${Math.round(\n (1000 * delta) / inputTimeScale,\n )} ms gap.`,\n );\n for (let j = 0; j < missing; j++) {\n const newStamp = Math.max(nextPts as number, 0);\n let fillFrame = AAC.getSilentFrame(\n track.parsedCodec || track.manifestCodec || track.codec,\n track.channelCount,\n );\n if (!fillFrame) {\n this.logger.log(\n '[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.',\n );\n fillFrame = sample.unit.subarray();\n }\n inputSamples.splice(i, 0, {\n unit: fillFrame,\n pts: newStamp,\n });\n nextPts += inputSampleDuration;\n i++;\n }\n }\n sample.pts = nextPts;\n nextPts += inputSampleDuration;\n }\n }\n let firstPTS: number | null = null;\n let lastPTS: number | null = null;\n let mdat: any;\n let mdatSize: number = 0;\n let sampleLength: number = inputSamples.length;\n while (sampleLength--) {\n mdatSize += inputSamples[sampleLength].unit.byteLength;\n }\n for (let j = 0, nbSamples = inputSamples.length; j < nbSamples; j++) {\n const audioSample = inputSamples[j];\n const unit = audioSample.unit;\n let pts = audioSample.pts;\n if (lastPTS !== null) {\n // If we have more than one sample, set the duration of the sample to the \"real\" duration; the PTS diff with\n // the previous sample\n const prevSample = outputSamples[j - 1];\n prevSample.duration = Math.round((pts - lastPTS) / scaleFactor);\n } else {\n if (contiguous && track.segmentCodec === 'aac') {\n // set PTS/DTS to expected PTS/DTS\n pts = nextAudioPts;\n }\n // remember first PTS of our audioSamples\n firstPTS = pts;\n if (mdatSize > 0) {\n /* concatenate the audio data and construct the mdat in place\n (need 8 more bytes to fill length and mdat type) */\n mdatSize += offset;\n try {\n mdat = new Uint8Array(mdatSize);\n } catch (err) {\n this.observer.emit(Events.ERROR, Events.ERROR, {\n type: ErrorTypes.MUX_ERROR,\n details: ErrorDetails.REMUX_ALLOC_ERROR,\n fatal: false,\n error: err,\n bytes: mdatSize,\n reason: `fail allocating audio mdat ${mdatSize}`,\n });\n return;\n }\n if (!rawMPEG) {\n const view = new DataView(mdat.buffer);\n view.setUint32(0, mdatSize);\n mdat.set(MP4.types.mdat, 4);\n }\n } else {\n // no audio samples\n return;\n }\n }\n mdat.set(unit, offset);\n const unitLen = unit.byteLength;\n offset += unitLen;\n // Default the sample's duration to the computed mp4SampleDuration, which will either be 1024 for AAC or 1152 for MPEG\n // In the case that we have 1 sample, this will be the duration. If we have more than one sample, the duration\n // becomes the PTS diff with the previous sample\n outputSamples.push(createMp4Sample(true, mp4SampleDuration, unitLen, 0));\n lastPTS = pts;\n }\n\n // We could end up with no audio samples if all input samples were overlapping with the previously remuxed ones\n const nbSamples = outputSamples.length;\n if (!nbSamples) {\n return;\n }\n\n // The next audio sample PTS should be equal to last sample PTS + duration\n const lastSample = outputSamples[outputSamples.length - 1];\n this.nextAudioPts = nextAudioPts =\n lastPTS! + scaleFactor * lastSample.duration;\n\n // Set the track samples from inputSamples to outputSamples before remuxing\n const moof = rawMPEG\n ? new Uint8Array(0)\n : MP4.moof(\n track.sequenceNumber++,\n firstPTS! / scaleFactor,\n Object.assign({}, track, { samples: outputSamples }),\n );\n\n // Clear the track samples. This also clears the samples array in the demuxer, since the reference is shared\n track.samples = [];\n const start = firstPTS! / inputTimeScale;\n const end = nextAudioPts / inputTimeScale;\n const type: SourceBufferName = 'audio';\n const audioData = {\n data1: moof,\n data2: mdat,\n startPTS: start,\n endPTS: end,\n startDTS: start,\n endDTS: end,\n type,\n hasAudio: true,\n hasVideo: false,\n nb: nbSamples,\n };\n\n this.isAudioContiguous = true;\n return audioData;\n }\n}\n\nexport function normalizePts(value: number, reference: number | null): number {\n let offset;\n if (reference === null) {\n return value;\n }\n\n if (reference < value) {\n // - 2^33\n offset = -8589934592;\n } else {\n // + 2^33\n offset = 8589934592;\n }\n /* PTS is 33bit (from 0 to 2^33 -1)\n if diff between value and reference is bigger than half of the amplitude (2^32) then it means that\n PTS looping occured. fill the gap */\n while (Math.abs(value - reference) > 4294967296) {\n value += offset;\n }\n\n return value;\n}\n\nfunction findKeyframeIndex(samples: Array<VideoSample>): number {\n for (let i = 0; i < samples.length; i++) {\n if (samples[i].key) {\n return i;\n }\n }\n return -1;\n}\n\nexport function flushTextTrackMetadataCueSamples(\n track: DemuxedMetadataTrack,\n timeOffset: number,\n initPTS: RationalTimestamp,\n initDTS: RationalTimestamp,\n): RemuxedMetadata | undefined {\n const length = track.samples.length;\n if (!length) {\n return;\n }\n const inputTimeScale = track.inputTimeScale;\n for (let index = 0; index < length; index++) {\n const sample = track.samples[index];\n // setting id3 pts, dts to relative time\n // using this._initPTS and this._initDTS to calculate relative time\n sample.pts =\n normalizePts(\n sample.pts - (initPTS.baseTime * inputTimeScale) / initPTS.timescale,\n timeOffset * inputTimeScale,\n ) / inputTimeScale;\n sample.dts =\n normalizePts(\n sample.dts - (initDTS.baseTime * inputTimeScale) / initDTS.timescale,\n timeOffset * inputTimeScale,\n ) / inputTimeScale;\n }\n const samples = track.samples;\n track.samples = [];\n return {\n samples,\n };\n}\n\nexport function flushTextTrackUserdataCueSamples(\n track: DemuxedUserdataTrack,\n timeOffset: number,\n initPTS: RationalTimestamp,\n): RemuxedUserdata | undefined {\n const length = track.samples.length;\n if (!length) {\n return;\n }\n\n const inputTimeScale = track.inputTimeScale;\n for (let index = 0; index < length; index++) {\n const sample = track.samples[index];\n // setting text pts, dts to relative time\n // using this._initPTS and this._initDTS to calculate relative time\n sample.pts =\n normalizePts(\n sample.pts - (initPTS.baseTime * inputTimeScale) / initPTS.timescale,\n timeOffset * inputTimeScale,\n ) / inputTimeScale;\n }\n track.samples.sort((a, b) => a.pts - b.pts);\n const samples = track.samples;\n track.samples = [];\n return {\n samples,\n };\n}\n","import type { BaseTrackSet } from '../types/buffer';\n\nexport function getMediaSource(\n preferManagedMediaSource = true,\n): typeof MediaSource | undefined {\n if (typeof self === 'undefined') return undefined;\n const mms =\n (preferManagedMediaSource || !self.MediaSource) &&\n ((self as any).ManagedMediaSource as undefined | typeof MediaSource);\n return (\n mms ||\n self.MediaSource ||\n ((self as any).WebKitMediaSource as typeof MediaSource)\n );\n}\n\nexport function isManagedMediaSource(source: typeof MediaSource | undefined) {\n return (\n typeof self !== 'undefined' && source === (self as any).ManagedMediaSource\n );\n}\n\nexport function isCompatibleTrackChange(\n currentTracks: BaseTrackSet,\n requiredTracks: BaseTrackSet,\n): boolean {\n const trackNames = Object.keys(currentTracks);\n const requiredTrackNames = Object.keys(requiredTracks);\n const trackCount = trackNames.length;\n const requiredTrackCount = requiredTrackNames.length;\n return (\n !trackCount ||\n !requiredTrackCount ||\n (trackCount === requiredTrackCount &&\n !trackNames.some((name) => requiredTrackNames.indexOf(name) === -1))\n );\n}\n","import { getMediaSource } from './mediasource-helper';\n\n// from http://mp4ra.org/codecs.html\n// values indicate codec selection preference (lower is higher priority)\nexport const sampleEntryCodesISO = {\n audio: {\n a3ds: 1,\n 'ac-3': 0.95,\n 'ac-4': 1,\n alac: 0.9,\n alaw: 1,\n dra1: 1,\n 'dts+': 1,\n 'dts-': 1,\n dtsc: 1,\n dtse: 1,\n dtsh: 1,\n 'ec-3': 0.9,\n enca: 1,\n fLaC: 0.9, // MP4-RA listed codec entry for FLAC\n flac: 0.9, // legacy browser codec name for FLAC\n FLAC: 0.9, // some manifests may list \"FLAC\" with Apple's tools\n g719: 1,\n g726: 1,\n m4ae: 1,\n mha1: 1,\n mha2: 1,\n mhm1: 1,\n mhm2: 1,\n mlpa: 1,\n mp4a: 1,\n 'raw ': 1,\n Opus: 1,\n opus: 1, // browsers expect this to be lowercase despite MP4RA says 'Opus'\n samr: 1,\n sawb: 1,\n sawp: 1,\n sevc: 1,\n sqcp: 1,\n ssmv: 1,\n twos: 1,\n ulaw: 1,\n },\n video: {\n avc1: 1,\n avc2: 1,\n avc3: 1,\n avc4: 1,\n avcp: 1,\n av01: 0.8,\n drac: 1,\n dva1: 1,\n dvav: 1,\n dvh1: 0.7,\n dvhe: 0.7,\n encv: 1,\n hev1: 0.75,\n hvc1: 0.75,\n mjp2: 1,\n mp4v: 1,\n mvc1: 1,\n mvc2: 1,\n mvc3: 1,\n mvc4: 1,\n resv: 1,\n rv60: 1,\n s263: 1,\n svc1: 1,\n svc2: 1,\n 'vc-1': 1,\n vp08: 1,\n vp09: 0.9,\n },\n text: {\n stpp: 1,\n wvtt: 1,\n },\n} as const;\n\nexport type CodecType = 'audio' | 'video';\n\nexport function isCodecType(codec: string, type: CodecType): boolean {\n const typeCodes = sampleEntryCodesISO[type];\n return !!typeCodes && !!typeCodes[codec.slice(0, 4)];\n}\n\nexport function areCodecsMediaSourceSupported(\n codecs: string,\n type: CodecType,\n preferManagedMediaSource = true,\n): boolean {\n return !codecs\n .split(',')\n .some(\n (codec) =>\n !isCodecMediaSourceSupported(codec, type, preferManagedMediaSource),\n );\n}\n\nfunction isCodecMediaSourceSupported(\n codec: string,\n type: CodecType,\n preferManagedMediaSource = true,\n): boolean {\n const MediaSource = getMediaSource(preferManagedMediaSource);\n return MediaSource?.isTypeSupported(mimeTypeForCodec(codec, type)) ?? false;\n}\n\nexport function mimeTypeForCodec(codec: string, type: CodecType): string {\n return `${type}/mp4;codecs=${codec}`;\n}\n\nexport function videoCodecPreferenceValue(\n videoCodec: string | undefined,\n): number {\n if (videoCodec) {\n const fourCC = videoCodec.substring(0, 4);\n return sampleEntryCodesISO.video[fourCC];\n }\n return 2;\n}\n\nexport function codecsSetSelectionPreferenceValue(codecSet: string): number {\n return codecSet.split(',').reduce((num, fourCC) => {\n const preferenceValue = sampleEntryCodesISO.video[fourCC];\n if (preferenceValue) {\n return (preferenceValue * 2 + num) / (num ? 3 : 2);\n }\n return (sampleEntryCodesISO.audio[fourCC] + num) / (num ? 2 : 1);\n }, 0);\n}\n\ninterface CodecNameCache {\n flac?: string;\n opus?: string;\n}\n\nconst CODEC_COMPATIBLE_NAMES: CodecNameCache = {};\n\ntype LowerCaseCodecType = 'flac' | 'opus';\n\nfunction getCodecCompatibleNameLower(\n lowerCaseCodec: LowerCaseCodecType,\n preferManagedMediaSource = true,\n): string {\n if (CODEC_COMPATIBLE_NAMES[lowerCaseCodec]) {\n return CODEC_COMPATIBLE_NAMES[lowerCaseCodec]!;\n }\n\n const codecsToCheck = {\n // Idealy fLaC and Opus would be first (spec-compliant) but\n // some browsers will report that fLaC is supported then fail.\n // see: https://bugs.chromium.org/p/chromium/issues/detail?id=1422728\n flac: ['flac', 'fLaC', 'FLAC'],\n opus: ['opus', 'Opus'],\n // Replace audio codec info if browser does not support mp4a.40.34,\n // and demuxer can fallback to 'audio/mpeg' or 'audio/mp4;codecs=\"mp3\"'\n 'mp4a.40.34': ['mp3'],\n }[lowerCaseCodec];\n\n for (let i = 0; i < codecsToCheck.length; i++) {\n if (\n isCodecMediaSourceSupported(\n codecsToCheck[i],\n 'audio',\n preferManagedMediaSource,\n )\n ) {\n CODEC_COMPATIBLE_NAMES[lowerCaseCodec] = codecsToCheck[i];\n return codecsToCheck[i];\n } else if (\n codecsToCheck[i] === 'mp3' &&\n getMediaSource(preferManagedMediaSource)?.isTypeSupported('audio/mpeg')\n ) {\n return '';\n }\n }\n\n return lowerCaseCodec;\n}\n\nconst AUDIO_CODEC_REGEXP = /flac|opus|mp4a\\.40\\.34/i;\nexport function getCodecCompatibleName(\n codec: string,\n preferManagedMediaSource = true,\n): string {\n return codec.replace(AUDIO_CODEC_REGEXP, (m) =>\n getCodecCompatibleNameLower(\n m.toLowerCase() as LowerCaseCodecType,\n preferManagedMediaSource,\n ),\n );\n}\n\nexport function pickMostCompleteCodecName(\n parsedCodec: string | undefined,\n levelCodec: string | undefined,\n): string | undefined {\n // Parsing of mp4a codecs strings in mp4-tools from media is incomplete as of d8c6c7a\n // so use level codec is parsed codec is unavailable or incomplete\n if (\n parsedCodec &&\n (parsedCodec.length > 4 ||\n ['ac-3', 'ec-3', 'alac', 'fLaC', 'Opus'].indexOf(parsedCodec) !== -1)\n ) {\n return parsedCodec;\n }\n if (levelCodec) {\n const levelCodecs = levelCodec.split(',');\n if (levelCodecs.length > 1) {\n if (parsedCodec) {\n for (let i = levelCodecs.length; i--; ) {\n if (levelCodecs[i].substring(0, 4) === parsedCodec.substring(0, 4)) {\n return levelCodecs[i];\n }\n }\n }\n return levelCodecs[0];\n }\n }\n return levelCodec || parsedCodec;\n}\n\nexport function convertAVC1ToAVCOTI(videoCodecs: string): string {\n // Convert avc1 codec string from RFC-4281 to RFC-6381 for MediaSource.isTypeSupported\n // Examples: avc1.66.30 to avc1.42001e and avc1.77.30,avc1.66.30 to avc1.4d001e,avc1.42001e.\n const codecs = videoCodecs.split(',');\n for (let i = 0; i < codecs.length; i++) {\n const avcdata = codecs[i].split('.');\n if (avcdata.length > 2) {\n let result = avcdata.shift() + '.';\n result += parseInt(avcdata.shift() as string).toString(16);\n result += (\n '000' + parseInt(avcdata.shift() as string).toString(16)\n ).slice(-4);\n codecs[i] = result;\n }\n }\n return codecs.join(',');\n}\n\nexport function fillInMissingAV01Params(videoCodec: string): string {\n // Used to fill in incomplete AV1 playlist CODECS strings for mediaCapabilities.decodingInfo queries\n if (videoCodec.startsWith('av01.')) {\n const av1params = videoCodec.split('.');\n const placeholders = ['0', '111', '01', '01', '01', '0'];\n for (let i = av1params.length; i > 4 && i < 10; i++) {\n av1params[i] = placeholders[i - 4];\n }\n return av1params.join('.');\n }\n return videoCodec;\n}\n\nexport interface TypeSupported {\n mpeg: boolean;\n mp3: boolean;\n ac3: boolean;\n}\n\nexport function getM2TSSupportedAudioTypes(\n preferManagedMediaSource: boolean,\n): TypeSupported {\n const MediaSource = getMediaSource(preferManagedMediaSource) || {\n isTypeSupported: () => false,\n };\n return {\n mpeg: MediaSource.isTypeSupported('audio/mpeg'),\n mp3: MediaSource.isTypeSupported('audio/mp4; codecs=\"mp3\"'),\n ac3: __USE_M2TS_ADVANCED_CODECS__\n ? MediaSource.isTypeSupported('audio/mp4; codecs=\"ac-3\"')\n : false,\n };\n}\n","import {\n flushTextTrackMetadataCueSamples,\n flushTextTrackUserdataCueSamples,\n} from './mp4-remuxer';\nimport { ElementaryStreamTypes } from '../loader/fragment';\nimport { getCodecCompatibleName } from '../utils/codecs';\nimport { type ILogger, logger } from '../utils/logger';\nimport { patchEncyptionData } from '../utils/mp4-tools';\nimport {\n getDuration,\n getStartDTS,\n offsetStartDTS,\n parseInitSegment,\n} from '../utils/mp4-tools';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport type { DecryptData } from '../loader/level-key';\nimport type {\n DemuxedAudioTrack,\n DemuxedMetadataTrack,\n DemuxedUserdataTrack,\n PassthroughTrack,\n} from '../types/demuxer';\nimport type {\n InitSegmentData,\n RemuxedTrack,\n Remuxer,\n RemuxerResult,\n} from '../types/remuxer';\nimport type { TrackSet } from '../types/track';\nimport type { TypeSupported } from '../utils/codecs';\nimport type { InitData, InitDataTrack } from '../utils/mp4-tools';\nimport type { RationalTimestamp } from '../utils/timescale-conversion';\n\nclass PassThroughRemuxer implements Remuxer {\n private readonly logger: ILogger;\n private emitInitSegment: boolean = false;\n private audioCodec?: string;\n private videoCodec?: string;\n private initData?: InitData;\n private initPTS: RationalTimestamp | null = null;\n private initTracks?: TrackSet;\n private lastEndTime: number | null = null;\n\n constructor(\n observer: HlsEventEmitter,\n config: HlsConfig,\n typeSupported: TypeSupported,\n logger: ILogger,\n ) {\n this.logger = logger;\n }\n\n public destroy() {}\n\n public resetTimeStamp(defaultInitPTS: RationalTimestamp | null) {\n this.initPTS = defaultInitPTS;\n this.lastEndTime = null;\n }\n\n public resetNextTimestamp() {\n this.lastEndTime = null;\n }\n\n public resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n decryptdata: DecryptData | null,\n ) {\n this.audioCodec = audioCodec;\n this.videoCodec = videoCodec;\n this.generateInitSegment(patchEncyptionData(initSegment, decryptdata));\n this.emitInitSegment = true;\n }\n\n private generateInitSegment(initSegment: Uint8Array | undefined): void {\n let { audioCodec, videoCodec } = this;\n if (!initSegment?.byteLength) {\n this.initTracks = undefined;\n this.initData = undefined;\n return;\n }\n const initData = (this.initData = parseInitSegment(initSegment));\n\n // Get codec from initSegment\n if (initData.audio) {\n audioCodec = getParsedTrackCodec(\n initData.audio,\n ElementaryStreamTypes.AUDIO,\n );\n }\n\n if (initData.video) {\n videoCodec = getParsedTrackCodec(\n initData.video,\n ElementaryStreamTypes.VIDEO,\n );\n }\n\n const tracks: TrackSet = {};\n if (initData.audio && initData.video) {\n tracks.audiovideo = {\n container: 'video/mp4',\n codec: audioCodec + ',' + videoCodec,\n initSegment,\n id: 'main',\n };\n } else if (initData.audio) {\n tracks.audio = {\n container: 'audio/mp4',\n codec: audioCodec,\n initSegment,\n id: 'audio',\n };\n } else if (initData.video) {\n tracks.video = {\n container: 'video/mp4',\n codec: videoCodec,\n initSegment,\n id: 'main',\n };\n } else {\n this.logger.warn(\n '[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.',\n );\n }\n this.initTracks = tracks;\n }\n\n public remux(\n audioTrack: DemuxedAudioTrack,\n videoTrack: PassthroughTrack,\n id3Track: DemuxedMetadataTrack,\n textTrack: DemuxedUserdataTrack,\n timeOffset: number,\n accurateTimeOffset: boolean,\n ): RemuxerResult {\n let { initPTS, lastEndTime } = this;\n const result: RemuxerResult = {\n audio: undefined,\n video: undefined,\n text: textTrack,\n id3: id3Track,\n initSegment: undefined,\n };\n\n // If we haven't yet set a lastEndDTS, or it was reset, set it to the provided timeOffset. We want to use the\n // lastEndDTS over timeOffset whenever possible; during progressive playback, the media source will not update\n // the media duration (which is what timeOffset is provided as) before we need to process the next chunk.\n if (!Number.isFinite(lastEndTime!)) {\n lastEndTime = this.lastEndTime = timeOffset || 0;\n }\n\n // The binary segment data is added to the videoTrack in the mp4demuxer. We don't check to see if the data is only\n // audio or video (or both); adding it to video was an arbitrary choice.\n const data = videoTrack.samples;\n if (!data?.length) {\n return result;\n }\n\n const initSegment: InitSegmentData = {\n initPTS: undefined,\n timescale: 1,\n };\n let initData = this.initData;\n if (!initData?.length) {\n this.generateInitSegment(data);\n initData = this.initData;\n }\n if (!initData?.length) {\n // We can't remux if the initSegment could not be generated\n this.logger.warn(\n '[passthrough-remuxer.ts]: Failed to generate initSegment.',\n );\n return result;\n }\n if (this.emitInitSegment) {\n initSegment.tracks = this.initTracks as TrackSet;\n this.emitInitSegment = false;\n }\n\n const duration = getDuration(data, initData);\n const startDTS = getStartDTS(initData, data);\n const decodeTime = startDTS === null ? timeOffset : startDTS;\n if (\n (accurateTimeOffset || !initPTS) &&\n (isInvalidInitPts(initPTS, decodeTime, timeOffset, duration) ||\n initSegment.timescale !== initPTS.timescale)\n ) {\n initSegment.initPTS = decodeTime - timeOffset;\n if (initPTS && initPTS.timescale === 1) {\n this.logger.warn(\n `Adjusting initPTS @${timeOffset} from ${initPTS.baseTime / initPTS.timescale} to ${initSegment.initPTS}`,\n );\n }\n this.initPTS = initPTS = {\n baseTime: initSegment.initPTS,\n timescale: 1,\n };\n }\n\n const startTime = audioTrack\n ? decodeTime - initPTS.baseTime / initPTS.timescale\n : (lastEndTime as number);\n const endTime = startTime + duration;\n offsetStartDTS(initData, data, initPTS.baseTime / initPTS.timescale);\n\n if (duration > 0) {\n this.lastEndTime = endTime;\n } else {\n this.logger.warn('Duration parsed from mp4 should be greater than zero');\n this.resetNextTimestamp();\n }\n\n const hasAudio = !!initData.audio;\n const hasVideo = !!initData.video;\n\n let type: any = '';\n if (hasAudio) {\n type += 'audio';\n }\n\n if (hasVideo) {\n type += 'video';\n }\n\n const track: RemuxedTrack = {\n data1: data,\n startPTS: startTime,\n startDTS: startTime,\n endPTS: endTime,\n endDTS: endTime,\n type,\n hasAudio,\n hasVideo,\n nb: 1,\n dropped: 0,\n };\n\n result.audio = track.type === 'audio' ? track : undefined;\n result.video = track.type !== 'audio' ? track : undefined;\n result.initSegment = initSegment;\n result.id3 = flushTextTrackMetadataCueSamples(\n id3Track,\n timeOffset,\n initPTS,\n initPTS,\n );\n\n if (textTrack.samples.length) {\n result.text = flushTextTrackUserdataCueSamples(\n textTrack,\n timeOffset,\n initPTS,\n );\n }\n\n return result;\n }\n}\n\nfunction isInvalidInitPts(\n initPTS: RationalTimestamp | null,\n startDTS: number,\n timeOffset: number,\n duration: number,\n): initPTS is null {\n if (initPTS === null) {\n return true;\n }\n // InitPTS is invalid when distance from program would be more than segment duration or a minimum of one second\n const minDuration = Math.max(duration, 1);\n const startTime = startDTS - initPTS.baseTime / initPTS.timescale;\n return Math.abs(startTime - timeOffset) > minDuration;\n}\n\nfunction getParsedTrackCodec(\n track: InitDataTrack,\n type: ElementaryStreamTypes.AUDIO | ElementaryStreamTypes.VIDEO,\n): string {\n const parsedCodec = track?.codec;\n if (parsedCodec && parsedCodec.length > 4) {\n return parsedCodec;\n }\n if (type === ElementaryStreamTypes.AUDIO) {\n if (\n parsedCodec === 'ec-3' ||\n parsedCodec === 'ac-3' ||\n parsedCodec === 'alac'\n ) {\n return parsedCodec;\n }\n if (parsedCodec === 'fLaC' || parsedCodec === 'Opus') {\n // Opting not to get `preferManagedMediaSource` from player config for isSupported() check for simplicity\n const preferManagedMediaSource = false;\n return getCodecCompatibleName(parsedCodec, preferManagedMediaSource);\n }\n\n logger.warn(`Unhandled audio codec \"${parsedCodec}\" in mp4 MAP`);\n return parsedCodec || 'mp4a';\n }\n // Provide defaults based on codec type\n // This allows for some playback of some fmp4 playlists without CODECS defined in manifest\n logger.warn(`Unhandled video codec \"${parsedCodec}\" in mp4 MAP`);\n return parsedCodec || 'avc1';\n}\nexport default PassThroughRemuxer;\n","import AACDemuxer from './audio/aacdemuxer';\nimport { AC3Demuxer } from './audio/ac3-demuxer';\nimport MP3Demuxer from './audio/mp3demuxer';\nimport Decrypter from '../crypt/decrypter';\nimport MP4Demuxer from '../demux/mp4demuxer';\nimport TSDemuxer from '../demux/tsdemuxer';\nimport { ErrorDetails, ErrorTypes } from '../errors';\nimport { Events } from '../events';\nimport MP4Remuxer from '../remux/mp4-remuxer';\nimport PassThroughRemuxer from '../remux/passthrough-remuxer';\nimport { PlaylistLevelType } from '../types/loader';\nimport {\n getAesModeFromFullSegmentMethod,\n isFullSegmentEncryption,\n} from '../utils/encryption-methods-util';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport type { DecryptData } from '../loader/level-key';\nimport type { Demuxer, DemuxerResult, KeyData } from '../types/demuxer';\nimport type { Remuxer } from '../types/remuxer';\nimport type { ChunkMetadata, TransmuxerResult } from '../types/transmuxer';\nimport type { TypeSupported } from '../utils/codecs';\nimport type { ILogger } from '../utils/logger';\nimport type { RationalTimestamp } from '../utils/timescale-conversion';\n\nlet now: () => number;\n// performance.now() not available on WebWorker, at least on Safari Desktop\ntry {\n now = self.performance.now.bind(self.performance);\n} catch (err) {\n now = Date.now;\n}\n\ntype MuxConfig =\n | { demux: typeof MP4Demuxer; remux: typeof PassThroughRemuxer }\n | { demux: typeof TSDemuxer; remux: typeof MP4Remuxer }\n | { demux: typeof AC3Demuxer; remux: typeof MP4Remuxer }\n | { demux: typeof AACDemuxer; remux: typeof MP4Remuxer }\n | { demux: typeof MP3Demuxer; remux: typeof MP4Remuxer };\n\nconst muxConfig: MuxConfig[] = [\n { demux: MP4Demuxer, remux: PassThroughRemuxer },\n { demux: TSDemuxer, remux: MP4Remuxer },\n { demux: AACDemuxer, remux: MP4Remuxer },\n { demux: MP3Demuxer, remux: MP4Remuxer },\n];\n\nif (__USE_M2TS_ADVANCED_CODECS__) {\n muxConfig.splice(2, 0, { demux: AC3Demuxer, remux: MP4Remuxer });\n}\n\nexport default class Transmuxer {\n private asyncResult: boolean = false;\n private logger: ILogger;\n private observer: HlsEventEmitter;\n private typeSupported: TypeSupported;\n private config: HlsConfig;\n private id: PlaylistLevelType;\n private demuxer?: Demuxer;\n private remuxer?: Remuxer;\n private decrypter?: Decrypter;\n private probe!: Function;\n private decryptionPromise: Promise<TransmuxerResult> | null = null;\n private transmuxConfig!: TransmuxConfig;\n private currentTransmuxState!: TransmuxState;\n\n constructor(\n observer: HlsEventEmitter,\n typeSupported: TypeSupported,\n config: HlsConfig,\n vendor: string,\n id: PlaylistLevelType,\n logger: ILogger,\n ) {\n this.observer = observer;\n this.typeSupported = typeSupported;\n this.config = config;\n this.id = id;\n this.logger = logger;\n }\n\n configure(transmuxConfig: TransmuxConfig) {\n this.transmuxConfig = transmuxConfig;\n if (this.decrypter) {\n this.decrypter.reset();\n }\n }\n\n push(\n data: ArrayBuffer,\n decryptdata: DecryptData | null,\n chunkMeta: ChunkMetadata,\n state?: TransmuxState,\n ): TransmuxerResult | Promise<TransmuxerResult> {\n const stats = chunkMeta.transmuxing;\n stats.executeStart = now();\n\n let uintData: Uint8Array = new Uint8Array(data);\n const { currentTransmuxState, transmuxConfig } = this;\n if (state) {\n this.currentTransmuxState = state;\n }\n\n const {\n contiguous,\n discontinuity,\n trackSwitch,\n accurateTimeOffset,\n timeOffset,\n initSegmentChange,\n } = state || currentTransmuxState;\n const {\n audioCodec,\n videoCodec,\n defaultInitPts,\n duration,\n initSegmentData,\n } = transmuxConfig;\n\n const keyData = getEncryptionType(uintData, decryptdata);\n if (keyData && isFullSegmentEncryption(keyData.method)) {\n const decrypter = this.getDecrypter();\n const aesMode = getAesModeFromFullSegmentMethod(keyData.method);\n\n // Software decryption is synchronous; webCrypto is not\n if (decrypter.isSync()) {\n // Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached\n // data is handled in the flush() call\n let decryptedData = decrypter.softwareDecrypt(\n uintData,\n keyData.key.buffer,\n keyData.iv.buffer,\n aesMode,\n );\n // For Low-Latency HLS Parts, decrypt in place, since part parsing is expected on push progress\n const loadingParts = chunkMeta.part > -1;\n if (loadingParts) {\n const data = decrypter.flush();\n decryptedData = data ? data.buffer : data;\n }\n if (!decryptedData) {\n stats.executeEnd = now();\n return emptyResult(chunkMeta);\n }\n uintData = new Uint8Array(decryptedData);\n } else {\n this.asyncResult = true;\n this.decryptionPromise = decrypter\n .webCryptoDecrypt(\n uintData,\n keyData.key.buffer,\n keyData.iv.buffer,\n aesMode,\n )\n .then((decryptedData): TransmuxerResult => {\n // Calling push here is important; if flush() is called while this is still resolving, this ensures that\n // the decrypted data has been transmuxed\n const result = this.push(\n decryptedData,\n null,\n chunkMeta,\n ) as TransmuxerResult;\n this.decryptionPromise = null;\n return result;\n });\n return this.decryptionPromise;\n }\n }\n\n const resetMuxers = this.needsProbing(discontinuity, trackSwitch);\n if (resetMuxers) {\n const error = this.configureTransmuxer(uintData);\n if (error) {\n this.logger.warn(`[transmuxer] ${error.message}`);\n this.observer.emit(Events.ERROR, Events.ERROR, {\n type: ErrorTypes.MEDIA_ERROR,\n details: ErrorDetails.FRAG_PARSING_ERROR,\n fatal: false,\n error,\n reason: error.message,\n });\n stats.executeEnd = now();\n return emptyResult(chunkMeta);\n }\n }\n\n if (discontinuity || trackSwitch || initSegmentChange || resetMuxers) {\n this.resetInitSegment(\n initSegmentData,\n audioCodec,\n videoCodec,\n duration,\n decryptdata,\n );\n }\n\n if (discontinuity || initSegmentChange || resetMuxers) {\n this.resetInitialTimestamp(defaultInitPts);\n }\n\n if (!contiguous) {\n this.resetContiguity();\n }\n\n const result = this.transmux(\n uintData,\n keyData,\n timeOffset,\n accurateTimeOffset,\n chunkMeta,\n );\n this.asyncResult = isPromise(result);\n\n const currentState = this.currentTransmuxState;\n\n currentState.contiguous = true;\n currentState.discontinuity = false;\n currentState.trackSwitch = false;\n\n stats.executeEnd = now();\n return result;\n }\n\n // Due to data caching, flush calls can produce more than one TransmuxerResult (hence the Array type)\n flush(\n chunkMeta: ChunkMetadata,\n ): TransmuxerResult[] | Promise<TransmuxerResult[]> {\n const stats = chunkMeta.transmuxing;\n stats.executeStart = now();\n\n const { decrypter, currentTransmuxState, decryptionPromise } = this;\n\n if (decryptionPromise) {\n this.asyncResult = true;\n // Upon resolution, the decryption promise calls push() and returns its TransmuxerResult up the stack. Therefore\n // only flushing is required for async decryption\n return decryptionPromise.then(() => {\n return this.flush(chunkMeta);\n });\n }\n\n const transmuxResults: TransmuxerResult[] = [];\n const { timeOffset } = currentTransmuxState;\n if (decrypter) {\n // The decrypter may have data cached, which needs to be demuxed. In this case we'll have two TransmuxResults\n // This happens in the case that we receive only 1 push call for a segment (either for non-progressive downloads,\n // or for progressive downloads with small segments)\n const decryptedData = decrypter.flush();\n if (decryptedData) {\n // Push always returns a TransmuxerResult if decryptdata is null\n transmuxResults.push(\n this.push(decryptedData.buffer, null, chunkMeta) as TransmuxerResult,\n );\n }\n }\n\n const { demuxer, remuxer } = this;\n if (!demuxer || !remuxer) {\n // If probing failed, then Hls.js has been given content its not able to handle\n stats.executeEnd = now();\n const emptyResults = [emptyResult(chunkMeta)];\n if (this.asyncResult) {\n return Promise.resolve(emptyResults);\n }\n return emptyResults;\n }\n\n const demuxResultOrPromise = demuxer.flush(timeOffset);\n if (isPromise(demuxResultOrPromise)) {\n this.asyncResult = true;\n // Decrypt final SAMPLE-AES samples\n return demuxResultOrPromise.then((demuxResult) => {\n this.flushRemux(transmuxResults, demuxResult, chunkMeta);\n return transmuxResults;\n });\n }\n\n this.flushRemux(transmuxResults, demuxResultOrPromise, chunkMeta);\n if (this.asyncResult) {\n return Promise.resolve(transmuxResults);\n }\n return transmuxResults;\n }\n\n private flushRemux(\n transmuxResults: TransmuxerResult[],\n demuxResult: DemuxerResult,\n chunkMeta: ChunkMetadata,\n ) {\n const { audioTrack, videoTrack, id3Track, textTrack } = demuxResult;\n const { accurateTimeOffset, timeOffset } = this.currentTransmuxState;\n this.logger.log(\n `[transmuxer.ts]: Flushed ${this.id} sn: ${chunkMeta.sn}${\n chunkMeta.part > -1 ? ' part: ' + chunkMeta.part : ''\n } of ${this.id === PlaylistLevelType.MAIN ? 'level' : 'track'} ${chunkMeta.level}`,\n );\n const remuxResult = this.remuxer!.remux(\n audioTrack,\n videoTrack,\n id3Track,\n textTrack,\n timeOffset,\n accurateTimeOffset,\n true,\n this.id,\n );\n transmuxResults.push({\n remuxResult,\n chunkMeta,\n });\n\n chunkMeta.transmuxing.executeEnd = now();\n }\n\n resetInitialTimestamp(defaultInitPts: RationalTimestamp | null) {\n const { demuxer, remuxer } = this;\n if (!demuxer || !remuxer) {\n return;\n }\n demuxer.resetTimeStamp(defaultInitPts);\n remuxer.resetTimeStamp(defaultInitPts);\n }\n\n resetContiguity() {\n const { demuxer, remuxer } = this;\n if (!demuxer || !remuxer) {\n return;\n }\n demuxer.resetContiguity();\n remuxer.resetNextTimestamp();\n }\n\n resetInitSegment(\n initSegmentData: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n decryptdata: DecryptData | null,\n ) {\n const { demuxer, remuxer } = this;\n if (!demuxer || !remuxer) {\n return;\n }\n demuxer.resetInitSegment(\n initSegmentData,\n audioCodec,\n videoCodec,\n trackDuration,\n );\n remuxer.resetInitSegment(\n initSegmentData,\n audioCodec,\n videoCodec,\n decryptdata,\n );\n }\n\n destroy(): void {\n if (this.demuxer) {\n this.demuxer.destroy();\n this.demuxer = undefined;\n }\n if (this.remuxer) {\n this.remuxer.destroy();\n this.remuxer = undefined;\n }\n }\n\n private transmux(\n data: Uint8Array,\n keyData: KeyData | null,\n timeOffset: number,\n accurateTimeOffset: boolean,\n chunkMeta: ChunkMetadata,\n ): TransmuxerResult | Promise<TransmuxerResult> {\n let result: TransmuxerResult | Promise<TransmuxerResult>;\n if (keyData && keyData.method === 'SAMPLE-AES') {\n result = this.transmuxSampleAes(\n data,\n keyData,\n timeOffset,\n accurateTimeOffset,\n chunkMeta,\n );\n } else {\n result = this.transmuxUnencrypted(\n data,\n timeOffset,\n accurateTimeOffset,\n chunkMeta,\n );\n }\n return result;\n }\n\n private transmuxUnencrypted(\n data: Uint8Array,\n timeOffset: number,\n accurateTimeOffset: boolean,\n chunkMeta: ChunkMetadata,\n ): TransmuxerResult {\n const { audioTrack, videoTrack, id3Track, textTrack } = (\n this.demuxer as Demuxer\n ).demux(data, timeOffset, false, !this.config.progressive);\n const remuxResult = this.remuxer!.remux(\n audioTrack,\n videoTrack,\n id3Track,\n textTrack,\n timeOffset,\n accurateTimeOffset,\n false,\n this.id,\n );\n return {\n remuxResult,\n chunkMeta,\n };\n }\n\n private transmuxSampleAes(\n data: Uint8Array,\n decryptData: KeyData,\n timeOffset: number,\n accurateTimeOffset: boolean,\n chunkMeta: ChunkMetadata,\n ): Promise<TransmuxerResult> {\n return (this.demuxer as Demuxer)\n .demuxSampleAes(data, decryptData, timeOffset)\n .then((demuxResult) => {\n const remuxResult = this.remuxer!.remux(\n demuxResult.audioTrack,\n demuxResult.videoTrack,\n demuxResult.id3Track,\n demuxResult.textTrack,\n timeOffset,\n accurateTimeOffset,\n false,\n this.id,\n );\n return {\n remuxResult,\n chunkMeta,\n };\n });\n }\n\n private configureTransmuxer(data: Uint8Array): void | Error {\n const { config, observer, typeSupported } = this;\n // probe for content type\n let mux;\n for (let i = 0, len = muxConfig.length; i < len; i++) {\n if (muxConfig[i].demux?.probe(data, this.logger)) {\n mux = muxConfig[i];\n break;\n }\n }\n if (!mux) {\n return new Error('Failed to find demuxer by probing fragment data');\n }\n // so let's check that current remuxer and demuxer are still valid\n const demuxer = this.demuxer;\n const remuxer = this.remuxer;\n const Remuxer: MuxConfig['remux'] = mux.remux;\n const Demuxer: MuxConfig['demux'] = mux.demux;\n if (!remuxer || !(remuxer instanceof Remuxer)) {\n this.remuxer = new Remuxer(observer, config, typeSupported, this.logger);\n }\n if (!demuxer || !(demuxer instanceof Demuxer)) {\n this.demuxer = new Demuxer(observer, config, typeSupported, this.logger);\n this.probe = Demuxer.probe;\n }\n }\n\n private needsProbing(discontinuity: boolean, trackSwitch: boolean): boolean {\n // in case of continuity change, or track switch\n // we might switch from content type (AAC container to TS container, or TS to fmp4 for example)\n return !this.demuxer || !this.remuxer || discontinuity || trackSwitch;\n }\n\n private getDecrypter(): Decrypter {\n let decrypter = this.decrypter;\n if (!decrypter) {\n decrypter = this.decrypter = new Decrypter(this.config);\n }\n return decrypter;\n }\n}\n\nfunction getEncryptionType(\n data: Uint8Array,\n decryptData: DecryptData | null,\n): KeyData | null {\n let encryptionType: KeyData | null = null;\n if (\n data.byteLength > 0 &&\n decryptData?.key != null &&\n decryptData.iv !== null &&\n decryptData.method != null\n ) {\n encryptionType = decryptData as KeyData;\n }\n return encryptionType;\n}\n\nconst emptyResult = (chunkMeta): TransmuxerResult => ({\n remuxResult: {},\n chunkMeta,\n});\n\nexport function isPromise<T>(p: Promise<T> | any): p is Promise<T> {\n return 'then' in p && p.then instanceof Function;\n}\n\nexport class TransmuxConfig {\n public audioCodec?: string;\n public videoCodec?: string;\n public initSegmentData?: Uint8Array;\n public duration: number;\n public defaultInitPts: RationalTimestamp | null;\n\n constructor(\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n initSegmentData: Uint8Array | undefined,\n duration: number,\n defaultInitPts?: RationalTimestamp,\n ) {\n this.audioCodec = audioCodec;\n this.videoCodec = videoCodec;\n this.initSegmentData = initSegmentData;\n this.duration = duration;\n this.defaultInitPts = defaultInitPts || null;\n }\n}\n\nexport class TransmuxState {\n public discontinuity: boolean;\n public contiguous: boolean;\n public accurateTimeOffset: boolean;\n public trackSwitch: boolean;\n public timeOffset: number;\n public initSegmentChange: boolean;\n\n constructor(\n discontinuity: boolean,\n contiguous: boolean,\n accurateTimeOffset: boolean,\n trackSwitch: boolean,\n timeOffset: number,\n initSegmentChange: boolean,\n ) {\n this.discontinuity = discontinuity;\n this.contiguous = contiguous;\n this.accurateTimeOffset = accurateTimeOffset;\n this.trackSwitch = trackSwitch;\n this.timeOffset = timeOffset;\n this.initSegmentChange = initSegmentChange;\n }\n}\n","import { DecrypterAesMode } from '../crypt/decrypter-aes-mode';\n\nexport function isFullSegmentEncryption(method: string): boolean {\n return (\n method === 'AES-128' || method === 'AES-256' || method === 'AES-256-CTR'\n );\n}\n\nexport function getAesModeFromFullSegmentMethod(\n method: string,\n): DecrypterAesMode {\n switch (method) {\n case 'AES-128':\n case 'AES-256':\n return DecrypterAesMode.cbc;\n case 'AES-256-CTR':\n return DecrypterAesMode.ctr;\n default:\n throw new Error(`invalid full segment method ${method}`);\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport Transmuxer, { isPromise } from '../demux/transmuxer';\nimport { ErrorDetails, ErrorTypes } from '../errors';\nimport { Events } from '../events';\nimport { enableLogs, type ILogFunction, type ILogger } from '../utils/logger';\nimport type { RemuxedTrack, RemuxerResult } from '../types/remuxer';\nimport type { ChunkMetadata, TransmuxerResult } from '../types/transmuxer';\n\nconst transmuxers: (Transmuxer | undefined)[] = [];\n\nif (typeof __IN_WORKER__ !== 'undefined' && __IN_WORKER__) {\n startWorker();\n}\n\nfunction startWorker() {\n self.addEventListener('message', (ev) => {\n const data = ev.data;\n const instanceNo = data.instanceNo;\n if (instanceNo === undefined) {\n return;\n }\n const transmuxer = transmuxers[instanceNo];\n if (data.cmd === 'reset') {\n delete transmuxers[data.resetNo];\n if (transmuxer) {\n transmuxer.destroy();\n }\n data.cmd = 'init';\n }\n if (data.cmd === 'init') {\n const config = JSON.parse(data.config);\n const observer = new EventEmitter();\n observer.on(Events.FRAG_DECRYPTED, forwardMessage);\n observer.on(Events.ERROR, forwardMessage);\n const logger = enableLogs(config.debug, data.id);\n forwardWorkerLogs(logger, instanceNo);\n transmuxers[instanceNo] = new Transmuxer(\n observer,\n data.typeSupported,\n config,\n '',\n data.id,\n logger,\n );\n forwardMessage('init', null, instanceNo);\n return;\n }\n if (!transmuxer) {\n return;\n }\n switch (data.cmd) {\n case 'configure': {\n transmuxer.configure(data.config);\n break;\n }\n case 'demux': {\n const transmuxResult: TransmuxerResult | Promise<TransmuxerResult> =\n transmuxer.push(\n data.data,\n data.decryptdata,\n data.chunkMeta,\n data.state,\n );\n if (isPromise(transmuxResult)) {\n transmuxResult\n .then((data) => {\n emitTransmuxComplete(self, data, instanceNo);\n })\n .catch((error) => {\n forwardMessage(\n Events.ERROR,\n {\n instanceNo,\n type: ErrorTypes.MEDIA_ERROR,\n details: ErrorDetails.FRAG_PARSING_ERROR,\n chunkMeta: data.chunkMeta,\n fatal: false,\n error,\n err: error,\n reason: `transmuxer-worker push error`,\n },\n instanceNo,\n );\n });\n } else {\n emitTransmuxComplete(self, transmuxResult, instanceNo);\n }\n break;\n }\n case 'flush': {\n const chunkMeta = data.chunkMeta as ChunkMetadata;\n const transmuxResult = transmuxer.flush(chunkMeta);\n if (isPromise(transmuxResult)) {\n transmuxResult\n .then((results: Array<TransmuxerResult>) => {\n handleFlushResult(\n self,\n results as Array<TransmuxerResult>,\n chunkMeta,\n instanceNo,\n );\n })\n .catch((error) => {\n forwardMessage(\n Events.ERROR,\n {\n type: ErrorTypes.MEDIA_ERROR,\n details: ErrorDetails.FRAG_PARSING_ERROR,\n chunkMeta: data.chunkMeta,\n fatal: false,\n error,\n err: error,\n reason: `transmuxer-worker flush error`,\n },\n instanceNo,\n );\n });\n } else {\n handleFlushResult(\n self,\n transmuxResult as Array<TransmuxerResult>,\n chunkMeta,\n instanceNo,\n );\n }\n break;\n }\n default:\n break;\n }\n });\n}\n\nfunction emitTransmuxComplete(\n self: any,\n transmuxResult: TransmuxerResult,\n instanceNo: number,\n): boolean {\n if (isEmptyResult(transmuxResult.remuxResult)) {\n return false;\n }\n const transferable: Array<ArrayBuffer> = [];\n const { audio, video } = transmuxResult.remuxResult;\n if (audio) {\n addToTransferable(transferable, audio);\n }\n if (video) {\n addToTransferable(transferable, video);\n }\n self.postMessage(\n { event: 'transmuxComplete', data: transmuxResult, instanceNo },\n transferable,\n );\n return true;\n}\n\n// Converts data to a transferable object https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast)\n// in order to minimize message passing overhead\nfunction addToTransferable(\n transferable: Array<ArrayBuffer>,\n track: RemuxedTrack,\n) {\n if (track.data1) {\n transferable.push(track.data1.buffer);\n }\n if (track.data2) {\n transferable.push(track.data2.buffer);\n }\n}\n\nfunction handleFlushResult(\n self: any,\n results: Array<TransmuxerResult>,\n chunkMeta: ChunkMetadata,\n instanceNo: number,\n) {\n const parsed = results.reduce(\n (parsed, result) =>\n emitTransmuxComplete(self, result, instanceNo) || parsed,\n false,\n );\n if (!parsed) {\n // Emit at least one \"transmuxComplete\" message even if media is not found to update stream-controller state to PARSING\n self.postMessage({\n event: 'transmuxComplete',\n data: results[0],\n instanceNo,\n });\n }\n self.postMessage({ event: 'flush', data: chunkMeta, instanceNo });\n}\n\nfunction forwardMessage(event, data, instanceNo) {\n self.postMessage({ event, data, instanceNo });\n}\n\nfunction forwardWorkerLogs(logger: ILogger, instanceNo: number) {\n for (const logFn in logger) {\n const func: ILogFunction = (message?) => {\n forwardMessage(\n 'workerLog',\n {\n logType: logFn,\n message,\n },\n instanceNo,\n );\n };\n logger[logFn] = func;\n }\n}\n\nfunction isEmptyResult(remuxResult: RemuxerResult) {\n return (\n !remuxResult.audio &&\n !remuxResult.video &&\n !remuxResult.text &&\n !remuxResult.id3 &&\n !remuxResult.initSegment\n );\n}\n"],"names":["has","Object","prototype","hasOwnProperty","prefix","Events","EE","fn","context","once","this","addListener","emitter","event","TypeError","listener","evt","_events","push","_eventsCount","clearEvent","EventEmitter","create","__proto__","eventNames","events","name","names","call","slice","getOwnPropertySymbols","concat","listeners","handlers","i","l","length","ee","Array","listenerCount","emit","a1","a2","a3","a4","a5","args","len","arguments","removeListener","undefined","apply","j","on","removeAllListeners","off","prefixed","module","exports","isId3Footer","data","offset","isId3Header","readId3Size","size","getId3Data","front","subarray","ErrorTypes","ErrorDetails","noop","fakeLogger","trace","debug","log","warn","info","error","createLogger","_extends","getLoggerFn","key","debugConfig","id","bind","type","func","self","console","exportedLogger","logger","isHeaderPattern","getHeaderLength","getFullFrameLength","isHeader","probe","headerLength","frameLength","newOffset","initTrackConfig","track","observer","audioCodec","samplerate","config","manifestCodec","byte2","adtsSamplingIndex","adtsObjectType","channelCount","codec","aacSampleIndex","parsedCodec","Error","ERROR","MEDIA_ERROR","details","FRAG_PARSING_ERROR","fatal","reason","message","getAudioConfig","getFrameDuration","appendFrame","pts","frameIndex","unit","stamp","header","parseFrameHeader","missing","Math","max","Uint8Array","set","sample","samples","isFiniteNumber","Number","isFinite","value","isSafeInteger","abs","MAX_SAFE_INTEGER","canParseId3","utf8ArrayToStr","array","exitOnNull","TextDecoder","decoded","decode","idx","indexOf","substring","replace","c","char2","char3","out","String","fromCharCode","toUint8","Infinity","Type","buffer","view","ArrayBuffer","unsafeGetArrayBuffer","bytesPerElement","BYTES_PER_ELEMENT","dataOffset","obj","byteLength","byteOffset","dataEnd","rawStart","start","floor","min","end","decodeId3ImageFrame","frame","metadataFrame","description","mimeType","pictureType","mimeTypeEndIndex","descriptionEndIndex","toArrayBuffer","decodeId3Frame","owner","privateData","decodeId3PrivFrame","index","url","decodeId3UrlFrame","text","decodeId3TextFrame","getId3FrameData","HEADER_FOOTER_SIZE","FRAME_SIZE","isId3TimestampFrame","readId3Timestamp","timeStampFrame","pts33Bit","timestamp","round","getId3Timestamp","frames","id3Data","frameData","getId3Frames","MetadataSchema","Hex","str","h","toString","sliceUint8","URL_REGEX","FIRST_SEGMENT_REGEX","SLASH_DOT_REGEX","SLASH_DOT_DOT_REGEX","URLToolkit","buildAbsoluteURL","baseURL","relativeURL","opts","trim","alwaysNormalize","basePartsForNormalise","parseURL","path","normalizePath","buildURLFromParts","relativeParts","scheme","baseParts","netLoc","pathParts","exec","builtParts","params","query","fragment","baseURLPath","newPath","lastIndexOf","parts","split","reverse","join","ElementaryStreamTypes","UINT32_MAX","pow","RemuxerTrackIdConfig","video","audio","id3","bin2str","readUint16","val","readUint32","readSint32","readUint64","result","writeUint32","findBox","results","endbox","subresults","parseSegmentIndex","sidx","references","version","timescale","earliestPresentationTime","firstOffset","startByte","referencesCount","referenceIndex","referenceInfo","referenceSize","subsegmentDuration","duration","parseInitSegment","initSegment","traks","trak","tkhd","trackId","mdhd","hdlr","hdlrType","soun","vide","stsdData","parseStsd","_objectSpread","forEach","trex","default","flags","stsd","sampleEntries","sampleEntriesEnd","fourCC","encrypted","encBox","sinf","schm","frma","avcCBox","toHex","codecBox","esdsBox","skipBERInteger","objectType","firstByte","audioObjectType","hvcCBox","profileByte","profileSpace","generalProfileIdc","profileCompat","tierFlag","levelIDC","constraintIndicator","toUpperCase","constraintString","byte","dvcCBox","profile","level","addLeadingZero","vpcCBox","bitDepth","av1CBox","highBitDepth","twelveBit","monochrome","chromaSubsamplingX","chromaSubsamplingY","chromaSamplePosition","bytes","limit","x","num","patchEncyptionData","decryptdata","keyId","isCommonEncryption","encBoxes","isAudio","enc","tenc","parseSinf","tencKeyId","some","b","computeRawDurationFromSamples","trun","sampleCount","appendUint8Array","data1","data2","temp","parseSamples","timeOffset","seiSamples","videoData","isHEVCFlavor","map","moof","moofOffset","traf","baseTime","tfdt","tfhd","tfhdFlags","defaultSampleDuration","defaultSampleSizePresent","defaultSampleSize","defaultSampleFlagsPresent","tfhdOffset","delimit","baseCodec","isHEVC","dataOffsetPresent","firstSampleFlagsPresent","sampleDurationPresent","sampleDuration","sampleSizePresent","sampleSize","sampleFlagsPresent","sampleCompositionOffsetsPresent","compositionOffset","trunOffset","sampleOffset","ix","naluTotalSize","naluSize","isSEIMessage","parseSEIMessageFromNALu","naluHeader","naluType","unescapedData","headerSize","discardEPB","seiPtr","payloadType","payloadSize","leftOver","payPtr","providerCode","userStructure","userDataType","enabled","totalBytes","byteArray","uuidStrArray","userDataBytes","uuid","userData","EPBPositions","newLength","newData","sourceIndex","shift","dummyTrack","inputTimeScale","pid","sequenceNumber","dropped","BaseAudioDemuxer","_audioTrack","_id3Track","cachedData","basePTS","initPTS","lastPTS","_proto","resetInitSegment","videoCodec","trackDuration","resetTimeStamp","deaultTimestamp","resetContiguity","canParse","demux","lastDataIndex","id3Track","_isFiniteNumber","initPTSFn","dts","audioId3","POSITIVE_INFINITY","partialData","audioTrack","videoTrack","textTrack","demuxSampleAes","keyData","Promise","reject","flush","destroy","_isFiniteNumber2","chromeVersion","BitratesMap","SamplingRateMap","SamplesCoefficients","BytesInSlot","parseHeader","samplesPerFrame","sampleRate","mpegVersion","mpegLayer","bitRateIndex","sampleRateIndex","paddingBit","channelMode","bitRate","sampleCoefficient","bytesInSlot","navigator","userAgent","match","parseInt","AACDemuxer","_BaseAudioDemuxer","_this","_inheritsLoose","container","segmentCodec","MpegAudio","ADTS","canGetFrameLength","getAudioBSID","bsid","numBits","Uint32Array","mask","bits","AC3Demuxer","samplingRateCode","frameSizeCode","skipCount","lfeon","bsmod","MP3Demuxer","DecrypterAesMode","AESCrypto","subtle","iv","aesMode","aesIV","decrypt","counter","AESDecryptor","rcon","subMix","invSubMix","sBox","invSBox","ksRows","keySize","keySchedule","invKeySchedule","initTable","uint8ArrayToUint32Array_","arrayBuffer","DataView","newArray","getUint32","subMix0","subMix1","subMix2","subMix3","invSubMix0","invSubMix1","invSubMix2","invSubMix3","d","xi","sx","x2","x4","x8","t","expandKey","keyBuffer","sameKey","ksRow","invKsRow","prev","sbox","networkToHostOrderSwap","word","inputArrayBuffer","t0","t1","t2","t3","s0","s1","s2","s3","inputWords0","inputWords1","inputWords2","inputWords3","nRounds","invSBOX","initVector","initVector0","initVector1","initVector2","initVector3","inputInt32","Int32Array","outputInt32","swapWord","FastAESKey","subtleAlgoName","getSubtleAlgoName","importKey","Decrypter","_temp","_ref$removePKCS7Paddi","removePKCS7Padding","logEnabled","softwareDecrypter","fastAesKey","remainderData","currentIV","currentResult","useSoftware","enableSoftwareAES","browserCrypto","crypto","webkitSubtle","e","isSync","reset","outputBytes","paddingBytes","getUint8","resolve","dataView","isView","softwareDecrypt","decryptResult","webCryptoDecrypt","logOnce","currentChunk","getValidChunk","_this2","onWebCryptoError","then","aesKey","catch","err","splitPoint","msg","emsgSchemePattern","MP4Demuxer","txtTrack","captionTrack","initData","_initData$video","_initData$audio","hasMoofData","videoSamples","progressive","segmentedData","segmentedRange","valid","remainder","moofs","last","segmentValidRange","extractID3Track","emsgs","emsgInfo","schemeIdUri","timeScale","presentationTimeDelta","presentationTime","eventDuration","leftPresentationTime","rightPresentationTime","_isSafeInteger","payload","parseEmsg","test","getEmsgStartTime","emsg","enableEmsgKLVMetadata","startsWith","misbklv","SampleAesDecrypter","decrypter","decryptBuffer","encryptedData","decryptAacSample","sampleIndex","callback","curUnit","encryptedBuffer","decryptedBuffer","decryptedData","decryptAacSamples","getAvcEncryptedData","decodedData","encryptedDataLen","Int8Array","outputPos","inputPos","getAvcDecryptedUnit","uint8DecryptedData","decryptAvcSample","unitIndex","decryptAvcSamples","curUnits","units","BaseVideoParser","VideoSample","createVideoSample","getLastNalUnit","_VideoSample","lastUnit","pushAccessUnit","nbSamples","lastSample","parseNALu","endOfSegment","overflow","state","naluState","lastState","lastUnitStart","lastUnitType","getNALuType","ExpGolomb","bytesAvailable","bitsAvailable","loadWord","position","workingBytes","availableBytes","skipBits","count","skipBytes","readBits","valu","skipLZ","leadingZeroCount","skipUEG","skipEG","readUEG","clz","readEG","readBoolean","readUByte","readUShort","readUInt","AvcVideoParser","_BaseVideoParser","parsePES","pes","spsfound","audFound","_VideoSample2","_VideoSample3","iskey","sliceType","readSliceType","_track$pixelRatio","_track$pixelRatio2","sps","readSPS","width","height","pixelRatio","codecarray","codecstring","pps","eg","skipScalingList","reader","lastScale","nextScale","numRefFramesInPicOrderCntCycle","scalingListCount","frameCropLeftOffset","frameCropRightOffset","frameCropTopOffset","frameCropBottomOffset","profileIdc","chromaFormatIdc","picOrderCntType","picWidthInMbsMinus1","picHeightInMapUnitsMinus1","frameMbsOnlyFlag","ceil","HevcVideoParser","_len","_key","initVPS","vps","readVPS","matchSPS","prop","codecString","pushParameterSet","readPPS","parameterSets","ebsp2rbsp","arr","dst","dstIdx","numTemporalLayers","temporalIdNested","max_sub_layers_minus1","general_profile_space","general_tier_flag","general_profile_idc","general_profile_compatibility_flags_1","general_profile_compatibility_flags_2","general_profile_compatibility_flags_3","general_profile_compatibility_flags_4","general_constraint_indicator_flags_1","general_constraint_indicator_flags_2","general_constraint_indicator_flags_3","general_constraint_indicator_flags_4","general_constraint_indicator_flags_5","general_constraint_indicator_flags_6","general_level_idc","sub_layer_profile_present_flags","sub_layer_level_present_flags","chroma_format_idc","pic_width_in_luma_samples","pic_height_in_luma_samples","conformance_window_flag","pic_left_offset","pic_right_offset","pic_top_offset","pic_bottom_offset","bit_depth_luma_minus8","bit_depth_chroma_minus8","log2_max_pic_order_cnt_lsb_minus4","sizeId","matrixId","coefNum","num_short_term_ref_pic_sets","num_delta_pocs","inter_ref_pic_set_prediction_flag","next_num_delta_pocs","used_by_curr_pic_flag","use_delta_flag","num_negative_pics","num_positive_pics","num_long_term_ref_pics_sps","min_spatial_segmentation_idc","sar_width","sar_height","fps_fixed","fps_den","fps_num","default_display_window_flag","aspect_ratio_idc","nal_hrd_parameters_present_flag","vcl_hrd_parameters_present_flag","sub_pic_hrd_params_present_flag","low_delay_hrd_flag","cpb_cnt","chroma_scale_w","chroma_scale_h","profile_space_string","profile_compatibility_buf","profile_compatibility_rev","profile_compatibility_flags_string","tier_flag_string","general_profile_compatibility_flags","general_constraint_indicator_flags","bit_depth","frame_rate","fixed","fps","tiles_enabled_flag","entropy_coding_sync_enabled_flag","parallelismType","sps1","sps2","substr","PACKET_LENGTH","TSDemuxer","typeSupported","sampleAes","pmtParsed","_pmtId","_videoTrack","_txtTrack","aacOverFlow","videoParser","syncOffset","scanwindow","foundPat","packetStart","tsPackets","parsePID","createTrack","pesData","isSampleAes","videoPid","audioPid","id3Pid","audioData","unknownPID","pmtId","tsPacketErrors","stt","parseAACPES","parseMPEGPES","parseAC3PES","parseID3PES","parsePAT","parsedPIDs","parsePMT","segmentVideoCodec","segmentAudioCodec","emitParsingError","demuxResult","extractRemainingSamples","startOffset","frameMissingBytes","sampleLength","frameOverflowBytes","recoverable","frameDuration","parsed","AC3","id3Sample","tableEnd","esInfoLength","logEncryptedSamplesFoundInUnencryptedStream","mpeg","mp3","ac3","parsePos","remaining","descriptorLen","levelRetry","stream","frag","pesLen","pesHdrLen","pesPts","pesDts","splice","pesFlags","payloadStartOffset","dataLen","AAC","getSilentFrame","MP4","init","types","avc1","avcC","hvc1","hvcC","btrt","dinf","dref","esds","ftyp","mdat","mdia","mfhd","minf","moov","mp4a","dac3","mvex","mvhd","pasp","sdtp","stbl","stco","stsc","stsz","stts","vmhd","smhd","charCodeAt","videoHdlr","audioHdlr","HDLR_TYPES","STTS","STSC","STCO","STSZ","VMHD","SMHD","STSD","majorBrand","avc1Brand","minorVersion","FTYP","box","DINF","upperWordDuration","lowerWordDuration","sn","baseMediaDecodeTime","tracks","boxes","dependsOn","isDependedOn","hasRedundancy","avcc","hSpacing","vSpacing","audioStsd","sampleDependencyTable","upperWordBaseMediaDecodeTime","lowerWordBaseMediaDecodeTime","cts","arraylen","isLeading","paddingValue","isNonSync","degradPrio","movie","ps","NALuLengthSize","temporal_id_nested","num_temporal_layers","iMax","hvcc","PlaylistLevelType","toMsFromMpegTsClock","destScale","srcBase","toTimescaleFromBase","safariWebkitVersion","createMp4Sample","isKeyframe","MP4Remuxer","ISGenerated","_initPTS","_initDTS","nextAvcDts","nextAudioPts","videoSampleDuration","isAudioContiguous","isVideoContiguous","videoTrackConfig","defaultTimeStamp","resetNextTimestamp","getVideoStartPts","rolloverDetected","firstPts","startPTS","reduce","minPTS","delta","normalizePts","remux","accurateTimeOffset","playlistType","independent","audioTimeOffset","videoTimeOffset","hasAudio","hasVideo","enoughAudioSamples","enoughVideoSamples","_videoTrack$pixelRati","_config$pixelRatio","_videoTrack$pixelRati2","_config$pixelRatio2","generateIS","firstKeyFramePTS","firstKeyFrameIndex","findKeyframeIndex","forceKeyFrameOnDiscontinuity","audiovideoTimestampDelta","remuxAudio","audioTrackLength","endPTS","remuxVideo","firstKeyFrame","flushTextTrackMetadataCueSamples","flushTextTrackUserdataCueSamples","initDTS","audioSamples","computePTSDTS","metadata","keys","contiguous","firstDTS","lastDTS","inputSamples","outputSamples","mp4SampleDuration","maxPTS","NEGATIVE_INFINITY","sortSamples","initTime","sort","a","deltadts","deltapts","inputDuration","averageSampleDuration","foundHole","foundOverlap","toFixed","firstPTS","isPTSOrderRetained","prevPTS","nextSamplePTS","nbNalu","naluLen","dtsStep","nbUnits","sampleLen","mdatSize","MUX_ERROR","REMUX_ALLOC_ERROR","setUint32","stretchedLastFrame","minDtsDelta","minPtsDelta","maxDtsDelta","maxPtsDelta","VideoSampleUnits","mp4SampleLength","unitData","unitDataLen","ptsDelta","lastFrameDuration","stretchShortVideoTrack","gapTolerance","maxBufferHole","deltaToFrameEnd","compositionTimeOffset","nextDts","nextPts","startDTS","endDTS","nb","getSamplesPerFrame","scaleFactor","inputSampleDuration","rawMPEG","alignedWithVideo","timeOffsetMpegTS","filter","maxAudioFramesDrift","newStamp","fillFrame","audioSample","unitLen","reference","getMediaSource","preferManagedMediaSource","MediaSource","ManagedMediaSource","WebKitMediaSource","isCodecMediaSourceSupported","_MediaSource$isTypeSu","isTypeSupported","mimeTypeForCodec","CODEC_COMPATIBLE_NAMES","AUDIO_CODEC_REGEXP","getCodecCompatibleName","m","lowerCaseCodec","codecsToCheck","flac","opus","_getMediaSource","getCodecCompatibleNameLower","toLowerCase","now","PassThroughRemuxer","emitInitSegment","initTracks","lastEndTime","defaultInitPTS","generateInitSegment","getParsedTrackCodec","audiovideo","_initData","_initData2","rawDuration","videoDuration","audioDuration","trafs","trackDefault","truns","sidxMinStart","sidxMaxEnd","sidxDuration","sidxs","subSegmentDuration","dur","ref","_isFiniteNumber3","getDuration","fmp4","startTime","getStartDTS","decodeTime","minDuration","isInvalidInitPts","endTime","upper","lower","offsetStartDTS","performance","Date","muxConfig","Transmuxer","vendor","asyncResult","demuxer","remuxer","decryptionPromise","transmuxConfig","currentTransmuxState","configure","chunkMeta","stats","transmuxing","executeStart","uintData","method","_ref","discontinuity","trackSwitch","initSegmentChange","defaultInitPts","initSegmentData","decryptData","encryptionType","getEncryptionType","getDecrypter","getAesModeFromFullSegmentMethod","part","executeEnd","emptyResult","resetMuxers","needsProbing","configureTransmuxer","resetInitialTimestamp","transmux","isPromise","currentState","transmuxResults","emptyResults","demuxResultOrPromise","flushRemux","_this$currentTransmux","remuxResult","transmuxSampleAes","transmuxUnencrypted","_demux","_this3","mux","_muxConfig$i$demux","Remuxer","Demuxer","p","Function","transmuxers","emitTransmuxComplete","transmuxResult","instanceNo","transferable","_transmuxResult$remux","addToTransferable","postMessage","handleFlushResult","forwardMessage","addEventListener","ev","transmuxer","cmd","resetNo","JSON","parse","FRAG_DECRYPTED","newLogger","enableLogs","_loop","logFn","logType","forwardWorkerLogs"],"mappings":"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M,GACNC,KAAM,GACNxjB,KAAM,GACNyjB,KAAM,GACNC,KAAM,GACN,OAAQ,GACRC,KAAM,GACN,OAAQ,GACRC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNxoB,KAAM,GACNyoB,KAAM,GACNC,KAAM,GACNhkB,KAAM,GACNC,KAAM,GACNH,KAAM,GACNvF,KAAM,GACNyE,KAAM,GACN7D,KAAM,GACNX,KAAM,GACNypB,KAAM,GACNC,KAAM,IAIE7B,EAAIE,MACRF,EAAIE,MAAM55B,eAAe+B,KAC3B23B,EAAIE,MAAM73B,GAAK,CACbA,EAAEy5B,WAAW,GACbz5B,EAAEy5B,WAAW,GACbz5B,EAAEy5B,WAAW,GACbz5B,EAAEy5B,WAAW,KAKnB,IAAMC,EAAY,IAAIvzB,WAAW,CAC/B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,IACA,IACA,IACA,IACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,IACA,IACA,IACA,IACA,GACA,GACA,IACA,IACA,IACA,IACA,IACA,IAGIwzB,EAAY,IAAIxzB,WAAW,CAC/B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,IACA,IACA,IACA,IACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,IACA,IACA,IACA,IACA,GACA,GACA,IACA,IACA,IACA,IACA,IACA,IAGFwxB,EAAIiC,WAAa,CACf/rB,MAAO6rB,EACP5rB,MAAO6rB,GAGT,IAAMvB,EAAO,IAAIjyB,WAAW,CAC1B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,IACA,IACA,IACA,GACA,EACA,EACA,EACA,IAGIgzB,EAAO,IAAIhzB,WAAW,CAC1B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,IAGFwxB,EAAIkC,KAAOlC,EAAImC,KAAOnC,EAAIoC,KAAOZ,EAEjCxB,EAAIqC,KAAO,IA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,OAAQF,IAEhCa,GADAa,EAAOwC,EAAM+nB,IAAIjsB,IACN0I,WACXujB,EAAIjtB,KAAM6B,IAAQ,EAAK,KACvBorB,EAAIjtB,KAAW,IAAN6B,GAGTorB,EAAMA,EAAIpsB,OAAOO,MAAMpC,UAAU2B,MAAMD,KAAKgC,IAI9C,IAAK1B,EAAI,EAAGA,EAAIkE,EAAMsoB,IAAItsB,OAAQF,IAEhCa,GADAa,EAAOwC,EAAMsoB,IAAIxsB,IACN0I,WACX8jB,EAAIxtB,KAAM6B,IAAQ,EAAK,KACvB2rB,EAAIxtB,KAAW,IAAN6B,GAET2rB,EAAMA,EAAI3sB,OAAOO,MAAMpC,UAAU2B,MAAMD,KAAKgC,IAG9C,IAAMy5B,EAAOxD,EAAI6C,IACf7C,EAAIE,MAAME,KACV,IAAI5xB,WACF,CACE,EACA8lB,EAAI,GACJA,EAAI,GACJA,EAAI,GACJ,IACA,IAAO/nB,EAAM+nB,IAAI/rB,QAEhBL,OAAOosB,GACPpsB,OAAO,CACNqE,EAAMsoB,IAAItsB,SAEXL,OAAO2sB,KAGRL,EAAQjoB,EAAMioB,MACdC,EAASloB,EAAMkoB,OACfgP,EAAWl3B,EAAMmoB,WAAW,GAC5BgP,EAAWn3B,EAAMmoB,WAAW,GAElC,OAAOsL,EAAI6C,IACT7C,EAAIE,MAAMC,KACV,IAAI3xB,WAAW,CACb,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACCgmB,GAAS,EAAK,IACP,IAARA,EACCC,GAAU,EAAK,IACP,IAATA,EACA,EACA,GACA,EACA,EACA,EACA,GACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,IACA,GACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACA,IACA,IACA,IACA,GACA,IACA,IACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,GACA,KAEF+O,EACAxD,EAAI6C,IACF7C,EAAI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B,GAAqB,GACpBA,GAAqB,GAAM,IAC3BA,GAAqB,EAAK,IACP,IAApBA,EACAC,GAAqB,GACpBA,GAAqB,GAAM,IAC3BA,GAAqB,EAAK,IACP,IAApBA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,EACA,EACA,EACCxO,GAAS,EAAK,IACP,IAARA,EACA,EACA,EACCC,GAAU,EAAK,IACP,IAATA,EACA,EACA,IAGL,EAAAuL,EAEMviB,KAAP,SAAYlR,EAAyB22B,GACnC,IAAMU,EAAwB5D,EAAIsB,KAAK/0B,GACjCjB,EAAKiB,EAAMjB,GACXu4B,EAA+Bv1B,KAAK8C,MACxC8xB,GAAuBntB,GAAa,IAEhC+tB,EAA+Bx1B,KAAK8C,MACxC8xB,GAAuBntB,GAAa,IAEtC,OAAOiqB,EAAI6C,IACT7C,EAAIE,MAAMziB,KACVuiB,EAAI6C,IACF7C,EAAIE,MAAMtiB,KACV,IAAIpP,WAAW,CACb,EACA,EACA,EACA,EACAlD,GAAM,GACLA,GAAM,GAAM,IACZA,GAAM,EAAK,IACP,IAALA,KAGJ00B,EAAI6C,IACF7C,EAAIE,MAAMviB,KACV,IAAInP,WAAW,CACb,EACA,EACA,EACA,EACAq1B,GAAgC,GAC/BA,GAAgC,GAAM,IACtCA,GAAgC,EAAK,IACP,IAA/BA,EACAC,GAAgC,GAC/BA,GAAgC,GAAM,IACtCA,GAAgC,EAAK,IACP,IAA/BA,KAGJ9D,EAAIrjB,KACFpQ,EACAq3B,EAAsBr7B,OACpB,GACA,GACA,EACA,GACA,EACA,GAEJq7B,EAEJ,EAEA5D,EAIO9nB,KAAP,SAAY3L,GAEV,OADAA,EAAMuL,SAAWvL,EAAMuL,UAAY,WAC5BkoB,EAAI6C,IAAI7C,EAAIE,MAAMhoB,KAAM8nB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EAAOpE,OAGhB,IADA,IAAMm8B,EAAO3T,EAAMxoB,OAAS,EACnBF,EAAI,EAAGA,EAAI0oB,EAAMxoB,OAAQF,GAAK,EAAG,CACxCi4B,EAAK7xB,IACH,IAAID,WAAW,CACZ,GAAKnG,GAAMA,IAAMq8B,EAAO,IAAM,GAC/B,EACA3T,EAAM1oB,GAAGE,SAEXA,GAEFA,GAAU,EACV,IAAK,IAAIgB,EAAI,EAAGA,EAAIwnB,EAAM1oB,GAAGE,OAAQgB,GAAK,EACxC+2B,EAAK7xB,IACH,IAAID,WAAW,CAACuiB,EAAM1oB,GAAGkB,GAAGhB,QAAU,EAAwB,IAArBwoB,EAAM1oB,GAAGkB,GAAGhB,SACrDA,GAEFA,GAAU,EACV+3B,EAAK7xB,IAAIsiB,EAAM1oB,GAAGkB,GAAIhB,GACtBA,GAAUwoB,EAAM1oB,GAAGkB,GAAGhB,MAE1B,CACA,IAAMo8B,EAAO3E,EAAI6C,IAAI7C,EAAIE,MAAMI,KAAMA,GAC/B9L,EAAQjoB,EAAMioB,MACdC,EAASloB,EAAMkoB,OACfgP,EAAWl3B,EAAMmoB,WAAW,GAC5BgP,EAAWn3B,EAAMmoB,WAAW,GAElC,OAAOsL,EAAI6C,IACT7C,EAAIE,MAAMG,KACV,IAAI7xB,WAAW,CACb,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACCgmB,GAAS,EAAK,IACP,IAARA,EACCC,GAAU,EAAK,IACP,IAATA,EACA,EACA,GACA,EACA,EACA,EACA,GACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,IACA,GACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACA,IACA,IACA,IACA,GACA,IACA,IACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,GACA,KAEFkQ,EACA3E,EAAI6C,IACF7C,EAAIE,MAAMK,KACV,IAAI/xB,WAAW,CACb,EACA,GACA,IACA,I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","x_google_ignoreList":[0,1,2,3,4,10,11,12,13,14,15,16,17,18,19,20,21,22,23,27]}
|
1
|
+
{"version":3,"file":"hls.worker.js.map","sources":["node_modules/eventemitter3/index.js","node_modules/@svta/common-media-library/dist/id3/util/isId3Footer.js","node_modules/@svta/common-media-library/dist/id3/util/isId3Header.js","node_modules/@svta/common-media-library/dist/id3/util/readId3Size.js","node_modules/@svta/common-media-library/dist/id3/getId3Data.js","src/errors.ts","src/events.ts","src/utils/logger.ts","src/demux/audio/adts.ts","src/polyfills/number.ts","node_modules/@svta/common-media-library/dist/id3/canParseId3.js","node_modules/@svta/common-media-library/dist/utils/utf8ArrayToStr.js","node_modules/@svta/common-media-library/dist/id3/util/utf8.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3ImageFrame.js","node_modules/@svta/common-media-library/dist/id3/util/toArrayBuffer.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3Frame.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3PrivFrame.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3UrlFrame.js","node_modules/@svta/common-media-library/dist/id3/util/decodeId3TextFrame.js","node_modules/@svta/common-media-library/dist/id3/util/getId3FrameData.js","node_modules/@svta/common-media-library/dist/id3/getId3Frames.js","node_modules/@svta/common-media-library/dist/id3/isId3TimestampFrame.js","node_modules/@svta/common-media-library/dist/id3/util/readId3Timestamp.js","node_modules/@svta/common-media-library/dist/id3/getId3Timestamp.js","src/types/demuxer.ts","src/utils/hex.ts","src/utils/typed-array.ts","node_modules/url-toolkit/src/url-toolkit.js","src/loader/fragment.ts","src/utils/mp4-tools.ts","src/demux/dummy-demuxed-track.ts","src/demux/audio/base-audio-demuxer.ts","src/demux/audio/mpegaudio.ts","src/demux/audio/aacdemuxer.ts","src/demux/audio/dolby.ts","src/demux/audio/ac3-demuxer.ts","src/demux/audio/mp3demuxer.ts","src/crypt/decrypter-aes-mode.ts","src/crypt/aes-crypto.ts","src/crypt/aes-decryptor.ts","src/crypt/fast-aes-key.ts","src/crypt/decrypter.ts","src/demux/mp4demuxer.ts","src/demux/sample-aes.ts","src/demux/video/base-video-parser.ts","src/demux/video/exp-golomb.ts","src/demux/video/avc-video-parser.ts","src/demux/video/hevc-video-parser.ts","src/demux/tsdemuxer.ts","src/remux/aac-helper.ts","src/remux/mp4-generator.ts","src/types/loader.ts","src/utils/timescale-conversion.ts","src/remux/mp4-remuxer.ts","src/utils/mediasource-helper.ts","src/utils/codecs.ts","src/remux/passthrough-remuxer.ts","src/demux/transmuxer.ts","src/utils/encryption-methods-util.ts","src/demux/transmuxer-worker.ts"],"sourcesContent":["'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */\nfunction addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') {\n throw new TypeError('The listener must be a function');\n }\n\n var listener = new EE(fn, context || emitter, once)\n , evt = prefix ? prefix + event : event;\n\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [emitter._events[evt], listener];\n\n return emitter;\n}\n\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */\nfunction clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new Events();\n else delete emitter._events[evt];\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */\nEventEmitter.prototype.listeners = function listeners(event) {\n var evt = prefix ? prefix + event : event\n , handlers = this._events[evt];\n\n if (!handlers) return [];\n if (handlers.fn) return [handlers.fn];\n\n for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {\n ee[i] = handlers[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */\nEventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = prefix ? prefix + event : event\n , listeners = this._events[evt];\n\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n return addListener(this, event, fn, context, false);\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n return addListener(this, event, fn, context, true);\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n clearEvent(this, evt);\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn &&\n (!once || listeners.once) &&\n (!context || listeners.context === context)\n ) {\n clearEvent(this, evt);\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn ||\n (once && !listeners[i].once) ||\n (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else clearEvent(this, evt);\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) clearEvent(this, evt);\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n","/**\n * Returns true if an ID3 footer can be found at offset in data\n *\n * @param data - The data to search in\n * @param offset - The offset at which to start searching\n *\n * @returns `true` if an ID3 footer is found\n *\n * @internal\n *\n * @group ID3\n */\nexport function isId3Footer(data, offset) {\n /*\n * The footer is a copy of the header, but with a different identifier\n */\n if (offset + 10 <= data.length) {\n // look for '3DI' identifier\n if (data[offset] === 0x33 &&\n data[offset + 1] === 0x44 &&\n data[offset + 2] === 0x49) {\n // check version is within range\n if (data[offset + 3] < 0xff && data[offset + 4] < 0xff) {\n // check size is within range\n if (data[offset + 6] < 0x80 &&\n data[offset + 7] < 0x80 &&\n data[offset + 8] < 0x80 &&\n data[offset + 9] < 0x80) {\n return true;\n }\n }\n }\n }\n return false;\n}\n//# sourceMappingURL=isId3Footer.js.map","/**\n * Returns true if an ID3 header can be found at offset in data\n *\n * @param data - The data to search in\n * @param offset - The offset at which to start searching\n *\n * @returns `true` if an ID3 header is found\n *\n * @internal\n *\n * @group ID3\n */\nexport function isId3Header(data, offset) {\n /*\n * http://id3.org/id3v2.3.0\n * [0] = 'I'\n * [1] = 'D'\n * [2] = '3'\n * [3,4] = {Version}\n * [5] = {Flags}\n * [6-9] = {ID3 Size}\n *\n * An ID3v2 tag can be detected with the following pattern:\n * $49 44 33 yy yy xx zz zz zz zz\n * Where yy is less than $FF, xx is the 'flags' byte and zz is less than $80\n */\n if (offset + 10 <= data.length) {\n // look for 'ID3' identifier\n if (data[offset] === 0x49 &&\n data[offset + 1] === 0x44 &&\n data[offset + 2] === 0x33) {\n // check version is within range\n if (data[offset + 3] < 0xff && data[offset + 4] < 0xff) {\n // check size is within range\n if (data[offset + 6] < 0x80 &&\n data[offset + 7] < 0x80 &&\n data[offset + 8] < 0x80 &&\n data[offset + 9] < 0x80) {\n return true;\n }\n }\n }\n }\n return false;\n}\n//# sourceMappingURL=isId3Header.js.map","/**\n * Read ID3 size\n *\n * @param data - The data to read from\n * @param offset - The offset at which to start reading\n *\n * @returns The size\n *\n * @internal\n *\n * @group ID3\n */\nexport function readId3Size(data, offset) {\n let size = 0;\n size = (data[offset] & 0x7f) << 21;\n size |= (data[offset + 1] & 0x7f) << 14;\n size |= (data[offset + 2] & 0x7f) << 7;\n size |= data[offset + 3] & 0x7f;\n return size;\n}\n//# sourceMappingURL=readId3Size.js.map","import { isId3Footer } from './util/isId3Footer.js';\nimport { isId3Header } from './util/isId3Header.js';\nimport { readId3Size } from './util/readId3Size.js';\n/**\n * Returns any adjacent ID3 tags found in data starting at offset, as one block of data\n *\n * @param data - The data to search in\n * @param offset - The offset at which to start searching\n *\n * @returns The block of data containing any ID3 tags found\n * or `undefined` if no header is found at the starting offset\n *\n * @internal\n *\n * @group ID3\n */\nexport function getId3Data(data, offset) {\n const front = offset;\n let length = 0;\n while (isId3Header(data, offset)) {\n // ID3 header is 10 bytes\n length += 10;\n const size = readId3Size(data, offset + 6);\n length += size;\n if (isId3Footer(data, offset + 10)) {\n // ID3 footer is 10 bytes\n length += 10;\n }\n offset += length;\n }\n if (length > 0) {\n return data.subarray(front, front + length);\n }\n return undefined;\n}\n//# sourceMappingURL=getId3Data.js.map","export enum ErrorTypes {\n // Identifier for a network error (loading error / timeout ...)\n NETWORK_ERROR = 'networkError',\n // Identifier for a media Error (video/parsing/mediasource error)\n MEDIA_ERROR = 'mediaError',\n // EME (encrypted media extensions) errors\n KEY_SYSTEM_ERROR = 'keySystemError',\n // Identifier for a mux Error (demuxing/remuxing)\n MUX_ERROR = 'muxError',\n // Identifier for all other errors\n OTHER_ERROR = 'otherError',\n}\n\nexport enum ErrorDetails {\n KEY_SYSTEM_NO_KEYS = 'keySystemNoKeys',\n KEY_SYSTEM_NO_ACCESS = 'keySystemNoAccess',\n KEY_SYSTEM_NO_SESSION = 'keySystemNoSession',\n KEY_SYSTEM_NO_CONFIGURED_LICENSE = 'keySystemNoConfiguredLicense',\n KEY_SYSTEM_LICENSE_REQUEST_FAILED = 'keySystemLicenseRequestFailed',\n KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED = 'keySystemServerCertificateRequestFailed',\n KEY_SYSTEM_SERVER_CERTIFICATE_UPDATE_FAILED = 'keySystemServerCertificateUpdateFailed',\n KEY_SYSTEM_SESSION_UPDATE_FAILED = 'keySystemSessionUpdateFailed',\n KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED = 'keySystemStatusOutputRestricted',\n KEY_SYSTEM_STATUS_INTERNAL_ERROR = 'keySystemStatusInternalError',\n KEY_SYSTEM_DESTROY_MEDIA_KEYS_ERROR = 'keySystemDestroyMediaKeysError',\n KEY_SYSTEM_DESTROY_CLOSE_SESSION_ERROR = 'keySystemDestroyCloseSessionError',\n KEY_SYSTEM_DESTROY_REMOVE_SESSION_ERROR = 'keySystemDestroyRemoveSessionError',\n // Identifier for a manifest load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n MANIFEST_LOAD_ERROR = 'manifestLoadError',\n // Identifier for a manifest load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n MANIFEST_LOAD_TIMEOUT = 'manifestLoadTimeOut',\n // Identifier for a manifest parsing error - data: { url : faulty URL, reason : error reason}\n MANIFEST_PARSING_ERROR = 'manifestParsingError',\n // Identifier for a manifest with only incompatible codecs error - data: { url : faulty URL, reason : error reason}\n MANIFEST_INCOMPATIBLE_CODECS_ERROR = 'manifestIncompatibleCodecsError',\n // Identifier for a level which contains no fragments - data: { url: faulty URL, reason: \"no fragments found in level\", level: index of the bad level }\n LEVEL_EMPTY_ERROR = 'levelEmptyError',\n // Identifier for a level load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n LEVEL_LOAD_ERROR = 'levelLoadError',\n // Identifier for a level load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n LEVEL_LOAD_TIMEOUT = 'levelLoadTimeOut',\n // Identifier for a level parse error - data: { url : faulty URL, error: Error, reason: error message }\n LEVEL_PARSING_ERROR = 'levelParsingError',\n // Identifier for a level switch error - data: { level : faulty level Id, event : error description}\n LEVEL_SWITCH_ERROR = 'levelSwitchError',\n // Identifier for an audio track load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n AUDIO_TRACK_LOAD_ERROR = 'audioTrackLoadError',\n // Identifier for an audio track load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n AUDIO_TRACK_LOAD_TIMEOUT = 'audioTrackLoadTimeOut',\n // Identifier for a subtitle track load error - data: { url : faulty URL, response : { code: error code, text: error text }}\n SUBTITLE_LOAD_ERROR = 'subtitleTrackLoadError',\n // Identifier for a subtitle track load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}\n SUBTITLE_TRACK_LOAD_TIMEOUT = 'subtitleTrackLoadTimeOut',\n // Identifier for fragment load error - data: { frag : fragment object, response : { code: error code, text: error text }}\n FRAG_LOAD_ERROR = 'fragLoadError',\n // Identifier for fragment load timeout error - data: { frag : fragment object}\n FRAG_LOAD_TIMEOUT = 'fragLoadTimeOut',\n // Identifier for a fragment decryption error event - data: {id : demuxer Id,frag: fragment object, reason : parsing error description }\n FRAG_DECRYPT_ERROR = 'fragDecryptError',\n // Identifier for a fragment parsing error event - data: { id : demuxer Id, reason : parsing error description }\n // will be renamed DEMUX_PARSING_ERROR and switched to MUX_ERROR in the next major release\n FRAG_PARSING_ERROR = 'fragParsingError',\n // Identifier for a fragment or part load skipped because of a GAP tag or attribute\n FRAG_GAP = 'fragGap',\n // Identifier for a remux alloc error event - data: { id : demuxer Id, frag : fragment object, bytes : nb of bytes on which allocation failed , reason : error text }\n REMUX_ALLOC_ERROR = 'remuxAllocError',\n // Identifier for decrypt key load error - data: { frag : fragment object, response : { code: error code, text: error text }}\n KEY_LOAD_ERROR = 'keyLoadError',\n // Identifier for decrypt key load timeout error - data: { frag : fragment object}\n KEY_LOAD_TIMEOUT = 'keyLoadTimeOut',\n // Triggered when an exception occurs while adding a sourceBuffer to MediaSource - data : { error : exception , mimeType : mimeType }\n BUFFER_ADD_CODEC_ERROR = 'bufferAddCodecError',\n // Triggered when source buffer(s) could not be created using level (manifest CODECS attribute), parsed media, or best guess codec(s) - data: { reason : error reason }\n BUFFER_INCOMPATIBLE_CODECS_ERROR = 'bufferIncompatibleCodecsError',\n // Identifier for a buffer append error - data: append error description\n BUFFER_APPEND_ERROR = 'bufferAppendError',\n // Identifier for a buffer appending error event - data: appending error description\n BUFFER_APPENDING_ERROR = 'bufferAppendingError',\n // Identifier for a buffer stalled error event\n BUFFER_STALLED_ERROR = 'bufferStalledError',\n // Identifier for a buffer full event\n BUFFER_FULL_ERROR = 'bufferFullError',\n // Identifier for a buffer seek over hole event\n BUFFER_SEEK_OVER_HOLE = 'bufferSeekOverHole',\n // Identifier for a buffer nudge on stall (playback is stuck although currentTime is in a buffered area)\n BUFFER_NUDGE_ON_STALL = 'bufferNudgeOnStall',\n // Identifier for a Interstitial Asset List load error - data: { url: faulty URL, response: { code: error code, text: error text } }\n ASSET_LIST_LOAD_ERROR = 'assetListLoadError',\n // Identifier for a Interstitial Asset List load timeout - data: { url: faulty URL, response: { code: error code, text: error text } }\n ASSET_LIST_LOAD_TIMEOUT = 'assetListLoadTimeout',\n // Identifier for a Interstitial Asset List parsing error - data: { url : faulty URL, reason : error reason, response : { code: error code, text: error text }}\n ASSET_LIST_PARSING_ERROR = 'assetListParsingError',\n // Identifier for a Interstitial Asset List parsing error - data: { url : faulty URL, reason : error reason, response : { code: error code, text: error text }}\n INTERSTITIAL_ASSET_ITEM_ERROR = 'interstitialAssetItemError',\n // Identifier for an internal exception happening inside hls.js while handling an event\n INTERNAL_EXCEPTION = 'internalException',\n // Identifier for an internal call to abort a loader\n INTERNAL_ABORTED = 'aborted',\n // Triggered when attachMedia fails\n ATTACH_MEDIA_ERROR = 'attachMediaError',\n // Uncategorized error\n UNKNOWN = 'unknown',\n}\n","import type {\n AssetListLoadedData,\n AssetListLoadingData,\n AudioTrackLoadedData,\n AudioTracksUpdatedData,\n AudioTrackSwitchedData,\n AudioTrackSwitchingData,\n AudioTrackUpdatedData,\n BackBufferData,\n BufferAppendedData,\n BufferAppendingData,\n BufferCodecsData,\n BufferCreatedData,\n BufferEOSData,\n BufferFlushedData,\n BufferFlushingData,\n CuesParsedData,\n ErrorData,\n FPSDropData,\n FPSDropLevelCappingData,\n FragBufferedData,\n FragChangedData,\n FragDecryptedData,\n FragLoadedData,\n FragLoadEmergencyAbortedData,\n FragLoadingData,\n FragParsedData,\n FragParsingInitSegmentData,\n FragParsingMetadataData,\n FragParsingUserdataData,\n InitPTSFoundData,\n InterstitialAssetEndedData,\n InterstitialAssetErrorData,\n InterstitialAssetPlayerCreatedData,\n InterstitialAssetStartedData,\n InterstitialEndedData,\n InterstitialsBufferedToBoundaryData,\n InterstitialsPrimaryResumed,\n InterstitialStartedData,\n InterstitialsUpdatedData,\n KeyLoadedData,\n KeyLoadingData,\n LevelLoadedData,\n LevelLoadingData,\n LevelPTSUpdatedData,\n LevelsUpdatedData,\n LevelSwitchedData,\n LevelSwitchingData,\n LevelUpdatedData,\n LiveBackBufferData,\n ManifestLoadedData,\n ManifestLoadingData,\n ManifestParsedData,\n MaxAutoLevelUpdatedData,\n MediaAttachedData,\n MediaAttachingData,\n MediaDetachedData,\n MediaDetachingData,\n MediaEndedData,\n NonNativeTextTracksData,\n SteeringManifestLoadedData,\n SubtitleFragProcessedData,\n SubtitleTrackLoadedData,\n SubtitleTracksUpdatedData,\n SubtitleTrackSwitchData,\n SubtitleTrackUpdatedData,\n TrackLoadingData,\n} from './types/events';\n\nexport enum Events {\n // Fired before MediaSource is attaching to media element\n MEDIA_ATTACHING = 'hlsMediaAttaching',\n // Fired when MediaSource has been successfully attached to media element\n MEDIA_ATTACHED = 'hlsMediaAttached',\n // Fired before detaching MediaSource from media element\n MEDIA_DETACHING = 'hlsMediaDetaching',\n // Fired when MediaSource has been detached from media element\n MEDIA_DETACHED = 'hlsMediaDetached',\n // Fired when HTMLMediaElement dispatches \"ended\" event, or stalls at end of VOD program\n MEDIA_ENDED = 'hlsMediaEnded',\n // Fired after playback stall is resolved with playing, seeked, or ended event following BUFFER_STALLED_ERROR\n STALL_RESOLVED = 'hlsStallResolved',\n // Fired when the buffer is going to be reset\n BUFFER_RESET = 'hlsBufferReset',\n // Fired when we know about the codecs that we need buffers for to push into - data: {tracks : { container, codec, levelCodec, initSegment, metadata }}\n BUFFER_CODECS = 'hlsBufferCodecs',\n // fired when sourcebuffers have been created - data: { tracks : tracks }\n BUFFER_CREATED = 'hlsBufferCreated',\n // fired when we append a segment to the buffer - data: { segment: segment object }\n BUFFER_APPENDING = 'hlsBufferAppending',\n // fired when we are done with appending a media segment to the buffer - data : { parent : segment parent that triggered BUFFER_APPENDING, pending : nb of segments waiting for appending for this segment parent}\n BUFFER_APPENDED = 'hlsBufferAppended',\n // fired when the stream is finished and we want to notify the media buffer that there will be no more data - data: { }\n BUFFER_EOS = 'hlsBufferEos',\n // fired when all buffers are full to the end of the program, after calling MediaSource.endOfStream() (unless restricted)\n BUFFERED_TO_END = 'hlsBufferedToEnd',\n // fired when the media buffer should be flushed - data { startOffset, endOffset }\n BUFFER_FLUSHING = 'hlsBufferFlushing',\n // fired when the media buffer has been flushed - data: { }\n BUFFER_FLUSHED = 'hlsBufferFlushed',\n // fired to signal that a manifest loading starts - data: { url : manifestURL}\n MANIFEST_LOADING = 'hlsManifestLoading',\n // fired after manifest has been loaded - data: { levels : [available quality levels], audioTracks : [ available audio tracks ], url : manifestURL, stats : LoaderStats }\n MANIFEST_LOADED = 'hlsManifestLoaded',\n // fired after manifest has been parsed - data: { levels : [available quality levels], firstLevel : index of first quality level appearing in Manifest}\n MANIFEST_PARSED = 'hlsManifestParsed',\n // fired when a level switch is requested - data: { level : id of new level }\n LEVEL_SWITCHING = 'hlsLevelSwitching',\n // fired when a level switch is effective - data: { level : id of new level }\n LEVEL_SWITCHED = 'hlsLevelSwitched',\n // fired when a level playlist loading starts - data: { url : level URL, level : id of level being loaded}\n LEVEL_LOADING = 'hlsLevelLoading',\n // fired when a level playlist loading finishes - data: { details : levelDetails object, level : id of loaded level, stats : LoaderStats }\n LEVEL_LOADED = 'hlsLevelLoaded',\n // fired when a level's details have been updated based on previous details, after it has been loaded - data: { details : levelDetails object, level : id of updated level }\n LEVEL_UPDATED = 'hlsLevelUpdated',\n // fired when a level's PTS information has been updated after parsing a fragment - data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }\n LEVEL_PTS_UPDATED = 'hlsLevelPtsUpdated',\n // fired to notify that levels have changed after removing a level - data: { levels : [available quality levels] }\n LEVELS_UPDATED = 'hlsLevelsUpdated',\n // fired to notify that audio track lists has been updated - data: { audioTracks : audioTracks }\n AUDIO_TRACKS_UPDATED = 'hlsAudioTracksUpdated',\n // fired when an audio track switching is requested - data: { id : audio track id }\n AUDIO_TRACK_SWITCHING = 'hlsAudioTrackSwitching',\n // fired when an audio track switch actually occurs - data: { id : audio track id }\n AUDIO_TRACK_SWITCHED = 'hlsAudioTrackSwitched',\n // fired when an audio track loading starts - data: { url : audio track URL, id : audio track id }\n AUDIO_TRACK_LOADING = 'hlsAudioTrackLoading',\n // fired when an audio track loading finishes - data: { details : levelDetails object, id : audio track id, stats : LoaderStats }\n AUDIO_TRACK_LOADED = 'hlsAudioTrackLoaded',\n // fired when an audio tracks's details have been updated based on previous details, after it has been loaded - data: { details : levelDetails object, id : track id }\n AUDIO_TRACK_UPDATED = 'hlsAudioTrackUpdated',\n // fired to notify that subtitle track lists has been updated - data: { subtitleTracks : subtitleTracks }\n SUBTITLE_TRACKS_UPDATED = 'hlsSubtitleTracksUpdated',\n // fired to notify that subtitle tracks were cleared as a result of stopping the media\n SUBTITLE_TRACKS_CLEARED = 'hlsSubtitleTracksCleared',\n // fired when an subtitle track switch occurs - data: { id : subtitle track id }\n SUBTITLE_TRACK_SWITCH = 'hlsSubtitleTrackSwitch',\n // fired when a subtitle track loading starts - data: { url : subtitle track URL, id : subtitle track id }\n SUBTITLE_TRACK_LOADING = 'hlsSubtitleTrackLoading',\n // fired when a subtitle track loading finishes - data: { details : levelDetails object, id : subtitle track id, stats : LoaderStats }\n SUBTITLE_TRACK_LOADED = 'hlsSubtitleTrackLoaded',\n // fired when a subtitle racks's details have been updated based on previous details, after it has been loaded - data: { details : levelDetails object, id : track id }\n SUBTITLE_TRACK_UPDATED = 'hlsSubtitleTrackUpdated',\n // fired when a subtitle fragment has been processed - data: { success : boolean, frag : the processed frag }\n SUBTITLE_FRAG_PROCESSED = 'hlsSubtitleFragProcessed',\n // fired when a set of VTTCues to be managed externally has been parsed - data: { type: string, track: string, cues: [ VTTCue ] }\n CUES_PARSED = 'hlsCuesParsed',\n // fired when a text track to be managed externally is found - data: { tracks: [ { label: string, kind: string, default: boolean } ] }\n NON_NATIVE_TEXT_TRACKS_FOUND = 'hlsNonNativeTextTracksFound',\n // fired when the first timestamp is found - data: { id : demuxer id, initPTS: initPTS, timescale: timescale, frag : fragment object }\n INIT_PTS_FOUND = 'hlsInitPtsFound',\n // fired when a fragment loading starts - data: { frag : fragment object }\n FRAG_LOADING = 'hlsFragLoading',\n // fired when a fragment loading is progressing - data: { frag : fragment object, { trequest, tfirst, loaded } }\n // FRAG_LOAD_PROGRESS = 'hlsFragLoadProgress',\n // Identifier for fragment load aborting for emergency switch down - data: { frag : fragment object }\n FRAG_LOAD_EMERGENCY_ABORTED = 'hlsFragLoadEmergencyAborted',\n // fired when a fragment loading is completed - data: { frag : fragment object, payload : fragment payload, stats : LoaderStats }\n FRAG_LOADED = 'hlsFragLoaded',\n // fired when a fragment has finished decrypting - data: { id : demuxer id, frag: fragment object, payload : fragment payload, stats : { tstart, tdecrypt } }\n FRAG_DECRYPTED = 'hlsFragDecrypted',\n // fired when Init Segment has been extracted from fragment - data: { id : demuxer id, frag: fragment object, moov : moov MP4 box, codecs : codecs found while parsing fragment }\n FRAG_PARSING_INIT_SEGMENT = 'hlsFragParsingInitSegment',\n // fired when parsing sei text is completed - data: { id : demuxer id, frag: fragment object, samples : [ sei samples pes ] }\n FRAG_PARSING_USERDATA = 'hlsFragParsingUserdata',\n // fired when parsing id3 is completed - data: { id : demuxer id, frag: fragment object, samples : [ id3 samples pes ] }\n FRAG_PARSING_METADATA = 'hlsFragParsingMetadata',\n // fired when data have been extracted from fragment - data: { id : demuxer id, frag: fragment object, data1 : moof MP4 box or TS fragments, data2 : mdat MP4 box or null}\n // FRAG_PARSING_DATA = 'hlsFragParsingData',\n // fired when fragment parsing is completed - data: { id : demuxer id, frag: fragment object }\n FRAG_PARSED = 'hlsFragParsed',\n // fired when fragment remuxed MP4 boxes have all been appended into SourceBuffer - data: { id : demuxer id, frag : fragment object, stats : LoaderStats }\n FRAG_BUFFERED = 'hlsFragBuffered',\n // fired when fragment matching with current media position is changing - data : { id : demuxer id, frag : fragment object }\n FRAG_CHANGED = 'hlsFragChanged',\n // Identifier for a FPS drop event - data: { currentDropped, currentDecoded, totalDroppedFrames }\n FPS_DROP = 'hlsFpsDrop',\n // triggered when FPS drop triggers auto level capping - data: { level, droppedLevel }\n FPS_DROP_LEVEL_CAPPING = 'hlsFpsDropLevelCapping',\n // triggered when maxAutoLevel changes - data { autoLevelCapping, levels, maxAutoLevel, minAutoLevel, maxHdcpLevel }\n MAX_AUTO_LEVEL_UPDATED = 'hlsMaxAutoLevelUpdated',\n // Identifier for an error event - data: { type : error type, details : error details, fatal : if true, hls.js cannot/will not try to recover, if false, hls.js will try to recover,other error specific data }\n ERROR = 'hlsError',\n // fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a media to the instance of hls.js to handle mid-rolls for example - data: { }\n DESTROYING = 'hlsDestroying',\n // fired when a decrypt key loading starts - data: { frag : fragment object }\n KEY_LOADING = 'hlsKeyLoading',\n // fired when a decrypt key loading is completed - data: { frag : fragment object, keyInfo : KeyLoaderInfo }\n KEY_LOADED = 'hlsKeyLoaded',\n // deprecated; please use BACK_BUFFER_REACHED - data : { bufferEnd: number }\n LIVE_BACK_BUFFER_REACHED = 'hlsLiveBackBufferReached',\n // fired when the back buffer is reached as defined by the backBufferLength config option - data : { bufferEnd: number }\n BACK_BUFFER_REACHED = 'hlsBackBufferReached',\n // fired after steering manifest has been loaded - data: { steeringManifest: SteeringManifest object, url: steering manifest URL }\n STEERING_MANIFEST_LOADED = 'hlsSteeringManifestLoaded',\n // fired when asset list has begun loading\n ASSET_LIST_LOADING = 'hlsAssetListLoading',\n // fired when a valid asset list is loaded\n ASSET_LIST_LOADED = 'hlsAssetListLoaded',\n // fired when the list of Interstitial Events and Interstitial Schedule is updated\n INTERSTITIALS_UPDATED = 'hlsInterstitialsUpdated',\n // fired when the buffer reaches an Interstitial Schedule boundary (both Primary segments and Interstitial Assets)\n INTERSTITIALS_BUFFERED_TO_BOUNDARY = 'hlsInterstitialsBufferedToBoundary',\n // fired when a player instance for an Interstitial Asset has been created\n INTERSTITIAL_ASSET_PLAYER_CREATED = 'hlsInterstitialAssetPlayerCreated',\n // Interstitial playback started\n INTERSTITIAL_STARTED = 'hlsInterstitialStarted',\n // InterstitialAsset playback started\n INTERSTITIAL_ASSET_STARTED = 'hlsInterstitialAssetStarted',\n // InterstitialAsset playback ended\n INTERSTITIAL_ASSET_ENDED = 'hlsInterstitialAssetEnded',\n // InterstitialAsset playback errored\n INTERSTITIAL_ASSET_ERROR = 'hlsInterstitialAssetError',\n // Interstitial playback ended\n INTERSTITIAL_ENDED = 'hlsInterstitialEnded',\n // Interstitial schedule resumed primary playback\n INTERSTITIALS_PRIMARY_RESUMED = 'hlsInterstitialsPrimaryResumed',\n // Interstitial players dispatch this event when playout limit is reached\n PLAYOUT_LIMIT_REACHED = 'hlsPlayoutLimitReached',\n // Event DateRange cue \"enter\" event dispatched\n EVENT_CUE_ENTER = 'hlsEventCueEnter',\n}\n\n/**\n * Defines each Event type and payload by Event name. Used in {@link hls.js#HlsEventEmitter} to strongly type the event listener API.\n */\nexport interface HlsListeners {\n [Events.MEDIA_ATTACHING]: (\n event: Events.MEDIA_ATTACHING,\n data: MediaAttachingData,\n ) => void;\n [Events.MEDIA_ATTACHED]: (\n event: Events.MEDIA_ATTACHED,\n data: MediaAttachedData,\n ) => void;\n [Events.MEDIA_DETACHING]: (\n event: Events.MEDIA_DETACHING,\n data: MediaDetachingData,\n ) => void;\n [Events.MEDIA_DETACHED]: (\n event: Events.MEDIA_DETACHED,\n data: MediaDetachedData,\n ) => void;\n [Events.MEDIA_ENDED]: (\n event: Events.MEDIA_ENDED,\n data: MediaEndedData,\n ) => void;\n [Events.STALL_RESOLVED]: (event: Events.STALL_RESOLVED, data: {}) => void;\n [Events.BUFFER_RESET]: (event: Events.BUFFER_RESET) => void;\n [Events.BUFFER_CODECS]: (\n event: Events.BUFFER_CODECS,\n data: BufferCodecsData,\n ) => void;\n [Events.BUFFER_CREATED]: (\n event: Events.BUFFER_CREATED,\n data: BufferCreatedData,\n ) => void;\n [Events.BUFFER_APPENDING]: (\n event: Events.BUFFER_APPENDING,\n data: BufferAppendingData,\n ) => void;\n [Events.BUFFER_APPENDED]: (\n event: Events.BUFFER_APPENDED,\n data: BufferAppendedData,\n ) => void;\n [Events.BUFFER_EOS]: (event: Events.BUFFER_EOS, data: BufferEOSData) => void;\n [Events.BUFFERED_TO_END]: (event: Events.BUFFERED_TO_END) => void;\n [Events.BUFFER_FLUSHING]: (\n event: Events.BUFFER_FLUSHING,\n data: BufferFlushingData,\n ) => void;\n [Events.BUFFER_FLUSHED]: (\n event: Events.BUFFER_FLUSHED,\n data: BufferFlushedData,\n ) => void;\n [Events.MANIFEST_LOADING]: (\n event: Events.MANIFEST_LOADING,\n data: ManifestLoadingData,\n ) => void;\n [Events.MANIFEST_LOADED]: (\n event: Events.MANIFEST_LOADED,\n data: ManifestLoadedData,\n ) => void;\n [Events.MANIFEST_PARSED]: (\n event: Events.MANIFEST_PARSED,\n data: ManifestParsedData,\n ) => void;\n [Events.LEVEL_SWITCHING]: (\n event: Events.LEVEL_SWITCHING,\n data: LevelSwitchingData,\n ) => void;\n [Events.LEVEL_SWITCHED]: (\n event: Events.LEVEL_SWITCHED,\n data: LevelSwitchedData,\n ) => void;\n [Events.LEVEL_LOADING]: (\n event: Events.LEVEL_LOADING,\n data: LevelLoadingData,\n ) => void;\n [Events.LEVEL_LOADED]: (\n event: Events.LEVEL_LOADED,\n data: LevelLoadedData,\n ) => void;\n [Events.LEVEL_UPDATED]: (\n event: Events.LEVEL_UPDATED,\n data: LevelUpdatedData,\n ) => void;\n [Events.LEVEL_PTS_UPDATED]: (\n event: Events.LEVEL_PTS_UPDATED,\n data: LevelPTSUpdatedData,\n ) => void;\n [Events.LEVELS_UPDATED]: (\n event: Events.LEVELS_UPDATED,\n data: LevelsUpdatedData,\n ) => void;\n [Events.AUDIO_TRACKS_UPDATED]: (\n event: Events.AUDIO_TRACKS_UPDATED,\n data: AudioTracksUpdatedData,\n ) => void;\n [Events.AUDIO_TRACK_SWITCHING]: (\n event: Events.AUDIO_TRACK_SWITCHING,\n data: AudioTrackSwitchingData,\n ) => void;\n [Events.AUDIO_TRACK_SWITCHED]: (\n event: Events.AUDIO_TRACK_SWITCHED,\n data: AudioTrackSwitchedData,\n ) => void;\n [Events.AUDIO_TRACK_LOADING]: (\n event: Events.AUDIO_TRACK_LOADING,\n data: TrackLoadingData,\n ) => void;\n [Events.AUDIO_TRACK_LOADED]: (\n event: Events.AUDIO_TRACK_LOADED,\n data: AudioTrackLoadedData,\n ) => void;\n [Events.AUDIO_TRACK_UPDATED]: (\n event: Events.AUDIO_TRACK_UPDATED,\n data: AudioTrackUpdatedData,\n ) => void;\n [Events.SUBTITLE_TRACKS_UPDATED]: (\n event: Events.SUBTITLE_TRACKS_UPDATED,\n data: SubtitleTracksUpdatedData,\n ) => void;\n [Events.SUBTITLE_TRACKS_CLEARED]: (\n event: Events.SUBTITLE_TRACKS_CLEARED,\n ) => void;\n [Events.SUBTITLE_TRACK_SWITCH]: (\n event: Events.SUBTITLE_TRACK_SWITCH,\n data: SubtitleTrackSwitchData,\n ) => void;\n [Events.SUBTITLE_TRACK_LOADING]: (\n event: Events.SUBTITLE_TRACK_LOADING,\n data: TrackLoadingData,\n ) => void;\n [Events.SUBTITLE_TRACK_LOADED]: (\n event: Events.SUBTITLE_TRACK_LOADED,\n data: SubtitleTrackLoadedData,\n ) => void;\n [Events.SUBTITLE_TRACK_UPDATED]: (\n event: Events.SUBTITLE_TRACK_UPDATED,\n data: SubtitleTrackUpdatedData,\n ) => void;\n [Events.SUBTITLE_FRAG_PROCESSED]: (\n event: Events.SUBTITLE_FRAG_PROCESSED,\n data: SubtitleFragProcessedData,\n ) => void;\n [Events.CUES_PARSED]: (\n event: Events.CUES_PARSED,\n data: CuesParsedData,\n ) => void;\n [Events.NON_NATIVE_TEXT_TRACKS_FOUND]: (\n event: Events.NON_NATIVE_TEXT_TRACKS_FOUND,\n data: NonNativeTextTracksData,\n ) => void;\n [Events.INIT_PTS_FOUND]: (\n event: Events.INIT_PTS_FOUND,\n data: InitPTSFoundData,\n ) => void;\n [Events.FRAG_LOADING]: (\n event: Events.FRAG_LOADING,\n data: FragLoadingData,\n ) => void;\n // [Events.FRAG_LOAD_PROGRESS]: TodoEventType\n [Events.FRAG_LOAD_EMERGENCY_ABORTED]: (\n event: Events.FRAG_LOAD_EMERGENCY_ABORTED,\n data: FragLoadEmergencyAbortedData,\n ) => void;\n [Events.FRAG_LOADED]: (\n event: Events.FRAG_LOADED,\n data: FragLoadedData,\n ) => void;\n [Events.FRAG_DECRYPTED]: (\n event: Events.FRAG_DECRYPTED,\n data: FragDecryptedData,\n ) => void;\n [Events.FRAG_PARSING_INIT_SEGMENT]: (\n event: Events.FRAG_PARSING_INIT_SEGMENT,\n data: FragParsingInitSegmentData,\n ) => void;\n [Events.FRAG_PARSING_USERDATA]: (\n event: Events.FRAG_PARSING_USERDATA,\n data: FragParsingUserdataData,\n ) => void;\n [Events.FRAG_PARSING_METADATA]: (\n event: Events.FRAG_PARSING_METADATA,\n data: FragParsingMetadataData,\n ) => void;\n // [Events.FRAG_PARSING_DATA]: TodoEventType\n [Events.FRAG_PARSED]: (\n event: Events.FRAG_PARSED,\n data: FragParsedData,\n ) => void;\n [Events.FRAG_BUFFERED]: (\n event: Events.FRAG_BUFFERED,\n data: FragBufferedData,\n ) => void;\n [Events.FRAG_CHANGED]: (\n event: Events.FRAG_CHANGED,\n data: FragChangedData,\n ) => void;\n [Events.FPS_DROP]: (event: Events.FPS_DROP, data: FPSDropData) => void;\n [Events.FPS_DROP_LEVEL_CAPPING]: (\n event: Events.FPS_DROP_LEVEL_CAPPING,\n data: FPSDropLevelCappingData,\n ) => void;\n [Events.MAX_AUTO_LEVEL_UPDATED]: (\n event: Events.MAX_AUTO_LEVEL_UPDATED,\n data: MaxAutoLevelUpdatedData,\n ) => void;\n [Events.ERROR]: (event: Events.ERROR, data: ErrorData) => void;\n [Events.DESTROYING]: (event: Events.DESTROYING) => void;\n [Events.KEY_LOADING]: (\n event: Events.KEY_LOADING,\n data: KeyLoadingData,\n ) => void;\n [Events.KEY_LOADED]: (event: Events.KEY_LOADED, data: KeyLoadedData) => void;\n [Events.LIVE_BACK_BUFFER_REACHED]: (\n event: Events.LIVE_BACK_BUFFER_REACHED,\n data: LiveBackBufferData,\n ) => void;\n [Events.BACK_BUFFER_REACHED]: (\n event: Events.BACK_BUFFER_REACHED,\n data: BackBufferData,\n ) => void;\n [Events.STEERING_MANIFEST_LOADED]: (\n event: Events.STEERING_MANIFEST_LOADED,\n data: SteeringManifestLoadedData,\n ) => void;\n [Events.ASSET_LIST_LOADING]: (\n event: Events.ASSET_LIST_LOADING,\n data: AssetListLoadingData,\n ) => void;\n [Events.ASSET_LIST_LOADED]: (\n event: Events.ASSET_LIST_LOADED,\n data: AssetListLoadedData,\n ) => void;\n [Events.INTERSTITIALS_UPDATED]: (\n event: Events.INTERSTITIALS_UPDATED,\n data: InterstitialsUpdatedData,\n ) => void;\n [Events.INTERSTITIALS_BUFFERED_TO_BOUNDARY]: (\n event: Events.INTERSTITIALS_BUFFERED_TO_BOUNDARY,\n data: InterstitialsBufferedToBoundaryData,\n ) => void;\n [Events.INTERSTITIAL_ASSET_PLAYER_CREATED]: (\n event: Events.INTERSTITIAL_ASSET_PLAYER_CREATED,\n data: InterstitialAssetPlayerCreatedData,\n ) => void;\n [Events.INTERSTITIAL_STARTED]: (\n event: Events.INTERSTITIAL_STARTED,\n data: InterstitialStartedData,\n ) => void;\n [Events.INTERSTITIAL_ASSET_STARTED]: (\n event: Events.INTERSTITIAL_ASSET_STARTED,\n data: InterstitialAssetStartedData,\n ) => void;\n [Events.INTERSTITIAL_ASSET_ENDED]: (\n event: Events.INTERSTITIAL_ASSET_ENDED,\n data: InterstitialAssetEndedData,\n ) => void;\n [Events.INTERSTITIAL_ASSET_ERROR]: (\n event: Events.INTERSTITIAL_ASSET_ERROR,\n data: InterstitialAssetErrorData,\n ) => void;\n [Events.INTERSTITIAL_ENDED]: (\n event: Events.INTERSTITIAL_ENDED,\n data: InterstitialEndedData,\n ) => void;\n [Events.INTERSTITIALS_PRIMARY_RESUMED]: (\n event: Events.INTERSTITIALS_PRIMARY_RESUMED,\n data: InterstitialsPrimaryResumed,\n ) => void;\n [Events.PLAYOUT_LIMIT_REACHED]: (\n event: Events.PLAYOUT_LIMIT_REACHED,\n data: {},\n ) => void;\n [Events.EVENT_CUE_ENTER]: (event: Events.EVENT_CUE_ENTER, data: {}) => void;\n}\nexport interface HlsEventEmitter {\n on<E extends keyof HlsListeners, Context = undefined>(\n event: E,\n listener: HlsListeners[E],\n context?: Context,\n ): void;\n once<E extends keyof HlsListeners, Context = undefined>(\n event: E,\n listener: HlsListeners[E],\n context?: Context,\n ): void;\n\n removeAllListeners<E extends keyof HlsListeners>(event?: E): void;\n off<E extends keyof HlsListeners, Context = undefined>(\n event: E,\n listener?: HlsListeners[E],\n context?: Context,\n once?: boolean,\n ): void;\n\n listeners<E extends keyof HlsListeners>(event: E): HlsListeners[E][];\n emit<E extends keyof HlsListeners>(\n event: E,\n name: E,\n eventObject: Parameters<HlsListeners[E]>[1],\n ): boolean;\n listenerCount<E extends keyof HlsListeners>(event: E): number;\n}\n","export interface ILogFunction {\n (message?: any, ...optionalParams: any[]): void;\n}\n\nexport interface ILogger {\n trace: ILogFunction;\n debug: ILogFunction;\n log: ILogFunction;\n warn: ILogFunction;\n info: ILogFunction;\n error: ILogFunction;\n}\n\nexport class Logger implements ILogger {\n trace: ILogFunction;\n debug: ILogFunction;\n log: ILogFunction;\n warn: ILogFunction;\n info: ILogFunction;\n error: ILogFunction;\n\n constructor(label: string, logger: ILogger) {\n const lb = `[${label}]:`;\n this.trace = noop;\n this.debug = logger.debug.bind(null, lb);\n this.log = logger.log.bind(null, lb);\n this.warn = logger.warn.bind(null, lb);\n this.info = logger.info.bind(null, lb);\n this.error = logger.error.bind(null, lb);\n }\n}\n\nconst noop: ILogFunction = function () {};\n\nconst fakeLogger: ILogger = {\n trace: noop,\n debug: noop,\n log: noop,\n warn: noop,\n info: noop,\n error: noop,\n};\n\nfunction createLogger() {\n return Object.assign({}, fakeLogger);\n}\n\n// let lastCallTime;\n// function formatMsgWithTimeInfo(type, msg) {\n// const now = Date.now();\n// const diff = lastCallTime ? '+' + (now - lastCallTime) : '0';\n// lastCallTime = now;\n// msg = (new Date(now)).toISOString() + ' | [' + type + '] > ' + msg + ' ( ' + diff + ' ms )';\n// return msg;\n// }\n\nfunction consolePrintFn(type: string, id: string | undefined): ILogFunction {\n const func: ILogFunction = self.console[type];\n return func\n ? func.bind(self.console, `${id ? '[' + id + '] ' : ''}[${type}] >`)\n : noop;\n}\n\nfunction getLoggerFn(\n key: string,\n debugConfig: boolean | Partial<ILogger>,\n id?: string,\n): ILogFunction {\n return debugConfig[key]\n ? debugConfig[key].bind(debugConfig)\n : consolePrintFn(key, id);\n}\n\nconst exportedLogger: ILogger = createLogger();\n\nexport function enableLogs(\n debugConfig: boolean | ILogger,\n context: string,\n id?: string | undefined,\n): ILogger {\n // check that console is available\n const newLogger = createLogger();\n if (\n (typeof console === 'object' && debugConfig === true) ||\n typeof debugConfig === 'object'\n ) {\n const keys: (keyof ILogger)[] = [\n // Remove out from list here to hard-disable a log-level\n // 'trace',\n 'debug',\n 'log',\n 'info',\n 'warn',\n 'error',\n ];\n keys.forEach((key) => {\n newLogger[key] = getLoggerFn(key, debugConfig, id);\n });\n // Some browsers don't allow to use bind on console object anyway\n // fallback to default if needed\n try {\n newLogger.log(\n `Debug logs enabled for \"${context}\" in hls.js version ${__VERSION__}`,\n );\n } catch (e) {\n /* log fn threw an exception. All logger methods are no-ops. */\n return createLogger();\n }\n // global exported logger uses the same functions as new logger without `id`\n keys.forEach((key) => {\n exportedLogger[key] = getLoggerFn(key, debugConfig);\n });\n } else {\n // Reset global exported logger\n Object.assign(exportedLogger, newLogger);\n }\n return newLogger;\n}\n\nexport const logger: ILogger = exportedLogger;\n","/**\n * ADTS parser helper\n * @link https://wiki.multimedia.cx/index.php?title=ADTS\n */\nimport { ErrorDetails, ErrorTypes } from '../../errors';\nimport { Events } from '../../events';\nimport { logger } from '../../utils/logger';\nimport type { HlsEventEmitter } from '../../events';\nimport type {\n AudioFrame,\n AudioSample,\n DemuxedAudioTrack,\n} from '../../types/demuxer';\n\ntype AudioConfig = {\n config: [number, number];\n samplerate: number;\n channelCount: number;\n codec: string;\n parsedCodec: string;\n manifestCodec: string | undefined;\n};\n\ntype FrameHeader = {\n headerLength: number;\n frameLength: number;\n};\n\nexport function getAudioConfig(\n observer: HlsEventEmitter,\n data: Uint8Array,\n offset: number,\n manifestCodec: string | undefined,\n): AudioConfig | void {\n const adtsSamplingRates = [\n 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025,\n 8000, 7350,\n ];\n const byte2 = data[offset + 2];\n const adtsSamplingIndex = (byte2 >> 2) & 0xf;\n if (adtsSamplingIndex > 12) {\n const error = new Error(`invalid ADTS sampling index:${adtsSamplingIndex}`);\n observer.emit(Events.ERROR, Events.ERROR, {\n type: ErrorTypes.MEDIA_ERROR,\n details: ErrorDetails.FRAG_PARSING_ERROR,\n fatal: true,\n error,\n reason: error.message,\n });\n return;\n }\n // MPEG-4 Audio Object Type (profile_ObjectType+1)\n const adtsObjectType = ((byte2 >> 6) & 0x3) + 1;\n const channelCount = ((data[offset + 3] >> 6) & 0x3) | ((byte2 & 1) << 2);\n const codec = 'mp4a.40.' + adtsObjectType;\n /* refer to http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config\n ISO/IEC 14496-3 - Table 1.13 — Syntax of AudioSpecificConfig()\n Audio Profile / Audio Object Type\n 0: Null\n 1: AAC Main\n 2: AAC LC (Low Complexity)\n 3: AAC SSR (Scalable Sample Rate)\n 4: AAC LTP (Long Term Prediction)\n 5: SBR (Spectral Band Replication)\n 6: AAC Scalable\n sampling freq\n 0: 96000 Hz\n 1: 88200 Hz\n 2: 64000 Hz\n 3: 48000 Hz\n 4: 44100 Hz\n 5: 32000 Hz\n 6: 24000 Hz\n 7: 22050 Hz\n 8: 16000 Hz\n 9: 12000 Hz\n 10: 11025 Hz\n 11: 8000 Hz\n 12: 7350 Hz\n 13: Reserved\n 14: Reserved\n 15: frequency is written explictly\n Channel Configurations\n These are the channel configurations:\n 0: Defined in AOT Specifc Config\n 1: 1 channel: front-center\n 2: 2 channels: front-left, front-right\n */\n // audioObjectType = profile => profile, the MPEG-4 Audio Object Type minus 1\n const samplerate = adtsSamplingRates[adtsSamplingIndex];\n let aacSampleIndex = adtsSamplingIndex;\n if (adtsObjectType === 5 || adtsObjectType === 29) {\n // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies\n // there is a factor 2 between frame sample rate and output sample rate\n // multiply frequency by 2 (see table above, equivalent to substract 3)\n aacSampleIndex -= 3;\n }\n const config: [number, number] = [\n (adtsObjectType << 3) | ((aacSampleIndex & 0x0e) >> 1),\n ((aacSampleIndex & 0x01) << 7) | (channelCount << 3),\n ];\n logger.log(\n `manifest codec:${manifestCodec}, parsed codec:${codec}, channels:${channelCount}, rate:${samplerate} (ADTS object type:${adtsObjectType} sampling index:${adtsSamplingIndex})`,\n );\n return {\n config,\n samplerate,\n channelCount,\n codec,\n parsedCodec: codec,\n manifestCodec,\n };\n}\n\nexport function isHeaderPattern(data: Uint8Array, offset: number): boolean {\n return data[offset] === 0xff && (data[offset + 1] & 0xf6) === 0xf0;\n}\n\nexport function getHeaderLength(data: Uint8Array, offset: number): number {\n return data[offset + 1] & 0x01 ? 7 : 9;\n}\n\nexport function getFullFrameLength(data: Uint8Array, offset: number): number {\n return (\n ((data[offset + 3] & 0x03) << 11) |\n (data[offset + 4] << 3) |\n ((data[offset + 5] & 0xe0) >>> 5)\n );\n}\n\nexport function canGetFrameLength(data: Uint8Array, offset: number): boolean {\n return offset + 5 < data.length;\n}\n\nexport function isHeader(data: Uint8Array, offset: number): boolean {\n // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1\n // Layer bits (position 14 and 15) in header should be always 0 for ADTS\n // More info https://wiki.multimedia.cx/index.php?title=ADTS\n return offset + 1 < data.length && isHeaderPattern(data, offset);\n}\n\nexport function canParse(data: Uint8Array, offset: number): boolean {\n return (\n canGetFrameLength(data, offset) &&\n isHeaderPattern(data, offset) &&\n getFullFrameLength(data, offset) <= data.length - offset\n );\n}\n\nexport function probe(data: Uint8Array, offset: number): boolean {\n // same as isHeader but we also check that ADTS frame follows last ADTS frame\n // or end of data is reached\n if (isHeader(data, offset)) {\n // ADTS header Length\n const headerLength = getHeaderLength(data, offset);\n if (offset + headerLength >= data.length) {\n return false;\n }\n // ADTS frame Length\n const frameLength = getFullFrameLength(data, offset);\n if (frameLength <= headerLength) {\n return false;\n }\n\n const newOffset = offset + frameLength;\n return newOffset === data.length || isHeader(data, newOffset);\n }\n return false;\n}\n\nexport function initTrackConfig(\n track: DemuxedAudioTrack,\n observer: HlsEventEmitter,\n data: Uint8Array,\n offset: number,\n audioCodec: string | undefined,\n) {\n if (!track.samplerate) {\n const config = getAudioConfig(observer, data, offset, audioCodec);\n if (!config) {\n return;\n }\n Object.assign(track, config);\n }\n}\n\nexport function getFrameDuration(samplerate: number): number {\n return (1024 * 90000) / samplerate;\n}\n\nexport function parseFrameHeader(\n data: Uint8Array,\n offset: number,\n): FrameHeader | void {\n // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header\n const headerLength = getHeaderLength(data, offset);\n if (offset + headerLength <= data.length) {\n // retrieve frame size\n const frameLength = getFullFrameLength(data, offset) - headerLength;\n if (frameLength > 0) {\n // logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}`);\n return { headerLength, frameLength };\n }\n }\n}\n\nexport function appendFrame(\n track: DemuxedAudioTrack,\n data: Uint8Array,\n offset: number,\n pts: number,\n frameIndex: number,\n): AudioFrame {\n const frameDuration = getFrameDuration(track.samplerate as number);\n const stamp = pts + frameIndex * frameDuration;\n const header = parseFrameHeader(data, offset);\n let unit: Uint8Array;\n if (header) {\n const { frameLength, headerLength } = header;\n const length = headerLength + frameLength;\n const missing = Math.max(0, offset + length - data.length);\n // logger.log(`AAC frame ${frameIndex}, pts:${stamp} length@offset/total: ${frameLength}@${offset+headerLength}/${data.byteLength} missing: ${missing}`);\n if (missing) {\n unit = new Uint8Array(length - headerLength);\n unit.set(data.subarray(offset + headerLength, data.length), 0);\n } else {\n unit = data.subarray(offset + headerLength, offset + length);\n }\n\n const sample: AudioSample = {\n unit,\n pts: stamp,\n };\n if (!missing) {\n track.samples.push(sample as AudioSample);\n }\n\n return { sample, length, missing };\n }\n // overflow incomplete header\n const length = data.length - offset;\n unit = new Uint8Array(length);\n unit.set(data.subarray(offset, data.length), 0);\n const sample: AudioSample = {\n unit,\n pts: stamp,\n };\n return { sample, length, missing: -1 };\n}\n","// https://caniuse.com/mdn-javascript_builtins_number_isfinite\nexport const isFiniteNumber =\n Number.isFinite ||\n function (value) {\n return typeof value === 'number' && isFinite(value);\n };\n\n// https://caniuse.com/mdn-javascript_builtins_number_issafeinteger\nexport const isSafeInteger =\n Number.isSafeInteger ||\n function (value) {\n return typeof value === 'number' && Math.abs(value) <= MAX_SAFE_INTEGER;\n };\n\nexport const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;\n","import { isId3Header } from './util/isId3Header.js';\nimport { readId3Size } from './util/readId3Size.js';\n/**\n * Checks if the given data contains an ID3 tag.\n *\n * @param data - The data to check\n * @param offset - The offset at which to start checking\n *\n * @returns `true` if an ID3 tag is found\n *\n * @group ID3\n *\n * @beta\n */\nexport function canParseId3(data, offset) {\n return (isId3Header(data, offset) &&\n readId3Size(data, offset + 6) + 10 <= data.length - offset);\n}\n//# sourceMappingURL=canParseId3.js.map","// http://stackoverflow.com/questions/8936984/uint8array-to-string-in-javascript/22373197\n// http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt\n/* utf.js - UTF-8 <=> UTF-16 convertion\n *\n * Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>\n * Version: 1.0\n * LastModified: Dec 25 1999\n * This library is free. You can redistribute it and/or modify it.\n */\n/**\n * Converts a UTF-8 array to a string.\n *\n * @param array - The UTF-8 array to convert\n *\n * @returns The string\n *\n * @group Utils\n *\n * @beta\n */\nexport function utf8ArrayToStr(array, exitOnNull = false) {\n if (typeof TextDecoder !== 'undefined') {\n const decoder = new TextDecoder('utf-8');\n const decoded = decoder.decode(array);\n if (exitOnNull) {\n // grab up to the first null\n const idx = decoded.indexOf('\\0');\n return idx !== -1 ? decoded.substring(0, idx) : decoded;\n }\n // remove any null characters\n return decoded.replace(/\\0/g, '');\n }\n const len = array.length;\n let c;\n let char2;\n let char3;\n let out = '';\n let i = 0;\n while (i < len) {\n c = array[i++];\n if (c === 0x00 && exitOnNull) {\n return out;\n }\n else if (c === 0x00 || c === 0x03) {\n // If the character is 3 (END_OF_TEXT) or 0 (NULL) then skip it\n continue;\n }\n switch (c >> 4) {\n case 0:\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n case 6:\n case 7:\n // 0xxxxxxx\n out += String.fromCharCode(c);\n break;\n case 12:\n case 13:\n // 110x xxxx 10xx xxxx\n char2 = array[i++];\n out += String.fromCharCode(((c & 0x1f) << 6) | (char2 & 0x3f));\n break;\n case 14:\n // 1110 xxxx 10xx xxxx 10xx xxxx\n char2 = array[i++];\n char3 = array[i++];\n out += String.fromCharCode(((c & 0x0f) << 12) | ((char2 & 0x3f) << 6) | ((char3 & 0x3f) << 0));\n break;\n default:\n }\n }\n return out;\n}\n//# sourceMappingURL=utf8ArrayToStr.js.map","export function toUint8(data, offset = 0, length = Infinity) {\n return view(data, offset, length, Uint8Array);\n}\nfunction view(data, offset, length, Type) {\n const buffer = unsafeGetArrayBuffer(data);\n let bytesPerElement = 1;\n if ('BYTES_PER_ELEMENT' in Type) {\n bytesPerElement = Type.BYTES_PER_ELEMENT;\n }\n // Absolute end of the |data| view within |buffer|.\n const dataOffset = isArrayBufferView(data) ? data.byteOffset : 0;\n const dataEnd = ((dataOffset) + data.byteLength) / bytesPerElement;\n // Absolute start of the result within |buffer|.\n const rawStart = ((dataOffset) + offset) / bytesPerElement;\n const start = Math.floor(Math.max(0, Math.min(rawStart, dataEnd)));\n // Absolute end of the result within |buffer|.\n const end = Math.floor(Math.min(start + Math.max(length, 0), dataEnd));\n return new Type(buffer, start, end - start);\n}\nfunction unsafeGetArrayBuffer(view) {\n if (view instanceof ArrayBuffer) {\n return view;\n }\n else {\n return view.buffer;\n }\n}\nfunction isArrayBufferView(obj) {\n return obj && obj.buffer instanceof ArrayBuffer && obj.byteLength !== undefined && obj.byteOffset !== undefined;\n}\n//# sourceMappingURL=utf8.js.map","import { utf8ArrayToStr } from '../../utils.js';\nimport { toArrayBuffer } from './toArrayBuffer.js';\nimport { toUint8 } from './utf8.js';\nexport function decodeId3ImageFrame(frame) {\n const metadataFrame = {\n key: frame.type,\n description: '',\n data: '',\n mimeType: null,\n pictureType: null,\n };\n const utf8Encoding = 0x03;\n if (frame.size < 2) {\n return undefined;\n }\n if (frame.data[0] !== utf8Encoding) {\n console.log('Ignore frame with unrecognized character ' + 'encoding');\n return undefined;\n }\n const mimeTypeEndIndex = frame.data.subarray(1).indexOf(0);\n if (mimeTypeEndIndex === -1) {\n return undefined;\n }\n const mimeType = utf8ArrayToStr(toUint8(frame.data, 1, mimeTypeEndIndex));\n const pictureType = frame.data[2 + mimeTypeEndIndex];\n const descriptionEndIndex = frame.data\n .subarray(3 + mimeTypeEndIndex)\n .indexOf(0);\n if (descriptionEndIndex === -1) {\n return undefined;\n }\n const description = utf8ArrayToStr(toUint8(frame.data, 3 + mimeTypeEndIndex, descriptionEndIndex));\n let data;\n if (mimeType === '-->') {\n data = utf8ArrayToStr(toUint8(frame.data, 4 + mimeTypeEndIndex + descriptionEndIndex));\n }\n else {\n data = toArrayBuffer(frame.data.subarray(4 + mimeTypeEndIndex + descriptionEndIndex));\n }\n metadataFrame.mimeType = mimeType;\n metadataFrame.pictureType = pictureType;\n metadataFrame.description = description;\n metadataFrame.data = data;\n return metadataFrame;\n}\n//# sourceMappingURL=decodeId3ImageFrame.js.map","export function toArrayBuffer(view) {\n if (view instanceof ArrayBuffer) {\n return view;\n }\n else {\n if (view.byteOffset == 0 && view.byteLength == view.buffer.byteLength) {\n // This is a TypedArray over the whole buffer.\n return view.buffer;\n }\n // This is a 'view' on the buffer. Create a new buffer that only contains\n // the data. Note that since this isn't an ArrayBuffer, the 'new' call\n // will allocate a new buffer to hold the copy.\n return new Uint8Array(view).buffer;\n }\n}\n//# sourceMappingURL=toArrayBuffer.js.map","import { decodeId3PrivFrame } from './decodeId3PrivFrame.js';\nimport { decodeId3TextFrame } from './decodeId3TextFrame.js';\nimport { decodeId3UrlFrame } from './decodeId3UrlFrame.js';\nimport { decodeId3ImageFrame } from './decodeId3ImageFrame.js';\n/**\n * Decode an ID3 frame.\n *\n * @param frame - the ID3 frame\n *\n * @returns The decoded ID3 frame\n *\n * @internal\n *\n * @group ID3\n */\nexport function decodeId3Frame(frame) {\n if (frame.type === 'PRIV') {\n return decodeId3PrivFrame(frame);\n }\n else if (frame.type[0] === 'W') {\n return decodeId3UrlFrame(frame);\n }\n else if (frame.type === 'APIC') {\n return decodeId3ImageFrame(frame);\n }\n return decodeId3TextFrame(frame);\n}\n//# sourceMappingURL=decodeId3Frame.js.map","import { utf8ArrayToStr } from '../../utils/utf8ArrayToStr.js';\n/**\n * Decode an ID3 PRIV frame.\n *\n * @param frame - the ID3 PRIV frame\n *\n * @returns The decoded ID3 PRIV frame\n *\n * @internal\n *\n * @group ID3\n */\nexport function decodeId3PrivFrame(frame) {\n /*\n Format: <text string>\\0<binary data>\n */\n if (frame.size < 2) {\n return undefined;\n }\n const owner = utf8ArrayToStr(frame.data, true);\n const privateData = new Uint8Array(frame.data.subarray(owner.length + 1));\n return { key: frame.type, info: owner, data: privateData.buffer };\n}\n//# sourceMappingURL=decodeId3PrivFrame.js.map","import { utf8ArrayToStr } from '../../utils/utf8ArrayToStr.js';\n/**\n * Decode a URL frame\n *\n * @param frame - the ID3 URL frame\n *\n * @returns The decoded ID3 URL frame\n *\n * @internal\n *\n * @group ID3\n */\nexport function decodeId3UrlFrame(frame) {\n if (frame.type === 'WXXX') {\n /*\n Format:\n [0] = {Text Encoding}\n [1-?] = {Description}\\0{URL}\n */\n if (frame.size < 2) {\n return undefined;\n }\n let index = 1;\n const description = utf8ArrayToStr(frame.data.subarray(index), true);\n index += description.length + 1;\n const value = utf8ArrayToStr(frame.data.subarray(index));\n return { key: frame.type, info: description, data: value };\n }\n /*\n Format:\n [0-?] = {URL}\n */\n const url = utf8ArrayToStr(frame.data);\n return { key: frame.type, info: '', data: url };\n}\n//# sourceMappingURL=decodeId3UrlFrame.js.map","import { utf8ArrayToStr } from '../../utils/utf8ArrayToStr.js';\n/**\n * Decodes an ID3 text frame\n *\n * @param frame - the ID3 text frame\n *\n * @returns The decoded ID3 text frame\n *\n * @internal\n *\n * @group ID3\n */\nexport function decodeId3TextFrame(frame) {\n if (frame.size < 2) {\n return undefined;\n }\n if (frame.type === 'TXXX') {\n /*\n Format:\n [0] = {Text Encoding}\n [1-?] = {Description}\\0{Value}\n */\n let index = 1;\n const description = utf8ArrayToStr(frame.data.subarray(index), true);\n index += description.length + 1;\n const value = utf8ArrayToStr(frame.data.subarray(index));\n return { key: frame.type, info: description, data: value };\n }\n /*\n Format:\n [0] = {Text Encoding}\n [1-?] = {Value}\n */\n const text = utf8ArrayToStr(frame.data.subarray(1));\n return { key: frame.type, info: '', data: text };\n}\n//# sourceMappingURL=decodeId3TextFrame.js.map","import { readId3Size } from './readId3Size.js';\n/**\n * Returns the data of an ID3 frame.\n *\n * @param data - The data to read from\n *\n * @returns The data of the ID3 frame\n *\n * @internal\n *\n * @group ID3\n */\nexport function getId3FrameData(data) {\n /*\n Frame ID $xx xx xx xx (four characters)\n Size $xx xx xx xx\n Flags $xx xx\n */\n const type = String.fromCharCode(data[0], data[1], data[2], data[3]);\n const size = readId3Size(data, 4);\n // skip frame id, size, and flags\n const offset = 10;\n return { type, size, data: data.subarray(offset, offset + size) };\n}\n//# sourceMappingURL=getId3FrameData.js.map","import { decodeId3Frame } from './util/decodeId3Frame.js';\nimport { getId3FrameData } from './util/getId3FrameData.js';\nimport { isId3Footer } from './util/isId3Footer.js';\nimport { isId3Header } from './util/isId3Header.js';\nimport { readId3Size } from './util/readId3Size.js';\nconst HEADER_FOOTER_SIZE = 10;\nconst FRAME_SIZE = 10;\n/**\n * Returns an array of ID3 frames found in all the ID3 tags in the id3Data\n *\n * @param id3Data - The ID3 data containing one or more ID3 tags\n *\n * @returns Array of ID3 frame objects\n *\n * @group ID3\n *\n * @beta\n */\nexport function getId3Frames(id3Data) {\n let offset = 0;\n const frames = [];\n while (isId3Header(id3Data, offset)) {\n const size = readId3Size(id3Data, offset + 6);\n if ((id3Data[offset + 5] >> 6) & 1) {\n // skip extended header\n offset += HEADER_FOOTER_SIZE;\n }\n // skip past ID3 header\n offset += HEADER_FOOTER_SIZE;\n const end = offset + size;\n // loop through frames in the ID3 tag\n while (offset + FRAME_SIZE < end) {\n const frameData = getId3FrameData(id3Data.subarray(offset));\n const frame = decodeId3Frame(frameData);\n if (frame) {\n frames.push(frame);\n }\n // skip frame header and frame data\n offset += frameData.size + HEADER_FOOTER_SIZE;\n }\n if (isId3Footer(id3Data, offset)) {\n offset += HEADER_FOOTER_SIZE;\n }\n }\n return frames;\n}\n//# sourceMappingURL=getId3Frames.js.map","/**\n * Returns true if the ID3 frame is an Elementary Stream timestamp frame\n *\n * @param frame - the ID3 frame\n *\n * @returns `true` if the ID3 frame is an Elementary Stream timestamp frame\n *\n * @internal\n *\n * @group ID3\n */\nexport function isId3TimestampFrame(frame) {\n return (frame &&\n frame.key === 'PRIV' &&\n frame.info === 'com.apple.streaming.transportStreamTimestamp');\n}\n//# sourceMappingURL=isId3TimestampFrame.js.map","/**\n * Read a 33 bit timestamp from an ID3 frame.\n *\n * @param timeStampFrame - the ID3 frame\n *\n * @returns The timestamp\n *\n * @internal\n *\n * @group ID3\n */\nexport function readId3Timestamp(timeStampFrame) {\n if (timeStampFrame.data.byteLength === 8) {\n const data = new Uint8Array(timeStampFrame.data);\n // timestamp is 33 bit expressed as a big-endian eight-octet number,\n // with the upper 31 bits set to zero.\n const pts33Bit = data[3] & 0x1;\n let timestamp = (data[4] << 23) + (data[5] << 15) + (data[6] << 7) + data[7];\n timestamp /= 45;\n if (pts33Bit) {\n timestamp += 47721858.84;\n } // 2^32 / 90\n return Math.round(timestamp);\n }\n return undefined;\n}\n//# sourceMappingURL=readId3Timestamp.js.map","import { getId3Frames } from './getId3Frames.js';\nimport { isId3TimestampFrame } from './isId3TimestampFrame.js';\nimport { readId3Timestamp } from './util/readId3Timestamp.js';\n/**\n * Searches for the Elementary Stream timestamp found in the ID3 data chunk\n *\n * @param data - Block of data containing one or more ID3 tags\n *\n * @returns The timestamp\n *\n * @group ID3\n *\n * @beta\n */\nexport function getId3Timestamp(data) {\n const frames = getId3Frames(data);\n for (let i = 0; i < frames.length; i++) {\n const frame = frames[i];\n if (isId3TimestampFrame(frame)) {\n return readId3Timestamp(frame);\n }\n }\n return undefined;\n}\n//# sourceMappingURL=getId3Timestamp.js.map","import type { RationalTimestamp } from '../utils/timescale-conversion';\n\nexport interface Demuxer {\n demux(\n data: Uint8Array,\n timeOffset: number,\n isSampleAes?: boolean,\n flush?: boolean,\n ): DemuxerResult;\n demuxSampleAes(\n data: Uint8Array,\n keyData: KeyData,\n timeOffset: number,\n ): Promise<DemuxerResult>;\n flush(timeOffset?: number): DemuxerResult | Promise<DemuxerResult>;\n destroy(): void;\n resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n );\n resetTimeStamp(defaultInitPTS?: RationalTimestamp | null): void;\n resetContiguity(): void;\n}\n\nexport interface DemuxerResult {\n audioTrack: DemuxedAudioTrack;\n videoTrack: DemuxedVideoTrackBase;\n id3Track: DemuxedMetadataTrack;\n textTrack: DemuxedUserdataTrack;\n}\n\nexport interface DemuxedTrack {\n type: string;\n id: number;\n pid: number;\n inputTimeScale: number;\n sequenceNumber: number;\n samples:\n | AudioSample[]\n | VideoSample[]\n | MetadataSample[]\n | UserdataSample[]\n | Uint8Array;\n timescale?: number;\n container?: string;\n dropped: number;\n duration?: number;\n pesData?: ElementaryStreamData | null;\n codec?: string;\n}\n\nexport interface PassthroughTrack extends DemuxedTrack {\n sampleDuration: number;\n samples: Uint8Array;\n timescale: number;\n duration: number;\n codec: string;\n}\nexport interface DemuxedAudioTrack extends DemuxedTrack {\n type: 'audio';\n segmentCodec: 'aac' | 'ac3' | 'mp3';\n config?: number[] | Uint8Array;\n samplerate?: number;\n channelCount?: number;\n manifestCodec?: string;\n parsedCodec?: string;\n samples: AudioSample[];\n}\n\nexport type DemuxedAC3 = DemuxedAudioTrack & {\n segmentCodec: 'ac3';\n config: Uint8Array;\n};\n\nexport interface DemuxedVideoTrackBase extends DemuxedTrack {\n width?: number;\n height?: number;\n pixelRatio?: [number, number];\n audFound?: boolean;\n vps?: Uint8Array[];\n pps?: Uint8Array[];\n sps?: Uint8Array[];\n naluState?: number;\n segmentCodec?: string;\n manifestCodec?: string;\n samples: VideoSample[] | Uint8Array;\n params?: object;\n}\n\nexport interface DemuxedVideoTrack extends DemuxedVideoTrackBase {\n type: 'video';\n segmentCodec: 'avc' | 'hevc';\n samples: VideoSample[];\n pixelRatio: [number, number];\n width: number;\n height: number;\n}\n\nexport type DemuxedAVC1 = DemuxedVideoTrack & {\n segmentCodec: 'avc';\n pps: Uint8Array[];\n sps: Uint8Array[];\n};\n\nexport type DemuxedHEVC = DemuxedVideoTrack & {\n segmentCodec: 'hevc';\n params: {\n general_profile_space: number;\n general_tier_flag: number;\n general_profile_idc: number;\n general_profile_compatibility_flags: number[];\n general_constraint_indicator_flags: number[];\n general_level_idc: number;\n min_spatial_segmentation_idc: number;\n parallelismType: number;\n chroma_format_idc: number;\n bit_depth_luma_minus8: number;\n bit_depth_chroma_minus8: number;\n frame_rate: { fps: string; fixed: boolean };\n temporal_id_nested: number;\n num_temporal_layers: number;\n };\n pps: Uint8Array[];\n sps: Uint8Array[];\n vps: Uint8Array;\n};\n\nexport interface DemuxedMetadataTrack extends DemuxedTrack {\n samples: MetadataSample[];\n}\n\nexport interface DemuxedUserdataTrack extends DemuxedTrack {\n samples: UserdataSample[];\n}\n\nexport enum MetadataSchema {\n audioId3 = 'org.id3',\n dateRange = 'com.apple.quicktime.HLS',\n emsg = 'https://aomedia.org/emsg/ID3',\n misbklv = 'urn:misb:KLV:bin:1910.1',\n}\nexport interface MetadataSample {\n pts: number;\n dts: number;\n duration: number;\n len?: number;\n data: Uint8Array;\n type: MetadataSchema;\n}\n\nexport interface UserdataSample {\n pts: number;\n bytes?: Uint8Array;\n type?: number;\n payloadType?: number;\n uuid?: string;\n userData?: string;\n userDataBytes?: Uint8Array;\n}\n\nexport interface VideoSample {\n dts: number;\n pts: number;\n key: boolean;\n frame: boolean;\n units: VideoSampleUnit[];\n length: number;\n}\n\nexport interface VideoSampleUnit {\n data: Uint8Array;\n type: number;\n state?: number;\n}\n\nexport type AudioSample = {\n unit: Uint8Array;\n pts: number;\n};\n\nexport type AudioFrame = {\n sample: AudioSample;\n length: number;\n missing: number;\n};\n\nexport interface ElementaryStreamData {\n data: Uint8Array[];\n size: number;\n}\n\nexport interface KeyData {\n method: string;\n key: Uint8Array;\n iv: Uint8Array;\n}\n","/**\n * hex dump helper class\n */\n\nconst Hex = {\n hexDump: function (array: Uint8Array) {\n let str = '';\n for (let i = 0; i < array.length; i++) {\n let h = array[i].toString(16);\n if (h.length < 2) {\n h = '0' + h;\n }\n\n str += h;\n }\n return str;\n },\n};\n\nexport default Hex;\n","export function sliceUint8(\n array: Uint8Array,\n start?: number,\n end?: number,\n): Uint8Array {\n // @ts-expect-error This polyfills IE11 usage of Uint8Array slice.\n // It always exists in the TypeScript definition so fails, but it fails at runtime on IE11.\n return Uint8Array.prototype.slice\n ? array.slice(start, end)\n : new Uint8Array(Array.prototype.slice.call(array, start, end));\n}\n","// see https://tools.ietf.org/html/rfc1808\n\n(function (root) {\n var URL_REGEX =\n /^(?=((?:[a-zA-Z0-9+\\-.]+:)?))\\1(?=((?:\\/\\/[^\\/?#]*)?))\\2(?=((?:(?:[^?#\\/]*\\/)*[^;?#\\/]*)?))\\3((?:;[^?#]*)?)(\\?[^#]*)?(#[^]*)?$/;\n var FIRST_SEGMENT_REGEX = /^(?=([^\\/?#]*))\\1([^]*)$/;\n var SLASH_DOT_REGEX = /(?:\\/|^)\\.(?=\\/)/g;\n var SLASH_DOT_DOT_REGEX = /(?:\\/|^)\\.\\.\\/(?!\\.\\.\\/)[^\\/]*(?=\\/)/g;\n\n var URLToolkit = {\n // If opts.alwaysNormalize is true then the path will always be normalized even when it starts with / or //\n // E.g\n // With opts.alwaysNormalize = false (default, spec compliant)\n // http://a.com/b/cd + /e/f/../g => http://a.com/e/f/../g\n // With opts.alwaysNormalize = true (not spec compliant)\n // http://a.com/b/cd + /e/f/../g => http://a.com/e/g\n buildAbsoluteURL: function (baseURL, relativeURL, opts) {\n opts = opts || {};\n // remove any remaining space and CRLF\n baseURL = baseURL.trim();\n relativeURL = relativeURL.trim();\n if (!relativeURL) {\n // 2a) If the embedded URL is entirely empty, it inherits the\n // entire base URL (i.e., is set equal to the base URL)\n // and we are done.\n if (!opts.alwaysNormalize) {\n return baseURL;\n }\n var basePartsForNormalise = URLToolkit.parseURL(baseURL);\n if (!basePartsForNormalise) {\n throw new Error('Error trying to parse base URL.');\n }\n basePartsForNormalise.path = URLToolkit.normalizePath(\n basePartsForNormalise.path\n );\n return URLToolkit.buildURLFromParts(basePartsForNormalise);\n }\n var relativeParts = URLToolkit.parseURL(relativeURL);\n if (!relativeParts) {\n throw new Error('Error trying to parse relative URL.');\n }\n if (relativeParts.scheme) {\n // 2b) If the embedded URL starts with a scheme name, it is\n // interpreted as an absolute URL and we are done.\n if (!opts.alwaysNormalize) {\n return relativeURL;\n }\n relativeParts.path = URLToolkit.normalizePath(relativeParts.path);\n return URLToolkit.buildURLFromParts(relativeParts);\n }\n var baseParts = URLToolkit.parseURL(baseURL);\n if (!baseParts) {\n throw new Error('Error trying to parse base URL.');\n }\n if (!baseParts.netLoc && baseParts.path && baseParts.path[0] !== '/') {\n // If netLoc missing and path doesn't start with '/', assume everthing before the first '/' is the netLoc\n // This causes 'example.com/a' to be handled as '//example.com/a' instead of '/example.com/a'\n var pathParts = FIRST_SEGMENT_REGEX.exec(baseParts.path);\n baseParts.netLoc = pathParts[1];\n baseParts.path = pathParts[2];\n }\n if (baseParts.netLoc && !baseParts.path) {\n baseParts.path = '/';\n }\n var builtParts = {\n // 2c) Otherwise, the embedded URL inherits the scheme of\n // the base URL.\n scheme: baseParts.scheme,\n netLoc: relativeParts.netLoc,\n path: null,\n params: relativeParts.params,\n query: relativeParts.query,\n fragment: relativeParts.fragment,\n };\n if (!relativeParts.netLoc) {\n // 3) If the embedded URL's <net_loc> is non-empty, we skip to\n // Step 7. Otherwise, the embedded URL inherits the <net_loc>\n // (if any) of the base URL.\n builtParts.netLoc = baseParts.netLoc;\n // 4) If the embedded URL path is preceded by a slash \"/\", the\n // path is not relative and we skip to Step 7.\n if (relativeParts.path[0] !== '/') {\n if (!relativeParts.path) {\n // 5) If the embedded URL path is empty (and not preceded by a\n // slash), then the embedded URL inherits the base URL path\n builtParts.path = baseParts.path;\n // 5a) if the embedded URL's <params> is non-empty, we skip to\n // step 7; otherwise, it inherits the <params> of the base\n // URL (if any) and\n if (!relativeParts.params) {\n builtParts.params = baseParts.params;\n // 5b) if the embedded URL's <query> is non-empty, we skip to\n // step 7; otherwise, it inherits the <query> of the base\n // URL (if any) and we skip to step 7.\n if (!relativeParts.query) {\n builtParts.query = baseParts.query;\n }\n }\n } else {\n // 6) The last segment of the base URL's path (anything\n // following the rightmost slash \"/\", or the entire path if no\n // slash is present) is removed and the embedded URL's path is\n // appended in its place.\n var baseURLPath = baseParts.path;\n var newPath =\n baseURLPath.substring(0, baseURLPath.lastIndexOf('/') + 1) +\n relativeParts.path;\n builtParts.path = URLToolkit.normalizePath(newPath);\n }\n }\n }\n if (builtParts.path === null) {\n builtParts.path = opts.alwaysNormalize\n ? URLToolkit.normalizePath(relativeParts.path)\n : relativeParts.path;\n }\n return URLToolkit.buildURLFromParts(builtParts);\n },\n parseURL: function (url) {\n var parts = URL_REGEX.exec(url);\n if (!parts) {\n return null;\n }\n return {\n scheme: parts[1] || '',\n netLoc: parts[2] || '',\n path: parts[3] || '',\n params: parts[4] || '',\n query: parts[5] || '',\n fragment: parts[6] || '',\n };\n },\n normalizePath: function (path) {\n // The following operations are\n // then applied, in order, to the new path:\n // 6a) All occurrences of \"./\", where \".\" is a complete path\n // segment, are removed.\n // 6b) If the path ends with \".\" as a complete path segment,\n // that \".\" is removed.\n path = path.split('').reverse().join('').replace(SLASH_DOT_REGEX, '');\n // 6c) All occurrences of \"<segment>/../\", where <segment> is a\n // complete path segment not equal to \"..\", are removed.\n // Removal of these path segments is performed iteratively,\n // removing the leftmost matching pattern on each iteration,\n // until no matching pattern remains.\n // 6d) If the path ends with \"<segment>/..\", where <segment> is a\n // complete path segment not equal to \"..\", that\n // \"<segment>/..\" is removed.\n while (\n path.length !== (path = path.replace(SLASH_DOT_DOT_REGEX, '')).length\n ) {}\n return path.split('').reverse().join('');\n },\n buildURLFromParts: function (parts) {\n return (\n parts.scheme +\n parts.netLoc +\n parts.path +\n parts.params +\n parts.query +\n parts.fragment\n );\n },\n };\n\n if (typeof exports === 'object' && typeof module === 'object')\n module.exports = URLToolkit;\n else if (typeof define === 'function' && define.amd)\n define([], function () {\n return URLToolkit;\n });\n else if (typeof exports === 'object') exports['URLToolkit'] = URLToolkit;\n else root['URLToolkit'] = URLToolkit;\n})(this);\n","import { buildAbsoluteURL } from 'url-toolkit';\nimport { LoadStats } from './load-stats';\nimport type { LevelKey } from './level-key';\nimport type {\n FragmentLoaderContext,\n KeyLoaderContext,\n Loader,\n PlaylistLevelType,\n} from '../types/loader';\nimport type { AttrList } from '../utils/attr-list';\nimport type { KeySystemFormats } from '../utils/mediakeys-helper';\n\nexport const enum ElementaryStreamTypes {\n AUDIO = 'audio',\n VIDEO = 'video',\n AUDIOVIDEO = 'audiovideo',\n}\n\nexport interface ElementaryStreamInfo {\n startPTS: number;\n endPTS: number;\n startDTS: number;\n endDTS: number;\n partial?: boolean;\n}\n\nexport type ElementaryStreams = Record<\n ElementaryStreamTypes,\n ElementaryStreamInfo | null\n>;\n\nexport type Base = {\n url: string;\n};\n\nexport class BaseSegment {\n private _byteRange: [number, number] | null = null;\n private _url: string | null = null;\n private _stats: LoadStats | null = null;\n private _streams: ElementaryStreams | null = null;\n\n // baseurl is the URL to the playlist\n public readonly base: Base;\n\n // relurl is the portion of the URL that comes from inside the playlist.\n public relurl?: string;\n\n constructor(base: Base | string) {\n if (typeof base === 'string') {\n base = { url: base };\n }\n this.base = base;\n makeEnumerable(this, 'stats');\n }\n\n // setByteRange converts a EXT-X-BYTERANGE attribute into a two element array\n setByteRange(value: string, previous?: BaseSegment) {\n const params = value.split('@', 2);\n let start: number;\n if (params.length === 1) {\n start = previous?.byteRangeEndOffset || 0;\n } else {\n start = parseInt(params[1]);\n }\n this._byteRange = [start, parseInt(params[0]) + start];\n }\n\n get baseurl(): string {\n return this.base.url;\n }\n\n get byteRange(): [number, number] | [] {\n if (this._byteRange === null) {\n return [];\n }\n\n return this._byteRange;\n }\n\n get byteRangeStartOffset(): number | undefined {\n return this.byteRange[0];\n }\n\n get byteRangeEndOffset(): number | undefined {\n return this.byteRange[1];\n }\n\n get elementaryStreams(): ElementaryStreams {\n if (this._streams === null) {\n this._streams = {\n [ElementaryStreamTypes.AUDIO]: null,\n [ElementaryStreamTypes.VIDEO]: null,\n [ElementaryStreamTypes.AUDIOVIDEO]: null,\n };\n }\n return this._streams;\n }\n\n set elementaryStreams(value: ElementaryStreams) {\n this._streams = value;\n }\n\n get hasStats(): boolean {\n return this._stats !== null;\n }\n\n get hasStreams(): boolean {\n return this._streams !== null;\n }\n\n get stats(): LoadStats {\n if (this._stats === null) {\n this._stats = new LoadStats();\n }\n return this._stats;\n }\n\n set stats(value: LoadStats) {\n this._stats = value;\n }\n\n get url(): string {\n if (!this._url && this.baseurl && this.relurl) {\n this._url = buildAbsoluteURL(this.baseurl, this.relurl, {\n alwaysNormalize: true,\n });\n }\n return this._url || '';\n }\n\n set url(value: string) {\n this._url = value;\n }\n\n clearElementaryStreamInfo() {\n const { elementaryStreams } = this;\n elementaryStreams[ElementaryStreamTypes.AUDIO] = null;\n elementaryStreams[ElementaryStreamTypes.VIDEO] = null;\n elementaryStreams[ElementaryStreamTypes.AUDIOVIDEO] = null;\n }\n}\n\nexport interface MediaFragment extends Fragment {\n sn: number;\n ref: MediaFragmentRef;\n}\n\nexport type MediaFragmentRef = {\n base: Base;\n start: number;\n duration: number;\n sn: number;\n programDateTime: number | null;\n};\n\nexport function isMediaFragment(frag: Fragment): frag is MediaFragment {\n return frag.sn !== 'initSegment';\n}\n\n/**\n * Object representing parsed data from an HLS Segment. Found in {@link hls.js#LevelDetails.fragments}.\n */\nexport class Fragment extends BaseSegment {\n private _decryptdata: LevelKey | null = null;\n private _programDateTime: number | null = null;\n private _ref: MediaFragmentRef | null = null;\n // Approximate bit rate of the fragment expressed in bits per second (bps) as indicated by the last EXT-X-BITRATE (kbps) tag\n private _bitrate?: number;\n\n public rawProgramDateTime: string | null = null;\n public tagList: Array<string[]> = [];\n\n // EXTINF has to be present for a m3u8 to be considered valid\n public duration: number = 0;\n // sn notates the sequence number for a segment, and if set to a string can be 'initSegment'\n public sn: number | 'initSegment' = 0;\n // levelkeys are the EXT-X-KEY tags that apply to this segment for decryption\n // core difference from the private field _decryptdata is the lack of the initialized IV\n // _decryptdata will set the IV for this segment based on the segment number in the fragment\n public levelkeys?: { [key: string]: LevelKey };\n // A string representing the fragment type\n public readonly type: PlaylistLevelType;\n // A reference to the loader. Set while the fragment is loading, and removed afterwards. Used to abort fragment loading\n public loader: Loader<FragmentLoaderContext> | null = null;\n // A reference to the key loader. Set while the key is loading, and removed afterwards. Used to abort key loading\n public keyLoader: Loader<KeyLoaderContext> | null = null;\n // The level/track index to which the fragment belongs\n public level: number = -1;\n // The continuity counter of the fragment\n public cc: number = 0;\n // The starting Presentation Time Stamp (PTS) of the fragment. Set after transmux complete.\n public startPTS?: number;\n // The ending Presentation Time Stamp (PTS) of the fragment. Set after transmux complete.\n public endPTS?: number;\n // The starting Decode Time Stamp (DTS) of the fragment. Set after transmux complete.\n public startDTS?: number;\n // The ending Decode Time Stamp (DTS) of the fragment. Set after transmux complete.\n public endDTS?: number;\n // The start time of the fragment, as listed in the manifest. Updated after transmux complete.\n public start: number = 0;\n // The offset time (seconds) of the fragment from the start of the Playlist\n public playlistOffset: number = 0;\n // Set by `updateFragPTSDTS` in level-helper\n public deltaPTS?: number;\n // The maximum starting Presentation Time Stamp (audio/video PTS) of the fragment. Set after transmux complete.\n public maxStartPTS?: number;\n // The minimum ending Presentation Time Stamp (audio/video PTS) of the fragment. Set after transmux complete.\n public minEndPTS?: number;\n // Init Segment bytes (unset for media segments)\n public data?: Uint8Array;\n // A flag indicating whether the segment was downloaded in order to test bitrate, and was not buffered\n public bitrateTest: boolean = false;\n // #EXTINF segment title\n public title: string | null = null;\n // The Media Initialization Section for this segment\n public initSegment: Fragment | null = null;\n // Fragment is the last fragment in the media playlist\n public endList?: boolean;\n // Fragment is marked by an EXT-X-GAP tag indicating that it does not contain media data and should not be loaded\n public gap?: boolean;\n // Deprecated\n public urlId: number = 0;\n\n constructor(type: PlaylistLevelType, base: Base | string) {\n super(base);\n this.type = type;\n }\n\n get byteLength(): number | null {\n if (this.hasStats) {\n const total = this.stats.total;\n if (total) {\n return total;\n }\n }\n if (this.byteRange) {\n const start = this.byteRange[0];\n const end = this.byteRange[1];\n if (Number.isFinite(start) && Number.isFinite(end)) {\n return (end as number) - (start as number);\n }\n }\n return null;\n }\n\n get bitrate(): number | null {\n if (this.byteLength) {\n return (this.byteLength * 8) / this.duration;\n }\n if (this._bitrate) {\n return this._bitrate;\n }\n return null;\n }\n\n set bitrate(value: number) {\n this._bitrate = value;\n }\n\n get decryptdata(): LevelKey | null {\n const { levelkeys } = this;\n if (!levelkeys && !this._decryptdata) {\n return null;\n }\n\n if (!this._decryptdata && this.levelkeys && !this.levelkeys.NONE) {\n const key = this.levelkeys.identity;\n if (key) {\n this._decryptdata = key.getDecryptData(this.sn);\n } else {\n const keyFormats = Object.keys(this.levelkeys);\n if (keyFormats.length === 1) {\n return (this._decryptdata = this.levelkeys[\n keyFormats[0]\n ].getDecryptData(this.sn));\n } else {\n // Multiple keys. key-loader to call Fragment.setKeyFormat based on selected key-system.\n }\n }\n }\n\n return this._decryptdata;\n }\n\n get end(): number {\n return this.start + this.duration;\n }\n\n get endProgramDateTime() {\n if (this.programDateTime === null) {\n return null;\n }\n\n const duration = !Number.isFinite(this.duration) ? 0 : this.duration;\n\n return this.programDateTime + duration * 1000;\n }\n\n get encrypted() {\n // At the m3u8-parser level we need to add support for manifest signalled keyformats\n // when we want the fragment to start reporting that it is encrypted.\n // Currently, keyFormat will only be set for identity keys\n if (this._decryptdata?.encrypted) {\n return true;\n } else if (this.levelkeys) {\n const keyFormats = Object.keys(this.levelkeys);\n const len = keyFormats.length;\n if (len > 1 || (len === 1 && this.levelkeys[keyFormats[0]].encrypted)) {\n return true;\n }\n }\n return false;\n }\n\n get programDateTime(): number | null {\n if (this._programDateTime === null && this.rawProgramDateTime) {\n this.programDateTime = Date.parse(this.rawProgramDateTime);\n }\n return this._programDateTime;\n }\n\n set programDateTime(value: number | null) {\n if (!Number.isFinite(value)) {\n this._programDateTime = this.rawProgramDateTime = null;\n return;\n }\n this._programDateTime = value;\n }\n\n get ref(): MediaFragmentRef | null {\n if (!isMediaFragment(this)) {\n return null;\n }\n if (!this._ref) {\n this._ref = {\n base: this.base,\n start: this.start,\n duration: this.duration,\n sn: this.sn,\n programDateTime: this.programDateTime,\n };\n }\n return this._ref;\n }\n\n addStart(value: number) {\n this.setStart(this.start + value);\n }\n\n setStart(value: number) {\n this.start = value;\n if (this._ref) {\n this._ref.start = value;\n }\n }\n\n setDuration(value: number) {\n this.duration = value;\n if (this._ref) {\n this._ref.duration = value;\n }\n }\n\n setKeyFormat(keyFormat: KeySystemFormats) {\n if (this.levelkeys) {\n const key = this.levelkeys[keyFormat];\n if (key && !this._decryptdata) {\n this._decryptdata = key.getDecryptData(this.sn);\n }\n }\n }\n\n abortRequests(): void {\n this.loader?.abort();\n this.keyLoader?.abort();\n }\n\n setElementaryStreamInfo(\n type: ElementaryStreamTypes,\n startPTS: number,\n endPTS: number,\n startDTS: number,\n endDTS: number,\n partial: boolean = false,\n ) {\n const { elementaryStreams } = this;\n const info = elementaryStreams[type];\n if (!info) {\n elementaryStreams[type] = {\n startPTS,\n endPTS,\n startDTS,\n endDTS,\n partial,\n };\n return;\n }\n\n info.startPTS = Math.min(info.startPTS, startPTS);\n info.endPTS = Math.max(info.endPTS, endPTS);\n info.startDTS = Math.min(info.startDTS, startDTS);\n info.endDTS = Math.max(info.endDTS, endDTS);\n }\n}\n\n/**\n * Object representing parsed data from an HLS Partial Segment. Found in {@link hls.js#LevelDetails.partList}.\n */\nexport class Part extends BaseSegment {\n public readonly fragOffset: number = 0;\n public readonly duration: number = 0;\n public readonly gap: boolean = false;\n public readonly independent: boolean = false;\n public readonly relurl: string;\n public readonly fragment: MediaFragment;\n public readonly index: number;\n\n constructor(\n partAttrs: AttrList,\n frag: MediaFragment,\n base: Base | string,\n index: number,\n previous?: Part,\n ) {\n super(base);\n this.duration = partAttrs.decimalFloatingPoint('DURATION');\n this.gap = partAttrs.bool('GAP');\n this.independent = partAttrs.bool('INDEPENDENT');\n this.relurl = partAttrs.enumeratedString('URI') as string;\n this.fragment = frag;\n this.index = index;\n const byteRange = partAttrs.enumeratedString('BYTERANGE');\n if (byteRange) {\n this.setByteRange(byteRange, previous);\n }\n if (previous) {\n this.fragOffset = previous.fragOffset + previous.duration;\n }\n }\n\n get start(): number {\n return this.fragment.start + this.fragOffset;\n }\n\n get end(): number {\n return this.start + this.duration;\n }\n\n get loaded(): boolean {\n const { elementaryStreams } = this;\n return !!(\n elementaryStreams.audio ||\n elementaryStreams.video ||\n elementaryStreams.audiovideo\n );\n }\n}\n\nfunction getOwnPropertyDescriptorFromPrototypeChain(\n object: Object | undefined,\n property: string,\n) {\n const prototype = Object.getPrototypeOf(object);\n if (prototype) {\n const propertyDescriptor = Object.getOwnPropertyDescriptor(\n prototype,\n property,\n );\n if (propertyDescriptor) {\n return propertyDescriptor;\n }\n return getOwnPropertyDescriptorFromPrototypeChain(prototype, property);\n }\n}\n\nfunction makeEnumerable(object: Object, property: string) {\n const d = getOwnPropertyDescriptorFromPrototypeChain(object, property);\n if (d) {\n d.enumerable = true;\n Object.defineProperty(object, property, d);\n }\n}\n","import { utf8ArrayToStr } from '@svta/common-media-library/utils/utf8ArrayToStr';\nimport Hex from './hex';\nimport { sliceUint8 } from './typed-array';\nimport { ElementaryStreamTypes } from '../loader/fragment';\nimport { logger } from '../utils/logger';\nimport type { KeySystemIds } from './mediakeys-helper';\nimport type { DecryptData } from '../loader/level-key';\nimport type { PassthroughTrack, UserdataSample } from '../types/demuxer';\n\nconst UINT32_MAX = Math.pow(2, 32) - 1;\nconst push = [].push;\n\n// We are using fixed track IDs for driving the MP4 remuxer\n// instead of following the TS PIDs.\n// There is no reason not to do this and some browsers/SourceBuffer-demuxers\n// may not like if there are TrackID \"switches\"\n// See https://github.com/video-dev/hls.js/issues/1331\n// Here we are mapping our internal track types to constant MP4 track IDs\n// With MSE currently one can only have one track of each, and we are muxing\n// whatever video/audio rendition in them.\nexport const RemuxerTrackIdConfig = {\n video: 1,\n audio: 2,\n id3: 3,\n text: 4,\n};\n\nexport function bin2str(data: Uint8Array): string {\n return String.fromCharCode.apply(null, data);\n}\n\nexport function readUint16(buffer: Uint8Array, offset: number): number {\n const val = (buffer[offset] << 8) | buffer[offset + 1];\n return val < 0 ? 65536 + val : val;\n}\n\nexport function readUint32(buffer: Uint8Array, offset: number): number {\n const val = readSint32(buffer, offset);\n return val < 0 ? 4294967296 + val : val;\n}\n\nexport function readUint64(buffer: Uint8Array, offset: number) {\n let result = readUint32(buffer, offset);\n result *= Math.pow(2, 32);\n result += readUint32(buffer, offset + 4);\n return result;\n}\n\nexport function readSint32(buffer: Uint8Array, offset: number): number {\n return (\n (buffer[offset] << 24) |\n (buffer[offset + 1] << 16) |\n (buffer[offset + 2] << 8) |\n buffer[offset + 3]\n );\n}\n\nexport function writeUint32(buffer: Uint8Array, offset: number, value: number) {\n buffer[offset] = value >> 24;\n buffer[offset + 1] = (value >> 16) & 0xff;\n buffer[offset + 2] = (value >> 8) & 0xff;\n buffer[offset + 3] = value & 0xff;\n}\n\n// Find \"moof\" box\nexport function hasMoofData(data: Uint8Array): boolean {\n const end = data.byteLength;\n for (let i = 0; i < end; ) {\n const size = readUint32(data, i);\n if (\n size > 8 &&\n data[i + 4] === 0x6d &&\n data[i + 5] === 0x6f &&\n data[i + 6] === 0x6f &&\n data[i + 7] === 0x66\n ) {\n return true;\n }\n i = size > 1 ? i + size : end;\n }\n return false;\n}\n\n// Find the data for a box specified by its path\nexport function findBox(data: Uint8Array, path: string[]): Uint8Array[] {\n const results = [] as Uint8Array[];\n if (!path.length) {\n // short-circuit the search for empty paths\n return results;\n }\n const end = data.byteLength;\n\n for (let i = 0; i < end; ) {\n const size = readUint32(data, i);\n const type = bin2str(data.subarray(i + 4, i + 8));\n const endbox = size > 1 ? i + size : end;\n if (type === path[0]) {\n if (path.length === 1) {\n // this is the end of the path and we've found the box we were\n // looking for\n results.push(data.subarray(i + 8, endbox));\n } else {\n // recursively search for the next box along the path\n const subresults = findBox(data.subarray(i + 8, endbox), path.slice(1));\n if (subresults.length) {\n push.apply(results, subresults);\n }\n }\n }\n i = endbox;\n }\n\n // we've finished searching all of data\n return results;\n}\n\ntype SidxInfo = {\n earliestPresentationTime: number;\n timescale: number;\n version: number;\n referencesCount: number;\n references: any[];\n};\n\nexport function parseSegmentIndex(sidx: Uint8Array): SidxInfo | null {\n const references: any[] = [];\n\n const version = sidx[0];\n\n // set initial offset, we skip the reference ID (not needed)\n let index = 8;\n\n const timescale = readUint32(sidx, index);\n index += 4;\n\n let earliestPresentationTime = 0;\n let firstOffset = 0;\n\n if (version === 0) {\n earliestPresentationTime = readUint32(sidx, index);\n firstOffset = readUint32(sidx, index + 4);\n index += 8;\n } else {\n earliestPresentationTime = readUint64(sidx, index);\n firstOffset = readUint64(sidx, index + 8);\n index += 16;\n }\n\n // skip reserved\n index += 2;\n\n let startByte = sidx.length + firstOffset;\n\n const referencesCount = readUint16(sidx, index);\n index += 2;\n\n for (let i = 0; i < referencesCount; i++) {\n let referenceIndex = index;\n\n const referenceInfo = readUint32(sidx, referenceIndex);\n referenceIndex += 4;\n\n const referenceSize = referenceInfo & 0x7fffffff;\n const referenceType = (referenceInfo & 0x80000000) >>> 31;\n\n if (referenceType === 1) {\n logger.warn('SIDX has hierarchical references (not supported)');\n return null;\n }\n\n const subsegmentDuration = readUint32(sidx, referenceIndex);\n referenceIndex += 4;\n\n references.push({\n referenceSize,\n subsegmentDuration, // unscaled\n info: {\n duration: subsegmentDuration / timescale,\n start: startByte,\n end: startByte + referenceSize - 1,\n },\n });\n\n startByte += referenceSize;\n\n // Skipping 1 bit for |startsWithSap|, 3 bits for |sapType|, and 28 bits\n // for |sapDelta|.\n referenceIndex += 4;\n\n // skip to next ref\n index = referenceIndex;\n }\n\n return {\n earliestPresentationTime,\n timescale,\n version,\n referencesCount,\n references,\n };\n}\n\n/**\n * Parses an MP4 initialization segment and extracts stream type and\n * timescale values for any declared tracks. Timescale values indicate the\n * number of clock ticks per second to assume for time-based values\n * elsewhere in the MP4.\n *\n * To determine the start time of an MP4, you need two pieces of\n * information: the timescale unit and the earliest base media decode\n * time. Multiple timescales can be specified within an MP4 but the\n * base media decode time is always expressed in the timescale from\n * the media header box for the track:\n * ```\n * moov > trak > mdia > mdhd.timescale\n * moov > trak > mdia > hdlr\n * ```\n * @param initSegment the bytes of the init segment\n * @returns a hash of track type to timescale values or null if\n * the init segment is malformed.\n */\n\nexport interface InitDataTrack {\n timescale: number;\n id: number;\n codec: string;\n}\n\ntype HdlrType = ElementaryStreamTypes.AUDIO | ElementaryStreamTypes.VIDEO;\n\nexport interface InitData extends Array<any> {\n [index: number]:\n | {\n timescale: number;\n type: HdlrType;\n default?: {\n duration: number;\n flags: number;\n };\n }\n | undefined;\n audio?: InitDataTrack;\n video?: InitDataTrack;\n caption?: InitDataTrack;\n}\n\nexport function parseInitSegment(initSegment: Uint8Array): InitData {\n const result: InitData = [];\n const traks = findBox(initSegment, ['moov', 'trak']);\n for (let i = 0; i < traks.length; i++) {\n const trak = traks[i];\n const tkhd = findBox(trak, ['tkhd'])[0];\n if (tkhd) {\n let version = tkhd[0];\n const trackId = readUint32(tkhd, version === 0 ? 12 : 20);\n const mdhd = findBox(trak, ['mdia', 'mdhd'])[0];\n if (mdhd) {\n version = mdhd[0];\n const timescale = readUint32(mdhd, version === 0 ? 12 : 20);\n const hdlr = findBox(trak, ['mdia', 'hdlr'])[0];\n if (hdlr) {\n const hdlrType = bin2str(hdlr.subarray(8, 12));\n const type: HdlrType | undefined = {\n soun: ElementaryStreamTypes.AUDIO as const,\n vide: ElementaryStreamTypes.VIDEO as const,\n }[hdlrType];\n if (type) {\n // Parse codec details\n const stsd = findBox(trak, ['mdia', 'minf', 'stbl', 'stsd'])[0];\n const stsdData = parseStsd(stsd);\n result[trackId] = { timescale, type };\n result[type] = { timescale, id: trackId, ...stsdData };\n }\n }\n }\n }\n }\n\n const trex = findBox(initSegment, ['moov', 'mvex', 'trex']);\n trex.forEach((trex) => {\n const trackId = readUint32(trex, 4);\n const track = result[trackId];\n if (track) {\n track.default = {\n duration: readUint32(trex, 12),\n flags: readUint32(trex, 20),\n };\n }\n });\n\n return result;\n}\n\nfunction parseStsd(stsd: Uint8Array): { codec: string; encrypted: boolean } {\n const sampleEntries = stsd.subarray(8);\n const sampleEntriesEnd = sampleEntries.subarray(8 + 78);\n const fourCC = bin2str(sampleEntries.subarray(4, 8));\n let codec = fourCC;\n const encrypted = fourCC === 'enca' || fourCC === 'encv';\n if (encrypted) {\n const encBox = findBox(sampleEntries, [fourCC])[0];\n const encBoxChildren = encBox.subarray(fourCC === 'enca' ? 28 : 78);\n const sinfs = findBox(encBoxChildren, ['sinf']);\n sinfs.forEach((sinf) => {\n const schm = findBox(sinf, ['schm'])[0];\n if (schm) {\n const scheme = bin2str(schm.subarray(4, 8));\n if (scheme === 'cbcs' || scheme === 'cenc') {\n const frma = findBox(sinf, ['frma'])[0];\n if (frma) {\n // for encrypted content codec fourCC will be in frma\n codec = bin2str(frma);\n }\n }\n }\n });\n }\n switch (codec) {\n case 'avc1':\n case 'avc2':\n case 'avc3':\n case 'avc4': {\n // extract profile + compatibility + level out of avcC box\n const avcCBox = findBox(sampleEntriesEnd, ['avcC'])[0];\n codec += '.' + toHex(avcCBox[1]) + toHex(avcCBox[2]) + toHex(avcCBox[3]);\n break;\n }\n case 'mp4a': {\n const codecBox = findBox(sampleEntries, [fourCC])[0];\n const esdsBox = findBox(codecBox.subarray(28), ['esds'])[0];\n if (esdsBox && esdsBox.length > 7) {\n let i = 4;\n // ES Descriptor tag\n if (esdsBox[i++] !== 0x03) {\n break;\n }\n i = skipBERInteger(esdsBox, i);\n i += 2; // skip es_id;\n const flags = esdsBox[i++];\n if (flags & 0x80) {\n i += 2; // skip dependency es_id\n }\n if (flags & 0x40) {\n i += esdsBox[i++]; // skip URL\n }\n // Decoder config descriptor\n if (esdsBox[i++] !== 0x04) {\n break;\n }\n i = skipBERInteger(esdsBox, i);\n const objectType = esdsBox[i++];\n if (objectType === 0x40) {\n codec += '.' + toHex(objectType);\n } else {\n break;\n }\n i += 12;\n // Decoder specific info\n if (esdsBox[i++] !== 0x05) {\n break;\n }\n i = skipBERInteger(esdsBox, i);\n const firstByte = esdsBox[i++];\n let audioObjectType = (firstByte & 0xf8) >> 3;\n if (audioObjectType === 31) {\n audioObjectType +=\n 1 + ((firstByte & 0x7) << 3) + ((esdsBox[i] & 0xe0) >> 5);\n }\n codec += '.' + audioObjectType;\n }\n break;\n }\n case 'hvc1':\n case 'hev1': {\n const hvcCBox = findBox(sampleEntriesEnd, ['hvcC'])[0];\n const profileByte = hvcCBox[1];\n const profileSpace = ['', 'A', 'B', 'C'][profileByte >> 6];\n const generalProfileIdc = profileByte & 0x1f;\n const profileCompat = readUint32(hvcCBox, 2);\n const tierFlag = (profileByte & 0x20) >> 5 ? 'H' : 'L';\n const levelIDC = hvcCBox[12];\n const constraintIndicator = hvcCBox.subarray(6, 12);\n codec += '.' + profileSpace + generalProfileIdc;\n codec += '.' + profileCompat.toString(16).toUpperCase();\n codec += '.' + tierFlag + levelIDC;\n let constraintString = '';\n for (let i = constraintIndicator.length; i--; ) {\n const byte = constraintIndicator[i];\n if (byte || constraintString) {\n const encodedByte = byte.toString(16).toUpperCase();\n constraintString = '.' + encodedByte + constraintString;\n }\n }\n codec += constraintString;\n break;\n }\n case 'dvh1':\n case 'dvhe': {\n const dvcCBox = findBox(sampleEntriesEnd, ['dvcC'])[0];\n const profile = (dvcCBox[2] >> 1) & 0x7f;\n const level = ((dvcCBox[2] << 5) & 0x20) | ((dvcCBox[3] >> 3) & 0x1f);\n codec += '.' + addLeadingZero(profile) + '.' + addLeadingZero(level);\n break;\n }\n case 'vp09': {\n const vpcCBox = findBox(sampleEntriesEnd, ['vpcC'])[0];\n const profile = vpcCBox[4];\n const level = vpcCBox[5];\n const bitDepth = (vpcCBox[6] >> 4) & 0x0f;\n codec +=\n '.' +\n addLeadingZero(profile) +\n '.' +\n addLeadingZero(level) +\n '.' +\n addLeadingZero(bitDepth);\n break;\n }\n case 'av01': {\n const av1CBox = findBox(sampleEntriesEnd, ['av1C'])[0];\n const profile = av1CBox[1] >>> 5;\n const level = av1CBox[1] & 0x1f;\n const tierFlag = av1CBox[2] >>> 7 ? 'H' : 'M';\n const highBitDepth = (av1CBox[2] & 0x40) >> 6;\n const twelveBit = (av1CBox[2] & 0x20) >> 5;\n const bitDepth =\n profile === 2 && highBitDepth\n ? twelveBit\n ? 12\n : 10\n : highBitDepth\n ? 10\n : 8;\n const monochrome = (av1CBox[2] & 0x10) >> 4;\n const chromaSubsamplingX = (av1CBox[2] & 0x08) >> 3;\n const chromaSubsamplingY = (av1CBox[2] & 0x04) >> 2;\n const chromaSamplePosition = av1CBox[2] & 0x03;\n // TODO: parse color_description_present_flag\n // default it to BT.709/limited range for now\n // more info https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox-syntax\n const colorPrimaries = 1;\n const transferCharacteristics = 1;\n const matrixCoefficients = 1;\n const videoFullRangeFlag = 0;\n codec +=\n '.' +\n profile +\n '.' +\n addLeadingZero(level) +\n tierFlag +\n '.' +\n addLeadingZero(bitDepth) +\n '.' +\n monochrome +\n '.' +\n chromaSubsamplingX +\n chromaSubsamplingY +\n chromaSamplePosition +\n '.' +\n addLeadingZero(colorPrimaries) +\n '.' +\n addLeadingZero(transferCharacteristics) +\n '.' +\n addLeadingZero(matrixCoefficients) +\n '.' +\n videoFullRangeFlag;\n break;\n }\n case 'ac-3':\n case 'ec-3':\n case 'alac':\n case 'fLaC':\n case 'Opus':\n default:\n break;\n }\n return { codec, encrypted };\n}\n\nfunction skipBERInteger(bytes: Uint8Array, i: number): number {\n const limit = i + 5;\n while (bytes[i++] & 0x80 && i < limit) {\n /* do nothing */\n }\n return i;\n}\n\nfunction toHex(x: number): string {\n return ('0' + x.toString(16).toUpperCase()).slice(-2);\n}\n\nfunction addLeadingZero(num: number): string {\n return (num < 10 ? '0' : '') + num;\n}\n\nexport function patchEncyptionData(\n initSegment: Uint8Array | undefined,\n decryptdata: DecryptData | null,\n): Uint8Array | undefined {\n if (!initSegment || !decryptdata) {\n return initSegment;\n }\n const keyId = decryptdata.keyId;\n if (keyId && decryptdata.isCommonEncryption) {\n const traks = findBox(initSegment, ['moov', 'trak']);\n traks.forEach((trak) => {\n const stsd = findBox(trak, ['mdia', 'minf', 'stbl', 'stsd'])[0];\n\n // skip the sample entry count\n const sampleEntries = stsd.subarray(8);\n let encBoxes = findBox(sampleEntries, ['enca']);\n const isAudio = encBoxes.length > 0;\n if (!isAudio) {\n encBoxes = findBox(sampleEntries, ['encv']);\n }\n encBoxes.forEach((enc) => {\n const encBoxChildren = isAudio ? enc.subarray(28) : enc.subarray(78);\n const sinfBoxes = findBox(encBoxChildren, ['sinf']);\n sinfBoxes.forEach((sinf) => {\n const tenc = parseSinf(sinf);\n if (tenc) {\n // Look for default key id (keyID offset is always 8 within the tenc box):\n const tencKeyId = tenc.subarray(8, 24);\n if (!tencKeyId.some((b) => b !== 0)) {\n logger.log(\n `[eme] Patching keyId in 'enc${\n isAudio ? 'a' : 'v'\n }>sinf>>tenc' box: ${Hex.hexDump(tencKeyId)} -> ${Hex.hexDump(\n keyId,\n )}`,\n );\n tenc.set(keyId, 8);\n }\n }\n });\n });\n });\n }\n\n return initSegment;\n}\n\nexport function parseSinf(sinf: Uint8Array): Uint8Array | null {\n const schm = findBox(sinf, ['schm'])[0];\n if (schm) {\n const scheme = bin2str(schm.subarray(4, 8));\n if (scheme === 'cbcs' || scheme === 'cenc') {\n return findBox(sinf, ['schi', 'tenc'])[0];\n }\n }\n return null;\n}\n\n/**\n * Determine the base media decode start time, in seconds, for an MP4\n * fragment. If multiple fragments are specified, the earliest time is\n * returned.\n *\n * The base media decode time can be parsed from track fragment\n * metadata:\n * ```\n * moof > traf > tfdt.baseMediaDecodeTime\n * ```\n * It requires the timescale value from the mdhd to interpret.\n *\n * @param initData - a hash of track type to timescale values\n * @param fmp4 - the bytes of the mp4 fragment\n * @returns the earliest base media decode start time for the\n * fragment, in seconds\n */\nexport function getStartDTS(\n initData: InitData,\n fmp4: Uint8Array,\n): number | null {\n // we need info from two children of each track fragment box\n return findBox(fmp4, ['moof', 'traf']).reduce(\n (result: number | null, traf) => {\n const tfdt = findBox(traf, ['tfdt'])[0];\n const version = tfdt[0];\n const start = findBox(traf, ['tfhd']).reduce(\n (result: number | null, tfhd) => {\n // get the track id from the tfhd\n const id = readUint32(tfhd, 4);\n const track = initData[id];\n if (track) {\n let baseTime = readUint32(tfdt, 4);\n if (version === 1) {\n // If value is too large, assume signed 64-bit. Negative track fragment decode times are invalid, but they exist in the wild.\n // This prevents large values from being used for initPTS, which can cause playlist sync issues.\n // https://github.com/video-dev/hls.js/issues/5303\n if (baseTime === UINT32_MAX) {\n logger.warn(\n `[mp4-demuxer]: Ignoring assumed invalid signed 64-bit track fragment decode time`,\n );\n return result;\n }\n baseTime *= UINT32_MAX + 1;\n baseTime += readUint32(tfdt, 8);\n }\n // assume a 90kHz clock if no timescale was specified\n const scale = track.timescale || 90e3;\n // convert base time to seconds\n const startTime = baseTime / scale;\n if (\n Number.isFinite(startTime) &&\n (result === null || startTime < result)\n ) {\n return startTime;\n }\n }\n return result;\n },\n null,\n );\n if (\n start !== null &&\n Number.isFinite(start) &&\n (result === null || start < result)\n ) {\n return start;\n }\n return result;\n },\n null,\n );\n}\n\n/*\n For Reference:\n aligned(8) class TrackFragmentHeaderBox\n extends FullBox(‘tfhd’, 0, tf_flags){\n unsigned int(32) track_ID;\n // all the following are optional fields\n unsigned int(64) base_data_offset;\n unsigned int(32) sample_description_index;\n unsigned int(32) default_sample_duration;\n unsigned int(32) default_sample_size;\n unsigned int(32) default_sample_flags\n }\n */\nexport function getDuration(data: Uint8Array, initData: InitData) {\n let rawDuration = 0;\n let videoDuration = 0;\n let audioDuration = 0;\n const trafs = findBox(data, ['moof', 'traf']);\n for (let i = 0; i < trafs.length; i++) {\n const traf = trafs[i];\n // There is only one tfhd & trun per traf\n // This is true for CMAF style content, and we should perhaps check the ftyp\n // and only look for a single trun then, but for ISOBMFF we should check\n // for multiple track runs.\n const tfhd = findBox(traf, ['tfhd'])[0];\n // get the track id from the tfhd\n const id = readUint32(tfhd, 4);\n const track = initData[id];\n if (!track) {\n continue;\n }\n const trackDefault = track.default;\n const tfhdFlags = readUint32(tfhd, 0) | trackDefault?.flags!;\n let sampleDuration: number | undefined = trackDefault?.duration;\n if (tfhdFlags & 0x000008) {\n // 0x000008 indicates the presence of the default_sample_duration field\n if (tfhdFlags & 0x000002) {\n // 0x000002 indicates the presence of the sample_description_index field, which precedes default_sample_duration\n // If present, the default_sample_duration exists at byte offset 12\n sampleDuration = readUint32(tfhd, 12);\n } else {\n // Otherwise, the duration is at byte offset 8\n sampleDuration = readUint32(tfhd, 8);\n }\n }\n // assume a 90kHz clock if no timescale was specified\n const timescale = track.timescale || 90e3;\n const truns = findBox(traf, ['trun']);\n for (let j = 0; j < truns.length; j++) {\n rawDuration = computeRawDurationFromSamples(truns[j]);\n if (!rawDuration && sampleDuration) {\n const sampleCount = readUint32(truns[j], 4);\n rawDuration = sampleDuration * sampleCount;\n }\n if (track.type === ElementaryStreamTypes.VIDEO) {\n videoDuration += rawDuration / timescale;\n } else if (track.type === ElementaryStreamTypes.AUDIO) {\n audioDuration += rawDuration / timescale;\n }\n }\n }\n if (videoDuration === 0 && audioDuration === 0) {\n // If duration samples are not available in the traf use sidx subsegment_duration\n let sidxMinStart = Infinity;\n let sidxMaxEnd = 0;\n let sidxDuration = 0;\n const sidxs = findBox(data, ['sidx']);\n for (let i = 0; i < sidxs.length; i++) {\n const sidx = parseSegmentIndex(sidxs[i]);\n if (sidx?.references) {\n sidxMinStart = Math.min(\n sidxMinStart,\n sidx.earliestPresentationTime / sidx.timescale,\n );\n const subSegmentDuration = sidx.references.reduce(\n (dur, ref) => dur + ref.info.duration || 0,\n 0,\n );\n sidxMaxEnd = Math.max(\n sidxMaxEnd,\n subSegmentDuration + sidx.earliestPresentationTime / sidx.timescale,\n );\n sidxDuration = sidxMaxEnd - sidxMinStart;\n }\n }\n if (sidxDuration && Number.isFinite(sidxDuration)) {\n return sidxDuration;\n }\n }\n if (videoDuration) {\n return videoDuration;\n }\n return audioDuration;\n}\n\n/*\n For Reference:\n aligned(8) class TrackRunBox\n extends FullBox(‘trun’, version, tr_flags) {\n unsigned int(32) sample_count;\n // the following are optional fields\n signed int(32) data_offset;\n unsigned int(32) first_sample_flags;\n // all fields in the following array are optional\n {\n unsigned int(32) sample_duration;\n unsigned int(32) sample_size;\n unsigned int(32) sample_flags\n if (version == 0)\n { unsigned int(32)\n else\n { signed int(32)\n }[ sample_count ]\n }\n */\nexport function computeRawDurationFromSamples(trun): number {\n const flags = readUint32(trun, 0);\n // Flags are at offset 0, non-optional sample_count is at offset 4. Therefore we start 8 bytes in.\n // Each field is an int32, which is 4 bytes\n let offset = 8;\n // data-offset-present flag\n if (flags & 0x000001) {\n offset += 4;\n }\n // first-sample-flags-present flag\n if (flags & 0x000004) {\n offset += 4;\n }\n\n let duration = 0;\n const sampleCount = readUint32(trun, 4);\n for (let i = 0; i < sampleCount; i++) {\n // sample-duration-present flag\n if (flags & 0x000100) {\n const sampleDuration = readUint32(trun, offset);\n duration += sampleDuration;\n offset += 4;\n }\n // sample-size-present flag\n if (flags & 0x000200) {\n offset += 4;\n }\n // sample-flags-present flag\n if (flags & 0x000400) {\n offset += 4;\n }\n // sample-composition-time-offsets-present flag\n if (flags & 0x000800) {\n offset += 4;\n }\n }\n return duration;\n}\n\nexport function offsetStartDTS(\n initData: InitData,\n fmp4: Uint8Array,\n timeOffset: number,\n) {\n findBox(fmp4, ['moof', 'traf']).forEach((traf) => {\n findBox(traf, ['tfhd']).forEach((tfhd) => {\n // get the track id from the tfhd\n const id = readUint32(tfhd, 4);\n const track = initData[id];\n if (!track) {\n return;\n }\n // assume a 90kHz clock if no timescale was specified\n const timescale = track.timescale || 90e3;\n // get the base media decode time from the tfdt\n findBox(traf, ['tfdt']).forEach((tfdt) => {\n const version = tfdt[0];\n const offset = timeOffset * timescale;\n if (offset) {\n let baseMediaDecodeTime = readUint32(tfdt, 4);\n if (version === 0) {\n baseMediaDecodeTime -= offset;\n baseMediaDecodeTime = Math.max(baseMediaDecodeTime, 0);\n writeUint32(tfdt, 4, baseMediaDecodeTime);\n } else {\n baseMediaDecodeTime *= Math.pow(2, 32);\n baseMediaDecodeTime += readUint32(tfdt, 8);\n baseMediaDecodeTime -= offset;\n baseMediaDecodeTime = Math.max(baseMediaDecodeTime, 0);\n const upper = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1));\n const lower = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1));\n writeUint32(tfdt, 4, upper);\n writeUint32(tfdt, 8, lower);\n }\n }\n });\n });\n });\n}\n\n// TODO: Check if the last moof+mdat pair is part of the valid range\nexport function segmentValidRange(data: Uint8Array): SegmentedRange {\n const segmentedRange: SegmentedRange = {\n valid: null,\n remainder: null,\n };\n\n const moofs = findBox(data, ['moof']);\n if (moofs.length < 2) {\n segmentedRange.remainder = data;\n return segmentedRange;\n }\n const last = moofs[moofs.length - 1];\n // Offset by 8 bytes; findBox offsets the start by as much\n segmentedRange.valid = sliceUint8(data, 0, last.byteOffset - 8);\n segmentedRange.remainder = sliceUint8(data, last.byteOffset - 8);\n return segmentedRange;\n}\n\nexport interface SegmentedRange {\n valid: Uint8Array | null;\n remainder: Uint8Array | null;\n}\n\nexport function appendUint8Array(\n data1: Uint8Array,\n data2: Uint8Array,\n): Uint8Array {\n const temp = new Uint8Array(data1.length + data2.length);\n temp.set(data1);\n temp.set(data2, data1.length);\n\n return temp;\n}\n\nexport interface IEmsgParsingData {\n schemeIdUri: string;\n value: string;\n timeScale: number;\n presentationTimeDelta?: number;\n presentationTime?: number;\n eventDuration: number;\n id: number;\n payload: Uint8Array;\n}\n\nexport function parseSamples(\n timeOffset: number,\n track: PassthroughTrack,\n): UserdataSample[] {\n const seiSamples = [] as UserdataSample[];\n const videoData = track.samples;\n const timescale = track.timescale;\n const trackId = track.id;\n let isHEVCFlavor = false;\n\n const moofs = findBox(videoData, ['moof']);\n moofs.map((moof) => {\n const moofOffset = moof.byteOffset - 8;\n const trafs = findBox(moof, ['traf']);\n trafs.map((traf) => {\n // get the base media decode time from the tfdt\n const baseTime = findBox(traf, ['tfdt']).map((tfdt) => {\n const version = tfdt[0];\n let result = readUint32(tfdt, 4);\n if (version === 1) {\n result *= Math.pow(2, 32);\n result += readUint32(tfdt, 8);\n }\n return result / timescale;\n })[0];\n\n if (baseTime !== undefined) {\n timeOffset = baseTime;\n }\n\n return findBox(traf, ['tfhd']).map((tfhd) => {\n const id = readUint32(tfhd, 4);\n const tfhdFlags = readUint32(tfhd, 0) & 0xffffff;\n const baseDataOffsetPresent = (tfhdFlags & 0x000001) !== 0;\n const sampleDescriptionIndexPresent = (tfhdFlags & 0x000002) !== 0;\n const defaultSampleDurationPresent = (tfhdFlags & 0x000008) !== 0;\n let defaultSampleDuration = 0;\n const defaultSampleSizePresent = (tfhdFlags & 0x000010) !== 0;\n let defaultSampleSize = 0;\n const defaultSampleFlagsPresent = (tfhdFlags & 0x000020) !== 0;\n let tfhdOffset = 8;\n\n if (id === trackId) {\n if (baseDataOffsetPresent) {\n tfhdOffset += 8;\n }\n if (sampleDescriptionIndexPresent) {\n tfhdOffset += 4;\n }\n if (defaultSampleDurationPresent) {\n defaultSampleDuration = readUint32(tfhd, tfhdOffset);\n tfhdOffset += 4;\n }\n if (defaultSampleSizePresent) {\n defaultSampleSize = readUint32(tfhd, tfhdOffset);\n tfhdOffset += 4;\n }\n if (defaultSampleFlagsPresent) {\n tfhdOffset += 4;\n }\n if (track.type === 'video') {\n isHEVCFlavor = isHEVC(track.codec);\n }\n\n findBox(traf, ['trun']).map((trun) => {\n const version = trun[0];\n const flags = readUint32(trun, 0) & 0xffffff;\n const dataOffsetPresent = (flags & 0x000001) !== 0;\n let dataOffset = 0;\n const firstSampleFlagsPresent = (flags & 0x000004) !== 0;\n const sampleDurationPresent = (flags & 0x000100) !== 0;\n let sampleDuration = 0;\n const sampleSizePresent = (flags & 0x000200) !== 0;\n let sampleSize = 0;\n const sampleFlagsPresent = (flags & 0x000400) !== 0;\n const sampleCompositionOffsetsPresent = (flags & 0x000800) !== 0;\n let compositionOffset = 0;\n const sampleCount = readUint32(trun, 4);\n let trunOffset = 8; // past version, flags, and sample count\n\n if (dataOffsetPresent) {\n dataOffset = readUint32(trun, trunOffset);\n trunOffset += 4;\n }\n if (firstSampleFlagsPresent) {\n trunOffset += 4;\n }\n\n let sampleOffset = dataOffset + moofOffset;\n\n for (let ix = 0; ix < sampleCount; ix++) {\n if (sampleDurationPresent) {\n sampleDuration = readUint32(trun, trunOffset);\n trunOffset += 4;\n } else {\n sampleDuration = defaultSampleDuration;\n }\n if (sampleSizePresent) {\n sampleSize = readUint32(trun, trunOffset);\n trunOffset += 4;\n } else {\n sampleSize = defaultSampleSize;\n }\n if (sampleFlagsPresent) {\n trunOffset += 4;\n }\n if (sampleCompositionOffsetsPresent) {\n if (version === 0) {\n compositionOffset = readUint32(trun, trunOffset);\n } else {\n compositionOffset = readSint32(trun, trunOffset);\n }\n trunOffset += 4;\n }\n if (track.type === ElementaryStreamTypes.VIDEO) {\n let naluTotalSize = 0;\n while (naluTotalSize < sampleSize) {\n const naluSize = readUint32(videoData, sampleOffset);\n sampleOffset += 4;\n if (isSEIMessage(isHEVCFlavor, videoData[sampleOffset])) {\n const data = videoData.subarray(\n sampleOffset,\n sampleOffset + naluSize,\n );\n parseSEIMessageFromNALu(\n data,\n isHEVCFlavor ? 2 : 1,\n timeOffset + compositionOffset / timescale,\n seiSamples,\n );\n }\n sampleOffset += naluSize;\n naluTotalSize += naluSize + 4;\n }\n }\n\n timeOffset += sampleDuration / timescale;\n }\n });\n }\n });\n });\n });\n return seiSamples;\n}\n\nexport function isHEVC(codec: string | undefined) {\n if (!codec) {\n return false;\n }\n const baseCodec = codec.substring(0, 4);\n return (\n baseCodec === 'hvc1' ||\n baseCodec === 'hev1' ||\n // Dolby Vision\n baseCodec === 'dvh1' ||\n baseCodec === 'dvhe'\n );\n}\n\nfunction isSEIMessage(isHEVCFlavor: boolean, naluHeader: number) {\n if (isHEVCFlavor) {\n const naluType = (naluHeader >> 1) & 0x3f;\n return naluType === 39 || naluType === 40;\n } else {\n const naluType = naluHeader & 0x1f;\n return naluType === 6;\n }\n}\n\nexport function parseSEIMessageFromNALu(\n unescapedData: Uint8Array,\n headerSize: number,\n pts: number,\n samples: UserdataSample[],\n) {\n const data = discardEPB(unescapedData);\n let seiPtr = 0;\n // skip nal header\n seiPtr += headerSize;\n let payloadType = 0;\n let payloadSize = 0;\n let b = 0;\n\n while (seiPtr < data.length) {\n payloadType = 0;\n do {\n if (seiPtr >= data.length) {\n break;\n }\n b = data[seiPtr++];\n payloadType += b;\n } while (b === 0xff);\n\n // Parse payload size.\n payloadSize = 0;\n do {\n if (seiPtr >= data.length) {\n break;\n }\n b = data[seiPtr++];\n payloadSize += b;\n } while (b === 0xff);\n\n const leftOver = data.length - seiPtr;\n // Create a variable to process the payload\n let payPtr = seiPtr;\n\n // Increment the seiPtr to the end of the payload\n if (payloadSize < leftOver) {\n seiPtr += payloadSize;\n } else if (payloadSize > leftOver) {\n // Some type of corruption has happened?\n logger.error(\n `Malformed SEI payload. ${payloadSize} is too small, only ${leftOver} bytes left to parse.`,\n );\n // We might be able to parse some data, but let's be safe and ignore it.\n break;\n }\n\n if (payloadType === 4) {\n const countryCode = data[payPtr++];\n if (countryCode === 181) {\n const providerCode = readUint16(data, payPtr);\n payPtr += 2;\n\n if (providerCode === 49) {\n const userStructure = readUint32(data, payPtr);\n payPtr += 4;\n\n if (userStructure === 0x47413934) {\n const userDataType = data[payPtr++];\n\n // Raw CEA-608 bytes wrapped in CEA-708 packet\n if (userDataType === 3) {\n const firstByte = data[payPtr++];\n const totalCCs = 0x1f & firstByte;\n const enabled = 0x40 & firstByte;\n const totalBytes = enabled ? 2 + totalCCs * 3 : 0;\n const byteArray = new Uint8Array(totalBytes);\n if (enabled) {\n byteArray[0] = firstByte;\n for (let i = 1; i < totalBytes; i++) {\n byteArray[i] = data[payPtr++];\n }\n }\n\n samples.push({\n type: userDataType,\n payloadType,\n pts,\n bytes: byteArray,\n });\n }\n }\n }\n }\n } else if (payloadType === 5) {\n if (payloadSize > 16) {\n const uuidStrArray: Array<string> = [];\n for (let i = 0; i < 16; i++) {\n const b = data[payPtr++].toString(16);\n uuidStrArray.push(b.length == 1 ? '0' + b : b);\n\n if (i === 3 || i === 5 || i === 7 || i === 9) {\n uuidStrArray.push('-');\n }\n }\n const length = payloadSize - 16;\n const userDataBytes = new Uint8Array(length);\n for (let i = 0; i < length; i++) {\n userDataBytes[i] = data[payPtr++];\n }\n\n samples.push({\n payloadType,\n pts,\n uuid: uuidStrArray.join(''),\n userData: utf8ArrayToStr(userDataBytes),\n userDataBytes,\n });\n }\n }\n }\n}\n\n/**\n * remove Emulation Prevention bytes from a RBSP\n */\nexport function discardEPB(data: Uint8Array): Uint8Array {\n const length = data.byteLength;\n const EPBPositions = [] as Array<number>;\n let i = 1;\n\n // Find all `Emulation Prevention Bytes`\n while (i < length - 2) {\n if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 0x03) {\n EPBPositions.push(i + 2);\n i += 2;\n } else {\n i++;\n }\n }\n\n // If no Emulation Prevention Bytes were found just return the original\n // array\n if (EPBPositions.length === 0) {\n return data;\n }\n\n // Create a new array to hold the NAL unit data\n const newLength = length - EPBPositions.length;\n const newData = new Uint8Array(newLength);\n let sourceIndex = 0;\n\n for (i = 0; i < newLength; sourceIndex++, i++) {\n if (sourceIndex === EPBPositions[0]) {\n // Skip this byte\n sourceIndex++;\n // Remove this position index\n EPBPositions.shift();\n }\n newData[i] = data[sourceIndex];\n }\n return newData;\n}\n\nexport function parseEmsg(data: Uint8Array): IEmsgParsingData {\n const version = data[0];\n let schemeIdUri: string = '';\n let value: string = '';\n let timeScale: number = 0;\n let presentationTimeDelta: number = 0;\n let presentationTime: number = 0;\n let eventDuration: number = 0;\n let id: number = 0;\n let offset: number = 0;\n\n if (version === 0) {\n while (bin2str(data.subarray(offset, offset + 1)) !== '\\0') {\n schemeIdUri += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n }\n\n schemeIdUri += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n\n while (bin2str(data.subarray(offset, offset + 1)) !== '\\0') {\n value += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n }\n\n value += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n\n timeScale = readUint32(data, 12);\n presentationTimeDelta = readUint32(data, 16);\n eventDuration = readUint32(data, 20);\n id = readUint32(data, 24);\n offset = 28;\n } else if (version === 1) {\n offset += 4;\n timeScale = readUint32(data, offset);\n offset += 4;\n const leftPresentationTime = readUint32(data, offset);\n offset += 4;\n const rightPresentationTime = readUint32(data, offset);\n offset += 4;\n presentationTime = 2 ** 32 * leftPresentationTime + rightPresentationTime;\n if (!Number.isSafeInteger(presentationTime)) {\n presentationTime = Number.MAX_SAFE_INTEGER;\n logger.warn(\n 'Presentation time exceeds safe integer limit and wrapped to max safe integer in parsing emsg box',\n );\n }\n\n eventDuration = readUint32(data, offset);\n offset += 4;\n id = readUint32(data, offset);\n offset += 4;\n\n while (bin2str(data.subarray(offset, offset + 1)) !== '\\0') {\n schemeIdUri += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n }\n\n schemeIdUri += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n\n while (bin2str(data.subarray(offset, offset + 1)) !== '\\0') {\n value += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n }\n\n value += bin2str(data.subarray(offset, offset + 1));\n offset += 1;\n }\n const payload = data.subarray(offset, data.byteLength);\n\n return {\n schemeIdUri,\n value,\n timeScale,\n presentationTime,\n presentationTimeDelta,\n eventDuration,\n id,\n payload,\n };\n}\n\nexport function mp4Box(type: ArrayLike<number>, ...payload: Uint8Array[]) {\n const len = payload.length;\n let size = 8;\n let i = len;\n while (i--) {\n size += payload[i].byteLength;\n }\n const result = new Uint8Array(size);\n result[0] = (size >> 24) & 0xff;\n result[1] = (size >> 16) & 0xff;\n result[2] = (size >> 8) & 0xff;\n result[3] = size & 0xff;\n result.set(type, 4);\n for (i = 0, size = 8; i < len; i++) {\n result.set(payload[i], size);\n size += payload[i].byteLength;\n }\n return result;\n}\n\nexport function mp4pssh(\n systemId: Uint8Array,\n keyids: Array<Uint8Array> | null,\n data: Uint8Array,\n) {\n if (systemId.byteLength !== 16) {\n throw new RangeError('Invalid system id');\n }\n let version;\n let kids;\n if (keyids) {\n version = 1;\n kids = new Uint8Array(keyids.length * 16);\n for (let ix = 0; ix < keyids.length; ix++) {\n const k = keyids[ix]; // uint8array\n if (k.byteLength !== 16) {\n throw new RangeError('Invalid key');\n }\n kids.set(k, ix * 16);\n }\n } else {\n version = 0;\n kids = new Uint8Array();\n }\n let kidCount;\n if (version > 0) {\n kidCount = new Uint8Array(4);\n if (keyids!.length > 0) {\n new DataView(kidCount.buffer).setUint32(0, keyids!.length, false);\n }\n } else {\n kidCount = new Uint8Array();\n }\n const dataSize = new Uint8Array(4);\n if (data && data.byteLength > 0) {\n new DataView(dataSize.buffer).setUint32(0, data.byteLength, false);\n }\n return mp4Box(\n [112, 115, 115, 104],\n new Uint8Array([\n version,\n 0x00,\n 0x00,\n 0x00, // Flags\n ]),\n systemId, // 16 bytes\n kidCount,\n kids,\n dataSize,\n data || new Uint8Array(),\n );\n}\n\nexport type PsshData = {\n version: 0 | 1;\n systemId: KeySystemIds;\n kids: null | Uint8Array[];\n data: null | Uint8Array;\n offset: number;\n size: number;\n};\n\nexport type PsshInvalidResult = {\n systemId?: undefined;\n offset: number;\n size: number;\n};\n\nexport function parseMultiPssh(\n initData: ArrayBuffer,\n): (PsshData | PsshInvalidResult)[] {\n const results: (PsshData | PsshInvalidResult)[] = [];\n if (initData instanceof ArrayBuffer) {\n const length = initData.byteLength;\n let offset = 0;\n while (offset + 32 < length) {\n const view = new DataView(initData, offset);\n const pssh = parsePssh(view);\n results.push(pssh);\n offset += pssh.size;\n }\n }\n return results;\n}\n\nfunction parsePssh(view: DataView): PsshData | PsshInvalidResult {\n const size = view.getUint32(0);\n const offset = view.byteOffset;\n const length = view.byteLength;\n if (length < size) {\n return {\n offset,\n size: length,\n };\n }\n const type = view.getUint32(4);\n if (type !== 0x70737368) {\n return { offset, size };\n }\n const version = view.getUint32(8) >>> 24;\n if (version !== 0 && version !== 1) {\n return { offset, size };\n }\n const buffer = view.buffer;\n const systemId = Hex.hexDump(\n new Uint8Array(buffer, offset + 12, 16),\n ) as KeySystemIds;\n const dataSizeOrKidCount = view.getUint32(28);\n let kids: null | Uint8Array[] = null;\n let data: null | Uint8Array = null;\n if (version === 0) {\n if (size - 32 < dataSizeOrKidCount || dataSizeOrKidCount < 22) {\n return { offset, size };\n }\n data = new Uint8Array(buffer, offset + 32, dataSizeOrKidCount);\n } else if (version === 1) {\n if (\n !dataSizeOrKidCount ||\n length < offset + 32 + dataSizeOrKidCount * 16 + 16\n ) {\n return { offset, size };\n }\n kids = [];\n for (let i = 0; i < dataSizeOrKidCount; i++) {\n kids.push(new Uint8Array(buffer, offset + 32 + i * 16, 16));\n }\n }\n return {\n version,\n systemId,\n kids,\n data,\n offset,\n size,\n };\n}\n","import type { DemuxedTrack } from '../types/demuxer';\n\nexport function dummyTrack(type = '', inputTimeScale = 90000): DemuxedTrack {\n return {\n type,\n id: -1,\n pid: -1,\n inputTimeScale,\n sequenceNumber: -1,\n samples: [],\n dropped: 0,\n };\n}\n","import { canParseId3 } from '@svta/common-media-library/id3/canParseId3';\nimport { getId3Data } from '@svta/common-media-library/id3/getId3Data';\nimport { getId3Timestamp } from '@svta/common-media-library/id3/getId3Timestamp';\nimport {\n type AudioFrame,\n type DemuxedAudioTrack,\n type DemuxedMetadataTrack,\n type DemuxedUserdataTrack,\n type DemuxedVideoTrackBase,\n type Demuxer,\n type DemuxerResult,\n type KeyData,\n MetadataSchema,\n} from '../../types/demuxer';\nimport { appendUint8Array } from '../../utils/mp4-tools';\nimport { sliceUint8 } from '../../utils/typed-array';\nimport { dummyTrack } from '../dummy-demuxed-track';\nimport type { RationalTimestamp } from '../../utils/timescale-conversion';\n\nclass BaseAudioDemuxer implements Demuxer {\n protected _audioTrack?: DemuxedAudioTrack;\n protected _id3Track?: DemuxedMetadataTrack;\n protected frameIndex: number = 0;\n protected cachedData: Uint8Array | null = null;\n protected basePTS: number | null = null;\n protected initPTS: RationalTimestamp | null = null;\n protected lastPTS: number | null = null;\n\n resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n ) {\n this._id3Track = {\n type: 'id3',\n id: 3,\n pid: -1,\n inputTimeScale: 90000,\n sequenceNumber: 0,\n samples: [],\n dropped: 0,\n };\n }\n\n resetTimeStamp(deaultTimestamp: RationalTimestamp | null) {\n this.initPTS = deaultTimestamp;\n this.resetContiguity();\n }\n\n resetContiguity(): void {\n this.basePTS = null;\n this.lastPTS = null;\n this.frameIndex = 0;\n }\n\n canParse(data: Uint8Array, offset: number): boolean {\n return false;\n }\n\n appendFrame(\n track: DemuxedAudioTrack,\n data: Uint8Array,\n offset: number,\n ): AudioFrame | void {}\n\n // feed incoming data to the front of the parsing pipeline\n demux(data: Uint8Array, timeOffset: number): DemuxerResult {\n if (this.cachedData) {\n data = appendUint8Array(this.cachedData, data);\n this.cachedData = null;\n }\n\n let id3Data: Uint8Array | undefined = getId3Data(data, 0);\n let offset = id3Data ? id3Data.length : 0;\n let lastDataIndex;\n const track = this._audioTrack as DemuxedAudioTrack;\n const id3Track = this._id3Track as DemuxedMetadataTrack;\n const timestamp = id3Data ? getId3Timestamp(id3Data) : undefined;\n const length = data.length;\n\n if (\n this.basePTS === null ||\n (this.frameIndex === 0 && Number.isFinite(timestamp))\n ) {\n this.basePTS = initPTSFn(timestamp, timeOffset, this.initPTS);\n this.lastPTS = this.basePTS;\n }\n\n if (this.lastPTS === null) {\n this.lastPTS = this.basePTS;\n }\n\n // more expressive than alternative: id3Data?.length\n if (id3Data && id3Data.length > 0) {\n id3Track.samples.push({\n pts: this.lastPTS,\n dts: this.lastPTS,\n data: id3Data,\n type: MetadataSchema.audioId3,\n duration: Number.POSITIVE_INFINITY,\n });\n }\n\n while (offset < length) {\n if (this.canParse(data, offset)) {\n const frame = this.appendFrame(track, data, offset);\n if (frame) {\n this.frameIndex++;\n this.lastPTS = frame.sample.pts;\n offset += frame.length;\n lastDataIndex = offset;\n } else {\n offset = length;\n }\n } else if (canParseId3(data, offset)) {\n // after a canParse, a call to getId3Data *should* always returns some data\n id3Data = getId3Data(data, offset)!;\n id3Track.samples.push({\n pts: this.lastPTS,\n dts: this.lastPTS,\n data: id3Data,\n type: MetadataSchema.audioId3,\n duration: Number.POSITIVE_INFINITY,\n });\n offset += id3Data.length;\n lastDataIndex = offset;\n } else {\n offset++;\n }\n if (offset === length && lastDataIndex !== length) {\n const partialData = sliceUint8(data, lastDataIndex);\n if (this.cachedData) {\n this.cachedData = appendUint8Array(this.cachedData, partialData);\n } else {\n this.cachedData = partialData;\n }\n }\n }\n\n return {\n audioTrack: track,\n videoTrack: dummyTrack() as DemuxedVideoTrackBase,\n id3Track,\n textTrack: dummyTrack() as DemuxedUserdataTrack,\n };\n }\n\n demuxSampleAes(\n data: Uint8Array,\n keyData: KeyData,\n timeOffset: number,\n ): Promise<DemuxerResult> {\n return Promise.reject(\n new Error(\n `[${this}] This demuxer does not support Sample-AES decryption`,\n ),\n );\n }\n\n flush(timeOffset: number): DemuxerResult {\n // Parse cache in case of remaining frames.\n const cachedData = this.cachedData;\n if (cachedData) {\n this.cachedData = null;\n this.demux(cachedData, 0);\n }\n\n return {\n audioTrack: this._audioTrack as DemuxedAudioTrack,\n videoTrack: dummyTrack() as DemuxedVideoTrackBase,\n id3Track: this._id3Track as DemuxedMetadataTrack,\n textTrack: dummyTrack() as DemuxedUserdataTrack,\n };\n }\n\n destroy() {\n this.cachedData = null;\n // @ts-ignore\n this._audioTrack = this._id3Track = undefined;\n }\n}\n\n/**\n * Initialize PTS\n * <p>\n * use timestamp unless it is undefined, NaN or Infinity\n * </p>\n */\nexport const initPTSFn = (\n timestamp: number | undefined,\n timeOffset: number,\n initPTS: RationalTimestamp | null,\n): number => {\n if (Number.isFinite(timestamp as number)) {\n return timestamp! * 90;\n }\n const init90kHz = initPTS\n ? (initPTS.baseTime * 90000) / initPTS.timescale\n : 0;\n return timeOffset * 90000 + init90kHz;\n};\nexport default BaseAudioDemuxer;\n","/**\n * MPEG parser helper\n */\nimport type { DemuxedAudioTrack } from '../../types/demuxer';\n\nlet chromeVersion: number | null = null;\n\nconst BitratesMap = [\n 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56,\n 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80,\n 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112, 128, 144,\n 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144,\n 160,\n];\n\nconst SamplingRateMap = [\n 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000,\n];\n\nconst SamplesCoefficients = [\n // MPEG 2.5\n [\n 0, // Reserved\n 72, // Layer3\n 144, // Layer2\n 12, // Layer1\n ],\n // Reserved\n [\n 0, // Reserved\n 0, // Layer3\n 0, // Layer2\n 0, // Layer1\n ],\n // MPEG 2\n [\n 0, // Reserved\n 72, // Layer3\n 144, // Layer2\n 12, // Layer1\n ],\n // MPEG 1\n [\n 0, // Reserved\n 144, // Layer3\n 144, // Layer2\n 12, // Layer1\n ],\n];\n\nconst BytesInSlot = [\n 0, // Reserved\n 1, // Layer3\n 1, // Layer2\n 4, // Layer1\n];\n\nexport function appendFrame(\n track: DemuxedAudioTrack,\n data: Uint8Array,\n offset: number,\n pts: number,\n frameIndex: number,\n) {\n // Using http://www.datavoyage.com/mpgscript/mpeghdr.htm as a reference\n if (offset + 24 > data.length) {\n return;\n }\n\n const header = parseHeader(data, offset);\n if (header && offset + header.frameLength <= data.length) {\n const frameDuration = (header.samplesPerFrame * 90000) / header.sampleRate;\n const stamp = pts + frameIndex * frameDuration;\n const sample = {\n unit: data.subarray(offset, offset + header.frameLength),\n pts: stamp,\n dts: stamp,\n };\n\n track.config = [];\n track.channelCount = header.channelCount;\n track.samplerate = header.sampleRate;\n track.samples.push(sample);\n\n return { sample, length: header.frameLength, missing: 0 };\n }\n}\n\nexport function parseHeader(data: Uint8Array, offset: number) {\n const mpegVersion = (data[offset + 1] >> 3) & 3;\n const mpegLayer = (data[offset + 1] >> 1) & 3;\n const bitRateIndex = (data[offset + 2] >> 4) & 15;\n const sampleRateIndex = (data[offset + 2] >> 2) & 3;\n if (\n mpegVersion !== 1 &&\n bitRateIndex !== 0 &&\n bitRateIndex !== 15 &&\n sampleRateIndex !== 3\n ) {\n const paddingBit = (data[offset + 2] >> 1) & 1;\n const channelMode = data[offset + 3] >> 6;\n const columnInBitrates =\n mpegVersion === 3 ? 3 - mpegLayer : mpegLayer === 3 ? 3 : 4;\n const bitRate =\n BitratesMap[columnInBitrates * 14 + bitRateIndex - 1] * 1000;\n const columnInSampleRates =\n mpegVersion === 3 ? 0 : mpegVersion === 2 ? 1 : 2;\n const sampleRate =\n SamplingRateMap[columnInSampleRates * 3 + sampleRateIndex];\n const channelCount = channelMode === 3 ? 1 : 2; // If bits of channel mode are `11` then it is a single channel (Mono)\n const sampleCoefficient = SamplesCoefficients[mpegVersion][mpegLayer];\n const bytesInSlot = BytesInSlot[mpegLayer];\n const samplesPerFrame = sampleCoefficient * 8 * bytesInSlot;\n const frameLength =\n Math.floor((sampleCoefficient * bitRate) / sampleRate + paddingBit) *\n bytesInSlot;\n\n if (chromeVersion === null) {\n const userAgent = navigator.userAgent || '';\n const result = userAgent.match(/Chrome\\/(\\d+)/i);\n chromeVersion = result ? parseInt(result[1]) : 0;\n }\n const needChromeFix = !!chromeVersion && chromeVersion <= 87;\n\n if (\n needChromeFix &&\n mpegLayer === 2 &&\n bitRate >= 224000 &&\n channelMode === 0\n ) {\n // Work around bug in Chromium by setting channelMode to dual-channel (01) instead of stereo (00)\n data[offset + 3] = data[offset + 3] | 0x80;\n }\n\n return { sampleRate, channelCount, frameLength, samplesPerFrame };\n }\n}\n\nexport function isHeaderPattern(data: Uint8Array, offset: number): boolean {\n return (\n data[offset] === 0xff &&\n (data[offset + 1] & 0xe0) === 0xe0 &&\n (data[offset + 1] & 0x06) !== 0x00\n );\n}\n\nexport function isHeader(data: Uint8Array, offset: number): boolean {\n // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1\n // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)\n // More info http://www.mp3-tech.org/programmer/frame_header.html\n return offset + 1 < data.length && isHeaderPattern(data, offset);\n}\n\nexport function canParse(data: Uint8Array, offset: number): boolean {\n const headerSize = 4;\n\n return isHeaderPattern(data, offset) && headerSize <= data.length - offset;\n}\n\nexport function probe(data: Uint8Array, offset: number): boolean {\n // same as isHeader but we also check that MPEG frame follows last MPEG frame\n // or end of data is reached\n if (offset + 1 < data.length && isHeaderPattern(data, offset)) {\n // MPEG header Length\n const headerLength = 4;\n // MPEG frame Length\n const header = parseHeader(data, offset);\n let frameLength = headerLength;\n if (header?.frameLength) {\n frameLength = header.frameLength;\n }\n\n const newOffset = offset + frameLength;\n return newOffset === data.length || isHeader(data, newOffset);\n }\n return false;\n}\n","/**\n * AAC demuxer\n */\nimport { getId3Data } from '@svta/common-media-library/id3/getId3Data';\nimport * as ADTS from './adts';\nimport BaseAudioDemuxer from './base-audio-demuxer';\nimport * as MpegAudio from './mpegaudio';\nimport type { HlsConfig } from '../../config';\nimport type { HlsEventEmitter } from '../../events';\nimport type { DemuxedAudioTrack } from '../../types/demuxer';\nimport type { ILogger } from '../../utils/logger';\n\nclass AACDemuxer extends BaseAudioDemuxer {\n private readonly observer: HlsEventEmitter;\n private readonly config: HlsConfig;\n\n constructor(observer: HlsEventEmitter, config) {\n super();\n this.observer = observer;\n this.config = config;\n }\n\n resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n ) {\n super.resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration);\n this._audioTrack = {\n container: 'audio/adts',\n type: 'audio',\n id: 2,\n pid: -1,\n sequenceNumber: 0,\n segmentCodec: 'aac',\n samples: [],\n manifestCodec: audioCodec,\n duration: trackDuration,\n inputTimeScale: 90000,\n dropped: 0,\n };\n }\n\n // Source for probe info - https://wiki.multimedia.cx/index.php?title=ADTS\n static probe(data: Uint8Array | undefined, logger: ILogger): boolean {\n if (!data) {\n return false;\n }\n\n // Check for the ADTS sync word\n // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1\n // Layer bits (position 14 and 15) in header should be always 0 for ADTS\n // More info https://wiki.multimedia.cx/index.php?title=ADTS\n const id3Data = getId3Data(data, 0);\n let offset = id3Data?.length || 0;\n\n if (MpegAudio.probe(data, offset)) {\n return false;\n }\n\n for (let length = data.length; offset < length; offset++) {\n if (ADTS.probe(data, offset)) {\n logger.log('ADTS sync word found !');\n return true;\n }\n }\n return false;\n }\n\n canParse(data, offset) {\n return ADTS.canParse(data, offset);\n }\n\n appendFrame(track: DemuxedAudioTrack, data: Uint8Array, offset: number) {\n ADTS.initTrackConfig(\n track,\n this.observer,\n data,\n offset,\n track.manifestCodec,\n );\n const frame = ADTS.appendFrame(\n track,\n data,\n offset,\n this.basePTS as number,\n this.frameIndex,\n );\n if (frame && frame.missing === 0) {\n return frame;\n }\n }\n}\n\nexport default AACDemuxer;\n","export const getAudioBSID = (data: Uint8Array, offset: number): number => {\n // check the bsid to confirm ac-3 | ec-3\n let bsid = 0;\n let numBits = 5;\n offset += numBits;\n const temp = new Uint32Array(1); // unsigned 32 bit for temporary storage\n const mask = new Uint32Array(1); // unsigned 32 bit mask value\n const byte = new Uint8Array(1); // unsigned 8 bit for temporary storage\n while (numBits > 0) {\n byte[0] = data[offset];\n // read remaining bits, upto 8 bits at a time\n const bits = Math.min(numBits, 8);\n const shift = 8 - bits;\n mask[0] = (0xff000000 >>> (24 + shift)) << shift;\n temp[0] = (byte[0] & mask[0]) >> shift;\n bsid = !bsid ? temp[0] : (bsid << bits) | temp[0];\n offset += 1;\n numBits -= bits;\n }\n return bsid;\n};\n","import { getId3Data } from '@svta/common-media-library/id3/getId3Data';\nimport { getId3Timestamp } from '@svta/common-media-library/id3/getId3Timestamp';\nimport BaseAudioDemuxer from './base-audio-demuxer';\nimport { getAudioBSID } from './dolby';\nimport type { HlsEventEmitter } from '../../events';\nimport type { AudioFrame, DemuxedAudioTrack } from '../../types/demuxer';\n\nexport class AC3Demuxer extends BaseAudioDemuxer {\n private readonly observer: HlsEventEmitter;\n\n constructor(observer: HlsEventEmitter) {\n super();\n this.observer = observer;\n }\n\n resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n ) {\n super.resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration);\n this._audioTrack = {\n container: 'audio/ac-3',\n type: 'audio',\n id: 2,\n pid: -1,\n sequenceNumber: 0,\n segmentCodec: 'ac3',\n samples: [],\n manifestCodec: audioCodec,\n duration: trackDuration,\n inputTimeScale: 90000,\n dropped: 0,\n };\n }\n\n canParse(data: Uint8Array, offset: number): boolean {\n return offset + 64 < data.length;\n }\n\n appendFrame(\n track: DemuxedAudioTrack,\n data: Uint8Array,\n offset: number,\n ): AudioFrame | void {\n const frameLength = appendFrame(\n track,\n data,\n offset,\n this.basePTS as number,\n this.frameIndex,\n );\n if (frameLength !== -1) {\n const sample = track.samples[track.samples.length - 1];\n return { sample, length: frameLength, missing: 0 };\n }\n }\n\n static probe(data: Uint8Array | undefined): boolean {\n if (!data) {\n return false;\n }\n\n const id3Data = getId3Data(data, 0);\n if (!id3Data) {\n return false;\n }\n\n // look for the ac-3 sync bytes\n const offset = id3Data.length;\n if (\n data[offset] === 0x0b &&\n data[offset + 1] === 0x77 &&\n getId3Timestamp(id3Data) !== undefined &&\n // check the bsid to confirm ac-3\n getAudioBSID(data, offset) < 16\n ) {\n return true;\n }\n return false;\n }\n}\n\nexport function appendFrame(\n track: DemuxedAudioTrack,\n data: Uint8Array,\n start: number,\n pts: number,\n frameIndex: number,\n): number {\n if (start + 8 > data.length) {\n return -1; // not enough bytes left\n }\n\n if (data[start] !== 0x0b || data[start + 1] !== 0x77) {\n return -1; // invalid magic\n }\n\n // get sample rate\n const samplingRateCode = data[start + 4] >> 6;\n if (samplingRateCode >= 3) {\n return -1; // invalid sampling rate\n }\n\n const samplingRateMap = [48000, 44100, 32000];\n const sampleRate = samplingRateMap[samplingRateCode];\n\n // get frame size\n const frameSizeCode = data[start + 4] & 0x3f;\n const frameSizeMap = [\n 64, 69, 96, 64, 70, 96, 80, 87, 120, 80, 88, 120, 96, 104, 144, 96, 105,\n 144, 112, 121, 168, 112, 122, 168, 128, 139, 192, 128, 140, 192, 160, 174,\n 240, 160, 175, 240, 192, 208, 288, 192, 209, 288, 224, 243, 336, 224, 244,\n 336, 256, 278, 384, 256, 279, 384, 320, 348, 480, 320, 349, 480, 384, 417,\n 576, 384, 418, 576, 448, 487, 672, 448, 488, 672, 512, 557, 768, 512, 558,\n 768, 640, 696, 960, 640, 697, 960, 768, 835, 1152, 768, 836, 1152, 896, 975,\n 1344, 896, 976, 1344, 1024, 1114, 1536, 1024, 1115, 1536, 1152, 1253, 1728,\n 1152, 1254, 1728, 1280, 1393, 1920, 1280, 1394, 1920,\n ];\n\n const frameLength = frameSizeMap[frameSizeCode * 3 + samplingRateCode] * 2;\n if (start + frameLength > data.length) {\n return -1;\n }\n\n // get channel count\n const channelMode = data[start + 6] >> 5;\n let skipCount = 0;\n if (channelMode === 2) {\n skipCount += 2;\n } else {\n if (channelMode & 1 && channelMode !== 1) {\n skipCount += 2;\n }\n if (channelMode & 4) {\n skipCount += 2;\n }\n }\n\n const lfeon =\n (((data[start + 6] << 8) | data[start + 7]) >> (12 - skipCount)) & 1;\n\n const channelsMap = [2, 1, 2, 3, 3, 4, 4, 5];\n const channelCount = channelsMap[channelMode] + lfeon;\n\n // build dac3 box\n const bsid = data[start + 5] >> 3;\n const bsmod = data[start + 5] & 7;\n\n const config = new Uint8Array([\n (samplingRateCode << 6) | (bsid << 1) | (bsmod >> 2),\n ((bsmod & 3) << 6) |\n (channelMode << 3) |\n (lfeon << 2) |\n (frameSizeCode >> 4),\n (frameSizeCode << 4) & 0xe0,\n ]);\n\n const frameDuration = (1536 / sampleRate) * 90000;\n const stamp = pts + frameIndex * frameDuration;\n const unit = data.subarray(start, start + frameLength);\n\n track.config = config;\n track.channelCount = channelCount;\n track.samplerate = sampleRate;\n track.samples.push({ unit, pts: stamp });\n\n return frameLength;\n}\n","/**\n * MP3 demuxer\n */\nimport { getId3Data } from '@svta/common-media-library/id3/getId3Data';\nimport { getId3Timestamp } from '@svta/common-media-library/id3/getId3Timestamp';\nimport BaseAudioDemuxer from './base-audio-demuxer';\nimport { getAudioBSID } from './dolby';\nimport * as MpegAudio from './mpegaudio';\nimport { logger } from '../../utils/logger';\n\nclass MP3Demuxer extends BaseAudioDemuxer {\n resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n ) {\n super.resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration);\n this._audioTrack = {\n container: 'audio/mpeg',\n type: 'audio',\n id: 2,\n pid: -1,\n sequenceNumber: 0,\n segmentCodec: 'mp3',\n samples: [],\n manifestCodec: audioCodec,\n duration: trackDuration,\n inputTimeScale: 90000,\n dropped: 0,\n };\n }\n\n static probe(data: Uint8Array | undefined): boolean {\n if (!data) {\n return false;\n }\n\n // check if data contains ID3 timestamp and MPEG sync word\n // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1\n // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)\n // More info http://www.mp3-tech.org/programmer/frame_header.html\n const id3Data = getId3Data(data, 0);\n let offset = id3Data?.length || 0;\n\n // Check for ac-3|ec-3 sync bytes and return false if present\n if (\n id3Data &&\n data[offset] === 0x0b &&\n data[offset + 1] === 0x77 &&\n getId3Timestamp(id3Data) !== undefined &&\n // check the bsid to confirm ac-3 or ec-3 (not mp3)\n getAudioBSID(data, offset) <= 16\n ) {\n return false;\n }\n\n for (let length = data.length; offset < length; offset++) {\n if (MpegAudio.probe(data, offset)) {\n logger.log('MPEG Audio sync word found !');\n return true;\n }\n }\n return false;\n }\n\n canParse(data, offset) {\n return MpegAudio.canParse(data, offset);\n }\n\n appendFrame(track, data, offset) {\n if (this.basePTS === null) {\n return;\n }\n return MpegAudio.appendFrame(\n track,\n data,\n offset,\n this.basePTS,\n this.frameIndex,\n );\n }\n}\n\nexport default MP3Demuxer;\n","export const enum DecrypterAesMode {\n cbc = 0,\n ctr = 1,\n}\n","import { DecrypterAesMode } from './decrypter-aes-mode';\n\nexport default class AESCrypto {\n private subtle: SubtleCrypto;\n private aesIV: Uint8Array;\n private aesMode: DecrypterAesMode;\n\n constructor(subtle: SubtleCrypto, iv: Uint8Array, aesMode: DecrypterAesMode) {\n this.subtle = subtle;\n this.aesIV = iv;\n this.aesMode = aesMode;\n }\n\n decrypt(data: ArrayBuffer, key: CryptoKey) {\n switch (this.aesMode) {\n case DecrypterAesMode.cbc:\n return this.subtle.decrypt(\n { name: 'AES-CBC', iv: this.aesIV },\n key,\n data,\n );\n case DecrypterAesMode.ctr:\n return this.subtle.decrypt(\n { name: 'AES-CTR', counter: this.aesIV, length: 64 }, //64 : NIST SP800-38A standard suggests that the counter should occupy half of the counter block\n key,\n data,\n );\n default:\n throw new Error(`[AESCrypto] invalid aes mode ${this.aesMode}`);\n }\n }\n}\n","import { sliceUint8 } from '../utils/typed-array';\n\n// PKCS7\nexport function removePadding(array: Uint8Array): Uint8Array {\n const outputBytes = array.byteLength;\n const paddingBytes =\n outputBytes && new DataView(array.buffer).getUint8(outputBytes - 1);\n if (paddingBytes) {\n return sliceUint8(array, 0, outputBytes - paddingBytes);\n }\n return array;\n}\n\nexport default class AESDecryptor {\n private rcon: Array<number> = [\n 0x0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36,\n ];\n private subMix: Array<Uint32Array> = [\n new Uint32Array(256),\n new Uint32Array(256),\n new Uint32Array(256),\n new Uint32Array(256),\n ];\n private invSubMix: Array<Uint32Array> = [\n new Uint32Array(256),\n new Uint32Array(256),\n new Uint32Array(256),\n new Uint32Array(256),\n ];\n private sBox: Uint32Array = new Uint32Array(256);\n private invSBox: Uint32Array = new Uint32Array(256);\n private key: Uint32Array = new Uint32Array(0);\n\n private ksRows: number = 0;\n private keySize: number = 0;\n private keySchedule!: Uint32Array;\n private invKeySchedule!: Uint32Array;\n\n constructor() {\n this.initTable();\n }\n\n // Using view.getUint32() also swaps the byte order.\n uint8ArrayToUint32Array_(arrayBuffer) {\n const view = new DataView(arrayBuffer);\n const newArray = new Uint32Array(4);\n for (let i = 0; i < 4; i++) {\n newArray[i] = view.getUint32(i * 4);\n }\n\n return newArray;\n }\n\n initTable() {\n const sBox = this.sBox;\n const invSBox = this.invSBox;\n const subMix = this.subMix;\n const subMix0 = subMix[0];\n const subMix1 = subMix[1];\n const subMix2 = subMix[2];\n const subMix3 = subMix[3];\n const invSubMix = this.invSubMix;\n const invSubMix0 = invSubMix[0];\n const invSubMix1 = invSubMix[1];\n const invSubMix2 = invSubMix[2];\n const invSubMix3 = invSubMix[3];\n\n const d = new Uint32Array(256);\n let x = 0;\n let xi = 0;\n let i = 0;\n for (i = 0; i < 256; i++) {\n if (i < 128) {\n d[i] = i << 1;\n } else {\n d[i] = (i << 1) ^ 0x11b;\n }\n }\n\n for (i = 0; i < 256; i++) {\n let sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);\n sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;\n sBox[x] = sx;\n invSBox[sx] = x;\n\n // Compute multiplication\n const x2 = d[x];\n const x4 = d[x2];\n const x8 = d[x4];\n\n // Compute sub/invSub bytes, mix columns tables\n let t = (d[sx] * 0x101) ^ (sx * 0x1010100);\n subMix0[x] = (t << 24) | (t >>> 8);\n subMix1[x] = (t << 16) | (t >>> 16);\n subMix2[x] = (t << 8) | (t >>> 24);\n subMix3[x] = t;\n\n // Compute inv sub bytes, inv mix columns tables\n t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);\n invSubMix0[sx] = (t << 24) | (t >>> 8);\n invSubMix1[sx] = (t << 16) | (t >>> 16);\n invSubMix2[sx] = (t << 8) | (t >>> 24);\n invSubMix3[sx] = t;\n\n // Compute next counter\n if (!x) {\n x = xi = 1;\n } else {\n x = x2 ^ d[d[d[x8 ^ x2]]];\n xi ^= d[d[xi]];\n }\n }\n }\n\n expandKey(keyBuffer: ArrayBuffer) {\n // convert keyBuffer to Uint32Array\n const key = this.uint8ArrayToUint32Array_(keyBuffer);\n let sameKey = true;\n let offset = 0;\n\n while (offset < key.length && sameKey) {\n sameKey = key[offset] === this.key[offset];\n offset++;\n }\n\n if (sameKey) {\n return;\n }\n\n this.key = key;\n const keySize = (this.keySize = key.length);\n\n if (keySize !== 4 && keySize !== 6 && keySize !== 8) {\n throw new Error('Invalid aes key size=' + keySize);\n }\n\n const ksRows = (this.ksRows = (keySize + 6 + 1) * 4);\n let ksRow;\n let invKsRow;\n\n const keySchedule = (this.keySchedule = new Uint32Array(ksRows));\n const invKeySchedule = (this.invKeySchedule = new Uint32Array(ksRows));\n const sbox = this.sBox;\n const rcon = this.rcon;\n\n const invSubMix = this.invSubMix;\n const invSubMix0 = invSubMix[0];\n const invSubMix1 = invSubMix[1];\n const invSubMix2 = invSubMix[2];\n const invSubMix3 = invSubMix[3];\n\n let prev;\n let t;\n\n for (ksRow = 0; ksRow < ksRows; ksRow++) {\n if (ksRow < keySize) {\n prev = keySchedule[ksRow] = key[ksRow];\n continue;\n }\n t = prev;\n\n if (ksRow % keySize === 0) {\n // Rot word\n t = (t << 8) | (t >>> 24);\n\n // Sub word\n t =\n (sbox[t >>> 24] << 24) |\n (sbox[(t >>> 16) & 0xff] << 16) |\n (sbox[(t >>> 8) & 0xff] << 8) |\n sbox[t & 0xff];\n\n // Mix Rcon\n t ^= rcon[(ksRow / keySize) | 0] << 24;\n } else if (keySize > 6 && ksRow % keySize === 4) {\n // Sub word\n t =\n (sbox[t >>> 24] << 24) |\n (sbox[(t >>> 16) & 0xff] << 16) |\n (sbox[(t >>> 8) & 0xff] << 8) |\n sbox[t & 0xff];\n }\n\n keySchedule[ksRow] = prev = (keySchedule[ksRow - keySize] ^ t) >>> 0;\n }\n\n for (invKsRow = 0; invKsRow < ksRows; invKsRow++) {\n ksRow = ksRows - invKsRow;\n if (invKsRow & 3) {\n t = keySchedule[ksRow];\n } else {\n t = keySchedule[ksRow - 4];\n }\n\n if (invKsRow < 4 || ksRow <= 4) {\n invKeySchedule[invKsRow] = t;\n } else {\n invKeySchedule[invKsRow] =\n invSubMix0[sbox[t >>> 24]] ^\n invSubMix1[sbox[(t >>> 16) & 0xff]] ^\n invSubMix2[sbox[(t >>> 8) & 0xff]] ^\n invSubMix3[sbox[t & 0xff]];\n }\n\n invKeySchedule[invKsRow] = invKeySchedule[invKsRow] >>> 0;\n }\n }\n\n // Adding this as a method greatly improves performance.\n networkToHostOrderSwap(word) {\n return (\n (word << 24) |\n ((word & 0xff00) << 8) |\n ((word & 0xff0000) >> 8) |\n (word >>> 24)\n );\n }\n\n decrypt(inputArrayBuffer: ArrayBuffer, offset: number, aesIV: ArrayBuffer) {\n const nRounds = this.keySize + 6;\n const invKeySchedule = this.invKeySchedule;\n const invSBOX = this.invSBox;\n\n const invSubMix = this.invSubMix;\n const invSubMix0 = invSubMix[0];\n const invSubMix1 = invSubMix[1];\n const invSubMix2 = invSubMix[2];\n const invSubMix3 = invSubMix[3];\n\n const initVector = this.uint8ArrayToUint32Array_(aesIV);\n let initVector0 = initVector[0];\n let initVector1 = initVector[1];\n let initVector2 = initVector[2];\n let initVector3 = initVector[3];\n\n const inputInt32 = new Int32Array(inputArrayBuffer);\n const outputInt32 = new Int32Array(inputInt32.length);\n\n let t0, t1, t2, t3;\n let s0, s1, s2, s3;\n let inputWords0, inputWords1, inputWords2, inputWords3;\n\n let ksRow, i;\n const swapWord = this.networkToHostOrderSwap;\n\n while (offset < inputInt32.length) {\n inputWords0 = swapWord(inputInt32[offset]);\n inputWords1 = swapWord(inputInt32[offset + 1]);\n inputWords2 = swapWord(inputInt32[offset + 2]);\n inputWords3 = swapWord(inputInt32[offset + 3]);\n\n s0 = inputWords0 ^ invKeySchedule[0];\n s1 = inputWords3 ^ invKeySchedule[1];\n s2 = inputWords2 ^ invKeySchedule[2];\n s3 = inputWords1 ^ invKeySchedule[3];\n\n ksRow = 4;\n\n // Iterate through the rounds of decryption\n for (i = 1; i < nRounds; i++) {\n t0 =\n invSubMix0[s0 >>> 24] ^\n invSubMix1[(s1 >> 16) & 0xff] ^\n invSubMix2[(s2 >> 8) & 0xff] ^\n invSubMix3[s3 & 0xff] ^\n invKeySchedule[ksRow];\n t1 =\n invSubMix0[s1 >>> 24] ^\n invSubMix1[(s2 >> 16) & 0xff] ^\n invSubMix2[(s3 >> 8) & 0xff] ^\n invSubMix3[s0 & 0xff] ^\n invKeySchedule[ksRow + 1];\n t2 =\n invSubMix0[s2 >>> 24] ^\n invSubMix1[(s3 >> 16) & 0xff] ^\n invSubMix2[(s0 >> 8) & 0xff] ^\n invSubMix3[s1 & 0xff] ^\n invKeySchedule[ksRow + 2];\n t3 =\n invSubMix0[s3 >>> 24] ^\n invSubMix1[(s0 >> 16) & 0xff] ^\n invSubMix2[(s1 >> 8) & 0xff] ^\n invSubMix3[s2 & 0xff] ^\n invKeySchedule[ksRow + 3];\n // Update state\n s0 = t0;\n s1 = t1;\n s2 = t2;\n s3 = t3;\n\n ksRow = ksRow + 4;\n }\n\n // Shift rows, sub bytes, add round key\n t0 =\n (invSBOX[s0 >>> 24] << 24) ^\n (invSBOX[(s1 >> 16) & 0xff] << 16) ^\n (invSBOX[(s2 >> 8) & 0xff] << 8) ^\n invSBOX[s3 & 0xff] ^\n invKeySchedule[ksRow];\n t1 =\n (invSBOX[s1 >>> 24] << 24) ^\n (invSBOX[(s2 >> 16) & 0xff] << 16) ^\n (invSBOX[(s3 >> 8) & 0xff] << 8) ^\n invSBOX[s0 & 0xff] ^\n invKeySchedule[ksRow + 1];\n t2 =\n (invSBOX[s2 >>> 24] << 24) ^\n (invSBOX[(s3 >> 16) & 0xff] << 16) ^\n (invSBOX[(s0 >> 8) & 0xff] << 8) ^\n invSBOX[s1 & 0xff] ^\n invKeySchedule[ksRow + 2];\n t3 =\n (invSBOX[s3 >>> 24] << 24) ^\n (invSBOX[(s0 >> 16) & 0xff] << 16) ^\n (invSBOX[(s1 >> 8) & 0xff] << 8) ^\n invSBOX[s2 & 0xff] ^\n invKeySchedule[ksRow + 3];\n\n // Write\n outputInt32[offset] = swapWord(t0 ^ initVector0);\n outputInt32[offset + 1] = swapWord(t3 ^ initVector1);\n outputInt32[offset + 2] = swapWord(t2 ^ initVector2);\n outputInt32[offset + 3] = swapWord(t1 ^ initVector3);\n\n // reset initVector to last 4 unsigned int\n initVector0 = inputWords0;\n initVector1 = inputWords1;\n initVector2 = inputWords2;\n initVector3 = inputWords3;\n\n offset = offset + 4;\n }\n\n return outputInt32.buffer;\n }\n}\n","import { DecrypterAesMode } from './decrypter-aes-mode';\n\nexport default class FastAESKey {\n private subtle: SubtleCrypto;\n private key: ArrayBuffer;\n private aesMode: DecrypterAesMode;\n\n constructor(\n subtle: SubtleCrypto,\n key: ArrayBuffer,\n aesMode: DecrypterAesMode,\n ) {\n this.subtle = subtle;\n this.key = key;\n this.aesMode = aesMode;\n }\n\n expandKey() {\n const subtleAlgoName = getSubtleAlgoName(this.aesMode);\n return this.subtle.importKey(\n 'raw',\n this.key,\n { name: subtleAlgoName },\n false,\n ['encrypt', 'decrypt'],\n );\n }\n}\n\nfunction getSubtleAlgoName(aesMode: DecrypterAesMode) {\n switch (aesMode) {\n case DecrypterAesMode.cbc:\n return 'AES-CBC';\n case DecrypterAesMode.ctr:\n return 'AES-CTR';\n default:\n throw new Error(`[FastAESKey] invalid aes mode ${aesMode}`);\n }\n}\n","import AESCrypto from './aes-crypto';\nimport AESDecryptor, { removePadding } from './aes-decryptor';\nimport { DecrypterAesMode } from './decrypter-aes-mode';\nimport FastAESKey from './fast-aes-key';\nimport { logger } from '../utils/logger';\nimport { appendUint8Array } from '../utils/mp4-tools';\nimport { sliceUint8 } from '../utils/typed-array';\nimport type { HlsConfig } from '../config';\n\nconst CHUNK_SIZE = 16; // 16 bytes, 128 bits\n\nexport default class Decrypter {\n private logEnabled: boolean = true;\n private removePKCS7Padding: boolean;\n private subtle: SubtleCrypto | null = null;\n private softwareDecrypter: AESDecryptor | null = null;\n private key: ArrayBuffer | null = null;\n private fastAesKey: FastAESKey | null = null;\n private remainderData: Uint8Array | null = null;\n private currentIV: ArrayBuffer | null = null;\n private currentResult: ArrayBuffer | null = null;\n private useSoftware: boolean;\n private enableSoftwareAES: boolean;\n\n constructor(config: HlsConfig, { removePKCS7Padding = true } = {}) {\n this.enableSoftwareAES = config.enableSoftwareAES;\n this.removePKCS7Padding = removePKCS7Padding;\n // built in decryptor expects PKCS7 padding\n if (removePKCS7Padding) {\n try {\n const browserCrypto = self.crypto;\n if (browserCrypto) {\n this.subtle =\n browserCrypto.subtle ||\n ((browserCrypto as any).webkitSubtle as SubtleCrypto);\n }\n } catch (e) {\n /* no-op */\n }\n }\n this.useSoftware = !this.subtle;\n }\n\n destroy() {\n this.subtle = null;\n this.softwareDecrypter = null;\n this.key = null;\n this.fastAesKey = null;\n this.remainderData = null;\n this.currentIV = null;\n this.currentResult = null;\n }\n\n public isSync() {\n return this.useSoftware;\n }\n\n public flush(): Uint8Array | null {\n const { currentResult, remainderData } = this;\n if (!currentResult || remainderData) {\n this.reset();\n return null;\n }\n const data = new Uint8Array(currentResult);\n this.reset();\n if (this.removePKCS7Padding) {\n return removePadding(data);\n }\n return data;\n }\n\n public reset() {\n this.currentResult = null;\n this.currentIV = null;\n this.remainderData = null;\n if (this.softwareDecrypter) {\n this.softwareDecrypter = null;\n }\n }\n\n public decrypt(\n data: Uint8Array | ArrayBuffer,\n key: ArrayBuffer,\n iv: ArrayBuffer,\n aesMode: DecrypterAesMode,\n ): Promise<ArrayBuffer> {\n if (this.useSoftware) {\n return new Promise((resolve, reject) => {\n const dataView = ArrayBuffer.isView(data) ? data : new Uint8Array(data);\n this.softwareDecrypt(dataView, key, iv, aesMode);\n const decryptResult = this.flush();\n if (decryptResult) {\n resolve(decryptResult.buffer);\n } else {\n reject(new Error('[softwareDecrypt] Failed to decrypt data'));\n }\n });\n }\n return this.webCryptoDecrypt(new Uint8Array(data), key, iv, aesMode);\n }\n\n // Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached\n // data is handled in the flush() call\n public softwareDecrypt(\n data: Uint8Array,\n key: ArrayBuffer,\n iv: ArrayBuffer,\n aesMode: DecrypterAesMode,\n ): ArrayBuffer | null {\n const { currentIV, currentResult, remainderData } = this;\n if (aesMode !== DecrypterAesMode.cbc || key.byteLength !== 16) {\n logger.warn('SoftwareDecrypt: can only handle AES-128-CBC');\n return null;\n }\n this.logOnce('JS AES decrypt');\n // The output is staggered during progressive parsing - the current result is cached, and emitted on the next call\n // This is done in order to strip PKCS7 padding, which is found at the end of each segment. We only know we've reached\n // the end on flush(), but by that time we have already received all bytes for the segment.\n // Progressive decryption does not work with WebCrypto\n\n if (remainderData) {\n data = appendUint8Array(remainderData, data);\n this.remainderData = null;\n }\n\n // Byte length must be a multiple of 16 (AES-128 = 128 bit blocks = 16 bytes)\n const currentChunk = this.getValidChunk(data);\n if (!currentChunk.length) {\n return null;\n }\n\n if (currentIV) {\n iv = currentIV;\n }\n\n let softwareDecrypter = this.softwareDecrypter;\n if (!softwareDecrypter) {\n softwareDecrypter = this.softwareDecrypter = new AESDecryptor();\n }\n softwareDecrypter.expandKey(key);\n\n const result = currentResult;\n\n this.currentResult = softwareDecrypter.decrypt(currentChunk.buffer, 0, iv);\n this.currentIV = sliceUint8(currentChunk, -16).buffer;\n\n if (!result) {\n return null;\n }\n return result;\n }\n\n public webCryptoDecrypt(\n data: Uint8Array,\n key: ArrayBuffer,\n iv: ArrayBuffer,\n aesMode: DecrypterAesMode,\n ): Promise<ArrayBuffer> {\n if (this.key !== key || !this.fastAesKey) {\n if (!this.subtle) {\n return Promise.resolve(this.onWebCryptoError(data, key, iv, aesMode));\n }\n this.key = key;\n this.fastAesKey = new FastAESKey(this.subtle, key, aesMode);\n }\n return this.fastAesKey\n .expandKey()\n .then((aesKey: CryptoKey) => {\n // decrypt using web crypto\n if (!this.subtle) {\n return Promise.reject(new Error('web crypto not initialized'));\n }\n this.logOnce('WebCrypto AES decrypt');\n const crypto = new AESCrypto(this.subtle, new Uint8Array(iv), aesMode);\n return crypto.decrypt(data.buffer, aesKey);\n })\n .catch((err) => {\n logger.warn(\n `[decrypter]: WebCrypto Error, disable WebCrypto API, ${err.name}: ${err.message}`,\n );\n\n return this.onWebCryptoError(data, key, iv, aesMode);\n });\n }\n\n private onWebCryptoError(\n data: Uint8Array,\n key: ArrayBuffer,\n iv: ArrayBuffer,\n aesMode: DecrypterAesMode,\n ): ArrayBuffer | never {\n const enableSoftwareAES = this.enableSoftwareAES;\n if (enableSoftwareAES) {\n this.useSoftware = true;\n this.logEnabled = true;\n this.softwareDecrypt(data, key, iv, aesMode);\n const decryptResult = this.flush();\n if (decryptResult) {\n return decryptResult.buffer;\n }\n }\n throw new Error(\n 'WebCrypto' +\n (enableSoftwareAES ? ' and softwareDecrypt' : '') +\n ': failed to decrypt data',\n );\n }\n\n private getValidChunk(data: Uint8Array): Uint8Array {\n let currentChunk = data;\n const splitPoint = data.length - (data.length % CHUNK_SIZE);\n if (splitPoint !== data.length) {\n currentChunk = sliceUint8(data, 0, splitPoint);\n this.remainderData = sliceUint8(data, splitPoint);\n }\n return currentChunk;\n }\n\n private logOnce(msg: string) {\n if (!this.logEnabled) {\n return;\n }\n logger.log(`[decrypter]: ${msg}`);\n this.logEnabled = false;\n }\n}\n","/**\n * MP4 demuxer\n */\nimport { dummyTrack } from './dummy-demuxed-track';\nimport {\n type DemuxedAudioTrack,\n type DemuxedMetadataTrack,\n type DemuxedUserdataTrack,\n type Demuxer,\n type DemuxerResult,\n type KeyData,\n MetadataSchema,\n type PassthroughTrack,\n} from '../types/demuxer';\nimport {\n appendUint8Array,\n findBox,\n hasMoofData,\n parseEmsg,\n parseInitSegment,\n parseSamples,\n RemuxerTrackIdConfig,\n segmentValidRange,\n} from '../utils/mp4-tools';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport type { IEmsgParsingData } from '../utils/mp4-tools';\n\nconst emsgSchemePattern = /\\/emsg[-/]ID3/i;\n\nclass MP4Demuxer implements Demuxer {\n private remainderData: Uint8Array | null = null;\n private timeOffset: number = 0;\n private config: HlsConfig;\n private videoTrack?: PassthroughTrack;\n private audioTrack?: DemuxedAudioTrack;\n private id3Track?: DemuxedMetadataTrack;\n private txtTrack?: DemuxedUserdataTrack;\n\n constructor(observer: HlsEventEmitter, config: HlsConfig) {\n this.config = config;\n }\n\n public resetTimeStamp() {}\n\n public resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n ) {\n const videoTrack = (this.videoTrack = dummyTrack(\n 'video',\n 1,\n ) as PassthroughTrack);\n const audioTrack = (this.audioTrack = dummyTrack(\n 'audio',\n 1,\n ) as DemuxedAudioTrack);\n const captionTrack = (this.txtTrack = dummyTrack(\n 'text',\n 1,\n ) as DemuxedUserdataTrack);\n\n this.id3Track = dummyTrack('id3', 1) as DemuxedMetadataTrack;\n this.timeOffset = 0;\n\n if (!initSegment?.byteLength) {\n return;\n }\n const initData = parseInitSegment(initSegment);\n\n if (initData.video) {\n const { id, timescale, codec } = initData.video;\n videoTrack.id = id;\n videoTrack.timescale = captionTrack.timescale = timescale;\n videoTrack.codec = codec;\n }\n\n if (initData.audio) {\n const { id, timescale, codec } = initData.audio;\n audioTrack.id = id;\n audioTrack.timescale = timescale;\n audioTrack.codec = codec;\n }\n\n captionTrack.id = RemuxerTrackIdConfig.text;\n videoTrack.sampleDuration = 0;\n videoTrack.duration = audioTrack.duration = trackDuration;\n }\n\n public resetContiguity(): void {\n this.remainderData = null;\n }\n\n static probe(data: Uint8Array) {\n return hasMoofData(data);\n }\n\n public demux(data: Uint8Array, timeOffset: number): DemuxerResult {\n this.timeOffset = timeOffset;\n // Load all data into the avc track. The CMAF remuxer will look for the data in the samples object; the rest of the fields do not matter\n let videoSamples = data;\n const videoTrack = this.videoTrack as PassthroughTrack;\n const textTrack = this.txtTrack as DemuxedUserdataTrack;\n if (this.config.progressive) {\n // Split the bytestream into two ranges: one encompassing all data up until the start of the last moof, and everything else.\n // This is done to guarantee that we're sending valid data to MSE - when demuxing progressively, we have no guarantee\n // that the fetch loader gives us flush moof+mdat pairs. If we push jagged data to MSE, it will throw an exception.\n if (this.remainderData) {\n videoSamples = appendUint8Array(this.remainderData, data);\n }\n const segmentedData = segmentValidRange(videoSamples);\n this.remainderData = segmentedData.remainder;\n videoTrack.samples = segmentedData.valid || new Uint8Array();\n } else {\n videoTrack.samples = videoSamples;\n }\n const id3Track = this.extractID3Track(videoTrack, timeOffset);\n textTrack.samples = parseSamples(timeOffset, videoTrack);\n\n return {\n videoTrack,\n audioTrack: this.audioTrack as DemuxedAudioTrack,\n id3Track,\n textTrack: this.txtTrack as DemuxedUserdataTrack,\n };\n }\n\n public flush() {\n const timeOffset = this.timeOffset;\n const videoTrack = this.videoTrack as PassthroughTrack;\n const textTrack = this.txtTrack as DemuxedUserdataTrack;\n videoTrack.samples = this.remainderData || new Uint8Array();\n this.remainderData = null;\n\n const id3Track = this.extractID3Track(videoTrack, this.timeOffset);\n textTrack.samples = parseSamples(timeOffset, videoTrack);\n\n return {\n videoTrack,\n audioTrack: dummyTrack() as DemuxedAudioTrack,\n id3Track,\n textTrack: dummyTrack() as DemuxedUserdataTrack,\n };\n }\n\n private extractID3Track(\n videoTrack: PassthroughTrack,\n timeOffset: number,\n ): DemuxedMetadataTrack {\n const id3Track = this.id3Track as DemuxedMetadataTrack;\n if (videoTrack.samples.length) {\n const emsgs = findBox(videoTrack.samples, ['emsg']);\n if (emsgs) {\n emsgs.forEach((data: Uint8Array) => {\n const emsgInfo = parseEmsg(data);\n if (emsgSchemePattern.test(emsgInfo.schemeIdUri)) {\n const pts = getEmsgStartTime(emsgInfo, timeOffset);\n let duration =\n emsgInfo.eventDuration === 0xffffffff\n ? Number.POSITIVE_INFINITY\n : emsgInfo.eventDuration / emsgInfo.timeScale;\n // Safari takes anything <= 0.001 seconds and maps it to Infinity\n if (duration <= 0.001) {\n duration = Number.POSITIVE_INFINITY;\n }\n const payload = emsgInfo.payload;\n id3Track.samples.push({\n data: payload,\n len: payload.byteLength,\n dts: pts,\n pts: pts,\n type: MetadataSchema.emsg,\n duration: duration,\n });\n } else if (\n this.config.enableEmsgKLVMetadata &&\n emsgInfo.schemeIdUri.startsWith('urn:misb:KLV:bin:1910.1')\n ) {\n const pts = getEmsgStartTime(emsgInfo, timeOffset);\n id3Track.samples.push({\n data: emsgInfo.payload,\n len: emsgInfo.payload.byteLength,\n dts: pts,\n pts: pts,\n type: MetadataSchema.misbklv,\n duration: Number.POSITIVE_INFINITY,\n });\n }\n });\n }\n }\n return id3Track;\n }\n\n demuxSampleAes(\n data: Uint8Array,\n keyData: KeyData,\n timeOffset: number,\n ): Promise<DemuxerResult> {\n return Promise.reject(\n new Error('The MP4 demuxer does not support SAMPLE-AES decryption'),\n );\n }\n\n destroy() {\n // @ts-ignore\n this.config = null;\n this.remainderData = null;\n this.videoTrack =\n this.audioTrack =\n this.id3Track =\n this.txtTrack =\n undefined;\n }\n}\n\nfunction getEmsgStartTime(\n emsgInfo: IEmsgParsingData,\n timeOffset: number,\n): number {\n return Number.isFinite(emsgInfo.presentationTime)\n ? (emsgInfo.presentationTime as number) / emsgInfo.timeScale\n : timeOffset +\n (emsgInfo.presentationTimeDelta as number) / emsgInfo.timeScale;\n}\n\nexport default MP4Demuxer;\n","/**\n * SAMPLE-AES decrypter\n */\n\nimport Decrypter from '../crypt/decrypter';\nimport { DecrypterAesMode } from '../crypt/decrypter-aes-mode';\nimport { discardEPB } from '../utils/mp4-tools';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport type {\n AudioSample,\n DemuxedVideoTrackBase,\n KeyData,\n VideoSample,\n VideoSampleUnit,\n} from '../types/demuxer';\n\nclass SampleAesDecrypter {\n private keyData: KeyData;\n private decrypter: Decrypter;\n\n constructor(observer: HlsEventEmitter, config: HlsConfig, keyData: KeyData) {\n this.keyData = keyData;\n this.decrypter = new Decrypter(config, {\n removePKCS7Padding: false,\n });\n }\n\n decryptBuffer(encryptedData: Uint8Array | ArrayBuffer): Promise<ArrayBuffer> {\n return this.decrypter.decrypt(\n encryptedData,\n this.keyData.key.buffer,\n this.keyData.iv.buffer,\n DecrypterAesMode.cbc,\n );\n }\n\n // AAC - encrypt all full 16 bytes blocks starting from offset 16\n private decryptAacSample(\n samples: AudioSample[],\n sampleIndex: number,\n callback: () => void,\n ) {\n const curUnit = samples[sampleIndex].unit;\n if (curUnit.length <= 16) {\n // No encrypted portion in this sample (first 16 bytes is not\n // encrypted, see https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption/Encryption/Encryption.html),\n return;\n }\n const encryptedData = curUnit.subarray(\n 16,\n curUnit.length - (curUnit.length % 16),\n );\n const encryptedBuffer = encryptedData.buffer.slice(\n encryptedData.byteOffset,\n encryptedData.byteOffset + encryptedData.length,\n );\n\n this.decryptBuffer(encryptedBuffer).then((decryptedBuffer: ArrayBuffer) => {\n const decryptedData = new Uint8Array(decryptedBuffer);\n curUnit.set(decryptedData, 16);\n\n if (!this.decrypter.isSync()) {\n this.decryptAacSamples(samples, sampleIndex + 1, callback);\n }\n });\n }\n\n decryptAacSamples(\n samples: AudioSample[],\n sampleIndex: number,\n callback: () => void,\n ) {\n for (; ; sampleIndex++) {\n if (sampleIndex >= samples.length) {\n callback();\n return;\n }\n\n if (samples[sampleIndex].unit.length < 32) {\n continue;\n }\n\n this.decryptAacSample(samples, sampleIndex, callback);\n\n if (!this.decrypter.isSync()) {\n return;\n }\n }\n }\n\n // AVC - encrypt one 16 bytes block out of ten, starting from offset 32\n getAvcEncryptedData(decodedData: Uint8Array) {\n const encryptedDataLen =\n Math.floor((decodedData.length - 48) / 160) * 16 + 16;\n const encryptedData = new Int8Array(encryptedDataLen);\n let outputPos = 0;\n for (\n let inputPos = 32;\n inputPos < decodedData.length - 16;\n inputPos += 160, outputPos += 16\n ) {\n encryptedData.set(\n decodedData.subarray(inputPos, inputPos + 16),\n outputPos,\n );\n }\n\n return encryptedData;\n }\n\n getAvcDecryptedUnit(\n decodedData: Uint8Array,\n decryptedData: ArrayLike<number> | ArrayBuffer | SharedArrayBuffer,\n ) {\n const uint8DecryptedData = new Uint8Array(decryptedData);\n let inputPos = 0;\n for (\n let outputPos = 32;\n outputPos < decodedData.length - 16;\n outputPos += 160, inputPos += 16\n ) {\n decodedData.set(\n uint8DecryptedData.subarray(inputPos, inputPos + 16),\n outputPos,\n );\n }\n\n return decodedData;\n }\n\n decryptAvcSample(\n samples: VideoSample[],\n sampleIndex: number,\n unitIndex: number,\n callback: () => void,\n curUnit: VideoSampleUnit,\n ) {\n const decodedData = discardEPB(curUnit.data);\n const encryptedData = this.getAvcEncryptedData(decodedData);\n\n this.decryptBuffer(encryptedData.buffer).then(\n (decryptedBuffer: ArrayBuffer) => {\n curUnit.data = this.getAvcDecryptedUnit(decodedData, decryptedBuffer);\n\n if (!this.decrypter.isSync()) {\n this.decryptAvcSamples(samples, sampleIndex, unitIndex + 1, callback);\n }\n },\n );\n }\n\n decryptAvcSamples(\n samples: DemuxedVideoTrackBase['samples'],\n sampleIndex: number,\n unitIndex: number,\n callback: () => void,\n ) {\n if (samples instanceof Uint8Array) {\n throw new Error('Cannot decrypt samples of type Uint8Array');\n }\n\n for (; ; sampleIndex++, unitIndex = 0) {\n if (sampleIndex >= samples.length) {\n callback();\n return;\n }\n\n const curUnits = samples[sampleIndex].units;\n for (; ; unitIndex++) {\n if (unitIndex >= curUnits.length) {\n break;\n }\n\n const curUnit = curUnits[unitIndex];\n if (\n curUnit.data.length <= 48 ||\n (curUnit.type !== 1 && curUnit.type !== 5)\n ) {\n continue;\n }\n\n this.decryptAvcSample(\n samples,\n sampleIndex,\n unitIndex,\n callback,\n curUnit,\n );\n\n if (!this.decrypter.isSync()) {\n return;\n }\n }\n }\n }\n}\n\nexport default SampleAesDecrypter;\n","import { appendUint8Array } from '../../utils/mp4-tools';\nimport type {\n DemuxedUserdataTrack,\n DemuxedVideoTrack,\n VideoSample,\n VideoSampleUnit,\n} from '../../types/demuxer';\nimport type { ParsedVideoSample } from '../tsdemuxer';\nimport type { PES } from '../tsdemuxer';\n\nabstract class BaseVideoParser {\n protected VideoSample: ParsedVideoSample | null = null;\n\n protected createVideoSample(\n key: boolean,\n pts: number | undefined,\n dts: number | undefined,\n ): ParsedVideoSample {\n return {\n key,\n frame: false,\n pts,\n dts,\n units: [],\n length: 0,\n };\n }\n\n protected getLastNalUnit(\n samples: VideoSample[],\n ): VideoSampleUnit | undefined {\n let VideoSample = this.VideoSample;\n let lastUnit: VideoSampleUnit | undefined;\n // try to fallback to previous sample if current one is empty\n if (!VideoSample || VideoSample.units.length === 0) {\n VideoSample = samples[samples.length - 1];\n }\n if (VideoSample?.units) {\n const units = VideoSample.units;\n lastUnit = units[units.length - 1];\n }\n return lastUnit;\n }\n\n protected pushAccessUnit(\n VideoSample: ParsedVideoSample,\n videoTrack: DemuxedVideoTrack,\n ) {\n if (VideoSample.units.length && VideoSample.frame) {\n // if sample does not have PTS/DTS, patch with last sample PTS/DTS\n if (VideoSample.pts === undefined) {\n const samples = videoTrack.samples;\n const nbSamples = samples.length;\n if (nbSamples) {\n const lastSample = samples[nbSamples - 1];\n VideoSample.pts = lastSample.pts;\n VideoSample.dts = lastSample.dts;\n } else {\n // dropping samples, no timestamp found\n videoTrack.dropped++;\n return;\n }\n }\n videoTrack.samples.push(VideoSample as VideoSample);\n }\n }\n\n abstract parsePES(\n track: DemuxedVideoTrack,\n textTrack: DemuxedUserdataTrack,\n pes: PES,\n last: boolean,\n );\n\n protected abstract getNALuType(data: Uint8Array, offset: number): number;\n\n protected parseNALu(\n track: DemuxedVideoTrack,\n array: Uint8Array,\n endOfSegment: boolean,\n ): Array<{\n data: Uint8Array;\n type: number;\n state?: number;\n }> {\n const len = array.byteLength;\n let state = track.naluState || 0;\n const lastState = state;\n const units: VideoSampleUnit[] = [];\n let i = 0;\n let value: number;\n let overflow: number;\n let unitType: number;\n let lastUnitStart = -1;\n let lastUnitType: number = 0;\n // logger.log('PES:' + Hex.hexDump(array));\n\n if (state === -1) {\n // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet\n lastUnitStart = 0;\n // NALu type is value read from offset 0\n lastUnitType = this.getNALuType(array, 0);\n state = 0;\n i = 1;\n }\n\n while (i < len) {\n value = array[i++];\n // optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case\n if (!state) {\n state = value ? 0 : 1;\n continue;\n }\n if (state === 1) {\n state = value ? 0 : 2;\n continue;\n }\n // here we have state either equal to 2 or 3\n if (!value) {\n state = 3;\n } else if (value === 1) {\n overflow = i - state - 1;\n if (lastUnitStart >= 0) {\n const unit: VideoSampleUnit = {\n data: array.subarray(lastUnitStart, overflow),\n type: lastUnitType,\n };\n // logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);\n units.push(unit);\n } else {\n // lastUnitStart is undefined => this is the first start code found in this PES packet\n // first check if start code delimiter is overlapping between 2 PES packets,\n // ie it started in last packet (lastState not zero)\n // and ended at the beginning of this PES packet (i <= 4 - lastState)\n const lastUnit = this.getLastNalUnit(track.samples);\n if (lastUnit) {\n if (lastState && i <= 4 - lastState) {\n // start delimiter overlapping between PES packets\n // strip start delimiter bytes from the end of last NAL unit\n // check if lastUnit had a state different from zero\n if (lastUnit.state) {\n // strip last bytes\n lastUnit.data = lastUnit.data.subarray(\n 0,\n lastUnit.data.byteLength - lastState,\n );\n }\n }\n // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.\n\n if (overflow > 0) {\n // logger.log('first NALU found with overflow:' + overflow);\n lastUnit.data = appendUint8Array(\n lastUnit.data,\n array.subarray(0, overflow),\n );\n lastUnit.state = 0;\n }\n }\n }\n // check if we can read unit type\n if (i < len) {\n unitType = this.getNALuType(array, i);\n // logger.log('find NALU @ offset:' + i + ',type:' + unitType);\n lastUnitStart = i;\n lastUnitType = unitType;\n state = 0;\n } else {\n // not enough byte to read unit type. let's read it on next PES parsing\n state = -1;\n }\n } else {\n state = 0;\n }\n }\n if (lastUnitStart >= 0 && state >= 0) {\n const unit: VideoSampleUnit = {\n data: array.subarray(lastUnitStart, len),\n type: lastUnitType,\n state: state,\n };\n units.push(unit);\n // logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);\n }\n // no NALu found\n if (units.length === 0) {\n // append pes.data to previous NAL unit\n const lastUnit = this.getLastNalUnit(track.samples);\n if (lastUnit) {\n lastUnit.data = appendUint8Array(lastUnit.data, array);\n }\n }\n track.naluState = state;\n return units;\n }\n}\n\nexport default BaseVideoParser;\n","/**\n * Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264.\n */\n\nimport { logger } from '../../utils/logger';\n\nclass ExpGolomb {\n private data: Uint8Array;\n public bytesAvailable: number;\n private word: number;\n private bitsAvailable: number;\n\n constructor(data: Uint8Array) {\n this.data = data;\n // the number of bytes left to examine in this.data\n this.bytesAvailable = data.byteLength;\n // the current word being examined\n this.word = 0; // :uint\n // the number of bits left to examine in the current word\n this.bitsAvailable = 0; // :uint\n }\n\n // ():void\n loadWord(): void {\n const data = this.data;\n const bytesAvailable = this.bytesAvailable;\n const position = data.byteLength - bytesAvailable;\n const workingBytes = new Uint8Array(4);\n const availableBytes = Math.min(4, bytesAvailable);\n if (availableBytes === 0) {\n throw new Error('no bytes available');\n }\n\n workingBytes.set(data.subarray(position, position + availableBytes));\n this.word = new DataView(workingBytes.buffer).getUint32(0);\n // track the amount of this.data that has been processed\n this.bitsAvailable = availableBytes * 8;\n this.bytesAvailable -= availableBytes;\n }\n\n // (count:int):void\n skipBits(count: number): void {\n let skipBytes; // :int\n count = Math.min(count, this.bytesAvailable * 8 + this.bitsAvailable);\n if (this.bitsAvailable > count) {\n this.word <<= count;\n this.bitsAvailable -= count;\n } else {\n count -= this.bitsAvailable;\n skipBytes = count >> 3;\n count -= skipBytes << 3;\n this.bytesAvailable -= skipBytes;\n this.loadWord();\n this.word <<= count;\n this.bitsAvailable -= count;\n }\n }\n\n // (size:int):uint\n readBits(size: number): number {\n let bits = Math.min(this.bitsAvailable, size); // :uint\n const valu = this.word >>> (32 - bits); // :uint\n if (size > 32) {\n logger.error('Cannot read more than 32 bits at a time');\n }\n\n this.bitsAvailable -= bits;\n if (this.bitsAvailable > 0) {\n this.word <<= bits;\n } else if (this.bytesAvailable > 0) {\n this.loadWord();\n } else {\n throw new Error('no bits available');\n }\n\n bits = size - bits;\n if (bits > 0 && this.bitsAvailable) {\n return (valu << bits) | this.readBits(bits);\n } else {\n return valu;\n }\n }\n\n // ():uint\n skipLZ(): number {\n let leadingZeroCount; // :uint\n for (\n leadingZeroCount = 0;\n leadingZeroCount < this.bitsAvailable;\n ++leadingZeroCount\n ) {\n if ((this.word & (0x80000000 >>> leadingZeroCount)) !== 0) {\n // the first bit of working word is 1\n this.word <<= leadingZeroCount;\n this.bitsAvailable -= leadingZeroCount;\n return leadingZeroCount;\n }\n }\n // we exhausted word and still have not found a 1\n this.loadWord();\n return leadingZeroCount + this.skipLZ();\n }\n\n // ():void\n skipUEG(): void {\n this.skipBits(1 + this.skipLZ());\n }\n\n // ():void\n skipEG(): void {\n this.skipBits(1 + this.skipLZ());\n }\n\n // ():uint\n readUEG(): number {\n const clz = this.skipLZ(); // :uint\n return this.readBits(clz + 1) - 1;\n }\n\n // ():int\n readEG(): number {\n const valu = this.readUEG(); // :int\n if (0x01 & valu) {\n // the number is odd if the low order bit is set\n return (1 + valu) >>> 1; // add 1 to make it even, and divide by 2\n } else {\n return -1 * (valu >>> 1); // divide by two then make it negative\n }\n }\n\n // Some convenience functions\n // :Boolean\n readBoolean(): boolean {\n return this.readBits(1) === 1;\n }\n\n // ():int\n readUByte(): number {\n return this.readBits(8);\n }\n\n // ():int\n readUShort(): number {\n return this.readBits(16);\n }\n\n // ():int\n readUInt(): number {\n return this.readBits(32);\n }\n}\n\nexport default ExpGolomb;\n","import BaseVideoParser from './base-video-parser';\nimport ExpGolomb from './exp-golomb';\nimport { parseSEIMessageFromNALu } from '../../utils/mp4-tools';\nimport type {\n DemuxedUserdataTrack,\n DemuxedVideoTrack,\n} from '../../types/demuxer';\nimport type { PES } from '../tsdemuxer';\n\nclass AvcVideoParser extends BaseVideoParser {\n public parsePES(\n track: DemuxedVideoTrack,\n textTrack: DemuxedUserdataTrack,\n pes: PES,\n endOfSegment: boolean,\n ) {\n const units = this.parseNALu(track, pes.data, endOfSegment);\n let VideoSample = this.VideoSample;\n let push: boolean;\n let spsfound = false;\n // free pes.data to save up some memory\n (pes as any).data = null;\n\n // if new NAL units found and last sample still there, let's push ...\n // this helps parsing streams with missing AUD (only do this if AUD never found)\n if (VideoSample && units.length && !track.audFound) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = this.VideoSample = this.createVideoSample(\n false,\n pes.pts,\n pes.dts,\n );\n }\n\n units.forEach((unit) => {\n switch (unit.type) {\n // NDR\n case 1: {\n let iskey = false;\n push = true;\n const data = unit.data;\n // only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)\n if (spsfound && data.length > 4) {\n // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR\n const sliceType = this.readSliceType(data);\n // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice\n // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.\n // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.\n // I slice: A slice that is not an SI slice that is decoded using intra prediction only.\n // if (sliceType === 2 || sliceType === 7) {\n if (\n sliceType === 2 ||\n sliceType === 4 ||\n sliceType === 7 ||\n sliceType === 9\n ) {\n iskey = true;\n }\n }\n\n if (iskey) {\n // if we have non-keyframe data already, that cannot belong to the same frame as a keyframe, so force a push\n if (VideoSample?.frame && !VideoSample.key) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = this.VideoSample = null;\n }\n }\n\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n true,\n pes.pts,\n pes.dts,\n );\n }\n VideoSample.frame = true;\n VideoSample.key = iskey;\n\n break;\n // IDR\n }\n case 5:\n push = true;\n // handle PES not starting with AUD\n // if we have frame data already, that cannot belong to the same frame, so force a push\n if (VideoSample?.frame && !VideoSample.key) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = this.VideoSample = null;\n }\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n true,\n pes.pts,\n pes.dts,\n );\n }\n\n VideoSample.key = true;\n VideoSample.frame = true;\n break;\n // SEI\n case 6: {\n push = true;\n parseSEIMessageFromNALu(\n unit.data,\n 1,\n pes.pts as number,\n textTrack.samples,\n );\n break;\n // SPS\n }\n case 7: {\n push = true;\n spsfound = true;\n const sps = unit.data;\n const config = this.readSPS(sps);\n if (\n !track.sps ||\n track.width !== config.width ||\n track.height !== config.height ||\n track.pixelRatio?.[0] !== config.pixelRatio[0] ||\n track.pixelRatio?.[1] !== config.pixelRatio[1]\n ) {\n track.width = config.width;\n track.height = config.height;\n track.pixelRatio = config.pixelRatio;\n track.sps = [sps];\n const codecarray = sps.subarray(1, 4);\n let codecstring = 'avc1.';\n for (let i = 0; i < 3; i++) {\n let h = codecarray[i].toString(16);\n if (h.length < 2) {\n h = '0' + h;\n }\n\n codecstring += h;\n }\n track.codec = codecstring;\n }\n break;\n }\n // PPS\n case 8:\n push = true;\n\n track.pps = [unit.data];\n\n break;\n // AUD\n case 9:\n push = true;\n track.audFound = true;\n if (VideoSample?.frame) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = null;\n }\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n false,\n pes.pts,\n pes.dts,\n );\n }\n break;\n // Filler Data\n case 12:\n push = true;\n break;\n default:\n push = false;\n\n break;\n }\n if (VideoSample && push) {\n const units = VideoSample.units;\n units.push(unit);\n }\n });\n // if last PES packet, push samples\n if (endOfSegment && VideoSample) {\n this.pushAccessUnit(VideoSample, track);\n this.VideoSample = null;\n }\n }\n\n protected getNALuType(data: Uint8Array, offset: number): number {\n return data[offset] & 0x1f;\n }\n\n readSliceType(data: Uint8Array) {\n const eg = new ExpGolomb(data);\n // skip NALu type\n eg.readUByte();\n // discard first_mb_in_slice\n eg.readUEG();\n // return slice_type\n return eg.readUEG();\n }\n\n /**\n * The scaling list is optionally transmitted as part of a sequence parameter\n * set and is not relevant to transmuxing.\n * @param count the number of entries in this scaling list\n * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1\n */\n skipScalingList(count: number, reader: ExpGolomb): void {\n let lastScale = 8;\n let nextScale = 8;\n let deltaScale;\n for (let j = 0; j < count; j++) {\n if (nextScale !== 0) {\n deltaScale = reader.readEG();\n nextScale = (lastScale + deltaScale + 256) % 256;\n }\n lastScale = nextScale === 0 ? lastScale : nextScale;\n }\n }\n\n /**\n * Read a sequence parameter set and return some interesting video\n * properties. A sequence parameter set is the H264 metadata that\n * describes the properties of upcoming video frames.\n * @returns an object with configuration parsed from the\n * sequence parameter set, including the dimensions of the\n * associated video frames.\n */\n readSPS(sps: Uint8Array): {\n width: number;\n height: number;\n pixelRatio: [number, number];\n } {\n const eg = new ExpGolomb(sps);\n let frameCropLeftOffset = 0;\n let frameCropRightOffset = 0;\n let frameCropTopOffset = 0;\n let frameCropBottomOffset = 0;\n let numRefFramesInPicOrderCntCycle;\n let scalingListCount;\n let i;\n const readUByte = eg.readUByte.bind(eg);\n const readBits = eg.readBits.bind(eg);\n const readUEG = eg.readUEG.bind(eg);\n const readBoolean = eg.readBoolean.bind(eg);\n const skipBits = eg.skipBits.bind(eg);\n const skipEG = eg.skipEG.bind(eg);\n const skipUEG = eg.skipUEG.bind(eg);\n const skipScalingList = this.skipScalingList.bind(this);\n\n readUByte();\n const profileIdc = readUByte(); // profile_idc\n readBits(5); // profileCompat constraint_set[0-4]_flag, u(5)\n skipBits(3); // reserved_zero_3bits u(3),\n readUByte(); // level_idc u(8)\n skipUEG(); // seq_parameter_set_id\n // some profiles have more optional data we don't need\n if (\n profileIdc === 100 ||\n profileIdc === 110 ||\n profileIdc === 122 ||\n profileIdc === 244 ||\n profileIdc === 44 ||\n profileIdc === 83 ||\n profileIdc === 86 ||\n profileIdc === 118 ||\n profileIdc === 128\n ) {\n const chromaFormatIdc = readUEG();\n if (chromaFormatIdc === 3) {\n skipBits(1);\n } // separate_colour_plane_flag\n\n skipUEG(); // bit_depth_luma_minus8\n skipUEG(); // bit_depth_chroma_minus8\n skipBits(1); // qpprime_y_zero_transform_bypass_flag\n if (readBoolean()) {\n // seq_scaling_matrix_present_flag\n scalingListCount = chromaFormatIdc !== 3 ? 8 : 12;\n for (i = 0; i < scalingListCount; i++) {\n if (readBoolean()) {\n // seq_scaling_list_present_flag[ i ]\n if (i < 6) {\n skipScalingList(16, eg);\n } else {\n skipScalingList(64, eg);\n }\n }\n }\n }\n }\n skipUEG(); // log2_max_frame_num_minus4\n const picOrderCntType = readUEG();\n if (picOrderCntType === 0) {\n readUEG(); // log2_max_pic_order_cnt_lsb_minus4\n } else if (picOrderCntType === 1) {\n skipBits(1); // delta_pic_order_always_zero_flag\n skipEG(); // offset_for_non_ref_pic\n skipEG(); // offset_for_top_to_bottom_field\n numRefFramesInPicOrderCntCycle = readUEG();\n for (i = 0; i < numRefFramesInPicOrderCntCycle; i++) {\n skipEG();\n } // offset_for_ref_frame[ i ]\n }\n skipUEG(); // max_num_ref_frames\n skipBits(1); // gaps_in_frame_num_value_allowed_flag\n const picWidthInMbsMinus1 = readUEG();\n const picHeightInMapUnitsMinus1 = readUEG();\n const frameMbsOnlyFlag = readBits(1);\n if (frameMbsOnlyFlag === 0) {\n skipBits(1);\n } // mb_adaptive_frame_field_flag\n\n skipBits(1); // direct_8x8_inference_flag\n if (readBoolean()) {\n // frame_cropping_flag\n frameCropLeftOffset = readUEG();\n frameCropRightOffset = readUEG();\n frameCropTopOffset = readUEG();\n frameCropBottomOffset = readUEG();\n }\n let pixelRatio: [number, number] = [1, 1];\n if (readBoolean()) {\n // vui_parameters_present_flag\n if (readBoolean()) {\n // aspect_ratio_info_present_flag\n const aspectRatioIdc = readUByte();\n switch (aspectRatioIdc) {\n case 1:\n pixelRatio = [1, 1];\n break;\n case 2:\n pixelRatio = [12, 11];\n break;\n case 3:\n pixelRatio = [10, 11];\n break;\n case 4:\n pixelRatio = [16, 11];\n break;\n case 5:\n pixelRatio = [40, 33];\n break;\n case 6:\n pixelRatio = [24, 11];\n break;\n case 7:\n pixelRatio = [20, 11];\n break;\n case 8:\n pixelRatio = [32, 11];\n break;\n case 9:\n pixelRatio = [80, 33];\n break;\n case 10:\n pixelRatio = [18, 11];\n break;\n case 11:\n pixelRatio = [15, 11];\n break;\n case 12:\n pixelRatio = [64, 33];\n break;\n case 13:\n pixelRatio = [160, 99];\n break;\n case 14:\n pixelRatio = [4, 3];\n break;\n case 15:\n pixelRatio = [3, 2];\n break;\n case 16:\n pixelRatio = [2, 1];\n break;\n case 255: {\n pixelRatio = [\n (readUByte() << 8) | readUByte(),\n (readUByte() << 8) | readUByte(),\n ];\n break;\n }\n }\n }\n }\n return {\n width: Math.ceil(\n (picWidthInMbsMinus1 + 1) * 16 -\n frameCropLeftOffset * 2 -\n frameCropRightOffset * 2,\n ),\n height:\n (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 -\n (frameMbsOnlyFlag ? 2 : 4) *\n (frameCropTopOffset + frameCropBottomOffset),\n pixelRatio: pixelRatio,\n };\n }\n}\n\nexport default AvcVideoParser;\n","import BaseVideoParser from './base-video-parser';\nimport ExpGolomb from './exp-golomb';\nimport { parseSEIMessageFromNALu } from '../../utils/mp4-tools';\nimport type {\n DemuxedUserdataTrack,\n DemuxedVideoTrack,\n} from '../../types/demuxer';\nimport type { ParsedVideoSample } from '../tsdemuxer';\nimport type { PES } from '../tsdemuxer';\n\nclass HevcVideoParser extends BaseVideoParser {\n protected initVPS: Uint8Array | null = null;\n\n public parsePES(\n track: DemuxedVideoTrack,\n textTrack: DemuxedUserdataTrack,\n pes: PES,\n endOfSegment: boolean,\n ) {\n const units = this.parseNALu(track, pes.data, endOfSegment);\n let VideoSample = this.VideoSample;\n let push: boolean;\n let spsfound = false;\n // free pes.data to save up some memory\n (pes as any).data = null;\n\n // if new NAL units found and last sample still there, let's push ...\n // this helps parsing streams with missing AUD (only do this if AUD never found)\n if (VideoSample && units.length && !track.audFound) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = this.VideoSample = this.createVideoSample(\n false,\n pes.pts,\n pes.dts,\n );\n }\n\n units.forEach((unit) => {\n switch (unit.type) {\n // NON-IDR, NON RANDOM ACCESS SLICE\n case 0:\n case 1:\n case 2:\n case 3:\n case 4:\n case 5:\n case 6:\n case 7:\n case 8:\n case 9:\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n false,\n pes.pts,\n pes.dts,\n );\n }\n VideoSample.frame = true;\n push = true;\n break;\n\n // CRA, BLA (random access picture)\n case 16:\n case 17:\n case 18:\n case 21:\n push = true;\n if (spsfound) {\n // handle PES not starting with AUD\n // if we have frame data already, that cannot belong to the same frame, so force a push\n if (VideoSample?.frame && !VideoSample.key) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = this.VideoSample = null;\n }\n }\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n true,\n pes.pts,\n pes.dts,\n );\n }\n\n VideoSample.key = true;\n VideoSample.frame = true;\n break;\n\n // IDR\n case 19:\n case 20:\n push = true;\n // handle PES not starting with AUD\n // if we have frame data already, that cannot belong to the same frame, so force a push\n if (VideoSample?.frame && !VideoSample.key) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = this.VideoSample = null;\n }\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n true,\n pes.pts,\n pes.dts,\n );\n }\n\n VideoSample.key = true;\n VideoSample.frame = true;\n break;\n\n // SEI\n case 39:\n push = true;\n parseSEIMessageFromNALu(\n unit.data,\n 2, // NALu header size\n pes.pts as number,\n textTrack.samples,\n );\n break;\n\n // VPS\n case 32:\n push = true;\n if (!track.vps) {\n if (typeof track.params !== 'object') {\n track.params = {};\n }\n track.params = Object.assign(track.params, this.readVPS(unit.data));\n this.initVPS = unit.data;\n }\n track.vps = [unit.data];\n break;\n\n // SPS\n case 33:\n push = true;\n spsfound = true;\n if (\n track.vps !== undefined &&\n track.vps[0] !== this.initVPS &&\n track.sps !== undefined &&\n !this.matchSPS(track.sps[0], unit.data)\n ) {\n this.initVPS = track.vps[0];\n track.sps = track.pps = undefined;\n }\n if (!track.sps) {\n const config = this.readSPS(unit.data);\n track.width = config.width;\n track.height = config.height;\n track.pixelRatio = config.pixelRatio;\n track.codec = config.codecString;\n track.sps = [];\n if (typeof track.params !== 'object') {\n track.params = {};\n }\n for (const prop in config.params) {\n track.params[prop] = config.params[prop];\n }\n }\n this.pushParameterSet(track.sps, unit.data, track.vps);\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n true,\n pes.pts,\n pes.dts,\n );\n }\n VideoSample.key = true;\n break;\n\n // PPS\n case 34:\n push = true;\n if (typeof track.params === 'object') {\n if (!track.pps) {\n track.pps = [];\n const config = this.readPPS(unit.data);\n for (const prop in config) {\n track.params[prop] = config[prop];\n }\n }\n this.pushParameterSet(track.pps, unit.data, track.vps);\n }\n break;\n\n // ACCESS UNIT DELIMITER\n case 35:\n push = true;\n track.audFound = true;\n if (VideoSample?.frame) {\n this.pushAccessUnit(VideoSample, track);\n VideoSample = null;\n }\n if (!VideoSample) {\n VideoSample = this.VideoSample = this.createVideoSample(\n false,\n pes.pts,\n pes.dts,\n );\n }\n break;\n\n default:\n push = false;\n break;\n }\n if (VideoSample && push) {\n const units = VideoSample.units;\n units.push(unit);\n }\n });\n // if last PES packet, push samples\n if (endOfSegment && VideoSample) {\n this.pushAccessUnit(VideoSample, track);\n this.VideoSample = null;\n }\n }\n\n private pushParameterSet(\n parameterSets: Uint8Array[],\n data: Uint8Array,\n vps: Uint8Array[] | undefined,\n ) {\n if ((vps && vps[0] === this.initVPS) || (!vps && !parameterSets.length)) {\n parameterSets.push(data);\n }\n }\n\n protected getNALuType(data: Uint8Array, offset: number): number {\n return (data[offset] & 0x7e) >>> 1;\n }\n\n protected ebsp2rbsp(arr: Uint8Array): Uint8Array {\n const dst = new Uint8Array(arr.byteLength);\n let dstIdx = 0;\n for (let i = 0; i < arr.byteLength; i++) {\n if (i >= 2) {\n // Unescape: Skip 0x03 after 00 00\n if (arr[i] === 0x03 && arr[i - 1] === 0x00 && arr[i - 2] === 0x00) {\n continue;\n }\n }\n dst[dstIdx] = arr[i];\n dstIdx++;\n }\n return new Uint8Array(dst.buffer, 0, dstIdx);\n }\n\n protected pushAccessUnit(\n VideoSample: ParsedVideoSample,\n videoTrack: DemuxedVideoTrack,\n ) {\n super.pushAccessUnit(VideoSample, videoTrack);\n if (this.initVPS) {\n this.initVPS = null; // null initVPS to prevent possible track's sps/pps growth until next VPS\n }\n }\n\n readVPS(vps: Uint8Array): {\n numTemporalLayers: number;\n temporalIdNested: boolean;\n } {\n const eg = new ExpGolomb(vps);\n // remove header\n eg.readUByte();\n eg.readUByte();\n\n eg.readBits(4); // video_parameter_set_id\n eg.skipBits(2);\n eg.readBits(6); // max_layers_minus1\n const max_sub_layers_minus1 = eg.readBits(3);\n const temporal_id_nesting_flag = eg.readBoolean();\n // ...vui fps can be here, but empty fps value is not critical for metadata\n\n return {\n numTemporalLayers: max_sub_layers_minus1 + 1,\n temporalIdNested: temporal_id_nesting_flag,\n };\n }\n\n readSPS(sps: Uint8Array): {\n codecString: string;\n params: object;\n width: number;\n height: number;\n pixelRatio: [number, number];\n } {\n const eg = new ExpGolomb(this.ebsp2rbsp(sps));\n eg.readUByte();\n eg.readUByte();\n\n eg.readBits(4); //video_parameter_set_id\n const max_sub_layers_minus1 = eg.readBits(3);\n eg.readBoolean(); // temporal_id_nesting_flag\n\n // profile_tier_level\n const general_profile_space = eg.readBits(2);\n const general_tier_flag = eg.readBoolean();\n const general_profile_idc = eg.readBits(5);\n const general_profile_compatibility_flags_1 = eg.readUByte();\n const general_profile_compatibility_flags_2 = eg.readUByte();\n const general_profile_compatibility_flags_3 = eg.readUByte();\n const general_profile_compatibility_flags_4 = eg.readUByte();\n const general_constraint_indicator_flags_1 = eg.readUByte();\n const general_constraint_indicator_flags_2 = eg.readUByte();\n const general_constraint_indicator_flags_3 = eg.readUByte();\n const general_constraint_indicator_flags_4 = eg.readUByte();\n const general_constraint_indicator_flags_5 = eg.readUByte();\n const general_constraint_indicator_flags_6 = eg.readUByte();\n const general_level_idc = eg.readUByte();\n const sub_layer_profile_present_flags: boolean[] = [];\n const sub_layer_level_present_flags: boolean[] = [];\n for (let i = 0; i < max_sub_layers_minus1; i++) {\n sub_layer_profile_present_flags.push(eg.readBoolean());\n sub_layer_level_present_flags.push(eg.readBoolean());\n }\n if (max_sub_layers_minus1 > 0) {\n for (let i = max_sub_layers_minus1; i < 8; i++) {\n eg.readBits(2);\n }\n }\n for (let i = 0; i < max_sub_layers_minus1; i++) {\n if (sub_layer_profile_present_flags[i]) {\n eg.readUByte(); // sub_layer_profile_space, sub_layer_tier_flag, sub_layer_profile_idc\n eg.readUByte();\n eg.readUByte();\n eg.readUByte();\n eg.readUByte(); // sub_layer_profile_compatibility_flag\n eg.readUByte();\n eg.readUByte();\n eg.readUByte();\n eg.readUByte();\n eg.readUByte();\n eg.readUByte();\n }\n if (sub_layer_level_present_flags[i]) {\n eg.readUByte();\n }\n }\n\n eg.readUEG(); // seq_parameter_set_id\n const chroma_format_idc = eg.readUEG();\n if (chroma_format_idc == 3) {\n eg.skipBits(1); //separate_colour_plane_flag\n }\n const pic_width_in_luma_samples = eg.readUEG();\n const pic_height_in_luma_samples = eg.readUEG();\n const conformance_window_flag = eg.readBoolean();\n let pic_left_offset = 0,\n pic_right_offset = 0,\n pic_top_offset = 0,\n pic_bottom_offset = 0;\n if (conformance_window_flag) {\n pic_left_offset += eg.readUEG();\n pic_right_offset += eg.readUEG();\n pic_top_offset += eg.readUEG();\n pic_bottom_offset += eg.readUEG();\n }\n const bit_depth_luma_minus8 = eg.readUEG();\n const bit_depth_chroma_minus8 = eg.readUEG();\n const log2_max_pic_order_cnt_lsb_minus4 = eg.readUEG();\n const sub_layer_ordering_info_present_flag = eg.readBoolean();\n for (\n let i = sub_layer_ordering_info_present_flag ? 0 : max_sub_layers_minus1;\n i <= max_sub_layers_minus1;\n i++\n ) {\n eg.skipUEG(); // max_dec_pic_buffering_minus1[i]\n eg.skipUEG(); // max_num_reorder_pics[i]\n eg.skipUEG(); // max_latency_increase_plus1[i]\n }\n eg.skipUEG(); // log2_min_luma_coding_block_size_minus3\n eg.skipUEG(); // log2_diff_max_min_luma_coding_block_size\n eg.skipUEG(); // log2_min_transform_block_size_minus2\n eg.skipUEG(); // log2_diff_max_min_transform_block_size\n eg.skipUEG(); // max_transform_hierarchy_depth_inter\n eg.skipUEG(); // max_transform_hierarchy_depth_intra\n const scaling_list_enabled_flag = eg.readBoolean();\n if (scaling_list_enabled_flag) {\n const sps_scaling_list_data_present_flag = eg.readBoolean();\n if (sps_scaling_list_data_present_flag) {\n for (let sizeId = 0; sizeId < 4; sizeId++) {\n for (\n let matrixId = 0;\n matrixId < (sizeId === 3 ? 2 : 6);\n matrixId++\n ) {\n const scaling_list_pred_mode_flag = eg.readBoolean();\n if (!scaling_list_pred_mode_flag) {\n eg.readUEG(); // scaling_list_pred_matrix_id_delta\n } else {\n const coefNum = Math.min(64, 1 << (4 + (sizeId << 1)));\n if (sizeId > 1) {\n eg.readEG();\n }\n for (let i = 0; i < coefNum; i++) {\n eg.readEG();\n }\n }\n }\n }\n }\n }\n\n eg.readBoolean(); // amp_enabled_flag\n eg.readBoolean(); // sample_adaptive_offset_enabled_flag\n const pcm_enabled_flag = eg.readBoolean();\n if (pcm_enabled_flag) {\n eg.readUByte();\n eg.skipUEG();\n eg.skipUEG();\n eg.readBoolean();\n }\n const num_short_term_ref_pic_sets = eg.readUEG();\n let num_delta_pocs = 0;\n for (let i = 0; i < num_short_term_ref_pic_sets; i++) {\n let inter_ref_pic_set_prediction_flag = false;\n if (i !== 0) {\n inter_ref_pic_set_prediction_flag = eg.readBoolean();\n }\n if (inter_ref_pic_set_prediction_flag) {\n if (i === num_short_term_ref_pic_sets) {\n eg.readUEG();\n }\n eg.readBoolean();\n eg.readUEG();\n let next_num_delta_pocs = 0;\n for (let j = 0; j <= num_delta_pocs; j++) {\n const used_by_curr_pic_flag = eg.readBoolean();\n let use_delta_flag = false;\n if (!used_by_curr_pic_flag) {\n use_delta_flag = eg.readBoolean();\n }\n if (used_by_curr_pic_flag || use_delta_flag) {\n next_num_delta_pocs++;\n }\n }\n num_delta_pocs = next_num_delta_pocs;\n } else {\n const num_negative_pics = eg.readUEG();\n const num_positive_pics = eg.readUEG();\n num_delta_pocs = num_negative_pics + num_positive_pics;\n for (let j = 0; j < num_negative_pics; j++) {\n eg.readUEG();\n eg.readBoolean();\n }\n for (let j = 0; j < num_positive_pics; j++) {\n eg.readUEG();\n eg.readBoolean();\n }\n }\n }\n\n const long_term_ref_pics_present_flag = eg.readBoolean();\n if (long_term_ref_pics_present_flag) {\n const num_long_term_ref_pics_sps = eg.readUEG();\n for (let i = 0; i < num_long_term_ref_pics_sps; i++) {\n for (let j = 0; j < log2_max_pic_order_cnt_lsb_minus4 + 4; j++) {\n eg.readBits(1);\n }\n eg.readBits(1);\n }\n }\n\n let min_spatial_segmentation_idc = 0;\n let sar_width = 1,\n sar_height = 1;\n let fps_fixed = true,\n fps_den = 1,\n fps_num = 0;\n eg.readBoolean(); // sps_temporal_mvp_enabled_flag\n eg.readBoolean(); // strong_intra_smoothing_enabled_flag\n let default_display_window_flag = false;\n const vui_parameters_present_flag = eg.readBoolean();\n if (vui_parameters_present_flag) {\n const aspect_ratio_info_present_flag = eg.readBoolean();\n if (aspect_ratio_info_present_flag) {\n const aspect_ratio_idc = eg.readUByte();\n const sar_width_table = [\n 1, 12, 10, 16, 40, 24, 20, 32, 80, 18, 15, 64, 160, 4, 3, 2,\n ];\n const sar_height_table = [\n 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1,\n ];\n if (aspect_ratio_idc > 0 && aspect_ratio_idc < 16) {\n sar_width = sar_width_table[aspect_ratio_idc - 1];\n sar_height = sar_height_table[aspect_ratio_idc - 1];\n } else if (aspect_ratio_idc === 255) {\n sar_width = eg.readBits(16);\n sar_height = eg.readBits(16);\n }\n }\n const overscan_info_present_flag = eg.readBoolean();\n if (overscan_info_present_flag) {\n eg.readBoolean();\n }\n const video_signal_type_present_flag = eg.readBoolean();\n if (video_signal_type_present_flag) {\n eg.readBits(3);\n eg.readBoolean();\n const colour_description_present_flag = eg.readBoolean();\n if (colour_description_present_flag) {\n eg.readUByte();\n eg.readUByte();\n eg.readUByte();\n }\n }\n const chroma_loc_info_present_flag = eg.readBoolean();\n if (chroma_loc_info_present_flag) {\n eg.readUEG();\n eg.readUEG();\n }\n eg.readBoolean(); // neutral_chroma_indication_flag\n eg.readBoolean(); // field_seq_flag\n eg.readBoolean(); // frame_field_info_present_flag\n default_display_window_flag = eg.readBoolean();\n if (default_display_window_flag) {\n pic_left_offset += eg.readUEG();\n pic_right_offset += eg.readUEG();\n pic_top_offset += eg.readUEG();\n pic_bottom_offset += eg.readUEG();\n }\n const vui_timing_info_present_flag = eg.readBoolean();\n if (vui_timing_info_present_flag) {\n fps_den = eg.readBits(32);\n fps_num = eg.readBits(32);\n const vui_poc_proportional_to_timing_flag = eg.readBoolean();\n if (vui_poc_proportional_to_timing_flag) {\n eg.readUEG();\n }\n const vui_hrd_parameters_present_flag = eg.readBoolean();\n if (vui_hrd_parameters_present_flag) {\n //const commonInfPresentFlag = true;\n //if (commonInfPresentFlag) {\n const nal_hrd_parameters_present_flag = eg.readBoolean();\n const vcl_hrd_parameters_present_flag = eg.readBoolean();\n let sub_pic_hrd_params_present_flag = false;\n if (\n nal_hrd_parameters_present_flag ||\n vcl_hrd_parameters_present_flag\n ) {\n sub_pic_hrd_params_present_flag = eg.readBoolean();\n if (sub_pic_hrd_params_present_flag) {\n eg.readUByte();\n eg.readBits(5);\n eg.readBoolean();\n eg.readBits(5);\n }\n eg.readBits(4); // bit_rate_scale\n eg.readBits(4); // cpb_size_scale\n if (sub_pic_hrd_params_present_flag) {\n eg.readBits(4);\n }\n eg.readBits(5);\n eg.readBits(5);\n eg.readBits(5);\n }\n //}\n for (let i = 0; i <= max_sub_layers_minus1; i++) {\n fps_fixed = eg.readBoolean(); // fixed_pic_rate_general_flag\n const fixed_pic_rate_within_cvs_flag =\n fps_fixed || eg.readBoolean();\n let low_delay_hrd_flag = false;\n if (fixed_pic_rate_within_cvs_flag) {\n eg.readEG();\n } else {\n low_delay_hrd_flag = eg.readBoolean();\n }\n const cpb_cnt = low_delay_hrd_flag ? 1 : eg.readUEG() + 1;\n if (nal_hrd_parameters_present_flag) {\n for (let j = 0; j < cpb_cnt; j++) {\n eg.readUEG();\n eg.readUEG();\n if (sub_pic_hrd_params_present_flag) {\n eg.readUEG();\n eg.readUEG();\n }\n eg.skipBits(1);\n }\n }\n if (vcl_hrd_parameters_present_flag) {\n for (let j = 0; j < cpb_cnt; j++) {\n eg.readUEG();\n eg.readUEG();\n if (sub_pic_hrd_params_present_flag) {\n eg.readUEG();\n eg.readUEG();\n }\n eg.skipBits(1);\n }\n }\n }\n }\n }\n const bitstream_restriction_flag = eg.readBoolean();\n if (bitstream_restriction_flag) {\n eg.readBoolean(); // tiles_fixed_structure_flag\n eg.readBoolean(); // motion_vectors_over_pic_boundaries_flag\n eg.readBoolean(); // restricted_ref_pic_lists_flag\n min_spatial_segmentation_idc = eg.readUEG();\n }\n }\n\n let width = pic_width_in_luma_samples,\n height = pic_height_in_luma_samples;\n if (conformance_window_flag || default_display_window_flag) {\n let chroma_scale_w = 1,\n chroma_scale_h = 1;\n if (chroma_format_idc === 1) {\n // YUV 420\n chroma_scale_w = chroma_scale_h = 2;\n } else if (chroma_format_idc == 2) {\n // YUV 422\n chroma_scale_w = 2;\n }\n width =\n pic_width_in_luma_samples -\n chroma_scale_w * pic_right_offset -\n chroma_scale_w * pic_left_offset;\n height =\n pic_height_in_luma_samples -\n chroma_scale_h * pic_bottom_offset -\n chroma_scale_h * pic_top_offset;\n }\n\n const profile_space_string = general_profile_space\n ? ['A', 'B', 'C'][general_profile_space]\n : '';\n const profile_compatibility_buf =\n (general_profile_compatibility_flags_1 << 24) |\n (general_profile_compatibility_flags_2 << 16) |\n (general_profile_compatibility_flags_3 << 8) |\n general_profile_compatibility_flags_4;\n let profile_compatibility_rev = 0;\n for (let i = 0; i < 32; i++) {\n profile_compatibility_rev =\n (profile_compatibility_rev |\n (((profile_compatibility_buf >> i) & 1) << (31 - i))) >>>\n 0; // reverse bit position (and cast as UInt32)\n }\n let profile_compatibility_flags_string =\n profile_compatibility_rev.toString(16);\n if (\n general_profile_idc === 1 &&\n profile_compatibility_flags_string === '2'\n ) {\n profile_compatibility_flags_string = '6';\n }\n const tier_flag_string = general_tier_flag ? 'H' : 'L';\n\n return {\n codecString: `hvc1.${profile_space_string}${general_profile_idc}.${profile_compatibility_flags_string}.${tier_flag_string}${general_level_idc}.B0`,\n params: {\n general_tier_flag,\n general_profile_idc,\n general_profile_space,\n general_profile_compatibility_flags: [\n general_profile_compatibility_flags_1,\n general_profile_compatibility_flags_2,\n general_profile_compatibility_flags_3,\n general_profile_compatibility_flags_4,\n ],\n general_constraint_indicator_flags: [\n general_constraint_indicator_flags_1,\n general_constraint_indicator_flags_2,\n general_constraint_indicator_flags_3,\n general_constraint_indicator_flags_4,\n general_constraint_indicator_flags_5,\n general_constraint_indicator_flags_6,\n ],\n general_level_idc,\n bit_depth: bit_depth_luma_minus8 + 8,\n bit_depth_luma_minus8,\n bit_depth_chroma_minus8,\n min_spatial_segmentation_idc,\n chroma_format_idc: chroma_format_idc,\n frame_rate: {\n fixed: fps_fixed,\n fps: fps_num / fps_den,\n },\n },\n width,\n height,\n pixelRatio: [sar_width, sar_height],\n };\n }\n\n readPPS(pps: Uint8Array): {\n parallelismType: number;\n } {\n const eg = new ExpGolomb(this.ebsp2rbsp(pps));\n eg.readUByte();\n eg.readUByte();\n eg.skipUEG(); // pic_parameter_set_id\n eg.skipUEG(); // seq_parameter_set_id\n eg.skipBits(2); // dependent_slice_segments_enabled_flag, output_flag_present_flag\n eg.skipBits(3); // num_extra_slice_header_bits\n eg.skipBits(2); // sign_data_hiding_enabled_flag, cabac_init_present_flag\n eg.skipUEG();\n eg.skipUEG();\n eg.skipEG(); // init_qp_minus26\n eg.skipBits(2); // constrained_intra_pred_flag, transform_skip_enabled_flag\n const cu_qp_delta_enabled_flag = eg.readBoolean();\n if (cu_qp_delta_enabled_flag) {\n eg.skipUEG();\n }\n eg.skipEG(); // cb_qp_offset\n eg.skipEG(); // cr_qp_offset\n eg.skipBits(4); // pps_slice_chroma_qp_offsets_present_flag, weighted_pred_flag, weighted_bipred_flag, transquant_bypass_enabled_flag\n const tiles_enabled_flag = eg.readBoolean();\n const entropy_coding_sync_enabled_flag = eg.readBoolean();\n let parallelismType = 1; // slice-based parallel decoding\n if (entropy_coding_sync_enabled_flag && tiles_enabled_flag) {\n parallelismType = 0; // mixed-type parallel decoding\n } else if (entropy_coding_sync_enabled_flag) {\n parallelismType = 3; // wavefront-based parallel decoding\n } else if (tiles_enabled_flag) {\n parallelismType = 2; // tile-based parallel decoding\n }\n\n return {\n parallelismType,\n };\n }\n\n matchSPS(sps1: Uint8Array, sps2: Uint8Array): boolean {\n // compare without headers and VPS related params\n return (\n String.fromCharCode.apply(null, sps1).substr(3) ===\n String.fromCharCode.apply(null, sps2).substr(3)\n );\n }\n}\n\nexport default HevcVideoParser;\n","/**\n * highly optimized TS demuxer:\n * parse PAT, PMT\n * extract PES packet from audio and video PIDs\n * extract AVC/H264 (or HEVC/H265) NAL units and AAC/ADTS samples from PES packet\n * trigger the remuxer upon parsing completion\n * it also tries to workaround as best as it can audio codec switch (HE-AAC to AAC and vice versa), without having to restart the MediaSource.\n * it also controls the remuxing process :\n * upon discontinuity or level switch detection, it will also notifies the remuxer so that it can reset its state.\n */\n\nimport * as AC3 from './audio/ac3-demuxer';\nimport * as ADTS from './audio/adts';\nimport * as MpegAudio from './audio/mpegaudio';\nimport SampleAesDecrypter from './sample-aes';\nimport AvcVideoParser from './video/avc-video-parser';\nimport HevcVideoParser from './video/hevc-video-parser';\nimport { ErrorDetails, ErrorTypes } from '../errors';\nimport { Events } from '../events';\nimport {\n type DemuxedAudioTrack,\n type DemuxedMetadataTrack,\n type DemuxedTrack,\n type DemuxedUserdataTrack,\n type DemuxedVideoTrack,\n type Demuxer,\n type DemuxerResult,\n type ElementaryStreamData,\n type KeyData,\n MetadataSchema,\n type VideoSample,\n} from '../types/demuxer';\nimport { appendUint8Array, RemuxerTrackIdConfig } from '../utils/mp4-tools';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport type BaseVideoParser from './video/base-video-parser';\nimport type { AudioFrame } from '../types/demuxer';\nimport type { TypeSupported } from '../utils/codecs';\nimport type { ILogger } from '../utils/logger';\n\nexport type ParsedTimestamp = {\n pts?: number;\n dts?: number;\n};\n\nexport type PES = ParsedTimestamp & {\n data: Uint8Array;\n len: number;\n};\n\nexport type ParsedVideoSample = ParsedTimestamp &\n Omit<VideoSample, 'pts' | 'dts'>;\n\nconst PACKET_LENGTH = 188;\n\nclass TSDemuxer implements Demuxer {\n private readonly logger: ILogger;\n private readonly observer: HlsEventEmitter;\n private readonly config: HlsConfig;\n private readonly typeSupported: TypeSupported;\n\n private sampleAes: SampleAesDecrypter | null = null;\n private pmtParsed: boolean = false;\n private audioCodec?: string;\n private videoCodec?: string;\n private _pmtId: number = -1;\n\n private _videoTrack?: DemuxedVideoTrack;\n private _audioTrack?: DemuxedAudioTrack;\n private _id3Track?: DemuxedMetadataTrack;\n private _txtTrack?: DemuxedUserdataTrack;\n private aacOverFlow: AudioFrame | null = null;\n private remainderData: Uint8Array | null = null;\n private videoParser: BaseVideoParser | null;\n\n constructor(\n observer: HlsEventEmitter,\n config: HlsConfig,\n typeSupported: TypeSupported,\n logger: ILogger,\n ) {\n this.observer = observer;\n this.config = config;\n this.typeSupported = typeSupported;\n this.logger = logger;\n this.videoParser = null;\n }\n\n static probe(data: Uint8Array, logger: ILogger) {\n const syncOffset = TSDemuxer.syncOffset(data);\n if (syncOffset > 0) {\n logger.warn(\n `MPEG2-TS detected but first sync word found @ offset ${syncOffset}`,\n );\n }\n return syncOffset !== -1;\n }\n\n static syncOffset(data: Uint8Array): number {\n const length = data.length;\n let scanwindow = Math.min(PACKET_LENGTH * 5, length - PACKET_LENGTH) + 1;\n let i = 0;\n while (i < scanwindow) {\n // a TS init segment should contain at least 2 TS packets: PAT and PMT, each starting with 0x47\n let foundPat = false;\n let packetStart = -1;\n let tsPackets = 0;\n for (let j = i; j < length; j += PACKET_LENGTH) {\n if (\n data[j] === 0x47 &&\n (length - j === PACKET_LENGTH || data[j + PACKET_LENGTH] === 0x47)\n ) {\n tsPackets++;\n if (packetStart === -1) {\n packetStart = j;\n // First sync word found at offset, increase scan length (#5251)\n if (packetStart !== 0) {\n scanwindow =\n Math.min(\n packetStart + PACKET_LENGTH * 99,\n data.length - PACKET_LENGTH,\n ) + 1;\n }\n }\n if (!foundPat) {\n foundPat = parsePID(data, j) === 0;\n }\n // Sync word found at 0 with 3 packets, or found at offset least 2 packets up to scanwindow (#5501)\n if (\n foundPat &&\n tsPackets > 1 &&\n ((packetStart === 0 && tsPackets > 2) ||\n j + PACKET_LENGTH > scanwindow)\n ) {\n return packetStart;\n }\n } else if (tsPackets) {\n // Exit if sync word found, but does not contain contiguous packets\n return -1;\n } else {\n break;\n }\n }\n i++;\n }\n return -1;\n }\n\n /**\n * Creates a track model internal to demuxer used to drive remuxing input\n */\n static createTrack(\n type: 'audio' | 'video' | 'id3' | 'text',\n duration?: number,\n ): DemuxedTrack {\n return {\n container:\n type === 'video' || type === 'audio' ? 'video/mp2t' : undefined,\n type,\n id: RemuxerTrackIdConfig[type],\n pid: -1,\n inputTimeScale: 90000,\n sequenceNumber: 0,\n samples: [],\n dropped: 0,\n duration: type === 'audio' ? duration : undefined,\n };\n }\n\n /**\n * Initializes a new init segment on the demuxer/remuxer interface. Needed for discontinuities/track-switches (or at stream start)\n * Resets all internal track instances of the demuxer.\n */\n public resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string,\n videoCodec: string,\n trackDuration: number,\n ) {\n this.pmtParsed = false;\n this._pmtId = -1;\n\n this._videoTrack = TSDemuxer.createTrack('video') as DemuxedVideoTrack;\n this._videoTrack.duration = trackDuration;\n this._audioTrack = TSDemuxer.createTrack(\n 'audio',\n trackDuration,\n ) as DemuxedAudioTrack;\n this._id3Track = TSDemuxer.createTrack('id3') as DemuxedMetadataTrack;\n this._txtTrack = TSDemuxer.createTrack('text') as DemuxedUserdataTrack;\n this._audioTrack.segmentCodec = 'aac';\n\n // flush any partial content\n this.aacOverFlow = null;\n this.remainderData = null;\n this.audioCodec = audioCodec;\n this.videoCodec = videoCodec;\n }\n\n public resetTimeStamp() {}\n\n public resetContiguity(): void {\n const { _audioTrack, _videoTrack, _id3Track } = this;\n if (_audioTrack) {\n _audioTrack.pesData = null;\n }\n if (_videoTrack) {\n _videoTrack.pesData = null;\n }\n if (_id3Track) {\n _id3Track.pesData = null;\n }\n this.aacOverFlow = null;\n this.remainderData = null;\n }\n\n public demux(\n data: Uint8Array,\n timeOffset: number,\n isSampleAes = false,\n flush = false,\n ): DemuxerResult {\n if (!isSampleAes) {\n this.sampleAes = null;\n }\n\n let pes: PES | null;\n\n const videoTrack = this._videoTrack as DemuxedVideoTrack;\n const audioTrack = this._audioTrack as DemuxedAudioTrack;\n const id3Track = this._id3Track as DemuxedMetadataTrack;\n const textTrack = this._txtTrack as DemuxedUserdataTrack;\n\n let videoPid = videoTrack.pid;\n let videoData = videoTrack.pesData;\n let audioPid = audioTrack.pid;\n let id3Pid = id3Track.pid;\n let audioData = audioTrack.pesData;\n let id3Data = id3Track.pesData;\n let unknownPID: number | null = null;\n let pmtParsed = this.pmtParsed;\n let pmtId = this._pmtId;\n\n let len = data.length;\n if (this.remainderData) {\n data = appendUint8Array(this.remainderData, data);\n len = data.length;\n this.remainderData = null;\n }\n\n if (len < PACKET_LENGTH && !flush) {\n this.remainderData = data;\n return {\n audioTrack,\n videoTrack,\n id3Track,\n textTrack,\n };\n }\n\n const syncOffset = Math.max(0, TSDemuxer.syncOffset(data));\n len -= (len - syncOffset) % PACKET_LENGTH;\n if (len < data.byteLength && !flush) {\n this.remainderData = new Uint8Array(\n data.buffer,\n len,\n data.buffer.byteLength - len,\n );\n }\n\n // loop through TS packets\n let tsPacketErrors = 0;\n for (let start = syncOffset; start < len; start += PACKET_LENGTH) {\n if (data[start] === 0x47) {\n const stt = !!(data[start + 1] & 0x40);\n const pid = parsePID(data, start);\n const atf = (data[start + 3] & 0x30) >> 4;\n\n // if an adaption field is present, its length is specified by the fifth byte of the TS packet header.\n let offset: number;\n if (atf > 1) {\n offset = start + 5 + data[start + 4];\n // continue if there is only adaptation field\n if (offset === start + PACKET_LENGTH) {\n continue;\n }\n } else {\n offset = start + 4;\n }\n switch (pid) {\n case videoPid:\n if (stt) {\n if (videoData && (pes = parsePES(videoData, this.logger))) {\n if (this.videoParser === null) {\n switch (videoTrack.segmentCodec) {\n case 'avc':\n this.videoParser = new AvcVideoParser();\n break;\n case 'hevc':\n if (__USE_M2TS_ADVANCED_CODECS__) {\n this.videoParser = new HevcVideoParser();\n }\n break;\n }\n }\n if (this.videoParser !== null) {\n this.videoParser.parsePES(videoTrack, textTrack, pes, false);\n }\n }\n\n videoData = { data: [], size: 0 };\n }\n if (videoData) {\n videoData.data.push(data.subarray(offset, start + PACKET_LENGTH));\n videoData.size += start + PACKET_LENGTH - offset;\n }\n break;\n case audioPid:\n if (stt) {\n if (audioData && (pes = parsePES(audioData, this.logger))) {\n switch (audioTrack.segmentCodec) {\n case 'aac':\n this.parseAACPES(audioTrack, pes);\n break;\n case 'mp3':\n this.parseMPEGPES(audioTrack, pes);\n break;\n case 'ac3':\n if (__USE_M2TS_ADVANCED_CODECS__) {\n this.parseAC3PES(audioTrack, pes);\n }\n break;\n }\n }\n audioData = { data: [], size: 0 };\n }\n if (audioData) {\n audioData.data.push(data.subarray(offset, start + PACKET_LENGTH));\n audioData.size += start + PACKET_LENGTH - offset;\n }\n break;\n case id3Pid:\n if (stt) {\n if (id3Data && (pes = parsePES(id3Data, this.logger))) {\n this.parseID3PES(id3Track, pes);\n }\n\n id3Data = { data: [], size: 0 };\n }\n if (id3Data) {\n id3Data.data.push(data.subarray(offset, start + PACKET_LENGTH));\n id3Data.size += start + PACKET_LENGTH - offset;\n }\n break;\n case 0:\n if (stt) {\n offset += data[offset] + 1;\n }\n\n pmtId = this._pmtId = parsePAT(data, offset);\n // this.logger.log('PMT PID:' + this._pmtId);\n break;\n case pmtId: {\n if (stt) {\n offset += data[offset] + 1;\n }\n\n const parsedPIDs = parsePMT(\n data,\n offset,\n this.typeSupported,\n isSampleAes,\n this.observer,\n this.logger,\n );\n\n // only update track id if track PID found while parsing PMT\n // this is to avoid resetting the PID to -1 in case\n // track PID transiently disappears from the stream\n // this could happen in case of transient missing audio samples for example\n // NOTE this is only the PID of the track as found in TS,\n // but we are not using this for MP4 track IDs.\n videoPid = parsedPIDs.videoPid;\n if (videoPid > 0) {\n videoTrack.pid = videoPid;\n videoTrack.segmentCodec = parsedPIDs.segmentVideoCodec;\n }\n\n audioPid = parsedPIDs.audioPid;\n if (audioPid > 0) {\n audioTrack.pid = audioPid;\n audioTrack.segmentCodec = parsedPIDs.segmentAudioCodec;\n }\n id3Pid = parsedPIDs.id3Pid;\n if (id3Pid > 0) {\n id3Track.pid = id3Pid;\n }\n\n if (unknownPID !== null && !pmtParsed) {\n this.logger.warn(\n `MPEG-TS PMT found at ${start} after unknown PID '${unknownPID}'. Backtracking to sync byte @${syncOffset} to parse all TS packets.`,\n );\n unknownPID = null;\n // we set it to -188, the += 188 in the for loop will reset start to 0\n start = syncOffset - 188;\n }\n pmtParsed = this.pmtParsed = true;\n break;\n }\n case 0x11:\n case 0x1fff:\n break;\n default:\n unknownPID = pid;\n break;\n }\n } else {\n tsPacketErrors++;\n }\n }\n\n if (tsPacketErrors > 0) {\n emitParsingError(\n this.observer,\n new Error(\n `Found ${tsPacketErrors} TS packet/s that do not start with 0x47`,\n ),\n undefined,\n this.logger,\n );\n }\n\n videoTrack.pesData = videoData;\n audioTrack.pesData = audioData;\n id3Track.pesData = id3Data;\n\n const demuxResult: DemuxerResult = {\n audioTrack,\n videoTrack,\n id3Track,\n textTrack,\n };\n\n if (flush) {\n this.extractRemainingSamples(demuxResult);\n }\n\n return demuxResult;\n }\n\n public flush(): DemuxerResult | Promise<DemuxerResult> {\n const { remainderData } = this;\n this.remainderData = null;\n let result: DemuxerResult;\n if (remainderData) {\n result = this.demux(remainderData, -1, false, true);\n } else {\n result = {\n videoTrack: this._videoTrack as DemuxedVideoTrack,\n audioTrack: this._audioTrack as DemuxedAudioTrack,\n id3Track: this._id3Track as DemuxedMetadataTrack,\n textTrack: this._txtTrack as DemuxedUserdataTrack,\n };\n }\n this.extractRemainingSamples(result);\n if (this.sampleAes) {\n return this.decrypt(result, this.sampleAes);\n }\n return result;\n }\n\n private extractRemainingSamples(demuxResult: DemuxerResult) {\n const { audioTrack, videoTrack, id3Track, textTrack } = demuxResult;\n const videoData = videoTrack.pesData;\n const audioData = audioTrack.pesData;\n const id3Data = id3Track.pesData;\n // try to parse last PES packets\n let pes: PES | null;\n if (videoData && (pes = parsePES(videoData, this.logger))) {\n if (this.videoParser === null) {\n switch (videoTrack.segmentCodec) {\n case 'avc':\n this.videoParser = new AvcVideoParser();\n break;\n case 'hevc':\n if (__USE_M2TS_ADVANCED_CODECS__) {\n this.videoParser = new HevcVideoParser();\n }\n break;\n }\n }\n if (this.videoParser !== null) {\n this.videoParser.parsePES(\n videoTrack as DemuxedVideoTrack,\n textTrack as DemuxedUserdataTrack,\n pes,\n true,\n );\n videoTrack.pesData = null;\n }\n } else {\n // either avcData null or PES truncated, keep it for next frag parsing\n videoTrack.pesData = videoData;\n }\n\n if (audioData && (pes = parsePES(audioData, this.logger))) {\n switch (audioTrack.segmentCodec) {\n case 'aac':\n this.parseAACPES(audioTrack, pes);\n break;\n case 'mp3':\n this.parseMPEGPES(audioTrack, pes);\n break;\n case 'ac3':\n if (__USE_M2TS_ADVANCED_CODECS__) {\n this.parseAC3PES(audioTrack, pes);\n }\n break;\n }\n audioTrack.pesData = null;\n } else {\n if (audioData?.size) {\n this.logger.log(\n 'last AAC PES packet truncated,might overlap between fragments',\n );\n }\n\n // either audioData null or PES truncated, keep it for next frag parsing\n audioTrack.pesData = audioData;\n }\n\n if (id3Data && (pes = parsePES(id3Data, this.logger))) {\n this.parseID3PES(id3Track, pes);\n id3Track.pesData = null;\n } else {\n // either id3Data null or PES truncated, keep it for next frag parsing\n id3Track.pesData = id3Data;\n }\n }\n\n public demuxSampleAes(\n data: Uint8Array,\n keyData: KeyData,\n timeOffset: number,\n ): Promise<DemuxerResult> {\n const demuxResult = this.demux(\n data,\n timeOffset,\n true,\n !this.config.progressive,\n );\n const sampleAes = (this.sampleAes = new SampleAesDecrypter(\n this.observer,\n this.config,\n keyData,\n ));\n return this.decrypt(demuxResult, sampleAes);\n }\n\n private decrypt(\n demuxResult: DemuxerResult,\n sampleAes: SampleAesDecrypter,\n ): Promise<DemuxerResult> {\n return new Promise((resolve) => {\n const { audioTrack, videoTrack } = demuxResult;\n if (audioTrack.samples && audioTrack.segmentCodec === 'aac') {\n sampleAes.decryptAacSamples(audioTrack.samples, 0, () => {\n if (videoTrack.samples) {\n sampleAes.decryptAvcSamples(videoTrack.samples, 0, 0, () => {\n resolve(demuxResult);\n });\n } else {\n resolve(demuxResult);\n }\n });\n } else if (videoTrack.samples) {\n sampleAes.decryptAvcSamples(videoTrack.samples, 0, 0, () => {\n resolve(demuxResult);\n });\n }\n });\n }\n\n public destroy() {\n if (this.observer) {\n this.observer.removeAllListeners();\n }\n // @ts-ignore\n this.config = this.logger = this.observer = null;\n this.aacOverFlow =\n this.videoParser =\n this.remainderData =\n this.sampleAes =\n null;\n this._videoTrack =\n this._audioTrack =\n this._id3Track =\n this._txtTrack =\n undefined;\n }\n\n private parseAACPES(track: DemuxedAudioTrack, pes: PES) {\n let startOffset = 0;\n const aacOverFlow = this.aacOverFlow;\n let data = pes.data;\n if (aacOverFlow) {\n this.aacOverFlow = null;\n const frameMissingBytes = aacOverFlow.missing;\n const sampleLength = aacOverFlow.sample.unit.byteLength;\n // logger.log(`AAC: append overflowing ${sampleLength} bytes to beginning of new PES`);\n if (frameMissingBytes === -1) {\n data = appendUint8Array(aacOverFlow.sample.unit, data);\n } else {\n const frameOverflowBytes = sampleLength - frameMissingBytes;\n aacOverFlow.sample.unit.set(\n data.subarray(0, frameMissingBytes),\n frameOverflowBytes,\n );\n track.samples.push(aacOverFlow.sample);\n startOffset = aacOverFlow.missing;\n }\n }\n // look for ADTS header (0xFFFx)\n let offset: number;\n let len: number;\n for (offset = startOffset, len = data.length; offset < len - 1; offset++) {\n if (ADTS.isHeader(data, offset)) {\n break;\n }\n }\n // if ADTS header does not start straight from the beginning of the PES payload, raise an error\n if (offset !== startOffset) {\n let reason: string;\n const recoverable = offset < len - 1;\n if (recoverable) {\n reason = `AAC PES did not start with ADTS header,offset:${offset}`;\n } else {\n reason = 'No ADTS header found in AAC PES';\n }\n emitParsingError(\n this.observer,\n new Error(reason),\n recoverable,\n this.logger,\n );\n if (!recoverable) {\n return;\n }\n }\n\n ADTS.initTrackConfig(track, this.observer, data, offset, this.audioCodec);\n\n let pts: number;\n if (pes.pts !== undefined) {\n pts = pes.pts;\n } else if (aacOverFlow) {\n // if last AAC frame is overflowing, we should ensure timestamps are contiguous:\n // first sample PTS should be equal to last sample PTS + frameDuration\n const frameDuration = ADTS.getFrameDuration(track.samplerate as number);\n pts = aacOverFlow.sample.pts + frameDuration;\n } else {\n this.logger.warn('[tsdemuxer]: AAC PES unknown PTS');\n return;\n }\n\n // scan for aac samples\n let frameIndex = 0;\n let frame;\n while (offset < len) {\n frame = ADTS.appendFrame(track, data, offset, pts, frameIndex);\n offset += frame.length;\n if (!frame.missing) {\n frameIndex++;\n for (; offset < len - 1; offset++) {\n if (ADTS.isHeader(data, offset)) {\n break;\n }\n }\n } else {\n this.aacOverFlow = frame;\n break;\n }\n }\n }\n\n private parseMPEGPES(track: DemuxedAudioTrack, pes: PES) {\n const data = pes.data;\n const length = data.length;\n let frameIndex = 0;\n let offset = 0;\n const pts = pes.pts;\n if (pts === undefined) {\n this.logger.warn('[tsdemuxer]: MPEG PES unknown PTS');\n return;\n }\n\n while (offset < length) {\n if (MpegAudio.isHeader(data, offset)) {\n const frame = MpegAudio.appendFrame(\n track,\n data,\n offset,\n pts,\n frameIndex,\n );\n if (frame) {\n offset += frame.length;\n frameIndex++;\n } else {\n // logger.log('Unable to parse Mpeg audio frame');\n break;\n }\n } else {\n // nothing found, keep looking\n offset++;\n }\n }\n }\n\n private parseAC3PES(track: DemuxedAudioTrack, pes: PES) {\n if (__USE_M2TS_ADVANCED_CODECS__) {\n const data = pes.data;\n const pts = pes.pts;\n if (pts === undefined) {\n this.logger.warn('[tsdemuxer]: AC3 PES unknown PTS');\n return;\n }\n const length = data.length;\n let frameIndex = 0;\n let offset = 0;\n let parsed;\n\n while (\n offset < length &&\n (parsed = AC3.appendFrame(track, data, offset, pts, frameIndex++)) > 0\n ) {\n offset += parsed;\n }\n }\n }\n\n private parseID3PES(id3Track: DemuxedMetadataTrack, pes: PES) {\n if (pes.pts === undefined) {\n this.logger.warn('[tsdemuxer]: ID3 PES unknown PTS');\n return;\n }\n const id3Sample = Object.assign({}, pes as Required<PES>, {\n type: this._videoTrack ? MetadataSchema.emsg : MetadataSchema.audioId3,\n duration: Number.POSITIVE_INFINITY,\n });\n id3Track.samples.push(id3Sample);\n }\n}\n\nfunction parsePID(data: Uint8Array, offset: number): number {\n // pid is a 13-bit field starting at the last bit of TS[1]\n return ((data[offset + 1] & 0x1f) << 8) + data[offset + 2];\n}\n\nfunction parsePAT(data: Uint8Array, offset: number): number {\n // skip the PSI header and parse the first PMT entry\n return ((data[offset + 10] & 0x1f) << 8) | data[offset + 11];\n}\n\nfunction parsePMT(\n data: Uint8Array,\n offset: number,\n typeSupported: TypeSupported,\n isSampleAes: boolean,\n observer: HlsEventEmitter,\n logger: ILogger,\n) {\n const result = {\n audioPid: -1,\n videoPid: -1,\n id3Pid: -1,\n segmentVideoCodec: 'avc' as 'avc' | 'hevc',\n segmentAudioCodec: 'aac' as 'aac' | 'ac3' | 'mp3',\n };\n const sectionLength = ((data[offset + 1] & 0x0f) << 8) | data[offset + 2];\n const tableEnd = offset + 3 + sectionLength - 4;\n // to determine where the table is, we have to figure out how\n // long the program info descriptors are\n const programInfoLength =\n ((data[offset + 10] & 0x0f) << 8) | data[offset + 11];\n // advance the offset to the first entry in the mapping table\n offset += 12 + programInfoLength;\n while (offset < tableEnd) {\n const pid = parsePID(data, offset);\n const esInfoLength = ((data[offset + 3] & 0x0f) << 8) | data[offset + 4];\n switch (data[offset]) {\n case 0xcf: // SAMPLE-AES AAC\n if (!isSampleAes) {\n logEncryptedSamplesFoundInUnencryptedStream('ADTS AAC', logger);\n break;\n }\n /* falls through */\n case 0x0f: // ISO/IEC 13818-7 ADTS AAC (MPEG-2 lower bit-rate audio)\n // logger.log('AAC PID:' + pid);\n if (result.audioPid === -1) {\n result.audioPid = pid;\n }\n\n break;\n\n // Packetized metadata (ID3)\n case 0x15:\n // logger.log('ID3 PID:' + pid);\n if (result.id3Pid === -1) {\n result.id3Pid = pid;\n }\n\n break;\n\n case 0xdb: // SAMPLE-AES AVC\n if (!isSampleAes) {\n logEncryptedSamplesFoundInUnencryptedStream('H.264', logger);\n break;\n }\n /* falls through */\n case 0x1b: // ITU-T Rec. H.264 and ISO/IEC 14496-10 (lower bit-rate video)\n // logger.log('AVC PID:' + pid);\n if (result.videoPid === -1) {\n result.videoPid = pid;\n }\n\n break;\n\n // ISO/IEC 11172-3 (MPEG-1 audio)\n // or ISO/IEC 13818-3 (MPEG-2 halved sample rate audio)\n case 0x03:\n case 0x04:\n // logger.log('MPEG PID:' + pid);\n if (!typeSupported.mpeg && !typeSupported.mp3) {\n logger.log('MPEG audio found, not supported in this browser');\n } else if (result.audioPid === -1) {\n result.audioPid = pid;\n result.segmentAudioCodec = 'mp3';\n }\n break;\n\n case 0xc1: // SAMPLE-AES AC3\n if (!isSampleAes) {\n logEncryptedSamplesFoundInUnencryptedStream('AC-3', logger);\n break;\n }\n /* falls through */\n case 0x81:\n if (__USE_M2TS_ADVANCED_CODECS__) {\n if (!typeSupported.ac3) {\n logger.log('AC-3 audio found, not supported in this browser');\n } else if (result.audioPid === -1) {\n result.audioPid = pid;\n result.segmentAudioCodec = 'ac3';\n }\n } else {\n logger.warn('AC-3 in M2TS support not included in build');\n }\n break;\n\n case 0x06:\n // stream_type 6 can mean a lot of different things in case of DVB.\n // We need to look at the descriptors. Right now, we're only interested\n // in AC-3 audio, so we do the descriptor parsing only when we don't have\n // an audio PID yet.\n if (result.audioPid === -1 && esInfoLength > 0) {\n let parsePos = offset + 5;\n let remaining = esInfoLength;\n\n while (remaining > 2) {\n const descriptorId = data[parsePos];\n\n switch (descriptorId) {\n case 0x6a: // DVB Descriptor for AC-3\n if (__USE_M2TS_ADVANCED_CODECS__) {\n if (typeSupported.ac3 !== true) {\n logger.log(\n 'AC-3 audio found, not supported in this browser for now',\n );\n } else {\n result.audioPid = pid;\n result.segmentAudioCodec = 'ac3';\n }\n } else {\n logger.warn('AC-3 in M2TS support not included in build');\n }\n break;\n }\n\n const descriptorLen = data[parsePos + 1] + 2;\n parsePos += descriptorLen;\n remaining -= descriptorLen;\n }\n }\n break;\n\n case 0xc2: // SAMPLE-AES EC3\n /* falls through */\n case 0x87:\n emitParsingError(\n observer,\n new Error('Unsupported EC-3 in M2TS found'),\n undefined,\n logger,\n );\n return result;\n\n case 0x24: // ITU-T Rec. H.265 and ISO/IEC 23008-2 (HEVC)\n if (__USE_M2TS_ADVANCED_CODECS__) {\n if (result.videoPid === -1) {\n result.videoPid = pid;\n result.segmentVideoCodec = 'hevc';\n logger.log('HEVC in M2TS found');\n }\n } else {\n emitParsingError(\n observer,\n new Error('Unsupported HEVC in M2TS found'),\n undefined,\n logger,\n );\n return result;\n }\n break;\n\n default:\n // logger.log('unknown stream type:' + data[offset]);\n break;\n }\n // move to the next table entry\n // skip past the elementary stream descriptors, if present\n offset += esInfoLength + 5;\n }\n return result;\n}\n\nfunction emitParsingError(\n observer: HlsEventEmitter,\n error: Error,\n levelRetry: boolean | undefined,\n logger: ILogger,\n) {\n logger.warn(`parsing error: ${error.message}`);\n observer.emit(Events.ERROR, Events.ERROR, {\n type: ErrorTypes.MEDIA_ERROR,\n details: ErrorDetails.FRAG_PARSING_ERROR,\n fatal: false,\n levelRetry,\n error,\n reason: error.message,\n });\n}\n\nfunction logEncryptedSamplesFoundInUnencryptedStream(\n type: string,\n logger: ILogger,\n) {\n logger.log(`${type} with AES-128-CBC encryption found in unencrypted stream`);\n}\n\nfunction parsePES(stream: ElementaryStreamData, logger: ILogger): PES | null {\n let i = 0;\n let frag: Uint8Array;\n let pesLen: number;\n let pesHdrLen: number;\n let pesPts: number | undefined;\n let pesDts: number | undefined;\n const data = stream.data;\n // safety check\n if (!stream || stream.size === 0) {\n return null;\n }\n\n // we might need up to 19 bytes to read PES header\n // if first chunk of data is less than 19 bytes, let's merge it with following ones until we get 19 bytes\n // usually only one merge is needed (and this is rare ...)\n while (data[0].length < 19 && data.length > 1) {\n data[0] = appendUint8Array(data[0], data[1]);\n data.splice(1, 1);\n }\n // retrieve PTS/DTS from first fragment\n frag = data[0];\n const pesPrefix = (frag[0] << 16) + (frag[1] << 8) + frag[2];\n if (pesPrefix === 1) {\n pesLen = (frag[4] << 8) + frag[5];\n // if PES parsed length is not zero and greater than total received length, stop parsing. PES might be truncated\n // minus 6 : PES header size\n if (pesLen && pesLen > stream.size - 6) {\n return null;\n }\n\n const pesFlags = frag[7];\n if (pesFlags & 0xc0) {\n /* PES header described here : http://dvd.sourceforge.net/dvdinfo/pes-hdr.html\n as PTS / DTS is 33 bit we cannot use bitwise operator in JS,\n as Bitwise operators treat their operands as a sequence of 32 bits */\n pesPts =\n (frag[9] & 0x0e) * 536870912 + // 1 << 29\n (frag[10] & 0xff) * 4194304 + // 1 << 22\n (frag[11] & 0xfe) * 16384 + // 1 << 14\n (frag[12] & 0xff) * 128 + // 1 << 7\n (frag[13] & 0xfe) / 2;\n\n if (pesFlags & 0x40) {\n pesDts =\n (frag[14] & 0x0e) * 536870912 + // 1 << 29\n (frag[15] & 0xff) * 4194304 + // 1 << 22\n (frag[16] & 0xfe) * 16384 + // 1 << 14\n (frag[17] & 0xff) * 128 + // 1 << 7\n (frag[18] & 0xfe) / 2;\n\n if (pesPts - pesDts > 60 * 90000) {\n logger.warn(\n `${Math.round(\n (pesPts - pesDts) / 90000,\n )}s delta between PTS and DTS, align them`,\n );\n pesPts = pesDts;\n }\n } else {\n pesDts = pesPts;\n }\n }\n pesHdrLen = frag[8];\n // 9 bytes : 6 bytes for PES header + 3 bytes for PES extension\n let payloadStartOffset = pesHdrLen + 9;\n if (stream.size <= payloadStartOffset) {\n return null;\n }\n stream.size -= payloadStartOffset;\n // reassemble PES packet\n const pesData = new Uint8Array(stream.size);\n for (let j = 0, dataLen = data.length; j < dataLen; j++) {\n frag = data[j];\n let len = frag.byteLength;\n if (payloadStartOffset) {\n if (payloadStartOffset > len) {\n // trim full frag if PES header bigger than frag\n payloadStartOffset -= len;\n continue;\n } else {\n // trim partial frag if PES header smaller than frag\n frag = frag.subarray(payloadStartOffset);\n len -= payloadStartOffset;\n payloadStartOffset = 0;\n }\n }\n pesData.set(frag, i);\n i += len;\n }\n if (pesLen) {\n // payload size : remove PES header + PES extension\n pesLen -= pesHdrLen + 3;\n }\n return { data: pesData, pts: pesPts, dts: pesDts, len: pesLen };\n }\n return null;\n}\n\nexport default TSDemuxer;\n","/**\n * AAC helper\n */\n\nclass AAC {\n static getSilentFrame(\n codec?: string,\n channelCount?: number,\n ): Uint8Array | undefined {\n switch (codec) {\n case 'mp4a.40.2':\n if (channelCount === 1) {\n return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);\n } else if (channelCount === 2) {\n return new Uint8Array([\n 0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80,\n ]);\n } else if (channelCount === 3) {\n return new Uint8Array([\n 0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64,\n 0x00, 0x8e,\n ]);\n } else if (channelCount === 4) {\n return new Uint8Array([\n 0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64,\n 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38,\n ]);\n } else if (channelCount === 5) {\n return new Uint8Array([\n 0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64,\n 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38,\n ]);\n } else if (channelCount === 6) {\n return new Uint8Array([\n 0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64,\n 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2,\n 0x00, 0x20, 0x08, 0xe0,\n ]);\n }\n\n break;\n // handle HE-AAC below (mp4a.40.5 / mp4a.40.29)\n default:\n if (channelCount === 1) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0:d=0.05\" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([\n 0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0,\n 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5e,\n ]);\n } else if (channelCount === 2) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0|0:d=0.05\" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([\n 0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0,\n 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5e,\n ]);\n } else if (channelCount === 3) {\n // ffmpeg -y -f lavfi -i \"aevalsrc=0|0|0:d=0.05\" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 \"0x%x,\" \"\\n\"' -v output.aac\n return new Uint8Array([\n 0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0,\n 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,\n 0x5a, 0x5e,\n ]);\n }\n break;\n }\n return undefined;\n }\n}\n\nexport default AAC;\n","/**\n * Generate MP4 Box\n */\n\nimport { appendUint8Array } from '../utils/mp4-tools';\nimport type {\n DemuxedAC3,\n DemuxedAudioTrack,\n DemuxedAVC1,\n DemuxedHEVC,\n DemuxedVideoTrack,\n} from '../types/demuxer';\nimport type {\n Mp4SampleFlags,\n RemuxedAudioTrackSamples,\n RemuxedVideoTrackSamples,\n} from '../types/remuxer';\n\ntype MediaTrackType = DemuxedAudioTrack | DemuxedVideoTrack;\ntype RemuxedTrackType = RemuxedAudioTrackSamples | RemuxedVideoTrackSamples;\n\ntype HdlrTypes = {\n video: Uint8Array;\n audio: Uint8Array;\n};\n\nconst UINT32_MAX = Math.pow(2, 32) - 1;\n\nclass MP4 {\n public static types: Record<string, number[]>;\n private static HDLR_TYPES: HdlrTypes;\n private static STTS: Uint8Array;\n private static STSC: Uint8Array;\n private static STCO: Uint8Array;\n private static STSZ: Uint8Array;\n private static VMHD: Uint8Array;\n private static SMHD: Uint8Array;\n private static STSD: Uint8Array;\n private static FTYP: Uint8Array;\n private static DINF: Uint8Array;\n\n static init() {\n MP4.types = {\n avc1: [], // codingname\n avcC: [],\n hvc1: [],\n hvcC: [],\n btrt: [],\n dinf: [],\n dref: [],\n esds: [],\n ftyp: [],\n hdlr: [],\n mdat: [],\n mdhd: [],\n mdia: [],\n mfhd: [],\n minf: [],\n moof: [],\n moov: [],\n mp4a: [],\n '.mp3': [],\n dac3: [],\n 'ac-3': [],\n mvex: [],\n mvhd: [],\n pasp: [],\n sdtp: [],\n stbl: [],\n stco: [],\n stsc: [],\n stsd: [],\n stsz: [],\n stts: [],\n tfdt: [],\n tfhd: [],\n traf: [],\n trak: [],\n trun: [],\n trex: [],\n tkhd: [],\n vmhd: [],\n smhd: [],\n };\n\n let i: string;\n for (i in MP4.types) {\n if (MP4.types.hasOwnProperty(i)) {\n MP4.types[i] = [\n i.charCodeAt(0),\n i.charCodeAt(1),\n i.charCodeAt(2),\n i.charCodeAt(3),\n ];\n }\n }\n\n const videoHdlr = new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00, // pre_defined\n 0x76,\n 0x69,\n 0x64,\n 0x65, // handler_type: 'vide'\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x56,\n 0x69,\n 0x64,\n 0x65,\n 0x6f,\n 0x48,\n 0x61,\n 0x6e,\n 0x64,\n 0x6c,\n 0x65,\n 0x72,\n 0x00, // name: 'VideoHandler'\n ]);\n\n const audioHdlr = new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00, // pre_defined\n 0x73,\n 0x6f,\n 0x75,\n 0x6e, // handler_type: 'soun'\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x53,\n 0x6f,\n 0x75,\n 0x6e,\n 0x64,\n 0x48,\n 0x61,\n 0x6e,\n 0x64,\n 0x6c,\n 0x65,\n 0x72,\n 0x00, // name: 'SoundHandler'\n ]);\n\n MP4.HDLR_TYPES = {\n video: videoHdlr,\n audio: audioHdlr,\n };\n\n const dref = new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x01, // entry_count\n 0x00,\n 0x00,\n 0x00,\n 0x0c, // entry_size\n 0x75,\n 0x72,\n 0x6c,\n 0x20, // 'url' type\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x01, // entry_flags\n ]);\n\n const stco = new Uint8Array([\n 0x00, // version\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00, // entry_count\n ]);\n\n MP4.STTS = MP4.STSC = MP4.STCO = stco;\n\n MP4.STSZ = new Uint8Array([\n 0x00, // version\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00, // sample_size\n 0x00,\n 0x00,\n 0x00,\n 0x00, // sample_count\n ]);\n MP4.VMHD = new Uint8Array([\n 0x00, // version\n 0x00,\n 0x00,\n 0x01, // flags\n 0x00,\n 0x00, // graphicsmode\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // opcolor\n ]);\n MP4.SMHD = new Uint8Array([\n 0x00, // version\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00, // balance\n 0x00,\n 0x00, // reserved\n ]);\n\n MP4.STSD = new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x01,\n ]); // entry_count\n\n const majorBrand = new Uint8Array([105, 115, 111, 109]); // isom\n const avc1Brand = new Uint8Array([97, 118, 99, 49]); // avc1\n const minorVersion = new Uint8Array([0, 0, 0, 1]);\n\n MP4.FTYP = MP4.box(\n MP4.types.ftyp,\n majorBrand,\n minorVersion,\n majorBrand,\n avc1Brand,\n );\n MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref));\n }\n\n static box(type: number[], ...payload: Uint8Array[]) {\n let size = 8;\n let i = payload.length;\n const len = i;\n // calculate the total size we need to allocate\n while (i--) {\n size += payload[i].byteLength;\n }\n\n const result = new Uint8Array(size);\n result[0] = (size >> 24) & 0xff;\n result[1] = (size >> 16) & 0xff;\n result[2] = (size >> 8) & 0xff;\n result[3] = size & 0xff;\n result.set(type, 4);\n // copy the payload into the result\n for (i = 0, size = 8; i < len; i++) {\n // copy payload[i] array @ offset size\n result.set(payload[i], size);\n size += payload[i].byteLength;\n }\n return result;\n }\n\n static hdlr(type: keyof HdlrTypes) {\n return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]);\n }\n\n static mdat(data: Uint8Array) {\n return MP4.box(MP4.types.mdat, data);\n }\n\n static mdhd(timescale: number, duration: number) {\n duration *= timescale;\n const upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));\n const lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));\n return MP4.box(\n MP4.types.mdhd,\n new Uint8Array([\n 0x01, // version 1\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x02, // creation_time\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x03, // modification_time\n (timescale >> 24) & 0xff,\n (timescale >> 16) & 0xff,\n (timescale >> 8) & 0xff,\n timescale & 0xff, // timescale\n upperWordDuration >> 24,\n (upperWordDuration >> 16) & 0xff,\n (upperWordDuration >> 8) & 0xff,\n upperWordDuration & 0xff,\n lowerWordDuration >> 24,\n (lowerWordDuration >> 16) & 0xff,\n (lowerWordDuration >> 8) & 0xff,\n lowerWordDuration & 0xff,\n 0x55,\n 0xc4, // 'und' language (undetermined)\n 0x00,\n 0x00,\n ]),\n );\n }\n\n static mdia(track: MediaTrackType) {\n return MP4.box(\n MP4.types.mdia,\n MP4.mdhd(track.timescale || 0, track.duration || 0),\n MP4.hdlr(track.type),\n MP4.minf(track),\n );\n }\n\n static mfhd(sequenceNumber: number) {\n return MP4.box(\n MP4.types.mfhd,\n new Uint8Array([\n 0x00,\n 0x00,\n 0x00,\n 0x00, // flags\n sequenceNumber >> 24,\n (sequenceNumber >> 16) & 0xff,\n (sequenceNumber >> 8) & 0xff,\n sequenceNumber & 0xff, // sequence_number\n ]),\n );\n }\n\n static minf(track: MediaTrackType) {\n if (track.type === 'audio') {\n return MP4.box(\n MP4.types.minf,\n MP4.box(MP4.types.smhd, MP4.SMHD),\n MP4.DINF,\n MP4.stbl(track),\n );\n } else {\n return MP4.box(\n MP4.types.minf,\n MP4.box(MP4.types.vmhd, MP4.VMHD),\n MP4.DINF,\n MP4.stbl(track),\n );\n }\n }\n\n static moof(\n sn: number,\n baseMediaDecodeTime: number,\n track: RemuxedTrackType,\n ) {\n return MP4.box(\n MP4.types.moof,\n MP4.mfhd(sn),\n MP4.traf(track, baseMediaDecodeTime),\n );\n }\n\n static moov(tracks: MediaTrackType[]) {\n let i = tracks.length;\n const boxes: Uint8Array[] = [];\n\n while (i--) {\n boxes[i] = MP4.trak(tracks[i]);\n }\n\n return MP4.box.apply(\n null,\n [\n MP4.types.moov,\n MP4.mvhd(tracks[0].timescale || 0, tracks[0].duration || 0),\n ]\n .concat(boxes)\n .concat(MP4.mvex(tracks)),\n );\n }\n\n static mvex(tracks: MediaTrackType[]) {\n let i = tracks.length;\n const boxes: Uint8Array[] = [];\n\n while (i--) {\n boxes[i] = MP4.trex(tracks[i]);\n }\n\n return MP4.box.apply(null, [MP4.types.mvex, ...boxes]);\n }\n\n static mvhd(timescale: number, duration: number) {\n duration *= timescale;\n const upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));\n const lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));\n const bytes = new Uint8Array([\n 0x01, // version 1\n 0x00,\n 0x00,\n 0x00, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x02, // creation_time\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x03, // modification_time\n (timescale >> 24) & 0xff,\n (timescale >> 16) & 0xff,\n (timescale >> 8) & 0xff,\n timescale & 0xff, // timescale\n upperWordDuration >> 24,\n (upperWordDuration >> 16) & 0xff,\n (upperWordDuration >> 8) & 0xff,\n upperWordDuration & 0xff,\n lowerWordDuration >> 24,\n (lowerWordDuration >> 16) & 0xff,\n (lowerWordDuration >> 8) & 0xff,\n lowerWordDuration & 0xff,\n 0x00,\n 0x01,\n 0x00,\n 0x00, // 1.0 rate\n 0x01,\n 0x00, // 1.0 volume\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x01,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x40,\n 0x00,\n 0x00,\n 0x00, // transformation: unity matrix\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // pre_defined\n 0xff,\n 0xff,\n 0xff,\n 0xff, // next_track_ID\n ]);\n return MP4.box(MP4.types.mvhd, bytes);\n }\n\n static sdtp(track: RemuxedTrackType) {\n const samples = track.samples || [];\n const bytes = new Uint8Array(4 + samples.length);\n let i: number;\n let flags: Mp4SampleFlags;\n // leave the full box header (4 bytes) all zero\n // write the sample table\n for (i = 0; i < samples.length; i++) {\n flags = samples[i].flags;\n bytes[i + 4] =\n (flags.dependsOn << 4) |\n (flags.isDependedOn << 2) |\n flags.hasRedundancy;\n }\n\n return MP4.box(MP4.types.sdtp, bytes);\n }\n\n static stbl(track: MediaTrackType) {\n return MP4.box(\n MP4.types.stbl,\n MP4.stsd(track),\n MP4.box(MP4.types.stts, MP4.STTS),\n MP4.box(MP4.types.stsc, MP4.STSC),\n MP4.box(MP4.types.stsz, MP4.STSZ),\n MP4.box(MP4.types.stco, MP4.STCO),\n );\n }\n\n static avc1(track: DemuxedAVC1) {\n let sps: number[] = [];\n let pps: number[] = [];\n let i;\n let data;\n let len;\n // assemble the SPSs\n\n for (i = 0; i < track.sps.length; i++) {\n data = track.sps[i];\n len = data.byteLength;\n sps.push((len >>> 8) & 0xff);\n sps.push(len & 0xff);\n\n // SPS\n sps = sps.concat(Array.prototype.slice.call(data));\n }\n\n // assemble the PPSs\n for (i = 0; i < track.pps.length; i++) {\n data = track.pps[i];\n len = data.byteLength;\n pps.push((len >>> 8) & 0xff);\n pps.push(len & 0xff);\n\n pps = pps.concat(Array.prototype.slice.call(data));\n }\n\n const avcc = MP4.box(\n MP4.types.avcC,\n new Uint8Array(\n [\n 0x01, // version\n sps[3], // profile\n sps[4], // profile compat\n sps[5], // level\n 0xfc | 3, // lengthSizeMinusOne, hard-coded to 4 bytes\n 0xe0 | track.sps.length, // 3bit reserved (111) + numOfSequenceParameterSets\n ]\n .concat(sps)\n .concat([\n track.pps.length, // numOfPictureParameterSets\n ])\n .concat(pps),\n ),\n ); // \"PPS\"\n const width = track.width;\n const height = track.height;\n const hSpacing = track.pixelRatio[0];\n const vSpacing = track.pixelRatio[1];\n\n return MP4.box(\n MP4.types.avc1,\n new Uint8Array([\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01, // data_reference_index\n 0x00,\n 0x00, // pre_defined\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // pre_defined\n (width >> 8) & 0xff,\n width & 0xff, // width\n (height >> 8) & 0xff,\n height & 0xff, // height\n 0x00,\n 0x48,\n 0x00,\n 0x00, // horizresolution\n 0x00,\n 0x48,\n 0x00,\n 0x00, // vertresolution\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01, // frame_count\n 0x12,\n 0x64,\n 0x61,\n 0x69,\n 0x6c, // dailymotion/hls.js\n 0x79,\n 0x6d,\n 0x6f,\n 0x74,\n 0x69,\n 0x6f,\n 0x6e,\n 0x2f,\n 0x68,\n 0x6c,\n 0x73,\n 0x2e,\n 0x6a,\n 0x73,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // compressorname\n 0x00,\n 0x18, // depth = 24\n 0x11,\n 0x11,\n ]), // pre_defined = -1\n avcc,\n MP4.box(\n MP4.types.btrt,\n new Uint8Array([\n 0x00,\n 0x1c,\n 0x9c,\n 0x80, // bufferSizeDB\n 0x00,\n 0x2d,\n 0xc6,\n 0xc0, // maxBitrate\n 0x00,\n 0x2d,\n 0xc6,\n 0xc0,\n ]),\n ), // avgBitrate\n MP4.box(\n MP4.types.pasp,\n new Uint8Array([\n hSpacing >> 24, // hSpacing\n (hSpacing >> 16) & 0xff,\n (hSpacing >> 8) & 0xff,\n hSpacing & 0xff,\n vSpacing >> 24, // vSpacing\n (vSpacing >> 16) & 0xff,\n (vSpacing >> 8) & 0xff,\n vSpacing & 0xff,\n ]),\n ),\n );\n }\n\n static esds(track: DemuxedAudioTrack) {\n const config = track.config as [number, number];\n return new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n\n 0x03, // descriptor_type\n 0x19, // length\n\n 0x00,\n 0x01, // es_id\n\n 0x00, // stream_priority\n\n 0x04, // descriptor_type\n 0x11, // length\n 0x40, // codec : mpeg4_audio\n 0x15, // stream_type\n 0x00,\n 0x00,\n 0x00, // buffer_size\n 0x00,\n 0x00,\n 0x00,\n 0x00, // maxBitrate\n 0x00,\n 0x00,\n 0x00,\n 0x00, // avgBitrate\n\n 0x05, // descriptor_type\n 0x02, // length\n ...config,\n 0x06,\n 0x01,\n 0x02, // GASpecificConfig)); // length + audio config descriptor\n ]);\n }\n\n static audioStsd(track: DemuxedAudioTrack) {\n const samplerate = track.samplerate || 0;\n return new Uint8Array([\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01, // data_reference_index\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n track.channelCount || 0, // channelcount\n 0x00,\n 0x10, // sampleSize:16bits\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved2\n (samplerate >> 8) & 0xff,\n samplerate & 0xff, //\n 0x00,\n 0x00,\n ]);\n }\n\n static mp4a(track: DemuxedAudioTrack) {\n return MP4.box(\n MP4.types.mp4a,\n MP4.audioStsd(track),\n MP4.box(MP4.types.esds, MP4.esds(track)),\n );\n }\n\n static mp3(track: DemuxedAudioTrack) {\n return MP4.box(MP4.types['.mp3'], MP4.audioStsd(track));\n }\n\n static ac3(track: DemuxedAudioTrack) {\n return MP4.box(\n MP4.types['ac-3'],\n MP4.audioStsd(track),\n MP4.box(MP4.types.dac3, track.config as Uint8Array),\n );\n }\n\n static stsd(track: MediaTrackType | DemuxedAC3): Uint8Array {\n const { segmentCodec } = track;\n if (track.type === 'audio') {\n if (segmentCodec === 'aac') {\n return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));\n }\n if (\n __USE_M2TS_ADVANCED_CODECS__ &&\n segmentCodec === 'ac3' &&\n track.config\n ) {\n return MP4.box(MP4.types.stsd, MP4.STSD, MP4.ac3(track));\n }\n if (segmentCodec === 'mp3' && track.codec === 'mp3') {\n return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp3(track));\n }\n } else {\n if (track.pps && track.sps) {\n if (segmentCodec === 'avc') {\n return MP4.box(\n MP4.types.stsd,\n MP4.STSD,\n MP4.avc1(track as DemuxedAVC1),\n );\n }\n if (\n __USE_M2TS_ADVANCED_CODECS__ &&\n segmentCodec === 'hevc' &&\n track.vps\n ) {\n return MP4.box(\n MP4.types.stsd,\n MP4.STSD,\n MP4.hvc1(track as DemuxedHEVC),\n );\n }\n } else {\n throw new Error(`video track missing pps or sps`);\n }\n }\n\n throw new Error(\n `unsupported ${track.type} segment codec (${segmentCodec}/${track.codec})`,\n );\n }\n\n static tkhd(track: MediaTrackType) {\n const id = track.id;\n const duration = (track.duration || 0) * (track.timescale || 0);\n const width = (track as any).width || 0;\n const height = (track as any).height || 0;\n const upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));\n const lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));\n return MP4.box(\n MP4.types.tkhd,\n new Uint8Array([\n 0x01, // version 1\n 0x00,\n 0x00,\n 0x07, // flags\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x02, // creation_time\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x03, // modification_time\n (id >> 24) & 0xff,\n (id >> 16) & 0xff,\n (id >> 8) & 0xff,\n id & 0xff, // track_ID\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n upperWordDuration >> 24,\n (upperWordDuration >> 16) & 0xff,\n (upperWordDuration >> 8) & 0xff,\n upperWordDuration & 0xff,\n lowerWordDuration >> 24,\n (lowerWordDuration >> 16) & 0xff,\n (lowerWordDuration >> 8) & 0xff,\n lowerWordDuration & 0xff,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00, // layer\n 0x00,\n 0x00, // alternate_group\n 0x00,\n 0x00, // non-audio track volume\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x01,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x40,\n 0x00,\n 0x00,\n 0x00, // transformation: unity matrix\n (width >> 8) & 0xff,\n width & 0xff,\n 0x00,\n 0x00, // width\n (height >> 8) & 0xff,\n height & 0xff,\n 0x00,\n 0x00, // height\n ]),\n );\n }\n\n static traf(track: RemuxedTrackType, baseMediaDecodeTime: number) {\n const sampleDependencyTable = MP4.sdtp(track);\n const id = track.id;\n const upperWordBaseMediaDecodeTime = Math.floor(\n baseMediaDecodeTime / (UINT32_MAX + 1),\n );\n const lowerWordBaseMediaDecodeTime = Math.floor(\n baseMediaDecodeTime % (UINT32_MAX + 1),\n );\n return MP4.box(\n MP4.types.traf,\n MP4.box(\n MP4.types.tfhd,\n new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n id >> 24,\n (id >> 16) & 0xff,\n (id >> 8) & 0xff,\n id & 0xff, // track_ID\n ]),\n ),\n MP4.box(\n MP4.types.tfdt,\n new Uint8Array([\n 0x01, // version 1\n 0x00,\n 0x00,\n 0x00, // flags\n upperWordBaseMediaDecodeTime >> 24,\n (upperWordBaseMediaDecodeTime >> 16) & 0xff,\n (upperWordBaseMediaDecodeTime >> 8) & 0xff,\n upperWordBaseMediaDecodeTime & 0xff,\n lowerWordBaseMediaDecodeTime >> 24,\n (lowerWordBaseMediaDecodeTime >> 16) & 0xff,\n (lowerWordBaseMediaDecodeTime >> 8) & 0xff,\n lowerWordBaseMediaDecodeTime & 0xff,\n ]),\n ),\n MP4.trun(\n track,\n sampleDependencyTable.length +\n 16 + // tfhd\n 20 + // tfdt\n 8 + // traf header\n 16 + // mfhd\n 8 + // moof header\n 8,\n ), // mdat header\n sampleDependencyTable,\n );\n }\n\n /**\n * Generate a track box.\n * @param track a track definition\n */\n static trak(track: MediaTrackType) {\n track.duration = track.duration || 0xffffffff;\n return MP4.box(MP4.types.trak, MP4.tkhd(track), MP4.mdia(track));\n }\n\n static trex(track: MediaTrackType) {\n const id = track.id;\n return MP4.box(\n MP4.types.trex,\n new Uint8Array([\n 0x00, // version 0\n 0x00,\n 0x00,\n 0x00, // flags\n id >> 24,\n (id >> 16) & 0xff,\n (id >> 8) & 0xff,\n id & 0xff, // track_ID\n 0x00,\n 0x00,\n 0x00,\n 0x01, // default_sample_description_index\n 0x00,\n 0x00,\n 0x00,\n 0x00, // default_sample_duration\n 0x00,\n 0x00,\n 0x00,\n 0x00, // default_sample_size\n 0x00,\n 0x01,\n 0x00,\n 0x01, // default_sample_flags\n ]),\n );\n }\n\n static trun(track: MediaTrackType, offset: number) {\n const samples = track.samples || [];\n const len = samples.length;\n const arraylen = 12 + 16 * len;\n const array = new Uint8Array(arraylen);\n let i;\n let sample;\n let duration;\n let size;\n let flags;\n let cts;\n offset += 8 + arraylen;\n array.set(\n [\n track.type === 'video' ? 0x01 : 0x00, // version 1 for video with signed-int sample_composition_time_offset\n 0x00,\n 0x0f,\n 0x01, // flags\n (len >>> 24) & 0xff,\n (len >>> 16) & 0xff,\n (len >>> 8) & 0xff,\n len & 0xff, // sample_count\n (offset >>> 24) & 0xff,\n (offset >>> 16) & 0xff,\n (offset >>> 8) & 0xff,\n offset & 0xff, // data_offset\n ],\n 0,\n );\n for (i = 0; i < len; i++) {\n sample = samples[i];\n duration = sample.duration;\n size = sample.size;\n flags = sample.flags;\n cts = sample.cts;\n array.set(\n [\n (duration >>> 24) & 0xff,\n (duration >>> 16) & 0xff,\n (duration >>> 8) & 0xff,\n duration & 0xff, // sample_duration\n (size >>> 24) & 0xff,\n (size >>> 16) & 0xff,\n (size >>> 8) & 0xff,\n size & 0xff, // sample_size\n (flags.isLeading << 2) | flags.dependsOn,\n (flags.isDependedOn << 6) |\n (flags.hasRedundancy << 4) |\n (flags.paddingValue << 1) |\n flags.isNonSync,\n flags.degradPrio & (0xf0 << 8),\n flags.degradPrio & 0x0f, // sample_flags\n (cts >>> 24) & 0xff,\n (cts >>> 16) & 0xff,\n (cts >>> 8) & 0xff,\n cts & 0xff, // sample_composition_time_offset\n ],\n 12 + 16 * i,\n );\n }\n return MP4.box(MP4.types.trun, array);\n }\n\n static initSegment(tracks: MediaTrackType[]) {\n if (!MP4.types) {\n MP4.init();\n }\n\n const movie = MP4.moov(tracks);\n const result = appendUint8Array(MP4.FTYP, movie);\n return result;\n }\n\n static hvc1(track: DemuxedHEVC) {\n if (!__USE_M2TS_ADVANCED_CODECS__) {\n return new Uint8Array();\n }\n const ps = track.params;\n const units: Uint8Array[][] = [track.vps, track.sps, track.pps];\n const NALuLengthSize = 4;\n const config = new Uint8Array([\n 0x01,\n (ps.general_profile_space << 6) |\n (ps.general_tier_flag ? 32 : 0) |\n ps.general_profile_idc,\n ps.general_profile_compatibility_flags[0],\n ps.general_profile_compatibility_flags[1],\n ps.general_profile_compatibility_flags[2],\n ps.general_profile_compatibility_flags[3],\n ps.general_constraint_indicator_flags[0],\n ps.general_constraint_indicator_flags[1],\n ps.general_constraint_indicator_flags[2],\n ps.general_constraint_indicator_flags[3],\n ps.general_constraint_indicator_flags[4],\n ps.general_constraint_indicator_flags[5],\n ps.general_level_idc,\n 240 | (ps.min_spatial_segmentation_idc >> 8),\n 255 & ps.min_spatial_segmentation_idc,\n 252 | ps.parallelismType,\n 252 | ps.chroma_format_idc,\n 248 | ps.bit_depth_luma_minus8,\n 248 | ps.bit_depth_chroma_minus8,\n 0x00,\n parseInt(ps.frame_rate.fps),\n (NALuLengthSize - 1) |\n (ps.temporal_id_nested << 2) |\n (ps.num_temporal_layers << 3) |\n (ps.frame_rate.fixed ? 64 : 0),\n units.length,\n ]);\n\n // compute hvcC size in bytes\n let length = config.length;\n for (let i = 0; i < units.length; i += 1) {\n length += 3;\n for (let j = 0; j < units[i].length; j += 1) {\n length += 2 + units[i][j].length;\n }\n }\n\n const hvcC = new Uint8Array(length);\n hvcC.set(config, 0);\n length = config.length;\n // append parameter set units: one vps, one or more sps and pps\n const iMax = units.length - 1;\n for (let i = 0; i < units.length; i += 1) {\n hvcC.set(\n new Uint8Array([\n (32 + i) | (i === iMax ? 128 : 0),\n 0x00,\n units[i].length,\n ]),\n length,\n );\n length += 3;\n for (let j = 0; j < units[i].length; j += 1) {\n hvcC.set(\n new Uint8Array([units[i][j].length >> 8, units[i][j].length & 255]),\n length,\n );\n length += 2;\n hvcC.set(units[i][j], length);\n length += units[i][j].length;\n }\n }\n const hvcc = MP4.box(MP4.types.hvcC, hvcC);\n const width = track.width;\n const height = track.height;\n const hSpacing = track.pixelRatio[0];\n const vSpacing = track.pixelRatio[1];\n\n return MP4.box(\n MP4.types.hvc1,\n new Uint8Array([\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01, // data_reference_index\n 0x00,\n 0x00, // pre_defined\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // pre_defined\n (width >> 8) & 0xff,\n width & 0xff, // width\n (height >> 8) & 0xff,\n height & 0xff, // height\n 0x00,\n 0x48,\n 0x00,\n 0x00, // horizresolution\n 0x00,\n 0x48,\n 0x00,\n 0x00, // vertresolution\n 0x00,\n 0x00,\n 0x00,\n 0x00, // reserved\n 0x00,\n 0x01, // frame_count\n 0x12,\n 0x64,\n 0x61,\n 0x69,\n 0x6c, // dailymotion/hls.js\n 0x79,\n 0x6d,\n 0x6f,\n 0x74,\n 0x69,\n 0x6f,\n 0x6e,\n 0x2f,\n 0x68,\n 0x6c,\n 0x73,\n 0x2e,\n 0x6a,\n 0x73,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n 0x00, // compressorname\n 0x00,\n 0x18, // depth = 24\n 0x11,\n 0x11,\n ]), // pre_defined = -1\n hvcc,\n MP4.box(\n MP4.types.btrt,\n new Uint8Array([\n 0x00,\n 0x1c,\n 0x9c,\n 0x80, // bufferSizeDB\n 0x00,\n 0x2d,\n 0xc6,\n 0xc0, // maxBitrate\n 0x00,\n 0x2d,\n 0xc6,\n 0xc0,\n ]),\n ), // avgBitrate\n MP4.box(\n MP4.types.pasp,\n new Uint8Array([\n hSpacing >> 24, // hSpacing\n (hSpacing >> 16) & 0xff,\n (hSpacing >> 8) & 0xff,\n hSpacing & 0xff,\n vSpacing >> 24, // vSpacing\n (vSpacing >> 16) & 0xff,\n (vSpacing >> 8) & 0xff,\n vSpacing & 0xff,\n ]),\n ),\n );\n }\n}\n\nexport default MP4;\n","import type { LoaderConfig } from '../config';\nimport type { HlsUrlParameters, Level } from './level';\nimport type { MediaPlaylist } from './media-playlist';\nimport type { Fragment } from '../loader/fragment';\nimport type { Part } from '../loader/fragment';\nimport type { KeyLoaderInfo } from '../loader/key-loader';\nimport type { LevelDetails } from '../loader/level-details';\n\nexport interface LoaderContext {\n // target URL\n url: string;\n // loader response type (arraybuffer or default response type for playlist)\n responseType: string;\n // headers\n headers?: Record<string, string>;\n // start byte range offset\n rangeStart?: number;\n // end byte range offset\n rangeEnd?: number;\n // true if onProgress should report partial chunk of loaded content\n progressData?: boolean;\n}\n\nexport interface FragmentLoaderContext extends LoaderContext {\n frag: Fragment;\n part: Part | null;\n resetIV?: boolean;\n}\n\nexport interface KeyLoaderContext extends LoaderContext {\n keyInfo: KeyLoaderInfo;\n frag: Fragment;\n}\n\nexport interface LoaderConfiguration {\n // LoaderConfig policy that overrides required settings\n loadPolicy: LoaderConfig;\n /**\n * @deprecated use LoaderConfig timeoutRetry and errorRetry maxNumRetry\n */\n // Max number of load retries\n maxRetry: number;\n /**\n * @deprecated use LoaderConfig maxTimeToFirstByteMs and maxLoadTimeMs\n */\n // Timeout after which `onTimeOut` callback will be triggered\n // when loading has not finished after that delay\n timeout: number;\n /**\n * @deprecated use LoaderConfig timeoutRetry and errorRetry retryDelayMs\n */\n // Delay between an I/O error and following connection retry (ms).\n // This to avoid spamming the server\n retryDelay: number;\n /**\n * @deprecated use LoaderConfig timeoutRetry and errorRetry maxRetryDelayMs\n */\n // max connection retry delay (ms)\n maxRetryDelay: number;\n // When streaming progressively, this is the minimum chunk size required to emit a PROGRESS event\n highWaterMark?: number;\n}\n\nexport interface LoaderResponse {\n url: string;\n data?: string | ArrayBuffer | Object;\n // Errors can include HTTP status code and error message\n // Successful responses should include status code 200\n code?: number;\n text?: string;\n}\n\nexport interface LoaderStats {\n aborted: boolean;\n loaded: number;\n retry: number;\n total: number;\n chunkCount: number;\n bwEstimate: number;\n loading: HlsProgressivePerformanceTiming;\n parsing: HlsPerformanceTiming;\n buffering: HlsProgressivePerformanceTiming;\n}\n\nexport interface HlsPerformanceTiming {\n start: number;\n end: number;\n}\n\nexport interface HlsChunkPerformanceTiming extends HlsPerformanceTiming {\n executeStart: number;\n executeEnd: number;\n}\n\nexport interface HlsProgressivePerformanceTiming extends HlsPerformanceTiming {\n first: number;\n}\n\nexport type LoaderOnSuccess<T extends LoaderContext> = (\n response: LoaderResponse,\n stats: LoaderStats,\n context: T,\n networkDetails: any,\n) => void;\n\nexport type LoaderOnProgress<T extends LoaderContext> = (\n stats: LoaderStats,\n context: T,\n data: string | ArrayBuffer,\n networkDetails: any,\n) => void;\n\nexport type LoaderOnError<T extends LoaderContext> = (\n error: {\n // error status code\n code: number;\n // error description\n text: string;\n },\n context: T,\n networkDetails: any,\n stats: LoaderStats,\n) => void;\n\nexport type LoaderOnTimeout<T extends LoaderContext> = (\n stats: LoaderStats,\n context: T,\n networkDetails: any,\n) => void;\n\nexport type LoaderOnAbort<T extends LoaderContext> = (\n stats: LoaderStats,\n context: T,\n networkDetails: any,\n) => void;\n\nexport interface LoaderCallbacks<T extends LoaderContext> {\n onSuccess: LoaderOnSuccess<T>;\n onError: LoaderOnError<T>;\n onTimeout: LoaderOnTimeout<T>;\n onAbort?: LoaderOnAbort<T>;\n onProgress?: LoaderOnProgress<T>;\n}\n\nexport interface Loader<T extends LoaderContext> {\n destroy(): void;\n abort(): void;\n load(\n context: T,\n config: LoaderConfiguration,\n callbacks: LoaderCallbacks<T>,\n ): void;\n /**\n * `getCacheAge()` is called by hls.js to get the duration that a given object\n * has been sitting in a cache proxy when playing live. If implemented,\n * this should return a value in seconds.\n *\n * For HTTP based loaders, this should return the contents of the \"age\" header.\n *\n * @returns time object being lodaded\n */\n getCacheAge?: () => number | null;\n getResponseHeader?: (name: string) => string | null;\n context: T | null;\n stats: LoaderStats;\n}\n\nexport const enum PlaylistContextType {\n MANIFEST = 'manifest',\n LEVEL = 'level',\n AUDIO_TRACK = 'audioTrack',\n SUBTITLE_TRACK = 'subtitleTrack',\n}\n\nexport const enum PlaylistLevelType {\n MAIN = 'main',\n AUDIO = 'audio',\n SUBTITLE = 'subtitle',\n}\n\nexport interface PlaylistLoaderContext extends LoaderContext {\n type: PlaylistContextType;\n // the level index to load\n level: number | null;\n // level or track id from LevelLoadingData / TrackLoadingData\n id: number | null;\n // Media Playlist Group ID\n groupId?: string;\n // Content Steering Pathway ID (or undefined for default Pathway \".\")\n pathwayId?: string;\n // internal representation of a parsed m3u8 level playlist\n levelDetails?: LevelDetails;\n // Blocking playlist request delivery directives (or null id none were added to playlist url\n deliveryDirectives: HlsUrlParameters | null;\n // Reference to level or track object in hls.levels, hls.allAudioTracks, or hls.allSubtitleTracks (null when loading MVP)\n levelOrTrack: Level | MediaPlaylist | null;\n}\n","const MPEG_TS_CLOCK_FREQ_HZ = 90000;\n\nexport type RationalTimestamp = {\n baseTime: number; // ticks\n timescale: number; // ticks per second\n};\n\nexport function toTimescaleFromBase(\n baseTime: number,\n destScale: number,\n srcBase: number = 1,\n round: boolean = false,\n): number {\n const result = baseTime * destScale * srcBase; // equivalent to `(value * scale) / (1 / base)`\n return round ? Math.round(result) : result;\n}\n\nexport function toTimescaleFromScale(\n baseTime: number,\n destScale: number,\n srcScale: number = 1,\n round: boolean = false,\n): number {\n return toTimescaleFromBase(baseTime, destScale, 1 / srcScale, round);\n}\n\nexport function toMsFromMpegTsClock(\n baseTime: number,\n round: boolean = false,\n): number {\n return toTimescaleFromBase(baseTime, 1000, 1 / MPEG_TS_CLOCK_FREQ_HZ, round);\n}\n\nexport function toMpegTsClockFromTimescale(\n baseTime: number,\n srcScale: number = 1,\n): number {\n return toTimescaleFromBase(baseTime, MPEG_TS_CLOCK_FREQ_HZ, 1 / srcScale);\n}\n","import AAC from './aac-helper';\nimport MP4 from './mp4-generator';\nimport { ErrorDetails, ErrorTypes } from '../errors';\nimport { Events } from '../events';\nimport { PlaylistLevelType } from '../types/loader';\nimport { toMsFromMpegTsClock } from '../utils/timescale-conversion';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport type { SourceBufferName } from '../types/buffer';\nimport type {\n AudioSample,\n DemuxedAudioTrack,\n DemuxedMetadataTrack,\n DemuxedUserdataTrack,\n DemuxedVideoTrack,\n VideoSample,\n} from '../types/demuxer';\nimport type {\n InitSegmentData,\n Mp4Sample,\n RemuxedMetadata,\n RemuxedTrack,\n RemuxedUserdata,\n Remuxer,\n RemuxerResult,\n} from '../types/remuxer';\nimport type { TrackSet } from '../types/track';\nimport type { TypeSupported } from '../utils/codecs';\nimport type { ILogger } from '../utils/logger';\nimport type { RationalTimestamp } from '../utils/timescale-conversion';\n\nconst MAX_SILENT_FRAME_DURATION = 10 * 1000; // 10 seconds\nconst AAC_SAMPLES_PER_FRAME = 1024;\nconst MPEG_AUDIO_SAMPLE_PER_FRAME = 1152;\nconst AC3_SAMPLES_PER_FRAME = 1536;\n\nlet chromeVersion: number | null = null;\nlet safariWebkitVersion: number | null = null;\n\nfunction createMp4Sample(\n isKeyframe: boolean,\n duration: number,\n size: number,\n cts: number,\n): Mp4Sample {\n return {\n duration,\n size,\n cts,\n flags: {\n isLeading: 0,\n isDependedOn: 0,\n hasRedundancy: 0,\n degradPrio: 0,\n dependsOn: isKeyframe ? 2 : 1,\n isNonSync: isKeyframe ? 0 : 1,\n },\n };\n}\nexport default class MP4Remuxer implements Remuxer {\n private readonly logger: ILogger;\n private readonly observer: HlsEventEmitter;\n private readonly config: HlsConfig;\n private readonly typeSupported: TypeSupported;\n private ISGenerated: boolean = false;\n private _initPTS: RationalTimestamp | null = null;\n private _initDTS: RationalTimestamp | null = null;\n private nextAvcDts: number | null = null;\n private nextAudioPts: number | null = null;\n private videoSampleDuration: number | null = null;\n private isAudioContiguous: boolean = false;\n private isVideoContiguous: boolean = false;\n private videoTrackConfig?: {\n width?: number;\n height?: number;\n pixelRatio?: [number, number];\n };\n\n constructor(\n observer: HlsEventEmitter,\n config: HlsConfig,\n typeSupported: TypeSupported,\n logger: ILogger,\n ) {\n this.observer = observer;\n this.config = config;\n this.typeSupported = typeSupported;\n this.logger = logger;\n this.ISGenerated = false;\n\n if (chromeVersion === null) {\n const userAgent = navigator.userAgent || '';\n const result = userAgent.match(/Chrome\\/(\\d+)/i);\n chromeVersion = result ? parseInt(result[1]) : 0;\n }\n if (safariWebkitVersion === null) {\n const result = navigator.userAgent.match(/Safari\\/(\\d+)/i);\n safariWebkitVersion = result ? parseInt(result[1]) : 0;\n }\n }\n\n destroy() {\n // @ts-ignore\n this.config = this.videoTrackConfig = this._initPTS = this._initDTS = null;\n }\n\n resetTimeStamp(defaultTimeStamp: RationalTimestamp | null) {\n this.logger.log('[mp4-remuxer]: initPTS & initDTS reset');\n this._initPTS = this._initDTS = defaultTimeStamp;\n }\n\n resetNextTimestamp() {\n this.logger.log('[mp4-remuxer]: reset next timestamp');\n this.isVideoContiguous = false;\n this.isAudioContiguous = false;\n }\n\n resetInitSegment() {\n this.logger.log('[mp4-remuxer]: ISGenerated flag reset');\n this.ISGenerated = false;\n this.videoTrackConfig = undefined;\n }\n\n getVideoStartPts(videoSamples: VideoSample[]) {\n // Get the minimum PTS value relative to the first sample's PTS, normalized for 33-bit wrapping\n let rolloverDetected = false;\n const firstPts = videoSamples[0].pts;\n const startPTS = videoSamples.reduce((minPTS, sample) => {\n let pts = sample.pts;\n let delta = pts - minPTS;\n if (delta < -4294967296) {\n // 2^32, see PTSNormalize for reasoning, but we're hitting a rollover here, and we don't want that to impact the timeOffset calculation\n rolloverDetected = true;\n pts = normalizePts(pts, firstPts);\n delta = pts - minPTS;\n }\n if (delta > 0) {\n return minPTS;\n }\n return pts;\n }, firstPts);\n if (rolloverDetected) {\n this.logger.debug('PTS rollover detected');\n }\n return startPTS;\n }\n\n remux(\n audioTrack: DemuxedAudioTrack,\n videoTrack: DemuxedVideoTrack,\n id3Track: DemuxedMetadataTrack,\n textTrack: DemuxedUserdataTrack,\n timeOffset: number,\n accurateTimeOffset: boolean,\n flush: boolean,\n playlistType: PlaylistLevelType,\n ): RemuxerResult {\n let video: RemuxedTrack | undefined;\n let audio: RemuxedTrack | undefined;\n let initSegment: InitSegmentData | undefined;\n let text: RemuxedUserdata | undefined;\n let id3: RemuxedMetadata | undefined;\n let independent: boolean | undefined;\n let audioTimeOffset = timeOffset;\n let videoTimeOffset = timeOffset;\n\n // If we're remuxing audio and video progressively, wait until we've received enough samples for each track before proceeding.\n // This is done to synchronize the audio and video streams. We know if the current segment will have samples if the \"pid\"\n // parameter is greater than -1. The pid is set when the PMT is parsed, which contains the tracks list.\n // However, if the initSegment has already been generated, or we've reached the end of a segment (flush),\n // then we can remux one track without waiting for the other.\n const hasAudio = audioTrack.pid > -1;\n const hasVideo = videoTrack.pid > -1;\n const length = videoTrack.samples.length;\n const enoughAudioSamples = audioTrack.samples.length > 0;\n const enoughVideoSamples = (flush && length > 0) || length > 1;\n const canRemuxAvc =\n ((!hasAudio || enoughAudioSamples) &&\n (!hasVideo || enoughVideoSamples)) ||\n this.ISGenerated ||\n flush;\n\n if (canRemuxAvc) {\n if (this.ISGenerated) {\n const config = this.videoTrackConfig;\n if (\n (config &&\n (videoTrack.width !== config.width ||\n videoTrack.height !== config.height ||\n videoTrack.pixelRatio?.[0] !== config.pixelRatio?.[0] ||\n videoTrack.pixelRatio?.[1] !== config.pixelRatio?.[1])) ||\n (!config && enoughVideoSamples) ||\n (this.nextAudioPts === null && enoughAudioSamples)\n ) {\n this.resetInitSegment();\n }\n }\n if (!this.ISGenerated) {\n initSegment = this.generateIS(\n audioTrack,\n videoTrack,\n timeOffset,\n accurateTimeOffset,\n );\n }\n\n const isVideoContiguous = this.isVideoContiguous;\n let firstKeyFrameIndex = -1;\n let firstKeyFramePTS;\n\n if (enoughVideoSamples) {\n firstKeyFrameIndex = findKeyframeIndex(videoTrack.samples);\n if (!isVideoContiguous && this.config.forceKeyFrameOnDiscontinuity) {\n independent = true;\n if (firstKeyFrameIndex > 0) {\n this.logger.warn(\n `[mp4-remuxer]: Dropped ${firstKeyFrameIndex} out of ${length} video samples due to a missing keyframe`,\n );\n const startPTS = this.getVideoStartPts(videoTrack.samples);\n videoTrack.samples = videoTrack.samples.slice(firstKeyFrameIndex);\n videoTrack.dropped += firstKeyFrameIndex;\n videoTimeOffset +=\n (videoTrack.samples[0].pts - startPTS) /\n videoTrack.inputTimeScale;\n firstKeyFramePTS = videoTimeOffset;\n } else if (firstKeyFrameIndex === -1) {\n this.logger.warn(\n `[mp4-remuxer]: No keyframe found out of ${length} video samples`,\n );\n independent = false;\n }\n }\n }\n\n if (this.ISGenerated) {\n if (enoughAudioSamples && enoughVideoSamples) {\n // timeOffset is expected to be the offset of the first timestamp of this fragment (first DTS)\n // if first audio DTS is not aligned with first video DTS then we need to take that into account\n // when providing timeOffset to remuxAudio / remuxVideo. if we don't do that, there might be a permanent / small\n // drift between audio and video streams\n const startPTS = this.getVideoStartPts(videoTrack.samples);\n const tsDelta =\n normalizePts(audioTrack.samples[0].pts, startPTS) - startPTS;\n const audiovideoTimestampDelta = tsDelta / videoTrack.inputTimeScale;\n audioTimeOffset += Math.max(0, audiovideoTimestampDelta);\n videoTimeOffset += Math.max(0, -audiovideoTimestampDelta);\n }\n\n // Purposefully remuxing audio before video, so that remuxVideo can use nextAudioPts, which is calculated in remuxAudio.\n if (enoughAudioSamples) {\n // if initSegment was generated without audio samples, regenerate it again\n if (!audioTrack.samplerate) {\n this.logger.warn(\n '[mp4-remuxer]: regenerate InitSegment as audio detected',\n );\n initSegment = this.generateIS(\n audioTrack,\n videoTrack,\n timeOffset,\n accurateTimeOffset,\n );\n }\n audio = this.remuxAudio(\n audioTrack,\n audioTimeOffset,\n this.isAudioContiguous,\n accurateTimeOffset,\n hasVideo ||\n enoughVideoSamples ||\n playlistType === PlaylistLevelType.AUDIO\n ? videoTimeOffset\n : undefined,\n );\n if (enoughVideoSamples) {\n const audioTrackLength = audio ? audio.endPTS - audio.startPTS : 0;\n // if initSegment was generated without video samples, regenerate it again\n if (!videoTrack.inputTimeScale) {\n this.logger.warn(\n '[mp4-remuxer]: regenerate InitSegment as video detected',\n );\n initSegment = this.generateIS(\n audioTrack,\n videoTrack,\n timeOffset,\n accurateTimeOffset,\n );\n }\n video = this.remuxVideo(\n videoTrack,\n videoTimeOffset,\n isVideoContiguous,\n audioTrackLength,\n );\n }\n } else if (enoughVideoSamples) {\n video = this.remuxVideo(\n videoTrack,\n videoTimeOffset,\n isVideoContiguous,\n 0,\n );\n }\n if (video) {\n video.firstKeyFrame = firstKeyFrameIndex;\n video.independent = firstKeyFrameIndex !== -1;\n video.firstKeyFramePTS = firstKeyFramePTS;\n }\n }\n }\n\n // Allow ID3 and text to remux, even if more audio/video samples are required\n if (this.ISGenerated && this._initPTS && this._initDTS) {\n if (id3Track.samples.length) {\n id3 = flushTextTrackMetadataCueSamples(\n id3Track,\n timeOffset,\n this._initPTS,\n this._initDTS,\n );\n }\n\n if (textTrack.samples.length) {\n text = flushTextTrackUserdataCueSamples(\n textTrack,\n timeOffset,\n this._initPTS,\n );\n }\n }\n\n return {\n audio,\n video,\n initSegment,\n independent,\n text,\n id3,\n };\n }\n\n generateIS(\n audioTrack: DemuxedAudioTrack,\n videoTrack: DemuxedVideoTrack,\n timeOffset: number,\n accurateTimeOffset: boolean,\n ): InitSegmentData | undefined {\n const audioSamples = audioTrack.samples;\n const videoSamples = videoTrack.samples;\n const typeSupported = this.typeSupported;\n const tracks: TrackSet = {};\n const _initPTS = this._initPTS;\n let computePTSDTS = !_initPTS || accurateTimeOffset;\n let container = 'audio/mp4';\n let initPTS: number | undefined;\n let initDTS: number | undefined;\n let timescale: number | undefined;\n\n if (computePTSDTS) {\n initPTS = initDTS = Infinity;\n }\n\n if (audioTrack.config && audioSamples.length) {\n // let's use audio sampling rate as MP4 time scale.\n // rationale is that there is a integer nb of audio frames per audio sample (1024 for AAC)\n // using audio sampling rate here helps having an integer MP4 frame duration\n // this avoids potential rounding issue and AV sync issue\n audioTrack.timescale = audioTrack.samplerate;\n switch (audioTrack.segmentCodec) {\n case 'mp3':\n if (typeSupported.mpeg) {\n // Chrome and Safari\n container = 'audio/mpeg';\n audioTrack.codec = '';\n } else if (typeSupported.mp3) {\n // Firefox\n audioTrack.codec = 'mp3';\n }\n break;\n\n case 'ac3':\n audioTrack.codec = 'ac-3';\n break;\n }\n tracks.audio = {\n id: 'audio',\n container: container,\n codec: audioTrack.codec,\n initSegment:\n audioTrack.segmentCodec === 'mp3' && typeSupported.mpeg\n ? new Uint8Array(0)\n : MP4.initSegment([audioTrack]),\n metadata: {\n channelCount: audioTrack.channelCount,\n },\n };\n if (computePTSDTS) {\n timescale = audioTrack.inputTimeScale;\n if (!_initPTS || timescale !== _initPTS.timescale) {\n // remember first PTS of this demuxing context. for audio, PTS = DTS\n initPTS = initDTS =\n audioSamples[0].pts - Math.round(timescale * timeOffset);\n } else {\n computePTSDTS = false;\n }\n }\n }\n\n if (videoTrack.sps && videoTrack.pps && videoSamples.length) {\n // let's use input time scale as MP4 video timescale\n // we use input time scale straight away to avoid rounding issues on frame duration / cts computation\n videoTrack.timescale = videoTrack.inputTimeScale;\n tracks.video = {\n id: 'main',\n container: 'video/mp4',\n codec: videoTrack.codec,\n initSegment: MP4.initSegment([videoTrack]),\n metadata: {\n width: videoTrack.width,\n height: videoTrack.height,\n },\n };\n if (computePTSDTS) {\n timescale = videoTrack.inputTimeScale;\n if (!_initPTS || timescale !== _initPTS.timescale) {\n const startPTS = this.getVideoStartPts(videoSamples);\n const startOffset = Math.round(timescale * timeOffset);\n initDTS = Math.min(\n initDTS as number,\n normalizePts(videoSamples[0].dts, startPTS) - startOffset,\n );\n initPTS = Math.min(initPTS as number, startPTS - startOffset);\n } else {\n computePTSDTS = false;\n }\n }\n this.videoTrackConfig = {\n width: videoTrack.width,\n height: videoTrack.height,\n pixelRatio: videoTrack.pixelRatio,\n };\n }\n\n if (Object.keys(tracks).length) {\n this.ISGenerated = true;\n if (computePTSDTS) {\n this._initPTS = {\n baseTime: initPTS as number,\n timescale: timescale as number,\n };\n this._initDTS = {\n baseTime: initDTS as number,\n timescale: timescale as number,\n };\n } else {\n initPTS = timescale = undefined;\n }\n\n return {\n tracks,\n initPTS,\n timescale,\n };\n }\n }\n\n remuxVideo(\n track: DemuxedVideoTrack,\n timeOffset: number,\n contiguous: boolean,\n audioTrackLength: number,\n ): RemuxedTrack | undefined {\n const timeScale: number = track.inputTimeScale;\n const inputSamples: Array<VideoSample> = track.samples;\n const outputSamples: Array<Mp4Sample> = [];\n const nbSamples = inputSamples.length;\n const initPTS = this._initPTS as RationalTimestamp;\n let nextAvcDts = this.nextAvcDts;\n let offset = 8;\n let mp4SampleDuration = this.videoSampleDuration;\n let firstDTS;\n let lastDTS;\n let minPTS: number = Number.POSITIVE_INFINITY;\n let maxPTS: number = Number.NEGATIVE_INFINITY;\n let sortSamples = false;\n\n // if parsed fragment is contiguous with last one, let's use last DTS value as reference\n if (!contiguous || nextAvcDts === null) {\n const pts = timeOffset * timeScale;\n const cts =\n inputSamples[0].pts -\n normalizePts(inputSamples[0].dts, inputSamples[0].pts);\n if (\n chromeVersion &&\n nextAvcDts !== null &&\n Math.abs(pts - cts - nextAvcDts) < 15000\n ) {\n // treat as contigous to adjust samples that would otherwise produce video buffer gaps in Chrome\n contiguous = true;\n } else {\n // if not contiguous, let's use target timeOffset\n nextAvcDts = pts - cts;\n }\n }\n\n // PTS is coded on 33bits, and can loop from -2^32 to 2^32\n // PTSNormalize will make PTS/DTS value monotonic, we use last known DTS value as reference value\n const initTime = (initPTS.baseTime * timeScale) / initPTS.timescale;\n for (let i = 0; i < nbSamples; i++) {\n const sample = inputSamples[i];\n sample.pts = normalizePts(sample.pts - initTime, nextAvcDts);\n sample.dts = normalizePts(sample.dts - initTime, nextAvcDts);\n if (sample.dts < inputSamples[i > 0 ? i - 1 : i].dts) {\n sortSamples = true;\n }\n }\n\n // sort video samples by DTS then PTS then demux id order\n if (sortSamples) {\n inputSamples.sort(function (a, b) {\n const deltadts = a.dts - b.dts;\n const deltapts = a.pts - b.pts;\n return deltadts || deltapts;\n });\n }\n\n // Get first/last DTS\n firstDTS = inputSamples[0].dts;\n lastDTS = inputSamples[inputSamples.length - 1].dts;\n\n // Sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS\n // set this constant duration as being the avg delta between consecutive DTS.\n const inputDuration = lastDTS - firstDTS;\n const averageSampleDuration = inputDuration\n ? Math.round(inputDuration / (nbSamples - 1))\n : mp4SampleDuration || track.inputTimeScale / 30;\n\n // if fragment are contiguous, detect hole/overlapping between fragments\n if (contiguous) {\n // check timestamp continuity across consecutive fragments (this is to remove inter-fragment gap/hole)\n const delta = firstDTS - nextAvcDts;\n const foundHole = delta > averageSampleDuration;\n const foundOverlap = delta < -1;\n if (foundHole || foundOverlap) {\n if (foundHole) {\n this.logger.warn(\n `${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(\n delta,\n true,\n )} ms (${delta}dts) hole between fragments detected at ${timeOffset.toFixed(\n 3,\n )}`,\n );\n } else {\n this.logger.warn(\n `${(track.segmentCodec || '').toUpperCase()}: ${toMsFromMpegTsClock(\n -delta,\n true,\n )} ms (${delta}dts) overlapping between fragments detected at ${timeOffset.toFixed(\n 3,\n )}`,\n );\n }\n if (\n !foundOverlap ||\n nextAvcDts >= inputSamples[0].pts ||\n chromeVersion\n ) {\n firstDTS = nextAvcDts;\n const firstPTS = inputSamples[0].pts - delta;\n if (foundHole) {\n inputSamples[0].dts = firstDTS;\n inputSamples[0].pts = firstPTS;\n } else {\n let isPTSOrderRetained = true;\n for (let i = 0; i < inputSamples.length; i++) {\n if (inputSamples[i].dts > firstPTS && isPTSOrderRetained) {\n break;\n }\n\n const prevPTS = inputSamples[i].pts;\n inputSamples[i].dts -= delta;\n inputSamples[i].pts -= delta;\n\n // check to see if this sample's PTS order has changed\n // relative to the next one\n if (i < inputSamples.length - 1) {\n const nextSamplePTS = inputSamples[i + 1].pts;\n const currentSamplePTS = inputSamples[i].pts;\n\n const currentOrder = nextSamplePTS <= currentSamplePTS;\n const prevOrder = nextSamplePTS <= prevPTS;\n\n isPTSOrderRetained = currentOrder == prevOrder;\n }\n }\n }\n this.logger.log(\n `Video: Initial PTS/DTS adjusted: ${toMsFromMpegTsClock(\n firstPTS,\n true,\n )}/${toMsFromMpegTsClock(\n firstDTS,\n true,\n )}, delta: ${toMsFromMpegTsClock(delta, true)} ms`,\n );\n }\n }\n }\n\n firstDTS = Math.max(0, firstDTS);\n\n let nbNalu = 0;\n let naluLen = 0;\n let dtsStep = firstDTS;\n for (let i = 0; i < nbSamples; i++) {\n // compute total/avc sample length and nb of NAL units\n const sample = inputSamples[i];\n const units = sample.units;\n const nbUnits = units.length;\n let sampleLen = 0;\n for (let j = 0; j < nbUnits; j++) {\n sampleLen += units[j].data.length;\n }\n\n naluLen += sampleLen;\n nbNalu += nbUnits;\n sample.length = sampleLen;\n\n // ensure sample monotonic DTS\n if (sample.dts < dtsStep) {\n sample.dts = dtsStep;\n dtsStep += (averageSampleDuration / 4) | 0 || 1;\n } else {\n dtsStep = sample.dts;\n }\n\n minPTS = Math.min(sample.pts, minPTS);\n maxPTS = Math.max(sample.pts, maxPTS);\n }\n lastDTS = inputSamples[nbSamples - 1].dts;\n\n /* concatenate the video data and construct the mdat in place\n (need 8 more bytes to fill length and mpdat type) */\n const mdatSize = naluLen + 4 * nbNalu + 8;\n let mdat;\n try {\n mdat = new Uint8Array(mdatSize);\n } catch (err) {\n this.observer.emit(Events.ERROR, Events.ERROR, {\n type: ErrorTypes.MUX_ERROR,\n details: ErrorDetails.REMUX_ALLOC_ERROR,\n fatal: false,\n error: err,\n bytes: mdatSize,\n reason: `fail allocating video mdat ${mdatSize}`,\n });\n return;\n }\n const view = new DataView(mdat.buffer);\n view.setUint32(0, mdatSize);\n mdat.set(MP4.types.mdat, 4);\n\n let stretchedLastFrame = false;\n let minDtsDelta = Number.POSITIVE_INFINITY;\n let minPtsDelta = Number.POSITIVE_INFINITY;\n let maxDtsDelta = Number.NEGATIVE_INFINITY;\n let maxPtsDelta = Number.NEGATIVE_INFINITY;\n for (let i = 0; i < nbSamples; i++) {\n const VideoSample = inputSamples[i];\n const VideoSampleUnits = VideoSample.units;\n let mp4SampleLength = 0;\n // convert NALU bitstream to MP4 format (prepend NALU with size field)\n for (let j = 0, nbUnits = VideoSampleUnits.length; j < nbUnits; j++) {\n const unit = VideoSampleUnits[j];\n const unitData = unit.data;\n const unitDataLen = unit.data.byteLength;\n view.setUint32(offset, unitDataLen);\n offset += 4;\n mdat.set(unitData, offset);\n offset += unitDataLen;\n mp4SampleLength += 4 + unitDataLen;\n }\n\n // expected sample duration is the Decoding Timestamp diff of consecutive samples\n let ptsDelta;\n if (i < nbSamples - 1) {\n mp4SampleDuration = inputSamples[i + 1].dts - VideoSample.dts;\n ptsDelta = inputSamples[i + 1].pts - VideoSample.pts;\n } else {\n const config = this.config;\n const lastFrameDuration =\n i > 0\n ? VideoSample.dts - inputSamples[i - 1].dts\n : averageSampleDuration;\n ptsDelta =\n i > 0\n ? VideoSample.pts - inputSamples[i - 1].pts\n : averageSampleDuration;\n if (config.stretchShortVideoTrack && this.nextAudioPts !== null) {\n // In some cases, a segment's audio track duration may exceed the video track duration.\n // Since we've already remuxed audio, and we know how long the audio track is, we look to\n // see if the delta to the next segment is longer than maxBufferHole.\n // If so, playback would potentially get stuck, so we artificially inflate\n // the duration of the last frame to minimize any potential gap between segments.\n const gapTolerance = Math.floor(config.maxBufferHole * timeScale);\n const deltaToFrameEnd =\n (audioTrackLength\n ? minPTS + audioTrackLength * timeScale\n : this.nextAudioPts) - VideoSample.pts;\n if (deltaToFrameEnd > gapTolerance) {\n // We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video\n // frame overlap. maxBufferHole should be >> lastFrameDuration anyway.\n mp4SampleDuration = deltaToFrameEnd - lastFrameDuration;\n if (mp4SampleDuration < 0) {\n mp4SampleDuration = lastFrameDuration;\n } else {\n stretchedLastFrame = true;\n }\n this.logger.log(\n `[mp4-remuxer]: It is approximately ${\n deltaToFrameEnd / 90\n } ms to the next segment; using duration ${\n mp4SampleDuration / 90\n } ms for the last video frame.`,\n );\n } else {\n mp4SampleDuration = lastFrameDuration;\n }\n } else {\n mp4SampleDuration = lastFrameDuration;\n }\n }\n const compositionTimeOffset = Math.round(\n VideoSample.pts - VideoSample.dts,\n );\n minDtsDelta = Math.min(minDtsDelta, mp4SampleDuration);\n maxDtsDelta = Math.max(maxDtsDelta, mp4SampleDuration);\n minPtsDelta = Math.min(minPtsDelta, ptsDelta);\n maxPtsDelta = Math.max(maxPtsDelta, ptsDelta);\n\n outputSamples.push(\n createMp4Sample(\n VideoSample.key,\n mp4SampleDuration,\n mp4SampleLength,\n compositionTimeOffset,\n ),\n );\n }\n\n if (outputSamples.length) {\n if (chromeVersion) {\n if (chromeVersion < 70) {\n // Chrome workaround, mark first sample as being a Random Access Point (keyframe) to avoid sourcebuffer append issue\n // https://code.google.com/p/chromium/issues/detail?id=229412\n const flags = outputSamples[0].flags;\n flags.dependsOn = 2;\n flags.isNonSync = 0;\n }\n } else if (safariWebkitVersion) {\n // Fix for \"CNN special report, with CC\" in test-streams (Safari browser only)\n // Ignore DTS when frame durations are irregular. Safari MSE does not handle this leading to gaps.\n if (\n maxPtsDelta - minPtsDelta < maxDtsDelta - minDtsDelta &&\n averageSampleDuration / maxDtsDelta < 0.025 &&\n outputSamples[0].cts === 0\n ) {\n this.logger.warn(\n 'Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.',\n );\n let dts = firstDTS;\n for (let i = 0, len = outputSamples.length; i < len; i++) {\n const nextDts = dts + outputSamples[i].duration;\n const pts = dts + outputSamples[i].cts;\n if (i < len - 1) {\n const nextPts = nextDts + outputSamples[i + 1].cts;\n outputSamples[i].duration = nextPts - pts;\n } else {\n outputSamples[i].duration = i\n ? outputSamples[i - 1].duration\n : averageSampleDuration;\n }\n outputSamples[i].cts = 0;\n dts = nextDts;\n }\n }\n }\n }\n // next AVC/HEVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)\n mp4SampleDuration =\n stretchedLastFrame || !mp4SampleDuration\n ? averageSampleDuration\n : mp4SampleDuration;\n this.nextAvcDts = nextAvcDts = lastDTS + mp4SampleDuration;\n this.videoSampleDuration = mp4SampleDuration;\n this.isVideoContiguous = true;\n const moof = MP4.moof(\n track.sequenceNumber++,\n firstDTS,\n Object.assign(track, {\n samples: outputSamples,\n }),\n );\n const type: SourceBufferName = 'video';\n const data = {\n data1: moof,\n data2: mdat,\n startPTS: minPTS / timeScale,\n endPTS: (maxPTS + mp4SampleDuration) / timeScale,\n startDTS: firstDTS / timeScale,\n endDTS: (nextAvcDts as number) / timeScale,\n type,\n hasAudio: false,\n hasVideo: true,\n nb: outputSamples.length,\n dropped: track.dropped,\n };\n track.samples = [];\n track.dropped = 0;\n return data;\n }\n\n getSamplesPerFrame(track: DemuxedAudioTrack) {\n switch (track.segmentCodec) {\n case 'mp3':\n return MPEG_AUDIO_SAMPLE_PER_FRAME;\n case 'ac3':\n return AC3_SAMPLES_PER_FRAME;\n default:\n return AAC_SAMPLES_PER_FRAME;\n }\n }\n\n remuxAudio(\n track: DemuxedAudioTrack,\n timeOffset: number,\n contiguous: boolean,\n accurateTimeOffset: boolean,\n videoTimeOffset?: number,\n ): RemuxedTrack | undefined {\n const inputTimeScale: number = track.inputTimeScale;\n const mp4timeScale: number = track.samplerate\n ? track.samplerate\n : inputTimeScale;\n const scaleFactor: number = inputTimeScale / mp4timeScale;\n const mp4SampleDuration: number = this.getSamplesPerFrame(track);\n const inputSampleDuration: number = mp4SampleDuration * scaleFactor;\n const initPTS = this._initPTS as RationalTimestamp;\n const rawMPEG: boolean =\n track.segmentCodec === 'mp3' && this.typeSupported.mpeg;\n const outputSamples: Array<Mp4Sample> = [];\n const alignedWithVideo = videoTimeOffset !== undefined;\n\n let inputSamples: Array<AudioSample> = track.samples;\n let offset: number = rawMPEG ? 0 : 8;\n let nextAudioPts: number = this.nextAudioPts || -1;\n\n // window.audioSamples ? window.audioSamples.push(inputSamples.map(s => s.pts)) : (window.audioSamples = [inputSamples.map(s => s.pts)]);\n\n // for audio samples, also consider consecutive fragments as being contiguous (even if a level switch occurs),\n // for sake of clarity:\n // consecutive fragments are frags with\n // - less than 100ms gaps between new time offset (if accurate) and next expected PTS OR\n // - less than 20 audio frames distance\n // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)\n // this helps ensuring audio continuity\n // and this also avoids audio glitches/cut when switching quality, or reporting wrong duration on first audio frame\n const timeOffsetMpegTS = timeOffset * inputTimeScale;\n const initTime = (initPTS.baseTime * inputTimeScale) / initPTS.timescale;\n this.isAudioContiguous = contiguous =\n contiguous ||\n ((inputSamples.length &&\n nextAudioPts > 0 &&\n ((accurateTimeOffset &&\n Math.abs(timeOffsetMpegTS - nextAudioPts) < 9000) ||\n Math.abs(\n normalizePts(inputSamples[0].pts - initTime, timeOffsetMpegTS) -\n nextAudioPts,\n ) <\n 20 * inputSampleDuration)) as boolean);\n\n // compute normalized PTS\n inputSamples.forEach(function (sample) {\n sample.pts = normalizePts(sample.pts - initTime, timeOffsetMpegTS);\n });\n\n if (!contiguous || nextAudioPts < 0) {\n // filter out sample with negative PTS that are not playable anyway\n // if we don't remove these negative samples, they will shift all audio samples forward.\n // leading to audio overlap between current / next fragment\n inputSamples = inputSamples.filter((sample) => sample.pts >= 0);\n\n // in case all samples have negative PTS, and have been filtered out, return now\n if (!inputSamples.length) {\n return;\n }\n\n if (videoTimeOffset === 0) {\n // Set the start to 0 to match video so that start gaps larger than inputSampleDuration are filled with silence\n nextAudioPts = 0;\n } else if (accurateTimeOffset && !alignedWithVideo) {\n // When not seeking, not live, and LevelDetails.PTSKnown, use fragment start as predicted next audio PTS\n nextAudioPts = Math.max(0, timeOffsetMpegTS);\n } else {\n // if frags are not contiguous and if we cant trust time offset, let's use first sample PTS as next audio PTS\n nextAudioPts = inputSamples[0].pts;\n }\n }\n\n // If the audio track is missing samples, the frames seem to get \"left-shifted\" within the\n // resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment.\n // In an effort to prevent this from happening, we inject frames here where there are gaps.\n // When possible, we inject a silent frame; when that's not possible, we duplicate the last\n // frame.\n\n if (track.segmentCodec === 'aac') {\n const maxAudioFramesDrift = this.config.maxAudioFramesDrift;\n for (let i = 0, nextPts = nextAudioPts; i < inputSamples.length; i++) {\n // First, let's see how far off this frame is from where we expect it to be\n const sample = inputSamples[i];\n const pts = sample.pts;\n const delta = pts - nextPts;\n const duration = Math.abs((1000 * delta) / inputTimeScale);\n\n // When remuxing with video, if we're overlapping by more than a duration, drop this sample to stay in sync\n if (\n delta <= -maxAudioFramesDrift * inputSampleDuration &&\n alignedWithVideo\n ) {\n if (i === 0) {\n this.logger.warn(\n `Audio frame @ ${(pts / inputTimeScale).toFixed(\n 3,\n )}s overlaps nextAudioPts by ${Math.round(\n (1000 * delta) / inputTimeScale,\n )} ms.`,\n );\n this.nextAudioPts = nextAudioPts = nextPts = pts;\n }\n } // eslint-disable-line brace-style\n\n // Insert missing frames if:\n // 1: We're more than maxAudioFramesDrift frame away\n // 2: Not more than MAX_SILENT_FRAME_DURATION away\n // 3: currentTime (aka nextPtsNorm) is not 0\n // 4: remuxing with video (videoTimeOffset !== undefined)\n else if (\n delta >= maxAudioFramesDrift * inputSampleDuration &&\n duration < MAX_SILENT_FRAME_DURATION &&\n alignedWithVideo\n ) {\n let missing = Math.round(delta / inputSampleDuration);\n // Adjust nextPts so that silent samples are aligned with media pts. This will prevent media samples from\n // later being shifted if nextPts is based on timeOffset and delta is not a multiple of inputSampleDuration.\n nextPts = pts - missing * inputSampleDuration;\n if (nextPts < 0) {\n missing--;\n nextPts += inputSampleDuration;\n }\n if (i === 0) {\n this.nextAudioPts = nextAudioPts = nextPts;\n }\n this.logger.warn(\n `[mp4-remuxer]: Injecting ${missing} audio frame @ ${(\n nextPts / inputTimeScale\n ).toFixed(3)}s due to ${Math.round(\n (1000 * delta) / inputTimeScale,\n )} ms gap.`,\n );\n for (let j = 0; j < missing; j++) {\n const newStamp = Math.max(nextPts as number, 0);\n let fillFrame = AAC.getSilentFrame(\n track.parsedCodec || track.manifestCodec || track.codec,\n track.channelCount,\n );\n if (!fillFrame) {\n this.logger.log(\n '[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.',\n );\n fillFrame = sample.unit.subarray();\n }\n inputSamples.splice(i, 0, {\n unit: fillFrame,\n pts: newStamp,\n });\n nextPts += inputSampleDuration;\n i++;\n }\n }\n sample.pts = nextPts;\n nextPts += inputSampleDuration;\n }\n }\n let firstPTS: number | null = null;\n let lastPTS: number | null = null;\n let mdat: any;\n let mdatSize: number = 0;\n let sampleLength: number = inputSamples.length;\n while (sampleLength--) {\n mdatSize += inputSamples[sampleLength].unit.byteLength;\n }\n for (let j = 0, nbSamples = inputSamples.length; j < nbSamples; j++) {\n const audioSample = inputSamples[j];\n const unit = audioSample.unit;\n let pts = audioSample.pts;\n if (lastPTS !== null) {\n // If we have more than one sample, set the duration of the sample to the \"real\" duration; the PTS diff with\n // the previous sample\n const prevSample = outputSamples[j - 1];\n prevSample.duration = Math.round((pts - lastPTS) / scaleFactor);\n } else {\n if (contiguous && track.segmentCodec === 'aac') {\n // set PTS/DTS to expected PTS/DTS\n pts = nextAudioPts;\n }\n // remember first PTS of our audioSamples\n firstPTS = pts;\n if (mdatSize > 0) {\n /* concatenate the audio data and construct the mdat in place\n (need 8 more bytes to fill length and mdat type) */\n mdatSize += offset;\n try {\n mdat = new Uint8Array(mdatSize);\n } catch (err) {\n this.observer.emit(Events.ERROR, Events.ERROR, {\n type: ErrorTypes.MUX_ERROR,\n details: ErrorDetails.REMUX_ALLOC_ERROR,\n fatal: false,\n error: err,\n bytes: mdatSize,\n reason: `fail allocating audio mdat ${mdatSize}`,\n });\n return;\n }\n if (!rawMPEG) {\n const view = new DataView(mdat.buffer);\n view.setUint32(0, mdatSize);\n mdat.set(MP4.types.mdat, 4);\n }\n } else {\n // no audio samples\n return;\n }\n }\n mdat.set(unit, offset);\n const unitLen = unit.byteLength;\n offset += unitLen;\n // Default the sample's duration to the computed mp4SampleDuration, which will either be 1024 for AAC or 1152 for MPEG\n // In the case that we have 1 sample, this will be the duration. If we have more than one sample, the duration\n // becomes the PTS diff with the previous sample\n outputSamples.push(createMp4Sample(true, mp4SampleDuration, unitLen, 0));\n lastPTS = pts;\n }\n\n // We could end up with no audio samples if all input samples were overlapping with the previously remuxed ones\n const nbSamples = outputSamples.length;\n if (!nbSamples) {\n return;\n }\n\n // The next audio sample PTS should be equal to last sample PTS + duration\n const lastSample = outputSamples[outputSamples.length - 1];\n this.nextAudioPts = nextAudioPts =\n lastPTS! + scaleFactor * lastSample.duration;\n\n // Set the track samples from inputSamples to outputSamples before remuxing\n const moof = rawMPEG\n ? new Uint8Array(0)\n : MP4.moof(\n track.sequenceNumber++,\n firstPTS! / scaleFactor,\n Object.assign({}, track, { samples: outputSamples }),\n );\n\n // Clear the track samples. This also clears the samples array in the demuxer, since the reference is shared\n track.samples = [];\n const start = firstPTS! / inputTimeScale;\n const end = nextAudioPts / inputTimeScale;\n const type: SourceBufferName = 'audio';\n const audioData = {\n data1: moof,\n data2: mdat,\n startPTS: start,\n endPTS: end,\n startDTS: start,\n endDTS: end,\n type,\n hasAudio: true,\n hasVideo: false,\n nb: nbSamples,\n };\n\n this.isAudioContiguous = true;\n return audioData;\n }\n}\n\nexport function normalizePts(value: number, reference: number | null): number {\n let offset;\n if (reference === null) {\n return value;\n }\n\n if (reference < value) {\n // - 2^33\n offset = -8589934592;\n } else {\n // + 2^33\n offset = 8589934592;\n }\n /* PTS is 33bit (from 0 to 2^33 -1)\n if diff between value and reference is bigger than half of the amplitude (2^32) then it means that\n PTS looping occured. fill the gap */\n while (Math.abs(value - reference) > 4294967296) {\n value += offset;\n }\n\n return value;\n}\n\nfunction findKeyframeIndex(samples: Array<VideoSample>): number {\n for (let i = 0; i < samples.length; i++) {\n if (samples[i].key) {\n return i;\n }\n }\n return -1;\n}\n\nexport function flushTextTrackMetadataCueSamples(\n track: DemuxedMetadataTrack,\n timeOffset: number,\n initPTS: RationalTimestamp,\n initDTS: RationalTimestamp,\n): RemuxedMetadata | undefined {\n const length = track.samples.length;\n if (!length) {\n return;\n }\n const inputTimeScale = track.inputTimeScale;\n for (let index = 0; index < length; index++) {\n const sample = track.samples[index];\n // setting id3 pts, dts to relative time\n // using this._initPTS and this._initDTS to calculate relative time\n sample.pts =\n normalizePts(\n sample.pts - (initPTS.baseTime * inputTimeScale) / initPTS.timescale,\n timeOffset * inputTimeScale,\n ) / inputTimeScale;\n sample.dts =\n normalizePts(\n sample.dts - (initDTS.baseTime * inputTimeScale) / initDTS.timescale,\n timeOffset * inputTimeScale,\n ) / inputTimeScale;\n }\n const samples = track.samples;\n track.samples = [];\n return {\n samples,\n };\n}\n\nexport function flushTextTrackUserdataCueSamples(\n track: DemuxedUserdataTrack,\n timeOffset: number,\n initPTS: RationalTimestamp,\n): RemuxedUserdata | undefined {\n const length = track.samples.length;\n if (!length) {\n return;\n }\n\n const inputTimeScale = track.inputTimeScale;\n for (let index = 0; index < length; index++) {\n const sample = track.samples[index];\n // setting text pts, dts to relative time\n // using this._initPTS and this._initDTS to calculate relative time\n sample.pts =\n normalizePts(\n sample.pts - (initPTS.baseTime * inputTimeScale) / initPTS.timescale,\n timeOffset * inputTimeScale,\n ) / inputTimeScale;\n }\n track.samples.sort((a, b) => a.pts - b.pts);\n const samples = track.samples;\n track.samples = [];\n return {\n samples,\n };\n}\n","import type { BaseTrackSet } from '../types/buffer';\n\nexport function getMediaSource(\n preferManagedMediaSource = true,\n): typeof MediaSource | undefined {\n if (typeof self === 'undefined') return undefined;\n const mms =\n (preferManagedMediaSource || !self.MediaSource) &&\n ((self as any).ManagedMediaSource as undefined | typeof MediaSource);\n return (\n mms ||\n self.MediaSource ||\n ((self as any).WebKitMediaSource as typeof MediaSource)\n );\n}\n\nexport function isManagedMediaSource(source: typeof MediaSource | undefined) {\n return (\n typeof self !== 'undefined' && source === (self as any).ManagedMediaSource\n );\n}\n\nexport function isCompatibleTrackChange(\n currentTracks: BaseTrackSet,\n requiredTracks: BaseTrackSet,\n): boolean {\n const trackNames = Object.keys(currentTracks);\n const requiredTrackNames = Object.keys(requiredTracks);\n const trackCount = trackNames.length;\n const requiredTrackCount = requiredTrackNames.length;\n return (\n !trackCount ||\n !requiredTrackCount ||\n (trackCount === requiredTrackCount &&\n !trackNames.some((name) => requiredTrackNames.indexOf(name) === -1))\n );\n}\n","import { getMediaSource } from './mediasource-helper';\nimport { isHEVC } from './mp4-tools';\n\nexport const userAgentHevcSupportIsInaccurate = () => {\n return /\\(Windows.+Firefox\\//i.test(navigator.userAgent);\n};\n\n// from http://mp4ra.org/codecs.html\n// values indicate codec selection preference (lower is higher priority)\nexport const sampleEntryCodesISO = {\n audio: {\n a3ds: 1,\n 'ac-3': 0.95,\n 'ac-4': 1,\n alac: 0.9,\n alaw: 1,\n dra1: 1,\n 'dts+': 1,\n 'dts-': 1,\n dtsc: 1,\n dtse: 1,\n dtsh: 1,\n 'ec-3': 0.9,\n enca: 1,\n fLaC: 0.9, // MP4-RA listed codec entry for FLAC\n flac: 0.9, // legacy browser codec name for FLAC\n FLAC: 0.9, // some manifests may list \"FLAC\" with Apple's tools\n g719: 1,\n g726: 1,\n m4ae: 1,\n mha1: 1,\n mha2: 1,\n mhm1: 1,\n mhm2: 1,\n mlpa: 1,\n mp4a: 1,\n 'raw ': 1,\n Opus: 1,\n opus: 1, // browsers expect this to be lowercase despite MP4RA says 'Opus'\n samr: 1,\n sawb: 1,\n sawp: 1,\n sevc: 1,\n sqcp: 1,\n ssmv: 1,\n twos: 1,\n ulaw: 1,\n },\n video: {\n avc1: 1,\n avc2: 1,\n avc3: 1,\n avc4: 1,\n avcp: 1,\n av01: 0.8,\n drac: 1,\n dva1: 1,\n dvav: 1,\n dvh1: 0.7,\n dvhe: 0.7,\n encv: 1,\n hev1: 0.75,\n hvc1: 0.75,\n mjp2: 1,\n mp4v: 1,\n mvc1: 1,\n mvc2: 1,\n mvc3: 1,\n mvc4: 1,\n resv: 1,\n rv60: 1,\n s263: 1,\n svc1: 1,\n svc2: 1,\n 'vc-1': 1,\n vp08: 1,\n vp09: 0.9,\n },\n text: {\n stpp: 1,\n wvtt: 1,\n },\n} as const;\n\nexport type CodecType = 'audio' | 'video';\n\nexport function isCodecType(codec: string, type: CodecType): boolean {\n const typeCodes = sampleEntryCodesISO[type];\n return !!typeCodes && !!typeCodes[codec.slice(0, 4)];\n}\n\nexport function areCodecsMediaSourceSupported(\n codecs: string,\n type: CodecType,\n preferManagedMediaSource = true,\n): boolean {\n return !codecs\n .split(',')\n .some(\n (codec) =>\n !isCodecMediaSourceSupported(codec, type, preferManagedMediaSource),\n );\n}\n\nfunction isCodecMediaSourceSupported(\n codec: string,\n type: CodecType,\n preferManagedMediaSource = true,\n): boolean {\n const MediaSource = getMediaSource(preferManagedMediaSource);\n return MediaSource?.isTypeSupported(mimeTypeForCodec(codec, type)) ?? false;\n}\n\nexport function mimeTypeForCodec(codec: string, type: CodecType): string {\n return `${type}/mp4;codecs=${codec}`;\n}\n\nexport function videoCodecPreferenceValue(\n videoCodec: string | undefined,\n): number {\n if (videoCodec) {\n const fourCC = videoCodec.substring(0, 4);\n return sampleEntryCodesISO.video[fourCC];\n }\n return 2;\n}\n\nexport function codecsSetSelectionPreferenceValue(codecSet: string): number {\n const limitedHevcSupport = userAgentHevcSupportIsInaccurate();\n return codecSet.split(',').reduce((num, fourCC) => {\n const lowerPriority = limitedHevcSupport && isHEVC(fourCC);\n const preferenceValue = lowerPriority\n ? 9\n : sampleEntryCodesISO.video[fourCC];\n if (preferenceValue) {\n return (preferenceValue * 2 + num) / (num ? 3 : 2);\n }\n return (sampleEntryCodesISO.audio[fourCC] + num) / (num ? 2 : 1);\n }, 0);\n}\n\ninterface CodecNameCache {\n flac?: string;\n opus?: string;\n}\n\nconst CODEC_COMPATIBLE_NAMES: CodecNameCache = {};\n\ntype LowerCaseCodecType = 'flac' | 'opus';\n\nfunction getCodecCompatibleNameLower(\n lowerCaseCodec: LowerCaseCodecType,\n preferManagedMediaSource = true,\n): string {\n if (CODEC_COMPATIBLE_NAMES[lowerCaseCodec]) {\n return CODEC_COMPATIBLE_NAMES[lowerCaseCodec]!;\n }\n\n const codecsToCheck = {\n // Idealy fLaC and Opus would be first (spec-compliant) but\n // some browsers will report that fLaC is supported then fail.\n // see: https://bugs.chromium.org/p/chromium/issues/detail?id=1422728\n flac: ['flac', 'fLaC', 'FLAC'],\n opus: ['opus', 'Opus'],\n // Replace audio codec info if browser does not support mp4a.40.34,\n // and demuxer can fallback to 'audio/mpeg' or 'audio/mp4;codecs=\"mp3\"'\n 'mp4a.40.34': ['mp3'],\n }[lowerCaseCodec];\n\n for (let i = 0; i < codecsToCheck.length; i++) {\n if (\n isCodecMediaSourceSupported(\n codecsToCheck[i],\n 'audio',\n preferManagedMediaSource,\n )\n ) {\n CODEC_COMPATIBLE_NAMES[lowerCaseCodec] = codecsToCheck[i];\n return codecsToCheck[i];\n } else if (\n codecsToCheck[i] === 'mp3' &&\n getMediaSource(preferManagedMediaSource)?.isTypeSupported('audio/mpeg')\n ) {\n return '';\n }\n }\n\n return lowerCaseCodec;\n}\n\nconst AUDIO_CODEC_REGEXP = /flac|opus|mp4a\\.40\\.34/i;\nexport function getCodecCompatibleName(\n codec: string,\n preferManagedMediaSource = true,\n): string {\n return codec.replace(AUDIO_CODEC_REGEXP, (m) =>\n getCodecCompatibleNameLower(\n m.toLowerCase() as LowerCaseCodecType,\n preferManagedMediaSource,\n ),\n );\n}\n\nexport function pickMostCompleteCodecName(\n parsedCodec: string | undefined,\n levelCodec: string | undefined,\n): string | undefined {\n // Parsing of mp4a codecs strings in mp4-tools from media is incomplete as of d8c6c7a\n // so use level codec is parsed codec is unavailable or incomplete\n if (\n parsedCodec &&\n (parsedCodec.length > 4 ||\n ['ac-3', 'ec-3', 'alac', 'fLaC', 'Opus'].indexOf(parsedCodec) !== -1)\n ) {\n return parsedCodec;\n }\n if (levelCodec) {\n const levelCodecs = levelCodec.split(',');\n if (levelCodecs.length > 1) {\n if (parsedCodec) {\n for (let i = levelCodecs.length; i--; ) {\n if (levelCodecs[i].substring(0, 4) === parsedCodec.substring(0, 4)) {\n return levelCodecs[i];\n }\n }\n }\n return levelCodecs[0];\n }\n }\n return levelCodec || parsedCodec;\n}\n\nexport function convertAVC1ToAVCOTI(videoCodecs: string): string {\n // Convert avc1 codec string from RFC-4281 to RFC-6381 for MediaSource.isTypeSupported\n // Examples: avc1.66.30 to avc1.42001e and avc1.77.30,avc1.66.30 to avc1.4d001e,avc1.42001e.\n const codecs = videoCodecs.split(',');\n for (let i = 0; i < codecs.length; i++) {\n const avcdata = codecs[i].split('.');\n if (avcdata.length > 2) {\n let result = avcdata.shift() + '.';\n result += parseInt(avcdata.shift() as string).toString(16);\n result += (\n '000' + parseInt(avcdata.shift() as string).toString(16)\n ).slice(-4);\n codecs[i] = result;\n }\n }\n return codecs.join(',');\n}\n\nexport function fillInMissingAV01Params(videoCodec: string): string {\n // Used to fill in incomplete AV1 playlist CODECS strings for mediaCapabilities.decodingInfo queries\n if (videoCodec.startsWith('av01.')) {\n const av1params = videoCodec.split('.');\n const placeholders = ['0', '111', '01', '01', '01', '0'];\n for (let i = av1params.length; i > 4 && i < 10; i++) {\n av1params[i] = placeholders[i - 4];\n }\n return av1params.join('.');\n }\n return videoCodec;\n}\n\nexport interface TypeSupported {\n mpeg: boolean;\n mp3: boolean;\n ac3: boolean;\n}\n\nexport function getM2TSSupportedAudioTypes(\n preferManagedMediaSource: boolean,\n): TypeSupported {\n const MediaSource = getMediaSource(preferManagedMediaSource) || {\n isTypeSupported: () => false,\n };\n return {\n mpeg: MediaSource.isTypeSupported('audio/mpeg'),\n mp3: MediaSource.isTypeSupported('audio/mp4; codecs=\"mp3\"'),\n ac3: __USE_M2TS_ADVANCED_CODECS__\n ? MediaSource.isTypeSupported('audio/mp4; codecs=\"ac-3\"')\n : false,\n };\n}\n\nexport function getCodecsForMimeType(mimeType: string): string {\n return mimeType.replace(/^.+codecs=[\"']?([^\"']+).*$/, '$1');\n}\n","import {\n flushTextTrackMetadataCueSamples,\n flushTextTrackUserdataCueSamples,\n} from './mp4-remuxer';\nimport { ElementaryStreamTypes } from '../loader/fragment';\nimport { getCodecCompatibleName } from '../utils/codecs';\nimport { type ILogger, logger } from '../utils/logger';\nimport { patchEncyptionData } from '../utils/mp4-tools';\nimport {\n getDuration,\n getStartDTS,\n offsetStartDTS,\n parseInitSegment,\n} from '../utils/mp4-tools';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport type { DecryptData } from '../loader/level-key';\nimport type {\n DemuxedAudioTrack,\n DemuxedMetadataTrack,\n DemuxedUserdataTrack,\n PassthroughTrack,\n} from '../types/demuxer';\nimport type {\n InitSegmentData,\n RemuxedTrack,\n Remuxer,\n RemuxerResult,\n} from '../types/remuxer';\nimport type { TrackSet } from '../types/track';\nimport type { TypeSupported } from '../utils/codecs';\nimport type { InitData, InitDataTrack } from '../utils/mp4-tools';\nimport type { RationalTimestamp } from '../utils/timescale-conversion';\n\nclass PassThroughRemuxer implements Remuxer {\n private readonly logger: ILogger;\n private emitInitSegment: boolean = false;\n private audioCodec?: string;\n private videoCodec?: string;\n private initData?: InitData;\n private initPTS: RationalTimestamp | null = null;\n private initTracks?: TrackSet;\n private lastEndTime: number | null = null;\n\n constructor(\n observer: HlsEventEmitter,\n config: HlsConfig,\n typeSupported: TypeSupported,\n logger: ILogger,\n ) {\n this.logger = logger;\n }\n\n public destroy() {}\n\n public resetTimeStamp(defaultInitPTS: RationalTimestamp | null) {\n this.initPTS = defaultInitPTS;\n this.lastEndTime = null;\n }\n\n public resetNextTimestamp() {\n this.lastEndTime = null;\n }\n\n public resetInitSegment(\n initSegment: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n decryptdata: DecryptData | null,\n ) {\n this.audioCodec = audioCodec;\n this.videoCodec = videoCodec;\n this.generateInitSegment(patchEncyptionData(initSegment, decryptdata));\n this.emitInitSegment = true;\n }\n\n private generateInitSegment(initSegment: Uint8Array | undefined): void {\n let { audioCodec, videoCodec } = this;\n if (!initSegment?.byteLength) {\n this.initTracks = undefined;\n this.initData = undefined;\n return;\n }\n const initData = (this.initData = parseInitSegment(initSegment));\n\n // Get codec from initSegment\n if (initData.audio) {\n audioCodec = getParsedTrackCodec(\n initData.audio,\n ElementaryStreamTypes.AUDIO,\n );\n }\n\n if (initData.video) {\n videoCodec = getParsedTrackCodec(\n initData.video,\n ElementaryStreamTypes.VIDEO,\n );\n }\n\n const tracks: TrackSet = {};\n if (initData.audio && initData.video) {\n tracks.audiovideo = {\n container: 'video/mp4',\n codec: audioCodec + ',' + videoCodec,\n initSegment,\n id: 'main',\n };\n } else if (initData.audio) {\n tracks.audio = {\n container: 'audio/mp4',\n codec: audioCodec,\n initSegment,\n id: 'audio',\n };\n } else if (initData.video) {\n tracks.video = {\n container: 'video/mp4',\n codec: videoCodec,\n initSegment,\n id: 'main',\n };\n } else {\n this.logger.warn(\n '[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.',\n );\n }\n this.initTracks = tracks;\n }\n\n public remux(\n audioTrack: DemuxedAudioTrack,\n videoTrack: PassthroughTrack,\n id3Track: DemuxedMetadataTrack,\n textTrack: DemuxedUserdataTrack,\n timeOffset: number,\n accurateTimeOffset: boolean,\n ): RemuxerResult {\n let { initPTS, lastEndTime } = this;\n const result: RemuxerResult = {\n audio: undefined,\n video: undefined,\n text: textTrack,\n id3: id3Track,\n initSegment: undefined,\n };\n\n // If we haven't yet set a lastEndDTS, or it was reset, set it to the provided timeOffset. We want to use the\n // lastEndDTS over timeOffset whenever possible; during progressive playback, the media source will not update\n // the media duration (which is what timeOffset is provided as) before we need to process the next chunk.\n if (!Number.isFinite(lastEndTime!)) {\n lastEndTime = this.lastEndTime = timeOffset || 0;\n }\n\n // The binary segment data is added to the videoTrack in the mp4demuxer. We don't check to see if the data is only\n // audio or video (or both); adding it to video was an arbitrary choice.\n const data = videoTrack.samples;\n if (!data?.length) {\n return result;\n }\n\n const initSegment: InitSegmentData = {\n initPTS: undefined,\n timescale: 1,\n };\n let initData = this.initData;\n if (!initData?.length) {\n this.generateInitSegment(data);\n initData = this.initData;\n }\n if (!initData?.length) {\n // We can't remux if the initSegment could not be generated\n this.logger.warn(\n '[passthrough-remuxer.ts]: Failed to generate initSegment.',\n );\n return result;\n }\n if (this.emitInitSegment) {\n initSegment.tracks = this.initTracks as TrackSet;\n this.emitInitSegment = false;\n }\n\n const duration = getDuration(data, initData);\n const startDTS = getStartDTS(initData, data);\n const decodeTime = startDTS === null ? timeOffset : startDTS;\n if (\n (accurateTimeOffset || !initPTS) &&\n (isInvalidInitPts(initPTS, decodeTime, timeOffset, duration) ||\n initSegment.timescale !== initPTS.timescale)\n ) {\n initSegment.initPTS = decodeTime - timeOffset;\n if (initPTS && initPTS.timescale === 1) {\n this.logger.warn(\n `Adjusting initPTS @${timeOffset} from ${initPTS.baseTime / initPTS.timescale} to ${initSegment.initPTS}`,\n );\n }\n this.initPTS = initPTS = {\n baseTime: initSegment.initPTS,\n timescale: 1,\n };\n }\n\n const startTime = audioTrack\n ? decodeTime - initPTS.baseTime / initPTS.timescale\n : (lastEndTime as number);\n const endTime = startTime + duration;\n offsetStartDTS(initData, data, initPTS.baseTime / initPTS.timescale);\n\n if (duration > 0) {\n this.lastEndTime = endTime;\n } else {\n this.logger.warn('Duration parsed from mp4 should be greater than zero');\n this.resetNextTimestamp();\n }\n\n const hasAudio = !!initData.audio;\n const hasVideo = !!initData.video;\n\n let type: any = '';\n if (hasAudio) {\n type += 'audio';\n }\n\n if (hasVideo) {\n type += 'video';\n }\n\n const track: RemuxedTrack = {\n data1: data,\n startPTS: startTime,\n startDTS: startTime,\n endPTS: endTime,\n endDTS: endTime,\n type,\n hasAudio,\n hasVideo,\n nb: 1,\n dropped: 0,\n };\n\n result.audio = track.type === 'audio' ? track : undefined;\n result.video = track.type !== 'audio' ? track : undefined;\n result.initSegment = initSegment;\n result.id3 = flushTextTrackMetadataCueSamples(\n id3Track,\n timeOffset,\n initPTS,\n initPTS,\n );\n\n if (textTrack.samples.length) {\n result.text = flushTextTrackUserdataCueSamples(\n textTrack,\n timeOffset,\n initPTS,\n );\n }\n\n return result;\n }\n}\n\nfunction isInvalidInitPts(\n initPTS: RationalTimestamp | null,\n startDTS: number,\n timeOffset: number,\n duration: number,\n): initPTS is null {\n if (initPTS === null) {\n return true;\n }\n // InitPTS is invalid when distance from program would be more than segment duration or a minimum of one second\n const minDuration = Math.max(duration, 1);\n const startTime = startDTS - initPTS.baseTime / initPTS.timescale;\n return Math.abs(startTime - timeOffset) > minDuration;\n}\n\nfunction getParsedTrackCodec(\n track: InitDataTrack,\n type: ElementaryStreamTypes.AUDIO | ElementaryStreamTypes.VIDEO,\n): string {\n const parsedCodec = track?.codec;\n if (parsedCodec && parsedCodec.length > 4) {\n return parsedCodec;\n }\n if (type === ElementaryStreamTypes.AUDIO) {\n if (\n parsedCodec === 'ec-3' ||\n parsedCodec === 'ac-3' ||\n parsedCodec === 'alac'\n ) {\n return parsedCodec;\n }\n if (parsedCodec === 'fLaC' || parsedCodec === 'Opus') {\n // Opting not to get `preferManagedMediaSource` from player config for isSupported() check for simplicity\n const preferManagedMediaSource = false;\n return getCodecCompatibleName(parsedCodec, preferManagedMediaSource);\n }\n\n logger.warn(`Unhandled audio codec \"${parsedCodec}\" in mp4 MAP`);\n return parsedCodec || 'mp4a';\n }\n // Provide defaults based on codec type\n // This allows for some playback of some fmp4 playlists without CODECS defined in manifest\n logger.warn(`Unhandled video codec \"${parsedCodec}\" in mp4 MAP`);\n return parsedCodec || 'avc1';\n}\nexport default PassThroughRemuxer;\n","import AACDemuxer from './audio/aacdemuxer';\nimport { AC3Demuxer } from './audio/ac3-demuxer';\nimport MP3Demuxer from './audio/mp3demuxer';\nimport Decrypter from '../crypt/decrypter';\nimport MP4Demuxer from '../demux/mp4demuxer';\nimport TSDemuxer from '../demux/tsdemuxer';\nimport { ErrorDetails, ErrorTypes } from '../errors';\nimport { Events } from '../events';\nimport MP4Remuxer from '../remux/mp4-remuxer';\nimport PassThroughRemuxer from '../remux/passthrough-remuxer';\nimport { PlaylistLevelType } from '../types/loader';\nimport {\n getAesModeFromFullSegmentMethod,\n isFullSegmentEncryption,\n} from '../utils/encryption-methods-util';\nimport type { HlsConfig } from '../config';\nimport type { HlsEventEmitter } from '../events';\nimport type { DecryptData } from '../loader/level-key';\nimport type { Demuxer, DemuxerResult, KeyData } from '../types/demuxer';\nimport type { Remuxer } from '../types/remuxer';\nimport type { ChunkMetadata, TransmuxerResult } from '../types/transmuxer';\nimport type { TypeSupported } from '../utils/codecs';\nimport type { ILogger } from '../utils/logger';\nimport type { RationalTimestamp } from '../utils/timescale-conversion';\n\nlet now: () => number;\n// performance.now() not available on WebWorker, at least on Safari Desktop\ntry {\n now = self.performance.now.bind(self.performance);\n} catch (err) {\n now = Date.now;\n}\n\ntype MuxConfig =\n | { demux: typeof MP4Demuxer; remux: typeof PassThroughRemuxer }\n | { demux: typeof TSDemuxer; remux: typeof MP4Remuxer }\n | { demux: typeof AC3Demuxer; remux: typeof MP4Remuxer }\n | { demux: typeof AACDemuxer; remux: typeof MP4Remuxer }\n | { demux: typeof MP3Demuxer; remux: typeof MP4Remuxer };\n\nconst muxConfig: MuxConfig[] = [\n { demux: MP4Demuxer, remux: PassThroughRemuxer },\n { demux: TSDemuxer, remux: MP4Remuxer },\n { demux: AACDemuxer, remux: MP4Remuxer },\n { demux: MP3Demuxer, remux: MP4Remuxer },\n];\n\nif (__USE_M2TS_ADVANCED_CODECS__) {\n muxConfig.splice(2, 0, { demux: AC3Demuxer, remux: MP4Remuxer });\n}\n\nexport default class Transmuxer {\n private asyncResult: boolean = false;\n private logger: ILogger;\n private observer: HlsEventEmitter;\n private typeSupported: TypeSupported;\n private config: HlsConfig;\n private id: PlaylistLevelType;\n private demuxer?: Demuxer;\n private remuxer?: Remuxer;\n private decrypter?: Decrypter;\n private probe!: Function;\n private decryptionPromise: Promise<TransmuxerResult> | null = null;\n private transmuxConfig!: TransmuxConfig;\n private currentTransmuxState!: TransmuxState;\n\n constructor(\n observer: HlsEventEmitter,\n typeSupported: TypeSupported,\n config: HlsConfig,\n vendor: string,\n id: PlaylistLevelType,\n logger: ILogger,\n ) {\n this.observer = observer;\n this.typeSupported = typeSupported;\n this.config = config;\n this.id = id;\n this.logger = logger;\n }\n\n configure(transmuxConfig: TransmuxConfig) {\n this.transmuxConfig = transmuxConfig;\n if (this.decrypter) {\n this.decrypter.reset();\n }\n }\n\n push(\n data: ArrayBuffer,\n decryptdata: DecryptData | null,\n chunkMeta: ChunkMetadata,\n state?: TransmuxState,\n ): TransmuxerResult | Promise<TransmuxerResult> {\n const stats = chunkMeta.transmuxing;\n stats.executeStart = now();\n\n let uintData: Uint8Array = new Uint8Array(data);\n const { currentTransmuxState, transmuxConfig } = this;\n if (state) {\n this.currentTransmuxState = state;\n }\n\n const {\n contiguous,\n discontinuity,\n trackSwitch,\n accurateTimeOffset,\n timeOffset,\n initSegmentChange,\n } = state || currentTransmuxState;\n const {\n audioCodec,\n videoCodec,\n defaultInitPts,\n duration,\n initSegmentData,\n } = transmuxConfig;\n\n const keyData = getEncryptionType(uintData, decryptdata);\n if (keyData && isFullSegmentEncryption(keyData.method)) {\n const decrypter = this.getDecrypter();\n const aesMode = getAesModeFromFullSegmentMethod(keyData.method);\n\n // Software decryption is synchronous; webCrypto is not\n if (decrypter.isSync()) {\n // Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached\n // data is handled in the flush() call\n let decryptedData = decrypter.softwareDecrypt(\n uintData,\n keyData.key.buffer,\n keyData.iv.buffer,\n aesMode,\n );\n // For Low-Latency HLS Parts, decrypt in place, since part parsing is expected on push progress\n const loadingParts = chunkMeta.part > -1;\n if (loadingParts) {\n const data = decrypter.flush();\n decryptedData = data ? data.buffer : data;\n }\n if (!decryptedData) {\n stats.executeEnd = now();\n return emptyResult(chunkMeta);\n }\n uintData = new Uint8Array(decryptedData);\n } else {\n this.asyncResult = true;\n this.decryptionPromise = decrypter\n .webCryptoDecrypt(\n uintData,\n keyData.key.buffer,\n keyData.iv.buffer,\n aesMode,\n )\n .then((decryptedData): TransmuxerResult => {\n // Calling push here is important; if flush() is called while this is still resolving, this ensures that\n // the decrypted data has been transmuxed\n const result = this.push(\n decryptedData,\n null,\n chunkMeta,\n ) as TransmuxerResult;\n this.decryptionPromise = null;\n return result;\n });\n return this.decryptionPromise;\n }\n }\n\n const resetMuxers = this.needsProbing(discontinuity, trackSwitch);\n if (resetMuxers) {\n const error = this.configureTransmuxer(uintData);\n if (error) {\n this.logger.warn(`[transmuxer] ${error.message}`);\n this.observer.emit(Events.ERROR, Events.ERROR, {\n type: ErrorTypes.MEDIA_ERROR,\n details: ErrorDetails.FRAG_PARSING_ERROR,\n fatal: false,\n error,\n reason: error.message,\n });\n stats.executeEnd = now();\n return emptyResult(chunkMeta);\n }\n }\n\n if (discontinuity || trackSwitch || initSegmentChange || resetMuxers) {\n this.resetInitSegment(\n initSegmentData,\n audioCodec,\n videoCodec,\n duration,\n decryptdata,\n );\n }\n\n if (discontinuity || initSegmentChange || resetMuxers) {\n this.resetInitialTimestamp(defaultInitPts);\n }\n\n if (!contiguous) {\n this.resetContiguity();\n }\n\n const result = this.transmux(\n uintData,\n keyData,\n timeOffset,\n accurateTimeOffset,\n chunkMeta,\n );\n this.asyncResult = isPromise(result);\n\n const currentState = this.currentTransmuxState;\n\n currentState.contiguous = true;\n currentState.discontinuity = false;\n currentState.trackSwitch = false;\n\n stats.executeEnd = now();\n return result;\n }\n\n // Due to data caching, flush calls can produce more than one TransmuxerResult (hence the Array type)\n flush(\n chunkMeta: ChunkMetadata,\n ): TransmuxerResult[] | Promise<TransmuxerResult[]> {\n const stats = chunkMeta.transmuxing;\n stats.executeStart = now();\n\n const { decrypter, currentTransmuxState, decryptionPromise } = this;\n\n if (decryptionPromise) {\n this.asyncResult = true;\n // Upon resolution, the decryption promise calls push() and returns its TransmuxerResult up the stack. Therefore\n // only flushing is required for async decryption\n return decryptionPromise.then(() => {\n return this.flush(chunkMeta);\n });\n }\n\n const transmuxResults: TransmuxerResult[] = [];\n const { timeOffset } = currentTransmuxState;\n if (decrypter) {\n // The decrypter may have data cached, which needs to be demuxed. In this case we'll have two TransmuxResults\n // This happens in the case that we receive only 1 push call for a segment (either for non-progressive downloads,\n // or for progressive downloads with small segments)\n const decryptedData = decrypter.flush();\n if (decryptedData) {\n // Push always returns a TransmuxerResult if decryptdata is null\n transmuxResults.push(\n this.push(decryptedData.buffer, null, chunkMeta) as TransmuxerResult,\n );\n }\n }\n\n const { demuxer, remuxer } = this;\n if (!demuxer || !remuxer) {\n // If probing failed, then Hls.js has been given content its not able to handle\n stats.executeEnd = now();\n const emptyResults = [emptyResult(chunkMeta)];\n if (this.asyncResult) {\n return Promise.resolve(emptyResults);\n }\n return emptyResults;\n }\n\n const demuxResultOrPromise = demuxer.flush(timeOffset);\n if (isPromise(demuxResultOrPromise)) {\n this.asyncResult = true;\n // Decrypt final SAMPLE-AES samples\n return demuxResultOrPromise.then((demuxResult) => {\n this.flushRemux(transmuxResults, demuxResult, chunkMeta);\n return transmuxResults;\n });\n }\n\n this.flushRemux(transmuxResults, demuxResultOrPromise, chunkMeta);\n if (this.asyncResult) {\n return Promise.resolve(transmuxResults);\n }\n return transmuxResults;\n }\n\n private flushRemux(\n transmuxResults: TransmuxerResult[],\n demuxResult: DemuxerResult,\n chunkMeta: ChunkMetadata,\n ) {\n const { audioTrack, videoTrack, id3Track, textTrack } = demuxResult;\n const { accurateTimeOffset, timeOffset } = this.currentTransmuxState;\n this.logger.log(\n `[transmuxer.ts]: Flushed ${this.id} sn: ${chunkMeta.sn}${\n chunkMeta.part > -1 ? ' part: ' + chunkMeta.part : ''\n } of ${this.id === PlaylistLevelType.MAIN ? 'level' : 'track'} ${chunkMeta.level}`,\n );\n const remuxResult = this.remuxer!.remux(\n audioTrack,\n videoTrack,\n id3Track,\n textTrack,\n timeOffset,\n accurateTimeOffset,\n true,\n this.id,\n );\n transmuxResults.push({\n remuxResult,\n chunkMeta,\n });\n\n chunkMeta.transmuxing.executeEnd = now();\n }\n\n resetInitialTimestamp(defaultInitPts: RationalTimestamp | null) {\n const { demuxer, remuxer } = this;\n if (!demuxer || !remuxer) {\n return;\n }\n demuxer.resetTimeStamp(defaultInitPts);\n remuxer.resetTimeStamp(defaultInitPts);\n }\n\n resetContiguity() {\n const { demuxer, remuxer } = this;\n if (!demuxer || !remuxer) {\n return;\n }\n demuxer.resetContiguity();\n remuxer.resetNextTimestamp();\n }\n\n resetInitSegment(\n initSegmentData: Uint8Array | undefined,\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n trackDuration: number,\n decryptdata: DecryptData | null,\n ) {\n const { demuxer, remuxer } = this;\n if (!demuxer || !remuxer) {\n return;\n }\n demuxer.resetInitSegment(\n initSegmentData,\n audioCodec,\n videoCodec,\n trackDuration,\n );\n remuxer.resetInitSegment(\n initSegmentData,\n audioCodec,\n videoCodec,\n decryptdata,\n );\n }\n\n destroy(): void {\n if (this.demuxer) {\n this.demuxer.destroy();\n this.demuxer = undefined;\n }\n if (this.remuxer) {\n this.remuxer.destroy();\n this.remuxer = undefined;\n }\n }\n\n private transmux(\n data: Uint8Array,\n keyData: KeyData | null,\n timeOffset: number,\n accurateTimeOffset: boolean,\n chunkMeta: ChunkMetadata,\n ): TransmuxerResult | Promise<TransmuxerResult> {\n let result: TransmuxerResult | Promise<TransmuxerResult>;\n if (keyData && keyData.method === 'SAMPLE-AES') {\n result = this.transmuxSampleAes(\n data,\n keyData,\n timeOffset,\n accurateTimeOffset,\n chunkMeta,\n );\n } else {\n result = this.transmuxUnencrypted(\n data,\n timeOffset,\n accurateTimeOffset,\n chunkMeta,\n );\n }\n return result;\n }\n\n private transmuxUnencrypted(\n data: Uint8Array,\n timeOffset: number,\n accurateTimeOffset: boolean,\n chunkMeta: ChunkMetadata,\n ): TransmuxerResult {\n const { audioTrack, videoTrack, id3Track, textTrack } = (\n this.demuxer as Demuxer\n ).demux(data, timeOffset, false, !this.config.progressive);\n const remuxResult = this.remuxer!.remux(\n audioTrack,\n videoTrack,\n id3Track,\n textTrack,\n timeOffset,\n accurateTimeOffset,\n false,\n this.id,\n );\n return {\n remuxResult,\n chunkMeta,\n };\n }\n\n private transmuxSampleAes(\n data: Uint8Array,\n decryptData: KeyData,\n timeOffset: number,\n accurateTimeOffset: boolean,\n chunkMeta: ChunkMetadata,\n ): Promise<TransmuxerResult> {\n return (this.demuxer as Demuxer)\n .demuxSampleAes(data, decryptData, timeOffset)\n .then((demuxResult) => {\n const remuxResult = this.remuxer!.remux(\n demuxResult.audioTrack,\n demuxResult.videoTrack,\n demuxResult.id3Track,\n demuxResult.textTrack,\n timeOffset,\n accurateTimeOffset,\n false,\n this.id,\n );\n return {\n remuxResult,\n chunkMeta,\n };\n });\n }\n\n private configureTransmuxer(data: Uint8Array): void | Error {\n const { config, observer, typeSupported } = this;\n // probe for content type\n let mux;\n for (let i = 0, len = muxConfig.length; i < len; i++) {\n if (muxConfig[i].demux?.probe(data, this.logger)) {\n mux = muxConfig[i];\n break;\n }\n }\n if (!mux) {\n return new Error('Failed to find demuxer by probing fragment data');\n }\n // so let's check that current remuxer and demuxer are still valid\n const demuxer = this.demuxer;\n const remuxer = this.remuxer;\n const Remuxer: MuxConfig['remux'] = mux.remux;\n const Demuxer: MuxConfig['demux'] = mux.demux;\n if (!remuxer || !(remuxer instanceof Remuxer)) {\n this.remuxer = new Remuxer(observer, config, typeSupported, this.logger);\n }\n if (!demuxer || !(demuxer instanceof Demuxer)) {\n this.demuxer = new Demuxer(observer, config, typeSupported, this.logger);\n this.probe = Demuxer.probe;\n }\n }\n\n private needsProbing(discontinuity: boolean, trackSwitch: boolean): boolean {\n // in case of continuity change, or track switch\n // we might switch from content type (AAC container to TS container, or TS to fmp4 for example)\n return !this.demuxer || !this.remuxer || discontinuity || trackSwitch;\n }\n\n private getDecrypter(): Decrypter {\n let decrypter = this.decrypter;\n if (!decrypter) {\n decrypter = this.decrypter = new Decrypter(this.config);\n }\n return decrypter;\n }\n}\n\nfunction getEncryptionType(\n data: Uint8Array,\n decryptData: DecryptData | null,\n): KeyData | null {\n let encryptionType: KeyData | null = null;\n if (\n data.byteLength > 0 &&\n decryptData?.key != null &&\n decryptData.iv !== null &&\n decryptData.method != null\n ) {\n encryptionType = decryptData as KeyData;\n }\n return encryptionType;\n}\n\nconst emptyResult = (chunkMeta): TransmuxerResult => ({\n remuxResult: {},\n chunkMeta,\n});\n\nexport function isPromise<T>(p: Promise<T> | any): p is Promise<T> {\n return 'then' in p && p.then instanceof Function;\n}\n\nexport class TransmuxConfig {\n public audioCodec?: string;\n public videoCodec?: string;\n public initSegmentData?: Uint8Array;\n public duration: number;\n public defaultInitPts: RationalTimestamp | null;\n\n constructor(\n audioCodec: string | undefined,\n videoCodec: string | undefined,\n initSegmentData: Uint8Array | undefined,\n duration: number,\n defaultInitPts?: RationalTimestamp,\n ) {\n this.audioCodec = audioCodec;\n this.videoCodec = videoCodec;\n this.initSegmentData = initSegmentData;\n this.duration = duration;\n this.defaultInitPts = defaultInitPts || null;\n }\n}\n\nexport class TransmuxState {\n public discontinuity: boolean;\n public contiguous: boolean;\n public accurateTimeOffset: boolean;\n public trackSwitch: boolean;\n public timeOffset: number;\n public initSegmentChange: boolean;\n\n constructor(\n discontinuity: boolean,\n contiguous: boolean,\n accurateTimeOffset: boolean,\n trackSwitch: boolean,\n timeOffset: number,\n initSegmentChange: boolean,\n ) {\n this.discontinuity = discontinuity;\n this.contiguous = contiguous;\n this.accurateTimeOffset = accurateTimeOffset;\n this.trackSwitch = trackSwitch;\n this.timeOffset = timeOffset;\n this.initSegmentChange = initSegmentChange;\n }\n}\n","import { DecrypterAesMode } from '../crypt/decrypter-aes-mode';\n\nexport function isFullSegmentEncryption(method: string): boolean {\n return (\n method === 'AES-128' || method === 'AES-256' || method === 'AES-256-CTR'\n );\n}\n\nexport function getAesModeFromFullSegmentMethod(\n method: string,\n): DecrypterAesMode {\n switch (method) {\n case 'AES-128':\n case 'AES-256':\n return DecrypterAesMode.cbc;\n case 'AES-256-CTR':\n return DecrypterAesMode.ctr;\n default:\n throw new Error(`invalid full segment method ${method}`);\n }\n}\n","import { EventEmitter } from 'eventemitter3';\nimport Transmuxer, { isPromise } from '../demux/transmuxer';\nimport { ErrorDetails, ErrorTypes } from '../errors';\nimport { Events } from '../events';\nimport { enableLogs, type ILogFunction, type ILogger } from '../utils/logger';\nimport type { RemuxedTrack, RemuxerResult } from '../types/remuxer';\nimport type { ChunkMetadata, TransmuxerResult } from '../types/transmuxer';\n\nconst transmuxers: (Transmuxer | undefined)[] = [];\n\nif (typeof __IN_WORKER__ !== 'undefined' && __IN_WORKER__) {\n startWorker();\n}\n\nfunction startWorker() {\n self.addEventListener('message', (ev) => {\n const data = ev.data;\n const instanceNo = data.instanceNo;\n if (instanceNo === undefined) {\n return;\n }\n const transmuxer = transmuxers[instanceNo];\n if (data.cmd === 'reset') {\n delete transmuxers[data.resetNo];\n if (transmuxer) {\n transmuxer.destroy();\n }\n data.cmd = 'init';\n }\n if (data.cmd === 'init') {\n const config = JSON.parse(data.config);\n const observer = new EventEmitter();\n observer.on(Events.FRAG_DECRYPTED, forwardMessage);\n observer.on(Events.ERROR, forwardMessage);\n const logger = enableLogs(config.debug, data.id);\n forwardWorkerLogs(logger, instanceNo);\n transmuxers[instanceNo] = new Transmuxer(\n observer,\n data.typeSupported,\n config,\n '',\n data.id,\n logger,\n );\n forwardMessage('init', null, instanceNo);\n return;\n }\n if (!transmuxer) {\n return;\n }\n switch (data.cmd) {\n case 'configure': {\n transmuxer.configure(data.config);\n break;\n }\n case 'demux': {\n const transmuxResult: TransmuxerResult | Promise<TransmuxerResult> =\n transmuxer.push(\n data.data,\n data.decryptdata,\n data.chunkMeta,\n data.state,\n );\n if (isPromise(transmuxResult)) {\n transmuxResult\n .then((data) => {\n emitTransmuxComplete(self, data, instanceNo);\n })\n .catch((error) => {\n forwardMessage(\n Events.ERROR,\n {\n instanceNo,\n type: ErrorTypes.MEDIA_ERROR,\n details: ErrorDetails.FRAG_PARSING_ERROR,\n chunkMeta: data.chunkMeta,\n fatal: false,\n error,\n err: error,\n reason: `transmuxer-worker push error`,\n },\n instanceNo,\n );\n });\n } else {\n emitTransmuxComplete(self, transmuxResult, instanceNo);\n }\n break;\n }\n case 'flush': {\n const chunkMeta = data.chunkMeta as ChunkMetadata;\n const transmuxResult = transmuxer.flush(chunkMeta);\n if (isPromise(transmuxResult)) {\n transmuxResult\n .then((results: Array<TransmuxerResult>) => {\n handleFlushResult(\n self,\n results as Array<TransmuxerResult>,\n chunkMeta,\n instanceNo,\n );\n })\n .catch((error) => {\n forwardMessage(\n Events.ERROR,\n {\n type: ErrorTypes.MEDIA_ERROR,\n details: ErrorDetails.FRAG_PARSING_ERROR,\n chunkMeta: data.chunkMeta,\n fatal: false,\n error,\n err: error,\n reason: `transmuxer-worker flush error`,\n },\n instanceNo,\n );\n });\n } else {\n handleFlushResult(\n self,\n transmuxResult as Array<TransmuxerResult>,\n chunkMeta,\n instanceNo,\n );\n }\n break;\n }\n default:\n break;\n }\n });\n}\n\nfunction emitTransmuxComplete(\n self: any,\n transmuxResult: TransmuxerResult,\n instanceNo: number,\n): boolean {\n if (isEmptyResult(transmuxResult.remuxResult)) {\n return false;\n }\n const transferable: Array<ArrayBuffer> = [];\n const { audio, video } = transmuxResult.remuxResult;\n if (audio) {\n addToTransferable(transferable, audio);\n }\n if (video) {\n addToTransferable(transferable, video);\n }\n self.postMessage(\n { event: 'transmuxComplete', data: transmuxResult, instanceNo },\n transferable,\n );\n return true;\n}\n\n// Converts data to a transferable object https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast)\n// in order to minimize message passing overhead\nfunction addToTransferable(\n transferable: Array<ArrayBuffer>,\n track: RemuxedTrack,\n) {\n if (track.data1) {\n transferable.push(track.data1.buffer);\n }\n if (track.data2) {\n transferable.push(track.data2.buffer);\n }\n}\n\nfunction handleFlushResult(\n self: any,\n results: Array<TransmuxerResult>,\n chunkMeta: ChunkMetadata,\n instanceNo: number,\n) {\n const parsed = results.reduce(\n (parsed, result) =>\n emitTransmuxComplete(self, result, instanceNo) || parsed,\n false,\n );\n if (!parsed) {\n // Emit at least one \"transmuxComplete\" message even if media is not found to update stream-controller state to PARSING\n self.postMessage({\n event: 'transmuxComplete',\n data: results[0],\n instanceNo,\n });\n }\n self.postMessage({ event: 'flush', data: chunkMeta, instanceNo });\n}\n\nfunction forwardMessage(event, data, instanceNo) {\n self.postMessage({ event, data, instanceNo });\n}\n\nfunction forwardWorkerLogs(logger: ILogger, instanceNo: number) {\n for (const logFn in logger) {\n const func: ILogFunction = (message?) => {\n forwardMessage(\n 'workerLog',\n {\n logType: logFn,\n message,\n },\n instanceNo,\n );\n };\n logger[logFn] = func;\n }\n}\n\nfunction isEmptyResult(remuxResult: RemuxerResult) {\n return (\n !remuxResult.audio &&\n !remuxResult.video &&\n !remuxResult.text &&\n !remuxResult.id3 &&\n !remuxResult.initSegment\n );\n}\n"],"names":["has","Object","prototype","hasOwnProperty","prefix","Events","EE","fn","context","once","this","addListener","emitter","event","TypeError","listener","evt","_events","push","_eventsCount","clearEvent","EventEmitter","create","__proto__","eventNames","events","name","names","call","slice","getOwnPropertySymbols","concat","listeners","handlers","i","l","length","ee","Array","listenerCount","emit","a1","a2","a3","a4","a5","args","len","arguments","removeListener","undefined","apply","j","on","removeAllListeners","off","prefixed","module","exports","isId3Footer","data","offset","isId3Header","readId3Size","size","getId3Data","front","subarray","ErrorTypes","ErrorDetails","noop","fakeLogger","trace","debug","log","warn","info","error","createLogger","_extends","getLoggerFn","key","debugConfig","id","bind","type","func","self","console","exportedLogger","logger","isHeaderPattern","getHeaderLength","getFullFrameLength","isHeader","probe","headerLength","frameLength","newOffset","initTrackConfig","track","observer","audioCodec","samplerate","config","manifestCodec","byte2","adtsSamplingIndex","adtsObjectType","channelCount","codec","aacSampleIndex","parsedCodec","Error","ERROR","MEDIA_ERROR","details","FRAG_PARSING_ERROR","fatal","reason","message","getAudioConfig","getFrameDuration","appendFrame","pts","frameIndex","unit","stamp","header","parseFrameHeader","missing","Math","max","Uint8Array","set","sample","samples","isFiniteNumber","Number","isFinite","value","isSafeInteger","abs","MAX_SAFE_INTEGER","canParseId3","utf8ArrayToStr","array","exitOnNull","TextDecoder","decoded","decode","idx","indexOf","substring","replace","c","char2","char3","out","String","fromCharCode","toUint8","Infinity","Type","buffer","view","ArrayBuffer","unsafeGetArrayBuffer","bytesPerElement","BYTES_PER_ELEMENT","dataOffset","obj","byteLength","byteOffset","dataEnd","rawStart","start","floor","min","end","decodeId3ImageFrame","frame","metadataFrame","description","mimeType","pictureType","mimeTypeEndIndex","descriptionEndIndex","toArrayBuffer","decodeId3Frame","owner","privateData","decodeId3PrivFrame","index","url","decodeId3UrlFrame","text","decodeId3TextFrame","getId3FrameData","HEADER_FOOTER_SIZE","FRAME_SIZE","isId3TimestampFrame","readId3Timestamp","timeStampFrame","pts33Bit","timestamp","round","getId3Timestamp","frames","id3Data","frameData","getId3Frames","MetadataSchema","Hex","str","h","toString","sliceUint8","URL_REGEX","FIRST_SEGMENT_REGEX","SLASH_DOT_REGEX","SLASH_DOT_DOT_REGEX","URLToolkit","buildAbsoluteURL","baseURL","relativeURL","opts","trim","alwaysNormalize","basePartsForNormalise","parseURL","path","normalizePath","buildURLFromParts","relativeParts","scheme","baseParts","netLoc","pathParts","exec","builtParts","params","query","fragment","baseURLPath","newPath","lastIndexOf","parts","split","reverse","join","ElementaryStreamTypes","UINT32_MAX","pow","RemuxerTrackIdConfig","video","audio","id3","bin2str","readUint16","val","readUint32","readSint32","readUint64","result","writeUint32","findBox","results","endbox","subresults","parseSegmentIndex","sidx","references","version","timescale","earliestPresentationTime","firstOffset","startByte","referencesCount","referenceIndex","referenceInfo","referenceSize","subsegmentDuration","duration","parseInitSegment","initSegment","traks","trak","tkhd","trackId","mdhd","hdlr","hdlrType","soun","vide","stsdData","parseStsd","_objectSpread","forEach","trex","default","flags","stsd","sampleEntries","sampleEntriesEnd","fourCC","encrypted","encBox","sinf","schm","frma","avcCBox","toHex","codecBox","esdsBox","skipBERInteger","objectType","firstByte","audioObjectType","hvcCBox","profileByte","profileSpace","generalProfileIdc","profileCompat","tierFlag","levelIDC","constraintIndicator","toUpperCase","constraintString","byte","dvcCBox","profile","level","addLeadingZero","vpcCBox","bitDepth","av1CBox","highBitDepth","twelveBit","monochrome","chromaSubsamplingX","chromaSubsamplingY","chromaSamplePosition","bytes","limit","x","num","patchEncyptionData","decryptdata","keyId","isCommonEncryption","encBoxes","isAudio","enc","tenc","parseSinf","tencKeyId","some","b","computeRawDurationFromSamples","trun","sampleCount","appendUint8Array","data1","data2","temp","parseSamples","timeOffset","seiSamples","videoData","isHEVCFlavor","map","moof","moofOffset","traf","baseTime","tfdt","tfhd","tfhdFlags","defaultSampleDuration","defaultSampleSizePresent","defaultSampleSize","defaultSampleFlagsPresent","tfhdOffset","baseCodec","isHEVC","dataOffsetPresent","firstSampleFlagsPresent","sampleDurationPresent","sampleDuration","sampleSizePresent","sampleSize","sampleFlagsPresent","sampleCompositionOffsetsPresent","compositionOffset","trunOffset","sampleOffset","ix","naluTotalSize","naluSize","isSEIMessage","parseSEIMessageFromNALu","naluHeader","naluType","unescapedData","headerSize","discardEPB","seiPtr","payloadType","payloadSize","leftOver","payPtr","providerCode","userStructure","userDataType","enabled","totalBytes","byteArray","uuidStrArray","userDataBytes","uuid","userData","EPBPositions","newLength","newData","sourceIndex","shift","dummyTrack","inputTimeScale","pid","sequenceNumber","dropped","BaseAudioDemuxer","_audioTrack","_id3Track","cachedData","basePTS","initPTS","lastPTS","_proto","resetInitSegment","videoCodec","trackDuration","resetTimeStamp","deaultTimestamp","resetContiguity","canParse","demux","lastDataIndex","id3Track","_isFiniteNumber","initPTSFn","dts","audioId3","POSITIVE_INFINITY","partialData","audioTrack","videoTrack","textTrack","demuxSampleAes","keyData","Promise","reject","flush","destroy","_isFiniteNumber2","chromeVersion","BitratesMap","SamplingRateMap","SamplesCoefficients","BytesInSlot","parseHeader","samplesPerFrame","sampleRate","mpegVersion","mpegLayer","bitRateIndex","sampleRateIndex","paddingBit","channelMode","bitRate","sampleCoefficient","bytesInSlot","navigator","userAgent","match","parseInt","AACDemuxer","_BaseAudioDemuxer","_this","_inheritsLoose","container","segmentCodec","MpegAudio","ADTS","canGetFrameLength","getAudioBSID","bsid","numBits","Uint32Array","mask","bits","AC3Demuxer","samplingRateCode","frameSizeCode","skipCount","lfeon","bsmod","MP3Demuxer","DecrypterAesMode","AESCrypto","subtle","iv","aesMode","aesIV","decrypt","counter","AESDecryptor","rcon","subMix","invSubMix","sBox","invSBox","ksRows","keySize","keySchedule","invKeySchedule","initTable","uint8ArrayToUint32Array_","arrayBuffer","DataView","newArray","getUint32","subMix0","subMix1","subMix2","subMix3","invSubMix0","invSubMix1","invSubMix2","invSubMix3","d","xi","sx","x2","x4","x8","t","expandKey","keyBuffer","sameKey","ksRow","invKsRow","prev","sbox","networkToHostOrderSwap","word","inputArrayBuffer","t0","t1","t2","t3","s0","s1","s2","s3","inputWords0","inputWords1","inputWords2","inputWords3","nRounds","invSBOX","initVector","initVector0","initVector1","initVector2","initVector3","inputInt32","Int32Array","outputInt32","swapWord","FastAESKey","subtleAlgoName","getSubtleAlgoName","importKey","Decrypter","_temp","_ref$removePKCS7Paddi","removePKCS7Padding","logEnabled","softwareDecrypter","fastAesKey","remainderData","currentIV","currentResult","useSoftware","enableSoftwareAES","browserCrypto","crypto","webkitSubtle","e","isSync","reset","outputBytes","paddingBytes","getUint8","resolve","dataView","isView","softwareDecrypt","decryptResult","webCryptoDecrypt","logOnce","currentChunk","getValidChunk","_this2","onWebCryptoError","then","aesKey","catch","err","splitPoint","msg","emsgSchemePattern","MP4Demuxer","txtTrack","captionTrack","initData","_initData$video","_initData$audio","hasMoofData","videoSamples","progressive","segmentedData","segmentedRange","valid","remainder","moofs","last","segmentValidRange","extractID3Track","emsgs","emsgInfo","schemeIdUri","timeScale","presentationTimeDelta","presentationTime","eventDuration","leftPresentationTime","rightPresentationTime","_isSafeInteger","payload","parseEmsg","test","getEmsgStartTime","emsg","enableEmsgKLVMetadata","startsWith","misbklv","SampleAesDecrypter","decrypter","decryptBuffer","encryptedData","decryptAacSample","sampleIndex","callback","curUnit","encryptedBuffer","decryptedBuffer","decryptedData","decryptAacSamples","getAvcEncryptedData","decodedData","encryptedDataLen","Int8Array","outputPos","inputPos","getAvcDecryptedUnit","uint8DecryptedData","decryptAvcSample","unitIndex","decryptAvcSamples","curUnits","units","BaseVideoParser","VideoSample","createVideoSample","getLastNalUnit","_VideoSample","lastUnit","pushAccessUnit","nbSamples","lastSample","parseNALu","endOfSegment","overflow","state","naluState","lastState","lastUnitStart","lastUnitType","getNALuType","ExpGolomb","bytesAvailable","bitsAvailable","loadWord","position","workingBytes","availableBytes","skipBits","count","skipBytes","readBits","valu","skipLZ","leadingZeroCount","skipUEG","skipEG","readUEG","clz","readEG","readBoolean","readUByte","readUShort","readUInt","AvcVideoParser","_BaseVideoParser","parsePES","pes","spsfound","audFound","_VideoSample2","_VideoSample3","iskey","sliceType","readSliceType","_track$pixelRatio","_track$pixelRatio2","sps","readSPS","width","height","pixelRatio","codecarray","codecstring","pps","eg","skipScalingList","reader","lastScale","nextScale","numRefFramesInPicOrderCntCycle","scalingListCount","frameCropLeftOffset","frameCropRightOffset","frameCropTopOffset","frameCropBottomOffset","profileIdc","chromaFormatIdc","picOrderCntType","picWidthInMbsMinus1","picHeightInMapUnitsMinus1","frameMbsOnlyFlag","ceil","HevcVideoParser","_len","_key","initVPS","vps","readVPS","matchSPS","prop","codecString","pushParameterSet","readPPS","parameterSets","ebsp2rbsp","arr","dst","dstIdx","numTemporalLayers","temporalIdNested","max_sub_layers_minus1","general_profile_space","general_tier_flag","general_profile_idc","general_profile_compatibility_flags_1","general_profile_compatibility_flags_2","general_profile_compatibility_flags_3","general_profile_compatibility_flags_4","general_constraint_indicator_flags_1","general_constraint_indicator_flags_2","general_constraint_indicator_flags_3","general_constraint_indicator_flags_4","general_constraint_indicator_flags_5","general_constraint_indicator_flags_6","general_level_idc","sub_layer_profile_present_flags","sub_layer_level_present_flags","chroma_format_idc","pic_width_in_luma_samples","pic_height_in_luma_samples","conformance_window_flag","pic_left_offset","pic_right_offset","pic_top_offset","pic_bottom_offset","bit_depth_luma_minus8","bit_depth_chroma_minus8","log2_max_pic_order_cnt_lsb_minus4","sizeId","matrixId","coefNum","num_short_term_ref_pic_sets","num_delta_pocs","inter_ref_pic_set_prediction_flag","next_num_delta_pocs","used_by_curr_pic_flag","use_delta_flag","num_negative_pics","num_positive_pics","num_long_term_ref_pics_sps","min_spatial_segmentation_idc","sar_width","sar_height","fps_fixed","fps_den","fps_num","default_display_window_flag","aspect_ratio_idc","nal_hrd_parameters_present_flag","vcl_hrd_parameters_present_flag","sub_pic_hrd_params_present_flag","low_delay_hrd_flag","cpb_cnt","chroma_scale_w","chroma_scale_h","profile_space_string","profile_compatibility_buf","profile_compatibility_rev","profile_compatibility_flags_string","tier_flag_string","general_profile_compatibility_flags","general_constraint_indicator_flags","bit_depth","frame_rate","fixed","fps","tiles_enabled_flag","entropy_coding_sync_enabled_flag","parallelismType","sps1","sps2","substr","PACKET_LENGTH","TSDemuxer","typeSupported","sampleAes","pmtParsed","_pmtId","_videoTrack","_txtTrack","aacOverFlow","videoParser","syncOffset","scanwindow","foundPat","packetStart","tsPackets","parsePID","createTrack","pesData","isSampleAes","videoPid","audioPid","id3Pid","audioData","unknownPID","pmtId","tsPacketErrors","stt","parseAACPES","parseMPEGPES","parseAC3PES","parseID3PES","parsePAT","parsedPIDs","parsePMT","segmentVideoCodec","segmentAudioCodec","emitParsingError","demuxResult","extractRemainingSamples","startOffset","frameMissingBytes","sampleLength","frameOverflowBytes","recoverable","frameDuration","parsed","AC3","id3Sample","tableEnd","esInfoLength","logEncryptedSamplesFoundInUnencryptedStream","mpeg","mp3","ac3","parsePos","remaining","descriptorLen","levelRetry","stream","frag","pesLen","pesHdrLen","pesPts","pesDts","splice","pesFlags","payloadStartOffset","dataLen","AAC","getSilentFrame","MP4","init","types","avc1","avcC","hvc1","hvcC","btrt","dinf","dref","esds","ftyp","mdat","mdia","mfhd","minf","moov","mp4a","dac3","mvex","mvhd","pasp","sdtp","stbl","stco","stsc","stsz","stts","vmhd","smhd","charCodeAt","videoHdlr","audioHdlr","HDLR_TYPES","STTS","STSC","STCO","STSZ","VMHD","SMHD","STSD","majorBrand","avc1Brand","minorVersion","FTYP","box","DINF","upperWordDuration","lowerWordDuration","sn","baseMediaDecodeTime","tracks","boxes","dependsOn","isDependedOn","hasRedundancy","avcc","hSpacing","vSpacing","audioStsd","sampleDependencyTable","upperWordBaseMediaDecodeTime","lowerWordBaseMediaDecodeTime","cts","arraylen","isLeading","paddingValue","isNonSync","degradPrio","movie","ps","NALuLengthSize","temporal_id_nested","num_temporal_layers","iMax","hvcc","PlaylistLevelType","toMsFromMpegTsClock","destScale","srcBase","toTimescaleFromBase","safariWebkitVersion","createMp4Sample","isKeyframe","MP4Remuxer","ISGenerated","_initPTS","_initDTS","nextAvcDts","nextAudioPts","videoSampleDuration","isAudioContiguous","isVideoContiguous","videoTrackConfig","defaultTimeStamp","resetNextTimestamp","getVideoStartPts","rolloverDetected","firstPts","startPTS","reduce","minPTS","delta","normalizePts","remux","accurateTimeOffset","playlistType","independent","audioTimeOffset","videoTimeOffset","hasAudio","hasVideo","enoughAudioSamples","enoughVideoSamples","_videoTrack$pixelRati","_config$pixelRatio","_videoTrack$pixelRati2","_config$pixelRatio2","generateIS","firstKeyFramePTS","firstKeyFrameIndex","findKeyframeIndex","forceKeyFrameOnDiscontinuity","audiovideoTimestampDelta","remuxAudio","audioTrackLength","endPTS","remuxVideo","firstKeyFrame","flushTextTrackMetadataCueSamples","flushTextTrackUserdataCueSamples","initDTS","audioSamples","computePTSDTS","metadata","keys","contiguous","firstDTS","lastDTS","inputSamples","outputSamples","mp4SampleDuration","maxPTS","NEGATIVE_INFINITY","sortSamples","initTime","sort","a","deltadts","deltapts","inputDuration","averageSampleDuration","foundHole","foundOverlap","toFixed","firstPTS","isPTSOrderRetained","prevPTS","nextSamplePTS","nbNalu","naluLen","dtsStep","nbUnits","sampleLen","mdatSize","MUX_ERROR","REMUX_ALLOC_ERROR","setUint32","stretchedLastFrame","minDtsDelta","minPtsDelta","maxDtsDelta","maxPtsDelta","VideoSampleUnits","mp4SampleLength","unitData","unitDataLen","ptsDelta","lastFrameDuration","stretchShortVideoTrack","gapTolerance","maxBufferHole","deltaToFrameEnd","compositionTimeOffset","nextDts","nextPts","startDTS","endDTS","nb","getSamplesPerFrame","scaleFactor","inputSampleDuration","rawMPEG","alignedWithVideo","timeOffsetMpegTS","filter","maxAudioFramesDrift","newStamp","fillFrame","audioSample","unitLen","reference","getMediaSource","preferManagedMediaSource","MediaSource","ManagedMediaSource","WebKitMediaSource","isCodecMediaSourceSupported","_MediaSource$isTypeSu","isTypeSupported","mimeTypeForCodec","CODEC_COMPATIBLE_NAMES","AUDIO_CODEC_REGEXP","getCodecCompatibleName","m","lowerCaseCodec","codecsToCheck","flac","opus","_getMediaSource","getCodecCompatibleNameLower","toLowerCase","now","PassThroughRemuxer","emitInitSegment","initTracks","lastEndTime","defaultInitPTS","generateInitSegment","getParsedTrackCodec","audiovideo","_initData","_initData2","rawDuration","videoDuration","audioDuration","trafs","trackDefault","truns","sidxMinStart","sidxMaxEnd","sidxDuration","sidxs","subSegmentDuration","dur","ref","_isFiniteNumber3","getDuration","fmp4","startTime","getStartDTS","decodeTime","minDuration","isInvalidInitPts","endTime","upper","lower","offsetStartDTS","performance","Date","muxConfig","Transmuxer","vendor","asyncResult","demuxer","remuxer","decryptionPromise","transmuxConfig","currentTransmuxState","configure","chunkMeta","stats","transmuxing","executeStart","uintData","method","_ref","discontinuity","trackSwitch","initSegmentChange","defaultInitPts","initSegmentData","decryptData","encryptionType","getEncryptionType","getDecrypter","getAesModeFromFullSegmentMethod","part","executeEnd","emptyResult","resetMuxers","needsProbing","configureTransmuxer","resetInitialTimestamp","transmux","isPromise","currentState","transmuxResults","emptyResults","demuxResultOrPromise","flushRemux","_this$currentTransmux","remuxResult","transmuxSampleAes","transmuxUnencrypted","_demux","_this3","mux","_muxConfig$i$demux","Remuxer","Demuxer","p","Function","transmuxers","emitTransmuxComplete","transmuxResult","instanceNo","transferable","_transmuxResult$remux","addToTransferable","postMessage","handleFlushResult","forwardMessage","addEventListener","ev","transmuxer","cmd","resetNo","JSON","parse","FRAG_DECRYPTED","newLogger","enableLogs","_loop","logFn","logType","forwardWorkerLogs"],"mappings":"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CN,OAAQ,GACRC,KAAM,GACN,OAAQ,GACRC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNC,KAAM,GACNvoB,KAAM,GACNwoB,KAAM,GACNC,KAAM,GACN/jB,KAAM,GACNC,KAAM,GACNH,KAAM,GACNvF,KAAM,GACNyE,KAAM,GACN7D,KAAM,GACNX,KAAM,GACNwpB,KAAM,GACNC,KAAM,IAIE7B,EAAIE,MACRF,EAAIE,MAAM35B,eAAe+B,KAC3B03B,EAAIE,MAAM53B,GAAK,CACbA,EAAEw5B,WAAW,GACbx5B,EAAEw5B,WAAW,GACbx5B,EAAEw5B,WAAW,GACbx5B,EAAEw5B,WAAW,KAKnB,IAAMC,EAAY,IAAItzB,WAAW,CAC/B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,IACA,IACA,IACA,IACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,IACA,IACA,IACA,IACA,GACA,GACA,IACA,IACA,IACA,IACA,IACA,IAGIuzB,EAAY,IAAIvzB,WAAW,CAC/B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,IACA,IACA,IACA,IACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,IACA,IACA,IACA,IACA,GACA,GACA,IACA,IACA,IACA,IACA,IACA,IAGFuxB,EAAIiC,WAAa,CACf9rB,MAAO4rB,EACP3rB,MAAO4rB,GAGT,IAAMvB,EAAO,IAAIhyB,WAAW,CAC1B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,IACA,IACA,IACA,GACA,EACA,EACA,EACA,IAGI+yB,EAAO,IAAI/yB,WAAW,CAC1B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,IAGFuxB,EAAIkC,KAAOlC,EAAImC,KAAOnC,EAAIoC,KAAOZ,EAEjCxB,EAAIqC,KAAO,IAAI5zB,WAAW,CACxB,EACA,EACA,EACA,EACA,EACA,EACA,EACA,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CXsjB,EAAIhtB,KAAM6B,IAAQ,EAAK,KACvBmrB,EAAIhtB,KAAW,IAAN6B,GAGTmrB,EAAMA,EAAInsB,OAAOO,MAAMpC,UAAU2B,MAAMD,KAAKgC,IAI9C,IAAK1B,EAAI,EAAGA,EAAIkE,EAAMqoB,IAAIrsB,OAAQF,IAEhCa,GADAa,EAAOwC,EAAMqoB,IAAIvsB,IACN0I,WACX6jB,EAAIvtB,KAAM6B,IAAQ,EAAK,KACvB0rB,EAAIvtB,KAAW,IAAN6B,GAET0rB,EAAMA,EAAI1sB,OAAOO,MAAMpC,UAAU2B,MAAMD,KAAKgC,IAG9C,IAAMw5B,EAAOxD,EAAI6C,IACf7C,EAAIE,MAAME,KACV,IAAI3xB,WACF,CACE,EACA6lB,EAAI,GACJA,EAAI,GACJA,EAAI,GACJ,IACA,IAAO9nB,EAAM8nB,IAAI9rB,QAEhBL,OAAOmsB,GACPnsB,OAAO,CACNqE,EAAMqoB,IAAIrsB,SAEXL,OAAO0sB,KAGRL,EAAQhoB,EAAMgoB,MACdC,EAASjoB,EAAMioB,OACfgP,EAAWj3B,EAAMkoB,WAAW,GAC5BgP,EAAWl3B,EAAMkoB,WAAW,GAElC,OAAOsL,EAAI6C,IACT7C,EAAIE,MAAMC,KACV,IAAI1xB,WAAW,CACb,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACC+lB,GAAS,EAAK,IACP,IAARA,EACCC,GAAU,EAAK,IACP,IAATA,EACA,EACA,GACA,EACA,EACA,EACA,GACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,IACA,GACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACA,IACA,IACA,IACA,GACA,IACA,IACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,GACA,KAEF+O,EACAxD,EAAI6C,IACF7C,EAAIE,MAAMK,KACV,IAAI9xB,WAAW,CACb,EACA,GACA,IACA,IACA,E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,EAAI,EAAGA,EAAIyoB,EAAMvoB,OAAQF,GAAK,EAAG,CACxCg4B,EAAK5xB,IACH,IAAID,WAAW,CACZ,GAAKnG,GAAMA,IAAMo8B,EAAO,IAAM,GAC/B,EACA3T,EAAMzoB,GAAGE,SAEXA,GAEFA,GAAU,EACV,IAAK,IAAIgB,EAAI,EAAGA,EAAIunB,EAAMzoB,GAAGE,OAAQgB,GAAK,EACxC82B,EAAK5xB,IACH,IAAID,WAAW,CAACsiB,EAAMzoB,GAAGkB,GAAGhB,QAAU,EAAwB,IAArBuoB,EAAMzoB,GAAGkB,GAAGhB,SACrDA,GAEFA,GAAU,EACV83B,EAAK5xB,IAAIqiB,EAAMzoB,GAAGkB,GAAIhB,GACtBA,GAAUuoB,EAAMzoB,GAAGkB,GAAGhB,MAE1B,CACA,IAAMm8B,EAAO3E,EAAI6C,IAAI7C,EAAIE,MAAMI,KAAMA,GAC/B9L,EAAQhoB,EAAMgoB,MACdC,EAASjoB,EAAMioB,OACfgP,EAAWj3B,EAAMkoB,WAAW,GAC5BgP,EAAWl3B,EAAMkoB,WAAW,GAElC,OAAOsL,EAAI6C,IACT7C,EAAIE,MAAMG,KACV,IAAI5xB,WAAW,CACb,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACC+lB,GAAS,EAAK,IACP,IAARA,EACCC,GAAU,EAAK,IACP,IAATA,EACA,EACA,GACA,EACA,EACA,EACA,GACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,IACA,GACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,IACA,GACA,IACA,IACA,IACA,GACA,IACA,IACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,GACA,GACA,KAEFkQ,EACA3E,EAAI6C,IACF7C,EAAIE,MAAMK,KACV,IAAI9xB,WAAW,CACb,EACA,GACA,IACA,IACA,EACA,GACA,IACA,IACA,EACA,GACA,IACA,OAGJuxB,EAAI6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","x_google_ignoreList":[0,1,2,3,4,10,11,12,13,14,15,16,17,18,19,20,21,22,23,27]}
|